[PATCH] drm: amdgpu: Fix logic error

2022-11-28 Thread Konstantin Meskhidze
This commit fixes logic error in function 'amdgpu_hw_ip_info':
   - value 'uvd' might be 'vcn'.

Signed-off-by: Konstantin Meskhidze 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index fe23e09eec98..28752a6a92c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -424,7 +424,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
case AMDGPU_HW_IP_VCN_DEC:
type = AMD_IP_BLOCK_TYPE_VCN;
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
-   if (adev->uvd.harvest_config & (1 << i))
+   if (adev->vcn.harvest_config & (1 << i))
continue;
 
if (adev->vcn.inst[i].ring_dec.sched.ready)
@@ -436,7 +436,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
case AMDGPU_HW_IP_VCN_ENC:
type = AMD_IP_BLOCK_TYPE_VCN;
for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
-   if (adev->uvd.harvest_config & (1 << i))
+   if (adev->vcn.harvest_config & (1 << i))
continue;
 
for (j = 0; j < adev->vcn.num_enc_rings; j++)
-- 
2.25.1



[PATCH] drm/amdkfd: Fix memory leakage

2022-11-28 Thread Konstantin Meskhidze
This patch fixes potential memory leakage and seg fault
in  _gpuvm_import_dmabuf() function

Signed-off-by: Konstantin Meskhidze 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 978d3970b5cc..e0084f712e02 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -2257,7 +2257,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct 
amdgpu_device *adev,
 
ret = drm_vma_node_allow(>vma_node, drm_priv);
if (ret) {
-   kfree(mem);
+   kfree(*mem);
return ret;
}
 
-- 
2.25.1



Re: [PATCH v2 1/3] ASoC: hdmi-codec: Add event handler for hdmi TX

2022-11-28 Thread 俞家鑫


[PATCH] drm/mediatek: Implement shutdown

2022-11-28 Thread Ricardo Ribalda
Poweroff the device properly, otherwise the device will not come back
from kexec().

Signed-off-by: Ricardo Ribalda 
---
To: Chun-Kuang Hu 
To: Philipp Zabel 
To: David Airlie 
To: Daniel Vetter 
To: Matthias Brugger 
Cc: dri-devel@lists.freedesktop.org
Cc: linux-media...@lists.infradead.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-ker...@vger.kernel.org
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 91f58db5915f..51dbd85796e9 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -829,6 +829,12 @@ static int mtk_drm_remove(struct platform_device *pdev)
return 0;
 }
 
+static void mtk_drm_shutdown(struct platform_device *pdev)
+{
+   component_master_del(>dev, _drm_ops);
+   pm_runtime_disable(>dev);
+}
+
 static int mtk_drm_sys_prepare(struct device *dev)
 {
struct mtk_drm_private *private = dev_get_drvdata(dev);
@@ -856,6 +862,7 @@ static const struct dev_pm_ops mtk_drm_pm_ops = {
 static struct platform_driver mtk_drm_platform_driver = {
.probe  = mtk_drm_probe,
.remove = mtk_drm_remove,
+   .shutdown = mtk_drm_shutdown,
.driver = {
.name   = "mediatek-drm",
.pm = _drm_pm_ops,

---
base-commit: 4312098baf37ee17a8350725e6e0d0e8590252d4
change-id: 20221128-mtk-drm-ca6c5ac6b389

Best regards,
-- 
Ricardo Ribalda 


[PATCH v1] drm/bridge: lt8912b: Add hot plug detection

2022-11-28 Thread Francesco Dolcini
From: Stefan Eichenberger 

Enable hot plug detection when it is available on the HDMI port.
Without this connecting to a different monitor with incompatible timing
before the 10 seconds poll period will lead to a broken display output.

Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge")
Signed-off-by: Stefan Eichenberger 
Signed-off-by: Francesco Dolcini 
---
 drivers/gpu/drm/bridge/lontium-lt8912b.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c 
b/drivers/gpu/drm/bridge/lontium-lt8912b.c
index a98efef0ba0e..5f0c9cd2a970 100644
--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c
+++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c
@@ -517,14 +517,27 @@ static int lt8912_attach_dsi(struct lt8912 *lt)
return 0;
 }
 
+static void lt8912_bridge_hpd_cb(void *data, enum drm_connector_status status)
+{
+   struct lt8912 *lt = data;
+
+   if (lt->bridge.dev)
+   drm_helper_hpd_irq_event(lt->bridge.dev);
+}
+
 static int lt8912_bridge_connector_init(struct drm_bridge *bridge)
 {
int ret;
struct lt8912 *lt = bridge_to_lt8912(bridge);
struct drm_connector *connector = >connector;
 
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
-   DRM_CONNECTOR_POLL_DISCONNECT;
+   if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD) {
+   drm_bridge_hpd_enable(lt->hdmi_port, lt8912_bridge_hpd_cb, lt);
+   connector->polled = DRM_CONNECTOR_POLL_HPD;
+   } else {
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+   }
 
ret = drm_connector_init(bridge->dev, connector,
 _connector_funcs,
@@ -578,6 +591,10 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
 
if (lt->is_attached) {
lt8912_hard_power_off(lt);
+
+   if (lt->hdmi_port->ops & DRM_BRIDGE_OP_HPD)
+   drm_bridge_hpd_disable(lt->hdmi_port);
+
drm_connector_unregister(>connector);
drm_connector_cleanup(>connector);
}
-- 
2.25.1



[PATCH v8 22/22] drm/i915/vm_bind: Support capture of persistent mappings

2022-11-28 Thread Niranjana Vishwanathapura
Support dump capture of persistent mappings upon user request.

Signed-off-by: Brian Welty 
Signed-off-by: Niranjana Vishwanathapura 
---
 .../drm/i915/gem/i915_gem_vm_bind_object.c| 11 +++
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  3 +++
 drivers/gpu/drm/i915/gt/intel_gtt.h   |  5 +
 drivers/gpu/drm/i915/i915_gpu_error.c | 19 +++
 drivers/gpu/drm/i915/i915_vma.c   |  1 +
 drivers/gpu/drm/i915/i915_vma_types.h |  2 ++
 include/uapi/drm/i915_drm.h   |  3 ++-
 7 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
index 78e7c0642c5f..50969613daf6 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
@@ -88,6 +88,11 @@ static void i915_gem_vm_bind_remove(struct i915_vma *vma, 
bool release_obj)
 {
lockdep_assert_held(>vm->vm_bind_lock);
 
+   spin_lock(>vm->vm_capture_lock);
+   if (!list_empty(>vm_capture_link))
+   list_del_init(>vm_capture_link);
+   spin_unlock(>vm->vm_capture_lock);
+
spin_lock(>vm->vm_rebind_lock);
if (!list_empty(>vm_rebind_link))
list_del_init(>vm_rebind_link);
@@ -357,6 +362,12 @@ static int i915_gem_vm_bind_obj(struct i915_address_space 
*vm,
continue;
}
 
+   if (va->flags & I915_GEM_VM_BIND_CAPTURE) {
+   spin_lock(>vm_capture_lock);
+   list_add_tail(>vm_capture_link, 
>vm_capture_list);
+   spin_unlock(>vm_capture_lock);
+   }
+
list_add_tail(>vm_bind_link, >vm_bound_list);
i915_vm_bind_it_insert(vma, >va);
if (!obj->priv_root)
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index ebf6830574a0..bdabe13fc30e 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -297,6 +297,9 @@ void i915_address_space_init(struct i915_address_space *vm, 
int subclass)
spin_lock_init(>vm_rebind_lock);
spin_lock_init(>userptr_invalidated_lock);
INIT_LIST_HEAD(>userptr_invalidated_list);
+
+   INIT_LIST_HEAD(>vm_capture_list);
+   spin_lock_init(>vm_capture_lock);
 }
 
 void *__px_vaddr(struct drm_i915_gem_object *p)
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h 
b/drivers/gpu/drm/i915/gt/intel_gtt.h
index 87e5b6568a00..8e4ddd073348 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -281,6 +281,11 @@ struct i915_address_space {
/** @root_obj: root object for dma-resv sharing by private objects */
struct drm_i915_gem_object *root_obj;
 
+   /* @vm_capture_list: list of vm captures */
+   struct list_head vm_capture_list;
+   /* @vm_capture_lock: protects vm_capture_list */
+   spinlock_t vm_capture_lock;
+
/* Global GTT */
bool is_ggtt:1;
 
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index 9d5d5a397b64..3b2b12a739f7 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1460,6 +1460,22 @@ capture_vma(struct intel_engine_capture_vma *next,
return next;
 }
 
+static struct intel_engine_capture_vma *
+capture_user_vm(struct intel_engine_capture_vma *capture,
+   struct i915_address_space *vm, gfp_t gfp)
+{
+   struct i915_vma *vma;
+
+   spin_lock(>vm_capture_lock);
+   /* vma->resource must be valid here as persistent vmas are bound */
+   list_for_each_entry(vma, >vm_capture_list, vm_capture_link)
+   capture = capture_vma_snapshot(capture, vma->resource,
+  gfp, "user");
+   spin_unlock(>vm_capture_lock);
+
+   return capture;
+}
+
 static struct intel_engine_capture_vma *
 capture_user(struct intel_engine_capture_vma *capture,
 const struct i915_request *rq,
@@ -1471,6 +1487,9 @@ capture_user(struct intel_engine_capture_vma *capture,
capture = capture_vma_snapshot(capture, c->vma_res, gfp,
   "user");
 
+   capture = capture_user_vm(capture, rq->context->vm,
+ GFP_NOWAIT | __GFP_NOWARN);
+
return capture;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 68a9ac77b4f2..0244864e94f7 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -248,6 +248,7 @@ vma_create(struct drm_i915_gem_object *obj,
INIT_LIST_HEAD(>non_priv_vm_bind_link);
INIT_LIST_HEAD(>vm_rebind_link);
INIT_LIST_HEAD(>userptr_invalidated_link);
+   INIT_LIST_HEAD(>vm_capture_link);
return vma;
 
 err_unlock:
diff --git 

[PATCH v8 20/22] drm/i915/vm_bind: Async vm_unbind support

2022-11-28 Thread Niranjana Vishwanathapura
Asynchronously unbind the vma upon vm_unbind call.
Fall back to synchronous unbind if backend doesn't support
async unbind or if async unbind fails.

No need for vm_unbind out fence support as i915 will internally
handle all sequencing and user need not try to sequence any
operation with the unbind completion.

v2: use i915_vma_destroy_async in vm_unbind ioctl
v3: Add force_unbind function variants

Reviewed-by: Matthew Auld 
Reviewed-by: Andi Shyti 
Signed-off-by: Niranjana Vishwanathapura 
---
 .../drm/i915/gem/i915_gem_vm_bind_object.c|  2 +-
 drivers/gpu/drm/i915/i915_vma.c   | 49 ++-
 drivers/gpu/drm/i915/i915_vma.h   |  1 +
 include/uapi/drm/i915_drm.h   |  3 +-
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
index 1cc0b8a4e0e7..78e7c0642c5f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
@@ -210,7 +210,7 @@ static int i915_gem_vm_unbind_vma(struct i915_address_space 
*vm,
 */
obj = vma->obj;
i915_gem_object_lock(obj, NULL);
-   i915_vma_destroy(vma);
+   i915_vma_destroy_async(vma);
i915_gem_object_unlock(obj);
 
i915_gem_object_put(obj);
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 5240463d5b48..1b9033865768 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -42,6 +42,8 @@
 #include "i915_vma.h"
 #include "i915_vma_resource.h"
 
+static struct dma_fence *__i915_vma_unbind_async(struct i915_vma *vma);
+
 static inline void assert_vma_held_evict(const struct i915_vma *vma)
 {
/*
@@ -1716,7 +1718,7 @@ void i915_vma_reopen(struct i915_vma *vma)
spin_unlock_irq(>closed_lock);
 }
 
-static void force_unbind(struct i915_vma *vma)
+static void __force_unbind(struct i915_vma *vma, bool async)
 {
if (!drm_mm_node_allocated(>node))
return;
@@ -1730,10 +1732,26 @@ static void force_unbind(struct i915_vma *vma)
i915_vma_set_purged(vma);
 
atomic_and(~I915_VMA_PIN_MASK, >flags);
-   WARN_ON(__i915_vma_unbind(vma));
+   if (async) {
+   struct dma_fence *fence;
+
+   fence = __i915_vma_unbind_async(vma);
+   if (IS_ERR_OR_NULL(fence)) {
+   async = false;
+   } else {
+   dma_resv_add_fence(vma->obj->base.resv, fence,
+  DMA_RESV_USAGE_READ);
+   dma_fence_put(fence);
+   }
+   }
+
+   if (!async)
+   WARN_ON(__i915_vma_unbind(vma));
GEM_BUG_ON(drm_mm_node_allocated(>node));
 }
 
+#define force_unbind(vma)  __force_unbind((vma), false)
+
 static void release_references(struct i915_vma *vma, struct intel_gt *gt,
   bool vm_ddestroy)
 {
@@ -1812,6 +1830,33 @@ void i915_vma_destroy(struct i915_vma *vma)
release_references(vma, gt, vm_ddestroy);
 }
 
+void i915_vma_destroy_async(struct i915_vma *vma)
+{
+   bool vm_ddestroy, async = vma->obj->mm.rsgt;
+   struct intel_gt *gt;
+
+   if (dma_resv_reserve_fences(vma->obj->base.resv, 1))
+   async = false;
+
+   mutex_lock(>vm->mutex);
+   /*
+* Ensure any asynchronous binding is complete while using
+* async unbind as we will be releasing the vma here.
+*/
+   if (async && i915_active_wait(>active))
+   async = false;
+
+   __force_unbind(vma, async);
+   list_del_init(>vm_link);
+   vm_ddestroy = vma->vm_ddestroy;
+   vma->vm_ddestroy = false;
+
+   /* vma->vm may be freed when releasing vma->vm->mutex. */
+   gt = vma->vm->gt;
+   mutex_unlock(>vm->mutex);
+   release_references(vma, gt, vm_ddestroy);
+}
+
 void i915_vma_parked(struct intel_gt *gt)
 {
struct i915_vma *vma, *next;
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 1ecc71cf2698..5f783ce21e06 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -273,6 +273,7 @@ void i915_vma_reopen(struct i915_vma *vma);
 
 void i915_vma_destroy_locked(struct i915_vma *vma);
 void i915_vma_destroy(struct i915_vma *vma);
+void i915_vma_destroy_async(struct i915_vma *vma);
 
 #define assert_vma_held(vma) dma_resv_assert_held((vma)->obj->base.resv)
 
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 3f27001a2c8d..b9167f950327 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -3970,7 +3970,8 @@ struct drm_i915_gem_vm_bind {
  * any error.
  *
  * VM_BIND/UNBIND ioctl calls executed on different CPU threads concurrently
- * are not ordered.
+ * are not ordered. Furthermore, parts of the VM_UNBIND operation can be done
+ * 

[PATCH v8 19/22] drm/i915/vm_bind: Render VM_BIND documentation

2022-11-28 Thread Niranjana Vishwanathapura
Update i915 documentation to include VM_BIND changes
and render all VM_BIND related documentation.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
---
 Documentation/gpu/i915.rst | 78 --
 1 file changed, 59 insertions(+), 19 deletions(-)

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 60ea21734902..01429a8f0d6c 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -283,15 +283,18 @@ An Intel GPU has multiple engines. There are several 
engine types.
 
 The Intel GPU family is a family of integrated GPU's using Unified
 Memory Access. For having the GPU "do work", user space will feed the
-GPU batch buffers via one of the ioctls `DRM_IOCTL_I915_GEM_EXECBUFFER2`
-or `DRM_IOCTL_I915_GEM_EXECBUFFER2_WR`. Most such batchbuffers will
-instruct the GPU to perform work (for example rendering) and that work
-needs memory from which to read and memory to which to write. All memory
-is encapsulated within GEM buffer objects (usually created with the ioctl
-`DRM_IOCTL_I915_GEM_CREATE`). An ioctl providing a batchbuffer for the GPU
-to create will also list all GEM buffer objects that the batchbuffer reads
-and/or writes. For implementation details of memory management see
-`GEM BO Management Implementation Details`_.
+GPU batch buffers via one of the ioctls `DRM_IOCTL_I915_GEM_EXECBUFFER2`,
+`DRM_IOCTL_I915_GEM_EXECBUFFER2_WR` or `DRM_IOCTL_I915_GEM_EXECBUFFER3`.
+Most such batchbuffers will instruct the GPU to perform work (for example
+rendering) and that work needs memory from which to read and memory to
+which to write. All memory is encapsulated within GEM buffer objects
+(usually created with the ioctl `DRM_IOCTL_I915_GEM_CREATE`). In vm_bind mode
+(see `VM_BIND mode`_), the batch buffer and all the GEM buffer objects that
+it reads and/or writes should be bound with vm_bind ioctl before submitting
+the batch buffer to GPU. In legacy (non-VM_BIND) mode, an ioctl providing a
+batchbuffer for the GPU to create will also list all GEM buffer objects that
+the batchbuffer reads and/or writes. For implementation details of memory
+management see `GEM BO Management Implementation Details`_.
 
 The i915 driver allows user space to create a context via the ioctl
 `DRM_IOCTL_I915_GEM_CONTEXT_CREATE` which is identified by a 32-bit
@@ -309,8 +312,9 @@ In addition to the ordering guarantees, the kernel will 
restore GPU
 state via HW context when commands are issued to a context, this saves
 user space the need to restore (most of atleast) the GPU state at the
 start of each batchbuffer. The non-deprecated ioctls to submit batchbuffer
-work can pass that ID (in the lower bits of drm_i915_gem_execbuffer2::rsvd1)
-to identify what context to use with the command.
+work can pass that ID (drm_i915_gem_execbuffer3::ctx_id, or in the lower
+bits of drm_i915_gem_execbuffer2::rsvd1) to identify what context to use
+with the command.
 
 The GPU has its own memory management and address space. The kernel
 driver maintains the memory translation table for the GPU. For older
@@ -318,14 +322,14 @@ GPUs (i.e. those before Gen8), there is a single global 
such translation
 table, a global Graphics Translation Table (GTT). For newer generation
 GPUs each context has its own translation table, called Per-Process
 Graphics Translation Table (PPGTT). Of important note, is that although
-PPGTT is named per-process it is actually per context. When user space
-submits a batchbuffer, the kernel walks the list of GEM buffer objects
-used by the batchbuffer and guarantees that not only is the memory of
-each such GEM buffer object resident but it is also present in the
-(PP)GTT. If the GEM buffer object is not yet placed in the (PP)GTT,
-then it is given an address. Two consequences of this are: the kernel
-needs to edit the batchbuffer submitted to write the correct value of
-the GPU address when a GEM BO is assigned a GPU address and the kernel
+PPGTT is named per-process it is actually per context. In legacy
+(non-vm_bind) mode, when user space submits a batchbuffer, the kernel walks
+the list of GEM buffer objects used by the batchbuffer and guarantees that
+not only is the memory of each such GEM buffer object resident but it is
+also present in the (PP)GTT. If the GEM buffer object is not yet placed in
+the (PP)GTT, then it is given an address. Two consequences of this are: the
+kernel needs to edit the batchbuffer submitted to write the correct value
+of the GPU address when a GEM BO is assigned a GPU address and the kernel
 might evict a different GEM BO from the (PP)GTT to make address room
 for another GEM BO. Consequently, the ioctls submitting a batchbuffer
 for execution also include a list of all locations within buffers that
@@ -407,6 +411,15 @@ objects, which has the goal to make space in gpu virtual 
address spaces.
 .. kernel-doc:: drivers/gpu/drm/i915/gem/i915_gem_shrinker.c
:internal:
 
+VM_BIND mode
+
+

[PATCH v8 06/22] drm/i915/vm_bind: Support for VM private BOs

2022-11-28 Thread Niranjana Vishwanathapura
Each VM creates a root_obj and shares it with all of its private objects
to use it as dma_resv object. This has a performance advantage as it
requires a single dma_resv object update for all private BOs vs list of
dma_resv objects update for shared BOs, in the execbuf path.

VM private BOs can be only mapped on specified VM and cannot be dmabuf
exported. Also, they are supported only in vm_bind mode.

v2: Pad struct drm_i915_gem_create_ext_vm_private for 64bit alignment,
add input validity checks.
v3: Create root_obj only for ppgtt.
v4: Fix releasing of obj->priv_root. Do not create vm->root_obj yet.
Allow vm private object creation only in vm_bind mode.
Replace vm->vm_bind_mode check with i915_gem_vm_is_vm_bind_mode().

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_create.c| 54 ++-
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|  6 +++
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|  4 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.c|  3 ++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  6 +++
 .../drm/i915/gem/i915_gem_vm_bind_object.c|  9 
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  1 +
 drivers/gpu/drm/i915/gt/intel_gtt.h   |  4 ++
 drivers/gpu/drm/i915/i915_vma.c   |  1 +
 drivers/gpu/drm/i915/i915_vma_types.h |  2 +
 include/uapi/drm/i915_drm.h   | 33 
 12 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 3a696f61af92..7d3366975e6d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -83,6 +83,7 @@
 
 #include "i915_file_private.h"
 #include "i915_gem_context.h"
+#include "i915_gem_internal.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 5c6e396ab74d..62648341780b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -11,6 +11,7 @@
 #include "pxp/intel_pxp.h"
 
 #include "i915_drv.h"
+#include "i915_gem_context.h"
 #include "i915_gem_create.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
@@ -251,6 +252,7 @@ struct create_ext {
unsigned int n_placements;
unsigned int placement_mask;
unsigned long flags;
+   u32 vm_id;
 };
 
 static void repr_placements(char *buf, size_t size,
@@ -400,9 +402,32 @@ static int ext_set_protected(struct i915_user_extension 
__user *base, void *data
return 0;
 }
 
+static int ext_set_vm_private(struct i915_user_extension __user *base,
+ void *data)
+{
+   struct drm_i915_gem_create_ext_vm_private ext;
+   struct create_ext *ext_data = data;
+
+   if (copy_from_user(, base, sizeof(ext)))
+   return -EFAULT;
+
+   /* Reserved fields must be 0 */
+   if (ext.rsvd)
+   return -EINVAL;
+
+   /* vm_id 0 is reserved */
+   if (!ext.vm_id)
+   return -ENOENT;
+
+   ext_data->vm_id = ext.vm_id;
+
+   return 0;
+}
+
 static const i915_user_extension_fn create_extensions[] = {
[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
+   [I915_GEM_CREATE_EXT_VM_PRIVATE] = ext_set_vm_private,
 };
 
 /**
@@ -418,6 +443,7 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void 
*data,
struct drm_i915_private *i915 = to_i915(dev);
struct drm_i915_gem_create_ext *args = data;
struct create_ext ext_data = { .i915 = i915 };
+   struct i915_address_space *vm = NULL;
struct drm_i915_gem_object *obj;
int ret;
 
@@ -431,6 +457,17 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void 
*data,
if (ret)
return ret;
 
+   if (ext_data.vm_id) {
+   vm = i915_gem_vm_lookup(file->driver_priv, ext_data.vm_id);
+   if (unlikely(!vm))
+   return -ENOENT;
+
+   if (!i915_gem_vm_is_vm_bind_mode(vm)) {
+   ret = -EINVAL;
+   goto vm_put;
+   }
+   }
+
if (!ext_data.n_placements) {
ext_data.placements[0] =
intel_memory_region_by_type(i915, INTEL_MEMORY_SYSTEM);
@@ -457,8 +494,21 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void 
*data,
ext_data.placements,
ext_data.n_placements,
ext_data.flags);
-   if (IS_ERR(obj))
-   return PTR_ERR(obj);
+   if (IS_ERR(obj)) {
+   ret = 

[PATCH v8 21/22] drm/i915/vm_bind: Properly build persistent map sg table

2022-11-28 Thread Niranjana Vishwanathapura
Properly build the sg table for persistent mapping which can
be partial map of the underlying object. Ensure the sg pages
are properly set for page backed regions. The dump capture
support requires this for page backed regions.

Signed-off-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/i915_vma.c | 120 +++-
 1 file changed, 119 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 1b9033865768..68a9ac77b4f2 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1298,6 +1298,120 @@ intel_partial_pages(const struct i915_gtt_view *view,
return ERR_PTR(ret);
 }
 
+static unsigned int
+intel_copy_dma_sg(struct sg_table *src_st, struct sg_table *dst_st,
+ u64 offset, u64 length, bool dry_run)
+{
+   struct scatterlist *dst_sg, *src_sg;
+   unsigned int i, len, nents = 0;
+
+   dst_sg = dst_st->sgl;
+   for_each_sgtable_dma_sg(src_st, src_sg, i) {
+   if (sg_dma_len(src_sg) <= offset) {
+   offset -= sg_dma_len(src_sg);
+   continue;
+   }
+
+   nents++;
+   len = min(sg_dma_len(src_sg) - offset, length);
+   if (!dry_run) {
+   sg_dma_address(dst_sg) = sg_dma_address(src_sg) + 
offset;
+   sg_dma_len(dst_sg) = len;
+   dst_sg = sg_next(dst_sg);
+   }
+
+   length -= len;
+   offset = 0;
+   if (!length)
+   break;
+   }
+   WARN_ON_ONCE(length);
+
+   return nents;
+}
+
+static unsigned int
+intel_copy_sg(struct sg_table *src_st, struct sg_table *dst_st,
+ u64 offset, u64 length, bool dry_run)
+{
+   struct scatterlist *dst_sg, *src_sg;
+   unsigned int i, len, nents = 0;
+
+   dst_sg = dst_st->sgl;
+   for_each_sgtable_sg(src_st, src_sg, i) {
+   if (src_sg->length <= offset) {
+   offset -= src_sg->length;
+   continue;
+   }
+
+   nents++;
+   len = min(src_sg->length - offset, length);
+   if (!dry_run) {
+   unsigned long pfn;
+
+   pfn = page_to_pfn(sg_page(src_sg)) + offset / PAGE_SIZE;
+   sg_set_page(dst_sg, pfn_to_page(pfn), len, 0);
+   dst_sg = sg_next(dst_sg);
+   }
+
+   length -= len;
+   offset = 0;
+   if (!length)
+   break;
+   }
+   WARN_ON_ONCE(length);
+
+   return nents;
+}
+
+static noinline struct sg_table *
+intel_persistent_partial_pages(const struct i915_gtt_view *view,
+  struct drm_i915_gem_object *obj)
+{
+   u64 offset = view->partial.offset << PAGE_SHIFT;
+   struct sg_table *st, *obj_st = obj->mm.pages;
+   u64 length = view->partial.size << PAGE_SHIFT;
+   struct scatterlist *sg;
+   unsigned int nents;
+   int ret = -ENOMEM;
+
+   st = kmalloc(sizeof(*st), GFP_KERNEL);
+   if (!st)
+   goto err_st_alloc;
+
+   /* Get required sg_table size */
+   nents = intel_copy_dma_sg(obj_st, st, offset, length, true);
+   if (i915_gem_object_has_struct_page(obj)) {
+   unsigned int pg_nents;
+
+   pg_nents = intel_copy_sg(obj_st, st, offset, length, true);
+   if (nents < pg_nents)
+   nents = pg_nents;
+   }
+
+   ret = sg_alloc_table(st, nents, GFP_KERNEL);
+   if (ret)
+   goto err_sg_alloc;
+
+   /* Build sg_table for specified  section */
+   intel_copy_dma_sg(obj_st, st, offset, length, false);
+   if (i915_gem_object_has_struct_page(obj))
+   intel_copy_sg(obj_st, st, offset, length, false);
+
+   /* Mark last sg */
+   sg = st->sgl;
+   while (sg_next(sg))
+   sg = sg_next(sg);
+   sg_mark_end(sg);
+
+   return st;
+
+err_sg_alloc:
+   kfree(st);
+err_st_alloc:
+   return ERR_PTR(ret);
+}
+
 static int
 __i915_vma_get_pages(struct i915_vma *vma)
 {
@@ -1330,7 +1444,11 @@ __i915_vma_get_pages(struct i915_vma *vma)
break;
 
case I915_GTT_VIEW_PARTIAL:
-   pages = intel_partial_pages(>gtt_view, vma->obj);
+   if (i915_vma_is_persistent(vma))
+   pages = intel_persistent_partial_pages(>gtt_view,
+  vma->obj);
+   else
+   pages = intel_partial_pages(>gtt_view, vma->obj);
break;
}
 
-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH v8 18/22] drm/i915/vm_bind: Add uapi for user to enable vm_bind_mode

2022-11-28 Thread Niranjana Vishwanathapura
Add getparam support for VM_BIND capability version.
Add VM creation time flag to enable vm_bind_mode for the VM.

v2: update kernel-doc
v3: create vm->root_obj only upon I915_VM_CREATE_FLAGS_USE_VM_BIND
v4: replace vm->vm_bind_mode check with i915_gem_vm_is_vm_bind_mode()

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 25 ++--
 drivers/gpu/drm/i915/gem/i915_gem_context.h |  3 +--
 drivers/gpu/drm/i915/gt/intel_gtt.c |  2 ++
 drivers/gpu/drm/i915/i915_drv.h |  2 ++
 drivers/gpu/drm/i915/i915_getparam.c|  3 +++
 include/uapi/drm/i915_drm.h | 26 -
 6 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index a048bf463916..a85f4febaafe 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1809,9 +1809,13 @@ int i915_gem_vm_create_ioctl(struct drm_device *dev, 
void *data,
if (!HAS_FULL_PPGTT(i915))
return -ENODEV;
 
-   if (args->flags)
+   if (args->flags & I915_VM_CREATE_FLAGS_UNKNOWN)
return -EINVAL;
 
+   if ((args->flags & I915_VM_CREATE_FLAGS_USE_VM_BIND) &&
+   !HAS_VM_BIND(i915))
+   return -EOPNOTSUPP;
+
ppgtt = i915_ppgtt_create(to_gt(i915), 0);
if (IS_ERR(ppgtt))
return PTR_ERR(ppgtt);
@@ -1824,15 +1828,32 @@ int i915_gem_vm_create_ioctl(struct drm_device *dev, 
void *data,
goto err_put;
}
 
+   if (args->flags & I915_VM_CREATE_FLAGS_USE_VM_BIND) {
+   struct drm_i915_gem_object *obj;
+
+   obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
+   if (IS_ERR(obj)) {
+   err = PTR_ERR(obj);
+   goto err_put;
+   }
+
+   ppgtt->vm.root_obj = obj;
+   }
+
err = xa_alloc(_priv->vm_xa, , >vm,
   xa_limit_32b, GFP_KERNEL);
if (err)
-   goto err_put;
+   goto err_root_obj_put;
 
GEM_BUG_ON(id == 0); /* reserved for invalid/unassigned ppgtt */
args->vm_id = id;
return 0;
 
+err_root_obj_put:
+   if (ppgtt->vm.root_obj) {
+   i915_gem_object_put(ppgtt->vm.root_obj);
+   ppgtt->vm.root_obj = NULL;
+   }
 err_put:
i915_vm_put(>vm);
return err;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h 
b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index e8b41aa8f8c4..b53aef2853cb 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -150,8 +150,7 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device 
*dev, void *data,
  */
 static inline bool i915_gem_vm_is_vm_bind_mode(struct i915_address_space *vm)
 {
-   /* No support to enable vm_bind mode yet */
-   return false;
+   return !!vm->root_obj;
 }
 
 struct i915_address_space *
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 0573b72ae678..ebf6830574a0 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -179,6 +179,8 @@ int i915_vm_lock_objects(struct i915_address_space *vm,
 void i915_address_space_fini(struct i915_address_space *vm)
 {
drm_mm_takedown(>mm);
+   if (vm->root_obj)
+   i915_gem_object_put(vm->root_obj);
GEM_BUG_ON(!RB_EMPTY_ROOT(>va.rb_root));
mutex_destroy(>vm_bind_lock);
 }
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index a380db36d52c..53653ad3ffa5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -967,6 +967,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_LMEMBAR_SMEM_STOLEN(i915) (!HAS_LMEM(i915) && \
   GRAPHICS_VER_FULL(i915) >= IP_VER(12, 
70))
 
+#define HAS_VM_BIND(i915) (GRAPHICS_VER(i915) >= 12)
+
 /* intel_device_info.c */
 static inline struct intel_device_info *
 mkwrite_device_info(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/i915_getparam.c 
b/drivers/gpu/drm/i915/i915_getparam.c
index 61ef2d9cfa62..20c1bf904a65 100644
--- a/drivers/gpu/drm/i915/i915_getparam.c
+++ b/drivers/gpu/drm/i915/i915_getparam.c
@@ -178,6 +178,9 @@ int i915_getparam_ioctl(struct drm_device *dev, void *data,
case I915_PARAM_OA_TIMESTAMP_FREQUENCY:
value = i915_perf_oa_timestamp_frequency(i915);
break;
+   case I915_PARAM_VM_BIND_VERSION:
+   value = HAS_VM_BIND(i915);
+   break;
default:
drm_dbg(>drm, "Unknown parameter %d\n", param->param);
return -EINVAL;
diff --git a/include/uapi/drm/i915_drm.h 

[PATCH v8 15/22] drm/i915/vm_bind: Handle persistent vmas in execbuf3

2022-11-28 Thread Niranjana Vishwanathapura
Handle persistent (VM_BIND) mappings during the request submission
in the execbuf3 path.

v2: Ensure requests wait for bindings to complete.
v3: Remove short term pinning with PIN_VALIDATE flag.
Individualize fences before adding to dma_resv obj.
v4: Fix bind completion check, use PIN_NOEVICT,
use proper lock while checking if vm_rebind_list is empty.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer3.c   | 215 +-
 1 file changed, 214 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
index 49045858a3e9..913b1f8bda9f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
@@ -3,6 +3,7 @@
  * Copyright © 2022 Intel Corporation
  */
 
+#include 
 #include 
 #include 
 
@@ -19,6 +20,7 @@
 #include "i915_gem_vm_bind.h"
 #include "i915_trace.h"
 
+#define __EXEC3_HAS_PINBIT_ULL(33)
 #define __EXEC3_ENGINE_PINNED  BIT_ULL(32)
 #define __EXEC3_INTERNAL_FLAGS (~0ull << 32)
 
@@ -42,7 +44,9 @@
  * execlist. Hence, no support for implicit sync.
  *
  * The new execbuf3 ioctl only works in VM_BIND mode and the VM_BIND mode only
- * works with execbuf3 ioctl for submission.
+ * works with execbuf3 ioctl for submission. All BOs mapped on that VM (through
+ * VM_BIND call) at the time of execbuf3 call are deemed required for that
+ * submission.
  *
  * The execbuf3 ioctl directly specifies the batch addresses instead of as
  * object handles as in execbuf2 ioctl. The execbuf3 ioctl will also not
@@ -58,6 +62,13 @@
  * So, a lot of code supporting execbuf2 ioctl, like relocations, VA evictions,
  * vma lookup table, implicit sync, vma active reference tracking etc., are not
  * applicable for execbuf3 ioctl.
+ *
+ * During each execbuf submission, request fence is added to all VM_BIND mapped
+ * objects with DMA_RESV_USAGE_BOOKKEEP. The DMA_RESV_USAGE_BOOKKEEP usage will
+ * prevent over sync (See enum dma_resv_usage). Note that DRM_I915_GEM_WAIT and
+ * DRM_I915_GEM_BUSY ioctls do not check for DMA_RESV_USAGE_BOOKKEEP usage and
+ * hence should not be used for end of batch check. Instead, the execbuf3
+ * timeline out fence should be used for end of batch check.
  */
 
 /**
@@ -129,6 +140,23 @@ eb_find_vma(struct i915_address_space *vm, u64 addr)
return i915_gem_vm_bind_lookup_vma(vm, va);
 }
 
+static void eb_scoop_unbound_vma_all(struct i915_address_space *vm)
+{
+   struct i915_vma *vma, *vn;
+
+   /**
+* Move all unbound vmas back into vm_bind_list so that they are
+* revalidated.
+*/
+   spin_lock(>vm_rebind_lock);
+   list_for_each_entry_safe(vma, vn, >vm_rebind_list, vm_rebind_link) {
+   list_del_init(>vm_rebind_link);
+   if (!list_empty(>vm_bind_link))
+   list_move_tail(>vm_bind_link, >vm_bind_list);
+   }
+   spin_unlock(>vm_rebind_lock);
+}
+
 static int eb_lookup_vma_all(struct i915_execbuffer *eb)
 {
struct i915_vma *vma;
@@ -142,14 +170,108 @@ static int eb_lookup_vma_all(struct i915_execbuffer *eb)
eb->batches[i] = vma;
}
 
+   eb_scoop_unbound_vma_all(eb->context->vm);
+
+   return 0;
+}
+
+static int eb_lock_vma_all(struct i915_execbuffer *eb)
+{
+   struct i915_address_space *vm = eb->context->vm;
+   struct i915_vma *vma;
+   int err;
+
+   err = i915_gem_object_lock(eb->context->vm->root_obj, >ww);
+   if (err)
+   return err;
+
+   list_for_each_entry(vma, >non_priv_vm_bind_list,
+   non_priv_vm_bind_link) {
+   err = i915_gem_object_lock(vma->obj, >ww);
+   if (err)
+   return err;
+   }
+
return 0;
 }
 
+static void eb_release_persistent_vma_all(struct i915_execbuffer *eb)
+{
+   struct i915_address_space *vm = eb->context->vm;
+   struct i915_vma *vma, *vn;
+
+   lockdep_assert_held(>vm_bind_lock);
+
+   if (!(eb->args->flags & __EXEC3_HAS_PIN))
+   return;
+
+   assert_object_held(vm->root_obj);
+
+   list_for_each_entry_safe(vma, vn, >vm_bind_list, vm_bind_link)
+   if (!i915_vma_verify_bind_complete(vma))
+   list_move_tail(>vm_bind_link, >vm_bound_list);
+
+   eb->args->flags &= ~__EXEC3_HAS_PIN;
+}
+
 static void eb_release_vma_all(struct i915_execbuffer *eb)
 {
+   eb_release_persistent_vma_all(eb);
eb_unpin_engine(eb);
 }
 
+static int eb_reserve_fence_for_persistent_vma_all(struct i915_execbuffer *eb)
+{
+   struct i915_address_space *vm = eb->context->vm;
+   u64 num_fences = 1;
+   struct i915_vma *vma;
+   int ret;
+
+   /* Reserve enough slots to accommodate composite fences */
+   if 

[PATCH v8 13/22] drm/i915/vm_bind: Update i915_vma_verify_bind_complete()

2022-11-28 Thread Niranjana Vishwanathapura
Ensure i915_vma_verify_bind_complete() handles case where bind
is not initiated. Also make it non static, add documentation
and move it out of CONFIG_DRM_I915_DEBUG_GEM.

v2: Fix fence leak

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/i915_vma.c | 22 --
 drivers/gpu/drm/i915/i915_vma.h |  1 +
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index c29e22b1cfea..e382c8a6cac4 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -441,12 +441,25 @@ int i915_vma_sync(struct i915_vma *vma)
return i915_vm_sync(vma->vm);
 }
 
-#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
-static int i915_vma_verify_bind_complete(struct i915_vma *vma)
+/**
+ * i915_vma_verify_bind_complete() - Check for the bind completion of the vma
+ * @vma: vma to check for bind completion
+ *
+ * As the fence reference is obtained under RCU, no locking is required by
+ * the caller.
+ *
+ * Returns: 0 if the vma bind is completed. Error code otherwise.
+ */
+int i915_vma_verify_bind_complete(struct i915_vma *vma)
 {
-   struct dma_fence *fence = i915_active_fence_get(>active.excl);
+   struct dma_fence *fence;
int err;
 
+   /* Ensure vma bind is initiated */
+   if (!i915_vma_is_bound(vma, I915_VMA_BIND_MASK))
+   return -EINVAL;
+
+   fence = i915_active_fence_get(>active.excl);
if (!fence)
return 0;
 
@@ -459,9 +472,6 @@ static int i915_vma_verify_bind_complete(struct i915_vma 
*vma)
 
return err;
 }
-#else
-#define i915_vma_verify_bind_complete(_vma) 0
-#endif
 
 I915_SELFTEST_EXPORT void
 i915_vma_resource_init_from_vma(struct i915_vma_resource *vma_res,
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 25e4aa69cd89..9a411a79badd 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -441,6 +441,7 @@ void i915_vma_make_purgeable(struct i915_vma *vma);
 
 int i915_vma_wait_for_bind(struct i915_vma *vma);
 int i915_vma_sync(struct i915_vma *vma);
+int i915_vma_verify_bind_complete(struct i915_vma *vma);
 
 /**
  * i915_vma_get_current_resource - Get the current resource of the vma
-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH v8 07/22] drm/i915/vm_bind: Add support to handle object evictions

2022-11-28 Thread Niranjana Vishwanathapura
Support eviction by maintaining a list of evicted persistent vmas
for rebinding during next submission. Ensure the list do not
include persistent vmas that are being purged.

v2: Remove unused I915_VMA_PURGED definition.
v3: Properly handle __i915_vma_unbind_async() case.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 .../drm/i915/gem/i915_gem_vm_bind_object.c|  6 
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  2 ++
 drivers/gpu/drm/i915/gt/intel_gtt.h   |  4 +++
 drivers/gpu/drm/i915/i915_vma.c   | 31 +--
 drivers/gpu/drm/i915/i915_vma.h   | 10 ++
 drivers/gpu/drm/i915/i915_vma_types.h |  8 +
 6 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
index 4f9df4b756d2..dc738677466b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
@@ -86,6 +86,12 @@ static void i915_gem_vm_bind_remove(struct i915_vma *vma, 
bool release_obj)
 {
lockdep_assert_held(>vm->vm_bind_lock);
 
+   spin_lock(>vm->vm_rebind_lock);
+   if (!list_empty(>vm_rebind_link))
+   list_del_init(>vm_rebind_link);
+   i915_vma_set_purged(vma);
+   spin_unlock(>vm->vm_rebind_lock);
+
list_del_init(>vm_bind_link);
list_del_init(>non_priv_vm_bind_link);
i915_vm_bind_it_remove(vma, >vm->va);
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 542c0f85bf6f..401075776a83 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -291,6 +291,8 @@ void i915_address_space_init(struct i915_address_space *vm, 
int subclass)
INIT_LIST_HEAD(>vm_bound_list);
mutex_init(>vm_bind_lock);
INIT_LIST_HEAD(>non_priv_vm_bind_list);
+   INIT_LIST_HEAD(>vm_rebind_list);
+   spin_lock_init(>vm_rebind_lock);
 }
 
 void *__px_vaddr(struct drm_i915_gem_object *p)
diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h 
b/drivers/gpu/drm/i915/gt/intel_gtt.h
index 8c1b81d2a56c..fc1b2622c66f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.h
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.h
@@ -266,6 +266,10 @@ struct i915_address_space {
struct list_head vm_bind_list;
/** @vm_bound_list: List of vm_binding completed */
struct list_head vm_bound_list;
+   /** @vm_rebind_list: list of vmas to be rebinded */
+   struct list_head vm_rebind_list;
+   /** @vm_rebind_lock: protects vm_rebound_list */
+   spinlock_t vm_rebind_lock;
/** @va: tree of persistent vmas */
struct rb_root_cached va;
/** @non_priv_vm_bind_list: list of non-private object mappings */
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 92dea99cc735..8de9f7a5b306 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -243,6 +243,7 @@ vma_create(struct drm_i915_gem_object *obj,
 
INIT_LIST_HEAD(>vm_bind_link);
INIT_LIST_HEAD(>non_priv_vm_bind_link);
+   INIT_LIST_HEAD(>vm_rebind_link);
return vma;
 
 err_unlock:
@@ -1686,6 +1687,14 @@ static void force_unbind(struct i915_vma *vma)
if (!drm_mm_node_allocated(>node))
return;
 
+   /*
+* Persistent vma should have been purged by now.
+* If not, issue a warning and purge it.
+*/
+   if (GEM_WARN_ON(i915_vma_is_persistent(vma) &&
+   !i915_vma_is_purged(vma)))
+   i915_vma_set_purged(vma);
+
atomic_and(~I915_VMA_PIN_MASK, >flags);
WARN_ON(__i915_vma_unbind(vma));
GEM_BUG_ON(drm_mm_node_allocated(>node));
@@ -2052,6 +2061,16 @@ int __i915_vma_unbind(struct i915_vma *vma)
__i915_vma_evict(vma, false);
 
drm_mm_remove_node(>node); /* pairs with i915_vma_release() */
+
+   if (i915_vma_is_persistent(vma)) {
+   spin_lock(>vm->vm_rebind_lock);
+   if (list_empty(>vm_rebind_link) &&
+   !i915_vma_is_purged(vma))
+   list_add_tail(>vm_rebind_link,
+ >vm->vm_rebind_list);
+   spin_unlock(>vm->vm_rebind_lock);
+   }
+
return 0;
 }
 
@@ -2064,8 +2083,7 @@ static struct dma_fence *__i915_vma_unbind_async(struct 
i915_vma *vma)
if (!drm_mm_node_allocated(>node))
return NULL;
 
-   if (i915_vma_is_pinned(vma) ||
-   >obj->mm.rsgt->table != vma->resource->bi.pages)
+   if (i915_vma_is_pinned(vma))
return ERR_PTR(-EAGAIN);
 
/*
@@ -2087,6 +2105,15 @@ static struct dma_fence *__i915_vma_unbind_async(struct 
i915_vma *vma)
 
drm_mm_remove_node(>node); /* pairs with i915_vma_release() */
 
+   if (i915_vma_is_persistent(vma)) {
+   

[PATCH v8 08/22] drm/i915/vm_bind: Support persistent vma activeness tracking

2022-11-28 Thread Niranjana Vishwanathapura
Do not use i915_vma activeness tracking for persistent vmas.

As persistent vmas are part of working set for each execbuf
submission on that address space (VM), a persistent vma is
active if the VM active. As vm->root_obj->base.resv will be
updated for each submission on that VM, it correctly
represent whether the VM is active or not.

Add i915_vm_is_active() and i915_vm_sync() functions based
on vm->root_obj->base.resv with DMA_RESV_USAGE_BOOKKEEP
usage. dma-resv fence list will be updated with this usage
during each submission with this VM in the new execbuf3
ioctl path.

Update i915_vma_is_active(), i915_vma_sync() and the
__i915_vma_unbind_async() functions to properly handle
persistent vmas.

v2: Ensure lvalue of dma_resv_wait_timeout() call is long.

Reviewed-by: Andi Shyti 
Signed-off-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/i915_gem_gtt.c | 39 +
 drivers/gpu/drm/i915/i915_gem_gtt.h |  3 +++
 drivers/gpu/drm/i915/i915_vma.c | 28 +
 drivers/gpu/drm/i915/i915_vma.h | 25 +-
 4 files changed, 83 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c 
b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 7bd1861ddbdf..1d8506548d4a 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -25,6 +25,45 @@
 #include "i915_trace.h"
 #include "i915_vgpu.h"
 
+/**
+ * i915_vm_sync() - Wait until address space is not in use
+ * @vm: address space
+ *
+ * Waits until all requests using the address space are complete.
+ *
+ * Returns: 0 if success, -ve err code upon failure
+ */
+int i915_vm_sync(struct i915_address_space *vm)
+{
+   long ret;
+
+   /* Wait for all requests under this vm to finish */
+   ret = dma_resv_wait_timeout(vm->root_obj->base.resv,
+   DMA_RESV_USAGE_BOOKKEEP, false,
+   MAX_SCHEDULE_TIMEOUT);
+   if (ret < 0)
+   return ret;
+   else if (ret > 0)
+   return 0;
+   else
+   return -ETIMEDOUT;
+}
+
+/**
+ * i915_vm_is_active() - Check if address space is being used
+ * @vm: address space
+ *
+ * Check if any request using the specified address space is
+ * active.
+ *
+ * Returns: true if address space is active, false otherwise.
+ */
+bool i915_vm_is_active(const struct i915_address_space *vm)
+{
+   return !dma_resv_test_signaled(vm->root_obj->base.resv,
+  DMA_RESV_USAGE_BOOKKEEP);
+}
+
 int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
   struct sg_table *pages)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h 
b/drivers/gpu/drm/i915/i915_gem_gtt.h
index 8c2f57eb5dda..a5bbdc59d9df 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.h
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.h
@@ -51,4 +51,7 @@ int i915_gem_gtt_insert(struct i915_address_space *vm,
 
 #define PIN_OFFSET_MASKI915_GTT_PAGE_MASK
 
+int i915_vm_sync(struct i915_address_space *vm);
+bool i915_vm_is_active(const struct i915_address_space *vm);
+
 #endif
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 8de9f7a5b306..9f284c3c6339 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -422,6 +422,24 @@ int i915_vma_wait_for_bind(struct i915_vma *vma)
return err;
 }
 
+/**
+ * i915_vma_sync() - Wait for the vma to be idle
+ * @vma: vma to be tested
+ *
+ * Returns 0 on success and error code on failure
+ */
+int i915_vma_sync(struct i915_vma *vma)
+{
+   int ret;
+
+   /* Wait for the asynchronous bindings and pending GPU reads */
+   ret = i915_active_wait(>active);
+   if (ret || !i915_vma_is_persistent(vma) || i915_vma_is_purged(vma))
+   return ret;
+
+   return i915_vm_sync(vma->vm);
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
 static int i915_vma_verify_bind_complete(struct i915_vma *vma)
 {
@@ -1887,6 +1905,8 @@ int _i915_vma_move_to_active(struct i915_vma *vma,
int err;
 
assert_object_held(obj);
+   if (i915_vma_is_persistent(vma))
+   return -EINVAL;
 
GEM_BUG_ON(!vma->pages);
 
@@ -2101,6 +2121,14 @@ static struct dma_fence *__i915_vma_unbind_async(struct 
i915_vma *vma)
return ERR_PTR(-EBUSY);
}
 
+   if (i915_vma_is_persistent(vma) &&
+   __i915_sw_fence_await_reservation(>resource->chain,
+ vma->vm->root_obj->base.resv,
+ DMA_RESV_USAGE_BOOKKEEP,
+ i915_fence_timeout(vma->vm->i915),
+ GFP_NOWAIT | __GFP_NOWARN) < 0)
+   return ERR_PTR(-EBUSY);
+
fence = __i915_vma_evict(vma, true);
 
drm_mm_remove_node(>node); /* pairs with i915_vma_release() */
diff --git 

[PATCH v8 14/22] drm/i915/vm_bind: Expose i915_request_await_bind()

2022-11-28 Thread Niranjana Vishwanathapura
Rename __i915_request_await_bind() as i915_request_await_bind()
and make it non-static as it will be used in execbuf3 ioctl path.

v2: add documentation

Reviewed-by: Matthew Auld 
Reviewed-by: Andi Shyti 
Signed-off-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/i915_vma.c |  8 +---
 drivers/gpu/drm/i915/i915_vma.h | 16 
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index e382c8a6cac4..931277dfe706 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1893,18 +1893,12 @@ void i915_vma_revoke_mmap(struct i915_vma *vma)
list_del(>obj->userfault_link);
 }
 
-static int
-__i915_request_await_bind(struct i915_request *rq, struct i915_vma *vma)
-{
-   return __i915_request_await_exclusive(rq, >active);
-}
-
 static int __i915_vma_move_to_active(struct i915_vma *vma, struct i915_request 
*rq)
 {
int err;
 
/* Wait for the vma to be bound before we start! */
-   err = __i915_request_await_bind(rq, vma);
+   err = i915_request_await_bind(rq, vma);
if (err)
return err;
 
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 9a411a79badd..1ecc71cf2698 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -55,6 +55,22 @@ void i915_vma_unpin_and_release(struct i915_vma **p_vma, 
unsigned int flags);
 #define __EXEC_OBJECT_NO_RESERVE BIT(31)
 #define __EXEC_OBJECT_NO_REQUEST_AWAIT BIT(30)
 
+/**
+ * i915_request_await_bind() - Setup request to wait for a vma bind completion
+ * @rq: the request which should wait
+ * @vma: vma whose binding @rq should wait to complete
+ *
+ * Setup the request @rq to asynchronously wait for @vma bind to complete
+ * before starting execution.
+ *
+ * Returns 0 on success, error code on failure.
+ */
+static inline int
+i915_request_await_bind(struct i915_request *rq, struct i915_vma *vma)
+{
+   return __i915_request_await_exclusive(rq, >active);
+}
+
 int __must_check _i915_vma_move_to_active(struct i915_vma *vma,
  struct i915_request *rq,
  struct dma_fence *fence,
-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH v8 17/22] drm/i915/vm_bind: Limit vm_bind mode to non-recoverable contexts

2022-11-28 Thread Niranjana Vishwanathapura
Only support vm_bind mode with non-recoverable contexts.
With new vm_bind mode with eb3 submission path, we need not
support older recoverable contexts.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 7d3366975e6d..a048bf463916 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -1617,6 +1617,12 @@ i915_gem_create_context(struct drm_i915_private *i915,
INIT_LIST_HEAD(>stale.engines);
 
if (pc->vm) {
+   /* Only non-recoverable contexts are allowed in vm_bind mode */
+   if (i915_gem_vm_is_vm_bind_mode(pc->vm) &&
+   (pc->user_flags & BIT(UCONTEXT_RECOVERABLE))) {
+   err = -EINVAL;
+   goto err_ctx;
+   }
vm = i915_vm_get(pc->vm);
} else if (HAS_FULL_PPGTT(i915)) {
struct i915_ppgtt *ppgtt;
-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH v8 09/22] drm/i915/vm_bind: Add out fence support

2022-11-28 Thread Niranjana Vishwanathapura
Add support for handling out fence for vm_bind call.

v2: Reset vma->vm_bind_fence.syncobj to NULL at the end
of vm_bind call.
v3: Remove vm_unbind out fence uapi which is not supported yet.
v4: Return error if I915_TIMELINE_FENCE_WAIT fence flag is set.
Wait for bind to complete iff I915_TIMELINE_FENCE_SIGNAL is
not specified.
v5: Ensure __I915_TIMELINE_FENCE_UNKNOWN_FLAGS are not set.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h   |  4 +
 .../drm/i915/gem/i915_gem_vm_bind_object.c| 98 ++-
 drivers/gpu/drm/i915/i915_vma.c   |  7 +-
 drivers/gpu/drm/i915/i915_vma_types.h |  7 ++
 include/uapi/drm/i915_drm.h   | 58 ++-
 5 files changed, 165 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h 
b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h
index 36262a6357b5..b70e900e35ab 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h
@@ -8,6 +8,7 @@
 
 #include 
 
+struct dma_fence;
 struct drm_device;
 struct drm_file;
 struct i915_address_space;
@@ -23,4 +24,7 @@ int i915_gem_vm_unbind_ioctl(struct drm_device *dev, void 
*data,
 
 void i915_gem_vm_unbind_all(struct i915_address_space *vm);
 
+void i915_vm_bind_signal_fence(struct i915_vma *vma,
+  struct dma_fence * const fence);
+
 #endif /* __I915_GEM_VM_BIND_H */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
index dc738677466b..fd1d82ce99e6 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
@@ -7,6 +7,8 @@
 
 #include 
 
+#include 
+
 #include "gem/i915_gem_context.h"
 #include "gem/i915_gem_vm_bind.h"
 
@@ -101,6 +103,77 @@ static void i915_gem_vm_bind_remove(struct i915_vma *vma, 
bool release_obj)
i915_gem_object_put(vma->obj);
 }
 
+static int i915_vm_bind_add_fence(struct drm_file *file, struct i915_vma *vma,
+ u32 handle, u64 point)
+{
+   struct drm_syncobj *syncobj;
+
+   syncobj = drm_syncobj_find(file, handle);
+   if (!syncobj) {
+   drm_dbg(>vm->i915->drm,
+   "Invalid syncobj handle provided\n");
+   return -ENOENT;
+   }
+
+   /*
+* For timeline syncobjs we need to preallocate chains for
+* later signaling.
+*/
+   if (point) {
+   vma->vm_bind_fence.chain_fence = dma_fence_chain_alloc();
+   if (!vma->vm_bind_fence.chain_fence) {
+   drm_syncobj_put(syncobj);
+   return -ENOMEM;
+   }
+   } else {
+   vma->vm_bind_fence.chain_fence = NULL;
+   }
+   vma->vm_bind_fence.syncobj = syncobj;
+   vma->vm_bind_fence.value = point;
+
+   return 0;
+}
+
+static void i915_vm_bind_put_fence(struct i915_vma *vma)
+{
+   if (!vma->vm_bind_fence.syncobj)
+   return;
+
+   drm_syncobj_put(vma->vm_bind_fence.syncobj);
+   dma_fence_chain_free(vma->vm_bind_fence.chain_fence);
+   vma->vm_bind_fence.syncobj = NULL;
+}
+
+/**
+ * i915_vm_bind_signal_fence() - Add fence to vm_bind syncobj
+ * @vma: vma mapping requiring signaling
+ * @fence: fence to be added
+ *
+ * Associate specified @fence with the @vma's syncobj to be
+ * signaled after the @fence work completes.
+ */
+void i915_vm_bind_signal_fence(struct i915_vma *vma,
+  struct dma_fence * const fence)
+{
+   struct drm_syncobj *syncobj = vma->vm_bind_fence.syncobj;
+
+   if (!syncobj)
+   return;
+
+   if (vma->vm_bind_fence.chain_fence) {
+   drm_syncobj_add_point(syncobj,
+ vma->vm_bind_fence.chain_fence,
+ fence, vma->vm_bind_fence.value);
+   /*
+* The chain's ownership is transferred to the
+* timeline.
+*/
+   vma->vm_bind_fence.chain_fence = NULL;
+   } else {
+   drm_syncobj_replace_fence(syncobj, fence);
+   }
+}
+
 static int i915_gem_vm_unbind_vma(struct i915_address_space *vm,
  struct drm_i915_gem_vm_unbind *va)
 {
@@ -206,6 +279,11 @@ static int i915_gem_vm_bind_obj(struct i915_address_space 
*vm,
if (!va->length || !IS_ALIGNED(va->start, I915_GTT_PAGE_SIZE))
ret = -EINVAL;
 
+   /* In fences are not supported */
+   if ((va->fence.flags & I915_TIMELINE_FENCE_WAIT) ||
+   (va->fence.flags & __I915_TIMELINE_FENCE_UNKNOWN_FLAGS))
+   ret = -EINVAL;
+
obj = i915_gem_object_lookup(file, va->handle);
if (!obj)
return -ENOENT;
@@ -238,6 +316,13 @@ static int 

[PATCH v8 16/22] drm/i915/vm_bind: userptr dma-resv changes

2022-11-28 Thread Niranjana Vishwanathapura
For persistent (vm_bind) vmas of userptr BOs, handle the user
page pinning by using the i915_gem_object_userptr_submit_init()
/done() functions

v2: Do not double add vma to vm->userptr_invalidated_list
v3: Initialize vma->userptr_invalidated_link

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer3.c   | 84 ++-
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c   | 19 +
 .../drm/i915/gem/i915_gem_vm_bind_object.c| 15 
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  2 +
 drivers/gpu/drm/i915/gt/intel_gtt.h   |  4 +
 drivers/gpu/drm/i915/i915_vma.c   |  1 +
 drivers/gpu/drm/i915/i915_vma_types.h |  2 +
 7 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
index 913b1f8bda9f..a1aee477e2df 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
@@ -20,6 +20,7 @@
 #include "i915_gem_vm_bind.h"
 #include "i915_trace.h"
 
+#define __EXEC3_USERPTR_USED   BIT_ULL(34)
 #define __EXEC3_HAS_PINBIT_ULL(33)
 #define __EXEC3_ENGINE_PINNED  BIT_ULL(32)
 #define __EXEC3_INTERNAL_FLAGS (~0ull << 32)
@@ -144,7 +145,22 @@ static void eb_scoop_unbound_vma_all(struct 
i915_address_space *vm)
 {
struct i915_vma *vma, *vn;
 
-   /**
+#ifdef CONFIG_MMU_NOTIFIER
+   /*
+* Move all invalidated userptr vmas back into vm_bind_list so that
+* they are looked up and revalidated.
+*/
+   spin_lock(>userptr_invalidated_lock);
+   list_for_each_entry_safe(vma, vn, >userptr_invalidated_list,
+userptr_invalidated_link) {
+   list_del_init(>userptr_invalidated_link);
+   if (!list_empty(>vm_bind_link))
+   list_move_tail(>vm_bind_link, >vm_bind_list);
+   }
+   spin_unlock(>userptr_invalidated_lock);
+#endif
+
+   /*
 * Move all unbound vmas back into vm_bind_list so that they are
 * revalidated.
 */
@@ -157,10 +173,47 @@ static void eb_scoop_unbound_vma_all(struct 
i915_address_space *vm)
spin_unlock(>vm_rebind_lock);
 }
 
+static int eb_lookup_persistent_userptr_vmas(struct i915_execbuffer *eb)
+{
+   struct i915_address_space *vm = eb->context->vm;
+   struct i915_vma *last_vma = NULL;
+   struct i915_vma *vma;
+   int err;
+
+   lockdep_assert_held(>vm_bind_lock);
+
+   list_for_each_entry(vma, >vm_bind_list, vm_bind_link) {
+   if (!i915_gem_object_is_userptr(vma->obj))
+   continue;
+
+   err = i915_gem_object_userptr_submit_init(vma->obj);
+   if (err)
+   return err;
+
+   /*
+* The above submit_init() call does the object unbind and
+* hence adds vma into vm_rebind_list. Remove it from that
+* list as it is already scooped for revalidation.
+*/
+   spin_lock(>vm_rebind_lock);
+   if (!list_empty(>vm_rebind_link))
+   list_del_init(>vm_rebind_link);
+   spin_unlock(>vm_rebind_lock);
+
+   last_vma = vma;
+   }
+
+   if (last_vma)
+   eb->args->flags |= __EXEC3_USERPTR_USED;
+
+   return 0;
+}
+
 static int eb_lookup_vma_all(struct i915_execbuffer *eb)
 {
struct i915_vma *vma;
unsigned int i;
+   int err = 0;
 
for (i = 0; i < eb->num_batches; i++) {
vma = eb_find_vma(eb->context->vm, eb->batch_addresses[i]);
@@ -172,6 +225,10 @@ static int eb_lookup_vma_all(struct i915_execbuffer *eb)
 
eb_scoop_unbound_vma_all(eb->context->vm);
 
+   err = eb_lookup_persistent_userptr_vmas(eb);
+   if (err)
+   return err;
+
return 0;
 }
 
@@ -344,6 +401,29 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
}
}
 
+#ifdef CONFIG_MMU_NOTIFIER
+   /* Check for further userptr invalidations */
+   spin_lock(>userptr_invalidated_lock);
+   if (!list_empty(>userptr_invalidated_list))
+   err = -EAGAIN;
+   spin_unlock(>userptr_invalidated_lock);
+
+   if (!err && (eb->args->flags & __EXEC3_USERPTR_USED)) {
+   read_lock(>i915->mm.notifier_lock);
+   list_for_each_entry(vma, >vm_bind_list, vm_bind_link) {
+   if (!i915_gem_object_is_userptr(vma->obj))
+   continue;
+
+   err = i915_gem_object_userptr_submit_done(vma->obj);
+   if (err)
+   break;
+   }
+   read_unlock(>i915->mm.notifier_lock);
+   }
+#endif
+   if (unlikely(err))
+   goto err_skip;
+

[PATCH v8 03/22] drm/i915/vm_bind: Expose i915_gem_object_max_page_size()

2022-11-28 Thread Niranjana Vishwanathapura
Expose i915_gem_object_max_page_size() function non-static
which will be used by the vm_bind feature.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 18 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.h |  2 ++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 33673fe7ee0a..5c6e396ab74d 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -15,10 +15,18 @@
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
 
-static u32 object_max_page_size(struct intel_memory_region **placements,
-   unsigned int n_placements)
+/**
+ * i915_gem_object_max_page_size() - max of min_page_size of the regions
+ * @placements:  list of regions
+ * @n_placements: number of the placements
+ *
+ * Returns the largest of min_page_size of the @placements,
+ * or I915_GTT_PAGE_SIZE_4K if @n_placements is 0.
+ */
+u32 i915_gem_object_max_page_size(struct intel_memory_region **placements,
+ unsigned int n_placements)
 {
-   u32 max_page_size = 0;
+   u32 max_page_size = I915_GTT_PAGE_SIZE_4K;
int i;
 
for (i = 0; i < n_placements; i++) {
@@ -28,7 +36,6 @@ static u32 object_max_page_size(struct intel_memory_region 
**placements,
max_page_size = max_t(u32, max_page_size, mr->min_page_size);
}
 
-   GEM_BUG_ON(!max_page_size);
return max_page_size;
 }
 
@@ -99,7 +106,8 @@ __i915_gem_object_create_user_ext(struct drm_i915_private 
*i915, u64 size,
 
i915_gem_flush_free_objects(i915);
 
-   size = round_up(size, object_max_page_size(placements, n_placements));
+   size = round_up(size, i915_gem_object_max_page_size(placements,
+   n_placements));
if (size == 0)
return ERR_PTR(-EINVAL);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 3db53769864c..5455ca0eabe9 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -47,6 +47,8 @@ static inline bool i915_gem_object_size_2big(u64 size)
 }
 
 void i915_gem_init__objects(struct drm_i915_private *i915);
+u32 i915_gem_object_max_page_size(struct intel_memory_region **placements,
+ unsigned int n_placements);
 
 void i915_objects_module_exit(void);
 int i915_objects_module_init(void);
-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH v8 10/22] drm/i915/vm_bind: Abstract out common execbuf functions

2022-11-28 Thread Niranjana Vishwanathapura
The new execbuf3 ioctl path and the legacy execbuf ioctl
paths have many common functionalities.
Abstract out the common execbuf functionalities into a
separate file where possible, thus allowing code sharing.

v2: Use drm_dbg instead of DRM_DEBUG

Reviewed-by: Andi Shyti 
Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../drm/i915/gem/i915_gem_execbuffer_common.c | 671 ++
 .../drm/i915/gem/i915_gem_execbuffer_common.h |  76 ++
 3 files changed, 748 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_execbuffer_common.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_execbuffer_common.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 71d5c992..81ce17f4406b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -150,6 +150,7 @@ gem-y += \
gem/i915_gem_create.o \
gem/i915_gem_dmabuf.o \
gem/i915_gem_domain.o \
+   gem/i915_gem_execbuffer_common.o \
gem/i915_gem_execbuffer.o \
gem/i915_gem_internal.o \
gem/i915_gem_object.o \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer_common.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer_common.c
new file mode 100644
index ..fb1364f08a61
--- /dev/null
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer_common.c
@@ -0,0 +1,671 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include 
+
+#include 
+
+#include "gt/intel_context.h"
+#include "gt/intel_gt.h"
+#include "gt/intel_gt_pm.h"
+#include "gt/intel_ring.h"
+
+#include "i915_drv.h"
+#include "i915_gem_execbuffer_common.h"
+
+#define __EXEC_COMMON_FENCE_WAIT   BIT(0)
+#define __EXEC_COMMON_FENCE_SIGNAL BIT(1)
+
+static struct i915_request *eb_throttle(struct intel_context *ce)
+{
+   struct intel_ring *ring = ce->ring;
+   struct intel_timeline *tl = ce->timeline;
+   struct i915_request *rq;
+
+   /*
+* Completely unscientific finger-in-the-air estimates for suitable
+* maximum user request size (to avoid blocking) and then backoff.
+*/
+   if (intel_ring_update_space(ring) >= PAGE_SIZE)
+   return NULL;
+
+   /*
+* Find a request that after waiting upon, there will be at least half
+* the ring available. The hysteresis allows us to compete for the
+* shared ring and should mean that we sleep less often prior to
+* claiming our resources, but not so long that the ring completely
+* drains before we can submit our next request.
+*/
+   list_for_each_entry(rq, >requests, link) {
+   if (rq->ring != ring)
+   continue;
+
+   if (__intel_ring_space(rq->postfix,
+  ring->emit, ring->size) > ring->size / 2)
+   break;
+   }
+   if (>link == >requests)
+   return NULL; /* weird, we will check again later for real */
+
+   return i915_request_get(rq);
+}
+
+static int eb_pin_timeline(struct intel_context *ce, bool throttle,
+  bool nonblock)
+{
+   struct intel_timeline *tl;
+   struct i915_request *rq = NULL;
+
+   /*
+* Take a local wakeref for preparing to dispatch the execbuf as
+* we expect to access the hardware fairly frequently in the
+* process, and require the engine to be kept awake between accesses.
+* Upon dispatch, we acquire another prolonged wakeref that we hold
+* until the timeline is idle, which in turn releases the wakeref
+* taken on the engine, and the parent device.
+*/
+   tl = intel_context_timeline_lock(ce);
+   if (IS_ERR(tl))
+   return PTR_ERR(tl);
+
+   intel_context_enter(ce);
+   if (throttle)
+   rq = eb_throttle(ce);
+   intel_context_timeline_unlock(tl);
+
+   if (rq) {
+   long timeout = nonblock ? 0 : MAX_SCHEDULE_TIMEOUT;
+
+   if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE,
+ timeout) < 0) {
+   i915_request_put(rq);
+
+   /*
+* Error path, cannot use intel_context_timeline_lock as
+* that is user interruptable and this clean up step
+* must be done.
+*/
+   mutex_lock(>timeline->mutex);
+   intel_context_exit(ce);
+   mutex_unlock(>timeline->mutex);
+
+   if (nonblock)
+   return -EWOULDBLOCK;
+   else
+   return -EINTR;
+   }
+   i915_request_put(rq);
+   }
+
+   return 0;
+}
+
+/**
+ * i915_eb_pin_engine() - Pin the engine
+ * @ce: 

[PATCH v8 11/22] drm/i915/vm_bind: Use common execbuf functions in execbuf path

2022-11-28 Thread Niranjana Vishwanathapura
Update the execbuf path to use common execbuf functions to
reduce code duplication with the newer execbuf3 path.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 513 ++
 1 file changed, 39 insertions(+), 474 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index aeb591d38a20..d8fa37acfba1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -28,6 +28,7 @@
 #include "i915_file_private.h"
 #include "i915_gem_clflush.h"
 #include "i915_gem_context.h"
+#include "i915_gem_execbuffer_common.h"
 #include "i915_gem_evict.h"
 #include "i915_gem_ioctls.h"
 #include "i915_reg.h"
@@ -236,13 +237,6 @@ enum {
  * the batchbuffer in trusted mode, otherwise the ioctl is rejected.
  */
 
-struct eb_fence {
-   struct drm_syncobj *syncobj; /* Use with ptr_mask_bits() */
-   struct dma_fence *dma_fence;
-   u64 value;
-   struct dma_fence_chain *chain_fence;
-};
-
 struct i915_execbuffer {
struct drm_i915_private *i915; /** i915 backpointer */
struct drm_file *file; /** per-file lookup tables and limits */
@@ -2449,164 +2443,29 @@ static const enum intel_engine_id user_ring_map[] = {
[I915_EXEC_VEBOX]   = VECS0
 };
 
-static struct i915_request *eb_throttle(struct i915_execbuffer *eb, struct 
intel_context *ce)
-{
-   struct intel_ring *ring = ce->ring;
-   struct intel_timeline *tl = ce->timeline;
-   struct i915_request *rq;
-
-   /*
-* Completely unscientific finger-in-the-air estimates for suitable
-* maximum user request size (to avoid blocking) and then backoff.
-*/
-   if (intel_ring_update_space(ring) >= PAGE_SIZE)
-   return NULL;
-
-   /*
-* Find a request that after waiting upon, there will be at least half
-* the ring available. The hysteresis allows us to compete for the
-* shared ring and should mean that we sleep less often prior to
-* claiming our resources, but not so long that the ring completely
-* drains before we can submit our next request.
-*/
-   list_for_each_entry(rq, >requests, link) {
-   if (rq->ring != ring)
-   continue;
-
-   if (__intel_ring_space(rq->postfix,
-  ring->emit, ring->size) > ring->size / 2)
-   break;
-   }
-   if (>link == >requests)
-   return NULL; /* weird, we will check again later for real */
-
-   return i915_request_get(rq);
-}
-
-static int eb_pin_timeline(struct i915_execbuffer *eb, struct intel_context 
*ce,
-  bool throttle)
-{
-   struct intel_timeline *tl;
-   struct i915_request *rq = NULL;
-
-   /*
-* Take a local wakeref for preparing to dispatch the execbuf as
-* we expect to access the hardware fairly frequently in the
-* process, and require the engine to be kept awake between accesses.
-* Upon dispatch, we acquire another prolonged wakeref that we hold
-* until the timeline is idle, which in turn releases the wakeref
-* taken on the engine, and the parent device.
-*/
-   tl = intel_context_timeline_lock(ce);
-   if (IS_ERR(tl))
-   return PTR_ERR(tl);
-
-   intel_context_enter(ce);
-   if (throttle)
-   rq = eb_throttle(eb, ce);
-   intel_context_timeline_unlock(tl);
-
-   if (rq) {
-   bool nonblock = eb->file->filp->f_flags & O_NONBLOCK;
-   long timeout = nonblock ? 0 : MAX_SCHEDULE_TIMEOUT;
-
-   if (i915_request_wait(rq, I915_WAIT_INTERRUPTIBLE,
- timeout) < 0) {
-   i915_request_put(rq);
-
-   /*
-* Error path, cannot use intel_context_timeline_lock as
-* that is user interruptable and this clean up step
-* must be done.
-*/
-   mutex_lock(>timeline->mutex);
-   intel_context_exit(ce);
-   mutex_unlock(>timeline->mutex);
-
-   if (nonblock)
-   return -EWOULDBLOCK;
-   else
-   return -EINTR;
-   }
-   i915_request_put(rq);
-   }
-
-   return 0;
-}
-
 static int eb_pin_engine(struct i915_execbuffer *eb, bool throttle)
 {
-   struct intel_context *ce = eb->context, *child;
int err;
-   int i = 0, j = 0;
 
GEM_BUG_ON(eb->args->flags & __EXEC_ENGINE_PINNED);
 
-   if (unlikely(intel_context_is_banned(ce)))
-   return -EIO;
-
-   /*
-* Pinning the contexts may generate requests in 

[PATCH v8 12/22] drm/i915/vm_bind: Implement I915_GEM_EXECBUFFER3 ioctl

2022-11-28 Thread Niranjana Vishwanathapura
Implement new execbuf3 ioctl (I915_GEM_EXECBUFFER3) which only
works in vm_bind mode. The vm_bind mode only works with
this new execbuf3 ioctl.

The new execbuf3 ioctl will not have any list of objects to validate
bind as all required objects binding would have been requested by the
userspace before submitting the execbuf3.

Legacy features like relocations etc are not supported by execbuf3.

v2: Add more input validity checks.
v3: batch_address is a VA (not an array) if num_batches=1,
minor cleanup
v4: replace vm->vm_bind_mode check with i915_gem_vm_is_vm_bind_mode()
v5: Remove unwanted krealloc() and address other review comments.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer3.c   | 579 ++
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h|   2 +
 drivers/gpu/drm/i915/i915_driver.c|   1 +
 include/uapi/drm/i915_drm.h   |  61 ++
 5 files changed, 644 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 81ce17f4406b..e5a4cf20839b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -152,6 +152,7 @@ gem-y += \
gem/i915_gem_domain.o \
gem/i915_gem_execbuffer_common.o \
gem/i915_gem_execbuffer.o \
+   gem/i915_gem_execbuffer3.o \
gem/i915_gem_internal.o \
gem/i915_gem_object.o \
gem/i915_gem_lmem.o \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
new file mode 100644
index ..49045858a3e9
--- /dev/null
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
@@ -0,0 +1,579 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#include 
+#include 
+
+#include 
+
+#include "gt/intel_context.h"
+#include "gt/intel_gpu_commands.h"
+#include "gt/intel_gt.h"
+
+#include "i915_drv.h"
+#include "i915_gem_context.h"
+#include "i915_gem_execbuffer_common.h"
+#include "i915_gem_ioctls.h"
+#include "i915_gem_vm_bind.h"
+#include "i915_trace.h"
+
+#define __EXEC3_ENGINE_PINNED  BIT_ULL(32)
+#define __EXEC3_INTERNAL_FLAGS (~0ull << 32)
+
+/* Catch emission of unexpected errors for CI! */
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+#undef EINVAL
+#define EINVAL ({ \
+   DRM_DEBUG_DRIVER("EINVAL at %s:%d\n", __func__, __LINE__); \
+   22; \
+})
+#endif
+
+/**
+ * DOC: User command execution 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.
+ *
+ * The new execbuf3 ioctl only works in VM_BIND mode and the VM_BIND mode only
+ * works with execbuf3 ioctl for submission.
+ *
+ * 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 etc. (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 check the
+ * dma-resv object's fence list for that.
+ *
+ * So, a lot of code supporting execbuf2 ioctl, like relocations, VA evictions,
+ * vma lookup table, implicit sync, vma active reference tracking etc., are not
+ * applicable for execbuf3 ioctl.
+ */
+
+/**
+ * struct i915_execbuffer - execbuf struct for execbuf3
+ * @i915: reference to the i915 instance we run on
+ * @file: drm file reference
+ * @args: execbuf3 ioctl structure
+ * @gt: reference to the gt instance ioctl submitted for
+ * @context: logical state for the request
+ * @gem_context: callers context
+ * @requests: requests to be build
+ * @composite_fence: used for excl fence in dma_resv objects when > 1 BB 
submitted
+ * @ww: i915_gem_ww_ctx instance
+ * @num_batches: number of batches submitted
+ * @batch_addresses: addresses corresponds to the submitted batches
+ * @batches: references to the i915_vmas corresponding to the batches
+ * @fences: array of execbuf fences (See struct eb_fence)
+ * @num_fences: number of fences in @fences array
+ */
+struct i915_execbuffer {
+   struct drm_i915_private *i915;
+   struct drm_file *file;
+   struct drm_i915_gem_execbuffer3 *args;
+
+   

[PATCH v8 05/22] drm/i915/vm_bind: Implement bind and unbind of object

2022-11-28 Thread Niranjana Vishwanathapura
Add uapi and implement support for bind and unbind of an
object at the specified GPU virtual addresses.

The vm_bind mode is not supported in legacy execbuf2 ioctl.
It will be supported only in the newer execbuf3 ioctl.

v2: On older platforms ctx->vm is not set, check for it.
In vm_bind call, add vma to vm_bind_list.
Add more input validity checks.
Update some documentation.
v3: In vm_bind call, add vma to vm_bound_list as user can
request a fence and pass to execbuf3 as input fence.
Remove short term pinning with PIN_VALIDATE flag.
v4: Replace vm->vm_bind_mode check with i915_gem_vm_is_vm_bind_mode().
v5: Ensure all reserved fields are 0, use PIN_NOEVICT.
v6: Add reserved fields to drm_i915_gem_vm_bind.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Prathap Kumar Valsan 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/Makefile |   1 +
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |  15 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c|   5 +
 drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h   |  26 ++
 .../drm/i915/gem/i915_gem_vm_bind_object.c| 330 ++
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  10 +
 drivers/gpu/drm/i915/gt/intel_gtt.h   |   9 +
 drivers/gpu/drm/i915/i915_driver.c|   3 +
 drivers/gpu/drm/i915/i915_vma.c   |   1 +
 drivers/gpu/drm/i915/i915_vma_types.h |  14 +
 include/uapi/drm/i915_drm.h   | 105 ++
 11 files changed, 519 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 01974b82d205..71d5c992 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -168,6 +168,7 @@ gem-y += \
gem/i915_gem_ttm_move.o \
gem/i915_gem_ttm_pm.o \
gem/i915_gem_userptr.o \
+   gem/i915_gem_vm_bind_object.o \
gem/i915_gem_wait.o \
gem/i915_gemfs.o
 i915-y += \
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h 
b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index 899fa8f1e0fe..e8b41aa8f8c4 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -139,6 +139,21 @@ int i915_gem_context_setparam_ioctl(struct drm_device 
*dev, void *data,
 int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file);
 
+/**
+ * i915_gem_vm_is_vm_bind_mode() - Check if address space is in vm_bind mode
+ * @vm: the address space
+ *
+ * Returns:
+ * true: @vm is in vm_bind mode; allows only vm_bind method of binding.
+ * false: @vm is not in vm_bind mode; allows only legacy execbuff method
+ *of binding.
+ */
+static inline bool i915_gem_vm_is_vm_bind_mode(struct i915_address_space *vm)
+{
+   /* No support to enable vm_bind mode yet */
+   return false;
+}
+
 struct i915_address_space *
 i915_gem_vm_lookup(struct drm_i915_file_private *file_priv, u32 id);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 29e9e8d5b6fe..6fdb7ce09afc 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -782,6 +782,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
if (unlikely(IS_ERR(ctx)))
return PTR_ERR(ctx);
 
+   if (ctx->vm && i915_gem_vm_is_vm_bind_mode(ctx->vm)) {
+   i915_gem_context_put(ctx);
+   return -EOPNOTSUPP;
+   }
+
eb->gem_context = ctx;
if (i915_gem_context_has_full_ppgtt(ctx))
eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h 
b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h
new file mode 100644
index ..36262a6357b5
--- /dev/null
+++ b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2022 Intel Corporation
+ */
+
+#ifndef __I915_GEM_VM_BIND_H
+#define __I915_GEM_VM_BIND_H
+
+#include 
+
+struct drm_device;
+struct drm_file;
+struct i915_address_space;
+struct i915_vma;
+
+struct i915_vma *
+i915_gem_vm_bind_lookup_vma(struct i915_address_space *vm, u64 va);
+
+int i915_gem_vm_bind_ioctl(struct drm_device *dev, void *data,
+  struct drm_file *file);
+int i915_gem_vm_unbind_ioctl(struct drm_device *dev, void *data,
+struct drm_file *file);
+
+void i915_gem_vm_unbind_all(struct i915_address_space *vm);
+
+#endif /* __I915_GEM_VM_BIND_H */
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c 
b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c
new file mode 100644
index ..5064aba9ab87
--- /dev/null
+++ b/drivers/gpu/drm/i915/gem/i915_gem_vm_bind_object.c

[PATCH v8 01/22] drm/i915/vm_bind: Expose vm lookup function

2022-11-28 Thread Niranjana Vishwanathapura
Make i915_gem_vm_lookup() function non-static as it will be
used by the vm_bind feature.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c | 11 ++-
 drivers/gpu/drm/i915/gem/i915_gem_context.h |  3 +++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c 
b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index 7f2831efc798..3a696f61af92 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -346,7 +346,16 @@ static int proto_context_register(struct 
drm_i915_file_private *fpriv,
return ret;
 }
 
-static struct i915_address_space *
+/**
+ * i915_gem_vm_lookup() - looks up for the VM reference given the vm id
+ * @file_priv: the private data associated with the user's file
+ * @id: the VM id
+ *
+ * Finds the VM reference associated to a specific id.
+ *
+ * Returns the VM pointer on success, NULL in case of failure.
+ */
+struct i915_address_space *
 i915_gem_vm_lookup(struct drm_i915_file_private *file_priv, u32 id)
 {
struct i915_address_space *vm;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h 
b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index e5b0f66ea1fe..899fa8f1e0fe 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -139,6 +139,9 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, 
void *data,
 int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
   struct drm_file *file);
 
+struct i915_address_space *
+i915_gem_vm_lookup(struct drm_i915_file_private *file_priv, u32 id);
+
 struct i915_gem_context *
 i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id);
 
-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH v8 04/22] drm/i915/vm_bind: Add support to create persistent vma

2022-11-28 Thread Niranjana Vishwanathapura
Add i915_vma_instance_persistent() to create persistent vmas.
Persistent vmas will use i915_gtt_view to support partial binding.

vma_lookup is tied to segment of the object instead of section
of VA space. Hence, it do not support aliasing. ie., multiple
mappings (at different VA) point to the same gtt_view of object.
Skip vma_lookup for persistent vmas to support aliasing.

v2: Remove unused I915_VMA_PERSISTENT definition,
update validity check in i915_vma_compare(),
remove unwanted is_persistent check in release_references().

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
Signed-off-by: Andi Shyti 
---
 drivers/gpu/drm/i915/i915_vma.c   | 36 +--
 drivers/gpu/drm/i915/i915_vma.h   | 17 -
 drivers/gpu/drm/i915/i915_vma_types.h |  6 +
 3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index 726705b10637..9462a29764eb 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -111,7 +111,8 @@ static void __i915_vma_retire(struct i915_active *ref)
 static struct i915_vma *
 vma_create(struct drm_i915_gem_object *obj,
   struct i915_address_space *vm,
-  const struct i915_gtt_view *view)
+  const struct i915_gtt_view *view,
+  bool skip_lookup_cache)
 {
struct i915_vma *pos = ERR_PTR(-E2BIG);
struct i915_vma *vma;
@@ -198,6 +199,9 @@ vma_create(struct drm_i915_gem_object *obj,
__set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma));
}
 
+   if (skip_lookup_cache)
+   goto skip_rb_insert;
+
rb = NULL;
p = >vma.tree.rb_node;
while (*p) {
@@ -222,6 +226,7 @@ vma_create(struct drm_i915_gem_object *obj,
rb_link_node(>obj_node, rb, p);
rb_insert_color(>obj_node, >vma.tree);
 
+skip_rb_insert:
if (i915_vma_is_ggtt(vma))
/*
 * We put the GGTT vma at the start of the vma-list, followed
@@ -301,7 +306,34 @@ i915_vma_instance(struct drm_i915_gem_object *obj,
 
/* vma_create() will resolve the race if another creates the vma */
if (unlikely(!vma))
-   vma = vma_create(obj, vm, view);
+   vma = vma_create(obj, vm, view, false);
+
+   GEM_BUG_ON(!IS_ERR(vma) && i915_vma_compare(vma, vm, view));
+   return vma;
+}
+
+/**
+ * i915_vma_create_persistent - create a persistent VMA
+ * @obj: parent  drm_i915_gem_object to be mapped
+ * @vm: address space in which the mapping is located
+ * @view: additional mapping requirements
+ *
+ * Creates a persistent vma.
+ *
+ * Returns the vma, or an error pointer.
+ */
+struct i915_vma *
+i915_vma_create_persistent(struct drm_i915_gem_object *obj,
+  struct i915_address_space *vm,
+  const struct i915_gtt_view *view)
+{
+   struct i915_vma *vma;
+
+   GEM_BUG_ON(!kref_read(>ref));
+
+   vma = vma_create(obj, vm, view, true);
+   if (!IS_ERR(vma))
+   i915_vma_set_persistent(vma);
 
GEM_BUG_ON(!IS_ERR(vma) && i915_vma_compare(vma, vm, view));
return vma;
diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h
index 0757977a489b..0a4662fbe6c3 100644
--- a/drivers/gpu/drm/i915/i915_vma.h
+++ b/drivers/gpu/drm/i915/i915_vma.h
@@ -44,6 +44,10 @@ struct i915_vma *
 i915_vma_instance(struct drm_i915_gem_object *obj,
  struct i915_address_space *vm,
  const struct i915_gtt_view *view);
+struct i915_vma *
+i915_vma_create_persistent(struct drm_i915_gem_object *obj,
+  struct i915_address_space *vm,
+  const struct i915_gtt_view *view);
 
 void i915_vma_unpin_and_release(struct i915_vma **p_vma, unsigned int flags);
 #define I915_VMA_RELEASE_MAP BIT(0)
@@ -139,6 +143,16 @@ static inline u32 i915_ggtt_pin_bias(struct i915_vma *vma)
return i915_vm_to_ggtt(vma->vm)->pin_bias;
 }
 
+static inline bool i915_vma_is_persistent(const struct i915_vma *vma)
+{
+   return test_bit(I915_VMA_PERSISTENT_BIT, __i915_vma_flags(vma));
+}
+
+static inline void i915_vma_set_persistent(struct i915_vma *vma)
+{
+   set_bit(I915_VMA_PERSISTENT_BIT, __i915_vma_flags(vma));
+}
+
 static inline struct i915_vma *i915_vma_get(struct i915_vma *vma)
 {
i915_gem_object_get(vma->obj);
@@ -165,7 +179,8 @@ i915_vma_compare(struct i915_vma *vma,
 {
ptrdiff_t cmp;
 
-   GEM_BUG_ON(view && !i915_is_ggtt_or_dpt(vm));
+   GEM_BUG_ON(view && !(i915_is_ggtt_or_dpt(vm) ||
+i915_vma_is_persistent(vma)));
 
cmp = ptrdiff(vma->vm, vm);
if (cmp)
diff --git a/drivers/gpu/drm/i915/i915_vma_types.h 
b/drivers/gpu/drm/i915/i915_vma_types.h
index ec0f6c9f57d0..3144d71a0c3e 100644
--- a/drivers/gpu/drm/i915/i915_vma_types.h
+++ b/drivers/gpu/drm/i915/i915_vma_types.h
@@ -264,6 

[PATCH v8 02/22] drm/i915/vm_bind: Add __i915_sw_fence_await_reservation()

2022-11-28 Thread Niranjana Vishwanathapura
Add function __i915_sw_fence_await_reservation() for
asynchronous wait on a dma-resv object with specified
dma_resv_usage. This is required for async vma unbind
with vm_bind.

Reviewed-by: Matthew Auld 
Signed-off-by: Niranjana Vishwanathapura 
---
 drivers/gpu/drm/i915/i915_sw_fence.c | 28 +---
 drivers/gpu/drm/i915/i915_sw_fence.h | 23 +--
 2 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c 
b/drivers/gpu/drm/i915/i915_sw_fence.c
index cc2a8821d22a..ae06d35db056 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.c
+++ b/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -7,7 +7,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include "i915_sw_fence.h"
 #include "i915_selftest.h"
@@ -569,11 +568,26 @@ int __i915_sw_fence_await_dma_fence(struct i915_sw_fence 
*fence,
return ret;
 }
 
-int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
-   struct dma_resv *resv,
-   bool write,
-   unsigned long timeout,
-   gfp_t gfp)
+/**
+ * __i915_sw_fence_await_reservation() - Setup a fence to wait on a dma-resv
+ * object with specified usage.
+ * @fence: the fence that needs to wait
+ * @resv: dma-resv object
+ * @usage: dma_resv_usage (See enum dma_resv_usage)
+ * @timeout: how long to wait in jiffies
+ * @gfp: allocation mode
+ *
+ * Setup the @fence to asynchronously wait on dma-resv object @resv for
+ * @usage to complete before signaling.
+ *
+ * Returns 0 if there is nothing to wait on, -ve error code upon error
+ * and >0 upon successfully setting up the wait.
+ */
+int __i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
+ struct dma_resv *resv,
+ enum dma_resv_usage usage,
+ unsigned long timeout,
+ gfp_t gfp)
 {
struct dma_resv_iter cursor;
struct dma_fence *f;
@@ -582,7 +596,7 @@ int i915_sw_fence_await_reservation(struct i915_sw_fence 
*fence,
debug_fence_assert(fence);
might_sleep_if(gfpflags_allow_blocking(gfp));
 
-   dma_resv_iter_begin(, resv, dma_resv_usage_rw(write));
+   dma_resv_iter_begin(, resv, usage);
dma_resv_for_each_fence_unlocked(, f) {
pending = i915_sw_fence_await_dma_fence(fence, f, timeout,
gfp);
diff --git a/drivers/gpu/drm/i915/i915_sw_fence.h 
b/drivers/gpu/drm/i915/i915_sw_fence.h
index f752bfc7c6e1..9c4859dc4c0d 100644
--- a/drivers/gpu/drm/i915/i915_sw_fence.h
+++ b/drivers/gpu/drm/i915/i915_sw_fence.h
@@ -10,13 +10,13 @@
 #define _I915_SW_FENCE_H_
 
 #include 
+#include 
 #include 
 #include 
 #include  /* for NOTIFY_DONE */
 #include 
 
 struct completion;
-struct dma_resv;
 struct i915_sw_fence;
 
 enum i915_sw_fence_notify {
@@ -89,11 +89,22 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence 
*fence,
  unsigned long timeout,
  gfp_t gfp);
 
-int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
-   struct dma_resv *resv,
-   bool write,
-   unsigned long timeout,
-   gfp_t gfp);
+int __i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
+ struct dma_resv *resv,
+ enum dma_resv_usage usage,
+ unsigned long timeout,
+ gfp_t gfp);
+
+static inline int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
+ struct dma_resv *resv,
+ bool write,
+ unsigned long timeout,
+ gfp_t gfp)
+{
+   return __i915_sw_fence_await_reservation(fence, resv,
+dma_resv_usage_rw(write),
+timeout, gfp);
+}
 
 bool i915_sw_fence_await(struct i915_sw_fence *fence);
 void i915_sw_fence_complete(struct i915_sw_fence *fence);
-- 
2.21.0.rc0.32.g243a4c7e27



[PATCH v8 00/22] drm/i915/vm_bind: Add VM_BIND functionality

2022-11-28 Thread Niranjana Vishwanathapura
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). Multiple mappings can map
to the same physical pages of an object (aliasing). 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).

This patch series support VM_BIND version 1, as described by the param
I915_PARAM_VM_BIND_VERSION.

Add new execbuf3 ioctl (I915_GEM_EXECBUFFER3) which only works in
vm_bind mode. The vm_bind mode only works with this new execbuf3 ioctl.
The new execbuf3 ioctl will not have any execlist support and all the
legacy support like relocations etc., are removed.

NOTEs:
* It is based on below VM_BIND design+uapi rfc.
  Documentation/gpu/rfc/i915_vm_bind.rst

* The IGT RFC series is posted as,
  [PATCH i-g-t v8 0/14] vm_bind: Add VM_BIND validation support

v2: Address various review comments
v3: Address review comments and other fixes
v4: Remove vm_unbind out fence uapi which is not supported yet,
replace vm->vm_bind_mode check with i915_gem_vm_is_vm_bind_mode()
v5: Render kernel-doc, use PIN_NOEVICT, limit vm_bind support to
non-recoverable faults
v6: Rebased, minor fixes, add reserved fields to drm_i915_gem_vm_bind,
add new patch for async vm_unbind support
v7: Rebased, minor cleanups as per review feedback
v8: Rebased, add capture support

Test-with: 20221129072355.769-1-niranjana.vishwanathap...@intel.com

Signed-off-by: Niranjana Vishwanathapura 

Niranjana Vishwanathapura (22):
  drm/i915/vm_bind: Expose vm lookup function
  drm/i915/vm_bind: Add __i915_sw_fence_await_reservation()
  drm/i915/vm_bind: Expose i915_gem_object_max_page_size()
  drm/i915/vm_bind: Add support to create persistent vma
  drm/i915/vm_bind: Implement bind and unbind of object
  drm/i915/vm_bind: Support for VM private BOs
  drm/i915/vm_bind: Add support to handle object evictions
  drm/i915/vm_bind: Support persistent vma activeness tracking
  drm/i915/vm_bind: Add out fence support
  drm/i915/vm_bind: Abstract out common execbuf functions
  drm/i915/vm_bind: Use common execbuf functions in execbuf path
  drm/i915/vm_bind: Implement I915_GEM_EXECBUFFER3 ioctl
  drm/i915/vm_bind: Update i915_vma_verify_bind_complete()
  drm/i915/vm_bind: Expose i915_request_await_bind()
  drm/i915/vm_bind: Handle persistent vmas in execbuf3
  drm/i915/vm_bind: userptr dma-resv changes
  drm/i915/vm_bind: Limit vm_bind mode to non-recoverable contexts
  drm/i915/vm_bind: Add uapi for user to enable vm_bind_mode
  drm/i915/vm_bind: Render VM_BIND documentation
  drm/i915/vm_bind: Async vm_unbind support
  drm/i915/vm_bind: Properly build persistent map sg table
  drm/i915/vm_bind: Support capture of persistent mappings

 Documentation/gpu/i915.rst|  78 +-
 drivers/gpu/drm/i915/Makefile |   3 +
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  43 +-
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |  17 +
 drivers/gpu/drm/i915/gem/i915_gem_create.c|  72 +-
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c|   6 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c| 522 +--
 .../gpu/drm/i915/gem/i915_gem_execbuffer3.c   | 872 ++
 .../drm/i915/gem/i915_gem_execbuffer_common.c | 671 ++
 .../drm/i915/gem/i915_gem_execbuffer_common.h |  76 ++
 drivers/gpu/drm/i915/gem/i915_gem_ioctls.h|   2 +
 drivers/gpu/drm/i915/gem/i915_gem_object.c|   3 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h|   2 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   6 +
 drivers/gpu/drm/i915/gem/i915_gem_userptr.c   |  19 +
 drivers/gpu/drm/i915/gem/i915_gem_vm_bind.h   |  30 +
 .../drm/i915/gem/i915_gem_vm_bind_object.c| 461 +
 drivers/gpu/drm/i915/gt/intel_gtt.c   |  20 +
 drivers/gpu/drm/i915/gt/intel_gtt.h   |  26 +
 drivers/gpu/drm/i915/i915_driver.c|   4 +
 drivers/gpu/drm/i915/i915_drv.h   |   2 +
 drivers/gpu/drm/i915/i915_gem_gtt.c   |  39 +
 drivers/gpu/drm/i915/i915_gem_gtt.h   |   3 +
 drivers/gpu/drm/i915/i915_getparam.c  |   3 +
 drivers/gpu/drm/i915/i915_gpu_error.c |  19 +
 drivers/gpu/drm/i915/i915_sw_fence.c  |  28 +-
 drivers/gpu/drm/i915/i915_sw_fence.h  |  23 +-
 drivers/gpu/drm/i915/i915_vma.c   | 305 +-
 drivers/gpu/drm/i915/i915_vma.h   |  70 +-
 drivers/gpu/drm/i915/i915_vma_types.h |  41 +
 include/uapi/drm/i915_drm.h   | 277 +-
 31 files changed, 3192 insertions(+), 551 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_execbuffer3.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_execbuffer_common.c
 create mode 100644 drivers/gpu/drm/i915/gem/i915_gem_execbuffer_common.h
 

Re: [PATCH v1 7/8] drm: rcar-du: dsi: Add r8A779g0 support

2022-11-28 Thread Tomi Valkeinen

On 29/11/2022 02:43, Laurent Pinchart wrote:

On Tue, Nov 22, 2022 at 10:50:30AM +0200, Tomi Valkeinen wrote:

On 17/11/2022 17:46, Kieran Bingham wrote:

Quoting Tomi Valkeinen (2022-11-17 12:25:46)

From: Tomi Valkeinen 

Add DSI support for r8a779g0. The main differences to r8a779a0 are in
the PLL and PHTW setups.

Signed-off-by: Tomi Valkeinen 
---
   drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c  | 484 +++
   drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h |   6 +-
   2 files changed, 384 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
index a7f2b7f66a17..723c35726c38 100644
--- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
+++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
@@ -9,6 +9,7 @@
   #include 
   #include 
   #include 
+#include 
   #include 
   #include 
   #include 
@@ -28,6 +29,20 @@
   #include "rcar_mipi_dsi.h"
   #include "rcar_mipi_dsi_regs.h"
   
+#define MHZ(v) ((v) * 100u)

+
+enum rcar_mipi_dsi_hw_model {
+   RCAR_DSI_R8A779A0,
+   RCAR_DSI_R8A779G0,
+};
+
+struct rcar_mipi_dsi_device_info {
+   enum rcar_mipi_dsi_hw_model model;
+   const struct dsi_clk_config *clk_cfg;
+   u8 clockset2_m_offset;
+   u8 clockset2_n_offset;
+};
+
   struct rcar_mipi_dsi {
  struct device *dev;
  const struct rcar_mipi_dsi_device_info *info;
@@ -50,6 +65,17 @@ struct rcar_mipi_dsi {
  unsigned int lanes;
   };
   
+struct dsi_setup_info {

+   unsigned long hsfreq;
+   u16 hsfreqrange;
+
+   unsigned long fout;
+   u16 m;
+   u16 n;
+   u16 vclk_divider;
+   const struct dsi_clk_config *clkset;
+};
+
   static inline struct rcar_mipi_dsi *
   bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
   {
@@ -62,22 +88,6 @@ host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
  return container_of(host, struct rcar_mipi_dsi, host);
   }
   
-static const u32 phtw[] = {

-   0x01020114, 0x01600115, /* General testing */
-   0x01030116, 0x0102011d, /* General testing */
-   0x011101a4, 0x018601a4, /* 1Gbps testing */
-   0x014201a0, 0x010001a3, /* 1Gbps testing */
-   0x0101011f, /* 1Gbps testing */
-};
-
-static const u32 phtw2[] = {
-   0x010c0130, 0x010c0140, /* General testing */
-   0x010c0150, 0x010c0180, /* General testing */
-   0x010c0190,
-   0x010a0160, 0x010a0170,
-   0x01800164, 0x01800174, /* 1Gbps testing */
-};
-
   static const u32 hsfreqrange_table[][2] = {
  { 8000U,   0x00 }, { 9000U,   0x10 }, { 1U,  0x20 },
  { 11000U,  0x30 }, { 12000U,  0x01 }, { 13000U,  0x11 },
@@ -103,24 +113,53 @@ static const u32 hsfreqrange_table[][2] = {
  { /* sentinel */ },
   };
   
-struct vco_cntrl_value {

+struct dsi_clk_config {
  u32 min_freq;
  u32 max_freq;
-   u16 value;
+   u8 vco_cntrl;
+   u8 cpbias_cntrl;
+   u8 gmp_cntrl;
+   u8 int_cntrl;
+   u8 prop_cntrl;
   };
   
-static const struct vco_cntrl_value vco_cntrl_table[] = {

-   { .min_freq = 4000U,   .max_freq = 5500U,   .value = 0x3f },
-   { .min_freq = 5250U,   .max_freq = 8000U,   .value = 0x39 },
-   { .min_freq = 8000U,   .max_freq = 11000U,  .value = 0x2f },
-   { .min_freq = 10500U,  .max_freq = 16000U,  .value = 0x29 },
-   { .min_freq = 16000U,  .max_freq = 22000U,  .value = 0x1f },
-   { .min_freq = 21000U,  .max_freq = 32000U,  .value = 0x19 },
-   { .min_freq = 32000U,  .max_freq = 44000U,  .value = 0x0f },
-   { .min_freq = 42000U,  .max_freq = 66000U,  .value = 0x09 },
-   { .min_freq = 63000U,  .max_freq = 114900U, .value = 0x03 },
-   { .min_freq = 11U, .max_freq = 115200U, .value = 0x01 },
-   { .min_freq = 115000U, .max_freq = 125000U, .value = 0x01 },
+static const struct dsi_clk_config dsi_clk_cfg_r8a779a0[] = {
+   {   4000u,   5500u, 0x3f, 0x10, 0x01, 0x00, 0x0b },
+   {   5250u,   8000u, 0x39, 0x10, 0x01, 0x00, 0x0b },
+   {   8000u,  11000u, 0x2f, 0x10, 0x01, 0x00, 0x0b },
+   {  10500u,  16000u, 0x29, 0x10, 0x01, 0x00, 0x0b },
+   {  16000u,  22000u, 0x1f, 0x10, 0x01, 0x00, 0x0b },
+   {  21000u,  32000u, 0x19, 0x10, 0x01, 0x00, 0x0b },
+   {  32000u,  44000u, 0x0f, 0x10, 0x01, 0x00, 0x0b },
+   {  42000u,  66000u, 0x09, 0x10, 0x01, 0x00, 0x0b },
+   {  63000u, 114900u, 0x03, 0x10, 0x01, 0x00, 0x0b },
+   { 11u, 115200u, 0x01, 0x10, 0x01, 0x00, 0x0b },
+   { 115000u, 125000u, 0x01, 0x10, 0x01, 0x00, 0x0c },


Sigh ... is it this one 0x0c value that means we need to keep all these
entries repeated ? :-S

If it weren't for that, it seems we could keep just two sets of

+   u8 cpbias_cntrl;
+   u8 gmp_cntrl;
+   u8 int_cntrl;
+   

Re: [Intel-gfx] [PATCH v4] drm/i915/mtl: Media GT and Render GT share common GGTT

2022-11-28 Thread Lucas De Marchi

On Tue, Nov 29, 2022 at 11:33:15AM +0530, Iddamsetty, Aravind wrote:



On 29-11-2022 11:24, Lucas De Marchi wrote:

On Wed, Nov 23, 2022 at 09:47:03AM +0530, Iddamsetty, Aravind wrote:



On 23-11-2022 05:29, Matt Roper wrote:

On Tue, Nov 22, 2022 at 12:31:26PM +0530, Aravind Iddamsetty wrote:

On XE_LPM+ platforms the media engines are carved out into a separate
GT but have a common GGTMMADR address range which essentially makes
the GGTT address space to be shared between media and render GT. As a
result any updates in GGTT shall invalidate TLB of GTs sharing it and
similarly any operation on GGTT requiring an action on a GT will
have to
involve all GTs sharing it. setup_private_pat was being done on a per
GGTT based as that doesn't touch any GGTT structures moved it to per GT
based.

BSPEC: 63834

v2:
1. Add details to commit msg
2. includes fix for failure to add item to ggtt->gt_list, as suggested
by Lucas
3. as ggtt_flush() is used only for ggtt drop i915_is_ggtt check within
it.
4. setup_private_pat moved out of intel_gt_tiles_init

v3:
1. Move out for_each_gt from i915_driver.c (Jani Nikula)

v4: drop using RCU primitives on ggtt->gt_list as it is not an RCU list
(Matt Roper)

Cc: Matt Roper 
Signed-off-by: Aravind Iddamsetty 


Reviewed-by: Matt Roper 


Thanks Matt, could you also help with merging the change.

Regards,
Aravind.



---
 drivers/gpu/drm/i915/gt/intel_ggtt.c  | 54 +--
 drivers/gpu/drm/i915/gt/intel_gt.c    | 13 +-
 drivers/gpu/drm/i915/gt/intel_gt_types.h  |  3 ++
 drivers/gpu/drm/i915/gt/intel_gtt.h   |  4 ++
 drivers/gpu/drm/i915/i915_driver.c    | 12 ++---
 drivers/gpu/drm/i915/i915_gem.c   |  2 +
 drivers/gpu/drm/i915/i915_gem_evict.c | 51 +++--
 drivers/gpu/drm/i915/i915_vma.c   |  5 ++-
 drivers/gpu/drm/i915/selftests/i915_gem.c |  2 +
 9 files changed, 111 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 8145851ad23d..7644738b9cdb 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -8,6 +8,7 @@
 #include 
 #include 

+#include 
 #include 
 #include 

@@ -196,10 +197,13 @@ void i915_ggtt_suspend_vm(struct
i915_address_space *vm)

 void i915_ggtt_suspend(struct i915_ggtt *ggtt)
 {
+    struct intel_gt *gt;
+
 i915_ggtt_suspend_vm(>vm);
 ggtt->invalidate(ggtt);

-    intel_gt_check_and_clear_faults(ggtt->vm.gt);
+    list_for_each_entry(gt, >gt_list, ggtt_link)
+    intel_gt_check_and_clear_faults(gt);
 }

 void gen6_ggtt_invalidate(struct i915_ggtt *ggtt)
@@ -225,16 +229,21 @@ static void gen8_ggtt_invalidate(struct
i915_ggtt *ggtt)

 static void guc_ggtt_invalidate(struct i915_ggtt *ggtt)
 {
-    struct intel_uncore *uncore = ggtt->vm.gt->uncore;
 struct drm_i915_private *i915 = ggtt->vm.i915;

 gen8_ggtt_invalidate(ggtt);

-    if (GRAPHICS_VER(i915) >= 12)
-    intel_uncore_write_fw(uncore, GEN12_GUC_TLB_INV_CR,
-  GEN12_GUC_TLB_INV_CR_INVALIDATE);
-    else
-    intel_uncore_write_fw(uncore, GEN8_GTCR,
GEN8_GTCR_INVALIDATE);
+    if (GRAPHICS_VER(i915) >= 12) {
+    struct intel_gt *gt;
+
+    list_for_each_entry(gt, >gt_list, ggtt_link)
+    intel_uncore_write_fw(gt->uncore,
+  GEN12_GUC_TLB_INV_CR,
+  GEN12_GUC_TLB_INV_CR_INVALIDATE);
+    } else {
+    intel_uncore_write_fw(ggtt->vm.gt->uncore,
+  GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+    }
 }

 u64 gen8_ggtt_pte_encode(dma_addr_t addr,
@@ -986,8 +995,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)

 ggtt->vm.pte_encode = gen8_ggtt_pte_encode;

-    setup_private_pat(ggtt->vm.gt);
-
 return ggtt_probe_common(ggtt, size);
 }

@@ -1196,7 +1203,14 @@ static int ggtt_probe_hw(struct i915_ggtt
*ggtt, struct intel_gt *gt)
  */
 int i915_ggtt_probe_hw(struct drm_i915_private *i915)
 {
-    int ret;
+    struct intel_gt *gt;
+    int ret, i;
+
+    for_each_gt(gt, i915, i) {
+    ret = intel_gt_assign_ggtt(gt);


in v3 the intel_gt_assign_ggtt() call is not in i915_driver.c anymore but
rather moved here. We could make i915_ggtt_create() static, doing the
allocation here and intel_gt_assign_ggtt() would be in charge of just
assigning the ggtt. Not very important though and can be done later.


well we call intel_gt_assign_ggtt in i915_gem_gtt_mock_selftests but not
i915_ggtt_probe_hw.


makes sense, let's leave it as is.

Lucas De Marchi


Re: [Intel-gfx] [PATCH v4] drm/i915/mtl: Media GT and Render GT share common GGTT

2022-11-28 Thread Iddamsetty, Aravind



On 29-11-2022 11:24, Lucas De Marchi wrote:
> On Wed, Nov 23, 2022 at 09:47:03AM +0530, Iddamsetty, Aravind wrote:
>>
>>
>> On 23-11-2022 05:29, Matt Roper wrote:
>>> On Tue, Nov 22, 2022 at 12:31:26PM +0530, Aravind Iddamsetty wrote:
 On XE_LPM+ platforms the media engines are carved out into a separate
 GT but have a common GGTMMADR address range which essentially makes
 the GGTT address space to be shared between media and render GT. As a
 result any updates in GGTT shall invalidate TLB of GTs sharing it and
 similarly any operation on GGTT requiring an action on a GT will
 have to
 involve all GTs sharing it. setup_private_pat was being done on a per
 GGTT based as that doesn't touch any GGTT structures moved it to per GT
 based.

 BSPEC: 63834

 v2:
 1. Add details to commit msg
 2. includes fix for failure to add item to ggtt->gt_list, as suggested
 by Lucas
 3. as ggtt_flush() is used only for ggtt drop i915_is_ggtt check within
 it.
 4. setup_private_pat moved out of intel_gt_tiles_init

 v3:
 1. Move out for_each_gt from i915_driver.c (Jani Nikula)

 v4: drop using RCU primitives on ggtt->gt_list as it is not an RCU list
 (Matt Roper)

 Cc: Matt Roper 
 Signed-off-by: Aravind Iddamsetty 
>>>
>>> Reviewed-by: Matt Roper 
>>
>> Thanks Matt, could you also help with merging the change.
>>
>> Regards,
>> Aravind.
>>>
 ---
  drivers/gpu/drm/i915/gt/intel_ggtt.c  | 54 +--
  drivers/gpu/drm/i915/gt/intel_gt.c    | 13 +-
  drivers/gpu/drm/i915/gt/intel_gt_types.h  |  3 ++
  drivers/gpu/drm/i915/gt/intel_gtt.h   |  4 ++
  drivers/gpu/drm/i915/i915_driver.c    | 12 ++---
  drivers/gpu/drm/i915/i915_gem.c   |  2 +
  drivers/gpu/drm/i915/i915_gem_evict.c | 51 +++--
  drivers/gpu/drm/i915/i915_vma.c   |  5 ++-
  drivers/gpu/drm/i915/selftests/i915_gem.c |  2 +
  9 files changed, 111 insertions(+), 35 deletions(-)

 diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c
 b/drivers/gpu/drm/i915/gt/intel_ggtt.c
 index 8145851ad23d..7644738b9cdb 100644
 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
 +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
 @@ -8,6 +8,7 @@
  #include 
  #include 

 +#include 
  #include 
  #include 

 @@ -196,10 +197,13 @@ void i915_ggtt_suspend_vm(struct
 i915_address_space *vm)

  void i915_ggtt_suspend(struct i915_ggtt *ggtt)
  {
 +    struct intel_gt *gt;
 +
  i915_ggtt_suspend_vm(>vm);
  ggtt->invalidate(ggtt);

 -    intel_gt_check_and_clear_faults(ggtt->vm.gt);
 +    list_for_each_entry(gt, >gt_list, ggtt_link)
 +    intel_gt_check_and_clear_faults(gt);
  }

  void gen6_ggtt_invalidate(struct i915_ggtt *ggtt)
 @@ -225,16 +229,21 @@ static void gen8_ggtt_invalidate(struct
 i915_ggtt *ggtt)

  static void guc_ggtt_invalidate(struct i915_ggtt *ggtt)
  {
 -    struct intel_uncore *uncore = ggtt->vm.gt->uncore;
  struct drm_i915_private *i915 = ggtt->vm.i915;

  gen8_ggtt_invalidate(ggtt);

 -    if (GRAPHICS_VER(i915) >= 12)
 -    intel_uncore_write_fw(uncore, GEN12_GUC_TLB_INV_CR,
 -  GEN12_GUC_TLB_INV_CR_INVALIDATE);
 -    else
 -    intel_uncore_write_fw(uncore, GEN8_GTCR,
 GEN8_GTCR_INVALIDATE);
 +    if (GRAPHICS_VER(i915) >= 12) {
 +    struct intel_gt *gt;
 +
 +    list_for_each_entry(gt, >gt_list, ggtt_link)
 +    intel_uncore_write_fw(gt->uncore,
 +  GEN12_GUC_TLB_INV_CR,
 +  GEN12_GUC_TLB_INV_CR_INVALIDATE);
 +    } else {
 +    intel_uncore_write_fw(ggtt->vm.gt->uncore,
 +  GEN8_GTCR, GEN8_GTCR_INVALIDATE);
 +    }
  }

  u64 gen8_ggtt_pte_encode(dma_addr_t addr,
 @@ -986,8 +995,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)

  ggtt->vm.pte_encode = gen8_ggtt_pte_encode;

 -    setup_private_pat(ggtt->vm.gt);
 -
  return ggtt_probe_common(ggtt, size);
  }

 @@ -1196,7 +1203,14 @@ static int ggtt_probe_hw(struct i915_ggtt
 *ggtt, struct intel_gt *gt)
   */
  int i915_ggtt_probe_hw(struct drm_i915_private *i915)
  {
 -    int ret;
 +    struct intel_gt *gt;
 +    int ret, i;
 +
 +    for_each_gt(gt, i915, i) {
 +    ret = intel_gt_assign_ggtt(gt);
> 
> in v3 the intel_gt_assign_ggtt() call is not in i915_driver.c anymore but
> rather moved here. We could make i915_ggtt_create() static, doing the
> allocation here and intel_gt_assign_ggtt() would be in charge of just
> assigning the ggtt. Not very important though and can be done later.

well we call intel_gt_assign_ggtt in 

Re: [Intel-gfx] [PATCH v4] drm/i915/mtl: Media GT and Render GT share common GGTT

2022-11-28 Thread Lucas De Marchi

On Wed, Nov 23, 2022 at 09:47:03AM +0530, Iddamsetty, Aravind wrote:



On 23-11-2022 05:29, Matt Roper wrote:

On Tue, Nov 22, 2022 at 12:31:26PM +0530, Aravind Iddamsetty wrote:

On XE_LPM+ platforms the media engines are carved out into a separate
GT but have a common GGTMMADR address range which essentially makes
the GGTT address space to be shared between media and render GT. As a
result any updates in GGTT shall invalidate TLB of GTs sharing it and
similarly any operation on GGTT requiring an action on a GT will have to
involve all GTs sharing it. setup_private_pat was being done on a per
GGTT based as that doesn't touch any GGTT structures moved it to per GT
based.

BSPEC: 63834

v2:
1. Add details to commit msg
2. includes fix for failure to add item to ggtt->gt_list, as suggested
by Lucas
3. as ggtt_flush() is used only for ggtt drop i915_is_ggtt check within
it.
4. setup_private_pat moved out of intel_gt_tiles_init

v3:
1. Move out for_each_gt from i915_driver.c (Jani Nikula)

v4: drop using RCU primitives on ggtt->gt_list as it is not an RCU list
(Matt Roper)

Cc: Matt Roper 
Signed-off-by: Aravind Iddamsetty 


Reviewed-by: Matt Roper 


Thanks Matt, could you also help with merging the change.

Regards,
Aravind.



---
 drivers/gpu/drm/i915/gt/intel_ggtt.c  | 54 +--
 drivers/gpu/drm/i915/gt/intel_gt.c| 13 +-
 drivers/gpu/drm/i915/gt/intel_gt_types.h  |  3 ++
 drivers/gpu/drm/i915/gt/intel_gtt.h   |  4 ++
 drivers/gpu/drm/i915/i915_driver.c| 12 ++---
 drivers/gpu/drm/i915/i915_gem.c   |  2 +
 drivers/gpu/drm/i915/i915_gem_evict.c | 51 +++--
 drivers/gpu/drm/i915/i915_vma.c   |  5 ++-
 drivers/gpu/drm/i915/selftests/i915_gem.c |  2 +
 9 files changed, 111 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 8145851ad23d..7644738b9cdb 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -8,6 +8,7 @@
 #include 
 #include 

+#include 
 #include 
 #include 

@@ -196,10 +197,13 @@ void i915_ggtt_suspend_vm(struct i915_address_space *vm)

 void i915_ggtt_suspend(struct i915_ggtt *ggtt)
 {
+   struct intel_gt *gt;
+
i915_ggtt_suspend_vm(>vm);
ggtt->invalidate(ggtt);

-   intel_gt_check_and_clear_faults(ggtt->vm.gt);
+   list_for_each_entry(gt, >gt_list, ggtt_link)
+   intel_gt_check_and_clear_faults(gt);
 }

 void gen6_ggtt_invalidate(struct i915_ggtt *ggtt)
@@ -225,16 +229,21 @@ static void gen8_ggtt_invalidate(struct i915_ggtt *ggtt)

 static void guc_ggtt_invalidate(struct i915_ggtt *ggtt)
 {
-   struct intel_uncore *uncore = ggtt->vm.gt->uncore;
struct drm_i915_private *i915 = ggtt->vm.i915;

gen8_ggtt_invalidate(ggtt);

-   if (GRAPHICS_VER(i915) >= 12)
-   intel_uncore_write_fw(uncore, GEN12_GUC_TLB_INV_CR,
- GEN12_GUC_TLB_INV_CR_INVALIDATE);
-   else
-   intel_uncore_write_fw(uncore, GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+   if (GRAPHICS_VER(i915) >= 12) {
+   struct intel_gt *gt;
+
+   list_for_each_entry(gt, >gt_list, ggtt_link)
+   intel_uncore_write_fw(gt->uncore,
+ GEN12_GUC_TLB_INV_CR,
+ GEN12_GUC_TLB_INV_CR_INVALIDATE);
+   } else {
+   intel_uncore_write_fw(ggtt->vm.gt->uncore,
+ GEN8_GTCR, GEN8_GTCR_INVALIDATE);
+   }
 }

 u64 gen8_ggtt_pte_encode(dma_addr_t addr,
@@ -986,8 +995,6 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt)

ggtt->vm.pte_encode = gen8_ggtt_pte_encode;

-   setup_private_pat(ggtt->vm.gt);
-
return ggtt_probe_common(ggtt, size);
 }

@@ -1196,7 +1203,14 @@ static int ggtt_probe_hw(struct i915_ggtt *ggtt, struct 
intel_gt *gt)
  */
 int i915_ggtt_probe_hw(struct drm_i915_private *i915)
 {
-   int ret;
+   struct intel_gt *gt;
+   int ret, i;
+
+   for_each_gt(gt, i915, i) {
+   ret = intel_gt_assign_ggtt(gt);


in v3 the intel_gt_assign_ggtt() call is not in i915_driver.c anymore but
rather moved here. We could make i915_ggtt_create() static, doing the
allocation here and intel_gt_assign_ggtt() would be in charge of just
assigning the ggtt. Not very important though and can be done later.

pushed, thanks

Lucas De Marchi


+   if (ret)
+   return ret;
+   }

ret = ggtt_probe_hw(to_gt(i915)->ggtt, to_gt(i915));
if (ret)
@@ -1208,6 +1222,19 @@ int i915_ggtt_probe_hw(struct drm_i915_private *i915)
return 0;
 }

+struct i915_ggtt *i915_ggtt_create(struct drm_i915_private *i915)
+{
+   struct i915_ggtt *ggtt;
+
+   ggtt = drmm_kzalloc(>drm, sizeof(*ggtt), GFP_KERNEL);
+   if (!ggtt)
+   return ERR_PTR(-ENOMEM);
+
+   

Re: [PATCH] drm/amdkfd: Fix memory leakage

2022-11-28 Thread Felix Kuehling

Am 2022-11-28 um 22:47 schrieb Konstantin Meskhidze:

This patch fixes potential memory leakage and seg fault
in  _gpuvm_import_dmabuf() function

Signed-off-by: Konstantin Meskhidze 


Thank you for the patch. I'm adding a Fixes tag and pushing the patch to 
amd-staging-drm-next.


Fixes: d4ec4bdc0bd5 ("drm/amdkfd: Allow access for mmapping KFD BOs")
Reviewed-by: Felix Kuehling 



---
  drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 978d3970b5cc..e0084f712e02 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -2257,7 +2257,7 @@ int amdgpu_amdkfd_gpuvm_import_dmabuf(struct 
amdgpu_device *adev,
  
  	ret = drm_vma_node_allow(>vma_node, drm_priv);

if (ret) {
-   kfree(mem);
+   kfree(*mem);
return ret;
}
  


Re: AMD GPU problems under Xen

2022-11-28 Thread Demi Marie Obenour
On Mon, Nov 28, 2022 at 11:18:00AM -0500, Alex Deucher wrote:
> On Mon, Nov 28, 2022 at 2:18 AM Demi Marie Obenour
>  wrote:
> >
> > Dear Christian:
> >
> > What is the status of the AMDGPU work for Xen dom0?  That was mentioned in
> > https://lore.kernel.org/dri-devel/b2dec9b3-03a7-e7ac-306e-1da024af8...@amd.com/
> > and there have been bug reports to Qubes OS about problems with AMDGPU
> > under Xen (such as https://github.com/QubesOS/qubes-issues/issues/7648).
> 
> I would say it's a work in progress.  It depends what GPU  you have
> and what type of xen setup you are using (PV vs PVH, etc.).

The current situation is:

- dom0 is PV.
- VMs with assigned PCI devices are HVM and use a Linux-based stubdomain
  QEMU does not run in dom0.
- Everything else is PVH.

In the future, I believe the goal is to move away from PV and HVM in
favor of PVH, though HVM support will remain for compatibility with
guests (such as Windows) that need emulated devices.

> In general, your best bet currently is dGPU add in boards because they
> are largely self contained.

The main problem is that for the trusted GUI to work, there needs to
be at least one GPU attached to a trusted VM, such as the host or a
dedicated GUI VM.  That VM will typically not be running graphics-
intensive workloads, so the compute power of a dGPU is largely wasted.
SR-IOV support would help with that, but the only GPU vendor with open
source SR-IOV support is Intel and it is still not upstream.  I am also
not certain if the support extends to Arc dGPUs.

> APUs and platforms with integrated dGPUs
> are a bit more complicated as they tend to have more platform
> dependencies like ACPI tables and methods in order for the driver to
> be able to initialize the hardware properly.

Is Xen dom0/domU support for such GPUs being worked on?  Is there an
estimate as to when the needed support will be available upstream?  This
is mostly directed at Christian and other people who work for hardware
vendors.

> Additionally, GPUs map a
> lot of system memory so bounce buffers aren't really viable.  You'll
> really need IOMMU,

Qubes OS already needs an IOMMU so that is not a concern.  
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab


signature.asc
Description: PGP signature


回复: [PATCH v3] drm: Optimise for continuous memory allocation

2022-11-28 Thread Pan, Xinhui
[AMD Official Use Only - General]

Hi Arun,
Thanks for your reply. comments are inline.

发件人: Paneer Selvam, Arunpravin 
发送时间: 2022年11月29日 1:09
收件人: Pan, Xinhui; amd-...@lists.freedesktop.org
抄送: linux-ker...@vger.kernel.org; dri-devel@lists.freedesktop.org; 
matthew.a...@intel.com; dan...@ffwll.ch; Koenig, Christian
主题: Re: [PATCH v3] drm: Optimise for continuous memory allocation

Hi Xinhui,

On 11/28/2022 12:04 PM, xinhui pan wrote:
> Currently drm-buddy does not have full knowledge of continuous memory.
>
> Lets consider scenario below.
> order 1:L R
> order 0: LL   LR  RL  RR
> for order 1 allocation, it can offer L or R or LR+RL.
>
> For now, we only implement L or R case for continuous memory allocation.
> So this patch aims to implement the LR+RL case.
>
> Signed-off-by: xinhui pan 
> ---
> change from v2:
> search continuous block in nearby root if needed
>
> change from v1:
> implement top-down continuous allocation
> ---
>   drivers/gpu/drm/drm_buddy.c | 78 +
>   1 file changed, 71 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
> index 11bb59399471..ff58eb3136d2 100644
> --- a/drivers/gpu/drm/drm_buddy.c
> +++ b/drivers/gpu/drm/drm_buddy.c
> @@ -386,6 +386,58 @@ alloc_range_bias(struct drm_buddy *mm,
>   return ERR_PTR(err);
>   }
>
> +static struct drm_buddy_block *
> +find_continuous_blocks(struct drm_buddy *mm,
> +int order,
> +unsigned long flags,
> +struct drm_buddy_block **rn)
> +{
> + struct list_head *head = >free_list[order];
> + struct drm_buddy_block *node, *parent, *free_node, *max_node = NULL;
NIT: We usually name the variable as *block or ***_block for drm buddy
and we have *node or ***_node for drm mm manager.

[xh] Oh, yes. The code naming is important. Will fix it.

> + int i;
> +
> + list_for_each_entry(free_node, head, link) {
> + if (max_node) {
> + if (!(flags & DRM_BUDDY_TOPDOWN_ALLOCATION))
> + break;
> +
> + if (drm_buddy_block_offset(free_node) <
> + drm_buddy_block_offset(max_node))
> + continue;
> + }
> +
> + parent = free_node;
> + do {
> + node = parent;
> + parent = parent->parent;
> + } while (parent && parent->right == node);
> +
> + if (!parent) {
> + for (i = 0; i < mm->n_roots - 1; i++)
> + if (mm->roots[i] == node)
> + break;
> + if (i == mm->n_roots - 1)
> + continue;
> + node = mm->roots[i + 1];
> + } else {
> + node = parent->right;
> + }
> +
> + while (drm_buddy_block_is_split(node))
> + node = node->left;
> +
> + if (drm_buddy_block_is_free(node) &&
> + drm_buddy_block_order(node) == order) {
> + *rn = node;
> + max_node = free_node;
> + BUG_ON(drm_buddy_block_offset(node) !=
> + drm_buddy_block_offset(max_node) +
> + drm_buddy_block_size(mm, max_node));
> + }
> + }
> + return max_node;
> +}
> +
>   static struct drm_buddy_block *
>   get_maxblock(struct list_head *head)
>   {
> @@ -637,7 +689,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>  struct list_head *blocks,
>  unsigned long flags)
>   {
> - struct drm_buddy_block *block = NULL;
> + struct drm_buddy_block *block = NULL, *rblock = NULL;
>   unsigned int min_order, order;
>   unsigned long pages;
>   LIST_HEAD(allocated);
> @@ -689,17 +741,29 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
>   break;
>
>   if (order-- == min_order) {
> + if (!(flags & DRM_BUDDY_RANGE_ALLOCATION) &&
> + min_order != 0 && pages == BIT(order + 1)) {
> + block = find_continuous_blocks(mm,
> +order,
> +flags,
> +);
> + if (block)
> + break;
> + }
>   err = -ENOSPC;
>   goto err_free;
>   }
>   } while (1);
>
> - mark_allocated(block);
> - 

Re: [PATCH v2 0/7] Renesas V4H DSI & DP output support

2022-11-28 Thread Laurent Pinchart
Hi Tomi,

On Wed, Nov 23, 2022 at 08:59:39AM +0200, Tomi Valkeinen wrote:
> From: Tomi Valkeinen 
> 
> Hi,
> 
> These add support for DSI on V4H SoC (r8a779g0) and DP for Whitehawk
> board.
> 
> Changes in v2:
> - A few cosmetic changes
> - Increase vspd address range in dts to 0x7000
> - Arrange nodes in dts by the block address
> - Use gen = 4 for r8a779g0 du
> - Drop the CLOCKSET1 hack patch
> 
> The CLOCKSET1 patch is apparently not needed to get the DSI & DP
> working. Which is baffling, as I'm quite sure it was needed. There are a
> few possible explanations: 1) it was never needed and I was just messing
> things up, 2) it was needed, but some of my later improvements made it
> unnecessary, 3) Whitehawk board firmware was updated in the middle of
> the development of this series, possibly the firmware made the patch
> unnecessary.
> 
>  Tomi
> 
> Tomi Valkeinen (7):
>   dt-bindings: display: renesas,du: Provide bindings for r8a779g0
>   dt-bindings: display: bridge: renesas,dsi-csi2-tx: Add r8a779g0
>   clk: renesas: r8a779g0: Add display related clocks
>   arm64: dts: renesas: r8a779g0: Add display related nodes
>   arm64: dts: renesas: white-hawk-cpu: Add DP output support
>   drm: rcar-du: Add r8a779g0 support
>   drm: rcar-du: dsi: Add r8A779g0 support

I'll take patches 1/7, 2/7 and 6/7 in my tree already for v6.3. I expect
Geert to handle 3/7, 4/7 and 5/7. 7/7 needs a v3.

> 
>  .../display/bridge/renesas,dsi-csi2-tx.yaml   |   3 +-
>  .../bindings/display/renesas,du.yaml  |   2 +
>  .../dts/renesas/r8a779g0-white-hawk-cpu.dtsi  |  94 
>  arch/arm64/boot/dts/renesas/r8a779g0.dtsi | 130 +
>  drivers/clk/renesas/r8a779g0-cpg-mssr.c   |  14 +
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c |  22 +
>  drivers/gpu/drm/rcar-du/rcar_du_group.c   |   2 +-
>  drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c   | 484 ++
>  drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h  |   6 +-
>  9 files changed, 649 insertions(+), 108 deletions(-)
> 

-- 
Regards,

Laurent Pinchart


Re: [PATCH v2 7/7] drm: rcar-du: dsi: Add r8a779g0 support

2022-11-28 Thread Laurent Pinchart
Hi Tomi,

Thank you for the patch.

On Wed, Nov 23, 2022 at 08:59:46AM +0200, Tomi Valkeinen wrote:
> Add DSI support for r8a779g0. The main differences to r8a779a0 are in
> the PLL and PHTW setups.
> 
> Signed-off-by: Tomi Valkeinen 
> ---
>  drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c  | 484 +++
>  drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h |   6 +-
>  2 files changed, 384 insertions(+), 106 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
> b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> index a7f2b7f66a17..723c35726c38 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> @@ -9,6 +9,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -28,6 +29,20 @@
>  #include "rcar_mipi_dsi.h"
>  #include "rcar_mipi_dsi_regs.h"
>  
> +#define MHZ(v) ((v) * 100u)

Isn't the U suffix usually spelled in uppercase ? Same below.

> +
> +enum rcar_mipi_dsi_hw_model {
> + RCAR_DSI_R8A779A0,
> + RCAR_DSI_R8A779G0,
> +};
> +
> +struct rcar_mipi_dsi_device_info {
> + enum rcar_mipi_dsi_hw_model model;
> + const struct dsi_clk_config *clk_cfg;
> + u8 clockset2_m_offset;
> + u8 clockset2_n_offset;
> +};
> +
>  struct rcar_mipi_dsi {
>   struct device *dev;
>   const struct rcar_mipi_dsi_device_info *info;
> @@ -50,6 +65,17 @@ struct rcar_mipi_dsi {
>   unsigned int lanes;
>  };
>  
> +struct dsi_setup_info {
> + unsigned long hsfreq;
> + u16 hsfreqrange;
> +
> + unsigned long fout;
> + u16 m;
> + u16 n;
> + u16 vclk_divider;
> + const struct dsi_clk_config *clkset;
> +};
> +
>  static inline struct rcar_mipi_dsi *
>  bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
>  {
> @@ -62,22 +88,6 @@ host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
>   return container_of(host, struct rcar_mipi_dsi, host);
>  }
>  
> -static const u32 phtw[] = {
> - 0x01020114, 0x01600115, /* General testing */
> - 0x01030116, 0x0102011d, /* General testing */
> - 0x011101a4, 0x018601a4, /* 1Gbps testing */
> - 0x014201a0, 0x010001a3, /* 1Gbps testing */
> - 0x0101011f, /* 1Gbps testing */
> -};
> -
> -static const u32 phtw2[] = {
> - 0x010c0130, 0x010c0140, /* General testing */
> - 0x010c0150, 0x010c0180, /* General testing */
> - 0x010c0190,
> - 0x010a0160, 0x010a0170,
> - 0x01800164, 0x01800174, /* 1Gbps testing */
> -};
> -
>  static const u32 hsfreqrange_table[][2] = {
>   { 8000U,   0x00 }, { 9000U,   0x10 }, { 1U,  0x20 },
>   { 11000U,  0x30 }, { 12000U,  0x01 }, { 13000U,  0x11 },
> @@ -103,24 +113,53 @@ static const u32 hsfreqrange_table[][2] = {
>   { /* sentinel */ },
>  };
>  
> -struct vco_cntrl_value {
> +struct dsi_clk_config {
>   u32 min_freq;
>   u32 max_freq;
> - u16 value;
> + u8 vco_cntrl;
> + u8 cpbias_cntrl;
> + u8 gmp_cntrl;
> + u8 int_cntrl;
> + u8 prop_cntrl;
>  };
>  
> -static const struct vco_cntrl_value vco_cntrl_table[] = {
> - { .min_freq = 4000U,   .max_freq = 5500U,   .value = 0x3f },
> - { .min_freq = 5250U,   .max_freq = 8000U,   .value = 0x39 },
> - { .min_freq = 8000U,   .max_freq = 11000U,  .value = 0x2f },
> - { .min_freq = 10500U,  .max_freq = 16000U,  .value = 0x29 },
> - { .min_freq = 16000U,  .max_freq = 22000U,  .value = 0x1f },
> - { .min_freq = 21000U,  .max_freq = 32000U,  .value = 0x19 },
> - { .min_freq = 32000U,  .max_freq = 44000U,  .value = 0x0f },
> - { .min_freq = 42000U,  .max_freq = 66000U,  .value = 0x09 },
> - { .min_freq = 63000U,  .max_freq = 114900U, .value = 0x03 },
> - { .min_freq = 11U, .max_freq = 115200U, .value = 0x01 },
> - { .min_freq = 115000U, .max_freq = 125000U, .value = 0x01 },
> +static const struct dsi_clk_config dsi_clk_cfg_r8a779a0[] = {
> + {   4000u,   5500u, 0x3f, 0x10, 0x01, 0x00, 0x0b },
> + {   5250u,   8000u, 0x39, 0x10, 0x01, 0x00, 0x0b },

Would MHZ(52.5) do the right thing ? If so, I'd use the macro through
those tables.

> + {   8000u,  11000u, 0x2f, 0x10, 0x01, 0x00, 0x0b },
> + {  10500u,  16000u, 0x29, 0x10, 0x01, 0x00, 0x0b },
> + {  16000u,  22000u, 0x1f, 0x10, 0x01, 0x00, 0x0b },
> + {  21000u,  32000u, 0x19, 0x10, 0x01, 0x00, 0x0b },
> + {  32000u,  44000u, 0x0f, 0x10, 0x01, 0x00, 0x0b },
> + {  42000u,  66000u, 0x09, 0x10, 0x01, 0x00, 0x0b },
> + {  63000u, 114900u, 0x03, 0x10, 0x01, 0x00, 0x0b },
> + { 11u, 115200u, 0x01, 0x10, 0x01, 0x00, 0x0b },
> + { 115000u, 125000u, 0x01, 0x10, 0x01, 0x00, 0x0c },
> + { /* sentinel */ },
> +};
> +
> +static const struct dsi_clk_config dsi_clk_cfg_r8a779g0[] = {
> + {   4000u,   4531u, 0x2b, 0x00, 0x00, 

Re: [PATCH] drm/bridge: ti-sn65dsi86: Fix output polarity setting bug

2022-11-28 Thread Doug Anderson
Hi,

On Fri, Nov 25, 2022 at 2:54 AM Qiqi Zhang  wrote:
>
> According to the description in ti-sn65dsi86's datasheet:
>
> CHA_HSYNC_POLARITY:
> 0 = Active High Pulse. Synchronization signal is high for the sync
> pulse width. (default)
> 1 = Active Low Pulse. Synchronization signal is low for the sync
> pulse width.
>
> CHA_VSYNC_POLARITY:
> 0 = Active High Pulse. Synchronization signal is high for the sync
> pulse width. (Default)
> 1 = Active Low Pulse. Synchronization signal is low for the sync
> pulse width.
>
> We should only set these bits when the polarity is negative.
> Signed-off-by: Qiqi Zhang 
> ---
>  drivers/gpu/drm/bridge/ti-sn65dsi86.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c 
> b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> index 3c3561942eb6..eb24322df721 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
> @@ -931,9 +931,9 @@ static void ti_sn_bridge_set_video_timings(struct 
> ti_sn65dsi86 *pdata)
> >bridge.encoder->crtc->state->adjusted_mode;
> u8 hsync_polarity = 0, vsync_polarity = 0;
>
> -   if (mode->flags & DRM_MODE_FLAG_PHSYNC)
> +   if (mode->flags & DRM_MODE_FLAG_NHSYNC)
> hsync_polarity = CHA_HSYNC_POLARITY;
> -   if (mode->flags & DRM_MODE_FLAG_PVSYNC)
> +   if (mode->flags & DRM_MODE_FLAG_NVSYNC)
> vsync_polarity = CHA_VSYNC_POLARITY;

Looks right to me.

Reviewed-by: Douglas Anderson 

I've never seen the polarity matter for any eDP panels I've worked
with, which presumably explains why this was wrong for so long. As far
as I can tell, it's been wrong since the start. Probably you should
have:

Fixes: a095f15c00e2 ("drm/bridge: add support for sn65dsi86 bridge driver")

I put this on a sc7180-trogdor-lazor device and it didn't make
anything worse. Since the sync polarity never mattered to begin with,
I guess this isn't a surprise. ...so I guess that's a weak tested-by:

Tested-by: Douglas Anderson 

I'm happy to land this patch, but sounds like we're hoping to get
extra testing so I'll hold off for now.

-Doug


Re: [PATCH v1 7/8] drm: rcar-du: dsi: Add r8A779g0 support

2022-11-28 Thread Laurent Pinchart
On Tue, Nov 22, 2022 at 10:50:30AM +0200, Tomi Valkeinen wrote:
> On 17/11/2022 17:46, Kieran Bingham wrote:
> > Quoting Tomi Valkeinen (2022-11-17 12:25:46)
> >> From: Tomi Valkeinen 
> >>
> >> Add DSI support for r8a779g0. The main differences to r8a779a0 are in
> >> the PLL and PHTW setups.
> >>
> >> Signed-off-by: Tomi Valkeinen 
> >> ---
> >>   drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c  | 484 +++
> >>   drivers/gpu/drm/rcar-du/rcar_mipi_dsi_regs.h |   6 +-
> >>   2 files changed, 384 insertions(+), 106 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c 
> >> b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> >> index a7f2b7f66a17..723c35726c38 100644
> >> --- a/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> >> +++ b/drivers/gpu/drm/rcar-du/rcar_mipi_dsi.c
> >> @@ -9,6 +9,7 @@
> >>   #include 
> >>   #include 
> >>   #include 
> >> +#include 
> >>   #include 
> >>   #include 
> >>   #include 
> >> @@ -28,6 +29,20 @@
> >>   #include "rcar_mipi_dsi.h"
> >>   #include "rcar_mipi_dsi_regs.h"
> >>   
> >> +#define MHZ(v) ((v) * 100u)
> >> +
> >> +enum rcar_mipi_dsi_hw_model {
> >> +   RCAR_DSI_R8A779A0,
> >> +   RCAR_DSI_R8A779G0,
> >> +};
> >> +
> >> +struct rcar_mipi_dsi_device_info {
> >> +   enum rcar_mipi_dsi_hw_model model;
> >> +   const struct dsi_clk_config *clk_cfg;
> >> +   u8 clockset2_m_offset;
> >> +   u8 clockset2_n_offset;
> >> +};
> >> +
> >>   struct rcar_mipi_dsi {
> >>  struct device *dev;
> >>  const struct rcar_mipi_dsi_device_info *info;
> >> @@ -50,6 +65,17 @@ struct rcar_mipi_dsi {
> >>  unsigned int lanes;
> >>   };
> >>   
> >> +struct dsi_setup_info {
> >> +   unsigned long hsfreq;
> >> +   u16 hsfreqrange;
> >> +
> >> +   unsigned long fout;
> >> +   u16 m;
> >> +   u16 n;
> >> +   u16 vclk_divider;
> >> +   const struct dsi_clk_config *clkset;
> >> +};
> >> +
> >>   static inline struct rcar_mipi_dsi *
> >>   bridge_to_rcar_mipi_dsi(struct drm_bridge *bridge)
> >>   {
> >> @@ -62,22 +88,6 @@ host_to_rcar_mipi_dsi(struct mipi_dsi_host *host)
> >>  return container_of(host, struct rcar_mipi_dsi, host);
> >>   }
> >>   
> >> -static const u32 phtw[] = {
> >> -   0x01020114, 0x01600115, /* General testing */
> >> -   0x01030116, 0x0102011d, /* General testing */
> >> -   0x011101a4, 0x018601a4, /* 1Gbps testing */
> >> -   0x014201a0, 0x010001a3, /* 1Gbps testing */
> >> -   0x0101011f, /* 1Gbps testing */
> >> -};
> >> -
> >> -static const u32 phtw2[] = {
> >> -   0x010c0130, 0x010c0140, /* General testing */
> >> -   0x010c0150, 0x010c0180, /* General testing */
> >> -   0x010c0190,
> >> -   0x010a0160, 0x010a0170,
> >> -   0x01800164, 0x01800174, /* 1Gbps testing */
> >> -};
> >> -
> >>   static const u32 hsfreqrange_table[][2] = {
> >>  { 8000U,   0x00 }, { 9000U,   0x10 }, { 1U,  0x20 
> >> },
> >>  { 11000U,  0x30 }, { 12000U,  0x01 }, { 13000U,  0x11 
> >> },
> >> @@ -103,24 +113,53 @@ static const u32 hsfreqrange_table[][2] = {
> >>  { /* sentinel */ },
> >>   };
> >>   
> >> -struct vco_cntrl_value {
> >> +struct dsi_clk_config {
> >>  u32 min_freq;
> >>  u32 max_freq;
> >> -   u16 value;
> >> +   u8 vco_cntrl;
> >> +   u8 cpbias_cntrl;
> >> +   u8 gmp_cntrl;
> >> +   u8 int_cntrl;
> >> +   u8 prop_cntrl;
> >>   };
> >>   
> >> -static const struct vco_cntrl_value vco_cntrl_table[] = {
> >> -   { .min_freq = 4000U,   .max_freq = 5500U,   .value = 0x3f 
> >> },
> >> -   { .min_freq = 5250U,   .max_freq = 8000U,   .value = 0x39 
> >> },
> >> -   { .min_freq = 8000U,   .max_freq = 11000U,  .value = 0x2f 
> >> },
> >> -   { .min_freq = 10500U,  .max_freq = 16000U,  .value = 0x29 
> >> },
> >> -   { .min_freq = 16000U,  .max_freq = 22000U,  .value = 0x1f 
> >> },
> >> -   { .min_freq = 21000U,  .max_freq = 32000U,  .value = 0x19 
> >> },
> >> -   { .min_freq = 32000U,  .max_freq = 44000U,  .value = 0x0f 
> >> },
> >> -   { .min_freq = 42000U,  .max_freq = 66000U,  .value = 0x09 
> >> },
> >> -   { .min_freq = 63000U,  .max_freq = 114900U, .value = 0x03 
> >> },
> >> -   { .min_freq = 11U, .max_freq = 115200U, .value = 0x01 
> >> },
> >> -   { .min_freq = 115000U, .max_freq = 125000U, .value = 0x01 
> >> },
> >> +static const struct dsi_clk_config dsi_clk_cfg_r8a779a0[] = {
> >> +   {   4000u,   5500u, 0x3f, 0x10, 0x01, 0x00, 0x0b },
> >> +   {   5250u,   8000u, 0x39, 0x10, 0x01, 0x00, 0x0b },
> >> +   {   8000u,  11000u, 0x2f, 0x10, 0x01, 0x00, 0x0b },
> >> +   {  10500u,  16000u, 0x29, 0x10, 0x01, 0x00, 0x0b },
> >> +   {  16000u,  22000u, 0x1f, 0x10, 0x01, 0x00, 0x0b },
> >> +   {  21000u,  32000u, 0x19, 0x10, 

[PATCH v2 4/5] drm/i915/mtl: Add hardware-level lock for steering

2022-11-28 Thread Matt Roper
Starting with MTL, the driver needs to not only protect the steering
control register from simultaneous software accesses, but also protect
against races with hardware/firmware agents.  The hardware provides a
dedicated locking mechanism to support this via the MTL_STEER_SEMAPHORE
register.  Reading the register acts as a 'trylock' operation; the read
will return 0x1 if the lock is acquired or 0x0 if something else is
already holding the lock; once acquired, writing 0x1 to the register
will release the lock.

We'll continue to grab the software lock as well, just so lockdep can
track our locking; assuming the hardware lock is behaving properly,
there should never be any contention on the software lock in this case.

v2:
 - Extend hardware semaphore timeout and add a taint for CI if it ever
   happens (this would imply misbehaving hardware/firmware).  (Mika)
 - Add "MTL_" prefix to new steering semaphore register.  (Mika)

Cc: Mika Kuoppala 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c  | 38 ++---
 drivers/gpu/drm/i915/gt/intel_gt_regs.h |  1 +
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index aa070ae57f11..087e4ac5b68d 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -347,10 +347,9 @@ static u32 rw_with_mcr_steering(struct intel_gt *gt,
  * @flags: storage to save IRQ flags to
  *
  * Performs locking to protect the steering for the duration of an MCR
- * operation.  Depending on the platform, this may be a software lock
- * (gt->mcr_lock) or a hardware lock (i.e., a register that synchronizes
- * access not only for the driver, but also for external hardware and
- * firmware agents).
+ * operation.  On MTL and beyond, a hardware lock will also be taken to
+ * serialize access not only for the driver, but also for external hardware and
+ * firmware agents.
  *
  * Context: Takes gt->mcr_lock.  uncore->lock should *not* be held when this
  *  function is called, although it may be acquired after this
@@ -359,12 +358,40 @@ static u32 rw_with_mcr_steering(struct intel_gt *gt,
 void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long *flags)
 {
unsigned long __flags;
+   int err = 0;
 
lockdep_assert_not_held(>uncore->lock);
 
+   /*
+* Starting with MTL, we need to coordinate not only with other
+* driver threads, but also with hardware/firmware agents.  A dedicated
+* locking register is used.
+*/
+   if (GRAPHICS_VER(gt->i915) >= IP_VER(12, 70))
+   err = wait_for(intel_uncore_read_fw(gt->uncore,
+   MTL_STEER_SEMAPHORE) == 
0x1, 100);
+
+   /*
+* Even on platforms with a hardware lock, we'll continue to grab
+* a software spinlock too for lockdep purposes.  If the hardware lock
+* was already acquired, there should never be contention on the
+* software lock.
+*/
spin_lock_irqsave(>mcr_lock, __flags);
 
*flags = __flags;
+
+   /*
+* In theory we should never fail to acquire the HW semaphore; this
+* would indicate some hardware/firmware is misbehaving and not
+* releasing it properly.
+*/
+   if (err == -ETIMEDOUT) {
+   drm_err_ratelimited(>i915->drm,
+   "GT%u hardware MCR steering semaphore timed 
out",
+   gt->info.id);
+   add_taint_for_CI(gt->i915, TAINT_WARN);  /* CI is now 
unreliable */
+   }
 }
 
 /**
@@ -379,6 +406,9 @@ void intel_gt_mcr_lock(struct intel_gt *gt, unsigned long 
*flags)
 void intel_gt_mcr_unlock(struct intel_gt *gt, unsigned long flags)
 {
spin_unlock_irqrestore(>mcr_lock, flags);
+
+   if (GRAPHICS_VER(gt->i915) >= IP_VER(12, 70))
+   intel_uncore_write_fw(gt->uncore, MTL_STEER_SEMAPHORE, 0x1);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index 784152548472..1618d46cb8c7 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -67,6 +67,7 @@
 #define GMD_ID_MEDIA   _MMIO(MTL_MEDIA_GSI_BASE + 
0xd8c)
 
 #define MCFG_MCR_SELECTOR  _MMIO(0xfd0)
+#define MTL_STEER_SEMAPHORE_MMIO(0xfd0)
 #define MTL_MCR_SELECTOR   _MMIO(0xfd4)
 #define SF_MCR_SELECTOR_MMIO(0xfd8)
 #define GEN8_MCR_SELECTOR  _MMIO(0xfdc)
-- 
2.38.1



[PATCH v2 3/5] drm/i915/gt: Add dedicated MCR lock

2022-11-28 Thread Matt Roper
We've been overloading uncore->lock to protect access to the MCR
steering register.  That's not really what uncore->lock is intended for,
and it would be better if we didn't need to hold such a high-traffic
spinlock for the whole sequence of (apply steering, access MCR register,
restore steering).  Let's create a dedicated MCR lock to protect the
steering control register over this critical section and stop relying on
the high-traffic uncore->lock.

For now the new lock is a software lock.  However some platforms (MTL
and beyond) have a hardware-provided locking mechanism that can be used
to serialize not only software accesses, but also hardware/firmware
accesses as well; support for that hardware level lock will be added in
a future patch.

v2:
 - Use irqsave/irqrestore spinlock calls; platforms using execlist
   submission rather than GuC submission can perform MCR accesses in
   interrupt context because reset -> errordump happens in a tasklet.

Cc: Chris Wilson 
Cc: Mika Kuoppala 
Cc: Balasubramani Vivekanandan 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_gt.c  |  7 +-
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c  | 79 +++--
 drivers/gpu/drm/i915/gt/intel_gt_mcr.h  |  2 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h|  8 +++
 drivers/gpu/drm/i915/gt/intel_mocs.c|  3 +
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 12 ++--
 6 files changed, 101 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index 7ef0edb2e37c..6847f3bd2b03 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -1079,6 +1079,7 @@ static void mmio_invalidate_full(struct intel_gt *gt)
enum intel_engine_id id;
const i915_reg_t *regs;
unsigned int num = 0;
+   unsigned long flags;
 
if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50)) {
regs = NULL;
@@ -1099,7 +1100,8 @@ static void mmio_invalidate_full(struct intel_gt *gt)
 
intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
 
-   spin_lock_irq(>lock); /* serialise invalidate with GT reset */
+   intel_gt_mcr_lock(gt, );
+   spin_lock(>lock); /* serialise invalidate with GT reset */
 
awake = 0;
for_each_engine(engine, gt, id) {
@@ -1133,7 +1135,8 @@ static void mmio_invalidate_full(struct intel_gt *gt)
 IS_ALDERLAKE_P(i915)))
intel_uncore_write_fw(uncore, GEN12_OA_TLB_INV_CR, 1);
 
-   spin_unlock_irq(>lock);
+   spin_unlock(>lock);
+   intel_gt_mcr_unlock(gt, flags);
 
for_each_engine_masked(engine, gt, awake, tmp) {
struct reg_and_bit rb;
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index f4484bb18ec9..aa070ae57f11 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -143,6 +143,8 @@ void intel_gt_mcr_init(struct intel_gt *gt)
unsigned long fuse;
int i;
 
+   spin_lock_init(>mcr_lock);
+
/*
 * An mslice is unavailable only if both the meml3 for the slice is
 * disabled *and* all of the DSS in the slice (quadrant) are disabled.
@@ -228,6 +230,7 @@ static i915_reg_t mcr_reg_cast(const i915_mcr_reg_t mcr)
  * @instance: instance number (documented as "subsliceid" on older platforms)
  * @value: register value to be written (ignored for read)
  *
+ * Context: The caller must hold the MCR lock
  * Return: 0 for write access. register value for read access.
  *
  * Caller needs to make sure the relevant forcewake wells are up.
@@ -239,7 +242,7 @@ static u32 rw_with_mcr_steering_fw(struct intel_gt *gt,
struct intel_uncore *uncore = gt->uncore;
u32 mcr_mask, mcr_ss, mcr, old_mcr, val = 0;
 
-   lockdep_assert_held(>lock);
+   lockdep_assert_held(>mcr_lock);
 
if (GRAPHICS_VER_FULL(uncore->i915) >= IP_VER(12, 70)) {
/*
@@ -316,6 +319,7 @@ static u32 rw_with_mcr_steering(struct intel_gt *gt,
 {
struct intel_uncore *uncore = gt->uncore;
enum forcewake_domains fw_domains;
+   unsigned long flags;
u32 val;
 
fw_domains = intel_uncore_forcewake_for_reg(uncore, mcr_reg_cast(reg),
@@ -324,17 +328,59 @@ static u32 rw_with_mcr_steering(struct intel_gt *gt,
 GEN8_MCR_SELECTOR,
 FW_REG_READ | 
FW_REG_WRITE);
 
-   spin_lock_irq(>lock);
+   intel_gt_mcr_lock(gt, );
+   spin_lock(>lock);
intel_uncore_forcewake_get__locked(uncore, fw_domains);
 
val = rw_with_mcr_steering_fw(gt, reg, rw_flag, group, instance, value);
 
intel_uncore_forcewake_put__locked(uncore, fw_domains);
-   spin_unlock_irq(>lock);
+   spin_unlock(>lock);
+   intel_gt_mcr_unlock(gt, flags);
 
return val;
 }
 
+/**
+ * intel_gt_mcr_lock - Acquire MCR steering 

[PATCH v2 5/5] drm/i915/mtl: Hold forcewake and MCR lock over PPAT setup

2022-11-28 Thread Matt Roper
PPAT setup involves a series of multicast writes.  This can be optimized
slightly be acquiring forcewake and the steering lock just once for the
entire sequence.

Suggested-by: Balasubramani Vivekanandan 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_gtt.c | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c 
b/drivers/gpu/drm/i915/gt/intel_gtt.c
index 2ba3983984b9..288d9f118ee9 100644
--- a/drivers/gpu/drm/i915/gt/intel_gtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gtt.c
@@ -482,14 +482,25 @@ static void tgl_setup_private_ppat(struct intel_uncore 
*uncore)
 
 static void xehp_setup_private_ppat(struct intel_gt *gt)
 {
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(0), GEN8_PPAT_WB);
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(1), GEN8_PPAT_WC);
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(2), GEN8_PPAT_WT);
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(3), GEN8_PPAT_UC);
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(4), GEN8_PPAT_WB);
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(5), GEN8_PPAT_WB);
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(6), GEN8_PPAT_WB);
-   intel_gt_mcr_multicast_write(gt, XEHP_PAT_INDEX(7), GEN8_PPAT_WB);
+   enum forcewake_domains fw;
+   unsigned long flags;
+
+   fw = intel_uncore_forcewake_for_reg(gt->uncore, 
_MMIO(XEHP_PAT_INDEX(0).reg),
+   FW_REG_READ);
+   intel_uncore_forcewake_get(gt->uncore, fw);
+
+   intel_gt_mcr_lock(gt, );
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(0), GEN8_PPAT_WB);
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(1), GEN8_PPAT_WC);
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(2), GEN8_PPAT_WT);
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(3), GEN8_PPAT_UC);
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(4), GEN8_PPAT_WB);
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(5), GEN8_PPAT_WB);
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(6), GEN8_PPAT_WB);
+   intel_gt_mcr_multicast_write_fw(gt, XEHP_PAT_INDEX(7), GEN8_PPAT_WB);
+   intel_gt_mcr_unlock(gt, flags);
+
+   intel_uncore_forcewake_put(gt->uncore, fw);
 }
 
 static void icl_setup_private_ppat(struct intel_uncore *uncore)
-- 
2.38.1



[PATCH v2 1/5] drm/i915/gt: Correct kerneldoc for intel_gt_mcr_wait_for_reg()

2022-11-28 Thread Matt Roper
The kerneldoc function name was not updated when this function was
converted to a non-fw form.

Fixes: 192bb40f030a ("drm/i915/gt: Manage uncore->lock while waiting on MCR 
register")
Reported-by: kernel test robot 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index d9a8ff9e5e57..ea86c1ab5dc5 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -702,7 +702,7 @@ void intel_gt_mcr_get_ss_steering(struct intel_gt *gt, 
unsigned int dss,
 }
 
 /**
- * intel_gt_mcr_wait_for_reg_fw - wait until MCR register matches expected 
state
+ * intel_gt_mcr_wait_for_reg - wait until MCR register matches expected state
  * @gt: GT structure
  * @reg: the register to read
  * @mask: mask to apply to register value
-- 
2.38.1



[PATCH v2 0/5] i915: dedicated MCR locking and hardware semaphore

2022-11-28 Thread Matt Roper
We've been overloading uncore->lock to protect access to the MCR
steering register.  That's not really what uncore->lock is intended for,
and it would be better if we didn't need to hold such a high-traffic
spinlock for the whole sequence of (apply steering, access MCR register,
restore steering).  Switch to a dedicated MCR lock to protect the
steering control register over this critical section and stop relying on
the high-traffic uncore->lock.  On pre-MTL platforms the dedicated MCR
lock is just another software lock, but on MTL and beyond we also
utilize the hardware-provided STEER_SEMAPHORE that allows us to
synchronize with external hardware and firmware agents.

v2:
 - Use irqsave/irqrestore locking; on platforms that use execlist
   submission instead of GuC, MCR accesses can happen in interrupt
   context (tasklet) during reset -> error dump.
 - Extend timeout for hardware semaphore and CI taint if we ever
   encounter it (this implies a hardware/firmware problem).  (Mika)
 - Add an extra patch optimizing xehp_setup_private_ppat by holding
   forcewake & mcr lock over the sequence of register writes.  (Bala)

Cc: Mika Kuoppala 
Cc: Balasubramani Vivekanandan 

Matt Roper (5):
  drm/i915/gt: Correct kerneldoc for intel_gt_mcr_wait_for_reg()
  drm/i915/gt: Pass gt rather than uncore to lowest-level reads/writes
  drm/i915/gt: Add dedicated MCR lock
  drm/i915/mtl: Add hardware-level lock for steering
  drm/i915/mtl: Hold forcewake and MCR lock over PPAT setup

 drivers/gpu/drm/i915/gt/intel_gt.c  |   7 +-
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c  | 129 ++--
 drivers/gpu/drm/i915/gt/intel_gt_mcr.h  |   2 +
 drivers/gpu/drm/i915/gt/intel_gt_regs.h |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_types.h|   8 ++
 drivers/gpu/drm/i915/gt/intel_gtt.c |  27 ++--
 drivers/gpu/drm/i915/gt/intel_mocs.c|   3 +
 drivers/gpu/drm/i915/gt/intel_workarounds.c |  12 +-
 8 files changed, 162 insertions(+), 27 deletions(-)

-- 
2.38.1



[PATCH v2 2/5] drm/i915/gt: Pass gt rather than uncore to lowest-level reads/writes

2022-11-28 Thread Matt Roper
Passing the GT rather than uncore to the lowest level MCR read and write
functions will make it easier to introduce dedicated MCR locking in a
following patch.

Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/gt/intel_gt_mcr.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c 
b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
index ea86c1ab5dc5..f4484bb18ec9 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_mcr.c
@@ -221,7 +221,7 @@ static i915_reg_t mcr_reg_cast(const i915_mcr_reg_t mcr)
 
 /*
  * rw_with_mcr_steering_fw - Access a register with specific MCR steering
- * @uncore: pointer to struct intel_uncore
+ * @gt: GT to read register from
  * @reg: register being accessed
  * @rw_flag: FW_REG_READ for read access or FW_REG_WRITE for write access
  * @group: group number (documented as "sliceid" on older platforms)
@@ -232,10 +232,11 @@ static i915_reg_t mcr_reg_cast(const i915_mcr_reg_t mcr)
  *
  * Caller needs to make sure the relevant forcewake wells are up.
  */
-static u32 rw_with_mcr_steering_fw(struct intel_uncore *uncore,
+static u32 rw_with_mcr_steering_fw(struct intel_gt *gt,
   i915_mcr_reg_t reg, u8 rw_flag,
   int group, int instance, u32 value)
 {
+   struct intel_uncore *uncore = gt->uncore;
u32 mcr_mask, mcr_ss, mcr, old_mcr, val = 0;
 
lockdep_assert_held(>lock);
@@ -308,11 +309,12 @@ static u32 rw_with_mcr_steering_fw(struct intel_uncore 
*uncore,
return val;
 }
 
-static u32 rw_with_mcr_steering(struct intel_uncore *uncore,
+static u32 rw_with_mcr_steering(struct intel_gt *gt,
i915_mcr_reg_t reg, u8 rw_flag,
int group, int instance,
u32 value)
 {
+   struct intel_uncore *uncore = gt->uncore;
enum forcewake_domains fw_domains;
u32 val;
 
@@ -325,7 +327,7 @@ static u32 rw_with_mcr_steering(struct intel_uncore *uncore,
spin_lock_irq(>lock);
intel_uncore_forcewake_get__locked(uncore, fw_domains);
 
-   val = rw_with_mcr_steering_fw(uncore, reg, rw_flag, group, instance, 
value);
+   val = rw_with_mcr_steering_fw(gt, reg, rw_flag, group, instance, value);
 
intel_uncore_forcewake_put__locked(uncore, fw_domains);
spin_unlock_irq(>lock);
@@ -347,7 +349,7 @@ u32 intel_gt_mcr_read(struct intel_gt *gt,
  i915_mcr_reg_t reg,
  int group, int instance)
 {
-   return rw_with_mcr_steering(gt->uncore, reg, FW_REG_READ, group, 
instance, 0);
+   return rw_with_mcr_steering(gt, reg, FW_REG_READ, group, instance, 0);
 }
 
 /**
@@ -364,7 +366,7 @@ u32 intel_gt_mcr_read(struct intel_gt *gt,
 void intel_gt_mcr_unicast_write(struct intel_gt *gt, i915_mcr_reg_t reg, u32 
value,
int group, int instance)
 {
-   rw_with_mcr_steering(gt->uncore, reg, FW_REG_WRITE, group, instance, 
value);
+   rw_with_mcr_steering(gt, reg, FW_REG_WRITE, group, instance, value);
 }
 
 /**
@@ -588,7 +590,7 @@ u32 intel_gt_mcr_read_any_fw(struct intel_gt *gt, 
i915_mcr_reg_t reg)
for (type = 0; type < NUM_STEERING_TYPES; type++) {
if (reg_needs_read_steering(gt, reg, type)) {
get_nonterminated_steering(gt, type, , );
-   return rw_with_mcr_steering_fw(gt->uncore, reg,
+   return rw_with_mcr_steering_fw(gt, reg,
   FW_REG_READ,
   group, instance, 0);
}
@@ -615,7 +617,7 @@ u32 intel_gt_mcr_read_any(struct intel_gt *gt, 
i915_mcr_reg_t reg)
for (type = 0; type < NUM_STEERING_TYPES; type++) {
if (reg_needs_read_steering(gt, reg, type)) {
get_nonterminated_steering(gt, type, , );
-   return rw_with_mcr_steering(gt->uncore, reg,
+   return rw_with_mcr_steering(gt, reg,
FW_REG_READ,
group, instance, 0);
}
-- 
2.38.1



Re: [6.1][regression] after commit dd80d9c8eecac8c516da5b240d01a35660ba6cb6 some games (Cyberpunk 2077, Forza Horizon 4/5) hang at start

2022-11-28 Thread Mikhail Gavrilov
On Tue, Nov 22, 2022 at 12:16 PM Christian König
 wrote:
>
> Ah, thanks a lot for this. I've already pushed the patches into our
> internal branch, but getting this confirmation is still great!
>
> This was quite some fundamental bug in the handling and I hope to get
> this completely reworked at some point since it is currently only mitigated.

Looks like the final version of this patch successfully merged in 6.1-rc7.
Big thanks, all games work again!

> No idea what that could be. Modesetting is not something I work on.
>
> The best advice I can give you is to maybe ping Harry and our other
> display people, they should know that stuff better than I do.

Unfortunately Harry didn't answer. I hope my email wasn't marked as spam.

-- 
Best Regards,
Mike Gavrilov.


Re: [PATCH mm-unstable v1 16/20] mm/frame-vector: remove FOLL_FORCE usage

2022-11-28 Thread Andrew Morton
On Mon, 28 Nov 2022 09:18:47 +0100 David Hildenbrand  wrote:

> > Less chances of things going wrong that way.
> > 
> > Just mention in the v2 cover letter that the first patch was added to
> > make it easy to backport that fix without being hampered by merge
> > conflicts if it was added after your frame_vector.c patch.
> 
> Yes, that's the way I would naturally do, it, however, Andrew prefers 
> delta updates for minor changes.
> 
> @Andrew, whatever you prefer!

I'm inclined to let things sit as they are.  Cross-tree conflicts
happen, and Linus handles them.  I'll flag this (very simple) conflict
in the pull request, if MM merges second.  If v4l merges second then
hopefully they will do the same.  But this one is so simple that Linus
hardly needs our help.

But Linus won't be editing changelogs so that the changelog makes more
sense after both trees are joined.  I'm inclined to let the changelog
sit as it is as well.


Re: [PATCH v2 00/17] drm: Introduce Kunit Tests to VC4

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> Hi,
> 
> This series introduce Kunit tests to the vc4 KMS driver, but unlike what we
> have been doing so far in KMS, it actually tests the atomic modesetting code.
> 
> In order to do so, I've had to improve a fair bit on the Kunit helpers already
> found in the tree in order to register a full blown and somewhat functional 
> KMS
> driver.
> 
> It's of course relying on a mock so that we can test it anywhere. The mocking
> approach created a number of issues, the main one being that we need to create
> a decent mock in the first place, see patch 22. The basic idea is that I
> created some structures to provide a decent approximation of the actual
> hardware, and that would support both major architectures supported by vc4.
> 
> This is of course meant to evolve over time and support more tests, but I've
> focused on testing the HVS FIFO assignment code which is fairly tricky (and 
> the
> tests have actually revealed one more bug with our current implementation). I
> used to have a userspace implementation of those tests, where I would copy and
> paste the kernel code and run the tests on a regular basis. It's was obviously
> fairly suboptimal, so it seemed like the perfect testbed for that series.
> 
> It can be run using:
> ./tools/testing/kunit/kunit.py run \
> --kunitconfig=drivers/gpu/drm/vc4/tests/.kunitconfig \
> --cross_compile aarch64-linux-gnu- --arch arm64
> 
> Let me know what you think,
> Maxime

Hi Maxime,

It is great to see some device mocking with KUnit! Other than the
comments that I pointed out in the series, I believe that a small entry
on the VC4 documentation would be nice to cover how to run the tests and
also what the tests are currently covering.

Best Regards,
- Maíra Canal

> 
> To: David Airlie 
> To: Daniel Vetter 
> To: Maarten Lankhorst 
> To: Maxime Ripard 
> To: Thomas Zimmermann 
> Cc: Dave Stevenson 
> Cc: Javier Martinez Canillas 
> Cc: Greg Kroah-Hartman 
> Cc: Maíra Canal 
> Cc: Brendan Higgins 
> Cc: David Gow 
> Cc: linux-kselft...@vger.kernel.org
> Cc: kunit-...@googlegroups.com
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-ker...@vger.kernel.org
> Cc: linux-me...@vger.kernel.org
> Cc: linaro-mm-...@lists.linaro.org
> Signed-off-by: Maxime Ripard 
> 
> ---
> Changes in v2:
> - Added some documentation for public functions
> - Removed the fake device probe/remove workqueue 
> - Made sure the tests could be compiled as modules
> - Moved the vc4 tests in the vc4 module
> - Applied some of the preliminary patches
> - Rebased on top of current drm-misc-next branch
> - Fixed checkpatch issues
> - Introduced BCM2835 (Pi0-3) tests for muxing
> - Introduced tests to cover past bugs we had
> - Link to v1: 
> https://lore.kernel.org/r/20221123-rpi-kunit-tests-v1-0-051a0bb60...@cerno.tech
> 
> ---
> Maxime Ripard (17):
>   drm/tests: helpers: Move the helper header to include/drm
>   drm/tests: helpers: Document drm_kunit_device_init()
>   drm/tests: helpers: Rename the device init helper
>   drm/tests: helpers: Remove the name parameter
>   drm/tests: helpers: Create the device in another function
>   drm/tests: helpers: Switch to a platform_device
>   drm/tests: helpers: Make sure the device is bound
>   drm/tests: helpers: Allow for a custom device struct to be allocated
>   drm/tests: helpers: Allow to pass a custom drm_driver
>   drm/tests: Add a test for DRM managed actions
>   drm/vc4: Move HVS state to main header
>   drm/vc4: crtc: Introduce a lower-level crtc init helper
>   drm/vc4: crtc: Make encoder lookup helper public
>   drm/vc4: hvs: Provide a function to initialize the HVS structure
>   drm/vc4: tests: Introduce a mocking infrastructure
>   drm/vc4: tests: Fail the current test if we access a register
>   drm/vc4: tests: Add unit test suite for the PV muxing
> 
>  drivers/gpu/drm/tests/Makefile  |1 +
>  drivers/gpu/drm/tests/drm_client_modeset_test.c |   19 +-
>  drivers/gpu/drm/tests/drm_kunit_helpers.c   |  106 ++-
>  drivers/gpu/drm/tests/drm_kunit_helpers.h   |   11 -
>  drivers/gpu/drm/tests/drm_managed_test.c|   71 ++
>  drivers/gpu/drm/tests/drm_modes_test.c  |   19 +-
>  drivers/gpu/drm/tests/drm_probe_helper_test.c   |   20 +-
>  drivers/gpu/drm/vc4/Kconfig |   15 +
>  drivers/gpu/drm/vc4/Makefile|7 +
>  drivers/gpu/drm/vc4/tests/.kunitconfig  |   14 +
>  drivers/gpu/drm/vc4/tests/vc4_mock.c|  200 +
>  drivers/gpu/drm/vc4/tests/vc4_mock.h|   63 ++
>  drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c   |   41 +
>  drivers/gpu/drm/vc4/tests/vc4_mock_output.c |  138 +++
>  drivers/gpu/drm/vc4/tests/vc4_mock_plane.c  |   47 +
>  drivers/gpu/drm/vc4/tests/vc4_test_pv_muxing.c  | 1039 
> +++
>  drivers/gpu/drm/vc4/vc4_crtc.c  |  102 ++-
>  

Re: [PATCH v2 03/17] drm/tests: helpers: Rename the device init helper

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> The name doesn't really fit the conventions for the other helpers in
> DRM/KMS, so let's rename it to make it obvious that we allocate a new
> DRM device.
> 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal

> ---
>  drivers/gpu/drm/tests/drm_client_modeset_test.c | 3 ++-
>  drivers/gpu/drm/tests/drm_kunit_helpers.c   | 8 +---
>  drivers/gpu/drm/tests/drm_modes_test.c  | 3 ++-
>  drivers/gpu/drm/tests/drm_probe_helper_test.c   | 5 +++--
>  include/drm/drm_kunit_helpers.h | 5 -
>  5 files changed, 16 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_client_modeset_test.c 
> b/drivers/gpu/drm/tests/drm_client_modeset_test.c
> index ed2f62e92fea..6cdf08f582ce 100644
> --- a/drivers/gpu/drm/tests/drm_client_modeset_test.c
> +++ b/drivers/gpu/drm/tests/drm_client_modeset_test.c
> @@ -59,7 +59,8 @@ static int drm_client_modeset_test_init(struct kunit *test)
>  
>   test->priv = priv;
>  
> - priv->drm = drm_kunit_device_init(test, DRIVER_MODESET, 
> "drm-client-modeset-test");
> + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET,
> +   
> "drm-client-modeset-test");
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
>  
>   ret = drmm_connector_init(priv->drm, >connector,
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
> b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 46a68c2fd80c..2f67f6cf78d0 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -36,7 +36,7 @@ static void dev_free(struct kunit_resource *res)
>  }
>  
>  /**
> - * drm_kunit_device_init - Allocates a mock DRM device for Kunit tests
> + * drm_kunit_helper_alloc_drm_device - Allocates a mock DRM device for Kunit 
> tests
>   * @test: The test context object
>   * @features: Mocked DRM device driver features
>   * @name: Name of the struct  to allocate
> @@ -52,7 +52,9 @@ static void dev_free(struct kunit_resource *res)
>   * Returns:
>   * A pointer to the new drm_device, or an ERR_PTR() otherwise.
>   */
> -struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, 
> char *name)
> +struct drm_device *
> +drm_kunit_helper_alloc_drm_device(struct kunit *test,
> +   u32 features, char *name)
>  {
>   struct kunit_dev *kdev;
>   struct drm_device *drm;
> @@ -82,7 +84,7 @@ struct drm_device *drm_kunit_device_init(struct kunit 
> *test, u32 features, char
>  
>   return drm;
>  }
> -EXPORT_SYMBOL(drm_kunit_device_init);
> +EXPORT_SYMBOL(drm_kunit_helper_alloc_drm_device);
>  
>  MODULE_AUTHOR("Maxime Ripard ");
>  MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/tests/drm_modes_test.c 
> b/drivers/gpu/drm/tests/drm_modes_test.c
> index 3953e478c4d0..6723089dff9f 100644
> --- a/drivers/gpu/drm/tests/drm_modes_test.c
> +++ b/drivers/gpu/drm/tests/drm_modes_test.c
> @@ -22,7 +22,8 @@ static int drm_test_modes_init(struct kunit *test)
>   priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
>   KUNIT_ASSERT_NOT_NULL(test, priv);
>  
> - priv->drm = drm_kunit_device_init(test, DRIVER_MODESET, 
> "drm-modes-test");
> + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET,
> +   "drm-modes-test");
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
>  
>   test->priv = priv;
> diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c 
> b/drivers/gpu/drm/tests/drm_probe_helper_test.c
> index 1f3941c150ae..85236ff4744f 100644
> --- a/drivers/gpu/drm/tests/drm_probe_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c
> @@ -39,8 +39,9 @@ static int drm_probe_helper_test_init(struct kunit *test)
>   KUNIT_ASSERT_NOT_NULL(test, priv);
>   test->priv = priv;
>  
> - priv->drm = drm_kunit_device_init(test, DRIVER_MODESET | DRIVER_ATOMIC,
> -   "drm-probe-helper-test");
> + priv->drm = drm_kunit_helper_alloc_drm_device(test,
> +   DRIVER_MODESET | 
> DRIVER_ATOMIC,
> +   "drm-probe-helper-test");
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
>  
>   connector = >connector;
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index 20ab6eec4c89..e9870c7911fe 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -6,6 +6,9 @@
>  struct drm_device;
>  struct kunit;
>  
> -struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, 
> char *name);
> +struct drm_device *
> +drm_kunit_helper_alloc_drm_device(struct kunit *test,
> +   u32 features,
> +   char *name);
>  
>  #endif // DRM_KUNIT_HELPERS_H_
> 


Re: [PATCH v2 15/17] drm/vc4: tests: Introduce a mocking infrastructure

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> In order to test the current atomic_check hooks we need to have a DRM
> device that has roughly the same capabilities and layout that the actual
> hardware. We'll also need a bunch of functions to create arbitrary
> atomic states.
> 
> Let's create some helpers to create a device that behaves like the real
> one, and some helpers to maintain the atomic state we want to check.
> 
> Signed-off-by: Maxime Ripard 
> ---
>  drivers/gpu/drm/vc4/Kconfig |  15 +++
>  drivers/gpu/drm/vc4/Makefile|   6 +
>  drivers/gpu/drm/vc4/tests/.kunitconfig  |  14 ++
>  drivers/gpu/drm/vc4/tests/vc4_mock.c| 200 
> 
>  drivers/gpu/drm/vc4/tests/vc4_mock.h|  60 +
>  drivers/gpu/drm/vc4/tests/vc4_mock_crtc.c   |  41 ++
>  drivers/gpu/drm/vc4/tests/vc4_mock_output.c |  99 ++
>  drivers/gpu/drm/vc4/tests/vc4_mock_plane.c  |  47 +++
>  drivers/gpu/drm/vc4/vc4_crtc.c  |  20 +--
>  drivers/gpu/drm/vc4/vc4_drv.c   |   4 +-
>  drivers/gpu/drm/vc4/vc4_drv.h   |  16 +++
>  drivers/gpu/drm/vc4/vc4_txp.c   |   2 +-
>  12 files changed, 511 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/Kconfig b/drivers/gpu/drm/vc4/Kconfig
> index 246305d17a52..dcdcc9e5cac4 100644
> --- a/drivers/gpu/drm/vc4/Kconfig
> +++ b/drivers/gpu/drm/vc4/Kconfig
> @@ -34,3 +34,18 @@ config DRM_VC4_HDMI_CEC
>   help
> Choose this option if you have a Broadcom VC4 GPU
> and want to use CEC.
> +
> +config DRM_VC4_KUNIT_TEST
> + bool "KUnit tests for VC4" if !KUNIT_ALL_TESTS
> + depends on DRM_VC4 && KUNIT
> + default KUNIT_ALL_TESTS
> + help
> +   This builds unit tests for the VC4 DRM/KMS driver. This option is
> +   not useful for distributions or general kernels, but only for kernel
> +   developers working on the VC4 driver.
> +
> +   For more information on KUnit and unit tests in general,
> +   please refer to the KUnit documentation in
> +   Documentation/dev-tools/kunit/.
> +
> +   If in doubt, say "N".
> diff --git a/drivers/gpu/drm/vc4/Makefile b/drivers/gpu/drm/vc4/Makefile
> index d0163e18e9ca..f974a8c80e2f 100644
> --- a/drivers/gpu/drm/vc4/Makefile
> +++ b/drivers/gpu/drm/vc4/Makefile
> @@ -25,6 +25,12 @@ vc4-y := \
>   vc4_validate.o \
>   vc4_validate_shaders.o
>  
> +vc4-$(CONFIG_DRM_VC4_KUNIT_TEST) += \
> + tests/vc4_mock.o \
> + tests/vc4_mock_crtc.o \
> + tests/vc4_mock_output.o \
> + tests/vc4_mock_plane.o
> +
>  vc4-$(CONFIG_DEBUG_FS) += vc4_debugfs.o
>  
>  obj-$(CONFIG_DRM_VC4)  += vc4.o
> diff --git a/drivers/gpu/drm/vc4/tests/.kunitconfig 
> b/drivers/gpu/drm/vc4/tests/.kunitconfig
> new file mode 100644
> index ..bfd9899ed6e0
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/tests/.kunitconfig
> @@ -0,0 +1,14 @@
> +CONFIG_ARCH_BCM=y
> +CONFIG_ARCH_BCM2835=y
> +CONFIG_BCM2835_MBOX=y
> +CONFIG_KUNIT=y
> +CONFIG_DRM=y
> +CONFIG_DRM_KUNIT_TEST=y

I'm not sure if it makes sense to run the DRM tests here as well. Maybe
it would be better to separate the compilation of the drm_kunit_helpers
from the compilation of the rest of the DRM tests. This way, this
Kconfig entry could be dropped and only the vc4 tests would run.
Moreover, it would allow to run the vc4 tests with --arch=arm.

Best Regards,
- Maíra Canal

> +CONFIG_DRM_VC4=y
> +CONFIG_DRM_VC4_KUNIT_TEST=y
> +CONFIG_MAILBOX=y
> +CONFIG_RASPBERRYPI_FIRMWARE=y
> +CONFIG_SND=y
> +CONFIG_SND_SOC=y
> +CONFIG_SOUND=y
> +CONFIG_COMMON_CLK=y
> diff --git a/drivers/gpu/drm/vc4/tests/vc4_mock.c 
> b/drivers/gpu/drm/vc4/tests/vc4_mock.c
> new file mode 100644
> index ..a4bed26af32f
> --- /dev/null
> +++ b/drivers/gpu/drm/vc4/tests/vc4_mock.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "vc4_mock.h"
> +
> +struct vc4_mock_output_desc {
> + enum vc4_encoder_type   vc4_encoder_type;
> + unsigned intencoder_type;
> + unsigned intconnector_type;
> +};
> +
> +#define VC4_MOCK_OUTPUT_DESC(_vc4_type, _etype, _ctype)  
> \
> + {   
> \
> + .vc4_encoder_type = _vc4_type,  
> \
> + .encoder_type = _etype, 
> \
> + .connector_type = _ctype,   
> \
> + }
> +
> +struct vc4_mock_pipe_desc {
> + const struct vc4_crtc_data *data;
> + const struct vc4_mock_output_desc *outputs;
> + unsigned int noutputs;
> +};
> +
> +#define VC4_MOCK_CRTC_DESC(_data, ...)   
> \
> + {   
>

Re: [PATCH v2 13/17] drm/vc4: crtc: Make encoder lookup helper public

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> We'll need a function that looks up an encoder by its vc4_encoder_type.
> Such a function is already present in the CRTC code, so let's make it
> public so that we can reuse it in the unit tests.
> 
> Reviewed-by: Javier Martinez Canillas 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 17 +
>  drivers/gpu/drm/vc4/vc4_drv.h  | 16 
>  2 files changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 7a2c54efecb0..59e473059fa2 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -486,21 +486,6 @@ static int vc4_crtc_disable(struct drm_crtc *crtc,
>   return 0;
>  }
>  
> -static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc 
> *crtc,
> - enum vc4_encoder_type 
> type)
> -{
> - struct drm_encoder *encoder;
> -
> - drm_for_each_encoder(encoder, crtc->dev) {
> - struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
> -
> - if (vc4_encoder->type == type)
> - return encoder;
> - }
> -
> - return NULL;
> -}
> -
>  int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
>  {
>   struct drm_device *drm = crtc->dev;
> @@ -536,7 +521,7 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
>  
>   pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
>   encoder_type = pv_data->encoder_types[encoder_sel];
> - encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type);
> + encoder = vc4_find_encoder_by_type(drm, encoder_type);
>   if (WARN_ON(!encoder))
>   return 0;
>  
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index cd2002fff115..54352db48476 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -495,6 +495,22 @@ to_vc4_encoder(const struct drm_encoder *encoder)
>   return container_of(encoder, struct vc4_encoder, base);
>  }
>  
> +static inline
> +struct drm_encoder *vc4_find_encoder_by_type(struct drm_device *drm,
> +  enum vc4_encoder_type type)
> +{
> + struct drm_encoder *encoder;
> +
> + drm_for_each_encoder(encoder, drm) {
> + struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
> +
> + if (vc4_encoder->type == type)
> + return encoder;
> + }
> +
> + return NULL;
> +}
> +
>  struct vc4_crtc_data {
>   const char *name;
>  
> 


Re: [PATCH v2 12/17] drm/vc4: crtc: Introduce a lower-level crtc init helper

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> The current vc4_crtc_init() helper assumes that we will be using
> hardware planes and calls vc4_plane_init().
> 
> While it's a reasonable assumption, we'll want to mock the plane and
> thus provide our own. Let's create a helper that will take the plane as
> an argument.
> 
> Reviewed-by: Javier Martinez Canillas 
> Signed-off-by: Maxime Ripard 

Although the commit message explains a bit about why __vc4_crtc_init is
being created, it would be nice to add a comment in the code explaining
that __vc4_crtc_init can be used for tests as it allows mocking the
plane. This way the distinction between vc4_crtc_init and
__vc4_crtc_init will be cleaner to the reader.

Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal

> ---
>  drivers/gpu/drm/vc4/vc4_crtc.c | 52 
> +++---
>  drivers/gpu/drm/vc4/vc4_drv.h  |  6 +
>  2 files changed, 39 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
> index 333529ed3a0d..7a2c54efecb0 100644
> --- a/drivers/gpu/drm/vc4/vc4_crtc.c
> +++ b/drivers/gpu/drm/vc4/vc4_crtc.c
> @@ -1286,31 +1286,20 @@ static void vc4_set_crtc_possible_masks(struct 
> drm_device *drm,
>   }
>  }
>  
> -int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev,
> -   struct vc4_crtc *vc4_crtc,
> -   const struct vc4_crtc_data *data,
> -   const struct drm_crtc_funcs *crtc_funcs,
> -   const struct drm_crtc_helper_funcs *crtc_helper_funcs,
> -   bool feeds_txp)
> +int __vc4_crtc_init(struct drm_device *drm,
> + struct platform_device *pdev,
> + struct vc4_crtc *vc4_crtc,
> + const struct vc4_crtc_data *data,
> + struct drm_plane *primary_plane,
> + const struct drm_crtc_funcs *crtc_funcs,
> + const struct drm_crtc_helper_funcs *crtc_helper_funcs,
> + bool feeds_txp)
>  {
>   struct vc4_dev *vc4 = to_vc4_dev(drm);
>   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,
> -  * but to do that we would need to compute the bandwidth
> -  * requirement of the plane configuration, and reject ones
> -  * that will take too much.
> -  */
> - 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);
> - }
> -
>   vc4_crtc->data = data;
>   vc4_crtc->pdev = pdev;
>   vc4_crtc->feeds_txp = feeds_txp;
> @@ -1342,6 +1331,31 @@ int vc4_crtc_init(struct drm_device *drm, struct 
> platform_device *pdev,
>   return 0;
>  }
>  
> +int vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev,
> +   struct vc4_crtc *vc4_crtc,
> +   const struct vc4_crtc_data *data,
> +   const struct drm_crtc_funcs *crtc_funcs,
> +   const struct drm_crtc_helper_funcs *crtc_helper_funcs,
> +   bool feeds_txp)
> +{
> + struct drm_plane *primary_plane;
> +
> + /* For now, we create just the primary and the legacy cursor
> +  * planes.  We should be able to stack more planes on easily,
> +  * but to do that we would need to compute the bandwidth
> +  * requirement of the plane configuration, and reject ones
> +  * that will take too much.
> +  */
> + 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);
> + }
> +
> + return __vc4_crtc_init(drm, pdev, vc4_crtc, data, primary_plane,
> +crtc_funcs, crtc_helper_funcs, feeds_txp);
> +}
> +
>  static int vc4_crtc_bind(struct device *dev, struct device *master, void 
> *data)
>  {
>   struct platform_device *pdev = to_platform_device(dev);
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 051c2e3b6d43..cd2002fff115 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -888,6 +888,12 @@ int vc4_bo_debugfs_init(struct drm_minor *minor);
>  /* vc4_crtc.c */
>  extern struct platform_driver vc4_crtc_driver;
>  int vc4_crtc_disable_at_boot(struct drm_crtc *crtc);
> +int __vc4_crtc_init(struct drm_device *drm, struct platform_device *pdev,
> + struct vc4_crtc *vc4_crtc, const struct vc4_crtc_data *data,
> + struct drm_plane *primary_plane,
> + const struct drm_crtc_funcs *crtc_funcs,
> + const struct drm_crtc_helper_funcs 

Re: [PATCH -next] drm/amdgpu: update docum. filename following rename

2022-11-28 Thread Alex Deucher
Applied.  Thanks!

Alex

On Fri, Nov 25, 2022 at 4:01 PM Randy Dunlap  wrote:
>
> Fix documentation build errors for amdgpu: correct the filename.
>
> Error: Cannot open file ../drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> Error: Cannot open file ../drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> Error: Cannot open file ../drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>
> WARNING: kernel-doc '../scripts/kernel-doc -rst -enable-lineno 
> -sphinx-version 5.3.0 -function MMU Notifier 
> ../drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c' failed with return code 1
> WARNING: kernel-doc '../scripts/kernel-doc -rst -enable-lineno 
> -sphinx-version 5.3.0 -internal ../drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c' 
> failed with return code 2
>
> Fixes: d9483ecd327b ("drm/amdgpu: rename the files for HMM handling")
> Signed-off-by: Randy Dunlap 
> Cc: Christian König 
> Cc: Alex Deucher 
> Cc: Felix Kuehling 
> Cc: David Airlie 
> Cc: Daniel Vetter 
> Cc: Jonathan Corbet 
> Cc: amd-...@lists.freedesktop.org
> Cc: dri-devel@lists.freedesktop.org
> ---
>  Documentation/gpu/amdgpu/driver-core.rst |4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff -- a/Documentation/gpu/amdgpu/driver-core.rst 
> b/Documentation/gpu/amdgpu/driver-core.rst
> --- a/Documentation/gpu/amdgpu/driver-core.rst
> +++ b/Documentation/gpu/amdgpu/driver-core.rst
> @@ -148,10 +148,10 @@ PRIME Buffer Sharing
>  MMU Notifier
>  
>
> -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
> :doc: MMU Notifier
>
> -.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +.. kernel-doc:: drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
> :internal:
>
>  AMDGPU Virtual Memory


Re: [PATCH v2 11/17] drm/vc4: Move HVS state to main header

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> In order to introduce unit tests for the HVS state computation, we'll
> need access to the vc4_hvs_state struct definition and its associated
> helpers.
> 
> Let's move them in our driver header.
> 
> Reviewed-by: Javier Martinez Canillas 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal

> ---
>  drivers/gpu/drm/vc4/vc4_drv.h | 23 +++
>  drivers/gpu/drm/vc4/vc4_kms.c | 25 +++--
>  2 files changed, 26 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
> index 6af615c2eb65..051c2e3b6d43 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.h
> +++ b/drivers/gpu/drm/vc4/vc4_drv.h
> @@ -355,6 +355,29 @@ struct vc4_hvs {
>   bool vc5_hdmi_enable_4096by2160;
>  };
>  
> +#define HVS_NUM_CHANNELS 3
> +
> +struct vc4_hvs_state {
> + struct drm_private_state base;
> + unsigned long core_clock_rate;
> +
> + struct {
> + unsigned in_use: 1;
> + unsigned long fifo_load;
> + struct drm_crtc_commit *pending_commit;
> + } fifo_state[HVS_NUM_CHANNELS];
> +};
> +
> +static inline struct vc4_hvs_state *
> +to_vc4_hvs_state(const struct drm_private_state *priv)
> +{
> + return container_of(priv, struct vc4_hvs_state, base);
> +}
> +
> +struct vc4_hvs_state *vc4_hvs_get_global_state(struct drm_atomic_state 
> *state);
> +struct vc4_hvs_state *vc4_hvs_get_old_global_state(const struct 
> drm_atomic_state *state);
> +struct vc4_hvs_state *vc4_hvs_get_new_global_state(const struct 
> drm_atomic_state *state);
> +
>  struct vc4_plane {
>   struct drm_plane base;
>  };
> diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
> index 7282545c54a1..53d9f30460cf 100644
> --- a/drivers/gpu/drm/vc4/vc4_kms.c
> +++ b/drivers/gpu/drm/vc4/vc4_kms.c
> @@ -25,8 +25,6 @@
>  #include "vc4_drv.h"
>  #include "vc4_regs.h"
>  
> -#define HVS_NUM_CHANNELS 3
> -
>  struct vc4_ctm_state {
>   struct drm_private_state base;
>   struct drm_color_ctm *ctm;
> @@ -39,23 +37,6 @@ to_vc4_ctm_state(const struct drm_private_state *priv)
>   return container_of(priv, struct vc4_ctm_state, base);
>  }
>  
> -struct vc4_hvs_state {
> - struct drm_private_state base;
> - unsigned long core_clock_rate;
> -
> - struct {
> - unsigned in_use: 1;
> - unsigned long fifo_load;
> - struct drm_crtc_commit *pending_commit;
> - } fifo_state[HVS_NUM_CHANNELS];
> -};
> -
> -static struct vc4_hvs_state *
> -to_vc4_hvs_state(const struct drm_private_state *priv)
> -{
> - return container_of(priv, struct vc4_hvs_state, base);
> -}
> -
>  struct vc4_load_tracker_state {
>   struct drm_private_state base;
>   u64 hvs_load;
> @@ -191,7 +172,7 @@ vc4_ctm_commit(struct vc4_dev *vc4, struct 
> drm_atomic_state *state)
> VC4_SET_FIELD(ctm_state->fifo, SCALER_OLEDOFFS_DISPFIFO));
>  }
>  
> -static struct vc4_hvs_state *
> +struct vc4_hvs_state *
>  vc4_hvs_get_new_global_state(const struct drm_atomic_state *state)
>  {
>   struct vc4_dev *vc4 = to_vc4_dev(state->dev);
> @@ -204,7 +185,7 @@ vc4_hvs_get_new_global_state(const struct 
> drm_atomic_state *state)
>   return to_vc4_hvs_state(priv_state);
>  }
>  
> -static struct vc4_hvs_state *
> +struct vc4_hvs_state *
>  vc4_hvs_get_old_global_state(const struct drm_atomic_state *state)
>  {
>   struct vc4_dev *vc4 = to_vc4_dev(state->dev);
> @@ -217,7 +198,7 @@ vc4_hvs_get_old_global_state(const struct 
> drm_atomic_state *state)
>   return to_vc4_hvs_state(priv_state);
>  }
>  
> -static struct vc4_hvs_state *
> +struct vc4_hvs_state *
>  vc4_hvs_get_global_state(struct drm_atomic_state *state)
>  {
>   struct vc4_dev *vc4 = to_vc4_dev(state->dev);
> 


Re: [PATCH v2 10/17] drm/tests: Add a test for DRM managed actions

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> DRM-managed actions are supposed to be ran whenever the device is
> released. Let's introduce a basic unit test to make sure it happens.
> 
> Reviewed-by: Javier Martinez Canillas 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal

> ---
>  drivers/gpu/drm/tests/Makefile   |  1 +
>  drivers/gpu/drm/tests/drm_managed_test.c | 71 
> 
>  2 files changed, 72 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
> index 94fe546d937d..486053052ba9 100644
> --- a/drivers/gpu/drm/tests/Makefile
> +++ b/drivers/gpu/drm/tests/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST) += \
>   drm_format_test.o \
>   drm_framebuffer_test.o \
>   drm_kunit_helpers.o \
> + drm_managed_test.o \
>   drm_mm_test.o \
>   drm_modes_test.o \
>   drm_plane_helper_test.o \
> diff --git a/drivers/gpu/drm/tests/drm_managed_test.c 
> b/drivers/gpu/drm/tests/drm_managed_test.c
> new file mode 100644
> index ..1652dca11d30
> --- /dev/null
> +++ b/drivers/gpu/drm/tests/drm_managed_test.c
> @@ -0,0 +1,71 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include 
> +
> +/* Ought to be enough for anybody */
> +#define TEST_TIMEOUT_MS  100
> +
> +struct managed_test_priv {
> + bool action_done;
> + wait_queue_head_t action_wq;
> +};
> +
> +static void drm_action(struct drm_device *drm, void *ptr)
> +{
> + struct managed_test_priv *priv = ptr;
> +
> + priv->action_done = true;
> + wake_up_interruptible(>action_wq);
> +}
> +
> +static void drm_test_managed_run_action(struct kunit *test)
> +{
> + struct managed_test_priv *priv;
> + struct drm_device *drm;
> + struct device *dev;
> + int ret;
> +
> + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
> + init_waitqueue_head(>action_wq);
> +
> + dev = drm_kunit_helper_alloc_device(test);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
> +
> + drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, 
> DRIVER_MODESET);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
> +
> + ret = drmm_add_action_or_reset(drm, drm_action, priv);
> + KUNIT_EXPECT_EQ(test, ret, 0);
> +
> + ret = drm_dev_register(drm, 0);
> + KUNIT_ASSERT_EQ(test, ret, 0);
> +
> + drm_dev_unregister(drm);
> + drm_kunit_helper_free_device(test, dev);
> +
> + ret = wait_event_interruptible_timeout(priv->action_wq, 
> priv->action_done,
> +
> msecs_to_jiffies(TEST_TIMEOUT_MS));
> + KUNIT_EXPECT_GT(test, ret, 0);
> +}
> +
> +static struct kunit_case drm_managed_tests[] = {
> + KUNIT_CASE(drm_test_managed_run_action),
> + {}
> +};
> +
> +static struct kunit_suite drm_managed_test_suite = {
> + .name = "drm-test-managed",
> + .test_cases = drm_managed_tests
> +};
> +
> +kunit_test_suite(drm_managed_test_suite);
> +
> +MODULE_AUTHOR("Maxime Ripard ");
> +MODULE_LICENSE("GPL");
> 


Re: [PATCH v2 07/17] drm/tests: helpers: Make sure the device is bound

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> The device managed resources are freed when the device is detached, so
> it has to be bound in the first place.
> 
> Let's create a fake driver that we will bind to our fake device to
> benefit from the device managed cleanups in our tests.
> 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal

> ---
>  drivers/gpu/drm/tests/drm_kunit_helpers.c | 26 +-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
> b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 15678ab823b0..5d3e29353d1a 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -18,12 +18,32 @@ struct kunit_dev {
>  static const struct drm_mode_config_funcs drm_mode_config_funcs = {
>  };
>  
> +static int fake_probe(struct platform_device *pdev)
> +{
> + return 0;
> +}
> +
> +static int fake_remove(struct platform_device *pdev)
> +{
> + return 0;
> +}
> +
> +static struct platform_driver fake_platform_driver = {
> + .probe  = fake_probe,
> + .remove = fake_remove,
> + .driver = {
> + .name   = KUNIT_DEVICE_NAME,
> + },
> +};
> +
>  /**
>   * drm_kunit_helper_alloc_device - Allocate a mock device for a KUnit test
>   * @test: The test context object
>   *
>   * This allocates a fake struct  to create a mock for a Kunit
> - * test.
> + * test. The device will also be bound to a fake driver. It will thus be
> + * able to leverage the usual infrastructure and most notably the
> + * device-managed resources just like a "real" device.
>   *
>   * Callers need to make sure drm_kunit_helper_free_device() on the
>   * device when done.
> @@ -36,6 +56,9 @@ struct device *drm_kunit_helper_alloc_device(struct kunit 
> *test)
>   struct platform_device *pdev;
>   int ret;
>  
> + ret = platform_driver_register(_platform_driver);
> + KUNIT_ASSERT_EQ(test, ret, 0);
> +
>   pdev = platform_device_alloc(KUNIT_DEVICE_NAME, PLATFORM_DEVID_NONE);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
>  
> @@ -58,6 +81,7 @@ void drm_kunit_helper_free_device(struct kunit *test, 
> struct device *dev)
>   struct platform_device *pdev = to_platform_device(dev);
>  
>   platform_device_unregister(pdev);
> + platform_driver_unregister(_platform_driver);
>  }
>  EXPORT_SYMBOL(drm_kunit_helper_free_device);
>  
> 


Re: [PATCH v2 06/17] drm/tests: helpers: Switch to a platform_device

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> The device managed resources are ran if the device has bus, which is not
> the case of a root_device.
> 
> Let's use a platform_device instead.
> 
> Reviewed-by: Javier Martinez Canillas 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Maíra Canal 

Best Regards,
- Maíra Canal

> ---
>  drivers/gpu/drm/tests/drm_kunit_helpers.c | 16 ++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
> b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 9fb045fa685f..15678ab823b0 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -7,6 +7,7 @@
>  #include 
>  
>  #include 
> +#include 
>  
>  #define KUNIT_DEVICE_NAME"drm-kunit-mock-device"
>  
> @@ -32,7 +33,16 @@ static const struct drm_mode_config_funcs 
> drm_mode_config_funcs = {
>   */
>  struct device *drm_kunit_helper_alloc_device(struct kunit *test)
>  {
> - return root_device_register(KUNIT_DEVICE_NAME);
> + struct platform_device *pdev;
> + int ret;
> +
> + pdev = platform_device_alloc(KUNIT_DEVICE_NAME, PLATFORM_DEVID_NONE);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
> +
> + ret = platform_device_add(pdev);
> + KUNIT_ASSERT_EQ(test, ret, 0);
> +
> + return >dev;
>  }
>  EXPORT_SYMBOL(drm_kunit_helper_alloc_device);
>  
> @@ -45,7 +55,9 @@ EXPORT_SYMBOL(drm_kunit_helper_alloc_device);
>   */
>  void drm_kunit_helper_free_device(struct kunit *test, struct device *dev)
>  {
> - root_device_unregister(dev);
> + struct platform_device *pdev = to_platform_device(dev);
> +
> + platform_device_unregister(pdev);
>  }
>  EXPORT_SYMBOL(drm_kunit_helper_free_device);
>  
> 


Re: [PATCH v2 05/17] drm/tests: helpers: Create the device in another function

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> We'll need in some tests to control when the device needs to be added
> and removed, so let's split the device creation from the DRM device
> creation function.
> 
> Signed-off-by: Maxime Ripard 

Just a small nit below,

Reviewed-by: Maíra Canal 

>  
> diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c 
> b/drivers/gpu/drm/tests/drm_probe_helper_test.c
> index be61a92b79d2..438b1d42b843 100644
> --- a/drivers/gpu/drm/tests/drm_probe_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c
> @@ -17,6 +17,7 @@
>  
>  struct drm_probe_helper_test_priv {
>   struct drm_device *drm;
> + struct device *dev;
>   struct drm_connector connector;
>  };
>  
> @@ -39,7 +40,10 @@ static int drm_probe_helper_test_init(struct kunit *test)
>   KUNIT_ASSERT_NOT_NULL(test, priv);
>   test->priv = priv;
>  
> - priv->drm = drm_kunit_helper_alloc_drm_device(test,
> + priv->dev = drm_kunit_helper_alloc_device(test);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
> +
> + priv->drm = drm_kunit_helper_alloc_drm_device(test, priv->dev,
> DRIVER_MODESET | 
> DRIVER_ATOMIC);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
>  
> @@ -55,6 +59,13 @@ static int drm_probe_helper_test_init(struct kunit *test)
>   return 0;
>  }
>  
> +static void drm_probe_helper_test_exit(struct kunit *test)
> +{
> + struct drm_probe_helper_test_priv *priv = test->priv;;

There are two semicolons by the end of this statement.

Best Regards,
- Maíra Canal

> +
> + drm_kunit_helper_free_device(test, priv->dev);
> +}
> +
>  typedef struct drm_display_mode *(*expected_mode_func_t)(struct drm_device 
> *);
>  
>  struct drm_connector_helper_tv_get_modes_test {
> @@ -195,6 +206,7 @@ static struct kunit_case 
> drm_test_connector_helper_tv_get_modes_tests[] = {
>  static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = {
>   .name = "drm_connector_helper_tv_get_modes",
>   .init = drm_probe_helper_test_init,
> + .exit = drm_probe_helper_test_exit,
>   .test_cases = drm_test_connector_helper_tv_get_modes_tests,
>  };
>  
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index 6c12b1426ba0..b4277fe92c38 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -6,8 +6,11 @@
>  struct drm_device;
>  struct kunit;
>  
> +struct device *drm_kunit_helper_alloc_device(struct kunit *test);
> +void drm_kunit_helper_free_device(struct kunit *test, struct device *dev);
> +
>  struct drm_device *
> -drm_kunit_helper_alloc_drm_device(struct kunit *test,
> +drm_kunit_helper_alloc_drm_device(struct kunit *test, struct device *dev,
> u32 features);
>  
>  #endif // DRM_KUNIT_HELPERS_H_
> 


Re: [PATCH v2 04/17] drm/tests: helpers: Remove the name parameter

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> The device name isn't really useful, we can just define it instead of
> exposing it in the API.
> 
> Signed-off-by: Maxime Ripard 

Reviewed-by: Maíra Canal 

Best Regards
- Maíra Canal

> ---
>  drivers/gpu/drm/tests/drm_client_modeset_test.c | 3 +--
>  drivers/gpu/drm/tests/drm_kunit_helpers.c   | 7 ---
>  drivers/gpu/drm/tests/drm_modes_test.c  | 3 +--
>  drivers/gpu/drm/tests/drm_probe_helper_test.c   | 3 +--
>  include/drm/drm_kunit_helpers.h | 3 +--
>  5 files changed, 8 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tests/drm_client_modeset_test.c 
> b/drivers/gpu/drm/tests/drm_client_modeset_test.c
> index 6cdf08f582ce..4d475ae6dbb6 100644
> --- a/drivers/gpu/drm/tests/drm_client_modeset_test.c
> +++ b/drivers/gpu/drm/tests/drm_client_modeset_test.c
> @@ -59,8 +59,7 @@ static int drm_client_modeset_test_init(struct kunit *test)
>  
>   test->priv = priv;
>  
> - priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET,
> -   
> "drm-client-modeset-test");
> + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
>  
>   ret = drmm_connector_init(priv->drm, >connector,
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
> b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 2f67f6cf78d0..16c7926d83c2 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -8,6 +8,8 @@
>  
>  #include 
>  
> +#define KUNIT_DEVICE_NAME"drm-kunit-mock-device"
> +
>  struct kunit_dev {
>   struct drm_device base;
>  };
> @@ -39,7 +41,6 @@ static void dev_free(struct kunit_resource *res)
>   * drm_kunit_helper_alloc_drm_device - Allocates a mock DRM device for Kunit 
> tests
>   * @test: The test context object
>   * @features: Mocked DRM device driver features
> - * @name: Name of the struct  to allocate
>   *
>   * This function allocates a new struct , creates a struct
>   * _driver and will create a struct _device using both.
> @@ -54,7 +55,7 @@ static void dev_free(struct kunit_resource *res)
>   */
>  struct drm_device *
>  drm_kunit_helper_alloc_drm_device(struct kunit *test,
> -   u32 features, char *name)
> +   u32 features)
>  {
>   struct kunit_dev *kdev;
>   struct drm_device *drm;
> @@ -62,7 +63,7 @@ drm_kunit_helper_alloc_drm_device(struct kunit *test,
>   struct device *dev;
>   int ret;
>  
> - dev = kunit_alloc_resource(test, dev_init, dev_free, GFP_KERNEL, name);
> + dev = kunit_alloc_resource(test, dev_init, dev_free, GFP_KERNEL, 
> KUNIT_DEVICE_NAME);
>   if (!dev)
>   return ERR_PTR(-ENOMEM);
>  
> diff --git a/drivers/gpu/drm/tests/drm_modes_test.c 
> b/drivers/gpu/drm/tests/drm_modes_test.c
> index 6723089dff9f..35965ad86188 100644
> --- a/drivers/gpu/drm/tests/drm_modes_test.c
> +++ b/drivers/gpu/drm/tests/drm_modes_test.c
> @@ -22,8 +22,7 @@ static int drm_test_modes_init(struct kunit *test)
>   priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
>   KUNIT_ASSERT_NOT_NULL(test, priv);
>  
> - priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET,
> -   "drm-modes-test");
> + priv->drm = drm_kunit_helper_alloc_drm_device(test, DRIVER_MODESET);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
>  
>   test->priv = priv;
> diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c 
> b/drivers/gpu/drm/tests/drm_probe_helper_test.c
> index 85236ff4744f..be61a92b79d2 100644
> --- a/drivers/gpu/drm/tests/drm_probe_helper_test.c
> +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c
> @@ -40,8 +40,7 @@ static int drm_probe_helper_test_init(struct kunit *test)
>   test->priv = priv;
>  
>   priv->drm = drm_kunit_helper_alloc_drm_device(test,
> -   DRIVER_MODESET | 
> DRIVER_ATOMIC,
> -   "drm-probe-helper-test");
> +   DRIVER_MODESET | 
> DRIVER_ATOMIC);
>   KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
>  
>   connector = >connector;
> diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
> index e9870c7911fe..6c12b1426ba0 100644
> --- a/include/drm/drm_kunit_helpers.h
> +++ b/include/drm/drm_kunit_helpers.h
> @@ -8,7 +8,6 @@ struct kunit;
>  
>  struct drm_device *
>  drm_kunit_helper_alloc_drm_device(struct kunit *test,
> -   u32 features,
> -   char *name);
> +   u32 features);
>  
>  #endif // DRM_KUNIT_HELPERS_H_
> 


Re: [PATCH v2 02/17] drm/tests: helpers: Document drm_kunit_device_init()

2022-11-28 Thread Maíra Canal
On 11/28/22 11:53, Maxime Ripard wrote:
> Commit 44a3928324e9 ("drm/tests: Add Kunit Helpers") introduced the
> drm_kunit_device_init() function but didn't document it properly. Add
> that documentation.
> 
> Signed-off-by: Maxime Ripard 

Just a minor nit on naming, besides that:

Reviewed-by: Maíra Canal 

> ---
>  drivers/gpu/drm/tests/drm_kunit_helpers.c | 17 +
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c 
> b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> index 6600a4db3158..46a68c2fd80c 100644
> --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
> +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
> @@ -35,6 +35,23 @@ static void dev_free(struct kunit_resource *res)
>   root_device_unregister(dev);
>  }
>  
> +/**
> + * drm_kunit_device_init - Allocates a mock DRM device for Kunit tests

s/Kunit/KUnit

Best Regards,
- Maíra Canal

> + * @test: The test context object
> + * @features: Mocked DRM device driver features
> + * @name: Name of the struct  to allocate
> + *
> + * This function allocates a new struct , creates a struct
> + * _driver and will create a struct _device using both.
> + *
> + * The device and driver are tied to the @test context and will get
> + * cleaned at the end of the test. The drm_device is allocated through
> + * devm_drm_dev_alloc() and will thus be freed through a device-managed
> + * resource.
> + *
> + * Returns:
> + * A pointer to the new drm_device, or an ERR_PTR() otherwise.
> + */
>  struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, 
> char *name)
>  {
>   struct kunit_dev *kdev;
> 


Re: [PATCH] drm/i915/huc: always init the delayed load fence

2022-11-28 Thread John Harrison

On 11/23/2022 15:54, Daniele Ceraolo Spurio wrote:

The fence is only tracking if the HuC load is in progress or not and
doesn't distinguish between already loaded, not supported or disabled,
so we can always initialize it to completed, no matter the actual
support. We already do that for most platforms, but we skip it on
GTs that lack VCS engines (i.e. MTL root GT), so fix that. Note that the

i.e. -> e.g., there is more than just MTL root GT.


cleanup is already unconditional.

While at it, move the init/fini to helper functions.

Fixes: 02224691cb0f ("drm/i915/huc: fix leak of debug object in huc load fence on 
driver unload")
Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
Cc: Alan Previn 
---
  drivers/gpu/drm/i915/gt/uc/intel_huc.c | 47 +++---
  1 file changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index 0976e9101346..5f393f8e8b2e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -211,6 +211,30 @@ void intel_huc_unregister_gsc_notifier(struct intel_huc 
*huc, struct bus_type *b
huc->delayed_load.nb.notifier_call = NULL;
  }
  
+static void delayed_huc_load_init(struct intel_huc *huc)

+{
+   /*
+* Initialize fence to be complete as this is expected to be complete
+* unless there is a delayed HuC reload in progress.

reload -> load?


+*/
+   i915_sw_fence_init(>delayed_load.fence,
+  sw_fence_dummy_notify);
+   i915_sw_fence_commit(>delayed_load.fence);
+
+   hrtimer_init(>delayed_load.timer, CLOCK_MONOTONIC, 
HRTIMER_MODE_REL);
+   huc->delayed_load.timer.function = huc_delayed_load_timer_callback;
+}
+
+static void delayed_huc_load_fini(struct intel_huc *huc)
+{
+   /*
+* the fence is initialized in init_early, so we need to clean it up
+* even if HuC loading is off.
+*/
+   delayed_huc_load_complete(huc);
+   i915_sw_fence_fini(>delayed_load.fence);
+}
+
  static bool vcs_supported(struct intel_gt *gt)
  {
intel_engine_mask_t mask = gt->info.engine_mask;
@@ -241,6 +265,15 @@ void intel_huc_init_early(struct intel_huc *huc)
  
  	intel_uc_fw_init_early(>fw, INTEL_UC_FW_TYPE_HUC);
  
+	/*

+* we always init the fence as already completed, even if HuC is not
+* supported. This way we don't have to distinguish between HuC not
+* supported/disabled or already loaded, band can focus on if the load

band -> and

Looks good otherwise. So with the typos fixed:
Reviewed-by: John Harrison 


+* is currently in progress (fence not complete) or not, which is what
+* we care about for stalling userspace submissions.
+*/
+   delayed_huc_load_init(huc);
+
if (!vcs_supported(gt)) {
intel_uc_fw_change_status(>fw, 
INTEL_UC_FIRMWARE_NOT_SUPPORTED);
return;
@@ -255,17 +288,6 @@ void intel_huc_init_early(struct intel_huc *huc)
huc->status.mask = HUC_FW_VERIFIED;
huc->status.value = HUC_FW_VERIFIED;
}
-
-   /*
-* Initialize fence to be complete as this is expected to be complete
-* unless there is a delayed HuC reload in progress.
-*/
-   i915_sw_fence_init(>delayed_load.fence,
-  sw_fence_dummy_notify);
-   i915_sw_fence_commit(>delayed_load.fence);
-
-   hrtimer_init(>delayed_load.timer, CLOCK_MONOTONIC, 
HRTIMER_MODE_REL);
-   huc->delayed_load.timer.function = huc_delayed_load_timer_callback;
  }
  
  #define HUC_LOAD_MODE_STRING(x) (x ? "GSC" : "legacy")

@@ -333,8 +355,7 @@ void intel_huc_fini(struct intel_huc *huc)
 * the fence is initialized in init_early, so we need to clean it up
 * even if HuC loading is off.
 */
-   delayed_huc_load_complete(huc);
-   i915_sw_fence_fini(>delayed_load.fence);
+   delayed_huc_load_fini(huc);
  
  	if (intel_uc_fw_is_loadable(>fw))

intel_uc_fw_fini(>fw);




Re: [PATCH v2] drm: Only select I2C_ALGOBIT for drivers that actually need it

2022-11-28 Thread Thomas Zimmermann

Hi

Am 12.09.22 um 11:15 schrieb Uwe Kleine-König:

While working on a drm driver that doesn't need the i2c algobit stuff I
noticed that DRM selects this code even tough only 8 drivers actually use
it. While also only some drivers use i2c, keep the select for I2C for the
next cleanup patch. Still prepare this already by also selecting I2C for
the individual drivers.

Signed-off-by: Uwe Kleine-König 
---
Changes since v1
(20210514100142.1182997-1-u.kleine-koe...@pengutronix.de) from
2021-05-14:

  - rebased to next-20220909
was something around v5.13-rc2 before, required to fix context
changes in the nouveau Kconfig file. git am -3 handled it just fine.

I reverified that no new drivers were added that need a corresponding
select.

Best regards
Uwe

  drivers/gpu/drm/Kconfig | 5 -
  drivers/gpu/drm/ast/Kconfig | 2 ++
  drivers/gpu/drm/gma500/Kconfig  | 2 ++
  drivers/gpu/drm/hisilicon/hibmc/Kconfig | 2 ++
  drivers/gpu/drm/i915/Kconfig| 2 ++
  drivers/gpu/drm/mgag200/Kconfig | 2 ++
  drivers/gpu/drm/nouveau/Kconfig | 2 ++
  7 files changed, 16 insertions(+), 1 deletion(-)


amdgpu and radeon also include . Are they special 
in some way?


Best regards
Thomas



diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 198ba846d34b..593d7335b10a 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -13,7 +13,6 @@ menuconfig DRM
select HDMI
select FB_CMDLINE
select I2C
-   select I2C_ALGOBIT
select DMA_SHARED_BUFFER
select SYNC_FILE
  # gallium uses SYS_kcmp for os_same_file_description() to de-duplicate
@@ -231,6 +230,8 @@ config DRM_RADEON
  select DRM_KMS_HELPER
  select DRM_TTM
select DRM_TTM_HELPER
+   select I2C
+   select I2C_ALGOBIT
select POWER_SUPPLY
select HWMON
select BACKLIGHT_CLASS_DEVICE
@@ -262,6 +263,8 @@ config DRM_AMDGPU
select DRM_SCHED
select DRM_TTM
select DRM_TTM_HELPER
+   select I2C
+   select I2C_ALGOBIT
select POWER_SUPPLY
select HWMON
select BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/gpu/drm/ast/Kconfig b/drivers/gpu/drm/ast/Kconfig
index fbcf2f45cef5..bcc25decd485 100644
--- a/drivers/gpu/drm/ast/Kconfig
+++ b/drivers/gpu/drm/ast/Kconfig
@@ -6,6 +6,8 @@ config DRM_AST
select DRM_VRAM_HELPER
select DRM_TTM
select DRM_TTM_HELPER
+   select I2C
+   select I2C_ALGOBIT
help
 Say yes for experimental AST GPU driver. Do not enable
 this driver without having a working -modesetting,
diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 807b989e3c77..2efc0eb41c64 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -3,6 +3,8 @@ config DRM_GMA500
tristate "Intel GMA500/600/3600/3650 KMS Framebuffer"
depends on DRM && PCI && X86 && MMU
select DRM_KMS_HELPER
+   select I2C
+   select I2C_ALGOBIT
# GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
select ACPI_VIDEO if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
diff --git a/drivers/gpu/drm/hisilicon/hibmc/Kconfig 
b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
index 073adfe438dd..90b9e6cce49c 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/Kconfig
+++ b/drivers/gpu/drm/hisilicon/hibmc/Kconfig
@@ -6,6 +6,8 @@ config DRM_HISI_HIBMC
select DRM_VRAM_HELPER
select DRM_TTM
select DRM_TTM_HELPER
+   select I2C
+   select I2C_ALGOBIT
help
  Choose this option if you have a Hisilicon Hibmc soc chipset.
  If M is selected the module will be called hibmc-drm.
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 3efce05d7b57..c6e3792622f2 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -18,6 +18,8 @@ config DRM_I915
select DRM_PANEL
select DRM_MIPI_DSI
select RELAY
+   select I2C
+   select I2C_ALGOBIT
select IRQ_WORK
# i915 depends on ACPI_VIDEO when ACPI is enabled
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index eec59658a938..b28c5e4828f4 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -4,6 +4,8 @@ config DRM_MGAG200
depends on DRM && PCI && MMU
select DRM_GEM_SHMEM_HELPER
select DRM_KMS_HELPER
+   select I2C
+   select I2C_ALGOBIT
help
 This is a KMS driver for Matrox G200 chips. It supports the original
 MGA G200 desktop chips and the server variants. It requires 0.3.0
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 03d12caf9e26..a0bb3987bf63 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ 

Re: [PATCH v2] drm: Only select I2C_ALGOBIT for drivers that actually need it

2022-11-28 Thread Uwe Kleine-König
Hello Javier,

On Mon, Nov 28, 2022 at 05:54:32PM +0100, Javier Martinez Canillas wrote:
> On 9/12/22 11:15, Uwe Kleine-König wrote:
> > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> > index 198ba846d34b..593d7335b10a 100644
> > --- a/drivers/gpu/drm/Kconfig
> > +++ b/drivers/gpu/drm/Kconfig
> > @@ -13,7 +13,6 @@ menuconfig DRM
> > select HDMI
> > select FB_CMDLINE
> > select I2C
> 
> Is I2C still required or was just a dependency of I2C_ALGOBIT ?

I didn't convince myself I2C can go away, but I would expect this to be
an opportunity for another cleanup as I mentioned in the commit log.
 
> I'll wait a few days in case others want to review this change too
> and then can push this to drm-misc-next. 

I'm looking forward to all the people reviewing my patch now who missed
the patch during the last 18 months but who will take the opportunity of
these additional few days :-)

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


[PATCH AUTOSEL 4.19 10/12] fbcon: Use kzalloc() in fbcon_prepare_logo()

2022-11-28 Thread Sasha Levin
From: Tetsuo Handa 

[ Upstream commit a6a00d7e8ffd78d1cdb7a43f1278f081038c638f ]

A kernel built with syzbot's config file reported that

  scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2))

causes uninitialized "save" to be copied.

  --
  [drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
  [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
  Console: switching to colour frame buffer device 128x48
  =
  BUG: KMSAN: uninit-value in do_update_region+0x4b8/0xba0
   do_update_region+0x4b8/0xba0
   update_region+0x40d/0x840
   fbcon_switch+0x3364/0x35e0
   redraw_screen+0xae3/0x18a0
   do_bind_con_driver+0x1cb3/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was stored to memory at:
   fbcon_prepare_logo+0x143b/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was created at:
   __kmem_cache_alloc_node+0xb69/0x1020
   __kmalloc+0x379/0x680
   fbcon_prepare_logo+0x704/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  CPU: 2 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc4-00356-g8f2975c2bb4c #924
  Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
  --

Signed-off-by: Tetsuo Handa 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/cad03d25-0ea0-32c4-8173-fd1895314...@i-love.sakura.ne.jp
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 417f4bcc1182..9fcd583b7835 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -579,7 +579,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct 
fb_info *info,
if (scr_readw(r) != vc->vc_video_erase_char)
break;
if (r != q && new_rows >= rows + logo_lines) {
-   save = kmalloc(array3_size(logo_lines, new_cols, 2),
+   save = kzalloc(array3_size(logo_lines, new_cols, 2),
   GFP_KERNEL);
if (save) {
int i = cols < new_cols ? cols : new_cols;
-- 
2.35.1



Re: [PATCH v1] dt-bindings: display: Convert fsl,imx-fb.txt to dt-schema

2022-11-28 Thread Uwe Kleine-König
On Thu, Nov 17, 2022 at 06:49:02PM +0100, Krzysztof Kozlowski wrote:
> On 16/11/2022 18:49, Philipp Zabel wrote:
> > On Thu, Nov 10, 2022 at 10:49:45AM +0100, Uwe Kleine-König wrote:
> > [...]
> >> new file mode 100644
> >> index ..c3cf6f92a766
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx-lcdc.yaml
> >> @@ -0,0 +1,110 @@
> >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/display/imx/fsl,imx-lcdc.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Freescale i.MX LCD Controller, found on i.MX1, i.MX21, i.MX25 and 
> >> i.MX27
> >> +
> >> +maintainers:
> >> +  - Sascha Hauer 
> >> +  - Pengutronix Kernel Team 
> >> +
> >> +properties:
> >> +  compatible:
> >> +oneOf:
> >> +  - items:
> >> +  - enum:
> >> +  - fsl,imx1-fb
> >> +  - fsl,imx21-fb
> > 
> > Are the items/enum keywords superfluous here? Couldn't this just be two
> > 
> >  - const: fsl,imx1-fb
> >  - const: fsl,imx21-fb
> > 
> > entries?
> 
> Only "items" is, so should be dropped.

Status quo are the following settings:

imx25.dtsi uses:
compatible = "fsl,imx25-fb", "fsl,imx21-fb";
imx27.dtsi uses:
compatible = "fsl,imx27-fb", "fsl,imx21-fb";

The fb driver (drivers/video/fbdev/imxfb.c) supports devices with
"fsl,imx1-fb" and "fsl,imx21-fb" in their comaptible list.

So my best guess is to assume an i.MX21 would use

compatible = "fsl,imx21-fb";

and an i.MX1 would use:

compatible = "fsl,imx1-fb";

. Looking at the driver it might be that it works in i.MX1 mode on an
i.MX2x. The latter has some additional registers, higher y-resolution
and supports 16, 18 and 24 bpp.

However my actual plan was to support the drm driver with the saner
binding on i.MX25 and not cleanup the driver and binding I want to
deprecate.

So I'd go for putting into the legacy binding what is currently done in
arch/arm/boot/dts and the driver allowing exactly:

compatible = "fsl,imx27-fb", "fsl,imx21-fb";
compatible = "fsl,imx25-fb", "fsl,imx21-fb";
compatible = "fsl,imx21-fb";
compatible = "fsl,imx1-fb";

I thinks this is accomplished using:

  compatible:
oneOf:
  - enum:
  - fsl,imx1-fb
  - fsl,imx21-fb
  - items
  - enum:
  - fsl,imx25-fb
  - fsl,imx27-fb
  - const: fsl,imx21-fb

right?

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


[PATCH AUTOSEL 5.4 14/16] fbcon: Use kzalloc() in fbcon_prepare_logo()

2022-11-28 Thread Sasha Levin
From: Tetsuo Handa 

[ Upstream commit a6a00d7e8ffd78d1cdb7a43f1278f081038c638f ]

A kernel built with syzbot's config file reported that

  scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2))

causes uninitialized "save" to be copied.

  --
  [drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
  [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
  Console: switching to colour frame buffer device 128x48
  =
  BUG: KMSAN: uninit-value in do_update_region+0x4b8/0xba0
   do_update_region+0x4b8/0xba0
   update_region+0x40d/0x840
   fbcon_switch+0x3364/0x35e0
   redraw_screen+0xae3/0x18a0
   do_bind_con_driver+0x1cb3/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was stored to memory at:
   fbcon_prepare_logo+0x143b/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was created at:
   __kmem_cache_alloc_node+0xb69/0x1020
   __kmalloc+0x379/0x680
   fbcon_prepare_logo+0x704/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  CPU: 2 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc4-00356-g8f2975c2bb4c #924
  Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
  --

Signed-off-by: Tetsuo Handa 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/cad03d25-0ea0-32c4-8173-fd1895314...@i-love.sakura.ne.jp
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 4a544e1e2038..673af5937489 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -604,7 +604,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct 
fb_info *info,
if (scr_readw(r) != vc->vc_video_erase_char)
break;
if (r != q && new_rows >= rows + logo_lines) {
-   save = kmalloc(array3_size(logo_lines, new_cols, 2),
+   save = kzalloc(array3_size(logo_lines, new_cols, 2),
   GFP_KERNEL);
if (save) {
int i = cols < new_cols ? cols : new_cols;
-- 
2.35.1



[PATCH AUTOSEL 5.10 16/19] fbcon: Use kzalloc() in fbcon_prepare_logo()

2022-11-28 Thread Sasha Levin
From: Tetsuo Handa 

[ Upstream commit a6a00d7e8ffd78d1cdb7a43f1278f081038c638f ]

A kernel built with syzbot's config file reported that

  scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2))

causes uninitialized "save" to be copied.

  --
  [drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
  [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
  Console: switching to colour frame buffer device 128x48
  =
  BUG: KMSAN: uninit-value in do_update_region+0x4b8/0xba0
   do_update_region+0x4b8/0xba0
   update_region+0x40d/0x840
   fbcon_switch+0x3364/0x35e0
   redraw_screen+0xae3/0x18a0
   do_bind_con_driver+0x1cb3/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was stored to memory at:
   fbcon_prepare_logo+0x143b/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was created at:
   __kmem_cache_alloc_node+0xb69/0x1020
   __kmalloc+0x379/0x680
   fbcon_prepare_logo+0x704/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  CPU: 2 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc4-00356-g8f2975c2bb4c #924
  Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
  --

Signed-off-by: Tetsuo Handa 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/cad03d25-0ea0-32c4-8173-fd1895314...@i-love.sakura.ne.jp
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 2618d3beef64..27828435dd4f 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -609,7 +609,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct 
fb_info *info,
if (scr_readw(r) != vc->vc_video_erase_char)
break;
if (r != q && new_rows >= rows + logo_lines) {
-   save = kmalloc(array3_size(logo_lines, new_cols, 2),
+   save = kzalloc(array3_size(logo_lines, new_cols, 2),
   GFP_KERNEL);
if (save) {
int i = cols < new_cols ? cols : new_cols;
-- 
2.35.1



[PATCH AUTOSEL 5.15 21/24] fbcon: Use kzalloc() in fbcon_prepare_logo()

2022-11-28 Thread Sasha Levin
From: Tetsuo Handa 

[ Upstream commit a6a00d7e8ffd78d1cdb7a43f1278f081038c638f ]

A kernel built with syzbot's config file reported that

  scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2))

causes uninitialized "save" to be copied.

  --
  [drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
  [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
  Console: switching to colour frame buffer device 128x48
  =
  BUG: KMSAN: uninit-value in do_update_region+0x4b8/0xba0
   do_update_region+0x4b8/0xba0
   update_region+0x40d/0x840
   fbcon_switch+0x3364/0x35e0
   redraw_screen+0xae3/0x18a0
   do_bind_con_driver+0x1cb3/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was stored to memory at:
   fbcon_prepare_logo+0x143b/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was created at:
   __kmem_cache_alloc_node+0xb69/0x1020
   __kmalloc+0x379/0x680
   fbcon_prepare_logo+0x704/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  CPU: 2 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc4-00356-g8f2975c2bb4c #924
  Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
  --

Signed-off-by: Tetsuo Handa 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/cad03d25-0ea0-32c4-8173-fd1895314...@i-love.sakura.ne.jp
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index e035a63bbe5b..1f37904b0405 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -601,7 +601,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct 
fb_info *info,
if (scr_readw(r) != vc->vc_video_erase_char)
break;
if (r != q && new_rows >= rows + logo_lines) {
-   save = kmalloc(array3_size(logo_lines, new_cols, 2),
+   save = kzalloc(array3_size(logo_lines, new_cols, 2),
   GFP_KERNEL);
if (save) {
int i = cols < new_cols ? cols : new_cols;
-- 
2.35.1



[PATCH AUTOSEL 6.0 38/39] drm/amd/display: Use new num clk levels struct for max mclk index

2022-11-28 Thread Sasha Levin
From: Dillon Varone 

[ Upstream commit e667ee3b0c049bf0c69426879586a2572bb28d26 ]

[WHY?]
When calculating watermark and dlg values, the max mclk level index and
associated speed are needed to find the correlated dummy latency value.
Currently the incorrect index is given due to a clock manager refactor.

[HOW?]
Use num_memclk_level from num_entries_per_clk struct for getting the correct max
mem speed.

Reviewed-by: Jun Lei 
Acked-by: Brian Chang 
Signed-off-by: Dillon Varone 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index b9d3a4000c3d..221253638b4d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -1797,7 +1797,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct 
dc_state *context,
 
if 
(context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] ==
dm_dram_clock_change_unsupported) {
-   int min_dram_speed_mts_offset = 
dc->clk_mgr->bw_params->clk_table.num_entries - 1;
+   int min_dram_speed_mts_offset = 
dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1;
 
min_dram_speed_mts =

dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz 
* 16;
-- 
2.35.1



[PATCH AUTOSEL 6.0 39/39] drm/amdgpu: fix use-after-free during gpu recovery

2022-11-28 Thread Sasha Levin
From: "Stanley.Yang" 

[ Upstream commit 3cb93f390453cde4d6afda1587aaa00e75e09617 ]

[Why]
[  754.862560] refcount_t: underflow; use-after-free.
[  754.862898] Call Trace:
[  754.862903]  
[  754.862913]  amdgpu_job_free_cb+0xc2/0xe1 [amdgpu]
[  754.863543]  drm_sched_main.cold+0x34/0x39 [amd_sched]

[How]
The fw_fence may be not init, check whether dma_fence_init
is performed before job free

Signed-off-by: Stanley.Yang 
Reviewed-by: Tao Zhou 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index c2fd6f3076a6..e9583a58cce0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -150,7 +150,11 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
amdgpu_sync_free(>sync);
amdgpu_sync_free(>sched_sync);
 
-   dma_fence_put(>hw_fence);
+   /* only put the hw fence if has embedded fence */
+   if (!job->hw_fence.ops)
+   kfree(job);
+   else
+   dma_fence_put(>hw_fence);
 }
 
 void amdgpu_job_free(struct amdgpu_job *job)
-- 
2.35.1



[PATCH AUTOSEL 6.0 37/39] drm/amd/display: Avoid setting pixel rate divider to N/A

2022-11-28 Thread Sasha Levin
From: Taimur Hassan 

[ Upstream commit 2a5dd86a69ea5435f1a837bdb7fafcda609a7c91 ]

[Why]
Pixel rate divider values should never be set to N/A (0xF) as the K1/K2
field is only 1/2 bits wide.

[How]
Set valid divider values for virtual and FRL/DP2 cases.

Reviewed-by: Nicholas Kazlauskas 
Acked-by: Brian Chang 
Signed-off-by: Taimur Hassan 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c  | 7 +++
 drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c | 3 ++-
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c| 4 +++-
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c   | 1 +
 4 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
index fb729674953b..de9fa534b77a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
@@ -96,6 +96,13 @@ static void dccg314_set_pixel_rate_div(
struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = 
PIXEL_RATE_DIV_NA;
 
+   // Don't program 0xF into the register field. Not valid since
+   // K1 / K2 field is only 1 / 2 bits wide
+   if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
+   BREAK_TO_DEBUGGER();
+   return;
+   }
+
dccg314_get_pixel_rate_div(dccg, otg_inst, _k1, _k2);
if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 
&& k2 == cur_k2))
return;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
index f4d1b83979fe..a0741794db62 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
@@ -349,6 +349,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct 
pipe_ctx *pipe_ctx, unsig
odm_combine_factor = get_odm_config(pipe_ctx, NULL);
 
if (is_dp_128b_132b_signal(pipe_ctx)) {
+   *k1_div = PIXEL_RATE_DIV_BY_1;
*k2_div = PIXEL_RATE_DIV_BY_1;
} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || 
dc_is_dvi_signal(pipe_ctx->stream->signal)) {
*k1_div = PIXEL_RATE_DIV_BY_1;
@@ -356,7 +357,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct 
pipe_ctx *pipe_ctx, unsig
*k2_div = PIXEL_RATE_DIV_BY_2;
else
*k2_div = PIXEL_RATE_DIV_BY_4;
-   } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+   } else if (dc_is_dp_signal(pipe_ctx->stream->signal) || 
dc_is_virtual_signal(pipe_ctx->stream->signal)) {
if (two_pix_per_container) {
*k1_div = PIXEL_RATE_DIV_BY_1;
*k2_div = PIXEL_RATE_DIV_BY_2;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c 
b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
index 6640d0ac4304..6dd8dadd68a5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
@@ -96,8 +96,10 @@ static void dccg32_set_pixel_rate_div(
 
// Don't program 0xF into the register field. Not valid since
// K1 / K2 field is only 1 / 2 bits wide
-   if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA)
+   if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
+   BREAK_TO_DEBUGGER();
return;
+   }
 
dccg32_get_pixel_rate_div(dccg, otg_inst, _k1, _k2);
if (k1 == cur_k1 && k2 == cur_k2)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
index c72166e096ba..ecdb730f2e96 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
@@ -1186,6 +1186,7 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct 
pipe_ctx *pipe_ctx, unsign
odm_combine_factor = get_odm_config(pipe_ctx, NULL);
 
if (is_dp_128b_132b_signal(pipe_ctx)) {
+   *k1_div = PIXEL_RATE_DIV_BY_1;
*k2_div = PIXEL_RATE_DIV_BY_1;
} else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || 
dc_is_dvi_signal(pipe_ctx->stream->signal)) {
*k1_div = PIXEL_RATE_DIV_BY_1;
-- 
2.35.1



[PATCH AUTOSEL 6.0 36/39] drm/amd/display: Use viewport height for subvp mall allocation size

2022-11-28 Thread Sasha Levin
From: Dillon Varone 

[ Upstream commit dd2c028c1395d622df7ddd6837f8ab2dc94008ee ]

[WHY?]
MALL allocation size depends on the viewport height, not the addressable
vertical lines, which will not match when scaling.

[HOW?]
Base MALL allocation size calculations off viewport height.

Reviewed-by: Alvin Lee 
Reviewed-by: Martin Leung 
Acked-by: Brian Chang 
Signed-off-by: Dillon Varone 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c 
b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
index 13cd1f2e50ca..902c69d126d5 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
@@ -101,7 +101,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct 
dc *dc, struct dc_stat
mall_alloc_width_blk_aligned = 
full_vp_width_blk_aligned;
 
/* mall_alloc_height_blk_aligned_l/c = 
CEILING(sub_vp_height_l/c - 1, blk_height_l/c) + blk_height_l/c */
-   mall_alloc_height_blk_aligned = 
(pipe->stream->timing.v_addressable - 1 + mblk_height - 1) /
+   mall_alloc_height_blk_aligned = 
(pipe->plane_res.scl_data.viewport.height - 1 + mblk_height - 1) /
mblk_height * mblk_height + mblk_height;
 
/* full_mblk_width_ub_l/c = 
mall_alloc_width_blk_aligned_l/c;
-- 
2.35.1



[PATCH AUTOSEL 6.0 32/39] fbcon: Use kzalloc() in fbcon_prepare_logo()

2022-11-28 Thread Sasha Levin
From: Tetsuo Handa 

[ Upstream commit a6a00d7e8ffd78d1cdb7a43f1278f081038c638f ]

A kernel built with syzbot's config file reported that

  scr_memcpyw(q, save, array3_size(logo_lines, new_cols, 2))

causes uninitialized "save" to be copied.

  --
  [drm] Initialized vgem 1.0.0 20120112 for vgem on minor 0
  [drm] Initialized vkms 1.0.0 20180514 for vkms on minor 1
  Console: switching to colour frame buffer device 128x48
  =
  BUG: KMSAN: uninit-value in do_update_region+0x4b8/0xba0
   do_update_region+0x4b8/0xba0
   update_region+0x40d/0x840
   fbcon_switch+0x3364/0x35e0
   redraw_screen+0xae3/0x18a0
   do_bind_con_driver+0x1cb3/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was stored to memory at:
   fbcon_prepare_logo+0x143b/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  Uninit was created at:
   __kmem_cache_alloc_node+0xb69/0x1020
   __kmalloc+0x379/0x680
   fbcon_prepare_logo+0x704/0x1940
   fbcon_init+0x2c1b/0x31c0
   visual_init+0x3e7/0x820
   do_bind_con_driver+0x14a4/0x1df0
   do_take_over_console+0x11cb/0x13f0
   fbcon_fb_registered+0xacc/0xfd0
   register_framebuffer+0x1179/0x1320
   __drm_fb_helper_initial_config_and_unlock+0x23ad/0x2b40
   drm_fbdev_client_hotplug+0xbea/0xda0
   drm_fbdev_generic_setup+0x65e/0x9d0
   vkms_init+0x9f3/0xc76
   (...snipped...)

  CPU: 2 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc4-00356-g8f2975c2bb4c #924
  Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
  --

Signed-off-by: Tetsuo Handa 
Signed-off-by: Daniel Vetter 
Link: 
https://patchwork.freedesktop.org/patch/msgid/cad03d25-0ea0-32c4-8173-fd1895314...@i-love.sakura.ne.jp
Signed-off-by: Sasha Levin 
---
 drivers/video/fbdev/core/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 098b62f7b701..c0143d38df83 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -577,7 +577,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct 
fb_info *info,
if (scr_readw(r) != vc->vc_video_erase_char)
break;
if (r != q && new_rows >= rows + logo_lines) {
-   save = kmalloc(array3_size(logo_lines, new_cols, 2),
+   save = kzalloc(array3_size(logo_lines, new_cols, 2),
   GFP_KERNEL);
if (save) {
int i = min(cols, new_cols);
-- 
2.35.1



[linux-next:master] BUILD REGRESSION 15f2f20ccbf2d04cb14e3e7635aa0447208c71e7

2022-11-28 Thread kernel test robot
tree/branch: 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
branch HEAD: 15f2f20ccbf2d04cb14e3e7635aa0447208c71e7  Add linux-next specific 
files for 20221128

Error/Warning reports:

https://lore.kernel.org/oe-kbuild-all/202211041320.coq8eelj-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211080348.bosishom-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211090634.ryfkk0ws-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211242120.mzzvguln-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211282102.qur7hhrw-...@intel.com
https://lore.kernel.org/oe-kbuild-all/202211282244.c1faavio-...@intel.com

Error/Warning: (recently discovered and may have been fixed)

arch/arm/mach-s3c/devs.c:32:10: fatal error: linux/platform_data/dma-s3c24xx.h: 
No such file or directory
arch/powerpc/kernel/kvm_emul.o: warning: objtool: kvm_template_end(): can't 
find starting instruction
arch/powerpc/kernel/optprobes_head.o: warning: objtool: 
optprobe_template_end(): can't find starting instruction
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link_dp.c:5075:24: warning: 
implicit conversion from 'enum ' to 'enum dc_status' 
[-Wenum-conversion]
drivers/gpu/drm/amd/amdgpu/../display/dc/irq/dcn201/irq_service_dcn201.c:40:20: 
warning: no previous prototype for 'to_dal_irq_source_dcn201' 
[-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c:451:1: warning: no previous 
prototype for 'gf100_fifo_nonstall_block' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c:34:1: warning: no previous 
prototype for 'nvkm_engn_cgrp_get' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/engine/gr/tu102.c:210:1: warning: no previous 
prototype for 'tu102_gr_load' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: warning: no previous prototype 
for 'wpr_generic_header_dump' [-Wmissing-prototypes]
drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c:221:21: warning: variable 'loc' 
set but not used [-Wunused-but-set-variable]
vmlinux.o: warning: objtool: __btrfs_map_block+0x21ad: unreachable instruction
vmlinux.o: warning: objtool: btrfs_calc_avail_data_space+0x4f: unreachable 
instruction

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- alpha-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-irq-dcn201-irq_service_dcn201.c:warning:no-previous-prototype-for-to_dal_irq_source_dcn201
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-gf100.c:warning:no-previous-prototype-for-gf100_fifo_nonstall_block
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-runl.c:warning:no-previous-prototype-for-nvkm_engn_cgrp_get
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-gr-tu102.c:warning:no-previous-prototype-for-tu102_gr_load
|   |-- 
drivers-gpu-drm-nouveau-nvkm-nvfw-acr.c:warning:no-previous-prototype-for-wpr_generic_header_dump
|   `-- 
drivers-gpu-drm-nouveau-nvkm-subdev-acr-lsfw.c:warning:variable-loc-set-but-not-used
|-- alpha-randconfig-r031-20221128
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-gf100.c:warning:no-previous-prototype-for-gf100_fifo_nonstall_block
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-runl.c:warning:no-previous-prototype-for-nvkm_engn_cgrp_get
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-gr-tu102.c:warning:no-previous-prototype-for-tu102_gr_load
|   |-- 
drivers-gpu-drm-nouveau-nvkm-nvfw-acr.c:warning:no-previous-prototype-for-wpr_generic_header_dump
|   `-- 
drivers-gpu-drm-nouveau-nvkm-subdev-acr-lsfw.c:warning:variable-loc-set-but-not-used
|-- arc-allyesconfig
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-irq-dcn201-irq_service_dcn201.c:warning:no-previous-prototype-for-to_dal_irq_source_dcn201
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-gf100.c:warning:no-previous-prototype-for-gf100_fifo_nonstall_block
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-runl.c:warning:no-previous-prototype-for-nvkm_engn_cgrp_get
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-gr-tu102.c:warning:no-previous-prototype-for-tu102_gr_load
|   |-- 
drivers-gpu-drm-nouveau-nvkm-nvfw-acr.c:warning:no-previous-prototype-for-wpr_generic_header_dump
|   `-- 
drivers-gpu-drm-nouveau-nvkm-subdev-acr-lsfw.c:warning:variable-loc-set-but-not-used
|-- arc-randconfig-r024-20221127
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-core-dc_link_dp.c:warning:implicit-conversion-from-enum-anonymous-to-enum-dc_status
|   |-- 
drivers-gpu-drm-amd-amdgpu-..-display-dc-irq-dcn201-irq_service_dcn201.c:warning:no-previous-prototype-for-to_dal_irq_source_dcn201
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-gf100.c:warning:no-previous-prototype-for-gf100_fifo_nonstall_block
|   |-- 
drivers-gpu-drm-nouveau-nvkm-engine-fifo-runl.c:warning:no-previous-prototype

Re: [PATCH v1] dt-bindings: display: Convert fsl,imx-fb.txt to dt-schema

2022-11-28 Thread Uwe Kleine-König
Hello,

On Wed, Nov 16, 2022 at 11:21:31AM -0600, Rob Herring wrote:
> On Thu, Nov 10, 2022 at 10:49:45AM +0100, Uwe Kleine-König wrote:
> > This is a straight forward conversion. Note that fsl,imx-lcdc was picked
> > as the new name as this is the compatible that should supersede the
> > legacy fb binding.
> > 
> > Signed-off-by: Uwe Kleine-König 
> > ---
> > Hello,
> > 
> > the eventual goal is to add drm support for this hardware. That one will
> > use a different (and more sensible) binding. However fsl,imx*-fb won't
> > go away directly, and Rob requested to describe both bindings in the
> > same file given that it describes a single hardware type.
> > 
> > As a first step I convert the old binding to yaml. I tried to put the
> > new binding on top of that but I'm not sure about a few things in this
> > patch and so post only this first patch and once it's accepted add the
> > new binding which I guess is less overall work.
> > 
> > What I'm unsure about is the description of the display node (Is there a
> > better description? I didn't find a schema for that.)
> 
> That's going to be a challenge to describe because every panel binding 
> will need a reference to those custom properties. It's a similar problem 
> that spi-peripheral-props.yaml solved. But here, there may not be enough 
> instances to do such a general solution. Do the panels used even have 
> schemas yet?

Looking at the dts files in the tree[1] I only found sharp,lq035q7db03
in simple-panel which might match the display used in
arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts.

> It's kind of a separate problem. You could start with just creating a 
> schema just listing the custom properties.

Understood that. Will try it.
 
> > Further I didn't find documentation about additionalProperties and
> > unevaluatedProperties. Did I pick the right one here?
> 
> example-schema.yaml talks about it some. In general, if there's a 
> $ref to other properties for a node not defined locally, then you need 
> unevaluatedProperties. Otherwise, additionalProperties is fine.

Not sure I got the complete picture. I'll stick to additionalProperties
and rely on people and tools to tell me if I'm wrong :-)

Best regards and thanks for the feedback,
Uwe

[1]
 in arch/arm/boot/dts/imx25-pdk.dts
_qvga in 
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts
_svga in 
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts
_vga in 
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts
 in arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
 in arch/arm/boot/dts/imx27-apf27dev.dts
 in arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
 in arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
 in arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


Re: [PATCH v3] drm: Optimise for continuous memory allocation

2022-11-28 Thread Arunpravin Paneer Selvam

Hi Xinhui,

On 11/28/2022 12:04 PM, xinhui pan wrote:

Currently drm-buddy does not have full knowledge of continuous memory.

Lets consider scenario below.
order 1:L   R
order 0: LL LR  RL  RR
for order 1 allocation, it can offer L or R or LR+RL.

For now, we only implement L or R case for continuous memory allocation.
So this patch aims to implement the LR+RL case.

Signed-off-by: xinhui pan 
---
change from v2:
search continuous block in nearby root if needed

change from v1:
implement top-down continuous allocation
---
  drivers/gpu/drm/drm_buddy.c | 78 +
  1 file changed, 71 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index 11bb59399471..ff58eb3136d2 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -386,6 +386,58 @@ alloc_range_bias(struct drm_buddy *mm,
return ERR_PTR(err);
  }
  
+static struct drm_buddy_block *

+find_continuous_blocks(struct drm_buddy *mm,
+  int order,
+  unsigned long flags,
+  struct drm_buddy_block **rn)
+{
+   struct list_head *head = >free_list[order];
+   struct drm_buddy_block *node, *parent, *free_node, *max_node = NULL;
NIT: We usually name the variable as *block or ***_block for drm buddy 
and we have *node or ***_node for drm mm manager.

+   int i;
+
+   list_for_each_entry(free_node, head, link) {
+   if (max_node) {
+   if (!(flags & DRM_BUDDY_TOPDOWN_ALLOCATION))
+   break;
+
+   if (drm_buddy_block_offset(free_node) <
+   drm_buddy_block_offset(max_node))
+   continue;
+   }
+
+   parent = free_node;
+   do {
+   node = parent;
+   parent = parent->parent;
+   } while (parent && parent->right == node);
+
+   if (!parent) {
+   for (i = 0; i < mm->n_roots - 1; i++)
+   if (mm->roots[i] == node)
+   break;
+   if (i == mm->n_roots - 1)
+   continue;
+   node = mm->roots[i + 1];
+   } else {
+   node = parent->right;
+   }
+
+   while (drm_buddy_block_is_split(node))
+   node = node->left;
+
+   if (drm_buddy_block_is_free(node) &&
+   drm_buddy_block_order(node) == order) {
+   *rn = node;
+   max_node = free_node;
+   BUG_ON(drm_buddy_block_offset(node) !=
+   drm_buddy_block_offset(max_node) +
+   drm_buddy_block_size(mm, max_node));
+   }
+   }
+   return max_node;
+}
+
  static struct drm_buddy_block *
  get_maxblock(struct list_head *head)
  {
@@ -637,7 +689,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
   struct list_head *blocks,
   unsigned long flags)
  {
-   struct drm_buddy_block *block = NULL;
+   struct drm_buddy_block *block = NULL, *rblock = NULL;
unsigned int min_order, order;
unsigned long pages;
LIST_HEAD(allocated);
@@ -689,17 +741,29 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm,
break;
  
  			if (order-- == min_order) {

+   if (!(flags & DRM_BUDDY_RANGE_ALLOCATION) &&
+   min_order != 0 && pages == BIT(order + 1)) {
+   block = find_continuous_blocks(mm,
+  order,
+  flags,
+  );
+   if (block)
+   break;
+   }
err = -ENOSPC;
goto err_free;
}
} while (1);
  
-		mark_allocated(block);

-   mm->avail -= drm_buddy_block_size(mm, block);
-   kmemleak_update_trace(block);
-   list_add_tail(>link, );
-
-   pages -= BIT(order);
+   do {
+   mark_allocated(block);
+   mm->avail -= drm_buddy_block_size(mm, block);
+   kmemleak_update_trace(block);
+   list_add_tail(>link, );
+   pages -= BIT(order);
+   block = rblock;
+   rblock = NULL;
+   } while (block);
I think with this 

Re: [PATCH v2] drm: Only select I2C_ALGOBIT for drivers that actually need it

2022-11-28 Thread Javier Martinez Canillas
Hello Uwe,

Thanks for your patch.

On 9/12/22 11:15, Uwe Kleine-König wrote:
> While working on a drm driver that doesn't need the i2c algobit stuff I
> noticed that DRM selects this code even tough only 8 drivers actually use
> it. While also only some drivers use i2c, keep the select for I2C for the
> next cleanup patch. Still prepare this already by also selecting I2C for
> the individual drivers.
> 
> Signed-off-by: Uwe Kleine-König 
> ---

Makes sense to me. It would be good to drop this dependency, specially now
that many distros have CONFIG_DRM=y to use simpledrm for early boot.

> Changes since v1
> (20210514100142.1182997-1-u.kleine-koe...@pengutronix.de) from
> 2021-05-14:
> 
>  - rebased to next-20220909
>was something around v5.13-rc2 before, required to fix context
>changes in the nouveau Kconfig file. git am -3 handled it just fine.
> 
> I reverified that no new drivers were added that need a corresponding
> select.
> 
> Best regards
> Uwe
> 
>  drivers/gpu/drm/Kconfig | 5 -
>  drivers/gpu/drm/ast/Kconfig | 2 ++
>  drivers/gpu/drm/gma500/Kconfig  | 2 ++
>  drivers/gpu/drm/hisilicon/hibmc/Kconfig | 2 ++
>  drivers/gpu/drm/i915/Kconfig| 2 ++
>  drivers/gpu/drm/mgag200/Kconfig | 2 ++
>  drivers/gpu/drm/nouveau/Kconfig | 2 ++
>  7 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 198ba846d34b..593d7335b10a 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -13,7 +13,6 @@ menuconfig DRM
>   select HDMI
>   select FB_CMDLINE
>   select I2C

Is I2C still required or was just a dependency of I2C_ALGOBIT ?

I'll wait a few days in case others want to review this change too
and then can push this to drm-misc-next. 

Reviewed-by: Javier Martinez Canillas 

-- 
Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat



Re: [PATCH v2] drm: Only select I2C_ALGOBIT for drivers that actually need it

2022-11-28 Thread Uwe Kleine-König
On Mon, Sep 12, 2022 at 11:15:05AM +0200, Uwe Kleine-König wrote:
> While working on a drm driver that doesn't need the i2c algobit stuff I
> noticed that DRM selects this code even tough only 8 drivers actually use
> it. While also only some drivers use i2c, keep the select for I2C for the
> next cleanup patch. Still prepare this already by also selecting I2C for
> the individual drivers.
> 
> Signed-off-by: Uwe Kleine-König 

ping! Is there anything I do wrong to not get any attention here?

Best regards
Uwe

-- 
Pengutronix e.K.   | Uwe Kleine-König|
Industrial Linux Solutions | https://www.pengutronix.de/ |


signature.asc
Description: PGP signature


[pull] drm/msm: drm-msm-next-2022-11-28 for v6.2

2022-11-28 Thread Rob Clark
Hi Dave & Daniel,

Here are the gpu/gem bits for v6.2.  Dmitry already sent a separate
pull request[1] for the display bits.  Summary below and in tag.

[1] 
https://patchwork.kernel.org/project/dri-devel/patch/20221126102141.721353-1-dmitry.barysh...@linaro.org/

The following changes since commit 7f7a942c0a338c4a2a7b359bdb2b68e9896122ec:

  Merge tag 'drm-next-20221025' of git://linuxtv.org/pinchartl/media
into drm-next (2022-10-27 14:44:15 +1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/msm.git tags/drm-msm-next-2022-11-28

for you to fetch changes up to d73b1d02de0858b96f743e1e8b767fb092ae4c1b:

  drm/msm: Hangcheck progress detection (2022-11-17 10:39:12 -0800)


msm-next for v6.2 (the gpu/gem bits)

- Remove exclusive-fence hack that caused over-synchronization
- Fix speed-bin detection vs. probe-defer
- Enable clamp_to_idle on 7c3
- Improved hangcheck detection


Rob Clark (6):
  drm/msm: Remove exclusive-fence hack
  drm/msm/a6xx: Fix speed-bin detection vs probe-defer
  drm/msm: Enable clamp_to_idle for 7c3
  drm/msm: Enable unpin/eviction by default
  drm/msm/adreno: Simplify read64/write64 helpers
  drm/msm: Hangcheck progress detection

 drivers/gpu/drm/msm/adreno/a4xx_gpu.c   |  3 +-
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c   | 27 --
 drivers/gpu/drm/msm/adreno/a5xx_preempt.c   |  4 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 84 ++---
 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c |  3 +-
 drivers/gpu/drm/msm/msm_drv.c   |  1 -
 drivers/gpu/drm/msm/msm_drv.h   |  8 ++-
 drivers/gpu/drm/msm/msm_gem_shrinker.c  |  2 +-
 drivers/gpu/drm/msm/msm_gem_submit.c|  3 +-
 drivers/gpu/drm/msm/msm_gpu.c   | 31 ++-
 drivers/gpu/drm/msm/msm_gpu.h   | 22 +---
 drivers/gpu/drm/msm/msm_ringbuffer.h| 28 ++
 12 files changed, 150 insertions(+), 66 deletions(-)


Re: [PATCH] drm/i915/huc: fix leak of debug object in huc load fence on driver unload

2022-11-28 Thread Ceraolo Spurio, Daniele




On 11/28/2022 5:08 AM, Ville Syrjälä wrote:

On Mon, Nov 28, 2022 at 01:10:58AM -0800, Ceraolo Spurio, Daniele wrote:


On 11/25/2022 5:54 AM, Ville Syrjälä wrote:

On Thu, Nov 10, 2022 at 04:56:51PM -0800, Daniele Ceraolo Spurio wrote:

The fence is always initialized in huc_init_early, but the cleanup in
huc_fini is only being run if HuC is enabled. This causes a leaking of
the debug object when HuC is disabled/not supported, which can in turn
trigger a warning if we try to register a new debug offset at the same
address on driver reload.

To fix the issue, make sure to always run the cleanup code.

This oopsing in ci now. Somehow the patchwork run did not
hit that oops.

Can you point me to the oops log? I opened a few recent runs at random
but I wasn't able to find it.

https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_12425/fi-blb-e6850/igt@core_hotunp...@unbind-rebind.html


Thanks, it's indeed the same issue (and I've just confirmed that the 
pre-merge result for the fix do mention that this test is moving from 
incomplete to pass). From just a visual inspection I thought the problem 
would only affect MTL, which does have HuC but only on one of the 2 GTs, 
but it looks like this impacts also platforms without HuC at all (as 
long as they also have no VCS engines). I'll try to get the fix reviewed 
and merged ASAP.


Thanks,
Daniele




[PATCH v2 RESEND 3/4] drm/panel: Add driver for JDI LPM102A188A

2022-11-28 Thread Diogo Ivo
The JDI LPM102A188A is a 2560x1800 IPS panel found in the Google Pixel C.
This driver is based on the downstream GPLv2 driver released by Google
written by Sean Paul [1], which was then adapted to the newer kernel APIs.

[1]: 
https://android.googlesource.com/kernel/tegra/+/refs/heads/android-tegra-dragon-3.18-oreo/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c

Signed-off-by: Diogo Ivo 
---
Changes in v2:
 - tuned backlight delays

 drivers/gpu/drm/panel/Kconfig |  11 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c | 509 ++
 3 files changed, 521 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a582ddd583c2..80eda8f6bee0 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -214,6 +214,17 @@ config DRM_PANEL_JDI_LT070ME05000
  The panel has a 1200(RGB)×1920 (WUXGA) resolution and uses
  24 bit per pixel.
 
+config DRM_PANEL_JDI_LPM102A188A
+   tristate "JDI LPM102A188A DSI panel"
+   depends on OF && GPIOLIB
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for JDI LPM102A188A DSI
+ control mode panel as found in Google Pixel C devices.
+ The panel has a 2560×1800 resolution. It provides a MIPI DSI interface
+ to the host.
+
 config DRM_PANEL_JDI_R63452
tristate "JDI R63452 Full HD DSI panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 34e717382dbb..2870cba96d14 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += 
panel-ilitek-ili9881c.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
+obj-$(CONFIG_DRM_PANEL_JDI_LPM102A188A) += panel-jdi-lpm102a188a.o
 obj-$(CONFIG_DRM_PANEL_JDI_R63452) += panel-jdi-fhd-r63452.o
 obj-$(CONFIG_DRM_PANEL_KHADAS_TS050) += panel-khadas-ts050.o
 obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o
diff --git a/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c 
b/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c
new file mode 100644
index ..980af82ad6d6
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c
@@ -0,0 +1,509 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Copyright (C) 2022 Diogo Ivo 
+ *
+ * Adapted from the downstream Pixel C driver written by Sean Paul
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+struct jdi_panel {
+   struct drm_panel base;
+   struct mipi_dsi_device *link1;
+   struct mipi_dsi_device *link2;
+
+   struct regulator *supply;
+   struct regulator *ddi_supply;
+   struct backlight_device *backlight;
+
+   struct gpio_desc *enable_gpio;
+   struct gpio_desc *reset_gpio;
+
+   const struct drm_display_mode *mode;
+
+   bool prepared;
+   bool enabled;
+};
+
+static inline struct jdi_panel *to_panel_jdi(struct drm_panel *panel)
+{
+   return container_of(panel, struct jdi_panel, base);
+}
+
+static void jdi_wait_frames(struct jdi_panel *jdi, unsigned int frames)
+{
+   unsigned int refresh = drm_mode_vrefresh(jdi->mode);
+
+   if (WARN_ON(frames > refresh))
+   return;
+
+   msleep(1000 / (refresh / frames));
+}
+
+static int jdi_panel_disable(struct drm_panel *panel)
+{
+   struct jdi_panel *jdi = to_panel_jdi(panel);
+
+   if (!jdi->enabled)
+   return 0;
+
+   backlight_disable(jdi->backlight);
+
+   jdi_wait_frames(jdi, 2);
+
+   jdi->enabled = false;
+
+   return 0;
+}
+
+static int jdi_panel_unprepare(struct drm_panel *panel)
+{
+   struct jdi_panel *jdi = to_panel_jdi(panel);
+   int ret;
+
+   if (!jdi->prepared)
+   return 0;
+
+   ret = mipi_dsi_dcs_set_display_off(jdi->link1);
+   if (ret < 0)
+   dev_err(panel->dev, "failed to set display off: %d\n", ret);
+   ret = mipi_dsi_dcs_set_display_off(jdi->link2);
+   if (ret < 0)
+   dev_err(panel->dev, "failed to set display off: %d\n", ret);
+
+   /* Specified by JDI @ 50ms, subject to change */
+   msleep(50);
+
+   ret = mipi_dsi_dcs_enter_sleep_mode(jdi->link1);
+   if (ret < 0)
+   dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret);
+   ret = mipi_dsi_dcs_enter_sleep_mode(jdi->link2);
+   if (ret < 0)
+   dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret);
+
+   /* Specified by JDI @ 150ms, subject to change */
+   

[PATCH v2 RESEND 0/4] Add JDI LPM102A188A display panel support

2022-11-28 Thread Diogo Ivo
Hello,

These patches add support for the JDI LPM102A188A display panel,
found in the Google Pixel C.

Patch 1 adds the DT bindings for the panel (omitted in RESEND).

Patch 2 adds a register clear to the Tegra DSI driver, needed for the
panel initialization commands to be properly sent.

Patch 3 adds the panel driver, which is based on the downstream
kernel driver published by Google and developed by Sean Paul.

Patch 4 adds the DT node for the Google Pixel C. 

The first version of this patch series can be found at:
https://lore.kernel.org/all/20220929170502.1034040-1-diogo@tecnico.ulisboa.pt/

The first submission of v2 can be found at:
https://lore.kernel.org/all/20221025153746.101278-1-diogo@tecnico.ulisboa.pt/

Changes in v2:
 - Patch 1: remove touchscreen reset gpio property
 - Patch 2: clear register based on its value rather than a DT property
 - Patch 3: tune backlight delay values
 - Patch 4: add generic node names, remove underscores

Thank you.

Diogo Ivo (4):

  dt-bindings: display: Add bindings for JDI LPM102A188A
  drm/tegra: dsi: Clear enable register if powered by bootloader
  drm/panel: Add driver for JDI LPM102A188A
  arm64: dts: smaug: Add display panel node

 .../display/panel/jdi,lpm102a188a.yaml|  94 
 arch/arm64/boot/dts/nvidia/tegra210-smaug.dts |  70 +++
 drivers/gpu/drm/panel/Kconfig |  11 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c | 509 ++
 drivers/gpu/drm/tegra/dsi.c   |   9 +
 6 files changed, 694 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/jdi,lpm102a188a.yaml
 create mode 100644 drivers/gpu/drm/panel/panel-jdi-lpm102a188a.c

-- 
2.38.1



[PATCH v2 RESEND 2/4] drm/tegra: dsi: Clear enable register if powered by bootloader

2022-11-28 Thread Diogo Ivo
In cases where the DSI module is left on by the bootloader
some panels may fail to initialize if the enable register is not cleared
before the panel's initialization sequence is sent, so clear it if that
is the case. 

Signed-off-by: Diogo Ivo 
---
Changes in v2:
 - detect if the DSI module is on based on the register value,
   instead of a DT property.
 - remove Display Controller clear, since it is redundant.

 drivers/gpu/drm/tegra/dsi.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index de1333dc0d86..5954676a7ab1 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -912,6 +912,15 @@ static void tegra_dsi_encoder_enable(struct drm_encoder 
*encoder)
u32 value;
int err;
 
+   /* If the bootloader enabled DSI it needs to be disabled
+* in order for the panel initialization commands to be
+* properly sent.
+*/
+   value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
+
+   if (value & DSI_POWER_CONTROL_ENABLE)
+   tegra_dsi_disable(dsi);
+
err = tegra_dsi_prepare(dsi);
if (err < 0) {
dev_err(dsi->dev, "failed to prepare: %d\n", err);
-- 
2.38.1



[PATCH v2 RESEND 4/4] arm64: dts: smaug: Add display panel node

2022-11-28 Thread Diogo Ivo
The Google Pixel C has a JDI LPM102A188A display panel. Add a
DT node for it. Tested on Pixel C.

Signed-off-by: Diogo Ivo 
---
Changes in v2:
 - renamed backlight node to a generic name
 - removed underscores

 arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 70 +++
 1 file changed, 70 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts 
b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
index 84ec4d8b7f10..5db0b25c8d58 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts
@@ -31,6 +31,37 @@ memory {
};
 
host1x@5000 {
+   dc@5420 {
+   status = "okay";
+   };
+
+   dsia: dsi@5430 {
+   avdd-dsi-csi-supply = <_dsi_csi>;
+   status = "okay";
+
+   link2: panel@0 {
+   compatible = "jdi,lpm102a188a";
+   reg = <0>;
+   };
+   };
+
+   dsib: dsi@5440 {
+   avdd-dsi-csi-supply = <_dsi_csi>;
+   nvidia,ganged-mode = <>;
+   status = "okay";
+
+   link1: panel@0 {
+   compatible = "jdi,lpm102a188a";
+   reg = <0>;
+   power-supply = <_vdd>;
+   ddi-supply = <_lcdio>;
+   enable-gpios = < TEGRA_GPIO(V, 1) 
GPIO_ACTIVE_HIGH>;
+   reset-gpios = < TEGRA_GPIO(V, 2) 
GPIO_ACTIVE_LOW>;
+   link2 = <>;
+   backlight = <>;
+   };
+   };
+
dpaux: dpaux@545c {
status = "okay";
};
@@ -1627,6 +1658,37 @@ nau8825@1a {
status = "okay";
};
 
+   backlight: backlight@2c {
+   compatible = "ti,lp8557";
+   reg = <0x2c>;
+   power-supply = <_vdd>;
+   enable-supply = <_lcdio>;
+   bl-name = "lp8557-backlight";
+   dev-ctrl = /bits/ 8 <0x01>;
+   init-brt = /bits/ 8 <0x80>;
+
+   /* Full scale current, 20mA */
+   rom-11h {
+   rom-addr = /bits/ 8 <0x11>;
+   rom-val = /bits/ 8 <0x05>;
+   };
+   /* Frequency = 4.9kHz, magic undocumented val */
+   rom-12h {
+   rom-addr = /bits/ 8 <0x12>;
+   rom-val = /bits/ 8 <0x29>;
+   };
+   /* Boost freq = 1MHz, BComp option = 1 */
+   rom-13h {
+   rom-addr = /bits/ 8 <0x13>;
+   rom-val = /bits/ 8 <0x03>;
+   };
+   /* 4V OV, 6 output LED string enabled */
+   rom-14h {
+   rom-addr = /bits/ 8 <0x14>;
+   rom-val = /bits/ 8 <0xbf>;
+   };
+   };
+
audio-codec@2d {
compatible = "realtek,rt5677";
reg = <0x2d>;
@@ -1908,4 +1970,12 @@ usbc_vbus: regulator-usbc-vbus {
regulator-min-microvolt = <500>;
regulator-max-microvolt = <500>;
};
+
+   vdd_dsi_csi: regulator-vdd-dsi-csi {
+   compatible = "regulator-fixed";
+   regulator-name = "AVDD_DSI_CSI_1V2";
+   regulator-min-microvolt = <120>;
+   regulator-max-microvolt = <120>;
+   vin-supply = <_avdd>;
+   };
 };
-- 
2.38.1



Re: AMD GPU problems under Xen

2022-11-28 Thread Alex Deucher
On Mon, Nov 28, 2022 at 2:18 AM Demi Marie Obenour
 wrote:
>
> Dear Christian:
>
> What is the status of the AMDGPU work for Xen dom0?  That was mentioned in
> https://lore.kernel.org/dri-devel/b2dec9b3-03a7-e7ac-306e-1da024af8...@amd.com/
> and there have been bug reports to Qubes OS about problems with AMDGPU
> under Xen (such as https://github.com/QubesOS/qubes-issues/issues/7648).

I would say it's a work in progress.  It depends what GPU  you have
and what type of xen setup you are using (PV vs PVH, etc.).  In
general, your best bet currently is dGPU add in boards because they
are largely self contained.  APUs and platforms with integrated dGPUs
are a bit more complicated as they tend to have more platform
dependencies like ACPI tables and methods in order for the driver to
be able to initialize the hardware properly.  Additionally, GPUs map a
lot of system memory so bounce buffers aren't really viable.  You'll
really need IOMMU,

Alex

> --
> Sincerely,
> Demi Marie Obenour (she/her/hers)
> Invisible Things Lab


[drm-misc:drm-misc-next 12/19] drivers/gpu/drm/tests/drm_probe_helper_test.c:119:3: warning: variable 'len' is uninitialized when used here

2022-11-28 Thread kernel test robot
tree:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
head:   0ae41323a83233610e64e926eefb4d132ecb9028
commit: 1e4a91db109f623d0e3ef7d8bfae3c88b4d2fa87 [12/19] drm/probe-helper: 
Provide a TV get_modes helper
config: hexagon-randconfig-r041-20221128
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 
6e4cea55f0d1104408b26ac574566a0e4de48036)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
git remote add drm-misc git://anongit.freedesktop.org/drm/drm-misc
git fetch --no-tags drm-misc drm-misc-next
git checkout 1e4a91db109f623d0e3ef7d8bfae3c88b4d2fa87
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=hexagon SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/gpu/drm/tests/drm_probe_helper_test.c:7:
   In file included from include/drm/drm_connector.h:32:
   In file included from include/drm/drm_util.h:35:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __raw_readb(PCI_IOBASE + addr);
 ~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
   ~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from 
macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
 ^
   In file included from drivers/gpu/drm/tests/drm_probe_helper_test.c:7:
   In file included from include/drm/drm_connector.h:32:
   In file included from include/drm/drm_util.h:35:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
   ~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from 
macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
 ^
   In file included from drivers/gpu/drm/tests/drm_probe_helper_test.c:7:
   In file included from include/drm/drm_connector.h:32:
   In file included from include/drm/drm_util.h:35:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   __raw_writeb(value, PCI_IOBASE + addr);
   ~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
 ~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
 ~~ ^
>> drivers/gpu/drm/tests/drm_probe_helper_test.c:119:3: warning: variable 'len' 

[PATCH v2 07/21] staging: media: tegra-video: improve error messages

2022-11-28 Thread Luca Ceresoli
tegra_vi_channels_alloc() can primarily fail for two reasons:

 1. "ports" node not found
 2. port_num > vi->soc->vi_max_channels

Case 1 prints nothing, case 2 has a dev_err(). The caller [tegra_vi_init()]
has a generic dev_err() on any failure. This mean that in case 2 we print
two messages, and in case 1 we only print a generic message.

Remove the generic message and add a specific message when case 1 happens,
so that we always have one specific message without even increasing the
number of dev_dbg*() calls.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index b24b9353077f..24de4ed1eaf0 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1272,7 +1272,7 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
 
ports = of_get_child_by_name(node, "ports");
if (!ports)
-   return -ENODEV;
+   return dev_err_probe(vi->dev, -ENODEV, "%pOF: missing 'ports' 
node\n", node);
 
for_each_child_of_node(ports, port) {
if (!of_node_name_eq(port, "port"))
@@ -1824,11 +1824,8 @@ static int tegra_vi_init(struct host1x_client *client)
ret = tegra_vi_tpg_channels_alloc(vi);
else
ret = tegra_vi_channels_alloc(vi);
-   if (ret < 0) {
-   dev_err(vi->dev,
-   "failed to allocate vi channels: %d\n", ret);
+   if (ret < 0)
goto free_chans;
-   }
 
ret = tegra_vi_channels_init(vi);
if (ret < 0)
-- 
2.34.1



[PATCH v2 17/21] staging: media: tegra-video: add syncpts for Tegra20 to struct tegra_vi

2022-11-28 Thread Luca Ceresoli
In preparation to implement Tegra20 parallel video capture, add variables
to hold the required syncpt.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/vi.h | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 8fadca33bcc9..ba563cd17296 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -117,11 +117,13 @@ struct tegra_vi {
  * @vi: Tegra video input device structure
  * @frame_start_sp: host1x syncpoint pointer to synchronize programmed capture
  * start condition with hardware frame start events through host1x
- * syncpoint counters.
+ * syncpoint counters. (Tegra210)
  * @mw_ack_sp: host1x syncpoint pointer to synchronize programmed memory write
  * ack trigger condition with hardware memory write done at end of
- * frame through host1x syncpoint counters.
+ * frame through host1x syncpoint counters. (Tegra210)
  * @sp_incr_lock: protects cpu syncpoint increment.
+ * @out_sp: host1x syncpoint pointer for frame sync (Tegra20)
+ * @next_out_sp_idx: next expected value for @out_sp (Tegra20)
  *
  * @kthread_start_capture: kthread to start capture of single frame when
  * vb buffer is available. This thread programs VI CSI hardware
@@ -173,6 +175,8 @@ struct tegra_vi_channel {
struct host1x_syncpt *mw_ack_sp[GANG_PORTS_MAX];
/* protects the cpu syncpoint increment */
spinlock_t sp_incr_lock[GANG_PORTS_MAX];
+   struct host1x_syncpt *out_sp;
+   u32 next_out_sp_idx;
 
struct task_struct *kthread_start_capture;
wait_queue_head_t start_wait;
-- 
2.34.1



[PATCH v2 10/21] staging: media: tegra-video: remove unneeded include

2022-11-28 Thread Luca Ceresoli
There is only a pointer reference to struct tegra_vi in video.h, thus vi.h
is not needed.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/video.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/video.h 
b/drivers/staging/media/tegra-video/video.h
index fadaf2189dc9..1e9be1474a9c 100644
--- a/drivers/staging/media/tegra-video/video.h
+++ b/drivers/staging/media/tegra-video/video.h
@@ -12,7 +12,6 @@
 #include 
 
 #include "vi.h"
-#include "csi.h"
 
 struct tegra_video_device {
struct v4l2_device v4l2_dev;
-- 
2.34.1



[PATCH v2 21/21] staging: media: tegra-video: add tegra20 variant

2022-11-28 Thread Luca Ceresoli
The staging tegra-video driver currently implements MIPI CSI-2 video
capture for Tegra210. Add support for parallel video capture (VIP) on
Tegra20. With the generalizations added to the VI driver in previous
commits, this is only a matter of adding the tegra20.c implementation and
registering it.

Unfortunately there was no documentation available for the VI or VIP
peripherals of Tegra20 (or any other Tegra chips). This implementation has
been based entirely on the code from a vendor kernel based on Linux 3.1 and
massively adapted to fit into the tegra-video driver. Parts of this code is
definitely non-optimal to say the least (especially tegra20_vi_enable() and
the single-frame capture logic), but it was impossible to improve it.

Signed-off-by: Luca Ceresoli 

---

Changed in v2:
 - fix tegra20_vi_enable() to clear bit when on==false
 - clamp width/height from set/try_fmt to avoid returning sizeimage=0
   (fixes v4l2-compliance)
---
 MAINTAINERS |   1 +
 drivers/staging/media/tegra-video/Makefile  |   1 +
 drivers/staging/media/tegra-video/tegra20.c | 661 
 drivers/staging/media/tegra-video/vi.c  |   3 +
 drivers/staging/media/tegra-video/vi.h  |   3 +
 drivers/staging/media/tegra-video/video.c   |   5 +
 drivers/staging/media/tegra-video/video.h   |   1 +
 7 files changed, 675 insertions(+)
 create mode 100644 drivers/staging/media/tegra-video/tegra20.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1601465e8e31..9869746863b2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20322,6 +20322,7 @@ L:  linux-te...@vger.kernel.org
 S: Maintained
 F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
 F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml
+F: drivers/staging/media/tegra-video/tegra20.c
 F: drivers/staging/media/tegra-video/vip.*
 
 TEGRA XUSB PADCTL DRIVER
diff --git a/drivers/staging/media/tegra-video/Makefile 
b/drivers/staging/media/tegra-video/Makefile
index 3c8ec1bb1f3e..6c7552e05109 100644
--- a/drivers/staging/media/tegra-video/Makefile
+++ b/drivers/staging/media/tegra-video/Makefile
@@ -5,5 +5,6 @@ tegra-video-objs := \
vip.o \
csi.o
 
+tegra-video-$(CONFIG_ARCH_TEGRA_2x_SOC)  += tegra20.o
 tegra-video-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
 obj-$(CONFIG_VIDEO_TEGRA) += tegra-video.o
diff --git a/drivers/staging/media/tegra-video/tegra20.c 
b/drivers/staging/media/tegra-video/tegra20.c
new file mode 100644
index ..002a66d12ecb
--- /dev/null
+++ b/drivers/staging/media/tegra-video/tegra20.c
@@ -0,0 +1,661 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Tegra20-specific VI implementation
+ *
+ * Copyright (C) 2022 SKIDATA GmbH
+ * Author: Luca Ceresoli 
+ */
+
+/*
+ * This source file contains Tegra20 supported video formats,
+ * VI and VIP SoC specific data, operations and registers accessors.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "vip.h"
+#include "vi.h"
+
+#define TEGRA_VI_SYNCPT_WAIT_TIMEOUT   msecs_to_jiffies(200)
+
+/* This are just good-sense numbers. The actual min/max is not documented. */
+#define TEGRA20_MIN_WIDTH  32U
+#define TEGRA20_MIN_HEIGHT 32U
+#define TEGRA20_MAX_WIDTH  2048U
+#define TEGRA20_MAX_HEIGHT 2048U
+
+/* --
+ * Registers
+ */
+
+#define TEGRA_VI_CONT_SYNCPT_OUT_1 0x0060
+#define   VI_CONT_SYNCPT_OUT_1_CONTINUOUS_SYNCPT   BIT(8)
+#define   VI_CONT_SYNCPT_OUT_1_SYNCPT_IDX_SFT  0
+
+#define TEGRA_VI_VI_INPUT_CONTROL  0x0088
+#define   VI_INPUT_FIELD_DETECTBIT(27)
+#define   VI_INPUT_BT656   BIT(25)
+#define   VI_INPUT_YUV_INPUT_FORMAT_SFT8  /* bits [9:8] */
+#define   VI_INPUT_YUV_INPUT_FORMAT_UYVY   (0 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_VYUY   (1 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_YUYV   (2 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_YUV_INPUT_FORMAT_YVYU   (3 << 
VI_INPUT_YUV_INPUT_FORMAT_SFT)
+#define   VI_INPUT_INPUT_FORMAT_SFT2  /* bits 
[5:2] */
+#define   VI_INPUT_INPUT_FORMAT_YUV422 (0 << 
VI_INPUT_INPUT_FORMAT_SFT)
+#define   VI_INPUT_VIP_INPUT_ENABLEBIT(1)
+
+#define TEGRA_VI_VI_CORE_CONTROL   0x008c
+#define   VI_VI_CORE_CONTROL_PLANAR_CONV_IN_SEL_EXTBIT(31)
+#define   VI_VI_CORE_CONTROL_CSC_INPUT_SEL_EXT BIT(30)
+#define   VI_VI_CORE_CONTROL_INPUT_TO_ALT_MUX_SFT  27
+#define   VI_VI_CORE_CONTROL_INPUT_TO_CORE_EXT_SFT 24
+#define   VI_VI_CORE_CONTROL_OUTPUT_TO_ISP_EXT_SFT 21
+#define   VI_VI_CORE_CONTROL_ISP_HOST_STALL_OFFBIT(20)
+#define   

[PATCH v2 14/21] staging: media: tegra-video: move MIPI calibration calls from VI to CSI

2022-11-28 Thread Luca Ceresoli
The CSI module does not handle all the MIPI lane calibration procedure,
leaving a small part of it to the VI module. In doing this,
tegra_channel_enable_stream() (vi.c) manipulates the private data of the
upstream subdev casting it to struct 'tegra_csi_channel', which will be
wrong after introducing a VIP (parallel video input) channel.

This prevents adding support for the VIP module.  It also breaks the
logical isolation between modules.

Since the lane calibration requirement does not exist in the parallel input
module, moving the calibration function to a per-module op is not
optimal. Instead move the calibration procedure in the CSI module, together
with the rest of the calibration procedures. After this change,
tegra_channel_enable_stream() just calls v4l2_subdev_call() to ask for a
stream start/stop to the CSI module, which in turn knows all the
CSI-specific details to implement it.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/csi.c | 44 
 drivers/staging/media/tegra-video/vi.c  | 54 ++---
 2 files changed, 48 insertions(+), 50 deletions(-)

diff --git a/drivers/staging/media/tegra-video/csi.c 
b/drivers/staging/media/tegra-video/csi.c
index 426e653bd55d..3a614f568a31 100644
--- a/drivers/staging/media/tegra-video/csi.c
+++ b/drivers/staging/media/tegra-video/csi.c
@@ -328,12 +328,42 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
*subdev)
}
 
csi_chan->pg_mode = chan->pg_mode;
+
+   /*
+* Tegra CSI receiver can detect the first LP to HS transition.
+* So, start the CSI stream-on prior to sensor stream-on and
+* vice-versa for stream-off.
+*/
ret = csi->ops->csi_start_streaming(csi_chan);
if (ret < 0)
goto finish_calibration;
 
+   if (csi_chan->mipi) {
+   struct v4l2_subdev *src_subdev;
+   /*
+* TRM has incorrectly documented to wait for done status from
+* calibration logic after CSI interface power on.
+* As per the design, calibration results are latched and 
applied
+* to the pads only when the link is in LP11 state which will 
happen
+* during the sensor stream-on.
+* CSI subdev stream-on triggers start of MIPI pads calibration.
+* Wait for calibration to finish here after sensor subdev 
stream-on.
+*/
+   src_subdev = tegra_channel_get_remote_source_subdev(chan);
+   ret = v4l2_subdev_call(src_subdev, video, s_stream, true);
+   err = tegra_mipi_finish_calibration(csi_chan->mipi);
+
+   if (ret < 0 && ret != -ENOIOCTLCMD)
+   goto disable_csi_stream;
+
+   if (err < 0)
+   dev_warn(csi->dev, "MIPI calibration failed: %d\n", 
err);
+   }
+
return 0;
 
+disable_csi_stream:
+   csi->ops->csi_stop_streaming(csi_chan);
 finish_calibration:
if (csi_chan->mipi)
tegra_mipi_finish_calibration(csi_chan->mipi);
@@ -352,10 +382,24 @@ static int tegra_csi_enable_stream(struct v4l2_subdev 
*subdev)
 
 static int tegra_csi_disable_stream(struct v4l2_subdev *subdev)
 {
+   struct tegra_vi_channel *chan = v4l2_get_subdev_hostdata(subdev);
struct tegra_csi_channel *csi_chan = to_csi_chan(subdev);
struct tegra_csi *csi = csi_chan->csi;
int err;
 
+   /*
+* Stream-off subdevices in reverse order to stream-on.
+* Remote source subdev in TPG mode is same as CSI subdev.
+*/
+   if (csi_chan->mipi) {
+   struct v4l2_subdev *src_subdev;
+
+   src_subdev = tegra_channel_get_remote_source_subdev(chan);
+   err = v4l2_subdev_call(src_subdev, video, s_stream, false);
+   if (err < 0 && err != -ENOIOCTLCMD)
+   dev_err_probe(csi->dev, err, "source subdev stream off 
failed\n");
+   }
+
csi->ops->csi_stop_streaming(csi_chan);
 
if (csi_chan->mipi) {
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 8b6cf50e1eae..2dd3c6c944a2 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -187,49 +187,15 @@ tegra_channel_get_remote_source_subdev(struct 
tegra_vi_channel *chan)
 
 static int tegra_channel_enable_stream(struct tegra_vi_channel *chan)
 {
-   struct v4l2_subdev *csi_subdev, *src_subdev;
-   struct tegra_csi_channel *csi_chan;
-   int ret, err;
+   struct v4l2_subdev *subdev;
+   int ret;
 
-   /*
-* Tegra CSI receiver can detect the first LP to HS transition.
-* So, start the CSI stream-on prior to sensor stream-on and
-* vice-versa for stream-off.
-*/
-   csi_subdev = tegra_channel_get_remote_csi_subdev(chan);
-   ret = 

[PATCH v2 13/21] staging: media: tegra-video: move default format to soc-specific data

2022-11-28 Thread Luca Ceresoli
The tegra_default_format in vi.c is specific to Tegra210 CSI.

In preparation for adding Tegra20 VIP support, move the default format to a
new field in the soc-specific `struct tegra_vi_soc`. Instead of an entire
format struct, only store a pointer to an item in the existing format
array.

No functional changes. The format pointed to is the same that used to be in
vi.c.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c |  2 ++
 drivers/staging/media/tegra-video/vi.c   | 11 +--
 drivers/staging/media/tegra-video/vi.h   |  2 ++
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 71483d0c19bf..28d3d05c12c4 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -771,8 +771,10 @@ const struct tegra_vi_soc tegra210_vi_soc = {
.hw_revision = 3,
.vi_max_channels = 6,
 #if IS_ENABLED(CONFIG_VIDEO_TEGRA_TPG)
+   .default_video_format = _video_formats[0],
.vi_max_clk_hz = 49920,
 #else
+   .default_video_format = _video_formats[4],
.vi_max_clk_hz = 99840,
 #endif
 };
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 12c2fa760c81..8b6cf50e1eae 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -44,15 +44,6 @@ struct tegra_vi_graph_entity {
struct v4l2_subdev *subdev;
 };
 
-static const struct tegra_video_format tegra_default_format = {
-   .img_dt = TEGRA_IMAGE_DT_RAW10,
-   .bit_width = 10,
-   .code = MEDIA_BUS_FMT_SRGGB10_1X10,
-   .bpp = 2,
-   .img_fmt = TEGRA_IMAGE_FORMAT_DEF,
-   .fourcc = V4L2_PIX_FMT_SRGGB10,
-};
-
 static inline struct tegra_vi *
 host1x_client_to_vi(struct host1x_client *client)
 {
@@ -,7 +1102,7 @@ static int tegra_channel_init(struct tegra_vi_channel 
*chan)
init_waitqueue_head(>done_wait);
 
/* initialize the video format */
-   chan->fmtinfo = _default_format;
+   chan->fmtinfo = chan->vi->soc->default_video_format;
chan->format.pixelformat = chan->fmtinfo->fourcc;
chan->format.colorspace = V4L2_COLORSPACE_SRGB;
chan->format.field = V4L2_FIELD_NONE;
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 1021c730b595..879547073371 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -58,6 +58,7 @@ struct tegra_vi_ops {
  *
  * @video_formats: supported video formats
  * @nformats: total video formats
+ * @default_video_format: default video format (pointer to a @video_formats 
item)
  * @ops: vi operations
  * @hw_revision: VI hw_revision
  * @vi_max_channels: supported max streaming channels
@@ -66,6 +67,7 @@ struct tegra_vi_ops {
 struct tegra_vi_soc {
const struct tegra_video_format *video_formats;
const unsigned int nformats;
+   const struct tegra_video_format *default_video_format;
const struct tegra_vi_ops *ops;
u32 hw_revision;
unsigned int vi_max_channels;
-- 
2.34.1



[PATCH v2 19/21] staging: media: tegra-video: add H/V flip controls

2022-11-28 Thread Luca Ceresoli
Tegra20 can do horizontal and vertical image flip, but Tegra210 cannot
(either the hardware, or this driver).

In preparation to adding Tegra20 support, add a flag in struct tegra_vi_soc
so the generic vi.c code knows whether the flip controls should be added or
not.

Also provide a generic implementation that simply sets two flags in the
channel struct. The Tegra20 implementation will enable flipping at stream
start based on those flags.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 14 +-
 drivers/staging/media/tegra-video/vi.h |  8 
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index ebb502a45e96..0dbc3da6f98c 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -29,7 +29,7 @@
 #include "vi.h"
 #include "video.h"
 
-#define MAX_CID_CONTROLS   1
+#define MAX_CID_CONTROLS   3
 
 /**
  * struct tegra_vi_graph_entity - Entity in the video graph
@@ -893,6 +893,12 @@ static int vi_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_TEGRA_SYNCPT_TIMEOUT_RETRY:
chan->syncpt_timeout_retry = ctrl->val;
break;
+   case V4L2_CID_HFLIP:
+   chan->hflip = ctrl->val;
+   break;
+   case V4L2_CID_VFLIP:
+   chan->vflip = ctrl->val;
+   break;
default:
return -EINVAL;
}
@@ -964,6 +970,12 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
v4l2_ctrl_handler_free(>ctrl_handler);
return ret;
}
+
+   if (chan->vi->soc->has_h_v_flip) {
+   v4l2_ctrl_new_std(>ctrl_handler, _ctrl_ops, 
V4L2_CID_HFLIP, 0, 1, 1, 0);
+   v4l2_ctrl_new_std(>ctrl_handler, _ctrl_ops, 
V4L2_CID_VFLIP, 0, 1, 1, 0);
+   }
+
 #endif
 
/* setup the controls */
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index a23ee8800d33..7cb038957f1b 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -74,6 +74,7 @@ struct tegra_vi_ops {
  * @hw_revision: VI hw_revision
  * @vi_max_channels: supported max streaming channels
  * @vi_max_clk_hz: VI clock max frequency
+ * @has_h_v_flip: the chip can do H adn V flip, and the driver implements it
  */
 struct tegra_vi_soc {
const struct tegra_video_format *video_formats;
@@ -83,6 +84,7 @@ struct tegra_vi_soc {
u32 hw_revision;
unsigned int vi_max_channels;
unsigned int vi_max_clk_hz;
+   bool has_h_v_flip:1;
 };
 
 /**
@@ -170,6 +172,9 @@ struct tegra_vi {
  * @syncpt_timeout_retry: syncpt timeout retry count for the capture
  * @pg_mode: test pattern generator mode (disabled/direct/patch)
  * @notifier: V4L2 asynchronous subdevs notifier
+ *
+ * @hflip: Horizontal flip is enabled
+ * @vflip: Vertical flip is enabled
  */
 struct tegra_vi_channel {
struct list_head list;
@@ -219,6 +224,9 @@ struct tegra_vi_channel {
enum tegra_vi_pg_mode pg_mode;
 
struct v4l2_async_notifier notifier;
+
+   bool hflip:1;
+   bool vflip:1;
 };
 
 /**
-- 
2.34.1



[PATCH v2 11/21] staging: media: tegra-video: Kconfig: allow TPG only on Tegra210

2022-11-28 Thread Luca Ceresoli
We are about to add support for the Tegra20 parallel video capture, which
has no TPG. In preparation for that, limit the VIDEO_TEGRA_TPG option to
Tegra210 which is the only implementation currently provided by this
driver.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/media/tegra-video/Kconfig 
b/drivers/staging/media/tegra-video/Kconfig
index df1b2cff2417..c53441822fdf 100644
--- a/drivers/staging/media/tegra-video/Kconfig
+++ b/drivers/staging/media/tegra-video/Kconfig
@@ -15,5 +15,6 @@ config VIDEO_TEGRA
 config VIDEO_TEGRA_TPG
bool "NVIDIA Tegra VI driver TPG mode"
depends on VIDEO_TEGRA
+   depends on ARCH_TEGRA_210_SOC
help
  Say yes here to enable Tegra internal TPG mode
-- 
2.34.1



[PATCH v2 16/21] staging: media: tegra-video: move syncpt init/free to a per-soc op

2022-11-28 Thread Luca Ceresoli
tegra_channel_host1x_syncpt_init() gets the host1x syncpts needed for the
Tegra210 implementation, and tegra_channel_host1x_syncpts_free() puts
them.

Tegra20 needs to get and put a different syncpt. In preparation for adding
Tegra20 support, move these functions to new ops in the soc-specific
`struct tegra_vi_ops` .

No functional changes.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/tegra210.c | 52 
 drivers/staging/media/tegra-video/vi.c   | 52 ++--
 drivers/staging/media/tegra-video/vi.h   |  5 ++
 3 files changed, 60 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/media/tegra-video/tegra210.c 
b/drivers/staging/media/tegra-video/tegra210.c
index 28d3d05c12c4..d47ba79bac75 100644
--- a/drivers/staging/media/tegra-video/tegra210.c
+++ b/drivers/staging/media/tegra-video/tegra210.c
@@ -179,6 +179,56 @@ static u32 vi_csi_read(struct tegra_vi_channel *chan, u8 
portno,
 /*
  * Tegra210 VI channel capture operations
  */
+
+static int tegra210_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
+{
+   struct tegra_vi *vi = chan->vi;
+   unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
+   struct host1x_syncpt *fs_sp;
+   struct host1x_syncpt *mw_sp;
+   int ret, i;
+
+   for (i = 0; i < chan->numgangports; i++) {
+   fs_sp = host1x_syncpt_request(>client, flags);
+   if (!fs_sp) {
+   dev_err(vi->dev, "failed to request frame start 
syncpoint\n");
+   ret = -ENOMEM;
+   goto free_syncpts;
+   }
+
+   mw_sp = host1x_syncpt_request(>client, flags);
+   if (!mw_sp) {
+   dev_err(vi->dev, "failed to request memory ack 
syncpoint\n");
+   host1x_syncpt_put(fs_sp);
+   ret = -ENOMEM;
+   goto free_syncpts;
+   }
+
+   chan->frame_start_sp[i] = fs_sp;
+   chan->mw_ack_sp[i] = mw_sp;
+   spin_lock_init(>sp_incr_lock[i]);
+   }
+
+   return 0;
+
+free_syncpts:
+   for (i = 0; i < chan->numgangports; i++) {
+   host1x_syncpt_put(chan->mw_ack_sp[i]);
+   host1x_syncpt_put(chan->frame_start_sp[i]);
+   }
+   return ret;
+}
+
+static void tegra210_channel_host1x_syncpt_free(struct tegra_vi_channel *chan)
+{
+   int i;
+
+   for (i = 0; i < chan->numgangports; i++) {
+   host1x_syncpt_put(chan->mw_ack_sp[i]);
+   host1x_syncpt_put(chan->frame_start_sp[i]);
+   }
+}
+
 static void tegra210_fmt_align(struct v4l2_pix_format *pix, unsigned int bpp)
 {
unsigned int min_bpl;
@@ -758,6 +808,8 @@ static const struct tegra_video_format 
tegra210_video_formats[] = {
 
 /* Tegra210 VI operations */
 static const struct tegra_vi_ops tegra210_vi_ops = {
+   .channel_host1x_syncpt_init = tegra210_channel_host1x_syncpt_init,
+   .channel_host1x_syncpt_free = tegra210_channel_host1x_syncpt_free,
.vi_fmt_align = tegra210_fmt_align,
.vi_start_streaming = tegra210_vi_start_streaming,
.vi_stop_streaming = tegra210_vi_stop_streaming,
diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index d0c387873d4e..854ffb4b5617 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -973,21 +973,11 @@ static int tegra_channel_setup_ctrl_handler(struct 
tegra_vi_channel *chan)
return 0;
 }
 
-static void tegra_channel_host1x_syncpts_free(struct tegra_vi_channel *chan)
-{
-   int i;
-
-   for (i = 0; i < chan->numgangports; i++) {
-   host1x_syncpt_put(chan->mw_ack_sp[i]);
-   host1x_syncpt_put(chan->frame_start_sp[i]);
-   }
-}
-
 static void tegra_channel_cleanup(struct tegra_vi_channel *chan)
 {
v4l2_ctrl_handler_free(>ctrl_handler);
media_entity_cleanup(>video.entity);
-   tegra_channel_host1x_syncpts_free(chan);
+   chan->vi->ops->channel_host1x_syncpt_free(chan);
mutex_destroy(>video_lock);
 }
 
@@ -1005,42 +995,6 @@ void tegra_channels_cleanup(struct tegra_vi *vi)
}
 }
 
-static int tegra_channel_host1x_syncpt_init(struct tegra_vi_channel *chan)
-{
-   struct tegra_vi *vi = chan->vi;
-   unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
-   struct host1x_syncpt *fs_sp;
-   struct host1x_syncpt *mw_sp;
-   int ret, i;
-
-   for (i = 0; i < chan->numgangports; i++) {
-   fs_sp = host1x_syncpt_request(>client, flags);
-   if (!fs_sp) {
-   dev_err(vi->dev, "failed to request frame start 
syncpoint\n");
-   ret = -ENOMEM;
-   goto free_syncpts;
-   }
-
-   mw_sp = host1x_syncpt_request(>client, flags);
-   if (!mw_sp) {
-   

[PATCH v2 20/21] staging: media: tegra-video: add support for VIP (parallel video input)

2022-11-28 Thread Luca Ceresoli
The VI peripheral of Tegra supports capturing from MIPI CSI-2 or parallel
video (called VIP in the docs). MIPI CSI-2 is already implemented. Add a
VIP implementation.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 MAINTAINERS|   1 +
 drivers/staging/media/tegra-video/Makefile |   1 +
 drivers/staging/media/tegra-video/vip.c| 298 +
 drivers/staging/media/tegra-video/vip.h|  72 +
 4 files changed, 372 insertions(+)
 create mode 100644 drivers/staging/media/tegra-video/vip.c
 create mode 100644 drivers/staging/media/tegra-video/vip.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 0c97ce22735d..1601465e8e31 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20322,6 +20322,7 @@ L:  linux-te...@vger.kernel.org
 S: Maintained
 F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml
 F: Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-vip.yaml
+F: drivers/staging/media/tegra-video/vip.*
 
 TEGRA XUSB PADCTL DRIVER
 M: JC Kuo 
diff --git a/drivers/staging/media/tegra-video/Makefile 
b/drivers/staging/media/tegra-video/Makefile
index dfa2ef8f99ef..3c8ec1bb1f3e 100644
--- a/drivers/staging/media/tegra-video/Makefile
+++ b/drivers/staging/media/tegra-video/Makefile
@@ -2,6 +2,7 @@
 tegra-video-objs := \
video.o \
vi.o \
+   vip.o \
csi.o
 
 tegra-video-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
diff --git a/drivers/staging/media/tegra-video/vip.c 
b/drivers/staging/media/tegra-video/vip.c
new file mode 100644
index ..cbf0c36fb098
--- /dev/null
+++ b/drivers/staging/media/tegra-video/vip.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Parallel video capture module (VIP) for the Tegra VI.
+ *
+ * This file implements the VIP-specific infrastructure.
+ *
+ * Copyright (C) 2022 SKIDATA GmbH
+ * Author: Luca Ceresoli 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "vip.h"
+
+static inline struct tegra_vip *host1x_client_to_vip(struct host1x_client 
*client)
+{
+   return container_of(client, struct tegra_vip, client);
+}
+
+static inline struct tegra_vip_channel *subdev_to_vip_channel(struct 
v4l2_subdev *subdev)
+{
+   return container_of(subdev, struct tegra_vip_channel, subdev);
+}
+
+static inline struct tegra_vip *vip_channel_to_vip(struct tegra_vip_channel 
*chan)
+{
+   return container_of(chan, struct tegra_vip, chan);
+}
+
+/* Find the previous subdev in the pipeline (i.e. the one connected to our 
sink pad) */
+static struct v4l2_subdev *tegra_vip_channel_get_prev_subdev(struct 
tegra_vip_channel *chan)
+{
+   struct media_pad *remote_pad;
+
+   remote_pad = 
media_pad_remote_pad_first(>pads[TEGRA_VIP_PAD_SINK]);
+   if (!remote_pad)
+   return NULL;
+
+   return media_entity_to_v4l2_subdev(remote_pad->entity);
+}
+
+static int tegra_vip_enable_stream(struct v4l2_subdev *subdev)
+{
+   struct tegra_vip_channel *vip_chan = subdev_to_vip_channel(subdev);
+   struct tegra_vip *vip = vip_channel_to_vip(vip_chan);
+   struct v4l2_subdev *prev_subdev = 
tegra_vip_channel_get_prev_subdev(vip_chan);
+   int err;
+
+   err = pm_runtime_resume_and_get(vip->dev);
+   if (err)
+   return dev_err_probe(vip->dev, err, "failed to get runtime 
PM\n");
+
+   err = vip->soc->ops->vip_start_streaming(vip_chan);
+   if (err < 0)
+   goto err_start_streaming;
+
+   err = v4l2_subdev_call(prev_subdev, video, s_stream, true);
+   if (err < 0 && err != -ENOIOCTLCMD)
+   goto err_prev_subdev_start_stream;
+
+   return 0;
+
+err_prev_subdev_start_stream:
+err_start_streaming:
+   pm_runtime_put(vip->dev);
+   return err;
+}
+
+static int tegra_vip_disable_stream(struct v4l2_subdev *subdev)
+{
+   struct tegra_vip_channel *vip_chan = subdev_to_vip_channel(subdev);
+   struct tegra_vip *vip = vip_channel_to_vip(vip_chan);
+   struct v4l2_subdev *prev_subdev = 
tegra_vip_channel_get_prev_subdev(vip_chan);
+
+   v4l2_subdev_call(prev_subdev, video, s_stream, false);
+
+   pm_runtime_put(vip->dev);
+
+   return 0;
+}
+
+static int tegra_vip_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+   int err;
+
+   if (enable)
+   err = tegra_vip_enable_stream(subdev);
+   else
+   err = tegra_vip_disable_stream(subdev);
+
+   return err;
+}
+
+static const struct v4l2_subdev_video_ops tegra_vip_video_ops = {
+   .s_stream = tegra_vip_s_stream,
+};
+
+static const struct v4l2_subdev_ops tegra_vip_ops = {
+   .video  = _vip_video_ops,
+};
+
+static int tegra_vip_channel_of_parse(struct tegra_vip *vip)
+{
+   struct device *dev = vip->dev;
+   struct device_node *node;
+   struct v4l2_fwnode_endpoint v4l2_ep = {
+   .bus_type = 

[PATCH v2 15/21] staging: media: tegra-video: add a per-soc enable/disable op

2022-11-28 Thread Luca Ceresoli
The Tegra20 VI needs an additional operation to enable the VI, add an
operation for that.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 7 +++
 drivers/staging/media/tegra-video/vi.h | 4 
 2 files changed, 11 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 2dd3c6c944a2..d0c387873d4e 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1853,6 +1853,9 @@ static int tegra_vi_probe(struct platform_device *pdev)
vi->client.ops = _client_ops;
vi->client.dev = >dev;
 
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, true);
+
ret = host1x_client_register(>client);
if (ret < 0) {
dev_err(>dev,
@@ -1863,6 +1866,8 @@ static int tegra_vi_probe(struct platform_device *pdev)
return 0;
 
 rpm_disable:
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, false);
pm_runtime_disable(>dev);
return ret;
 }
@@ -1879,6 +1884,8 @@ static int tegra_vi_remove(struct platform_device *pdev)
return err;
}
 
+   if (vi->ops->vi_enable)
+   vi->ops->vi_enable(vi, false);
pm_runtime_disable(>dev);
 
return 0;
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index 879547073371..851c4f3fcb91 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -37,8 +37,11 @@ enum tegra_vi_pg_mode {
TEGRA_VI_PG_PATCH,
 };
 
+struct tegra_vi;
+
 /**
  * struct tegra_vi_ops - Tegra VI operations
+ * @vi_enable: soc-specific operations needed to enable/disable the VI 
peripheral
  * @vi_fmt_align: modify `pix` to fit the hardware alignment
  * requirements and fill image geometry
  * @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
@@ -48,6 +51,7 @@ enum tegra_vi_pg_mode {
  * back any queued buffers.
  */
 struct tegra_vi_ops {
+   int (*vi_enable)(struct tegra_vi *vi, bool on);
void (*vi_fmt_align)(struct v4l2_pix_format *pix, unsigned int bpp);
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
void (*vi_stop_streaming)(struct vb2_queue *vq);
-- 
2.34.1



[PATCH v2 18/21] staging: media: tegra-video: add hooks for planar YUV and H/V flip

2022-11-28 Thread Luca Ceresoli
Tegra20 supports planar YUV422 capture, which can be implemented by writing
U and V base address registers in addition to the "main" base buffer
address register.

It also supports H and V flip, which among others requires to write the
start address (i.e. the 1st offset to write, at the end of the buffer or
line) in more registers for Y and, for planar formats, U and V.

Add minimal hooks in VI to allow per-SoC optional support to those
features:

 - variables in struct tegra_vi for the U and V buffer base offsets
 - variables in struct tegra_vi for the Y, U and V buffer start offsets
 - an optional per-soc VI operation to compute those values on queue setup

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/vi.c |  4 
 drivers/staging/media/tegra-video/vi.h | 14 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 854ffb4b5617..ebb502a45e96 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -92,6 +92,7 @@ tegra_get_format_by_fourcc(struct tegra_vi *vi, u32 fourcc)
 /*
  * videobuf2 queue operations
  */
+
 static int tegra_channel_queue_setup(struct vb2_queue *vq,
 unsigned int *nbuffers,
 unsigned int *nplanes,
@@ -107,6 +108,9 @@ static int tegra_channel_queue_setup(struct vb2_queue *vq,
sizes[0] = chan->format.sizeimage;
alloc_devs[0] = chan->vi->dev;
 
+   if (chan->vi->ops->channel_queue_setup)
+   chan->vi->ops->channel_queue_setup(chan);
+
return 0;
 }
 
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index ba563cd17296..a23ee8800d33 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -47,6 +47,7 @@ struct tegra_vi_channel;
  * @channel_host1x_syncpt_free: free all synchronization points
  * @vi_fmt_align: modify `pix` to fit the hardware alignment
  * requirements and fill image geometry
+ * @channel_queue_setup: additional operations at the end of 
vb2_ops::queue_setup
  * @vi_start_streaming: starts media pipeline, subdevice streaming, sets up
  * VI for capture and runs capture start and capture finish
  * kthreads for capturing frames to buffer and returns them back.
@@ -58,6 +59,7 @@ struct tegra_vi_ops {
int (*channel_host1x_syncpt_init)(struct tegra_vi_channel *chan);
void (*channel_host1x_syncpt_free)(struct tegra_vi_channel *chan);
void (*vi_fmt_align)(struct v4l2_pix_format *pix, unsigned int bpp);
+   void (*channel_queue_setup)(struct tegra_vi_channel *chan);
int (*vi_start_streaming)(struct vb2_queue *vq, u32 count);
void (*vi_stop_streaming)(struct vb2_queue *vq);
 };
@@ -148,6 +150,12 @@ struct tegra_vi {
  * @queue: vb2 buffers queue
  * @sequence: V4L2 buffers sequence number
  *
+ * @addr_offset_u: U plane base address, relative to buffer base address (only 
for planar)
+ * @addr_offset_v: V plane base address, relative to buffer base address (only 
for planar)
+ * @start_offset:   1st Y byte to write, relative to buffer base address (for 
H/V flip)
+ * @start_offset_u: 1st U byte to write, relative to buffer base address (for 
H/V flip)
+ * @start_offset_v: 1st V byte to write, relative to buffer base address (for 
H/V flip)
+ *
  * @capture: list of queued buffers for capture
  * @start_lock: protects the capture queued list
  * @done: list of capture done queued buffers
@@ -188,6 +196,12 @@ struct tegra_vi_channel {
struct vb2_queue queue;
u32 sequence;
 
+   unsigned int addr_offset_u;
+   unsigned int addr_offset_v;
+   unsigned int start_offset;
+   unsigned int start_offset_u;
+   unsigned int start_offset_v;
+
struct list_head capture;
/* protects the capture queued list */
spinlock_t start_lock;
-- 
2.34.1



[PATCH v2 09/21] staging: media: tegra-video: move private struct declaration to C file

2022-11-28 Thread Luca Ceresoli
struct tegra_vi_graph_entity is an internal implementation detail of the VI
module. Move its declaration from vi.h to vi.c.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 13 +
 drivers/staging/media/tegra-video/vi.h | 13 -
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 2657207e5b7d..55a135bef1a9 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -31,6 +31,19 @@
 
 #define MAX_CID_CONTROLS   1
 
+/**
+ * struct tegra_vi_graph_entity - Entity in the video graph
+ *
+ * @asd: subdev asynchronous registration information
+ * @entity: media entity from the corresponding V4L2 subdev
+ * @subdev: V4L2 subdev
+ */
+struct tegra_vi_graph_entity {
+   struct v4l2_async_subdev asd;
+   struct media_entity *entity;
+   struct v4l2_subdev *subdev;
+};
+
 static const struct tegra_video_format tegra_default_format = {
.img_dt = TEGRA_IMAGE_DT_RAW10,
.bit_width = 10,
diff --git a/drivers/staging/media/tegra-video/vi.h 
b/drivers/staging/media/tegra-video/vi.h
index dd35c3ac992b..dfd834a69848 100644
--- a/drivers/staging/media/tegra-video/vi.h
+++ b/drivers/staging/media/tegra-video/vi.h
@@ -98,19 +98,6 @@ struct tegra_vi {
struct list_head vi_chans;
 };
 
-/**
- * struct tegra_vi_graph_entity - Entity in the video graph
- *
- * @asd: subdev asynchronous registration information
- * @entity: media entity from the corresponding V4L2 subdev
- * @subdev: V4L2 subdev
- */
-struct tegra_vi_graph_entity {
-   struct v4l2_async_subdev asd;
-   struct media_entity *entity;
-   struct v4l2_subdev *subdev;
-};
-
 /**
  * struct tegra_vi_channel - Tegra video channel
  *
-- 
2.34.1



[PATCH v2 08/21] staging: media: tegra-video: slightly simplify cleanup on errors

2022-11-28 Thread Luca Ceresoli
of_node_put(node) does nothing if node == NULL, so it can be moved to the
cleanup section at the bottom.

Signed-off-by: Luca Ceresoli 

---

No changes in v2
---
 drivers/staging/media/tegra-video/vi.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/tegra-video/vi.c 
b/drivers/staging/media/tegra-video/vi.c
index 24de4ed1eaf0..2657207e5b7d 100644
--- a/drivers/staging/media/tegra-video/vi.c
+++ b/drivers/staging/media/tegra-video/vi.c
@@ -1263,7 +1263,7 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
struct device_node *node = vi->dev->of_node;
struct device_node *ep = NULL;
struct device_node *ports;
-   struct device_node *port;
+   struct device_node *port = NULL;
unsigned int port_num;
struct device_node *parent;
struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
@@ -1286,7 +1286,6 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
dev_err(vi->dev, "invalid port num %d for %pOF\n",
port_num, port);
ret = -EINVAL;
-   of_node_put(port);
goto cleanup;
}
 
@@ -1309,13 +1308,12 @@ static int tegra_vi_channels_alloc(struct tegra_vi *vi)
 
lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
ret = tegra_vi_channel_alloc(vi, port_num, port, lanes);
-   if (ret < 0) {
-   of_node_put(port);
+   if (ret < 0)
goto cleanup;
-   }
}
 
 cleanup:
+   of_node_put(port);
of_node_put(ports);
return ret;
 }
-- 
2.34.1



  1   2   >