Linux Media Controller development
 help / color / mirror / Atom feed
* Re: [PATCH 4/5] media: dt-bindings: add NXP i.MX95 compatible string
From: Krzysztof Kozlowski @ 2026-04-15  8:10 UTC (permalink / raw)
  To: Guoniu Zhou
  Cc: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li, linux-media, linux-kernel, devicetree,
	imx, linux-arm-kernel, linux-rockchip
In-Reply-To: <20260415-csi2_imx95-v1-4-7d63f3508719@oss.nxp.com>

On Wed, Apr 15, 2026 at 11:46:55AM +0800, Guoniu Zhou wrote:
> The i.MX95 CSI-2 controller is nearly identical to i.MX93, with the
> only difference being the use of IDI (Image Data Interface) instead
> of IPI (Image Pixel Interface). The binding constraints are otherwise
> the same.

Nearly identical with some difference really, really suggests they are
compatible. Express compatibility or explain why they are not compatible
(difference between IDI and IPI unfortunately does not help me).

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH 2/2] dma-fence: Fix potential tracepoint null pointer dereferences
From: Tvrtko Ursulin @ 2026-04-15  7:58 UTC (permalink / raw)
  To: Christian König, dri-devel
  Cc: kernel-dev, Philipp Stanner, Boris Brezillon, linux-media,
	linaro-mm-sig
In-Reply-To: <650e835e-b60d-44fd-b212-47f8a9d18c15@amd.com>


On 14/04/2026 19:30, Christian König wrote:
> On 4/14/26 17:49, Tvrtko Ursulin wrote:
>> Trace_dma_fence_signaled, trace_dma_fence_wait_end and
>> trace_dma_fence_destroy can all currently dereference a null fence->ops
>> pointer after it has been reset on fence signalling.
>>
>> Lets use the safe string getters for most tracepoints to avoid this class
>> of a problem, while for the signal tracepoint we move it to before ops are
>> cleared to avoid losing the driver and timeline name information. Apart
>> from moving it we also need to add a new tracepoint class to bypass the
>> safe name getters since the signaled bit is already set.
>>
>> For dma_fence_init we also need to use the new tracepoint class since the
>> rcu read lock is not held there, and we can do the same for the enable
>> signaling since there we are certain the fence cannot be signaled while
>> we are holding the lock and have even validated the fence->ops.
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
>> Fixes: 541c8f2468b9 ("dma-buf: detach fence ops on signal v3")
>> Cc: Christian König <christian.koenig@amd.com>
>> Cc: Philipp Stanner <phasta@kernel.org>
>> Cc: Boris Brezillon <boris.brezillon@collabora.com>
>> Cc: linux-media@vger.kernel.org
>> Cc: linaro-mm-sig@lists.linaro.org
>> ---
>>   drivers/dma-buf/dma-fence.c      |  3 ++-
>>   include/trace/events/dma_fence.h | 33 ++++++++++++++++++++++++++++----
>>   2 files changed, 31 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
>> index a2aa82f4eedd..b3bfa6943a8e 100644
>> --- a/drivers/dma-buf/dma-fence.c
>> +++ b/drivers/dma-buf/dma-fence.c
>> @@ -363,6 +363,8 @@ void dma_fence_signal_timestamp_locked(struct dma_fence *fence,
>>   				      &fence->flags)))
>>   		return;
>>   
>> +	trace_dma_fence_signaled(fence);
>> +
>>   	/*
>>   	 * When neither a release nor a wait operation is specified set the ops
>>   	 * pointer to NULL to allow the fence structure to become independent
>> @@ -377,7 +379,6 @@ void dma_fence_signal_timestamp_locked(struct dma_fence *fence,
>>   
>>   	fence->timestamp = timestamp;
>>   	set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
>> -	trace_dma_fence_signaled(fence);
> 
> I think this part here should be a separate patch.

I had that in 
https://lore.kernel.org/dri-devel/20260330133623.17704-1-tvrtko.ursulin@igalia.com/ 
but the discussion fizzled out before an rb.

> 
>>   
>>   	list_for_each_entry_safe(cur, tmp, &cb_list, node) {
>>   		INIT_LIST_HEAD(&cur->node);
>> diff --git a/include/trace/events/dma_fence.h b/include/trace/events/dma_fence.h
>> index 3abba45c0601..9e0cb9ce2388 100644
>> --- a/include/trace/events/dma_fence.h
>> +++ b/include/trace/events/dma_fence.h
>> @@ -9,12 +9,37 @@
>>   
>>   struct dma_fence;
>>   
>> +DECLARE_EVENT_CLASS(dma_fence,
>> +
>> +	TP_PROTO(struct dma_fence *fence),
>> +
>> +	TP_ARGS(fence),
>> +
>> +	TP_STRUCT__entry(
>> +		__string(driver, dma_fence_driver_name(fence))
>> +		__string(timeline, dma_fence_timeline_name(fence))
>> +		__field(unsigned int, context)
>> +		__field(unsigned int, seqno)
>> +	),
>> +
>> +	TP_fast_assign(
>> +		__assign_str(driver);
>> +		__assign_str(timeline);
>> +		__entry->context = fence->context;
>> +		__entry->seqno = fence->seqno;
>> +	),
>> +
>> +	TP_printk("driver=%s timeline=%s context=%u seqno=%u",
>> +		  __get_str(driver), __get_str(timeline), __entry->context,
>> +		  __entry->seqno)
>> +);
>> +
> 
> Mhm, I'm strongly in favor to just use this approach for all trace points.
> 
> The minimal extra overhead shouldn't really matter at all.

Yeah, I am a bit on the fence. It would required a bit of an ugly 
rcu_read_lock around trace_dma_fence_signal_init and 
trace_dma_fence_signaled would lose the driver/timeline info _unless_ 
name helpers would also be changed to look at fence->ops instead of "is 
signaled". Those have no memory barriers so not sure I want to think 
about racyness and how to solve it.

Regards,

Tvrtko

> 
> Regards,
> Christian.
> 
>>   /*
>>    * Safe only for call sites which are guaranteed to not race with fence
>>    * signaling,holding the fence->lock and having checked for not signaled, or the
>>    * signaling path itself.
>>    */
>> -DECLARE_EVENT_CLASS(dma_fence,
>> +DECLARE_EVENT_CLASS(dma_fence_ops,
>>   
>>   	TP_PROTO(struct dma_fence *fence),
>>   
>> @@ -46,7 +71,7 @@ DEFINE_EVENT(dma_fence, dma_fence_emit,
>>   	TP_ARGS(fence)
>>   );
>>   
>> -DEFINE_EVENT(dma_fence, dma_fence_init,
>> +DEFINE_EVENT(dma_fence_ops, dma_fence_init,
>>   
>>   	TP_PROTO(struct dma_fence *fence),
>>   
>> @@ -60,14 +85,14 @@ DEFINE_EVENT(dma_fence, dma_fence_destroy,
>>   	TP_ARGS(fence)
>>   );
>>   
>> -DEFINE_EVENT(dma_fence, dma_fence_enable_signal,
>> +DEFINE_EVENT(dma_fence_ops, dma_fence_enable_signal,
>>   
>>   	TP_PROTO(struct dma_fence *fence),
>>   
>>   	TP_ARGS(fence)
>>   );
>>   
>> -DEFINE_EVENT(dma_fence, dma_fence_signaled,
>> +DEFINE_EVENT(dma_fence_ops, dma_fence_signaled,
>>   
>>   	TP_PROTO(struct dma_fence *fence),
>>   
> 


^ permalink raw reply

* Re: [PATCH 15901/15901] drm/vmwgfx: fix NULL pointer dereference in vmw_validation_bo_fence()
From: Christian König @ 2026-04-15  7:56 UTC (permalink / raw)
  To: Zack Rusin
  Cc: popov.nkv, bcm-kernel-feedback-list, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Sumit Semwal, dri-devel, linux-kernel, linux-media, linaro-mm-sig,
	lvc-project, stable, Ian Forbes
In-Reply-To: <CABQX2QMH2XFcuz00DQQWU4uKw2B8OzE4rCE5=8LMXDg4t0AqWQ@mail.gmail.com>

On 4/15/26 03:08, Zack Rusin wrote:
> On Tue, Apr 14, 2026 at 9:25 AM Christian König
> <christian.koenig@amd.com> wrote:
>>
>> On 4/14/26 12:55, popov.nkv@gmail.com wrote:
>>> From: Vladimir Popov <popov.nkv@gmail.com>
>>>
>>> If vmw_execbuf_fence_commands() call fails in
>>> vmw_kms_helper_validation_finish(), it sets *p_fence = NULL. If
>>> ctx->bo_list is not empty, the caller, vmw_kms_helper_validation_finish(),
>>> passes the fence through a chain of functions to dma_fence_is_array(),
>>> which causes a NULL pointer dereference in dma_fence_is_array():
>>>
>>> vmw_kms_helper_validation_finish() // pass NULL fence
>>>   vmw_validation_done()
>>>     vmw_validation_bo_fence()
>>>       ttm_eu_fence_buffer_objects() // pass NULL fence
>>>         dma_resv_add_fence()
>>>           dma_fence_is_container()
>>>             dma_fence_is_array() // NULL deref
>>
>> Well good catch, but that is clearly not the right fix.
>>
>> I'm not an expert for the vmwgfx code but in case of an error vmw_validation_revert() should be called an not vmw_kms_helper_validation_finish().
> 
> To me the patch looks correct. This path is explicitly for submission
> failure and does BO backoff plus vmw_validation_res_unreserve(ctx,
> true). The backoff=true branch skips committing dirty-state /
> backup-MOB changes, which is only correct if commands were not
> committed. Here the commands have already been submitted; only fence
> creation failed. So I think unlocking BO reservations without
> attaching a fence, then letting vmw_validation_done() keep taking the
> success path for resources is correct.

Ah! I would just avoid adding more TTM exec code dependencies.

We also have the always signaled stub fence for such use cases. How about that change here:

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index e1f18020170a..8dcb8cd19e29 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -3843,7 +3843,7 @@ int vmw_execbuf_fence_commands(struct drm_file *file_priv,
        if (unlikely(ret != 0 && !synced)) {
                (void) vmw_fallback_wait(dev_priv, false, false, sequence,
                                         false, VMW_FENCE_WAIT_TIMEOUT);
-               *p_fence = NULL;
+               *p_fence = dma_fence_get_stub();
        }
 
        return ret;

> iirc the same helper is used by execbuf, and the shared-helper fix
> correctly covers both paths so this is probably not only a kms issue.
> 
> Untangling this code would make sense because it's confusing, but
> that's not something I'd expect Vladimir to do :)

Yeah fence memory allocation should definitely be move before submitting the commands.

But that is clearly more work.

Thanks,
Christian.

> 
> z


^ permalink raw reply related

* Re: [PATCH v2 1/2] dt-bindings: media: i2c: Add os02g10 sensor
From: Krzysztof Kozlowski @ 2026-04-15  7:54 UTC (permalink / raw)
  To: Elgin Perumbilly
  Cc: sakari.ailus, tarang.raval, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Hans Verkuil, Hans de Goede,
	Vladimir Zapolskiy, Mehdi Djait, Laurent Pinchart,
	Benjamin Mugnier, Sylvain Petinot, Hardevsinh Palaniya,
	Heimir Thor Sverrisson, Jingjing Xiong, Himanshu Bhavani,
	Svyatoslav Ryhel, linux-media, devicetree, linux-kernel
In-Reply-To: <20260414084952.217215-2-elgin.perumbilly@siliconsignals.io>

On Tue, Apr 14, 2026 at 02:19:44PM +0530, Elgin Perumbilly wrote:
> Add bindings for Omnivision OS02G10 sensor.
> 
> Signed-off-by: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> ---
>  .../bindings/media/i2c/ovti,os02g10.yaml      | 96 +++++++++++++++++++
>  MAINTAINERS                                   |  7 ++
>  2 files changed, 103 insertions(+)

Your changelog in cover letters says nothing changed here, so same
comments as v1. Please go back to v1 and read the feedback carefully.

Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH v5 0/5] media: qcom: camss: Add PIX support for CSID/VFE-340
From: Bryan O'Donoghue @ 2026-04-15  7:52 UTC (permalink / raw)
  To: Loic Poulain, vladimir.zapolskiy
  Cc: linux-media, linux-arm-msm, mchehab, konrad.dybcio,
	dmitry.baryshkov
In-Reply-To: <CAFEp6-1+TeEDodfMM+ZmvGOwxr2sQa5pJ9vuk+h2WWPtkMvVXA@mail.gmail.com>

On 14/04/2026 20:31, Loic Poulain wrote:
> Hi Bryan,
> 
> On Tue, Apr 14, 2026 at 8:52 PM Loic Poulain
> <loic.poulain@oss.qualcomm.com> wrote:
>>
>> Add PIX-path support to the CAMSS pipeline on CSID-340 and VFE-340,
>> allowing frames to be routed to the VFE PIX interface and exposed
>> through PIX output devices such as msm_vfe0_pix.
>>
>> On CM2290/TFE, the PIX interface includes a minimal inline processing
>> engine, which we will be able to leverage later to export statistics
>> needed for proper 3A frame processing. This also fixes the PIX path
>> not being usable on this platform, as PIX routing was previously
>> unsupported, causing frame capture hangs.
> 
> I forgot to mention this series now depends on your CSID/port series:
> https://lore.kernel.org/all/20260407-camss-rdi-fix-v3-0-08f72d1f3442@kernel.org/
Thanks for clarifying, I was trying to work out if the indexing was 
still included.

---
bod

^ permalink raw reply

* Re: [PATCH 05/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
From: Mukesh Ojha @ 2026-04-15  7:41 UTC (permalink / raw)
  To: Vishnu Reddy
  Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
	Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
	Hans Verkuil, linux-media, linux-arm-msm, devicetree,
	linux-kernel, iommu
In-Reply-To: <20260415073605.qqvpf36uhqmghg5h@hu-mojha-hyd.qualcomm.com>

On Wed, Apr 15, 2026 at 01:06:05PM +0530, Mukesh Ojha wrote:
> On Tue, Apr 14, 2026 at 12:01:28PM +0530, Mukesh Ojha wrote:
> > On Tue, Apr 14, 2026 at 10:30:01AM +0530, Vishnu Reddy wrote:
> > > From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > > 
> > > Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> > > or QHEE), which typically handles IOMMU configuration. This includes
> > > mapping memory regions and device memory resources for remote processors
> > > by intercepting qcom_scm_pas_auth_and_reset() calls. These mappings are
> > > later removed during teardown. Additionally, SHM bridge setup is required
> > > to enable memory protection for both remoteproc metadata and its memory
> > > regions.
> > > 
> > > When the hypervisor is absent, the operating system must perform these
> > > configurations instead.
> > > 
> > > Support for handling IOMMU and SHM setup in the absence of a hypervisor
> > > is now in place. Extend the Iris driver to enable this functionality on
> > > platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
> > > 
> > > Additionally, the Iris driver must map the firmware and its required
> > > resources to the firmware SID, which is now specified via iommu-map in
> > > the device tree.
> > > 
> > > Co-developed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > > Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > > Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> > > ---
> > >  drivers/media/platform/qcom/iris/iris_core.h     |  4 ++
> > >  drivers/media/platform/qcom/iris/iris_firmware.c | 71 +++++++++++++++++++++---
> > >  2 files changed, 66 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
> > > index fb194c967ad4..aa7abef6f0e0 100644
> > > --- a/drivers/media/platform/qcom/iris/iris_core.h
> > > +++ b/drivers/media/platform/qcom/iris/iris_core.h
> > > @@ -34,6 +34,8 @@ enum domain_type {
> > >   * struct iris_core - holds core parameters valid for all instances
> > >   *
> > >   * @dev: reference to device structure
> > > + * @dev_fw: reference to the context bank device used for firmware load
> > > + * @ctx_fw: SCM PAS context for authenticated firmware load and shutdown
> > >   * @reg_base: IO memory base address
> > >   * @irq: iris irq
> > >   * @v4l2_dev: a holder for v4l2 device structure
> > > @@ -77,6 +79,8 @@ enum domain_type {
> > >  
> > >  struct iris_core {
> > >  	struct device				*dev;
> > > +	struct device				*dev_fw;
> > > +	struct qcom_scm_pas_context		*ctx_fw;
> > 
> > fw_dev suits better and ctx_fw is always for firmware, maybe pas_ctx is
> > better.
> > 
> > >  	void __iomem				*reg_base;
> > >  	int					irq;
> > >  	struct v4l2_device			v4l2_dev;
> > > diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
> > > index 5f408024e967..93d77996c83f 100644
> > > --- a/drivers/media/platform/qcom/iris/iris_firmware.c
> > > +++ b/drivers/media/platform/qcom/iris/iris_firmware.c
> > > @@ -5,6 +5,7 @@
> > >  
> > >  #include <linux/firmware.h>
> > >  #include <linux/firmware/qcom/qcom_scm.h>
> > > +#include <linux/iommu.h>
> > >  #include <linux/of_address.h>
> > >  #include <linux/of_reserved_mem.h>
> > >  #include <linux/soc/qcom/mdt_loader.h>
> > > @@ -13,12 +14,15 @@
> > >  #include "iris_firmware.h"
> > >  
> > >  #define MAX_FIRMWARE_NAME_SIZE	128
> > > +#define IRIS_FW_START_ADDR	0
> > >  
> > >  static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > >  {
> > > +	struct device *dev = core->dev_fw ? core->dev_fw : core->dev;
> > >  	u32 pas_id = core->iris_platform_data->pas_id;
> > >  	const struct firmware *firmware = NULL;
> > > -	struct device *dev = core->dev;
> > > +	struct qcom_scm_pas_context *ctx_fw;
> > > +	struct iommu_domain *domain;
> > >  	struct resource res;
> > >  	phys_addr_t mem_phys;
> > >  	size_t res_size;
> > > @@ -29,13 +33,17 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > >  	if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
> > >  		return -EINVAL;
> > >  
> > > -	ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);
> > > +	ret = of_reserved_mem_region_to_resource(core->dev->of_node, 0, &res);
> > >  	if (ret)
> > >  		return ret;
> > >  
> > >  	mem_phys = res.start;
> > >  	res_size = resource_size(&res);
> > >  
> > > +	ctx_fw = devm_qcom_scm_pas_context_alloc(dev, pas_id, mem_phys, res_size);
> > > +	if (IS_ERR(ctx_fw))
> > > +		return PTR_ERR(ctx_fw);
> > > +
> > >  	ret = request_firmware(&firmware, fw_name, dev);
> > >  	if (ret)
> > >  		return ret;
> > > @@ -52,9 +60,27 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > >  		goto err_release_fw;
> > >  	}
> > >  
> > > -	ret = qcom_mdt_load(dev, firmware, fw_name,
> > > -			    pas_id, mem_virt, mem_phys, res_size, NULL);
> > > +	ctx_fw->use_tzmem = !!core->dev_fw;
> > > +	ret = qcom_mdt_pas_load(ctx_fw, firmware, fw_name, mem_virt, NULL);
> 
> We need to release the metadata because this is the change compared to
> the previous qcom_mdt_load() API, which silently released DMA memory for
> metadata in the pas_init SCM call for clients that passed metadata ctx
> as NULL. Since with this new API every new client must pass the new pas
> ctx, it cannot be NULL anymore. I intended to document this clearly when
> introducing qcom_mdt_pas_load() API, but I did not do so. but thinking
> it over again, we should not be asking client to release the memory
> which they not allocated, so let me write a patch for this where I
> client like remoteproc explicitly ask or set it if they do not want to
> release this memory as their XPU locked and can only released after auth
> and reset successful.

Just to further clarify, nothing extra related to metadata release need
to done for unaffected client like video who were passing NULL as part
of qcom_mdt_load() earlier., so no changes needed in this patch., I will
basically introduce boolean and set this only for remoteproc clients.


> 
> 
> > > +	if (ret)
> > > +
> > > +	if (ctx_fw->use_tzmem) {
> > > +		domain = iommu_get_domain_for_dev(core->dev_fw);
> > > +		if (!domain) {
> > > +			ret = -ENODEV;
> > > +			goto err_mem_unmap;
> > > +		}
> > > +
> > > +		ret = iommu_map(domain, IRIS_FW_START_ADDR, mem_phys, res_size,
> > > +				IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
> > > +		if (ret)
> > > +			goto err_mem_unmap;
> > > +	}
> > >  
> > > +	core->ctx_fw = ctx_fw;
> > > +
> > > +err_mem_unmap:
> > >  	memunmap(mem_virt);
> > >  err_release_fw:
> > >  	release_firmware(firmware);
> > > @@ -62,6 +88,19 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> > >  	return ret;
> > >  }
> > >  
> > > +static void iris_fw_iommu_unmap(struct iris_core *core)
> > > +{
> > > +	bool use_tzmem = core->ctx_fw->use_tzmem;
> > > +	struct iommu_domain *domain;
> > > +
> > > +	if (!use_tzmem)
> > > +		return;
> > > +
> > > +	domain = iommu_get_domain_for_dev(core->dev_fw);
> > > +	if (domain)
> > > +		iommu_unmap(domain, IRIS_FW_START_ADDR, core->ctx_fw->mem_size);
> > > +}
> > > +
> > >  int iris_fw_load(struct iris_core *core)
> > >  {
> > >  	const struct tz_cp_config *cp_config;
> > > @@ -79,10 +118,10 @@ int iris_fw_load(struct iris_core *core)
> > >  		return -ENOMEM;
> > >  	}
> > >  
> > > -	ret = qcom_scm_pas_auth_and_reset(core->iris_platform_data->pas_id);
> > > +	ret = qcom_scm_pas_prepare_and_auth_reset(core->ctx_fw);
> > >  	if (ret)  {
> > >  		dev_err(core->dev, "auth and reset failed: %d\n", ret);
> > > -		return ret;
> > > +		goto err_unmap;
> > >  	}
> > >  
> > >  	for (i = 0; i < core->iris_platform_data->tz_cp_config_data_size; i++) {
> > > @@ -93,17 +132,31 @@ int iris_fw_load(struct iris_core *core)
> > >  						     cp_config->cp_nonpixel_size);
> > >  		if (ret) {
> > >  			dev_err(core->dev, "qcom_scm_mem_protect_video_var failed: %d\n", ret);
> > > -			qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> > > -			return ret;
> > > +			goto err_pas_shutdown;
> > >  		}
> > >  	}
> > >  
> > > +	return 0;
> > > +
> > > +err_pas_shutdown:
> > > +	qcom_scm_pas_shutdown(core->ctx_fw->pas_id);
> > > +err_unmap:
> > > +	iris_fw_iommu_unmap(core);
> > > +
> > >  	return ret;
> > >  }
> > >  
> > >  int iris_fw_unload(struct iris_core *core)
> > >  {
> > > -	return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> > > +	int ret;
> > > +
> > > +	ret = qcom_scm_pas_shutdown(core->ctx_fw->pas_id);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	iris_fw_iommu_unmap(core);
> > > +
> > > +	return ret;
> > >  }
> > >  
> > >  int iris_set_hw_state(struct iris_core *core, bool resume)
> > > 
> > > -- 
> > > 2.34.1
> > > 
> > 
> > -- 
> > -Mukesh Ojha
> 
> -- 
> -Mukesh Ojha

-- 
-Mukesh Ojha

^ permalink raw reply

* [PATCH v3] media: verisilicon: Create AV1 helper library
From: Benjamin Gaignard @ 2026-04-15  7:38 UTC (permalink / raw)
  To: nicolas.dufresne, p.zabel, mchehab, heiko
  Cc: linux-kernel, linux-media, linux-rockchip, linux-arm-kernel,
	kernel, Benjamin Gaignard

Regroup all none hardware related AV1 functions into a helper library.
The goal is to avoid code duplication for futur AV1 codecs.

Tested on rock 5b board Fluster score remains the same 204/241.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
---
changes in version 3:
 - Remove useless wrapper functions.

 drivers/media/platform/verisilicon/Makefile   |   7 +-
 .../media/platform/verisilicon/hantro_av1.c   | 780 +++++++++++++++
 .../media/platform/verisilicon/hantro_av1.h   |  62 ++
 ...entropymode.c => hantro_av1_entropymode.c} |  18 +-
 ...entropymode.h => hantro_av1_entropymode.h} |  18 +-
 ...av1_filmgrain.c => hantro_av1_filmgrain.c} |  82 +-
 .../verisilicon/hantro_av1_filmgrain.h        |  44 +
 .../media/platform/verisilicon/hantro_hw.h    |   7 +-
 .../verisilicon/rockchip_av1_filmgrain.h      |  36 -
 .../verisilicon/rockchip_vpu981_hw_av1_dec.c  | 935 ++----------------
 .../platform/verisilicon/rockchip_vpu_hw.c    |   7 +-
 11 files changed, 1041 insertions(+), 955 deletions(-)
 create mode 100644 drivers/media/platform/verisilicon/hantro_av1.c
 create mode 100644 drivers/media/platform/verisilicon/hantro_av1.h
 rename drivers/media/platform/verisilicon/{rockchip_av1_entropymode.c => hantro_av1_entropymode.c} (99%)
 rename drivers/media/platform/verisilicon/{rockchip_av1_entropymode.h => hantro_av1_entropymode.h} (95%)
 rename drivers/media/platform/verisilicon/{rockchip_av1_filmgrain.c => hantro_av1_filmgrain.c} (92%)
 create mode 100644 drivers/media/platform/verisilicon/hantro_av1_filmgrain.h
 delete mode 100644 drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h

diff --git a/drivers/media/platform/verisilicon/Makefile b/drivers/media/platform/verisilicon/Makefile
index f6f019d04ff0..a1dd6c2d29be 100644
--- a/drivers/media/platform/verisilicon/Makefile
+++ b/drivers/media/platform/verisilicon/Makefile
@@ -19,7 +19,10 @@ hantro-vpu-y += \
 		hantro_hevc.o \
 		hantro_mpeg2.o \
 		hantro_vp8.o \
-		hantro_vp9.o
+		hantro_vp9.o \
+		hantro_av1.o \
+		hantro_av1_filmgrain.o \
+		hantro_av1_entropymode.o
 
 hantro-vpu-$(CONFIG_VIDEO_HANTRO_IMX8M) += \
 		imx8m_vpu_hw.o
@@ -33,8 +36,6 @@ hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \
 		rockchip_vpu2_hw_mpeg2_dec.o \
 		rockchip_vpu2_hw_vp8_dec.o \
 		rockchip_vpu981_hw_av1_dec.o \
-		rockchip_av1_filmgrain.o \
-		rockchip_av1_entropymode.o \
 		rockchip_vpu_hw.o
 
 hantro-vpu-$(CONFIG_VIDEO_HANTRO_SUNXI) += \
diff --git a/drivers/media/platform/verisilicon/hantro_av1.c b/drivers/media/platform/verisilicon/hantro_av1.c
new file mode 100644
index 000000000000..5a51ac877c9c
--- /dev/null
+++ b/drivers/media/platform/verisilicon/hantro_av1.c
@@ -0,0 +1,780 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026, Collabora
+ *
+ * Author: Benjamin Gaignard <benjamin.gaignard@collabora.com>
+ */
+
+#include <linux/types.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+
+#include "hantro.h"
+#include "hantro_av1.h"
+#include "hantro_hw.h"
+
+#define GM_GLOBAL_MODELS_PER_FRAME	7
+#define GLOBAL_MODEL_TOTAL_SIZE	(6 * 4 + 4 * 2)
+#define GLOBAL_MODEL_SIZE	ALIGN(GM_GLOBAL_MODELS_PER_FRAME * GLOBAL_MODEL_TOTAL_SIZE, 2048)
+#define AV1_MAX_TILES		128
+#define AV1_TILE_INFO_SIZE	(AV1_MAX_TILES * 16)
+#define AV1_INVALID_IDX		-1
+#define AV1_TILE_SIZE		ALIGN(32 * 128, 4096)
+
+#define SUPERRES_SCALE_BITS 3
+
+#define DIV_LUT_PREC_BITS 14
+#define DIV_LUT_BITS 8
+#define DIV_LUT_NUM BIT(DIV_LUT_BITS)
+#define WARP_PARAM_REDUCE_BITS 6
+#define WARPEDMODEL_PREC_BITS 16
+
+#define AV1_DIV_ROUND_UP_POW2(value, n)			\
+({							\
+	typeof(n) _n  = n;				\
+	typeof(value) _value = value;			\
+	(_value + (BIT(_n) >> 1)) >> _n;		\
+})
+
+#define AV1_DIV_ROUND_UP_POW2_SIGNED(value, n)				\
+({									\
+	typeof(n) _n_  = n;						\
+	typeof(value) _value_ = value;					\
+	(((_value_) < 0) ? -AV1_DIV_ROUND_UP_POW2(-(_value_), (_n_))	\
+		: AV1_DIV_ROUND_UP_POW2((_value_), (_n_)));		\
+})
+
+static const short div_lut[DIV_LUT_NUM + 1] = {
+	16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768,
+	15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 15142,
+	15087, 15033, 14980, 14926, 14873, 14821, 14769, 14717, 14665, 14614, 14564,
+	14513, 14463, 14413, 14364, 14315, 14266, 14218, 14170, 14122, 14075, 14028,
+	13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662, 13618, 13574, 13530,
+	13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, 13107, 13066,
+	13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, 12672, 12633,
+	12596, 12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, 12264, 12228,
+	12193, 12157, 12122, 12087, 12053, 12018, 11984, 11950, 11916, 11882, 11848,
+	11815, 11782, 11749, 11716, 11683, 11651, 11619, 11586, 11555, 11523, 11491,
+	11460, 11429, 11398, 11367, 11336, 11305, 11275, 11245, 11215, 11185, 11155,
+	11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894, 10866, 10838,
+	10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, 10565, 10538,
+	10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, 10280, 10255,
+	10230, 10205, 10180, 10156, 10131, 10107, 10082, 10058, 10034, 10010, 9986,
+	9963,  9939,  9916,  9892,  9869,  9846,  9823,  9800,  9777,  9754,  9732,
+	9709,  9687,  9664,  9642,  9620,  9598,  9576,  9554,  9533,  9511,  9489,
+	9468,  9447,  9425,  9404,  9383,  9362,  9341,  9321,  9300,  9279,  9259,
+	9239,  9218,  9198,  9178,  9158,  9138,  9118,  9098,  9079,  9059,  9039,
+	9020,  9001,  8981,  8962,  8943,  8924,  8905,  8886,  8867,  8849,  8830,
+	8812,  8793,  8775,  8756,  8738,  8720,  8702,  8684,  8666,  8648,  8630,
+	8613,  8595,  8577,  8560,  8542,  8525,  8508,  8490,  8473,  8456,  8439,
+	8422,  8405,  8389,  8372,  8355,  8339,  8322,  8306,  8289,  8273,  8257,
+	8240,  8224,  8208,  8192,
+};
+
+enum hantro_av1_tx_mode {
+	HANTRO_AV1_TX_MODE_ONLY_4X4	= 0,
+	HANTRO_AV1_TX_MODE_8X8		= 1,
+	HANTRO_AV1_TX_MODE_16x16	= 2,
+	HANTRO_AV1_TX_MODE_32x32	= 3,
+	HANTRO_AV1_TX_MODE_SELECT	= 4,
+};
+
+enum hantro_av1_inter_prediction_filter_type {
+	HANTRO_AV1_EIGHT_TAP_SMOOTH	= 0,
+	HANTRO_AV1_EIGHT_TAP		= 1,
+	HANTRO_AV1_EIGHT_TAP_SHARP	= 2,
+	HANTRO_AV1_BILINEAR		= 3,
+	HANTRO_AV1_SWITCHABLE		= 4,
+};
+
+int hantro_av1_get_hardware_tx_mode(enum v4l2_av1_tx_mode tx_mode)
+{
+	switch (tx_mode) {
+	case V4L2_AV1_TX_MODE_ONLY_4X4:
+		return HANTRO_AV1_TX_MODE_ONLY_4X4;
+	case V4L2_AV1_TX_MODE_LARGEST:
+		return HANTRO_AV1_TX_MODE_32x32;
+	case V4L2_AV1_TX_MODE_SELECT:
+		return HANTRO_AV1_TX_MODE_SELECT;
+	}
+
+	return HANTRO_AV1_TX_MODE_32x32;
+}
+
+int hantro_av1_get_hardware_mcomp_filt_type(int interpolation_filter)
+{
+	switch (interpolation_filter) {
+	case V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP:
+		return HANTRO_AV1_EIGHT_TAP;
+	case V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH:
+		return HANTRO_AV1_EIGHT_TAP_SMOOTH;
+	case V4L2_AV1_INTERPOLATION_FILTER_EIGHTTAP_SHARP:
+		return HANTRO_AV1_EIGHT_TAP_SHARP;
+	case V4L2_AV1_INTERPOLATION_FILTER_BILINEAR:
+		return HANTRO_AV1_BILINEAR;
+	case V4L2_AV1_INTERPOLATION_FILTER_SWITCHABLE:
+		return HANTRO_AV1_SWITCHABLE;
+	}
+
+	return HANTRO_AV1_EIGHT_TAP_SMOOTH;
+}
+
+int hantro_av1_get_frame_index(struct hantro_ctx *ctx, int ref)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
+	u64 timestamp;
+	int i, idx = frame->ref_frame_idx[ref];
+
+	if (idx >= V4L2_AV1_TOTAL_REFS_PER_FRAME || idx < 0)
+		return AV1_INVALID_IDX;
+
+	timestamp = frame->reference_frame_ts[idx];
+	for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) {
+		if (!av1_dec->frame_refs[i].used)
+			continue;
+		if (av1_dec->frame_refs[i].timestamp == timestamp)
+			return i;
+	}
+
+	return AV1_INVALID_IDX;
+}
+
+int hantro_av1_get_order_hint(struct hantro_ctx *ctx, int ref)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	int idx = hantro_av1_get_frame_index(ctx, ref);
+
+	if (idx != AV1_INVALID_IDX)
+		return av1_dec->frame_refs[idx].order_hint;
+
+	return 0;
+}
+
+int hantro_av1_frame_ref(struct hantro_ctx *ctx, u64 timestamp)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
+	int i;
+
+	for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) {
+		int j;
+
+		if (av1_dec->frame_refs[i].used)
+			continue;
+
+		av1_dec->frame_refs[i].width = frame->frame_width_minus_1 + 1;
+		av1_dec->frame_refs[i].height = frame->frame_height_minus_1 + 1;
+		av1_dec->frame_refs[i].mi_cols = DIV_ROUND_UP(frame->frame_width_minus_1 + 1, 8);
+		av1_dec->frame_refs[i].mi_rows = DIV_ROUND_UP(frame->frame_height_minus_1 + 1, 8);
+		av1_dec->frame_refs[i].timestamp = timestamp;
+		av1_dec->frame_refs[i].frame_type = frame->frame_type;
+		av1_dec->frame_refs[i].order_hint = frame->order_hint;
+		av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx);
+
+		for (j = 0; j < V4L2_AV1_TOTAL_REFS_PER_FRAME; j++)
+			av1_dec->frame_refs[i].order_hints[j] = frame->order_hints[j];
+		av1_dec->frame_refs[i].used = true;
+		av1_dec->current_frame_index = i;
+
+		return i;
+	}
+
+	return AV1_INVALID_IDX;
+}
+
+static void hantro_av1_frame_unref(struct hantro_ctx *ctx, int idx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+
+	if (idx >= 0)
+		av1_dec->frame_refs[idx].used = false;
+}
+
+void hantro_av1_clean_refs(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+
+	int ref, idx;
+
+	for (idx = 0; idx < AV1_MAX_FRAME_BUF_COUNT; idx++) {
+		u64 timestamp = av1_dec->frame_refs[idx].timestamp;
+		bool used = false;
+
+		if (!av1_dec->frame_refs[idx].used)
+			continue;
+
+		for (ref = 0; ref < V4L2_AV1_TOTAL_REFS_PER_FRAME; ref++) {
+			if (ctrls->frame->reference_frame_ts[ref] == timestamp)
+				used = true;
+		}
+
+		if (!used)
+			hantro_av1_frame_unref(ctx, idx);
+	}
+}
+
+size_t hantro_av1_luma_size(struct hantro_ctx *ctx)
+{
+	return ctx->ref_fmt.plane_fmt[0].bytesperline * ctx->ref_fmt.height;
+}
+
+size_t hantro_av1_chroma_size(struct hantro_ctx *ctx)
+{
+	size_t cr_offset = hantro_av1_luma_size(ctx);
+
+	return ALIGN((cr_offset * 3) / 2, 64);
+}
+
+static void hantro_av1_tiles_free(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+
+	if (av1_dec->db_data_col.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->db_data_col.size,
+				  av1_dec->db_data_col.cpu,
+				  av1_dec->db_data_col.dma);
+	av1_dec->db_data_col.cpu = NULL;
+
+	if (av1_dec->db_ctrl_col.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->db_ctrl_col.size,
+				  av1_dec->db_ctrl_col.cpu,
+				  av1_dec->db_ctrl_col.dma);
+	av1_dec->db_ctrl_col.cpu = NULL;
+
+	if (av1_dec->cdef_col.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->cdef_col.size,
+				  av1_dec->cdef_col.cpu, av1_dec->cdef_col.dma);
+	av1_dec->cdef_col.cpu = NULL;
+
+	if (av1_dec->sr_col.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->sr_col.size,
+				  av1_dec->sr_col.cpu, av1_dec->sr_col.dma);
+	av1_dec->sr_col.cpu = NULL;
+
+	if (av1_dec->lr_col.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->lr_col.size,
+				  av1_dec->lr_col.cpu, av1_dec->lr_col.dma);
+	av1_dec->lr_col.cpu = NULL;
+}
+
+static int hantro_av1_tiles_reallocate(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info;
+	unsigned int num_tile_cols = tile_info->tile_cols;
+	unsigned int height = ALIGN(ctrls->frame->frame_height_minus_1 + 1, 64);
+	unsigned int height_in_sb = height / 64;
+	unsigned int stripe_num = ((height + 8) + 63) / 64;
+	size_t size;
+
+	if (av1_dec->db_data_col.size >=
+	    ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols)
+		return 0;
+
+	hantro_av1_tiles_free(ctx);
+
+	size = ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols;
+	av1_dec->db_data_col.cpu = dma_alloc_coherent(vpu->dev, size,
+						      &av1_dec->db_data_col.dma,
+						      GFP_KERNEL);
+	if (!av1_dec->db_data_col.cpu)
+		goto buffer_allocation_error;
+	av1_dec->db_data_col.size = size;
+
+	size = ALIGN(height * 2 * 16 / 4, 128) * num_tile_cols;
+	av1_dec->db_ctrl_col.cpu = dma_alloc_coherent(vpu->dev, size,
+						      &av1_dec->db_ctrl_col.dma,
+						      GFP_KERNEL);
+	if (!av1_dec->db_ctrl_col.cpu)
+		goto buffer_allocation_error;
+	av1_dec->db_ctrl_col.size = size;
+
+	size = ALIGN(height_in_sb * 44 * ctx->bit_depth * 16 / 8, 128) * num_tile_cols;
+	av1_dec->cdef_col.cpu = dma_alloc_coherent(vpu->dev, size,
+						   &av1_dec->cdef_col.dma,
+						   GFP_KERNEL);
+	if (!av1_dec->cdef_col.cpu)
+		goto buffer_allocation_error;
+	av1_dec->cdef_col.size = size;
+
+	size = ALIGN(height_in_sb * (3040 + 1280), 128) * num_tile_cols;
+	av1_dec->sr_col.cpu = dma_alloc_coherent(vpu->dev, size,
+						 &av1_dec->sr_col.dma,
+						 GFP_KERNEL);
+	if (!av1_dec->sr_col.cpu)
+		goto buffer_allocation_error;
+	av1_dec->sr_col.size = size;
+
+	size = ALIGN(stripe_num * 1536 * ctx->bit_depth / 8, 128) * num_tile_cols;
+	av1_dec->lr_col.cpu = dma_alloc_coherent(vpu->dev, size,
+						 &av1_dec->lr_col.dma,
+						 GFP_KERNEL);
+	if (!av1_dec->lr_col.cpu)
+		goto buffer_allocation_error;
+	av1_dec->lr_col.size = size;
+
+	av1_dec->num_tile_cols_allocated = num_tile_cols;
+	return 0;
+
+buffer_allocation_error:
+	hantro_av1_tiles_free(ctx);
+	return -ENOMEM;
+}
+
+void hantro_av1_exit(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+
+	if (av1_dec->global_model.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->global_model.size,
+				  av1_dec->global_model.cpu,
+				  av1_dec->global_model.dma);
+	av1_dec->global_model.cpu = NULL;
+
+	if (av1_dec->tile_info.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->tile_info.size,
+				  av1_dec->tile_info.cpu,
+				  av1_dec->tile_info.dma);
+	av1_dec->tile_info.cpu = NULL;
+
+	if (av1_dec->film_grain.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->film_grain.size,
+				  av1_dec->film_grain.cpu,
+				  av1_dec->film_grain.dma);
+	av1_dec->film_grain.cpu = NULL;
+
+	if (av1_dec->prob_tbl.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->prob_tbl.size,
+				  av1_dec->prob_tbl.cpu, av1_dec->prob_tbl.dma);
+	av1_dec->prob_tbl.cpu = NULL;
+
+	if (av1_dec->prob_tbl_out.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->prob_tbl_out.size,
+				  av1_dec->prob_tbl_out.cpu,
+				  av1_dec->prob_tbl_out.dma);
+	av1_dec->prob_tbl_out.cpu = NULL;
+
+	if (av1_dec->tile_buf.cpu)
+		dma_free_coherent(vpu->dev, av1_dec->tile_buf.size,
+				  av1_dec->tile_buf.cpu, av1_dec->tile_buf.dma);
+	av1_dec->tile_buf.cpu = NULL;
+
+	hantro_av1_tiles_free(ctx);
+}
+
+int hantro_av1_init(struct hantro_ctx *ctx)
+{
+	struct hantro_dev *vpu = ctx->dev;
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+
+	memset(av1_dec, 0, sizeof(*av1_dec));
+
+	av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, GLOBAL_MODEL_SIZE,
+						       &av1_dec->global_model.dma,
+						       GFP_KERNEL);
+	if (!av1_dec->global_model.cpu)
+		return -ENOMEM;
+	av1_dec->global_model.size = GLOBAL_MODEL_SIZE;
+
+	av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, AV1_TILE_INFO_SIZE,
+						    &av1_dec->tile_info.dma,
+						    GFP_KERNEL);
+	if (!av1_dec->tile_info.cpu)
+		return -ENOMEM;
+	av1_dec->tile_info.size = AV1_TILE_INFO_SIZE;
+
+	av1_dec->film_grain.cpu = dma_alloc_coherent(vpu->dev,
+						     ALIGN(sizeof(struct hantro_av1_film_grain), 2048),
+						     &av1_dec->film_grain.dma,
+						     GFP_KERNEL);
+	if (!av1_dec->film_grain.cpu)
+		return -ENOMEM;
+	av1_dec->film_grain.size = ALIGN(sizeof(struct hantro_av1_film_grain), 2048);
+
+	av1_dec->prob_tbl.cpu = dma_alloc_coherent(vpu->dev,
+						   ALIGN(sizeof(struct av1cdfs), 2048),
+						   &av1_dec->prob_tbl.dma,
+						   GFP_KERNEL);
+	if (!av1_dec->prob_tbl.cpu)
+		return -ENOMEM;
+	av1_dec->prob_tbl.size = ALIGN(sizeof(struct av1cdfs), 2048);
+
+	av1_dec->prob_tbl_out.cpu = dma_alloc_coherent(vpu->dev,
+						       ALIGN(sizeof(struct av1cdfs), 2048),
+						       &av1_dec->prob_tbl_out.dma,
+						       GFP_KERNEL);
+	if (!av1_dec->prob_tbl_out.cpu)
+		return -ENOMEM;
+	av1_dec->prob_tbl_out.size = ALIGN(sizeof(struct av1cdfs), 2048);
+	av1_dec->cdfs = &av1_dec->default_cdfs;
+	av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc;
+
+	hantro_av1_set_default_cdfs(av1_dec->cdfs, av1_dec->cdfs_ndvc);
+
+	av1_dec->tile_buf.cpu = dma_alloc_coherent(vpu->dev,
+						   AV1_TILE_SIZE,
+						   &av1_dec->tile_buf.dma,
+						   GFP_KERNEL);
+	if (!av1_dec->tile_buf.cpu)
+		return -ENOMEM;
+	av1_dec->tile_buf.size = AV1_TILE_SIZE;
+
+	return 0;
+}
+
+int hantro_av1_prepare_run(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+
+	ctrls->sequence = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_SEQUENCE);
+	if (WARN_ON(!ctrls->sequence))
+		return -EINVAL;
+
+	ctrls->tile_group_entry =
+	    hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY);
+	if (WARN_ON(!ctrls->tile_group_entry))
+		return -EINVAL;
+
+	ctrls->frame = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FRAME);
+	if (WARN_ON(!ctrls->frame))
+		return -EINVAL;
+
+	ctrls->film_grain =
+	    hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FILM_GRAIN);
+
+	return hantro_av1_tiles_reallocate(ctx);
+}
+
+static int hantro_av1_get_msb(u32 n)
+{
+	if (n == 0)
+		return 0;
+	return 31 ^ __builtin_clz(n);
+}
+
+static short hantro_av1_resolve_divisor_32(u32 d, short *shift)
+{
+	int f;
+	u64 e;
+
+	*shift = hantro_av1_get_msb(d);
+	/* e is obtained from D after resetting the most significant 1 bit. */
+	e = d - ((u32)1 << *shift);
+	/* Get the most significant DIV_LUT_BITS (8) bits of e into f */
+	if (*shift > DIV_LUT_BITS)
+		f = AV1_DIV_ROUND_UP_POW2(e, *shift - DIV_LUT_BITS);
+	else
+		f = e << (DIV_LUT_BITS - *shift);
+	if (f > DIV_LUT_NUM)
+		return -1;
+	*shift += DIV_LUT_PREC_BITS;
+	/* Use f as lookup into the precomputed table of multipliers */
+	return div_lut[f];
+}
+
+static void hantro_av1_get_shear_params(const u32 *params, s64 *alpha,
+					s64 *beta, s64 *gamma, s64 *delta)
+{
+	const int *mat = params;
+	short shift;
+	short y;
+	long long gv, dv;
+
+	if (mat[2] <= 0)
+		return;
+
+	*alpha = clamp_val(mat[2] - (1 << WARPEDMODEL_PREC_BITS), S16_MIN, S16_MAX);
+	*beta = clamp_val(mat[3], S16_MIN, S16_MAX);
+
+	y = hantro_av1_resolve_divisor_32(abs(mat[2]), &shift) * (mat[2] < 0 ? -1 : 1);
+
+	gv = ((long long)mat[4] * (1 << WARPEDMODEL_PREC_BITS)) * y;
+
+	*gamma = clamp_val((int)AV1_DIV_ROUND_UP_POW2_SIGNED(gv, shift), S16_MIN, S16_MAX);
+
+	dv = ((long long)mat[3] * mat[4]) * y;
+	*delta = clamp_val(mat[5] -
+		(int)AV1_DIV_ROUND_UP_POW2_SIGNED(dv, shift) - (1 << WARPEDMODEL_PREC_BITS),
+		S16_MIN, S16_MAX);
+
+	*alpha = AV1_DIV_ROUND_UP_POW2_SIGNED(*alpha, WARP_PARAM_REDUCE_BITS)
+		 * (1 << WARP_PARAM_REDUCE_BITS);
+	*beta = AV1_DIV_ROUND_UP_POW2_SIGNED(*beta, WARP_PARAM_REDUCE_BITS)
+		* (1 << WARP_PARAM_REDUCE_BITS);
+	*gamma = AV1_DIV_ROUND_UP_POW2_SIGNED(*gamma, WARP_PARAM_REDUCE_BITS)
+		 * (1 << WARP_PARAM_REDUCE_BITS);
+	*delta = AV1_DIV_ROUND_UP_POW2_SIGNED(*delta, WARP_PARAM_REDUCE_BITS)
+		* (1 << WARP_PARAM_REDUCE_BITS);
+}
+
+void hantro_av1_set_global_model(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
+	const struct v4l2_av1_global_motion *gm = &frame->global_motion;
+	u8 *dst = av1_dec->global_model.cpu;
+	int ref_frame, i;
+
+	memset(dst, 0, GLOBAL_MODEL_SIZE);
+	for (ref_frame = 0; ref_frame < V4L2_AV1_REFS_PER_FRAME; ++ref_frame) {
+		s64 alpha = 0, beta = 0, gamma = 0, delta = 0;
+
+		for (i = 0; i < 6; ++i) {
+			if (i == 2)
+				*(s32 *)dst =
+					gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][3];
+			else if (i == 3)
+				*(s32 *)dst =
+					gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][2];
+			else
+				*(s32 *)dst =
+					gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][i];
+			dst += 4;
+		}
+
+		if (gm->type[V4L2_AV1_REF_LAST_FRAME + ref_frame] <= V4L2_AV1_WARP_MODEL_AFFINE)
+			hantro_av1_get_shear_params(&gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][0],
+						    &alpha, &beta, &gamma, &delta);
+
+		*(s16 *)dst = alpha;
+		dst += 2;
+		*(s16 *)dst = beta;
+		dst += 2;
+		*(s16 *)dst = gamma;
+		dst += 2;
+		*(s16 *)dst = delta;
+		dst += 2;
+	}
+}
+
+int hantro_av1_tile_log2(int target)
+{
+	int k;
+
+	/*
+	 * returns the smallest value for k such that 1 << k is greater
+	 * than or equal to target
+	 */
+	for (k = 0; (1 << k) < target; k++);
+
+	return k;
+}
+
+int hantro_av1_get_dist(struct hantro_ctx *ctx, int a, int b)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	int bits = ctrls->sequence->order_hint_bits - 1;
+	int diff, m;
+
+	if (!ctrls->sequence->order_hint_bits)
+		return 0;
+
+	diff = a - b;
+	m = 1 << bits;
+	diff = (diff & (m - 1)) - (diff & m);
+
+	return diff;
+}
+
+void hantro_av1_set_frame_sign_bias(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
+	const struct v4l2_ctrl_av1_sequence *sequence = ctrls->sequence;
+	int i;
+
+	if (!sequence->order_hint_bits || IS_INTRA(frame->frame_type)) {
+		for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME; i++)
+			av1_dec->ref_frame_sign_bias[i] = 0;
+
+		return;
+	}
+	// Identify the nearest forward and backward references.
+	for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME - 1; i++) {
+		if (hantro_av1_get_frame_index(ctx, i) >= 0) {
+			int rel_off =
+			    hantro_av1_get_dist(ctx,
+						hantro_av1_get_order_hint(ctx, i),
+						frame->order_hint);
+			av1_dec->ref_frame_sign_bias[i + 1] = (rel_off <= 0) ? 0 : 1;
+		}
+	}
+}
+
+void hantro_av1_init_scaling_function(const u8 *values, const u8 *scaling,
+				      u8 num_points, u8 *scaling_lut)
+{
+	int i, point;
+
+	if (num_points == 0) {
+		memset(scaling_lut, 0, 256);
+		return;
+	}
+
+	for (point = 0; point < num_points - 1; point++) {
+		int x;
+		s32 delta_y = scaling[point + 1] - scaling[point];
+		s32 delta_x = values[point + 1] - values[point];
+		s64 delta =
+		    delta_x ? delta_y * ((65536 + (delta_x >> 1)) /
+					 delta_x) : 0;
+
+		for (x = 0; x < delta_x; x++) {
+			scaling_lut[values[point] + x] =
+			    scaling[point] +
+			    (s32)((x * delta + 32768) >> 16);
+		}
+	}
+
+	for (i = values[num_points - 1]; i < 256; i++)
+		scaling_lut[i] = scaling[num_points - 1];
+}
+
+void hantro_av1_set_tile_info(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info;
+	const struct v4l2_ctrl_av1_tile_group_entry *group_entry =
+	    ctrls->tile_group_entry;
+	u8 *dst = av1_dec->tile_info.cpu;
+	int tile0, tile1;
+
+	memset(dst, 0, av1_dec->tile_info.size);
+
+	for (tile0 = 0; tile0 < tile_info->tile_cols; tile0++) {
+		for (tile1 = 0; tile1 < tile_info->tile_rows; tile1++) {
+			int tile_id = tile1 * tile_info->tile_cols + tile0;
+			u32 start, end;
+			u32 y0 =
+			    tile_info->height_in_sbs_minus_1[tile1] + 1;
+			u32 x0 = tile_info->width_in_sbs_minus_1[tile0] + 1;
+
+			/* tile size in SB units (width,height) */
+			*dst++ = x0;
+			*dst++ = 0;
+			*dst++ = 0;
+			*dst++ = 0;
+			*dst++ = y0;
+			*dst++ = 0;
+			*dst++ = 0;
+			*dst++ = 0;
+
+			/* tile start position */
+			start = group_entry[tile_id].tile_offset - group_entry[0].tile_offset;
+			*dst++ = start & 255;
+			*dst++ = (start >> 8) & 255;
+			*dst++ = (start >> 16) & 255;
+			*dst++ = (start >> 24) & 255;
+
+			/* number of bytes in tile data */
+			end = start + group_entry[tile_id].tile_size;
+			*dst++ = end & 255;
+			*dst++ = (end >> 8) & 255;
+			*dst++ = (end >> 16) & 255;
+			*dst++ = (end >> 24) & 255;
+		}
+	}
+}
+
+bool hantro_av1_is_lossless(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
+	const struct v4l2_av1_segmentation *segmentation = &frame->segmentation;
+	const struct v4l2_av1_quantization *quantization = &frame->quantization;
+	int i;
+
+	for (i = 0; i < V4L2_AV1_MAX_SEGMENTS; i++) {
+		int qindex = quantization->base_q_idx;
+
+		if (segmentation->feature_enabled[i] &
+		    V4L2_AV1_SEGMENT_FEATURE_ENABLED(V4L2_AV1_SEG_LVL_ALT_Q)) {
+			qindex += segmentation->feature_data[i][V4L2_AV1_SEG_LVL_ALT_Q];
+		}
+		qindex = clamp(qindex, 0, 255);
+
+		if (qindex ||
+		    quantization->delta_q_y_dc ||
+		    quantization->delta_q_u_dc ||
+		    quantization->delta_q_u_ac ||
+		    quantization->delta_q_v_dc ||
+		    quantization->delta_q_v_ac)
+			return false;
+	}
+
+	return true;
+}
+
+void hantro_av1_update_prob(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
+	bool frame_is_intra = IS_INTRA(frame->frame_type);
+	struct av1cdfs *out_cdfs = (struct av1cdfs *)av1_dec->prob_tbl_out.cpu;
+	int i;
+
+	if (frame->flags & V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF)
+		return;
+
+	for (i = 0; i < NUM_REF_FRAMES; i++) {
+		if (frame->refresh_frame_flags & BIT(i)) {
+			struct mvcdfs stored_mv_cdf;
+
+			hantro_av1_get_cdfs(ctx, i);
+			stored_mv_cdf = av1_dec->cdfs->mv_cdf;
+			*av1_dec->cdfs = *out_cdfs;
+			if (frame_is_intra) {
+				av1_dec->cdfs->mv_cdf = stored_mv_cdf;
+				*av1_dec->cdfs_ndvc = out_cdfs->mv_cdf;
+			}
+			hantro_av1_store_cdfs(ctx, frame->refresh_frame_flags);
+			break;
+		}
+	}
+}
+
+void hantro_av1_set_prob(struct hantro_ctx *ctx)
+{
+	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
+	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
+	const struct v4l2_av1_quantization *quantization = &frame->quantization;
+	bool error_resilient_mode =
+	    !!(frame->flags & V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE);
+	bool frame_is_intra = IS_INTRA(frame->frame_type);
+
+	if (error_resilient_mode || frame_is_intra ||
+	    frame->primary_ref_frame == AV1_PRIMARY_REF_NONE) {
+		av1_dec->cdfs = &av1_dec->default_cdfs;
+		av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc;
+		hantro_av1_default_coeff_probs(quantization->base_q_idx,
+					       av1_dec->cdfs);
+	} else {
+		hantro_av1_get_cdfs(ctx, frame->ref_frame_idx[frame->primary_ref_frame]);
+	}
+	hantro_av1_store_cdfs(ctx, frame->refresh_frame_flags);
+
+	memcpy(av1_dec->prob_tbl.cpu, av1_dec->cdfs, sizeof(struct av1cdfs));
+
+	if (frame_is_intra) {
+		int mv_offset = offsetof(struct av1cdfs, mv_cdf);
+		/* Overwrite MV context area with intrabc MV context */
+		memcpy(av1_dec->prob_tbl.cpu + mv_offset, av1_dec->cdfs_ndvc,
+		       sizeof(struct mvcdfs));
+	}
+}
diff --git a/drivers/media/platform/verisilicon/hantro_av1.h b/drivers/media/platform/verisilicon/hantro_av1.h
new file mode 100644
index 000000000000..4e2122b95cdd
--- /dev/null
+++ b/drivers/media/platform/verisilicon/hantro_av1.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _HANTRO_AV1_H_
+#define _HANTRO_AV1_H_
+
+#define AV1_PRIMARY_REF_NONE	7
+#define AV1_REF_SCALE_SHIFT	14
+#define MAX_FRAME_DISTANCE	31
+#define AV1DEC_MAX_PIC_BUFFERS	24
+
+#define SCALE_NUMERATOR 8
+#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1)
+
+#define RS_SCALE_SUBPEL_BITS 14
+#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1)
+#define RS_SUBPEL_BITS 6
+#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1)
+#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS)
+#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1))
+
+/*
+ * These 3 values aren't defined enum v4l2_av1_segment_feature because
+ * they are not part of the specification
+ */
+#define V4L2_AV1_SEG_LVL_ALT_LF_Y_H	2
+#define V4L2_AV1_SEG_LVL_ALT_LF_U	3
+#define V4L2_AV1_SEG_LVL_ALT_LF_V	4
+
+#define IS_INTRA(type) ((type == V4L2_AV1_KEY_FRAME) || (type == V4L2_AV1_INTRA_ONLY_FRAME))
+
+#define LST_BUF_IDX (V4L2_AV1_REF_LAST_FRAME - V4L2_AV1_REF_LAST_FRAME)
+#define LST2_BUF_IDX (V4L2_AV1_REF_LAST2_FRAME - V4L2_AV1_REF_LAST_FRAME)
+#define LST3_BUF_IDX (V4L2_AV1_REF_LAST3_FRAME - V4L2_AV1_REF_LAST_FRAME)
+#define GLD_BUF_IDX (V4L2_AV1_REF_GOLDEN_FRAME - V4L2_AV1_REF_LAST_FRAME)
+#define BWD_BUF_IDX (V4L2_AV1_REF_BWDREF_FRAME - V4L2_AV1_REF_LAST_FRAME)
+#define ALT2_BUF_IDX (V4L2_AV1_REF_ALTREF2_FRAME - V4L2_AV1_REF_LAST_FRAME)
+#define ALT_BUF_IDX (V4L2_AV1_REF_ALTREF_FRAME - V4L2_AV1_REF_LAST_FRAME)
+
+int hantro_av1_get_frame_index(struct hantro_ctx *ctx, int ref);
+int hantro_av1_get_order_hint(struct hantro_ctx *ctx, int ref);
+int hantro_av1_frame_ref(struct hantro_ctx *ctx, u64 timestamp);
+void hantro_av1_clean_refs(struct hantro_ctx *ctx);
+size_t hantro_av1_luma_size(struct hantro_ctx *ctx);
+size_t hantro_av1_chroma_size(struct hantro_ctx *ctx);
+void hantro_av1_exit(struct hantro_ctx *ctx);
+int hantro_av1_init(struct hantro_ctx *ctx);
+int hantro_av1_prepare_run(struct hantro_ctx *ctx);
+void hantro_av1_set_global_model(struct hantro_ctx *ctx);
+int hantro_av1_tile_log2(int target);
+int hantro_av1_get_dist(struct hantro_ctx *ctx, int a, int b);
+void hantro_av1_set_frame_sign_bias(struct hantro_ctx *ctx);
+void hantro_av1_init_scaling_function(const u8 *values, const u8 *scaling,
+				      u8 num_points, u8 *scaling_lut);
+void hantro_av1_set_tile_info(struct hantro_ctx *ctx);
+bool hantro_av1_is_lossless(struct hantro_ctx *ctx);
+void hantro_av1_update_prob(struct hantro_ctx *ctx);
+void hantro_av1_set_prob(struct hantro_ctx *ctx);
+
+int hantro_av1_get_hardware_mcomp_filt_type(int interpolation_filter);
+int hantro_av1_get_hardware_tx_mode(enum v4l2_av1_tx_mode tx_mode);
+
+#endif
diff --git a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.c b/drivers/media/platform/verisilicon/hantro_av1_entropymode.c
similarity index 99%
rename from drivers/media/platform/verisilicon/rockchip_av1_entropymode.c
rename to drivers/media/platform/verisilicon/hantro_av1_entropymode.c
index b1ae72ad675e..4f7bfec73668 100644
--- a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.c
+++ b/drivers/media/platform/verisilicon/hantro_av1_entropymode.c
@@ -11,7 +11,7 @@
  */
 
 #include "hantro.h"
-#include "rockchip_av1_entropymode.h"
+#include "hantro_av1_entropymode.h"
 
 #define AOM_ICDF ICDF
 #define AOM_CDF2(a0) AOM_ICDF(a0)
@@ -4195,7 +4195,7 @@ static const u16 default_bits_cdf[][10] = {
 	}
 };
 
-static int rockchip_av1_get_q_ctx(int q)
+static int hantro_av1_get_q_ctx(int q)
 {
 	if (q <= 20)
 		return 0;
@@ -4206,10 +4206,10 @@ static int rockchip_av1_get_q_ctx(int q)
 	return 3;
 }
 
-void rockchip_av1_default_coeff_probs(u32 base_qindex, void *ptr)
+void hantro_av1_default_coeff_probs(u32 base_qindex, void *ptr)
 {
 	struct av1cdfs *cdfs = (struct av1cdfs *)ptr;
-	const int index = rockchip_av1_get_q_ctx(base_qindex);
+	const int index = hantro_av1_get_q_ctx(base_qindex);
 
 	memcpy(cdfs->txb_skip_cdf, av1_default_txb_skip_cdfs[index],
 	       sizeof(av1_default_txb_skip_cdfs[0]));
@@ -4240,8 +4240,8 @@ void rockchip_av1_default_coeff_probs(u32 base_qindex, void *ptr)
 	       sizeof(av1_default_eob_multi1024_cdfs[0]));
 }
 
-void rockchip_av1_set_default_cdfs(struct av1cdfs *cdfs,
-				   struct mvcdfs *cdfs_ndvc)
+void hantro_av1_set_default_cdfs(struct av1cdfs *cdfs,
+				 struct mvcdfs *cdfs_ndvc)
 {
 	memcpy(cdfs->partition_cdf, default_partition_cdf,
 	       sizeof(cdfs->partition_cdf));
@@ -4398,7 +4398,7 @@ void rockchip_av1_set_default_cdfs(struct av1cdfs *cdfs,
 	       sizeof(cdfs->compound_idx_cdf));
 }
 
-void rockchip_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx)
+void hantro_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx)
 {
 	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
 
@@ -4406,8 +4406,8 @@ void rockchip_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx)
 	av1_dec->cdfs_ndvc = &av1_dec->cdfs_last_ndvc[ref_idx];
 }
 
-void rockchip_av1_store_cdfs(struct hantro_ctx *ctx,
-			     u32 refresh_frame_flags)
+void hantro_av1_store_cdfs(struct hantro_ctx *ctx,
+			   u32 refresh_frame_flags)
 {
 	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
 	int i;
diff --git a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.h b/drivers/media/platform/verisilicon/hantro_av1_entropymode.h
similarity index 95%
rename from drivers/media/platform/verisilicon/rockchip_av1_entropymode.h
rename to drivers/media/platform/verisilicon/hantro_av1_entropymode.h
index bbf8424c7d2c..abbc660ecce3 100644
--- a/drivers/media/platform/verisilicon/rockchip_av1_entropymode.h
+++ b/drivers/media/platform/verisilicon/hantro_av1_entropymode.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
-#ifndef _ROCKCHIP_AV1_ENTROPYMODE_H_
-#define _ROCKCHIP_AV1_ENTROPYMODE_H_
+#ifndef _HANTRO_AV1_ENTROPYMODE_H_
+#define _HANTRO_AV1_ENTROPYMODE_H_
 
 #include <linux/types.h>
 
@@ -262,11 +262,11 @@ struct av1cdfs {
 	u16 dummy3[16];
 };
 
-void rockchip_av1_store_cdfs(struct hantro_ctx *ctx,
-			     u32 refresh_frame_flags);
-void rockchip_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx);
-void rockchip_av1_set_default_cdfs(struct av1cdfs *cdfs,
-				   struct mvcdfs *cdfs_ndvc);
-void rockchip_av1_default_coeff_probs(u32 base_qindex, void *ptr);
+void hantro_av1_store_cdfs(struct hantro_ctx *ctx,
+			   u32 refresh_frame_flags);
+void hantro_av1_get_cdfs(struct hantro_ctx *ctx, u32 ref_idx);
+void hantro_av1_set_default_cdfs(struct av1cdfs *cdfs,
+				 struct mvcdfs *cdfs_ndvc);
+void hantro_av1_default_coeff_probs(u32 base_qindex, void *ptr);
 
-#endif /* _ROCKCHIP_AV1_ENTROPYMODE_H_ */
+#endif /* _HANTRO_AV1_ENTROPYMODE_H_ */
diff --git a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.c b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.c
similarity index 92%
rename from drivers/media/platform/verisilicon/rockchip_av1_filmgrain.c
rename to drivers/media/platform/verisilicon/hantro_av1_filmgrain.c
index f64dea797eff..06a21974e24e 100644
--- a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.c
+++ b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only OR Apache-2.0
 
-#include "rockchip_av1_filmgrain.h"
+#include "hantro_av1_filmgrain.h"
 
 static const s32 gaussian_sequence[2048] = {
 	56, 568, -180, 172, 124, -84, 172, -64, -900, 24, 820,
@@ -204,8 +204,8 @@ static inline s32 round_power_of_two(const s32 val, s32 n)
 	return (val + a) >> n;
 }
 
-static void rockchip_av1_init_random_generator(u8 luma_num, u16 seed,
-					       u16 *random_register)
+static void hantro_av1_init_random_generator(u8 luma_num, u16 seed,
+					     u16 *random_register)
 {
 	u16 random_reg = seed;
 
@@ -214,7 +214,7 @@ static void rockchip_av1_init_random_generator(u8 luma_num, u16 seed,
 	*random_register = random_reg;
 }
 
-static inline void rockchip_av1_update_random_register(u16 *random_register)
+static inline void hantro_av1_update_random_register(u16 *random_register)
 {
 	u16 bit;
 	u16 random_reg = *random_register;
@@ -224,21 +224,21 @@ static inline void rockchip_av1_update_random_register(u16 *random_register)
 	*random_register = (random_reg >> 1) | (bit << 15);
 }
 
-static inline s32 rockchip_av1_get_random_number(u16 random_register)
+static inline s32 hantro_av1_get_random_number(u16 random_register)
 {
 	return (random_register >> 5) & ((1 << 11) - 1);
 }
 
-void rockchip_av1_generate_luma_grain_block(s32 (*luma_grain_block)[73][82],
-					    s32 bitdepth,
-					    u8 num_y_points,
-					    s32 grain_scale_shift,
-					    s32 ar_coeff_lag,
-					    s32 (*ar_coeffs_y)[24],
-					    s32 ar_coeff_shift,
-					    s32 grain_min,
-					    s32 grain_max,
-					    u16 random_seed)
+void hantro_av1_generate_luma_grain_block(s32 (*luma_grain_block)[73][82],
+					  s32 bitdepth,
+					  u8 num_y_points,
+					  s32 grain_scale_shift,
+					  s32 ar_coeff_lag,
+					  s32 (*ar_coeffs_y)[24],
+					  s32 ar_coeff_shift,
+					  s32 grain_min,
+					  s32 grain_max,
+					  u16 random_seed)
 {
 	s32 gauss_sec_shift = 12 - bitdepth + grain_scale_shift;
 	u16 grain_random_register = random_seed;
@@ -247,11 +247,11 @@ void rockchip_av1_generate_luma_grain_block(s32 (*luma_grain_block)[73][82],
 	for (i = 0; i < 73; i++) {
 		for (j = 0; j < 82; j++) {
 			if (num_y_points > 0) {
-				rockchip_av1_update_random_register
+				hantro_av1_update_random_register
 				    (&grain_random_register);
 				(*luma_grain_block)[i][j] =
 				    round_power_of_two(gaussian_sequence
-					     [rockchip_av1_get_random_number
+					     [hantro_av1_get_random_number
 					      (grain_random_register)],
 					     gauss_sec_shift);
 			} else {
@@ -285,37 +285,37 @@ void rockchip_av1_generate_luma_grain_block(s32 (*luma_grain_block)[73][82],
 }
 
 // Calculate chroma grain noise once per frame
-void rockchip_av1_generate_chroma_grain_block(s32 (*luma_grain_block)[73][82],
-					      s32 (*cb_grain_block)[38][44],
-					      s32 (*cr_grain_block)[38][44],
-					      s32 bitdepth,
-					      u8 num_y_points,
-					      u8 num_cb_points,
-					      u8 num_cr_points,
-					      s32 grain_scale_shift,
-					      s32 ar_coeff_lag,
-					      s32 (*ar_coeffs_cb)[25],
-					      s32 (*ar_coeffs_cr)[25],
-					      s32 ar_coeff_shift,
-					      s32 grain_min,
-					      s32 grain_max,
-					      u8 chroma_scaling_from_luma,
-					      u16 random_seed)
+void hantro_av1_generate_chroma_grain_block(s32 (*luma_grain_block)[73][82],
+					    s32 (*cb_grain_block)[38][44],
+					    s32 (*cr_grain_block)[38][44],
+					    s32 bitdepth,
+					    u8 num_y_points,
+					    u8 num_cb_points,
+					    u8 num_cr_points,
+					    s32 grain_scale_shift,
+					    s32 ar_coeff_lag,
+					    s32 (*ar_coeffs_cb)[25],
+					    s32 (*ar_coeffs_cr)[25],
+					    s32 ar_coeff_shift,
+					    s32 grain_min,
+					    s32 grain_max,
+					    u8 chroma_scaling_from_luma,
+					    u16 random_seed)
 {
 	s32 gauss_sec_shift = 12 - bitdepth + grain_scale_shift;
 	u16 grain_random_register = 0;
 	s32 i, j;
 
-	rockchip_av1_init_random_generator(7, random_seed,
-					   &grain_random_register);
+	hantro_av1_init_random_generator(7, random_seed,
+					 &grain_random_register);
 	for (i = 0; i < 38; i++) {
 		for (j = 0; j < 44; j++) {
 			if (num_cb_points || chroma_scaling_from_luma) {
-				rockchip_av1_update_random_register
+				hantro_av1_update_random_register
 				    (&grain_random_register);
 				(*cb_grain_block)[i][j] =
 				    round_power_of_two(gaussian_sequence
-					     [rockchip_av1_get_random_number
+					     [hantro_av1_get_random_number
 					      (grain_random_register)],
 					     gauss_sec_shift);
 			} else {
@@ -324,16 +324,16 @@ void rockchip_av1_generate_chroma_grain_block(s32 (*luma_grain_block)[73][82],
 		}
 	}
 
-	rockchip_av1_init_random_generator(11, random_seed,
-					   &grain_random_register);
+	hantro_av1_init_random_generator(11, random_seed,
+					 &grain_random_register);
 	for (i = 0; i < 38; i++) {
 		for (j = 0; j < 44; j++) {
 			if (num_cr_points || chroma_scaling_from_luma) {
-				rockchip_av1_update_random_register
+				hantro_av1_update_random_register
 				    (&grain_random_register);
 				(*cr_grain_block)[i][j] =
 				    round_power_of_two(gaussian_sequence
-					     [rockchip_av1_get_random_number
+					     [hantro_av1_get_random_number
 					      (grain_random_register)],
 					     gauss_sec_shift);
 			} else {
diff --git a/drivers/media/platform/verisilicon/hantro_av1_filmgrain.h b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.h
new file mode 100644
index 000000000000..5593e84114d0
--- /dev/null
+++ b/drivers/media/platform/verisilicon/hantro_av1_filmgrain.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _HANTRO_AV1_FILMGRAIN_H_
+#define _HANTRO_AV1_FILMGRAIN_H_
+
+#include <linux/types.h>
+
+struct hantro_av1_film_grain {
+	u8 scaling_lut_y[256];
+	u8 scaling_lut_cb[256];
+	u8 scaling_lut_cr[256];
+	s16 cropped_luma_grain_block[4096];
+	s16 cropped_chroma_grain_block[1024 * 2];
+};
+
+void hantro_av1_generate_luma_grain_block(s32 (*luma_grain_block)[73][82],
+					  s32 bitdepth,
+					  u8 num_y_points,
+					  s32 grain_scale_shift,
+					  s32 ar_coeff_lag,
+					  s32 (*ar_coeffs_y)[24],
+					  s32 ar_coeff_shift,
+					  s32 grain_min,
+					  s32 grain_max,
+					  u16 random_seed);
+
+void hantro_av1_generate_chroma_grain_block(s32 (*luma_grain_block)[73][82],
+					    s32 (*cb_grain_block)[38][44],
+					    s32 (*cr_grain_block)[38][44],
+					    s32 bitdepth,
+					    u8 num_y_points,
+					    u8 num_cb_points,
+					    u8 num_cr_points,
+					    s32 grain_scale_shift,
+					    s32 ar_coeff_lag,
+					    s32 (*ar_coeffs_cb)[25],
+					    s32 (*ar_coeffs_cr)[25],
+					    s32 ar_coeff_shift,
+					    s32 grain_min,
+					    s32 grain_max,
+					    u8 chroma_scaling_from_luma,
+					    u16 random_seed);
+
+#endif
diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h
index 5f2011529f02..d1d39d1df5d2 100644
--- a/drivers/media/platform/verisilicon/hantro_hw.h
+++ b/drivers/media/platform/verisilicon/hantro_hw.h
@@ -15,8 +15,8 @@
 #include <media/v4l2-vp9.h>
 #include <media/videobuf2-core.h>
 
-#include "rockchip_av1_entropymode.h"
-#include "rockchip_av1_filmgrain.h"
+#include "hantro_av1_entropymode.h"
+#include "hantro_av1_filmgrain.h"
 
 #define DEC_8190_ALIGN_MASK	0x07U
 
@@ -459,10 +459,7 @@ void hantro_hevc_ref_init(struct hantro_ctx *ctx);
 dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, s32 poc);
 int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
 
-int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx);
-void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx);
 int rockchip_vpu981_av1_dec_run(struct hantro_ctx *ctx);
-void rockchip_vpu981_av1_dec_done(struct hantro_ctx *ctx);
 
 static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
 {
diff --git a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h b/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h
deleted file mode 100644
index 31a8b7920c31..000000000000
--- a/drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#ifndef _ROCKCHIP_AV1_FILMGRAIN_H_
-#define _ROCKCHIP_AV1_FILMGRAIN_H_
-
-#include <linux/types.h>
-
-void rockchip_av1_generate_luma_grain_block(s32 (*luma_grain_block)[73][82],
-					    s32 bitdepth,
-					    u8 num_y_points,
-					    s32 grain_scale_shift,
-					    s32 ar_coeff_lag,
-					    s32 (*ar_coeffs_y)[24],
-					    s32 ar_coeff_shift,
-					    s32 grain_min,
-					    s32 grain_max,
-					    u16 random_seed);
-
-void rockchip_av1_generate_chroma_grain_block(s32 (*luma_grain_block)[73][82],
-					      s32 (*cb_grain_block)[38][44],
-					      s32 (*cr_grain_block)[38][44],
-					      s32 bitdepth,
-					      u8 num_y_points,
-					      u8 num_cb_points,
-					      u8 num_cr_points,
-					      s32 grain_scale_shift,
-					      s32 ar_coeff_lag,
-					      s32 (*ar_coeffs_cb)[25],
-					      s32 (*ar_coeffs_cr)[25],
-					      s32 ar_coeff_shift,
-					      s32 grain_min,
-					      s32 grain_max,
-					      u8 chroma_scaling_from_luma,
-					      u16 random_seed);
-
-#endif
diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
index e4e21ad37323..990a5e6b5531 100644
--- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
@@ -7,622 +7,35 @@
 
 #include <media/v4l2-mem2mem.h>
 #include "hantro.h"
+#include "hantro_av1.h"
 #include "hantro_v4l2.h"
 #include "rockchip_vpu981_regs.h"
 
 #define AV1_DEC_MODE		17
-#define GM_GLOBAL_MODELS_PER_FRAME	7
-#define GLOBAL_MODEL_TOTAL_SIZE	(6 * 4 + 4 * 2)
-#define GLOBAL_MODEL_SIZE	ALIGN(GM_GLOBAL_MODELS_PER_FRAME * GLOBAL_MODEL_TOTAL_SIZE, 2048)
-#define AV1_MAX_TILES		128
-#define AV1_TILE_INFO_SIZE	(AV1_MAX_TILES * 16)
-#define AV1DEC_MAX_PIC_BUFFERS	24
-#define AV1_REF_SCALE_SHIFT	14
-#define AV1_INVALID_IDX		-1
-#define MAX_FRAME_DISTANCE	31
-#define AV1_PRIMARY_REF_NONE	7
-#define AV1_TILE_SIZE		ALIGN(32 * 128, 4096)
-/*
- * These 3 values aren't defined enum v4l2_av1_segment_feature because
- * they are not part of the specification
- */
-#define V4L2_AV1_SEG_LVL_ALT_LF_Y_H	2
-#define V4L2_AV1_SEG_LVL_ALT_LF_U	3
-#define V4L2_AV1_SEG_LVL_ALT_LF_V	4
-
-#define SUPERRES_SCALE_BITS 3
-#define SCALE_NUMERATOR 8
-#define SUPERRES_SCALE_DENOMINATOR_MIN (SCALE_NUMERATOR + 1)
-
-#define RS_SUBPEL_BITS 6
-#define RS_SUBPEL_MASK ((1 << RS_SUBPEL_BITS) - 1)
-#define RS_SCALE_SUBPEL_BITS 14
-#define RS_SCALE_SUBPEL_MASK ((1 << RS_SCALE_SUBPEL_BITS) - 1)
-#define RS_SCALE_EXTRA_BITS (RS_SCALE_SUBPEL_BITS - RS_SUBPEL_BITS)
-#define RS_SCALE_EXTRA_OFF (1 << (RS_SCALE_EXTRA_BITS - 1))
-
-#define IS_INTRA(type) ((type == V4L2_AV1_KEY_FRAME) || (type == V4L2_AV1_INTRA_ONLY_FRAME))
-
-#define LST_BUF_IDX (V4L2_AV1_REF_LAST_FRAME - V4L2_AV1_REF_LAST_FRAME)
-#define LST2_BUF_IDX (V4L2_AV1_REF_LAST2_FRAME - V4L2_AV1_REF_LAST_FRAME)
-#define LST3_BUF_IDX (V4L2_AV1_REF_LAST3_FRAME - V4L2_AV1_REF_LAST_FRAME)
-#define GLD_BUF_IDX (V4L2_AV1_REF_GOLDEN_FRAME - V4L2_AV1_REF_LAST_FRAME)
-#define BWD_BUF_IDX (V4L2_AV1_REF_BWDREF_FRAME - V4L2_AV1_REF_LAST_FRAME)
-#define ALT2_BUF_IDX (V4L2_AV1_REF_ALTREF2_FRAME - V4L2_AV1_REF_LAST_FRAME)
-#define ALT_BUF_IDX (V4L2_AV1_REF_ALTREF_FRAME - V4L2_AV1_REF_LAST_FRAME)
-
-#define DIV_LUT_PREC_BITS 14
-#define DIV_LUT_BITS 8
-#define DIV_LUT_NUM BIT(DIV_LUT_BITS)
-#define WARP_PARAM_REDUCE_BITS 6
-#define WARPEDMODEL_PREC_BITS 16
-
-#define AV1_DIV_ROUND_UP_POW2(value, n)			\
-({							\
-	typeof(n) _n  = n;				\
-	typeof(value) _value = value;			\
-	(_value + (BIT(_n) >> 1)) >> _n;		\
-})
-
-#define AV1_DIV_ROUND_UP_POW2_SIGNED(value, n)				\
-({									\
-	typeof(n) _n_  = n;						\
-	typeof(value) _value_ = value;					\
-	(((_value_) < 0) ? -AV1_DIV_ROUND_UP_POW2(-(_value_), (_n_))	\
-		: AV1_DIV_ROUND_UP_POW2((_value_), (_n_)));		\
-})
-
-enum rockchip_av1_tx_mode {
-	ROCKCHIP_AV1_TX_MODE_ONLY_4X4	= 0,
-	ROCKCHIP_AV1_TX_MODE_8X8	= 1,
-	ROCKCHIP_AV1_TX_MODE_16x16	= 2,
-	ROCKCHIP_AV1_TX_MODE_32x32	= 3,
-	ROCKCHIP_AV1_TX_MODE_SELECT	= 4,
-};
-
-struct rockchip_av1_film_grain {
-	u8 scaling_lut_y[256];
-	u8 scaling_lut_cb[256];
-	u8 scaling_lut_cr[256];
-	s16 cropped_luma_grain_block[4096];
-	s16 cropped_chroma_grain_block[1024 * 2];
-};
-
-static const short div_lut[DIV_LUT_NUM + 1] = {
-	16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768,
-	15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 15142,
-	15087, 15033, 14980, 14926, 14873, 14821, 14769, 14717, 14665, 14614, 14564,
-	14513, 14463, 14413, 14364, 14315, 14266, 14218, 14170, 14122, 14075, 14028,
-	13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662, 13618, 13574, 13530,
-	13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, 13107, 13066,
-	13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, 12672, 12633,
-	12596, 12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, 12264, 12228,
-	12193, 12157, 12122, 12087, 12053, 12018, 11984, 11950, 11916, 11882, 11848,
-	11815, 11782, 11749, 11716, 11683, 11651, 11619, 11586, 11555, 11523, 11491,
-	11460, 11429, 11398, 11367, 11336, 11305, 11275, 11245, 11215, 11185, 11155,
-	11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894, 10866, 10838,
-	10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, 10565, 10538,
-	10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, 10280, 10255,
-	10230, 10205, 10180, 10156, 10131, 10107, 10082, 10058, 10034, 10010, 9986,
-	9963,  9939,  9916,  9892,  9869,  9846,  9823,  9800,  9777,  9754,  9732,
-	9709,  9687,  9664,  9642,  9620,  9598,  9576,  9554,  9533,  9511,  9489,
-	9468,  9447,  9425,  9404,  9383,  9362,  9341,  9321,  9300,  9279,  9259,
-	9239,  9218,  9198,  9178,  9158,  9138,  9118,  9098,  9079,  9059,  9039,
-	9020,  9001,  8981,  8962,  8943,  8924,  8905,  8886,  8867,  8849,  8830,
-	8812,  8793,  8775,  8756,  8738,  8720,  8702,  8684,  8666,  8648,  8630,
-	8613,  8595,  8577,  8560,  8542,  8525,  8508,  8490,  8473,  8456,  8439,
-	8422,  8405,  8389,  8372,  8355,  8339,  8322,  8306,  8289,  8273,  8257,
-	8240,  8224,  8208,  8192,
-};
-
-static int rockchip_vpu981_get_frame_index(struct hantro_ctx *ctx, int ref)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
-	u64 timestamp;
-	int i, idx = frame->ref_frame_idx[ref];
-
-	if (idx >= V4L2_AV1_TOTAL_REFS_PER_FRAME || idx < 0)
-		return AV1_INVALID_IDX;
-
-	timestamp = frame->reference_frame_ts[idx];
-	for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) {
-		if (!av1_dec->frame_refs[i].used)
-			continue;
-		if (av1_dec->frame_refs[i].timestamp == timestamp)
-			return i;
-	}
-
-	return AV1_INVALID_IDX;
-}
-
-static int rockchip_vpu981_get_order_hint(struct hantro_ctx *ctx, int ref)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	int idx = rockchip_vpu981_get_frame_index(ctx, ref);
-
-	if (idx != AV1_INVALID_IDX)
-		return av1_dec->frame_refs[idx].order_hint;
-
-	return 0;
-}
-
-static int rockchip_vpu981_av1_dec_frame_ref(struct hantro_ctx *ctx,
-					     u64 timestamp)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
-	int i;
-
-	for (i = 0; i < AV1_MAX_FRAME_BUF_COUNT; i++) {
-		int j;
-
-		if (av1_dec->frame_refs[i].used)
-			continue;
-
-		av1_dec->frame_refs[i].width = frame->frame_width_minus_1 + 1;
-		av1_dec->frame_refs[i].height = frame->frame_height_minus_1 + 1;
-		av1_dec->frame_refs[i].mi_cols = DIV_ROUND_UP(frame->frame_width_minus_1 + 1, 8);
-		av1_dec->frame_refs[i].mi_rows = DIV_ROUND_UP(frame->frame_height_minus_1 + 1, 8);
-		av1_dec->frame_refs[i].timestamp = timestamp;
-		av1_dec->frame_refs[i].frame_type = frame->frame_type;
-		av1_dec->frame_refs[i].order_hint = frame->order_hint;
-		av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx);
-
-		for (j = 0; j < V4L2_AV1_TOTAL_REFS_PER_FRAME; j++)
-			av1_dec->frame_refs[i].order_hints[j] = frame->order_hints[j];
-		av1_dec->frame_refs[i].used = true;
-		av1_dec->current_frame_index = i;
-
-		return i;
-	}
-
-	return AV1_INVALID_IDX;
-}
-
-static void rockchip_vpu981_av1_dec_frame_unref(struct hantro_ctx *ctx, int idx)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-
-	if (idx >= 0)
-		av1_dec->frame_refs[idx].used = false;
-}
-
-static void rockchip_vpu981_av1_dec_clean_refs(struct hantro_ctx *ctx)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-
-	int ref, idx;
-
-	for (idx = 0; idx < AV1_MAX_FRAME_BUF_COUNT; idx++) {
-		u64 timestamp = av1_dec->frame_refs[idx].timestamp;
-		bool used = false;
-
-		if (!av1_dec->frame_refs[idx].used)
-			continue;
-
-		for (ref = 0; ref < V4L2_AV1_TOTAL_REFS_PER_FRAME; ref++) {
-			if (ctrls->frame->reference_frame_ts[ref] == timestamp)
-				used = true;
-		}
-
-		if (!used)
-			rockchip_vpu981_av1_dec_frame_unref(ctx, idx);
-	}
-}
-
-static size_t rockchip_vpu981_av1_dec_luma_size(struct hantro_ctx *ctx)
-{
-	return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8;
-}
-
-static size_t rockchip_vpu981_av1_dec_chroma_size(struct hantro_ctx *ctx)
-{
-	size_t cr_offset = rockchip_vpu981_av1_dec_luma_size(ctx);
-
-	return ALIGN((cr_offset * 3) / 2, 64);
-}
-
-static void rockchip_vpu981_av1_dec_tiles_free(struct hantro_ctx *ctx)
-{
-	struct hantro_dev *vpu = ctx->dev;
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-
-	if (av1_dec->db_data_col.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->db_data_col.size,
-				  av1_dec->db_data_col.cpu,
-				  av1_dec->db_data_col.dma);
-	av1_dec->db_data_col.cpu = NULL;
-
-	if (av1_dec->db_ctrl_col.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->db_ctrl_col.size,
-				  av1_dec->db_ctrl_col.cpu,
-				  av1_dec->db_ctrl_col.dma);
-	av1_dec->db_ctrl_col.cpu = NULL;
-
-	if (av1_dec->cdef_col.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->cdef_col.size,
-				  av1_dec->cdef_col.cpu, av1_dec->cdef_col.dma);
-	av1_dec->cdef_col.cpu = NULL;
-
-	if (av1_dec->sr_col.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->sr_col.size,
-				  av1_dec->sr_col.cpu, av1_dec->sr_col.dma);
-	av1_dec->sr_col.cpu = NULL;
-
-	if (av1_dec->lr_col.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->lr_col.size,
-				  av1_dec->lr_col.cpu, av1_dec->lr_col.dma);
-	av1_dec->lr_col.cpu = NULL;
-}
-
-static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx)
-{
-	struct hantro_dev *vpu = ctx->dev;
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info;
-	unsigned int num_tile_cols = tile_info->tile_cols;
-	unsigned int height = ALIGN(ctrls->frame->frame_height_minus_1 + 1, 64);
-	unsigned int height_in_sb = height / 64;
-	unsigned int stripe_num = ((height + 8) + 63) / 64;
-	size_t size;
-
-	if (av1_dec->db_data_col.size >=
-	    ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols)
-		return 0;
-
-	rockchip_vpu981_av1_dec_tiles_free(ctx);
-
-	size = ALIGN(height * 12 * ctx->bit_depth / 8, 128) * num_tile_cols;
-	av1_dec->db_data_col.cpu = dma_alloc_coherent(vpu->dev, size,
-						      &av1_dec->db_data_col.dma,
-						      GFP_KERNEL);
-	if (!av1_dec->db_data_col.cpu)
-		goto buffer_allocation_error;
-	av1_dec->db_data_col.size = size;
-
-	size = ALIGN(height * 2 * 16 / 4, 128) * num_tile_cols;
-	av1_dec->db_ctrl_col.cpu = dma_alloc_coherent(vpu->dev, size,
-						      &av1_dec->db_ctrl_col.dma,
-						      GFP_KERNEL);
-	if (!av1_dec->db_ctrl_col.cpu)
-		goto buffer_allocation_error;
-	av1_dec->db_ctrl_col.size = size;
-
-	size = ALIGN(height_in_sb * 44 * ctx->bit_depth * 16 / 8, 128) * num_tile_cols;
-	av1_dec->cdef_col.cpu = dma_alloc_coherent(vpu->dev, size,
-						   &av1_dec->cdef_col.dma,
-						   GFP_KERNEL);
-	if (!av1_dec->cdef_col.cpu)
-		goto buffer_allocation_error;
-	av1_dec->cdef_col.size = size;
-
-	size = ALIGN(height_in_sb * (3040 + 1280), 128) * num_tile_cols;
-	av1_dec->sr_col.cpu = dma_alloc_coherent(vpu->dev, size,
-						 &av1_dec->sr_col.dma,
-						 GFP_KERNEL);
-	if (!av1_dec->sr_col.cpu)
-		goto buffer_allocation_error;
-	av1_dec->sr_col.size = size;
-
-	size = ALIGN(stripe_num * 1536 * ctx->bit_depth / 8, 128) * num_tile_cols;
-	av1_dec->lr_col.cpu = dma_alloc_coherent(vpu->dev, size,
-						 &av1_dec->lr_col.dma,
-						 GFP_KERNEL);
-	if (!av1_dec->lr_col.cpu)
-		goto buffer_allocation_error;
-	av1_dec->lr_col.size = size;
-
-	av1_dec->num_tile_cols_allocated = num_tile_cols;
-	return 0;
-
-buffer_allocation_error:
-	rockchip_vpu981_av1_dec_tiles_free(ctx);
-	return -ENOMEM;
-}
-
-void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx)
-{
-	struct hantro_dev *vpu = ctx->dev;
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-
-	if (av1_dec->global_model.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->global_model.size,
-				  av1_dec->global_model.cpu,
-				  av1_dec->global_model.dma);
-	av1_dec->global_model.cpu = NULL;
-
-	if (av1_dec->tile_info.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->tile_info.size,
-				  av1_dec->tile_info.cpu,
-				  av1_dec->tile_info.dma);
-	av1_dec->tile_info.cpu = NULL;
-
-	if (av1_dec->film_grain.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->film_grain.size,
-				  av1_dec->film_grain.cpu,
-				  av1_dec->film_grain.dma);
-	av1_dec->film_grain.cpu = NULL;
-
-	if (av1_dec->prob_tbl.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->prob_tbl.size,
-				  av1_dec->prob_tbl.cpu, av1_dec->prob_tbl.dma);
-	av1_dec->prob_tbl.cpu = NULL;
-
-	if (av1_dec->prob_tbl_out.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->prob_tbl_out.size,
-				  av1_dec->prob_tbl_out.cpu,
-				  av1_dec->prob_tbl_out.dma);
-	av1_dec->prob_tbl_out.cpu = NULL;
-
-	if (av1_dec->tile_buf.cpu)
-		dma_free_coherent(vpu->dev, av1_dec->tile_buf.size,
-				  av1_dec->tile_buf.cpu, av1_dec->tile_buf.dma);
-	av1_dec->tile_buf.cpu = NULL;
-
-	rockchip_vpu981_av1_dec_tiles_free(ctx);
-}
-
-int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)
-{
-	struct hantro_dev *vpu = ctx->dev;
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-
-	memset(av1_dec, 0, sizeof(*av1_dec));
-
-	av1_dec->global_model.cpu = dma_alloc_coherent(vpu->dev, GLOBAL_MODEL_SIZE,
-						       &av1_dec->global_model.dma,
-						       GFP_KERNEL);
-	if (!av1_dec->global_model.cpu)
-		return -ENOMEM;
-	av1_dec->global_model.size = GLOBAL_MODEL_SIZE;
-
-	av1_dec->tile_info.cpu = dma_alloc_coherent(vpu->dev, AV1_TILE_INFO_SIZE,
-						    &av1_dec->tile_info.dma,
-						    GFP_KERNEL);
-	if (!av1_dec->tile_info.cpu)
-		return -ENOMEM;
-	av1_dec->tile_info.size = AV1_TILE_INFO_SIZE;
-
-	av1_dec->film_grain.cpu = dma_alloc_coherent(vpu->dev,
-						     ALIGN(sizeof(struct rockchip_av1_film_grain), 2048),
-						     &av1_dec->film_grain.dma,
-						     GFP_KERNEL);
-	if (!av1_dec->film_grain.cpu)
-		return -ENOMEM;
-	av1_dec->film_grain.size = ALIGN(sizeof(struct rockchip_av1_film_grain), 2048);
-
-	av1_dec->prob_tbl.cpu = dma_alloc_coherent(vpu->dev,
-						   ALIGN(sizeof(struct av1cdfs), 2048),
-						   &av1_dec->prob_tbl.dma,
-						   GFP_KERNEL);
-	if (!av1_dec->prob_tbl.cpu)
-		return -ENOMEM;
-	av1_dec->prob_tbl.size = ALIGN(sizeof(struct av1cdfs), 2048);
-
-	av1_dec->prob_tbl_out.cpu = dma_alloc_coherent(vpu->dev,
-						       ALIGN(sizeof(struct av1cdfs), 2048),
-						       &av1_dec->prob_tbl_out.dma,
-						       GFP_KERNEL);
-	if (!av1_dec->prob_tbl_out.cpu)
-		return -ENOMEM;
-	av1_dec->prob_tbl_out.size = ALIGN(sizeof(struct av1cdfs), 2048);
-	av1_dec->cdfs = &av1_dec->default_cdfs;
-	av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc;
-
-	rockchip_av1_set_default_cdfs(av1_dec->cdfs, av1_dec->cdfs_ndvc);
-
-	av1_dec->tile_buf.cpu = dma_alloc_coherent(vpu->dev,
-						   AV1_TILE_SIZE,
-						   &av1_dec->tile_buf.dma,
-						   GFP_KERNEL);
-	if (!av1_dec->tile_buf.cpu)
-		return -ENOMEM;
-	av1_dec->tile_buf.size = AV1_TILE_SIZE;
-
-	return 0;
-}
-
-static int rockchip_vpu981_av1_dec_prepare_run(struct hantro_ctx *ctx)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-
-	ctrls->sequence = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_SEQUENCE);
-	if (WARN_ON(!ctrls->sequence))
-		return -EINVAL;
-
-	ctrls->tile_group_entry =
-	    hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY);
-	if (WARN_ON(!ctrls->tile_group_entry))
-		return -EINVAL;
-
-	ctrls->frame = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FRAME);
-	if (WARN_ON(!ctrls->frame))
-		return -EINVAL;
-
-	ctrls->film_grain =
-	    hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FILM_GRAIN);
-
-	return rockchip_vpu981_av1_dec_tiles_reallocate(ctx);
-}
-
-static inline int rockchip_vpu981_av1_dec_get_msb(u32 n)
-{
-	if (n == 0)
-		return 0;
-	return 31 ^ __builtin_clz(n);
-}
-
-static short rockchip_vpu981_av1_dec_resolve_divisor_32(u32 d, short *shift)
-{
-	int f;
-	u64 e;
-
-	*shift = rockchip_vpu981_av1_dec_get_msb(d);
-	/* e is obtained from D after resetting the most significant 1 bit. */
-	e = d - ((u32)1 << *shift);
-	/* Get the most significant DIV_LUT_BITS (8) bits of e into f */
-	if (*shift > DIV_LUT_BITS)
-		f = AV1_DIV_ROUND_UP_POW2(e, *shift - DIV_LUT_BITS);
-	else
-		f = e << (DIV_LUT_BITS - *shift);
-	if (f > DIV_LUT_NUM)
-		return -1;
-	*shift += DIV_LUT_PREC_BITS;
-	/* Use f as lookup into the precomputed table of multipliers */
-	return div_lut[f];
-}
-
-static void
-rockchip_vpu981_av1_dec_get_shear_params(const u32 *params, s64 *alpha,
-					 s64 *beta, s64 *gamma, s64 *delta)
-{
-	const int *mat = params;
-	short shift;
-	short y;
-	long long gv, dv;
-
-	if (mat[2] <= 0)
-		return;
-
-	*alpha = clamp_val(mat[2] - (1 << WARPEDMODEL_PREC_BITS), S16_MIN, S16_MAX);
-	*beta = clamp_val(mat[3], S16_MIN, S16_MAX);
-
-	y = rockchip_vpu981_av1_dec_resolve_divisor_32(abs(mat[2]), &shift) * (mat[2] < 0 ? -1 : 1);
-
-	gv = ((long long)mat[4] * (1 << WARPEDMODEL_PREC_BITS)) * y;
-
-	*gamma = clamp_val((int)AV1_DIV_ROUND_UP_POW2_SIGNED(gv, shift), S16_MIN, S16_MAX);
-
-	dv = ((long long)mat[3] * mat[4]) * y;
-	*delta = clamp_val(mat[5] -
-		(int)AV1_DIV_ROUND_UP_POW2_SIGNED(dv, shift) - (1 << WARPEDMODEL_PREC_BITS),
-		S16_MIN, S16_MAX);
-
-	*alpha = AV1_DIV_ROUND_UP_POW2_SIGNED(*alpha, WARP_PARAM_REDUCE_BITS)
-		 * (1 << WARP_PARAM_REDUCE_BITS);
-	*beta = AV1_DIV_ROUND_UP_POW2_SIGNED(*beta, WARP_PARAM_REDUCE_BITS)
-		* (1 << WARP_PARAM_REDUCE_BITS);
-	*gamma = AV1_DIV_ROUND_UP_POW2_SIGNED(*gamma, WARP_PARAM_REDUCE_BITS)
-		 * (1 << WARP_PARAM_REDUCE_BITS);
-	*delta = AV1_DIV_ROUND_UP_POW2_SIGNED(*delta, WARP_PARAM_REDUCE_BITS)
-		* (1 << WARP_PARAM_REDUCE_BITS);
-}
 
 static void rockchip_vpu981_av1_dec_set_global_model(struct hantro_ctx *ctx)
 {
 	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
-	const struct v4l2_av1_global_motion *gm = &frame->global_motion;
-	u8 *dst = av1_dec->global_model.cpu;
 	struct hantro_dev *vpu = ctx->dev;
-	int ref_frame, i;
-
-	memset(dst, 0, GLOBAL_MODEL_SIZE);
-	for (ref_frame = 0; ref_frame < V4L2_AV1_REFS_PER_FRAME; ++ref_frame) {
-		s64 alpha = 0, beta = 0, gamma = 0, delta = 0;
-
-		for (i = 0; i < 6; ++i) {
-			if (i == 2)
-				*(s32 *)dst =
-					gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][3];
-			else if (i == 3)
-				*(s32 *)dst =
-					gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][2];
-			else
-				*(s32 *)dst =
-					gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][i];
-			dst += 4;
-		}
-
-		if (gm->type[V4L2_AV1_REF_LAST_FRAME + ref_frame] <= V4L2_AV1_WARP_MODEL_AFFINE)
-			rockchip_vpu981_av1_dec_get_shear_params(&gm->params[V4L2_AV1_REF_LAST_FRAME + ref_frame][0],
-								 &alpha, &beta, &gamma, &delta);
-
-		*(s16 *)dst = alpha;
-		dst += 2;
-		*(s16 *)dst = beta;
-		dst += 2;
-		*(s16 *)dst = gamma;
-		dst += 2;
-		*(s16 *)dst = delta;
-		dst += 2;
-	}
 
+	hantro_av1_set_global_model(ctx);
 	hantro_write_addr(vpu, AV1_GLOBAL_MODEL, av1_dec->global_model.dma);
 }
 
-static int rockchip_vpu981_av1_tile_log2(int target)
-{
-	int k;
-
-	/*
-	 * returns the smallest value for k such that 1 << k is greater
-	 * than or equal to target
-	 */
-	for (k = 0; (1 << k) < target; k++);
-
-	return k;
-}
-
 static void rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx)
 {
 	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
 	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
 	const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info;
-	const struct v4l2_ctrl_av1_tile_group_entry *group_entry =
-	    ctrls->tile_group_entry;
 	int context_update_y =
 	    tile_info->context_update_tile_id / tile_info->tile_cols;
 	int context_update_x =
 	    tile_info->context_update_tile_id % tile_info->tile_cols;
 	int context_update_tile_id =
 	    context_update_x * tile_info->tile_rows + context_update_y;
-	u8 *dst = av1_dec->tile_info.cpu;
 	struct hantro_dev *vpu = ctx->dev;
-	int tile0, tile1;
-
-	memset(dst, 0, av1_dec->tile_info.size);
-
-	for (tile0 = 0; tile0 < tile_info->tile_cols; tile0++) {
-		for (tile1 = 0; tile1 < tile_info->tile_rows; tile1++) {
-			int tile_id = tile1 * tile_info->tile_cols + tile0;
-			u32 start, end;
-			u32 y0 =
-			    tile_info->height_in_sbs_minus_1[tile1] + 1;
-			u32 x0 = tile_info->width_in_sbs_minus_1[tile0] + 1;
-
-			/* tile size in SB units (width,height) */
-			*dst++ = x0;
-			*dst++ = 0;
-			*dst++ = 0;
-			*dst++ = 0;
-			*dst++ = y0;
-			*dst++ = 0;
-			*dst++ = 0;
-			*dst++ = 0;
-
-			/* tile start position */
-			start = group_entry[tile_id].tile_offset - group_entry[0].tile_offset;
-			*dst++ = start & 255;
-			*dst++ = (start >> 8) & 255;
-			*dst++ = (start >> 16) & 255;
-			*dst++ = (start >> 24) & 255;
-
-			/* number of bytes in tile data */
-			end = start + group_entry[tile_id].tile_size;
-			*dst++ = end & 255;
-			*dst++ = (end >> 8) & 255;
-			*dst++ = (end >> 16) & 255;
-			*dst++ = (end >> 24) & 255;
-		}
-	}
+
+	hantro_av1_set_tile_info(ctx);
 
 	hantro_reg_write(vpu, &av1_multicore_expect_context_update, !!(context_update_x == 0));
 	hantro_reg_write(vpu, &av1_tile_enable,
@@ -631,8 +44,8 @@ static void rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx)
 	hantro_reg_write(vpu, &av1_num_tile_rows_8k, tile_info->tile_rows);
 	hantro_reg_write(vpu, &av1_context_update_tile_id, context_update_tile_id);
 	hantro_reg_write(vpu, &av1_tile_transpose, 1);
-	if (rockchip_vpu981_av1_tile_log2(tile_info->tile_cols) ||
-	    rockchip_vpu981_av1_tile_log2(tile_info->tile_rows))
+	if (hantro_av1_tile_log2(tile_info->tile_cols) ||
+	    hantro_av1_tile_log2(tile_info->tile_rows))
 		hantro_reg_write(vpu, &av1_dec_tile_size_mag, tile_info->tile_size_bytes - 1);
 	else
 		hantro_reg_write(vpu, &av1_dec_tile_size_mag, 3);
@@ -640,50 +53,6 @@ static void rockchip_vpu981_av1_dec_set_tile_info(struct hantro_ctx *ctx)
 	hantro_write_addr(vpu, AV1_TILE_BASE, av1_dec->tile_info.dma);
 }
 
-static int rockchip_vpu981_av1_dec_get_dist(struct hantro_ctx *ctx,
-					    int a, int b)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	int bits = ctrls->sequence->order_hint_bits - 1;
-	int diff, m;
-
-	if (!ctrls->sequence->order_hint_bits)
-		return 0;
-
-	diff = a - b;
-	m = 1 << bits;
-	diff = (diff & (m - 1)) - (diff & m);
-
-	return diff;
-}
-
-static void rockchip_vpu981_av1_dec_set_frame_sign_bias(struct hantro_ctx *ctx)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
-	const struct v4l2_ctrl_av1_sequence *sequence = ctrls->sequence;
-	int i;
-
-	if (!sequence->order_hint_bits || IS_INTRA(frame->frame_type)) {
-		for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME; i++)
-			av1_dec->ref_frame_sign_bias[i] = 0;
-
-		return;
-	}
-	// Identify the nearest forward and backward references.
-	for (i = 0; i < V4L2_AV1_TOTAL_REFS_PER_FRAME - 1; i++) {
-		if (rockchip_vpu981_get_frame_index(ctx, i) >= 0) {
-			int rel_off =
-			    rockchip_vpu981_av1_dec_get_dist(ctx,
-							     rockchip_vpu981_get_order_hint(ctx, i),
-							     frame->order_hint);
-			av1_dec->ref_frame_sign_bias[i + 1] = (rel_off <= 0) ? 0 : 1;
-		}
-	}
-}
-
 static bool
 rockchip_vpu981_av1_dec_set_ref(struct hantro_ctx *ctx, int ref, int idx,
 				int width, int height)
@@ -806,12 +175,12 @@ static void rockchip_vpu981_av1_dec_set_segmentation(struct hantro_ctx *ctx)
 
 	if (!!(seg->flags & V4L2_AV1_SEGMENTATION_FLAG_ENABLED) &&
 	    frame->primary_ref_frame < V4L2_AV1_REFS_PER_FRAME) {
-		int idx = rockchip_vpu981_get_frame_index(ctx, frame->primary_ref_frame);
+		int idx = hantro_av1_get_frame_index(ctx, frame->primary_ref_frame);
 
 		if (idx >= 0) {
 			dma_addr_t luma_addr, mv_addr = 0;
 			struct hantro_decoded_buffer *seg;
-			size_t mv_offset = rockchip_vpu981_av1_dec_chroma_size(ctx);
+			size_t mv_offset = hantro_av1_chroma_size(ctx);
 
 			seg = vb2_to_hantro_decoded_buf(&av1_dec->frame_refs[idx].vb2_ref->vb2_buf);
 			luma_addr = hantro_get_dec_buf_addr(ctx, &seg->base.vb.vb2_buf);
@@ -1041,35 +410,6 @@ static void rockchip_vpu981_av1_dec_set_segmentation(struct hantro_ctx *ctx)
 			 segval[7][V4L2_AV1_SEG_LVL_REF_GLOBALMV]);
 }
 
-static bool rockchip_vpu981_av1_dec_is_lossless(struct hantro_ctx *ctx)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
-	const struct v4l2_av1_segmentation *segmentation = &frame->segmentation;
-	const struct v4l2_av1_quantization *quantization = &frame->quantization;
-	int i;
-
-	for (i = 0; i < V4L2_AV1_MAX_SEGMENTS; i++) {
-		int qindex = quantization->base_q_idx;
-
-		if (segmentation->feature_enabled[i] &
-		    V4L2_AV1_SEGMENT_FEATURE_ENABLED(V4L2_AV1_SEG_LVL_ALT_Q)) {
-			qindex += segmentation->feature_data[i][V4L2_AV1_SEG_LVL_ALT_Q];
-		}
-		qindex = clamp(qindex, 0, 255);
-
-		if (qindex ||
-		    quantization->delta_q_y_dc ||
-		    quantization->delta_q_u_dc ||
-		    quantization->delta_q_u_ac ||
-		    quantization->delta_q_v_dc ||
-		    quantization->delta_q_v_ac)
-			return false;
-	}
-	return true;
-}
-
 static void rockchip_vpu981_av1_dec_set_loopfilter(struct hantro_ctx *ctx)
 {
 	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
@@ -1089,7 +429,7 @@ static void rockchip_vpu981_av1_dec_set_loopfilter(struct hantro_ctx *ctx)
 	hantro_reg_write(vpu, &av1_filt_level3, loop_filter->level[3]);
 
 	if (loop_filter->flags & V4L2_AV1_LOOP_FILTER_FLAG_DELTA_ENABLED &&
-	    !rockchip_vpu981_av1_dec_is_lossless(ctx) &&
+	    !hantro_av1_is_lossless(ctx) &&
 	    !(frame->flags & V4L2_AV1_FRAME_FLAG_ALLOW_INTRABC)) {
 		hantro_reg_write(vpu, &av1_filt_ref_adj_0,
 				 loop_filter->ref_deltas[0]);
@@ -1128,112 +468,23 @@ static void rockchip_vpu981_av1_dec_set_loopfilter(struct hantro_ctx *ctx)
 	hantro_write_addr(vpu, AV1_DB_CTRL_COL, av1_dec->db_ctrl_col.dma);
 }
 
-static void rockchip_vpu981_av1_dec_update_prob(struct hantro_ctx *ctx)
-{
-	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
-	bool frame_is_intra = IS_INTRA(frame->frame_type);
-	struct av1cdfs *out_cdfs = (struct av1cdfs *)av1_dec->prob_tbl_out.cpu;
-	int i;
-
-	if (frame->flags & V4L2_AV1_FRAME_FLAG_DISABLE_FRAME_END_UPDATE_CDF)
-		return;
-
-	for (i = 0; i < NUM_REF_FRAMES; i++) {
-		if (frame->refresh_frame_flags & BIT(i)) {
-			struct mvcdfs stored_mv_cdf;
-
-			rockchip_av1_get_cdfs(ctx, i);
-			stored_mv_cdf = av1_dec->cdfs->mv_cdf;
-			*av1_dec->cdfs = *out_cdfs;
-			if (frame_is_intra) {
-				av1_dec->cdfs->mv_cdf = stored_mv_cdf;
-				*av1_dec->cdfs_ndvc = out_cdfs->mv_cdf;
-			}
-			rockchip_av1_store_cdfs(ctx,
-						frame->refresh_frame_flags);
-			break;
-		}
-	}
-}
-
-void rockchip_vpu981_av1_dec_done(struct hantro_ctx *ctx)
-{
-	rockchip_vpu981_av1_dec_update_prob(ctx);
-}
-
 static void rockchip_vpu981_av1_dec_set_prob(struct hantro_ctx *ctx)
 {
 	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
-	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
-	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
-	const struct v4l2_av1_quantization *quantization = &frame->quantization;
 	struct hantro_dev *vpu = ctx->dev;
-	bool error_resilient_mode =
-	    !!(frame->flags & V4L2_AV1_FRAME_FLAG_ERROR_RESILIENT_MODE);
-	bool frame_is_intra = IS_INTRA(frame->frame_type);
-
-	if (error_resilient_mode || frame_is_intra ||
-	    frame->primary_ref_frame == AV1_PRIMARY_REF_NONE) {
-		av1_dec->cdfs = &av1_dec->default_cdfs;
-		av1_dec->cdfs_ndvc = &av1_dec->default_cdfs_ndvc;
-		rockchip_av1_default_coeff_probs(quantization->base_q_idx,
-						 av1_dec->cdfs);
-	} else {
-		rockchip_av1_get_cdfs(ctx, frame->ref_frame_idx[frame->primary_ref_frame]);
-	}
-	rockchip_av1_store_cdfs(ctx, frame->refresh_frame_flags);
-
-	memcpy(av1_dec->prob_tbl.cpu, av1_dec->cdfs, sizeof(struct av1cdfs));
-
-	if (frame_is_intra) {
-		int mv_offset = offsetof(struct av1cdfs, mv_cdf);
-		/* Overwrite MV context area with intrabc MV context */
-		memcpy(av1_dec->prob_tbl.cpu + mv_offset, av1_dec->cdfs_ndvc,
-		       sizeof(struct mvcdfs));
-	}
 
+	hantro_av1_set_prob(ctx);
 	hantro_write_addr(vpu, AV1_PROP_TABLE_OUT, av1_dec->prob_tbl_out.dma);
 	hantro_write_addr(vpu, AV1_PROP_TABLE, av1_dec->prob_tbl.dma);
 }
 
-static void
-rockchip_vpu981_av1_dec_init_scaling_function(const u8 *values, const u8 *scaling,
-					      u8 num_points, u8 *scaling_lut)
-{
-	int i, point;
-
-	if (num_points == 0) {
-		memset(scaling_lut, 0, 256);
-		return;
-	}
-
-	for (point = 0; point < num_points - 1; point++) {
-		int x;
-		s32 delta_y = scaling[point + 1] - scaling[point];
-		s32 delta_x = values[point + 1] - values[point];
-		s64 delta =
-		    delta_x ? delta_y * ((65536 + (delta_x >> 1)) /
-					 delta_x) : 0;
-
-		for (x = 0; x < delta_x; x++) {
-			scaling_lut[values[point] + x] =
-			    scaling[point] +
-			    (s32)((x * delta + 32768) >> 16);
-		}
-	}
-
-	for (i = values[num_points - 1]; i < 256; i++)
-		scaling_lut[i] = scaling[num_points - 1];
-}
 
 static void rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx)
 {
 	struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
 	struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
 	const struct v4l2_ctrl_av1_film_grain *film_grain = ctrls->film_grain;
-	struct rockchip_av1_film_grain *fgmem = av1_dec->film_grain.cpu;
+	struct hantro_av1_film_grain *fgmem = av1_dec->film_grain.cpu;
 	struct hantro_dev *vpu = ctx->dev;
 	bool scaling_from_luma =
 		!!(film_grain->flags & V4L2_AV1_FILM_GRAIN_FLAG_CHROMA_SCALING_FROM_LUMA);
@@ -1316,10 +567,10 @@ static void rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx)
 	hantro_reg_write(vpu, &av1_chroma_scaling_from_luma, scaling_from_luma);
 	hantro_reg_write(vpu, &av1_random_seed, film_grain->grain_seed);
 
-	rockchip_vpu981_av1_dec_init_scaling_function(film_grain->point_y_value,
-						      film_grain->point_y_scaling,
-						      film_grain->num_y_points,
-						      fgmem->scaling_lut_y);
+	hantro_av1_init_scaling_function(film_grain->point_y_value,
+					 film_grain->point_y_scaling,
+					 film_grain->num_y_points,
+					 fgmem->scaling_lut_y);
 
 	if (film_grain->flags &
 	    V4L2_AV1_FILM_GRAIN_FLAG_CHROMA_SCALING_FROM_LUMA) {
@@ -1328,10 +579,10 @@ static void rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx)
 		memcpy(fgmem->scaling_lut_cr, fgmem->scaling_lut_y,
 		       sizeof(*fgmem->scaling_lut_y) * 256);
 	} else {
-		rockchip_vpu981_av1_dec_init_scaling_function
+		hantro_av1_init_scaling_function
 		    (film_grain->point_cb_value, film_grain->point_cb_scaling,
 		     film_grain->num_cb_points, fgmem->scaling_lut_cb);
-		rockchip_vpu981_av1_dec_init_scaling_function
+		hantro_av1_init_scaling_function
 		    (film_grain->point_cr_value, film_grain->point_cr_scaling,
 		     film_grain->num_cr_points, fgmem->scaling_lut_cr);
 	}
@@ -1351,21 +602,21 @@ static void rockchip_vpu981_av1_dec_set_fgs(struct hantro_ctx *ctx)
 	grain_min = 0 - grain_center;
 	grain_max = (256 << (bitdepth - 8)) - 1 - grain_center;
 
-	rockchip_av1_generate_luma_grain_block(luma_grain_block, bitdepth,
-					       film_grain->num_y_points, grain_scale_shift,
-					       ar_coeff_lag, ar_coeffs_y, ar_coeff_shift,
-					       grain_min, grain_max, film_grain->grain_seed);
-
-	rockchip_av1_generate_chroma_grain_block(luma_grain_block, cb_grain_block,
-						 cr_grain_block, bitdepth,
-						 film_grain->num_y_points,
-						 film_grain->num_cb_points,
-						 film_grain->num_cr_points,
-						 grain_scale_shift, ar_coeff_lag, ar_coeffs_cb,
-						 ar_coeffs_cr, ar_coeff_shift, grain_min,
-						 grain_max,
-						 scaling_from_luma,
-						 film_grain->grain_seed);
+	hantro_av1_generate_luma_grain_block(luma_grain_block, bitdepth,
+					     film_grain->num_y_points, grain_scale_shift,
+					     ar_coeff_lag, ar_coeffs_y, ar_coeff_shift,
+					     grain_min, grain_max, film_grain->grain_seed);
+
+	hantro_av1_generate_chroma_grain_block(luma_grain_block, cb_grain_block,
+					       cr_grain_block, bitdepth,
+					       film_grain->num_y_points,
+					       film_grain->num_cb_points,
+					       film_grain->num_cr_points,
+					       grain_scale_shift, ar_coeff_lag, ar_coeffs_cb,
+					       ar_coeffs_cr, ar_coeff_shift, grain_min,
+					       grain_max,
+					       scaling_from_luma,
+					       film_grain->grain_seed);
 
 	for (i = 0; i < 64; i++) {
 		for (j = 0; j < 64; j++)
@@ -1617,12 +868,12 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 	int ref_ind = 0;
 	int rf, idx;
 
-	alt_frame_offset = rockchip_vpu981_get_order_hint(ctx, ALT_BUF_IDX);
-	gld_frame_offset = rockchip_vpu981_get_order_hint(ctx, GLD_BUF_IDX);
-	bwd_frame_offset = rockchip_vpu981_get_order_hint(ctx, BWD_BUF_IDX);
-	alt2_frame_offset = rockchip_vpu981_get_order_hint(ctx, ALT2_BUF_IDX);
+	alt_frame_offset = hantro_av1_get_order_hint(ctx, ALT_BUF_IDX);
+	gld_frame_offset = hantro_av1_get_order_hint(ctx, GLD_BUF_IDX);
+	bwd_frame_offset = hantro_av1_get_order_hint(ctx, BWD_BUF_IDX);
+	alt2_frame_offset = hantro_av1_get_order_hint(ctx, ALT2_BUF_IDX);
 
-	idx = rockchip_vpu981_get_frame_index(ctx, LST_BUF_IDX);
+	idx = hantro_av1_get_frame_index(ctx, LST_BUF_IDX);
 	if (idx >= 0) {
 		int alt_frame_offset_in_lst =
 			av1_dec->frame_refs[idx].order_hints[V4L2_AV1_REF_ALTREF_FRAME];
@@ -1644,8 +895,8 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 		ref_stamp--;
 	}
 
-	idx = rockchip_vpu981_get_frame_index(ctx, BWD_BUF_IDX);
-	if (rockchip_vpu981_av1_dec_get_dist(ctx, bwd_frame_offset, cur_frame_offset) > 0) {
+	idx = hantro_av1_get_frame_index(ctx, BWD_BUF_IDX);
+	if (hantro_av1_get_dist(ctx, bwd_frame_offset, cur_frame_offset) > 0) {
 		int bwd_mi_cols = av1_dec->frame_refs[idx].mi_cols;
 		int bwd_mi_rows = av1_dec->frame_refs[idx].mi_rows;
 		bool bwd_intra_only =
@@ -1659,8 +910,8 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 		}
 	}
 
-	idx = rockchip_vpu981_get_frame_index(ctx, ALT2_BUF_IDX);
-	if (rockchip_vpu981_av1_dec_get_dist(ctx, alt2_frame_offset, cur_frame_offset) > 0) {
+	idx = hantro_av1_get_frame_index(ctx, ALT2_BUF_IDX);
+	if (hantro_av1_get_dist(ctx, alt2_frame_offset, cur_frame_offset) > 0) {
 		int alt2_mi_cols = av1_dec->frame_refs[idx].mi_cols;
 		int alt2_mi_rows = av1_dec->frame_refs[idx].mi_rows;
 		bool alt2_intra_only =
@@ -1674,8 +925,8 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 		}
 	}
 
-	idx = rockchip_vpu981_get_frame_index(ctx, ALT_BUF_IDX);
-	if (rockchip_vpu981_av1_dec_get_dist(ctx, alt_frame_offset, cur_frame_offset) > 0 &&
+	idx = hantro_av1_get_frame_index(ctx, ALT_BUF_IDX);
+	if (hantro_av1_get_dist(ctx, alt_frame_offset, cur_frame_offset) > 0 &&
 	    ref_stamp >= 0) {
 		int alt_mi_cols = av1_dec->frame_refs[idx].mi_cols;
 		int alt_mi_rows = av1_dec->frame_refs[idx].mi_rows;
@@ -1690,7 +941,7 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 		}
 	}
 
-	idx = rockchip_vpu981_get_frame_index(ctx, LST2_BUF_IDX);
+	idx = hantro_av1_get_frame_index(ctx, LST2_BUF_IDX);
 	if (idx >= 0 && ref_stamp >= 0) {
 		int lst2_mi_cols = av1_dec->frame_refs[idx].mi_cols;
 		int lst2_mi_rows = av1_dec->frame_refs[idx].mi_rows;
@@ -1706,14 +957,14 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 	}
 
 	for (rf = 0; rf < V4L2_AV1_TOTAL_REFS_PER_FRAME - 1; ++rf) {
-		idx = rockchip_vpu981_get_frame_index(ctx, rf);
+		idx = hantro_av1_get_frame_index(ctx, rf);
 		if (idx >= 0) {
-			int rf_order_hint = rockchip_vpu981_get_order_hint(ctx, rf);
+			int rf_order_hint = hantro_av1_get_order_hint(ctx, rf);
 
 			cur_offset[rf] =
-			    rockchip_vpu981_av1_dec_get_dist(ctx, cur_frame_offset, rf_order_hint);
+			    hantro_av1_get_dist(ctx, cur_frame_offset, rf_order_hint);
 			cur_roffset[rf] =
-			    rockchip_vpu981_av1_dec_get_dist(ctx, rf_order_hint, cur_frame_offset);
+			    hantro_av1_get_dist(ctx, rf_order_hint, cur_frame_offset);
 		} else {
 			cur_offset[rf] = 0;
 			cur_roffset[rf] = 0;
@@ -1736,32 +987,32 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 	if (use_ref_frame_mvs && ref_ind > 0 &&
 	    cur_offset[mf_types[0] - V4L2_AV1_REF_LAST_FRAME] <= MAX_FRAME_DISTANCE &&
 	    cur_offset[mf_types[0] - V4L2_AV1_REF_LAST_FRAME] >= -MAX_FRAME_DISTANCE) {
-		int rf = rockchip_vpu981_get_order_hint(ctx, refs_selected[0]);
-		int idx = rockchip_vpu981_get_frame_index(ctx, refs_selected[0]);
+		int rf = hantro_av1_get_order_hint(ctx, refs_selected[0]);
+		int idx = hantro_av1_get_frame_index(ctx, refs_selected[0]);
 		u32 *oh = av1_dec->frame_refs[idx].order_hints;
 		int val;
 
 		hantro_reg_write(vpu, &av1_use_temporal0_mvs, 1);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST_FRAME]);
 		hantro_reg_write(vpu, &av1_mf1_last_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST2_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST2_FRAME]);
 		hantro_reg_write(vpu, &av1_mf1_last2_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST3_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST3_FRAME]);
 		hantro_reg_write(vpu, &av1_mf1_last3_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_GOLDEN_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_GOLDEN_FRAME]);
 		hantro_reg_write(vpu, &av1_mf1_golden_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_BWDREF_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_BWDREF_FRAME]);
 		hantro_reg_write(vpu, &av1_mf1_bwdref_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF2_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF2_FRAME]);
 		hantro_reg_write(vpu, &av1_mf1_altref2_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF_FRAME]);
 		hantro_reg_write(vpu, &av1_mf1_altref_offset, val);
 	}
 
@@ -1776,32 +1027,32 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 	if (use_ref_frame_mvs && ref_ind > 1 &&
 	    cur_offset[mf_types[1] - V4L2_AV1_REF_LAST_FRAME] <= MAX_FRAME_DISTANCE &&
 	    cur_offset[mf_types[1] - V4L2_AV1_REF_LAST_FRAME] >= -MAX_FRAME_DISTANCE) {
-		int rf = rockchip_vpu981_get_order_hint(ctx, refs_selected[1]);
-		int idx = rockchip_vpu981_get_frame_index(ctx, refs_selected[1]);
+		int rf = hantro_av1_get_order_hint(ctx, refs_selected[1]);
+		int idx = hantro_av1_get_frame_index(ctx, refs_selected[1]);
 		u32 *oh = av1_dec->frame_refs[idx].order_hints;
 		int val;
 
 		hantro_reg_write(vpu, &av1_use_temporal1_mvs, 1);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST_FRAME]);
 		hantro_reg_write(vpu, &av1_mf2_last_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST2_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST2_FRAME]);
 		hantro_reg_write(vpu, &av1_mf2_last2_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST3_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST3_FRAME]);
 		hantro_reg_write(vpu, &av1_mf2_last3_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_GOLDEN_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_GOLDEN_FRAME]);
 		hantro_reg_write(vpu, &av1_mf2_golden_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_BWDREF_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_BWDREF_FRAME]);
 		hantro_reg_write(vpu, &av1_mf2_bwdref_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF2_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF2_FRAME]);
 		hantro_reg_write(vpu, &av1_mf2_altref2_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF_FRAME]);
 		hantro_reg_write(vpu, &av1_mf2_altref_offset, val);
 	}
 
@@ -1816,32 +1067,32 @@ static void rockchip_vpu981_av1_dec_set_other_frames(struct hantro_ctx *ctx)
 	if (use_ref_frame_mvs && ref_ind > 2 &&
 	    cur_offset[mf_types[2] - V4L2_AV1_REF_LAST_FRAME] <= MAX_FRAME_DISTANCE &&
 	    cur_offset[mf_types[2] - V4L2_AV1_REF_LAST_FRAME] >= -MAX_FRAME_DISTANCE) {
-		int rf = rockchip_vpu981_get_order_hint(ctx, refs_selected[2]);
-		int idx = rockchip_vpu981_get_frame_index(ctx, refs_selected[2]);
+		int rf = hantro_av1_get_order_hint(ctx, refs_selected[2]);
+		int idx = hantro_av1_get_frame_index(ctx, refs_selected[2]);
 		u32 *oh = av1_dec->frame_refs[idx].order_hints;
 		int val;
 
 		hantro_reg_write(vpu, &av1_use_temporal2_mvs, 1);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST_FRAME]);
 		hantro_reg_write(vpu, &av1_mf3_last_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST2_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST2_FRAME]);
 		hantro_reg_write(vpu, &av1_mf3_last2_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST3_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_LAST3_FRAME]);
 		hantro_reg_write(vpu, &av1_mf3_last3_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_GOLDEN_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_GOLDEN_FRAME]);
 		hantro_reg_write(vpu, &av1_mf3_golden_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_BWDREF_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_BWDREF_FRAME]);
 		hantro_reg_write(vpu, &av1_mf3_bwdref_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF2_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF2_FRAME]);
 		hantro_reg_write(vpu, &av1_mf3_altref2_offset, val);
 
-		val = rockchip_vpu981_av1_dec_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF_FRAME]);
+		val = hantro_av1_get_dist(ctx, rf, oh[V4L2_AV1_REF_ALTREF_FRAME]);
 		hantro_reg_write(vpu, &av1_mf3_altref_offset, val);
 	}
 
@@ -1883,7 +1134,7 @@ static void rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx)
 
 	if (!allow_intrabc) {
 		for (i = 0; i < V4L2_AV1_REFS_PER_FRAME; i++) {
-			int idx = rockchip_vpu981_get_frame_index(ctx, i);
+			int idx = hantro_av1_get_frame_index(ctx, i);
 
 			if (idx >= 0)
 				ref_count[idx]++;
@@ -1898,7 +1149,7 @@ static void rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx)
 	}
 	hantro_reg_write(vpu, &av1_ref_frames, ref_frames);
 
-	rockchip_vpu981_av1_dec_set_frame_sign_bias(ctx);
+	hantro_av1_set_frame_sign_bias(ctx);
 
 	for (i = V4L2_AV1_REF_LAST_FRAME; i < V4L2_AV1_TOTAL_REFS_PER_FRAME; i++) {
 		u32 ref = i - 1;
@@ -1910,8 +1161,8 @@ static void rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx)
 			width = frame->frame_width_minus_1 + 1;
 			height = frame->frame_height_minus_1 + 1;
 		} else {
-			if (rockchip_vpu981_get_frame_index(ctx, ref) > 0)
-				idx = rockchip_vpu981_get_frame_index(ctx, ref);
+			if (hantro_av1_get_frame_index(ctx, ref) > 0)
+				idx = hantro_av1_get_frame_index(ctx, ref);
 			width = av1_dec->frame_refs[idx].width;
 			height = av1_dec->frame_refs[idx].height;
 		}
@@ -1943,20 +1194,6 @@ static void rockchip_vpu981_av1_dec_set_reference_frames(struct hantro_ctx *ctx)
 	rockchip_vpu981_av1_dec_set_other_frames(ctx);
 }
 
-static int rockchip_vpu981_av1_get_hardware_tx_mode(enum v4l2_av1_tx_mode tx_mode)
-{
-	switch (tx_mode) {
-	case V4L2_AV1_TX_MODE_ONLY_4X4:
-		return ROCKCHIP_AV1_TX_MODE_ONLY_4X4;
-	case V4L2_AV1_TX_MODE_LARGEST:
-		return ROCKCHIP_AV1_TX_MODE_32x32;
-	case V4L2_AV1_TX_MODE_SELECT:
-		return ROCKCHIP_AV1_TX_MODE_SELECT;
-	}
-
-	return ROCKCHIP_AV1_TX_MODE_32x32;
-}
-
 static void rockchip_vpu981_av1_dec_set_parameters(struct hantro_ctx *ctx)
 {
 	struct hantro_dev *vpu = ctx->dev;
@@ -2029,7 +1266,7 @@ static void rockchip_vpu981_av1_dec_set_parameters(struct hantro_ctx *ctx)
 	hantro_reg_write(vpu, &av1_comp_pred_mode,
 			 (ctrls->frame->flags & V4L2_AV1_FRAME_FLAG_REFERENCE_SELECT) ? 2 : 0);
 
-	tx_mode = rockchip_vpu981_av1_get_hardware_tx_mode(ctrls->frame->tx_mode);
+	tx_mode = hantro_av1_get_hardware_tx_mode(ctrls->frame->tx_mode);
 	hantro_reg_write(vpu, &av1_transform_mode, tx_mode);
 	hantro_reg_write(vpu, &av1_max_cb_size,
 			 (ctrls->sequence->flags
@@ -2061,7 +1298,7 @@ static void rockchip_vpu981_av1_dec_set_parameters(struct hantro_ctx *ctx)
 		hantro_reg_write(vpu, &av1_qmlevel_v, 0xff);
 	}
 
-	hantro_reg_write(vpu, &av1_lossless_e, rockchip_vpu981_av1_dec_is_lossless(ctx));
+	hantro_reg_write(vpu, &av1_lossless_e, hantro_av1_is_lossless(ctx));
 	hantro_reg_write(vpu, &av1_quant_delta_v_dc, ctrls->frame->quantization.delta_q_v_dc);
 	hantro_reg_write(vpu, &av1_quant_delta_v_ac, ctrls->frame->quantization.delta_q_v_ac);
 
@@ -2109,8 +1346,8 @@ rockchip_vpu981_av1_dec_set_output_buffer(struct hantro_ctx *ctx)
 	struct hantro_decoded_buffer *dst;
 	struct vb2_v4l2_buffer *vb2_dst;
 	dma_addr_t luma_addr, chroma_addr, mv_addr = 0;
-	size_t cr_offset = rockchip_vpu981_av1_dec_luma_size(ctx);
-	size_t mv_offset = rockchip_vpu981_av1_dec_chroma_size(ctx);
+	size_t cr_offset = hantro_av1_luma_size(ctx);
+	size_t mv_offset = hantro_av1_chroma_size(ctx);
 
 	vb2_dst = av1_dec->frame_refs[av1_dec->current_frame_index].vb2_ref;
 	dst = vb2_to_hantro_decoded_buf(&vb2_dst->vb2_buf);
@@ -2134,7 +1371,7 @@ int rockchip_vpu981_av1_dec_run(struct hantro_ctx *ctx)
 
 	hantro_start_prepare_run(ctx);
 
-	ret = rockchip_vpu981_av1_dec_prepare_run(ctx);
+	ret = hantro_av1_prepare_run(ctx);
 	if (ret)
 		goto prepare_error;
 
@@ -2144,8 +1381,8 @@ int rockchip_vpu981_av1_dec_run(struct hantro_ctx *ctx)
 		goto prepare_error;
 	}
 
-	rockchip_vpu981_av1_dec_clean_refs(ctx);
-	rockchip_vpu981_av1_dec_frame_ref(ctx, vb2_src->vb2_buf.timestamp);
+	hantro_av1_clean_refs(ctx);
+	hantro_av1_frame_ref(ctx, vb2_src->vb2_buf.timestamp);
 
 	rockchip_vpu981_av1_dec_set_parameters(ctx);
 	rockchip_vpu981_av1_dec_set_global_model(ctx);
diff --git a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c
index 02673be9878e..f50a3e38097e 100644
--- a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 
 #include "hantro.h"
+#include "hantro_av1.h"
 #include "hantro_jpeg.h"
 #include "hantro_g1_regs.h"
 #include "hantro_h1_regs.h"
@@ -608,9 +609,9 @@ static const struct hantro_codec_ops rk3568_vepu_codec_ops[] = {
 static const struct hantro_codec_ops rk3588_vpu981_codec_ops[] = {
 	[HANTRO_MODE_AV1_DEC] = {
 		.run = rockchip_vpu981_av1_dec_run,
-		.init = rockchip_vpu981_av1_dec_init,
-		.exit = rockchip_vpu981_av1_dec_exit,
-		.done = rockchip_vpu981_av1_dec_done,
+		.init = hantro_av1_init,
+		.exit = hantro_av1_exit,
+		.done = hantro_av1_update_prob,
 	},
 };
 /*
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH 05/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
From: Mukesh Ojha @ 2026-04-15  7:36 UTC (permalink / raw)
  To: Vishnu Reddy
  Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
	Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
	Hans Verkuil, linux-media, linux-arm-msm, devicetree,
	linux-kernel, iommu
In-Reply-To: <20260414063128.6ass64wfi7nmtzti@hu-mojha-hyd.qualcomm.com>

On Tue, Apr 14, 2026 at 12:01:28PM +0530, Mukesh Ojha wrote:
> On Tue, Apr 14, 2026 at 10:30:01AM +0530, Vishnu Reddy wrote:
> > From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > 
> > Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> > or QHEE), which typically handles IOMMU configuration. This includes
> > mapping memory regions and device memory resources for remote processors
> > by intercepting qcom_scm_pas_auth_and_reset() calls. These mappings are
> > later removed during teardown. Additionally, SHM bridge setup is required
> > to enable memory protection for both remoteproc metadata and its memory
> > regions.
> > 
> > When the hypervisor is absent, the operating system must perform these
> > configurations instead.
> > 
> > Support for handling IOMMU and SHM setup in the absence of a hypervisor
> > is now in place. Extend the Iris driver to enable this functionality on
> > platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
> > 
> > Additionally, the Iris driver must map the firmware and its required
> > resources to the firmware SID, which is now specified via iommu-map in
> > the device tree.
> > 
> > Co-developed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> > ---
> >  drivers/media/platform/qcom/iris/iris_core.h     |  4 ++
> >  drivers/media/platform/qcom/iris/iris_firmware.c | 71 +++++++++++++++++++++---
> >  2 files changed, 66 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
> > index fb194c967ad4..aa7abef6f0e0 100644
> > --- a/drivers/media/platform/qcom/iris/iris_core.h
> > +++ b/drivers/media/platform/qcom/iris/iris_core.h
> > @@ -34,6 +34,8 @@ enum domain_type {
> >   * struct iris_core - holds core parameters valid for all instances
> >   *
> >   * @dev: reference to device structure
> > + * @dev_fw: reference to the context bank device used for firmware load
> > + * @ctx_fw: SCM PAS context for authenticated firmware load and shutdown
> >   * @reg_base: IO memory base address
> >   * @irq: iris irq
> >   * @v4l2_dev: a holder for v4l2 device structure
> > @@ -77,6 +79,8 @@ enum domain_type {
> >  
> >  struct iris_core {
> >  	struct device				*dev;
> > +	struct device				*dev_fw;
> > +	struct qcom_scm_pas_context		*ctx_fw;
> 
> fw_dev suits better and ctx_fw is always for firmware, maybe pas_ctx is
> better.
> 
> >  	void __iomem				*reg_base;
> >  	int					irq;
> >  	struct v4l2_device			v4l2_dev;
> > diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c
> > index 5f408024e967..93d77996c83f 100644
> > --- a/drivers/media/platform/qcom/iris/iris_firmware.c
> > +++ b/drivers/media/platform/qcom/iris/iris_firmware.c
> > @@ -5,6 +5,7 @@
> >  
> >  #include <linux/firmware.h>
> >  #include <linux/firmware/qcom/qcom_scm.h>
> > +#include <linux/iommu.h>
> >  #include <linux/of_address.h>
> >  #include <linux/of_reserved_mem.h>
> >  #include <linux/soc/qcom/mdt_loader.h>
> > @@ -13,12 +14,15 @@
> >  #include "iris_firmware.h"
> >  
> >  #define MAX_FIRMWARE_NAME_SIZE	128
> > +#define IRIS_FW_START_ADDR	0
> >  
> >  static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> >  {
> > +	struct device *dev = core->dev_fw ? core->dev_fw : core->dev;
> >  	u32 pas_id = core->iris_platform_data->pas_id;
> >  	const struct firmware *firmware = NULL;
> > -	struct device *dev = core->dev;
> > +	struct qcom_scm_pas_context *ctx_fw;
> > +	struct iommu_domain *domain;
> >  	struct resource res;
> >  	phys_addr_t mem_phys;
> >  	size_t res_size;
> > @@ -29,13 +33,17 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> >  	if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
> >  		return -EINVAL;
> >  
> > -	ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);
> > +	ret = of_reserved_mem_region_to_resource(core->dev->of_node, 0, &res);
> >  	if (ret)
> >  		return ret;
> >  
> >  	mem_phys = res.start;
> >  	res_size = resource_size(&res);
> >  
> > +	ctx_fw = devm_qcom_scm_pas_context_alloc(dev, pas_id, mem_phys, res_size);
> > +	if (IS_ERR(ctx_fw))
> > +		return PTR_ERR(ctx_fw);
> > +
> >  	ret = request_firmware(&firmware, fw_name, dev);
> >  	if (ret)
> >  		return ret;
> > @@ -52,9 +60,27 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> >  		goto err_release_fw;
> >  	}
> >  
> > -	ret = qcom_mdt_load(dev, firmware, fw_name,
> > -			    pas_id, mem_virt, mem_phys, res_size, NULL);
> > +	ctx_fw->use_tzmem = !!core->dev_fw;
> > +	ret = qcom_mdt_pas_load(ctx_fw, firmware, fw_name, mem_virt, NULL);

We need to release the metadata because this is the change compared to
the previous qcom_mdt_load() API, which silently released DMA memory for
metadata in the pas_init SCM call for clients that passed metadata ctx
as NULL. Since with this new API every new client must pass the new pas
ctx, it cannot be NULL anymore. I intended to document this clearly when
introducing qcom_mdt_pas_load() API, but I did not do so. but thinking
it over again, we should not be asking client to release the memory
which they not allocated, so let me write a patch for this where I
client like remoteproc explicitly ask or set it if they do not want to
release this memory as their XPU locked and can only released after auth
and reset successful.


> > +	if (ret)
> > +
> > +	if (ctx_fw->use_tzmem) {
> > +		domain = iommu_get_domain_for_dev(core->dev_fw);
> > +		if (!domain) {
> > +			ret = -ENODEV;
> > +			goto err_mem_unmap;
> > +		}
> > +
> > +		ret = iommu_map(domain, IRIS_FW_START_ADDR, mem_phys, res_size,
> > +				IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL);
> > +		if (ret)
> > +			goto err_mem_unmap;
> > +	}
> >  
> > +	core->ctx_fw = ctx_fw;
> > +
> > +err_mem_unmap:
> >  	memunmap(mem_virt);
> >  err_release_fw:
> >  	release_firmware(firmware);
> > @@ -62,6 +88,19 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name)
> >  	return ret;
> >  }
> >  
> > +static void iris_fw_iommu_unmap(struct iris_core *core)
> > +{
> > +	bool use_tzmem = core->ctx_fw->use_tzmem;
> > +	struct iommu_domain *domain;
> > +
> > +	if (!use_tzmem)
> > +		return;
> > +
> > +	domain = iommu_get_domain_for_dev(core->dev_fw);
> > +	if (domain)
> > +		iommu_unmap(domain, IRIS_FW_START_ADDR, core->ctx_fw->mem_size);
> > +}
> > +
> >  int iris_fw_load(struct iris_core *core)
> >  {
> >  	const struct tz_cp_config *cp_config;
> > @@ -79,10 +118,10 @@ int iris_fw_load(struct iris_core *core)
> >  		return -ENOMEM;
> >  	}
> >  
> > -	ret = qcom_scm_pas_auth_and_reset(core->iris_platform_data->pas_id);
> > +	ret = qcom_scm_pas_prepare_and_auth_reset(core->ctx_fw);
> >  	if (ret)  {
> >  		dev_err(core->dev, "auth and reset failed: %d\n", ret);
> > -		return ret;
> > +		goto err_unmap;
> >  	}
> >  
> >  	for (i = 0; i < core->iris_platform_data->tz_cp_config_data_size; i++) {
> > @@ -93,17 +132,31 @@ int iris_fw_load(struct iris_core *core)
> >  						     cp_config->cp_nonpixel_size);
> >  		if (ret) {
> >  			dev_err(core->dev, "qcom_scm_mem_protect_video_var failed: %d\n", ret);
> > -			qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> > -			return ret;
> > +			goto err_pas_shutdown;
> >  		}
> >  	}
> >  
> > +	return 0;
> > +
> > +err_pas_shutdown:
> > +	qcom_scm_pas_shutdown(core->ctx_fw->pas_id);
> > +err_unmap:
> > +	iris_fw_iommu_unmap(core);
> > +
> >  	return ret;
> >  }
> >  
> >  int iris_fw_unload(struct iris_core *core)
> >  {
> > -	return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id);
> > +	int ret;
> > +
> > +	ret = qcom_scm_pas_shutdown(core->ctx_fw->pas_id);
> > +	if (ret)
> > +		return ret;
> > +
> > +	iris_fw_iommu_unmap(core);
> > +
> > +	return ret;
> >  }
> >  
> >  int iris_set_hw_state(struct iris_core *core, bool resume)
> > 
> > -- 
> > 2.34.1
> > 
> 
> -- 
> -Mukesh Ojha

-- 
-Mukesh Ojha

^ permalink raw reply

* Re: [PATCH RFC 6/7] media: qcom: iris: vdec: update find_format to handle 8bit and 10bit formats
From: Neil Armstrong @ 2026-04-15  7:35 UTC (permalink / raw)
  To: Vishnu Reddy, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
	Bryan O'Donoghue, Mauro Carvalho Chehab
  Cc: linux-media, linux-arm-msm, linux-kernel
In-Reply-To: <faa04229-1070-3a2f-94e6-a7e238fb8121@oss.qualcomm.com>

Hi,

On 4/15/26 08:39, Vishnu Reddy wrote:
> 
> On 4/8/2026 10:13 PM, Neil Armstrong wrote:
>> The 10bit pixel format can be only used when the decoder identifies the
>> stream as decoding into 10bit pixel format buffers, so update the
>> find_format helpers to filter the formats.
> 
> This series breaks the v4l2 compliance tests for the existing platforms.
> Decoder failed for below:
> VIDIOC_S_FMT: FAIL
> Cropping: FAIL
> Composing: FAIL
> Encoder streaming tests failed.
> Please check once.

Sure I'll run the test before posting v2.

Neil

> 
> Regards,
> Vishnu Reddy.
> 
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>>   .../platform/qcom/iris/iris_platform_common.h      |  1 +
>>   drivers/media/platform/qcom/iris/iris_vdec.c       | 41 ++++++++++++++++++++--
>>   2 files changed, 40 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> index 5a489917580e..cd3509da4b75 100644
>> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> @@ -18,6 +18,7 @@ struct iris_inst;
>>   #define REGISTER_BIT_DEPTH(luma, chroma)    ((luma) << 16 | (chroma))
>>   #define BIT_DEPTH_8                REGISTER_BIT_DEPTH(8, 8)
>> +#define BIT_DEPTH_10                REGISTER_BIT_DEPTH(10, 10)
>>   #define CODED_FRAMES_PROGRESSIVE        0x0
>>   #define DEFAULT_MAX_HOST_BUF_COUNT        64
>>   #define DEFAULT_MAX_HOST_BURST_BUF_COUNT    256
>> diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
>> index ca0518c27834..bfc13c1044c7 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vdec.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vdec.c
>> @@ -105,6 +105,16 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
>>       if (i == size || fmt[i].type != type)
>>           return NULL;
>> +    if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
>> +        if (iris_fmt_is_8bit(fmt[i].pixfmt) &&
>> +            inst->fw_caps[BIT_DEPTH].value == BIT_DEPTH_8)
>> +            return NULL;
>> +
>> +        if (iris_fmt_is_10bit(fmt[i].pixfmt) &&
>> +            inst->fw_caps[BIT_DEPTH].value != BIT_DEPTH_10)
>> +            return NULL;
>> +    }
>> +
>>       return &fmt[i];
>>   }
>> @@ -113,6 +123,7 @@ find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
>>   {
>>       const struct iris_fmt *fmt = NULL;
>>       unsigned int size = 0;
>> +    unsigned int i, k = 0;
>>       switch (type) {
>>       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
>> @@ -127,10 +138,36 @@ find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
>>           return NULL;
>>       }
>> -    if (index >= size || fmt[index].type != type)
>> +    if (index >= size)
>>           return NULL;
>> -    return &fmt[index];
>> +    if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
>> +        if (fmt[index].type != type)
>> +            return NULL;
>> +
>> +        return &fmt[index];
>> +    }
>> +
>> +    /* Loop over the valid capture formats and return the index */
>> +    for (i = 0; i < size; i++) {
>> +        if (fmt[i].type != type)
>> +            continue;
>> +
>> +        if (iris_fmt_is_8bit(fmt[i].pixfmt) &&
>> +            inst->fw_caps[BIT_DEPTH].value == BIT_DEPTH_10)
>> +            continue;
>> +
>> +        if (iris_fmt_is_10bit(fmt[i].pixfmt) &&
>> +            inst->fw_caps[BIT_DEPTH].value != BIT_DEPTH_10)
>> +            continue;
>> +
>> +        if (k == index)
>> +            return &fmt[i];
>> +
>> +        k++;
>> +    }
>> +
>> +    return NULL;
>>   }
>>   int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
>>


^ permalink raw reply

* Re: [PATCH v7 02/18] media: uapi: Add extensible param and stats blocks for RPPX1
From: Jai Luthra @ 2026-04-15  7:10 UTC (permalink / raw)
  To: Jacopo Mondi, Jai Luthra
  Cc: Mauro Carvalho Chehab, Niklas Söderlund, Geert Uytterhoeven,
	Magnus Damm, Kuninori Morimoto, linux-media, linux-kernel,
	linux-renesas-soc, Laurent Pinchart, Jacopo Mondi, Marek Vasut
In-Reply-To: <ad0F38XgZ5N_FQY7@zed>

Quoting Jacopo Mondi (2026-04-14 20:35:05)
> Hi Jai
> 
> On Fri, Apr 10, 2026 at 02:35:37PM +0530, Jai Luthra wrote:
> > Define the userspace API for the Dreamchip RPP-X1 ISP extensible
> > parameters and statistics. The RPP-X1 is functionally similar to the
> > RkISP1 already supported upstream, but operates at higher bit depths (up
> > to 24-bit precision in many blocks) and exposes additional configuration
> > options. This warrants a dedicated uAPI rather than reusing the RkISP1
> > definitions.
> >
> > The parameter blocks follow the V4L2 extensible parameters framework
> > using struct v4l2_isp_params_block_header, with each ISP functional
> > block represented as a tagged configuration structure. The statistics
> > buffer provides AWB, auto-exposure and histogram measurement results at
> > native RPP-X1 precision.
> >
> > Not all functional blocks present on the RPP-X1 hardware are included
> > yet, but the format is extensible and new blocks can be added without
> > breaking existing userspace.
> 
> Let me continue the uAPI review
> 
> >
> > Signed-off-by: Jai Luthra <jai.luthra+renesas@ideasonboard.com>
> > ---

[snip]

> > +/**
> > + * struct rppx1_lin_curve - Linearization curve for one color channel
> > + *
> > + * The RPP-X1 linearization module supports 12/20/24-bit precision depending
> > + * on hardware version. Values are provided at 24-bit precision; the driver
> > + * truncates to the hardware capability.
> > + *
> > + * @gamma_y: curve y-axis values, each up to 24 bits
> > + */
> > +struct rppx1_lin_curve {
> > +     __u32 gamma_y[RPPX1_LIN_SAMPLES_NUM];
> > +};
> > +
> > +/**
> > + * struct rppx1_lin_curve_dx - Linearization curve x-axis (sampling points)
> > + * increments.
> > + *
> > + * gamma_dx[0] is for the lower samples, so Bits 0:3 for sample 1, ... Bits
> > + * 28:31 for sample 8
> > + * gamma_dx[1] is for the higher samples, so Bits 0:3 for sample 9, ... Bits
> > + * 28:31 for sample 16
> > + *
> > + * The reset values for both fields is 0xcccccccc. This means that each sample
> > + * is 12 units away from the previous one on the x-axis.
> > + *
> > + * @gamma_dx: curve x-axis increments in 4-bit precision
> > + */
> > +struct rppx1_lin_curve_dx {
> > +     __u32 gamma_dx[2];
> > +};
> > +
> > +/**
> > + * struct rppx1_params_lin_config - Linearization (Sensor De-gamma) configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_LIN)
> > + * @curve_r: linearization curve for red channel
> > + * @curve_g: linearization curve for green channel
> > + * @curve_b: linearization curve for blue channel
> > + * @xa_pnts: x axis increment definitions
> > + */
> > +struct rppx1_params_lin_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     struct rppx1_lin_curve curve_r;
> > +     struct rppx1_lin_curve curve_g;
> > +     struct rppx1_lin_curve curve_b;
> > +     struct rppx1_lin_curve_dx xa_pnts;
> > +};
> > +
> > +/**
> > + * struct rppx1_params_lsc_config - Lens Shading Correction configuration
> > + *
> 
> A little more details maybe
> 
> The correction factor are expressed as a grid of 16x16 segments that are
> mapped on the image. The size of each segment is expressed by the
> @x_size_tbl and @y_size_tbl arrays.
> 
> The correction factors are expressed per-color channel in the
> @r_data_tbl, @gr_data_tbl, @gb_data_tbl and @b_data_tbl fields in
> Q2.10 format ranging from 1 to 3.999.
> 
> Pre-calculated multiplication factors shall be provided in the
> @x_grad_tbl and @y_grad_tbl fields. Gradients are expressed as 12 bits
> integer values.
> 

Ack.

> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_LSC)
> > + * @r_data_tbl: sample table red
> 
> I would drop _tbl and use
> 
>       @r_data: Correction factors for the red channel in Q2.10 format
> 
> > + * @gr_data_tbl: sample table green (red)
> > + * @gb_data_tbl: sample table green (blue)
> > + * @b_data_tbl: sample table blue
> 
> Same for these
> 
> > + * @x_grad_tbl: gradient table x
> 
> I would drop _tbl and use
> 
>       @x_grad: Interpolation gradients for each horizontal sector
> 
> > + * @y_grad_tbl: gradient table y
> 
>       @y_grad: Interpolation gradients for each vertical sector
> 
> > + * @x_size_tbl: size table x
> 
>       @x_sect_size: Horizontal sectors sizes
> 
> > + * @y_size_tbl: size table y
> 
>       @y_sect_size: Vertical sectors sizes
> 
> > + * @config_width: reserved
> > + * @config_height: reserved
> 
> What for ?
> 

No idea :(

I copied these over from RkISP1 but can't figure out the potential use.
Will drop.

> > + */
> > +struct rppx1_params_lsc_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u16 r_data_tbl[RPPX1_LSC_SAMPLES_MAX][RPPX1_LSC_SAMPLES_MAX];
> > +     __u16 gr_data_tbl[RPPX1_LSC_SAMPLES_MAX][RPPX1_LSC_SAMPLES_MAX];
> > +     __u16 gb_data_tbl[RPPX1_LSC_SAMPLES_MAX][RPPX1_LSC_SAMPLES_MAX];
> > +     __u16 b_data_tbl[RPPX1_LSC_SAMPLES_MAX][RPPX1_LSC_SAMPLES_MAX];
> > +     __u16 x_grad_tbl[RPPX1_LSC_SECTORS_TBL_SIZE];
> > +     __u16 y_grad_tbl[RPPX1_LSC_SECTORS_TBL_SIZE];
> > +     __u16 x_size_tbl[RPPX1_LSC_SECTORS_TBL_SIZE];
> > +     __u16 y_size_tbl[RPPX1_LSC_SECTORS_TBL_SIZE];
> 
> Both sectors and gradients are 16 and not 8.

The change from 8 to 16 is handled in a separate SQUASH patch.

> I would name RPPX1_LSC_SECTORS_TBL_SIZE as RPPX1_LSC_NUM_SECTORS
> 
> > +     __u16 config_width;
> > +     __u16 config_height;
> 
> Drop these if not used

Ack.

> 
> > +};
> > +
> > +/**
> > + * struct rppx1_params_awb_gain_config  - AWB gain configuration
> > + *
> > + * RPP-X1 AWB gains are 18-bit with 12-bit fractional part (0x1000 = 1.0),
> 
> The White Balance (WB) module allows to specify per-color channel
> gains  WB gains are expressed as unsigned fixed-point values in
> Q6.12 format with a maximum of 63.999.
> 
> > + * giving a range of 0.0 to 64.0.
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_AWB_GAIN)
> > + * @gain_red: gain for red component, 18-bit (Q6.12)
> > + * @gain_green_r: gain for green-in-red component, 18-bit (Q6.12)
> > + * @gain_blue: gain for blue component, 18-bit (Q6.12)
> > + * @gain_green_b: gain for green-in-blue component, 18-bit (Q6.12)
> > + */
> > +struct rppx1_params_awb_gain_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u32 gain_red;
> > +     __u32 gain_green_r;
> > +     __u32 gain_blue;
> > +     __u32 gain_green_b;
> > +};
> > +
> > +/**
> > + * struct rppx1_params_flt_config - Filter (demosaic/denoise) configuration
> 
> The filter/sharpening block seems to be embedded in the Debayer block.
> I don't think we have exercised this one enough to be confident we
> have a suitable userspace implementation yet.
> 
> Can maybe post-pone this one ?
> 

Sure, will drop.

> > + *
> > + * RPP-X1 thresholds are 18-bit and factors are 8-bit.
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_FLT)
> > + * @mode: filter mode
> > + * @grn_stage1: green filter stage 1 select (range 0x0...0x8)
> > + * @chr_h_mode: chroma filter horizontal mode
> > + * @chr_v_mode: chroma filter vertical mode
> > + * @thresh_bl0: If thresh_bl1 < sum_grad < thresh_bl0 then fac_bl0 is selected (blurring th)
> > + * @thresh_bl1: If sum_grad < thresh_bl1 then fac_bl1 is selected (blurring th)
> > + * @thresh_sh0: If thresh_sh0 < sum_grad < thresh_sh1 then thresh_sh0 is selected (sharpening th)
> > + * @thresh_sh1: If thresh_sh1 < sum_grad then thresh_sh1 is selected (sharpening th)
> > + * @lum_weight: luminance weight, min (bits 0:11), kink (bits 12:23), gain (bits 28:30)
> > + * @fac_sh1: filter factor for sharp1 level
> > + * @fac_sh0: filter factor for sharp0 level
> > + * @fac_mid: filter factor for mid level and for static filter mode
> > + * @fac_bl0: filter factor for blur0 level
> > + * @fac_bl1: filter factor for blur1 level (max blur)
> > + */
> > +struct rppx1_params_flt_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u32 mode;
> > +     __u8 grn_stage1;
> > +     __u8 chr_h_mode;
> > +     __u8 chr_v_mode;
> > +     __u32 thresh_bl0;
> > +     __u32 thresh_bl1;
> > +     __u32 thresh_sh0;
> > +     __u32 thresh_sh1;
> > +     __u32 lum_weight;
> > +     __u32 fac_sh1;
> > +     __u32 fac_sh0;
> > +     __u32 fac_mid;
> > +     __u32 fac_bl0;
> > +     __u32 fac_bl1;
> > +};
> > +
> > +/**
> > + * struct rppx1_params_bdm_config - Bayer Demosaic configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_BDM)
> > + * @demosaic_th: threshold for texture detection, 16-bit
> > + */
> > +struct rppx1_params_bdm_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u16 demosaic_th;
> > +};
> 
> We don't have an algo in libcamera, right ? This seems simple, but
> until it's not exercised by userspace I would defer introducing it.
> 

Ack.

> > +
> > +/**
> > + * struct rppx1_params_ctk_config - Color Correction (Cross-Talk) configuration
> 
> The module seems to be called CCOR (Color CORrection)
> 
> I would use that term
> 
> > + *
> > + * RPP-X1 coefficients are 16-bit signed fixed-point (Q4.12).
> > + * Range: -8.0 (0x8000) to +7.9996 (0x7FFF), 1.0 = 0x1000.
> 
> The CCOR (Color Correction) module performs color space conversion
> on a pixel-per-pixel basis using a 3x3 matrix of coefficients
> and per-color channel offsets.
> 
> The matrix coefficients are represented as signed fixed point values
> in Q4.12 format ranging from -8 to +7.999.
> 
> The per-channel color offsets are represented as 2's complement values
> stored in 25 bits ranging from -16777216 to 16777215.
> 
> > + *
> > + * RPP-X1 offsets are up to 24-bit + sign depending on hardware version.
> 
> For RPP-X1 the value seems to be fixed to 24 bits.

Indeed, it is 24 + 1 sign bit for the POST and AWB modules.

I got confused by another CCOR instance used for RGB2YUV_CCOR module which
is 12 bit unsigned.

> 
> We might want to report the ccor_version register value in stats if
> this changes for other ISP model. However I would leave it out for the
> time being, assume 24 and if we need to support a different register
> size introduce ccor_version in stats and add a comment here. We won't
> need to change the block definition.
> 

Ah, so here too the driver currently right shifts the parameters if
hardware version reg reports 12/20 bit instead of 24bit.

So I have the same question as the previous patch, does the userspace
benefit from knowing what's actually used, or can we abstract it away in
the uAPI?

> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_CTK)
> > + * @coeff: 3x3 color correction matrix, Q4.12 signed
> > + * @ct_offset: R, G, B offsets, up to 25-bit signed
> > + */
> > +struct rppx1_params_ctk_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u16 coeff[3][3];
> > +     __u32 ct_offset[3];
> 
> Or simply 'offset'
> 

Ack.

> > +};
> > +
> > +/**
> > + * struct rppx1_params_goc_config - Gamma Out Correction configuration
> 
> mmm, I would have used 'gamma', as that's what the manual use. But
> registers are named GAMMA_OUT so I would be fine with goc if that's
> preferred
> 

I think GAMMA_OUT would be better for this one, and GAMMA_IN for the LIN
module configuration?

> > + *
> > + * RPP-X1 gamma output values are up to 24-bit depending on hardware version.
> 
> The module allows to apply a Gamma correction curve to RGB data
> represented with a table of 16 entries @gamma_y. The 16 input sample
> points can be equidistant or segmented using a logarithmic scale
> according to the value of @mode.
> 
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_GOC)
> > + * @mode: gamma curve mode (0 = logarithmic, 1 = equidistant)
> 
> Please define an enum and refer to it here
> 
> /**
>  * enum rppx1_params_goc_mode - GOC curve segmentation mode
>  * @RPPX1_PARAMS_GOC_MODE_LOGARITHMIC: Logarithmic segmentation mode (default)
>  * @RPPX1_PARAMS_GOC_MODE_EQUIDISTANT: Equidistant segmentation mode
>  */
> enum rppx1_params_goc_mode {
>         RPPX1_PARAMS_GOC_MODE_LOGARITHMIC,
>         RPPX1_PARAMS_GOC_MODE_EQUIDISTANT
> };
> 

Ack.

> > + * @gamma_y: gamma out curve y-axis values, up to 24-bit
> > + */
> > +struct rppx1_params_goc_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u32 mode;
> > +     __u32 gamma_y[RPPX1_GAMMA_OUT_MAX_SAMPLES];
> > +};
> > +
> > +/**
> > + * enum rppx1_dpf_gain_usage - DPF noise function gain usage mode
> > + * @RPPX1_DPF_GAIN_USAGE_DISABLED: gain not used
> > + * @RPPX1_DPF_GAIN_USAGE_NF_GAINS: use noise function gains
> > + * @RPPX1_DPF_GAIN_USAGE_LSC_GAINS: use LSC gains
> > + * @RPPX1_DPF_GAIN_USAGE_NF_LSC_GAINS: use noise function and LSC gains
> > + * @RPPX1_DPF_GAIN_USAGE_AWB_GAINS: use AWB gains
> > + * @RPPX1_DPF_GAIN_USAGE_AWB_LSC_GAINS: use AWB and LSC gains
> > + */
> > +enum rppx1_dpf_gain_usage {
> > +     RPPX1_DPF_GAIN_USAGE_DISABLED,
> > +     RPPX1_DPF_GAIN_USAGE_NF_GAINS,
> > +     RPPX1_DPF_GAIN_USAGE_LSC_GAINS,
> > +     RPPX1_DPF_GAIN_USAGE_NF_LSC_GAINS,
> > +     RPPX1_DPF_GAIN_USAGE_AWB_GAINS,
> > +     RPPX1_DPF_GAIN_USAGE_AWB_LSC_GAINS,
> > +};
> > +
> > +/**
> > + * enum rppx1_nll_scale_mode - DPF noise level lookup scale mode
> > + * @RPPX1_NLL_SCALE_LINEAR: linear scaling
> > + * @RPPX1_NLL_SCALE_LOGARITHMIC: logarithmic scaling
> > + */
> > +enum rppx1_nll_scale_mode {
> > +     RPPX1_NLL_SCALE_LINEAR,
> > +     RPPX1_NLL_SCALE_LOGARITHMIC,
> > +};
> > +
> > +/**
> > + * enum rppx1_dpf_rb_filtersize - DPF red/blue filter kernel size
> > + * @RPPX1_DPF_RB_FILTERSIZE_13x9: 13x9 filter size
> > + * @RPPX1_DPF_RB_FILTERSIZE_9x9: 9x9 filter size
> > + */
> > +enum rppx1_dpf_rb_filtersize {
> > +     RPPX1_DPF_RB_FILTERSIZE_13x9,
> > +     RPPX1_DPF_RB_FILTERSIZE_9x9,
> > +};
> > +
> > +/**
> > + * struct rppx1_dpf_gain - DPF noise function gain configuration
> > + *
> > + * @mode: gain usage mode
> > + * @nf_r_gain: noise function gain replacing AWB gain for red
> > + * @nf_b_gain: noise function gain replacing AWB gain for blue
> > + * @nf_gr_gain: noise function gain replacing AWB gain for green-in-red
> > + * @nf_gb_gain: noise function gain replacing AWB gain for green-in-blue
> > + */
> > +struct rppx1_dpf_gain {
> > +     __u32 mode;
> > +     __u16 nf_r_gain;
> > +     __u16 nf_b_gain;
> > +     __u16 nf_gr_gain;
> > +     __u16 nf_gb_gain;
> > +};
> > +
> > +#define RPPX1_DPF_MAX_NLF_COEFFS                     17
> > +#define RPPX1_DPF_MAX_SPATIAL_COEFFS                 6
> > +
> > +/**
> > + * struct rppx1_dpf_nll - DPF noise level lookup
> > + *
> > + * @coeff: noise level lookup coefficients
> > + * @scale_mode: 0 = linear, 1 = logarithmic
> > + */
> > +struct rppx1_dpf_nll {
> > +     __u16 coeff[RPPX1_DPF_MAX_NLF_COEFFS];
> > +     __u32 scale_mode;
> > +};
> > +
> > +/**
> > + * struct rppx1_dpf_rb_flt - DPF red/blue filter configuration
> > + *
> > + * @fltsize: filter kernel size (0 = 13x9, 1 = 9x9)
> > + * @spatial_coeff: spatial weight coefficients
> > + * @r_enable: enable filter for red pixels
> > + * @b_enable: enable filter for blue pixels
> > + */
> > +struct rppx1_dpf_rb_flt {
> > +     __u32 fltsize;
> > +     __u8 spatial_coeff[RPPX1_DPF_MAX_SPATIAL_COEFFS];
> > +     __u8 r_enable;
> > +     __u8 b_enable;
> > +};
> > +
> > +/**
> > + * struct rppx1_dpf_g_flt - DPF green filter configuration
> > + *
> > + * @spatial_coeff: spatial weight coefficients
> > + * @gr_enable: enable filter for green-in-red pixels
> > + * @gb_enable: enable filter for green-in-blue pixels
> > + */
> > +struct rppx1_dpf_g_flt {
> > +     __u8 spatial_coeff[RPPX1_DPF_MAX_SPATIAL_COEFFS];
> > +     __u8 gr_enable;
> > +     __u8 gb_enable;
> > +};
> > +
> > +/**
> > + * struct rppx1_params_dpf_config - De-noising Pre-Filter configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_DPF)
> > + * @gain: noise function gain
> > + * @g_flt: green filter configuration
> > + * @rb_flt: red/blue filter configuration
> > + * @nll: noise level lookup
> > + */
> > +struct rppx1_params_dpf_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     struct rppx1_dpf_gain gain;
> > +     struct rppx1_dpf_g_flt g_flt;
> > +     struct rppx1_dpf_rb_flt rb_flt;
> > +     struct rppx1_dpf_nll nll;
> > +};
> > +
> > +/**
> > + * struct rppx1_params_dpf_strength_config - DPF strength configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_DPF_STRENGTH)
> > + * @r: filter strength for RED
> > + * @g: filter strength for GREEN
> > + * @b: filter strength for BLUE
> > + */
> > +struct rppx1_params_dpf_strength_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u8 r;
> > +     __u8 g;
> > +     __u8 b;
> > +};
> 
> This seems to be named "Bilateral Denoise".
> 
> Same reasoning goes as per the filter module.
> 
> We have an algorithm in libcamera for RkISP1 but it has been under
> heavy rework and I wouldn't consider it final or even very well
> tested.
> 
> The whole denoising part need more work and I think we can we maybe
> post-pone DPF for RPP-X1 ?
> 
> The risk is to define blocks we'll have to re-define later on.
> 

Ack.

> > +
> > +/**
> > + * enum rppx1_awb_mode_type - AWB measurement mode
> > + * @RPPX1_AWB_MODE_MANUAL: manual white balance
> 
> I can't find any reference to Manual mode.
> 
> I see
> 1: RGB measurement
> 0: YcbCr

Indeed seems to be a leftover from RKISP, where too it is unused.

But looking at the implementation in rppx1_wbmeas.c, I see we are free to
program the CCOR coefficients and offsets, unlike RKISP.

WDYT about dropping the modes altogether and exposing that table to the
userspace?

> 
> > + * @RPPX1_AWB_MODE_RGB: RGB measurement mode
> > + * @RPPX1_AWB_MODE_YCBCR: YCbCr measurement mode
> > + */
> > +enum rppx1_awb_mode_type {
> 
> Maybe let's use AWB_MEAS as a prefix
> 
> > +     RPPX1_AWB_MODE_MANUAL,
> 
> Both for the type and the fields
> 
> > +     RPPX1_AWB_MODE_RGB,
> > +     RPPX1_AWB_MODE_YCBCR,
> > +};
> > +
> > +/**
> > + * struct rppx1_params_awb_meas_config - AWB measurement configuration
> > + *
> 
>     * The auto-white balance measurement module supports two
>     * measurement modes, selected by the @awb_mode field.
>     * The measurement window is programmed through the @awb_wnd field.
>     *
>     * To support measurement in YCbCr a color conversion matrix with
>     * programmable offset is available is available in the
>     * @ccor_coeff and @ccor_offs fields.
>     */
> 
> 
> > + * RPP-X1 min_y, max_y, min_c, max_csum, awb_ref_cr, awb_ref_cb are up to
> > + * 24-bit depending on hardware version (8/20/24-bit).
> 
> As for the other similar cases, I think for RPP-X1 we can assume 24
> bits. If another version appears with a different bitwidth, we should
> report `awb_meas_version` through stats and add a comment here about
> the expected fields width.
> 
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_AWB_MEAS)
> > + * @awb_wnd: measurement window
> > + * @awb_mode: measurement mode (from enum rppx1_awb_mode_type)
> 
> Missing 'awb_max_en' with the associated enum
> 

`__u8 enable_ymax_cmp` handles that bit.

IMO an enum would be overkill for a simple disable/enable, we don't do that
elsewhere right?

> /**
>  * enum rppx1_awb_max_en - Enable max luminance threshold
>  *
>  * Luminance max threshold enable. Only pixels with a luminance value
>  * lower than @max_y are considered. Only valid in YCbCr measurement mode.
>  *
>  * @RPPX1_AWB_MEAS_Y_MAX_DISABLE: Disable luminance threshold
>  * @RPPX1_AWB_MEAS_Y_MAX_ENABLE: Enable luminance threshold
>  */
> enum rppx1_awb_max_en {
>         RPPX1_AWB_MEAS_Y_MAX_DISABLE,
>          RPPX1_AWB_MEAS_Y_MAX_ENABLE
> };
> 
> > + * @max_y: upper pixel value limit, up to 24-bit
> 
> This is worth a longer explanation.
> 
>       @max_y: luminance maximum value. Only pixels with luminance
>               value below this threshold are considered. Only valid if
>               @awb_mode is set to YCbCr and @awb_max_en is set to
>               enable.

Ack.

> 
> > + * @min_y: lower pixel value limit, up to 24-bit
> 
>       @min_y_max_g: luminance minimum value in YCbCr mode; maximum
>       green value in RGB mode
> 
> > + * @max_csum: chrominance sum maximum, up to 24-bit
> 
> Missing:
> 
>       @enable_ymax_cmp: enable Y_MAX compare
> 

Hmm, I see it in my original mail?

> > + * @min_c: chrominance minimum, up to 24-bit
> > + * @frames: number of frames for mean value calculation (0 = 1 frame)
> 
>       (0 = 1 frame, ..., 7 = 8 frames)

> 
> > + * @awb_ref_cr: reference Cr for AWB regulation, up to 24-bit
> 
>       @ref_cr_max_r: reference Cr or maximum red pixels value

Ack.

> 
> > + * @awb_ref_cb: reference Cb for AWB regulation, up to 24-bit
> 
>       @ref_cb_max_b: reference Cb or maximum blue pixels value
> 
> > + *
> 
> Missing
>       @ccor_coeffs: Color conversion matrix coefficients. The
>       coefficients have to be programmed according to the measurement
>       mode in use.
>       @ccor_offs: Color conversion matrix offsets.
> 
> As these two fields match the color conversion matrix, it might be
> worth defining a type for it where to defer the description of the
> coefficients and offset representations.

So should we drop the RGB/YCbCr Modes and use only the table, or keep the
modes, and the "Manual mode" when the user wants to specify a table?

> 
> > + */
> > +struct rppx1_params_awb_meas_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     struct rppx1_window awb_wnd;
> > +     __u32 awb_mode;
> > +     __u32 max_y;
> > +     __u32 min_y;
> > +     __u32 max_csum;
> > +     __u32 min_c;
> > +     __u8 frames;
> > +     __u32 awb_ref_cr;
> > +     __u32 awb_ref_cb;
> > +     __u8 enable_ymax_cmp;
> > +};
> > +
> > +/**
> > + * enum rppx1_histogram_mode - Histogram measurement mode
> > + * @RPPX1_HISTOGRAM_MODE_DISABLE: histogram disabled
> > + * @RPPX1_HISTOGRAM_MODE_RGB_COMBINED: combined RGB histogram
> > + * @RPPX1_HISTOGRAM_MODE_R_HISTOGRAM: red channel histogram
> > + * @RPPX1_HISTOGRAM_MODE_G_HISTOGRAM: green channel histogram
> > + * @RPPX1_HISTOGRAM_MODE_B_HISTOGRAM: blue channel histogram
> > + * @RPPX1_HISTOGRAM_MODE_Y_HISTOGRAM: luminance histogram
> > + */
> > +enum rppx1_histogram_mode {
> > +     RPPX1_HISTOGRAM_MODE_DISABLE,
> > +     RPPX1_HISTOGRAM_MODE_RGB_COMBINED,
> > +     RPPX1_HISTOGRAM_MODE_R_HISTOGRAM,
> > +     RPPX1_HISTOGRAM_MODE_G_HISTOGRAM,
> > +     RPPX1_HISTOGRAM_MODE_B_HISTOGRAM,
> > +     RPPX1_HISTOGRAM_MODE_Y_HISTOGRAM,
> > +};
> > +
> > +#define RPPX1_HISTOGRAM_WEIGHT_GRIDS_SIZE            25
> 
> Missing the tap points definitions for HIST_CHANNEL_SEL

Handled in a SQUASH patch later.

> 
> > +
> > +/**
> > + * struct rppx1_params_hst_config - Histogram measurement configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_HST_MEAS)
> > + * @mode: histogram mode (from enum rppx1_histogram_mode)
> 
> Missing:
>       @tap_point
> 
> 
> > + * @histogram_predivider: process every Nth pixel
> 
> I see a separate v_stepsize and h_step_inc for the subsampling
> 

Yeah I chose to leave this particular one out because it seemed a little
more complex than others.

Will do before v8.

> > + * @meas_window: measurement window coordinates
> > + * @hist_weight: weighting factors for sub-windows (5x5 grid)
> 
> There also are three programmable coefficients, offsets and shifts

The coefficients are currently not exposed, instead we have `enum
rppx1_histogram_mode` handling RGB_COMBINED or separate R/G/B/Y
Histograms.

Same question as AWB, do we want to drop the modes and expose the
coefficients directly, or maybe have an extra "MANUAL" mode and keep the
enum?

> 
> > + */
> > +struct rppx1_params_hst_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u32 mode;
> > +     __u8 histogram_predivider;
> > +     struct rppx1_window meas_window;
> > +     __u8 hist_weight[RPPX1_HISTOGRAM_WEIGHT_GRIDS_SIZE];
> > +};
> > +
> > +/**
> > + * enum rppx1_exp_meas_mode - Exposure measurement mode
> > + * @RPPX1_EXP_MEASURING_MODE_0: Y = 16 + 0.25R + 0.5G + 0.1094B
> > + * @RPPX1_EXP_MEASURING_MODE_1: Y = (R + G + B) x (85/256)
> > + */
> > +enum rppx1_exp_meas_mode {
> > +     RPPX1_EXP_MEASURING_MODE_0,
> > +     RPPX1_EXP_MEASURING_MODE_1,
> 
> This doesn't match the definition of EXM_MODE I see:
> 
>         RPPX1_EXP_MEASURING_MODE_0 = Disabled
>         RPPX1_EXP_MEASURING_MODE_1 = Y/R/G/B exposure measurement
>         RPPX1_EXP_MEASURING_MODE_2 = RGB Bayer exposure measurement

This is fixed in the SQUASH patch later which also exposes programmable
coefficients and sampling point.

The "MODE_0 = Disabled" is not exposed in the enum but rather through the
V4L2_ISP_PARAMS_FL_BLOCK_DISABLE flag. Again, having only one toggle in
uAPI seems better than two.

> > +};
> > +
> 
> Missing TAP point definitions for EXM_CHANNEL_SEL
> 

Done in SQUASH patch later in the series.

> > +/**
> > + * struct rppx1_params_aec_config - Auto Exposure measurement configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_AEC_MEAS)
> > + * @mode: exposure measure mode (from enum rppx1_exp_meas_mode)
> > + * @autostop: 0 = continuous, 1 = stop after one frame
> 
> Seems not to be supported
> 

The hardware documentation defines the bit, but says it's not supported.
So, it would mean that it might be supported in some later revision of the
HW?

Thus, I kept it around. But we can drop it too and define a new block
later.

> > + * @meas_window: measurement window coordinates
> > + */
> > +struct rppx1_params_aec_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u32 mode;
> > +     __u32 autostop;
> 
> There also are coefficients
> 
>         /* Unsigned Q0.7 values ranging from 0 to 1.992 */
>         struct {
>                 r;
>                 gr;
>                 b;
>                 gb;
>         } coeffs;
> 

Handled in the SQUASH patch.

> > +     struct rppx1_window meas_window;
> > +};
> > +
> > +/**
> > + * RPPX1_PARAMS_MAX_SIZE - Maximum size of all RPP-X1 parameter blocks
> > + */
> > +#define RPPX1_PARAMS_MAX_SIZE                                                \
> > +     (sizeof(struct rppx1_params_bls_config)                 +       \
> > +     sizeof(struct rppx1_params_dpcc_config)                 +       \
> > +     sizeof(struct rppx1_params_lin_config)                  +       \
> > +     sizeof(struct rppx1_params_awb_gain_config)             +       \
> > +     sizeof(struct rppx1_params_flt_config)                  +       \
> > +     sizeof(struct rppx1_params_bdm_config)                  +       \
> > +     sizeof(struct rppx1_params_ctk_config)                  +       \
> > +     sizeof(struct rppx1_params_goc_config)                  +       \
> > +     sizeof(struct rppx1_params_dpf_config)                  +       \
> > +     sizeof(struct rppx1_params_dpf_strength_config)         +       \
> > +     sizeof(struct rppx1_params_lsc_config)                  +       \
> > +     sizeof(struct rppx1_params_awb_meas_config)             +       \
> > +     sizeof(struct rppx1_params_hst_config)                  +       \
> > +     sizeof(struct rppx1_params_aec_config))
> > +
> > +/* ---------------------------------------------------------------------------
> > + * Statistics Structures
> > + *
> > + * Native RPP-X1 precision. Fields use __u32 where the hardware provides
> > + * wider-than-8-bit results.
> > + */
> > +
> > +/**
> > + * struct rppx1_awb_meas - AWB measured values
> > + *
> > + * @cnt: white pixel count
> > + * @mean_y_or_g: mean Y (or G in RGB mode), up to 24-bit
> > + * @mean_cb_or_b: mean Cb (or B in RGB mode), up to 24-bit
> > + * @mean_cr_or_r: mean Cr (or R in RGB mode), up to 24-bit
> > + */
> > +struct rppx1_awb_meas {
> > +     __u32 cnt;
> > +     __u32 mean_y_or_g;
> > +     __u32 mean_cb_or_b;
> > +     __u32 mean_cr_or_r;
> > +};
> > +
> > +/**
> > + * struct rppx1_awb_stat - AWB statistics
> > + *
> > + * @awb_mean: measured AWB data
> > + */
> > +struct rppx1_awb_stat {
> > +     struct rppx1_awb_meas awb_mean[RPPX1_AWB_MAX_GRID];
> > +};
> > +
> > +/**
> > + * struct rppx1_bls_meas_val - BLS measured values
> > + *
> > + * RPP-X1 BLS statistics can be 8/20/24-bit depending on version.
> > + *
> > + * @meas_r: mean measured value for Bayer pattern R
> > + * @meas_gr: mean measured value for Bayer pattern Gr
> > + * @meas_gb: mean measured value for Bayer pattern Gb
> > + * @meas_b: mean measured value for Bayer pattern B
> > + */
> > +struct rppx1_bls_meas_val {
> > +     __u32 meas_r;
> > +     __u32 meas_gr;
> > +     __u32 meas_gb;
> > +     __u32 meas_b;
> > +};
> > +
> > +/**
> > + * struct rppx1_ae_stat - Auto Exposure statistics
> > + *
> > + * RPP-X1 exposure mean values are up to 20-bit depending on version.
> > + * The image is divided into a 5x5 grid (25 blocks).
> > + *
> > + * @exp_mean: mean luminance values per block, up to 20-bit
> > + * @bls_val: BLS measured values
> > + */
> > +struct rppx1_ae_stat {
> > +     __u32 exp_mean[RPPX1_EXM_MEAN_MAX];
> > +     struct rppx1_bls_meas_val bls_val;
> > +};
> > +
> > +/**
> > + * struct rppx1_hist_stat - Histogram statistics
> > + *
> > + * @hist_bins: 32 histogram bin counters, each 20-bit unsigned fixed point
> > + *          (bits 0-4 fractional, bits 5-19 integer)
> > + */
> > +struct rppx1_hist_stat {
> > +     __u32 hist_bins[RPPX1_HIST_BIN_N_MAX];
> > +};
> > +
> > +/**
> > + * struct rppx1_stat - RPP-X1 3A statistics
> > + *
> > + * @awb: auto white balance statistics
> > + * @ae: auto exposure statistics
> > + * @hist: histogram statistics
> > + */
> > +struct rppx1_stat {
> > +     struct rppx1_awb_stat awb;
> > +     struct rppx1_ae_stat ae;
> > +     struct rppx1_hist_stat hist;
> > +};
> > +
> > +/**
> > + * RPPX1_STAT_AWB - AWB measurement data available
> > + * RPPX1_STAT_AUTOEXP - Auto exposure measurement data available
> > + *
> Missing documentation of:
> 
>       RPPX1_STAT_HIST - Histogram measurement data available
> 
> > + */
> > +#define RPPX1_STAT_AWB                       (1U << 0)
> > +#define RPPX1_STAT_AUTOEXP           (1U << 1)
> > +#define RPPX1_STAT_HIST                      (1U << 2)
> > +
> > +/**
> > + * struct rppx1_stat_buffer - RPP-X1 statistics metadata buffer
> > + *
> > + * @meas_type: bitmask of available measurements (RPPX1_STAT_*)
> > + * @frame_id: frame identifier for synchronization
> > + * @params: statistics data
> > + */
> > +struct rppx1_stat_buffer {
> > +     __u32 meas_type;
> > +     __u32 frame_id;
> > +     struct rppx1_stat params;
> 
> Maybe name it stats as well ?
> 

Ack.

> Now that v2 of extensible stats is out, I would rebase this on top of
> them
> 

Will do.

Thanks,
    Jai

> Thank you!
>    j
> 
> > +};
> > +
> > +#endif /* __UAPI_RPP_X1_CONFIG_H */
> >
> > --
> > 2.53.0
> >
> >

^ permalink raw reply

* [PATCH] media: staging: ipu7: cleanup register names and suffixes
From: deep @ 2026-04-15  7:02 UTC (permalink / raw)
  To: sakari.ailus
  Cc: bingbu.cao, mchehab, gregkh, linux-media, linux-staging,
	linux-kernel, Kenet Jovan Sokoli

From: Kenet Jovan Sokoli <deep@crimson.net.eu.org>

Rename BUTTRESS_ registers to include IPU7_ prefix and
remove unnecessary U suffixes from numeric constants
for consistency.

Signed-off-by: Kenet Jovan Sokoli <deep@crimson.net.eu.org>
---
 .../staging/media/ipu7/ipu7-buttress-regs.h   | 18 ++---
 drivers/staging/media/ipu7/ipu7-buttress.c    | 38 +++++-----
 drivers/staging/media/ipu7/ipu7-cpd.c         | 38 +++++-----
 drivers/staging/media/ipu7/ipu7-fw-isys.c     |  8 +--
 .../staging/media/ipu7/ipu7-isys-csi-phy.c    | 72 +++++++++----------
 .../staging/media/ipu7/ipu7-isys-csi-phy.h    |  4 +-
 .../staging/media/ipu7/ipu7-isys-csi2-regs.h  | 14 ++--
 drivers/staging/media/ipu7/ipu7-isys-csi2.c   |  2 +-
 drivers/staging/media/ipu7/ipu7-isys-csi2.h   | 10 +--
 drivers/staging/media/ipu7/ipu7-isys-queue.c  |  4 +-
 drivers/staging/media/ipu7/ipu7-isys-subdev.c |  8 +--
 drivers/staging/media/ipu7/ipu7-isys-video.c  | 22 +++---
 drivers/staging/media/ipu7/ipu7-isys-video.h  |  8 +--
 drivers/staging/media/ipu7/ipu7-isys.c        | 18 ++---
 drivers/staging/media/ipu7/ipu7-isys.h        | 22 +++---
 drivers/staging/media/ipu7/ipu7-mmu.c         | 36 +++++-----
 drivers/staging/media/ipu7/ipu7.c             |  8 +--
 drivers/staging/media/ipu7/ipu7.h             | 40 +++++------
 18 files changed, 185 insertions(+), 185 deletions(-)

diff --git a/drivers/staging/media/ipu7/ipu7-buttress-regs.h b/drivers/staging/media/ipu7/ipu7-buttress-regs.h
index 3eafd6a3813d..e81669ef4824 100644
--- a/drivers/staging/media/ipu7/ipu7-buttress-regs.h
+++ b/drivers/staging/media/ipu7/ipu7-buttress-regs.h
@@ -280,14 +280,14 @@
 #define BUTTRESS_IRQ_PS_IRQ				BIT(31)
 
 /* buttress irq */
-#define	BUTTRESS_PWR_STATUS_HH_STATE_IDLE	0U
-#define	BUTTRESS_PWR_STATUS_HH_STATE_IN_PRGS	1U
-#define	BUTTRESS_PWR_STATUS_HH_STATE_DONE	2U
-#define	BUTTRESS_PWR_STATUS_HH_STATE_ERR	3U
+#define	IPU7_BUTTRESS_PWR_STATUS_HH_STATE_IDLE	0
+#define	IPU7_BUTTRESS_PWR_STATUS_HH_STATE_IN_PRGS	1
+#define	IPU7_BUTTRESS_PWR_STATUS_HH_STATE_DONE	2
+#define	IPU7_BUTTRESS_PWR_STATUS_HH_STATE_ERR	3
 
 #define BUTTRESS_TSC_CMD_START_TSC_SYNC		BIT(0)
 #define BUTTRESS_PWR_STATUS_HH_STATUS_SHIFT	11
-#define BUTTRESS_PWR_STATUS_HH_STATUS_MASK	(0x3U << 11)
+#define IPU7_BUTTRESS_PWR_STATUS_HH_STATUS_MASK	(0x3 << 11)
 #define BUTTRESS_TSW_WA_SOFT_RESET		BIT(8)
 /* new for PTL */
 #define BUTTRESS_SEL_PB_TIMESTAMP		BIT(9)
@@ -326,15 +326,15 @@
 #define BUTTRESS_CSE2IUDATA0_IPC_NACK_MASK 0xffff
 
 /* IS/PS freq control */
-#define BUTTRESS_IS_FREQ_CTL_RATIO_MASK	0xffU
-#define BUTTRESS_PS_FREQ_CTL_RATIO_MASK	0xffU
+#define IPU7_BUTTRESS_IS_FREQ_CTL_RATIO_MASK	0xff
+#define IPU7_BUTTRESS_PS_FREQ_CTL_RATIO_MASK	0xff
 
 #define IPU7_IS_FREQ_MAX		450
 #define IPU7_IS_FREQ_MIN		50
 #define IPU7_PS_FREQ_MAX		750
-#define BUTTRESS_PS_FREQ_RATIO_STEP		25U
+#define IPU7_BUTTRESS_PS_FREQ_RATIO_STEP		25
 /* valid for IPU8 */
-#define BUTTRESS_IS_FREQ_RATIO_STEP		25U
+#define IPU7_BUTTRESS_IS_FREQ_RATIO_STEP		25
 
 /* IS: 400mhz, PS: 500mhz */
 #define IPU7_IS_FREQ_CTL_DEFAULT_RATIO		0x1b
diff --git a/drivers/staging/media/ipu7/ipu7-buttress.c b/drivers/staging/media/ipu7/ipu7-buttress.c
index 40c6c8473357..b013f458ff60 100644
--- a/drivers/staging/media/ipu7/ipu7-buttress.c
+++ b/drivers/staging/media/ipu7/ipu7-buttress.c
@@ -28,13 +28,13 @@
 
 #define BOOTLOADER_STATUS_OFFSET	BUTTRESS_REG_FW_BOOT_PARAMS7
 
-#define BOOTLOADER_MAGIC_KEY		0xb00710adU
+#define IPU7_BOOTLOADER_MAGIC_KEY		0xb00710ad
 
 #define ENTRY	BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE1
 #define EXIT	BUTTRESS_IU2CSECSR_IPC_PEER_COMP_ACTIONS_RST_PHASE2
 #define QUERY	BUTTRESS_IU2CSECSR_IPC_PEER_QUERIED_IP_COMP_ACTIONS_RST_PHASE
 
-#define BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX	10U
+#define IPU7_BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX	10
 
 #define BUTTRESS_POWER_TIMEOUT_US		(200 * USEC_PER_MSEC)
 
@@ -47,9 +47,9 @@
 #define BUTTRESS_IPC_VALIDITY_TIMEOUT_US	(1 * USEC_PER_SEC)
 #define BUTTRESS_TSC_SYNC_TIMEOUT_US		(5 * USEC_PER_MSEC)
 
-#define BUTTRESS_IPC_RESET_RETRY		2000U
-#define BUTTRESS_CSE_IPC_RESET_RETRY		4U
-#define BUTTRESS_IPC_CMD_SEND_RETRY		1U
+#define IPU7_BUTTRESS_IPC_RESET_RETRY		2000
+#define IPU7_BUTTRESS_CSE_IPC_RESET_RETRY		4
+#define IPU7_BUTTRESS_IPC_CMD_SEND_RETRY		1
 
 struct ipu7_ipc_buttress_msg {
 	u32 cmd;
@@ -66,7 +66,7 @@ static const u32 ipu7_adev_irq_mask[2] = {
 int ipu_buttress_ipc_reset(struct ipu7_device *isp,
 			   struct ipu_buttress_ipc *ipc)
 {
-	unsigned int retries = BUTTRESS_IPC_RESET_RETRY;
+	unsigned int retries = IPU7_BUTTRESS_IPC_RESET_RETRY;
 	struct ipu_buttress *b = &isp->buttress;
 	struct device *dev = &isp->pdev->dev;
 	u32 val = 0, csr_in_clr;
@@ -221,7 +221,7 @@ static int ipu_buttress_ipc_send_msg(struct ipu7_device *isp,
 				     struct ipu7_ipc_buttress_msg *msg)
 {
 	unsigned long tx_timeout_jiffies, rx_timeout_jiffies;
-	unsigned int retry = BUTTRESS_IPC_CMD_SEND_RETRY;
+	unsigned int retry = IPU7_BUTTRESS_IPC_CMD_SEND_RETRY;
 	struct ipu_buttress *b = &isp->buttress;
 	struct ipu_buttress_ipc *ipc = &b->cse;
 	struct device *dev = &isp->pdev->dev;
@@ -779,9 +779,9 @@ int ipu_buttress_get_isys_freq(struct ipu7_device *isp, u32 *freq)
 	pm_runtime_put(&isp->isys->auxdev.dev);
 
 	if (is_ipu8(isp->hw_ver))
-		*freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 25;
+		*freq = (reg_val & IPU7_BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 25;
 	else
-		*freq = (reg_val & BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 50 / 3;
+		*freq = (reg_val & IPU7_BUTTRESS_IS_FREQ_CTL_RATIO_MASK) * 50 / 3;
 
 	return 0;
 }
@@ -803,8 +803,8 @@ int ipu_buttress_get_psys_freq(struct ipu7_device *isp, u32 *freq)
 
 	pm_runtime_put(&isp->psys->auxdev.dev);
 
-	reg_val &= BUTTRESS_PS_FREQ_CTL_RATIO_MASK;
-	*freq = BUTTRESS_PS_FREQ_RATIO_STEP * reg_val;
+	reg_val &= IPU7_BUTTRESS_PS_FREQ_CTL_RATIO_MASK;
+	*freq = IPU7_BUTTRESS_PS_FREQ_RATIO_STEP * reg_val;
 
 	return 0;
 }
@@ -901,7 +901,7 @@ int ipu_buttress_authenticate(struct ipu7_device *isp)
 	}
 
 	ret = readl_poll_timeout(isp->base + BOOTLOADER_STATUS_OFFSET,
-				 data, data == BOOTLOADER_MAGIC_KEY, 500,
+				 data, data == IPU7_BOOTLOADER_MAGIC_KEY, 500,
 				 BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
 	if (ret) {
 		dev_err(dev, "Unexpected magic number 0x%x\n", data);
@@ -951,19 +951,19 @@ static int ipu_buttress_send_tsc_request(struct ipu7_device *isp)
 	u32 val, mask, done;
 	int ret;
 
-	mask = BUTTRESS_PWR_STATUS_HH_STATUS_MASK;
+	mask = IPU7_BUTTRESS_PWR_STATUS_HH_STATUS_MASK;
 
 	writel(BUTTRESS_TSC_CMD_START_TSC_SYNC,
 	       isp->base + BUTTRESS_REG_TSC_CMD);
 
 	val = readl(isp->base + BUTTRESS_REG_PWR_STATUS);
 	val = FIELD_GET(mask, val);
-	if (val == BUTTRESS_PWR_STATUS_HH_STATE_ERR) {
+	if (val == IPU7_BUTTRESS_PWR_STATUS_HH_STATE_ERR) {
 		dev_err(&isp->pdev->dev, "Start tsc sync failed\n");
 		return -EINVAL;
 	}
 
-	done = BUTTRESS_PWR_STATUS_HH_STATE_DONE;
+	done = IPU7_BUTTRESS_PWR_STATUS_HH_STATE_DONE;
 	ret = readl_poll_timeout(isp->base + BUTTRESS_REG_PWR_STATUS, val,
 				 FIELD_GET(mask, val) == done, 500,
 				 BUTTRESS_TSC_SYNC_TIMEOUT_US);
@@ -980,7 +980,7 @@ int ipu_buttress_start_tsc_sync(struct ipu7_device *isp)
 	u32 val;
 
 	if (is_ipu8(isp->hw_ver)) {
-		for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
+		for (i = 0; i < IPU7_BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
 			val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID);
 			if (val == 1)
 				return 0;
@@ -996,7 +996,7 @@ int ipu_buttress_start_tsc_sync(struct ipu7_device *isp)
 		val |= BUTTRESS_SEL_PB_TIMESTAMP;
 		writel(val, base + BUTTRESS_REG_TSC_CTL);
 
-		for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
+		for (i = 0; i < IPU7_BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
 			val = readl(base + BUTTRESS_REG_PB_TIMESTAMP_VALID);
 			if (val == 1)
 				return 0;
@@ -1008,7 +1008,7 @@ int ipu_buttress_start_tsc_sync(struct ipu7_device *isp)
 		return -ETIMEDOUT;
 	}
 
-	for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
+	for (i = 0; i < IPU7_BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) {
 		int ret;
 
 		ret = ipu_buttress_send_tsc_request(isp);
@@ -1143,7 +1143,7 @@ void ipu_buttress_restore(struct ipu7_device *isp)
 
 int ipu_buttress_init(struct ipu7_device *isp)
 {
-	int ret, ipc_reset_retry = BUTTRESS_CSE_IPC_RESET_RETRY;
+	int ret, ipc_reset_retry = IPU7_BUTTRESS_CSE_IPC_RESET_RETRY;
 	struct ipu_buttress *b = &isp->buttress;
 	struct device *dev = &isp->pdev->dev;
 	u32 val;
diff --git a/drivers/staging/media/ipu7/ipu7-cpd.c b/drivers/staging/media/ipu7/ipu7-cpd.c
index 4f49fb57eae4..80b5834a9587 100644
--- a/drivers/staging/media/ipu7/ipu7-cpd.c
+++ b/drivers/staging/media/ipu7/ipu7-cpd.c
@@ -21,21 +21,21 @@
 #define MAX_MANIFEST_SIZE	(SZ_4K * sizeof(u32))
 
 #define CPD_MANIFEST_IDX	0
-#define CPD_BINARY_START_IDX	1U
-#define CPD_METADATA_START_IDX	2U
-#define CPD_BINARY_NUM		2U /* ISYS + PSYS */
+#define IPU7_CPD_BINARY_START_IDX	1
+#define IPU7_CPD_METADATA_START_IDX	2
+#define IPU7_CPD_BINARY_NUM		2 /* ISYS + PSYS */
 /*
  * Entries include:
  * 1 manifest entry.
  * 1 metadata entry for each sub system(ISYS and PSYS).
  * 1 binary entry for each sub system(ISYS and PSYS).
  */
-#define CPD_ENTRY_NUM		(CPD_BINARY_NUM * 2U + 1U)
+#define IPU7_CPD_ENTRY_NUM		(IPU7_CPD_BINARY_NUM * 2 + 1)
 
 #define CPD_METADATA_ATTR	0xa
 #define CPD_METADATA_IPL	0x1c
-#define ONLINE_METADATA_SIZE	128U
-#define ONLINE_METADATA_LINES	6U
+#define IPU7_ONLINE_METADATA_SIZE	128
+#define IPU7_ONLINE_METADATA_LINES	6
 
 struct ipu7_cpd_hdr {
 	u32 hdr_mark;
@@ -94,7 +94,7 @@ static inline struct ipu7_cpd_ent *ipu7_cpd_get_entry(const void *cpd, int idx)
 static struct ipu7_cpd_metadata *ipu7_cpd_get_metadata(const void *cpd, int idx)
 {
 	struct ipu7_cpd_ent *cpd_ent =
-		ipu7_cpd_get_entry(cpd, CPD_METADATA_START_IDX + idx * 2);
+		ipu7_cpd_get_entry(cpd, IPU7_CPD_METADATA_START_IDX + idx * 2);
 
 	return (struct ipu7_cpd_metadata *)((u8 *)cpd + cpd_ent->offset);
 }
@@ -123,7 +123,7 @@ static int ipu7_cpd_validate_cpd(struct ipu7_device *isp,
 	}
 
 	/* Sanity check for CPD entry header */
-	if (cpd_hdr->ent_cnt != CPD_ENTRY_NUM) {
+	if (cpd_hdr->ent_cnt != IPU7_CPD_ENTRY_NUM) {
 		dev_err(dev, "Invalid CPD entry number %d\n",
 			cpd_hdr->ent_cnt);
 		return -EINVAL;
@@ -151,7 +151,7 @@ static int ipu7_cpd_validate_metadata(struct ipu7_device *isp,
 				      const void *cpd, int idx)
 {
 	const struct ipu7_cpd_ent *cpd_ent =
-		ipu7_cpd_get_entry(cpd, CPD_METADATA_START_IDX + idx * 2);
+		ipu7_cpd_get_entry(cpd, IPU7_CPD_METADATA_START_IDX + idx * 2);
 	const struct ipu7_cpd_metadata *metadata =
 		ipu7_cpd_get_metadata(cpd, idx);
 	struct device *dev = &isp->pdev->dev;
@@ -210,7 +210,7 @@ int ipu7_cpd_validate_cpd_file(struct ipu7_device *isp, const void *cpd_file,
 	}
 
 	/* Validate metadata */
-	for (i = 0; i < CPD_BINARY_NUM; i++) {
+	for (i = 0; i < IPU7_CPD_BINARY_NUM; i++) {
 		ret = ipu7_cpd_validate_metadata(isp, cpd_file, i);
 		if (ret) {
 			dev_err(dev, "Invalid metadata%d\n", i);
@@ -219,24 +219,24 @@ int ipu7_cpd_validate_cpd_file(struct ipu7_device *isp, const void *cpd_file,
 	}
 
 	/* Get fw binary version. */
-	buf = kmalloc(ONLINE_METADATA_SIZE, GFP_KERNEL);
+	buf = kmalloc(IPU7_ONLINE_METADATA_SIZE, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
-	for (i = 0; i < CPD_BINARY_NUM; i++) {
-		char *lines[ONLINE_METADATA_LINES];
+	for (i = 0; i < IPU7_CPD_BINARY_NUM; i++) {
+		char *lines[IPU7_ONLINE_METADATA_LINES];
 		char *info = buf;
 		unsigned int l;
 
 		ent = ipu7_cpd_get_entry(cpd_file,
-					 CPD_BINARY_START_IDX + i * 2U);
+					 IPU7_CPD_BINARY_START_IDX + i * 2U);
 		memcpy(info, (u8 *)cpd_file + ent->offset + ent->len -
-		       ONLINE_METADATA_SIZE, ONLINE_METADATA_SIZE);
-		for (l = 0; l < ONLINE_METADATA_LINES; l++) {
+		       IPU7_ONLINE_METADATA_SIZE, IPU7_ONLINE_METADATA_SIZE);
+		for (l = 0; l < IPU7_ONLINE_METADATA_LINES; l++) {
 			lines[l] = strsep((char **)&info, "\n");
 			if (!lines[l])
 				break;
 		}
-		if (l < ONLINE_METADATA_LINES) {
+		if (l < IPU7_ONLINE_METADATA_LINES) {
 			dev_err(dev, "Failed to parse fw binary%d info.\n", i);
 			continue;
 		}
@@ -257,9 +257,9 @@ int ipu7_cpd_copy_binary(const void *cpd, const char *name,
 {
 	unsigned int i;
 
-	for (i = 0; i < CPD_BINARY_NUM; i++) {
+	for (i = 0; i < IPU7_CPD_BINARY_NUM; i++) {
 		const struct ipu7_cpd_ent *binary =
-			ipu7_cpd_get_entry(cpd, CPD_BINARY_START_IDX + i * 2U);
+			ipu7_cpd_get_entry(cpd, IPU7_CPD_BINARY_START_IDX + i * 2U);
 		const struct ipu7_cpd_metadata *metadata =
 			ipu7_cpd_get_metadata(cpd, i);
 
diff --git a/drivers/staging/media/ipu7/ipu7-fw-isys.c b/drivers/staging/media/ipu7/ipu7-fw-isys.c
index e4b9c364572b..25cfa7ff0b21 100644
--- a/drivers/staging/media/ipu7/ipu7-fw-isys.c
+++ b/drivers/staging/media/ipu7/ipu7-fw-isys.c
@@ -109,23 +109,23 @@ int ipu7_fw_isys_init(struct ipu7_isys *isys)
 	}
 	syscom->queue_configs = queue_configs;
 	queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].max_capacity =
-		IPU_ISYS_SIZE_RECV_QUEUE;
+		IPU7_ISYS_SIZE_RECV_QUEUE;
 	queue_configs[IPU_INSYS_OUTPUT_MSG_QUEUE].token_size_in_bytes =
 		sizeof(struct ipu7_insys_resp);
 	queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].max_capacity =
-		IPU_ISYS_SIZE_LOG_QUEUE;
+		IPU7_ISYS_SIZE_LOG_QUEUE;
 	queue_configs[IPU_INSYS_OUTPUT_LOG_QUEUE].token_size_in_bytes =
 		sizeof(struct ipu7_insys_resp);
 	queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].max_capacity = 0;
 	queue_configs[IPU_INSYS_OUTPUT_RESERVED_QUEUE].token_size_in_bytes = 0;
 
 	queue_configs[IPU_INSYS_INPUT_DEV_QUEUE].max_capacity =
-		IPU_ISYS_MAX_STREAMS;
+		IPU7_ISYS_MAX_STREAMS;
 	queue_configs[IPU_INSYS_INPUT_DEV_QUEUE].token_size_in_bytes =
 		sizeof(struct ipu7_insys_send_queue_token);
 
 	for (i = IPU_INSYS_INPUT_MSG_QUEUE; i < num_queues; i++) {
-		queue_configs[i].max_capacity = IPU_ISYS_SIZE_SEND_QUEUE;
+		queue_configs[i].max_capacity = IPU7_ISYS_SIZE_SEND_QUEUE;
 		queue_configs[i].token_size_in_bytes =
 			sizeof(struct ipu7_insys_send_queue_token);
 	}
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
index 3f15af3b4c79..3ca85babd615 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.c
@@ -23,13 +23,13 @@
 #include "ipu7-platform-regs.h"
 #include "ipu7-isys-csi-phy.h"
 
-#define PORT_A		0U
-#define PORT_B		1U
-#define PORT_C		2U
-#define PORT_D		3U
+#define IPU7_PORT_A		0
+#define IPU7_PORT_B		1
+#define IPU7_PORT_C		2
+#define IPU7_PORT_D		3
 
-#define N_DATA_IDS	8U
-static DECLARE_BITMAP(data_ids, N_DATA_IDS);
+#define IPU7_N_DATA_IDS	8
+static DECLARE_BITMAP(data_ids, IPU7_N_DATA_IDS);
 
 struct ddlcal_counter_ref_s {
 	u16 min_mbps;
@@ -275,8 +275,8 @@ static int __dids_config(struct ipu7_isys_csi2 *csi2, u32 id, u8 vc, u8 dt)
 		id, vc, dt);
 
 	dwc_csi_write(isys, id, VC_EXTENSION, 0x0);
-	n = find_first_zero_bit(data_ids, N_DATA_IDS);
-	if (n == N_DATA_IDS)
+	n = find_first_zero_bit(data_ids, IPU7_N_DATA_IDS);
+	if (n == IPU7_N_DATA_IDS)
 		return -ENOSPC;
 
 	ret = test_and_set_bit(n, data_ids);
@@ -340,7 +340,7 @@ static int ipu7_isys_csi_ctrl_dids_config(struct ipu7_isys_csi2 *csi2, u32 id)
 	return 0;
 }
 
-#define CDPHY_TIMEOUT 5000000U
+#define IPU7_CDPHY_TIMEOUT 5000000
 static int ipu7_isys_phy_ready(struct ipu7_isys *isys, u32 id)
 {
 	void __iomem *isys_base = isys->pdata->base;
@@ -355,7 +355,7 @@ static int ipu7_isys_phy_ready(struct ipu7_isys *isys, u32 id)
 	dev_dbg(dev, "waiting phy ready...\n");
 	ret = readl_poll_timeout(gpreg + PHY_READY, phy_ready,
 				 phy_ready & BIT(0) && phy_ready != ~0U,
-				 100, CDPHY_TIMEOUT);
+				 100, IPU7_CDPHY_TIMEOUT);
 	dev_dbg(dev, "phy %u ready = 0x%08x\n", id, readl(gpreg + PHY_READY));
 	dev_dbg(dev, "csi %u PHY_RX = 0x%08x\n", id,
 		dwc_csi_read(isys, id, PHY_RX));
@@ -509,7 +509,7 @@ static void ipu7_isys_dphy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
 	dwc_phy_write_mask(isys, id, CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_2,
 			   0, 0, 0);
 	if (!is_ipu7(isys->adev->isp->hw_ver) ||
-	    id == PORT_B || id == PORT_C) {
+	    id == IPU7_PORT_B || id == IPU7_PORT_C) {
 		dwc_phy_write_mask(isys, id,
 				   CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_2,
 				   1, 0, 0);
@@ -551,7 +551,7 @@ static void ipu7_isys_dphy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
 		dwc_phy_write_mask(isys, id, reg + (i * 0x400), val, 3, 3);
 	}
 
-	if (!is_ipu7(isys->adev->isp->hw_ver) || id == PORT_B || id == PORT_C)
+	if (!is_ipu7(isys->adev->isp->hw_ver) || id == IPU7_PORT_B || id == IPU7_PORT_C)
 		reg = CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_9;
 	else
 		reg = CORE_DIG_IOCTRL_RW_AFE_LANE2_CTRL_2_9;
@@ -572,7 +572,7 @@ static void ipu7_isys_dphy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
 		reg = CORE_DIG_IOCTRL_RW_AFE_LANE0_CTRL_2_15;
 		dwc_phy_write_mask(isys, id, reg, 3, 3, 4);
 
-		val = (id == PORT_A) ? 3 : 0;
+		val = (id == IPU7_PORT_A) ? 3 : 0;
 		reg = CORE_DIG_IOCTRL_RW_AFE_LANE1_CTRL_2_15;
 		dwc_phy_write_mask(isys, id, reg, val, 3, 4);
 
@@ -904,7 +904,7 @@ static int ipu7_isys_phy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
 			   563, 0, 11);
 	dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_2, 5, 0, 7);
 	/* bypass the RCAL state (bit6) */
-	if (aggregation && id != PORT_A)
+	if (aggregation && id != IPU7_PORT_A)
 		dwc_phy_write_mask(isys, id, PPI_STARTUP_RW_COMMON_DPHY_2, 0x45,
 				   0, 7);
 
@@ -945,9 +945,9 @@ static int ipu7_isys_phy_config(struct ipu7_isys *isys, u8 id, u8 lanes,
 	else
 		phy_mode = isys->csi2[id].phy_mode;
 
-	if (phy_mode == PHY_MODE_DPHY) {
+	if (phy_mode == IPU7_PHY_MODE_DPHY) {
 		ipu7_isys_dphy_config(isys, id, lanes, aggregation, mbps);
-	} else if (phy_mode == PHY_MODE_CPHY) {
+	} else if (phy_mode == IPU7_PHY_MODE_CPHY) {
 		ipu7_isys_cphy_config(isys, id, lanes, aggregation, mbps);
 	} else {
 		dev_err(dev, "unsupported phy mode %d!\n",
@@ -966,7 +966,7 @@ int ipu7_isys_csi_phy_powerup(struct ipu7_isys_csi2 *csi2)
 	int ret;
 
 	/* lanes remapping for aggregation (port AB) mode */
-	if (!is_ipu7(isys->adev->isp->hw_ver) && lanes > 2 && id == PORT_A) {
+	if (!is_ipu7(isys->adev->isp->hw_ver) && lanes > 2 && id == IPU7_PORT_A) {
 		aggregation = true;
 		lanes = 2;
 	}
@@ -978,14 +978,14 @@ int ipu7_isys_csi_phy_powerup(struct ipu7_isys_csi2 *csi2)
 	gpreg_write(isys, id, PHY_LANE_FORCE_CONTROL, 0xf);
 	gpreg_write(isys, id, PHY_MODE, csi2->phy_mode);
 
-	/* config PORT_B if aggregation mode */
+	/* config IPU7_PORT_B if aggregation mode */
 	if (aggregation) {
-		ipu7_isys_csi_phy_reset(isys, PORT_B);
-		gpreg_write(isys, PORT_B, PHY_CLK_LANE_CONTROL, 0x0);
-		gpreg_write(isys, PORT_B, PHY_LANE_CONTROL_EN, 0x3);
-		gpreg_write(isys, PORT_B, PHY_CLK_LANE_FORCE_CONTROL, 0x2);
-		gpreg_write(isys, PORT_B, PHY_LANE_FORCE_CONTROL, 0xf);
-		gpreg_write(isys, PORT_B, PHY_MODE, csi2->phy_mode);
+		ipu7_isys_csi_phy_reset(isys, IPU7_PORT_B);
+		gpreg_write(isys, IPU7_PORT_B, PHY_CLK_LANE_CONTROL, 0x0);
+		gpreg_write(isys, IPU7_PORT_B, PHY_LANE_CONTROL_EN, 0x3);
+		gpreg_write(isys, IPU7_PORT_B, PHY_CLK_LANE_FORCE_CONTROL, 0x2);
+		gpreg_write(isys, IPU7_PORT_B, PHY_LANE_FORCE_CONTROL, 0xf);
+		gpreg_write(isys, IPU7_PORT_B, PHY_MODE, csi2->phy_mode);
 	}
 
 	ipu7_isys_csi_ctrl_cfg(csi2);
@@ -1008,23 +1008,23 @@ int ipu7_isys_csi_phy_powerup(struct ipu7_isys_csi2 *csi2)
 	gpreg_write(isys, id, PHY_LANE_FORCE_CONTROL, 0);
 	gpreg_write(isys, id, PHY_CLK_LANE_FORCE_CONTROL, 0);
 
-	/* config PORT_B if aggregation mode */
+	/* config IPU7_PORT_B if aggregation mode */
 	if (aggregation) {
-		ret = ipu7_isys_phy_config(isys, PORT_B, 2, aggregation);
+		ret = ipu7_isys_phy_config(isys, IPU7_PORT_B, 2, aggregation);
 		if (ret < 0)
 			return ret;
 
-		gpreg_write(isys, PORT_B, PHY_RESET, 1);
-		gpreg_write(isys, PORT_B, PHY_SHUTDOWN, 1);
-		dwc_csi_write(isys, PORT_B, DPHY_RSTZ, 1);
-		dwc_csi_write(isys, PORT_B, PHY_SHUTDOWNZ, 1);
-		dwc_csi_write(isys, PORT_B, CSI2_RESETN, 1);
-		ret = ipu7_isys_phy_ready(isys, PORT_B);
+		gpreg_write(isys, IPU7_PORT_B, PHY_RESET, 1);
+		gpreg_write(isys, IPU7_PORT_B, PHY_SHUTDOWN, 1);
+		dwc_csi_write(isys, IPU7_PORT_B, DPHY_RSTZ, 1);
+		dwc_csi_write(isys, IPU7_PORT_B, PHY_SHUTDOWNZ, 1);
+		dwc_csi_write(isys, IPU7_PORT_B, CSI2_RESETN, 1);
+		ret = ipu7_isys_phy_ready(isys, IPU7_PORT_B);
 		if (ret < 0)
 			return ret;
 
-		gpreg_write(isys, PORT_B, PHY_LANE_FORCE_CONTROL, 0);
-		gpreg_write(isys, PORT_B, PHY_CLK_LANE_FORCE_CONTROL, 0);
+		gpreg_write(isys, IPU7_PORT_B, PHY_LANE_FORCE_CONTROL, 0);
+		gpreg_write(isys, IPU7_PORT_B, PHY_CLK_LANE_FORCE_CONTROL, 0);
 	}
 
 	return 0;
@@ -1036,6 +1036,6 @@ void ipu7_isys_csi_phy_powerdown(struct ipu7_isys_csi2 *csi2)
 
 	ipu7_isys_csi_phy_reset(isys, csi2->port);
 	if (!is_ipu7(isys->adev->isp->hw_ver) &&
-	    csi2->nlanes > 2U && csi2->port == PORT_A)
-		ipu7_isys_csi_phy_reset(isys, PORT_B);
+	    csi2->nlanes > 2U && csi2->port == IPU7_PORT_A)
+		ipu7_isys_csi_phy_reset(isys, IPU7_PORT_B);
 }
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.h b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.h
index dfdcb61540c4..5a6c47dd7485 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi-phy.h
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi-phy.h
@@ -8,8 +8,8 @@
 
 struct ipu7_isys;
 
-#define PHY_MODE_DPHY		0U
-#define PHY_MODE_CPHY		1U
+#define IPU7_PHY_MODE_DPHY		0
+#define IPU7_PHY_MODE_CPHY		1
 
 int ipu7_isys_csi_phy_powerup(struct ipu7_isys_csi2 *csi2);
 void ipu7_isys_csi_phy_powerdown(struct ipu7_isys_csi2 *csi2);
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h b/drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h
index aad52c44a005..02991a0d5e90 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi2-regs.h
@@ -54,7 +54,7 @@
 #define IS_MAIN_IRQ_CTL_LEVEL_NOT_PULSE		(IS_MAIN_IRQ_CTRL_BASE + 0x14)
 
 /* IS IO regs base */
-#define IS_PHY_NUM				4U
+#define IPU7_IS_PHY_NUM				4
 #define IS_IO_BASE				0x280000
 
 /* dwc csi cdphy registers */
@@ -1003,7 +1003,7 @@
 #define PORT_ARB_IRQ_CTL_CLEAR			0x8
 #define PORT_ARB_IRQ_CTL_ENABLE			0xc
 
-#define MGC_PPC					4U
+#define IPU7_MGC_PPC					4
 #define MGC_DTYPE_RAW(i)			(((i) - 8) / 2)
 #define IS_IO_MGC_BASE				(IS_IO_BASE + 0x48000)
 #define MGC_KICK				0x0
@@ -1048,8 +1048,8 @@
 #define MGC_MG_BUSY_STTS			0xa8
 #define MGC_MG_STOPPED_STTS			0xac
 /* tile width and height in pixels for Chess board and Color palette */
-#define MGC_TPG_TILE_WIDTH			64U
-#define MGC_TPG_TILE_HEIGHT			64U
+#define IPU7_MGC_TPG_TILE_WIDTH			64
+#define IPU7_MGC_TPG_TILE_HEIGHT			64
 
 #define IPU_CSI_PORT_A_ADDR_OFFSET		0x0
 #define IPU_CSI_PORT_B_ADDR_OFFSET		0x0
@@ -1152,8 +1152,8 @@
 #define IPU7_CSI_RX_SYNC_IRQ_MASK		0x0
 #define IPU7P5_CSI_RX_SYNC_FE_IRQ_MASK		0x0
 
-#define CSI_RX_NUM_ERRORS_IN_IRQ		12U
-#define CSI_RX_NUM_SYNC_IN_IRQ			32U
+#define IPU7_CSI_RX_NUM_ERRORS_IN_IRQ		12
+#define IPU7_CSI_RX_NUM_SYNC_IN_IRQ			32
 
 enum CSI_FE_MODE_TYPE {
 	CSI_FE_DPHY_MODE = 0,
@@ -1187,7 +1187,7 @@ enum CSI2HOST_SELECTION {
 #define CSI_REG_PORT_GPREG_CSI2_SLV_REG_SRST	0x4
 #define CSI_REG_PORT_GPREG_CSI2_PORT_CONTROL	0x8
 
-#define CSI_RX_NUM_IRQ				32U
+#define IPU7_CSI_RX_NUM_IRQ				32
 
 #define IPU7_CSI_RX_SYNC_FS_VC			0x55555555
 #define IPU7_CSI_RX_SYNC_FE_VC			0xaaaaaaaa
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.c b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
index f34eabfe8a98..a5e222e92edb 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi2.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.c
@@ -222,7 +222,7 @@ static int ipu7_isys_csi2_set_sel(struct v4l2_subdev *sd,
 	/* Non-bayer formats can't be single line cropped */
 	if (!ipu7_isys_is_bayer_format(sink_ffmt->code))
 		sel->r.top &= ~1U;
-	sel->r.height = clamp(sel->r.height & ~1U, IPU_ISYS_MIN_HEIGHT,
+	sel->r.height = clamp(sel->r.height & ~1U, IPU7_ISYS_MIN_HEIGHT,
 			      sink_ffmt->height - sel->r.top);
 	*crop = sel->r;
 
diff --git a/drivers/staging/media/ipu7/ipu7-isys-csi2.h b/drivers/staging/media/ipu7/ipu7-isys-csi2.h
index 6c23b80f92a2..a83b9a1e2bc7 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-csi2.h
+++ b/drivers/staging/media/ipu7/ipu7-isys-csi2.h
@@ -16,12 +16,12 @@ struct ipu7_isys;
 struct ipu7_isys_csi2_pdata;
 struct ipu7_isys_stream;
 
-#define IPU7_NR_OF_CSI2_VC		16U
+#define IPU7_NR_OF_CSI2_VC		16
 #define INVALID_VC_ID			-1
-#define IPU7_NR_OF_CSI2_SINK_PADS	1U
-#define IPU7_CSI2_PAD_SINK		0U
-#define IPU7_NR_OF_CSI2_SRC_PADS	8U
-#define IPU7_CSI2_PAD_SRC		1U
+#define IPU7_NR_OF_CSI2_SINK_PADS	1
+#define IPU7_CSI2_PAD_SINK		0
+#define IPU7_NR_OF_CSI2_SRC_PADS	8
+#define IPU7_CSI2_PAD_SRC		1
 #define IPU7_NR_OF_CSI2_PADS		(IPU7_NR_OF_CSI2_SINK_PADS + \
 					 IPU7_NR_OF_CSI2_SRC_PADS)
 
diff --git a/drivers/staging/media/ipu7/ipu7-isys-queue.c b/drivers/staging/media/ipu7/ipu7-isys-queue.c
index 434d9d9c7158..c6eecd5c86f3 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-queue.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-queue.c
@@ -652,7 +652,7 @@ get_sof_sequence_by_timestamp(struct ipu7_isys_stream *stream, u64 time)
 	if (time == 0)
 		return atomic_read(&stream->sequence) - 1;
 
-	for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++)
+	for (i = 0; i < IPU7_ISYS_MAX_PARALLEL_SOF; i++)
 		if (time == stream->seq[i].timestamp) {
 			dev_dbg(dev, "SOF: using seq nr %u for ts %llu\n",
 				stream->seq[i].sequence, time);
@@ -660,7 +660,7 @@ get_sof_sequence_by_timestamp(struct ipu7_isys_stream *stream, u64 time)
 		}
 
 	dev_dbg(dev, "SOF: looking for %llu\n", time);
-	for (i = 0; i < IPU_ISYS_MAX_PARALLEL_SOF; i++)
+	for (i = 0; i < IPU7_ISYS_MAX_PARALLEL_SOF; i++)
 		dev_dbg(dev, "SOF: sequence %u, timestamp value %llu\n",
 			stream->seq[i].sequence, stream->seq[i].timestamp);
 	dev_dbg(dev, "SOF sequence number not found\n");
diff --git a/drivers/staging/media/ipu7/ipu7-isys-subdev.c b/drivers/staging/media/ipu7/ipu7-isys-subdev.c
index 67a776033d5b..b05035b403d5 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-subdev.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-subdev.c
@@ -115,11 +115,11 @@ int ipu7_isys_subdev_set_fmt(struct v4l2_subdev *sd,
 	    sd->entity.num_pads > 1)
 		return v4l2_subdev_get_fmt(sd, state, format);
 
-	format->format.width = clamp(format->format.width, IPU_ISYS_MIN_WIDTH,
-				     IPU_ISYS_MAX_WIDTH);
+	format->format.width = clamp(format->format.width, IPU7_ISYS_MIN_WIDTH,
+				     IPU7_ISYS_MAX_WIDTH);
 	format->format.height = clamp(format->format.height,
-				      IPU_ISYS_MIN_HEIGHT,
-				      IPU_ISYS_MAX_HEIGHT);
+				      IPU7_ISYS_MIN_HEIGHT,
+				      IPU7_ISYS_MAX_HEIGHT);
 
 	for (i = 0; asd->supported_codes[i]; i++) {
 		if (asd->supported_codes[i] == format->format.code) {
diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.c b/drivers/staging/media/ipu7/ipu7-isys-video.c
index 8c6730833f24..4c5d9d1ec772 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-video.c
+++ b/drivers/staging/media/ipu7/ipu7-isys-video.c
@@ -152,10 +152,10 @@ static int ipu7_isys_vidioc_enum_framesizes(struct file *file, void *fh,
 			continue;
 
 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
-		fsize->stepwise.min_width = IPU_ISYS_MIN_WIDTH;
-		fsize->stepwise.max_width = IPU_ISYS_MAX_WIDTH;
-		fsize->stepwise.min_height = IPU_ISYS_MIN_HEIGHT;
-		fsize->stepwise.max_height = IPU_ISYS_MAX_HEIGHT;
+		fsize->stepwise.min_width = IPU7_ISYS_MIN_WIDTH;
+		fsize->stepwise.max_width = IPU7_ISYS_MAX_WIDTH;
+		fsize->stepwise.min_height = IPU7_ISYS_MIN_HEIGHT;
+		fsize->stepwise.max_height = IPU7_ISYS_MAX_HEIGHT;
 		fsize->stepwise.step_width = 2;
 		fsize->stepwise.step_height = 2;
 
@@ -183,8 +183,8 @@ static void ipu7_isys_try_fmt_cap(struct ipu7_isys_video *av, u32 type,
 		ipu7_isys_get_isys_format(*format);
 
 	*format = pfmt->pixelformat;
-	*width = clamp(*width, IPU_ISYS_MIN_WIDTH, IPU_ISYS_MAX_WIDTH);
-	*height = clamp(*height, IPU_ISYS_MIN_HEIGHT, IPU_ISYS_MAX_HEIGHT);
+	*width = clamp(*width, IPU7_ISYS_MIN_WIDTH, IPU7_ISYS_MAX_WIDTH);
+	*height = clamp(*height, IPU7_ISYS_MIN_HEIGHT, IPU7_ISYS_MAX_HEIGHT);
 
 	if (pfmt->bpp != pfmt->bpp_packed)
 		*bytesperline = *width * DIV_ROUND_UP(pfmt->bpp, BITS_PER_BYTE);
@@ -665,7 +665,7 @@ void ipu7_isys_put_stream(struct ipu7_isys_stream *stream)
 	dev = &stream->isys->adev->auxdev.dev;
 
 	spin_lock_irqsave(&stream->isys->streams_lock, flags);
-	for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) {
+	for (i = 0; i < IPU7_ISYS_MAX_STREAMS; i++) {
 		if (&stream->isys->streams[i] == stream) {
 			if (stream->isys->streams_ref_count[i] > 0)
 				stream->isys->streams_ref_count[i]--;
@@ -691,7 +691,7 @@ ipu7_isys_get_stream(struct ipu7_isys_video *av, struct ipu7_isys_subdev *asd)
 		return NULL;
 
 	spin_lock_irqsave(&isys->streams_lock, flags);
-	for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) {
+	for (i = 0; i < IPU7_ISYS_MAX_STREAMS; i++) {
 		if (isys->streams_ref_count[i] && isys->streams[i].vc == vc &&
 		    isys->streams[i].asd == asd) {
 			isys->streams_ref_count[i]++;
@@ -701,7 +701,7 @@ ipu7_isys_get_stream(struct ipu7_isys_video *av, struct ipu7_isys_subdev *asd)
 	}
 
 	if (!stream) {
-		for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) {
+		for (i = 0; i < IPU7_ISYS_MAX_STREAMS; i++) {
 			if (!isys->streams_ref_count[i]) {
 				isys->streams_ref_count[i]++;
 				stream = &isys->streams[i];
@@ -725,7 +725,7 @@ ipu7_isys_query_stream_by_handle(struct ipu7_isys *isys, u8 stream_handle)
 	if (!isys)
 		return NULL;
 
-	if (stream_handle >= IPU_ISYS_MAX_STREAMS) {
+	if (stream_handle >= IPU7_ISYS_MAX_STREAMS) {
 		dev_err(&isys->adev->auxdev.dev,
 			"stream_handle %d is invalid\n", stream_handle);
 		return NULL;
@@ -758,7 +758,7 @@ ipu7_isys_query_stream_by_source(struct ipu7_isys *isys, int source, u8 vc)
 	}
 
 	spin_lock_irqsave(&isys->streams_lock, flags);
-	for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) {
+	for (i = 0; i < IPU7_ISYS_MAX_STREAMS; i++) {
 		if (!isys->streams_ref_count[i])
 			continue;
 
diff --git a/drivers/staging/media/ipu7/ipu7-isys-video.h b/drivers/staging/media/ipu7/ipu7-isys-video.h
index 1ac1787fabef..55510c594655 100644
--- a/drivers/staging/media/ipu7/ipu7-isys-video.h
+++ b/drivers/staging/media/ipu7/ipu7-isys-video.h
@@ -17,8 +17,8 @@
 
 #include "ipu7-isys-queue.h"
 
-#define IPU_INSYS_OUTPUT_PINS		11U
-#define IPU_ISYS_MAX_PARALLEL_SOF	2U
+#define IPU7_INSYS_OUTPUT_PINS		11
+#define IPU7_ISYS_MAX_PARALLEL_SOF	2
 
 struct file;
 struct ipu7_isys;
@@ -55,7 +55,7 @@ struct ipu7_isys_stream {
 	atomic_t sequence;
 	atomic_t buf_id;
 	unsigned int seq_index;
-	struct sequence_info seq[IPU_ISYS_MAX_PARALLEL_SOF];
+	struct sequence_info seq[IPU7_ISYS_MAX_PARALLEL_SOF];
 	int stream_source;
 	int stream_handle;
 	unsigned int nr_output_pins;
@@ -71,7 +71,7 @@ struct ipu7_isys_stream {
 	struct completion stream_stop_completion;
 	struct ipu7_isys *isys;
 
-	struct output_pin_data output_pins[IPU_INSYS_OUTPUT_PINS];
+	struct output_pin_data output_pins[IPU7_INSYS_OUTPUT_PINS];
 	int error;
 	u8 vc;
 };
diff --git a/drivers/staging/media/ipu7/ipu7-isys.c b/drivers/staging/media/ipu7/ipu7-isys.c
index cb2f49f3e0fa..6cb597e114fa 100644
--- a/drivers/staging/media/ipu7/ipu7-isys.c
+++ b/drivers/staging/media/ipu7/ipu7-isys.c
@@ -82,9 +82,9 @@ isys_complete_ext_device_registration(struct ipu7_isys *isys,
 
 	isys->csi2[csi2->port].nlanes = csi2->nlanes;
 	if (csi2->bus_type == V4L2_MBUS_CSI2_DPHY)
-		isys->csi2[csi2->port].phy_mode = PHY_MODE_DPHY;
+		isys->csi2[csi2->port].phy_mode = IPU7_PHY_MODE_DPHY;
 	else
-		isys->csi2[csi2->port].phy_mode = PHY_MODE_CPHY;
+		isys->csi2[csi2->port].phy_mode = IPU7_PHY_MODE_CPHY;
 
 	return 0;
 
@@ -97,7 +97,7 @@ static void isys_stream_init(struct ipu7_isys *isys)
 {
 	unsigned int i;
 
-	for (i = 0; i < IPU_ISYS_MAX_STREAMS; i++) {
+	for (i = 0; i < IPU7_ISYS_MAX_STREAMS; i++) {
 		mutex_init(&isys->streams[i].mutex);
 		init_completion(&isys->streams[i].stream_open_completion);
 		init_completion(&isys->streams[i].stream_close_completion);
@@ -576,7 +576,7 @@ static void isys_remove(struct auxiliary_device *auxdev)
 	struct isys_fw_msgs *fwmsg, *safe;
 	struct ipu7_bus_device *adev = auxdev_to_adev(auxdev);
 
-	for (int i = 0; i < IPU_ISYS_MAX_STREAMS; i++)
+	for (int i = 0; i < IPU7_ISYS_MAX_STREAMS; i++)
 		mutex_destroy(&isys->streams[i].mutex);
 
 	list_for_each_entry_safe(fwmsg, safe, &isys->framebuflist, head)
@@ -779,7 +779,7 @@ static int isys_probe(struct auxiliary_device *auxdev,
 out_cleanup_isys:
 	cpu_latency_qos_remove_request(&isys->pm_qos);
 
-	for (unsigned int i = 0; i < IPU_ISYS_MAX_STREAMS; i++)
+	for (unsigned int i = 0; i < IPU7_ISYS_MAX_STREAMS; i++)
 		mutex_destroy(&isys->streams[i].mutex);
 
 	mutex_destroy(&isys->mutex);
@@ -846,7 +846,7 @@ static void ipu7_isys_csi2_error(struct ipu7_isys_csi2 *csi2)
 	csi2->receiver_errors = 0;
 	errors = dphy_rx_errors;
 
-	for (i = 0; i < CSI_RX_NUM_ERRORS_IN_IRQ; i++) {
+	for (i = 0; i < IPU7_CSI_RX_NUM_ERRORS_IN_IRQ; i++) {
 		if (status & BIT(i))
 			dev_err_ratelimited(&csi2->isys->adev->auxdev.dev,
 					    "csi2-%i error: %s\n",
@@ -934,7 +934,7 @@ int isys_isr_one(struct ipu7_bus_device *adev)
 		dev_dbg(dev, "\tts %llu\n", ts);
 	}
 
-	if (resp->stream_id >= IPU_ISYS_MAX_STREAMS) {
+	if (resp->stream_id >= IPU7_ISYS_MAX_STREAMS) {
 		dev_err(dev, "bad stream handle %u\n",
 			resp->stream_id);
 		goto leave;
@@ -974,7 +974,7 @@ int isys_isr_one(struct ipu7_bus_device *adev)
 		 * get pin_data_ready event
 		 */
 		ipu7_put_fw_msg_buf(ipu7_bus_get_drvdata(adev), resp->buf_id);
-		if (resp->pin_id < IPU_INSYS_OUTPUT_PINS &&
+		if (resp->pin_id < IPU7_INSYS_OUTPUT_PINS &&
 		    stream->output_pins[resp->pin_id].pin_ready)
 			stream->output_pins[resp->pin_id].pin_ready(stream,
 								    resp);
@@ -1002,7 +1002,7 @@ int isys_isr_one(struct ipu7_bus_device *adev)
 			resp->stream_id, resp->frame_id,
 			stream->seq[stream->seq_index].sequence, ts);
 		stream->seq_index = (stream->seq_index + 1U)
-			% IPU_ISYS_MAX_PARALLEL_SOF;
+			% IPU7_ISYS_MAX_PARALLEL_SOF;
 		break;
 	case IPU_INSYS_RESP_TYPE_FRAME_EOF:
 		if (csi2)
diff --git a/drivers/staging/media/ipu7/ipu7-isys.h b/drivers/staging/media/ipu7/ipu7-isys.h
index ef1ab1b42f6c..951a509db93d 100644
--- a/drivers/staging/media/ipu7/ipu7-isys.h
+++ b/drivers/staging/media/ipu7/ipu7-isys.h
@@ -28,21 +28,21 @@
 #define IPU_ISYS_ENTITY_PREFIX		"Intel IPU7"
 
 /* FW support max 16 streams */
-#define IPU_ISYS_MAX_STREAMS		16U
+#define IPU7_ISYS_MAX_STREAMS		16
 
 /*
  * Current message queue configuration. These must be big enough
  * so that they never gets full. Queues are located in system memory
  */
-#define IPU_ISYS_SIZE_RECV_QUEUE	40U
-#define IPU_ISYS_SIZE_LOG_QUEUE		256U
-#define IPU_ISYS_SIZE_SEND_QUEUE	40U
-#define IPU_ISYS_NUM_RECV_QUEUE		1U
+#define IPU7_ISYS_SIZE_RECV_QUEUE	40
+#define IPU7_ISYS_SIZE_LOG_QUEUE		256
+#define IPU7_ISYS_SIZE_SEND_QUEUE	40
+#define IPU7_ISYS_NUM_RECV_QUEUE		1
 
-#define IPU_ISYS_MIN_WIDTH		2U
-#define IPU_ISYS_MIN_HEIGHT		2U
-#define IPU_ISYS_MAX_WIDTH		8160U
-#define IPU_ISYS_MAX_HEIGHT		8190U
+#define IPU7_ISYS_MIN_WIDTH		2
+#define IPU7_ISYS_MIN_HEIGHT		2
+#define IPU7_ISYS_MAX_WIDTH		8160
+#define IPU7_ISYS_MAX_HEIGHT		8190
 
 #define FW_CALL_TIMEOUT_JIFFIES		\
 	msecs_to_jiffies(IPU_LIB_CALL_TIMEOUT_MS)
@@ -84,8 +84,8 @@ struct ipu7_isys {
 	u32 isr_csi2_mask;
 	u32 csi2_rx_ctrl_cached;
 	spinlock_t streams_lock;
-	struct ipu7_isys_stream streams[IPU_ISYS_MAX_STREAMS];
-	int streams_ref_count[IPU_ISYS_MAX_STREAMS];
+	struct ipu7_isys_stream streams[IPU7_ISYS_MAX_STREAMS];
+	int streams_ref_count[IPU7_ISYS_MAX_STREAMS];
 	u32 phy_rext_cal;
 	bool icache_prefetch;
 	bool csi2_cse_ipc_not_supported;
diff --git a/drivers/staging/media/ipu7/ipu7-mmu.c b/drivers/staging/media/ipu7/ipu7-mmu.c
index 6ded07ccd780..c5f83023ddbd 100644
--- a/drivers/staging/media/ipu7/ipu7-mmu.c
+++ b/drivers/staging/media/ipu7/ipu7-mmu.c
@@ -33,16 +33,16 @@
 
 #define ISP_PAGE_SHIFT		12
 #define ISP_PAGE_SIZE		BIT(ISP_PAGE_SHIFT)
-#define ISP_PAGE_MASK		(~(ISP_PAGE_SIZE - 1U))
+#define IPU7_ISP_PAGE_MASK		(~(ISP_PAGE_SIZE - 1))
 
 #define ISP_L1PT_SHIFT		22
-#define ISP_L1PT_MASK		(~((1U << ISP_L1PT_SHIFT) - 1))
+#define IPU7_ISP_L1PT_MASK		(~((1 << ISP_L1PT_SHIFT) - 1))
 
 #define ISP_L2PT_SHIFT		12
-#define ISP_L2PT_MASK		(~(ISP_L1PT_MASK | (~(ISP_PAGE_MASK))))
+#define ISP_L2PT_MASK		(~(IPU7_ISP_L1PT_MASK | (~(IPU7_ISP_PAGE_MASK))))
 
-#define ISP_L1PT_PTES		1024U
-#define ISP_L2PT_PTES		1024U
+#define IPU7_ISP_L1PT_PTES		1024
+#define IPU7_ISP_L2PT_PTES		1024
 
 #define ISP_PADDR_SHIFT		12
 
@@ -170,7 +170,7 @@ static int alloc_dummy_l2_pt(struct ipu7_mmu_info *mmu_info)
 		goto err_free_page;
 	}
 
-	for (i = 0; i < ISP_L2PT_PTES; i++)
+	for (i = 0; i < IPU7_ISP_L2PT_PTES; i++)
 		pt[i] = mmu_info->dummy_page_pteval;
 
 	mmu_info->dummy_l2_pt = pt;
@@ -202,7 +202,7 @@ static u32 *alloc_l1_pt(struct ipu7_mmu_info *mmu_info)
 
 	dev_dbg(mmu_info->dev, "alloc_l1: get_zeroed_page() = %p\n", pt);
 
-	for (i = 0; i < ISP_L1PT_PTES; i++)
+	for (i = 0; i < IPU7_ISP_L1PT_PTES; i++)
 		pt[i] = mmu_info->dummy_l2_pteval;
 
 	dma = map_single(mmu_info, pt);
@@ -231,7 +231,7 @@ static u32 *alloc_l2_pt(struct ipu7_mmu_info *mmu_info)
 
 	dev_dbg(mmu_info->dev, "alloc_l2: get_zeroed_page() = %p\n", pt);
 
-	for (i = 0; i < ISP_L2PT_PTES; i++)
+	for (i = 0; i < IPU7_ISP_L2PT_PTES; i++)
 		pt[i] = mmu_info->dummy_page_pteval;
 
 	return pt;
@@ -248,7 +248,7 @@ static void l2_unmap(struct ipu7_mmu_info *mmu_info, unsigned long iova,
 
 	spin_lock_irqsave(&mmu_info->lock, flags);
 	for (l1_idx = iova >> ISP_L1PT_SHIFT;
-	     size > 0U && l1_idx < ISP_L1PT_PTES; l1_idx++) {
+	     size > 0U && l1_idx < IPU7_ISP_L1PT_PTES; l1_idx++) {
 		dev_dbg(mmu_info->dev,
 			"unmapping l2 pgtable (l1 index %u (iova 0x%8.8lx))\n",
 			l1_idx, iova);
@@ -263,7 +263,7 @@ static void l2_unmap(struct ipu7_mmu_info *mmu_info, unsigned long iova,
 
 		l2_entries = 0;
 		for (l2_idx = (iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT;
-		     size > 0U && l2_idx < ISP_L2PT_PTES; l2_idx++) {
+		     size > 0U && l2_idx < IPU7_ISP_L2PT_PTES; l2_idx++) {
 			phys_addr_t pteval = TBL_PHYS_ADDR(l2_pt[l2_idx]);
 
 			dev_dbg(mmu_info->dev,
@@ -304,7 +304,7 @@ static int l2_map(struct ipu7_mmu_info *mmu_info, unsigned long iova,
 
 	paddr = ALIGN(paddr, ISP_PAGE_SIZE);
 	for (l1_idx = iova >> ISP_L1PT_SHIFT;
-	     size && l1_idx < ISP_L1PT_PTES; l1_idx++) {
+	     size && l1_idx < IPU7_ISP_L1PT_PTES; l1_idx++) {
 		dev_dbg(dev,
 			"mapping l2 page table for l1 index %u (iova %8.8x)\n",
 			l1_idx, (u32)iova);
@@ -343,7 +343,7 @@ static int l2_map(struct ipu7_mmu_info *mmu_info, unsigned long iova,
 		l2_entries = 0;
 
 		for (l2_idx = (iova & ISP_L2PT_MASK) >> ISP_L2PT_SHIFT;
-		     size && l2_idx < ISP_L2PT_PTES; l2_idx++) {
+		     size && l2_idx < IPU7_ISP_L2PT_PTES; l2_idx++) {
 			l2_pt[l2_idx] = paddr >> ISP_PADDR_SHIFT;
 
 			dev_dbg(dev, "l2 index %u mapped as 0x%8.8x\n", l2_idx,
@@ -518,7 +518,7 @@ static void __mmu_zlx_init(struct ipu7_mmu *mmu)
 		unsigned int j;
 
 		dev_dbg(mmu->dev, "mmu %s zlx init\n", mmu_hw->name);
-		for (j = 0; j < IPU_ZLX_POOL_NUM; j++) {
+		for (j = 0; j < IPU7_ZLX_POOL_NUM; j++) {
 			if (!mmu_hw->zlx_axi_pool[j])
 				continue;
 			writel(mmu_hw->zlx_axi_pool[j],
@@ -609,7 +609,7 @@ static struct ipu7_mmu_info *ipu7_mmu_alloc(struct ipu7_device *isp)
 	if (ret)
 		goto err_free_dummy_page;
 
-	mmu_info->l2_pts = vzalloc(ISP_L2PT_PTES * sizeof(*mmu_info->l2_pts));
+	mmu_info->l2_pts = vzalloc(IPU7_ISP_L2PT_PTES * sizeof(*mmu_info->l2_pts));
 	if (!mmu_info->l2_pts)
 		goto err_free_dummy_l2_pt;
 
@@ -772,7 +772,7 @@ static void ipu7_mmu_destroy(struct ipu7_mmu *mmu)
 		__free_page(mmu->trash_page);
 	}
 
-	for (l1_idx = 0; l1_idx < ISP_L1PT_PTES; l1_idx++) {
+	for (l1_idx = 0; l1_idx < IPU7_ISP_L1PT_PTES; l1_idx++) {
 		if (mmu_info->l1_pt[l1_idx] != mmu_info->dummy_l2_pteval) {
 			dma_unmap_single(mmu_info->dev,
 					 TBL_PHYS_ADDR(mmu_info->l1_pt[l1_idx]),
@@ -799,7 +799,7 @@ struct ipu7_mmu *ipu7_mmu_init(struct device *dev,
 	struct ipu7_mmu *mmu;
 	unsigned int i;
 
-	if (hw->nr_mmus > IPU_MMU_MAX_NUM)
+	if (hw->nr_mmus > IPU7_MMU_MAX_NUM)
 		return ERR_PTR(-EINVAL);
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@@ -810,8 +810,8 @@ struct ipu7_mmu *ipu7_mmu_init(struct device *dev,
 		struct ipu7_mmu_hw *pdata_mmu = &pdata->mmu_hw[i];
 		const struct ipu7_mmu_hw *src_mmu = &hw->mmu_hw[i];
 
-		if (src_mmu->nr_l1streams > IPU_MMU_MAX_TLB_L1_STREAMS ||
-		    src_mmu->nr_l2streams > IPU_MMU_MAX_TLB_L2_STREAMS)
+		if (src_mmu->nr_l1streams > IPU7_MMU_MAX_TLB_L1_STREAMS ||
+		    src_mmu->nr_l2streams > IPU7_MMU_MAX_TLB_L2_STREAMS)
 			return ERR_PTR(-EINVAL);
 
 		*pdata_mmu = *src_mmu;
diff --git a/drivers/staging/media/ipu7/ipu7.c b/drivers/staging/media/ipu7/ipu7.c
index c771e763f8c5..d5bff819a83a 100644
--- a/drivers/staging/media/ipu7/ipu7.c
+++ b/drivers/staging/media/ipu7/ipu7.c
@@ -52,7 +52,7 @@ static struct ipu_isys_internal_pdata ipu7p5_isys_ipdata = {
 	},
 	.hw_variant = {
 		.offset = IPU_UNIFIED_OFFSET,
-		.nr_mmus = IPU7P5_IS_MMU_NUM,
+		.nr_mmus = IPU7_7P5_IS_MMU_NUM,
 		.mmu_hw = {
 			{
 				.name = "IS_FW_RD",
@@ -333,7 +333,7 @@ static struct ipu_isys_internal_pdata ipu7p5_isys_ipdata = {
 static struct ipu_psys_internal_pdata ipu7p5_psys_ipdata = {
 	.hw_variant = {
 		.offset = IPU_UNIFIED_OFFSET,
-		.nr_mmus = IPU7P5_PS_MMU_NUM,
+		.nr_mmus = IPU7_7P5_PS_MMU_NUM,
 		.mmu_hw = {
 			{
 				.name = "PS_FW_RD",
@@ -1309,7 +1309,7 @@ static struct ipu_isys_internal_pdata ipu8_isys_ipdata = {
 	},
 	.hw_variant = {
 		.offset = IPU_UNIFIED_OFFSET,
-		.nr_mmus = IPU8_IS_MMU_NUM,
+		.nr_mmus = IPU7_8_IS_MMU_NUM,
 		.mmu_hw = {
 			{
 				.name = "IS_FW_RD",
@@ -1644,7 +1644,7 @@ static struct ipu_isys_internal_pdata ipu8_isys_ipdata = {
 static struct ipu_psys_internal_pdata ipu8_psys_ipdata = {
 	.hw_variant = {
 		.offset = IPU_UNIFIED_OFFSET,
-		.nr_mmus = IPU8_PS_MMU_NUM,
+		.nr_mmus = IPU7_8_PS_MMU_NUM,
 		.mmu_hw = {
 			{
 				.name = "PS_FW_RD",
diff --git a/drivers/staging/media/ipu7/ipu7.h b/drivers/staging/media/ipu7/ipu7.h
index ac8ac0689468..79cf750e85b4 100644
--- a/drivers/staging/media/ipu7/ipu7.h
+++ b/drivers/staging/media/ipu7/ipu7.h
@@ -100,18 +100,18 @@ struct ipu7_device {
 /* FW is accessible within the first 2 GiB only in non-secure mode. */
 #define IPU_MMU_ADDR_BITS_NON_SECURE	31
 
-#define IPU7_IS_MMU_NUM			4U
-#define IPU7_PS_MMU_NUM			4U
-#define IPU7P5_IS_MMU_NUM		4U
-#define IPU7P5_PS_MMU_NUM		4U
-#define IPU8_IS_MMU_NUM			5U
-#define IPU8_PS_MMU_NUM			4U
-#define IPU_MMU_MAX_NUM			5U /* max(IS, PS) */
-#define IPU_MMU_MAX_TLB_L1_STREAMS	40U
-#define IPU_MMU_MAX_TLB_L2_STREAMS	40U
-#define IPU_ZLX_MAX_NUM			32U
-#define IPU_ZLX_POOL_NUM		8U
-#define IPU_UAO_PLANE_MAX_NUM		64U
+#define IPU7_IS_MMU_NUM			4
+#define IPU7_PS_MMU_NUM			4
+#define IPU7_7P5_IS_MMU_NUM		4
+#define IPU7_7P5_PS_MMU_NUM		4
+#define IPU7_8_IS_MMU_NUM			5
+#define IPU7_8_PS_MMU_NUM			4
+#define IPU7_MMU_MAX_NUM			5 /* max(IS, PS) */
+#define IPU7_MMU_MAX_TLB_L1_STREAMS	40
+#define IPU7_MMU_MAX_TLB_L2_STREAMS	40
+#define IPU7_ZLX_MAX_NUM			32
+#define IPU7_ZLX_POOL_NUM		8
+#define IPU7_UAO_PLANE_MAX_NUM		64
 
 /*
  * To maximize the IOSF utlization, IPU need to send requests in bursts.
@@ -175,21 +175,21 @@ struct ipu7_mmu_hw {
 
 	u8 nr_l1streams;
 	u8 nr_l2streams;
-	u32 l1_block_sz[IPU_MMU_MAX_TLB_L1_STREAMS];
-	u32 l2_block_sz[IPU_MMU_MAX_TLB_L2_STREAMS];
+	u32 l1_block_sz[IPU7_MMU_MAX_TLB_L1_STREAMS];
+	u32 l2_block_sz[IPU7_MMU_MAX_TLB_L2_STREAMS];
 
 	u8 zlx_nr;
-	u32 zlx_axi_pool[IPU_ZLX_POOL_NUM];
-	u32 zlx_en[IPU_ZLX_MAX_NUM];
-	u32 zlx_conf[IPU_ZLX_MAX_NUM];
+	u32 zlx_axi_pool[IPU7_ZLX_POOL_NUM];
+	u32 zlx_en[IPU7_ZLX_MAX_NUM];
+	u32 zlx_conf[IPU7_ZLX_MAX_NUM];
 
 	u32 uao_p_num;
-	u32 uao_p2tlb[IPU_UAO_PLANE_MAX_NUM];
+	u32 uao_p2tlb[IPU7_UAO_PLANE_MAX_NUM];
 };
 
 struct ipu7_mmu_pdata {
 	u32 nr_mmus;
-	struct ipu7_mmu_hw mmu_hw[IPU_MMU_MAX_NUM];
+	struct ipu7_mmu_hw mmu_hw[IPU7_MMU_MAX_NUM];
 	int mmid;
 };
 
@@ -206,7 +206,7 @@ struct ipu7_isys_internal_csi2_pdata {
 struct ipu7_hw_variants {
 	unsigned long offset;
 	u32 nr_mmus;
-	struct ipu7_mmu_hw mmu_hw[IPU_MMU_MAX_NUM];
+	struct ipu7_mmu_hw mmu_hw[IPU7_MMU_MAX_NUM];
 	u8 cdc_fifos;
 	u8 cdc_fifo_threshold[IPU_MAX_VC_IOSF_PORTS];
 	u32 dmem_offset;
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH RFC 6/7] media: qcom: iris: vdec: update find_format to handle 8bit and 10bit formats
From: Vishnu Reddy @ 2026-04-15  6:39 UTC (permalink / raw)
  To: Neil Armstrong, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
	Bryan O'Donoghue, Mauro Carvalho Chehab
  Cc: linux-media, linux-arm-msm, linux-kernel
In-Reply-To: <20260408-topic-sm8x50-iris-10bit-decoding-v1-6-428c1ec2e3f3@linaro.org>


On 4/8/2026 10:13 PM, Neil Armstrong wrote:
> The 10bit pixel format can be only used when the decoder identifies the
> stream as decoding into 10bit pixel format buffers, so update the
> find_format helpers to filter the formats.

This series breaks the v4l2 compliance tests for the existing platforms.
Decoder failed for below:
VIDIOC_S_FMT: FAIL
Cropping: FAIL
Composing: FAIL
Encoder streaming tests failed.
Please check once.

Regards,
Vishnu Reddy.

>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
>   .../platform/qcom/iris/iris_platform_common.h      |  1 +
>   drivers/media/platform/qcom/iris/iris_vdec.c       | 41 ++++++++++++++++++++--
>   2 files changed, 40 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 5a489917580e..cd3509da4b75 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -18,6 +18,7 @@ struct iris_inst;
>   
>   #define REGISTER_BIT_DEPTH(luma, chroma)	((luma) << 16 | (chroma))
>   #define BIT_DEPTH_8				REGISTER_BIT_DEPTH(8, 8)
> +#define BIT_DEPTH_10				REGISTER_BIT_DEPTH(10, 10)
>   #define CODED_FRAMES_PROGRESSIVE		0x0
>   #define DEFAULT_MAX_HOST_BUF_COUNT		64
>   #define DEFAULT_MAX_HOST_BURST_BUF_COUNT	256
> diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c
> index ca0518c27834..bfc13c1044c7 100644
> --- a/drivers/media/platform/qcom/iris/iris_vdec.c
> +++ b/drivers/media/platform/qcom/iris/iris_vdec.c
> @@ -105,6 +105,16 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type)
>   	if (i == size || fmt[i].type != type)
>   		return NULL;
>   
> +	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> +		if (iris_fmt_is_8bit(fmt[i].pixfmt) &&
> +		    inst->fw_caps[BIT_DEPTH].value == BIT_DEPTH_8)
> +			return NULL;
> +
> +		if (iris_fmt_is_10bit(fmt[i].pixfmt) &&
> +		    inst->fw_caps[BIT_DEPTH].value != BIT_DEPTH_10)
> +			return NULL;
> +	}
> +
>   	return &fmt[i];
>   }
>   
> @@ -113,6 +123,7 @@ find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
>   {
>   	const struct iris_fmt *fmt = NULL;
>   	unsigned int size = 0;
> +	unsigned int i, k = 0;
>   
>   	switch (type) {
>   	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
> @@ -127,10 +138,36 @@ find_format_by_index(struct iris_inst *inst, u32 index, u32 type)
>   		return NULL;
>   	}
>   
> -	if (index >= size || fmt[index].type != type)
> +	if (index >= size)
>   		return NULL;
>   
> -	return &fmt[index];
> +	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> +		if (fmt[index].type != type)
> +			return NULL;
> +
> +		return &fmt[index];
> +	}
> +
> +	/* Loop over the valid capture formats and return the index */
> +	for (i = 0; i < size; i++) {
> +		if (fmt[i].type != type)
> +			continue;
> +
> +		if (iris_fmt_is_8bit(fmt[i].pixfmt) &&
> +		    inst->fw_caps[BIT_DEPTH].value == BIT_DEPTH_10)
> +			continue;
> +
> +		if (iris_fmt_is_10bit(fmt[i].pixfmt) &&
> +		    inst->fw_caps[BIT_DEPTH].value != BIT_DEPTH_10)
> +			continue;
> +
> +		if (k == index)
> +			return &fmt[i];
> +
> +		k++;
> +	}
> +
> +	return NULL;
>   }
>   
>   int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
>

^ permalink raw reply

* Re: [PATCH v7 02/18] media: uapi: Add extensible param and stats blocks for RPPX1
From: Jai Luthra @ 2026-04-15  6:22 UTC (permalink / raw)
  To: Jacopo Mondi, Jai Luthra
  Cc: Mauro Carvalho Chehab, Niklas Söderlund, Geert Uytterhoeven,
	Magnus Damm, Kuninori Morimoto, linux-media, linux-kernel,
	linux-renesas-soc, Laurent Pinchart, Jacopo Mondi, Marek Vasut
In-Reply-To: <adkN3HLFanUYJs20@zed>

Hi Jacopo

Thanks for the review.

Quoting Jacopo Mondi (2026-04-10 21:40:26)
> Hi Jai
> 
> On Fri, Apr 10, 2026 at 02:35:37PM +0530, Jai Luthra wrote:
> > Define the userspace API for the Dreamchip RPP-X1 ISP extensible
> > parameters and statistics. The RPP-X1 is functionally similar to the
> > RkISP1 already supported upstream, but operates at higher bit depths (up
> > to 24-bit precision in many blocks) and exposes additional configuration
> > options. This warrants a dedicated uAPI rather than reusing the RkISP1
> > definitions.
> >
> > The parameter blocks follow the V4L2 extensible parameters framework
> > using struct v4l2_isp_params_block_header, with each ISP functional
> > block represented as a tagged configuration structure. The statistics
> > buffer provides AWB, auto-exposure and histogram measurement results at
> > native RPP-X1 precision.
> >
> > Not all functional blocks present on the RPP-X1 hardware are included
> > yet, but the format is extensible and new blocks can be added without
> > breaking existing userspace.
> >
> > Signed-off-by: Jai Luthra <jai.luthra+renesas@ideasonboard.com>
> > ---
> >  include/uapi/linux/media/dreamchip/rppx1-config.h | 728 ++++++++++++++++++++++
> >  1 file changed, 728 insertions(+)
> >
> > diff --git a/include/uapi/linux/media/dreamchip/rppx1-config.h b/include/uapi/linux/media/dreamchip/rppx1-config.h
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..b9083e6f32b15329333eb13491b50c0aea8d1a32
> > --- /dev/null
> > +++ b/include/uapi/linux/media/dreamchip/rppx1-config.h
> > @@ -0,0 +1,728 @@
> > +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> > +/*
> > + * Dreamchip RPP-X1 ISP Driver - Userspace API
> > + *
> > + * Copyright (C) 2026 Renesas Electronics Corp.
> > + * Copyright (C) 2026 Ideas on Board Oy
> > + * Copyright (C) 2026 Ragnatech AB
> > + */
> > +
> > +#ifndef __UAPI_RPP_X1_CONFIG_H
> > +#define __UAPI_RPP_X1_CONFIG_H
> > +
> > +#include <linux/types.h>
> > +#include <linux/media/v4l2-isp.h>
> > +
> > +/*
> > + * Defect Pixel Cluster Correction
> > + */
> > +#define RPPX1_DPCC_METHODS_MAX                               3
> > +
> > +/* Linearization (Sensor De-gamma) */
> > +#define RPPX1_LIN_SAMPLES_NUM                                17
> > +
> > +/* Gamma Out */
> > +#define RPPX1_GAMMA_OUT_MAX_SAMPLES                  17
> > +
> > +/* Lens Shade Correction */
> > +#define RPPX1_LSC_SECTORS_TBL_SIZE                   8
> > +#define RPPX1_LSC_SAMPLES_MAX                                17
> > +
> > +/* Histogram */
> > +#define RPPX1_HIST_BIN_N_MAX                         32
> > +
> > +/* Exposure Measurement */
> > +#define RPPX1_EXM_MEAN_MAX                           25
> > +
> > +/* AWB Measurement */
> > +#define RPPX1_AWB_MAX_GRID                           1
> > +
> > +/* Color Correction Matrix */
> > +#define RPPX1_CTK_COEFF_MAX                          0x8000
> > +#define RPPX1_CTK_OFFSET_MAX                         0x800000
> > +
> > +/* Filter */
> > +#define RPPX1_BDM_MAX_TH                             0xffff
> > +
> > +/**
> > + * enum rppx1_params_block_type - RPP-X1 extensible params block types
> > + *
> > + * @RPPX1_PARAMS_BLOCK_TYPE_BLS: Black Level Subtraction
> > + * @RPPX1_PARAMS_BLOCK_TYPE_DPCC: Defect Pixel Cluster Correction
> > + * @RPPX1_PARAMS_BLOCK_TYPE_LIN: Linearization (Sensor De-gamma)
> > + * @RPPX1_PARAMS_BLOCK_TYPE_AWB_GAIN: Auto White Balance Gains
> > + * @RPPX1_PARAMS_BLOCK_TYPE_FLT: ISP Filtering
> > + * @RPPX1_PARAMS_BLOCK_TYPE_BDM: Bayer Demosaic
> > + * @RPPX1_PARAMS_BLOCK_TYPE_CTK: Color Correction (Cross-Talk)
> > + * @RPPX1_PARAMS_BLOCK_TYPE_GOC: Gamma Out Correction
> > + * @RPPX1_PARAMS_BLOCK_TYPE_DPF: De-noise Pre-Filter
> > + * @RPPX1_PARAMS_BLOCK_TYPE_DPF_STRENGTH: De-noise Pre-Filter Strength
> > + * @RPPX1_PARAMS_BLOCK_TYPE_LSC: Lens Shading Correction
> > + * @RPPX1_PARAMS_BLOCK_TYPE_AWB_MEAS: AWB Measurement Configuration
> > + * @RPPX1_PARAMS_BLOCK_TYPE_HST_MEAS: Histogram Measurement Configuration
> > + * @RPPX1_PARAMS_BLOCK_TYPE_AEC_MEAS: Auto Exposure Measurement Configuration
> > + */
> > +enum rppx1_params_block_type {
> > +     RPPX1_PARAMS_BLOCK_TYPE_BLS,
> > +     RPPX1_PARAMS_BLOCK_TYPE_DPCC,
> > +     RPPX1_PARAMS_BLOCK_TYPE_LIN,
> > +     RPPX1_PARAMS_BLOCK_TYPE_AWB_GAIN,
> > +     RPPX1_PARAMS_BLOCK_TYPE_FLT,
> > +     RPPX1_PARAMS_BLOCK_TYPE_BDM,
> > +     RPPX1_PARAMS_BLOCK_TYPE_CTK,
> > +     RPPX1_PARAMS_BLOCK_TYPE_GOC,
> > +     RPPX1_PARAMS_BLOCK_TYPE_DPF,
> > +     RPPX1_PARAMS_BLOCK_TYPE_DPF_STRENGTH,
> > +     RPPX1_PARAMS_BLOCK_TYPE_LSC,
> > +     RPPX1_PARAMS_BLOCK_TYPE_AWB_MEAS,
> > +     RPPX1_PARAMS_BLOCK_TYPE_HST_MEAS,
> > +     RPPX1_PARAMS_BLOCK_TYPE_AEC_MEAS,
> > +};
> 
> Let me start with a review of some of the blocks, we'll go through
> them one by one.
> 
> > +
> > +/**
> > + * struct rppx1_window - Measurement window
> > + *
> > + * @h_offs: horizontal offset from the left of the frame in pixels
> 
> I think it's relevant saying these are 14 bits values
> 
> > + * @v_offs: vertical offset from the top of the frame in pixels
> > + * @h_size: horizontal size of the window in pixels
> > + * @v_size: vertical size of the window in pixels
> > + */
> > +struct rppx1_window {
> > +     __u16 h_offs;
> > +     __u16 v_offs;
> > +     __u16 h_size;
> > +     __u16 v_size;
> > +};
> > +
> > +/**
> > + * struct rppx1_bls_fixed_val - BLS fixed subtraction values
> > + *
> > + * Fixed black level values subtracted from sensor data per Bayer channel.
> > + * Negative values result in addition. Each value is a 24-bit + sign
> > + * (25-bit signed) fixed-point number stored in a __s32.
> 
> I think these should be described as
> 
> "Each value is is stored as a signed 2's complement representation
> ranging from -2^24 to 2^24-1."
> 
> As the fixed point representation in 2's complement allows to
> represent a negative number with an integer I think the type of the
> fields should be __u32.

Ack, will fix.

> 
> > + *
> > + * RPP-X1 supports 12/20/24-bit + sign depending on hardware version.
> 
> The ISP reports this through the "bls_version" register field.
> 
> I would introduce an enumeration for this and reference it here.
> More on this below.
> 
> > + * Userspace should provide values at full 24-bit precision; the driver
> > + * truncates to match the hardware.
> 
> If you're looking at "bls_version" I didn't find where it is said that
> it impacts the fixed values, I only read it impacts the measured
> values. Have I missed that ?
> 

Yes, the BLS_VERSION register doesn't talk about the fixed values, only the
measured values.

But the PRE1_BLS_A_FIXED is 24 bits while PRE2_BLS_A_FIXED is 12 bits,
which matches the measured values described in the BLS_VERSION register.

> > + *
> > + * @r: subtraction value for Bayer pattern R
> > + * @gr: subtraction value for Bayer pattern Gr
> > + * @gb: subtraction value for Bayer pattern Gb
> > + * @b: subtraction value for Bayer pattern B
> 
> The manual describes the values as "A", "B", "C" and "D".
> 
> These values are matched with the Bayer components according to the
> cropping configuration on the input port. The pipeline should
> carefully crop to the macro-pixel boundary so that A B C and D
> correspond to the sensor's native Bayer ordering.
> 

That's a good point, will add a note in the comments. Are you also implying
that we should use A/B/C/D for the names of these parameters here?

> Also, I wouldn't say "subtraction" but simply "Fixed black level for
> channel ..."

Ack.

> 
> > + */
> > +struct rppx1_bls_fixed_val {
> > +     __s32 r;
> > +     __s32 gr;
> > +     __s32 gb;
> > +     __s32 b;
> > +};
> > +
> > +/**
> > + * struct rppx1_params_bls_config - Black Level Subtraction configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_BLS)
> > + * @enable_auto: 1 = use measured values, 0 = use fixed_val
> 
> I would call this "bls_mode" and create and enum for it
> 
> enum rppx1_bls_mode {
>         RPPX1_BLS_MODE_FIXED,
>         RPPX1_BLS_MODE_MEAS,
> };
> 
> > + * @en_windows: enabled measurement windows bitmask
> 
> For this one as well
> 
> enum rppx1_bls_win_en {
>         RPPX1_BLS_WIN_EN_OFF,
>         RPPX1_BLS_WIN_EN_WIN1,
>         RPPX1_BLS_WIN_EN_WIN2,
>         RPPX1_BLS_WIN_EN_WIN12,
> };
> 

Ack.

> > + * @bls_window1: measurement window 1
> > + * @bls_window2: measurement window 2
> > + * @bls_samples: log2 of the number of measured pixels per Bayer position
> > + * @fixed_val: fixed subtraction values (24-bit + sign)
> 
> Let's defer the field length description to the documentation of
> rppx1_bls_fixed_val.
> 
> Also, I would document these as "fixed black level values"
> 
> > + */
> > +struct rppx1_params_bls_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u8 enable_auto;
> > +     __u8 en_windows;
> 
> I was about to complaint that you're missing the enable bit but we can
> use the block header maybe ?
> 

Indeed, that's what is done in all the module implementations. IMO that's
cleaner than having two different enable toggles.

> > +     struct rppx1_window bls_window1;
> > +     struct rppx1_window bls_window2;
> > +     __u8 bls_samples;
> > +     struct rppx1_bls_fixed_val fixed_val;
> > +};
> > +
> > +/**
> > + * struct rppx1_dpcc_methods_config - DPCC methods set configuration
> > + *
> > + * This structure stores the configuration of one set of methods for the DPCC
> > + * algorithm. Multiple methods can be selected in each set (independently for
> > + * the Green and Red/Blue components) through the @method field, the result is
> > + * the logical AND of all enabled methods. The remaining fields set thresholds
> > + * and factors for each method.
> > + *
> > + * @method: method enable bits (RPPX1_DPCC_METHODS_SET_*)
> > + * @line_thresh: line threshold (RPPX1_DPCC_LINE_THRESH_*)
> > + * @line_mad_fac: line MAD factor (RPPX1_DPCC_LINE_MAD_FAC_*)
> > + * @pg_fac: peak gradient factor (RPPX1_DPCC_PG_FAC_*)
> > + * @rnd_thresh: rank neighbor difference threshold (RPPX1_DPCC_RND_THRESH_*)
> > + * @rg_fac: rank gradient factor (RPPX1_DPCC_RG_FAC_*)
> > + */
> > +struct rppx1_dpcc_methods_config {
> > +     __u32 method;
> 
> Shoulf we define each bit ?
> 
> #define RPPX1_DPCC_METHODS_RG_RB_EN             (1 << 12)
> #define RPPX1_DPCC_METHODS_RND_RB_EN            (1 << 11)
> #define RPPX1_DPCC_METHODS_RO_RB_EN             (1 << 10)
> #define RPPX1_DPCC_METHODS_LC_RB_EN             (1 << 9)
> #define RPPX1_DPCC_METHODS_PG_RB_EN             (1 << 8)
> #define RPPX1_DPCC_METHODS_RG_G_EN              (1 << 4)
> #define RPPX1_DPCC_METHODS_RND_G_EN             (1 << 3)
> #define RPPX1_DPCC_METHODS_RO_G_EN              (1 << 2)
> #define RPPX1_DPCC_METHODS_LC_G_EN              (1 << 1)
> #define RPPX1_DPCC_METHODS_PG_G_EN              (1 << 0)
> 

DPCC implementation is currently stubbed out. Maybe we can just drop it for
this first iteration of the uAPI?

In case we want to implement it before v8, I agree on defining these bits
in the header.

> > +     __u32 line_thresh;
> > +     __u32 line_mad_fac;
> 
> For these and other fields you can define bitshits like the RkISP1
> uAPI header does
> 
> > +     __u32 pg_fac;
> > +     __u32 rnd_thresh;
> > +     __u32 rg_fac;
> > +};
> > +
> > +/**
> > + * struct rppx1_params_dpcc_config - Defect Pixel Cluster Correction configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_DPCC)
> > + * @mode: DPCC mode (RPPX1_DPCC_MODE_*)
> > + * @output_mode: interpolation output mode (RPPX1_DPCC_OUTPUT_MODE_*)
> > + * @set_use: methods sets selection (RPPX1_DPCC_SET_USE_*)
> > + * @methods: methods sets configuration
> > + * @ro_limits: rank order limits (RPPX1_DPCC_RO_LIMITS_*)
> > + * @rnd_offs: differential rank offsets (RPPX1_DPCC_RND_OFFS_*)
> > + */
> > +struct rppx1_params_dpcc_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     __u32 mode;
> 
> Here as well it might be useful to define
> 
> #define RPPX1_DPCC_MODE_STAGE1_EN               (1 << 2)
> #define RPPX1_DPCC_MODE_GRAYSCALE               (1 << 1)
> #define RPPX1_DPPC_MODE_ENABLE                  (1 << 0)
> 
> > +     __u32 output_mode;
> > +     __u32 set_use;
> 
> The same applies to these two registers

Ack. I missed them because they were unused.
Will go through other modules too before v8.

> 
> > +     struct rppx1_dpcc_methods_config methods[RPPX1_DPCC_METHODS_MAX];
> > +     __u32 ro_limits;
> > +     __u32 rnd_offs;
> > +};
> 
> DPPC reports a version number that allows to identify the bit width.
> Should it be communicated to userspace through statistics ?
> 

Ah, so throughout this series I have picked the largest bit width for the
uAPI. The module driver implementation handles shifting the data before
reading from (stats) and writing to (config) registers. Abstracting away
that detail from userspace.

I thought that would make life easy for libcamera tuning, where it is done
only once for the highest bitdepth.

Am I missing some case where this information is important for tuning?

> > +
> > +/**
> > + * struct rppx1_lin_curve - Linearization curve for one color channel
> > + *
> > + * The RPP-X1 linearization module supports 12/20/24-bit precision depending
> > + * on hardware version. Values are provided at 24-bit precision; the driver
> 
> The hardware version should be reported through stats with proper
> defines
> 
> Did you get what the difference is between:
> 0x006: 24 bit version
> 0x009: 24 bit, 4 bit dxi
> 
> It seems to me dxi samples are 4 bits, aren't they ?
> 

I believe in the other version dxi samples will be 3 bits, like they're in
RkISP.

> > + *
> > + * @gamma_y: curve y-axis values, each up to 24 bits
> > + */
> > +struct rppx1_lin_curve {
> > +     __u32 gamma_y[RPPX1_LIN_SAMPLES_NUM];
> > +};
> > +
> > +/**
> > + * struct rppx1_lin_curve_dx - Linearization curve x-axis (sampling points)
> > + * increments.
> > + *
> > + * gamma_dx[0] is for the lower samples, so Bits 0:3 for sample 1, ... Bits
> > + * 28:31 for sample 8
> > + * gamma_dx[1] is for the higher samples, so Bits 0:3 for sample 9, ... Bits
> > + * 28:31 for sample 16
> > + *
> > + * The reset values for both fields is 0xcccccccc. This means that each sample
> > + * is 12 units away from the previous one on the x-axis.
> > + *
> > + * @gamma_dx: curve x-axis increments in 4-bit precision
> > + */
> > +struct rppx1_lin_curve_dx {
> > +     __u32 gamma_dx[2];
> > +};
> > +
> > +/**
> > + * struct rppx1_params_lin_config - Linearization (Sensor De-gamma) configuration
> > + *
> > + * @header: block header (type = RPPX1_PARAMS_BLOCK_TYPE_LIN)
> > + * @curve_r: linearization curve for red channel
> > + * @curve_g: linearization curve for green channel
> > + * @curve_b: linearization curve for blue channel
> > + * @xa_pnts: x axis increment definitions
> > + */
> > +struct rppx1_params_lin_config {
> > +     struct v4l2_isp_params_block_header header;
> > +     struct rppx1_lin_curve curve_r;
> > +     struct rppx1_lin_curve curve_g;
> > +     struct rppx1_lin_curve curve_b;
> > +     struct rppx1_lin_curve_dx xa_pnts;
> > +};
> 
> Ack, I'll stop here for the time being :)
> 

Thanks,
    Jai

[snip]

^ permalink raw reply

* [PATCH] dma-buf: fix stale @lock references in struct dma_buf documentation
From: Xiang Gao @ 2026-04-15  5:41 UTC (permalink / raw)
  To: sumit.semwal, christian.koenig
  Cc: linux-media, dri-devel, linaro-mm-sig, linux-kernel, Xiang Gao

From: Xiang Gao <gaoxiang17@xiaomi.com>

The kernel-doc comments for vmapping_counter and vmap_ptr in struct
dma_buf reference "@lock" as the protecting lock, but struct dma_buf
no longer has a "lock" member. The mutex was removed in favor of using
the dma_resv lock exclusively. The implementation correctly uses
dma_resv_assert_held(dmabuf->resv) in dma_buf_vmap() and
dma_buf_vunmap(), so update the documentation to reference @resv
instead.

Signed-off-by: gaoxiang17 <gaoxiang17@xiaomi.com>
---
 include/linux/dma-buf.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index 133b9e637b55..ef6d93fd7a2c 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -322,13 +322,13 @@ struct dma_buf {
 	 * @vmapping_counter:
 	 *
 	 * Used internally to refcnt the vmaps returned by dma_buf_vmap().
-	 * Protected by @lock.
+	 * Protected by @resv.
 	 */
 	unsigned vmapping_counter;
 
 	/**
 	 * @vmap_ptr:
-	 * The current vmap ptr if @vmapping_counter > 0. Protected by @lock.
+	 * The current vmap ptr if @vmapping_counter > 0. Protected by @resv.
 	 */
 	struct iosys_map vmap_ptr;
 
-- 
2.34.1


^ permalink raw reply related

* [PATCH 5/5] media: synopsys: Add support for i.MX95
From: Guoniu Zhou @ 2026-04-15  3:46 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou
In-Reply-To: <20260415-csi2_imx95-v1-0-7d63f3508719@oss.nxp.com>

Add support for the i.MX95 MIPI CSI-2 receiver. The i.MX95 variant is
nearly identical to i.MX93, with the main difference being the use of
IDI (Image Data Interface) instead of IPI (Image Pixel Interface).
However, the IDI interface is transparent to software, requiring only
a different register map definition while sharing the same PHY control
functions with i.MX93.

Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 27e4c1027816..bbb41baf789e 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -154,6 +154,17 @@ static const u32 imx93_regs[DW_MIPI_CSI2RX_MAX] = {
 	[DW_MIPI_CSI2RX_IPI_SOFTRSTN] = DW_REG(0xa0),
 };
 
+static const u32 imx95_regs[DW_MIPI_CSI2RX_MAX] = {
+	[DW_MIPI_CSI2RX_N_LANES] = DW_REG(0x4),
+	[DW_MIPI_CSI2RX_RESETN] = DW_REG(0x8),
+	[DW_MIPI_CSI2RX_PHY_SHUTDOWNZ] = DW_REG(0x40),
+	[DW_MIPI_CSI2RX_DPHY_RSTZ] = DW_REG(0x44),
+	[DW_MIPI_CSI2RX_PHY_STATE] = DW_REG(0x48),
+	[DW_MIPI_CSI2RX_PHY_STOPSTATE] = DW_REG(0x4c),
+	[DW_MIPI_CSI2RX_PHY_TST_CTRL0] = DW_REG(0x50),
+	[DW_MIPI_CSI2RX_PHY_TST_CTRL1] = DW_REG(0x54),
+};
+
 static const struct v4l2_mbus_framefmt default_format = {
 	.width = 3840,
 	.height = 2160,
@@ -901,11 +912,22 @@ static const struct dw_mipi_csi2rx_drvdata imx93_drvdata = {
 	.wait_for_phy_stopstate = imx93_csi2rx_wait_for_phy_stopstate,
 };
 
+static const struct dw_mipi_csi2rx_drvdata imx95_drvdata = {
+	.regs = imx95_regs,
+	.dphy_assert_reset = imx93_csi2rx_dphy_assert_reset,
+	.dphy_deassert_reset = imx93_csi2rx_dphy_deassert_reset,
+	.wait_for_phy_stopstate = imx93_csi2rx_wait_for_phy_stopstate,
+};
+
 static const struct of_device_id dw_mipi_csi2rx_of_match[] = {
 	{
 		.compatible = "fsl,imx93-mipi-csi2",
 		.data = &imx93_drvdata,
 	},
+	{
+		.compatible = "fsl,imx95-mipi-csi2",
+		.data = &imx95_drvdata,
+	},
 	{
 		.compatible = "rockchip,rk3568-mipi-csi2",
 		.data = &rk3568_drvdata,

-- 
2.34.1


^ permalink raw reply related

* [PATCH 4/5] media: dt-bindings: add NXP i.MX95 compatible string
From: Guoniu Zhou @ 2026-04-15  3:46 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou
In-Reply-To: <20260415-csi2_imx95-v1-0-7d63f3508719@oss.nxp.com>

The i.MX95 CSI-2 controller is nearly identical to i.MX93, with the
only difference being the use of IDI (Image Data Interface) instead
of IPI (Image Pixel Interface). The binding constraints are otherwise
the same.

Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
 .../devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml         | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
index 4ac4a3b6f406..78371e039e55 100644
--- a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
@@ -18,6 +18,7 @@ properties:
   compatible:
     enum:
       - fsl,imx93-mipi-csi2
+      - fsl,imx95-mipi-csi2
       - rockchip,rk3568-mipi-csi2
 
   reg:
@@ -124,7 +125,9 @@ allOf:
       properties:
         compatible:
           contains:
-            const: fsl,imx93-mipi-csi2
+            enum:
+              - fsl,imx93-mipi-csi2
+              - fsl,imx95-mipi-csi2
     then:
       properties:
         interrupts:

-- 
2.34.1


^ permalink raw reply related

* [PATCH 3/5] media: synopsys: Add PHY stopstate wait for i.MX93
From: Guoniu Zhou @ 2026-04-15  3:46 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou
In-Reply-To: <20260415-csi2_imx95-v1-0-7d63f3508719@oss.nxp.com>

Implement waiting for D-PHY lanes to enter stop state on i.MX93. This
ensures proper PHY initialization by verifying that the clock lane and
all active data lanes have entered the stop state before proceeding with
further operations.

Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 38 ++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 85a2a95bf080..27e4c1027816 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -11,6 +11,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/phy/phy.h>
@@ -35,6 +36,8 @@
 #define DW_REG_EXIST		BIT(31)
 #define DW_REG(x)		(DW_REG_EXIST | (x))
 
+#define DPHY_STOPSTATE_CLK_LANE		BIT(16)
+
 #define DPHY_TEST_CTRL0_TEST_CLR	BIT(0)
 
 #define IPI_VCID_VC(x)			FIELD_PREP(GENMASK(1, 0), (x))
@@ -65,6 +68,7 @@ enum dw_mipi_csi2rx_regs_index {
 	DW_MIPI_CSI2RX_PHY_TST_CTRL0,
 	DW_MIPI_CSI2RX_PHY_TST_CTRL1,
 	DW_MIPI_CSI2RX_PHY_SHUTDOWNZ,
+	DW_MIPI_CSI2RX_PHY_STOPSTATE,
 	DW_MIPI_CSI2RX_IPI_DATATYPE,
 	DW_MIPI_CSI2RX_IPI_MEM_FLUSH,
 	DW_MIPI_CSI2RX_IPI_MODE,
@@ -87,6 +91,7 @@ struct dw_mipi_csi2rx_drvdata {
 	void (*dphy_assert_reset)(struct dw_mipi_csi2rx_device *csi2);
 	void (*dphy_deassert_reset)(struct dw_mipi_csi2rx_device *csi2);
 	void (*ipi_enable)(struct dw_mipi_csi2rx_device *csi2);
+	int (*wait_for_phy_stopstate)(struct dw_mipi_csi2rx_device *csi2);
 };
 
 struct dw_mipi_csi2rx_format {
@@ -139,6 +144,7 @@ static const u32 imx93_regs[DW_MIPI_CSI2RX_MAX] = {
 	[DW_MIPI_CSI2RX_PHY_SHUTDOWNZ] = DW_REG(0x40),
 	[DW_MIPI_CSI2RX_DPHY_RSTZ] = DW_REG(0x44),
 	[DW_MIPI_CSI2RX_PHY_STATE] = DW_REG(0x48),
+	[DW_MIPI_CSI2RX_PHY_STOPSTATE] = DW_REG(0x4c),
 	[DW_MIPI_CSI2RX_PHY_TST_CTRL0] = DW_REG(0x50),
 	[DW_MIPI_CSI2RX_PHY_TST_CTRL1] = DW_REG(0x54),
 	[DW_MIPI_CSI2RX_IPI_MODE] = DW_REG(0x80),
@@ -410,6 +416,12 @@ static int dw_mipi_csi2rx_start(struct dw_mipi_csi2rx_device *csi2)
 
 	dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_RESETN, 1);
 
+	if (csi2->drvdata->wait_for_phy_stopstate) {
+		ret = csi2->drvdata->wait_for_phy_stopstate(csi2);
+		if (ret)
+			return ret;
+	}
+
 	if (csi2->drvdata->ipi_enable)
 		csi2->drvdata->ipi_enable(csi2);
 
@@ -856,11 +868,37 @@ static void imx93_csi2rx_dphy_ipi_enable(struct dw_mipi_csi2rx_device *csi2)
 	dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_IPI_MODE, val);
 }
 
+static int imx93_csi2rx_wait_for_phy_stopstate(struct dw_mipi_csi2rx_device *csi2)
+{
+	struct device *dev = csi2->dev;
+	void __iomem *addr;
+	u32 stopstate_mask;
+	u32 val;
+	int ret;
+
+	if (!dw_mipi_csi2rx_has_reg(csi2, DW_MIPI_CSI2RX_PHY_STOPSTATE)) {
+		dev_err(dev, "phy_stopstate register not available\n");
+		return -ENXIO;
+	}
+
+	stopstate_mask = DPHY_STOPSTATE_CLK_LANE | GENMASK(csi2->lanes_num - 1, 0);
+	addr = dw_mipi_csi2rx_get_regaddr(csi2, DW_MIPI_CSI2RX_PHY_STOPSTATE);
+
+	ret = readl_poll_timeout(addr, val, (val & stopstate_mask) != stopstate_mask,
+				 1000, 2000000);
+	if (ret)
+		dev_err(dev, "lanes are not in stop state: %#x, expected %#x\n",
+			val, stopstate_mask);
+
+	return ret;
+}
+
 static const struct dw_mipi_csi2rx_drvdata imx93_drvdata = {
 	.regs = imx93_regs,
 	.dphy_assert_reset = imx93_csi2rx_dphy_assert_reset,
 	.dphy_deassert_reset = imx93_csi2rx_dphy_deassert_reset,
 	.ipi_enable = imx93_csi2rx_dphy_ipi_enable,
+	.wait_for_phy_stopstate = imx93_csi2rx_wait_for_phy_stopstate,
 };
 
 static const struct of_device_id dw_mipi_csi2rx_of_match[] = {

-- 
2.34.1


^ permalink raw reply related

* [PATCH 2/5] media: synopsys: Add support for multiple streams
From: Guoniu Zhou @ 2026-04-15  3:46 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou
In-Reply-To: <20260415-csi2_imx95-v1-0-7d63f3508719@oss.nxp.com>

The current driver only supports single stream operation. Add support
for multiple concurrent streams by tracking enabled streams with a
bitmask and only initializing the hardware once for the first stream.

This enables use cases such as surround view systems where multiple
camera streams need to be processed simultaneously through the same
CSI-2 receiver interface.

Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 45 ++++++++++++++----------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index 46e2a4315ac2..85a2a95bf080 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -113,6 +113,7 @@ struct dw_mipi_csi2rx_device {
 
 	enum v4l2_mbus_type bus_type;
 	u32 lanes_num;
+	u64 enabled_streams;
 
 	const struct dw_mipi_csi2rx_drvdata *drvdata;
 };
@@ -528,28 +529,31 @@ static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd,
 					       DW_MIPI_CSI2RX_PAD_SRC,
 					       &streams_mask);
 
-	ret = pm_runtime_resume_and_get(dev);
-	if (ret)
-		goto err;
+	if (!csi2->enabled_streams) {
+		ret = pm_runtime_resume_and_get(dev);
+		if (ret)
+			return ret;
 
-	ret = dw_mipi_csi2rx_start(csi2);
-	if (ret) {
-		dev_err(dev, "failed to enable CSI hardware\n");
-		goto err_pm_runtime_put;
+		ret = dw_mipi_csi2rx_start(csi2);
+		if (ret) {
+			pm_runtime_put(dev);
+			dev_err(dev, "failed to enable CSI hardware\n");
+			return ret;
+		}
 	}
 
 	ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask);
-	if (ret)
-		goto err_csi_stop;
+	if (ret) {
+		if (!csi2->enabled_streams) {
+			dw_mipi_csi2rx_stop(csi2);
+			pm_runtime_put(dev);
+		}
+		return ret;
+	}
 
-	return 0;
+	csi2->enabled_streams |= streams_mask;
 
-err_csi_stop:
-	dw_mipi_csi2rx_stop(csi2);
-err_pm_runtime_put:
-	pm_runtime_put(dev);
-err:
-	return ret;
+	return 0;
 }
 
 static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
@@ -572,10 +576,15 @@ static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd,
 					       &streams_mask);
 
 	ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask);
+	if (ret)
+		dev_err(dev, "failed to disable streams on remote subdev: %d\n", ret);
 
-	dw_mipi_csi2rx_stop(csi2);
+	csi2->enabled_streams &= ~streams_mask;
 
-	pm_runtime_put(dev);
+	if (!csi2->enabled_streams) {
+		dw_mipi_csi2rx_stop(csi2);
+		pm_runtime_put(dev);
+	}
 
 	return ret;
 }

-- 
2.34.1


^ permalink raw reply related

* [PATCH 1/5] media: synopsys: Add support for RAW16 Bayer formats
From: Guoniu Zhou @ 2026-04-15  3:46 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou
In-Reply-To: <20260415-csi2_imx95-v1-0-7d63f3508719@oss.nxp.com>

This enables the driver to handle higher bit-depth raw image data
from image sensors that support 16-bit output.

Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
index ce17f986279e..46e2a4315ac2 100644
--- a/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
+++ b/drivers/media/platform/synopsys/dw-mipi-csi2rx.c
@@ -252,6 +252,26 @@ static const struct dw_mipi_csi2rx_format formats[] = {
 		.depth = 12,
 		.csi_dt = MIPI_CSI2_DT_RAW12,
 	},
+	{
+		.code = MEDIA_BUS_FMT_SBGGR16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGBRG16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SGRBG16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
+	{
+		.code = MEDIA_BUS_FMT_SRGGB16_1X16,
+		.depth = 16,
+		.csi_dt = MIPI_CSI2_DT_RAW16,
+	},
 };
 
 static inline struct dw_mipi_csi2rx_device *to_csi2(struct v4l2_subdev *sd)

-- 
2.34.1


^ permalink raw reply related

* [PATCH 0/5] media: synopsys: enhancements and i.MX95 support
From: Guoniu Zhou @ 2026-04-15  3:46 UTC (permalink / raw)
  To: Michael Riesch, Mauro Carvalho Chehab, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Laurent Pinchart, Frank Li
  Cc: linux-media, linux-kernel, devicetree, imx, linux-arm-kernel,
	linux-rockchip, Guoniu Zhou

This series enhances the Synopsys DesignWare MIPI CSI-2 receiver driver
with multiple stream support and adds i.MX95 platform support.

The i.MX95 variant is similar to i.MX93 but uses IDI instead of IPI. Since
IDI is software transparent, only a different register map is needed.

Tested on i.MX93 and i.MX95 platforms.

Signed-off-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
---
Guoniu Zhou (5):
      media: synopsys: Add support for RAW16 Bayer formats
      media: synopsys: Add support for multiple streams
      media: synopsys: Add PHY stopstate wait for i.MX93
      media: dt-bindings: add NXP i.MX95 compatible string
      media: synopsys: Add support for i.MX95

 .../bindings/media/rockchip,rk3568-mipi-csi2.yaml  |   5 +-
 drivers/media/platform/synopsys/dw-mipi-csi2rx.c   | 125 ++++++++++++++++++---
 2 files changed, 111 insertions(+), 19 deletions(-)
---
base-commit: 4fbeef21f5387234111b5d52924e77757626faa5
change-id: 20260414-csi2_imx95-65ad0e7f630a

Best regards,
-- 
Guoniu Zhou <guoniu.zhou@oss.nxp.com>


^ permalink raw reply

* Re: [PATCH 15901/15901] drm/vmwgfx: fix NULL pointer dereference in vmw_validation_bo_fence()
From: Zack Rusin @ 2026-04-15  1:08 UTC (permalink / raw)
  To: Christian König
  Cc: popov.nkv, bcm-kernel-feedback-list, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Sumit Semwal, dri-devel, linux-kernel, linux-media, linaro-mm-sig,
	lvc-project, stable, Ian Forbes
In-Reply-To: <ecf4cd01-b05d-4f51-943a-631cc4b27331@amd.com>

[-- Attachment #1: Type: text/plain, Size: 1843 bytes --]

On Tue, Apr 14, 2026 at 9:25 AM Christian König
<christian.koenig@amd.com> wrote:
>
> On 4/14/26 12:55, popov.nkv@gmail.com wrote:
> > From: Vladimir Popov <popov.nkv@gmail.com>
> >
> > If vmw_execbuf_fence_commands() call fails in
> > vmw_kms_helper_validation_finish(), it sets *p_fence = NULL. If
> > ctx->bo_list is not empty, the caller, vmw_kms_helper_validation_finish(),
> > passes the fence through a chain of functions to dma_fence_is_array(),
> > which causes a NULL pointer dereference in dma_fence_is_array():
> >
> > vmw_kms_helper_validation_finish() // pass NULL fence
> >   vmw_validation_done()
> >     vmw_validation_bo_fence()
> >       ttm_eu_fence_buffer_objects() // pass NULL fence
> >         dma_resv_add_fence()
> >           dma_fence_is_container()
> >             dma_fence_is_array() // NULL deref
>
> Well good catch, but that is clearly not the right fix.
>
> I'm not an expert for the vmwgfx code but in case of an error vmw_validation_revert() should be called an not vmw_kms_helper_validation_finish().

To me the patch looks correct. This path is explicitly for submission
failure and does BO backoff plus vmw_validation_res_unreserve(ctx,
true). The backoff=true branch skips committing dirty-state /
backup-MOB changes, which is only correct if commands were not
committed. Here the commands have already been submitted; only fence
creation failed. So I think unlocking BO reservations without
attaching a fence, then letting vmw_validation_done() keep taking the
success path for resources is correct.

iirc the same helper is used by execbuf, and the shared-helper fix
correctly covers both paths so this is probably not only a kms issue.

Untangling this code would make sense because it's confusing, but
that's not something I'd expect Vladimir to do :)

z

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5414 bytes --]

^ permalink raw reply

* Re: [PATCH RFC 4/7] media: qcom: iris: vdec: update size and stride calculations for 10bit formats
From: Nicolas Dufresne @ 2026-04-14 23:39 UTC (permalink / raw)
  To: Neil Armstrong, Vishnu Reddy, Vikash Garodia, Dikshita Agarwal,
	Abhinav Kumar, Bryan O'Donoghue, Mauro Carvalho Chehab
  Cc: linux-media, linux-arm-msm, linux-kernel
In-Reply-To: <0301bf82-0859-44cd-99df-3de997e2cff4@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 5631 bytes --]

Le vendredi 10 avril 2026 à 13:59 +0200, Neil Armstrong a écrit :
> On 4/10/26 12:10, Vishnu Reddy wrote:
> > 
> > On 4/8/2026 10:13 PM, Neil Armstrong wrote:
> > > Update the gen2 response and vdec s_fmt code to take in account
> > > the P010 and QC010 when calculating the width, height and stride.
> > > 
> > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> > > ---
> > >   .../platform/qcom/iris/iris_hfi_gen2_response.c     | 19
> > > ++++++++++++++++---
> > >   drivers/media/platform/qcom/iris/iris_vdec.c        | 21
> > > ++++++++++++++++++---
> > >   2 files changed, 34 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> > > b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> > > index 8e19f61bbbf9..d268149191ea 100644
> > > --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> > > +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c
> > > @@ -542,9 +542,22 @@ static void
> > > iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst)
> > >       pixmp_ip->width = width;
> > >       pixmp_ip->height = height;
> > > -    pixmp_op->width = ALIGN(width, 128);
> > > -    pixmp_op->height = ALIGN(height, 32);
> > > -    pixmp_op->plane_fmt[0].bytesperline = ALIGN(width, 128);
> > > +    pixmp_op->width = pixmp_op->pixelformat == V4L2_PIX_FMT_QC10C ?
> > > +        ALIGN(width, 192) : ALIGN(width, 128);
> > > +    pixmp_op->height = pixmp_op->pixelformat == V4L2_PIX_FMT_QC10C ?
> > > +        ALIGN(height, 16) : ALIGN(height, 32);
> > > +    switch (pixmp_op->pixelformat) {
> > > +    case V4L2_PIX_FMT_P010:
> > > +        pixmp_op->plane_fmt[0].bytesperline = ALIGN(width * 2, 256);
> > > +        break;
> > > +    case V4L2_PIX_FMT_QC10C:
> > > +        pixmp_op->plane_fmt[0].bytesperline = ALIGN(ALIGN(width, 192) * 4
> > > / 3, 256);
> > > +        break;
> > > +    case V4L2_PIX_FMT_NV12:
> > > +    case V4L2_PIX_FMT_QC08C:
> > > +        pixmp_op->plane_fmt[0].bytesperline = ALIGN(width, 128);
> > > +        break;
> > > +    }
> > >       pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst,
> > > BUF_OUTPUT);
> > >       matrix_coeff = subsc_params.color_info & 0xFF;
> > > diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c
> > > b/drivers/media/platform/qcom/iris/iris_vdec.c
> > > index 719217399a30..ca0518c27834 100644
> > > --- a/drivers/media/platform/qcom/iris/iris_vdec.c
> > > +++ b/drivers/media/platform/qcom/iris/iris_vdec.c
> > > @@ -272,10 +272,25 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct
> > > v4l2_format *f)
> > >           fmt = inst->fmt_dst;
> > >           fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
> > >           fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
> > > -        fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128);
> > > -        fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32);
> > > +        codec_align = f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C ?
> > > 192 : 128;
> > > +        fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
> > > +        codec_align = f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C ?
> > > 16 : 32;
> > > +        fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height,
> > > codec_align);
> > >           fmt->fmt.pix_mp.num_planes = 1;
> > > -        fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f-
> > > >fmt.pix_mp.width, 128);
> > > +        switch (f->fmt.pix_mp.pixelformat) {
> > > +        case V4L2_PIX_FMT_P010:
> > > +            fmt->fmt.pix_mp.plane_fmt[0].bytesperline =
> > > +                ALIGN(f->fmt.pix_mp.width * 2, 256);
> > > +            break;
> > > +        case V4L2_PIX_FMT_QC10C:
> > > +            fmt->fmt.pix_mp.plane_fmt[0].bytesperline =
> > > +                ALIGN(f->fmt.pix_mp.width * 4 / 3, 256);
> > > +            break;
> > > +        case V4L2_PIX_FMT_NV12:
> > > +        case V4L2_PIX_FMT_QC08C:
> > > +            fmt->fmt.pix_mp.plane_fmt[0].bytesperline = f-
> > > >fmt.pix_mp.width;
> > In the removed code, bytesperline for NV12 and QC08C was aligned to 128
> > bytes.
> > In the new code, Is that alignment missed or not required?
> 
> The alignment is done right before:
> 	codec_align = f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C ? 192 :
> 128;
> 	fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
> 
> calling ALIGN(f->fmt.pix_mp.width, 128) again is a no-op.

What typically other drivers do is implement a static table that associate a
v4l2_frmsize_stepwise to each format, and possibly per HW generation. And then
uses v4l2_apply_frmsize_constraints() to apply them generically in their
try/s_fmt functions. This make lot cleaner and clearer code then the sate of
this driver.

Nicolas

> 
> Thanks,
> Neil
> 
> > > +            break;
> > > +        }
> > >           fmt->fmt.pix_mp.plane_fmt[0].sizeimage =
> > > iris_get_buffer_size(inst, BUF_OUTPUT);
> > >           inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst,
> > > BUF_OUTPUT);
> > >           inst->buffers[BUF_OUTPUT].size = fmt-
> > > >fmt.pix_mp.plane_fmt[0].sizeimage;
> > > 
> 

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v5 0/5] media: qcom: camss: Add PIX support for CSID/VFE-340
From: Loic Poulain @ 2026-04-14 19:31 UTC (permalink / raw)
  To: bryan.odonoghue, vladimir.zapolskiy
  Cc: linux-media, linux-arm-msm, mchehab, konrad.dybcio,
	dmitry.baryshkov
In-Reply-To: <20260414185202.2714019-1-loic.poulain@oss.qualcomm.com>

Hi Bryan,

On Tue, Apr 14, 2026 at 8:52 PM Loic Poulain
<loic.poulain@oss.qualcomm.com> wrote:
>
> Add PIX-path support to the CAMSS pipeline on CSID-340 and VFE-340,
> allowing frames to be routed to the VFE PIX interface and exposed
> through PIX output devices such as msm_vfe0_pix.
>
> On CM2290/TFE, the PIX interface includes a minimal inline processing
> engine, which we will be able to leverage later to export statistics
> needed for proper 3A frame processing. This also fixes the PIX path
> not being usable on this platform, as PIX routing was previously
> unsupported, causing frame capture hangs.

I forgot to mention this series now depends on your CSID/port series:
https://lore.kernel.org/all/20260407-camss-rdi-fix-v3-0-08f72d1f3442@kernel.org/



>
> Changes in V5:
> - Rebase/Move from en_vc to en_port
> - Use common __csid_configure_stream for RDI and PIX
> - Use bitwise | for packing vfe width and height config
> - Simplify vfe_packer_format, no error expected
>
> Changes in V4:
> - Remove unnecessary boundary check for wm-to-client
> - Remove stray \n and fix commit subject for 2/5
> - Add proper define for PIX pad index in csid-340
>
> Changes in V3:
> - Introduce what PIX is/means in 2/5 as discussed with Dmitry.
> - Fix patches format/encoding (proper ASCII)
>
> Changes in V2:
> - Fix various typos, extra spaces, and reword commit messages.
> - Split the CSID-340 patch into three independent changes.
> - Make VC/DT-ID configuration explicit in the CSID/PIX setup.
> - Add the csid_vc_iface_map helper to retrieve the interface offset
>   from a Virtual Channel (VC).
> - Add cropping configuration in the VFE/PIX path so that it
>   respects the crop parameters defined in camss-vfe.
>
> Loic Poulain (5):
>   media: qcom: camss: csid-340: Switch to generic CSID_CFG/CTRL
>     registers
>   media: qcom: camss: csid-340: Add port-to-interface mapping
>   media: qcom: camss: csid-340: Enable PIX interface routing
>   media: qcom: camss: vfe-340: Proper client handling
>   media: qcom: camss: vfe-340: Support for PIX client
>
>  .../platform/qcom/camss/camss-csid-340.c      |  83 ++++++----
>  .../media/platform/qcom/camss/camss-vfe-340.c | 152 +++++++++++++-----
>  2 files changed, 156 insertions(+), 79 deletions(-)
>
> --
> 2.34.1
>

^ permalink raw reply

* Re: [ANNv4] Media Summit on May 26th in Nice, France
From: Loic Poulain @ 2026-04-14 19:25 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Michael Riesch, Ricardo Ribalda, Hans Verkuil, Nicolas Dufresne,
	Linux Media Mailing List, Mauro Carvalho Chehab, Sean Young,
	Sakari Ailus, Jacopo Mondi, Niklas Söderlund, Tomi Valkeinen,
	Alain Volmat, Bryan O'Donoghue, Dave Stevenson,
	Daniel Almeida, Michael Tretter, Tomasz Figa, Steve Cho,
	Kieran Bingham, Kevin Hilman, Paul Kocialkowski, Benjamin Mugnier,
	Hans de Goede, Maxime Ripard, Brandon Brnich, Marco Felsch,
	Sven Püschel, Devarsh Thakkar, Yemike Abhilash Chandra,
	Jackson Lee, Jai Luthra, Mehdi Djait, Padhi, Beleswar,
	Donadkar, Rishikesh, Rouven Czerwinski
In-Reply-To: <20260414084259.GC4061@killaraus.ideasonboard.com>

On Tue, Apr 14, 2026 at 10:43 AM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> On Tue, Apr 14, 2026 at 10:34:13AM +0200, Loic Poulain wrote:
> > On Tue, Apr 14, 2026 at 9:42 AM Laurent Pinchart wrote:
> > > On Tue, Apr 14, 2026 at 09:20:56AM +0200, Michael Riesch wrote:
> > > > On 4/14/26 08:55, Ricardo Ribalda wrote:
> > > > > On Tue, 14 Apr 2026 at 08:47, Hans Verkuil <hverkuil+cisco@kernel.org> wrote:
> > > > >> On 13/04/2026 23:16, Laurent Pinchart wrote:
> > > > >>> On Mon, Apr 13, 2026 at 04:25:54PM -0400, Nicolas Dufresne wrote:
> > > > >>>> Le lundi 13 avril 2026 à 23:19 +0300, Laurent Pinchart a écrit :
> > > > >>>>> On Mon, Apr 13, 2026 at 10:03:52PM +0200, Loic Poulain wrote:
> > > > >>>>>> Hi Hans,
> > > > >>>>>>
> > > > >>>>>> I would be happy to discuss this if a slot is available:
> > > > >>>>>>
> > > > >>>>>> Title: Generic V4L2 ISP M2M framework
> > > > >>>>>> Presenter: Loic Poulain
> > > > >>>>>> Time estimate: ~20min
> > > > >>>>>> Description: During early development of a Qualcomm Offline Image
> > > > >>>>>> Processing Engine (OPE), we relied on the V4L2 memory‑to‑memory
> > > > >>>>>> (v4l2‑m2m) framework, which is widely used and provides solid support
> > > > >>>>>> for buffer management and scheduling. However, applying it to an ISP
> > > > >>>>>> use case exposes limitations: ISP engines often require a richer media
> > > > >>>>>> graph, with multiple pads and metadata flows, similar to inline ISP
> > > > >>>>>> pipelines (params, stats, outputs). This talk proposes discussing the
> > > > >>>>>> need for and design of a common V4L2 ISP M2M framework to factor out
> > > > >>>>>> shared functionality across drivers, particularly around buffer/queue
> > > > >>>>>> management and job scheduling.
> > > >
> > > > It seems that we share some pain points.. :-) :-/
> > > >
> > > > Over the last year, some ideas have been brewing in my mind. Not
> > > > necessarily *my* ideas, mind you, rather ideas that have been around in
> > > > linux-media for quite a while, actually. What I would like to prepare
> > > > for the Media Summit goes along the same lines.
> > > >
> > > > >>>>> That's well aligned with the v4l2-isp framework that Jacopo started, and
> > > > >>>>> to the multi-context and media-jobs APIs that we have proposed. I
> > > > >>>>> wonder, however, if a short session at the media summit will be enough,
> > > > >>>>> or if we should try to organize a half day brainstorming workshop at
> > > > >>>>> some point. Depending on when the people interested in this topic plan
> > > > >>>>> to arrive, Monday could be an option.
> > > > >>>>
> > > > >>>> I'm also/still interested in the multi-context for m2m decoders that have inline
> > > > >>>> post-processing capabilities (current model forces us to waste a lot of RAM). We
> > > > >>>> just restarted some design discussion with the team, with an increased
> > > > >>>> confidence that multi-context is the way. The scheduler could come handy in the
> > > > >>>> future if we get to deal with more multi-stage codecs in the future. I'll be in
> > > > >>>> Nice all day Monday.
> > > > >>>
> > > > >>> I will unfortunately be available only until 15:00 on Monday, but Jacopo
> > > > >>> should be available through the day. Let's see who would be interested
> > > > >>> and available, and try to organize something.
> > > > >>
> > > > >> I'm available on Monday as well. I think this is a topic that is well suited
> > > > >> to a brainstorm session.
> > > > >
> > > > > I am also available on Monday and would like to attend the session.
> > > >
> > > > I'd be interested too. Right now the plan is to arrive on Monday
> > > > afternoon. Depending on what time you agree on it may work out anyway.
> > > > It would be great to know the exact time this session will start (as I
> > > > might need to adjust my travel arrangements).
> >
> > I can arrive on Monday, with a preference for the afternoon.
> >
> > > We need a volunteer to organize this, as in finding and booking a
> > > meeting space. Note that Monday is a public holiday in France (Monday
> > > the 25th of May in particular, not all Mondays).
> > >
> > > If the number of attendees was small I was thinking of hosting the event
> > > in the place where the Ideas on Board team will be staying, but it looks
> > > like we're already reaching a fair number of people.
> > >
> > > > > Regards!
> > > > >
> > > > >> The agenda for the media summit is getting quite full, and I agree with Laurent
> > > > >> that 20 minutes is likely not enough. If we can so a session on Monday instead,
> > > > >> then that would be a good solution.
> > > >
> > > > Apart from the time and date the scope of this session would be interesting.
> > > >
> > > > Will this be a birds of a feather session in which the next generation
> > > > kernel ISP framework will be discussed? Or even the next generation
> > > > kernel video processing framework, where video processing is image
> > > > signal processing, encoding/decoding, 2D graphics processing (fisheye
> > > > correction units, 2D GPU such as the Rockchip RGA3, ...)?
> > >
> > > I would focus on Loic's original scope. If the solution can be used for
> > > other devices that's great too. I believe that the current multi-context
> > > patch series is a good fit for codecs. If we broaden the scope too much
> > > right away we'll achieve nothing.
> > >
> > > > >> I have never been very enthusiastic about the m2m framework: it's fine for e.g.
> > > > >> simple scalers, but it's awkward to use for codecs let alone ISPs.
> > > > >>
> > > > >> I always felt that we really need variants of the m2m framework that are customized
> > > > >> to specific use-cases: i.e. a codec m2m framework, and (perhaps) an ISP m2m framework.
> > > > >>
> > > > >> The big problem with that is of course who will do the work. Making new frameworks
> > > > >> is difficult and takes a long time.
> >
> > A couple of weeks ago, I submitted an initial driver for a Qualcomm
> > Offline ISP based on the standard v4l2-m2m framework. Following
> > discussions around which parts could be generalized, I started
> > migrating this work to a new v4l2-isp-m2m framework:
> > (https://github.com/loicpoulain/linux/commit/5d575d7eff8f2371e91d8237148ffdb44b0af5b0).
>
> I definitely want to discuss this, but I will be available on Monday
> until 15:00 only.

I think I can arrange to arrive in the morning if 10am works.

>
> > The API and overall logic closely mirror v4l2-m2m.c, but are extended
> > to address ISP‑specific requirements such as multi‑device support and
> > multiple queue handling.
>
> That part I don't like. The V4L2 M2M framework is a big mid-layer that
> prevents drivers from having control of how operations are handled. It
> does too much, and doesn't give enough flexibility to drivers. It may
> have been fine when the framework was designed, for the devices we had
> back then, but today it's just painful. I want to turn this around and
> give control to the drivers, with helpers they can use to implement
> parts that are not driver-specific. This needs to be opt-in, not a layer
> that takes completely control between the uAPI and driver operations.
>
> Let's not reproduce the design mistakes made in the V4L2 M2M framework.
>
> I also think you need to decouple the context handling and scheduling in
> two separate components. They need to work together, but shouldn't be
> bundled into a monolithic system. Very importantly, a driver should be
> able to implement contexts with the multi-context helpers, and implement
> custom scheduling itself.

Understood, thanks for the feedback, these are important points.
Decoupling should be straightforward to address, and I will make sure
to take Jacopo’s multi‑context work into account as part of the
design.

I also need to find the right balance between what can be easily
generalized and moved out of the driver, and raising issues or
discussions that, while valid, could branch into too many parallel
topics and significantly delay integration. I guess this can be
addressed in multiple steps: starting with an initial driver, followed
by a gradual split and migration toward a common framework, as long as
the user‑facing API remains stable (video devices, media graph, etc.).



>
> > I am planning to submit this work as an RFC
> > before the Media Summit. At this stage, the framework is still fairly
> > basic and primarily tailored to the Qualcomm use case. There is
> > definitely room for improvement, for example, integrating Jacopo’s
> > multi‑context support, since for now, the Qualcomm driver simply
> > instantiates a single ISP‑M2M context.
> >
> > As I am still getting familiar with the media subsystem, this work may
> > overlap with or conflict with ongoing efforts. Synchronizing seems
> > indeed important. Based on my current understanding, there are several
> > related areas of work that appear either complementary or orthogonal:
> > - Multi‑context support, to instantiate multiple processing sessions
> > on shared hardware/driver.
> > - Media jobs, to synchronize work across multiple drivers within the
> > same media pipeline.
> > - ISP M2M, aiming to provide a v4l2-m2m‑like framework specifically
> > for memory‑to‑memory ISP devices.
> >
> > > > This may be naive and overly optimistic, but I feel there is quite a
> > > > number of people sharing the same pain points (which are similar to
> > > > those Loic pointed out). Maybe (hopefully) this birds of a feather
> > > > session leads to the formation of some work group?
> > > >
> > > > >>>>>> On Sun, Apr 12, 2026 at 12:25 PM Hans Verkuil wrote:
> > > > >>>>>>>
> > > > >>>>>>> (Please pass this on to anyone you think might be interested in this!)
> > > > >>>>>>>
> > > > >>>>>>> Hi all,
> > > > >>>>>>>
> > > > >>>>>>> This is the fourth version of this announcement, updating the list of attendees
> > > > >>>>>>> and the tentative agenda at the end: please let me know if you see mistakes.
> > > > >>>>>>> Note that there is still time for one or two other topics. Also please check
> > > > >>>>>>> the agenda if you need more (or perhaps less) time for your topic.
> > > > >>>>>>>
> > > > >>>>>>> This year's Media Summit will be held on Tuesday May 26th the day before the
> > > > >>>>>>> Embedded Recipes Conference in Nice, France:
> > > > >>>>>>>
> > > > >>>>>>> https://embedded-recipes.org/2026/
> > > > >>>>>>>
> > > > >>>>>>> The Media Summit will be held at Hotel Campanile and in the same meeting room
> > > > >>>>>>> as last year (Nikaia):
> > > > >>>>>>>
> > > > >>>>>>> https://nice-aeroport.campanile.com/en-us/
> > > > >>>>>>>
> > > > >>>>>>> It is close to the Airport and to the Embedded Recipes venue.
> > > > >>>>>>>
> > > > >>>>>>> The meeting room can hold up to 30 people and I will provide video conferencing support,
> > > > >>>>>>> just like last year. The location and the meeting room was quite nice last year, so
> > > > >>>>>>> I saw no need to change it.
> > > > >>>>>>>
> > > > >>>>>>> That said, in-person participation is very much preferred. This yearly summit is meant
> > > > >>>>>>> for active media developers to meet face-to-face and to discuss media subsystem issues.
> > > > >>>>>>>
> > > > >>>>>>> And it is also a good opportunity to talk to each other during the Embedded Recipes
> > > > >>>>>>> conference to discuss topics in a smaller group. But if you are an active media developer
> > > > >>>>>>> and are really not able to attend in person, then remote participation is an option.
> > > > >>>>>>>
> > > > >>>>>>> If you want to attend the meeting (either in person or remote), then send an email to me
> > > > >>>>>>> directly. The deadline for in-person attendance is May 14 as the hotel needs to know the
> > > > >>>>>>> final number of attendees by then.
> > > > >>>>>>>
> > > > >>>>>>> There is no registration fee, the meeting room is sponsored by Cisco and Collabora, and
> > > > >>>>>>> the lunch is sponsored by Ideas on Board! Many thanks to our sponsors, it's very much
> > > > >>>>>>> appreciated.
> > > > >>>>>>>
> > > > >>>>>>> If you have a topic that you want to discuss, just 'Reply All' to this announcement
> > > > >>>>>>> and give the topic title, a short description and a guesstimate of the time you need
> > > > >>>>>>> for your topic.
> > > > >>>>>>>
> > > > >>>>>>> See last year's Media Summit Report as an example of what to expect:
> > > > >>>>>>>
> > > > >>>>>>> https://lore.kernel.org/linux-media/21769183-ca57-4f8f-818a-6a1ad089298d@jjverkuil.nl/
> > > > >>>>>>>
> > > > >>>>>>> Regards,
> > > > >>>>>>>
> > > > >>>>>>>         Hans
> > > > >>>>>>>
> > > > >>>>>>> PS: Be aware that May 24 and 25 are public holidays in France. So many
> > > > >>>>>>> shops may be
> > > > >>>>>>> closed those days.
> > > > >>>>>>>
> > > > >>>>>>> In-person attendees:
> > > > >>>>>>> Sakari Ailus <sakari.ailus@linux.intel.com>
> > > > >>>>>>> Kieran Bingham <kieran.bingham@ideasonboard.com>
> > > > >>>>>>> Brandon Brnich <b-brnich@ti.com>
> > > > >>>>>>> Rouven Czerwinski <rouven.czerwinski@linaro.org>
> > > > >>>>>>> Mehdi Djait <mehdi.djait@linux.intel.com>
> > > > >>>>>>> Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> > > > >>>>>>> Nicolas Dufresne <nicolas.dufresne@collabora.com>
> > > > >>>>>>> Marco Felsch <m.felsch@pengutronix.de>
> > > > >>>>>>> Paul Kocialkowski <paulk@sys-base.io>
> > > > >>>>>>> Jai Luthra <jai.luthra@ideasonboard.com>
> > > > >>>>>>> Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> > > > >>>>>>> Benjamin Mugnier <benjamin.mugnier@foss.st.com>
> > > > >>>>>>> Beleswar Padhi <b-padhi@ti.com>
> > > > >>>>>>> Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > > >>>>>>> Loic Poulain <loic.poulain@oss.qualcomm.com>
> > > > >>>>>>> Sven Püschel <s.pueschel@pengutronix.de>
> > > > >>>>>>> Ricardo Ribalda <ribalda@chromium.org>
> > > > >>>>>>> Michael Riesch <michael.riesch@collabora.com>
> > > > >>>>>>> Devarsh Thakkar <devarsht@ti.com>
> > > > >>>>>>> Michael Tretter <m.tretter@pengutronix.de>
> > > > >>>>>>> Hans Verkuil <hverkuil@kernel.org>
> > > > >>>>>>>
> > > > >>>>>>> Remote attendees:
> > > > >>>>>>> Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
> > > > >>>>>>> Rishikesh Donadkar <r-donadkar@ti.com>
> > > > >>>>>>> Jackson Lee <jackson.lee@chipsnmedia.com>
> > > > >>>>>>> Dave Stevenson <dave.stevenson@raspberrypi.com> (tentative)
> > > > >>>>>>>
> > > > >>>>>>>
> > > > >>>>>>> Agenda (tentative):
> > > > >>>>>>>
> > > > >>>>>>> 8:45-9:20: Arrive, settle in
> > > > >>>>>>>
> > > > >>>>>>> 9:20-9:30: Short intro (Hans Verkuil)
> > > > >>>>>>>
> > > > >>>>>>> 9:30-9:45: Status of ISP support in V4L2
> > > > >>>>>>>         Presenter: Laurent Pinchart
> > > > >>>>>>>         Description: Summary of ISP-related development in V4L2 since the last
> > > > >>>>>>>         Linux Media Summit. This includes a brief overview of technical
> > > > >>>>>>>         developments, and a summary of the efforts to engage with vendors.
> > > > >>>>>>>
> > > > >>>>>>> 9:45-10:45: V4L2 Stateless Video Encoding uAPI Progress Update
> > > > >>>>>>>         Presenter: Paul Kocialkowski
> > > > >>>>>>>         Description: An update on the ongonig work to support stateless codecs in V4L2.
> > > > >>>>>>>         Some of the remaining open topics will be presented and discussed.
> > > > >>>>>>>
> > > > >>>>>>> 10:45-11:00: break
> > > > >>>>>>>
> > > > >>>>>>> 11:00-11:30: Vulkan Video Codecs
> > > > >>>>>>>         Presenter: Nicolas Dufresne
> > > > >>>>>>>         Description: Vulkan video codecs: what are the viable options for Linux Media
> > > > >>>>>>>         and what is in preparation outside of our subsystem. The second aspect is
> > > > >>>>>>>         informative as these discussions don't seem to lean toward our subsystem as the
> > > > >>>>>>>         foundation. But I think it's rather useful for everyone to understand why and
> > > > >>>>>>>         what is included.
> > > > >>>>>>>
> > > > >>>>>>> 11:30-12:00: Protected Video playback on i.MX8MQ
> > > > >>>>>>>         Presenter: Rouven Czerwinski
> > > > >>>>>>>         Description: Introduction to protected video playback
> > > > >>>>>>>         on i.MX8MQ and missing bits for linux-media & protected heap interoperability.
> > > > >>>>>>>
> > > > >>>>>>> 12:00-13:30: Lunch
> > > > >>>>>>>
> > > > >>>>>>> 13:30-14:00: HDCP support for HDMI receivers
> > > > >>>>>>>         Presenter: Hans Verkuil
> > > > >>>>>>>         Description: I have been working on adding HDCP support for HDMI receivers.
> > > > >>>>>>>         Specifically the HDCP negotiation between sources and sinks.
> > > > >>>>>>>
> > > > >>>>>>> 14:00-14:30: AI patches
> > > > >>>>>>>         Presenter: Sakari Ailus
> > > > >>>>>>>         Description: What is our policy w.r.t. AI generated patches?
> > > > >>>>>>>
> > > > >>>>>>> 14:30-15:00 Overview of Media CI: where do pipelines run?
> > > > >>>>>>>         Presenter: Ricardo Ribalda
> > > > >>>>>>>         Description: How are jobs in pipelines assigned? How does the infrastructure
> > > > >>>>>>>         for Media CI work? Are there things that can be tweaked to make it more
> > > > >>>>>>>         reliable?
> > > > >>>>>>>
> > > > >>>>>>> 15:00-15:15: Break
> > > > >>>>>>>
> > > > >>>>>>> 15:15-16:15: Discussion of the media subsystem development process
> > > > >>>>>>>         Presenter: Hans Verkuil
> > > > >>>>>>>         Description: Review of the multi-committer model: current status and next steps.
> > > > >>>>>>>         Are there any bottlenecks, any ideas for improvements, w.r.t. the development process?
> > > > >>>>>>>
> > > > >>>>>>> As you can see, there is still some available time for other topics.
>
> --
> Regards,
>
> Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 1/1] media: Documentation: Improve PIXEL_RATE control documentation
From: Sakari Ailus @ 2026-04-14 19:00 UTC (permalink / raw)
  To: Jacopo Mondi; +Cc: linux-media, laurent.pinchart, jai.luthra
In-Reply-To: <ad5d_I4LGrLLEVK2@zed>

Hi Jacopo,

On Tue, Apr 14, 2026 at 05:46:51PM +0200, Jacopo Mondi wrote:
> Hi Sakari
> 
> On Tue, Apr 14, 2026 at 01:35:59PM +0300, Sakari Ailus wrote:
> > Document explicitly that the PIXEL_RATE control reflects the actual
> > frequency at which the pixels are read in the pixel array. It is thus
> > orthogonal to analogue binning.
> >
> > Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
> > ---
> >  .../userspace-api/media/v4l/ext-ctrls-image-process.rst      | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst
> > index 6d516f041ca2..8616bcd67270 100644
> > --- a/Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst
> > +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-image-process.rst
> > @@ -41,6 +41,11 @@ Image Process Control IDs
> >      The configuration of the frame rate is performed by selecting the desired
> >      horizontal and vertical blanking. The unit of this control is Hz.
> >
> > +    Note that this control isn't affected by analogue binning as the pixels are
> > +    still being read at the same frequency as without analogue binning, only
> > +    what is being read is different (a single pixel value vs. a binned pixel
> > +    value based on the values of two or more pixels).
> > +
> 
> This breaks the model implemented to support "special" (aka analogue
> ?) binning mode on imx219 where we double the pixel rate to express an
> higher frame rate and halve the blanking values before writing them to
> registers

Note that this patch is a clarification to the existing documentation, not
a change as such. It was never expected to be used as it is currently in
the imx219 driver.

> 
> I guess we have to keep this mode working not to break existing
> userspace, also because it's the only way we can have it working
> without the introduction of the FLL and LLP controls.

The other option is indeed to leave the HBLANK as-is but based on a
discussion with Jai I decided to write a patch to remove the rate
multiplier. Overall I'd say it'd be better to change this now rather than
leave imx219 using a different interface behaviour than the rest.

> 
> With the new model and FLL and LLP controls, I presume analog binning
> would require userspace to program halved FLL and LLP values ?

The userspace would in fact use LLP and FLL as the sensor does, there's no
need to divide or multiply these values with another variable.

> 
> Currently in your proposal of V4L2_CID_BINNING_FACTORS it doesn't seem
> there is a way to distinguish between  a digital and an analogue
> binning mode, they're both 2x2 so I guess it's the driver that has to
> realize that if FLL and LLP are smaller the [output width + blank] it
> has to activate the analogue binning mode ?

The driver is indeed responsible for setting the limits for FLL and LLP (or
blanking) controls depending on binning and analogue cropping
configuration, a sensor supporting analogue binning is not a special case
as such.

> 
> 
> >  ``V4L2_CID_TEST_PATTERN (menu)``
> >      Some capture/display/sensor devices have the capability to generate
> >      test pattern images. These hardware specific test patterns can be

-- 
Kind regards,

Sakari Ailus

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox