[PATCH 0/3] drm/doc/rfc: i915 VM_BIND feature design + uapi

2022-06-10 Thread Niranjana Vishwanathapura
This is the i915 driver VM_BIND feature design RFC patch series along
with the required uapi definition and description of intended use cases.

This series is an updated version of the below RFC series. It address
the review feedback by adding execbuf3 ioctl for vm_bind, adding
multiple queues support for vm_bind/unbind ioctls and some formatting
and documentation updates.
https://www.spinics.net/lists/dri-devel/msg347731.html

Signed-off-by: Niranjana Vishwanathapura 

Niranjana Vishwanathapura (3):
  drm/doc/rfc: VM_BIND feature design document
  drm/i915: Update i915 uapi documentation
  drm/doc/rfc: VM_BIND uapi definition

 Documentation/driver-api/dma-buf.rst   |   2 +
 Documentation/gpu/rfc/i915_vm_bind.h   | 490 +
 Documentation/gpu/rfc/i915_vm_bind.rst | 309 
 Documentation/gpu/rfc/index.rst|   4 +
 include/uapi/drm/i915_drm.h| 203 +++---
 5 files changed, 963 insertions(+), 45 deletions(-)
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.rst

-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH 2/3] drm/i915: Update i915 uapi documentation

2022-06-10 Thread Niranjana Vishwanathapura
Add some missing i915 upai documentation which the new
i915 VM_BIND feature documentation will be refer to.

Signed-off-by: Niranjana Vishwanathapura 
---
 include/uapi/drm/i915_drm.h | 203 
 1 file changed, 158 insertions(+), 45 deletions(-)

diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index de49b68b4fc8..9cf3bf47c7f2 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -751,14 +751,27 @@ typedef struct drm_i915_irq_wait {
 
 /* Must be kept compact -- no holes and well documented */
 
-typedef struct drm_i915_getparam {
+/**
+ * struct drm_i915_getparam - Driver parameter query structure.
+ */
+struct drm_i915_getparam {
+   /** @param: Driver parameter to query. */
__s32 param;
-   /*
+
+   /**
+* @value: Address of memory where queried value should be put.
+*
 * WARNING: Using pointers instead of fixed-size u64 means we need to 
write
 * compat32 code. Don't repeat this mistake.
 */
int __user *value;
-} drm_i915_getparam_t;
+};
+
+/**
+ * typedef drm_i915_getparam_t - Driver parameter query structure.
+ * See struct drm_i915_getparam.
+ */
+typedef struct drm_i915_getparam drm_i915_getparam_t;
 
 /* Ioctl to set kernel params:
  */
@@ -1239,76 +1252,119 @@ struct drm_i915_gem_exec_object2 {
__u64 rsvd2;
 };
 
+/**
+ * struct drm_i915_gem_exec_fence - An input or output fence for the execbuf
+ * ioctl.
+ *
+ * The request will wait for input fence to signal before submission.
+ *
+ * The returned output fence will be signaled after the completion of the
+ * request.
+ */
 struct drm_i915_gem_exec_fence {
-   /**
-* User's handle for a drm_syncobj to wait on or signal.
-*/
+   /** @handle: User's handle for a drm_syncobj to wait on or signal. */
__u32 handle;
 
+   /**
+* @flags: Supported flags are:
+*
+* I915_EXEC_FENCE_WAIT:
+* Wait for the input fence before request submission.
+*
+* I915_EXEC_FENCE_SIGNAL:
+* Return request completion fence as output
+*/
+   __u32 flags;
 #define I915_EXEC_FENCE_WAIT(1<<0)
 #define I915_EXEC_FENCE_SIGNAL  (1<<1)
 #define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
-   __u32 flags;
 };
 
-/*
- * See drm_i915_gem_execbuffer_ext_timeline_fences.
- */
-#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
-
-/*
+/**
+ * struct drm_i915_gem_execbuffer_ext_timeline_fences - Timeline fences
+ * for execbuf ioctl.
+ *
  * This structure describes an array of drm_syncobj and associated points for
  * timeline variants of drm_syncobj. It is invalid to append this structure to
  * the execbuf if I915_EXEC_FENCE_ARRAY is set.
  */
 struct drm_i915_gem_execbuffer_ext_timeline_fences {
+#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
+   /** @base: Extension link. See struct i915_user_extension. */
struct i915_user_extension base;
 
/**
-* Number of element in the handles_ptr & value_ptr arrays.
+* @fence_count: Number of elements in the @handles_ptr & @value_ptr
+* arrays.
 */
__u64 fence_count;
 
/**
-* Pointer to an array of struct drm_i915_gem_exec_fence of length
-* fence_count.
+* @handles_ptr: Pointer to an array of struct drm_i915_gem_exec_fence
+* of length @fence_count.
 */
__u64 handles_ptr;
 
/**
-* Pointer to an array of u64 values of length fence_count. Values
-* must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
-* drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+* @values_ptr: Pointer to an array of u64 values of length
+* @fence_count.
+* Values must be 0 for a binary drm_syncobj. A Value of 0 for a
+* timeline drm_syncobj is invalid as it turns a drm_syncobj into a
+* binary one.
 */
__u64 values_ptr;
 };
 
+/**
+ * struct drm_i915_gem_execbuffer2 - Structure for DRM_I915_GEM_EXECBUFFER2
+ * ioctl.
+ */
 struct drm_i915_gem_execbuffer2 {
-   /**
-* List of gem_exec_object2 structs
-*/
+   /** @buffers_ptr: Pointer to a list of gem_exec_object2 structs */
__u64 buffers_ptr;
+
+   /** @buffer_count: Number of elements in @buffers_ptr array */
__u32 buffer_count;
 
-   /** Offset in the batchbuffer to start execution from. */
+   /**
+* @batch_start_offset: Offset in the batchbuffer to start execution
+* from.
+*/
__u32 batch_start_offset;
-   /** Bytes used in batchbuffer from batch_start_offset */
+
+   /**
+* @batch_len: Length in bytes of the batch buffer, starting from the
+* @batch_start_offset. If 0, length is assumed to be the batch buffer
+* object size.
+*/
__u32 batch_len;
+
+  

[PATCH 1/3] drm/doc/rfc: VM_BIND feature design document

2022-06-10 Thread Niranjana Vishwanathapura
VM_BIND design document with description of intended use cases.

Signed-off-by: Niranjana Vishwanathapura 
---
 Documentation/driver-api/dma-buf.rst   |   2 +
 Documentation/gpu/rfc/i915_vm_bind.rst | 309 +
 Documentation/gpu/rfc/index.rst|   4 +
 3 files changed, 315 insertions(+)
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.rst

diff --git a/Documentation/driver-api/dma-buf.rst 
b/Documentation/driver-api/dma-buf.rst
index 36a76cbe9095..64cb924ec5bb 100644
--- a/Documentation/driver-api/dma-buf.rst
+++ b/Documentation/driver-api/dma-buf.rst
@@ -200,6 +200,8 @@ DMA Fence uABI/Sync File
 .. kernel-doc:: include/linux/sync_file.h
:internal:
 
+.. _indefinite_dma_fences:
+
 Indefinite DMA Fences
 ~
 
diff --git a/Documentation/gpu/rfc/i915_vm_bind.rst 
b/Documentation/gpu/rfc/i915_vm_bind.rst
new file mode 100644
index ..8f911298dda5
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.rst
@@ -0,0 +1,309 @@
+==
+I915 VM_BIND feature design and use cases
+==
+
+VM_BIND feature
+
+DRM_I915_GEM_VM_BIND/UNBIND ioctls allows UMD to bind/unbind GEM buffer
+objects (BOs) or sections of a BOs at specified GPU virtual addresses on a
+specified address space (VM). These mappings (also referred to as persistent
+mappings) will be persistent across multiple GPU submissions (execbuf calls)
+issued by the UMD, without user having to provide a list of all required
+mappings during each submission (as required by older execbuf mode).
+
+VM_BIND/UNBIND ioctls will support 'in' and 'out' fences to allow userpace
+to specify how the binding/unbinding should sync with other operations
+like the GPU job submission. These fences will be timeline 'drm_syncobj's
+for non-Compute contexts (See struct drm_i915_vm_bind_ext_timeline_fences).
+For Compute contexts, they will be user/memory fences (See struct
+drm_i915_vm_bind_ext_user_fence).
+
+VM_BIND feature is advertised to user via I915_PARAM_HAS_VM_BIND.
+User has to opt-in for VM_BIND mode of binding for an address space (VM)
+during VM creation time via I915_VM_CREATE_FLAGS_USE_VM_BIND extension.
+
+VM_BIND/UNBIND ioctls support multiple queues and the binding/unbinding
+operations submitted are completed asynchronously after any specified 'in'
+fences are signaled. The operations submitted on a queue are completed in
+the order of submission. But operations submitted on different queues can
+get completed out of the submission order. Any 'out' fences returned by the
+VM_BIND/UNBIND ioctls are signaled once the operation is complete. Due to
+serialization, completion of an operation will also indicate that all
+previous operations on that queue are also complete.
+
+VM_BIND features include:
+
+* Multiple Virtual Address (VA) mappings can map to the same physical pages
+  of an object (aliasing).
+* VA mapping can map to a partial section of the BO (partial binding).
+* Support capture of persistent mappings in the dump upon GPU error.
+* TLB is flushed upon unbind completion. Batching of TLB flushes in some
+  use cases will be helpful.
+* Multiple queues where each can make progress independent of the other.
+* Asynchronous vm_bind and vm_unbind support with 'in' and 'out' fences.
+* Support for userptr gem objects (no special uapi is required for this).
+
+Execbuf ioctl in VM_BIND mode
+---
+A VM in VM_BIND mode will not support older execbuf mode of binding.
+The execbuf ioctl handling in VM_BIND mode differs significantly from the
+older execbuf2 ioctl (See struct drm_i915_gem_execbuffer2).
+Hence, a new execbuf3 ioctl has been added to support VM_BIND mode. (See
+struct drm_i915_gem_execbuffer3). The execbuf3 ioctl will not accept any
+execlist. Hence, no support for implicit sync. It is expected that the below
+work will be able to support requirements of object dependency setting in all
+use cases:
+
+"dma-buf: Add an API for exporting sync files"
+(https://lwn.net/Articles/859290/)
+
+The execbuf3 ioctl directly specifies the batch addresses instead of as
+object handles as in execbuf2 ioctl. The execbuf3 ioctl will also not
+support many of the older features like in/out/submit fences, fence array,
+default gem context and many more (see struct drm_i915_gem_execbuffer3).
+
+In VM_BIND mode, VA allocation is completely managed by the user instead of
+the i915 driver. Hence all VA assignment, eviction are not applicable in
+VM_BIND mode. Also, for determining object activeness, VM_BIND mode will not
+be using the i915_vma active reference tracking. It will instead use dma-resv
+object for that (See `VM_BIND dma_resv usage`_).
+
+So, a lot of existing code supporting execbuf2 ioctl, like relocations, VA
+evictions, vma lookup table, implicit sync, vma active reference tracking etc.,
+are not applicable for execbuf3 ioctl. Hence, all execbuf3 specific handling
+should be 

[PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Niranjana Vishwanathapura
VM_BIND and related uapi definitions

Signed-off-by: Niranjana Vishwanathapura 
---
 Documentation/gpu/rfc/i915_vm_bind.h | 490 +++
 1 file changed, 490 insertions(+)
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h

diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h
new file mode 100644
index ..9fc854969cfb
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.h
@@ -0,0 +1,490 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/**
+ * DOC: I915_PARAM_HAS_VM_BIND
+ *
+ * VM_BIND feature availability.
+ * See typedef drm_i915_getparam_t param.
+ * bit[0]: If set, VM_BIND is supported, otherwise not.
+ * bits[8-15]: VM_BIND implementation version.
+ * version 0 will not have VM_BIND/UNBIND timeline fence array support.
+ */
+#define I915_PARAM_HAS_VM_BIND 57
+
+/**
+ * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
+ *
+ * Flag to opt-in for VM_BIND mode of binding during VM creation.
+ * See struct drm_i915_gem_vm_control flags.
+ *
+ * The older execbuf2 ioctl will not support VM_BIND mode of operation.
+ * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any
+ * execlist (See struct drm_i915_gem_execbuffer3 for more details).
+ *
+ */
+#define I915_VM_CREATE_FLAGS_USE_VM_BIND   (1 << 0)
+
+/**
+ * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
+ *
+ * Flag to declare context as long running.
+ * See struct drm_i915_gem_context_create_ext flags.
+ *
+ * Usage of dma-fence expects that they complete in reasonable amount of time.
+ * Compute on the other hand can be long running. Hence it is not appropriate
+ * for compute contexts to export request completion dma-fence to user.
+ * The dma-fence usage will be limited to in-kernel consumption only.
+ * Compute contexts need to use user/memory fence.
+ *
+ * So, long running contexts do not support output fences. Hence,
+ * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) is expected
+ * to be not used. DRM_I915_GEM_WAIT ioctl call is also not supported for
+ * objects mapped to long running contexts.
+ */
+#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
+
+/* VM_BIND related ioctls */
+#define DRM_I915_GEM_VM_BIND   0x3d
+#define DRM_I915_GEM_VM_UNBIND 0x3e
+#define DRM_I915_GEM_EXECBUFFER3   0x3f
+#define DRM_I915_GEM_WAIT_USER_FENCE   0x40
+
+#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_UNBIND   DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)
+#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
+
+/**
+ * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
+ *
+ * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
+ * virtual address (VA) range to the section of an object that should be bound
+ * in the device page table of the specified address space (VM).
+ * The VA range specified must be unique (ie., not currently bound) and can
+ * be mapped to whole object or a section of the object (partial binding).
+ * Multiple VA mappings can be created to the same section of the object
+ * (aliasing).
+ *
+ * The @queue_idx specifies the queue to use for binding. Same queue can be
+ * used for both VM_BIND and VM_UNBIND calls. All submitted bind and unbind
+ * operations in a queue are performed in the order of submission.
+ *
+ * The @start, @offset and @length should be 4K page aligned. However the DG2
+ * and XEHPSDV has 64K page size for device local-memory and has compact page
+ * table. On those platforms, for binding device local-memory objects, the
+ * @start should be 2M aligned, @offset and @length should be 64K aligned.
+ * Also, on those platforms, it is not allowed to bind an device local-memory
+ * object and a system memory object in a single 2M section of VA range.
+ */
+struct drm_i915_gem_vm_bind {
+   /** @vm_id: VM (address space) id to bind */
+   __u32 vm_id;
+
+   /** @queue_idx: Index of queue for binding */
+   __u32 queue_idx;
+
+   /** @rsvd: Reserved, MBZ */
+   __u32 rsvd;
+
+   /** @handle: Object handle */
+   __u32 handle;
+
+   /** @start: Virtual Address start to bind */
+   __u64 start;
+
+   /** @offset: Offset in object to bind */
+   __u64 offset;
+
+   /** @length: Length of mapping to bind */
+   __u64 length;
+
+   /**
+* @flags: Supported flags are:
+*
+* I915_GEM_VM_BIND_READONLY:
+* Mapping is read-only.
+*
+* I915_GEM_VM_BIND_CAPTURE:
+* Capture this mapping in the dump upon GPU error.
+*/
+   __u64 flags;

[git pull] drm fixes for 5.19-rc2

2022-06-10 Thread Dave Airlie
Hi Linus,

Not a huge amount here, mainly a bunch of scattered amdgpu fixes, and
then some misc panfrost, bridge/panel ones, and one ast fix for
multi-monitors. Probably pick up a bit more next week like rc3 often
does.

Dave.

drm-fixes-2022-06-10:
drm fixes for 5.19-rc2

amdgpu:
- DCN 3.1 golden settings fix
- eDP fixes
- DMCUB fixes
- GFX11 fixes and cleanups
- VCN fix for yellow carp
- GMC11 fixes
- RAS fixes
- GPUVM TLB flush fixes
- SMU13 fixes
- VCN3 AV1 regression fix
- VCN2 JPEG fix
- Other misc fixes

amdkfd:
- MMU notifier fix
- Support for more GC 10.3.x families
- Pinned BO handling fix
- Partial migration bug fix

panfrost:
- fix a use after free

ti-sn65dsi83:
- fix invalid DT configuration

panel:
- two self refresh fixes

ast:
- multiple output fix
The following changes since commit f2906aa863381afb0015a9eb7fefad885d4e5a56:

  Linux 5.19-rc1 (2022-06-05 17:18:54 -0700)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2022-06-10

for you to fetch changes up to 1f192b9e8d8a5c619b33a868fb1af063af65ce5d:

  Merge tag 'drm-misc-fixes-2022-06-09' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2022-06-10
13:29:22 +1000)


drm fixes for 5.19-rc2

amdgpu:
- DCN 3.1 golden settings fix
- eDP fixes
- DMCUB fixes
- GFX11 fixes and cleanups
- VCN fix for yellow carp
- GMC11 fixes
- RAS fixes
- GPUVM TLB flush fixes
- SMU13 fixes
- VCN3 AV1 regression fix
- VCN2 JPEG fix
- Other misc fixes

amdkfd:
- MMU notifier fix
- Support for more GC 10.3.x families
- Pinned BO handling fix
- Partial migration bug fix

panfrost:
- fix a use after free

ti-sn65dsi83:
- fix invalid DT configuration

panel:
- two self refresh fixes

ast:
- multiple output fix


Alex Deucher (1):
  drm/amdgpu: update VCN codec support for Yellow Carp

Alvin (1):
  drm/amd/display: Don't clear ref_dtbclk value

Aric Cyr (1):
  drm/amd/display: 3.2.187

Aurabindo Pillai (1):
  drm/amd/display: remove stale config guards

Brian Norris (2):
  drm/bridge: analogix_dp: Support PSR-exit to disable transition
  drm/atomic: Force bridge self-refresh-exit on CRTC switch

Candice Li (1):
  drm/amdgpu: Resolve RAS GFX error count issue after cold boot on Arcturus

Christian König (2):
  drm/amdgpu: fix limiting AV1 to the first instance on VCN3
  drm/amdgpu: always flush the TLB on gfx8

Dave Airlie (3):
  Merge tag 'amd-drm-fixes-5.19-2022-06-08' of
https://gitlab.freedesktop.org/agd5f/linux into drm-fixes
  Merge tag 'drm-misc-fixes-2022-05-26' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes
  Merge tag 'drm-misc-fixes-2022-06-09' of
git://anongit.freedesktop.org/drm/drm-misc into drm-fixes

Evan Quan (2):
  drm/amd/pm: suppress compile warnings about possible unaligned accesses
  drm/amdgpu: suppress the compile warning about 64 bit type

Guchun Chen (1):
  Revert "drm/amdgpu: Ensure the DMA engine is deactivated during set ups"

Hung, Cruise (1):
  drm/amd/display: Fix DMUB outbox trace in S4 (#4465)

Ilya (1):
  drm/amd/display: Fix possible infinite loop in DP LT fallback

Jesse Zhang (1):
  drm/amdkfd:Fix fw version for 10.3.6

Jiapeng Chong (1):
  drm/amdgpu: make program_imu_rlc_ram static

Joseph Greathouse (1):
  drm/amdgpu: Add MODE register to wave debug info in gfx11

Lang Yu (1):
  drm/amdkfd: add pinned BOs to kfd_bo_list

Leung, Martin (1):
  drm/amd/display: revert Blank eDP on disable/enable drv

Marek Vasut (1):
  drm/bridge: ti-sn65dsi83: Handle dsi_lanes == 0 as invalid

Mario Limonciello (1):
  drm/amdkfd: Add GC 10.3.6 and 10.3.7 KFD definitions

Maxime Ripard (1):
  Merge v5.19-rc1 into drm-misc-fixes

Mohammad Zafar Ziya (1):
  drm/amdgpu/jpeg2: Add jpeg vmid update under IB submit

Nicholas Kazlauskas (2):
  drm/amd/display: Pass the new context into disable OTG WA
  Revert "drm/amd/display: Pass the new context into disable OTG WA"

Philip Yang (3):
  drm/amdkfd: Use mmget_not_zero in MMU notifier
  drm/amdgpu: Update PDEs flush TLB if PTB/PDB moved
  drm/amdkfd: Fix partial migration bugs

Roman Li (1):
  drm/amdgpu: fix aper_base for APU

Sherry Wang (1):
  drm/amd/display: Read Golden Settings Table from VBIOS

Stanley.Yang (1):
  drm/amdgpu: fix ras supported check

Steven Price (1):
  drm/panfrost: Job should reference MMU not file_priv

Sunil Khatri (1):
  drm/amdgpu: enable tmz by default for GC 10.3.7

Thomas Zimmermann (1):
  drm/ast: Support multiple outputs

Yifan Zhang (1):
  drm/amdgpu/mes: only invalid/prime icache when finish loading
both pipe MES FWs.

hengzhou (1):
  drm/amd/display: Wait DMCUB to idle state before reset.

sunliming (2):
  drm/amdgpu: fix a missing break in gfx_v11_0_handle_priv_fault
  drm/amdgpu: make gfx_v11_0_rlc_stop 

[PATCH] drm/vc4: hdmi: Fixed possible integer overflow

2022-06-10 Thread Saud Farooqui
Multiplying ints and saving it in unsigned long long
could lead to integer overflow before being type casted to
unsigned long long.

Addresses-Coverity:  1505113: Unintentional integer overflow.

Signed-off-by: Saud Farooqui 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 823d812f4982..ce9d1d91 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -1481,7 +1481,7 @@ vc4_hdmi_encoder_compute_mode_clock(const struct 
drm_display_mode *mode,
unsigned int bpc,
enum vc4_hdmi_output_format fmt)
 {
-   unsigned long long clock = mode->clock * 1000;
+   unsigned long long clock = mode->clock * 1000ULL;
 
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
clock = clock * 2;
-- 
2.25.1



Re: [PATCH 2/2] vfio/pci: Remove console drivers

2022-06-10 Thread Thomas Zimmermann

Hi

Am 09.06.22 um 23:44 schrieb Alex Williamson:

On Thu, 9 Jun 2022 15:41:02 -0600
Alex Williamson  wrote:


On Thu, 9 Jun 2022 11:13:22 +0200
Thomas Zimmermann  wrote:


Please have a look at the attached patch. It moves the aperture helpers
to a location common to the various possible users (DRM, fbdev, vfio).
The DRM interfaces remain untouched for now.  The patch should provide
what you need in vfio and also serve our future use cases for graphics
drivers. If possible, please create your patch on top of it.


Looks good to me, this of course makes the vfio change quite trivial.
One change I'd request:

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 40c50fa2dd70..7f3c44e1538b 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -10,6 +10,7 @@ config VGA_CONSOLE
depends on !4xx && !PPC_8xx && !SPARC && !M68K && !PARISC &&  !SUPERH 
&& \
(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) 
&& \
!ARM64 && !ARC && !MICROBLAZE && !OPENRISC && !S390 && !UML
+   select APERTURE_HELPERS if (DRM || FB || VFIO_PCI)
default y
help
  Saying Y here will allow you to use Linux in text mode through a

This should be VFIO_PCI_CORE.  Thanks,


I attached an updated patch to this email.



Also, whatever tree this lands in, I'd appreciate a topic branch being
made available so I can more easily get the vfio change in on the same
release.  Thanks,


You can add my patch to your series and merge it through vfio. You'd 
only have to cc dri-devel for the patch's review. I guess it's more 
important for vfio than DRM. We have no hurry on the DRM side, but v5.20 
would be nice.


Best regards
Thomas



Alex



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev
From 5e0293b7102c0772568ca490ef53b7e8775ed761 Mon Sep 17 00:00:00 2001
From: Thomas Zimmermann 
Date: Wed, 8 Jun 2022 20:52:50 +0200
Subject: [PATCH] drm: Implement DRM aperture helpers under video/

Implement DRM's aperture helpers under video/ for sharing with other
sub-systems. Remove DRM-isms from the interface. The helpers track
the ownership of framebuffer apertures and provide hand-over from
firmware, such as EFI and VESA, to native graphics drivers.

Other subsystems, such as fbdev and vfio, also have to maintain ownership
of framebuffer apertures. Moving DRM's aperture helpers to a more public
location allows all subsystems to interact with each other and share a
common implementation.

The aperture helpers are selected by the various firmware drivers within
DRM and fbdev, and the VGA text-console driver.

The original DRM interface is kept in place for use by DRM drivers.

Signed-off-by: Thomas Zimmermann 
---
 Documentation/driver-api/aperture.rst |  13 +
 Documentation/driver-api/index.rst|   1 +
 drivers/gpu/drm/drm_aperture.c| 174 +
 drivers/gpu/drm/tiny/Kconfig  |   1 +
 drivers/video/Kconfig |   6 +
 drivers/video/Makefile|   2 +
 drivers/video/aperture.c  | 340 ++
 drivers/video/console/Kconfig |   1 +
 drivers/video/fbdev/Kconfig   |   7 +-
 include/linux/aperture.h  |  56 +
 10 files changed, 435 insertions(+), 166 deletions(-)
 create mode 100644 Documentation/driver-api/aperture.rst
 create mode 100644 drivers/video/aperture.c
 create mode 100644 include/linux/aperture.h

diff --git a/Documentation/driver-api/aperture.rst b/Documentation/driver-api/aperture.rst
new file mode 100644
index ..d173f4e7a7d9
--- /dev/null
+++ b/Documentation/driver-api/aperture.rst
@@ -0,0 +1,13 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Managing Ownership of the Framebuffer Aperture
+==
+
+.. kernel-doc:: drivers/video/aperture.c
+   :doc: overview
+
+.. kernel-doc:: include/linux/aperture.h
+   :internal:
+
+.. kernel-doc:: drivers/video/aperture.c
+   :export:
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index a7b0223e2886..d6d6e77d8afc 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -27,6 +27,7 @@ available subsections can be seen below.
component
message-based
infiniband
+   aperture
frame-buffer
regulator
reset
diff --git a/drivers/gpu/drm/drm_aperture.c b/drivers/gpu/drm/drm_aperture.c
index 74bd4a76b253..388a205bd023 100644
--- a/drivers/gpu/drm/drm_aperture.c
+++ b/drivers/gpu/drm/drm_aperture.c
@@ -1,14 +1,7 @@
 // SPDX-License-Identifier: MIT
 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include  /* for firmware helpers */
-#include 
-#include 
-#include 
+#include 
+#include 
 
 #include 
 #include 
@@ -126,92 +119,6 @@
  * afterwards.
  */
 
-struct drm_aperture {
-	struct drm_device *dev;
-	

Re: [PATCH] dma-buf: Don't use typeof in va_arg

2022-06-10 Thread Christian König

Am 10.06.22 um 09:20 schrieb Wan Jiabing:

Fix following coccicheck warning:
./drivers/dma-buf/st-dma-fence-unwrap.c:75:39-45: ERROR: reference preceded by 
free on line 70

Use 'struct dma_fence *' instead of 'typeof(*fences)' to avoid this
warning and also fix other 'typeof(*fences)' to make them consistent.


Well that doesn't looks correct to me.

*fence should be valid at this point, why does coccicheck things it is 
freed?


Regards,
Christian.



Fixes: 0c5064fa8d5a ("dma-buf: cleanup dma_fence_unwrap selftest v2")
Signed-off-by: Wan Jiabing 
---
  drivers/dma-buf/st-dma-fence-unwrap.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c 
b/drivers/dma-buf/st-dma-fence-unwrap.c
index 4105d5ea8dde..1137a6d90b32 100644
--- a/drivers/dma-buf/st-dma-fence-unwrap.c
+++ b/drivers/dma-buf/st-dma-fence-unwrap.c
@@ -56,7 +56,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, 
...)
  
  	va_start(valist, num_fences);

for (i = 0; i < num_fences; ++i)
-   fences[i] = va_arg(valist, typeof(*fences));
+   fences[i] = va_arg(valist, struct dma_fence *);
va_end(valist);
  
  	array = dma_fence_array_create(num_fences, fences,

@@ -72,7 +72,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, 
...)
  error_put:
va_start(valist, num_fences);
for (i = 0; i < num_fences; ++i)
-   dma_fence_put(va_arg(valist, typeof(*fences)));
+   dma_fence_put(va_arg(valist, struct dma_fence *));
va_end(valist);
return NULL;
  }




Re: [PATCH] staging: olpc_dcon: mark driver as broken

2022-06-10 Thread Greg Kroah-Hartman
On Fri, Jun 10, 2022 at 12:34:24AM +0200, Javier Martinez Canillas wrote:
> The commit eecb3e4e5d9d ("staging: olpc_dcon: add OLPC display controller
> (DCON) support") added this driver in 2010, and has been in staging since
> then. It was marked as broken at some point because it didn't even build
> but that got removed once the build issues were addressed.
> 
> But it seems that the work to move this driver out of staging has stalled,
> the last non-trivial change to fix one of the items mentioned in its todo
> file was commit e40219d5e4b2 ("staging: olpc_dcon: allow simultaneous XO-1
> and XO-1.5 support") in 2019.
> 
> And even if work to destage the driver is resumed, the fbdev subsystem has
> been deprecated for a long time and instead it should be ported to DRM.
> 
> Now this driver is preventing to land a kernel wide change, that makes the
> num_registered_fb symbol to be private to the fbmem.c file.
> 
> So let's just mark the driver as broken. Someone can then work on making
> it not depend on the num_registered_fb symbol, allowing to drop the broken
> dependency again.

Thanks for doing this, will go queue it up now for 5.19-final.

greg k-h


Re: [PATCH v2 04/11] drm/msm/dsi/phy: Reindent and reflow multiline function calls

2022-06-10 Thread Marijn Suijten
On 2022-06-02 13:14:26, Dmitry Baryshkov wrote:
> On Thu, 2 Jun 2022 at 01:07, Marijn Suijten
>  wrote:
> >
> > Patch 613cbd1da3c9 ("drm/msm/dsi: use devm_clk_*register to registe DSI
> > PHY clocks") introduced the devm_ prefix to clk_hw registration calls,
> > without updating the indentation of the arguments on the following
> > lines.
> >
> > Similarly e55b3fc8 ("drm/msm/dsi: drop PLL accessor functions")
> > moved from pll_write to dsi_phy_write without updating the indentation
> > of followup arguments either.
> >
> > Preparing for a series that heavily touches the clk calls, reflow and
> > reindent function calls that are adhering to an 80-char column limit by
> > spanning multiple lines.  Where function names are very long the
> > arguments are indented with a fixed number of two tab characters instead
> > of aligning with the opening parenthesis of the function call.
> >
> 
> I'm not a fan of reindenting the code, but let's do it.

I don't like it either, but it's better than trying to figure out how to
add and flow new arguments into the call-site while also leaving the
indentation in the same broken state.  At the same time it seems more
consistent to fix up most faults rather than only touching clk calls.

It's unfortunate that there's no proper autoformatter for C, that is
consistently used across the kernel tree.  Makes for a lot of mundane,
error-prone, manual work.  But alas.

- Marijn


Re: [Intel-gfx] [RFC v3 1/3] drm/doc/rfc: VM_BIND feature design document

2022-06-10 Thread Lionel Landwerlin

On 09/06/2022 22:31, Niranjana Vishwanathapura wrote:

On Thu, Jun 09, 2022 at 05:49:09PM +0300, Lionel Landwerlin wrote:

  On 09/06/2022 00:55, Jason Ekstrand wrote:

    On Wed, Jun 8, 2022 at 4:44 PM Niranjana Vishwanathapura
     wrote:

  On Wed, Jun 08, 2022 at 08:33:25AM +0100, Tvrtko Ursulin wrote:
  >
  >
  >On 07/06/2022 22:32, Niranjana Vishwanathapura wrote:
  >>On Tue, Jun 07, 2022 at 11:18:11AM -0700, Niranjana 
Vishwanathapura

  wrote:
  >>>On Tue, Jun 07, 2022 at 12:12:03PM -0500, Jason Ekstrand wrote:
   On Fri, Jun 3, 2022 at 6:52 PM Niranjana Vishwanathapura
    wrote:
  
     On Fri, Jun 03, 2022 at 10:20:25AM +0300, Lionel Landwerlin
  wrote:
     >   On 02/06/2022 23:35, Jason Ekstrand wrote:
     >
     > On Thu, Jun 2, 2022 at 3:11 PM Niranjana 
Vishwanathapura

     >  wrote:
     >
     >   On Wed, Jun 01, 2022 at 01:28:36PM -0700, Matthew
  Brost wrote:
     >   >On Wed, Jun 01, 2022 at 05:25:49PM +0300, Lionel
  Landwerlin
     wrote:
     >   >> On 17/05/2022 21:32, Niranjana Vishwanathapura
  wrote:
     >   >> > +VM_BIND/UNBIND ioctl will immediately start
     binding/unbinding
     >   the mapping in an
     >   >> > +async worker. The binding and unbinding will
  work like a
     special
     >   GPU engine.
     >   >> > +The binding and unbinding operations are
  serialized and
     will
     >   wait on specified
     >   >> > +input fences before the operation and will 
signal

  the
     output
     >   fences upon the
     >   >> > +completion of the operation. Due to
  serialization,
     completion of
     >   an operation
     >   >> > +will also indicate that all previous 
operations

  are also
     >   complete.
     >   >>
     >   >> I guess we should avoid saying "will immediately
  start
     >   binding/unbinding" if
     >   >> there are fences involved.
     >   >>
     >   >> And the fact that it's happening in an async
  worker seem to
     imply
     >   it's not
     >   >> immediate.
     >   >>
     >
     >   Ok, will fix.
     >   This was added because in earlier design binding 
was

  deferred
     until
     >   next execbuff.
     >   But now it is non-deferred (immediate in that 
sense).

  But yah,
     this is
     >   confusing
     >   and will fix it.
     >
     >   >>
     >   >> I have a question on the behavior of the bind
  operation when
     no
     >   input fence
     >   >> is provided. Let say I do :
     >   >>
     >   >> VM_BIND (out_fence=fence1)
     >   >>
     >   >> VM_BIND (out_fence=fence2)
     >   >>
     >   >> VM_BIND (out_fence=fence3)
     >   >>
     >   >>
     >   >> In what order are the fences going to be 
signaled?

     >   >>
     >   >> In the order of VM_BIND ioctls? Or out of order?
     >   >>
     >   >> Because you wrote "serialized I assume it's : in
  order
     >   >>
     >
     >   Yes, in the order of VM_BIND/UNBIND ioctls. Note 
that

  bind and
     unbind
     >   will use
     >   the same queue and hence are ordered.
     >
     >   >>
     >   >> One thing I didn't realize is that because we 
only

  get one
     >   "VM_BIND" engine,
     >   >> there is a disconnect from the Vulkan 
specification.

     >   >>
     >   >> In Vulkan VM_BIND operations are serialized but
  per engine.
     >   >>
     >   >> So you could have something like this :
     >   >>
     >   >> VM_BIND (engine=rcs0, in_fence=fence1,
  out_fence=fence2)
     >   >>
     >   >> VM_BIND (engine=ccs0, in_fence=fence3,
  out_fence=fence4)
     >   >>
     >   >>
     >   >> fence1 is not signaled
     >   >>
     >   >> fence3 is signaled
     >   >>
     >   >> So the second VM_BIND will proceed before the
  first VM_BIND.
     >   >>
     >   >>
     >   >> I guess we can deal with that scenario in
  

Re: [PATCH] iosys-map: Add word-sized reads

2022-06-10 Thread Christian König

Am 10.06.22 um 01:20 schrieb Lucas De Marchi:

Instead of always falling back to memcpy_fromio() for any size, prefer
using read{b,w,l}(). When reading struct members it's common to read
individual integer variables individually. Going through memcpy_fromio()
for each of them poses a high penalty.

Employ a similar trick as __seqprop() by using _Generic() to generate
only the specific call based on a type-compatible variable.

For a pariticular i915 workload producing GPU context switches,
__get_engine_usage_record() is particularly hot since the engine usage
is read from device local memory with dgfx, possibly multiple times
since it's racy. Test execution time for this test shows a ~12.5%
improvement with DG2:

Before:
nrepeats = 1000; min = 7.63243e+06; max = 1.01817e+07;
median = 9.52548e+06; var = 526149;
After:
nrepeats = 1000; min = 7.03402e+06; max = 8.8832e+06;
median = 8.33955e+06; var = 333113;

Other things attempted that didn't prove very useful:
1) Change the _Generic() on x86 to just dereference the memory address
2) Change __get_engine_usage_record() to do just 1 read per loop,
comparing with the previous value read
3) Change __get_engine_usage_record() to access the fields directly as it
was before the conversion to iosys-map

(3) did gave a small improvement (~3%), but doesn't seem to scale well
to other similar cases in the driver.

Additional test by Chris Wilson using gem_create from igt with some
changes to track object creation time. This happens to accidentaly
stress this code path:

Pre iosys_map conversion of engine busyness:
lmem0: Creating262144 4KiB objects took 59274.2ms

Unpatched:
lmem0: Creating262144 4KiB objects took 108830.2ms

With readl (this patch):
lmem0: Creating262144 4KiB objects took 61348.6ms

s/readl/READ_ONCE/
lmem0: Creating262144 4KiB objects took 61333.2ms

So we do take a little bit more time than before the conversion, but
that is due to other factors: bringing the READ_ONCE back would be as
good as just doing this conversion.

Signed-off-by: Lucas De Marchi 
---

If this is acceptable we should probably add the write counterpart, too.
Sending here only the read for now since this fixes the issue we are
seeing and to gather feedback.


As far as I can see looks sane to me, but the kernel test robot tears 
the patch apart.


Probably just a typo somewhere in the 32bit handling.

Apart from that looks good to me.

Regards,
Christian.



  include/linux/iosys-map.h | 26 ++
  1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/include/linux/iosys-map.h b/include/linux/iosys-map.h
index e69a002d5aa4..4ae3e459419e 100644
--- a/include/linux/iosys-map.h
+++ b/include/linux/iosys-map.h
@@ -333,6 +333,20 @@ static inline void iosys_map_memset(struct iosys_map *dst, 
size_t offset,
memset(dst->vaddr + offset, value, len);
  }
  
+#ifdef CONFIG_64BIT

+#define __iosys_map_rd_io_u64_case(val_, vaddr_iomem_) \
+   u64: val_ = readq(vaddr_iomem_),
+#else
+#define __iosys_map_u64_case(val_, vaddr_iomem_)
+#endif
+
+#define __iosys_map_rd_io(val__, vaddr_iomem__, type__) _Generic(val__,
\
+   u8: val__ = readb(vaddr_iomem__),   \
+   u16: val__ = readw(vaddr_iomem__),  \
+   u32: val__ = readl(vaddr_iomem__),  \
+   __iosys_map_rd_io_u64_case(val__, vaddr_iomem__)\
+   default: memcpy_fromio(&(val__), vaddr_iomem__, sizeof(val__)))
+
  /**
   * iosys_map_rd - Read a C-type value from the iosys_map
   *
@@ -346,10 +360,14 @@ static inline void iosys_map_memset(struct iosys_map 
*dst, size_t offset,
   * Returns:
   * The value read from the mapping.
   */
-#define iosys_map_rd(map__, offset__, type__) ({   \
-   type__ val; \
-   iosys_map_memcpy_from(, map__, offset__, sizeof(val));  \
-   val;\
+#define iosys_map_rd(map__, offset__, type__) ({   
\
+   type__ val; 
\
+   if ((map__)->is_iomem) { \
+   __iosys_map_rd_io(val, (map__)->vaddr_iomem + offset__, 
type__);\
+   } else {
\
+   memcpy(, (map__)->vaddr + offset__, sizeof(val));   
 \
+   }   
\
+   val;
\
  })
  
  /**




[PATCH] dma-buf: Don't use typeof in va_arg

2022-06-10 Thread Wan Jiabing
Fix following coccicheck warning:
./drivers/dma-buf/st-dma-fence-unwrap.c:75:39-45: ERROR: reference preceded by 
free on line 70

Use 'struct dma_fence *' instead of 'typeof(*fences)' to avoid this
warning and also fix other 'typeof(*fences)' to make them consistent.

Fixes: 0c5064fa8d5a ("dma-buf: cleanup dma_fence_unwrap selftest v2")
Signed-off-by: Wan Jiabing 
---
 drivers/dma-buf/st-dma-fence-unwrap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c 
b/drivers/dma-buf/st-dma-fence-unwrap.c
index 4105d5ea8dde..1137a6d90b32 100644
--- a/drivers/dma-buf/st-dma-fence-unwrap.c
+++ b/drivers/dma-buf/st-dma-fence-unwrap.c
@@ -56,7 +56,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, 
...)
 
va_start(valist, num_fences);
for (i = 0; i < num_fences; ++i)
-   fences[i] = va_arg(valist, typeof(*fences));
+   fences[i] = va_arg(valist, struct dma_fence *);
va_end(valist);
 
array = dma_fence_array_create(num_fences, fences,
@@ -72,7 +72,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, 
...)
 error_put:
va_start(valist, num_fences);
for (i = 0; i < num_fences; ++i)
-   dma_fence_put(va_arg(valist, typeof(*fences)));
+   dma_fence_put(va_arg(valist, struct dma_fence *));
va_end(valist);
return NULL;
 }
-- 
2.36.1



Re: [RFC v3 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Matthew Brost
On Tue, May 17, 2022 at 11:32:12AM -0700, Niranjana Vishwanathapura wrote:
> VM_BIND and related uapi definitions
> 
> v2: Ensure proper kernel-doc formatting with cross references.
> Also add new uapi and documentation as per review comments
> from Daniel.
> 
> Signed-off-by: Niranjana Vishwanathapura 
> ---
>  Documentation/gpu/rfc/i915_vm_bind.h | 399 +++
>  1 file changed, 399 insertions(+)
>  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h
> 
> diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
> b/Documentation/gpu/rfc/i915_vm_bind.h
> new file mode 100644
> index ..589c0a009107
> --- /dev/null
> +++ b/Documentation/gpu/rfc/i915_vm_bind.h
> @@ -0,0 +1,399 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2022 Intel Corporation
> + */
> +
> +/**
> + * DOC: I915_PARAM_HAS_VM_BIND
> + *
> + * VM_BIND feature availability.
> + * See typedef drm_i915_getparam_t param.
> + */
> +#define I915_PARAM_HAS_VM_BIND   57
> +
> +/**
> + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
> + *
> + * Flag to opt-in for VM_BIND mode of binding during VM creation.
> + * See struct drm_i915_gem_vm_control flags.
> + *
> + * A VM in VM_BIND mode will not support the older execbuff mode of binding.
> + * In VM_BIND mode, execbuff ioctl will not accept any execlist (ie., the
> + * _i915_gem_execbuffer2.buffer_count must be 0).
> + * Also, _i915_gem_execbuffer2.batch_start_offset and
> + * _i915_gem_execbuffer2.batch_len must be 0.
> + * DRM_I915_GEM_EXECBUFFER_EXT_BATCH_ADDRESSES extension must be provided
> + * to pass in the batch buffer addresses.
> + *
> + * Additionally, I915_EXEC_NO_RELOC, I915_EXEC_HANDLE_LUT and
> + * I915_EXEC_BATCH_FIRST of _i915_gem_execbuffer2.flags must be 0
> + * (not used) in VM_BIND mode. I915_EXEC_USE_EXTENSIONS flag must always be
> + * set (See struct drm_i915_gem_execbuffer_ext_batch_addresses).
> + * The buffers_ptr, buffer_count, batch_start_offset and batch_len fields
> + * of struct drm_i915_gem_execbuffer2 are also not used and must be 0.
> + */
> +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0)
> +
> +/**
> + * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
> + *
> + * Flag to declare context as long running.
> + * See struct drm_i915_gem_context_create_ext flags.
> + *
> + * Usage of dma-fence expects that they complete in reasonable amount of 
> time.
> + * Compute on the other hand can be long running. Hence it is not appropriate
> + * for compute contexts to export request completion dma-fence to user.
> + * The dma-fence usage will be limited to in-kernel consumption only.
> + * Compute contexts need to use user/memory fence.
> + *
> + * So, long running contexts do not support output fences. Hence,
> + * I915_EXEC_FENCE_OUT (See _i915_gem_execbuffer2.flags and
> + * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) are expected
> + * to be not used.
> + *
> + * DRM_I915_GEM_WAIT ioctl call is also not supported for objects mapped
> + * to long running contexts.
> + */
> +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
> +
> +/* VM_BIND related ioctls */
> +#define DRM_I915_GEM_VM_BIND 0x3d
> +#define DRM_I915_GEM_VM_UNBIND   0x3e
> +#define DRM_I915_GEM_WAIT_USER_FENCE 0x3f
> +
> +#define DRM_IOCTL_I915_GEM_VM_BIND   DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
> +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
> +#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE   DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
> +
> +/**
> + * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
> + *
> + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
> + * virtual address (VA) range to the section of an object that should be 
> bound
> + * in the device page table of the specified address space (VM).
> + * The VA range specified must be unique (ie., not currently bound) and can
> + * be mapped to whole object or a section of the object (partial binding).
> + * Multiple VA mappings can be created to the same section of the object
> + * (aliasing).
> + */
> +struct drm_i915_gem_vm_bind {
> + /** @vm_id: VM (address space) id to bind */
> + __u32 vm_id;
> +
> + /** @handle: Object handle */
> + __u32 handle;
> +
> + /** @start: Virtual Address start to bind */
> + __u64 start;
> +
> + /** @offset: Offset in object to bind */
> + __u64 offset;
> +
> + /** @length: Length of mapping to bind */
> + __u64 length;
> +
> + /**
> +  * @flags: Supported flags are,
> +  *
> +  * I915_GEM_VM_BIND_READONLY:
> +  * Mapping is read-only.
> +  *
> +  * I915_GEM_VM_BIND_CAPTURE:
> +  * Capture this mapping in the dump upon GPU error.
> +  */
> + __u64 flags;
> +#define I915_GEM_VM_BIND_READONLY(1 << 0)
> +#define 

Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Daniel Vetter
Hi all,

Kinda top post because the thread is sprawling and I think we need a
summary/restart. I think there's at least 3 issues here:

- lack of hotspot property support, which means compositors can't really
  support hotspot with atomic. Which isn't entirely true, because you
  totally can use atomic for the primary planes/crtcs and the legacy
  cursor ioctls, but I understand that people might find that a bit silly :-)

  Anyway this problme is solved by the patch set here, and I think results
  in some nice cleanups to boot.

- the fact that cursors for virtual drivers are not planes, but really
  special things. Which just breaks the universal plane kms uapi. That
  part isn't solved, and I do agree with Simon and Pekka that we really
  should solve this before we unleash even more compositors onto the
  atomic paths of virtual drivers.

  I think the simplest solution for this is:
  1. add a new DRM_PLANE_TYPE_VIRTUAL_CURSOR, and set that for these
  special cursor planes on all virtual drivers
  2. add the new "I understand virtual cursors planes" setparam, filter
  virtual cursor planes for userspace which doesn't set this (like we do
  right now if userspace doesn't set the universal plane mode)
  3. backport the above patches to all stable kernels
  4. make sure the hotspot property is only set on VIRTUAL_CURSOR planes
  and nothing else in the rebased patch series

- third issue: These special virtual display properties arent documented.
  Aside from hotspot there's also suggested X/Y and maybe other stuff. I
  have no idea what suggested X/Y does and what userspace should do with
  it. I think we need a new section for virtualized drivers which:
  - documents all the properties involved
  - documents the new cap for enabling virtual cursor planes
  - documents some of the key flows that compositors should implement for
best experience
  - documents how exactly the user experience will degrade if compositors
pretend it's just a normal kms driver (maybe put that into each of the
special flows that a compositor ideally supports)
  - whatever other comments and gaps I've missed, I'm sure
Simon/Pekka/others will chime in once the patch exists.

There's a bit of fixing oopsies (virtualized drivers really shouldn't have
enabled universal planes for their cursors) and debt (all these properties
predate the push to document stuff so we need to fix that), but I don't
think it's too much. And I think, from reading the threads, that this
should cover everything?

Anything I've missed? Or got completely wrong?

Cheers, Daniel

On Fri, Jun 03, 2022 at 02:14:59PM +, Simon Ser wrote:
> Hi,
> 
> Please, read this thread:
> https://lists.freedesktop.org/archives/dri-devel/2020-March/thread.html#259615
> 
> It has a lot of information about the pitfalls of cursor hotspot and
> other things done by VM software.
> 
> In particular: since the driver will ignore the KMS cursor plane
> position set by user-space, I don't think it's okay to just expose
> without opt-in from user-space (e.g. with a DRM_CLIENT_CAP).
> 
> cc wayland-devel and Pekka for user-space feedback.
> 
> On Thursday, June 2nd, 2022 at 17:42, Zack Rusin  wrote:
> 
> > - all userspace code needs to hardcore a list of drivers which require
> > hotspots because there's no way to query from drm "does this driver
> > require hotspot"
> 
> Can you elaborate? I'm not sure I understand what you mean here.
> 
> Thanks,
> 
> Simon

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


[PATCH 62/64] drm/vc4: v3d: Stop disabling interrupts

2022-06-10 Thread Maxime Ripard
The vc4_irq_disable(), among other things, will call disable_irq() to
complete any in-flight interrupts.

This requires its counterpart, vc4_irq_enable(), to call enable_irq() which
causes issues addressed in a later patch.

However, vc4_irq_disable() is called by two callees: vc4_irq_uninstall()
and vc4_v3d_runtime_suspend().

vc4_irq_uninstall() also calls free_irq() which already disables the
interrupt line. We thus don't require an explicit disable_irq() for that
call site.

vc4_v3d_runtime_suspend() doesn't have any other code. However, the rest of
vc4_irq_disable() masks the interrupts coming from the v3d, so explictly
disabling the interrupt line is also redundant.

The only thing we really care about is thus to make sure we don't have any
handler in-flight, as suggested by the comment. We can thus replace
disable_irq() by synchronize_irq().

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_irq.c | 2 +-
 drivers/gpu/drm/vc4/vc4_v3d.c | 2 --
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index 4342fb43e8c1..1af0560ed16c 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -289,7 +289,7 @@ vc4_irq_disable(struct drm_device *dev)
V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);
 
/* Finish any interrupt handler still in flight. */
-   disable_irq(vc4->irq);
+   synchronize_irq(vc4->irq);
 
cancel_work_sync(>overflow_mem_work);
 }
diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index 8fd16ece5b5c..ad0dac62deb2 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -378,8 +378,6 @@ static int vc4_v3d_runtime_resume(struct device *dev)
 
vc4_v3d_init_hw(>base);
 
-   /* We disabled the IRQ as part of vc4_irq_uninstall in suspend. */
-   enable_irq(vc4->irq);
vc4_irq_enable(>base);
 
return 0;
-- 
2.36.1



[PATCH 63/64] drm/vc4: v3d: Rework the runtime_pm setup

2022-06-10 Thread Maxime Ripard
At bind time, vc4_v3d_bind() will read a register to retrieve the v3d
version and make sure it's a version we're compatible with.

However, the v3d has an optional clock that is enabled only after the
register read-out and a power domain that wasn't enabled at all in the bind
implementation. This was working fine at boot because both were enabled,
but resulted in the version check failing if we were unbinding and
rebinding the driver because the unbinding would have turned them off.

The fix isn't as easy as calling pm_runtime_resume_and_get() prior to the
register access to power up the power domain though.

Indeed, the runtime_resume implementation will enable the clock mentioned
above, call vc4_v3d_init_hw() and then vc4_irq_enable().

Prior to the previous patch, vc4_irq_enable() needed to occur after our
call to platform_get_irq() and vc4_irq_install(), since vc4_irq_enable()
used to call enable_irq() and vc4_irq_install() will call request_irq().

vc4_irq_install() will also do some register access, so needs the power
domain to be on. So we ended up in a situation where
vc4_v3d_runtime_resume() needed vc4_irq_install() to have been called
before, and vc4_irq_install() needed vc4_v3d_runtime_resume().

The previous patch removed the enable_irq() call in vc4_irq_enable() and
thus removed the dependency of vc4_v3d_runtime_resume() on
vc4_irq_install().

Thus, we can now rework our bind implementation to call
pm_runtime_resume_and_get() before our register access to make sure the
power domain is on. vc4_v3d_runtime_resume() also takes care of turning the
clock on and calling vc4_v3d_init_hw() so we can remove them from bind.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_v3d.c | 37 +--
 1 file changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index ad0dac62deb2..a3fcabf5e6ab 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -448,41 +448,48 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
}
}
 
+   ret = platform_get_irq(pdev, 0);
+   if (ret < 0)
+   return ret;
+   vc4->irq = ret;
+
+   pm_runtime_enable(dev);
+
+   ret = pm_runtime_resume_and_get(dev);
+   if (ret)
+   goto err_disable_runtime_pm;
+
if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) {
DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n",
  V3D_READ(V3D_IDENT0), V3D_EXPECTED_IDENT0);
-   return -EINVAL;
+   ret = -EINVAL;
+   goto err_put_runtime_pm;
}
 
-   ret = clk_prepare_enable(v3d->clk);
-   if (ret != 0)
-   return ret;
-
/* Reset the binner overflow address/size at setup, to be sure
 * we don't reuse an old one.
 */
V3D_WRITE(V3D_BPOA, 0);
V3D_WRITE(V3D_BPOS, 0);
 
-   vc4_v3d_init_hw(drm);
-
-   ret = platform_get_irq(pdev, 0);
-   if (ret < 0)
-   return ret;
-   vc4->irq = ret;
-
ret = vc4_irq_install(drm, vc4->irq);
if (ret) {
DRM_ERROR("Failed to install IRQ handler\n");
-   return ret;
+   goto err_put_runtime_pm;
}
 
-   pm_runtime_set_active(dev);
pm_runtime_use_autosuspend(dev);
pm_runtime_set_autosuspend_delay(dev, 40); /* a little over 2 frames. */
-   pm_runtime_enable(dev);
 
return 0;
+
+err_put_runtime_pm:
+   pm_runtime_put(dev);
+
+err_disable_runtime_pm:
+   pm_runtime_disable(dev);
+
+   return ret;
 }
 
 static void vc4_v3d_unbind(struct device *dev, struct device *master,
-- 
2.36.1



[PATCH 60/64] drm/vc4: Switch to drmm_mutex_init

2022-06-10 Thread Maxime Ripard
mutex_init is supposed to be balanced by a call to mutex_destroy that we
were never doing in the vc4 driver.

Since a DRM-managed mutex_init variant has been introduced, let's just
switch to it.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_bo.c   | 15 +--
 drivers/gpu/drm/vc4/vc4_drv.c  |  4 +++-
 drivers/gpu/drm/vc4/vc4_gem.c  | 10 --
 drivers/gpu/drm/vc4/vc4_hdmi.c |  5 -
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 68fe9903947d..f52c2cd85650 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -386,6 +386,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device 
*dev, size_t size)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_bo *bo;
+   int ret;
 
bo = kzalloc(sizeof(*bo), GFP_KERNEL);
if (!bo)
@@ -393,7 +394,11 @@ struct drm_gem_object *vc4_create_object(struct drm_device 
*dev, size_t size)
 
bo->madv = VC4_MADV_WILLNEED;
refcount_set(>usecnt, 0);
-   mutex_init(>madv_lock);
+
+   ret = drmm_mutex_init(dev, >madv_lock);
+   if (ret)
+   return ERR_PTR(ret);
+
mutex_lock(>bo_lock);
bo->label = VC4_BO_TYPE_KERNEL;
vc4->bo_labels[VC4_BO_TYPE_KERNEL].num_allocated++;
@@ -963,6 +968,7 @@ static void vc4_bo_cache_destroy(struct drm_device *dev, 
void *unused);
 int vc4_bo_cache_init(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
+   int ret;
int i;
 
/* Create the initial set of BO labels that the kernel will
@@ -979,7 +985,12 @@ int vc4_bo_cache_init(struct drm_device *dev)
for (i = 0; i < VC4_BO_TYPE_COUNT; i++)
vc4->bo_labels[i].name = bo_type_names[i];
 
-   mutex_init(>bo_lock);
+   ret = drmm_mutex_init(dev, >bo_lock);
+   if (ret) {
+   kfree(vc4->bo_labels);
+   return ret;
+   }
+
INIT_LIST_HEAD(>bo_cache.time_list);
 
INIT_WORK(>bo_cache.time_work, vc4_bo_cache_time_work);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 031f2cdd658d..df3b92d06bd0 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -243,7 +243,9 @@ static int vc4_drm_bind(struct device *dev)
platform_set_drvdata(pdev, drm);
INIT_LIST_HEAD(>debugfs_list);
 
-   mutex_init(>bin_bo_lock);
+   ret = drmm_mutex_init(drm, >bin_bo_lock);
+   if (ret)
+   return ret;
 
ret = vc4_bo_cache_init(drm);
if (ret)
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 9eaf304fc20d..45f96409a72e 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -1275,6 +1275,7 @@ static void vc4_gem_destroy(struct drm_device *dev, void 
*unused);
 int vc4_gem_init(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
+   int ret;
 
vc4->dma_fence_context = dma_fence_context_alloc(1);
 
@@ -1289,10 +1290,15 @@ int vc4_gem_init(struct drm_device *dev)
 
INIT_WORK(>job_done_work, vc4_job_done_work);
 
-   mutex_init(>power_lock);
+   ret = drmm_mutex_init(dev, >power_lock);
+   if (ret)
+   return ret;
 
INIT_LIST_HEAD(>purgeable.list);
-   mutex_init(>purgeable.lock);
+
+   ret = drmm_mutex_init(dev, >purgeable.lock);
+   if (ret)
+   return ret;
 
return drmm_add_action_or_reset(dev, vc4_gem_destroy, NULL);
 }
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 2092231001c8..6672542811c9 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -3173,7 +3173,10 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
if (!vc4_hdmi)
return -ENOMEM;
 
-   mutex_init(_hdmi->mutex);
+   ret = drmm_mutex_init(drm, _hdmi->mutex);
+   if (ret)
+   return ret;
+
spin_lock_init(_hdmi->hw_lock);
INIT_DELAYED_WORK(_hdmi->scrambling_work, vc4_hdmi_scrambling_wq);
 
-- 
2.36.1



[PATCH 64/64] drm/vc4: v3d: Switch to devm_pm_runtime_enable

2022-06-10 Thread Maxime Ripard
devm_pm_runtime_enable() simplifies the driver a bit since it will call
pm_runtime_disable() automatically through a device-managed action.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_v3d.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_v3d.c b/drivers/gpu/drm/vc4/vc4_v3d.c
index a3fcabf5e6ab..2d63124e2ac0 100644
--- a/drivers/gpu/drm/vc4/vc4_v3d.c
+++ b/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -453,11 +453,13 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
return ret;
vc4->irq = ret;
 
-   pm_runtime_enable(dev);
+   ret = devm_pm_runtime_enable(dev);
+   if (ret)
+   return ret;
 
ret = pm_runtime_resume_and_get(dev);
if (ret)
-   goto err_disable_runtime_pm;
+   return ret;
 
if (V3D_READ(V3D_IDENT0) != V3D_EXPECTED_IDENT0) {
DRM_ERROR("V3D_IDENT0 read 0x%08x instead of 0x%08x\n",
@@ -486,9 +488,6 @@ static int vc4_v3d_bind(struct device *dev, struct device 
*master, void *data)
 err_put_runtime_pm:
pm_runtime_put(dev);
 
-err_disable_runtime_pm:
-   pm_runtime_disable(dev);
-
return ret;
 }
 
@@ -498,8 +497,6 @@ static void vc4_v3d_unbind(struct device *dev, struct 
device *master,
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = to_vc4_dev(drm);
 
-   pm_runtime_disable(dev);
-
vc4_irq_uninstall(drm);
 
/* Disable the binner's overflow memory address, so the next
-- 
2.36.1



Re: [PATCH v6 0/6] Raspberry PI 4 V3D enablement

2022-06-10 Thread Melissa Wen
On 06/09, Stefan Wahren wrote:
> Hi Melissa,
> 
> Am 08.06.22 um 14:51 schrieb Melissa Wen:
> > On 06/03, Peter Robinson wrote:
> > > This is a follow up from my v4 patchset. The power management pieces have
> > > been split out to a separate independent set of patches by Stefan [1]. 
> > > This
> > > version 5 of the DRM patches are independent and given the V3D driver has
> > > been upstream for some time the two patches to enable it in defconfigs can
> > > be taken at anytime independent of the enablement for the Raspberry Pi 4.
> > Hi Peter,
> > 
> > I was able to check and run some tests on arm64, and it seems ok. But I
> > was not successful on bringing it up for arm using multi_v7_defconfig +
> > device_tree=bcm2711-rpi-4-b.dtb.
> 
> for Raspberry Pi 4 you also need to enable CONFIG_ARM_LPAE, which is not
> enabled in multi_v7_defconfig.

Hi Stefan,

Thanks for pointing it out.

I've checked again and it's fine. I think some bits are missing (maybe
from my side) to handle glx stuff on arm, but I can take a look later.

Thanks for this work!

Melissa

> 
> Best regards
> 
> > 
> > How can I check this path?
> > 
> > Btw, using the config from rpi downstream kernel works nicely for arm
> > (on my side)
> > 
> > Best regards,
> > 
> > Melissa
> > > I've tested this using mesa 22.0.x and Wayland/Gnome on Fedora 36, it's
> > > more or less stable with basic testing.
> > > 
> > > Changes since v5:
> > > - Update the DT compatible to match the others that were updated
> > > - Adjust the Kconfig help text
> > > - Add review tags
> > > 
> > > Changes since v4:
> > > - Fixes for device tree and bindings
> > > - Split out the power management changes into an independent set
> > > - Rebase to 5.18
> > > - Individual changes in patches
> > > 
> > > [1] https://www.spinics.net/lists/arm-kernel/msg980342.html
> > > 
> > > Nicolas Saenz Julienne (1):
> > >arm64: config: Enable DRM_V3D
> > > 
> > > Peter Robinson (5):
> > >dt-bindings: gpu: v3d: Add BCM2711's compatible
> > >drm/v3d: Get rid of pm code
> > >drm/v3d: Add support for bcm2711
> > >ARM: dts: bcm2711: Enable V3D
> > >ARM: configs: Enable DRM_V3D
> > > 
> > >   .../devicetree/bindings/gpu/brcm,bcm-v3d.yaml  |  1 +
> > >   arch/arm/boot/dts/bcm2711-rpi.dtsi |  4 
> > >   arch/arm/boot/dts/bcm2711.dtsi | 11 +++
> > >   arch/arm/configs/bcm2835_defconfig |  1 +
> > >   arch/arm/configs/multi_v7_defconfig|  1 +
> > >   arch/arm64/configs/defconfig   |  1 +
> > >   drivers/gpu/drm/v3d/Kconfig|  5 +++--
> > >   drivers/gpu/drm/v3d/v3d_debugfs.c  | 18 +-
> > >   drivers/gpu/drm/v3d/v3d_drv.c  | 12 +---
> > >   drivers/gpu/drm/v3d/v3d_gem.c  | 12 +---
> > >   10 files changed, 25 insertions(+), 41 deletions(-)
> > > 
> > > -- 
> > > 2.36.1
> > > 
> > > 
> > > ___
> > > linux-arm-kernel mailing list
> > > linux-arm-ker...@lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


signature.asc
Description: PGP signature


Re: [PATCH] dma-buf: Don't use typeof in va_arg

2022-06-10 Thread Jiabing Wan




On 2022/6/10 15:24, Christian König wrote:

Am 10.06.22 um 09:20 schrieb Wan Jiabing:

Fix following coccicheck warning:
./drivers/dma-buf/st-dma-fence-unwrap.c:75:39-45: ERROR: reference 
preceded by free on line 70


Use 'struct dma_fence *' instead of 'typeof(*fences)' to avoid this
warning and also fix other 'typeof(*fences)' to make them consistent.


Well that doesn't looks correct to me.

*fence should be valid at this point, why does coccicheck things it is 
freed?


*fence is valid. Coccicheck reports this because fence is freed.
But use 'struct dma_fence *' can avoid this wrong report.

I also grep all code and find it's unusual to use 'typeof' in va_arg, 
only two files.


grep -R "va_arg("  . | grep 'typeof'
./drivers/dma-buf/st-dma-fence-unwrap.c:    fences[i] = 
va_arg(valist, typeof(*fences));
./drivers/dma-buf/st-dma-fence-unwrap.c: dma_fence_put(va_arg(valist, 
typeof(*fences)));
./lib/test_scanf.c: typeof(*expect) got = *va_arg(ap, 
typeof(expect));  \


And other files all use declaration name directly.
So I send this patch makes code clearer and fix the wrong warning by the 
way.


Thanks,
Wan Jiabing



Regards,
Christian.



Fixes: 0c5064fa8d5a ("dma-buf: cleanup dma_fence_unwrap selftest v2")
Signed-off-by: Wan Jiabing 
---
  drivers/dma-buf/st-dma-fence-unwrap.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c 
b/drivers/dma-buf/st-dma-fence-unwrap.c

index 4105d5ea8dde..1137a6d90b32 100644
--- a/drivers/dma-buf/st-dma-fence-unwrap.c
+++ b/drivers/dma-buf/st-dma-fence-unwrap.c
@@ -56,7 +56,7 @@ static struct dma_fence *mock_array(unsigned int 
num_fences, ...)

    va_start(valist, num_fences);
  for (i = 0; i < num_fences; ++i)
-    fences[i] = va_arg(valist, typeof(*fences));
+    fences[i] = va_arg(valist, struct dma_fence *);
  va_end(valist);
    array = dma_fence_array_create(num_fences, fences,
@@ -72,7 +72,7 @@ static struct dma_fence *mock_array(unsigned int 
num_fences, ...)

  error_put:
  va_start(valist, num_fences);
  for (i = 0; i < num_fences; ++i)
-    dma_fence_put(va_arg(valist, typeof(*fences)));
+    dma_fence_put(va_arg(valist, struct dma_fence *));
  va_end(valist);
  return NULL;
  }






Re: [PATCH V2 0/3] DSI host and peripheral initialisation ordering

2022-06-10 Thread Lucas Stach
Hi,

Am Mittwoch, dem 11.05.2022 um 16:58 +0200 schrieb Marek Szyprowski:
> Hi Dave,
> 
> On 05.04.2022 13:43, Dave Stevenson wrote:
> > On Fri, 18 Mar 2022 at 12:25, Dave Stevenson
> >   wrote:
> > > On Fri, 4 Mar 2022 at 15:18, Dave Stevenson
> > >   wrote:
> > > > Hi All
> > > A gentle ping on this series. Any comments on the approach?
> > > Thanks.
> > I realise the merge window has just closed and therefore folks have
> > been busy, but no responses on this after a month?
> > 
> > Do I give up and submit a patch to document that DSI is broken and no one 
> > cares?
> 
> Thanks for pointing this patchset in the 'drm: bridge: Add Samsung MIPI 
> DSIM bridge' thread, otherwise I would miss it since I'm not involved 
> much in the DRM development.
> 
> This resolves most of the issues in the Exynos DSI and its recent 
> conversion to the drm bridge framework. I've added the needed 
> prepare_upstream_first flags to the panels and everything works fine 
> without the bridge chain order hacks.
> 
> Feel free to add:
> 
> Tested-by: Marek Szyprowski 
> 
> 
> The only remaining thing to resolve is the moment of enabling DSI host. 
> The proper sequence is:
> 
> 1. host power on, 2. device power on, 3. host init, 4. device init, 5. 
> video enable.
> 
> #1 is done in dsi's pre_enable, #2 is done in panel's prepare. #3 was so 
> far done in the first host transfer call, which usually happens in 
> panel's prepare, then the #4 happens. Then video enable is done in the 
> enable callbacks.
> 
> Jagan wants to move it to the dsi host pre_enable() to let it work with 
> DSI bridges controlled over different interfaces 
> (https://lore.kernel.org/all/20220504114021.33265-6-ja...@amarulasolutions.com/
>  
> ). This however fails on Exynos with DSI panels, because when dsi's 
> pre_enable is called, the dsi device is not yet powered. I've discussed 
> this with Andrzej Hajda and we came to the conclusion that this can be 
> resolved by adding the init() callback to the struct mipi_dsi_host_ops. 
> Then DSI client (next bridge or panel) would call it after powering self 
> on, but before sending any DSI commands in its pre_enable/prepare functions.
> 
> I've prepared a prototype of such solution. This approach finally 
> resolved all the initialization issues! The bridge chain finally matches 
> the hardware, no hack are needed, and everything is controlled by the 
> DRM core. This prototype also includes the Jagan's patches, which add 
> IMX support to Samsung DSIM. If one is interested, here is my git repo 
> with all the PoC patches:
> 
> https://github.com/mszyprow/linux/tree/v5.18-next-20220511-dsi-rework

While this needs rework on the bridge chip side, I fear that we need
something like that to allow the bridge to control the sequencing of
the DSI host init. While most bridges that aren't controlled via the
DSI channel might be fine with just initializing the host right before
a video signal is driven, there are some that need a different
sequencing.

The chip I'm currently looking at is a TC368767, where the datasheet
states that the DSI lanes must be in LP-11 before the reset is
released. While the datasheet doesn't specify what happens if that
sequence is violated, Marek Vasut found that the chip enters a test
mode if the lanes are not in LP-11 at that point and I can confirm this
observation.
Now with the TC358767 being a DSI to (e)DP converter, we need to
release the chip from reset pretty early to establish the DP AUX
connection to communicate with the display, in order to find out which
video modes we can drive. As the chip is controlled via i2c in my case,
initializing the DSI host on first DSI command transaction is out and
doing so before the bridge pre_enable is way too late.

What I would need for this chip to work properly is an explicit call,
like the mipi_dsi_host_init() added in the PoC above, to allow the
bridge driver to kick the DSI host initialization before releasing the
chip from reset state.

Regards,
Lucas



Re: [PATCH v4 2/2] drm: lcdif: Add support for i.MX8MP LCDIF variant

2022-06-10 Thread Lucas Stach
Hi Marek,

Am Donnerstag, dem 19.05.2022 um 13:48 +0200 schrieb Marek Vasut:
> Add support for i.MX8MP LCDIF variant. This is called LCDIFv3 and is
> completely different from the LCDIFv3 found in i.MX23 in that it has
> a completely scrambled register layout compared to all previous LCDIF
> variants. The new LCDIFv3 also supports 36bit address space.
> 
> Add a separate driver which is really a fork of MXSFB driver with the
> i.MX8MP LCDIF variant handling filled in.
> 
> Signed-off-by: Marek Vasut 
> Cc: Alexander Stein 
> Cc: Laurent Pinchart 
> Cc: Lucas Stach 
> Cc: Peng Fan 
> Cc: Robby Cai 
> Cc: Sam Ravnborg 
> Cc: Stefan Agner 
> ---
> V2: - Drop the pitch check from lcdif_fb_create()
> - Drop connector caching
> - Wait for shadow load bit to be cleared in IRQ handler
> - Make all clock mandatory and grab them all by name
> - Wait for EN to be cleared in lcdif_disable_controller
> - Rename to imx-lcdif
> - Move shadow load to atomic_flush
> V3: - Invert DE polarity to match MX8MPRM datasheet
> - Enable CSC in RGB to YUV mode for MEDIA_BUS_FMT_UYVY8_1X16
> V4: - Drop lcdif_overlay_plane_formats, it is unused
> ---
>  drivers/gpu/drm/mxsfb/Kconfig  |  16 +
>  drivers/gpu/drm/mxsfb/Makefile |   2 +
>  drivers/gpu/drm/mxsfb/lcdif_drv.c  | 361 +
>  drivers/gpu/drm/mxsfb/lcdif_drv.h  |  47 +++
>  drivers/gpu/drm/mxsfb/lcdif_kms.c  | 497 +
>  drivers/gpu/drm/mxsfb/lcdif_regs.h | 257 +++
>  6 files changed, 1180 insertions(+)
>  create mode 100644 drivers/gpu/drm/mxsfb/lcdif_drv.c
>  create mode 100644 drivers/gpu/drm/mxsfb/lcdif_drv.h
>  create mode 100644 drivers/gpu/drm/mxsfb/lcdif_kms.c
>  create mode 100644 drivers/gpu/drm/mxsfb/lcdif_regs.h
> 
> diff --git a/drivers/gpu/drm/mxsfb/Kconfig b/drivers/gpu/drm/mxsfb/Kconfig
> index 987170e16ebd6..873551b4552f5 100644
> --- a/drivers/gpu/drm/mxsfb/Kconfig
> +++ b/drivers/gpu/drm/mxsfb/Kconfig
> @@ -19,3 +19,19 @@ config DRM_MXSFB
> i.MX28, i.MX6SX, i.MX7 and i.MX8M).
>  
> If M is selected the module will be called mxsfb.
> +
> +config DRM_IMX_LCDIF
> + tristate "i.MX LCDIFv3 LCD controller"
> + depends on DRM && OF
> + depends on COMMON_CLK
> + select DRM_MXS
> + select DRM_KMS_HELPER
> + select DRM_GEM_CMA_HELPER
> + select DRM_PANEL
> + select DRM_PANEL_BRIDGE
> + help
> +   Choose this option if you have an LCDIFv3 LCD controller.
> +   Those devices are found in various i.MX SoC (i.MX8MP,
> +   i.MXRT).
> +
> +   If M is selected the module will be called imx-lcdif.
> diff --git a/drivers/gpu/drm/mxsfb/Makefile b/drivers/gpu/drm/mxsfb/Makefile
> index 26d153896d720..3fa44059b9d85 100644
> --- a/drivers/gpu/drm/mxsfb/Makefile
> +++ b/drivers/gpu/drm/mxsfb/Makefile
> @@ -1,3 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  mxsfb-y := mxsfb_drv.o mxsfb_kms.o
>  obj-$(CONFIG_DRM_MXSFB)  += mxsfb.o
> +imx-lcdif-y := lcdif_drv.o lcdif_kms.o
> +obj-$(CONFIG_DRM_IMX_LCDIF) += imx-lcdif.o

This needs a change in the Makefile above this one, as currently this
one is only taken into account when CONFIG_DRM_MXSFB is enabled. So
it's currently impossible to build the LCDIF driver without MXSFB also
being enabled.

> diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c 
> b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> new file mode 100644
> index 0..3e29c8a768487
> --- /dev/null
> +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> @@ -0,0 +1,361 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2022 Marek Vasut 
> + *
> + * This code is based on drivers/gpu/drm/mxsfb/mxsfb*
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "lcdif_drv.h"
> +#include "lcdif_regs.h"
> +
> +static struct drm_framebuffer *
> +lcdif_fb_create(struct drm_device *dev, struct drm_file *file_priv,
> + const struct drm_mode_fb_cmd2 *mode_cmd)
> +{
> + const struct drm_format_info *info;
> +
> + info = drm_get_format_info(dev, mode_cmd);
> + if (!info)
> + return ERR_PTR(-EINVAL);

This isn't needed. drm_gem_fb_create does the same check a bit down the
line.

> +
> + return drm_gem_fb_create(dev, file_priv, mode_cmd);
> +}
> +
> +static const struct drm_mode_config_funcs lcdif_mode_config_funcs = {
> + .fb_create  = lcdif_fb_create,
> + .atomic_check   = drm_atomic_helper_check,
> + .atomic_commit  = drm_atomic_helper_commit,
> +};
> +
> +static const struct drm_mode_config_helper_funcs lcdif_mode_config_helpers = 
> {
> + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
> +};
> +
> +static int lcdif_attach_bridge(struct lcdif_drm_private *lcdif)
> +{
> + struct 

[PATCH v2 14/14] drm/vc4: Warn if some v3d code is run on BCM2711

2022-06-10 Thread Maxime Ripard
The BCM2711 has a separate driver for the v3d, and thus we can't call
into any of the driver entrypoints that rely on the v3d being there.

Let's add a bunch of checks and complain loudly if that ever happen.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_bo.c   | 49 ++
 drivers/gpu/drm/vc4/vc4_drv.c  | 11 +
 drivers/gpu/drm/vc4/vc4_drv.h  |  6 +++
 drivers/gpu/drm/vc4/vc4_gem.c  | 40 ++
 drivers/gpu/drm/vc4/vc4_irq.c  | 16 +++
 drivers/gpu/drm/vc4/vc4_kms.c  |  4 ++
 drivers/gpu/drm/vc4/vc4_perfmon.c  | 47 -
 drivers/gpu/drm/vc4/vc4_render_cl.c|  4 ++
 drivers/gpu/drm/vc4/vc4_v3d.c  | 15 +++
 drivers/gpu/drm/vc4/vc4_validate.c | 16 +++
 drivers/gpu/drm/vc4/vc4_validate_shaders.c |  4 ++
 11 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 3ca16d682fc0..b8d856312846 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -248,6 +248,9 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo)
 {
struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return;
+
mutex_lock(>purgeable.lock);
list_add_tail(>size_head, >purgeable.list);
vc4->purgeable.num++;
@@ -259,6 +262,9 @@ static void vc4_bo_remove_from_purgeable_pool_locked(struct 
vc4_bo *bo)
 {
struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return;
+
/* list_del_init() is used here because the caller might release
 * the purgeable lock in order to acquire the madv one and update the
 * madv status.
@@ -387,6 +393,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device 
*dev, size_t size)
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_bo *bo;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return ERR_PTR(-ENODEV);
+
bo = kzalloc(sizeof(*bo), GFP_KERNEL);
if (!bo)
return ERR_PTR(-ENOMEM);
@@ -413,6 +422,9 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t 
unaligned_size,
struct drm_gem_cma_object *cma_obj;
struct vc4_bo *bo;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return ERR_PTR(-ENODEV);
+
if (size == 0)
return ERR_PTR(-EINVAL);
 
@@ -475,9 +487,13 @@ int vc4_bo_dumb_create(struct drm_file *file_priv,
   struct drm_device *dev,
   struct drm_mode_create_dumb *args)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_bo *bo = NULL;
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
ret = vc4_dumb_fixup_args(args);
if (ret)
return ret;
@@ -598,8 +614,12 @@ static void vc4_bo_cache_time_work(struct work_struct 
*work)
 
 int vc4_bo_inc_usecnt(struct vc4_bo *bo)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
/* Fast path: if the BO is already retained by someone, no need to
 * check the madv status.
 */
@@ -634,6 +654,11 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo)
 
 void vc4_bo_dec_usecnt(struct vc4_bo *bo)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
+
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return;
+
/* Fast path: if the BO is still retained by someone, no need to test
 * the madv value.
 */
@@ -753,6 +778,9 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
struct vc4_bo *bo = NULL;
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
ret = vc4_grab_bin_bo(vc4, vc4file);
if (ret)
return ret;
@@ -776,9 +804,13 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
 int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
  struct drm_file *file_priv)
 {
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_vc4_mmap_bo *args = data;
struct drm_gem_object *gem_obj;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
if (!gem_obj) {
DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
@@ -802,6 +834,9 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void 
*data,
struct vc4_bo *bo = NULL;
int ret;
 
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
if (args->size == 0)
return -EINVAL;
 
@@ -872,11 +907,15 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void 
*data,
 int 

[PATCH v2 10/14] drm/vc4: crtc: Move the BO handling out of common page-flip callback

2022-06-10 Thread Maxime Ripard
We'll soon introduce another completion callback source that won't need
to use the BO reference counting, so let's move it around to create a
function we will be able to share between both callbacks.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 34 --
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 1f247c037ce0..0410db97b9d1 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -802,21 +802,8 @@ vc4_async_page_flip_complete(struct vc4_async_flip_state 
*flip_state)
drm_crtc_vblank_put(crtc);
drm_framebuffer_put(flip_state->fb);
 
-   /* Decrement the BO usecnt in order to keep the inc/dec calls balanced
-* when the planes are updated through the async update path.
-* FIXME: we should move to generic async-page-flip when it's
-* available, so that we can get rid of this hand-made cleanup_fb()
-* logic.
-*/
-   if (flip_state->old_fb) {
-   struct drm_gem_cma_object *cma_bo;
-   struct vc4_bo *bo;
-
-   cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0);
-   bo = to_vc4_bo(_bo->base);
-   vc4_bo_dec_usecnt(bo);
+   if (flip_state->old_fb)
drm_framebuffer_put(flip_state->old_fb);
-   }
 
kfree(flip_state);
 }
@@ -825,8 +812,27 @@ static void vc4_async_page_flip_seqno_complete(struct 
vc4_seqno_cb *cb)
 {
struct vc4_async_flip_state *flip_state =
container_of(cb, struct vc4_async_flip_state, cb.seqno);
+   struct vc4_bo *bo = NULL;
+
+   if (flip_state->old_fb) {
+   struct drm_gem_cma_object *cma_bo =
+   drm_fb_cma_get_gem_obj(flip_state->old_fb, 0);
+   bo = to_vc4_bo(_bo->base);
+   }
 
vc4_async_page_flip_complete(flip_state);
+
+   /*
+* Decrement the BO usecnt in order to keep the inc/dec
+* calls balanced when the planes are updated through
+* the async update path.
+*
+* FIXME: we should move to generic async-page-flip when
+* it's available, so that we can get rid of this
+* hand-made cleanup_fb() logic.
+*/
+   if (bo)
+   vc4_bo_dec_usecnt(bo);
 }
 
 /* Implements async (non-vblank-synced) page flips.
-- 
2.36.1



[PATCH v2 03/14] drm/vc4: bo: Rename vc4_dumb_create

2022-06-10 Thread Maxime Ripard
We're going to add a new variant of the dumb BO allocation function, so
let's rename vc4_dumb_create() to something a bit more specific.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_bo.c  | 6 +++---
 drivers/gpu/drm/vc4/vc4_drv.c | 2 +-
 drivers/gpu/drm/vc4/vc4_drv.h | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 49c0f2ac868b..6d505da6b6cf 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -471,9 +471,9 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t 
unaligned_size,
return bo;
 }
 
-int vc4_dumb_create(struct drm_file *file_priv,
-   struct drm_device *dev,
-   struct drm_mode_create_dumb *args)
+int vc4_bo_dumb_create(struct drm_file *file_priv,
+  struct drm_device *dev,
+  struct drm_mode_create_dumb *args)
 {
int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
struct vc4_bo *bo = NULL;
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 53067525b586..5f39e40ef238 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -175,7 +175,7 @@ static struct drm_driver vc4_drm_driver = {
 
.gem_create_object = vc4_create_object,
 
-   DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_dumb_create),
+   DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc4_bo_dumb_create),
 
.ioctls = vc4_drm_ioctls,
.num_ioctls = ARRAY_SIZE(vc4_drm_ioctls),
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 82453a3bcffe..37c93654480f 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -814,9 +814,9 @@ struct vc4_validated_shader_info {
 struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
 struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
 bool from_cache, enum vc4_kernel_bo_type type);
-int vc4_dumb_create(struct drm_file *file_priv,
-   struct drm_device *dev,
-   struct drm_mode_create_dumb *args);
+int vc4_bo_dumb_create(struct drm_file *file_priv,
+  struct drm_device *dev,
+  struct drm_mode_create_dumb *args);
 int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
 int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
-- 
2.36.1



[PATCH v2 02/14] drm/vc4: Consolidate Hardware Revision Check

2022-06-10 Thread Maxime Ripard
A new generation of controller has been introduced with the
BCM2711/RaspberryPi4. This generation needs a bunch of quirks, and over
time we've piled on a number of checks in most parts of the drivers.

All these checks are performed several times, and are not always
consistent. Let's create a single, global, variable to hold it and use
it everywhere.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c  |  6 +++---
 drivers/gpu/drm/vc4/vc4_drv.c   |  4 
 drivers/gpu/drm/vc4/vc4_drv.h   |  6 +++---
 drivers/gpu/drm/vc4/vc4_hvs.c   | 18 +-
 drivers/gpu/drm/vc4/vc4_kms.c   | 12 +---
 drivers/gpu/drm/vc4/vc4_plane.c | 13 ++---
 6 files changed, 30 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 59b20c8f132b..dd5fb25d0f43 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -256,7 +256,7 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc 
*vc4_crtc, u32 format)
 * Removing 1 from the FIFO full level however
 * seems to completely remove that issue.
 */
-   if (!vc4->hvs->hvs5)
+   if (!vc4->is_vc5)
return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1;
 
return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
@@ -389,7 +389,7 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, 
struct drm_encoder *encode
if (is_dsi)
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 
-   if (vc4->hvs->hvs5)
+   if (vc4->is_vc5)
CRTC_WRITE(PV_MUX_CFG,
   VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP,
 PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
@@ -1149,7 +1149,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
*vc4_crtc,
  crtc_funcs, NULL);
drm_crtc_helper_add(crtc, crtc_helper_funcs);
 
-   if (!vc4->hvs->hvs5) {
+   if (!vc4->is_vc5) {
drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
 
drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 162bc18e7497..53067525b586 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -217,10 +217,13 @@ static int vc4_drm_bind(struct device *dev)
struct vc4_dev *vc4;
struct device_node *node;
struct drm_crtc *crtc;
+   bool is_vc5;
int ret = 0;
 
dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
+   is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5");
+
/* If VC4 V3D is missing, don't advertise render nodes. */
node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL);
if (!node || !of_device_is_available(node))
@@ -230,6 +233,7 @@ static int vc4_drm_bind(struct device *dev)
vc4 = devm_drm_dev_alloc(dev, _drm_driver, struct vc4_dev, base);
if (IS_ERR(vc4))
return PTR_ERR(vc4);
+   vc4->is_vc5 = is_vc5;
 
drm = >base;
platform_set_drvdata(pdev, drm);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 15e0c2ac3940..82453a3bcffe 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -74,6 +74,8 @@ struct vc4_perfmon {
 struct vc4_dev {
struct drm_device base;
 
+   bool is_vc5;
+
unsigned int irq;
 
struct vc4_hvs *hvs;
@@ -316,6 +318,7 @@ struct vc4_v3d {
 };
 
 struct vc4_hvs {
+   struct vc4_dev *vc4;
struct platform_device *pdev;
void __iomem *regs;
u32 __iomem *dlist;
@@ -333,9 +336,6 @@ struct vc4_hvs {
struct drm_mm_node mitchell_netravali_filter;
 
struct debugfs_regset32 regset;
-
-   /* HVS version 5 flag, therefore requires updated dlist structures */
-   bool hvs5;
 };
 
 struct vc4_plane {
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 2a58fc421cf6..ba2c8e5a9b64 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -220,10 +220,11 @@ u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, 
unsigned int fifo)
 
 int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, unsigned int output)
 {
+   struct vc4_dev *vc4 = hvs->vc4;
u32 reg;
int ret;
 
-   if (!hvs->hvs5)
+   if (!vc4->is_vc5)
return output;
 
switch (output) {
@@ -273,6 +274,7 @@ int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, 
unsigned int output)
 static int vc4_hvs_init_channel(struct vc4_hvs *hvs, struct drm_crtc *crtc,
struct drm_display_mode *mode, bool oneshot)
 {
+   struct vc4_dev *vc4 = hvs->vc4;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct 

[PATCH v2 07/14] drm/vc4: plane: Register a different drm_plane_helper_funcs on BCM2711

2022-06-10 Thread Maxime Ripard
On the BCM2711, our current definition of drm_plane_helper_funcs uses
the custom vc4_prepare_fb() and vc4_cleanup_fb().

Those functions rely on the buffer allocation path that was relying on
the GPU, and is no longer relevant.

Let's create another drm_plane_helper_funcs structure that we will
register on the BCM2711.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index ba7359516d75..1e866dc00ac3 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1389,6 +1389,13 @@ static const struct drm_plane_helper_funcs 
vc4_plane_helper_funcs = {
.atomic_async_update = vc4_plane_atomic_async_update,
 };
 
+static const struct drm_plane_helper_funcs vc5_plane_helper_funcs = {
+   .atomic_check = vc4_plane_atomic_check,
+   .atomic_update = vc4_plane_atomic_update,
+   .atomic_async_check = vc4_plane_atomic_async_check,
+   .atomic_async_update = vc4_plane_atomic_async_update,
+};
+
 static bool vc4_format_mod_supported(struct drm_plane *plane,
 uint32_t format,
 uint64_t modifier)
@@ -1493,7 +1500,10 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
if (ret)
return ERR_PTR(ret);
 
-   drm_plane_helper_add(plane, _plane_helper_funcs);
+   if (vc4->is_vc5)
+   drm_plane_helper_add(plane, _plane_helper_funcs);
+   else
+   drm_plane_helper_add(plane, _plane_helper_funcs);
 
drm_plane_create_alpha_property(plane);
drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
-- 
2.36.1



[PATCH v2 08/14] drm/vc4: drv: Skip BO Backend Initialization on BCM2711

2022-06-10 Thread Maxime Ripard
On the BCM2711, we currently call the vc4_bo_cache_init() and
vc4_gem_init() functions. These functions initialize the BO and GEM
backends.

However, this code was initially created to accomodate the requirements
of the GPU on the older SoCs, while the BCM2711 has a separate driver
for it. So let's just skip these calls when we're on a newer hardware.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 528a1e2761f1..ef4ab0563168 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -285,19 +285,23 @@ static int vc4_drm_bind(struct device *dev)
platform_set_drvdata(pdev, drm);
INIT_LIST_HEAD(>debugfs_list);
 
-   mutex_init(>bin_bo_lock);
+   if (!is_vc5) {
+   mutex_init(>bin_bo_lock);
 
-   ret = vc4_bo_cache_init(drm);
-   if (ret)
-   return ret;
+   ret = vc4_bo_cache_init(drm);
+   if (ret)
+   return ret;
+   }
 
ret = drmm_mode_config_init(drm);
if (ret)
return ret;
 
-   ret = vc4_gem_init(drm);
-   if (ret)
-   return ret;
+   if (!is_vc5) {
+   ret = vc4_gem_init(drm);
+   if (ret)
+   return ret;
+   }
 
node = of_find_compatible_node(NULL, NULL, 
"raspberrypi,bcm2835-firmware");
if (node) {
-- 
2.36.1



[PATCH v2 13/14] drm/vc4: crtc: Fix out of order frames during asynchronous page flips

2022-06-10 Thread Maxime Ripard
When doing an asynchronous page flip (PAGE_FLIP ioctl with the
DRM_MODE_PAGE_FLIP_ASYNC flag set), the current code waits for the
possible GPU buffer being rendered through a call to
vc4_queue_seqno_cb().

On the BCM2835-37, the GPU driver is part of the vc4 driver and that
function is defined in vc4_gem.c to wait for the buffer to be rendered,
and once it's done, call a callback.

However, on the BCM2711 used on the RaspberryPi4, the GPU driver is
separate (v3d) and that function won't do anything. This was working
because we were going into a path, due to uninitialized variables, that
was always scheduling the callback.

However, we were never actually waiting for the buffer to be rendered
which was resulting in frames being displayed out of order.

The generic API to signal those kind of completion in the kernel are the
DMA fences, and fortunately the v3d drivers supports them and signal
when its job is done. That API also provides an equivalent function that
allows to have a callback being executed when the fence is signalled as
done.

Let's change our driver a bit to rely on the previous function for the
older SoCs, and on DMA fences for the BCM2711.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 50 +++---
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index a3c04d6cbd20..9355213dc883 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -776,6 +776,7 @@ struct vc4_async_flip_state {
struct drm_pending_vblank_event *event;
 
union {
+   struct dma_fence_cb fence;
struct vc4_seqno_cb seqno;
} cb;
 };
@@ -835,6 +836,50 @@ static void vc4_async_page_flip_seqno_complete(struct 
vc4_seqno_cb *cb)
vc4_bo_dec_usecnt(bo);
 }
 
+static void vc4_async_page_flip_fence_complete(struct dma_fence *fence,
+  struct dma_fence_cb *cb)
+{
+   struct vc4_async_flip_state *flip_state =
+   container_of(cb, struct vc4_async_flip_state, cb.fence);
+
+   vc4_async_page_flip_complete(flip_state);
+   dma_fence_put(fence);
+}
+
+static int vc4_async_set_fence_cb(struct drm_device *dev,
+ struct vc4_async_flip_state *flip_state)
+{
+   struct drm_framebuffer *fb = flip_state->fb;
+   struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct dma_fence *fence;
+   int ret;
+
+   if (!vc4->is_vc5) {
+   struct vc4_bo *bo = to_vc4_bo(_bo->base);
+
+   return vc4_queue_seqno_cb(dev, _state->cb.seqno, bo->seqno,
+ vc4_async_page_flip_seqno_complete);
+   }
+
+   ret = dma_resv_get_singleton(cma_bo->base.resv, DMA_RESV_USAGE_READ, 
);
+   if (ret)
+   return ret;
+
+   /* If there's no fence, complete the page flip immediately */
+   if (!fence) {
+   vc4_async_page_flip_fence_complete(fence, 
_state->cb.fence);
+   return 0;
+   }
+
+   /* If the fence has already been completed, complete the page flip */
+   if (dma_fence_add_callback(fence, _state->cb.fence,
+  vc4_async_page_flip_fence_complete))
+   vc4_async_page_flip_fence_complete(fence, 
_state->cb.fence);
+
+   return 0;
+}
+
 static int
 vc4_async_page_flip_common(struct drm_crtc *crtc,
   struct drm_framebuffer *fb,
@@ -844,8 +889,6 @@ vc4_async_page_flip_common(struct drm_crtc *crtc,
struct drm_device *dev = crtc->dev;
struct drm_plane *plane = crtc->primary;
struct vc4_async_flip_state *flip_state;
-   struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
-   struct vc4_bo *bo = to_vc4_bo(_bo->base);
 
flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
if (!flip_state)
@@ -876,8 +919,7 @@ vc4_async_page_flip_common(struct drm_crtc *crtc,
 */
drm_atomic_set_fb_for_plane(plane->state, fb);
 
-   vc4_queue_seqno_cb(dev, _state->cb.seqno, bo->seqno,
-  vc4_async_page_flip_seqno_complete);
+   vc4_async_set_fence_cb(dev, flip_state);
 
/* Driver takes ownership of state on successful async commit. */
return 0;
-- 
2.36.1



[PATCH v2 05/14] drm/vc4: drv: Register a different driver on BCM2711

2022-06-10 Thread Maxime Ripard
Prior to the BCM2711/RaspberryPi4, the GPU was a part of the display
components of the SoC. It was thus a part of the vc4 driver.

However, with the BCM2711, it got split out and thus the v3d driver was
created. The vc4 driver now only handles the display part.

We didn't properly split out the code when doing the BCM2711 support
though, and most of the code around buffer allocations is still
involved, even though it doesn't have the backing hardware anymore.

Let's start the split out by creating a new drm_driver that only reports
and uses what we support on the BCM2711. The ioctl were properly
filtered already, but we were still exposing a .gem_create_object hook,
as well as having an .open and .postclose hooks which are only relevant
on older generations.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.c | 51 ---
 1 file changed, 42 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index eb08940028d3..528a1e2761f1 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -76,6 +76,19 @@ int vc4_dumb_fixup_args(struct drm_mode_create_dumb *args)
return 0;
 }
 
+static int vc5_dumb_create(struct drm_file *file_priv,
+  struct drm_device *dev,
+  struct drm_mode_create_dumb *args)
+{
+   int ret;
+
+   ret = vc4_dumb_fixup_args(args);
+   if (ret)
+   return ret;
+
+   return drm_gem_cma_dumb_create_internal(file_priv, dev, args);
+}
+
 static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv)
 {
@@ -173,7 +186,7 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
DRM_IOCTL_DEF_DRV(VC4_PERFMON_GET_VALUES, vc4_perfmon_get_values_ioctl, 
DRM_RENDER_ALLOW),
 };
 
-static struct drm_driver vc4_drm_driver = {
+static const struct drm_driver vc4_drm_driver = {
.driver_features = (DRIVER_MODESET |
DRIVER_ATOMIC |
DRIVER_GEM |
@@ -202,6 +215,27 @@ static struct drm_driver vc4_drm_driver = {
.patchlevel = DRIVER_PATCHLEVEL,
 };
 
+static const struct drm_driver vc5_drm_driver = {
+   .driver_features = (DRIVER_MODESET |
+   DRIVER_ATOMIC |
+   DRIVER_GEM),
+
+#if defined(CONFIG_DEBUG_FS)
+   .debugfs_init = vc4_debugfs_init,
+#endif
+
+   DRM_GEM_CMA_DRIVER_OPS_WITH_DUMB_CREATE(vc5_dumb_create),
+
+   .fops = _drm_fops,
+
+   .name = DRIVER_NAME,
+   .desc = DRIVER_DESC,
+   .date = DRIVER_DATE,
+   .major = DRIVER_MAJOR,
+   .minor = DRIVER_MINOR,
+   .patchlevel = DRIVER_PATCHLEVEL,
+};
+
 static void vc4_match_add_drivers(struct device *dev,
  struct component_match **match,
  struct platform_driver *const *drivers,
@@ -225,6 +259,7 @@ static void vc4_match_add_drivers(struct device *dev,
 static int vc4_drm_bind(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
+   const struct drm_driver *driver;
struct rpi_firmware *firmware = NULL;
struct drm_device *drm;
struct vc4_dev *vc4;
@@ -236,14 +271,12 @@ static int vc4_drm_bind(struct device *dev)
dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5");
+   if (is_vc5)
+   driver = _drm_driver;
+   else
+   driver = _drm_driver;
 
-   /* If VC4 V3D is missing, don't advertise render nodes. */
-   node = of_find_matching_node_and_match(NULL, vc4_v3d_dt_match, NULL);
-   if (!node || !of_device_is_available(node))
-   vc4_drm_driver.driver_features &= ~DRIVER_RENDER;
-   of_node_put(node);
-
-   vc4 = devm_drm_dev_alloc(dev, _drm_driver, struct vc4_dev, base);
+   vc4 = devm_drm_dev_alloc(dev, driver, struct vc4_dev, base);
if (IS_ERR(vc4))
return PTR_ERR(vc4);
vc4->is_vc5 = is_vc5;
@@ -275,7 +308,7 @@ static int vc4_drm_bind(struct device *dev)
return -EPROBE_DEFER;
}
 
-   ret = drm_aperture_remove_framebuffers(false, _drm_driver);
+   ret = drm_aperture_remove_framebuffers(false, driver);
if (ret)
return ret;
 
-- 
2.36.1



[PATCH v2 11/14] drm/vc4: crtc: Move the BO Handling out of Common Page-Flip Handler

2022-06-10 Thread Maxime Ripard
The function vc4_async_page_flip() handles asynchronous page-flips in
the vc4 driver.

However, it mixes some generic code with code that should only be run on
older generations that have the GPU handled by the vc4 driver.

Let's split the generic part out of vc4_async_page_flip() and into a
common function that we be reusable by an handler made for the BCM2711.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 73 ++
 1 file changed, 48 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 0410db97b9d1..c00fb964c534 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -835,40 +835,21 @@ static void vc4_async_page_flip_seqno_complete(struct 
vc4_seqno_cb *cb)
vc4_bo_dec_usecnt(bo);
 }
 
-/* Implements async (non-vblank-synced) page flips.
- *
- * The page flip ioctl needs to return immediately, so we grab the
- * modeset semaphore on the pipe, and queue the address update for
- * when V3D is done with the BO being flipped to.
- */
-static int vc4_async_page_flip(struct drm_crtc *crtc,
-  struct drm_framebuffer *fb,
-  struct drm_pending_vblank_event *event,
-  uint32_t flags)
+static int
+vc4_async_page_flip_common(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t flags)
 {
struct drm_device *dev = crtc->dev;
struct drm_plane *plane = crtc->primary;
-   int ret = 0;
struct vc4_async_flip_state *flip_state;
struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
struct vc4_bo *bo = to_vc4_bo(_bo->base);
 
-   /* Increment the BO usecnt here, so that we never end up with an
-* unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the
-* plane is later updated through the non-async path.
-* FIXME: we should move to generic async-page-flip when it's
-* available, so that we can get rid of this hand-made prepare_fb()
-* logic.
-*/
-   ret = vc4_bo_inc_usecnt(bo);
-   if (ret)
-   return ret;
-
flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
-   if (!flip_state) {
-   vc4_bo_dec_usecnt(bo);
+   if (!flip_state)
return -ENOMEM;
-   }
 
drm_framebuffer_get(fb);
flip_state->fb = fb;
@@ -902,6 +883,48 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
return 0;
 }
 
+/* Implements async (non-vblank-synced) page flips.
+ *
+ * The page flip ioctl needs to return immediately, so we grab the
+ * modeset semaphore on the pipe, and queue the address update for
+ * when V3D is done with the BO being flipped to.
+ */
+static int vc4_async_page_flip(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t flags)
+{
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+   struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
+   struct vc4_bo *bo = to_vc4_bo(_bo->base);
+   int ret;
+
+   if (WARN_ON_ONCE(vc4->is_vc5))
+   return -ENODEV;
+
+   /*
+* Increment the BO usecnt here, so that we never end up with an
+* unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the
+* plane is later updated through the non-async path.
+*
+* FIXME: we should move to generic async-page-flip when
+* it's available, so that we can get rid of this
+* hand-made prepare_fb() logic.
+*/
+   ret = vc4_bo_inc_usecnt(bo);
+   if (ret)
+   return ret;
+
+   ret = vc4_async_page_flip_common(crtc, fb, event, flags);
+   if (ret) {
+   vc4_bo_dec_usecnt(bo);
+   return ret;
+   }
+
+   return 0;
+}
+
 int vc4_page_flip(struct drm_crtc *crtc,
  struct drm_framebuffer *fb,
  struct drm_pending_vblank_event *event,
-- 
2.36.1



[PATCH v2 00/14] drm/vc4: Properly separate v3d on BCM2711, and fix frame ordering

2022-06-10 Thread Maxime Ripard
Hi,

Here's a series that fixes a significant issue we missed when adding support
for the BCM2711 / RaspberryPi4 in the vc4 driver.

Indeed, before the introduction of the BCM2711 support, the GPU was fairly
intertwined with the display hardware, and was thus supported by the vc4
driver. Among other things, the driver needed to accomodate for a bunch of
hardware limitations (such as a lack of IOMMU) by implementing a custom memory
management backend, tied with the v3d hardware.

On the BCM2711, that GPU got moved into a completely separate hardware block
and thus we gained a new driver for it, v3d.

However, when we introduced the display support for the BCM2711 in vc4, we
didn't properly split out the v3d-related functions and ended up reusing a
significant portion of the code supposed to be backed by the v3d.

This created a bunch of easy to miss issues that would only pop up with IGT
tests, or when heavily testing some features (like asynchronous page-flipping).

This series properly does the split now by creating separate code path where
relevant, adds a loud complain when we use a v3d entry-point on the BCM2711,
and fixes an issue where we would just ignore any fence on an asynchronous
page-flip, resulting in frames appearing out-of-order for some workloads.

Let me know what you think,
Maxime

Changes from v1:
  - Rebased on current drm-misc-next
  - Renamed vc4_dumb_create to vc5_dumb_create
  - Fixed intermediate compilation error
  - Fixed call to dma_resv_get_singleton
  - Complete async page flip immediately if there's no fence
  - Fix null pointer dereference on the Pi3
  - Collected tags from Melissa

Maxime Ripard (14):
  drm/vc4: plane: Prevent async update if we don't have a dlist
  drm/vc4: Consolidate Hardware Revision Check
  drm/vc4: bo: Rename vc4_dumb_create
  drm/vc4: bo: Split out Dumb buffers fixup
  drm/vc4: drv: Register a different driver on BCM2711
  drm/vc4: kms: Register a different drm_mode_config_funcs on BCM2711
  drm/vc4: plane: Register a different drm_plane_helper_funcs on BCM2711
  drm/vc4: drv: Skip BO Backend Initialization on BCM2711
  drm/vc4: crtc: Use an union to store the page flip callback
  drm/vc4: crtc: Move the BO handling out of common page-flip callback
  drm/vc4: crtc: Move the BO Handling out of Common Page-Flip Handler
  drm/vc4: crtc: Don't call into BO Handling on Async Page-Flips on
BCM2711
  drm/vc4: crtc: Fix out of order frames during asynchronous page flips
  drm/vc4: Warn if some v3d code is run on BCM2711

 drivers/gpu/drm/vc4/vc4_bo.c   |  62 ++-
 drivers/gpu/drm/vc4/vc4_crtc.c | 200 +++--
 drivers/gpu/drm/vc4/vc4_drv.c  |  97 --
 drivers/gpu/drm/vc4/vc4_drv.h  |  19 +-
 drivers/gpu/drm/vc4/vc4_gem.c  |  40 +
 drivers/gpu/drm/vc4/vc4_hvs.c  |  18 +-
 drivers/gpu/drm/vc4/vc4_irq.c  |  16 ++
 drivers/gpu/drm/vc4/vc4_kms.c  |  24 ++-
 drivers/gpu/drm/vc4/vc4_perfmon.c  |  47 -
 drivers/gpu/drm/vc4/vc4_plane.c|  29 ++-
 drivers/gpu/drm/vc4/vc4_render_cl.c|   4 +
 drivers/gpu/drm/vc4/vc4_v3d.c  |  15 ++
 drivers/gpu/drm/vc4/vc4_validate.c |  16 ++
 drivers/gpu/drm/vc4/vc4_validate_shaders.c |   4 +
 14 files changed, 482 insertions(+), 109 deletions(-)

-- 
2.36.1



[PATCH v2 01/14] drm/vc4: plane: Prevent async update if we don't have a dlist

2022-06-10 Thread Maxime Ripard
The vc4 planes are setup in hardware by creating a hardware descriptor
in a dedicated RAM. As part of the process to setup a plane in KMS, we
thus need to allocate some part of that dedicated RAM to store our
descriptor there.

The async update path will just reuse the descriptor already allocated
for that plane and will modify it directly in RAM to match whatever has
been asked for.

In order to do that, it will compare the descriptor for the old plane
state and the new plane state, will make sure they fit in the same size,
and check that only the position or buffer address have changed.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_plane.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index b3438f4a81ce..811a2d004cc4 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1321,6 +1321,10 @@ static int vc4_plane_atomic_async_check(struct drm_plane 
*plane,
 
old_vc4_state = to_vc4_plane_state(plane->state);
new_vc4_state = to_vc4_plane_state(new_plane_state);
+
+   if (!new_vc4_state->hw_dlist)
+   return -EINVAL;
+
if (old_vc4_state->dlist_count != new_vc4_state->dlist_count ||
old_vc4_state->pos0_offset != new_vc4_state->pos0_offset ||
old_vc4_state->pos2_offset != new_vc4_state->pos2_offset ||
-- 
2.36.1



[PATCH v2 04/14] drm/vc4: bo: Split out Dumb buffers fixup

2022-06-10 Thread Maxime Ripard
The vc4_bo_dumb_create() both fixes up the allocation arguments to match
the hardware constraints and actually performs the allocation.

Since we're going to introduce a new function that uses a different
allocator, let's split the arguments fixup to a separate function we
will be able to reuse.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_bo.c  |  9 +++--
 drivers/gpu/drm/vc4/vc4_drv.c | 13 +
 drivers/gpu/drm/vc4/vc4_drv.h |  1 +
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 6d505da6b6cf..3ca16d682fc0 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -475,15 +475,12 @@ int vc4_bo_dumb_create(struct drm_file *file_priv,
   struct drm_device *dev,
   struct drm_mode_create_dumb *args)
 {
-   int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
struct vc4_bo *bo = NULL;
int ret;
 
-   if (args->pitch < min_pitch)
-   args->pitch = min_pitch;
-
-   if (args->size < args->pitch * args->height)
-   args->size = args->pitch * args->height;
+   ret = vc4_dumb_fixup_args(args);
+   if (ret)
+   return ret;
 
bo = vc4_bo_create(dev, args->size, false, VC4_BO_TYPE_DUMB);
if (IS_ERR(bo))
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 5f39e40ef238..eb08940028d3 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -63,6 +63,19 @@ void __iomem *vc4_ioremap_regs(struct platform_device *pdev, 
int index)
return map;
 }
 
+int vc4_dumb_fixup_args(struct drm_mode_create_dumb *args)
+{
+   int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
+
+   if (args->pitch < min_pitch)
+   args->pitch = min_pitch;
+
+   if (args->size < args->pitch * args->height)
+   args->size = args->pitch * args->height;
+
+   return 0;
+}
+
 static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file_priv)
 {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 37c93654480f..9c324c12c410 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -885,6 +885,7 @@ static inline void vc4_debugfs_add_regset32(struct 
drm_device *drm,
 
 /* vc4_drv.c */
 void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
+int vc4_dumb_fixup_args(struct drm_mode_create_dumb *args);
 
 /* vc4_dpi.c */
 extern struct platform_driver vc4_dpi_driver;
-- 
2.36.1



[PATCH v2 09/14] drm/vc4: crtc: Use an union to store the page flip callback

2022-06-10 Thread Maxime Ripard
We'll need to extend the vc4_async_flip_state structure to rely on
another callback implementation, so let's move the current one into a
union.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index dd5fb25d0f43..1f247c037ce0 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -775,17 +775,17 @@ struct vc4_async_flip_state {
struct drm_framebuffer *old_fb;
struct drm_pending_vblank_event *event;
 
-   struct vc4_seqno_cb cb;
+   union {
+   struct vc4_seqno_cb seqno;
+   } cb;
 };
 
 /* Called when the V3D execution for the BO being flipped to is done, so that
  * we can actually update the plane's address to point to it.
  */
 static void
-vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
+vc4_async_page_flip_complete(struct vc4_async_flip_state *flip_state)
 {
-   struct vc4_async_flip_state *flip_state =
-   container_of(cb, struct vc4_async_flip_state, cb);
struct drm_crtc *crtc = flip_state->crtc;
struct drm_device *dev = crtc->dev;
struct drm_plane *plane = crtc->primary;
@@ -821,6 +821,14 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
kfree(flip_state);
 }
 
+static void vc4_async_page_flip_seqno_complete(struct vc4_seqno_cb *cb)
+{
+   struct vc4_async_flip_state *flip_state =
+   container_of(cb, struct vc4_async_flip_state, cb.seqno);
+
+   vc4_async_page_flip_complete(flip_state);
+}
+
 /* Implements async (non-vblank-synced) page flips.
  *
  * The page flip ioctl needs to return immediately, so we grab the
@@ -881,8 +889,8 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
 */
drm_atomic_set_fb_for_plane(plane->state, fb);
 
-   vc4_queue_seqno_cb(dev, _state->cb, bo->seqno,
-  vc4_async_page_flip_complete);
+   vc4_queue_seqno_cb(dev, _state->cb.seqno, bo->seqno,
+  vc4_async_page_flip_seqno_complete);
 
/* Driver takes ownership of state on successful async commit. */
return 0;
-- 
2.36.1



[PATCH v2 06/14] drm/vc4: kms: Register a different drm_mode_config_funcs on BCM2711

2022-06-10 Thread Maxime Ripard
On the BCM2711, our current definition of drm_mode_config_funcs uses the
custom vc4_fb_create().

However, that function relies on the buffer allocation path that was
relying on the GPU, and is no longer relevant.

Let's create another drm_mode_config_funcs structure that we will
register on the BCM2711.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_kms.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index 3c232d85ab85..1d3b31fb71ea 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -997,6 +997,12 @@ static const struct drm_mode_config_funcs vc4_mode_funcs = 
{
.fb_create = vc4_fb_create,
 };
 
+static const struct drm_mode_config_funcs vc5_mode_funcs = {
+   .atomic_check = vc4_atomic_check,
+   .atomic_commit = drm_atomic_helper_commit,
+   .fb_create = drm_gem_fb_create,
+};
+
 int vc4_kms_load(struct drm_device *dev)
 {
struct vc4_dev *vc4 = to_vc4_dev(dev);
@@ -1031,7 +1037,7 @@ int vc4_kms_load(struct drm_device *dev)
dev->mode_config.max_height = 2048;
}
 
-   dev->mode_config.funcs = _mode_funcs;
+   dev->mode_config.funcs = vc4->is_vc5 ? _mode_funcs : 
_mode_funcs;
dev->mode_config.helper_private = _mode_config_helpers;
dev->mode_config.preferred_depth = 24;
dev->mode_config.async_page_flip = true;
-- 
2.36.1



[PATCH v2 12/14] drm/vc4: crtc: Don't call into BO Handling on Async Page-Flips on BCM2711

2022-06-10 Thread Maxime Ripard
The BCM2711 doesn't have a v3d GPU so we don't want to call into its BO
management code. Let's create an asynchronous page-flip handler for the
BCM2711 that just calls into the common code.

Reviewed-by: Melissa Wen 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index c00fb964c534..a3c04d6cbd20 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -925,16 +925,31 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
return 0;
 }
 
+static int vc5_async_page_flip(struct drm_crtc *crtc,
+  struct drm_framebuffer *fb,
+  struct drm_pending_vblank_event *event,
+  uint32_t flags)
+{
+   return vc4_async_page_flip_common(crtc, fb, event, flags);
+}
+
 int vc4_page_flip(struct drm_crtc *crtc,
  struct drm_framebuffer *fb,
  struct drm_pending_vblank_event *event,
  uint32_t flags,
  struct drm_modeset_acquire_ctx *ctx)
 {
-   if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
-   return vc4_async_page_flip(crtc, fb, event, flags);
-   else
+   if (flags & DRM_MODE_PAGE_FLIP_ASYNC) {
+   struct drm_device *dev = crtc->dev;
+   struct vc4_dev *vc4 = to_vc4_dev(dev);
+
+   if (vc4->is_vc5)
+   return vc5_async_page_flip(crtc, fb, event, flags);
+   else
+   return vc4_async_page_flip(crtc, fb, event, flags);
+   } else {
return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
+   }
 }
 
 struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
-- 
2.36.1



Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Simon Ser
I agree with what others have replied, just adding a few more details.

On Thursday, June 9th, 2022 at 21:39, Zack Rusin  wrote:

> virtualized drivers send drm_kms_helper_hotplug_event which sends a HOTPLUG=1
> event with a changed preferred width/height

(Note: and the "hotplug_mode_update" property is set to 1.)

> suggested_x and suggested_y properties

These come with their own set of issues. They are poorly defined, but it seems
like they describe a position in physical pixel coordinates. Compositors don't
use physical pixel coordinates to organize their outputs, instead they use
logical coordinates. For instance, a HiDPI 4k screen with a scale of 2 will
take up 1920x1080 logical pixels. There is no way to convert physical pixel
coordinates to logical pixel coordinates in the general case, because there's
no "global scale factor". So suggested_x/y are incompatible with the way
compositors work.


Re: [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Matthew Brost
On Fri, Jun 10, 2022 at 01:53:40AM -0700, Matthew Brost wrote:
> On Fri, Jun 10, 2022 at 12:07:11AM -0700, Niranjana Vishwanathapura wrote:
> > VM_BIND and related uapi definitions
> > 
> > Signed-off-by: Niranjana Vishwanathapura 
> > 
> > ---
> >  Documentation/gpu/rfc/i915_vm_bind.h | 490 +++
> >  1 file changed, 490 insertions(+)
> >  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h
> > 
> > diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
> > b/Documentation/gpu/rfc/i915_vm_bind.h
> > new file mode 100644
> > index ..9fc854969cfb
> > --- /dev/null
> > +++ b/Documentation/gpu/rfc/i915_vm_bind.h
> > @@ -0,0 +1,490 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*
> > + * Copyright © 2022 Intel Corporation
> > + */
> > +
> > +/**
> > + * DOC: I915_PARAM_HAS_VM_BIND
> > + *
> > + * VM_BIND feature availability.
> > + * See typedef drm_i915_getparam_t param.
> > + * bit[0]: If set, VM_BIND is supported, otherwise not.
> > + * bits[8-15]: VM_BIND implementation version.
> > + * version 0 will not have VM_BIND/UNBIND timeline fence array support.
> > + */
> > +#define I915_PARAM_HAS_VM_BIND 57
> > +
> > +/**
> > + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
> > + *
> > + * Flag to opt-in for VM_BIND mode of binding during VM creation.
> > + * See struct drm_i915_gem_vm_control flags.
> > + *
> > + * The older execbuf2 ioctl will not support VM_BIND mode of operation.
> > + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any
> > + * execlist (See struct drm_i915_gem_execbuffer3 for more details).
> > + *
> > + */
> > +#define I915_VM_CREATE_FLAGS_USE_VM_BIND   (1 << 0)
> > +
> > +/**
> > + * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
> > + *
> > + * Flag to declare context as long running.
> > + * See struct drm_i915_gem_context_create_ext flags.
> > + *
> > + * Usage of dma-fence expects that they complete in reasonable amount of 
> > time.
> > + * Compute on the other hand can be long running. Hence it is not 
> > appropriate
> > + * for compute contexts to export request completion dma-fence to user.
> > + * The dma-fence usage will be limited to in-kernel consumption only.
> > + * Compute contexts need to use user/memory fence.
> > + *
> > + * So, long running contexts do not support output fences. Hence,
> > + * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) is expected
> > + * to be not used. DRM_I915_GEM_WAIT ioctl call is also not supported for
> > + * objects mapped to long running contexts.
> > + */
> > +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
> > +
> > +/* VM_BIND related ioctls */
> > +#define DRM_I915_GEM_VM_BIND   0x3d
> > +#define DRM_I915_GEM_VM_UNBIND 0x3e
> > +#define DRM_I915_GEM_EXECBUFFER3   0x3f
> > +#define DRM_I915_GEM_WAIT_USER_FENCE   0x40
> > +
> > +#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + 
> > DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
> > +#define DRM_IOCTL_I915_GEM_VM_UNBIND   
> > DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_VM_UNBIND, struct 
> > drm_i915_gem_vm_bind)
> > +#define DRM_IOCTL_I915_GEM_EXECBUFFER3 
> > DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct 
> > drm_i915_gem_execbuffer3)
> > +#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + 
> > DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
> > +
> > +/**
> > + * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
> > + *
> > + * This structure is passed to VM_BIND ioctl and specifies the mapping of 
> > GPU
> > + * virtual address (VA) range to the section of an object that should be 
> > bound
> > + * in the device page table of the specified address space (VM).
> > + * The VA range specified must be unique (ie., not currently bound) and can
> > + * be mapped to whole object or a section of the object (partial binding).
> > + * Multiple VA mappings can be created to the same section of the object
> > + * (aliasing).
> > + *
> > + * The @queue_idx specifies the queue to use for binding. Same queue can be
> > + * used for both VM_BIND and VM_UNBIND calls. All submitted bind and unbind
> > + * operations in a queue are performed in the order of submission.
> > + *
> > + * The @start, @offset and @length should be 4K page aligned. However the 
> > DG2
> > + * and XEHPSDV has 64K page size for device local-memory and has compact 
> > page
> > + * table. On those platforms, for binding device local-memory objects, the
> > + * @start should be 2M aligned, @offset and @length should be 64K aligned.
> > + * Also, on those platforms, it is not allowed to bind an device 
> > local-memory
> > + * object and a system memory object in a single 2M section of VA range.
> > + */
> > +struct drm_i915_gem_vm_bind {
> > +   /** @vm_id: VM (address space) id to bind */
> > +   __u32 vm_id;
> > +
> > +   /** @queue_idx: Index of queue for binding */
> > +   __u32 queue_idx;
> > +
> > +   /** 

Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Daniel Vetter
On Fri, Jun 10, 2022 at 08:54:03AM +, Simon Ser wrote:
> I agree with what others have replied, just adding a few more details.
> 
> On Thursday, June 9th, 2022 at 21:39, Zack Rusin  wrote:
> 
> > virtualized drivers send drm_kms_helper_hotplug_event which sends a 
> > HOTPLUG=1
> > event with a changed preferred width/height
> 
> (Note: and the "hotplug_mode_update" property is set to 1.)
> 
> > suggested_x and suggested_y properties
> 
> These come with their own set of issues. They are poorly defined, but it seems
> like they describe a position in physical pixel coordinates. Compositors don't
> use physical pixel coordinates to organize their outputs, instead they use
> logical coordinates. For instance, a HiDPI 4k screen with a scale of 2 will
> take up 1920x1080 logical pixels. There is no way to convert physical pixel
> coordinates to logical pixel coordinates in the general case, because there's
> no "global scale factor". So suggested_x/y are incompatible with the way
> compositors work.

I dropped a request for a proper doc section that explains all the
virtualized kms driver stuff. I think we should also put in a
"limitations" part there and just spec that any kind of scaling is a no-go
on these (and that drivers better validate this is the case).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


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

2022-06-10 Thread Javier Martinez Canillas
Hello Stephen,

On 6/10/22 06:49, Stephen Rothwell wrote:
> Hi all,
> 
> After merging the drm-misc tree, today's linux-next build (powerpc
> allyesconfig) failed like this:
> 
> drivers/firmware/efi/sysfb_efi.c:29:10: fatal error: asm/efi.h: No such file 
> or directory
>29 | #include 
>   |  ^~~
>

I noticed that this header include is not necessary so I posted [0] to
just drop it, and mentioned the build error too with your Reported-by.
 
> Caused by commit
> 
>   fa0e256450f2 ("fbdev: vesafb: Allow to be built if COMPILE_TEST is enabled")
>

I posted a revert [1] for this but for a different reason (since after
[0] I believe the issue in powerpc should be fixed), which is that the
patch led to linking errors on arches that don't define a screen_info.

[0]: https://lkml.org/lkml/2022/6/10/323
[1]: https://lkml.org/lkml/2022/6/10/316

-- 
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat



[PATCH 23/64] drm/vc4: dpi: Return an error if we can't enable our clock

2022-06-10 Thread Maxime Ripard
If we fail to enable the DPI clock, we just ignore the error and moves
forward. Let's return an error instead.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index d1eaafb43bd1..658e0aa9e2e1 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -270,6 +270,7 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
DRM_ERROR("Failed to get core clock: %d\n", ret);
return ret;
}
+
dpi->pixel_clock = devm_clk_get(dev, "pixel");
if (IS_ERR(dpi->pixel_clock)) {
ret = PTR_ERR(dpi->pixel_clock);
@@ -279,8 +280,10 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
}
 
ret = clk_prepare_enable(dpi->core_clock);
-   if (ret)
+   if (ret) {
DRM_ERROR("Failed to turn on core clock: %d\n", ret);
+   return ret;
+   }
 
drm_simple_encoder_init(drm, >encoder.base, DRM_MODE_ENCODER_DPI);
drm_encoder_helper_add(>encoder.base, 
_dpi_encoder_helper_funcs);
-- 
2.36.1



[PATCH 29/64] drm/vc4: dsi: Embed DRM structures into the private structure

2022-06-10 Thread Maxime Ripard
The VC4 DSI driver private structure contains only a pointer to the
encoder it implements. This makes the overall structure somewhat
inconsistent with the rest of the driver, and complicates its
initialisation without any apparent gain.

Let's embed the drm_encoder structure (through the vc4_encoder one) into
struct vc4_dsi to fix both issues.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dsi.c | 58 +--
 1 file changed, 22 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index 98308a17e4ed..dbb3f6fb39b4 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -507,10 +507,11 @@ struct vc4_dsi_variant {
 
 /* General DSI hardware state. */
 struct vc4_dsi {
-   struct platform_device *pdev;
-
+   struct vc4_encoder encoder;
struct mipi_dsi_host dsi_host;
-   struct drm_encoder *encoder;
+
+   struct platform_device *pdev;
+
struct drm_bridge *bridge;
struct list_head bridge_chain;
 
@@ -558,6 +559,12 @@ struct vc4_dsi {
 
 #define host_to_dsi(host) container_of(host, struct vc4_dsi, dsi_host)
 
+static inline struct vc4_dsi *
+to_vc4_dsi(struct drm_encoder *encoder)
+{
+   return container_of(encoder, struct vc4_dsi, encoder.base);
+}
+
 static inline void
 dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val)
 {
@@ -602,18 +609,6 @@ dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, 
u32 val)
DSI_WRITE(dsi->variant->port ? DSI1_##offset : DSI0_##offset, val)
 #define DSI_PORT_BIT(bit) (dsi->variant->port ? DSI1_##bit : DSI0_##bit)
 
-/* VC4 DSI encoder KMS struct */
-struct vc4_dsi_encoder {
-   struct vc4_encoder base;
-   struct vc4_dsi *dsi;
-};
-
-static inline struct vc4_dsi_encoder *
-to_vc4_dsi_encoder(struct drm_encoder *encoder)
-{
-   return container_of(encoder, struct vc4_dsi_encoder, base.base);
-}
-
 static const struct debugfs_reg32 dsi0_regs[] = {
VC4_REG32(DSI0_CTRL),
VC4_REG32(DSI0_STAT),
@@ -753,8 +748,7 @@ dsi_esc_timing(u32 ns)
 
 static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
 {
-   struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
-   struct vc4_dsi *dsi = vc4_encoder->dsi;
+   struct vc4_dsi *dsi = to_vc4_dsi(encoder);
struct device *dev = >pdev->dev;
struct drm_bridge *iter;
 
@@ -794,8 +788,7 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder 
*encoder,
   const struct drm_display_mode *mode,
   struct drm_display_mode *adjusted_mode)
 {
-   struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
-   struct vc4_dsi *dsi = vc4_encoder->dsi;
+   struct vc4_dsi *dsi = to_vc4_dsi(encoder);
struct clk *phy_parent = clk_get_parent(dsi->pll_phy_clock);
unsigned long parent_rate = clk_get_rate(phy_parent);
unsigned long pixel_clock_hz = mode->clock * 1000;
@@ -832,8 +825,7 @@ static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder 
*encoder,
 static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
 {
struct drm_display_mode *mode = >crtc->state->adjusted_mode;
-   struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
-   struct vc4_dsi *dsi = vc4_encoder->dsi;
+   struct vc4_dsi *dsi = to_vc4_dsi(encoder);
struct device *dev = >pdev->dev;
bool debug_dump_regs = false;
struct drm_bridge *iter;
@@ -1492,21 +1484,14 @@ static int vc4_dsi_bind(struct device *dev, struct 
device *master, void *data)
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dsi *dsi = dev_get_drvdata(dev);
-   struct vc4_dsi_encoder *vc4_dsi_encoder;
+   struct drm_encoder *encoder = >encoder.base;
dma_cap_mask_t dma_mask;
int ret;
 
dsi->variant = of_device_get_match_data(dev);
 
-   vc4_dsi_encoder = devm_kzalloc(dev, sizeof(*vc4_dsi_encoder),
-  GFP_KERNEL);
-   if (!vc4_dsi_encoder)
-   return -ENOMEM;
-
INIT_LIST_HEAD(>bridge_chain);
-   vc4_dsi_encoder->base.type = VC4_ENCODER_TYPE_DSI1;
-   vc4_dsi_encoder->dsi = dsi;
-   dsi->encoder = _dsi_encoder->base.base;
+   dsi->encoder.type = VC4_ENCODER_TYPE_DSI1;
 
dsi->regs = vc4_ioremap_regs(pdev, 0);
if (IS_ERR(dsi->regs))
@@ -1614,10 +1599,10 @@ static int vc4_dsi_bind(struct device *dev, struct 
device *master, void *data)
if (ret)
return ret;
 
-   drm_simple_encoder_init(drm, dsi->encoder, DRM_MODE_ENCODER_DSI);
-   drm_encoder_helper_add(dsi->encoder, _dsi_encoder_helper_funcs);
+   drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_DSI);
+   drm_encoder_helper_add(encoder, _dsi_encoder_helper_funcs);
 
-   ret = 

[PATCH 30/64] drm/vc4: dsi: Switch to DRM-managed encoder initialization

2022-06-10 Thread Maxime Ripard
The current code will call drm_encoder_cleanup() when the device is
unbound. However, by then, there might still be some references held to
that encoder, including by the userspace that might still have the DRM
device open.

Let's switch to a DRM-managed initialization to clean up after ourselves
only once the DRM device has been last closed.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dsi.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index dbb3f6fb39b4..bcaf87b43cbd 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -1599,7 +1599,10 @@ static int vc4_dsi_bind(struct device *dev, struct 
device *master, void *data)
if (ret)
return ret;
 
-   drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_DSI);
+   ret = drmm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_DSI);
+   if (ret)
+   return ret;
+
drm_encoder_helper_add(encoder, _dsi_encoder_helper_funcs);
 
ret = drm_bridge_attach(encoder, dsi->bridge, NULL, 0);
@@ -1632,7 +1635,6 @@ static void vc4_dsi_unbind(struct device *dev, struct 
device *master,
 * normally.
 */
list_splice_init(>bridge_chain, >bridge_chain);
-   drm_encoder_cleanup(encoder);
 }
 
 static const struct component_ops vc4_dsi_ops = {
-- 
2.36.1



[PATCH 21/64] drm/vc4: dpi: Embed DRM structures into the private structure

2022-06-10 Thread Maxime Ripard
The VC4 DPI driver private structure contains only a pointer to the
encoder it implements. This makes the overall structure somewhat
inconsistent with the rest of the driver, and complicates its
initialisation without any apparent gain.

Let's embed the drm_encoder structure (through the vc4_encoder one) into
struct vc4_dpi to fix both issues.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 49 ---
 1 file changed, 16 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index f2b46c524919..c88e8e397730 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -83,10 +83,10 @@
 
 /* General DPI hardware state. */
 struct vc4_dpi {
+   struct vc4_encoder encoder;
+
struct platform_device *pdev;
 
-   struct drm_encoder *encoder;
-
void __iomem *regs;
 
struct clk *pixel_clock;
@@ -95,21 +95,15 @@ struct vc4_dpi {
struct debugfs_regset32 regset;
 };
 
+static inline struct vc4_dpi *
+to_vc4_dpi(struct drm_encoder *encoder)
+{
+   return container_of(encoder, struct vc4_dpi, encoder.base);
+}
+
 #define DPI_READ(offset) readl(dpi->regs + (offset))
 #define DPI_WRITE(offset, val) writel(val, dpi->regs + (offset))
 
-/* VC4 DPI encoder KMS struct */
-struct vc4_dpi_encoder {
-   struct vc4_encoder base;
-   struct vc4_dpi *dpi;
-};
-
-static inline struct vc4_dpi_encoder *
-to_vc4_dpi_encoder(struct drm_encoder *encoder)
-{
-   return container_of(encoder, struct vc4_dpi_encoder, base.base);
-}
-
 static const struct debugfs_reg32 dpi_regs[] = {
VC4_REG32(DPI_C),
VC4_REG32(DPI_ID),
@@ -117,8 +111,7 @@ static const struct debugfs_reg32 dpi_regs[] = {
 
 static void vc4_dpi_encoder_disable(struct drm_encoder *encoder)
 {
-   struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder);
-   struct vc4_dpi *dpi = vc4_encoder->dpi;
+   struct vc4_dpi *dpi = to_vc4_dpi(encoder);
 
clk_disable_unprepare(dpi->pixel_clock);
 }
@@ -127,8 +120,7 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
*encoder)
 {
struct drm_device *dev = encoder->dev;
struct drm_display_mode *mode = >crtc->mode;
-   struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder);
-   struct vc4_dpi *dpi = vc4_encoder->dpi;
+   struct vc4_dpi *dpi = to_vc4_dpi(encoder);
struct drm_connector_list_iter conn_iter;
struct drm_connector *connector = NULL, *connector_scan;
u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE;
@@ -242,7 +234,7 @@ static int vc4_dpi_init_bridge(struct vc4_dpi *dpi)
return PTR_ERR(bridge);
}
 
-   return drm_bridge_attach(dpi->encoder, bridge, NULL, 0);
+   return drm_bridge_attach(>encoder.base, bridge, NULL, 0);
 }
 
 static int vc4_dpi_bind(struct device *dev, struct device *master, void *data)
@@ -250,21 +242,12 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dpi *dpi;
-   struct vc4_dpi_encoder *vc4_dpi_encoder;
int ret;
 
dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
if (!dpi)
return -ENOMEM;
-
-   vc4_dpi_encoder = devm_kzalloc(dev, sizeof(*vc4_dpi_encoder),
-  GFP_KERNEL);
-   if (!vc4_dpi_encoder)
-   return -ENOMEM;
-   vc4_dpi_encoder->base.type = VC4_ENCODER_TYPE_DPI;
-   vc4_dpi_encoder->dpi = dpi;
-   dpi->encoder = _dpi_encoder->base.base;
-
+   dpi->encoder.type = VC4_ENCODER_TYPE_DPI;
dpi->pdev = pdev;
dpi->regs = vc4_ioremap_regs(pdev, 0);
if (IS_ERR(dpi->regs))
@@ -298,8 +281,8 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
if (ret)
DRM_ERROR("Failed to turn on core clock: %d\n", ret);
 
-   drm_simple_encoder_init(drm, dpi->encoder, DRM_MODE_ENCODER_DPI);
-   drm_encoder_helper_add(dpi->encoder, _dpi_encoder_helper_funcs);
+   drm_simple_encoder_init(drm, >encoder.base, DRM_MODE_ENCODER_DPI);
+   drm_encoder_helper_add(>encoder.base, 
_dpi_encoder_helper_funcs);
 
ret = vc4_dpi_init_bridge(dpi);
if (ret)
@@ -312,7 +295,7 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
return 0;
 
 err_destroy_encoder:
-   drm_encoder_cleanup(dpi->encoder);
+   drm_encoder_cleanup(>encoder.base);
clk_disable_unprepare(dpi->core_clock);
return ret;
 }
@@ -324,7 +307,7 @@ static void vc4_dpi_unbind(struct device *dev, struct 
device *master,
 
drm_of_panel_bridge_remove(dev->of_node, 0, 0);
 
-   drm_encoder_cleanup(dpi->encoder);
+   drm_encoder_cleanup(>encoder.base);
 

[PATCH 20/64] drm/vc4: dpi: Remove vc4_dev dpi pointer

2022-06-10 Thread Maxime Ripard
There's no user for that pointer so let's just get rid of it.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 7 ---
 drivers/gpu/drm/vc4/vc4_drv.h | 1 -
 2 files changed, 8 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index c180eb60bee8..f2b46c524919 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -249,7 +249,6 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
 {
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = dev_get_drvdata(master);
-   struct vc4_dev *vc4 = to_vc4_dev(drm);
struct vc4_dpi *dpi;
struct vc4_dpi_encoder *vc4_dpi_encoder;
int ret;
@@ -308,8 +307,6 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
 
dev_set_drvdata(dev, dpi);
 
-   vc4->dpi = dpi;
-
vc4_debugfs_add_regset32(drm, "dpi_regs", >regset);
 
return 0;
@@ -323,8 +320,6 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
 static void vc4_dpi_unbind(struct device *dev, struct device *master,
   void *data)
 {
-   struct drm_device *drm = dev_get_drvdata(master);
-   struct vc4_dev *vc4 = to_vc4_dev(drm);
struct vc4_dpi *dpi = dev_get_drvdata(dev);
 
drm_of_panel_bridge_remove(dev->of_node, 0, 0);
@@ -332,8 +327,6 @@ static void vc4_dpi_unbind(struct device *dev, struct 
device *master,
drm_encoder_cleanup(dpi->encoder);
 
clk_disable_unprepare(dpi->core_clock);
-
-   vc4->dpi = NULL;
 }
 
 static const struct component_ops vc4_dpi_ops = {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index fff3772be2d4..846f3cda179a 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -79,7 +79,6 @@ struct vc4_dev {
 
struct vc4_hvs *hvs;
struct vc4_v3d *v3d;
-   struct vc4_dpi *dpi;
struct vc4_vec *vec;
struct vc4_txp *txp;
 
-- 
2.36.1



[PATCH 18/64] drm/vc4: crtc: Switch to drmm_kzalloc

2022-06-10 Thread Maxime Ripard
Our internal structure that stores the DRM entities structure is allocated
through a device-managed kzalloc.

This means that this will eventually be freed whenever the device is
removed. In our case, the most like source of removal is that the main
device is going to be unbound, and component_unbind_all() is being run.

However, it occurs while the DRM device is still registered, which will
create dangling pointers, eventually resulting in use-after-free.

Switch to a DRM-managed allocation to keep our structure until the DRM
driver doesn't need it anymore.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 1f7e987e68aa..c74fa3d07561 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -1178,7 +1178,7 @@ static int vc4_crtc_bind(struct device *dev, struct 
device *master, void *data)
struct drm_crtc *crtc;
int ret;
 
-   vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
+   vc4_crtc = drmm_kzalloc(drm, sizeof(*vc4_crtc), GFP_KERNEL);
if (!vc4_crtc)
return -ENOMEM;
crtc = _crtc->base;
-- 
2.36.1



[PATCH 24/64] drm/vc4: dpi: Remove unnecessary drm_of_panel_bridge_remove call

2022-06-10 Thread Maxime Ripard
Since we have a managed call to create our panel_bridge instance, the call
to drm_of_panel_bridge_remove() at unbind is both redundant and dangerous
since it might lead to a use-after-free.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 658e0aa9e2e1..5a6cdea7bf7b 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -309,8 +309,6 @@ static void vc4_dpi_unbind(struct device *dev, struct 
device *master,
 {
struct vc4_dpi *dpi = dev_get_drvdata(dev);
 
-   drm_of_panel_bridge_remove(dev->of_node, 0, 0);
-
drm_encoder_cleanup(>encoder.base);
 
clk_disable_unprepare(dpi->core_clock);
-- 
2.36.1



[PATCH 22/64] drm/vc4: dpi: Switch to drmm_kzalloc

2022-06-10 Thread Maxime Ripard
Our internal structure that stores the DRM entities structure is allocated
through a device-managed kzalloc.

This means that this will eventually be freed whenever the device is
removed. In our case, the most like source of removal is that the main
device is going to be unbound, and component_unbind_all() is being run.

However, it occurs while the DRM device is still registered, which will
create dangling pointers, eventually resulting in use-after-free.

Switch to a DRM-managed allocation to keep our structure until the DRM
driver doesn't need it anymore.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index c88e8e397730..d1eaafb43bd1 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -244,9 +244,10 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
struct vc4_dpi *dpi;
int ret;
 
-   dpi = devm_kzalloc(dev, sizeof(*dpi), GFP_KERNEL);
+   dpi = drmm_kzalloc(drm, sizeof(*dpi), GFP_KERNEL);
if (!dpi)
return -ENOMEM;
+
dpi->encoder.type = VC4_ENCODER_TYPE_DPI;
dpi->pdev = pdev;
dpi->regs = vc4_ioremap_regs(pdev, 0);
-- 
2.36.1



[PATCH 25/64] drm/vc4: dpi: Add action to disable the clock

2022-06-10 Thread Maxime Ripard
Adding a device-managed action will make the error path easier, so let's
create one to disable our clock.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 5a6cdea7bf7b..4e24dbad77f2 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -237,6 +237,13 @@ static int vc4_dpi_init_bridge(struct vc4_dpi *dpi)
return drm_bridge_attach(>encoder.base, bridge, NULL, 0);
 }
 
+static void vc4_dpi_disable_clock(void *ptr)
+{
+   struct vc4_dpi *dpi = ptr;
+
+   clk_disable_unprepare(dpi->core_clock);
+}
+
 static int vc4_dpi_bind(struct device *dev, struct device *master, void *data)
 {
struct platform_device *pdev = to_platform_device(dev);
@@ -285,6 +292,10 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
return ret;
}
 
+   ret = devm_add_action_or_reset(dev, vc4_dpi_disable_clock, dpi);
+   if (ret)
+   return ret;
+
drm_simple_encoder_init(drm, >encoder.base, DRM_MODE_ENCODER_DPI);
drm_encoder_helper_add(>encoder.base, 
_dpi_encoder_helper_funcs);
 
@@ -300,7 +311,6 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
 
 err_destroy_encoder:
drm_encoder_cleanup(>encoder.base);
-   clk_disable_unprepare(dpi->core_clock);
return ret;
 }
 
@@ -310,8 +320,6 @@ static void vc4_dpi_unbind(struct device *dev, struct 
device *master,
struct vc4_dpi *dpi = dev_get_drvdata(dev);
 
drm_encoder_cleanup(>encoder.base);
-
-   clk_disable_unprepare(dpi->core_clock);
 }
 
 static const struct component_ops vc4_dpi_ops = {
-- 
2.36.1



[PATCH 10/64] drm/bridge: panel: Introduce drmm_panel_bridge_add

2022-06-10 Thread Maxime Ripard
Unlike what can be found for other entities, there's no DRM-managed
function to create a panel_bridge instance from a panel.

Let's introduce one.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/bridge/panel.c | 39 ++
 include/drm/drm_bridge.h   |  2 ++
 2 files changed, 41 insertions(+)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 0ee563eb2b6f..07d720aa38c6 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -333,6 +334,44 @@ struct drm_bridge *devm_drm_panel_bridge_add_typed(struct 
device *dev,
 }
 EXPORT_SYMBOL(devm_drm_panel_bridge_add_typed);
 
+static void drmm_drm_panel_bridge_release(struct drm_device *drm, void *ptr)
+{
+   struct drm_bridge *bridge = ptr;
+
+   drm_panel_bridge_remove(bridge);
+}
+
+/**
+ * drmm_panel_bridge_add - Creates a DRM-managed _bridge and
+ * _connector that just calls the
+ * appropriate functions from _panel.
+ *
+ * @dev: DRM device to tie the bridge lifetime to
+ * @panel: The drm_panel being wrapped.  Must be non-NULL.
+ *
+ * This is the DRM-managed version of drm_panel_bridge_add() which
+ * automatically calls drm_panel_bridge_remove() when @dev is cleaned
+ * up.
+ */
+struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm,
+struct drm_panel *panel)
+{
+   struct drm_bridge *bridge;
+   int ret;
+
+   bridge = drm_panel_bridge_add_typed(panel, panel->connector_type);
+   if (IS_ERR(bridge))
+   return bridge;
+
+   ret = drmm_add_action_or_reset(drm, drmm_drm_panel_bridge_release,
+  bridge);
+   if (ret)
+   return ERR_PTR(ret);
+
+   return bridge;
+}
+EXPORT_SYMBOL(drmm_panel_bridge_add);
+
 /**
  * drm_panel_bridge_connector - return the connector for the panel bridge
  * @bridge: The drm_bridge.
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 42aec8612f37..8100a15dd9c2 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -927,6 +927,8 @@ struct drm_bridge *devm_drm_panel_bridge_add(struct device 
*dev,
 struct drm_bridge *devm_drm_panel_bridge_add_typed(struct device *dev,
   struct drm_panel *panel,
   u32 connector_type);
+struct drm_bridge *drmm_panel_bridge_add(struct drm_device *drm,
+struct drm_panel *panel);
 struct drm_connector *drm_panel_bridge_connector(struct drm_bridge *bridge);
 #endif
 
-- 
2.36.1



[PATCH 13/64] drm/vc4: hvs: Protect device resources after removal

2022-06-10 Thread Maxime Ripard
Whenever the device and driver are unbound, the main device and all the
subdevices will be removed by calling their unbind() method.

However, the DRM device itself will only be freed when the last user will
have closed it.

It means that there is a time window where the device and its resources
aren't there anymore, but the userspace can still call into our driver.

Fortunately, the DRM framework provides the drm_dev_enter() and
drm_dev_exit() functions to make sure our underlying device is still there
for the section protected by those calls. Let's add them to the HVS driver.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.h |   1 +
 drivers/gpu/drm/vc4/vc4_hvs.c | 106 +++---
 2 files changed, 99 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index aa4c5910ea05..080deae55f64 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -317,6 +317,7 @@ struct vc4_v3d {
 };
 
 struct vc4_hvs {
+   struct drm_device *dev;
struct platform_device *pdev;
void __iomem *regs;
u32 __iomem *dlist;
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 2a58fc421cf6..483053e7b14f 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -25,6 +25,7 @@
 #include 
 
 #include 
+#include 
 #include 
 
 #include "vc4_drv.h"
@@ -66,11 +67,15 @@ static const struct debugfs_reg32 hvs_regs[] = {
 
 void vc4_hvs_dump_state(struct vc4_hvs *hvs)
 {
+   struct drm_device *drm = hvs->dev;
struct drm_printer p = drm_info_printer(>pdev->dev);
-   int i;
+   int idx, i;
 
drm_print_regset32(, >regset);
 
+   if (!drm_dev_enter(drm, ))
+   return;
+
DRM_INFO("HVS ctx:\n");
for (i = 0; i < 64; i += 4) {
DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n",
@@ -80,6 +85,8 @@ void vc4_hvs_dump_state(struct vc4_hvs *hvs)
 readl((u32 __iomem *)hvs->dlist + i + 2),
 readl((u32 __iomem *)hvs->dlist + i + 3));
}
+
+   drm_dev_exit(idx);
 }
 
 static int vc4_hvs_debugfs_underrun(struct seq_file *m, void *data)
@@ -132,14 +139,18 @@ static int vc4_hvs_upload_linear_kernel(struct vc4_hvs 
*hvs,
struct drm_mm_node *space,
const u32 *kernel)
 {
-   int ret, i;
+   struct drm_device *drm = hvs->dev;
+   int idx, ret, i;
u32 __iomem *dst_kernel;
 
+   if (!drm_dev_enter(drm, ))
+   return -ENODEV;
+
ret = drm_mm_insert_node(>dlist_mm, space, VC4_KERNEL_DWORDS);
if (ret) {
DRM_ERROR("Failed to allocate space for filter kernel: %d\n",
  ret);
-   return ret;
+   goto err_dev_exit;
}
 
dst_kernel = hvs->dlist + space->start;
@@ -153,16 +164,26 @@ static int vc4_hvs_upload_linear_kernel(struct vc4_hvs 
*hvs,
}
}
 
+   drm_dev_exit(idx);
return 0;
+
+err_dev_exit:
+   drm_dev_exit(idx);
+   return ret;
 }
 
 static void vc4_hvs_lut_load(struct vc4_hvs *hvs,
 struct vc4_crtc *vc4_crtc)
 {
+   struct drm_device *drm = hvs->dev;
struct drm_crtc *crtc = _crtc->base;
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+   int idx;
u32 i;
 
+   if (!drm_dev_enter(drm, ))
+   return;
+
/* The LUT memory is laid out with each HVS channel in order,
 * each of which takes 256 writes for R, 256 for G, then 256
 * for B.
@@ -177,6 +198,8 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs,
HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_g[i]);
for (i = 0; i < crtc->gamma_size; i++)
HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]);
+
+   drm_dev_exit(idx);
 }
 
 static void vc4_hvs_update_gamma_lut(struct vc4_hvs *hvs,
@@ -198,7 +221,12 @@ static void vc4_hvs_update_gamma_lut(struct vc4_hvs *hvs,
 
 u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo)
 {
+   struct drm_device *drm = hvs->dev;
u8 field = 0;
+   int idx;
+
+   if (!drm_dev_enter(drm, ))
+   return 0;
 
switch (fifo) {
case 0:
@@ -215,6 +243,7 @@ u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, 
unsigned int fifo)
break;
}
 
+   drm_dev_exit(idx);
return field;
 }
 
@@ -226,6 +255,12 @@ int vc4_hvs_get_fifo_from_output(struct vc4_hvs *hvs, 
unsigned int output)
if (!hvs->hvs5)
return output;
 
+   /*
+* NOTE: We should probably use drm_dev_enter()/drm_dev_exit()
+* here, but this function is only used during the DRM device
+* initialization, so we should be fine.
+*/
+
switch (output) {
case 

[PATCH 14/64] drm/vc4: hvs: Remove planes currently allocated before taking down

2022-06-10 Thread Maxime Ripard
When the HVS driver is unbound, a lot of memory allocations in the LBM and
DLIST RAM are still assigned to planes that are still allocated.

Thus, we hit a warning when calling drm_mm_takedown() since the memory pool
is not completely free of allocations.

Let's free all the currently live entries before calling drm_mm_takedown().

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hvs.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c
index 483053e7b14f..b0906bb96c32 100644
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -834,11 +834,18 @@ static void vc4_hvs_unbind(struct device *dev, struct 
device *master,
struct drm_device *drm = dev_get_drvdata(master);
struct vc4_dev *vc4 = to_vc4_dev(drm);
struct vc4_hvs *hvs = vc4->hvs;
+   struct drm_mm_node *node, *next;
 
if (drm_mm_node_allocated(>hvs->mitchell_netravali_filter))
drm_mm_remove_node(>hvs->mitchell_netravali_filter);
 
+   drm_mm_for_each_node_safe(node, next, >hvs->dlist_mm)
+   drm_mm_remove_node(node);
+
drm_mm_takedown(>hvs->dlist_mm);
+
+   drm_mm_for_each_node_safe(node, next, >hvs->lbm_mm)
+   drm_mm_remove_node(node);
drm_mm_takedown(>hvs->lbm_mm);
 
clk_disable_unprepare(hvs->core_clk);
-- 
2.36.1



[PATCH 15/64] drm/vc4: plane: Take possible_crtcs as an argument

2022-06-10 Thread Maxime Ripard
vc4_plane_init() currently initialises the plane with no possible CRTCs,
and will expect the caller to set it up by itself.

Let's change that logic a bit to follow the syntax of
drm_universal_plane_init() and pass the possible CRTCs bitmask as an
argument to the function instead.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c  |  2 +-
 drivers/gpu/drm/vc4/vc4_drv.h   |  3 ++-
 drivers/gpu/drm/vc4/vc4_plane.c | 15 +++
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 59b20c8f132b..840a93484bb1 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -1138,7 +1138,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
*vc4_crtc,
 * requirement of the plane configuration, and reject ones
 * that will take too much.
 */
-   primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY);
+   primary_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_PRIMARY, 0);
if (IS_ERR(primary_plane)) {
dev_err(drm->dev, "failed to construct primary plane\n");
return PTR_ERR(primary_plane);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 080deae55f64..5125ca1a8158 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -952,7 +952,8 @@ int vc4_kms_load(struct drm_device *dev);
 
 /* vc4_plane.c */
 struct drm_plane *vc4_plane_init(struct drm_device *dev,
-enum drm_plane_type type);
+enum drm_plane_type type,
+unsigned int possible_crtcs);
 int vc4_plane_create_additional_planes(struct drm_device *dev);
 u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
 u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index b3438f4a81ce..17dab470ecdf 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1451,7 +1451,8 @@ static const struct drm_plane_funcs vc4_plane_funcs = {
 };
 
 struct drm_plane *vc4_plane_init(struct drm_device *dev,
-enum drm_plane_type type)
+enum drm_plane_type type,
+unsigned int possible_crtcs)
 {
struct drm_plane *plane = NULL;
struct vc4_plane *vc4_plane;
@@ -1483,7 +1484,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
}
 
plane = _plane->base;
-   ret = drm_universal_plane_init(dev, plane, 0,
+   ret = drm_universal_plane_init(dev, plane, possible_crtcs,
   _plane_funcs,
   formats, num_formats,
   modifiers, type, NULL);
@@ -1528,13 +1529,11 @@ int vc4_plane_create_additional_planes(struct 
drm_device *drm)
 */
for (i = 0; i < 16; i++) {
struct drm_plane *plane =
-   vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY);
+   vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
+  GENMASK(drm->mode_config.num_crtc - 1, 
0));
 
if (IS_ERR(plane))
continue;
-
-   plane->possible_crtcs =
-   GENMASK(drm->mode_config.num_crtc - 1, 0);
}
 
drm_for_each_crtc(crtc, drm) {
@@ -1542,9 +1541,9 @@ int vc4_plane_create_additional_planes(struct drm_device 
*drm)
 * since we overlay planes on the CRTC in the order they were
 * initialized.
 */
-   cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
+   cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR,
+ drm_crtc_mask(crtc));
if (!IS_ERR(cursor_plane)) {
-   cursor_plane->possible_crtcs = drm_crtc_mask(crtc);
crtc->cursor = cursor_plane;
}
}
-- 
2.36.1



[PATCH 12/64] drm/vc4: Call component_unbind_all()

2022-06-10 Thread Maxime Ripard
While we were using the component framework to deal with all the DRM
subdevices, we were not calling component_unbind_all().

This leads to none of the subdevices freeing up their resources as part of
their unbind() or device managed hooks.

Fixes: c8b75bca92cb ("drm/vc4: Add KMS support for Raspberry Pi.")
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_drv.c | 14 --
 drivers/gpu/drm/vc4/vc4_drv.h |  1 +
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 162bc18e7497..031f2cdd658d 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -209,6 +209,13 @@ static void vc4_match_add_drivers(struct device *dev,
}
 }
 
+static void vc4_component_unbind_all(void *ptr)
+{
+   struct vc4_dev *vc4 = ptr;
+
+   component_unbind_all(vc4->dev, >base);
+}
+
 static int vc4_drm_bind(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
@@ -230,6 +237,7 @@ static int vc4_drm_bind(struct device *dev)
vc4 = devm_drm_dev_alloc(dev, _drm_driver, struct vc4_dev, base);
if (IS_ERR(vc4))
return PTR_ERR(vc4);
+   vc4->dev = dev;
 
drm = >base;
platform_set_drvdata(pdev, drm);
@@ -276,6 +284,10 @@ static int vc4_drm_bind(struct device *dev)
if (ret)
return ret;
 
+   ret = devm_add_action_or_reset(dev, vc4_component_unbind_all, vc4);
+   if (ret)
+   return ret;
+
ret = vc4_plane_create_additional_planes(drm);
if (ret)
goto unbind_all;
@@ -296,8 +308,6 @@ static int vc4_drm_bind(struct device *dev)
return 0;
 
 unbind_all:
-   component_unbind_all(dev, drm);
-
return ret;
 }
 
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 15e0c2ac3940..aa4c5910ea05 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -73,6 +73,7 @@ struct vc4_perfmon {
 
 struct vc4_dev {
struct drm_device base;
+   struct device *dev;
 
unsigned int irq;
 
-- 
2.36.1



[PATCH 17/64] drm/vc4: crtc: Move debugfs_name to crtc_data

2022-06-10 Thread Maxime Ripard
All the CRTCs, including the TXP, have a debugfs file and name so we can
consolidate it into vc4_crtc_data.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 18 +-
 drivers/gpu/drm/vc4/vc4_drv.h  |  4 ++--
 drivers/gpu/drm/vc4/vc4_txp.c  |  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 7163f924b48b..1f7e987e68aa 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -978,10 +978,10 @@ static const struct drm_crtc_helper_funcs 
vc4_crtc_helper_funcs = {
 
 static const struct vc4_pv_data bcm2835_pv0_data = {
.base = {
+   .debugfs_name = "crtc0_regs",
.hvs_available_channels = BIT(0),
.hvs_output = 0,
},
-   .debugfs_name = "crtc0_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -992,10 +992,10 @@ static const struct vc4_pv_data bcm2835_pv0_data = {
 
 static const struct vc4_pv_data bcm2835_pv1_data = {
.base = {
+   .debugfs_name = "crtc1_regs",
.hvs_available_channels = BIT(2),
.hvs_output = 2,
},
-   .debugfs_name = "crtc1_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -1006,10 +1006,10 @@ static const struct vc4_pv_data bcm2835_pv1_data = {
 
 static const struct vc4_pv_data bcm2835_pv2_data = {
.base = {
+   .debugfs_name = "crtc2_regs",
.hvs_available_channels = BIT(1),
.hvs_output = 1,
},
-   .debugfs_name = "crtc2_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -1020,10 +1020,10 @@ static const struct vc4_pv_data bcm2835_pv2_data = {
 
 static const struct vc4_pv_data bcm2711_pv0_data = {
.base = {
+   .debugfs_name = "crtc0_regs",
.hvs_available_channels = BIT(0),
.hvs_output = 0,
},
-   .debugfs_name = "crtc0_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -1034,10 +1034,10 @@ static const struct vc4_pv_data bcm2711_pv0_data = {
 
 static const struct vc4_pv_data bcm2711_pv1_data = {
.base = {
+   .debugfs_name = "crtc1_regs",
.hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
.hvs_output = 3,
},
-   .debugfs_name = "crtc1_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -1048,10 +1048,10 @@ static const struct vc4_pv_data bcm2711_pv1_data = {
 
 static const struct vc4_pv_data bcm2711_pv2_data = {
.base = {
+   .debugfs_name = "crtc2_regs",
.hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
.hvs_output = 4,
},
-   .debugfs_name = "crtc2_regs",
.fifo_depth = 256,
.pixels_per_clock = 2,
.encoder_types = {
@@ -1061,10 +1061,10 @@ static const struct vc4_pv_data bcm2711_pv2_data = {
 
 static const struct vc4_pv_data bcm2711_pv3_data = {
.base = {
+   .debugfs_name = "crtc3_regs",
.hvs_available_channels = BIT(1),
.hvs_output = 1,
},
-   .debugfs_name = "crtc3_regs",
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
@@ -1074,10 +1074,10 @@ static const struct vc4_pv_data bcm2711_pv3_data = {
 
 static const struct vc4_pv_data bcm2711_pv4_data = {
.base = {
+   .debugfs_name = "crtc4_regs",
.hvs_available_channels = BIT(0) | BIT(1) | BIT(2),
.hvs_output = 5,
},
-   .debugfs_name = "crtc4_regs",
.fifo_depth = 64,
.pixels_per_clock = 2,
.encoder_types = {
@@ -1214,7 +1214,7 @@ static int vc4_crtc_bind(struct device *dev, struct 
device *master, void *data)
 
platform_set_drvdata(pdev, vc4_crtc);
 
-   vc4_debugfs_add_regset32(drm, pv_data->debugfs_name,
+   vc4_debugfs_add_regset32(drm, pv_data->base.debugfs_name,
 _crtc->regset);
 
return 0;
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 5125ca1a8158..9a53ace85d95 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -457,6 +457,8 @@ to_vc4_encoder(struct drm_encoder *encoder)
 }
 
 struct vc4_crtc_data {
+   const char *debugfs_name;
+
/* Bitmask of channels (FIFOs) of the HVS that the output can source 
from */
unsigned int hvs_available_channels;
 
@@ -474,8 +476,6 @@ struct vc4_pv_data {
u8 pixels_per_clock;
 
enum vc4_encoder_type encoder_types[4];
-   const char *debugfs_name;
-
 };
 
 struct vc4_crtc {
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index 82beb8c159f2..e983ff7c5e13 100644
--- 

[PATCH 06/64] drm/connector: Introduce drmm_connector_init

2022-06-10 Thread Maxime Ripard
Unlike other DRM entities, there's no helper to create a DRM-managed
initialisation of a connector.

Let's create an helper to initialise a connector that would be passed as an
argument, and handle the cleanup through a DRM-managed action.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_connector.c | 108 +---
 include/drm/drm_connector.h |   4 ++
 2 files changed, 90 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 2a78a23836d8..f150270b519f 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -212,28 +213,10 @@ void drm_connector_free_work_fn(struct work_struct *work)
}
 }
 
-/**
- * drm_connector_init - Init a preallocated connector
- * @dev: DRM device
- * @connector: the connector to init
- * @funcs: callbacks for this connector
- * @connector_type: user visible type of the connector
- *
- * Initialises a preallocated connector. Connectors should be
- * subclassed as part of driver connector objects.
- *
- * At driver unload time the driver's _connector_funcs.destroy hook
- * should call drm_connector_unregister(), drm_connector_cleanup() and
- * kfree() the connector structure. The connector structure should not
- * be allocated with devm_kzalloc().
- *
- * Returns:
- * Zero on success, error code on failure.
- */
-int drm_connector_init(struct drm_device *dev,
-  struct drm_connector *connector,
-  const struct drm_connector_funcs *funcs,
-  int connector_type)
+static int __drm_connector_init(struct drm_device *dev,
+   struct drm_connector *connector,
+   const struct drm_connector_funcs *funcs,
+   int connector_type)
 {
struct drm_mode_config *config = >mode_config;
int ret;
@@ -337,6 +320,39 @@ int drm_connector_init(struct drm_device *dev,
 
return ret;
 }
+
+/**
+ * drm_connector_init - Init a preallocated connector
+ * @dev: DRM device
+ * @connector: the connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ *
+ * Initialises a preallocated connector. Connectors should be
+ * subclassed as part of driver connector objects.
+ *
+ * At driver unload time the driver's _connector_funcs.destroy hook
+ * should call drm_connector_unregister(), drm_connector_cleanup() and
+ * kfree() the connector structure. The connector structure should not
+ * be allocated with devm_kzalloc().
+ *
+ * Note: consider using drmm_connector_init() instead of
+ * drm_connector_init() to let the DRM managed resource infrastructure
+ * take care of cleanup and deallocation.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_init(struct drm_device *dev,
+  struct drm_connector *connector,
+  const struct drm_connector_funcs *funcs,
+  int connector_type)
+{
+   if (WARN_ON(!(funcs && funcs->destroy)))
+   return -EINVAL;
+
+   return __drm_connector_init(dev, connector, funcs, connector_type);
+}
 EXPORT_SYMBOL(drm_connector_init);
 
 /**
@@ -379,6 +395,54 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_connector_init_with_ddc);
 
+static void drm_connector_cleanup_action(struct drm_device *dev,
+void *ptr)
+{
+   struct drm_connector *connector = ptr;
+
+   drm_connector_unregister(connector);
+   drm_connector_cleanup(connector);
+}
+
+/**
+ * drmm_connector_init - Init a preallocated connector
+ * @dev: DRM device
+ * @connector: the connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ *
+ * Initialises a preallocated connector. Connectors should be
+ * subclassed as part of driver connector objects. Cleanup is
+ * automatically handled through registering drm_connector_unregister()
+ * and drm_connector_cleanup() with drm_add_action(). The connector
+ * structure should be allocated with drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_init(struct drm_device *dev,
+   struct drm_connector *connector,
+   const struct drm_connector_funcs *funcs,
+   int connector_type)
+{
+   int ret;
+
+   if (WARN_ON(funcs && funcs->destroy))
+   return -EINVAL;
+
+   ret = __drm_connector_init(dev, connector, funcs, connector_type);
+   if (ret)
+   return ret;
+
+   ret = drmm_add_action_or_reset(dev, drm_connector_cleanup_action,
+  connector);
+   if (ret)
+   return ret;
+
+   return 0;
+}

[PATCH 07/64] drm/connector: Introduce drmm_connector_init_with_ddc

2022-06-10 Thread Maxime Ripard
Let's create a DRM-managed variant of drm_connector_init_with_ddc that will
take care of an action of the connector cleanup.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_connector.c | 72 -
 include/drm/drm_connector.h |  5 +++
 2 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index f150270b519f..f577e5a739f1 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -355,6 +355,30 @@ int drm_connector_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_connector_init);
 
+typedef int (*connector_init_t)(struct drm_device *dev,
+   struct drm_connector *connector,
+   const struct drm_connector_funcs *funcs,
+   int connector_type);
+
+static int __drm_connector_init_with_ddc(struct drm_device *dev,
+struct drm_connector *connector,
+connector_init_t init_func,
+const struct drm_connector_funcs 
*funcs,
+int connector_type,
+struct i2c_adapter *ddc)
+{
+   int ret;
+
+   ret = init_func(dev, connector, funcs, connector_type);
+   if (ret)
+   return ret;
+
+   /* provide ddc symlink in sysfs */
+   connector->ddc = ddc;
+
+   return ret;
+}
+
 /**
  * drm_connector_init_with_ddc - Init a preallocated connector
  * @dev: DRM device
@@ -373,6 +397,10 @@ EXPORT_SYMBOL(drm_connector_init);
  *
  * Ensures that the ddc field of the connector is correctly set.
  *
+ * Note: consider using drmm_connector_init_with_ddc() instead of
+ * drm_connector_init_with_ddc() to let the DRM managed resource
+ * infrastructure take care of cleanup and deallocation.
+ *
  * Returns:
  * Zero on success, error code on failure.
  */
@@ -382,16 +410,9 @@ int drm_connector_init_with_ddc(struct drm_device *dev,
int connector_type,
struct i2c_adapter *ddc)
 {
-   int ret;
-
-   ret = drm_connector_init(dev, connector, funcs, connector_type);
-   if (ret)
-   return ret;
-
-   /* provide ddc symlink in sysfs */
-   connector->ddc = ddc;
-
-   return ret;
+   return __drm_connector_init_with_ddc(dev, connector,
+drm_connector_init,
+funcs, connector_type, ddc);
 }
 EXPORT_SYMBOL(drm_connector_init_with_ddc);
 
@@ -443,6 +464,37 @@ int drmm_connector_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drmm_connector_init);
 
+/**
+ * drmm_connector_init_with_ddc - Init a preallocated connector
+ * @dev: DRM device
+ * @connector: the connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ * @ddc: pointer to the associated ddc adapter
+ *
+ * Initialises a preallocated connector. Connectors should be
+ * subclassed as part of driver connector objects. Cleanup is
+ * automatically handled through registering drm_connector_unregister()
+ * and drm_connector_cleanup() with drm_add_action(). The connector
+ * structure should be allocated with drmm_kzalloc().
+ *
+ * Ensures that the ddc field of the connector is correctly set.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_connector_init_with_ddc(struct drm_device *dev,
+struct drm_connector *connector,
+const struct drm_connector_funcs *funcs,
+int connector_type,
+struct i2c_adapter *ddc)
+{
+   return __drm_connector_init_with_ddc(dev, connector,
+drmm_connector_init,
+funcs, connector_type, ddc);
+}
+EXPORT_SYMBOL(drmm_connector_init_with_ddc);
+
 /**
  * drm_connector_attach_edid_property - attach edid property.
  * @connector: the connector
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 35a6b6e944b7..2565541f2c10 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1676,6 +1676,11 @@ int drmm_connector_init(struct drm_device *dev,
struct drm_connector *connector,
const struct drm_connector_funcs *funcs,
int connector_type);
+int drmm_connector_init_with_ddc(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);
 

[PATCH 09/64] drm/simple: Introduce drmm_simple_encoder_init

2022-06-10 Thread Maxime Ripard
The DRM-managed function to register an encoder is
drmm_simple_encoder_alloc() and its variants, which will allocate the
underlying structure and initialisation the encoder.

However, we might want to separate the structure creation and the encoder
initialisation, for example if the structure is shared across multiple DRM
entities, for example an encoder and a connector.

Let's create an helper to only initialise an encoder that would be passed
as an argument.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_simple_kms_helper.c | 46 +++--
 include/drm/drm_simple_kms_helper.h |  3 ++
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c 
b/drivers/gpu/drm/drm_simple_kms_helper.c
index 72989ed1baba..876870dd98e5 100644
--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -58,9 +58,10 @@ static const struct drm_encoder_funcs 
drm_simple_encoder_funcs_cleanup = {
  * stored in the device structure. Free the encoder's memory as part of
  * the device release function.
  *
- * Note: consider using drmm_simple_encoder_alloc() instead of
- * drm_simple_encoder_init() to let the DRM managed resource infrastructure
- * take care of cleanup and deallocation.
+ * Note: consider using drmm_simple_encoder_alloc() or
+ * drmm_simple_encoder_init() instead of drm_simple_encoder_init() to
+ * let the DRM managed resource infrastructure take care of cleanup and
+ * deallocation.
  *
  * Returns:
  * Zero on success, error code on failure.
@@ -75,6 +76,45 @@ int drm_simple_encoder_init(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_simple_encoder_init);
 
+static void drmm_simple_encoder_cleanup(struct drm_device *dev, void *ptr)
+{
+   struct drm_encoder *encoder = ptr;
+
+   drm_encoder_cleanup(encoder);
+}
+
+/**
+ * drmm_simple_encoder_init - Initialize a preallocated encoder with
+ *basic functionality.
+ * @dev: drm device
+ * @encoder: the encoder to initialize
+ * @encoder_type: user visible type of the encoder
+ *
+ * Initialises a preallocated encoder that has no further functionality.
+ * Settings for possible CRTC and clones are left to their initial
+ * values. The encoder will be cleaned up automatically using a
+ * DRM-managed action.
+ *
+ * The structure containing the encoder's memory should be allocated
+ * using drmm_kzalloc().
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_simple_encoder_init(struct drm_device *dev,
+struct drm_encoder *encoder,
+int encoder_type)
+{
+   int ret;
+
+   ret = drm_encoder_init(dev, encoder, NULL, encoder_type, NULL);
+   if (ret)
+   return ret;
+
+   return drmm_add_action_or_reset(dev, drmm_simple_encoder_cleanup, 
encoder);
+}
+EXPORT_SYMBOL(drmm_simple_encoder_init);
+
 void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size,
  size_t offset, int encoder_type)
 {
diff --git a/include/drm/drm_simple_kms_helper.h 
b/include/drm/drm_simple_kms_helper.h
index 0b3647e614dd..20456f4712f0 100644
--- a/include/drm/drm_simple_kms_helper.h
+++ b/include/drm/drm_simple_kms_helper.h
@@ -241,6 +241,9 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
 int drm_simple_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder,
int encoder_type);
+int drmm_simple_encoder_init(struct drm_device *dev,
+struct drm_encoder *encoder,
+int encoder_type);
 
 void *__drmm_simple_encoder_alloc(struct drm_device *dev, size_t size,
  size_t offset, int encoder_type);
-- 
2.36.1



[PATCH 19/64] drm/vc4: crtc: Switch to DRM-managed CRTC initialization

2022-06-10 Thread Maxime Ripard
The current code will call drm_crtc_cleanup() when the device is
unbound. However, by then, there might still be some references held to
that CRTC, including by the userspace that might still have the DRM
device open.

Let's switch to a DRM-managed initialization to clean up after ourselves
only once the DRM device has been last closed.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c | 18 +++---
 drivers/gpu/drm/vc4/vc4_drv.h  |  1 -
 drivers/gpu/drm/vc4/vc4_txp.c  |  1 -
 3 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index c74fa3d07561..24de4706b61a 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -205,11 +205,6 @@ static bool vc4_crtc_get_scanout_position(struct drm_crtc 
*crtc,
return ret;
 }
 
-void vc4_crtc_destroy(struct drm_crtc *crtc)
-{
-   drm_crtc_cleanup(crtc);
-}
-
 static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format)
 {
const struct vc4_crtc_data *crtc_data = 
vc4_crtc_to_vc4_crtc_data(vc4_crtc);
@@ -953,7 +948,6 @@ void vc4_crtc_reset(struct drm_crtc *crtc)
 
 static const struct drm_crtc_funcs vc4_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
-   .destroy = vc4_crtc_destroy,
.page_flip = vc4_page_flip,
.set_property = NULL,
.cursor_set = NULL, /* handled by drm_mode_cursor_universal */
@@ -1131,6 +1125,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc 
*vc4_crtc,
struct drm_crtc *crtc = _crtc->base;
struct drm_plane *primary_plane;
unsigned int i;
+   int ret;
 
/* For now, we create just the primary and the legacy cursor
 * planes.  We should be able to stack more planes on easily,
@@ -1144,10 +1139,13 @@ int vc4_crtc_init(struct drm_device *drm, struct 
vc4_crtc *vc4_crtc,
return PTR_ERR(primary_plane);
}
 
-   spin_lock_init(_crtc->irq_lock);
-   drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
- crtc_funcs, NULL);
+   ret = drmm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
+crtc_funcs, NULL);
+   if (ret)
+   return ret;
+
drm_crtc_helper_add(crtc, crtc_helper_funcs);
+   spin_lock_init(_crtc->irq_lock);
 
if (!vc4->hvs->hvs5) {
drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
@@ -1226,8 +1224,6 @@ static void vc4_crtc_unbind(struct device *dev, struct 
device *master,
struct platform_device *pdev = to_platform_device(dev);
struct vc4_crtc *vc4_crtc = dev_get_drvdata(dev);
 
-   vc4_crtc_destroy(_crtc->base);
-
CRTC_WRITE(PV_INTEN, 0);
 
platform_set_drvdata(pdev, NULL);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 9a53ace85d95..fff3772be2d4 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -845,7 +845,6 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc);
 int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc,
  const struct drm_crtc_funcs *crtc_funcs,
  const struct drm_crtc_helper_funcs *crtc_helper_funcs);
-void vc4_crtc_destroy(struct drm_crtc *crtc);
 int vc4_page_flip(struct drm_crtc *crtc,
  struct drm_framebuffer *fb,
  struct drm_pending_vblank_event *event,
diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index e983ff7c5e13..f306e05ac5b2 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -383,7 +383,6 @@ static void vc4_txp_disable_vblank(struct drm_crtc *crtc) {}
 
 static const struct drm_crtc_funcs vc4_txp_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
-   .destroy= vc4_crtc_destroy,
.page_flip  = vc4_page_flip,
.reset  = vc4_crtc_reset,
.atomic_duplicate_state = vc4_crtc_duplicate_state,
-- 
2.36.1



[PATCH 28/64] drm/vc4: dpi: Protect device resources

2022-06-10 Thread Maxime Ripard
Our current code now mixes some resources whose lifetime are tied to the
device (clocks, IO mappings, etc.) and some that are tied to the DRM device
(encoder, bridge).

The device one will be freed at unbind time, but the DRM one will only be
freed when the last user of the DRM device closes its file handle.

So we end up with a time window during which we can call the encoder hooks,
but we don't have access to the underlying resources and device.

Let's protect all those sections with drm_dev_enter() and drm_dev_exit() so
that we bail out if we are during that window.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 9950761449cf..ea3d20651f43 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -13,6 +13,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -111,9 +112,16 @@ static const struct debugfs_reg32 dpi_regs[] = {
 
 static void vc4_dpi_encoder_disable(struct drm_encoder *encoder)
 {
+   struct drm_device *dev = encoder->dev;
struct vc4_dpi *dpi = to_vc4_dpi(encoder);
+   int idx;
+
+   if (!drm_dev_enter(dev, ))
+   return;
 
clk_disable_unprepare(dpi->pixel_clock);
+
+   drm_dev_exit(idx);
 }
 
 static void vc4_dpi_encoder_enable(struct drm_encoder *encoder)
@@ -124,6 +132,7 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
*encoder)
struct drm_connector_list_iter conn_iter;
struct drm_connector *connector = NULL, *connector_scan;
u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE;
+   int idx;
int ret;
 
/* Look up the connector attached to DPI so we can get the
@@ -184,6 +193,9 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
*encoder)
else if (!(mode->flags & DRM_MODE_FLAG_PVSYNC))
dpi_c |= DPI_VSYNC_DISABLE;
 
+   if (!drm_dev_enter(dev, ))
+   return;
+
DPI_WRITE(DPI_C, dpi_c);
 
ret = clk_set_rate(dpi->pixel_clock, mode->clock * 1000);
@@ -193,6 +205,8 @@ static void vc4_dpi_encoder_enable(struct drm_encoder 
*encoder)
ret = clk_prepare_enable(dpi->pixel_clock);
if (ret)
DRM_ERROR("Failed to set clock rate: %d\n", ret);
+
+   drm_dev_exit(idx);
 }
 
 static enum drm_mode_status vc4_dpi_encoder_mode_valid(struct drm_encoder 
*encoder,
-- 
2.36.1



[PATCH 26/64] drm/vc4: dpi: Switch to DRM-managed encoder initialization

2022-06-10 Thread Maxime Ripard
The current code will call drm_encoder_cleanup() when the device is
unbound. However, by then, there might still be some references held to
that encoder, including by the userspace that might still have the DRM
device open.

Let's switch to a DRM-managed initialization to clean up after ourselves
only once the DRM device has been last closed.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dpi.c | 20 +---
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c
index 4e24dbad77f2..8a50de2c40d9 100644
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
@@ -296,35 +296,25 @@ static int vc4_dpi_bind(struct device *dev, struct device 
*master, void *data)
if (ret)
return ret;
 
-   drm_simple_encoder_init(drm, >encoder.base, DRM_MODE_ENCODER_DPI);
+   ret = drmm_simple_encoder_init(drm, >encoder.base, 
DRM_MODE_ENCODER_DPI);
+   if (ret)
+   return ret;
+
drm_encoder_helper_add(>encoder.base, 
_dpi_encoder_helper_funcs);
 
ret = vc4_dpi_init_bridge(dpi);
if (ret)
-   goto err_destroy_encoder;
+   return ret;
 
dev_set_drvdata(dev, dpi);
 
vc4_debugfs_add_regset32(drm, "dpi_regs", >regset);
 
return 0;
-
-err_destroy_encoder:
-   drm_encoder_cleanup(>encoder.base);
-   return ret;
-}
-
-static void vc4_dpi_unbind(struct device *dev, struct device *master,
-  void *data)
-{
-   struct vc4_dpi *dpi = dev_get_drvdata(dev);
-
-   drm_encoder_cleanup(>encoder.base);
 }
 
 static const struct component_ops vc4_dpi_ops = {
.bind   = vc4_dpi_bind,
-   .unbind = vc4_dpi_unbind,
 };
 
 static int vc4_dpi_dev_probe(struct platform_device *pdev)
-- 
2.36.1



[PATCH 08/64] drm/writeback: Introduce drmm_writeback_connector_init

2022-06-10 Thread Maxime Ripard
Let's create a DRM-managed variant of drmm_writeback_connector_init that
will take care of an action of the encoder and connector cleanup.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_writeback.c | 136 
 include/drm/drm_writeback.h |   5 ++
 2 files changed, 108 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c
index dccf4504f1bb..0b00921f3379 100644
--- a/drivers/gpu/drm/drm_writeback.c
+++ b/drivers/gpu/drm/drm_writeback.c
@@ -149,32 +149,27 @@ static const struct drm_encoder_funcs 
drm_writeback_encoder_funcs = {
.destroy = drm_encoder_cleanup,
 };
 
-/**
- * drm_writeback_connector_init - Initialize a writeback connector and its 
properties
- * @dev: DRM device
- * @wb_connector: Writeback connector to initialize
- * @con_funcs: Connector funcs vtable
- * @enc_helper_funcs: Encoder helper funcs vtable to be used by the internal 
encoder
- * @formats: Array of supported pixel formats for the writeback engine
- * @n_formats: Length of the formats array
- *
- * This function creates the writeback-connector-specific properties if they
- * have not been already created, initializes the connector as
- * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property
- * values. It will also create an internal encoder associated with the
- * drm_writeback_connector and set it to use the @enc_helper_funcs vtable for
- * the encoder helper.
- *
- * Drivers should always use this function instead of drm_connector_init() to
- * set up writeback connectors.
- *
- * Returns: 0 on success, or a negative error code
- */
-int drm_writeback_connector_init(struct drm_device *dev,
-struct drm_writeback_connector *wb_connector,
-const struct drm_connector_funcs *con_funcs,
-const struct drm_encoder_helper_funcs 
*enc_helper_funcs,
-const u32 *formats, int n_formats)
+typedef int (*encoder_init_t)(struct drm_device *dev,
+ struct drm_encoder *encoder,
+ const struct drm_encoder_funcs *funcs,
+ int encoder_type,
+ const char *name, ...);
+
+typedef int (*connector_init_t)(struct drm_device *dev,
+   struct drm_connector *connector,
+   const struct drm_connector_funcs *funcs,
+   int connector_type);
+
+static int writeback_init(struct drm_device *dev,
+ struct drm_writeback_connector *wb_connector,
+ connector_init_t conn_init,
+ void (*conn_destroy)(struct drm_connector *connector),
+ encoder_init_t enc_init,
+ void (*enc_destroy)(struct drm_encoder *encoder),
+ const struct drm_connector_funcs *con_funcs,
+ const struct drm_encoder_funcs *enc_funcs,
+ const struct drm_encoder_helper_funcs 
*enc_helper_funcs,
+ const u32 *formats, int n_formats)
 {
struct drm_property_blob *blob;
struct drm_connector *connector = _connector->base;
@@ -190,16 +185,16 @@ int drm_writeback_connector_init(struct drm_device *dev,
return PTR_ERR(blob);
 
drm_encoder_helper_add(_connector->encoder, enc_helper_funcs);
-   ret = drm_encoder_init(dev, _connector->encoder,
-  _writeback_encoder_funcs,
-  DRM_MODE_ENCODER_VIRTUAL, NULL);
+   ret = enc_init(dev, _connector->encoder,
+  enc_funcs,
+  DRM_MODE_ENCODER_VIRTUAL, NULL);
if (ret)
goto fail;
 
connector->interlace_allowed = 0;
 
-   ret = drm_connector_init(dev, connector, con_funcs,
-DRM_MODE_CONNECTOR_WRITEBACK);
+   ret = conn_init(dev, connector, con_funcs,
+   DRM_MODE_CONNECTOR_WRITEBACK);
if (ret)
goto connector_fail;
 
@@ -231,15 +226,90 @@ int drm_writeback_connector_init(struct drm_device *dev,
return 0;
 
 attach_fail:
-   drm_connector_cleanup(connector);
+   if (conn_destroy)
+   conn_destroy(connector);
 connector_fail:
-   drm_encoder_cleanup(_connector->encoder);
+   if (enc_destroy)
+   enc_destroy(_connector->encoder);
 fail:
drm_property_blob_put(blob);
return ret;
 }
+
+/**
+ * drm_writeback_connector_init - Initialize a writeback connector and its 
properties
+ * @dev: DRM device
+ * @wb_connector: Writeback connector to initialize
+ * @con_funcs: Connector funcs vtable
+ * @enc_helper_funcs: Encoder helper funcs vtable to be used by the internal 
encoder
+ * @formats: Array of supported pixel 

[PATCH 11/64] drm/bridge: panel: Introduce drmm_of_get_bridge

2022-06-10 Thread Maxime Ripard
Unlike what can be found for other DRM entities, we don't have a
DRM-managed function equivalent to devm_drm_of_get_bridge().

Let's create it.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/bridge/panel.c | 35 ++
 include/drm/drm_bridge.h   |  2 ++
 2 files changed, 37 insertions(+)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 07d720aa38c6..0bf824ca1f25 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -425,4 +425,39 @@ struct drm_bridge *devm_drm_of_get_bridge(struct device 
*dev,
return bridge;
 }
 EXPORT_SYMBOL(devm_drm_of_get_bridge);
+
+/**
+ * drmm_of_get_bridge - Return next bridge in the chain
+ * @dev: device to tie the bridge lifetime to
+ * @np: device tree node containing encoder output ports
+ * @port: port in the device tree node
+ * @endpoint: endpoint in the device tree node
+ *
+ * Given a DT node's port and endpoint number, finds the connected node
+ * and returns the associated bridge if any, or creates and returns a
+ * drm panel bridge instance if a panel is connected.
+ *
+ * Returns a pointer to the bridge if successful, or an error pointer
+ * otherwise.
+ */
+struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm,
+ struct device_node *np,
+ u32 port, u32 endpoint)
+{
+   struct drm_bridge *bridge;
+   struct drm_panel *panel;
+   int ret;
+
+   ret = drm_of_find_panel_or_bridge(np, port, endpoint,
+ , );
+   if (ret)
+   return ERR_PTR(ret);
+
+   if (panel)
+   bridge = drmm_panel_bridge_add(drm, panel);
+
+   return bridge;
+}
+EXPORT_SYMBOL(drmm_of_get_bridge);
+
 #endif
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 8100a15dd9c2..ddb92e745b2e 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -935,6 +935,8 @@ struct drm_connector *drm_panel_bridge_connector(struct 
drm_bridge *bridge);
 #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL_BRIDGE)
 struct drm_bridge *devm_drm_of_get_bridge(struct device *dev, struct 
device_node *node,
  u32 port, u32 endpoint);
+struct drm_bridge *drmm_of_get_bridge(struct drm_device *drm, struct 
device_node *node,
+ u32 port, u32 endpoint);
 #else
 static inline struct drm_bridge *devm_drm_of_get_bridge(struct device *dev,
struct device_node 
*node,
-- 
2.36.1



[PATCH 33/64] drm/vc4: dsi: Switch to devm_pm_runtime_enable

2022-06-10 Thread Maxime Ripard
devm_pm_runtime_enable() simplifies the driver a bit since it will call
pm_runtime_disable() automatically through a device-managed action.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dsi.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index 282537f27b8e..741db2dce8ab 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -1622,6 +1622,10 @@ static int vc4_dsi_bind(struct device *dev, struct 
device *master, void *data)
 
drm_encoder_helper_add(encoder, _dsi_encoder_helper_funcs);
 
+   ret = devm_pm_runtime_enable(dev);
+   if (ret)
+   return ret;
+
ret = drm_bridge_attach(encoder, dsi->bridge, NULL, 0);
if (ret)
return ret;
@@ -1634,8 +1638,6 @@ static int vc4_dsi_bind(struct device *dev, struct device 
*master, void *data)
 
vc4_debugfs_add_regset32(drm, dsi->variant->debugfs_name, >regset);
 
-   pm_runtime_enable(dev);
-
return 0;
 }
 
@@ -1645,8 +1647,6 @@ static void vc4_dsi_unbind(struct device *dev, struct 
device *master,
struct vc4_dsi *dsi = dev_get_drvdata(dev);
struct drm_encoder *encoder = >encoder.base;
 
-   pm_runtime_disable(dev);
-
/*
 * Restore the bridge_chain so the bridge detach procedure can happen
 * normally.
-- 
2.36.1



[PATCH 31/64] drm/vc4: dsi: Switch to drmm_of_get_bridge

2022-06-10 Thread Maxime Ripard
The current code uses a device-managed function to retrieve the next bridge
downstream.

However, that means that it will be removed at unbind time, where the DRM
device is still very much live and might still have some applications that
still have it open.

Switch to a DRM-managed variant to clean everything up once the DRM device
has been last closed.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_dsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c
index bcaf87b43cbd..10533a2a41b3 100644
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
@@ -1584,7 +1584,7 @@ static int vc4_dsi_bind(struct device *dev, struct device 
*master, void *data)
return ret;
}
 
-   dsi->bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
+   dsi->bridge = drmm_of_get_bridge(drm, dev->of_node, 0, 0);
if (IS_ERR(dsi->bridge))
return PTR_ERR(dsi->bridge);
 
-- 
2.36.1



[PATCH 16/64] drm/vc4: plane: Switch to drmm_universal_plane_alloc()

2022-06-10 Thread Maxime Ripard
Let's switch to drmm_universal_plane_alloc() for our plane allocation and
initialisation to make the driver a bit simpler.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_crtc.c  | 12 +---
 drivers/gpu/drm/vc4/vc4_plane.c | 23 ---
 2 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 840a93484bb1..7163f924b48b 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -1176,7 +1176,6 @@ static int vc4_crtc_bind(struct device *dev, struct 
device *master, void *data)
const struct vc4_pv_data *pv_data;
struct vc4_crtc *vc4_crtc;
struct drm_crtc *crtc;
-   struct drm_plane *destroy_plane, *temp;
int ret;
 
vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
@@ -1211,7 +1210,7 @@ static int vc4_crtc_bind(struct device *dev, struct 
device *master, void *data)
   IRQF_SHARED,
   "vc4 crtc", vc4_crtc);
if (ret)
-   goto err_destroy_planes;
+   return ret;
 
platform_set_drvdata(pdev, vc4_crtc);
 
@@ -1219,15 +1218,6 @@ static int vc4_crtc_bind(struct device *dev, struct 
device *master, void *data)
 _crtc->regset);
 
return 0;
-
-err_destroy_planes:
-   list_for_each_entry_safe(destroy_plane, temp,
->mode_config.plane_list, head) {
-   if (destroy_plane->possible_crtcs == drm_crtc_mask(crtc))
-   destroy_plane->funcs->destroy(destroy_plane);
-   }
-
-   return ret;
 }
 
 static void vc4_crtc_unbind(struct device *dev, struct device *master,
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 17dab470ecdf..673c963f5c5a 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -1442,8 +1442,6 @@ static bool vc4_format_mod_supported(struct drm_plane 
*plane,
 static const struct drm_plane_funcs vc4_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
-   .destroy = drm_plane_cleanup,
-   .set_property = NULL,
.reset = vc4_plane_reset,
.atomic_duplicate_state = vc4_plane_duplicate_state,
.atomic_destroy_state = vc4_plane_destroy_state,
@@ -1454,11 +1452,10 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
 enum drm_plane_type type,
 unsigned int possible_crtcs)
 {
-   struct drm_plane *plane = NULL;
+   struct drm_plane *plane;
struct vc4_plane *vc4_plane;
u32 formats[ARRAY_SIZE(hvs_formats)];
int num_formats = 0;
-   int ret = 0;
unsigned i;
bool hvs5 = of_device_is_compatible(dev->dev->of_node,
"brcm,bcm2711-vc5");
@@ -1471,11 +1468,6 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
DRM_FORMAT_MOD_INVALID
};
 
-   vc4_plane = devm_kzalloc(dev->dev, sizeof(*vc4_plane),
-GFP_KERNEL);
-   if (!vc4_plane)
-   return ERR_PTR(-ENOMEM);
-
for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
if (!hvs_formats[i].hvs5_only || hvs5) {
formats[num_formats] = hvs_formats[i].drm;
@@ -1483,13 +1475,14 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
}
}
 
+   vc4_plane = drmm_universal_plane_alloc(dev, struct vc4_plane, base,
+  possible_crtcs,
+  _plane_funcs,
+  formats, num_formats,
+  modifiers, type, NULL);
+   if (IS_ERR(vc4_plane))
+   return ERR_CAST(vc4_plane);
plane = _plane->base;
-   ret = drm_universal_plane_init(dev, plane, possible_crtcs,
-  _plane_funcs,
-  formats, num_formats,
-  modifiers, type, NULL);
-   if (ret)
-   return ERR_PTR(ret);
 
drm_plane_helper_add(plane, _plane_helper_funcs);
 
-- 
2.36.1



Re: [PATCH] fbdev: atmel_lcdfb: Rework backlight status updates

2022-06-10 Thread Daniel Thompson
On Thu, Jun 09, 2022 at 07:45:11PM +0200, Stephen Kitt wrote:
> Hi Sam, Daniel,
>
> On Thu, 9 Jun 2022 19:30:57 +0200, Sam Ravnborg  wrote:
> > thanks for taking care of all these backlight simplifications - this
> > really helps to make the code simpler and more readable.
>
> You’re welcome! I noticed fb_blank was deprecated and near enough unused, and
> started digging...

I saw Sam's comment and kinda wished I'd thought to say that... definitely
good to see these things being tidied up.


Daniel.


Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Daniel Vetter
On Fri, Jun 10, 2022 at 09:15:35AM +, Simon Ser wrote:
> On Friday, June 10th, 2022 at 10:41, Daniel Vetter  wrote:
> 
> > Anything I've missed? Or got completely wrong?
> 
> This plan looks good to me.
> 
> As Pekka mentionned, I'd also like to have a conversation of how far we want 
> to
> push virtualized driver features. I think KMS support is a good feature to 
> have
> to spin up a VM and have all of the basics working. However I don't think it's
> a good idea to try to plumb an ever-growing list of fancy features
> (seamless integration of guest windows into the host, HiDPI, multi-monitor,
> etc) into KMS. You'd just end up re-inventing Wayland or RDP on top of KMS.
> Instead of re-inventing these, just use RDP or waypipe or X11 forwarding
> directly.
> 
> So I think we need to draw a line somewhere, and decide e.g. that virtualized
> cursors are fine to add in KMS, but HiDPI is not.

It's getting a bit far off-topic, but google cros team has an out-of-tree
(at least I think it's not merged yet) wayland-virtio driver for exactly
this use-case. Trying to move towards something like that for fancy
virtualized setups sounds like the better approach indeed, with kms just
as the bare-bones fallback option.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Jonas Ådahl
On Fri, Jun 10, 2022 at 10:49:31AM +0300, Pekka Paalanen wrote:
> On Thu, 9 Jun 2022 19:39:39 +
> Zack Rusin  wrote:
> 
> > On Wed, 2022-06-08 at 10:53 +0300, Pekka Paalanen wrote:
> > > On Tue, 7 Jun 2022 17:50:24 +
> > > Zack Rusin  wrote:
> > >   
> > > > On Tue, 2022-06-07 at 11:07 +0300, Pekka Paalanen wrote:  
> > > > > On Fri, 03 Jun 2022 14:14:59 +
> > > > > Simon Ser  wrote:
> > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > Please, read this thread:
> > > > > > https://lists.freedesktop.org/archives/dri-devel/2020-March/thread.html#259615
> > > > > > 
> > > > > > It has a lot of information about the pitfalls of cursor hotspot and
> > > > > > other things done by VM software.
> > > > > > 
> > > > > > In particular: since the driver will ignore the KMS cursor plane
> > > > > > position set by user-space, I don't think it's okay to just expose
> > > > > > without opt-in from user-space (e.g. with a DRM_CLIENT_CAP).
> > > > > > 
> > > > > > cc wayland-devel and Pekka for user-space feedback.
> > > > > > 
> > > > > > On Thursday, June 2nd, 2022 at 17:42, Zack Rusin  
> > > > > > wrote:
> > > > > > 
> > > > > > > - all userspace code needs to hardcore a list of drivers which 
> > > > > > > require
> > > > > > > hotspots because there's no way to query from drm "does this 
> > > > > > > driver
> > > > > > > require hotspot"  
> > > > > > 
> > > > > > Can you elaborate? I'm not sure I understand what you mean here.
> > > > > > 
> > > > > 
> > > > > Hi Zack and everyone,
> > > > > 
> > > > > I would like to try to reboot this discussion and explain where I come
> > > > > from. Maybe I have misunderstood something.
> > > > 
> > > >  First of all thanks for restarting the discussions. I think Gerd 
> > > > did a good
> > > > job responding to individual points, so let me take a step back and 
> > > > explain the big
> > > > picture here so we can reboot.
> > > >   
> > > > > Which root problems do you want to solve exactly?
> > > > 
> > > > The problem that this patch set is solving is the relatively trivial 
> > > > problem of not
> > > > having a way of setting the hotspot in the atomic kms interface. When we
> > > > (virtualized drivers) are using the native cursor we need to know not 
> > > > only the image  
> > > 
> > > Could you clarify what is "native cursor" here?
> > > I guess it is the host window system pointer's cursor?  
> > 
> > Right, exactly. I'm a little hesitant to call it "host" because it gets 
> > tricky in
> > remote scenarios, where the host is some ESXi server but the local machine 
> > is the
> > one that's actually interacting with the guest. So it's the cursor of the 
> > machine
> > where the guest screen is displayed.
> > 
> > 
> > > > Now, where the disagreements come from is from the fact that all 
> > > > virtualized drivers
> > > > do not implement the atomic KMS cursor plane contract exactly as 
> > > > specified. In
> > > > atomic kms with universal planes the "cursor" plane can be anything so 
> > > > asking for
> > > > hotspot's for something that's not a cursor is a bit silly (but 
> > > > arguably so is
> > > > calling it a cursor plane and then complaining that people expect 
> > > > cursor in it).
> > > > 
> > > > So the argument is that we can't put hotspot data into atomic kms 
> > > > without first
> > > > rewriting all of the virtualized drivers cursor code to fix the 
> > > > underlying contract
> > > > violation that they all commit. That would likely be a lot easier sell 
> > > > if not that
> > > > gnome/kde don't put none cursor stuff in the cursor plane, so all this 
> > > > work is to
> > > > fix breakages that seem to affect 0 of our users (and I completely 
> > > > understand that
> > > > we'd still like all the drivers to be correct and unified in terms of 
> > > > their
> > > > behaviour, I'm just saying it's a hard sell without something that we 
> > > > can point to
> > > > and say "this fixes/improves things for our customers")   
> > > 
> > > What's the cost of making paravirtualized drivers honour the UAPI 
> > > contract?
> > > Can't you do that on the side of implementing these new hotspot
> > > properties, with the little addition to allowing guest userspace to be
> > > explicit about whether it supports commandeering or not?  
> > 
> > I'm reluctant here because "fixing" here seems to be a bit ephemeral as we 
> > move from
> > one solution to the next. I'm happy to write a patch that's adding a
> > DRM_CLIENT_CAP_VIRTUAL_CURSOR_AWARE flag and hiding the cursor plane in 
> > virtualized
> > drivers for clients that advertise DRM_CLIENT_CAP_ATOMIC but not
> > DRM_CLIENT_CAP_VIRTUAL_CURSOR_AWARE, but that doesn't solve Weston on 
> > virtualized
> > drivers.
> 
> Mind, I have not talked about hiding cursor planes. I have talked
> *only* about stopping commandeering cursor planes if guest userspace
> does not indicate it is prepared for commandeering.
> 
> I don't understand how it does not "solve on Weston 

Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Pekka Paalanen
On Fri, 10 Jun 2022 10:41:05 +0200
Daniel Vetter  wrote:

> Hi all,
> 
> Kinda top post because the thread is sprawling and I think we need a
> summary/restart. I think there's at least 3 issues here:
> 
> - lack of hotspot property support, which means compositors can't really
>   support hotspot with atomic. Which isn't entirely true, because you
>   totally can use atomic for the primary planes/crtcs and the legacy
>   cursor ioctls, but I understand that people might find that a bit silly :-)
> 
>   Anyway this problme is solved by the patch set here, and I think results
>   in some nice cleanups to boot.
> 
> - the fact that cursors for virtual drivers are not planes, but really
>   special things. Which just breaks the universal plane kms uapi. That
>   part isn't solved, and I do agree with Simon and Pekka that we really
>   should solve this before we unleash even more compositors onto the
>   atomic paths of virtual drivers.
> 
>   I think the simplest solution for this is:
>   1. add a new DRM_PLANE_TYPE_VIRTUAL_CURSOR, and set that for these
>   special cursor planes on all virtual drivers
>   2. add the new "I understand virtual cursors planes" setparam, filter
>   virtual cursor planes for userspace which doesn't set this (like we do
>   right now if userspace doesn't set the universal plane mode)
>   3. backport the above patches to all stable kernels
>   4. make sure the hotspot property is only set on VIRTUAL_CURSOR planes
>   and nothing else in the rebased patch series
> 
> - third issue: These special virtual display properties arent documented.
>   Aside from hotspot there's also suggested X/Y and maybe other stuff. I
>   have no idea what suggested X/Y does and what userspace should do with
>   it. I think we need a new section for virtualized drivers which:
>   - documents all the properties involved
>   - documents the new cap for enabling virtual cursor planes
>   - documents some of the key flows that compositors should implement for
> best experience
>   - documents how exactly the user experience will degrade if compositors
> pretend it's just a normal kms driver (maybe put that into each of the
> special flows that a compositor ideally supports)
>   - whatever other comments and gaps I've missed, I'm sure
> Simon/Pekka/others will chime in once the patch exists.
> 
> There's a bit of fixing oopsies (virtualized drivers really shouldn't have
> enabled universal planes for their cursors) and debt (all these properties
> predate the push to document stuff so we need to fix that), but I don't
> think it's too much. And I think, from reading the threads, that this
> should cover everything?
> 
> Anything I've missed? Or got completely wrong?

Hi,

sounds like a good plan to me.


Thanks,
pq


pgpOdwESYywAY.pgp
Description: OpenPGP digital signature


Re: [PATCH 2/3] drm/i915: Update i915 uapi documentation

2022-06-10 Thread Matthew Auld

On 10/06/2022 08:07, Niranjana Vishwanathapura wrote:

Add some missing i915 upai documentation which the new
i915 VM_BIND feature documentation will be refer to.

Signed-off-by: Niranjana Vishwanathapura 

Reviewed-by: Matthew Auld 

This one looks to be standalone. If no objections should we go ahead and 
merge this one?



---
  include/uapi/drm/i915_drm.h | 203 
  1 file changed, 158 insertions(+), 45 deletions(-)

diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index de49b68b4fc8..9cf3bf47c7f2 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -751,14 +751,27 @@ typedef struct drm_i915_irq_wait {
  
  /* Must be kept compact -- no holes and well documented */
  
-typedef struct drm_i915_getparam {

+/**
+ * struct drm_i915_getparam - Driver parameter query structure.
+ */
+struct drm_i915_getparam {
+   /** @param: Driver parameter to query. */
__s32 param;
-   /*
+
+   /**
+* @value: Address of memory where queried value should be put.
+*
 * WARNING: Using pointers instead of fixed-size u64 means we need to 
write
 * compat32 code. Don't repeat this mistake.
 */
int __user *value;
-} drm_i915_getparam_t;
+};
+
+/**
+ * typedef drm_i915_getparam_t - Driver parameter query structure.
+ * See struct drm_i915_getparam.
+ */
+typedef struct drm_i915_getparam drm_i915_getparam_t;
  
  /* Ioctl to set kernel params:

   */
@@ -1239,76 +1252,119 @@ struct drm_i915_gem_exec_object2 {
__u64 rsvd2;
  };
  
+/**

+ * struct drm_i915_gem_exec_fence - An input or output fence for the execbuf
+ * ioctl.
+ *
+ * The request will wait for input fence to signal before submission.
+ *
+ * The returned output fence will be signaled after the completion of the
+ * request.
+ */
  struct drm_i915_gem_exec_fence {
-   /**
-* User's handle for a drm_syncobj to wait on or signal.
-*/
+   /** @handle: User's handle for a drm_syncobj to wait on or signal. */
__u32 handle;
  
+	/**

+* @flags: Supported flags are:
+*
+* I915_EXEC_FENCE_WAIT:
+* Wait for the input fence before request submission.
+*
+* I915_EXEC_FENCE_SIGNAL:
+* Return request completion fence as output
+*/
+   __u32 flags;
  #define I915_EXEC_FENCE_WAIT(1<<0)
  #define I915_EXEC_FENCE_SIGNAL  (1<<1)
  #define __I915_EXEC_FENCE_UNKNOWN_FLAGS (-(I915_EXEC_FENCE_SIGNAL << 1))
-   __u32 flags;
  };
  
-/*

- * See drm_i915_gem_execbuffer_ext_timeline_fences.
- */
-#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
-
-/*
+/**
+ * struct drm_i915_gem_execbuffer_ext_timeline_fences - Timeline fences
+ * for execbuf ioctl.
+ *
   * This structure describes an array of drm_syncobj and associated points for
   * timeline variants of drm_syncobj. It is invalid to append this structure to
   * the execbuf if I915_EXEC_FENCE_ARRAY is set.
   */
  struct drm_i915_gem_execbuffer_ext_timeline_fences {
+#define DRM_I915_GEM_EXECBUFFER_EXT_TIMELINE_FENCES 0
+   /** @base: Extension link. See struct i915_user_extension. */
struct i915_user_extension base;
  
  	/**

-* Number of element in the handles_ptr & value_ptr arrays.
+* @fence_count: Number of elements in the @handles_ptr & @value_ptr
+* arrays.
 */
__u64 fence_count;
  
  	/**

-* Pointer to an array of struct drm_i915_gem_exec_fence of length
-* fence_count.
+* @handles_ptr: Pointer to an array of struct drm_i915_gem_exec_fence
+* of length @fence_count.
 */
__u64 handles_ptr;
  
  	/**

-* Pointer to an array of u64 values of length fence_count. Values
-* must be 0 for a binary drm_syncobj. A Value of 0 for a timeline
-* drm_syncobj is invalid as it turns a drm_syncobj into a binary one.
+* @values_ptr: Pointer to an array of u64 values of length
+* @fence_count.
+* Values must be 0 for a binary drm_syncobj. A Value of 0 for a
+* timeline drm_syncobj is invalid as it turns a drm_syncobj into a
+* binary one.
 */
__u64 values_ptr;
  };
  
+/**

+ * struct drm_i915_gem_execbuffer2 - Structure for DRM_I915_GEM_EXECBUFFER2
+ * ioctl.
+ */
  struct drm_i915_gem_execbuffer2 {
-   /**
-* List of gem_exec_object2 structs
-*/
+   /** @buffers_ptr: Pointer to a list of gem_exec_object2 structs */
__u64 buffers_ptr;
+
+   /** @buffer_count: Number of elements in @buffers_ptr array */
__u32 buffer_count;
  
-	/** Offset in the batchbuffer to start execution from. */

+   /**
+* @batch_start_offset: Offset in the batchbuffer to start execution
+* from.
+*/
__u32 batch_start_offset;
-   /** Bytes used in batchbuffer from batch_start_offset */
+
+   /**
+* @batch_len: Length in 

Re: [PATCH] dt-bindings: display: arm,malidp: remove bogus RQOS property

2022-06-10 Thread Liviu Dudau
On Thu, Jun 09, 2022 at 05:27:29PM +0100, Andre Przywara wrote:
> As Liviu pointed out, the arm,malidp-arqos-high-level property
> mentioned in the original .txt binding was a mistake, and
> arm,malidp-arqos-value needs to take its place.
> 
> The binding commit ce6eb0253cba ("dt/bindings: display: Add optional
> property node define for Mali DP500") mentions the right name in the
> commit message, but has the wrong name in the diff.
> Commit d298e6a27a81 ("drm/arm/mali-dp: Add display QoS interface
> configuration for Mali DP500") uses the property in the driver, but uses
> the shorter name.
> 
> Remove the wrong property from the binding, and use the proper name in
> the example. The actual property was already documented properly.
> 
> Fixes: 2c8b082a3ab1 ("dt-bindings: display: convert Arm Mali-DP to DT schema")
> Link: 
> https://lore.kernel.org/linux-arm-kernel/ynumgeilublhb...@e110455-lin.cambridge.arm.com/
> Signed-off-by: Andre Przywara 
> Reported-by: Liviu Dudau 

Reviewed-by: Liviu Dudau 

Thanks for cleaning this up!

Best regards,
Liviu

> ---
>  Documentation/devicetree/bindings/display/arm,malidp.yaml | 7 +--
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/arm,malidp.yaml 
> b/Documentation/devicetree/bindings/display/arm,malidp.yaml
> index 795a08ac9f128..2a17ec6fc97c0 100644
> --- a/Documentation/devicetree/bindings/display/arm,malidp.yaml
> +++ b/Documentation/devicetree/bindings/display/arm,malidp.yaml
> @@ -71,11 +71,6 @@ properties:
>- description: number of output lines for the green channel (G)
>- description: number of output lines for the blue channel (B)
>  
> -  arm,malidp-arqos-high-level:
> -$ref: /schemas/types.yaml#/definitions/uint32
> -description:
> -  integer describing the ARQoS levels of DP500's QoS signaling
> -
>arm,malidp-arqos-value:
>  $ref: /schemas/types.yaml#/definitions/uint32
>  description:
> @@ -113,7 +108,7 @@ examples:
>  clocks = <>, <>, <>, <>;
>  clock-names = "pxlclk", "mclk", "aclk", "pclk";
>  arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
> -arm,malidp-arqos-high-level = <0xd000d000>;
> +arm,malidp-arqos-value = <0xd000d000>;
>  
>  port {
>  dp0_output: endpoint {
> -- 
> 2.25.1
> 

-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯


Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Gerd Hoffmann
  Hi,

> > As Pekka mentionned, I'd also like to have a conversation of how far we 
> > want to
> > push virtualized driver features. I think KMS support is a good feature to 
> > have
> > to spin up a VM and have all of the basics working. However I don't think 
> > it's
> > a good idea to try to plumb an ever-growing list of fancy features
> > (seamless integration of guest windows into the host, HiDPI, multi-monitor,
> > etc) into KMS. You'd just end up re-inventing Wayland or RDP on top of KMS.
> > Instead of re-inventing these, just use RDP or waypipe or X11 forwarding
> > directly.

> > So I think we need to draw a line somewhere, and decide e.g. that 
> > virtualized
> > cursors are fine to add in KMS, but HiDPI is not.

What is the problem with HiDPI?  qemu generates standard edid blobs,
there should be no need to special-case virtualized drivers in any way.

What is the problem with multi-monitor?  That isn't much different than
physical multi-monitor either.

One little thing though:  On physical hardware you just don't know which
monitor is left and which is right until the user tells you.  In case of
a virtual multi-monitor setup we know how the two windows for the two
virtual monitors are arranged on the host and can pass that as hint to
the guest (not sure whenever *that* is the purpose of the
suggested_{x,y} properties).

> It's getting a bit far off-topic, but google cros team has an out-of-tree
> (at least I think it's not merged yet) wayland-virtio driver for exactly
> this use-case. Trying to move towards something like that for fancy
> virtualized setups sounds like the better approach indeed, with kms just
> as the bare-bones fallback option.

virtio-gpu got the ability to attach uuids to objects, to allow them
being identified on the host side.  So it could be that wayland-virtio
still uses kms for framebuffers (disclaimer: don't know how
wayland-virtio works in detail).  But, yes, all the scanout + cursor
handling would be out of the way, virtio-gpu would "only" handle fast
buffer sharing.

take care,
  Gerd



Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Pekka Paalanen
On Thu, 9 Jun 2022 19:39:39 +
Zack Rusin  wrote:

> On Wed, 2022-06-08 at 10:53 +0300, Pekka Paalanen wrote:
> > On Tue, 7 Jun 2022 17:50:24 +
> > Zack Rusin  wrote:
> >   
> > > On Tue, 2022-06-07 at 11:07 +0300, Pekka Paalanen wrote:  
> > > > On Fri, 03 Jun 2022 14:14:59 +
> > > > Simon Ser  wrote:
> > > > 
> > > > > Hi,
> > > > > 
> > > > > Please, read this thread:
> > > > > https://lists.freedesktop.org/archives/dri-devel/2020-March/thread.html#259615
> > > > > 
> > > > > It has a lot of information about the pitfalls of cursor hotspot and
> > > > > other things done by VM software.
> > > > > 
> > > > > In particular: since the driver will ignore the KMS cursor plane
> > > > > position set by user-space, I don't think it's okay to just expose
> > > > > without opt-in from user-space (e.g. with a DRM_CLIENT_CAP).
> > > > > 
> > > > > cc wayland-devel and Pekka for user-space feedback.
> > > > > 
> > > > > On Thursday, June 2nd, 2022 at 17:42, Zack Rusin  wrote:
> > > > > 
> > > > > > - all userspace code needs to hardcore a list of drivers which 
> > > > > > require
> > > > > > hotspots because there's no way to query from drm "does this driver
> > > > > > require hotspot"  
> > > > > 
> > > > > Can you elaborate? I'm not sure I understand what you mean here.
> > > > > 
> > > > 
> > > > Hi Zack and everyone,
> > > > 
> > > > I would like to try to reboot this discussion and explain where I come
> > > > from. Maybe I have misunderstood something.
> > > 
> > >  First of all thanks for restarting the discussions. I think Gerd 
> > > did a good
> > > job responding to individual points, so let me take a step back and 
> > > explain the big
> > > picture here so we can reboot.
> > >   
> > > > Which root problems do you want to solve exactly?
> > > 
> > > The problem that this patch set is solving is the relatively trivial 
> > > problem of not
> > > having a way of setting the hotspot in the atomic kms interface. When we
> > > (virtualized drivers) are using the native cursor we need to know not 
> > > only the image  
> > 
> > Could you clarify what is "native cursor" here?
> > I guess it is the host window system pointer's cursor?  
> 
> Right, exactly. I'm a little hesitant to call it "host" because it gets 
> tricky in
> remote scenarios, where the host is some ESXi server but the local machine is 
> the
> one that's actually interacting with the guest. So it's the cursor of the 
> machine
> where the guest screen is displayed.
> 
> 
> > > Now, where the disagreements come from is from the fact that all 
> > > virtualized drivers
> > > do not implement the atomic KMS cursor plane contract exactly as 
> > > specified. In
> > > atomic kms with universal planes the "cursor" plane can be anything so 
> > > asking for
> > > hotspot's for something that's not a cursor is a bit silly (but arguably 
> > > so is
> > > calling it a cursor plane and then complaining that people expect cursor 
> > > in it).
> > > 
> > > So the argument is that we can't put hotspot data into atomic kms without 
> > > first
> > > rewriting all of the virtualized drivers cursor code to fix the 
> > > underlying contract
> > > violation that they all commit. That would likely be a lot easier sell if 
> > > not that
> > > gnome/kde don't put none cursor stuff in the cursor plane, so all this 
> > > work is to
> > > fix breakages that seem to affect 0 of our users (and I completely 
> > > understand that
> > > we'd still like all the drivers to be correct and unified in terms of 
> > > their
> > > behaviour, I'm just saying it's a hard sell without something that we can 
> > > point to
> > > and say "this fixes/improves things for our customers")   
> > 
> > What's the cost of making paravirtualized drivers honour the UAPI contract?
> > Can't you do that on the side of implementing these new hotspot
> > properties, with the little addition to allowing guest userspace to be
> > explicit about whether it supports commandeering or not?  
> 
> I'm reluctant here because "fixing" here seems to be a bit ephemeral as we 
> move from
> one solution to the next. I'm happy to write a patch that's adding a
> DRM_CLIENT_CAP_VIRTUAL_CURSOR_AWARE flag and hiding the cursor plane in 
> virtualized
> drivers for clients that advertise DRM_CLIENT_CAP_ATOMIC but not
> DRM_CLIENT_CAP_VIRTUAL_CURSOR_AWARE, but that doesn't solve Weston on 
> virtualized
> drivers.

Mind, I have not talked about hiding cursor planes. I have talked
*only* about stopping commandeering cursor planes if guest userspace
does not indicate it is prepared for commandeering.

I don't understand how it does not "solve on Weston on virtualized
drivers". Can you explain what is not solved?

As far as I can see, it does solve Weston: it makes cursor plane
behaviour correct from KMS UAPI contract point of view. Anything that
is not quite optimal after that with cursor planes you can blame on
Weston not making use of additional optional features.


Re: [PATCH v2 03/11] clk: fixed-factor: Introduce *clk_hw_register_fixed_factor_parent_hw()

2022-06-10 Thread Marijn Suijten
On 2022-06-09 15:12:09, Stephen Boyd wrote:
> Quoting Dmitry Baryshkov (2022-06-02 03:20:19)
> > On Thu, 2 Jun 2022 at 01:07, Marijn Suijten
> >  wrote:
> > > diff --git a/drivers/clk/clk-fixed-factor.c 
> > > b/drivers/clk/clk-fixed-factor.c
> > > index 54942d758ee6..fabb98d0cdb2 100644
> > > --- a/drivers/clk/clk-fixed-factor.c
> > > +++ b/drivers/clk/clk-fixed-factor.c
> > > @@ -78,7 +78,8 @@ static void 
> > > devm_clk_hw_register_fixed_factor_release(struct device *dev, void *
> > >
> > >  static struct clk_hw *
> > >  __clk_hw_register_fixed_factor(struct device *dev, struct device_node 
> > > *np,
> > > -   const char *name, const char *parent_name, int index,
> > > +   const char *name, const char *parent_name,
> > > +   const struct clk_hw *parent_hw, int index,
> > > unsigned long flags, unsigned int mult, unsigned int div,
> > > bool devm)
> > >  {
> > > @@ -108,7 +109,9 @@ __clk_hw_register_fixed_factor(struct device *dev, 
> > > struct device_node *np,
> > > init.name = name;
> > > init.ops = _fixed_factor_ops;
> > > init.flags = flags;
> > > -   if (parent_name)
> > > +   if (parent_hw)
> > > +   init.parent_hws = _hw;
> > > +   else if (parent_name)
> > > init.parent_names = _name;
> > 
> > If you change the order of if clauses, you won't have to introduce
> > unnecessary changes.
> 
> Indeed, please do that.

The intent here was to prefer parent_hw over parent_name, but I later
reordered the function arguments again to have parent_name before
parent_hw; in-line with __clk_hw_register_divider.  Hence makes more
sense to swap these around indeed.

Besides, we don't expect more than one of these to be set anyway per
design of this private function, that is only called by well-defined
implementations below.

> > 
> > > else
> > > init.parent_data = 
> > > @@ -148,17 +151,50 @@ struct clk_hw 
> > > *devm_clk_hw_register_fixed_factor_index(struct device *dev,
> > > const char *name, unsigned int index, unsigned long flags,
> > > unsigned int mult, unsigned int div)
> > >  {
> > > -   return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, 
> > > index,
> > > - flags, mult, div, true);
> > > +   return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, NULL,
> > > + index, flags, mult, div, 
> > > true);
> > 
> > Here (and several times later) you are inserting an argument and then
> > moving arguments to the next line. My slight preference would be to
> > just insert the arg (and maybe break the line if it gets too long) w/o
> > touching the next lines.

That'll definitely look odd, as we'll end up with index floating on a
single line, all on its own.

> I'd just add the argument at the end because when it is added in the
> middle it makes the diff more difficult to read.

How strong is this feeling, against keeping argument ordering consistent
with other implementations of similar __clk_hw_register_* functions?

- Marijn


Re: [Intel-gfx] [RFC v3 1/3] drm/doc/rfc: VM_BIND feature design document

2022-06-10 Thread Lionel Landwerlin

On 10/06/2022 10:54, Niranjana Vishwanathapura wrote:

On Fri, Jun 10, 2022 at 09:53:24AM +0300, Lionel Landwerlin wrote:

On 09/06/2022 22:31, Niranjana Vishwanathapura wrote:

On Thu, Jun 09, 2022 at 05:49:09PM +0300, Lionel Landwerlin wrote:

  On 09/06/2022 00:55, Jason Ekstrand wrote:

    On Wed, Jun 8, 2022 at 4:44 PM Niranjana Vishwanathapura
     wrote:

  On Wed, Jun 08, 2022 at 08:33:25AM +0100, Tvrtko Ursulin wrote:
  >
  >
  >On 07/06/2022 22:32, Niranjana Vishwanathapura wrote:
  >>On Tue, Jun 07, 2022 at 11:18:11AM -0700, Niranjana 
Vishwanathapura

  wrote:
  >>>On Tue, Jun 07, 2022 at 12:12:03PM -0500, Jason Ekstrand 
wrote:

   On Fri, Jun 3, 2022 at 6:52 PM Niranjana Vishwanathapura
    wrote:
  
     On Fri, Jun 03, 2022 at 10:20:25AM +0300, Lionel 
Landwerlin

  wrote:
     >   On 02/06/2022 23:35, Jason Ekstrand wrote:
     >
     > On Thu, Jun 2, 2022 at 3:11 PM Niranjana 
Vishwanathapura

     >  wrote:
     >
     >   On Wed, Jun 01, 2022 at 01:28:36PM -0700, Matthew
  Brost wrote:
     >   >On Wed, Jun 01, 2022 at 05:25:49PM +0300, Lionel
  Landwerlin
     wrote:
     >   >> On 17/05/2022 21:32, Niranjana Vishwanathapura
  wrote:
     >   >> > +VM_BIND/UNBIND ioctl will immediately start
     binding/unbinding
     >   the mapping in an
     >   >> > +async worker. The binding and unbinding 
will

  work like a
     special
     >   GPU engine.
     >   >> > +The binding and unbinding operations are
  serialized and
     will
     >   wait on specified
     >   >> > +input fences before the operation and 
will signal

  the
     output
     >   fences upon the
     >   >> > +completion of the operation. Due to
  serialization,
     completion of
     >   an operation
     >   >> > +will also indicate that all previous 
operations

  are also
     >   complete.
     >   >>
     >   >> I guess we should avoid saying "will 
immediately

  start
     >   binding/unbinding" if
     >   >> there are fences involved.
     >   >>
     >   >> And the fact that it's happening in an async
  worker seem to
     imply
     >   it's not
     >   >> immediate.
     >   >>
     >
     >   Ok, will fix.
     >   This was added because in earlier design 
binding was

  deferred
     until
     >   next execbuff.
     >   But now it is non-deferred (immediate in that 
sense).

  But yah,
     this is
     >   confusing
     >   and will fix it.
     >
     >   >>
     >   >> I have a question on the behavior of the bind
  operation when
     no
     >   input fence
     >   >> is provided. Let say I do :
     >   >>
     >   >> VM_BIND (out_fence=fence1)
     >   >>
     >   >> VM_BIND (out_fence=fence2)
     >   >>
     >   >> VM_BIND (out_fence=fence3)
     >   >>
     >   >>
     >   >> In what order are the fences going to be 
signaled?

     >   >>
     >   >> In the order of VM_BIND ioctls? Or out of 
order?

     >   >>
     >   >> Because you wrote "serialized I assume it's 
: in

  order
     >   >>
     >
     >   Yes, in the order of VM_BIND/UNBIND ioctls. 
Note that

  bind and
     unbind
     >   will use
     >   the same queue and hence are ordered.
     >
     >   >>
     >   >> One thing I didn't realize is that because 
we only

  get one
     >   "VM_BIND" engine,
     >   >> there is a disconnect from the Vulkan 
specification.

     >   >>
     >   >> In Vulkan VM_BIND operations are serialized 
but

  per engine.
     >   >>
     >   >> So you could have something like this :
     >   >>
     >   >> VM_BIND (engine=rcs0, in_fence=fence1,
  out_fence=fence2)
     >   >>
     >   >> VM_BIND (engine=ccs0, in_fence=fence3,
  out_fence=fence4)
     >   >>
     >   >>
     >   >> fence1 is not signaled
     >   >>
     >   >> fence3 is signaled
     >   >>
     >   >> So the second VM_BIND will proceed before the
  

Re: [PATCH RESEND] drm: adv7511: override i2c address of cec before accessing it

2022-06-10 Thread Robert Foss
On Tue, 7 Jun 2022 at 23:32, Antonio Borneo  wrote:
>
> Commit 680532c50bca ("drm: adv7511: Add support for
> i2c_new_secondary_device") allows a device tree node to override
> the default addresses of the secondary i2c devices. This is useful
> for solving address conflicts on the i2c bus.
>
> In adv7511_init_cec_regmap() the new i2c address of cec device is
> read from device tree and immediately accessed, well before it is
> written in the proper register to override the default address.
> This can cause an i2c error during probe and a consequent probe
> failure.
>
> Once the new i2c address is read from the device tree, override
> the default address before any attempt to access the cec.
>
> Tested with adv7533 and stm32mp157f.
>
> Signed-off-by: Antonio Borneo 
> Fixes: 680532c50bca ("drm: adv7511: Add support for i2c_new_secondary_device")
> Reviewed-by: Kieran Bingham 
>
> ---
>
> This patch got somehow lost, I'm resending it.
> Added reviewed by Kieran Bingham.
> Rebased on drm-misc-next.
>
> ---
>  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
> b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> index 5bb9300040dd..074c2e650cae 100644
> --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
> @@ -1065,6 +1065,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
> ADV7511_CEC_I2C_ADDR_DEFAULT);
> if (IS_ERR(adv->i2c_cec))
> return PTR_ERR(adv->i2c_cec);
> +
> +   regmap_write(adv->regmap, ADV7511_REG_CEC_I2C_ADDR,
> +adv->i2c_cec->addr << 1);
> +
> i2c_set_clientdata(adv->i2c_cec, adv);
>
> adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,
> @@ -1271,9 +1275,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
> struct i2c_device_id *id)
> if (ret)
> goto err_i2c_unregister_packet;
>
> -   regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
> -adv7511->i2c_cec->addr << 1);
> -
> INIT_WORK(>hpd_work, adv7511_hpd_work);
>
> if (i2c->irq) {
>
> base-commit: dfa687bffc8a4a21ed929c7dececf01b8f1f52ee
> --
> 2.36.1
>

Applied to drm-misc-next.


[PATCH] Revert "fbdev: vesafb: Allow to be built if COMPILE_TEST is enabled"

2022-06-10 Thread Javier Martinez Canillas
This reverts commit fa0e256450f27a7d85f65c63f05e6897954a1d53. The kernel
test robot reported that attempting to build the vesafb driver fails on
some architectures, because these don't define a `struct screen_info`.

This leads to linking errors, for example on parisc with allyesconfig:

  hppa-linux-ld: drivers/video/fbdev/vesafb.o: in function `vesafb_probe':
>> (.text+0x738): undefined reference to `screen_info'
>> hppa-linux-ld: (.text+0x73c): undefined reference to `screen_info'
   hppa-linux-ld: drivers/firmware/sysfb.o: in function `sysfb_init':
>> (.init.text+0x28): undefined reference to `screen_info'
>> hppa-linux-ld: (.init.text+0x30): undefined reference to `screen_info'
   hppa-linux-ld: (.init.text+0x78): undefined reference to `screen_info'

The goal of commit fa0e256450f2 ("fbdev: vesafb: Allow to be built if
COMPILE_TEST is enabled") was to have more build coverage for the driver
but it wrongly assumed that all architectures would define a screen_info.

Reported-by: kernel test robot 
Signed-off-by: Javier Martinez Canillas 
---

 drivers/video/fbdev/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index bd849013f16f..f2a6b81e45c4 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -616,7 +616,7 @@ config FB_UVESA
 
 config FB_VESA
bool "VESA VGA graphics support"
-   depends on (FB = y) && (X86 || COMPILE_TEST)
+   depends on (FB = y) && X86
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
-- 
2.36.1



Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Simon Ser
On Friday, June 10th, 2022 at 10:41, Daniel Vetter  wrote:

> Anything I've missed? Or got completely wrong?

This plan looks good to me.

As Pekka mentionned, I'd also like to have a conversation of how far we want to
push virtualized driver features. I think KMS support is a good feature to have
to spin up a VM and have all of the basics working. However I don't think it's
a good idea to try to plumb an ever-growing list of fancy features
(seamless integration of guest windows into the host, HiDPI, multi-monitor,
etc) into KMS. You'd just end up re-inventing Wayland or RDP on top of KMS.
Instead of re-inventing these, just use RDP or waypipe or X11 forwarding
directly.

So I think we need to draw a line somewhere, and decide e.g. that virtualized
cursors are fine to add in KMS, but HiDPI is not.


[PATCH 00/64] drm/vc4: Fix hotplug for vc4

2022-06-10 Thread Maxime Ripard
Hi,

Here is a series that address multiple issues when trying to unbind/rebind
vc4-related devices to their drivers.

Most of these issues involve either use-after-free, improper resource
liberation or similar.

It has been tested on the Pi3 and Pi4, with X and glxgears running and KASAN
enabled to properly validate our memory accesses.

Pi3 isn't functional after a rebind though, with vblank timeouts occuring. I'm
not quite sure why at this point, but at least the kernel doesn't completely
crash now.

Let me know what you think,
Maxime

Maxime Ripard (64):
  drm/mipi-dsi: Detach devices when removing the host
  drm/crtc: Introduce drmm_crtc_init_with_planes
  drm/encoder: Introduce drmm_encoder_init
  drm/connector: Reorder headers
  drm/connector: Mention the cleanup after drm_connector_init
  drm/connector: Introduce drmm_connector_init
  drm/connector: Introduce drmm_connector_init_with_ddc
  drm/writeback: Introduce drmm_writeback_connector_init
  drm/simple: Introduce drmm_simple_encoder_init
  drm/bridge: panel: Introduce drmm_panel_bridge_add
  drm/bridge: panel: Introduce drmm_of_get_bridge
  drm/vc4: Call component_unbind_all()
  drm/vc4: hvs: Protect device resources after removal
  drm/vc4: hvs: Remove planes currently allocated before taking down
  drm/vc4: plane: Take possible_crtcs as an argument
  drm/vc4: plane: Switch to drmm_universal_plane_alloc()
  drm/vc4: crtc: Move debugfs_name to crtc_data
  drm/vc4: crtc: Switch to drmm_kzalloc
  drm/vc4: crtc: Switch to DRM-managed CRTC initialization
  drm/vc4: dpi: Remove vc4_dev dpi pointer
  drm/vc4: dpi: Embed DRM structures into the private structure
  drm/vc4: dpi: Switch to drmm_kzalloc
  drm/vc4: dpi: Return an error if we can't enable our clock
  drm/vc4: dpi: Remove unnecessary drm_of_panel_bridge_remove call
  drm/vc4: dpi: Add action to disable the clock
  drm/vc4: dpi: Switch to DRM-managed encoder initialization
  drm/vc4: dpi: Switch to drmm_of_get_bridge
  drm/vc4: dpi: Protect device resources
  drm/vc4: dsi: Embed DRM structures into the private structure
  drm/vc4: dsi: Switch to DRM-managed encoder initialization
  drm/vc4: dsi: Switch to drmm_of_get_bridge
  drm/vc4: dsi: Fix the driver structure lifetime
  drm/vc4: dsi: Switch to devm_pm_runtime_enable
  drm/vc4: hdmi: Switch to drmm_kzalloc
  drm/vc4: hdmi: Switch to DRM-managed encoder initialization
  drm/vc4: hdmi: Switch to DRM-managed connector initialization
  drm/vc4: hdmi: Switch to device-managed ALSA initialization
  drm/vc4: hdmi: Switch to device-managed CEC initialization
  drm/vc4: hdmi: Use a device-managed action for DDC
  drm/vc4: hdmi: Switch to DRM-managed kfree to build regsets
  drm/vc4: hdmi: Use devm to register hotplug interrupts
  drm/vc4: hdmi: Move audio structure offset checks
  drm/vc4: hdmi: Protect device resources after removal
  drm/vc4: hdmi: Switch to devm_pm_runtime_enable
  drm/vc4: txp: Remove vc4_dev txp pointer
  drm/vc4: txp: Remove duplicate regset
  drm/vc4: txp: Switch to drmm_kzalloc
  drm/vc4: txp: Switch to DRM-managed writeback initialization
  drm/vc4: txp: Protect device resources
  drm/vc4: vec: Remove vc4_dev vec pointer
  drm/vc4: vec: Embed DRM structures into the private structure
  drm/vc4: vec: Switch to drmm_kzalloc
  drm/vc4: vec: Switch to DRM-managed encoder initialization
  drm/vc4: vec: Switch to DRM-managed connector initialization
  drm/vc4: vec: Protect device resources after removal
  drm/vc4: vec: Switch to devm_pm_runtime_enable
  drm/vc4: debugfs: Protect device resources
  drm/vc4: debugfs: Return an error on failure
  drm/vc4: debugfs: Simplify debugfs registration
  drm/vc4: Switch to drmm_mutex_init
  drm/vc4: perfmon: Add missing mutex_destroy
  drm/vc4: v3d: Stop disabling interrupts
  drm/vc4: v3d: Rework the runtime_pm setup
  drm/vc4: v3d: Switch to devm_pm_runtime_enable

 drivers/gpu/drm/bridge/panel.c  |  74 +++
 drivers/gpu/drm/drm_connector.c | 186 +--
 drivers/gpu/drm/drm_crtc.c  |  70 ++-
 drivers/gpu/drm/drm_encoder.c   |  48 +-
 drivers/gpu/drm/drm_mipi_dsi.c  |   1 +
 drivers/gpu/drm/drm_simple_kms_helper.c |  46 +-
 drivers/gpu/drm/drm_writeback.c | 136 +++--
 drivers/gpu/drm/vc4/vc4_bo.c|  33 +-
 drivers/gpu/drm/vc4/vc4_crtc.c  |  69 ++-
 drivers/gpu/drm/vc4/vc4_debugfs.c   |  71 ++-
 drivers/gpu/drm/vc4/vc4_dpi.c   | 131 ++---
 drivers/gpu/drm/vc4/vc4_drv.c   |  18 +-
 drivers/gpu/drm/vc4/vc4_drv.h   |  47 +-
 drivers/gpu/drm/vc4/vc4_dsi.c   | 120 +++--
 drivers/gpu/drm/vc4/vc4_gem.c   |  10 +-
 drivers/gpu/drm/vc4/vc4_hdmi.c  | 637 +---
 drivers/gpu/drm/vc4/vc4_hdmi.h  |   3 +-
 drivers/gpu/drm/vc4/vc4_hvs.c   | 145 +-
 drivers/gpu/drm/vc4/vc4_irq.c   |   2 +-
 drivers/gpu/drm/vc4/vc4_perfmon.c   |   1 +
 drivers/gpu/drm/vc4/vc4_plane.c |  36 +-
 drivers/gpu/drm/vc4/vc4_txp.c   |  69 +--

[PATCH 02/64] drm/crtc: Introduce drmm_crtc_init_with_planes

2022-06-10 Thread Maxime Ripard
The DRM-managed function to register a CRTC is
drmm_crtc_alloc_with_planes(), which will allocate the underlying
structure and initialisation the CRTC.

However, we might want to separate the structure creation and the CRTC
initialisation, for example if the structure is shared across multiple
DRM entities, for example an encoder and a connector.

Let's create an helper to only initialise a CRTC that would be passed as
an argument.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_crtc.c | 70 --
 include/drm/drm_crtc.h |  6 
 2 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 26a77a735905..fd986a7dd4ad 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -341,9 +341,10 @@ static int __drm_crtc_init_with_planes(struct drm_device 
*dev, struct drm_crtc *
  * The @primary and @cursor planes are only relevant for legacy uAPI, see
  * _crtc.primary and _crtc.cursor.
  *
- * Note: consider using drmm_crtc_alloc_with_planes() instead of
- * drm_crtc_init_with_planes() to let the DRM managed resource infrastructure
- * take care of cleanup and deallocation.
+ * Note: consider using drmm_crtc_alloc_with_planes() or
+ * drmm_crtc_init_with_planes() instead of drm_crtc_init_with_planes()
+ * to let the DRM managed resource infrastructure take care of cleanup
+ * and deallocation.
  *
  * Returns:
  * Zero on success, error code on failure.
@@ -368,6 +369,69 @@ int drm_crtc_init_with_planes(struct drm_device *dev, 
struct drm_crtc *crtc,
 }
 EXPORT_SYMBOL(drm_crtc_init_with_planes);
 
+static void drmm_crtc_init_with_planes_cleanup(struct drm_device *dev,
+  void *ptr)
+{
+   struct drm_crtc *crtc = ptr;
+
+   drm_crtc_cleanup(crtc);
+}
+
+/**
+ * drmm_crtc_init_with_planes - Initialise a new CRTC object with
+ *specified primary and cursor planes.
+ * @dev: DRM device
+ * @crtc: CRTC object to init
+ * @primary: Primary plane for CRTC
+ * @cursor: Cursor plane for CRTC
+ * @funcs: callbacks for the new CRTC
+ * @name: printf style format string for the CRTC name, or NULL for default 
name
+ *
+ * Inits a new object created as base part of a driver crtc object. Drivers
+ * should use this function instead of drm_crtc_init(), which is only provided
+ * for backwards compatibility with drivers which do not yet support universal
+ * planes). For really simple hardware which has only 1 plane look at
+ * drm_simple_display_pipe_init() instead.
+ *
+ * Cleanup is automatically handled through registering
+ * drmm_crtc_cleanup() with drmm_add_action(). The crtc structure should
+ * be allocated with drmm_kzalloc().
+ *
+ * The @drm_crtc_funcs.destroy hook must be NULL.
+ *
+ * The @primary and @cursor planes are only relevant for legacy uAPI, see
+ * _crtc.primary and _crtc.cursor.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
+  struct drm_plane *primary,
+  struct drm_plane *cursor,
+  const struct drm_crtc_funcs *funcs,
+  const char *name, ...)
+{
+   va_list ap;
+   int ret;
+
+   WARN_ON(funcs && funcs->destroy);
+
+   va_start(ap, name);
+   ret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,
+ name, ap);
+   va_end(ap);
+   if (ret)
+   return ret;
+
+   ret = drmm_add_action_or_reset(dev, drmm_crtc_init_with_planes_cleanup,
+  crtc);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drmm_crtc_init_with_planes);
+
 static void drmm_crtc_alloc_with_planes_cleanup(struct drm_device *dev,
void *ptr)
 {
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index a70baea0636c..2babd5cffbf3 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -1229,6 +1229,12 @@ int drm_crtc_init_with_planes(struct drm_device *dev,
  struct drm_plane *cursor,
  const struct drm_crtc_funcs *funcs,
  const char *name, ...);
+int drmm_crtc_init_with_planes(struct drm_device *dev,
+  struct drm_crtc *crtc,
+  struct drm_plane *primary,
+  struct drm_plane *cursor,
+  const struct drm_crtc_funcs *funcs,
+  const char *name, ...);
 void drm_crtc_cleanup(struct drm_crtc *crtc);
 
 __printf(7, 8)
-- 
2.36.1



[PATCH 04/64] drm/connector: Reorder headers

2022-06-10 Thread Maxime Ripard
Unlike most of the other files in DRM, and Linux in general, the headers in
drm_connector.c aren't sorted alphabetically. Let's fix that.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_connector.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 1c48d162c77e..353d83ae09d3 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -22,14 +22,14 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
+#include 
 #include 
 #include 
+#include 
 
 #include 
 
-- 
2.36.1



[PATCH 05/64] drm/connector: Mention the cleanup after drm_connector_init

2022-06-10 Thread Maxime Ripard
Unlike encoders and CRTCs, the drm_connector_init() and
drm_connector_init_with_ddc() don't mention how the cleanup is supposed to
be done. Let's add it.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_connector.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 353d83ae09d3..2a78a23836d8 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -222,6 +222,11 @@ void drm_connector_free_work_fn(struct work_struct *work)
  * Initialises a preallocated connector. Connectors should be
  * subclassed as part of driver connector objects.
  *
+ * At driver unload time the driver's _connector_funcs.destroy hook
+ * should call drm_connector_unregister(), drm_connector_cleanup() and
+ * kfree() the connector structure. The connector structure should not
+ * be allocated with devm_kzalloc().
+ *
  * Returns:
  * Zero on success, error code on failure.
  */
@@ -345,6 +350,11 @@ EXPORT_SYMBOL(drm_connector_init);
  * Initialises a preallocated connector. Connectors should be
  * subclassed as part of driver connector objects.
  *
+ * At driver unload time the driver's _connector_funcs.destroy hook
+ * should call drm_connector_unregister(), drm_connector_cleanup() and
+ * kfree() the connector structure. The connector structure should not
+ * be allocated with devm_kzalloc().
+ *
  * Ensures that the ddc field of the connector is correctly set.
  *
  * Returns:
-- 
2.36.1



[PATCH 01/64] drm/mipi-dsi: Detach devices when removing the host

2022-06-10 Thread Maxime Ripard
Whenever the MIPI-DSI host is unregistered, the code of
mipi_dsi_host_unregister() loops over every device currently found on that
bus and will unregister it.

However, it doesn't detach it from the bus first, which leads to all kind
of resource leaks if the host wants to perform some clean up whenever a
device is detached.

Fixes: 068a00233969 ("drm: Add MIPI DSI bus support")
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_mipi_dsi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index c40bde96cfdf..c317ee9fa445 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -346,6 +346,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, 
void *priv)
 {
struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
 
+   mipi_dsi_detach(dsi);
mipi_dsi_device_unregister(dsi);
 
return 0;
-- 
2.36.1



[PATCH 03/64] drm/encoder: Introduce drmm_encoder_init

2022-06-10 Thread Maxime Ripard
The DRM-managed function to register an encoder is
drmm_encoder_alloc() and its variants, which will allocate the underlying
structure and initialisation the encoder.

However, we might want to separate the structure creation and the encoder
initialisation, for example if the structure is shared across multiple DRM
entities, for example an encoder and a connector.

Let's create an helper to only initialise an encoder that would be passed
as an argument.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_encoder.c | 48 ---
 include/drm/drm_encoder.h |  5 
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_encoder.c b/drivers/gpu/drm/drm_encoder.c
index a940024c8087..4b7b82f8c6fa 100644
--- a/drivers/gpu/drm/drm_encoder.c
+++ b/drivers/gpu/drm/drm_encoder.c
@@ -148,9 +148,9 @@ static int __drm_encoder_init(struct drm_device *dev,
  * the encoder structure. The encoder structure should not be allocated with
  * devm_kzalloc().
  *
- * Note: consider using drmm_encoder_alloc() instead of drm_encoder_init() to
- * let the DRM managed resource infrastructure take care of cleanup and
- * deallocation.
+ * Note: consider using drmm_encoder_alloc() or drmm_encoder_init()
+ * instead of drm_encoder_init() to let the DRM managed resource
+ * infrastructure take care of cleanup and deallocation.
  *
  * Returns:
  * Zero on success, error code on failure.
@@ -244,6 +244,48 @@ void *__drmm_encoder_alloc(struct drm_device *dev, size_t 
size, size_t offset,
 }
 EXPORT_SYMBOL(__drmm_encoder_alloc);
 
+/**
+ * drmm_encoder_init - Initialize a preallocated encoder
+ * @dev: drm device
+ * @encoder: the encoder to init
+ * @funcs: callbacks for this encoder (optional)
+ * @encoder_type: user visible type of the encoder
+ * @name: printf style format string for the encoder name, or NULL for default 
name
+ *
+ * Initializes a preallocated encoder. Encoder should be subclassed as
+ * part of driver encoder objects. Cleanup is automatically handled
+ * through registering drm_encoder_cleanup() with drmm_add_action(). The
+ * encoder structure should be allocated with drmm_kzalloc().
+ *
+ * The @drm_encoder_funcs.destroy hook must be NULL.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drmm_encoder_init(struct drm_device *dev, struct drm_encoder *encoder,
+ const struct drm_encoder_funcs *funcs,
+ int encoder_type, const char *name, ...)
+{
+   va_list ap;
+   int ret;
+
+   if (WARN_ON(funcs && funcs->destroy))
+   return -EINVAL;
+
+   va_start(ap, name);
+   ret = __drm_encoder_init(dev, encoder, funcs, encoder_type, name, ap);
+   va_end(ap);
+   if (ret)
+   return ret;
+
+   ret = drmm_add_action_or_reset(dev, drmm_encoder_alloc_release, 
encoder);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+EXPORT_SYMBOL(drmm_encoder_init);
+
 static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
 {
struct drm_connector *connector;
diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 6e91a0280f31..6713fe1804e9 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -194,6 +194,11 @@ int drm_encoder_init(struct drm_device *dev,
 const struct drm_encoder_funcs *funcs,
 int encoder_type, const char *name, ...);
 
+int drmm_encoder_init(struct drm_device *dev,
+ struct drm_encoder *encoder,
+ const struct drm_encoder_funcs *funcs,
+ int encoder_type, const char *name, ...);
+
 __printf(6, 7)
 void *__drmm_encoder_alloc(struct drm_device *dev,
   size_t size, size_t offset,
-- 
2.36.1



Re: [Intel-gfx] [RFC v3 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Tvrtko Ursulin



On 09/06/2022 19:53, Niranjana Vishwanathapura wrote:

On Thu, Jun 09, 2022 at 09:36:48AM +0100, Matthew Auld wrote:

On 08/06/2022 22:32, Niranjana Vishwanathapura wrote:

On Wed, Jun 08, 2022 at 10:12:05AM +0100, Matthew Auld wrote:

On 08/06/2022 08:17, Tvrtko Ursulin wrote:


On 07/06/2022 20:37, Niranjana Vishwanathapura wrote:

On Tue, Jun 07, 2022 at 11:27:14AM +0100, Tvrtko Ursulin wrote:


On 17/05/2022 19:32, Niranjana Vishwanathapura wrote:

VM_BIND and related uapi definitions

v2: Ensure proper kernel-doc formatting with cross references.
    Also add new uapi and documentation as per review comments
    from Daniel.

Signed-off-by: Niranjana Vishwanathapura 


---
 Documentation/gpu/rfc/i915_vm_bind.h | 399 
+++

 1 file changed, 399 insertions(+)
 create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h

diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h

new file mode 100644
index ..589c0a009107
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.h
@@ -0,0 +1,399 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/**
+ * DOC: I915_PARAM_HAS_VM_BIND
+ *
+ * VM_BIND feature availability.
+ * See typedef drm_i915_getparam_t param.
+ */
+#define I915_PARAM_HAS_VM_BIND    57
+
+/**
+ * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
+ *
+ * Flag to opt-in for VM_BIND mode of binding during VM creation.
+ * See struct drm_i915_gem_vm_control flags.
+ *
+ * A VM in VM_BIND mode will not support the older execbuff 
mode of binding.
+ * In VM_BIND mode, execbuff ioctl will not accept any execlist 
(ie., the

+ * _i915_gem_execbuffer2.buffer_count must be 0).
+ * Also, _i915_gem_execbuffer2.batch_start_offset and
+ * _i915_gem_execbuffer2.batch_len must be 0.
+ * DRM_I915_GEM_EXECBUFFER_EXT_BATCH_ADDRESSES extension must 
be provided

+ * to pass in the batch buffer addresses.
+ *
+ * Additionally, I915_EXEC_NO_RELOC, I915_EXEC_HANDLE_LUT and
+ * I915_EXEC_BATCH_FIRST of _i915_gem_execbuffer2.flags 
must be 0
+ * (not used) in VM_BIND mode. I915_EXEC_USE_EXTENSIONS flag 
must always be

+ * set (See struct drm_i915_gem_execbuffer_ext_batch_addresses).
+ * The buffers_ptr, buffer_count, batch_start_offset and 
batch_len fields
+ * of struct drm_i915_gem_execbuffer2 are also not used and 
must be 0.

+ */
+#define I915_VM_CREATE_FLAGS_USE_VM_BIND    (1 << 0)
+
+/**
+ * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
+ *
+ * Flag to declare context as long running.
+ * See struct drm_i915_gem_context_create_ext flags.
+ *
+ * Usage of dma-fence expects that they complete in reasonable 
amount of time.
+ * Compute on the other hand can be long running. Hence it is 
not appropriate
+ * for compute contexts to export request completion dma-fence 
to user.
+ * The dma-fence usage will be limited to in-kernel consumption 
only.

+ * Compute contexts need to use user/memory fence.
+ *
+ * So, long running contexts do not support output fences. Hence,
+ * I915_EXEC_FENCE_OUT (See _i915_gem_execbuffer2.flags and
+ * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) 
are expected

+ * to be not used.
+ *
+ * DRM_I915_GEM_WAIT ioctl call is also not supported for 
objects mapped

+ * to long running contexts.
+ */
+#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
+
+/* VM_BIND related ioctls */
+#define DRM_I915_GEM_VM_BIND    0x3d
+#define DRM_I915_GEM_VM_UNBIND    0x3e
+#define DRM_I915_GEM_WAIT_USER_FENCE    0x3f
+
+#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE 
+ DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE 
DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT_USER_FENCE, struct 
drm_i915_gem_wait_user_fence)

+
+/**
+ * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
+ *
+ * This structure is passed to VM_BIND ioctl and specifies the 
mapping of GPU
+ * virtual address (VA) range to the section of an object that 
should be bound

+ * in the device page table of the specified address space (VM).
+ * The VA range specified must be unique (ie., not currently 
bound) and can
+ * be mapped to whole object or a section of the object 
(partial binding).
+ * Multiple VA mappings can be created to the same section of 
the object

+ * (aliasing).
+ */
+struct drm_i915_gem_vm_bind {
+    /** @vm_id: VM (address space) id to bind */
+    __u32 vm_id;
+
+    /** @handle: Object handle */
+    __u32 handle;
+
+    /** @start: Virtual Address start to bind */
+    __u64 start;
+
+    /** @offset: Offset in object to bind */
+    __u64 offset;
+
+    /** @length: Length of mapping to bind */
+    __u64 length;


Does it support, or should it, equivalent of 
EXEC_OBJECT_PAD_TO_SIZE? Or if not userspace is expected to map 
the remainder of the space to a dummy object? In which case would 
there be any 

Re: [Intel-gfx] [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Tvrtko Ursulin



On 10/06/2022 08:07, Niranjana Vishwanathapura wrote:

VM_BIND and related uapi definitions

Signed-off-by: Niranjana Vishwanathapura 
---
  Documentation/gpu/rfc/i915_vm_bind.h | 490 +++
  1 file changed, 490 insertions(+)
  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h

diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
b/Documentation/gpu/rfc/i915_vm_bind.h
new file mode 100644
index ..9fc854969cfb
--- /dev/null
+++ b/Documentation/gpu/rfc/i915_vm_bind.h
@@ -0,0 +1,490 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+/**
+ * DOC: I915_PARAM_HAS_VM_BIND
+ *
+ * VM_BIND feature availability.
+ * See typedef drm_i915_getparam_t param.
+ * bit[0]: If set, VM_BIND is supported, otherwise not.
+ * bits[8-15]: VM_BIND implementation version.
+ * version 0 will not have VM_BIND/UNBIND timeline fence array support.
+ */
+#define I915_PARAM_HAS_VM_BIND 57
+
+/**
+ * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
+ *
+ * Flag to opt-in for VM_BIND mode of binding during VM creation.
+ * See struct drm_i915_gem_vm_control flags.
+ *
+ * The older execbuf2 ioctl will not support VM_BIND mode of operation.
+ * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any
+ * execlist (See struct drm_i915_gem_execbuffer3 for more details).
+ *
+ */
+#define I915_VM_CREATE_FLAGS_USE_VM_BIND   (1 << 0)
+
+/**
+ * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
+ *
+ * Flag to declare context as long running.
+ * See struct drm_i915_gem_context_create_ext flags.
+ *
+ * Usage of dma-fence expects that they complete in reasonable amount of time.
+ * Compute on the other hand can be long running. Hence it is not appropriate
+ * for compute contexts to export request completion dma-fence to user.
+ * The dma-fence usage will be limited to in-kernel consumption only.
+ * Compute contexts need to use user/memory fence.
+ *
+ * So, long running contexts do not support output fences. Hence,
+ * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) is expected
+ * to be not used. DRM_I915_GEM_WAIT ioctl call is also not supported for
+ * objects mapped to long running contexts.
+ */
+#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
+
+/* VM_BIND related ioctls */
+#define DRM_I915_GEM_VM_BIND   0x3d
+#define DRM_I915_GEM_VM_UNBIND 0x3e
+#define DRM_I915_GEM_EXECBUFFER3   0x3f
+#define DRM_I915_GEM_WAIT_USER_FENCE   0x40
+
+#define DRM_IOCTL_I915_GEM_VM_BIND DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_VM_UNBIND   DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER3 DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_EXECBUFFER3, struct drm_i915_gem_execbuffer3)
+#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE DRM_IOWR(DRM_COMMAND_BASE + 
DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
+
+/**
+ * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
+ *
+ * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
+ * virtual address (VA) range to the section of an object that should be bound
+ * in the device page table of the specified address space (VM).
+ * The VA range specified must be unique (ie., not currently bound) and can
+ * be mapped to whole object or a section of the object (partial binding).
+ * Multiple VA mappings can be created to the same section of the object
+ * (aliasing).
+ *
+ * The @queue_idx specifies the queue to use for binding. Same queue can be
+ * used for both VM_BIND and VM_UNBIND calls. All submitted bind and unbind
+ * operations in a queue are performed in the order of submission.
+ *
+ * The @start, @offset and @length should be 4K page aligned. However the DG2
+ * and XEHPSDV has 64K page size for device local-memory and has compact page
+ * table. On those platforms, for binding device local-memory objects, the
+ * @start should be 2M aligned, @offset and @length should be 64K aligned.
+ * Also, on those platforms, it is not allowed to bind an device local-memory
+ * object and a system memory object in a single 2M section of VA range.
+ */
+struct drm_i915_gem_vm_bind {
+   /** @vm_id: VM (address space) id to bind */
+   __u32 vm_id;
+
+   /** @queue_idx: Index of queue for binding */
+   __u32 queue_idx;


I have a question here to which I did not find an answer by browsing the 
old threads.


Queue index appears to be an implicit synchronisation mechanism, right? 
Operations on the same index are executed/complete in order of ioctl 
submission?


Do we _have_ to implement this on the kernel side and could just allow 
in/out fence and let userspace deal with it?


Arbitrary/on-demand number of queues will add the complexity on the 
kernel side which should be avoided if possible.


Regards,

Tvrtko


+
+   /** @rsvd: Reserved, MBZ */
+   __u32 

Re: [PATCH 0/6] drm: Add mouse cursor hotspot support to atomic KMS

2022-06-10 Thread Gerd Hoffmann
  Hi,

> >   4. make sure the hotspot property is only set on VIRTUAL_CURSOR planes
> >   and nothing else in the rebased patch series
> 
> Simon also mentioned on irc that these special planes must not expose the
> CRTC_X/Y property, since that doesn't really do much at all. Or is our
> understanding of how this all works for commandeered cursors wrong?

Depends.  In some cases the pointer position is a one-way host->guest
ticket (via tablet device).  In some cases the other direction works too
and the guest can warp the mouse pointer to another place on the host
display.  The guest can't easily figure whenever warp works or not
because that depends on host-side configuration the guest has no insight
to.

take care,
  Gerd



Re: [PATCH v6 0/6] Raspberry PI 4 V3D enablement

2022-06-10 Thread Javier Martinez Canillas
Hello Melissa,

On 6/10/22 13:05, Melissa Wen wrote:
> On 06/08, Javier Martinez Canillas wrote:

[snip]

> 
> Hi Javier,
> 
> Thanks for waiting a little.
> 
> Stefan guided me to the missing part and I'm okay on this serie.
>

No worries and thanks for the testing.
 
> If there's any r-b missing for drm/v3d, you can add mine:
> Reviewed-by: Melissa Wen 
> 
> But if you prefer that I applied them, just let me know.
> 

If you can apply them that's even better since you are more involved
with this driver. I was just trying to be helpful and that's why I
volunteered to push, to prevent this effort to get stalled :)

-- 
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat



[Bug 210301] *ERROR* IB test failed on gfx (-110) on Ryzen 4750u

2022-06-10 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=210301

ramast (m...@ramast.me) changed:

   What|Removed |Added

 CC||m...@ramast.me

--- Comment #1 from ramast (m...@ramast.me) ---
I had same problem. I found that removing iommu_v2 module from kernel solved
the problem.

-- 
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] dma-buf: Don't use typeof in va_arg

2022-06-10 Thread Christian König

Am 10.06.22 um 09:52 schrieb Jiabing Wan:



On 2022/6/10 15:24, Christian König wrote:

Am 10.06.22 um 09:20 schrieb Wan Jiabing:

Fix following coccicheck warning:
./drivers/dma-buf/st-dma-fence-unwrap.c:75:39-45: ERROR: reference 
preceded by free on line 70


Use 'struct dma_fence *' instead of 'typeof(*fences)' to avoid this
warning and also fix other 'typeof(*fences)' to make them consistent.


Well that doesn't looks correct to me.

*fence should be valid at this point, why does coccicheck things it 
is freed?


*fence is valid. Coccicheck reports this because fence is freed.
But use 'struct dma_fence *' can avoid this wrong report.


Well in this case that's just a clear NAK.

Using typeof(*var) is perfectly valid and preferred should the type 
change at some point.


As far as I can see your cocci script is somehow reporting a false warning.

Regards,
Christian.



I also grep all code and find it's unusual to use 'typeof' in va_arg, 
only two files.


grep -R "va_arg("  . | grep 'typeof'
./drivers/dma-buf/st-dma-fence-unwrap.c:    fences[i] = 
va_arg(valist, typeof(*fences));
./drivers/dma-buf/st-dma-fence-unwrap.c: dma_fence_put(va_arg(valist, 
typeof(*fences)));
./lib/test_scanf.c: typeof(*expect) got = *va_arg(ap, 
typeof(expect));  \


And other files all use declaration name directly.
So I send this patch makes code clearer and fix the wrong warning by 
the way.


Thanks,
Wan Jiabing



Regards,
Christian.



Fixes: 0c5064fa8d5a ("dma-buf: cleanup dma_fence_unwrap selftest v2")
Signed-off-by: Wan Jiabing 
---
  drivers/dma-buf/st-dma-fence-unwrap.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c 
b/drivers/dma-buf/st-dma-fence-unwrap.c

index 4105d5ea8dde..1137a6d90b32 100644
--- a/drivers/dma-buf/st-dma-fence-unwrap.c
+++ b/drivers/dma-buf/st-dma-fence-unwrap.c
@@ -56,7 +56,7 @@ static struct dma_fence *mock_array(unsigned int 
num_fences, ...)

    va_start(valist, num_fences);
  for (i = 0; i < num_fences; ++i)
-    fences[i] = va_arg(valist, typeof(*fences));
+    fences[i] = va_arg(valist, struct dma_fence *);
  va_end(valist);
    array = dma_fence_array_create(num_fences, fences,
@@ -72,7 +72,7 @@ static struct dma_fence *mock_array(unsigned int 
num_fences, ...)

  error_put:
  va_start(valist, num_fences);
  for (i = 0; i < num_fences; ++i)
-    dma_fence_put(va_arg(valist, typeof(*fences)));
+    dma_fence_put(va_arg(valist, struct dma_fence *));
  va_end(valist);
  return NULL;
  }








Re: [PATCH 3/3] drm/doc/rfc: VM_BIND uapi definition

2022-06-10 Thread Matthew Brost
On Fri, Jun 10, 2022 at 12:07:11AM -0700, Niranjana Vishwanathapura wrote:
> VM_BIND and related uapi definitions
> 
> Signed-off-by: Niranjana Vishwanathapura 
> ---
>  Documentation/gpu/rfc/i915_vm_bind.h | 490 +++
>  1 file changed, 490 insertions(+)
>  create mode 100644 Documentation/gpu/rfc/i915_vm_bind.h
> 
> diff --git a/Documentation/gpu/rfc/i915_vm_bind.h 
> b/Documentation/gpu/rfc/i915_vm_bind.h
> new file mode 100644
> index ..9fc854969cfb
> --- /dev/null
> +++ b/Documentation/gpu/rfc/i915_vm_bind.h
> @@ -0,0 +1,490 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2022 Intel Corporation
> + */
> +
> +/**
> + * DOC: I915_PARAM_HAS_VM_BIND
> + *
> + * VM_BIND feature availability.
> + * See typedef drm_i915_getparam_t param.
> + * bit[0]: If set, VM_BIND is supported, otherwise not.
> + * bits[8-15]: VM_BIND implementation version.
> + * version 0 will not have VM_BIND/UNBIND timeline fence array support.
> + */
> +#define I915_PARAM_HAS_VM_BIND   57
> +
> +/**
> + * DOC: I915_VM_CREATE_FLAGS_USE_VM_BIND
> + *
> + * Flag to opt-in for VM_BIND mode of binding during VM creation.
> + * See struct drm_i915_gem_vm_control flags.
> + *
> + * The older execbuf2 ioctl will not support VM_BIND mode of operation.
> + * For VM_BIND mode, we have new execbuf3 ioctl which will not accept any
> + * execlist (See struct drm_i915_gem_execbuffer3 for more details).
> + *
> + */
> +#define I915_VM_CREATE_FLAGS_USE_VM_BIND (1 << 0)
> +
> +/**
> + * DOC: I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING
> + *
> + * Flag to declare context as long running.
> + * See struct drm_i915_gem_context_create_ext flags.
> + *
> + * Usage of dma-fence expects that they complete in reasonable amount of 
> time.
> + * Compute on the other hand can be long running. Hence it is not appropriate
> + * for compute contexts to export request completion dma-fence to user.
> + * The dma-fence usage will be limited to in-kernel consumption only.
> + * Compute contexts need to use user/memory fence.
> + *
> + * So, long running contexts do not support output fences. Hence,
> + * I915_EXEC_FENCE_SIGNAL (See _i915_gem_exec_fence.flags) is expected
> + * to be not used. DRM_I915_GEM_WAIT ioctl call is also not supported for
> + * objects mapped to long running contexts.
> + */
> +#define I915_CONTEXT_CREATE_FLAGS_LONG_RUNNING   (1u << 2)
> +
> +/* VM_BIND related ioctls */
> +#define DRM_I915_GEM_VM_BIND 0x3d
> +#define DRM_I915_GEM_VM_UNBIND   0x3e
> +#define DRM_I915_GEM_EXECBUFFER3 0x3f
> +#define DRM_I915_GEM_WAIT_USER_FENCE 0x40
> +
> +#define DRM_IOCTL_I915_GEM_VM_BIND   DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_I915_GEM_VM_BIND, struct drm_i915_gem_vm_bind)
> +#define DRM_IOCTL_I915_GEM_VM_UNBIND DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_I915_GEM_VM_UNBIND, struct drm_i915_gem_vm_bind)
> +#define DRM_IOCTL_I915_GEM_EXECBUFFER3   
> DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER3, struct 
> drm_i915_gem_execbuffer3)
> +#define DRM_IOCTL_I915_GEM_WAIT_USER_FENCE   DRM_IOWR(DRM_COMMAND_BASE + 
> DRM_I915_GEM_WAIT_USER_FENCE, struct drm_i915_gem_wait_user_fence)
> +
> +/**
> + * struct drm_i915_gem_vm_bind - VA to object mapping to bind.
> + *
> + * This structure is passed to VM_BIND ioctl and specifies the mapping of GPU
> + * virtual address (VA) range to the section of an object that should be 
> bound
> + * in the device page table of the specified address space (VM).
> + * The VA range specified must be unique (ie., not currently bound) and can
> + * be mapped to whole object or a section of the object (partial binding).
> + * Multiple VA mappings can be created to the same section of the object
> + * (aliasing).
> + *
> + * The @queue_idx specifies the queue to use for binding. Same queue can be
> + * used for both VM_BIND and VM_UNBIND calls. All submitted bind and unbind
> + * operations in a queue are performed in the order of submission.
> + *
> + * The @start, @offset and @length should be 4K page aligned. However the DG2
> + * and XEHPSDV has 64K page size for device local-memory and has compact page
> + * table. On those platforms, for binding device local-memory objects, the
> + * @start should be 2M aligned, @offset and @length should be 64K aligned.
> + * Also, on those platforms, it is not allowed to bind an device local-memory
> + * object and a system memory object in a single 2M section of VA range.
> + */
> +struct drm_i915_gem_vm_bind {
> + /** @vm_id: VM (address space) id to bind */
> + __u32 vm_id;
> +
> + /** @queue_idx: Index of queue for binding */
> + __u32 queue_idx;
> +
> + /** @rsvd: Reserved, MBZ */
> + __u32 rsvd;
> +
> + /** @handle: Object handle */
> + __u32 handle;
> +
> + /** @start: Virtual Address start to bind */
> + __u64 start;
> +
> + /** @offset: Offset in object to bind */
> + __u64 offset;
> +
> + /** @length: Length of mapping to bind */

[PATCH 42/64] drm/vc4: hdmi: Move audio structure offset checks

2022-06-10 Thread Maxime Ripard
The HDMI driver unbind hook doesn't have any ALSA-related code anymore, so
let's move the ALSA sanity checks and comments we have to some other part
of the driver dedicated to ALSA.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 40 +-
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index ca0bc8be3e6a..814517c1fdaa 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2041,6 +2041,26 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
int index;
int ret;
 
+   /*
+* ASoC makes it a bit hard to retrieve a pointer to the
+* vc4_hdmi structure. Registering the card will overwrite our
+* device drvdata with a pointer to the snd_soc_card structure,
+* which can then be used to retrieve whatever drvdata we want
+* to associate.
+*
+* However, that doesn't fly in the case where we wouldn't
+* register an ASoC card (because of an old DT that is missing
+* the dmas properties for example), then the card isn't
+* registered and the device drvdata wouldn't be set.
+*
+* We can deal with both cases by making sure a snd_soc_card
+* pointer and a vc4_hdmi structure are pointing to the same
+* memory address, so we can treat them indistinctly without any
+* issue.
+*/
+   BUILD_BUG_ON(offsetof(struct vc4_hdmi_audio, card) != 0);
+   BUILD_BUG_ON(offsetof(struct vc4_hdmi, audio) != 0);
+
if (!of_find_property(dev->of_node, "dmas", NULL)) {
dev_warn(dev,
 "'dmas' DT property is missing, no HDMI audio\n");
@@ -3006,26 +3026,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 static void vc4_hdmi_unbind(struct device *dev, struct device *master,
void *data)
 {
-   /*
-* ASoC makes it a bit hard to retrieve a pointer to the
-* vc4_hdmi structure. Registering the card will overwrite our
-* device drvdata with a pointer to the snd_soc_card structure,
-* which can then be used to retrieve whatever drvdata we want
-* to associate.
-*
-* However, that doesn't fly in the case where we wouldn't
-* register an ASoC card (because of an old DT that is missing
-* the dmas properties for example), then the card isn't
-* registered and the device drvdata wouldn't be set.
-*
-* We can deal with both cases by making sure a snd_soc_card
-* pointer and a vc4_hdmi structure are pointing to the same
-* memory address, so we can treat them indistinctly without any
-* issue.
-*/
-   BUILD_BUG_ON(offsetof(struct vc4_hdmi_audio, card) != 0);
-   BUILD_BUG_ON(offsetof(struct vc4_hdmi, audio) != 0);
-
pm_runtime_disable(dev);
 }
 
-- 
2.36.1



[PATCH 44/64] drm/vc4: hdmi: Switch to devm_pm_runtime_enable

2022-06-10 Thread Maxime Ripard
devm_pm_runtime_enable() simplifies the driver a bit since it will call
pm_runtime_disable() automatically through a device-managed action.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index b4fd581861ea..b31487547070 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -3225,7 +3225,12 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 
pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
-   pm_runtime_enable(dev);
+
+   ret = devm_pm_runtime_enable(dev);
+   if (ret) {
+   vc4_hdmi_runtime_suspend(dev);
+   return ret;
+   }
 
if (vc4_hdmi->variant->reset)
vc4_hdmi->variant->reset(vc4_hdmi);
@@ -3270,20 +3275,12 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 
 err_put_runtime_pm:
pm_runtime_put_sync(dev);
-   pm_runtime_disable(dev);
 
return ret;
 }
 
-static void vc4_hdmi_unbind(struct device *dev, struct device *master,
-   void *data)
-{
-   pm_runtime_disable(dev);
-}
-
 static const struct component_ops vc4_hdmi_ops = {
.bind   = vc4_hdmi_bind,
-   .unbind = vc4_hdmi_unbind,
 };
 
 static int vc4_hdmi_dev_probe(struct platform_device *pdev)
-- 
2.36.1



[PATCH 48/64] drm/vc4: txp: Switch to DRM-managed writeback initialization

2022-06-10 Thread Maxime Ripard
The current code will call drm_connector_unregister() and
drm_connector_cleanup() when the device is unbound. However, by then, there
might still be some references held to that connector, including by the
userspace that might still have the DRM device open.

Let's switch to a DRM-managed initialization to clean up after ourselves
only once the DRM device has been last closed.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_txp.c | 24 
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index 6a16b2798724..3f214b702c47 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -335,16 +335,9 @@ vc4_txp_connector_detect(struct drm_connector *connector, 
bool force)
return connector_status_connected;
 }
 
-static void vc4_txp_connector_destroy(struct drm_connector *connector)
-{
-   drm_connector_unregister(connector);
-   drm_connector_cleanup(connector);
-}
-
 static const struct drm_connector_funcs vc4_txp_connector_funcs = {
.detect = vc4_txp_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
-   .destroy = vc4_txp_connector_destroy,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
@@ -498,10 +491,10 @@ static int vc4_txp_bind(struct device *dev, struct device 
*master, void *data)
 
drm_connector_helper_add(>connector.base,
 _txp_connector_helper_funcs);
-   ret = drm_writeback_connector_init(drm, >connector,
-  _txp_connector_funcs,
-  _txp_encoder_helper_funcs,
-  drm_fmts, ARRAY_SIZE(drm_fmts));
+   ret = drmm_writeback_connector_init(drm, >connector,
+   _txp_connector_funcs,
+   _txp_encoder_helper_funcs,
+   drm_fmts, ARRAY_SIZE(drm_fmts));
if (ret)
return ret;
 
@@ -525,17 +518,8 @@ static int vc4_txp_bind(struct device *dev, struct device 
*master, void *data)
return 0;
 }
 
-static void vc4_txp_unbind(struct device *dev, struct device *master,
-  void *data)
-{
-   struct vc4_txp *txp = dev_get_drvdata(dev);
-
-   vc4_txp_connector_destroy(>connector.base);
-}
-
 static const struct component_ops vc4_txp_ops = {
.bind   = vc4_txp_bind,
-   .unbind = vc4_txp_unbind,
 };
 
 static int vc4_txp_probe(struct platform_device *pdev)
-- 
2.36.1



[PATCH 43/64] drm/vc4: hdmi: Protect device resources after removal

2022-06-10 Thread Maxime Ripard
Whenever the device and driver are unbound, the main device and all the
subdevices will be removed by calling their unbind() method.

However, the DRM device itself will only be freed when the last user will
have closed it.

It means that there is a time window where the device and its resources
aren't there anymore, but the userspace can still call into our driver.

Fortunately, the DRM framework provides the drm_dev_enter() and
drm_dev_exit() functions to make sure our underlying device is still there
for the section protected by those calls. Let's add them to the HDMI driver.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 286 +++--
 1 file changed, 269 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index 814517c1fdaa..b4fd581861ea 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -140,17 +141,33 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void 
*unused)
 {
struct drm_info_node *node = (struct drm_info_node *)m->private;
struct vc4_hdmi *vc4_hdmi = node->info_ent->data;
+   struct drm_device *drm = vc4_hdmi->connector.dev;
struct drm_printer p = drm_seq_file_printer(m);
+   int idx;
+
+   if (!drm_dev_enter(drm, ))
+   return -ENODEV;
 
drm_print_regset32(, _hdmi->hdmi_regset);
drm_print_regset32(, _hdmi->hd_regset);
 
+   drm_dev_exit(idx);
+
return 0;
 }
 
 static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
 {
+   struct drm_device *drm = vc4_hdmi->connector.dev;
unsigned long flags;
+   int idx;
+
+   /*
+* We can be called by our bind callback, when the
+* connector->dev pointer might not be initialised yet.
+*/
+   if (drm && !drm_dev_enter(drm, ))
+   return;
 
spin_lock_irqsave(_hdmi->hw_lock, flags);
 
@@ -167,11 +184,23 @@ static void vc4_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
HDMI_WRITE(HDMI_SW_RESET_CONTROL, 0);
 
spin_unlock_irqrestore(_hdmi->hw_lock, flags);
+
+   if (drm)
+   drm_dev_exit(idx);
 }
 
 static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
 {
+   struct drm_device *drm = vc4_hdmi->connector.dev;
unsigned long flags;
+   int idx;
+
+   /*
+* We can be called by our bind callback, when the
+* connector->dev pointer might not be initialised yet.
+*/
+   if (drm && !drm_dev_enter(drm, ))
+   return;
 
reset_control_reset(vc4_hdmi->reset);
 
@@ -183,15 +212,25 @@ static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
   HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
 
spin_unlock_irqrestore(_hdmi->hw_lock, flags);
+
+   if (drm)
+   drm_dev_exit(idx);
 }
 
 #ifdef CONFIG_DRM_VC4_HDMI_CEC
 static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi)
 {
-   unsigned long cec_rate = clk_get_rate(vc4_hdmi->cec_clock);
+   struct drm_device *drm = vc4_hdmi->connector.dev;
+   unsigned long cec_rate;
unsigned long flags;
u16 clk_cnt;
u32 value;
+   int idx;
+
+   if (!drm_dev_enter(drm, ))
+   return;
+
+   cec_rate = clk_get_rate(vc4_hdmi->cec_clock);
 
spin_lock_irqsave(_hdmi->hw_lock, flags);
 
@@ -207,6 +246,8 @@ static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi 
*vc4_hdmi)
HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
 
spin_unlock_irqrestore(_hdmi->hw_lock, flags);
+
+   drm_dev_exit(idx);
 }
 #else
 static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {}
@@ -427,25 +468,34 @@ static int vc4_hdmi_stop_packet(struct drm_encoder 
*encoder,
bool poll)
 {
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+   struct drm_device *drm = vc4_hdmi->connector.dev;
u32 packet_id = type - 0x80;
unsigned long flags;
+   int ret = 0;
+   int idx;
+
+   if (!drm_dev_enter(drm, ))
+   return -ENODEV;
 
spin_lock_irqsave(_hdmi->hw_lock, flags);
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
   HDMI_READ(HDMI_RAM_PACKET_CONFIG) & ~BIT(packet_id));
spin_unlock_irqrestore(_hdmi->hw_lock, flags);
 
-   if (!poll)
-   return 0;
+   if (poll) {
+   ret = wait_for(!(HDMI_READ(HDMI_RAM_PACKET_STATUS) &
+BIT(packet_id)), 100);
+   }
 
-   return wait_for(!(HDMI_READ(HDMI_RAM_PACKET_STATUS) &
- BIT(packet_id)), 100);
+   drm_dev_exit(idx);
+   return ret;
 }
 
 static void vc4_hdmi_write_infoframe(struct drm_encoder *encoder,
 union hdmi_infoframe *frame)
 {
struct vc4_hdmi *vc4_hdmi = 

[PATCH 46/64] drm/vc4: txp: Remove duplicate regset

2022-06-10 Thread Maxime Ripard
There's already a regset in the vc4_crtc structure so there's no need to
duplicate it in vc4_txp.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_txp.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c
index 87c896f482fb..51ac01838093 100644
--- a/drivers/gpu/drm/vc4/vc4_txp.c
+++ b/drivers/gpu/drm/vc4/vc4_txp.c
@@ -154,7 +154,6 @@ struct vc4_txp {
struct drm_writeback_connector connector;
 
void __iomem *regs;
-   struct debugfs_regset32 regset;
 };
 
 static inline struct vc4_txp *encoder_to_vc4_txp(struct drm_encoder *encoder)
@@ -493,9 +492,9 @@ static int vc4_txp_bind(struct device *dev, struct device 
*master, void *data)
txp->regs = vc4_ioremap_regs(pdev, 0);
if (IS_ERR(txp->regs))
return PTR_ERR(txp->regs);
-   txp->regset.base = txp->regs;
-   txp->regset.regs = txp_regs;
-   txp->regset.nregs = ARRAY_SIZE(txp_regs);
+   vc4_crtc->regset.base = txp->regs;
+   vc4_crtc->regset.regs = txp_regs;
+   vc4_crtc->regset.nregs = ARRAY_SIZE(txp_regs);
 
drm_connector_helper_add(>connector.base,
 _txp_connector_helper_funcs);
@@ -521,7 +520,7 @@ static int vc4_txp_bind(struct device *dev, struct device 
*master, void *data)
 
dev_set_drvdata(dev, txp);
 
-   vc4_debugfs_add_regset32(drm, "txp_regs", >regset);
+   vc4_debugfs_add_regset32(drm, "txp_regs", _crtc->regset);
 
return 0;
 }
-- 
2.36.1



[PATCH 41/64] drm/vc4: hdmi: Use devm to register hotplug interrupts

2022-06-10 Thread Maxime Ripard
Commit 776efe800fed ("drm/vc4: hdmi: Drop devm interrupt handler for
hotplug interrupts") dropped the device-managed interrupt registration
because it was creating bugs and races whenever an interrupt was coming in
while the device was removed.

However, our latest patches to the HDMI controller driver fix this as well,
so we can use device-managed interrupt handlers again.

Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/vc4/vc4_hdmi.c | 41 +-
 1 file changed, 11 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index ecc898684c4b..ca0bc8be3e6a 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -2181,21 +2181,19 @@ static int vc4_hdmi_hotplug_init(struct vc4_hdmi 
*vc4_hdmi)
unsigned int hpd_con = platform_get_irq_byname(pdev, 
"hpd-connected");
unsigned int hpd_rm = platform_get_irq_byname(pdev, 
"hpd-removed");
 
-   ret = request_threaded_irq(hpd_con,
-  NULL,
-  vc4_hdmi_hpd_irq_thread, 
IRQF_ONESHOT,
-  "vc4 hdmi hpd connected", vc4_hdmi);
+   ret = devm_request_threaded_irq(>dev, hpd_con,
+   NULL,
+   vc4_hdmi_hpd_irq_thread, 
IRQF_ONESHOT,
+   "vc4 hdmi hpd connected", 
vc4_hdmi);
if (ret)
return ret;
 
-   ret = request_threaded_irq(hpd_rm,
-  NULL,
-  vc4_hdmi_hpd_irq_thread, 
IRQF_ONESHOT,
-  "vc4 hdmi hpd disconnected", 
vc4_hdmi);
-   if (ret) {
-   free_irq(hpd_con, vc4_hdmi);
+   ret = devm_request_threaded_irq(>dev, hpd_rm,
+   NULL,
+   vc4_hdmi_hpd_irq_thread, 
IRQF_ONESHOT,
+   "vc4 hdmi hpd disconnected", 
vc4_hdmi);
+   if (ret)
return ret;
-   }
 
connector->polled = DRM_CONNECTOR_POLL_HPD;
}
@@ -2203,16 +2201,6 @@ static int vc4_hdmi_hotplug_init(struct vc4_hdmi 
*vc4_hdmi)
return 0;
 }
 
-static void vc4_hdmi_hotplug_exit(struct vc4_hdmi *vc4_hdmi)
-{
-   struct platform_device *pdev = vc4_hdmi->pdev;
-
-   if (vc4_hdmi->variant->external_irq_controller) {
-   free_irq(platform_get_irq_byname(pdev, "hpd-connected"), 
vc4_hdmi);
-   free_irq(platform_get_irq_byname(pdev, "hpd-removed"), 
vc4_hdmi);
-   }
-}
-
 #ifdef CONFIG_DRM_VC4_HDMI_CEC
 static irqreturn_t vc4_cec_irq_handler_rx_thread(int irq, void *priv)
 {
@@ -2994,11 +2982,11 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 
ret = vc4_hdmi_cec_init(vc4_hdmi);
if (ret)
-   goto err_free_hotplug;
+   goto err_put_runtime_pm;
 
ret = vc4_hdmi_audio_init(vc4_hdmi);
if (ret)
-   goto err_free_hotplug;
+   goto err_put_runtime_pm;
 
vc4_debugfs_add_file(drm, variant->debugfs_name,
 vc4_hdmi_debugfs_regs,
@@ -3008,8 +2996,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 
return 0;
 
-err_free_hotplug:
-   vc4_hdmi_hotplug_exit(vc4_hdmi);
 err_put_runtime_pm:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
@@ -3020,8 +3006,6 @@ static int vc4_hdmi_bind(struct device *dev, struct 
device *master, void *data)
 static void vc4_hdmi_unbind(struct device *dev, struct device *master,
void *data)
 {
-   struct vc4_hdmi *vc4_hdmi;
-
/*
 * ASoC makes it a bit hard to retrieve a pointer to the
 * vc4_hdmi structure. Registering the card will overwrite our
@@ -3041,9 +3025,6 @@ static void vc4_hdmi_unbind(struct device *dev, struct 
device *master,
 */
BUILD_BUG_ON(offsetof(struct vc4_hdmi_audio, card) != 0);
BUILD_BUG_ON(offsetof(struct vc4_hdmi, audio) != 0);
-   vc4_hdmi = dev_get_drvdata(dev);
-
-   vc4_hdmi_hotplug_exit(vc4_hdmi);
 
pm_runtime_disable(dev);
 }
-- 
2.36.1



  1   2   3   >