Register "non_pixel" child node as a platform device, and configure its
DMA via of_dma_configure(). This ensures proper IOMMU attachment and DMA
setup for the "non_pixel" device.
All non pixel memory, i.e bitstream buffers, HFI queues and internal
buffers related to bitstream processing, would be managed by non_pixel
device.
Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
---
drivers/media/platform/qcom/iris/iris_core.h | 2 ++
drivers/media/platform/qcom/iris/iris_probe.c | 50 ++++++++++++++++++++++++++-
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
index aeeac32a1f6d9a9fa7027e8e3db4d95f021c552e..757efd16870876bd2b1d5b1e4103b2d2326b5f49 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -65,6 +65,7 @@ struct icc_info {
* @sys_error_handler: a delayed work for handling system fatal error
* @instances: a list_head of all instances
* @inst_fw_caps: an array of supported instance capabilities
+ * @np_dev: device to represent non pixel node
*/
struct iris_core {
@@ -105,6 +106,7 @@ struct iris_core {
struct delayed_work sys_error_handler;
struct list_head instances;
struct platform_inst_fw_cap inst_fw_caps[INST_FW_CAP_MAX];
+ struct device *np_dev;
};
int iris_core_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
index 9a7ce142f7007ffcda0bd422c1983f2374bb0d92..8fe87e30bd40f3c67ec41305c7d73520fbc9db7b 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -6,6 +6,8 @@
#include <linux/clk.h>
#include <linux/interconnect.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
@@ -127,6 +129,46 @@ static int iris_init_resets(struct iris_core *core)
core->iris_platform_data->controller_rst_tbl_size);
}
+static int iris_init_non_pixel_node(struct iris_core *core)
+{
+ struct platform_device_info info;
+ struct platform_device *pdev;
+ struct device_node *np_node;
+ int ret;
+
+ np_node = of_get_child_by_name(core->dev->of_node, "non_pixel");
+ if (!np_node)
+ return 0;
+
+ memset(&info, 0, sizeof(info));
+ info.fwnode = &np_node->fwnode;
+ info.parent = core->dev;
+ info.name = np_node->name;
+ info.dma_mask = DMA_BIT_MASK(32);
+
+ pdev = platform_device_register_full(&info);
+ if (IS_ERR(pdev)) {
+ of_node_put(np_node);
+ return PTR_ERR(pdev);
+ }
+ pdev->dev.of_node = np_node;
+
+ ret = of_dma_configure(&pdev->dev, np_node, true);
+ if (ret)
+ goto err_unregister;
+
+ core->np_dev = &pdev->dev;
+
+ of_node_put(np_node);
+
+ return 0;
+
+err_unregister:
+ platform_device_unregister(pdev);
+ of_node_put(np_node);
+ return ret;
+}
+
static int iris_init_resources(struct iris_core *core)
{
int ret;
@@ -143,7 +185,11 @@ static int iris_init_resources(struct iris_core *core)
if (ret)
return ret;
- return iris_init_resets(core);
+ ret = iris_init_resets(core);
+ if (ret)
+ return ret;
+
+ return iris_init_non_pixel_node(core);
}
static int iris_register_video_device(struct iris_core *core)
@@ -188,6 +234,8 @@ static void iris_remove(struct platform_device *pdev)
iris_core_deinit(core);
+ platform_device_unregister(to_platform_device(core->np_dev));
+
video_unregister_device(core->vdev_dec);
v4l2_device_unregister(&core->v4l2_dev);
--
2.34.1
On 6/27/25 5:48 PM, Vikash Garodia wrote:
> Register "non_pixel" child node as a platform device, and configure its
> DMA via of_dma_configure(). This ensures proper IOMMU attachment and DMA
> setup for the "non_pixel" device.
> All non pixel memory, i.e bitstream buffers, HFI queues and internal
> buffers related to bitstream processing, would be managed by non_pixel
> device.
>
> Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> ---
[...]
> + memset(&info, 0, sizeof(info));
> + info.fwnode = &np_node->fwnode;
> + info.parent = core->dev;
> + info.name = np_node->name;
> + info.dma_mask = DMA_BIT_MASK(32);
I'm not 1000% sure, but I fear that with the current description:
iris_resv: reservation-iris {
iommu-addresses = <&iris_non_pixel 0x0 0x0 0x0 0x25800000>,
<&iris_non_pixel 0x0 0xe0000000 0x0 0x20000000>;
};
this only works by luck, and once we introduce a platform that needs >32b
address space access, a change here will break the existing platforms, as
the higher parts are not forbidden.
We can work around it like the Tegra folks by filling out the upper size
dword, but I think it only further makes the iommu-addresses binding look
silly..
I'll submit a patch to (in my view) improve it soon
Konrad
On 27/06/2025 17:48, Vikash Garodia wrote:
>
> +static int iris_init_non_pixel_node(struct iris_core *core)
> +{
> + struct platform_device_info info;
> + struct platform_device *pdev;
> + struct device_node *np_node;
> + int ret;
> +
> + np_node = of_get_child_by_name(core->dev->of_node, "non_pixel");
Never tested.
Best regards,
Krzysztof
On 7/2/2025 4:34 PM, Krzysztof Kozlowski wrote:
> On 27/06/2025 17:48, Vikash Garodia wrote:
>>
>> +static int iris_init_non_pixel_node(struct iris_core *core)
>> +{
>> + struct platform_device_info info;
>> + struct platform_device *pdev;
>> + struct device_node *np_node;
>> + int ret;
>> +
>> + np_node = of_get_child_by_name(core->dev->of_node, "non_pixel");
>
> Never tested.
Yes, thats correct, but it have been sorted out now.
>
> Best regards,
> Krzysztof
On 27/06/2025 16:48, Vikash Garodia wrote:
> Register "non_pixel" child node as a platform device, and configure its
> DMA via of_dma_configure(). This ensures proper IOMMU attachment and DMA
> setup for the "non_pixel" device.
> All non pixel memory, i.e bitstream buffers, HFI queues and internal
> buffers related to bitstream processing, would be managed by non_pixel
> device.
>
> Signed-off-by: Vikash Garodia <quic_vgarodia@quicinc.com>
> ---
> drivers/media/platform/qcom/iris/iris_core.h | 2 ++
> drivers/media/platform/qcom/iris/iris_probe.c | 50 ++++++++++++++++++++++++++-
> 2 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
> index aeeac32a1f6d9a9fa7027e8e3db4d95f021c552e..757efd16870876bd2b1d5b1e4103b2d2326b5f49 100644
> --- a/drivers/media/platform/qcom/iris/iris_core.h
> +++ b/drivers/media/platform/qcom/iris/iris_core.h
> @@ -65,6 +65,7 @@ struct icc_info {
> * @sys_error_handler: a delayed work for handling system fatal error
> * @instances: a list_head of all instances
> * @inst_fw_caps: an array of supported instance capabilities
> + * @np_dev: device to represent non pixel node
> */
>
> struct iris_core {
> @@ -105,6 +106,7 @@ struct iris_core {
> struct delayed_work sys_error_handler;
> struct list_head instances;
> struct platform_inst_fw_cap inst_fw_caps[INST_FW_CAP_MAX];
> + struct device *np_dev;
> };
>
> int iris_core_init(struct iris_core *core);
> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
> index 9a7ce142f7007ffcda0bd422c1983f2374bb0d92..8fe87e30bd40f3c67ec41305c7d73520fbc9db7b 100644
> --- a/drivers/media/platform/qcom/iris/iris_probe.c
> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
> @@ -6,6 +6,8 @@
> #include <linux/clk.h>
> #include <linux/interconnect.h>
> #include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> #include <linux/pm_domain.h>
> #include <linux/pm_opp.h>
> #include <linux/pm_runtime.h>
> @@ -127,6 +129,46 @@ static int iris_init_resets(struct iris_core *core)
> core->iris_platform_data->controller_rst_tbl_size);
> }
>
> +static int iris_init_non_pixel_node(struct iris_core *core)
> +{
> + struct platform_device_info info;
> + struct platform_device *pdev;
> + struct device_node *np_node;
> + int ret;
> +
> + np_node = of_get_child_by_name(core->dev->of_node, "non_pixel");
> + if (!np_node)
> + return 0;
> +
> + memset(&info, 0, sizeof(info));
> + info.fwnode = &np_node->fwnode;
> + info.parent = core->dev;
> + info.name = np_node->name;
> + info.dma_mask = DMA_BIT_MASK(32);
> +
> + pdev = platform_device_register_full(&info);
> + if (IS_ERR(pdev)) {
> + of_node_put(np_node);
> + return PTR_ERR(pdev);
> + }
> + pdev->dev.of_node = np_node;
> +
> + ret = of_dma_configure(&pdev->dev, np_node, true);
> + if (ret)
> + goto err_unregister;
> +
> + core->np_dev = &pdev->dev;
> +
> + of_node_put(np_node);
> +
> + return 0;
> +
> +err_unregister:
> + platform_device_unregister(pdev);
> + of_node_put(np_node);
> + return ret;
> +}
> +
> static int iris_init_resources(struct iris_core *core)
> {
> int ret;
> @@ -143,7 +185,11 @@ static int iris_init_resources(struct iris_core *core)
> if (ret)
> return ret;
>
> - return iris_init_resets(core);
> + ret = iris_init_resets(core);
> + if (ret)
> + return ret;
> +
> + return iris_init_non_pixel_node(core);
> }
>
> static int iris_register_video_device(struct iris_core *core)
> @@ -188,6 +234,8 @@ static void iris_remove(struct platform_device *pdev)
>
> iris_core_deinit(core);
>
> + platform_device_unregister(to_platform_device(core->np_dev));
> +
> video_unregister_device(core->vdev_dec);
>
> v4l2_device_unregister(&core->v4l2_dev);
>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
© 2016 - 2026 Red Hat, Inc.