From b294e366e08e34222b01d8113e764478a27ce428 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Oct 2025 19:46:22 +0530 Subject: [PATCH 01/41] FROMLIST: media: dt-bindings: qcom-kaanapali-iris: Add kaanapali video codec binding Kaanapali SOC brings in the new generation of video IP i.e iris4. When compared to previous generation, iris3x, it has, - separate power domains for stream and pixel processing hardware blocks (bse and vpp). - additional power domain for apv codec. - power domains for individual pipes (VPPx). - different clocks and reset lines. Iommus include all the different stream-ids which can be possibly generated by vpu4 video hardware in both secure and non secure execution mode. The vpu have reserved iova, i.e some portion of the addressable range is reserved for IO registers. Iris_resv would describe the acceptable address range. Link: https://lore.kernel.org/linux-media/20251017-knp_video-v2-1-f568ce1a4be3@oss.qualcomm.com/ Signed-off-by: Vikash Garodia --- .../bindings/media/qcom,kaanapali-iris.yaml | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml diff --git a/Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml b/Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml new file mode 100644 index 0000000000000..39e9ac9dad221 --- /dev/null +++ b/Documentation/devicetree/bindings/media/qcom,kaanapali-iris.yaml @@ -0,0 +1,231 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/media/qcom,kaanapali-iris.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Kaanapali Iris video encoder and decoder + +maintainers: + - Vikash Garodia + - Dikshita Agarwal + +description: + The iris video processing unit is a video encode and decode accelerator + present on Qualcomm Kaanapali SoC. + +properties: + compatible: + const: qcom,kaanapali-iris + + reg: + maxItems: 1 + + clocks: + maxItems: 10 + + clock-names: + items: + - const: iface + - const: core + - const: vcodec0_core + - const: iface1 + - const: core_freerun + - const: vcodec0_core_freerun + - const: vcodec_bse + - const: vcodec_vpp0 + - const: vcodec_vpp1 + - const: vcodec_apv + + dma-coherent: true + + firmware-name: + maxItems: 1 + + interconnects: + maxItems: 2 + + interconnect-names: + items: + - const: cpu-cfg + - const: video-mem + + interrupts: + maxItems: 1 + + iommus: + minItems: 3 + maxItems: 8 + + memory-region: + minItems: 1 + maxItems: 2 + + operating-points-v2: true + opp-table: + type: object + + power-domains: + maxItems: 7 + + power-domain-names: + items: + - const: venus + - const: vcodec0 + - const: mxc + - const: mmcx + - const: vpp0 + - const: vpp1 + - const: apv + + resets: + maxItems: 4 + + reset-names: + items: + - const: bus0 + - const: bus1 + - const: core_freerun_reset + - const: vcodec0_core_freerun_reset + +required: + - compatible + - reg + - clocks + - clock-names + - dma-coherent + - interconnects + - interconnect-names + - interrupts + - iommus + - power-domains + - power-domain-names + - resets + - reset-names + +unevaluatedProperties: false + +examples: + - | + #include + #include + + video-codec@2000000 { + compatible = "qcom,kaanapali-iris"; + reg = <0x02000000 0xf0000>; + + clocks = <&gcc_video_axi0_clk>, + <&video_cc_mvs0c_clk>, + <&video_cc_mvs0_clk>, + <&gcc_video_axi1_clk>, + <&video_cc_mvs0c_freerun_clk>, + <&video_cc_mvs0_freerun_clk>, + <&video_cc_mvs0b_clk>, + <&video_cc_mvs0_vpp0_clk>, + <&video_cc_mvs0_vpp1_clk>, + <&video_cc_mvs0a_clk>; + clock-names = "iface", + "core", + "vcodec0_core", + "iface1", + "core_freerun", + "vcodec0_core_freerun", + "vcodec_bse", + "vcodec_vpp0", + "vcodec_vpp1", + "vcodec_apv"; + + dma-coherent; + + interconnects = <&gem_noc_master_appss_proc &config_noc_slave_venus_cfg>, + <&mmss_noc_master_video_mvp &mc_virt_slave_ebi1>; + interconnect-names = "cpu-cfg", + "video-mem"; + + interrupts = ; + + iommus = <&apps_smmu 0x1940 0x0>, + <&apps_smmu 0x1944 0x0>, + <&apps_smmu 0x1a20 0x0>, + <&apps_smmu 0x1943 0x0>; + + operating-points-v2 = <&iris_opp_table>; + + memory-region = <&video_mem>, <&iris_resv>; + + power-domains = <&video_cc_mvs0c_gdsc>, + <&video_cc_mvs0_gdsc>, + <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_MMCX>, + <&video_cc_mvs0_vpp0_gdsc>, + <&video_cc_mvs0_vpp1_gdsc>, + <&video_cc_mvs0a_gdsc>; + power-domain-names = "venus", + "vcodec0", + "mxc", + "mmcx", + "vpp0", + "vpp1", + "apv"; + + resets = <&gcc_video_axi0_clk_ares>, + <&gcc_video_axi1_clk_ares>, + <&video_cc_mvs0c_freerun_clk_ares>, + <&video_cc_mvs0_freerun_clk_ares>; + reset-names = "bus0", + "bus1", + "core_freerun_reset", + "vcodec0_core_freerun_reset"; + + iris_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-240000000 { + opp-hz = /bits/ 64 <240000000 240000000 240000000 360000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>, + <&rpmhpd_opp_low_svs_d1>; + }; + + opp-338000000 { + opp-hz = /bits/ 64 <338000000 338000000 338000000 507000000>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + }; + + opp-420000000 { + opp-hz = /bits/ 64 <420000000 420000000 420000000 630000000>; + required-opps = <&rpmhpd_opp_svs>, + <&rpmhpd_opp_svs>; + }; + + opp-444000000 { + opp-hz = /bits/ 64 <444000000 444000000 444000000 666000000>; + required-opps = <&rpmhpd_opp_svs_l1>, + <&rpmhpd_opp_svs_l1>; + }; + + opp-533000000 { + opp-hz = /bits/ 64 <533000000 533000000 533000000 800000000>; + required-opps = <&rpmhpd_opp_nom>, + <&rpmhpd_opp_nom>; + }; + + opp-630000000 { + opp-hz = /bits/ 64 <630000000 630000000 630000000 1104000000>; + required-opps = <&rpmhpd_opp_turbo>, + <&rpmhpd_opp_turbo>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000 630000000 630000000 1260000000>; + required-opps = <&rpmhpd_opp_turbo_l0>, + <&rpmhpd_opp_turbo_l0>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000 630000000 850000000 1260000000>; + required-opps = <&rpmhpd_opp_turbo_l1>, + <&rpmhpd_opp_turbo_l1>; + }; + }; + }; From 5b0afecfc719907eb69ff93ce6ebfff9ce4bc36b Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 17 Oct 2025 19:46:29 +0530 Subject: [PATCH 02/41] FROMLIST: media: iris: Add platform data for kaanapali Add support for the kaanapali platform by re-using the SM8550 definitions and using the vpu4 ops. Move the configurations that differs in a per-SoC platform header, that will contain SoC specific data. Link: https://lore.kernel.org/all/20251017-knp_video-v2-8-f568ce1a4be3@oss.qualcomm.com/ Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia Reviewed-by: Bryan O'Donoghue --- .../platform/qcom/iris/iris_platform_common.h | 1 + .../platform/qcom/iris/iris_platform_gen2.c | 88 +++++++++++++++++++ .../qcom/iris/iris_platform_kaanapali.h | 63 +++++++++++++ drivers/media/platform/qcom/iris/iris_probe.c | 4 + 4 files changed, 156 insertions(+) create mode 100644 drivers/media/platform/qcom/iris/iris_platform_kaanapali.h diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 5a489917580eb..8c1ad8ae46025 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -41,6 +41,7 @@ enum pipe_type { PIPE_4 = 4, }; +extern const struct iris_platform_data kaanapali_data; extern const struct iris_platform_data qcs8300_data; extern const struct iris_platform_data sc7280_data; extern const struct iris_platform_data sm8250_data; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 5da90d47f9c6e..e0c99d28762cd 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -12,6 +12,7 @@ #include "iris_vpu_buffer.h" #include "iris_vpu_common.h" +#include "iris_platform_kaanapali.h" #include "iris_platform_qcs8300.h" #include "iris_platform_sm8650.h" #include "iris_platform_sm8750.h" @@ -921,6 +922,93 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = { BUF_SCRATCH_2, }; +const struct iris_platform_data kaanapali_data = { + .get_instance = iris_hfi_gen2_get_instance, + .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, + .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, + .get_vpu_buffer_size = iris_vpu4x_buf_size, + .vpu_ops = &iris_vpu4x_ops, + .set_preset_registers = iris_set_sm8550_preset_registers, + .icc_tbl = sm8550_icc_table, + .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), + .clk_rst_tbl = kaanapali_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(kaanapali_clk_reset_table), + .bw_tbl_dec = sm8550_bw_table_dec, + .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), + .pmdomain_tbl = kaanapali_pmdomain_table, + .pmdomain_tbl_size = ARRAY_SIZE(kaanapali_pmdomain_table), + .opp_pd_tbl = sm8550_opp_pd_table, + .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), + .clk_tbl = kaanapali_clk_table, + .clk_tbl_size = ARRAY_SIZE(kaanapali_clk_table), + .opp_clk_tbl = kaanapali_opp_clk_table, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu40_p2_s7.mbn", + .pas_id = IRIS_PAS_ID, + .inst_iris_fmts = platform_fmts_sm8550_dec, + .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), + .inst_caps = &platform_inst_cap_sm8550, + .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, + .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), + .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), + .tz_cp_config_data = tz_cp_config_kaanapali, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), + .core_arch = VIDEO_ARCH_LX, + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, + .ubwc_config = &ubwc_config_sm8550, + .num_vpp_pipe = 2, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((8192 * 4352) / 256) * 60, + .dec_input_config_params_default = + sm8550_vdec_input_config_params_default, + .dec_input_config_params_default_size = + ARRAY_SIZE(sm8550_vdec_input_config_params_default), + .dec_input_config_params_hevc = + sm8550_vdec_input_config_param_hevc, + .dec_input_config_params_hevc_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), + .dec_input_config_params_vp9 = + sm8550_vdec_input_config_param_vp9, + .dec_input_config_params_vp9_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_output_config_params = + sm8550_vdec_output_config_params, + .dec_output_config_params_size = + ARRAY_SIZE(sm8550_vdec_output_config_params), + + .enc_input_config_params = + sm8550_venc_input_config_params, + .enc_input_config_params_size = + ARRAY_SIZE(sm8550_venc_input_config_params), + .enc_output_config_params = + sm8550_venc_output_config_params, + .enc_output_config_params_size = + ARRAY_SIZE(sm8550_venc_output_config_params), + + .dec_input_prop = sm8550_vdec_subscribe_input_properties, + .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), + .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, + .dec_output_prop_avc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), + .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, + .dec_output_prop_hevc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), + .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, + .dec_output_prop_vp9_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + + .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), + .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), + + .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, + .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), +}; + const struct iris_platform_data sm8550_data = { .get_instance = iris_hfi_gen2_get_instance, .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, diff --git a/drivers/media/platform/qcom/iris/iris_platform_kaanapali.h b/drivers/media/platform/qcom/iris/iris_platform_kaanapali.h new file mode 100644 index 0000000000000..247fb9d7cb632 --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_kaanapali.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __IRIS_PLATFORM_KAANAPALI_H__ +#define __IRIS_PLATFORM_KAANAPALI_H__ + +#define VIDEO_REGION_VM0_SECURE_NP_ID 1 +#define VIDEO_REGION_VM0_NONSECURE_NP_ID 5 + +static const char *const kaanapali_clk_reset_table[] = { + "bus0", + "bus1", + "core_freerun_reset", + "vcodec0_core_freerun_reset", +}; + +static const char *const kaanapali_pmdomain_table[] = { + "venus", + "vcodec0", + "vpp0", + "vpp1", + "apv", +}; + +static const struct platform_clk_data kaanapali_clk_table[] = { + { IRIS_AXI_CLK, "iface" }, + { IRIS_CTRL_CLK, "core" }, + { IRIS_HW_CLK, "vcodec0_core" }, + { IRIS_AXI1_CLK, "iface1" }, + { IRIS_CTRL_FREERUN_CLK, "core_freerun" }, + { IRIS_HW_FREERUN_CLK, "vcodec0_core_freerun" }, + { IRIS_BSE_HW_CLK, "vcodec_bse" }, + { IRIS_VPP0_HW_CLK, "vcodec_vpp0" }, + { IRIS_VPP1_HW_CLK, "vcodec_vpp1" }, + { IRIS_APV_HW_CLK, "vcodec_apv" }, +}; + +static const char *const kaanapali_opp_clk_table[] = { + "vcodec0_core", + "vcodec_apv", + "vcodec_bse", + "core", + NULL, +}; + +static struct tz_cp_config tz_cp_config_kaanapali[] = { + { + .cp_start = VIDEO_REGION_VM0_SECURE_NP_ID, + .cp_size = 0, + .cp_nonpixel_start = 0x01000000, + .cp_nonpixel_size = 0x24800000, + }, + { + .cp_start = VIDEO_REGION_VM0_NONSECURE_NP_ID, + .cp_size = 0, + .cp_nonpixel_start = 0x25800000, + .cp_nonpixel_size = 0xda400000, + }, +}; + +#endif /* __IRIS_PLATFORM_KAANAPALI_H__ */ diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index ddaacda523ecb..a27a23b960bdf 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -348,6 +348,10 @@ static const struct dev_pm_ops iris_pm_ops = { }; static const struct of_device_id iris_dt_match[] = { + { + .compatible = "qcom,kaanapali-iris", + .data = &kaanapali_data, + }, { .compatible = "qcom,qcs8300-iris", .data = &qcs8300_data, From 9cf49c46acd9176b1f64c8a69b1a8d34559adec3 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Wed, 11 Feb 2026 12:19:16 +0530 Subject: [PATCH 03/41] FROMLIST: media: iris: Enable Secure PAS support with IOMMU managed by Linux Most Qualcomm platforms feature a inhouse 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 the device tree. Link: https://lore.kernel.org/lkml/20250819165447.4149674-12-mukesh.ojha@oss.qualcomm.com/ Signed-off-by: Vikash Garodia Signed-off-by: Mukesh Ojha --- drivers/media/platform/qcom/iris/iris_core.c | 9 +- drivers/media/platform/qcom/iris/iris_core.h | 5 + .../media/platform/qcom/iris/iris_firmware.c | 127 ++++++++++++++++-- .../media/platform/qcom/iris/iris_firmware.h | 2 + 4 files changed, 133 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c index 8406c48d635b6..62a9e15b47372 100644 --- a/drivers/media/platform/qcom/iris/iris_core.c +++ b/drivers/media/platform/qcom/iris/iris_core.c @@ -18,6 +18,7 @@ void iris_core_deinit(struct iris_core *core) if (core->state != IRIS_CORE_DEINIT) { iris_fw_unload(core); iris_vpu_power_off(core); + iris_fw_deinit(core); iris_hfi_queues_deinit(core); core->state = IRIS_CORE_DEINIT; } @@ -67,10 +68,14 @@ int iris_core_init(struct iris_core *core) if (ret) goto error_queue_deinit; - ret = iris_fw_load(core); + ret = iris_fw_init(core); if (ret) goto error_power_off; + ret = iris_fw_load(core); + if (ret) + goto error_firmware_deinit; + ret = iris_vpu_boot_firmware(core); if (ret) goto error_unload_fw; @@ -85,6 +90,8 @@ int iris_core_init(struct iris_core *core) error_unload_fw: iris_fw_unload(core); +error_firmware_deinit: + iris_fw_deinit(core); error_power_off: iris_vpu_power_off(core); error_queue_deinit: diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h index fb194c967ad4f..ef081ccc3429d 100644 --- a/drivers/media/platform/qcom/iris/iris_core.h +++ b/drivers/media/platform/qcom/iris/iris_core.h @@ -82,6 +82,11 @@ struct iris_core { struct v4l2_device v4l2_dev; struct video_device *vdev_dec; struct video_device *vdev_enc; + struct video_firmware { + struct device *dev; + struct qcom_scm_pas_context *ctx; + struct iommu_domain *iommu_domain; + } fw; const struct v4l2_file_operations *iris_v4l2_file_ops; const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops_dec; const struct v4l2_ioctl_ops *iris_v4l2_ioctl_ops_enc; diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index 5f408024e967f..d74a5aed291d7 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -3,10 +3,15 @@ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ +#include #include #include +#include +#include #include +#include #include +#include #include #include "iris_core.h" @@ -17,6 +22,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) { u32 pas_id = core->iris_platform_data->pas_id; + struct qcom_scm_pas_context *ctx; const struct firmware *firmware = NULL; struct device *dev = core->dev; struct resource res; @@ -36,6 +42,14 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) mem_phys = res.start; res_size = resource_size(&res); + dev = core->fw.dev ? : core->dev; + + ctx = devm_qcom_scm_pas_context_alloc(dev, pas_id, mem_phys, res_size); + if (!ctx) + return -ENOMEM; + + ctx->use_tzmem = core->fw.dev; + ret = request_firmware(&firmware, fw_name, dev); if (ret) return ret; @@ -52,9 +66,29 @@ 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); + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL); + qcom_scm_pas_metadata_release(ctx); + if (ret) + goto err_mem_unmap; + + if (core->fw.iommu_domain) { + ret = iommu_map(core->fw.iommu_domain, 0, mem_phys, res_size, + IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL); + if (ret) + goto err_mem_unmap; + } + ret = qcom_scm_pas_prepare_and_auth_reset(ctx); + if (ret) + goto err_iommu_unmap; + + core->fw.ctx = ctx; + + return ret; + +err_iommu_unmap: + iommu_unmap(core->fw.iommu_domain, 0, res_size); +err_mem_unmap: memunmap(mem_virt); err_release_fw: release_firmware(firmware); @@ -79,12 +113,6 @@ int iris_fw_load(struct iris_core *core) return -ENOMEM; } - ret = qcom_scm_pas_auth_and_reset(core->iris_platform_data->pas_id); - if (ret) { - dev_err(core->dev, "auth and reset failed: %d\n", ret); - return ret; - } - for (i = 0; i < core->iris_platform_data->tz_cp_config_data_size; i++) { cp_config = &core->iris_platform_data->tz_cp_config_data[i]; ret = qcom_scm_mem_protect_video_var(cp_config->cp_start, @@ -103,10 +131,91 @@ int iris_fw_load(struct iris_core *core) int iris_fw_unload(struct iris_core *core) { - return qcom_scm_pas_shutdown(core->iris_platform_data->pas_id); + struct qcom_scm_pas_context *ctx = core->fw.ctx; + int ret; + + if (!ctx) + return -EINVAL; + + ret = qcom_scm_pas_shutdown(ctx->pas_id); + if (core->fw.iommu_domain) + iommu_unmap(core->fw.iommu_domain, 0, ctx->mem_size); + + core->fw.ctx = NULL; + return ret; } int iris_set_hw_state(struct iris_core *core, bool resume) { return qcom_scm_set_remote_state(resume, 0); } + +int iris_fw_init(struct iris_core *core) +{ + struct platform_device_info info; + struct iommu_domain *iommu_dom; + struct platform_device *pdev; + struct device_node *np; + int ret; + + np = of_get_child_by_name(core->dev->of_node, "video-firmware"); + if (!np) + return 0; + + memset(&info, 0, sizeof(info)); + info.fwnode = &np->fwnode; + info.parent = core->dev; + info.name = np->name; + info.dma_mask = DMA_BIT_MASK(32); + + pdev = platform_device_register_full(&info); + if (IS_ERR(pdev)) { + of_node_put(np); + return PTR_ERR(pdev); + } + + pdev->dev.of_node = np; + + ret = of_dma_configure(&pdev->dev, np, true); + if (ret) + goto err_unregister; + + core->fw.dev = &pdev->dev; + + iommu_dom = iommu_get_domain_for_dev(core->fw.dev); + if (!iommu_dom) { + ret = -EINVAL; + goto err_unset_fw_dev; + } + + ret = iommu_attach_device(iommu_dom, core->fw.dev); + if (ret) + goto err_unset_fw_dev; + + core->fw.iommu_domain = iommu_dom; + + of_node_put(np); + + return 0; + +err_unset_fw_dev: + core->fw.dev = NULL; +err_unregister: + platform_device_unregister(pdev); + of_node_put(np); + return ret; +} + +void iris_fw_deinit(struct iris_core *core) +{ + if (!core->fw.dev) + return; + + if (core->fw.iommu_domain) { + iommu_detach_device(core->fw.iommu_domain, core->fw.dev); + core->fw.iommu_domain = NULL; + } + + platform_device_unregister(to_platform_device(core->fw.dev)); + core->fw.dev = NULL; +} diff --git a/drivers/media/platform/qcom/iris/iris_firmware.h b/drivers/media/platform/qcom/iris/iris_firmware.h index e833ecd348871..adde461099667 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.h +++ b/drivers/media/platform/qcom/iris/iris_firmware.h @@ -11,5 +11,7 @@ struct iris_core; int iris_fw_load(struct iris_core *core); int iris_fw_unload(struct iris_core *core); int iris_set_hw_state(struct iris_core *core, bool resume); +int iris_fw_init(struct iris_core *core); +void iris_fw_deinit(struct iris_core *core); #endif From 0dffeb1b29a3f4d1db954b8aecf38dacb954c675 Mon Sep 17 00:00:00 2001 From: Gourav Kumar Date: Thu, 2 Apr 2026 11:44:12 +0530 Subject: [PATCH 04/41] PENDING: media: iris: update MDT PAS load call for new API The Qualcomm MDT loader changed qcom_mdt_pas_load() to take only four arguments and use the PAS context for relocation and memory handling. Update the iris firmware loading path to match that interface by dropping the temporary memremap/memunmap flow, removing the extra mem_virt argument from qcom_mdt_pas_load(), and simplifying the error path accordingly. This keeps the iris driver aligned with the SCM/PAS loader changes and fixes the build failure caused by the old five-argument call. Signed-off-by: Gourav Kumar --- drivers/media/platform/qcom/iris/iris_firmware.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index d74a5aed291d7..e19daf0c41262 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -29,7 +29,6 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) phys_addr_t mem_phys; size_t res_size; ssize_t fw_size; - void *mem_virt; int ret; if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4) @@ -60,22 +59,16 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) goto err_release_fw; } - mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC); - if (!mem_virt) { - ret = -ENOMEM; - goto err_release_fw; - } - - ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL); + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, NULL); qcom_scm_pas_metadata_release(ctx); if (ret) - goto err_mem_unmap; + goto err_release_fw; if (core->fw.iommu_domain) { ret = iommu_map(core->fw.iommu_domain, 0, mem_phys, res_size, IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL); if (ret) - goto err_mem_unmap; + goto err_release_fw; } ret = qcom_scm_pas_prepare_and_auth_reset(ctx); @@ -88,8 +81,6 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) err_iommu_unmap: iommu_unmap(core->fw.iommu_domain, 0, res_size); -err_mem_unmap: - memunmap(mem_virt); err_release_fw: release_firmware(firmware); From a8c200f510e6fb455abc51c9f46ebedf23f97cfd Mon Sep 17 00:00:00 2001 From: Renjiang Han Date: Thu, 19 Mar 2026 09:54:05 +0530 Subject: [PATCH 05/41] FROMLIST: media: qcom: venus: drop extra padding in NV12 raw size calculation get_framesize_raw_nv12() currently adds SZ_4K to the UV plane size and an additional SZ_8K to the total buffer size. This inflates the calculated sizeimage and leads userspace to over-allocate buffers without a clear requirement. Remove the extra SZ_4K/SZ_8K padding and compute the NV12 size as the sum of Y and UV planes, keeping the final ALIGN(size, SZ_4K) intact. Link: https://lore.kernel.org/linux-arm-msm/20260331-fix_venus_bug_issue-v1-1-e4ae7a1d8db2@oss.qualcomm.com Fixes: e1cb72de702ad ("media: venus: helpers: move frame size calculations on common place") Signed-off-by: Renjiang Han --- drivers/media/platform/qcom/venus/helpers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 747c388fe25fa..59eee3dd9e06c 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -954,8 +954,8 @@ static u32 get_framesize_raw_nv12(u32 width, u32 height) uv_sclines = ALIGN(((height + 1) >> 1), 16); y_plane = y_stride * y_sclines; - uv_plane = uv_stride * uv_sclines + SZ_4K; - size = y_plane + uv_plane + SZ_8K; + uv_plane = uv_stride * uv_sclines; + size = y_plane + uv_plane; return ALIGN(size, SZ_4K); } From 10e98dc02129d9ac71387aa9da47d73289fe653f Mon Sep 17 00:00:00 2001 From: Renjiang Han Date: Mon, 30 Mar 2026 16:47:59 +0530 Subject: [PATCH 06/41] FROMLIST: media: qcom: venus: relax encoder frame/blur dimension steps on v4 Encoder HFI capabilities on v4 advertise a 16-pixel step for frame and blur dimensions. This is overly restrictive and can cause userspace caps negotiation to fail even for valid resolutions. Relax the advertised step size to 1 and keep alignment enforcement in buffer layout and size calculations. Link: https://lore.kernel.org/linux-arm-msm/20260331-fix_venus_bug_issue-v1-2-e4ae7a1d8db2@oss.qualcomm.com Fixes: 8b88cabef404e ("media: venus: hfi_plat_v4: Populate codecs and capabilities for v4") Signed-off-by: Renjiang Han --- .../platform/qcom/venus/hfi_platform_v4.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v4.c b/drivers/media/platform/qcom/venus/hfi_platform_v4.c index cda888b56b5d4..e0b3652bb4409 100644 --- a/drivers/media/platform/qcom/venus/hfi_platform_v4.c +++ b/drivers/media/platform/qcom/venus/hfi_platform_v4.c @@ -136,8 +136,8 @@ static const struct hfi_plat_caps caps[] = { .codec = HFI_VIDEO_CODEC_H264, .domain = VIDC_SESSION_TYPE_ENC, .cap_bufs_mode_dynamic = true, - .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 96, 4096, 16}, - .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 96, 4096, 16}, + .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 96, 4096, 1}, + .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 96, 4096, 1}, .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 1, 36864, 1}, .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 120000000, 1}, .caps[4] = {HFI_CAPABILITY_SCALE_X, 8192, 65536, 1}, @@ -173,8 +173,8 @@ static const struct hfi_plat_caps caps[] = { .codec = HFI_VIDEO_CODEC_HEVC, .domain = VIDC_SESSION_TYPE_ENC, .cap_bufs_mode_dynamic = true, - .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 96, 4096, 16}, - .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 96, 4096, 16}, + .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 96, 4096, 1}, + .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 96, 4096, 1}, .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 1, 36864, 1}, .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 120000000, 1}, .caps[4] = {HFI_CAPABILITY_SCALE_X, 8192, 65536, 1}, @@ -195,8 +195,8 @@ static const struct hfi_plat_caps caps[] = { .caps[19] = {HFI_CAPABILITY_RATE_CONTROL_MODES, 0x1000001, 0x1000005, 1}, .caps[20] = {HFI_CAPABILITY_COLOR_SPACE_CONVERSION, 0, 2, 1}, .caps[21] = {HFI_CAPABILITY_ROTATION, 1, 4, 90}, - .caps[22] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 16}, - .caps[23] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 16}, + .caps[22] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 1}, + .caps[23] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 1}, .num_caps = 24, .pl[0] = {HFI_HEVC_PROFILE_MAIN, HFI_HEVC_LEVEL_6 | HFI_HEVC_TIER_HIGH0}, .pl[1] = {HFI_HEVC_PROFILE_MAIN10, HFI_HEVC_LEVEL_6 | HFI_HEVC_TIER_HIGH0}, @@ -210,8 +210,8 @@ static const struct hfi_plat_caps caps[] = { .codec = HFI_VIDEO_CODEC_VP8, .domain = VIDC_SESSION_TYPE_ENC, .cap_bufs_mode_dynamic = true, - .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 96, 4096, 16}, - .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 96, 4096, 16}, + .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 96, 4096, 1}, + .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 96, 4096, 1}, .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 1, 36864, 1}, .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 120000000, 1}, .caps[4] = {HFI_CAPABILITY_SCALE_X, 8192, 65536, 1}, @@ -229,8 +229,8 @@ static const struct hfi_plat_caps caps[] = { .caps[16] = {HFI_CAPABILITY_P_FRAME_QP, 0, 127, 1}, .caps[17] = {HFI_CAPABILITY_MAX_WORKMODES, 1, 2, 1}, .caps[18] = {HFI_CAPABILITY_RATE_CONTROL_MODES, 0x1000001, 0x1000005, 1}, - .caps[19] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 16}, - .caps[20] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 16}, + .caps[19] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 1}, + .caps[20] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 1}, .caps[21] = {HFI_CAPABILITY_COLOR_SPACE_CONVERSION, 0, 2, 1}, .caps[22] = {HFI_CAPABILITY_ROTATION, 1, 4, 90}, .num_caps = 23, From 20c719db89838dab6073b2e67667ef4f11075e3e Mon Sep 17 00:00:00 2001 From: Renjiang Han Date: Mon, 30 Mar 2026 16:51:33 +0530 Subject: [PATCH 07/41] FROMLIST: media: qcom: venus: relax encoder frame/blur step size on v6 Encoder HFI capabilities on v6 enforce a 16-pixel step for frame and blur dimensions, which does not reflect actual hardware requirements and can reject valid userspace configurations. Relax the step size to 1 while leaving min/max limits unchanged. Link: https://lore.kernel.org/linux-arm-msm/20260331-fix_venus_bug_issue-v1-3-e4ae7a1d8db2@oss.qualcomm.com Fixes: 869d77e706290 ("media: venus: hfi_plat_v6: Populate capabilities for v6") Signed-off-by: Renjiang Han --- .../media/platform/qcom/venus/hfi_platform_v6.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/venus/hfi_platform_v6.c b/drivers/media/platform/qcom/venus/hfi_platform_v6.c index d8568c08cc361..fb8d10ab34043 100644 --- a/drivers/media/platform/qcom/venus/hfi_platform_v6.c +++ b/drivers/media/platform/qcom/venus/hfi_platform_v6.c @@ -173,8 +173,8 @@ static const struct hfi_plat_caps caps[] = { .codec = HFI_VIDEO_CODEC_HEVC, .domain = VIDC_SESSION_TYPE_ENC, .cap_bufs_mode_dynamic = true, - .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 8192, 16}, - .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 8192, 16}, + .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 8192, 1}, + .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 8192, 1}, .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 64, 138240, 1}, .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 160000000, 1}, .caps[4] = {HFI_CAPABILITY_SCALE_X, 8192, 65536, 1}, @@ -195,8 +195,8 @@ static const struct hfi_plat_caps caps[] = { .caps[19] = {HFI_CAPABILITY_RATE_CONTROL_MODES, 0x1000001, 0x1000005, 1}, .caps[20] = {HFI_CAPABILITY_COLOR_SPACE_CONVERSION, 0, 2, 1}, .caps[21] = {HFI_CAPABILITY_ROTATION, 1, 4, 90}, - .caps[22] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 16}, - .caps[23] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 16}, + .caps[22] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 1}, + .caps[23] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 1}, .num_caps = 24, .pl[0] = {HFI_HEVC_PROFILE_MAIN, HFI_HEVC_LEVEL_6 | HFI_HEVC_TIER_HIGH0}, .pl[1] = {HFI_HEVC_PROFILE_MAIN10, HFI_HEVC_LEVEL_6 | HFI_HEVC_TIER_HIGH0}, @@ -210,8 +210,8 @@ static const struct hfi_plat_caps caps[] = { .codec = HFI_VIDEO_CODEC_VP8, .domain = VIDC_SESSION_TYPE_ENC, .cap_bufs_mode_dynamic = true, - .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 4096, 16}, - .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 4096, 16}, + .caps[0] = {HFI_CAPABILITY_FRAME_WIDTH, 128, 4096, 1}, + .caps[1] = {HFI_CAPABILITY_FRAME_HEIGHT, 128, 4096, 1}, .caps[2] = {HFI_CAPABILITY_MBS_PER_FRAME, 64, 36864, 1}, .caps[3] = {HFI_CAPABILITY_BITRATE, 1, 74000000, 1}, .caps[4] = {HFI_CAPABILITY_SCALE_X, 8192, 65536, 1}, @@ -229,8 +229,8 @@ static const struct hfi_plat_caps caps[] = { .caps[16] = {HFI_CAPABILITY_P_FRAME_QP, 0, 127, 1}, .caps[17] = {HFI_CAPABILITY_MAX_WORKMODES, 1, 2, 1}, .caps[18] = {HFI_CAPABILITY_RATE_CONTROL_MODES, 0x1000001, 0x1000005, 1}, - .caps[19] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 16}, - .caps[20] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 16}, + .caps[19] = {HFI_CAPABILITY_BLUR_WIDTH, 96, 4096, 1}, + .caps[20] = {HFI_CAPABILITY_BLUR_HEIGHT, 96, 4096, 1}, .caps[21] = {HFI_CAPABILITY_COLOR_SPACE_CONVERSION, 0, 2, 1}, .caps[22] = {HFI_CAPABILITY_ROTATION, 1, 4, 90}, .num_caps = 23, From 149d8eb1c6877b2f347dab3f60e16ad15188132d Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 30 Mar 2026 03:29:35 +0530 Subject: [PATCH 08/41] FROMLIST: media: qcom: iris: increase H265D_MAX_SLICE to fix H.265 decoding on SC7280 Follow commit bfe1326573ff ("venus: Fix for H265 decoding failure.") and increase H265D_MAX_SLICE following firmware requirements on that platform. Otherwise decoding of the H.265 streams fails withthe insufficient scratch_1 buffer size from the firmware. Link: https://lore.kernel.org/all/20260327-venus-iris-flip-switch-v5-3-2f4b6c636927@oss.qualcomm.com/ Signed-off-by: Dmitry Baryshkov Reviewed-by: Dikshita Agarwal Reviewed-by: Vikash Garodia Reviewed-by: Konrad Dybcio --- drivers/media/platform/qcom/iris/iris_vpu_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h index 12640eb5ed8c4..8c0d6b7b5de85 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h @@ -67,7 +67,7 @@ struct iris_inst; #define SIZE_DOLBY_RPU_METADATA (41 * 1024) #define H264_CABAC_HDR_RATIO_HD_TOT 1 #define H264_CABAC_RES_RATIO_HD_TOT 3 -#define H265D_MAX_SLICE 1200 +#define H265D_MAX_SLICE 3600 #define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T #define H265_CABAC_HDR_RATIO_HD_TOT 2 #define H265_CABAC_RES_RATIO_HD_TOT 2 From aad8bb890893ab77305a908f1326f5a61f28eccf Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 1 Apr 2026 12:40:43 +0000 Subject: [PATCH 09/41] FROMLIST: media: qcom: venus: flip the venus/iris switch With the Iris and Venus driver having more or less feature parity for HFI 6xx platforms and with Iris gaining support for SC7280, flip the switch. Use Iris by default for SM8250 and SC7280, the platforms which are supported by both drivers, and use Venus only if Iris is not compiled at all. Use IS_ENABLED to strip out the code and data structures which are used by the disabled platforms. Link: https://lore.kernel.org/all/20260327-venus-iris-flip-switch-v5-4-2f4b6c636927@oss.qualcomm.com/ Reviewed-by: Konrad Dybcio Reviewed-by: Vikash Garodia Signed-off-by: Dmitry Baryshkov Reviewed-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/Makefile | 5 +---- drivers/media/platform/qcom/iris/iris_probe.c | 2 -- drivers/media/platform/qcom/venus/core.c | 6 ++++++ drivers/media/platform/qcom/venus/core.h | 11 +++++++++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile index 2abbd3aeb4af0..2fde45f817276 100644 --- a/drivers/media/platform/qcom/iris/Makefile +++ b/drivers/media/platform/qcom/iris/Makefile @@ -10,6 +10,7 @@ qcom-iris-objs += iris_buffer.o \ iris_hfi_gen2_packet.o \ iris_hfi_gen2_response.o \ iris_hfi_queue.o \ + iris_platform_gen1.o \ iris_platform_gen2.o \ iris_power.o \ iris_probe.o \ @@ -26,8 +27,4 @@ qcom-iris-objs += iris_buffer.o \ iris_vpu_buffer.o \ iris_vpu_common.o \ -ifeq ($(CONFIG_VIDEO_QCOM_VENUS),) -qcom-iris-objs += iris_platform_gen1.o -endif - obj-$(CONFIG_VIDEO_QCOM_IRIS) += qcom-iris.o diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index a27a23b960bdf..fb5b31270c56a 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -356,7 +356,6 @@ static const struct of_device_id iris_dt_match[] = { .compatible = "qcom,qcs8300-iris", .data = &qcs8300_data, }, -#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_VENUS)) { .compatible = "qcom,sc7280-venus", .data = &sc7280_data, @@ -365,7 +364,6 @@ static const struct of_device_id iris_dt_match[] = { .compatible = "qcom,sm8250-venus", .data = &sm8250_data, }, -#endif { .compatible = "qcom,sm8550-iris", .data = &sm8550_data, diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 7e639760c41d9..45ce57406a4e5 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -949,6 +949,7 @@ static const struct venus_resources sc7180_res = { .enc_nodename = "video-encoder", }; +#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) static const struct freq_tbl sm8250_freq_table[] = { { 0, 444000000 }, { 0, 366000000 }, @@ -1069,6 +1070,7 @@ static const struct venus_resources sc7280_res = { .dec_nodename = "video-decoder", .enc_nodename = "video-encoder", }; +#endif static const struct bw_tbl qcm2290_bw_table_dec[] = { { 352800, 597000, 0, 746000, 0 }, /* 1080p@30 + 720p@30 */ @@ -1125,11 +1127,15 @@ static const struct of_device_id venus_dt_match[] = { { .compatible = "qcom,msm8998-venus", .data = &msm8998_res, }, { .compatible = "qcom,qcm2290-venus", .data = &qcm2290_res, }, { .compatible = "qcom,sc7180-venus", .data = &sc7180_res, }, +#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) { .compatible = "qcom,sc7280-venus", .data = &sc7280_res, }, +#endif { .compatible = "qcom,sdm660-venus", .data = &sdm660_res, }, { .compatible = "qcom,sdm845-venus", .data = &sdm845_res, }, { .compatible = "qcom,sdm845-venus-v2", .data = &sdm845_res_v2, }, +#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) { .compatible = "qcom,sm8250-venus", .data = &sm8250_res, }, +#endif { } }; MODULE_DEVICE_TABLE(of, venus_dt_match); diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 7506f5d0f609a..c7acacaa53b88 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -54,8 +54,10 @@ enum vpu_version { VPU_VERSION_AR50, VPU_VERSION_AR50_LITE, VPU_VERSION_IRIS1, +#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) VPU_VERSION_IRIS2, VPU_VERSION_IRIS2_1, +#endif }; struct firmware_version { @@ -525,13 +527,22 @@ struct venus_inst { #define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX) #define IS_V3(core) ((core)->res->hfi_version == HFI_VERSION_3XX) #define IS_V4(core) ((core)->res->hfi_version == HFI_VERSION_4XX) +#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) #define IS_V6(core) ((core)->res->hfi_version == HFI_VERSION_6XX) +#else +#define IS_V6(core) (0) +#endif #define IS_AR50(core) ((core)->res->vpu_version == VPU_VERSION_AR50) #define IS_AR50_LITE(core) ((core)->res->vpu_version == VPU_VERSION_AR50_LITE) #define IS_IRIS1(core) ((core)->res->vpu_version == VPU_VERSION_IRIS1) +#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) #define IS_IRIS2(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2) #define IS_IRIS2_1(core) ((core)->res->vpu_version == VPU_VERSION_IRIS2_1) +#else +#define IS_IRIS2(core) (0) +#define IS_IRIS2_1(core) (0) +#endif static inline bool is_lite(struct venus_core *core) { From b3ce088dfebc6d31d81c4ccd5f2ad7cf30d74fe4 Mon Sep 17 00:00:00 2001 From: Vishnu Reddy Date: Wed, 1 Apr 2026 19:19:29 +0530 Subject: [PATCH 10/41] FROMLIST: media: iris: add FPS calculation and VPP FW overhead in frequency formula MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver was using a fixed default FPS value when calculating the VPU frequency. This caused wrong frequency requests for high‑frame‑rate streams, for example 4K at 240 FPS. Because of this, the hardware was running at a lower frequency than needed. Add the FPS measurement based on the decoder input buffer arrival rate. The measured FPS is stored per instance and used in frequency calculation instead of the fixed default FPS. The value is clamped so that it does not exceed platform limits. Add a VPP firmware overhead when running in STAGE_2. Reviewed-by: Vikash Garodia Signed-off-by: Vishnu Reddy Link: https://lore.kernel.org/r/20260401-update_fps_calculation-v6-1-f44f8154ca39@oss.qualcomm.com --- .../media/platform/qcom/iris/iris_instance.h | 4 ++++ drivers/media/platform/qcom/iris/iris_vdec.c | 20 +++++++++++++++++++ drivers/media/platform/qcom/iris/iris_vpu2.c | 2 +- .../platform/qcom/iris/iris_vpu_common.c | 6 +++++- 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h index 16965150f427b..63dd889c9992a 100644 --- a/drivers/media/platform/qcom/iris/iris_instance.h +++ b/drivers/media/platform/qcom/iris/iris_instance.h @@ -67,6 +67,8 @@ struct iris_fmt { * @metadata_idx: index for metadata buffer * @codec: codec type * @last_buffer_dequeued: a flag to indicate that last buffer is sent by driver + * @last_buf_ns: start time of received input buffer for current one second FPS window + * @frame_counter: input buffer counter for current one second FPS window * @frame_rate: frame rate of current instance * @operating_rate: operating rate of current instance * @hfi_rc_type: rate control type @@ -109,6 +111,8 @@ struct iris_inst { u32 metadata_idx; u32 codec; bool last_buffer_dequeued; + u64 last_buf_ns; + u32 frame_counter; u32 frame_rate; u32 operating_rate; u32 hfi_rc_type; diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index 719217399a304..7fb45df37db6a 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -54,6 +54,7 @@ int iris_vdec_inst_init(struct iris_inst *inst) f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT; inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); inst->buffers[BUF_OUTPUT].size = f->fmt.pix_mp.plane_fmt[0].sizeimage; + inst->frame_rate = MAXIMUM_FPS; memcpy(&inst->fw_caps[0], &core->inst_fw_caps_dec[0], INST_FW_CAP_MAX * sizeof(struct platform_inst_fw_cap)); @@ -369,6 +370,8 @@ int iris_vdec_streamon_input(struct iris_inst *inst) if (ret) return ret; + inst->frame_counter = 0; + return iris_process_streamon_input(inst); } @@ -411,6 +414,7 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) { struct iris_buffer *buf = to_iris_buffer(vbuf); struct vb2_buffer *vb2 = &vbuf->vb2_buf; + u64 cur_buf_ns, delta_ns; struct vb2_queue *q; int ret; @@ -427,6 +431,22 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) return 0; } + if (buf->type == BUF_INPUT) { + cur_buf_ns = ktime_get_ns(); + + if (!inst->frame_counter) + inst->last_buf_ns = cur_buf_ns; + + inst->frame_counter++; + delta_ns = cur_buf_ns - inst->last_buf_ns; + + if (delta_ns >= NSEC_PER_SEC) { + inst->frame_rate = clamp_t(u32, inst->frame_counter, DEFAULT_FPS, + MAXIMUM_FPS); + inst->frame_counter = 0; + } + } + iris_scale_power(inst); return iris_queue_buffer(inst, buf); diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c index 9c103a2e4e4ea..73c201f4f3382 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c @@ -18,7 +18,7 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size) struct v4l2_format *inp_f = inst->fmt_src; u32 mbs_per_second, mbpf, height, width; unsigned long vpp_freq, vsp_freq; - u32 fps = DEFAULT_FPS; + u32 fps = inst->frame_rate; width = max(inp_f->fmt.pix_mp.width, inst->crop.width); height = max(inp_f->fmt.pix_mp.height, inst->crop.height); diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index 548e5f1727fdb..d621ccffa868e 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -416,7 +416,7 @@ u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_siz u32 height, width, mbs_per_second, mbpf; u64 fw_cycles, fw_vpp_cycles; u64 vsp_cycles, vpp_cycles; - u32 fps = DEFAULT_FPS; + u32 fps = inst->frame_rate; width = max(inp_f->fmt.pix_mp.width, inst->crop.width); height = max(inp_f->fmt.pix_mp.height, inst->crop.height); @@ -435,6 +435,10 @@ u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_siz if (inst->fw_caps[PIPE].value > 1) vpp_cycles += div_u64(vpp_cycles * 59, 1000); + /* 1.05 is VPP FW overhead */ + if (inst->fw_caps[STAGE].value == STAGE_2) + vpp_cycles += mult_frac(vpp_cycles, 5, 100); + vsp_cycles = fps * data_size * 8; vsp_cycles = div_u64(vsp_cycles, 2); /* VSP FW overhead 1.05 */ From 12898b775b14e8a1447637796cd156c18eec872d Mon Sep 17 00:00:00 2001 From: Vishnu Reddy Date: Tue, 7 Apr 2026 11:07:38 +0530 Subject: [PATCH 11/41] PENDING: media: iris: enable sm8550 context banks via init_cb_devs Wire up sm8550_init_cb_devs() in iris_platform_gen2.c to register the two child context-bank devices (iris_non_pixel and iris_pixel) using iris_create_cb_dev(), and hook it into the sm8550_data platform data via the .init_cb_devs callback. Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia Signed-off-by: Gourav Kumar --- .../platform/qcom/iris/iris_platform_gen2.c | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index e0c99d28762cd..f0c4504a9cc61 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -762,6 +762,47 @@ static void iris_set_sm8550_preset_registers(struct iris_core *core) writel(0x0, core->reg_base + 0xB0088); } +static int sm8550_init_cb_devs(struct iris_core *core) +{ + const u32 f_id_np = 0; /* IRIS_NON_PIXEL_VCODEC */ + const u32 f_id_p = 1; /* IRIS_PIXEL */ + struct device *dev; + + dev = iris_create_cb_dev(core, "iris_non_pixel", &f_id_np); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + core->dev_np = dev; + core->dev_bs = core->dev_np; + + dev = iris_create_cb_dev(core, "iris_pixel", &f_id_p); + if (IS_ERR(dev)) + goto err_unreg_dev_np; + + core->dev_p = dev; + + return 0; + +err_unreg_dev_np: + platform_device_unregister(to_platform_device(core->dev_np)); + core->dev_np = NULL; + core->dev_bs = NULL; + + return PTR_ERR(dev); +} + +static void sm8550_deinit_cb_devs(struct iris_core *core) +{ + if (core->dev_np) + platform_device_unregister(to_platform_device(core->dev_np)); + if (core->dev_p) + platform_device_unregister(to_platform_device(core->dev_p)); + + core->dev_np = NULL; + core->dev_bs = NULL; + core->dev_p = NULL; +} + static const struct icc_info sm8550_icc_table[] = { { "cpu-cfg", 1000, 1000 }, { "video-mem", 1000, 15000000 }, @@ -1016,6 +1057,8 @@ const struct iris_platform_data sm8550_data = { .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, .set_preset_registers = iris_set_sm8550_preset_registers, + .init_cb_devs = sm8550_init_cb_devs, + .deinit_cb_devs = sm8550_deinit_cb_devs, .icc_tbl = sm8550_icc_table, .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), .clk_rst_tbl = sm8550_clk_reset_table, From bce5f60e90e2f2606afc873834c4265f07b686a0 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 13 Mar 2026 18:49:38 +0530 Subject: [PATCH 12/41] PENDING: media: iris: add context bank devices using iommu-map Different stream IDs from VPU would be associated to one of these CB. Multiple CBs are needed to increase the IOVA for the video usecases like higher concurrent sessions. Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia --- drivers/media/platform/qcom/iris/iris_core.h | 6 ++++ .../platform/qcom/iris/iris_platform_common.h | 2 ++ drivers/media/platform/qcom/iris/iris_probe.c | 31 ++++++++++++++--- .../media/platform/qcom/iris/iris_resources.c | 34 +++++++++++++++++++ .../media/platform/qcom/iris/iris_resources.h | 1 + 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h index ef081ccc3429d..c85fd7f292467 100644 --- a/drivers/media/platform/qcom/iris/iris_core.h +++ b/drivers/media/platform/qcom/iris/iris_core.h @@ -34,6 +34,9 @@ enum domain_type { * struct iris_core - holds core parameters valid for all instances * * @dev: reference to device structure + * @dev_np: reference to non-pixel context bank device structure + * @dev_p: reference to pixel context bank device structure + * @dev_bs: reference to bitstream context bank device structure * @reg_base: IO memory base address * @irq: iris irq * @v4l2_dev: a holder for v4l2 device structure @@ -77,6 +80,9 @@ enum domain_type { struct iris_core { struct device *dev; + struct device *dev_np; + struct device *dev_p; + struct device *dev_bs; void __iomem *reg_base; int irq; struct v4l2_device v4l2_dev; diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 8c1ad8ae46025..a373407abadfb 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -220,6 +220,8 @@ struct iris_platform_data { u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); const struct vpu_ops *vpu_ops; void (*set_preset_registers)(struct iris_core *core); + int (*init_cb_devs)(struct iris_core *core); + void (*deinit_cb_devs)(struct iris_core *core); const struct icc_info *icc_tbl; unsigned int icc_tbl_size; const struct bw_info *bw_tbl_dec; diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index fb5b31270c56a..bfc71c4448f8f 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -123,6 +123,20 @@ static int iris_init_resets(struct iris_core *core) core->iris_platform_data->controller_rst_tbl_size); } +static int iris_init_cb_devs(struct iris_core *core) +{ + if (core->iris_platform_data->init_cb_devs) + return core->iris_platform_data->init_cb_devs(core); + + return 0; +} + +static void iris_deinit_cb_devs(struct iris_core *core) +{ + if (core->iris_platform_data->deinit_cb_devs) + core->iris_platform_data->deinit_cb_devs(core); +} + static int iris_init_resources(struct iris_core *core) { int ret; @@ -193,6 +207,7 @@ static void iris_remove(struct platform_device *pdev) return; iris_core_deinit(core); + iris_deinit_cb_devs(core); video_unregister_device(core->vdev_dec); video_unregister_device(core->vdev_enc); @@ -259,11 +274,15 @@ static int iris_probe(struct platform_device *pdev) if (ret) return ret; + ret = iris_init_cb_devs(core); + if (ret) + return ret; + iris_session_init_caps(core); ret = v4l2_device_register(dev, &core->v4l2_dev); if (ret) - return ret; + goto err_deinit_cb; ret = iris_register_video_device(core, DECODER); if (ret) @@ -277,9 +296,11 @@ static int iris_probe(struct platform_device *pdev) dma_mask = core->iris_platform_data->dma_mask; - ret = dma_set_mask_and_coherent(dev, dma_mask); - if (ret) - goto err_vdev_unreg_enc; + if (device_iommu_mapped(core->dev)) { + ret = dma_set_mask_and_coherent(core->dev, dma_mask); + if (ret) + goto err_vdev_unreg_enc; + } dma_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32)); dma_set_seg_boundary(&pdev->dev, DMA_BIT_MASK(32)); @@ -298,6 +319,8 @@ static int iris_probe(struct platform_device *pdev) video_unregister_device(core->vdev_dec); err_v4l2_unreg: v4l2_device_unregister(&core->v4l2_dev); +err_deinit_cb: + iris_deinit_cb_devs(core); return ret; } diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c index 773f6548370a2..b53a66d8851b6 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.c +++ b/drivers/media/platform/qcom/iris/iris_resources.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -141,3 +142,36 @@ int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type return 0; } + +struct device *iris_create_cb_dev(struct iris_core *core, const char *name, const u32 *f_id) +{ + struct platform_device *pdev; + int ret; + + pdev = platform_device_alloc(name, 0); + if (!pdev) + return ERR_PTR(-ENOMEM); + + pdev->dev.parent = core->dev; + + ret = platform_device_add(pdev); + if (ret) { + platform_device_put(pdev); + return ERR_PTR(ret); + } + + ret = of_dma_configure_id(&pdev->dev, core->dev->of_node, true, f_id); + if (ret) + goto error_unregister; + + ret = dma_set_mask_and_coherent(&pdev->dev, core->iris_platform_data->dma_mask); + if (ret) + goto error_unregister; + + return &pdev->dev; + +error_unregister: + platform_device_unregister(to_platform_device(&pdev->dev)); + + return ERR_PTR(ret); +} diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h index 6bfbd2dc6db09..4a494627ff238 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.h +++ b/drivers/media/platform/qcom/iris/iris_resources.h @@ -15,5 +15,6 @@ int iris_unset_icc_bw(struct iris_core *core); int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw); int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type); int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk_type); +struct device *iris_create_cb_dev(struct iris_core *core, const char *name, const u32 *f_id); #endif From 324a38544a7c5d1a0c64f1bf5b56c68229982ad7 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 13 Mar 2026 18:49:39 +0530 Subject: [PATCH 13/41] PENDING: media: iris: add helper to select context bank device Depending on the buffer type (input, output and internal), associated context bank is selected, if available. Fallback to parent device for backward compatibility. Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia --- .../media/platform/qcom/iris/iris_buffer.c | 8 ++-- .../media/platform/qcom/iris/iris_hfi_queue.c | 16 +++---- .../media/platform/qcom/iris/iris_resources.c | 42 +++++++++++++++++++ .../media/platform/qcom/iris/iris_resources.h | 1 + drivers/media/platform/qcom/iris/iris_vidc.c | 4 +- 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index 9151f43bc6b9c..76dc6afc81c22 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -336,7 +336,7 @@ static int iris_create_internal_buffer(struct iris_inst *inst, enum iris_buffer_type buffer_type, u32 index) { struct iris_buffers *buffers = &inst->buffers[buffer_type]; - struct iris_core *core = inst->core; + struct device *dev = iris_get_cb_dev(inst, buffer_type); struct iris_buffer *buffer; if (!buffers->size) @@ -352,7 +352,7 @@ static int iris_create_internal_buffer(struct iris_inst *inst, buffer->buffer_size = buffers->size; buffer->dma_attrs = DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING; - buffer->kvaddr = dma_alloc_attrs(core->dev, buffer->buffer_size, + buffer->kvaddr = dma_alloc_attrs(dev, buffer->buffer_size, &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs); if (!buffer->kvaddr) { kfree(buffer); @@ -489,10 +489,10 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buffer) { - struct iris_core *core = inst->core; + struct device *dev = iris_get_cb_dev(inst, buffer->type); list_del(&buffer->list); - dma_free_attrs(core->dev, buffer->buffer_size, buffer->kvaddr, + dma_free_attrs(dev, buffer->buffer_size, buffer->kvaddr, buffer->device_addr, buffer->dma_attrs); kfree(buffer); diff --git a/drivers/media/platform/qcom/iris/iris_hfi_queue.c b/drivers/media/platform/qcom/iris/iris_hfi_queue.c index b3ed06297953b..f465ff00a9ba3 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_queue.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_queue.c @@ -245,25 +245,26 @@ static void iris_hfi_queue_deinit(struct iris_iface_q_info *iface_q) int iris_hfi_queues_init(struct iris_core *core) { + struct device *dev = core->dev_np ? core->dev_np : core->dev; struct iris_hfi_queue_table_header *q_tbl_hdr; u32 queue_size; /* Iris hardware requires 4K queue alignment */ queue_size = ALIGN((sizeof(*q_tbl_hdr) + (IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ)), SZ_4K); - core->iface_q_table_vaddr = dma_alloc_attrs(core->dev, queue_size, + core->iface_q_table_vaddr = dma_alloc_attrs(dev, queue_size, &core->iface_q_table_daddr, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); if (!core->iface_q_table_vaddr) { - dev_err(core->dev, "queues alloc and map failed\n"); + dev_err(dev, "queues alloc and map failed\n"); return -ENOMEM; } - core->sfr_vaddr = dma_alloc_attrs(core->dev, SFR_SIZE, + core->sfr_vaddr = dma_alloc_attrs(dev, SFR_SIZE, &core->sfr_daddr, GFP_KERNEL, DMA_ATTR_WRITE_COMBINE); if (!core->sfr_vaddr) { - dev_err(core->dev, "sfr alloc and map failed\n"); - dma_free_attrs(core->dev, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr, + dev_err(dev, "sfr alloc and map failed\n"); + dma_free_attrs(dev, sizeof(*q_tbl_hdr), core->iface_q_table_vaddr, core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE); return -ENOMEM; } @@ -291,6 +292,7 @@ int iris_hfi_queues_init(struct iris_core *core) void iris_hfi_queues_deinit(struct iris_core *core) { + struct device *dev = core->dev_np ? core->dev_np : core->dev; u32 queue_size; if (!core->iface_q_table_vaddr) @@ -300,7 +302,7 @@ void iris_hfi_queues_deinit(struct iris_core *core) iris_hfi_queue_deinit(&core->message_queue); iris_hfi_queue_deinit(&core->command_queue); - dma_free_attrs(core->dev, SFR_SIZE, core->sfr_vaddr, + dma_free_attrs(dev, SFR_SIZE, core->sfr_vaddr, core->sfr_daddr, DMA_ATTR_WRITE_COMBINE); core->sfr_vaddr = NULL; @@ -309,7 +311,7 @@ void iris_hfi_queues_deinit(struct iris_core *core) queue_size = ALIGN(sizeof(struct iris_hfi_queue_table_header) + (IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ), SZ_4K); - dma_free_attrs(core->dev, queue_size, core->iface_q_table_vaddr, + dma_free_attrs(dev, queue_size, core->iface_q_table_vaddr, core->iface_q_table_daddr, DMA_ATTR_WRITE_COMBINE); core->iface_q_table_vaddr = NULL; diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c index b53a66d8851b6..b10884eb3ac64 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.c +++ b/drivers/media/platform/qcom/iris/iris_resources.c @@ -13,6 +13,7 @@ #include #include "iris_core.h" +#include "iris_instance.h" #include "iris_resources.h" #define BW_THRESHOLD 50000 @@ -175,3 +176,44 @@ struct device *iris_create_cb_dev(struct iris_core *core, const char *name, cons return ERR_PTR(ret); } + +struct device *iris_get_cb_dev(struct iris_inst *inst, enum iris_buffer_type buffer_type) +{ + struct iris_core *core = inst->core; + struct device *dev = NULL; + + switch (buffer_type) { + case BUF_INPUT: + if (inst->domain == DECODER) + dev = core->dev_bs; + else + dev = core->dev_p; + break; + case BUF_OUTPUT: + if (inst->domain == DECODER) + dev = core->dev_p; + else + dev = core->dev_bs; + break; + case BUF_BIN: + dev = core->dev_bs; + break; + case BUF_DPB: + case BUF_PARTIAL: + case BUF_SCRATCH_2: + case BUF_VPSS: + dev = core->dev_p; + break; + case BUF_ARP: + case BUF_COMV: + case BUF_LINE: + case BUF_NON_COMV: + case BUF_PERSIST: + dev = core->dev_np; + break; + default: + dev_err(core->dev, "invalid buffer type: %d\n", buffer_type); + } + + return dev ? dev : core->dev; +} diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h index 4a494627ff238..e6a6dc24a7f12 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.h +++ b/drivers/media/platform/qcom/iris/iris_resources.h @@ -16,5 +16,6 @@ int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw); int iris_disable_unprepare_clock(struct iris_core *core, enum platform_clk_type clk_type); int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk_type); struct device *iris_create_cb_dev(struct iris_core *core, const char *name, const u32 *f_id); +struct device *iris_get_cb_dev(struct iris_inst *inst, enum iris_buffer_type buffer_type); #endif diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index bd38d84c9cc79..8ed6520f5ae3a 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -107,7 +107,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ src_vq->drv_priv = inst; src_vq->buf_struct_size = sizeof(struct iris_buffer); src_vq->min_reqbufs_allocation = MIN_BUFFERS; - src_vq->dev = inst->core->dev; + src_vq->dev = iris_get_cb_dev(inst, BUF_INPUT); src_vq->lock = &inst->ctx_q_lock; ret = vb2_queue_init(src_vq); if (ret) @@ -121,7 +121,7 @@ iris_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_ dst_vq->drv_priv = inst; dst_vq->buf_struct_size = sizeof(struct iris_buffer); dst_vq->min_reqbufs_allocation = MIN_BUFFERS; - dst_vq->dev = inst->core->dev; + dst_vq->dev = iris_get_cb_dev(inst, BUF_OUTPUT); dst_vq->lock = &inst->ctx_q_lock; return vb2_queue_init(dst_vq); From 6bad098c14d3ef61f95aef81e444b6bce6efde82 Mon Sep 17 00:00:00 2001 From: Gourav Kumar Date: Fri, 10 Apr 2026 18:23:23 +0530 Subject: [PATCH 14/41] PENDING: dt-bindings: media: iris: add sm8550 iris context bank function IDs Add a dt-bindings header include/dt-bindings/media/qcom,sm8550-iris.h defining IRIS_NON_PIXEL_VCODEC (0) and IRIS_PIXEL (1) function IDs used to identify the non-pixel and pixel context bank SMMU stream mappings via iommu-map. Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia Signed-off-by: Gourav Kumar --- include/dt-bindings/media/qcom,sm8550-iris.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 include/dt-bindings/media/qcom,sm8550-iris.h diff --git a/include/dt-bindings/media/qcom,sm8550-iris.h b/include/dt-bindings/media/qcom,sm8550-iris.h new file mode 100644 index 0000000000000..5165ef817f8bb --- /dev/null +++ b/include/dt-bindings/media/qcom,sm8550-iris.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_MEDIA_QCOM_SM8550_IRIS_H_ +#define _DT_BINDINGS_MEDIA_QCOM_SM8550_IRIS_H_ + +/* Function identifiers for iommu-map to attach for the context bank devices */ +#define IRIS_NON_PIXEL_VCODEC 0 +#define IRIS_PIXEL 1 + +#endif From 89bb62a49f406d17051b239202a2f755df873180 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Fri, 13 Mar 2026 18:49:36 +0530 Subject: [PATCH 15/41] FROMLIST: media: iris: switch to hardware mode after firmware boot Currently the driver switches the vcodec GDSC to hardware (HW) mode before firmware load and boot sequence. GDSC can be powered off, keeping in hw mode, thereby the vcodec registers programmed in TrustZone (TZ) carry default (reset) values. Move the transition to HW mode after firmware load and boot sequence. The bug was exposed with driver configuring different stream ids to different devices via iommu-map. With registers carrying reset values, VPU would not generate desired stream-id, thereby leading to SMMU fault. For vpu4, when GDSC is switched to HW mode, there is a need to perform the reset operation. Without reset, there are occassional issues of register corruption observed. Hence the vpu GDSC switch also involves the reset. Link: https://lore.kernel.org/linux-media/20260313-kaanapali-iris-v3-2-9c0d1a67af4b@oss.qualcomm.com/ Fixes: dde659d37036 ("media: iris: Introduce vpu ops for vpu4 with necessary hooks") Co-developed-by: Vishnu Reddy Signed-off-by: Vishnu Reddy Signed-off-by: Vikash Garodia Reviewed-by: Dikshita Agarwal Reviewed-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/iris_core.c | 4 ++++ .../platform/qcom/iris/iris_hfi_common.c | 4 ++++ drivers/media/platform/qcom/iris/iris_vpu2.c | 1 + drivers/media/platform/qcom/iris/iris_vpu3x.c | 9 +++---- drivers/media/platform/qcom/iris/iris_vpu4x.c | 24 ++++++++++--------- .../platform/qcom/iris/iris_vpu_common.c | 16 ++++++++----- .../platform/qcom/iris/iris_vpu_common.h | 3 +++ 7 files changed, 38 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c index 62a9e15b47372..7a901a310e757 100644 --- a/drivers/media/platform/qcom/iris/iris_core.c +++ b/drivers/media/platform/qcom/iris/iris_core.c @@ -80,6 +80,10 @@ int iris_core_init(struct iris_core *core) if (ret) goto error_unload_fw; + ret = iris_vpu_switch_to_hwmode(core); + if (ret) + goto error_unload_fw; + ret = iris_hfi_core_init(core); if (ret) goto error_unload_fw; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/media/platform/qcom/iris/iris_hfi_common.c index 92112eb16c110..621c66593d88d 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c @@ -159,6 +159,10 @@ int iris_hfi_pm_resume(struct iris_core *core) if (ret) goto err_suspend_hw; + ret = iris_vpu_switch_to_hwmode(core); + if (ret) + goto err_suspend_hw; + ret = ops->sys_interframe_powercollapse(core); if (ret) goto err_suspend_hw; diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c index 73c201f4f3382..b8714dcbad10a 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c @@ -44,4 +44,5 @@ const struct vpu_ops iris_vpu2_ops = { .power_off_controller = iris_vpu_power_off_controller, .power_on_controller = iris_vpu_power_on_controller, .calc_freq = iris_vpu2_calc_freq, + .set_hwmode = iris_vpu_set_hwmode, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c index fe4423b951b1e..3dad47be78b58 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c @@ -234,14 +234,8 @@ static int iris_vpu35_power_on_hw(struct iris_core *core) if (ret) goto err_disable_hw_free_clk; - ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true); - if (ret) - goto err_disable_hw_clk; - return 0; -err_disable_hw_clk: - iris_disable_unprepare_clock(core, IRIS_HW_CLK); err_disable_hw_free_clk: iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK); err_disable_axi_clk: @@ -266,6 +260,7 @@ const struct vpu_ops iris_vpu3_ops = { .power_off_controller = iris_vpu_power_off_controller, .power_on_controller = iris_vpu_power_on_controller, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, + .set_hwmode = iris_vpu_set_hwmode, }; const struct vpu_ops iris_vpu33_ops = { @@ -274,6 +269,7 @@ const struct vpu_ops iris_vpu33_ops = { .power_off_controller = iris_vpu33_power_off_controller, .power_on_controller = iris_vpu_power_on_controller, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, + .set_hwmode = iris_vpu_set_hwmode, }; const struct vpu_ops iris_vpu35_ops = { @@ -283,4 +279,5 @@ const struct vpu_ops iris_vpu35_ops = { .power_on_controller = iris_vpu35_vpu4x_power_on_controller, .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, + .set_hwmode = iris_vpu_set_hwmode, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu4x.c b/drivers/media/platform/qcom/iris/iris_vpu4x.c index a8db02ce5c5ec..02e100a4045fc 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu4x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu4x.c @@ -252,21 +252,10 @@ static int iris_vpu4x_power_on_hardware(struct iris_core *core) ret = iris_vpu4x_power_on_apv(core); if (ret) goto disable_hw_clocks; - - iris_vpu4x_ahb_sync_reset_apv(core); } - iris_vpu4x_ahb_sync_reset_hardware(core); - - ret = iris_vpu4x_genpd_set_hwmode(core, true, efuse_value); - if (ret) - goto disable_apv_power_domain; - return 0; -disable_apv_power_domain: - if (!(efuse_value & DISABLE_VIDEO_APV_BIT)) - iris_vpu4x_power_off_apv(core); disable_hw_clocks: iris_vpu4x_disable_hardware_clocks(core, efuse_value); disable_vpp1_power_domain: @@ -359,6 +348,18 @@ static void iris_vpu4x_power_off_hardware(struct iris_core *core) iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); } +static int iris_vpu4x_set_hwmode(struct iris_core *core) +{ + u32 efuse_value = readl(core->reg_base + WRAPPER_EFUSE_MONITOR); + + if (!(efuse_value & DISABLE_VIDEO_APV_BIT)) + iris_vpu4x_ahb_sync_reset_apv(core); + + iris_vpu4x_ahb_sync_reset_hardware(core); + + return iris_vpu4x_genpd_set_hwmode(core, true, efuse_value); +} + const struct vpu_ops iris_vpu4x_ops = { .power_off_hw = iris_vpu4x_power_off_hardware, .power_on_hw = iris_vpu4x_power_on_hardware, @@ -366,4 +367,5 @@ const struct vpu_ops iris_vpu4x_ops = { .power_on_controller = iris_vpu35_vpu4x_power_on_controller, .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, + .set_hwmode = iris_vpu4x_set_hwmode, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index d621ccffa868e..3e3482d1841d2 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -292,14 +292,8 @@ int iris_vpu_power_on_hw(struct iris_core *core) if (ret && ret != -ENOENT) goto err_disable_hw_clock; - ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true); - if (ret) - goto err_disable_hw_ahb_clock; - return 0; -err_disable_hw_ahb_clock: - iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK); err_disable_hw_clock: iris_disable_unprepare_clock(core, IRIS_HW_CLK); err_disable_power: @@ -308,6 +302,16 @@ int iris_vpu_power_on_hw(struct iris_core *core) return ret; } +int iris_vpu_set_hwmode(struct iris_core *core) +{ + return dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true); +} + +int iris_vpu_switch_to_hwmode(struct iris_core *core) +{ + return core->iris_platform_data->vpu_ops->set_hwmode(core); +} + int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core) { u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index f6dffc613b822..dee3b1349c5e8 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -21,6 +21,7 @@ struct vpu_ops { int (*power_on_controller)(struct iris_core *core); void (*program_bootup_registers)(struct iris_core *core); u64 (*calc_freq)(struct iris_inst *inst, size_t data_size); + int (*set_hwmode)(struct iris_core *core); }; int iris_vpu_boot_firmware(struct iris_core *core); @@ -30,6 +31,8 @@ int iris_vpu_watchdog(struct iris_core *core, u32 intr_status); int iris_vpu_prepare_pc(struct iris_core *core); int iris_vpu_power_on_controller(struct iris_core *core); int iris_vpu_power_on_hw(struct iris_core *core); +int iris_vpu_set_hwmode(struct iris_core *core); +int iris_vpu_switch_to_hwmode(struct iris_core *core); int iris_vpu_power_on(struct iris_core *core); int iris_vpu_power_off_controller(struct iris_core *core); void iris_vpu_power_off_hw(struct iris_core *core); From bbaaf6658cb752183b054fc615caef797ea046e3 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:02 +0200 Subject: [PATCH 16/41] FROMLIST: media: qcom: iris: drop pas_id from the iris_platform_data struct The PAS ID, the authentication service ID, used by the Iris is a constant and it is not expected to change anytime. Drop it from the platform data and use the constant instead. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-1-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Reviewed-by: Konrad Dybcio Reviewed-by: Vikash Garodia Signed-off-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/iris_firmware.c | 7 ++++--- drivers/media/platform/qcom/iris/iris_platform_common.h | 2 -- drivers/media/platform/qcom/iris/iris_platform_gen1.c | 2 -- drivers/media/platform/qcom/iris/iris_platform_gen2.c | 5 ----- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index e19daf0c41262..da4da3648f983 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -17,11 +17,12 @@ #include "iris_core.h" #include "iris_firmware.h" +#define IRIS_PAS_ID 9 + #define MAX_FIRMWARE_NAME_SIZE 128 static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) { - u32 pas_id = core->iris_platform_data->pas_id; struct qcom_scm_pas_context *ctx; const struct firmware *firmware = NULL; struct device *dev = core->dev; @@ -43,7 +44,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) dev = core->fw.dev ? : core->dev; - ctx = devm_qcom_scm_pas_context_alloc(dev, pas_id, mem_phys, res_size); + ctx = devm_qcom_scm_pas_context_alloc(dev, IRIS_PAS_ID, mem_phys, res_size); if (!ctx) return -ENOMEM; @@ -112,7 +113,7 @@ 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); + qcom_scm_pas_shutdown(IRIS_PAS_ID); return ret; } } diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index a373407abadfb..4b1e27367bc30 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -12,7 +12,6 @@ struct iris_core; struct iris_inst; -#define IRIS_PAS_ID 9 #define HW_RESPONSE_TIMEOUT_VALUE (1000) /* milliseconds */ #define AUTOSUSPEND_DELAY_VALUE (HW_RESPONSE_TIMEOUT_VALUE + 500) /* milliseconds */ @@ -239,7 +238,6 @@ struct iris_platform_data { unsigned int controller_rst_tbl_size; u64 dma_mask; const char *fwname; - u32 pas_id; struct iris_fmt *inst_iris_fmts; u32 inst_iris_fmts_size; struct platform_inst_caps *inst_caps; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index df8e6bf9430ed..1bbdefc48d718 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -360,7 +360,6 @@ const struct iris_platform_data sm8250_data = { /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu-1.0/venus.mbn", - .pas_id = IRIS_PAS_ID, .inst_iris_fmts = platform_fmts_sm8250_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), .inst_caps = &platform_inst_cap_sm8250, @@ -413,7 +412,6 @@ const struct iris_platform_data sc7280_data = { /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu20_p1.mbn", - .pas_id = IRIS_PAS_ID, .inst_iris_fmts = platform_fmts_sm8250_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), .inst_caps = &platform_inst_cap_sm8250, diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index f0c4504a9cc61..e4cb38cecbb82 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -986,7 +986,6 @@ const struct iris_platform_data kaanapali_data = { /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu40_p2_s7.mbn", - .pas_id = IRIS_PAS_ID, .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_sm8550, @@ -1075,7 +1074,6 @@ const struct iris_platform_data sm8550_data = { /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu30_p4.mbn", - .pas_id = IRIS_PAS_ID, .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_sm8550, @@ -1180,7 +1178,6 @@ const struct iris_platform_data sm8650_data = { /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu33_p4.mbn", - .pas_id = IRIS_PAS_ID, .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_sm8550, @@ -1276,7 +1273,6 @@ const struct iris_platform_data sm8750_data = { /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu35_p4.mbn", - .pas_id = IRIS_PAS_ID, .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_sm8550, @@ -1376,7 +1372,6 @@ const struct iris_platform_data qcs8300_data = { /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, .fwname = "qcom/vpu/vpu30_p4_s6.mbn", - .pas_id = IRIS_PAS_ID, .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_qcs8300, From c8f9604e88faac140363add10e2e8c8ca1377a24 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:03 +0200 Subject: [PATCH 17/41] FROMLIST: media: qcom: iris: use common set_preset_registers function The set_preset_registers is (currently) common to all supported devices. Extract it to a iris_vpu_common.c and call it directly from iris_vpu_power_on(). Later, if any of the devices requires special handling, it can be sorted out separately. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-2-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Reviewed-by: Vikash Garodia Signed-off-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/iris_platform_gen1.c | 7 ------- drivers/media/platform/qcom/iris/iris_platform_gen2.c | 10 ---------- drivers/media/platform/qcom/iris/iris_vpu_common.c | 7 ++++++- drivers/media/platform/qcom/iris/iris_vpu_common.h | 2 ++ 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 1bbdefc48d718..546f6c025d547 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -260,11 +260,6 @@ static struct platform_inst_caps platform_inst_cap_sm8250 = { .max_operating_rate = MAXIMUM_FPS, }; -static void iris_set_sm8250_preset_registers(struct iris_core *core) -{ - writel(0x0, core->reg_base + 0xB0088); -} - static const struct icc_info sm8250_icc_table[] = { { "cpu-cfg", 1000, 1000 }, { "video-mem", 1000, 15000000 }, @@ -343,7 +338,6 @@ const struct iris_platform_data sm8250_data = { .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, - .set_preset_registers = iris_set_sm8250_preset_registers, .icc_tbl = sm8250_icc_table, .icc_tbl_size = ARRAY_SIZE(sm8250_icc_table), .clk_rst_tbl = sm8250_clk_reset_table, @@ -397,7 +391,6 @@ const struct iris_platform_data sc7280_data = { .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, - .set_preset_registers = iris_set_sm8250_preset_registers, .icc_tbl = sm8250_icc_table, .icc_tbl_size = ARRAY_SIZE(sm8250_icc_table), .bw_tbl_dec = sc7280_bw_table_dec, diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index e4cb38cecbb82..8e98857f76f99 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -757,11 +757,6 @@ static struct platform_inst_caps platform_inst_cap_sm8550 = { .max_operating_rate = MAXIMUM_FPS, }; -static void iris_set_sm8550_preset_registers(struct iris_core *core) -{ - writel(0x0, core->reg_base + 0xB0088); -} - static int sm8550_init_cb_devs(struct iris_core *core) { const u32 f_id_np = 0; /* IRIS_NON_PIXEL_VCODEC */ @@ -969,7 +964,6 @@ const struct iris_platform_data kaanapali_data = { .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, .get_vpu_buffer_size = iris_vpu4x_buf_size, .vpu_ops = &iris_vpu4x_ops, - .set_preset_registers = iris_set_sm8550_preset_registers, .icc_tbl = sm8550_icc_table, .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), .clk_rst_tbl = kaanapali_clk_reset_table, @@ -1055,7 +1049,6 @@ const struct iris_platform_data sm8550_data = { .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, - .set_preset_registers = iris_set_sm8550_preset_registers, .init_cb_devs = sm8550_init_cb_devs, .deinit_cb_devs = sm8550_deinit_cb_devs, .icc_tbl = sm8550_icc_table, @@ -1159,7 +1152,6 @@ const struct iris_platform_data sm8650_data = { .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu33_ops, - .set_preset_registers = iris_set_sm8550_preset_registers, .icc_tbl = sm8550_icc_table, .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), .clk_rst_tbl = sm8650_clk_reset_table, @@ -1256,7 +1248,6 @@ const struct iris_platform_data sm8750_data = { .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu35_ops, - .set_preset_registers = iris_set_sm8550_preset_registers, .icc_tbl = sm8550_icc_table, .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), .clk_rst_tbl = sm8750_clk_reset_table, @@ -1355,7 +1346,6 @@ const struct iris_platform_data qcs8300_data = { .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, - .set_preset_registers = iris_set_sm8550_preset_registers, .icc_tbl = sm8550_icc_table, .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), .clk_rst_tbl = sm8550_clk_reset_table, diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index 3e3482d1841d2..96e5b305c5f4a 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -476,7 +476,7 @@ int iris_vpu_power_on(struct iris_core *core) iris_opp_set_rate(core->dev, freq); - core->iris_platform_data->set_preset_registers(core); + iris_vpu_set_preset_registers(core); iris_vpu_interrupt_init(core); core->intr_status = 0; @@ -493,3 +493,8 @@ int iris_vpu_power_on(struct iris_core *core) return ret; } + +void iris_vpu_set_preset_registers(struct iris_core *core) +{ + writel(0x0, core->reg_base + 0xb0088); +} diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index dee3b1349c5e8..09799a375c142 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -42,4 +42,6 @@ int iris_vpu35_vpu4x_power_on_controller(struct iris_core *core); void iris_vpu35_vpu4x_program_bootup_registers(struct iris_core *core); u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_size); +void iris_vpu_set_preset_registers(struct iris_core *core); + #endif From 8d81f2038d4bdc74f9dcf2da75b30c6b32d4d644 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:04 +0200 Subject: [PATCH 18/41] FROMLIST: media: qcom: iris: don't use function indirection in gen2-specific code To note that iris_set_num_comv() is gen2-internal, rename it to iris_hfi_gen2_set_num_comv() and then stop using hfi_ops indirection to set session property (like other functions in this file do). Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-3-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Reviewed-by: Konrad Dybcio Reviewed-by: Vikash Garodia Signed-off-by: Dmitry Baryshkov --- .../platform/qcom/iris/iris_hfi_gen2_command.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index 30bfd90d423ba..e4f25b7f5d048 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -1205,7 +1205,7 @@ static u32 iris_hfi_gen2_buf_type_from_driver(u32 domain, enum iris_buffer_type } } -static int iris_set_num_comv(struct iris_inst *inst) +static int iris_hfi_gen2_set_num_comv(struct iris_inst *inst) { struct platform_inst_caps *caps; struct iris_core *core = inst->core; @@ -1220,12 +1220,12 @@ static int iris_set_num_comv(struct iris_inst *inst) num_comv = (inst->codec == V4L2_PIX_FMT_AV1) ? NUM_COMV_AV1 : caps->num_comv; - return core->hfi_ops->session_set_property(inst, - HFI_PROP_COMV_BUFFER_COUNT, - HFI_HOST_FLAGS_NONE, - HFI_PORT_BITSTREAM, - HFI_PAYLOAD_U32, - &num_comv, sizeof(u32)); + return iris_hfi_gen2_session_set_property(inst, + HFI_PROP_COMV_BUFFER_COUNT, + HFI_HOST_FLAGS_NONE, + HFI_PORT_BITSTREAM, + HFI_PAYLOAD_U32, + &num_comv, sizeof(u32)); } static void iris_hfi_gen2_get_buffer(u32 domain, struct iris_buffer *buffer, @@ -1257,7 +1257,7 @@ static int iris_hfi_gen2_session_queue_buffer(struct iris_inst *inst, struct iri iris_hfi_gen2_get_buffer(inst->domain, buffer, &hfi_buffer); if (buffer->type == BUF_COMV) { - ret = iris_set_num_comv(inst); + ret = iris_hfi_gen2_set_num_comv(inst); if (ret) return ret; } From 99ca152d2eb7c671737348994217dd0b70e74c2b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:05 +0200 Subject: [PATCH 19/41] FROMLIST: media: qcom: iris: split HFI session ops from core ops Calling HFI instance-specific ops should not require double indirection through the core ops. Split instance-specific ops to a separate struct, keep a pointer to it in struct iris_inst and set it directly in the get_instance function. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-4-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Reviewed-by: Vikash Garodia Signed-off-by: Dmitry Baryshkov --- .../media/platform/qcom/iris/iris_buffer.c | 4 +- .../media/platform/qcom/iris/iris_common.c | 8 ++-- drivers/media/platform/qcom/iris/iris_ctrls.c | 46 +++++++++---------- .../platform/qcom/iris/iris_hfi_common.h | 3 ++ .../qcom/iris/iris_hfi_gen1_command.c | 23 +++++++--- .../qcom/iris/iris_hfi_gen2_command.c | 17 +++++-- .../media/platform/qcom/iris/iris_instance.h | 4 ++ drivers/media/platform/qcom/iris/iris_vb2.c | 2 +- drivers/media/platform/qcom/iris/iris_vdec.c | 6 +-- drivers/media/platform/qcom/iris/iris_venc.c | 4 +- drivers/media/platform/qcom/iris/iris_vidc.c | 2 +- 11 files changed, 72 insertions(+), 47 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index 76dc6afc81c22..8c40207f12c76 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -404,7 +404,7 @@ int iris_create_internal_buffers(struct iris_inst *inst, u32 plane) int iris_queue_buffer(struct iris_inst *inst, struct iris_buffer *buf) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; int ret; ret = hfi_ops->session_queue_buf(inst, buf); @@ -572,7 +572,7 @@ int iris_destroy_dequeued_internal_buffers(struct iris_inst *inst, u32 plane) static int iris_release_internal_buffers(struct iris_inst *inst, enum iris_buffer_type buffer_type) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; struct iris_buffers *buffers = &inst->buffers[buffer_type]; struct iris_buffer *buffer, *next; int ret; diff --git a/drivers/media/platform/qcom/iris/iris_common.c b/drivers/media/platform/qcom/iris/iris_common.c index 7f1c7fe144f70..25836561bcf3e 100644 --- a/drivers/media/platform/qcom/iris/iris_common.c +++ b/drivers/media/platform/qcom/iris/iris_common.c @@ -48,7 +48,7 @@ void iris_set_ts_metadata(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) int iris_process_streamon_input(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; enum iris_inst_sub_state set_sub_state = 0; int ret; @@ -90,7 +90,7 @@ int iris_process_streamon_input(struct iris_inst *inst) int iris_process_streamon_output(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; enum iris_inst_sub_state clear_sub_state = 0; bool drain_active, drc_active, first_ipsc; int ret = 0; @@ -189,7 +189,7 @@ static void iris_flush_deferred_buffers(struct iris_inst *inst, static void iris_kill_session(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; if (!inst->session_id) return; @@ -200,7 +200,7 @@ static void iris_kill_session(struct iris_inst *inst) int iris_session_streamoff(struct iris_inst *inst, u32 plane) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; enum iris_buffer_type buffer_type; int ret; diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c index 3cec957580f5e..5a24aa869b2dc 100644 --- a/drivers/media/platform/qcom/iris/iris_ctrls.c +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c @@ -399,7 +399,7 @@ static u32 iris_get_port_info(struct iris_inst *inst, int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 hfi_value = inst->fw_caps[cap_id].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; @@ -412,7 +412,7 @@ int iris_set_u32_enum(struct iris_inst *inst, enum platform_inst_fw_cap_type cap int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 hfi_value = inst->fw_caps[cap_id].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; @@ -425,7 +425,7 @@ int iris_set_u32(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; struct v4l2_format *inp_f = inst->fmt_src; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; u32 height = inp_f->fmt.pix_mp.height; @@ -446,7 +446,7 @@ int iris_set_stage(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 work_route = inst->fw_caps[PIPE].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; @@ -459,7 +459,7 @@ int iris_set_pipe(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 hfi_id, hfi_value; if (inst->codec == V4L2_PIX_FMT_H264) { @@ -479,7 +479,7 @@ int iris_set_profile(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_ int iris_set_level(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 hfi_id, hfi_value; if (inst->codec == V4L2_PIX_FMT_H264) { @@ -499,7 +499,7 @@ int iris_set_level(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id int iris_set_profile_level_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; struct hfi_profile_level pl; @@ -520,7 +520,7 @@ int iris_set_profile_level_gen1(struct iris_inst *inst, enum platform_inst_fw_ca int iris_set_header_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 header_mode = inst->fw_caps[cap_id].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; u32 hfi_val; @@ -539,7 +539,7 @@ int iris_set_header_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_ int iris_set_header_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 prepend_sps_pps = inst->fw_caps[PREPEND_SPSPPS_TO_IDR].value; u32 header_mode = inst->fw_caps[cap_id].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; @@ -561,7 +561,7 @@ int iris_set_header_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_ int iris_set_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 entropy_mode = inst->fw_caps[ENTROPY_MODE].value; u32 bitrate = inst->fw_caps[cap_id].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; @@ -586,7 +586,7 @@ int iris_set_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_ int iris_set_peak_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 rc_mode = inst->fw_caps[BITRATE_MODE].value; u32 peak_bitrate = inst->fw_caps[cap_id].value; u32 bitrate = inst->fw_caps[BITRATE].value; @@ -613,7 +613,7 @@ int iris_set_peak_bitrate(struct iris_inst *inst, enum platform_inst_fw_cap_type int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 bitrate_mode = inst->fw_caps[BITRATE_MODE].value; u32 frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value; u32 frame_skip = inst->fw_caps[FRAME_SKIP_MODE].value; @@ -640,7 +640,7 @@ int iris_set_bitrate_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 bitrate_mode = inst->fw_caps[BITRATE_MODE].value; u32 frame_rc = inst->fw_caps[FRAME_RC_ENABLE].value; u32 frame_skip = inst->fw_caps[FRAME_SKIP_MODE].value; @@ -667,7 +667,7 @@ int iris_set_bitrate_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap int iris_set_entropy_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 entropy_mode = inst->fw_caps[cap_id].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; u32 hfi_val; @@ -687,7 +687,7 @@ int iris_set_entropy_mode_gen1(struct iris_inst *inst, enum platform_inst_fw_cap int iris_set_entropy_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 entropy_mode = inst->fw_caps[cap_id].value; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; u32 profile; @@ -712,7 +712,7 @@ int iris_set_entropy_mode_gen2(struct iris_inst *inst, enum platform_inst_fw_cap int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0; u32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0; u32 min_qp_enable = 0, client_qp_enable = 0; @@ -776,7 +776,7 @@ int iris_set_min_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_i int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0; u32 max_qp_enable = 0, client_qp_enable; u32 i_frame_qp, p_frame_qp, b_frame_qp; @@ -841,7 +841,7 @@ int iris_set_max_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_i int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0, client_qp_enable; u32 i_frame_qp, p_frame_qp, b_frame_qp; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; @@ -902,7 +902,7 @@ int iris_set_frame_qp(struct iris_inst *inst, enum platform_inst_fw_cap_type cap int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; struct hfi_quantization_range_v2 range; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; @@ -923,7 +923,7 @@ int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; u32 hfi_val; @@ -953,7 +953,7 @@ int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; u32 hfi_id = inst->fw_caps[cap_id].hfi_id; u32 hfi_val = HFI_DISABLE_FLIP; @@ -972,7 +972,7 @@ int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; struct vb2_queue *q = v4l2_m2m_get_dst_vq(inst->m2m_ctx); u32 ir_period = inst->fw_caps[cap_id].value; u32 ir_type = 0; @@ -998,7 +998,7 @@ int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type ca int iris_set_properties(struct iris_inst *inst, u32 plane) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; struct platform_inst_fw_cap *cap; int ret; u32 i; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h index 3edb5ae582b49..18684ada78b21 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h @@ -110,6 +110,9 @@ struct iris_hfi_command_ops { int (*sys_image_version)(struct iris_core *core); int (*sys_interframe_powercollapse)(struct iris_core *core); int (*sys_pc_prep)(struct iris_core *core); +}; + +struct iris_hfi_session_ops { int (*session_set_config_params)(struct iris_inst *inst, u32 plane); int (*session_set_property)(struct iris_inst *inst, u32 packet_type, u32 flag, u32 plane, u32 payload_type, diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index e42d17653c2c3..a28b0c7ebbadd 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -1063,11 +1063,7 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p return 0; } -static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { - .sys_init = iris_hfi_gen1_sys_init, - .sys_image_version = iris_hfi_gen1_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, +static const struct iris_hfi_session_ops iris_hfi_gen1_session_ops = { .session_open = iris_hfi_gen1_session_open, .session_set_config_params = iris_hfi_gen1_session_set_config_params, .session_set_property = iris_hfi_gen1_session_set_property, @@ -1080,6 +1076,13 @@ static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { .session_close = iris_hfi_gen1_session_close, }; +static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { + .sys_init = iris_hfi_gen1_sys_init, + .sys_image_version = iris_hfi_gen1_sys_image_version, + .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, + .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, +}; + void iris_hfi_gen1_command_ops_init(struct iris_core *core) { core->hfi_ops = &iris_hfi_gen1_command_ops; @@ -1087,5 +1090,13 @@ void iris_hfi_gen1_command_ops_init(struct iris_core *core) struct iris_inst *iris_hfi_gen1_get_instance(void) { - return kzalloc_obj(struct iris_inst); + struct iris_inst *out; + + out = kzalloc_obj(*out); + if (!out) + return NULL; + + out->hfi_session_ops = &iris_hfi_gen1_session_ops; + + return out; } diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index e4f25b7f5d048..ffb70fd9499cb 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -1300,11 +1300,7 @@ static int iris_hfi_gen2_session_release_buffer(struct iris_inst *inst, struct i inst_hfi_gen2->packet->size); } -static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { - .sys_init = iris_hfi_gen2_sys_init, - .sys_image_version = iris_hfi_gen2_sys_image_version, - .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, - .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, +static const struct iris_hfi_session_ops iris_hfi_gen2_session_ops = { .session_open = iris_hfi_gen2_session_open, .session_set_config_params = iris_hfi_gen2_session_set_config_params, .session_set_property = iris_hfi_gen2_session_set_property, @@ -1319,6 +1315,13 @@ static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { .session_close = iris_hfi_gen2_session_close, }; +static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { + .sys_init = iris_hfi_gen2_sys_init, + .sys_image_version = iris_hfi_gen2_sys_image_version, + .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, + .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, +}; + void iris_hfi_gen2_command_ops_init(struct iris_core *core) { core->hfi_ops = &iris_hfi_gen2_command_ops; @@ -1330,6 +1333,10 @@ struct iris_inst *iris_hfi_gen2_get_instance(void) /* The allocation is intentionally larger than struct iris_inst. */ out = kzalloc_obj(*out); + if (!out) + return NULL; + + out->inst.hfi_session_ops = &iris_hfi_gen2_session_ops; return &out->inst; } diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h index 63dd889c9992a..9fa635e27a28d 100644 --- a/drivers/media/platform/qcom/iris/iris_instance.h +++ b/drivers/media/platform/qcom/iris/iris_instance.h @@ -15,6 +15,8 @@ #define DEFAULT_WIDTH 320 #define DEFAULT_HEIGHT 240 +struct iris_hfi_session_ops; + enum iris_fmt_type_out { IRIS_FMT_H264, IRIS_FMT_HEVC, @@ -38,6 +40,7 @@ struct iris_fmt { * @list: used for attach an instance to the core * @core: pointer to core structure * @session_id: id of current video session + * @hfi_session_ops: iris HFI session ops * @ctx_q_lock: lock to serialize queues related ioctls * @lock: lock to seralise forward and reverse threads * @fh: reference of v4l2 file handler @@ -82,6 +85,7 @@ struct iris_inst { struct list_head list; struct iris_core *core; u32 session_id; + const struct iris_hfi_session_ops *hfi_session_ops; struct mutex ctx_q_lock;/* lock to serialize queues related ioctls */ struct mutex lock; /* lock to serialize forward and reverse threads */ struct v4l2_fh fh; diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c index bf0b8400996ec..a2ea2d67f60d0 100644 --- a/drivers/media/platform/qcom/iris/iris_vb2.c +++ b/drivers/media/platform/qcom/iris/iris_vb2.c @@ -129,7 +129,7 @@ int iris_vb2_queue_setup(struct vb2_queue *q, if (!inst->once_per_session_set) { inst->once_per_session_set = true; - ret = core->hfi_ops->session_open(inst); + ret = inst->hfi_session_ops->session_open(inst); if (ret) { ret = -EINVAL; dev_err(core->dev, "session open failed\n"); diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index 7fb45df37db6a..1d34c7bcf8f8a 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -377,7 +377,7 @@ int iris_vdec_streamon_input(struct iris_inst *inst) int iris_vdec_streamon_output(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; int ret; ret = hfi_ops->session_set_config_params(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); @@ -454,7 +454,7 @@ int iris_vdec_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) int iris_vdec_start_cmd(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; enum iris_inst_sub_state clear_sub_state = 0; struct vb2_queue *dst_vq; int ret; @@ -517,7 +517,7 @@ int iris_vdec_start_cmd(struct iris_inst *inst) int iris_vdec_stop_cmd(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; int ret; ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c index aa27b22704eb9..aeed756ee9cac 100644 --- a/drivers/media/platform/qcom/iris/iris_venc.c +++ b/drivers/media/platform/qcom/iris/iris_venc.c @@ -581,7 +581,7 @@ int iris_venc_qbuf(struct iris_inst *inst, struct vb2_v4l2_buffer *vbuf) int iris_venc_start_cmd(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; enum iris_inst_sub_state clear_sub_state = 0; struct vb2_queue *dst_vq; int ret; @@ -623,7 +623,7 @@ int iris_venc_start_cmd(struct iris_inst *inst) int iris_venc_stop_cmd(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; int ret; ret = hfi_ops->session_drain(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index 8ed6520f5ae3a..bd06a2823cc24 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -224,7 +224,7 @@ int iris_open(struct file *filp) static void iris_session_close(struct iris_inst *inst) { - const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; bool wait_for_response = true; int ret; From b22a60991c843912dde8207ddf15ee8bbfc77ad4 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:06 +0200 Subject: [PATCH 20/41] FROMLIST: media: qcom: iris: merge hfi_response_ops and hfi_command_ops There is little point in having two different structures for HFI-related core ops. Merge both of them into the new iris_hfi_ops structure. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-5-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Reviewed-by: Vikash Garodia Signed-off-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/iris_core.h | 6 ++---- .../media/platform/qcom/iris/iris_hfi_common.c | 6 +++--- .../media/platform/qcom/iris/iris_hfi_common.h | 8 +++----- drivers/media/platform/qcom/iris/iris_hfi_gen1.h | 4 ++-- .../platform/qcom/iris/iris_hfi_gen1_command.c | 8 +++++--- .../platform/qcom/iris/iris_hfi_gen1_response.c | 11 +---------- drivers/media/platform/qcom/iris/iris_hfi_gen2.h | 4 ++-- .../platform/qcom/iris/iris_hfi_gen2_command.c | 8 +++++--- .../platform/qcom/iris/iris_hfi_gen2_response.c | 11 +---------- .../platform/qcom/iris/iris_platform_common.h | 3 +-- .../media/platform/qcom/iris/iris_platform_gen1.c | 6 ++---- .../media/platform/qcom/iris/iris_platform_gen2.c | 15 +++++---------- drivers/media/platform/qcom/iris/iris_probe.c | 3 +-- .../media/platform/qcom/iris/iris_vpu_common.c | 2 +- 14 files changed, 34 insertions(+), 61 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h index c85fd7f292467..5f8668e1a16d7 100644 --- a/drivers/media/platform/qcom/iris/iris_core.h +++ b/drivers/media/platform/qcom/iris/iris_core.h @@ -68,8 +68,7 @@ enum domain_type { * @header_id: id of packet header * @packet_id: id of packet * @power: a structure for clock and bw information - * @hfi_ops: iris hfi command ops - * @hfi_response_ops: iris hfi response ops + * @hfi_sys_ops: iris HFI system ops * @core_init_done: structure of signal completion for system response * @intr_status: interrupt status * @sys_error_handler: a delayed work for handling system fatal error @@ -119,8 +118,7 @@ struct iris_core { u32 header_id; u32 packet_id; struct iris_core_power power; - const struct iris_hfi_command_ops *hfi_ops; - const struct iris_hfi_response_ops *hfi_response_ops; + const struct iris_hfi_sys_ops *hfi_sys_ops; struct completion core_init_done; u32 intr_status; struct delayed_work sys_error_handler; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/media/platform/qcom/iris/iris_hfi_common.c index 621c66593d88d..8769ec61f1176 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c @@ -76,7 +76,7 @@ u32 iris_hfi_get_v4l2_matrix_coefficients(u32 hfi_coefficients) int iris_hfi_core_init(struct iris_core *core) { - const struct iris_hfi_command_ops *hfi_ops = core->hfi_ops; + const struct iris_hfi_sys_ops *hfi_ops = core->hfi_sys_ops; int ret; ret = hfi_ops->sys_init(core); @@ -109,7 +109,7 @@ irqreturn_t iris_hfi_isr_handler(int irq, void *data) iris_vpu_clear_interrupt(core); mutex_unlock(&core->lock); - core->hfi_response_ops->hfi_response_handler(core); + core->hfi_sys_ops->sys_hfi_response_handler(core); if (!iris_vpu_watchdog(core, core->intr_status)) enable_irq(irq); @@ -144,7 +144,7 @@ int iris_hfi_pm_suspend(struct iris_core *core) int iris_hfi_pm_resume(struct iris_core *core) { - const struct iris_hfi_command_ops *ops = core->hfi_ops; + const struct iris_hfi_sys_ops *ops = core->hfi_sys_ops; int ret; ret = iris_vpu_power_on(core); diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h index 18684ada78b21..9aa84a1d8f950 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h @@ -105,11 +105,13 @@ struct iris_hfi_prop_type_handle { int (*handle)(struct iris_inst *inst, u32 plane); }; -struct iris_hfi_command_ops { +struct iris_hfi_sys_ops { int (*sys_init)(struct iris_core *core); int (*sys_image_version)(struct iris_core *core); int (*sys_interframe_powercollapse)(struct iris_core *core); int (*sys_pc_prep)(struct iris_core *core); + + void (*sys_hfi_response_handler)(struct iris_core *core); }; struct iris_hfi_session_ops { @@ -129,10 +131,6 @@ struct iris_hfi_session_ops { int (*session_close)(struct iris_inst *inst); }; -struct iris_hfi_response_ops { - void (*hfi_response_handler)(struct iris_core *core); -}; - struct hfi_subscription_params { u32 bitstream_resolution; u32 crop_offsets[2]; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h index 19b8e9054a757..38e9d262d7df4 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h @@ -9,8 +9,8 @@ struct iris_core; struct iris_inst; -void iris_hfi_gen1_command_ops_init(struct iris_core *core); -void iris_hfi_gen1_response_ops_init(struct iris_core *core); +void iris_hfi_gen1_sys_ops_init(struct iris_core *core); +void iris_hfi_gen1_response_handler(struct iris_core *core); struct iris_inst *iris_hfi_gen1_get_instance(void); #endif diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index a28b0c7ebbadd..26b7feb05d15b 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -1076,16 +1076,18 @@ static const struct iris_hfi_session_ops iris_hfi_gen1_session_ops = { .session_close = iris_hfi_gen1_session_close, }; -static const struct iris_hfi_command_ops iris_hfi_gen1_command_ops = { +static const struct iris_hfi_sys_ops iris_hfi_gen1_sys_ops = { .sys_init = iris_hfi_gen1_sys_init, .sys_image_version = iris_hfi_gen1_sys_image_version, .sys_interframe_powercollapse = iris_hfi_gen1_sys_interframe_powercollapse, .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, + + .sys_hfi_response_handler = iris_hfi_gen1_response_handler, }; -void iris_hfi_gen1_command_ops_init(struct iris_core *core) +void iris_hfi_gen1_sys_ops_init(struct iris_core *core) { - core->hfi_ops = &iris_hfi_gen1_command_ops; + core->hfi_sys_ops = &iris_hfi_gen1_sys_ops; } struct iris_inst *iris_hfi_gen1_get_instance(void) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c index 8e864c239e293..bfd7495bf44f0 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_response.c @@ -688,7 +688,7 @@ static void iris_hfi_gen1_flush_debug_queue(struct iris_core *core, u8 *packet) } } -static void iris_hfi_gen1_response_handler(struct iris_core *core) +void iris_hfi_gen1_response_handler(struct iris_core *core) { memset(core->response_packet, 0, sizeof(struct hfi_pkt_hdr)); while (!iris_hfi_queue_msg_read(core, core->response_packet)) { @@ -698,12 +698,3 @@ static void iris_hfi_gen1_response_handler(struct iris_core *core) iris_hfi_gen1_flush_debug_queue(core, core->response_packet); } - -static const struct iris_hfi_response_ops iris_hfi_gen1_response_ops = { - .hfi_response_handler = iris_hfi_gen1_response_handler, -}; - -void iris_hfi_gen1_response_ops_init(struct iris_core *core) -{ - core->hfi_response_ops = &iris_hfi_gen1_response_ops; -} diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h index b9d3749a10efe..6cc6d9890c128 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h @@ -34,8 +34,8 @@ struct iris_inst_hfi_gen2 { struct hfi_subscription_params dst_subcr_params; }; -void iris_hfi_gen2_command_ops_init(struct iris_core *core); -void iris_hfi_gen2_response_ops_init(struct iris_core *core); +void iris_hfi_gen2_sys_ops_init(struct iris_core *core); +void iris_hfi_gen2_response_handler(struct iris_core *core); struct iris_inst *iris_hfi_gen2_get_instance(void); #endif diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index ffb70fd9499cb..0c98d680bf094 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -1315,16 +1315,18 @@ static const struct iris_hfi_session_ops iris_hfi_gen2_session_ops = { .session_close = iris_hfi_gen2_session_close, }; -static const struct iris_hfi_command_ops iris_hfi_gen2_command_ops = { +static const struct iris_hfi_sys_ops iris_hfi_gen2_sys_ops = { .sys_init = iris_hfi_gen2_sys_init, .sys_image_version = iris_hfi_gen2_sys_image_version, .sys_interframe_powercollapse = iris_hfi_gen2_sys_interframe_powercollapse, .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, + + .sys_hfi_response_handler = iris_hfi_gen2_response_handler, }; -void iris_hfi_gen2_command_ops_init(struct iris_core *core) +void iris_hfi_gen2_sys_ops_init(struct iris_core *core) { - core->hfi_ops = &iris_hfi_gen2_command_ops; + core->hfi_sys_ops = &iris_hfi_gen2_sys_ops; } struct iris_inst *iris_hfi_gen2_get_instance(void) 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 8e19f61bbbf9e..c350d231265e5 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c @@ -977,7 +977,7 @@ static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet) } } -static void iris_hfi_gen2_response_handler(struct iris_core *core) +void iris_hfi_gen2_response_handler(struct iris_core *core) { if (iris_vpu_watchdog(core, core->intr_status)) { struct iris_hfi_packet pkt = {.type = HFI_SYS_ERROR_WD_TIMEOUT}; @@ -997,12 +997,3 @@ static void iris_hfi_gen2_response_handler(struct iris_core *core) iris_hfi_gen2_flush_debug_queue(core, core->response_packet); } - -static const struct iris_hfi_response_ops iris_hfi_gen2_response_ops = { - .hfi_response_handler = iris_hfi_gen2_response_handler, -}; - -void iris_hfi_gen2_response_ops_init(struct iris_core *core) -{ - core->hfi_response_ops = &iris_hfi_gen2_response_ops; -} diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 4b1e27367bc30..35e375ed27ea4 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -213,8 +213,7 @@ enum platform_pm_domain_type { }; struct iris_platform_data { - void (*init_hfi_command_ops)(struct iris_core *core); - void (*init_hfi_response_ops)(struct iris_core *core); + void (*init_hfi_ops)(struct iris_core *core); struct iris_inst *(*get_instance)(void); u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); const struct vpu_ops *vpu_ops; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 546f6c025d547..9eeb500c65d90 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -334,8 +334,7 @@ static const u32 sm8250_enc_ip_int_buf_tbl[] = { const struct iris_platform_data sm8250_data = { .get_instance = iris_hfi_gen1_get_instance, - .init_hfi_command_ops = &iris_hfi_gen1_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, + .init_hfi_ops = &iris_hfi_gen1_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, .icc_tbl = sm8250_icc_table, @@ -387,8 +386,7 @@ const struct iris_platform_data sm8250_data = { const struct iris_platform_data sc7280_data = { .get_instance = iris_hfi_gen1_get_instance, - .init_hfi_command_ops = &iris_hfi_gen1_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, + .init_hfi_ops = &iris_hfi_gen1_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, .icc_tbl = sm8250_icc_table, diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 8e98857f76f99..655098e260740 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -960,8 +960,7 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = { const struct iris_platform_data kaanapali_data = { .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, + .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu4x_buf_size, .vpu_ops = &iris_vpu4x_ops, .icc_tbl = sm8550_icc_table, @@ -1045,8 +1044,7 @@ const struct iris_platform_data kaanapali_data = { const struct iris_platform_data sm8550_data = { .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, + .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, .init_cb_devs = sm8550_init_cb_devs, @@ -1148,8 +1146,7 @@ const struct iris_platform_data sm8550_data = { */ const struct iris_platform_data sm8650_data = { .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, + .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu33_ops, .icc_tbl = sm8550_icc_table, @@ -1244,8 +1241,7 @@ const struct iris_platform_data sm8650_data = { const struct iris_platform_data sm8750_data = { .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, + .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu35_ops, .icc_tbl = sm8550_icc_table, @@ -1342,8 +1338,7 @@ const struct iris_platform_data sm8750_data = { */ const struct iris_platform_data qcs8300_data = { .get_instance = iris_hfi_gen2_get_instance, - .init_hfi_command_ops = iris_hfi_gen2_command_ops_init, - .init_hfi_response_ops = iris_hfi_gen2_response_ops_init, + .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, .icc_tbl = sm8550_icc_table, diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index bfc71c4448f8f..dbc99f6a0ebe8 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -267,8 +267,7 @@ static int iris_probe(struct platform_device *pdev) disable_irq_nosync(core->irq); iris_init_ops(core); - core->iris_platform_data->init_hfi_command_ops(core); - core->iris_platform_data->init_hfi_response_ops(core); + core->iris_platform_data->init_hfi_ops(core); ret = iris_init_resources(core); if (ret) diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index 96e5b305c5f4a..aa0b66954680d 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -149,7 +149,7 @@ int iris_vpu_prepare_pc(struct iris_core *core) if (!wfi_status || !idle_status) goto skip_power_off; - ret = core->hfi_ops->sys_pc_prep(core); + ret = core->hfi_sys_ops->sys_pc_prep(core); if (ret) goto skip_power_off; From 560eafb84d64ff8235f81a4fa2f0d423323a1c4f Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:07 +0200 Subject: [PATCH 21/41] FROMLIST: media: qcom: iris: move get_instance to iris_hfi_sys_ops The get_instance() is a callback tightly connected to the HFI implementation. Move it into the new iris_hfi_sys_ops structure, merging all core callbacks into a single vtable. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-6-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Reviewed-by: Vikash Garodia Signed-off-by: Dmitry Baryshkov --- .../platform/qcom/iris/iris_hfi_common.h | 2 ++ .../media/platform/qcom/iris/iris_hfi_gen1.h | 2 -- .../qcom/iris/iris_hfi_gen1_command.c | 28 +++++++++-------- .../media/platform/qcom/iris/iris_hfi_gen2.h | 1 - .../qcom/iris/iris_hfi_gen2_command.c | 30 ++++++++++--------- .../platform/qcom/iris/iris_platform_common.h | 1 - .../platform/qcom/iris/iris_platform_gen1.c | 2 -- .../platform/qcom/iris/iris_platform_gen2.c | 4 --- drivers/media/platform/qcom/iris/iris_vidc.c | 2 +- 9 files changed, 34 insertions(+), 38 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h index 9aa84a1d8f950..a27447eb25199 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h @@ -112,6 +112,8 @@ struct iris_hfi_sys_ops { int (*sys_pc_prep)(struct iris_core *core); void (*sys_hfi_response_handler)(struct iris_core *core); + + struct iris_inst *(*sys_get_instance)(void); }; struct iris_hfi_session_ops { diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h index 38e9d262d7df4..c37adf65055a5 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h @@ -7,10 +7,8 @@ #define __IRIS_HFI_GEN1_H__ struct iris_core; -struct iris_inst; void iris_hfi_gen1_sys_ops_init(struct iris_core *core); void iris_hfi_gen1_response_handler(struct iris_core *core); -struct iris_inst *iris_hfi_gen1_get_instance(void); #endif diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index 26b7feb05d15b..0017ade4adbd9 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -1076,6 +1076,19 @@ static const struct iris_hfi_session_ops iris_hfi_gen1_session_ops = { .session_close = iris_hfi_gen1_session_close, }; +static struct iris_inst *iris_hfi_gen1_get_instance(void) +{ + struct iris_inst *out; + + out = kzalloc_obj(*out); + if (!out) + return NULL; + + out->hfi_session_ops = &iris_hfi_gen1_session_ops; + + return out; +} + static const struct iris_hfi_sys_ops iris_hfi_gen1_sys_ops = { .sys_init = iris_hfi_gen1_sys_init, .sys_image_version = iris_hfi_gen1_sys_image_version, @@ -1083,22 +1096,11 @@ static const struct iris_hfi_sys_ops iris_hfi_gen1_sys_ops = { .sys_pc_prep = iris_hfi_gen1_sys_pc_prep, .sys_hfi_response_handler = iris_hfi_gen1_response_handler, + + .sys_get_instance = iris_hfi_gen1_get_instance, }; void iris_hfi_gen1_sys_ops_init(struct iris_core *core) { core->hfi_sys_ops = &iris_hfi_gen1_sys_ops; } - -struct iris_inst *iris_hfi_gen1_get_instance(void) -{ - struct iris_inst *out; - - out = kzalloc_obj(*out); - if (!out) - return NULL; - - out->hfi_session_ops = &iris_hfi_gen1_session_ops; - - return out; -} diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h index 6cc6d9890c128..21ab58e0aa840 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h @@ -36,6 +36,5 @@ struct iris_inst_hfi_gen2 { void iris_hfi_gen2_sys_ops_init(struct iris_core *core); void iris_hfi_gen2_response_handler(struct iris_core *core); -struct iris_inst *iris_hfi_gen2_get_instance(void); #endif diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index 0c98d680bf094..639b75fca1abd 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -1315,6 +1315,20 @@ static const struct iris_hfi_session_ops iris_hfi_gen2_session_ops = { .session_close = iris_hfi_gen2_session_close, }; +static struct iris_inst *iris_hfi_gen2_get_instance(void) +{ + struct iris_inst_hfi_gen2 *out; + + /* The allocation is intentionally larger than struct iris_inst. */ + out = kzalloc_obj(*out); + if (!out) + return NULL; + + out->inst.hfi_session_ops = &iris_hfi_gen2_session_ops; + + return &out->inst; +} + static const struct iris_hfi_sys_ops iris_hfi_gen2_sys_ops = { .sys_init = iris_hfi_gen2_sys_init, .sys_image_version = iris_hfi_gen2_sys_image_version, @@ -1322,23 +1336,11 @@ static const struct iris_hfi_sys_ops iris_hfi_gen2_sys_ops = { .sys_pc_prep = iris_hfi_gen2_sys_pc_prep, .sys_hfi_response_handler = iris_hfi_gen2_response_handler, + + .sys_get_instance = iris_hfi_gen2_get_instance, }; void iris_hfi_gen2_sys_ops_init(struct iris_core *core) { core->hfi_sys_ops = &iris_hfi_gen2_sys_ops; } - -struct iris_inst *iris_hfi_gen2_get_instance(void) -{ - struct iris_inst_hfi_gen2 *out; - - /* The allocation is intentionally larger than struct iris_inst. */ - out = kzalloc_obj(*out); - if (!out) - return NULL; - - out->inst.hfi_session_ops = &iris_hfi_gen2_session_ops; - - return &out->inst; -} diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 35e375ed27ea4..5013b6f5ce453 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -214,7 +214,6 @@ enum platform_pm_domain_type { struct iris_platform_data { void (*init_hfi_ops)(struct iris_core *core); - struct iris_inst *(*get_instance)(void); u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); const struct vpu_ops *vpu_ops; void (*set_preset_registers)(struct iris_core *core); diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 9eeb500c65d90..293834d6359b8 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -333,7 +333,6 @@ static const u32 sm8250_enc_ip_int_buf_tbl[] = { }; const struct iris_platform_data sm8250_data = { - .get_instance = iris_hfi_gen1_get_instance, .init_hfi_ops = &iris_hfi_gen1_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, @@ -385,7 +384,6 @@ const struct iris_platform_data sm8250_data = { }; const struct iris_platform_data sc7280_data = { - .get_instance = iris_hfi_gen1_get_instance, .init_hfi_ops = &iris_hfi_gen1_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 655098e260740..856caf46b9dfc 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -1043,7 +1043,6 @@ const struct iris_platform_data kaanapali_data = { }; const struct iris_platform_data sm8550_data = { - .get_instance = iris_hfi_gen2_get_instance, .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, @@ -1145,7 +1144,6 @@ const struct iris_platform_data sm8550_data = { * - fwname to "qcom/vpu/vpu33_p4.mbn" */ const struct iris_platform_data sm8650_data = { - .get_instance = iris_hfi_gen2_get_instance, .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu33_ops, @@ -1240,7 +1238,6 @@ const struct iris_platform_data sm8650_data = { }; const struct iris_platform_data sm8750_data = { - .get_instance = iris_hfi_gen2_get_instance, .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu35_ops, @@ -1337,7 +1334,6 @@ const struct iris_platform_data sm8750_data = { * - inst_caps to platform_inst_cap_qcs8300 */ const struct iris_platform_data qcs8300_data = { - .get_instance = iris_hfi_gen2_get_instance, .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index bd06a2823cc24..a782bba4d80fb 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -156,7 +156,7 @@ int iris_open(struct file *filp) pm_runtime_put_sync(core->dev); - inst = core->iris_platform_data->get_instance(); + inst = core->hfi_sys_ops->sys_get_instance(); if (!inst) return -ENOMEM; From 2c26be0934dd35e1f95c2cd5fad36f915d56cc5a Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:08 +0200 Subject: [PATCH 22/41] FROMLIST: media: qcom: iris: drop hw_response_timeout_val from platform data The HW response time is a constant between platforms. Remove it from the iris_platform_data structure and use it directly. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-7-eea672b03a95@oss.qualcomm.com/ Suggested-by: Vikash Garodia Reviewed-by: Vikash Garodia Reviewed-by: Dikshita Agarwal Signed-off-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/iris_core.c | 3 +-- drivers/media/platform/qcom/iris/iris_platform_common.h | 1 - drivers/media/platform/qcom/iris/iris_platform_gen1.c | 2 -- drivers/media/platform/qcom/iris/iris_platform_gen2.c | 6 ------ drivers/media/platform/qcom/iris/iris_utils.c | 5 +---- 5 files changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c index 7a901a310e757..48a5bd39d836f 100644 --- a/drivers/media/platform/qcom/iris/iris_core.c +++ b/drivers/media/platform/qcom/iris/iris_core.c @@ -29,14 +29,13 @@ void iris_core_deinit(struct iris_core *core) static int iris_wait_for_system_response(struct iris_core *core) { - u32 hw_response_timeout_val = core->iris_platform_data->hw_response_timeout; int ret; if (core->state == IRIS_CORE_ERROR) return -EIO; ret = wait_for_completion_timeout(&core->core_init_done, - msecs_to_jiffies(hw_response_timeout_val)); + msecs_to_jiffies(HW_RESPONSE_TIMEOUT_VALUE)); if (!ret) { core->state = IRIS_CORE_ERROR; return -ETIMEDOUT; diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 5013b6f5ce453..193e249132c53 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -246,7 +246,6 @@ struct iris_platform_data { const struct tz_cp_config *tz_cp_config_data; u32 tz_cp_config_data_size; u32 core_arch; - u32 hw_response_timeout; struct ubwc_config_data *ubwc_config; u32 num_vpp_pipe; bool no_aon; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 293834d6359b8..6592c1ed9ca50 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -361,7 +361,6 @@ const struct iris_platform_data sm8250_data = { .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), .tz_cp_config_data = tz_cp_config_sm8250, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .num_vpp_pipe = 4, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K, @@ -410,7 +409,6 @@ const struct iris_platform_data sc7280_data = { .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), .tz_cp_config_data = tz_cp_config_sm8250, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .num_vpp_pipe = 1, .no_aon = true, .max_session_count = 16, diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 856caf46b9dfc..deaf6248f7f9e 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -959,7 +959,6 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = { }; const struct iris_platform_data kaanapali_data = { - .get_instance = iris_hfi_gen2_get_instance, .init_hfi_ops = iris_hfi_gen2_sys_ops_init, .get_vpu_buffer_size = iris_vpu4x_buf_size, .vpu_ops = &iris_vpu4x_ops, @@ -989,7 +988,6 @@ const struct iris_platform_data kaanapali_data = { .tz_cp_config_data = tz_cp_config_kaanapali, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 2, .max_session_count = 16, @@ -1074,7 +1072,6 @@ const struct iris_platform_data sm8550_data = { .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, @@ -1175,7 +1172,6 @@ const struct iris_platform_data sm8650_data = { .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, @@ -1267,7 +1263,6 @@ const struct iris_platform_data sm8750_data = { .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, @@ -1363,7 +1358,6 @@ const struct iris_platform_data qcs8300_data = { .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), .core_arch = VIDEO_ARCH_LX, - .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 2, .max_session_count = 16, diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c index cfc5b576ec56b..29b07d88507eb 100644 --- a/drivers/media/platform/qcom/iris/iris_utils.c +++ b/drivers/media/platform/qcom/iris/iris_utils.c @@ -55,16 +55,13 @@ void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type, int iris_wait_for_session_response(struct iris_inst *inst, bool is_flush) { - struct iris_core *core = inst->core; - u32 hw_response_timeout_val; struct completion *done; int ret; - hw_response_timeout_val = core->iris_platform_data->hw_response_timeout; done = is_flush ? &inst->flush_completion : &inst->completion; mutex_unlock(&inst->lock); - ret = wait_for_completion_timeout(done, msecs_to_jiffies(hw_response_timeout_val)); + ret = wait_for_completion_timeout(done, msecs_to_jiffies(HW_RESPONSE_TIMEOUT_VALUE)); mutex_lock(&inst->lock); if (!ret) { iris_inst_change_state(inst, IRIS_INST_ERROR); From 74852164e19ea1cdfaa21a667ce19d1664d20429 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:09 +0200 Subject: [PATCH 23/41] FROMLIST: media: qcom: iris: split firmware_data from raw platform data Having firmware-related fields in platform data results in the tying platform data to the HFI firmware data rather than the actual hardware. For example, SM8450 uses Gen2 firmware, so currently its platform data should be placed next to the other gen2 platforms, although it has the VPU2.0 core, similar to the one found on SM8250 and SC7280 and so the hardware-specific platform data is also close to those devices. Split firmware data to a separate struct, separating hardware-related data from the firmware interfaces. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-8-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Signed-off-by: Dmitry Baryshkov --- .../media/platform/qcom/iris/iris_buffer.c | 82 ++--- drivers/media/platform/qcom/iris/iris_core.h | 2 + drivers/media/platform/qcom/iris/iris_ctrls.c | 8 +- .../qcom/iris/iris_hfi_gen1_command.c | 8 +- .../qcom/iris/iris_hfi_gen2_command.c | 66 ++-- .../platform/qcom/iris/iris_platform_common.h | 89 +++-- .../platform/qcom/iris/iris_platform_gen1.c | 67 ++-- .../platform/qcom/iris/iris_platform_gen2.c | 320 +++--------------- drivers/media/platform/qcom/iris/iris_probe.c | 3 +- drivers/media/platform/qcom/iris/iris_vidc.c | 10 +- .../platform/qcom/iris/iris_vpu_common.c | 2 +- 11 files changed, 221 insertions(+), 436 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index 8c40207f12c76..b10236cd2a58f 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -301,31 +301,31 @@ static void iris_fill_internal_buf_info(struct iris_inst *inst, void iris_get_internal_buffers(struct iris_inst *inst, u32 plane) { - const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data; const u32 *internal_buf_type; u32 internal_buffer_count, i; if (inst->domain == DECODER) { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->dec_ip_int_buf_tbl; - internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_ip_int_buf_tbl; + internal_buffer_count = firmware_data->dec_ip_int_buf_tbl_size; for (i = 0; i < internal_buffer_count; i++) iris_fill_internal_buf_info(inst, internal_buf_type[i]); } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_op_int_buf_tbl; + internal_buffer_count = firmware_data->dec_op_int_buf_tbl_size; for (i = 0; i < internal_buffer_count; i++) iris_fill_internal_buf_info(inst, internal_buf_type[i]); } } else { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->enc_ip_int_buf_tbl; - internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_ip_int_buf_tbl; + internal_buffer_count = firmware_data->enc_ip_int_buf_tbl_size; for (i = 0; i < internal_buffer_count; i++) iris_fill_internal_buf_info(inst, internal_buf_type[i]); } else { - internal_buf_type = platform_data->enc_op_int_buf_tbl; - internal_buffer_count = platform_data->enc_op_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_op_int_buf_tbl; + internal_buffer_count = firmware_data->enc_op_int_buf_tbl_size; for (i = 0; i < internal_buffer_count; i++) iris_fill_internal_buf_info(inst, internal_buf_type[i]); } @@ -366,7 +366,7 @@ static int iris_create_internal_buffer(struct iris_inst *inst, int iris_create_internal_buffers(struct iris_inst *inst, u32 plane) { - const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data; u32 internal_buffer_count, i, j; struct iris_buffers *buffers; const u32 *internal_buf_type; @@ -374,19 +374,19 @@ int iris_create_internal_buffers(struct iris_inst *inst, u32 plane) if (inst->domain == DECODER) { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->dec_ip_int_buf_tbl; - internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_ip_int_buf_tbl; + internal_buffer_count = firmware_data->dec_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_op_int_buf_tbl; + internal_buffer_count = firmware_data->dec_op_int_buf_tbl_size; } } else { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->enc_ip_int_buf_tbl; - internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_ip_int_buf_tbl; + internal_buffer_count = firmware_data->enc_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->enc_op_int_buf_tbl; - internal_buffer_count = platform_data->enc_op_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_op_int_buf_tbl; + internal_buffer_count = firmware_data->enc_op_int_buf_tbl_size; } } @@ -442,7 +442,7 @@ int iris_queue_internal_deferred_buffers(struct iris_inst *inst, enum iris_buffe int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) { - const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data; struct iris_buffer *buffer, *next; struct iris_buffers *buffers; const u32 *internal_buf_type; @@ -451,19 +451,19 @@ int iris_queue_internal_buffers(struct iris_inst *inst, u32 plane) if (inst->domain == DECODER) { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->dec_ip_int_buf_tbl; - internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_ip_int_buf_tbl; + internal_buffer_count = firmware_data->dec_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_op_int_buf_tbl; + internal_buffer_count = firmware_data->dec_op_int_buf_tbl_size; } } else { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->enc_ip_int_buf_tbl; - internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_ip_int_buf_tbl; + internal_buffer_count = firmware_data->enc_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->enc_op_int_buf_tbl; - internal_buffer_count = platform_data->enc_op_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_op_int_buf_tbl; + internal_buffer_count = firmware_data->enc_op_int_buf_tbl_size; } } @@ -501,7 +501,7 @@ int iris_destroy_internal_buffer(struct iris_inst *inst, struct iris_buffer *buf static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool force) { - const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data; struct iris_buffer *buf, *next; struct iris_buffers *buffers; const u32 *internal_buf_type; @@ -510,19 +510,19 @@ static int iris_destroy_internal_buffers(struct iris_inst *inst, u32 plane, bool if (inst->domain == DECODER) { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->dec_ip_int_buf_tbl; - len = platform_data->dec_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_ip_int_buf_tbl; + len = firmware_data->dec_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - len = platform_data->dec_op_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_op_int_buf_tbl; + len = firmware_data->dec_op_int_buf_tbl_size; } } else { if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->enc_ip_int_buf_tbl; - len = platform_data->enc_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_ip_int_buf_tbl; + len = firmware_data->enc_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->enc_op_int_buf_tbl; - len = platform_data->enc_op_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_op_int_buf_tbl; + len = firmware_data->enc_op_int_buf_tbl_size; } } @@ -593,17 +593,17 @@ static int iris_release_internal_buffers(struct iris_inst *inst, static int iris_release_input_internal_buffers(struct iris_inst *inst) { - const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data; const u32 *internal_buf_type; u32 internal_buffer_count, i; int ret; if (inst->domain == DECODER) { - internal_buf_type = platform_data->dec_ip_int_buf_tbl; - internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_ip_int_buf_tbl; + internal_buffer_count = firmware_data->dec_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->enc_ip_int_buf_tbl; - internal_buffer_count = platform_data->enc_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->enc_ip_int_buf_tbl; + internal_buffer_count = firmware_data->enc_ip_int_buf_tbl_size; } for (i = 0; i < internal_buffer_count; i++) { diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h index 5f8668e1a16d7..7d128e7724ed1 100644 --- a/drivers/media/platform/qcom/iris/iris_core.h +++ b/drivers/media/platform/qcom/iris/iris_core.h @@ -55,6 +55,7 @@ enum domain_type { * @resets: table of iris reset clocks * @controller_resets: table of controller reset clocks * @iris_platform_data: a structure for platform data + * @iris_firmware_data: a pointer to the firmware (or HFI) specific data * @state: current state of core * @iface_q_table_daddr: device address for interface queue table memory * @sfr_daddr: device address for SFR (Sub System Failure Reason) register memory @@ -105,6 +106,7 @@ struct iris_core { struct reset_control_bulk_data *resets; struct reset_control_bulk_data *controller_resets; const struct iris_platform_data *iris_platform_data; + const struct iris_firmware_data *iris_firmware_data; enum iris_core_state state; dma_addr_t iface_q_table_daddr; dma_addr_t sfr_daddr; diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c index 5a24aa869b2dc..ef7adac3764d7 100644 --- a/drivers/media/platform/qcom/iris/iris_ctrls.c +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c @@ -332,8 +332,8 @@ void iris_session_init_caps(struct iris_core *core) const struct platform_inst_fw_cap *caps; u32 i, num_cap, cap_id; - caps = core->iris_platform_data->inst_fw_caps_dec; - num_cap = core->iris_platform_data->inst_fw_caps_dec_size; + caps = core->iris_firmware_data->inst_fw_caps_dec; + num_cap = core->iris_firmware_data->inst_fw_caps_dec_size; for (i = 0; i < num_cap; i++) { cap_id = caps[i].cap_id; @@ -360,8 +360,8 @@ void iris_session_init_caps(struct iris_core *core) } } - caps = core->iris_platform_data->inst_fw_caps_enc; - num_cap = core->iris_platform_data->inst_fw_caps_enc_size; + caps = core->iris_firmware_data->inst_fw_caps_enc; + num_cap = core->iris_firmware_data->inst_fw_caps_enc_size; for (i = 0; i < num_cap; i++) { cap_id = caps[i].cap_id; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index 0017ade4adbd9..3fb90a466a64e 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -1033,8 +1033,8 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p }; if (inst->domain == DECODER) { - config_params = core->iris_platform_data->dec_input_config_params_default; - config_params_size = core->iris_platform_data->dec_input_config_params_default_size; + config_params = core->iris_firmware_data->dec_input_config_params_default; + config_params_size = core->iris_firmware_data->dec_input_config_params_default_size; if (V4L2_TYPE_IS_OUTPUT(plane)) { handler = vdec_prop_type_handle_inp_arr; handler_size = ARRAY_SIZE(vdec_prop_type_handle_inp_arr); @@ -1043,8 +1043,8 @@ static int iris_hfi_gen1_session_set_config_params(struct iris_inst *inst, u32 p handler_size = ARRAY_SIZE(vdec_prop_type_handle_out_arr); } } else { - config_params = core->iris_platform_data->enc_input_config_params; - config_params_size = core->iris_platform_data->enc_input_config_params_size; + config_params = core->iris_firmware_data->enc_input_config_params; + config_params_size = core->iris_firmware_data->enc_input_config_params_size; handler = venc_prop_type_handle_inp_arr; handler_size = ARRAY_SIZE(venc_prop_type_handle_inp_arr); } diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index 639b75fca1abd..c90b22a75bc56 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -601,7 +601,7 @@ static int iris_hfi_gen2_set_super_block(struct iris_inst *inst, u32 plane) static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 plane) { - const struct iris_platform_data *pdata = inst->core->iris_platform_data; + const struct iris_firmware_data *fdata = inst->core->iris_firmware_data; u32 config_params_size = 0, i, j; const u32 *config_params = NULL; int ret; @@ -630,31 +630,31 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p if (inst->domain == DECODER) { if (V4L2_TYPE_IS_OUTPUT(plane)) { if (inst->codec == V4L2_PIX_FMT_H264) { - config_params = pdata->dec_input_config_params_default; - config_params_size = pdata->dec_input_config_params_default_size; + config_params = fdata->dec_input_config_params_default; + config_params_size = fdata->dec_input_config_params_default_size; } else if (inst->codec == V4L2_PIX_FMT_HEVC) { - config_params = pdata->dec_input_config_params_hevc; - config_params_size = pdata->dec_input_config_params_hevc_size; + config_params = fdata->dec_input_config_params_hevc; + config_params_size = fdata->dec_input_config_params_hevc_size; } else if (inst->codec == V4L2_PIX_FMT_VP9) { - config_params = pdata->dec_input_config_params_vp9; - config_params_size = pdata->dec_input_config_params_vp9_size; + config_params = fdata->dec_input_config_params_vp9; + config_params_size = fdata->dec_input_config_params_vp9_size; } else if (inst->codec == V4L2_PIX_FMT_AV1) { - config_params = pdata->dec_input_config_params_av1; - config_params_size = pdata->dec_input_config_params_av1_size; + config_params = fdata->dec_input_config_params_av1; + config_params_size = fdata->dec_input_config_params_av1_size; } else { return -EINVAL; } } else { - config_params = pdata->dec_output_config_params; - config_params_size = pdata->dec_output_config_params_size; + config_params = fdata->dec_output_config_params; + config_params_size = fdata->dec_output_config_params_size; } } else { if (V4L2_TYPE_IS_OUTPUT(plane)) { - config_params = pdata->enc_input_config_params; - config_params_size = pdata->enc_input_config_params_size; + config_params = fdata->enc_input_config_params; + config_params_size = fdata->enc_input_config_params_size; } else { - config_params = pdata->enc_output_config_params; - config_params_size = pdata->enc_output_config_params_size; + config_params = fdata->enc_output_config_params; + config_params_size = fdata->enc_output_config_params_size; } } @@ -849,24 +849,24 @@ static int iris_hfi_gen2_subscribe_change_param(struct iris_inst *inst, u32 plan switch (inst->codec) { case V4L2_PIX_FMT_H264: - change_param = core->iris_platform_data->dec_input_config_params_default; + change_param = core->iris_firmware_data->dec_input_config_params_default; change_param_size = - core->iris_platform_data->dec_input_config_params_default_size; + core->iris_firmware_data->dec_input_config_params_default_size; break; case V4L2_PIX_FMT_HEVC: - change_param = core->iris_platform_data->dec_input_config_params_hevc; + change_param = core->iris_firmware_data->dec_input_config_params_hevc; change_param_size = - core->iris_platform_data->dec_input_config_params_hevc_size; + core->iris_firmware_data->dec_input_config_params_hevc_size; break; case V4L2_PIX_FMT_VP9: - change_param = core->iris_platform_data->dec_input_config_params_vp9; + change_param = core->iris_firmware_data->dec_input_config_params_vp9; change_param_size = - core->iris_platform_data->dec_input_config_params_vp9_size; + core->iris_firmware_data->dec_input_config_params_vp9_size; break; case V4L2_PIX_FMT_AV1: - change_param = core->iris_platform_data->dec_input_config_params_av1; + change_param = core->iris_firmware_data->dec_input_config_params_av1; change_param_size = - core->iris_platform_data->dec_input_config_params_av1_size; + core->iris_firmware_data->dec_input_config_params_av1_size; break; } @@ -996,29 +996,29 @@ static int iris_hfi_gen2_subscribe_property(struct iris_inst *inst, u32 plane) return 0; if (V4L2_TYPE_IS_OUTPUT(plane)) { - subscribe_prop_size = core->iris_platform_data->dec_input_prop_size; - subcribe_prop = core->iris_platform_data->dec_input_prop; + subscribe_prop_size = core->iris_firmware_data->dec_input_prop_size; + subcribe_prop = core->iris_firmware_data->dec_input_prop; } else { switch (inst->codec) { case V4L2_PIX_FMT_H264: - subcribe_prop = core->iris_platform_data->dec_output_prop_avc; + subcribe_prop = core->iris_firmware_data->dec_output_prop_avc; subscribe_prop_size = - core->iris_platform_data->dec_output_prop_avc_size; + core->iris_firmware_data->dec_output_prop_avc_size; break; case V4L2_PIX_FMT_HEVC: - subcribe_prop = core->iris_platform_data->dec_output_prop_hevc; + subcribe_prop = core->iris_firmware_data->dec_output_prop_hevc; subscribe_prop_size = - core->iris_platform_data->dec_output_prop_hevc_size; + core->iris_firmware_data->dec_output_prop_hevc_size; break; case V4L2_PIX_FMT_VP9: - subcribe_prop = core->iris_platform_data->dec_output_prop_vp9; + subcribe_prop = core->iris_firmware_data->dec_output_prop_vp9; subscribe_prop_size = - core->iris_platform_data->dec_output_prop_vp9_size; + core->iris_firmware_data->dec_output_prop_vp9_size; break; case V4L2_PIX_FMT_AV1: - subcribe_prop = core->iris_platform_data->dec_output_prop_av1; + subcribe_prop = core->iris_firmware_data->dec_output_prop_av1; subscribe_prop_size = - core->iris_platform_data->dec_output_prop_av1_size; + core->iris_firmware_data->dec_output_prop_av1_size; break; } } diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 193e249132c53..4dd17aed12606 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -212,48 +212,16 @@ enum platform_pm_domain_type { IRIS_APV_HW_POWER_DOMAIN, }; -struct iris_platform_data { +struct iris_firmware_data { void (*init_hfi_ops)(struct iris_core *core); - u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); - const struct vpu_ops *vpu_ops; - void (*set_preset_registers)(struct iris_core *core); - int (*init_cb_devs)(struct iris_core *core); - void (*deinit_cb_devs)(struct iris_core *core); - const struct icc_info *icc_tbl; - unsigned int icc_tbl_size; - const struct bw_info *bw_tbl_dec; - unsigned int bw_tbl_dec_size; - const char * const *pmdomain_tbl; - unsigned int pmdomain_tbl_size; - const char * const *opp_pd_tbl; - unsigned int opp_pd_tbl_size; - const struct platform_clk_data *clk_tbl; - const char * const *opp_clk_tbl; - unsigned int clk_tbl_size; - const char * const *clk_rst_tbl; - unsigned int clk_rst_tbl_size; - const char * const *controller_rst_tbl; - unsigned int controller_rst_tbl_size; - u64 dma_mask; - const char *fwname; - struct iris_fmt *inst_iris_fmts; - u32 inst_iris_fmts_size; - struct platform_inst_caps *inst_caps; + + u32 core_arch; + const struct platform_inst_fw_cap *inst_fw_caps_dec; u32 inst_fw_caps_dec_size; const struct platform_inst_fw_cap *inst_fw_caps_enc; u32 inst_fw_caps_enc_size; - const struct tz_cp_config *tz_cp_config_data; - u32 tz_cp_config_data_size; - u32 core_arch; - struct ubwc_config_data *ubwc_config; - u32 num_vpp_pipe; - bool no_aon; - u32 max_session_count; - /* max number of macroblocks per frame supported */ - u32 max_core_mbpf; - /* max number of macroblocks per second supported */ - u32 max_core_mbps; + const u32 *dec_input_config_params_default; unsigned int dec_input_config_params_default_size; const u32 *dec_input_config_params_hevc; @@ -268,6 +236,7 @@ struct iris_platform_data { unsigned int enc_input_config_params_size; const u32 *enc_output_config_params; unsigned int enc_output_config_params_size; + const u32 *dec_input_prop; unsigned int dec_input_prop_size; const u32 *dec_output_prop_avc; @@ -278,6 +247,7 @@ struct iris_platform_data { unsigned int dec_output_prop_vp9_size; const u32 *dec_output_prop_av1; unsigned int dec_output_prop_av1_size; + const u32 *dec_ip_int_buf_tbl; unsigned int dec_ip_int_buf_tbl_size; const u32 *dec_op_int_buf_tbl; @@ -288,4 +258,49 @@ struct iris_platform_data { unsigned int enc_op_int_buf_tbl_size; }; +struct iris_platform_data { + /* + * XXX: remove firmware_data pointer and consider moving + * get_vpu_buffer_size pointer once we have platforms supporting both + * firmware kinds. + */ + const struct iris_firmware_data *firmware_data; + u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); + + const struct vpu_ops *vpu_ops; + void (*set_preset_registers)(struct iris_core *core); + int (*init_cb_devs)(struct iris_core *core); + void (*deinit_cb_devs)(struct iris_core *core); + const struct icc_info *icc_tbl; + unsigned int icc_tbl_size; + const struct bw_info *bw_tbl_dec; + unsigned int bw_tbl_dec_size; + const char * const *pmdomain_tbl; + unsigned int pmdomain_tbl_size; + const char * const *opp_pd_tbl; + unsigned int opp_pd_tbl_size; + const struct platform_clk_data *clk_tbl; + const char * const *opp_clk_tbl; + unsigned int clk_tbl_size; + const char * const *clk_rst_tbl; + unsigned int clk_rst_tbl_size; + const char * const *controller_rst_tbl; + unsigned int controller_rst_tbl_size; + u64 dma_mask; + const char *fwname; + struct iris_fmt *inst_iris_fmts; + u32 inst_iris_fmts_size; + struct platform_inst_caps *inst_caps; + const struct tz_cp_config *tz_cp_config_data; + u32 tz_cp_config_data_size; + struct ubwc_config_data *ubwc_config; + u32 num_vpp_pipe; + bool no_aon; + u32 max_session_count; + /* max number of macroblocks per frame supported */ + u32 max_core_mbpf; + /* max number of macroblocks per second supported */ + u32 max_core_mbps; +}; + #endif diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 6592c1ed9ca50..9e632a973f476 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -332,8 +332,33 @@ static const u32 sm8250_enc_ip_int_buf_tbl[] = { BUF_SCRATCH_2, }; -const struct iris_platform_data sm8250_data = { +const struct iris_firmware_data iris_hfi_gen1_data = { .init_hfi_ops = &iris_hfi_gen1_sys_ops_init, + + .inst_fw_caps_dec = inst_fw_cap_sm8250_dec, + .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), + .inst_fw_caps_enc = inst_fw_cap_sm8250_enc, + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), + + .dec_input_config_params_default = + sm8250_vdec_input_config_param_default, + .dec_input_config_params_default_size = + ARRAY_SIZE(sm8250_vdec_input_config_param_default), + .enc_input_config_params = sm8250_venc_input_config_param, + .enc_input_config_params_size = + ARRAY_SIZE(sm8250_venc_input_config_param), + + .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl, + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl), + .dec_op_int_buf_tbl = sm8250_dec_op_int_buf_tbl, + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_op_int_buf_tbl), + + .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl, + .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl), +}; + +const struct iris_platform_data sm8250_data = { + .firmware_data = &iris_hfi_gen1_data, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, .icc_tbl = sm8250_icc_table, @@ -355,35 +380,16 @@ const struct iris_platform_data sm8250_data = { .inst_iris_fmts = platform_fmts_sm8250_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), .inst_caps = &platform_inst_cap_sm8250, - .inst_fw_caps_dec = inst_fw_cap_sm8250_dec, - .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), - .inst_fw_caps_enc = inst_fw_cap_sm8250_enc, - .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), .tz_cp_config_data = tz_cp_config_sm8250, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), .num_vpp_pipe = 4, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K, .max_core_mbps = ((7680 * 4320) / 256) * 60, - .dec_input_config_params_default = - sm8250_vdec_input_config_param_default, - .dec_input_config_params_default_size = - ARRAY_SIZE(sm8250_vdec_input_config_param_default), - .enc_input_config_params = sm8250_venc_input_config_param, - .enc_input_config_params_size = - ARRAY_SIZE(sm8250_venc_input_config_param), - - .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl, - .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl), - .dec_op_int_buf_tbl = sm8250_dec_op_int_buf_tbl, - .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_op_int_buf_tbl), - - .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl, - .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl), }; const struct iris_platform_data sc7280_data = { - .init_hfi_ops = &iris_hfi_gen1_sys_ops_init, + .firmware_data = &iris_hfi_gen1_data, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu2_ops, .icc_tbl = sm8250_icc_table, @@ -403,10 +409,6 @@ const struct iris_platform_data sc7280_data = { .inst_iris_fmts = platform_fmts_sm8250_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), .inst_caps = &platform_inst_cap_sm8250, - .inst_fw_caps_dec = inst_fw_cap_sm8250_dec, - .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), - .inst_fw_caps_enc = inst_fw_cap_sm8250_enc, - .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), .tz_cp_config_data = tz_cp_config_sm8250, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), .num_vpp_pipe = 1, @@ -415,19 +417,4 @@ const struct iris_platform_data sc7280_data = { .max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256, /* max spec for SC7280 is 4096x2176@60fps */ .max_core_mbps = 4096 * 2176 / 256 * 60, - .dec_input_config_params_default = - sm8250_vdec_input_config_param_default, - .dec_input_config_params_default_size = - ARRAY_SIZE(sm8250_vdec_input_config_param_default), - .enc_input_config_params = sm8250_venc_input_config_param, - .enc_input_config_params_size = - ARRAY_SIZE(sm8250_venc_input_config_param), - - .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl, - .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl), - .dec_op_int_buf_tbl = sm8250_dec_op_int_buf_tbl, - .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_op_int_buf_tbl), - - .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl, - .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl), }; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index deaf6248f7f9e..b83a2af4cb7d4 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -958,41 +958,16 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = { BUF_SCRATCH_2, }; -const struct iris_platform_data kaanapali_data = { +const struct iris_firmware_data iris_hfi_gen2_data = { .init_hfi_ops = iris_hfi_gen2_sys_ops_init, - .get_vpu_buffer_size = iris_vpu4x_buf_size, - .vpu_ops = &iris_vpu4x_ops, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = kaanapali_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(kaanapali_clk_reset_table), - .bw_tbl_dec = sm8550_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), - .pmdomain_tbl = kaanapali_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(kaanapali_pmdomain_table), - .opp_pd_tbl = sm8550_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), - .clk_tbl = kaanapali_clk_table, - .clk_tbl_size = ARRAY_SIZE(kaanapali_clk_table), - .opp_clk_tbl = kaanapali_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu40_p2_s7.mbn", - .inst_iris_fmts = platform_fmts_sm8550_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), - .inst_caps = &platform_inst_cap_sm8550, + + .core_arch = VIDEO_ARCH_LX, + .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), - .tz_cp_config_data = tz_cp_config_kaanapali, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), - .core_arch = VIDEO_ARCH_LX, - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 2, - .max_session_count = 16, - .max_core_mbpf = NUM_MBS_8K * 2, - .max_core_mbps = ((8192 * 4352) / 256) * 60, + .dec_input_config_params_default = sm8550_vdec_input_config_params_default, .dec_input_config_params_default_size = @@ -1005,6 +980,10 @@ const struct iris_platform_data kaanapali_data = { sm8550_vdec_input_config_param_vp9, .dec_input_config_params_vp9_size = ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_input_config_params_av1 = + sm8550_vdec_input_config_param_av1, + .dec_input_config_params_av1_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_av1), .dec_output_config_params = sm8550_vdec_output_config_params, .dec_output_config_params_size = @@ -1030,18 +1009,55 @@ const struct iris_platform_data kaanapali_data = { .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, .dec_output_prop_vp9_size = ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, + .dec_output_prop_av1_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), + .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl, + .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl), .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; +const struct iris_platform_data kaanapali_data = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu4x_buf_size, + .vpu_ops = &iris_vpu4x_ops, + .icc_tbl = sm8550_icc_table, + .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), + .clk_rst_tbl = kaanapali_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(kaanapali_clk_reset_table), + .bw_tbl_dec = sm8550_bw_table_dec, + .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), + .pmdomain_tbl = kaanapali_pmdomain_table, + .pmdomain_tbl_size = ARRAY_SIZE(kaanapali_pmdomain_table), + .opp_pd_tbl = sm8550_opp_pd_table, + .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), + .clk_tbl = kaanapali_clk_table, + .clk_tbl_size = ARRAY_SIZE(kaanapali_clk_table), + .opp_clk_tbl = kaanapali_opp_clk_table, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu40_p2_s7.mbn", + .inst_iris_fmts = platform_fmts_sm8550_dec, + .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), + .inst_caps = &platform_inst_cap_sm8550, + .tz_cp_config_data = tz_cp_config_kaanapali, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), + .ubwc_config = &ubwc_config_sm8550, + .num_vpp_pipe = 2, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((8192 * 4352) / 256) * 60, +}; + const struct iris_platform_data sm8550_data = { - .init_hfi_ops = iris_hfi_gen2_sys_ops_init, + .firmware_data = &iris_hfi_gen2_data, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, .init_cb_devs = sm8550_init_cb_devs, @@ -1065,72 +1081,13 @@ const struct iris_platform_data sm8550_data = { .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_sm8550, - .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, - .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), - .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, - .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .core_arch = VIDEO_ARCH_LX, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, - .dec_input_config_params_default = - sm8550_vdec_input_config_params_default, - .dec_input_config_params_default_size = - ARRAY_SIZE(sm8550_vdec_input_config_params_default), - .dec_input_config_params_hevc = - sm8550_vdec_input_config_param_hevc, - .dec_input_config_params_hevc_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), - .dec_input_config_params_vp9 = - sm8550_vdec_input_config_param_vp9, - .dec_input_config_params_vp9_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), - .dec_input_config_params_av1 = - sm8550_vdec_input_config_param_av1, - .dec_input_config_params_av1_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_av1), - .dec_output_config_params = - sm8550_vdec_output_config_params, - .dec_output_config_params_size = - ARRAY_SIZE(sm8550_vdec_output_config_params), - - .enc_input_config_params = - sm8550_venc_input_config_params, - .enc_input_config_params_size = - ARRAY_SIZE(sm8550_venc_input_config_params), - .enc_output_config_params = - sm8550_venc_output_config_params, - .enc_output_config_params_size = - ARRAY_SIZE(sm8550_venc_output_config_params), - - .dec_input_prop = sm8550_vdec_subscribe_input_properties, - .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, - .dec_output_prop_avc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), - .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, - .dec_output_prop_hevc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), - .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, - .dec_output_prop_vp9_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), - .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, - .dec_output_prop_av1_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), - - .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, - .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), - .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, - .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), - - .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl, - .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl), - .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, - .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; /* @@ -1141,7 +1098,7 @@ const struct iris_platform_data sm8550_data = { * - fwname to "qcom/vpu/vpu33_p4.mbn" */ const struct iris_platform_data sm8650_data = { - .init_hfi_ops = iris_hfi_gen2_sys_ops_init, + .firmware_data = &iris_hfi_gen2_data, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu33_ops, .icc_tbl = sm8550_icc_table, @@ -1165,76 +1122,17 @@ const struct iris_platform_data sm8650_data = { .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_sm8550, - .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, - .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), - .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, - .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .core_arch = VIDEO_ARCH_LX, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, - .dec_input_config_params_default = - sm8550_vdec_input_config_params_default, - .dec_input_config_params_default_size = - ARRAY_SIZE(sm8550_vdec_input_config_params_default), - .dec_input_config_params_hevc = - sm8550_vdec_input_config_param_hevc, - .dec_input_config_params_hevc_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), - .dec_input_config_params_vp9 = - sm8550_vdec_input_config_param_vp9, - .dec_input_config_params_vp9_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), - .dec_input_config_params_av1 = - sm8550_vdec_input_config_param_av1, - .dec_input_config_params_av1_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_av1), - .dec_output_config_params = - sm8550_vdec_output_config_params, - .dec_output_config_params_size = - ARRAY_SIZE(sm8550_vdec_output_config_params), - - .enc_input_config_params = - sm8550_venc_input_config_params, - .enc_input_config_params_size = - ARRAY_SIZE(sm8550_venc_input_config_params), - .enc_output_config_params = - sm8550_venc_output_config_params, - .enc_output_config_params_size = - ARRAY_SIZE(sm8550_venc_output_config_params), - - .dec_input_prop = sm8550_vdec_subscribe_input_properties, - .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, - .dec_output_prop_avc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), - .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, - .dec_output_prop_hevc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), - .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, - .dec_output_prop_vp9_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), - .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, - .dec_output_prop_av1_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), - - .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, - .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), - .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, - .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), - - .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl, - .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl), - .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, - .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; const struct iris_platform_data sm8750_data = { - .init_hfi_ops = iris_hfi_gen2_sys_ops_init, + .firmware_data = &iris_hfi_gen2_data, .get_vpu_buffer_size = iris_vpu33_buf_size, .vpu_ops = &iris_vpu35_ops, .icc_tbl = sm8550_icc_table, @@ -1256,72 +1154,13 @@ const struct iris_platform_data sm8750_data = { .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_sm8550, - .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, - .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), - .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, - .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .core_arch = VIDEO_ARCH_LX, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 4, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, - .dec_input_config_params_default = - sm8550_vdec_input_config_params_default, - .dec_input_config_params_default_size = - ARRAY_SIZE(sm8550_vdec_input_config_params_default), - .dec_input_config_params_hevc = - sm8550_vdec_input_config_param_hevc, - .dec_input_config_params_hevc_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), - .dec_input_config_params_vp9 = - sm8550_vdec_input_config_param_vp9, - .dec_input_config_params_vp9_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), - .dec_input_config_params_av1 = - sm8550_vdec_input_config_param_av1, - .dec_input_config_params_av1_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_av1), - .dec_output_config_params = - sm8550_vdec_output_config_params, - .dec_output_config_params_size = - ARRAY_SIZE(sm8550_vdec_output_config_params), - - .enc_input_config_params = - sm8550_venc_input_config_params, - .enc_input_config_params_size = - ARRAY_SIZE(sm8550_venc_input_config_params), - .enc_output_config_params = - sm8550_venc_output_config_params, - .enc_output_config_params_size = - ARRAY_SIZE(sm8550_venc_output_config_params), - - .dec_input_prop = sm8550_vdec_subscribe_input_properties, - .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, - .dec_output_prop_avc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), - .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, - .dec_output_prop_hevc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), - .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, - .dec_output_prop_vp9_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), - .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, - .dec_output_prop_av1_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), - - .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, - .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), - .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, - .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), - - .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl, - .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl), - .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, - .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; /* @@ -1329,7 +1168,7 @@ const struct iris_platform_data sm8750_data = { * - inst_caps to platform_inst_cap_qcs8300 */ const struct iris_platform_data qcs8300_data = { - .init_hfi_ops = iris_hfi_gen2_sys_ops_init, + .firmware_data = &iris_hfi_gen2_data, .get_vpu_buffer_size = iris_vpu_buf_size, .vpu_ops = &iris_vpu3_ops, .icc_tbl = sm8550_icc_table, @@ -1351,70 +1190,11 @@ const struct iris_platform_data qcs8300_data = { .inst_iris_fmts = platform_fmts_sm8550_dec, .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), .inst_caps = &platform_inst_cap_qcs8300, - .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, - .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), - .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, - .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), .tz_cp_config_data = tz_cp_config_sm8550, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .core_arch = VIDEO_ARCH_LX, .ubwc_config = &ubwc_config_sm8550, .num_vpp_pipe = 2, .max_session_count = 16, .max_core_mbpf = ((4096 * 2176) / 256) * 4, .max_core_mbps = (((3840 * 2176) / 256) * 120), - .dec_input_config_params_default = - sm8550_vdec_input_config_params_default, - .dec_input_config_params_default_size = - ARRAY_SIZE(sm8550_vdec_input_config_params_default), - .dec_input_config_params_hevc = - sm8550_vdec_input_config_param_hevc, - .dec_input_config_params_hevc_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), - .dec_input_config_params_vp9 = - sm8550_vdec_input_config_param_vp9, - .dec_input_config_params_vp9_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), - .dec_input_config_params_av1 = - sm8550_vdec_input_config_param_av1, - .dec_input_config_params_av1_size = - ARRAY_SIZE(sm8550_vdec_input_config_param_av1), - .dec_output_config_params = - sm8550_vdec_output_config_params, - .dec_output_config_params_size = - ARRAY_SIZE(sm8550_vdec_output_config_params), - - .enc_input_config_params = - sm8550_venc_input_config_params, - .enc_input_config_params_size = - ARRAY_SIZE(sm8550_venc_input_config_params), - .enc_output_config_params = - sm8550_venc_output_config_params, - .enc_output_config_params_size = - ARRAY_SIZE(sm8550_venc_output_config_params), - - .dec_input_prop = sm8550_vdec_subscribe_input_properties, - .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), - .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, - .dec_output_prop_avc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), - .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, - .dec_output_prop_hevc_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), - .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, - .dec_output_prop_vp9_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), - .dec_output_prop_av1 = sm8550_vdec_subscribe_output_properties_av1, - .dec_output_prop_av1_size = - ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_av1), - - .dec_ip_int_buf_tbl = sm8550_dec_ip_int_buf_tbl, - .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_ip_int_buf_tbl), - .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, - .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), - - .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl, - .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl), - .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, - .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index dbc99f6a0ebe8..62725cfdb7a9f 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -258,6 +258,7 @@ static int iris_probe(struct platform_device *pdev) return core->irq; core->iris_platform_data = of_device_get_match_data(core->dev); + core->iris_firmware_data = core->iris_platform_data->firmware_data; ret = devm_request_threaded_irq(core->dev, core->irq, iris_hfi_isr, iris_hfi_isr_handler, IRQF_TRIGGER_HIGH, "iris", core); @@ -267,7 +268,7 @@ static int iris_probe(struct platform_device *pdev) disable_irq_nosync(core->irq); iris_init_ops(core); - core->iris_platform_data->init_hfi_ops(core); + core->iris_firmware_data->init_hfi_ops(core); ret = iris_init_resources(core); if (ret) diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index a782bba4d80fb..6dcc854136a5b 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -243,7 +243,7 @@ static void iris_session_close(struct iris_inst *inst) static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 plane) { - const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + const struct iris_firmware_data *firmware_data = inst->core->iris_firmware_data; struct iris_buffer *buf, *next; struct iris_buffers *buffers; const u32 *internal_buf_type; @@ -251,11 +251,11 @@ static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 p u32 count = 0; if (V4L2_TYPE_IS_OUTPUT(plane)) { - internal_buf_type = platform_data->dec_ip_int_buf_tbl; - internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_ip_int_buf_tbl; + internal_buffer_count = firmware_data->dec_ip_int_buf_tbl_size; } else { - internal_buf_type = platform_data->dec_op_int_buf_tbl; - internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + internal_buf_type = firmware_data->dec_op_int_buf_tbl; + internal_buffer_count = firmware_data->dec_op_int_buf_tbl_size; } for (i = 0; i < internal_buffer_count; i++) { diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index aa0b66954680d..ca96e91222c67 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -63,7 +63,7 @@ static void iris_vpu_setup_ucregion_memory_map(struct iris_core *core) writel(QTBL_ENABLE, core->reg_base + QTBL_INFO); if (core->sfr_daddr) { - value = (u32)core->sfr_daddr + core->iris_platform_data->core_arch; + value = (u32)core->sfr_daddr + core->iris_firmware_data->core_arch; writel(value, core->reg_base + SFR_ADDR); } From 132beebe6a488bcb89d27ff5dd5766844603de37 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:10 +0200 Subject: [PATCH 24/41] FROMLIST: media: qcom: iris: split platform data from firmware data Finalize the logical separation of the software and hardware interface descriptions by moving hardware properties to the files specific to the particular VPU version. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-9-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Signed-off-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/Makefile | 7 +- .../{iris_platform_gen1.c => iris_hfi_gen1.c} | 134 -------- .../{iris_platform_gen2.c => iris_hfi_gen2.c} | 304 ------------------ .../platform/qcom/iris/iris_platform_common.h | 3 + .../platform/qcom/iris/iris_platform_sm8250.h | 29 ++ .../platform/qcom/iris/iris_platform_sm8550.h | 31 ++ .../platform/qcom/iris/iris_platform_vpu2.c | 124 +++++++ .../platform/qcom/iris/iris_platform_vpu3x.c | 261 +++++++++++++++ .../platform/qcom/iris/iris_platform_vpu4x.c | 104 ++++++ 9 files changed, 557 insertions(+), 440 deletions(-) rename drivers/media/platform/qcom/iris/{iris_platform_gen1.c => iris_hfi_gen1.c} (67%) rename drivers/media/platform/qcom/iris/{iris_platform_gen2.c => iris_hfi_gen2.c} (71%) create mode 100644 drivers/media/platform/qcom/iris/iris_platform_sm8250.h create mode 100644 drivers/media/platform/qcom/iris/iris_platform_sm8550.h create mode 100644 drivers/media/platform/qcom/iris/iris_platform_vpu2.c create mode 100644 drivers/media/platform/qcom/iris/iris_platform_vpu3x.c create mode 100644 drivers/media/platform/qcom/iris/iris_platform_vpu4x.c diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile index 2fde45f817276..f8a017d878d62 100644 --- a/drivers/media/platform/qcom/iris/Makefile +++ b/drivers/media/platform/qcom/iris/Makefile @@ -4,14 +4,17 @@ qcom-iris-objs += iris_buffer.o \ iris_ctrls.o \ iris_firmware.o \ iris_hfi_common.o \ + iris_hfi_gen1.o \ iris_hfi_gen1_command.o \ iris_hfi_gen1_response.o \ + iris_hfi_gen2.o \ iris_hfi_gen2_command.o \ iris_hfi_gen2_packet.o \ iris_hfi_gen2_response.o \ iris_hfi_queue.o \ - iris_platform_gen1.o \ - iris_platform_gen2.o \ + iris_platform_vpu2.o \ + iris_platform_vpu3x.o \ + iris_platform_vpu4x.o \ iris_power.o \ iris_probe.o \ iris_resources.o \ diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen1.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c similarity index 67% rename from drivers/media/platform/qcom/iris/iris_platform_gen1.c rename to drivers/media/platform/qcom/iris/iris_hfi_gen1.c index 9e632a973f476..60f51a1ba9412 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen1.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.c @@ -3,38 +3,16 @@ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ -#include "iris_core.h" #include "iris_ctrls.h" #include "iris_platform_common.h" -#include "iris_resources.h" #include "iris_hfi_gen1.h" #include "iris_hfi_gen1_defines.h" #include "iris_vpu_buffer.h" -#include "iris_vpu_common.h" -#include "iris_instance.h" - -#include "iris_platform_sc7280.h" #define BITRATE_MIN 32000 #define BITRATE_MAX 160000000 -#define BITRATE_PEAK_DEFAULT (BITRATE_DEFAULT * 2) #define BITRATE_STEP 100 -static struct iris_fmt platform_fmts_sm8250_dec[] = { - [IRIS_FMT_H264] = { - .pixfmt = V4L2_PIX_FMT_H264, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, - [IRIS_FMT_HEVC] = { - .pixfmt = V4L2_PIX_FMT_HEVC, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, - [IRIS_FMT_VP9] = { - .pixfmt = V4L2_PIX_FMT_VP9, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, -}; - static struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = { { .cap_id = PIPE, @@ -248,56 +226,6 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = { }, }; -static struct platform_inst_caps platform_inst_cap_sm8250 = { - .min_frame_width = 128, - .max_frame_width = 8192, - .min_frame_height = 128, - .max_frame_height = 8192, - .max_mbpf = 138240, - .mb_cycles_vsp = 25, - .mb_cycles_vpp = 200, - .max_frame_rate = MAXIMUM_FPS, - .max_operating_rate = MAXIMUM_FPS, -}; - -static const struct icc_info sm8250_icc_table[] = { - { "cpu-cfg", 1000, 1000 }, - { "video-mem", 1000, 15000000 }, -}; - -static const char * const sm8250_clk_reset_table[] = { "bus", "core" }; - -static const struct bw_info sm8250_bw_table_dec[] = { - { ((4096 * 2160) / 256) * 60, 2403000 }, - { ((4096 * 2160) / 256) * 30, 1224000 }, - { ((1920 * 1080) / 256) * 60, 812000 }, - { ((1920 * 1080) / 256) * 30, 416000 }, -}; - -static const char * const sm8250_pmdomain_table[] = { "venus", "vcodec0" }; - -static const char * const sm8250_opp_pd_table[] = { "mx" }; - -static const struct platform_clk_data sm8250_clk_table[] = { - {IRIS_AXI_CLK, "iface" }, - {IRIS_CTRL_CLK, "core" }, - {IRIS_HW_CLK, "vcodec0_core" }, -}; - -static const char * const sm8250_opp_clk_table[] = { - "vcodec0_core", - NULL, -}; - -static const struct tz_cp_config tz_cp_config_sm8250[] = { - { - .cp_start = 0, - .cp_size = 0x25800000, - .cp_nonpixel_start = 0x01000000, - .cp_nonpixel_size = 0x24800000, - }, -}; - static const u32 sm8250_vdec_input_config_param_default[] = { HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE, HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT, @@ -356,65 +284,3 @@ const struct iris_firmware_data iris_hfi_gen1_data = { .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl, .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl), }; - -const struct iris_platform_data sm8250_data = { - .firmware_data = &iris_hfi_gen1_data, - .get_vpu_buffer_size = iris_vpu_buf_size, - .vpu_ops = &iris_vpu2_ops, - .icc_tbl = sm8250_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8250_icc_table), - .clk_rst_tbl = sm8250_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(sm8250_clk_reset_table), - .bw_tbl_dec = sm8250_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sm8250_bw_table_dec), - .pmdomain_tbl = sm8250_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(sm8250_pmdomain_table), - .opp_pd_tbl = sm8250_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sm8250_opp_pd_table), - .clk_tbl = sm8250_clk_table, - .clk_tbl_size = ARRAY_SIZE(sm8250_clk_table), - .opp_clk_tbl = sm8250_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu-1.0/venus.mbn", - .inst_iris_fmts = platform_fmts_sm8250_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), - .inst_caps = &platform_inst_cap_sm8250, - .tz_cp_config_data = tz_cp_config_sm8250, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), - .num_vpp_pipe = 4, - .max_session_count = 16, - .max_core_mbpf = NUM_MBS_8K, - .max_core_mbps = ((7680 * 4320) / 256) * 60, -}; - -const struct iris_platform_data sc7280_data = { - .firmware_data = &iris_hfi_gen1_data, - .get_vpu_buffer_size = iris_vpu_buf_size, - .vpu_ops = &iris_vpu2_ops, - .icc_tbl = sm8250_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8250_icc_table), - .bw_tbl_dec = sc7280_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sc7280_bw_table_dec), - .pmdomain_tbl = sm8250_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(sm8250_pmdomain_table), - .opp_pd_tbl = sc7280_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sc7280_opp_pd_table), - .clk_tbl = sc7280_clk_table, - .clk_tbl_size = ARRAY_SIZE(sc7280_clk_table), - .opp_clk_tbl = sc7280_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu20_p1.mbn", - .inst_iris_fmts = platform_fmts_sm8250_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8250_dec), - .inst_caps = &platform_inst_cap_sm8250, - .tz_cp_config_data = tz_cp_config_sm8250, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8250), - .num_vpp_pipe = 1, - .no_aon = true, - .max_session_count = 16, - .max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256, - /* max spec for SC7280 is 4096x2176@60fps */ - .max_core_mbps = 4096 * 2176 / 256 * 60, -}; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c similarity index 71% rename from drivers/media/platform/qcom/iris/iris_platform_gen2.c rename to drivers/media/platform/qcom/iris/iris_hfi_gen2.c index b83a2af4cb7d4..ce8490d64854c 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c @@ -4,41 +4,15 @@ * Copyright (c) 2025 Linaro Ltd */ -#include "iris_core.h" #include "iris_ctrls.h" #include "iris_hfi_gen2.h" #include "iris_hfi_gen2_defines.h" #include "iris_platform_common.h" #include "iris_vpu_buffer.h" -#include "iris_vpu_common.h" - -#include "iris_platform_kaanapali.h" -#include "iris_platform_qcs8300.h" -#include "iris_platform_sm8650.h" -#include "iris_platform_sm8750.h" #define VIDEO_ARCH_LX 1 #define BITRATE_MAX 245000000 -static struct iris_fmt platform_fmts_sm8550_dec[] = { - [IRIS_FMT_H264] = { - .pixfmt = V4L2_PIX_FMT_H264, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, - [IRIS_FMT_HEVC] = { - .pixfmt = V4L2_PIX_FMT_HEVC, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, - [IRIS_FMT_VP9] = { - .pixfmt = V4L2_PIX_FMT_VP9, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, - [IRIS_FMT_AV1] = { - .pixfmt = V4L2_PIX_FMT_AV1, - .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, - }, -}; - static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { { .cap_id = PROFILE_H264, @@ -743,109 +717,6 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = { }, }; -static struct platform_inst_caps platform_inst_cap_sm8550 = { - .min_frame_width = 96, - .max_frame_width = 8192, - .min_frame_height = 96, - .max_frame_height = 8192, - .max_mbpf = (8192 * 4352) / 256, - .mb_cycles_vpp = 200, - .mb_cycles_fw = 489583, - .mb_cycles_fw_vpp = 66234, - .num_comv = 0, - .max_frame_rate = MAXIMUM_FPS, - .max_operating_rate = MAXIMUM_FPS, -}; - -static int sm8550_init_cb_devs(struct iris_core *core) -{ - const u32 f_id_np = 0; /* IRIS_NON_PIXEL_VCODEC */ - const u32 f_id_p = 1; /* IRIS_PIXEL */ - struct device *dev; - - dev = iris_create_cb_dev(core, "iris_non_pixel", &f_id_np); - if (IS_ERR(dev)) - return PTR_ERR(dev); - - core->dev_np = dev; - core->dev_bs = core->dev_np; - - dev = iris_create_cb_dev(core, "iris_pixel", &f_id_p); - if (IS_ERR(dev)) - goto err_unreg_dev_np; - - core->dev_p = dev; - - return 0; - -err_unreg_dev_np: - platform_device_unregister(to_platform_device(core->dev_np)); - core->dev_np = NULL; - core->dev_bs = NULL; - - return PTR_ERR(dev); -} - -static void sm8550_deinit_cb_devs(struct iris_core *core) -{ - if (core->dev_np) - platform_device_unregister(to_platform_device(core->dev_np)); - if (core->dev_p) - platform_device_unregister(to_platform_device(core->dev_p)); - - core->dev_np = NULL; - core->dev_bs = NULL; - core->dev_p = NULL; -} - -static const struct icc_info sm8550_icc_table[] = { - { "cpu-cfg", 1000, 1000 }, - { "video-mem", 1000, 15000000 }, -}; - -static const char * const sm8550_clk_reset_table[] = { "bus" }; - -static const struct bw_info sm8550_bw_table_dec[] = { - { ((4096 * 2160) / 256) * 60, 1608000 }, - { ((4096 * 2160) / 256) * 30, 826000 }, - { ((1920 * 1080) / 256) * 60, 567000 }, - { ((1920 * 1080) / 256) * 30, 294000 }, -}; - -static const char * const sm8550_pmdomain_table[] = { "venus", "vcodec0" }; - -static const char * const sm8550_opp_pd_table[] = { "mxc", "mmcx" }; - -static const struct platform_clk_data sm8550_clk_table[] = { - {IRIS_AXI_CLK, "iface" }, - {IRIS_CTRL_CLK, "core" }, - {IRIS_HW_CLK, "vcodec0_core" }, -}; - -static const char * const sm8550_opp_clk_table[] = { - "vcodec0_core", - NULL, -}; - -static struct ubwc_config_data ubwc_config_sm8550 = { - .max_channels = 8, - .mal_length = 32, - .highest_bank_bit = 16, - .bank_swzl_level = 0, - .bank_swz2_level = 1, - .bank_swz3_level = 1, - .bank_spreading = 1, -}; - -static const struct tz_cp_config tz_cp_config_sm8550[] = { - { - .cp_start = 0, - .cp_size = 0x25800000, - .cp_nonpixel_start = 0x01000000, - .cp_nonpixel_size = 0x24800000, - }, -}; - static const u32 sm8550_vdec_input_config_params_default[] = { HFI_PROP_BITSTREAM_RESOLUTION, HFI_PROP_CROP_OFFSETS, @@ -1023,178 +894,3 @@ const struct iris_firmware_data iris_hfi_gen2_data = { .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; - -const struct iris_platform_data kaanapali_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu4x_buf_size, - .vpu_ops = &iris_vpu4x_ops, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = kaanapali_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(kaanapali_clk_reset_table), - .bw_tbl_dec = sm8550_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), - .pmdomain_tbl = kaanapali_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(kaanapali_pmdomain_table), - .opp_pd_tbl = sm8550_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), - .clk_tbl = kaanapali_clk_table, - .clk_tbl_size = ARRAY_SIZE(kaanapali_clk_table), - .opp_clk_tbl = kaanapali_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu40_p2_s7.mbn", - .inst_iris_fmts = platform_fmts_sm8550_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), - .inst_caps = &platform_inst_cap_sm8550, - .tz_cp_config_data = tz_cp_config_kaanapali, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 2, - .max_session_count = 16, - .max_core_mbpf = NUM_MBS_8K * 2, - .max_core_mbps = ((8192 * 4352) / 256) * 60, -}; - -const struct iris_platform_data sm8550_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu_buf_size, - .vpu_ops = &iris_vpu3_ops, - .init_cb_devs = sm8550_init_cb_devs, - .deinit_cb_devs = sm8550_deinit_cb_devs, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8550_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table), - .bw_tbl_dec = sm8550_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), - .pmdomain_tbl = sm8550_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(sm8550_pmdomain_table), - .opp_pd_tbl = sm8550_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), - .clk_tbl = sm8550_clk_table, - .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), - .opp_clk_tbl = sm8550_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu30_p4.mbn", - .inst_iris_fmts = platform_fmts_sm8550_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), - .inst_caps = &platform_inst_cap_sm8550, - .tz_cp_config_data = tz_cp_config_sm8550, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 4, - .max_session_count = 16, - .max_core_mbpf = NUM_MBS_8K * 2, - .max_core_mbps = ((7680 * 4320) / 256) * 60, -}; - -/* - * Shares most of SM8550 data except: - * - vpu_ops to iris_vpu33_ops - * - clk_rst_tbl to sm8650_clk_reset_table - * - controller_rst_tbl to sm8650_controller_reset_table - * - fwname to "qcom/vpu/vpu33_p4.mbn" - */ -const struct iris_platform_data sm8650_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu33_buf_size, - .vpu_ops = &iris_vpu33_ops, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8650_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table), - .controller_rst_tbl = sm8650_controller_reset_table, - .controller_rst_tbl_size = ARRAY_SIZE(sm8650_controller_reset_table), - .bw_tbl_dec = sm8550_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), - .pmdomain_tbl = sm8550_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(sm8550_pmdomain_table), - .opp_pd_tbl = sm8550_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), - .clk_tbl = sm8550_clk_table, - .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), - .opp_clk_tbl = sm8550_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu33_p4.mbn", - .inst_iris_fmts = platform_fmts_sm8550_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), - .inst_caps = &platform_inst_cap_sm8550, - .tz_cp_config_data = tz_cp_config_sm8550, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 4, - .max_session_count = 16, - .max_core_mbpf = NUM_MBS_8K * 2, - .max_core_mbps = ((7680 * 4320) / 256) * 60, -}; - -const struct iris_platform_data sm8750_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu33_buf_size, - .vpu_ops = &iris_vpu35_ops, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8750_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(sm8750_clk_reset_table), - .bw_tbl_dec = sm8550_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), - .pmdomain_tbl = sm8550_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(sm8550_pmdomain_table), - .opp_pd_tbl = sm8550_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), - .clk_tbl = sm8750_clk_table, - .clk_tbl_size = ARRAY_SIZE(sm8750_clk_table), - .opp_clk_tbl = sm8550_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu35_p4.mbn", - .inst_iris_fmts = platform_fmts_sm8550_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), - .inst_caps = &platform_inst_cap_sm8550, - .tz_cp_config_data = tz_cp_config_sm8550, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 4, - .max_session_count = 16, - .max_core_mbpf = NUM_MBS_8K * 2, - .max_core_mbps = ((7680 * 4320) / 256) * 60, -}; - -/* - * Shares most of SM8550 data except: - * - inst_caps to platform_inst_cap_qcs8300 - */ -const struct iris_platform_data qcs8300_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu_buf_size, - .vpu_ops = &iris_vpu3_ops, - .icc_tbl = sm8550_icc_table, - .icc_tbl_size = ARRAY_SIZE(sm8550_icc_table), - .clk_rst_tbl = sm8550_clk_reset_table, - .clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table), - .bw_tbl_dec = sm8550_bw_table_dec, - .bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec), - .pmdomain_tbl = sm8550_pmdomain_table, - .pmdomain_tbl_size = ARRAY_SIZE(sm8550_pmdomain_table), - .opp_pd_tbl = sm8550_opp_pd_table, - .opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table), - .clk_tbl = sm8550_clk_table, - .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), - .opp_clk_tbl = sm8550_opp_clk_table, - /* Upper bound of DMA address range */ - .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu30_p4_s6.mbn", - .inst_iris_fmts = platform_fmts_sm8550_dec, - .inst_iris_fmts_size = ARRAY_SIZE(platform_fmts_sm8550_dec), - .inst_caps = &platform_inst_cap_qcs8300, - .tz_cp_config_data = tz_cp_config_sm8550, - .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_sm8550), - .ubwc_config = &ubwc_config_sm8550, - .num_vpp_pipe = 2, - .max_session_count = 16, - .max_core_mbpf = ((4096 * 2176) / 256) * 4, - .max_core_mbps = (((3840 * 2176) / 256) * 120), -}; diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 4dd17aed12606..acf8c5be4940c 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -40,6 +40,9 @@ enum pipe_type { PIPE_4 = 4, }; +extern const struct iris_firmware_data iris_hfi_gen1_data; +extern const struct iris_firmware_data iris_hfi_gen2_data; + extern const struct iris_platform_data kaanapali_data; extern const struct iris_platform_data qcs8300_data; extern const struct iris_platform_data sc7280_data; diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.h b/drivers/media/platform/qcom/iris/iris_platform_sm8250.h new file mode 100644 index 0000000000000..50306043eb8ec --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8250.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __IRIS_PLATFORM_SM8250_H__ +#define __IRIS_PLATFORM_SM8250_H__ + +static const struct bw_info sm8250_bw_table_dec[] = { + { ((4096 * 2160) / 256) * 60, 2403000 }, + { ((4096 * 2160) / 256) * 30, 1224000 }, + { ((1920 * 1080) / 256) * 60, 812000 }, + { ((1920 * 1080) / 256) * 30, 416000 }, +}; + +static const char * const sm8250_opp_pd_table[] = { "mx", "mmcx" }; + +static const struct platform_clk_data sm8250_clk_table[] = { + {IRIS_AXI_CLK, "iface" }, + {IRIS_CTRL_CLK, "core" }, + {IRIS_HW_CLK, "vcodec0_core" }, +}; + +static const char * const sm8250_opp_clk_table[] = { + "vcodec0_core", + NULL, +}; + +#endif diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8550.h b/drivers/media/platform/qcom/iris/iris_platform_sm8550.h new file mode 100644 index 0000000000000..a9d9709c2e352 --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8550.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __IRIS_PLATFORM_SM8550_H__ +#define __IRIS_PLATFORM_SM8550_H__ + +static const char * const sm8550_clk_reset_table[] = { "bus" }; + +static const struct platform_clk_data sm8550_clk_table[] = { + {IRIS_AXI_CLK, "iface" }, + {IRIS_CTRL_CLK, "core" }, + {IRIS_HW_CLK, "vcodec0_core" }, +}; + +static struct platform_inst_caps platform_inst_cap_sm8550 = { + .min_frame_width = 96, + .max_frame_width = 8192, + .min_frame_height = 96, + .max_frame_height = 8192, + .max_mbpf = (8192 * 4352) / 256, + .mb_cycles_vpp = 200, + .mb_cycles_fw = 489583, + .mb_cycles_fw_vpp = 66234, + .num_comv = 0, + .max_frame_rate = MAXIMUM_FPS, + .max_operating_rate = MAXIMUM_FPS, +}; + +#endif diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c new file mode 100644 index 0000000000000..ab2a19aa9c36c --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "iris_core.h" +#include "iris_ctrls.h" +#include "iris_platform_common.h" +#include "iris_resources.h" +#include "iris_hfi_gen1.h" +#include "iris_hfi_gen1_defines.h" +#include "iris_vpu_buffer.h" +#include "iris_vpu_common.h" +#include "iris_instance.h" + +#include "iris_platform_sc7280.h" +#include "iris_platform_sm8250.h" + +static struct iris_fmt iris_fmts_vpu2_dec[] = { + [IRIS_FMT_H264] = { + .pixfmt = V4L2_PIX_FMT_H264, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_HEVC] = { + .pixfmt = V4L2_PIX_FMT_HEVC, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_VP9] = { + .pixfmt = V4L2_PIX_FMT_VP9, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + +static struct platform_inst_caps platform_inst_cap_vpu2 = { + .min_frame_width = 128, + .max_frame_width = 8192, + .min_frame_height = 128, + .max_frame_height = 8192, + .max_mbpf = 138240, + .mb_cycles_vsp = 25, + .mb_cycles_vpp = 200, + .max_frame_rate = MAXIMUM_FPS, + .max_operating_rate = MAXIMUM_FPS, +}; + +static const struct icc_info iris_icc_info_vpu2[] = { + { "cpu-cfg", 1000, 1000 }, + { "video-mem", 1000, 15000000 }, +}; + +static const char * const iris_clk_reset_table_vpu2[] = { "bus", "core" }; + +static const char * const iris_pmdomain_table_vpu2[] = { "venus", "vcodec0" }; + +static const struct tz_cp_config tz_cp_config_vpu2[] = { + { + .cp_start = 0, + .cp_size = 0x25800000, + .cp_nonpixel_start = 0x01000000, + .cp_nonpixel_size = 0x24800000, + }, +}; + +const struct iris_platform_data sc7280_data = { + .firmware_data = &iris_hfi_gen1_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .vpu_ops = &iris_vpu2_ops, + .icc_tbl = iris_icc_info_vpu2, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu2), + .bw_tbl_dec = sc7280_bw_table_dec, + .bw_tbl_dec_size = ARRAY_SIZE(sc7280_bw_table_dec), + .pmdomain_tbl = iris_pmdomain_table_vpu2, + .pmdomain_tbl_size = ARRAY_SIZE(iris_pmdomain_table_vpu2), + .opp_pd_tbl = sc7280_opp_pd_table, + .opp_pd_tbl_size = ARRAY_SIZE(sc7280_opp_pd_table), + .clk_tbl = sc7280_clk_table, + .clk_tbl_size = ARRAY_SIZE(sc7280_clk_table), + .opp_clk_tbl = sc7280_opp_clk_table, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu20_p1.mbn", + .inst_iris_fmts = iris_fmts_vpu2_dec, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec), + .inst_caps = &platform_inst_cap_vpu2, + .tz_cp_config_data = tz_cp_config_vpu2, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2), + .num_vpp_pipe = 1, + .no_aon = true, + .max_session_count = 16, + .max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256, + /* max spec for SC7280 is 4096x2176@60fps */ + .max_core_mbps = 4096 * 2176 / 256 * 60, +}; + +const struct iris_platform_data sm8250_data = { + .firmware_data = &iris_hfi_gen1_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .vpu_ops = &iris_vpu2_ops, + .icc_tbl = iris_icc_info_vpu2, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu2), + .clk_rst_tbl = iris_clk_reset_table_vpu2, + .clk_rst_tbl_size = ARRAY_SIZE(iris_clk_reset_table_vpu2), + .bw_tbl_dec = sm8250_bw_table_dec, + .bw_tbl_dec_size = ARRAY_SIZE(sm8250_bw_table_dec), + .pmdomain_tbl = iris_pmdomain_table_vpu2, + .pmdomain_tbl_size = ARRAY_SIZE(iris_pmdomain_table_vpu2), + .opp_pd_tbl = sm8250_opp_pd_table, + .opp_pd_tbl_size = ARRAY_SIZE(sm8250_opp_pd_table), + .clk_tbl = sm8250_clk_table, + .clk_tbl_size = ARRAY_SIZE(sm8250_clk_table), + .opp_clk_tbl = sm8250_opp_clk_table, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu-1.0/venus.mbn", + .inst_iris_fmts = iris_fmts_vpu2_dec, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec), + .inst_caps = &platform_inst_cap_vpu2, + .tz_cp_config_data = tz_cp_config_vpu2, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2), + .num_vpp_pipe = 4, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K, + .max_core_mbps = ((7680 * 4320) / 256) * 60, +}; diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c new file mode 100644 index 0000000000000..f5cf933c3d445 --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2025 Linaro Ltd + */ + +#include "iris_core.h" +#include "iris_ctrls.h" +#include "iris_hfi_gen2.h" +#include "iris_hfi_gen2_defines.h" +#include "iris_platform_common.h" +#include "iris_vpu_buffer.h" +#include "iris_vpu_common.h" + +#include "iris_platform_qcs8300.h" +#include "iris_platform_sm8550.h" +#include "iris_platform_sm8650.h" +#include "iris_platform_sm8750.h" + +static struct iris_fmt iris_fmts_vpu3x_dec[] = { + [IRIS_FMT_H264] = { + .pixfmt = V4L2_PIX_FMT_H264, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_HEVC] = { + .pixfmt = V4L2_PIX_FMT_HEVC, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_VP9] = { + .pixfmt = V4L2_PIX_FMT_VP9, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_AV1] = { + .pixfmt = V4L2_PIX_FMT_AV1, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + +static const struct icc_info iris_icc_info_vpu3x[] = { + { "cpu-cfg", 1000, 1000 }, + { "video-mem", 1000, 15000000 }, +}; + +static const struct bw_info iris_bw_table_dec_vpu3x[] = { + { ((4096 * 2160) / 256) * 60, 1608000 }, + { ((4096 * 2160) / 256) * 30, 826000 }, + { ((1920 * 1080) / 256) * 60, 567000 }, + { ((1920 * 1080) / 256) * 30, 294000 }, +}; + +static const char * const iris_pmdomain_table_vpu3x[] = { "venus", "vcodec0" }; + +static const char * const iris_opp_pd_table_vpu3x[] = { "mxc", "mmcx" }; + +static const char * const iris_opp_clk_table_vpu3x[] = { + "vcodec0_core", + NULL, +}; + +static struct ubwc_config_data iris_ubwc_config_vpu3x = { + .max_channels = 8, + .mal_length = 32, + .highest_bank_bit = 16, + .bank_swzl_level = 0, + .bank_swz2_level = 1, + .bank_swz3_level = 1, + .bank_spreading = 1, +}; + +static const struct tz_cp_config tz_cp_config_vpu3[] = { + { + .cp_start = 0, + .cp_size = 0x25800000, + .cp_nonpixel_start = 0x01000000, + .cp_nonpixel_size = 0x24800000, + }, +}; + +static int sm8550_init_cb_devs(struct iris_core *core) +{ + const u32 f_id_np = 0; /* IRIS_NON_PIXEL_VCODEC */ + const u32 f_id_p = 1; /* IRIS_PIXEL */ + struct device *dev; + + dev = iris_create_cb_dev(core, "iris_non_pixel", &f_id_np); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + core->dev_np = dev; + core->dev_bs = core->dev_np; + + dev = iris_create_cb_dev(core, "iris_pixel", &f_id_p); + if (IS_ERR(dev)) + goto err_unreg_dev_np; + + core->dev_p = dev; + + return 0; + +err_unreg_dev_np: + platform_device_unregister(to_platform_device(core->dev_np)); + core->dev_np = NULL; + core->dev_bs = NULL; + + return PTR_ERR(dev); +} + +static void sm8550_deinit_cb_devs(struct iris_core *core) +{ + if (core->dev_np) + platform_device_unregister(to_platform_device(core->dev_np)); + if (core->dev_p) + platform_device_unregister(to_platform_device(core->dev_p)); + + core->dev_np = NULL; + core->dev_bs = NULL; + core->dev_p = NULL; +} + +/* + * Shares most of SM8550 data except: + * - inst_caps to platform_inst_cap_qcs8300 + */ +const struct iris_platform_data qcs8300_data = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .vpu_ops = &iris_vpu3_ops, + .icc_tbl = iris_icc_info_vpu3x, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu3x), + .clk_rst_tbl = sm8550_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table), + .bw_tbl_dec = iris_bw_table_dec_vpu3x, + .bw_tbl_dec_size = ARRAY_SIZE(iris_bw_table_dec_vpu3x), + .pmdomain_tbl = iris_pmdomain_table_vpu3x, + .pmdomain_tbl_size = ARRAY_SIZE(iris_pmdomain_table_vpu3x), + .opp_pd_tbl = iris_opp_pd_table_vpu3x, + .opp_pd_tbl_size = ARRAY_SIZE(iris_opp_pd_table_vpu3x), + .clk_tbl = sm8550_clk_table, + .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), + .opp_clk_tbl = iris_opp_clk_table_vpu3x, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu30_p4_s6.mbn", + .inst_iris_fmts = iris_fmts_vpu3x_dec, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), + .inst_caps = &platform_inst_cap_qcs8300, + .tz_cp_config_data = tz_cp_config_vpu3, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), + .ubwc_config = &iris_ubwc_config_vpu3x, + .num_vpp_pipe = 2, + .max_session_count = 16, + .max_core_mbpf = ((4096 * 2176) / 256) * 4, + .max_core_mbps = (((3840 * 2176) / 256) * 120), +}; + +const struct iris_platform_data sm8550_data = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .vpu_ops = &iris_vpu3_ops, + .init_cb_devs = sm8550_init_cb_devs, + .deinit_cb_devs = sm8550_deinit_cb_devs, + .icc_tbl = iris_icc_info_vpu3x, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu3x), + .clk_rst_tbl = sm8550_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table), + .bw_tbl_dec = iris_bw_table_dec_vpu3x, + .bw_tbl_dec_size = ARRAY_SIZE(iris_bw_table_dec_vpu3x), + .pmdomain_tbl = iris_pmdomain_table_vpu3x, + .pmdomain_tbl_size = ARRAY_SIZE(iris_pmdomain_table_vpu3x), + .opp_pd_tbl = iris_opp_pd_table_vpu3x, + .opp_pd_tbl_size = ARRAY_SIZE(iris_opp_pd_table_vpu3x), + .clk_tbl = sm8550_clk_table, + .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), + .opp_clk_tbl = iris_opp_clk_table_vpu3x, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu30_p4.mbn", + .inst_iris_fmts = iris_fmts_vpu3x_dec, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), + .inst_caps = &platform_inst_cap_sm8550, + .tz_cp_config_data = tz_cp_config_vpu3, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), + .ubwc_config = &iris_ubwc_config_vpu3x, + .num_vpp_pipe = 4, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((7680 * 4320) / 256) * 60, +}; + +/* + * Shares most of SM8550 data except: + * - vpu_ops to iris_vpu33_ops + * - clk_rst_tbl to sm8650_clk_reset_table + * - controller_rst_tbl to sm8650_controller_reset_table + * - fwname to "qcom/vpu/vpu33_p4.mbn" + */ +const struct iris_platform_data sm8650_data = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu33_buf_size, + .vpu_ops = &iris_vpu33_ops, + .icc_tbl = iris_icc_info_vpu3x, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu3x), + .clk_rst_tbl = sm8650_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table), + .controller_rst_tbl = sm8650_controller_reset_table, + .controller_rst_tbl_size = ARRAY_SIZE(sm8650_controller_reset_table), + .bw_tbl_dec = iris_bw_table_dec_vpu3x, + .bw_tbl_dec_size = ARRAY_SIZE(iris_bw_table_dec_vpu3x), + .pmdomain_tbl = iris_pmdomain_table_vpu3x, + .pmdomain_tbl_size = ARRAY_SIZE(iris_pmdomain_table_vpu3x), + .opp_pd_tbl = iris_opp_pd_table_vpu3x, + .opp_pd_tbl_size = ARRAY_SIZE(iris_opp_pd_table_vpu3x), + .clk_tbl = sm8550_clk_table, + .clk_tbl_size = ARRAY_SIZE(sm8550_clk_table), + .opp_clk_tbl = iris_opp_clk_table_vpu3x, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu33_p4.mbn", + .inst_iris_fmts = iris_fmts_vpu3x_dec, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), + .inst_caps = &platform_inst_cap_sm8550, + .tz_cp_config_data = tz_cp_config_vpu3, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), + .ubwc_config = &iris_ubwc_config_vpu3x, + .num_vpp_pipe = 4, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((7680 * 4320) / 256) * 60, +}; + +const struct iris_platform_data sm8750_data = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu33_buf_size, + .vpu_ops = &iris_vpu35_ops, + .icc_tbl = iris_icc_info_vpu3x, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu3x), + .clk_rst_tbl = sm8750_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(sm8750_clk_reset_table), + .bw_tbl_dec = iris_bw_table_dec_vpu3x, + .bw_tbl_dec_size = ARRAY_SIZE(iris_bw_table_dec_vpu3x), + .pmdomain_tbl = iris_pmdomain_table_vpu3x, + .pmdomain_tbl_size = ARRAY_SIZE(iris_pmdomain_table_vpu3x), + .opp_pd_tbl = iris_opp_pd_table_vpu3x, + .opp_pd_tbl_size = ARRAY_SIZE(iris_opp_pd_table_vpu3x), + .clk_tbl = sm8750_clk_table, + .clk_tbl_size = ARRAY_SIZE(sm8750_clk_table), + .opp_clk_tbl = iris_opp_clk_table_vpu3x, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu35_p4.mbn", + .inst_iris_fmts = iris_fmts_vpu3x_dec, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), + .inst_caps = &platform_inst_cap_sm8550, + .tz_cp_config_data = tz_cp_config_vpu3, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), + .ubwc_config = &iris_ubwc_config_vpu3x, + .num_vpp_pipe = 4, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((7680 * 4320) / 256) * 60, +}; diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c new file mode 100644 index 0000000000000..ad283afddda6f --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2025 Linaro Ltd + */ + +#include "iris_core.h" +#include "iris_ctrls.h" +#include "iris_hfi_gen2.h" +#include "iris_hfi_gen2_defines.h" +#include "iris_platform_common.h" +#include "iris_vpu_buffer.h" +#include "iris_vpu_common.h" + +#include "iris_platform_kaanapali.h" + +static struct iris_fmt iris_fmts_vpu4x_dec[] = { + [IRIS_FMT_H264] = { + .pixfmt = V4L2_PIX_FMT_H264, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_HEVC] = { + .pixfmt = V4L2_PIX_FMT_HEVC, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_VP9] = { + .pixfmt = V4L2_PIX_FMT_VP9, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_AV1] = { + .pixfmt = V4L2_PIX_FMT_AV1, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + +static const struct icc_info iris_icc_info_vpu4x[] = { + { "cpu-cfg", 1000, 1000 }, + { "video-mem", 1000, 15000000 }, +}; + +static const struct bw_info iris_bw_table_dec_vpu4x[] = { + { ((4096 * 2160) / 256) * 60, 1608000 }, + { ((4096 * 2160) / 256) * 30, 826000 }, + { ((1920 * 1080) / 256) * 60, 567000 }, + { ((1920 * 1080) / 256) * 30, 294000 }, +}; + +static const char * const iris_opp_pd_table_vpu4x[] = { "mxc", "mmcx" }; + +static struct platform_inst_caps iris_inst_cap_vpu4x = { + .min_frame_width = 96, + .max_frame_width = 8192, + .min_frame_height = 96, + .max_frame_height = 8192, + .max_mbpf = (8192 * 4352) / 256, + .mb_cycles_vpp = 200, + .mb_cycles_fw = 489583, + .mb_cycles_fw_vpp = 66234, + .num_comv = 0, + .max_frame_rate = MAXIMUM_FPS, + .max_operating_rate = MAXIMUM_FPS, +}; + +static struct ubwc_config_data iris_ubwc_config_vpu4x = { + .max_channels = 8, + .mal_length = 32, + .highest_bank_bit = 16, + .bank_swzl_level = 0, + .bank_swz2_level = 1, + .bank_swz3_level = 1, + .bank_spreading = 1, +}; + +const struct iris_platform_data kaanapali_data = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu4x_buf_size, + .vpu_ops = &iris_vpu4x_ops, + .icc_tbl = iris_icc_info_vpu4x, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu4x), + .clk_rst_tbl = kaanapali_clk_reset_table, + .clk_rst_tbl_size = ARRAY_SIZE(kaanapali_clk_reset_table), + .bw_tbl_dec = iris_bw_table_dec_vpu4x, + .bw_tbl_dec_size = ARRAY_SIZE(iris_bw_table_dec_vpu4x), + .pmdomain_tbl = kaanapali_pmdomain_table, + .pmdomain_tbl_size = ARRAY_SIZE(kaanapali_pmdomain_table), + .opp_pd_tbl = iris_opp_pd_table_vpu4x, + .opp_pd_tbl_size = ARRAY_SIZE(iris_opp_pd_table_vpu4x), + .clk_tbl = kaanapali_clk_table, + .clk_tbl_size = ARRAY_SIZE(kaanapali_clk_table), + .opp_clk_tbl = kaanapali_opp_clk_table, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu40_p2_s7.mbn", + .inst_iris_fmts = iris_fmts_vpu4x_dec, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu4x_dec), + .inst_caps = &iris_inst_cap_vpu4x, + .tz_cp_config_data = tz_cp_config_kaanapali, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), + .ubwc_config = &iris_ubwc_config_vpu4x, + .num_vpp_pipe = 2, + .max_session_count = 16, + .max_core_mbpf = NUM_MBS_8K * 2, + .max_core_mbps = ((8192 * 4352) / 256) * 60, +}; From e2188612ba7b0f553a466607b2f3cf81bd430964 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:11 +0200 Subject: [PATCH 25/41] FROMLIST: media: qcom: iris: use new firmware name for SM8250 The linux-firmware is providing the vpuNN_pM.mbn firmware for SM8250 since August of 2024. Stop using the legacy firmware name (vpu-1.0/venus.mbn) and switch to the standard firmware name schema (vpu/vpu20_p4.mbn). Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-10-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Vikash Garodia Reviewed-by: Dikshita Agarwal Signed-off-by: Dmitry Baryshkov --- drivers/media/platform/qcom/iris/iris_platform_vpu2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c index ab2a19aa9c36c..692fbc2aab564 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c @@ -111,7 +111,7 @@ const struct iris_platform_data sm8250_data = { .opp_clk_tbl = sm8250_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu-1.0/venus.mbn", + .fwname = "qcom/vpu/vpu20_p4.mbn", .inst_iris_fmts = iris_fmts_vpu2_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec), .inst_caps = &platform_inst_cap_vpu2, From 3003d305a8995ec3c18cde764ea367746eccdc19 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sun, 29 Mar 2026 02:33:12 +0200 Subject: [PATCH 26/41] FROMLIST: media: qcom: iris: extract firmware description data In preparation to adding support for several firmware revisions to be used for a platform, extract the firmware description data. It incorporates firmware name, HFI ops and buffer requirements of the particular firmware build. Link: https://lore.kernel.org/linux-media/20260329-iris-platform-data-v11-11-eea672b03a95@oss.qualcomm.com/ Reviewed-by: Dikshita Agarwal Signed-off-by: Dmitry Baryshkov --- .../media/platform/qcom/iris/iris_buffer.c | 2 +- drivers/media/platform/qcom/iris/iris_core.h | 2 + .../media/platform/qcom/iris/iris_firmware.c | 2 +- .../qcom/iris/iris_hfi_gen1_command.c | 2 +- .../platform/qcom/iris/iris_platform_common.h | 15 ++++--- .../platform/qcom/iris/iris_platform_vpu2.c | 20 ++++++--- .../platform/qcom/iris/iris_platform_vpu3x.c | 41 +++++++++++++------ .../platform/qcom/iris/iris_platform_vpu4x.c | 10 +++-- drivers/media/platform/qcom/iris/iris_probe.c | 3 +- 9 files changed, 65 insertions(+), 32 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index b10236cd2a58f..0e02eaf17d384 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -295,7 +295,7 @@ static void iris_fill_internal_buf_info(struct iris_inst *inst, { struct iris_buffers *buffers = &inst->buffers[buffer_type]; - buffers->size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, buffer_type); + buffers->size = inst->core->iris_firmware_desc->get_vpu_buffer_size(inst, buffer_type); buffers->min_count = iris_vpu_buf_count(inst, buffer_type); } diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h index 7d128e7724ed1..2a47fb7001331 100644 --- a/drivers/media/platform/qcom/iris/iris_core.h +++ b/drivers/media/platform/qcom/iris/iris_core.h @@ -56,6 +56,7 @@ enum domain_type { * @controller_resets: table of controller reset clocks * @iris_platform_data: a structure for platform data * @iris_firmware_data: a pointer to the firmware (or HFI) specific data + * @iris_firmware_desc: a pointer to the firmware-specific descriptive data * @state: current state of core * @iface_q_table_daddr: device address for interface queue table memory * @sfr_daddr: device address for SFR (Sub System Failure Reason) register memory @@ -107,6 +108,7 @@ struct iris_core { struct reset_control_bulk_data *controller_resets; const struct iris_platform_data *iris_platform_data; const struct iris_firmware_data *iris_firmware_data; + const struct iris_firmware_desc *iris_firmware_desc; enum iris_core_state state; dma_addr_t iface_q_table_daddr; dma_addr_t sfr_daddr; diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index da4da3648f983..07b1d71505baf 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -97,7 +97,7 @@ int iris_fw_load(struct iris_core *core) ret = of_property_read_string_index(core->dev->of_node, "firmware-name", 0, &fwpath); if (ret) - fwpath = core->iris_platform_data->fwname; + fwpath = core->iris_firmware_desc->fwname; ret = iris_load_fw_to_memory(core, fwpath); if (ret) { diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index 3fb90a466a64e..83373862655f7 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -918,7 +918,7 @@ static int iris_hfi_gen1_set_bufsize(struct iris_inst *inst, u32 plane) if (iris_split_mode_enabled(inst)) { bufsz.type = HFI_BUFFER_OUTPUT; - bufsz.size = inst->core->iris_platform_data->get_vpu_buffer_size(inst, BUF_DPB); + bufsz.size = inst->core->iris_firmware_desc->get_vpu_buffer_size(inst, BUF_DPB); ret = hfi_gen1_set_property(inst, ptype, &bufsz, sizeof(bufsz)); if (ret) diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index acf8c5be4940c..1204342aa6c5d 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -261,14 +261,18 @@ struct iris_firmware_data { unsigned int enc_op_int_buf_tbl_size; }; +struct iris_firmware_desc { + const struct iris_firmware_data *firmware_data; + u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); + const char *fwname; +}; + struct iris_platform_data { /* - * XXX: remove firmware_data pointer and consider moving - * get_vpu_buffer_size pointer once we have platforms supporting both - * firmware kinds. + * XXX: replace with gen1 / gen2 pointers once we have platforms + * supporting both firmware kinds. */ - const struct iris_firmware_data *firmware_data; - u32 (*get_vpu_buffer_size)(struct iris_inst *inst, enum iris_buffer_type buffer_type); + const struct iris_firmware_desc *firmware_desc; const struct vpu_ops *vpu_ops; void (*set_preset_registers)(struct iris_core *core); @@ -290,7 +294,6 @@ struct iris_platform_data { const char * const *controller_rst_tbl; unsigned int controller_rst_tbl_size; u64 dma_mask; - const char *fwname; struct iris_fmt *inst_iris_fmts; u32 inst_iris_fmts_size; struct platform_inst_caps *inst_caps; diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c index 692fbc2aab564..ff8ce078238a5 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c @@ -16,6 +16,18 @@ #include "iris_platform_sc7280.h" #include "iris_platform_sm8250.h" +const struct iris_firmware_desc iris_vpu20_p1_gen1_desc = { + .firmware_data = &iris_hfi_gen1_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .fwname = "qcom/vpu/vpu20_p1.mbn", +}; + +const struct iris_firmware_desc iris_vpu20_p4_gen1_desc = { + .firmware_data = &iris_hfi_gen1_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .fwname = "qcom/vpu/vpu20_p4.mbn", +}; + static struct iris_fmt iris_fmts_vpu2_dec[] = { [IRIS_FMT_H264] = { .pixfmt = V4L2_PIX_FMT_H264, @@ -62,8 +74,7 @@ static const struct tz_cp_config tz_cp_config_vpu2[] = { }; const struct iris_platform_data sc7280_data = { - .firmware_data = &iris_hfi_gen1_data, - .get_vpu_buffer_size = iris_vpu_buf_size, + .firmware_desc = &iris_vpu20_p1_gen1_desc, .vpu_ops = &iris_vpu2_ops, .icc_tbl = iris_icc_info_vpu2, .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu2), @@ -78,7 +89,6 @@ const struct iris_platform_data sc7280_data = { .opp_clk_tbl = sc7280_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu20_p1.mbn", .inst_iris_fmts = iris_fmts_vpu2_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec), .inst_caps = &platform_inst_cap_vpu2, @@ -93,8 +103,7 @@ const struct iris_platform_data sc7280_data = { }; const struct iris_platform_data sm8250_data = { - .firmware_data = &iris_hfi_gen1_data, - .get_vpu_buffer_size = iris_vpu_buf_size, + .firmware_desc = &iris_vpu20_p4_gen1_desc, .vpu_ops = &iris_vpu2_ops, .icc_tbl = iris_icc_info_vpu2, .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu2), @@ -111,7 +120,6 @@ const struct iris_platform_data sm8250_data = { .opp_clk_tbl = sm8250_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu20_p4.mbn", .inst_iris_fmts = iris_fmts_vpu2_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu2_dec), .inst_caps = &platform_inst_cap_vpu2, diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c index f5cf933c3d445..0d33196cc396d 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c @@ -17,6 +17,30 @@ #include "iris_platform_sm8650.h" #include "iris_platform_sm8750.h" +const struct iris_firmware_desc iris_vpu30_p4_s6_gen2_desc = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .fwname = "qcom/vpu/vpu30_p4_s6.mbn", +}; + +const struct iris_firmware_desc iris_vpu30_p4_gen2_desc = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu_buf_size, + .fwname = "qcom/vpu/vpu30_p4.mbn", +}; + +const struct iris_firmware_desc iris_vpu33_p4_gen2_desc = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu33_buf_size, + .fwname = "qcom/vpu/vpu33_p4.mbn", +}; + +const struct iris_firmware_desc iris_vpu35_p4_gen2_desc = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu33_buf_size, + .fwname = "qcom/vpu/vpu35_p4.mbn", +}; + static struct iris_fmt iris_fmts_vpu3x_dec[] = { [IRIS_FMT_H264] = { .pixfmt = V4L2_PIX_FMT_H264, @@ -122,8 +146,7 @@ static void sm8550_deinit_cb_devs(struct iris_core *core) * - inst_caps to platform_inst_cap_qcs8300 */ const struct iris_platform_data qcs8300_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu_buf_size, + .firmware_desc = &iris_vpu30_p4_s6_gen2_desc, .vpu_ops = &iris_vpu3_ops, .icc_tbl = iris_icc_info_vpu3x, .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu3x), @@ -140,7 +163,6 @@ const struct iris_platform_data qcs8300_data = { .opp_clk_tbl = iris_opp_clk_table_vpu3x, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu30_p4_s6.mbn", .inst_iris_fmts = iris_fmts_vpu3x_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), .inst_caps = &platform_inst_cap_qcs8300, @@ -154,8 +176,7 @@ const struct iris_platform_data qcs8300_data = { }; const struct iris_platform_data sm8550_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu_buf_size, + .firmware_desc = &iris_vpu30_p4_gen2_desc, .vpu_ops = &iris_vpu3_ops, .init_cb_devs = sm8550_init_cb_devs, .deinit_cb_devs = sm8550_deinit_cb_devs, @@ -174,7 +195,6 @@ const struct iris_platform_data sm8550_data = { .opp_clk_tbl = iris_opp_clk_table_vpu3x, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu30_p4.mbn", .inst_iris_fmts = iris_fmts_vpu3x_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), .inst_caps = &platform_inst_cap_sm8550, @@ -192,11 +212,9 @@ const struct iris_platform_data sm8550_data = { * - vpu_ops to iris_vpu33_ops * - clk_rst_tbl to sm8650_clk_reset_table * - controller_rst_tbl to sm8650_controller_reset_table - * - fwname to "qcom/vpu/vpu33_p4.mbn" */ const struct iris_platform_data sm8650_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu33_buf_size, + .firmware_desc = &iris_vpu33_p4_gen2_desc, .vpu_ops = &iris_vpu33_ops, .icc_tbl = iris_icc_info_vpu3x, .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu3x), @@ -215,7 +233,6 @@ const struct iris_platform_data sm8650_data = { .opp_clk_tbl = iris_opp_clk_table_vpu3x, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu33_p4.mbn", .inst_iris_fmts = iris_fmts_vpu3x_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), .inst_caps = &platform_inst_cap_sm8550, @@ -229,8 +246,7 @@ const struct iris_platform_data sm8650_data = { }; const struct iris_platform_data sm8750_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu33_buf_size, + .firmware_desc = &iris_vpu35_p4_gen2_desc, .vpu_ops = &iris_vpu35_ops, .icc_tbl = iris_icc_info_vpu3x, .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu3x), @@ -247,7 +263,6 @@ const struct iris_platform_data sm8750_data = { .opp_clk_tbl = iris_opp_clk_table_vpu3x, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu35_p4.mbn", .inst_iris_fmts = iris_fmts_vpu3x_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu3x_dec), .inst_caps = &platform_inst_cap_sm8550, diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c index ad283afddda6f..cbd5af0e651db 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c @@ -14,6 +14,12 @@ #include "iris_platform_kaanapali.h" +const struct iris_firmware_desc iris_vpu40_p2_s7_gen2_desc = { + .firmware_data = &iris_hfi_gen2_data, + .get_vpu_buffer_size = iris_vpu4x_buf_size, + .fwname = "qcom/vpu/vpu40_p2_s7.mbn", +}; + static struct iris_fmt iris_fmts_vpu4x_dec[] = { [IRIS_FMT_H264] = { .pixfmt = V4L2_PIX_FMT_H264, @@ -72,8 +78,7 @@ static struct ubwc_config_data iris_ubwc_config_vpu4x = { }; const struct iris_platform_data kaanapali_data = { - .firmware_data = &iris_hfi_gen2_data, - .get_vpu_buffer_size = iris_vpu4x_buf_size, + .firmware_desc = &iris_vpu40_p2_s7_gen2_desc, .vpu_ops = &iris_vpu4x_ops, .icc_tbl = iris_icc_info_vpu4x, .icc_tbl_size = ARRAY_SIZE(iris_icc_info_vpu4x), @@ -90,7 +95,6 @@ const struct iris_platform_data kaanapali_data = { .opp_clk_tbl = kaanapali_opp_clk_table, /* Upper bound of DMA address range */ .dma_mask = 0xe0000000 - 1, - .fwname = "qcom/vpu/vpu40_p2_s7.mbn", .inst_iris_fmts = iris_fmts_vpu4x_dec, .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_vpu4x_dec), .inst_caps = &iris_inst_cap_vpu4x, diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index 62725cfdb7a9f..5ef4e26df0c4b 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -258,7 +258,8 @@ static int iris_probe(struct platform_device *pdev) return core->irq; core->iris_platform_data = of_device_get_match_data(core->dev); - core->iris_firmware_data = core->iris_platform_data->firmware_data; + core->iris_firmware_desc = core->iris_platform_data->firmware_desc; + core->iris_firmware_data = core->iris_firmware_desc->firmware_data; ret = devm_request_threaded_irq(core->dev, core->irq, iris_hfi_isr, iris_hfi_isr_handler, IRQF_TRIGGER_HIGH, "iris", core); From dba3ddf5baad1c91a9210355dcf70d9833546604 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Sun, 19 Apr 2026 20:14:34 +0530 Subject: [PATCH 27/41] Revert "PENDING: media: iris: update MDT PAS load call for new API" This reverts commit e50a622d72418667d0747d59a772232054f85671. Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_firmware.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index 07b1d71505baf..2d5c0618e5d2a 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -30,6 +30,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) phys_addr_t mem_phys; size_t res_size; ssize_t fw_size; + void *mem_virt; int ret; if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4) @@ -60,16 +61,22 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) goto err_release_fw; } - ret = qcom_mdt_pas_load(ctx, firmware, fw_name, NULL); + mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC); + if (!mem_virt) { + ret = -ENOMEM; + goto err_release_fw; + } + + ret = qcom_mdt_pas_load(ctx, firmware, fw_name, mem_virt, NULL); qcom_scm_pas_metadata_release(ctx); if (ret) - goto err_release_fw; + goto err_mem_unmap; if (core->fw.iommu_domain) { ret = iommu_map(core->fw.iommu_domain, 0, mem_phys, res_size, IOMMU_READ | IOMMU_WRITE | IOMMU_PRIV, GFP_KERNEL); if (ret) - goto err_release_fw; + goto err_mem_unmap; } ret = qcom_scm_pas_prepare_and_auth_reset(ctx); @@ -82,6 +89,8 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) err_iommu_unmap: iommu_unmap(core->fw.iommu_domain, 0, res_size); +err_mem_unmap: + memunmap(mem_virt); err_release_fw: release_firmware(firmware); From f3333c319b219deed973e0235b011771598d8976 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 7 Apr 2026 15:37:33 +0530 Subject: [PATCH 28/41] media: iris: Skip UBWC configuration when not supported UBWC configuration is not applicable to all SoCs. Add a check to avoid configuring UBWC during sys init on unsupported platforms. Reviewed-by: Konrad Dybcio Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c index d77fa29f44fc6..8e065862378bf 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c @@ -136,6 +136,9 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); + if (!core->iris_platform_data->ubwc_config) + return; + payload = core->iris_platform_data->ubwc_config->max_channels; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_MAX_CHANNELS, From 6b9350311127f08a999e4b14ca8fdb8841558b0b Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 7 Apr 2026 15:43:24 +0530 Subject: [PATCH 29/41] media: iris: Filter UBWC raw formats based on hardware capabilities The raw formats supported by Iris were previously advertised unconditionally, assuming UBWC support on all platforms. However, some platforms do not support UBWC which results in incorrect format capability exposure. Use the UBWC configuration provided by the platform to dynamically filter raw formats at runtime. If UBWC is not supported, UBWC-based formats are omitted from the advertised capability list, while linear formats remain available. Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_vdec.c | 8 ++++++++ drivers/media/platform/qcom/iris/iris_venc.c | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index 1d34c7bcf8f8a..96fbfcedae643 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -82,6 +82,7 @@ static const struct iris_fmt iris_vdec_formats_cap[] = { static const struct iris_fmt * find_format(struct iris_inst *inst, u32 pixfmt, u32 type) { + struct ubwc_config_data *ubwc_config = inst->core->iris_platform_data->ubwc_config; const struct iris_fmt *fmt = NULL; unsigned int size = 0; unsigned int i; @@ -93,6 +94,9 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type) case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: fmt = iris_vdec_formats_cap; size = ARRAY_SIZE(iris_vdec_formats_cap); + /* Last format is UBWC; drop it if UBWC is unsupported */ + if (!ubwc_config) + size--; break; default: return NULL; @@ -112,6 +116,7 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type) static const struct iris_fmt * find_format_by_index(struct iris_inst *inst, u32 index, u32 type) { + struct ubwc_config_data *ubwc_config = inst->core->iris_platform_data->ubwc_config; const struct iris_fmt *fmt = NULL; unsigned int size = 0; @@ -123,6 +128,9 @@ find_format_by_index(struct iris_inst *inst, u32 index, u32 type) case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: fmt = iris_vdec_formats_cap; size = ARRAY_SIZE(iris_vdec_formats_cap); + /* Last format is UBWC; drop it if UBWC is unsupported */ + if (!ubwc_config) + size--; break; default: return NULL; diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c index aeed756ee9cac..c53d117153cf2 100644 --- a/drivers/media/platform/qcom/iris/iris_venc.c +++ b/drivers/media/platform/qcom/iris/iris_venc.c @@ -110,6 +110,7 @@ static const struct iris_fmt iris_venc_formats_out[] = { static const struct iris_fmt * find_format(struct iris_inst *inst, u32 pixfmt, u32 type) { + struct ubwc_config_data *ubwc_config = inst->core->iris_platform_data->ubwc_config; const struct iris_fmt *fmt = NULL; unsigned int size = 0; unsigned int i; @@ -117,6 +118,9 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type) case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: fmt = iris_venc_formats_out; size = ARRAY_SIZE(iris_venc_formats_out); + /* Last format is UBWC; drop it if UBWC is unsupported */ + if (!ubwc_config) + size--; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: fmt = iris_venc_formats_cap; @@ -140,6 +144,7 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type) static const struct iris_fmt * find_format_by_index(struct iris_inst *inst, u32 index, u32 type) { + struct ubwc_config_data *ubwc_config = inst->core->iris_platform_data->ubwc_config; const struct iris_fmt *fmt = NULL; unsigned int size = 0; @@ -147,6 +152,9 @@ find_format_by_index(struct iris_inst *inst, u32 index, u32 type) case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: fmt = iris_venc_formats_out; size = ARRAY_SIZE(iris_venc_formats_out); + /* Last format is UBWC; drop it if UBWC is unsupported */ + if (!ubwc_config) + size--; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: fmt = iris_venc_formats_cap; From b05dc320d1346b22fdf8435db8273c063de7724d Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 17 Mar 2026 18:15:03 +0530 Subject: [PATCH 30/41] media: iris: Introduce set_preset_register as a vpu_op The set_preset_registers sequence is currently shared across all supported devices. Starting with Qualcomm QCM2290 (AR50LT), the register programming would differ. Move set_preset_register into a vpu_op to allow per-device customization. This change prepares the driver for upcoming hardware variants. No functional change so far for existing devices. Reviewed-by: Dmitry Baryshkov Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_platform_common.h | 1 - drivers/media/platform/qcom/iris/iris_vpu2.c | 1 + drivers/media/platform/qcom/iris/iris_vpu3x.c | 3 +++ drivers/media/platform/qcom/iris/iris_vpu4x.c | 1 + drivers/media/platform/qcom/iris/iris_vpu_common.c | 2 +- drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 + 6 files changed, 7 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 1204342aa6c5d..b759889b5271f 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -275,7 +275,6 @@ struct iris_platform_data { const struct iris_firmware_desc *firmware_desc; const struct vpu_ops *vpu_ops; - void (*set_preset_registers)(struct iris_core *core); int (*init_cb_devs)(struct iris_core *core); void (*deinit_cb_devs)(struct iris_core *core); const struct icc_info *icc_tbl; diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c index b8714dcbad10a..2dc121a3f5e89 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c @@ -45,4 +45,5 @@ const struct vpu_ops iris_vpu2_ops = { .power_on_controller = iris_vpu_power_on_controller, .calc_freq = iris_vpu2_calc_freq, .set_hwmode = iris_vpu_set_hwmode, + .set_preset_registers = iris_vpu_set_preset_registers, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c index 3dad47be78b58..dc02ced1b9314 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c @@ -261,6 +261,7 @@ const struct vpu_ops iris_vpu3_ops = { .power_on_controller = iris_vpu_power_on_controller, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu_set_hwmode, + .set_preset_registers = iris_vpu_set_preset_registers, }; const struct vpu_ops iris_vpu33_ops = { @@ -270,6 +271,7 @@ const struct vpu_ops iris_vpu33_ops = { .power_on_controller = iris_vpu_power_on_controller, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu_set_hwmode, + .set_preset_registers = iris_vpu_set_preset_registers, }; const struct vpu_ops iris_vpu35_ops = { @@ -280,4 +282,5 @@ const struct vpu_ops iris_vpu35_ops = { .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu_set_hwmode, + .set_preset_registers = iris_vpu_set_preset_registers, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu4x.c b/drivers/media/platform/qcom/iris/iris_vpu4x.c index 02e100a4045fc..f608a297d4a34 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu4x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu4x.c @@ -368,4 +368,5 @@ const struct vpu_ops iris_vpu4x_ops = { .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers, .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu4x_set_hwmode, + .set_preset_registers = iris_vpu_set_preset_registers, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index ca96e91222c67..17a1dd27d5d8a 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -476,7 +476,7 @@ int iris_vpu_power_on(struct iris_core *core) iris_opp_set_rate(core->dev, freq); - iris_vpu_set_preset_registers(core); + core->iris_platform_data->vpu_ops->set_preset_registers(core); iris_vpu_interrupt_init(core); core->intr_status = 0; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index 09799a375c142..21ed4c9bd5e34 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -22,6 +22,7 @@ struct vpu_ops { void (*program_bootup_registers)(struct iris_core *core); u64 (*calc_freq)(struct iris_inst *inst, size_t data_size); int (*set_hwmode)(struct iris_core *core); + void (*set_preset_registers)(struct iris_core *core); }; int iris_vpu_boot_firmware(struct iris_core *core); From bea0a98c128f6acf2140376f30a201b9d660863a Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 17 Mar 2026 19:37:11 +0530 Subject: [PATCH 31/41] media: iris: Introduce interrupt_init as a vpu_op The interrupt_init sequence is currently shared across all supported devices. Starting with Qualcomm QCM2290 (AR50LT), the register programming would differ. Move interrupt_init into a vpu_op to allow per-device customization. This change prepares the driver for upcoming hardware variants. No functional change so far for existing devices. Reviewed-by: Dmitry Baryshkov Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_vpu2.c | 1 + drivers/media/platform/qcom/iris/iris_vpu3x.c | 3 +++ drivers/media/platform/qcom/iris/iris_vpu4x.c | 1 + drivers/media/platform/qcom/iris/iris_vpu_common.c | 4 ++-- drivers/media/platform/qcom/iris/iris_vpu_common.h | 2 ++ 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c index 2dc121a3f5e89..dd2eeae0d9eb8 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c @@ -46,4 +46,5 @@ const struct vpu_ops iris_vpu2_ops = { .calc_freq = iris_vpu2_calc_freq, .set_hwmode = iris_vpu_set_hwmode, .set_preset_registers = iris_vpu_set_preset_registers, + .interrupt_init = iris_vpu_interrupt_init, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c index dc02ced1b9314..c3b760730c981 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c @@ -262,6 +262,7 @@ const struct vpu_ops iris_vpu3_ops = { .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu_set_hwmode, .set_preset_registers = iris_vpu_set_preset_registers, + .interrupt_init = iris_vpu_interrupt_init, }; const struct vpu_ops iris_vpu33_ops = { @@ -272,6 +273,7 @@ const struct vpu_ops iris_vpu33_ops = { .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu_set_hwmode, .set_preset_registers = iris_vpu_set_preset_registers, + .interrupt_init = iris_vpu_interrupt_init, }; const struct vpu_ops iris_vpu35_ops = { @@ -283,4 +285,5 @@ const struct vpu_ops iris_vpu35_ops = { .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu_set_hwmode, .set_preset_registers = iris_vpu_set_preset_registers, + .interrupt_init = iris_vpu_interrupt_init, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu4x.c b/drivers/media/platform/qcom/iris/iris_vpu4x.c index f608a297d4a34..90ccdc0d2a076 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu4x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu4x.c @@ -369,4 +369,5 @@ const struct vpu_ops iris_vpu4x_ops = { .calc_freq = iris_vpu3x_vpu4x_calculate_frequency, .set_hwmode = iris_vpu4x_set_hwmode, .set_preset_registers = iris_vpu_set_preset_registers, + .interrupt_init = iris_vpu_interrupt_init, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index 17a1dd27d5d8a..03143648a3a85 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -31,7 +31,7 @@ #define UC_REGION_ADDR (CPU_CS_BASE_OFFS + 0x64) #define UC_REGION_SIZE (CPU_CS_BASE_OFFS + 0x68) -static void iris_vpu_interrupt_init(struct iris_core *core) +void iris_vpu_interrupt_init(struct iris_core *core) { u32 mask_val; @@ -478,7 +478,7 @@ int iris_vpu_power_on(struct iris_core *core) core->iris_platform_data->vpu_ops->set_preset_registers(core); - iris_vpu_interrupt_init(core); + core->iris_platform_data->vpu_ops->interrupt_init(core); core->intr_status = 0; enable_irq(core->irq); diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index 21ed4c9bd5e34..9151545065cda 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -23,6 +23,7 @@ struct vpu_ops { u64 (*calc_freq)(struct iris_inst *inst, size_t data_size); int (*set_hwmode)(struct iris_core *core); void (*set_preset_registers)(struct iris_core *core); + void (*interrupt_init)(struct iris_core *core); }; int iris_vpu_boot_firmware(struct iris_core *core); @@ -44,5 +45,6 @@ void iris_vpu35_vpu4x_program_bootup_registers(struct iris_core *core); u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t data_size); void iris_vpu_set_preset_registers(struct iris_core *core); +void iris_vpu_interrupt_init(struct iris_core *core); #endif From 5101832daf305fb0e8310247274089e444f009e4 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Wed, 1 Apr 2026 12:55:26 +0530 Subject: [PATCH 32/41] media: iris: add vpu op hook to disable ARP buffer On AR50LT platforms AbsolutelyPerfectRouting (ARP) needs to be disabled so firmware can configure the ARP internal buffer as non-secure for encoder usage. In preparation of adding support for AR50LT platforms, add an optional disable_arp callback to the VPU ops and invoke it from core init and resume paths. No functional change for existing platforms. Reviewed-by: Dmitry Baryshkov Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_core.c | 4 ++++ drivers/media/platform/qcom/iris/iris_hfi_common.c | 4 ++++ drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_core.c b/drivers/media/platform/qcom/iris/iris_core.c index 48a5bd39d836f..f56dda26cca86 100644 --- a/drivers/media/platform/qcom/iris/iris_core.c +++ b/drivers/media/platform/qcom/iris/iris_core.c @@ -46,6 +46,7 @@ static int iris_wait_for_system_response(struct iris_core *core) int iris_core_init(struct iris_core *core) { + const struct vpu_ops *vpu_ops = core->iris_platform_data->vpu_ops; int ret; mutex_lock(&core->lock); @@ -83,6 +84,9 @@ int iris_core_init(struct iris_core *core) if (ret) goto error_unload_fw; + if (vpu_ops->disable_arp) + vpu_ops->disable_arp(core); + ret = iris_hfi_core_init(core); if (ret) goto error_unload_fw; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/media/platform/qcom/iris/iris_hfi_common.c index 8769ec61f1176..8f04f3793d9af 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.c @@ -144,6 +144,7 @@ int iris_hfi_pm_suspend(struct iris_core *core) int iris_hfi_pm_resume(struct iris_core *core) { + const struct vpu_ops *vpu_ops = core->iris_platform_data->vpu_ops; const struct iris_hfi_sys_ops *ops = core->hfi_sys_ops; int ret; @@ -163,6 +164,9 @@ int iris_hfi_pm_resume(struct iris_core *core) if (ret) goto err_suspend_hw; + if (vpu_ops->disable_arp) + vpu_ops->disable_arp(core); + ret = ops->sys_interframe_powercollapse(core); if (ret) goto err_suspend_hw; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index 9151545065cda..71d96921ed372 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -24,6 +24,7 @@ struct vpu_ops { int (*set_hwmode)(struct iris_core *core); void (*set_preset_registers)(struct iris_core *core); void (*interrupt_init)(struct iris_core *core); + void (*disable_arp)(struct iris_core *core); }; int iris_vpu_boot_firmware(struct iris_core *core); From 36603b973d176f73e9fbdee5488be91103bd78ca Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 6 Apr 2026 14:54:02 +0530 Subject: [PATCH 33/41] media: iris: Add platform data field for watchdog interrupt mask For AR50LT core, the value of WRAPPER_INTR_STATUS_A2HWD_BMASK differs from the currently supported VPUs. In preparation for adding AR50LT support in subsequent patches, introduce a platform data field, wd_intr_mask, to capture the watchdog interrupt bitmask per platform. Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_platform_common.h | 1 + drivers/media/platform/qcom/iris/iris_platform_vpu2.c | 4 ++++ drivers/media/platform/qcom/iris/iris_platform_vpu3x.c | 6 ++++++ drivers/media/platform/qcom/iris/iris_platform_vpu4x.c | 3 +++ drivers/media/platform/qcom/iris/iris_vpu_common.c | 8 +++++--- .../media/platform/qcom/iris/iris_vpu_register_defines.h | 1 - 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index b759889b5271f..f5a4a575042f6 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -301,6 +301,7 @@ struct iris_platform_data { struct ubwc_config_data *ubwc_config; u32 num_vpp_pipe; bool no_aon; + u32 wd_intr_mask; u32 max_session_count; /* max number of macroblocks per frame supported */ u32 max_core_mbpf; diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c index ff8ce078238a5..78f9fa446bf33 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c @@ -16,6 +16,8 @@ #include "iris_platform_sc7280.h" #include "iris_platform_sm8250.h" +#define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) + const struct iris_firmware_desc iris_vpu20_p1_gen1_desc = { .firmware_data = &iris_hfi_gen1_data, .get_vpu_buffer_size = iris_vpu_buf_size, @@ -96,6 +98,7 @@ const struct iris_platform_data sc7280_data = { .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2), .num_vpp_pipe = 1, .no_aon = true, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, .max_session_count = 16, .max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256, /* max spec for SC7280 is 4096x2176@60fps */ @@ -126,6 +129,7 @@ const struct iris_platform_data sm8250_data = { .tz_cp_config_data = tz_cp_config_vpu2, .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2), .num_vpp_pipe = 4, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K, .max_core_mbps = ((7680 * 4320) / 256) * 60, diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c index 0d33196cc396d..c0a4cec30bb51 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c @@ -17,6 +17,8 @@ #include "iris_platform_sm8650.h" #include "iris_platform_sm8750.h" +#define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) + const struct iris_firmware_desc iris_vpu30_p4_s6_gen2_desc = { .firmware_data = &iris_hfi_gen2_data, .get_vpu_buffer_size = iris_vpu_buf_size, @@ -170,6 +172,7 @@ const struct iris_platform_data qcs8300_data = { .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 2, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, .max_session_count = 16, .max_core_mbpf = ((4096 * 2176) / 256) * 4, .max_core_mbps = (((3840 * 2176) / 256) * 120), @@ -202,6 +205,7 @@ const struct iris_platform_data sm8550_data = { .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 4, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, @@ -240,6 +244,7 @@ const struct iris_platform_data sm8650_data = { .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 4, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, @@ -270,6 +275,7 @@ const struct iris_platform_data sm8750_data = { .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu3), .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 4, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c index cbd5af0e651db..60401893f551f 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c @@ -14,6 +14,8 @@ #include "iris_platform_kaanapali.h" +#define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) + const struct iris_firmware_desc iris_vpu40_p2_s7_gen2_desc = { .firmware_data = &iris_hfi_gen2_data, .get_vpu_buffer_size = iris_vpu4x_buf_size, @@ -102,6 +104,7 @@ const struct iris_platform_data kaanapali_data = { .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_kaanapali), .ubwc_config = &iris_ubwc_config_vpu4x, .num_vpp_pipe = 2, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((8192 * 4352) / 256) * 60, diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index 03143648a3a85..cdf11e978af45 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -109,11 +109,11 @@ void iris_vpu_raise_interrupt(struct iris_core *core) void iris_vpu_clear_interrupt(struct iris_core *core) { + u32 wd_intr_mask = core->iris_platform_data->wd_intr_mask; u32 intr_status, mask; intr_status = readl(core->reg_base + WRAPPER_INTR_STATUS); - mask = (WRAPPER_INTR_STATUS_A2H_BMSK | - WRAPPER_INTR_STATUS_A2HWD_BMSK | + mask = (WRAPPER_INTR_STATUS_A2H_BMSK | wd_intr_mask | CTRL_INIT_IDLE_MSG_BMSK); if (intr_status & mask) @@ -124,7 +124,9 @@ void iris_vpu_clear_interrupt(struct iris_core *core) int iris_vpu_watchdog(struct iris_core *core, u32 intr_status) { - if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK) { + u32 wd_intr_mask = core->iris_platform_data->wd_intr_mask; + + if (intr_status & wd_intr_mask) { dev_err(core->dev, "received watchdog interrupt\n"); return -ETIME; } diff --git a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h index 72168b9ffa738..4fffa094c52fe 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h @@ -41,7 +41,6 @@ #define MSK_CORE_POWER_ON BIT(1) #define WRAPPER_INTR_STATUS (WRAPPER_BASE_OFFS + 0x0C) -#define WRAPPER_INTR_STATUS_A2HWD_BMSK BIT(3) #define WRAPPER_INTR_STATUS_A2H_BMSK BIT(2) #define WRAPPER_INTR_MASK (WRAPPER_BASE_OFFS + 0x10) From a6da7a2fd3f8adc9f296900f3fe68ba6bb23e549 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Mon, 6 Apr 2026 15:55:36 +0530 Subject: [PATCH 34/41] media: iris: Add platform flag for instantaneous bandwidth voting AR50LT require explicit instantaneous bandwidth (IB) voting in addition to average bandwidth (AB) when configuring interconnect QoS. This requirement is due to QSB (Qualcomm System Bus) 128b to QNS ( Qualcomm Network Switch) 256b conversion at video noc in AR50LT which is not needed for other IRIS cores. In preparation of adding support for AR50LT core, introduce platform-configurable IB multiplier and enable IB voting for all SoCs. Existing platforms default to IB == AB, while AR50LT requires 2x peak bandwidth. Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/iris_platform_common.h | 1 + drivers/media/platform/qcom/iris/iris_platform_vpu2.c | 2 ++ drivers/media/platform/qcom/iris/iris_platform_vpu3x.c | 4 ++++ drivers/media/platform/qcom/iris/iris_platform_vpu4x.c | 1 + drivers/media/platform/qcom/iris/iris_resources.c | 2 ++ 5 files changed, 10 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index f5a4a575042f6..938e38be5242d 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -302,6 +302,7 @@ struct iris_platform_data { u32 num_vpp_pipe; bool no_aon; u32 wd_intr_mask; + u32 icc_ib_multiplier; u32 max_session_count; /* max number of macroblocks per frame supported */ u32 max_core_mbpf; diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c index 78f9fa446bf33..7eaf334bcb58b 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu2.c @@ -99,6 +99,7 @@ const struct iris_platform_data sc7280_data = { .num_vpp_pipe = 1, .no_aon = true, .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 1, .max_session_count = 16, .max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256, /* max spec for SC7280 is 4096x2176@60fps */ @@ -130,6 +131,7 @@ const struct iris_platform_data sm8250_data = { .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_vpu2), .num_vpp_pipe = 4, .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 1, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K, .max_core_mbps = ((7680 * 4320) / 256) * 60, diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c index c0a4cec30bb51..fd6f836cf3f7a 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu3x.c @@ -173,6 +173,7 @@ const struct iris_platform_data qcs8300_data = { .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 2, .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 1, .max_session_count = 16, .max_core_mbpf = ((4096 * 2176) / 256) * 4, .max_core_mbps = (((3840 * 2176) / 256) * 120), @@ -206,6 +207,7 @@ const struct iris_platform_data sm8550_data = { .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 4, .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 1, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, @@ -245,6 +247,7 @@ const struct iris_platform_data sm8650_data = { .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 4, .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 1, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, @@ -276,6 +279,7 @@ const struct iris_platform_data sm8750_data = { .ubwc_config = &iris_ubwc_config_vpu3x, .num_vpp_pipe = 4, .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 1, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((7680 * 4320) / 256) * 60, diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c index 60401893f551f..fbf41da81933e 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu4x.c @@ -105,6 +105,7 @@ const struct iris_platform_data kaanapali_data = { .ubwc_config = &iris_ubwc_config_vpu4x, .num_vpp_pipe = 2, .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 1, .max_session_count = 16, .max_core_mbpf = NUM_MBS_8K * 2, .max_core_mbps = ((8192 * 4352) / 256) * 60, diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c index b10884eb3ac64..e9b0e6a3ad686 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.c +++ b/drivers/media/platform/qcom/iris/iris_resources.c @@ -20,6 +20,7 @@ int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw) { + u32 icc_ib_multiplier = core->iris_platform_data->icc_ib_multiplier; unsigned long bw_kbps = 0, bw_prev = 0; const struct icc_info *icc_tbl; int ret = 0, i; @@ -38,6 +39,7 @@ int iris_set_icc_bw(struct iris_core *core, unsigned long icc_bw) return ret; core->icc_tbl[i].avg_bw = bw_kbps; + core->icc_tbl[i].peak_bw = bw_kbps * icc_ib_multiplier; core->power.icc_bw = bw_kbps; break; From 5a54122fa0ab40183d7eb486691e3a35ef977b0f Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 17 Mar 2026 20:01:18 +0530 Subject: [PATCH 35/41] media: iris: Add framework support for AR50_LITE video core Add power sequence for ar5lt core. Add register handling for ar50lt by hooking up vpu op with ar50lt specific implementation or reuse from earlier generation wherever feasible. Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/Makefile | 1 + .../platform/qcom/iris/iris_platform_common.h | 2 + .../platform/qcom/iris/iris_vpu_ar50lt.c | 156 ++++++++++++++++++ .../platform/qcom/iris/iris_vpu_common.c | 3 +- .../platform/qcom/iris/iris_vpu_common.h | 1 + 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 drivers/media/platform/qcom/iris/iris_vpu_ar50lt.c diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile index f8a017d878d62..49a90e1622b39 100644 --- a/drivers/media/platform/qcom/iris/Makefile +++ b/drivers/media/platform/qcom/iris/Makefile @@ -27,6 +27,7 @@ qcom-iris-objs += iris_buffer.o \ iris_vpu2.o \ iris_vpu3x.o \ iris_vpu4x.o \ + iris_vpu_ar50lt.o \ iris_vpu_buffer.o \ iris_vpu_common.o \ diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 938e38be5242d..1f334a6f3faef 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -64,6 +64,7 @@ enum platform_clk_type { IRIS_VPP0_HW_CLK, IRIS_VPP1_HW_CLK, IRIS_APV_HW_CLK, + IRIS_THROTTLE_CLK, }; struct platform_clk_data { @@ -301,6 +302,7 @@ struct iris_platform_data { struct ubwc_config_data *ubwc_config; u32 num_vpp_pipe; bool no_aon; + bool no_rpmh; u32 wd_intr_mask; u32 icc_ib_multiplier; u32 max_session_count; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_ar50lt.c b/drivers/media/platform/qcom/iris/iris_vpu_ar50lt.c new file mode 100644 index 0000000000000..688b57291a815 --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_vpu_ar50lt.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2026 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include + +#include "iris_instance.h" +#include "iris_vpu_common.h" + +#include "iris_vpu_register_defines.h" + +#define WRAPPER_INTR_MASK_A2HVCODEC_BMSK_AR50LT BIT(3) + +#define WRAPPER_VCODEC0_CLOCK_CONFIG_AR50LT 0xb0080 + +#define CPU_CS_VCICMD 0xa0020 +#define CPU_CS_VCICMD_ARP_OFF 0x1 + +static void iris_vpu_ar50lt_set_preset_registers(struct iris_core *core) +{ + writel(0x0, core->reg_base + WRAPPER_VCODEC0_CLOCK_CONFIG_AR50LT); +} + +static void iris_vpu_ar50lt_interrupt_init(struct iris_core *core) +{ + writel(WRAPPER_INTR_MASK_A2HVCODEC_BMSK_AR50LT, core->reg_base + WRAPPER_INTR_MASK); +} + +static void iris_vpu_ar50lt_disable_arp(struct iris_core *core) +{ + writel(CPU_CS_VCICMD_ARP_OFF, core->reg_base + CPU_CS_VCICMD); +} + +static int iris_vpu_ar50lt_power_off_controller(struct iris_core *core) +{ + iris_disable_unprepare_clock(core, IRIS_AHB_CLK); + iris_disable_unprepare_clock(core, IRIS_AXI_CLK); + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); + + return 0; +} + +static void iris_vpu_ar50lt_power_off_hw(struct iris_core *core) +{ + dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], false); + iris_disable_unprepare_clock(core, IRIS_THROTTLE_CLK); + iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK); + iris_disable_unprepare_clock(core, IRIS_HW_CLK); + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); +} + +static int iris_vpu_ar50lt_power_on_controller(struct iris_core *core) +{ + int ret; + + ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); + if (ret) + return ret; + + ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK); + if (ret) + goto err_disable_power; + + ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK); + if (ret && ret != -ENOENT) + goto err_disable_ctrl_clock; + + ret = iris_prepare_enable_clock(core, IRIS_AHB_CLK); + if (ret) + goto err_disable_axi_clock; + + return 0; + +err_disable_axi_clock: + iris_disable_unprepare_clock(core, IRIS_AXI_CLK); +err_disable_ctrl_clock: + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); +err_disable_power: + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); + + return ret; +} + +static int iris_vpu_ar50lt_power_on_hw(struct iris_core *core) +{ + int ret; + + ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); + if (ret) + return ret; + + ret = iris_prepare_enable_clock(core, IRIS_HW_CLK); + if (ret) + goto err_disable_power; + + ret = iris_prepare_enable_clock(core, IRIS_HW_AHB_CLK); + if (ret) + goto err_disable_hw_clock; + + ret = iris_prepare_enable_clock(core, IRIS_THROTTLE_CLK); + if (ret && ret != -ENOENT) + goto err_disable_hw_ahb_clock; + + return 0; + +err_disable_hw_ahb_clock: + iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK); +err_disable_hw_clock: + iris_disable_unprepare_clock(core, IRIS_HW_CLK); +err_disable_power: + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); + + return ret; +} + +static u64 iris_vpu_ar50lt_calc_freq(struct iris_inst *inst, size_t data_size) +{ + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; + struct v4l2_format *inp_f = inst->fmt_src; + u32 mbs_per_second, mbpf, height, width; + unsigned long vpp_freq, vsp_freq; + u32 fps = DEFAULT_FPS; + + width = max(inp_f->fmt.pix_mp.width, inst->crop.width); + height = max(inp_f->fmt.pix_mp.height, inst->crop.height); + + mbpf = NUM_MBS_PER_FRAME(height, width); + mbs_per_second = mbpf * fps; + + vpp_freq = mbs_per_second * caps->mb_cycles_vpp; + + /* 21 / 20 is overhead factor */ + vpp_freq += vpp_freq / 20; + vsp_freq = mbs_per_second * caps->mb_cycles_vsp; + + /* 10 / 7 is overhead factor */ + vsp_freq += ((fps * data_size * 8) * 10) / 7; + + return max(vpp_freq, vsp_freq); +} + +const struct vpu_ops iris_vpu_ar50lt_ops = { + .power_off_hw = iris_vpu_ar50lt_power_off_hw, + .power_on_hw = iris_vpu_ar50lt_power_on_hw, + .power_off_controller = iris_vpu_ar50lt_power_off_controller, + .power_on_controller = iris_vpu_ar50lt_power_on_controller, + .calc_freq = iris_vpu_ar50lt_calc_freq, + .set_hwmode = iris_vpu_set_hwmode, + .set_preset_registers = iris_vpu_ar50lt_set_preset_registers, + .interrupt_init = iris_vpu_ar50lt_interrupt_init, + .disable_arp = iris_vpu_ar50lt_disable_arp, +}; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index cdf11e978af45..7fa762f6f7a9f 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -97,7 +97,8 @@ int iris_vpu_boot_firmware(struct iris_core *core) } writel(HOST2XTENSA_INTR_ENABLE, core->reg_base + CPU_CS_H2XSOFTINTEN); - writel(0x0, core->reg_base + CPU_CS_X2RPMH); + if (!core->iris_platform_data->no_rpmh) + writel(0x0, core->reg_base + CPU_CS_X2RPMH); return 0; } diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index 71d96921ed372..f00e2de5fa537 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -13,6 +13,7 @@ extern const struct vpu_ops iris_vpu3_ops; extern const struct vpu_ops iris_vpu33_ops; extern const struct vpu_ops iris_vpu35_ops; extern const struct vpu_ops iris_vpu4x_ops; +extern const struct vpu_ops iris_vpu_ar50lt_ops; struct vpu_ops { void (*power_off_hw)(struct iris_core *core); From 6161b88516f8f44da5888e5415d8e1a1a2643eb3 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 17 Mar 2026 20:39:36 +0530 Subject: [PATCH 36/41] media: iris: Introduce buffer size calculations for AR50LT Introduces AR50LT buffer size calculation for both encoder and decoder. Reuse the buffer size calculation which are common, while adding the AR50LT specific ones separately. Signed-off-by: Dikshita Agarwal --- .../platform/qcom/iris/iris_vpu_buffer.c | 402 ++++++++++++++++++ .../platform/qcom/iris/iris_vpu_buffer.h | 37 ++ 2 files changed, 439 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c index 9270422c16019..938019cf4f126 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.c @@ -50,6 +50,32 @@ static u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height, u32 num_vpp_p return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); } +static u32 size_h264d_hw_bin_buffer_ar50lt(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 size_yuv, size_bin_hdr, size_bin_res; + + size_yuv = ((frame_width * frame_height * 3) >> 1); + if (size_yuv <= 1920 * 1088 * 3 / 2) { + size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_SM_TOT; + size_bin_res = size_yuv * H264_CABAC_RES_RATIO_SM_TOT; + } else { + size_bin_hdr = (size_yuv * 3) / 5; + size_bin_res = (size_yuv * 3) / 2; + } + size_bin_hdr = ALIGN(size_bin_hdr, DMA_ALIGNMENT); + size_bin_res = ALIGN(size_bin_res, DMA_ALIGNMENT); + + return size_bin_hdr + size_bin_res; +} + +static u32 hfi_buffer_bin_h264d_ar50lt(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 n_aligned_h = ALIGN(frame_height, 16); + u32 n_aligned_w = ALIGN(frame_width, 16); + + return size_h264d_hw_bin_buffer_ar50lt(n_aligned_w, n_aligned_h, num_vpp_pipes); +} + static u32 size_av1d_hw_bin_buffer(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) { u32 size_yuv, size_bin_hdr, size_bin_res; @@ -103,6 +129,21 @@ static u32 hfi_buffer_bin_vp9d(u32 frame_width, u32 frame_height, u32 num_vpp_pi return _size * num_vpp_pipes; } +static u32 hfi_buffer_bin_vp9d_ar50lt(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 size_yuv, size; + + size_yuv = ALIGN(frame_width, 16) * ALIGN(frame_height, 16) * 3 / 2; + size_yuv = ALIGN(size_yuv, DMA_ALIGNMENT); + + size = ALIGN(((((MAX(size_yuv, VPX_DECODER_FRAME_BIN_BUFFER_SIZE)) * 6) / 5) / + num_vpp_pipes), DMA_ALIGNMENT) + + ALIGN((((MAX(size_yuv, VPX_DECODER_FRAME_BIN_BUFFER_SIZE)) * 4) / num_vpp_pipes), + DMA_ALIGNMENT); + + return size * num_vpp_pipes; +} + static u32 hfi_buffer_bin_h265d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) { u32 n_aligned_w = ALIGN(frame_width, 16); @@ -111,6 +152,32 @@ static u32 hfi_buffer_bin_h265d(u32 frame_width, u32 frame_height, u32 num_vpp_p return size_h265d_hw_bin_buffer(n_aligned_w, n_aligned_h, num_vpp_pipes); } +static u32 size_h265d_hw_bin_buffer_ar50lt(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 size_yuv, size_bin_hdr, size_bin_res; + + size_yuv = ((frame_width * frame_height * 3) >> 1); + if (size_yuv <= ((BIN_BUFFER_THRESHOLD * 3) >> 1)) { + size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_SM_TOT; + size_bin_res = size_yuv * H265_CABAC_RES_RATIO_SM_TOT; + } else { + size_bin_hdr = (size_yuv * 41) / 50; + size_bin_res = (size_yuv * 59) / 50; + } + size_bin_hdr = ALIGN(size_bin_hdr, DMA_ALIGNMENT); + size_bin_res = ALIGN(size_bin_res, DMA_ALIGNMENT); + + return size_bin_hdr + size_bin_res; +} + +static u32 hfi_buffer_bin_h265d_ar50lt(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 n_aligned_w = ALIGN(frame_width, 16); + u32 n_aligned_h = ALIGN(frame_height, 16); + + return size_h265d_hw_bin_buffer_ar50lt(n_aligned_w, n_aligned_h, num_vpp_pipes); +} + static u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height, u32 _comv_bufcount) { u32 frame_height_in_mbs = DIV_ROUND_UP(frame_height, 16); @@ -174,17 +241,38 @@ static u32 size_h264d_bse_cmd_buf(u32 frame_height) SIZE_H264D_BSE_CMD_PER_BUF; } +static u32 size_h264d_bse_cmd_buf_ar50lt(u32 frame_height) +{ + u32 height = ALIGN(frame_height, 32); + + return min_t(u32, (DIV_ROUND_UP(height, 16) * 12), H264D_MAX_SLICE) * + SIZE_H264D_BSE_CMD_PER_BUF; +} + static u32 size_h265d_bse_cmd_buf(u32 frame_width, u32 frame_height) { u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * NUM_HW_PIC_BUF, DMA_ALIGNMENT); + _size = min_t(u32, _size, H265D_MAX_SLICE + 1); _size = 2 * _size * SIZE_H265D_BSE_CMD_PER_BUF; return _size; } +static u32 size_h265d_bse_cmd_buf_ar50lt(u32 frame_width, u32 frame_height) +{ + u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * + NUM_HW_PIC_BUF, DMA_ALIGNMENT); + + _size = min_t(u32, _size, H265D_MAX_SLICE_AR50LT + 1); + _size = 2 * _size * SIZE_H265D_BSE_CMD_PER_BUF; + + return _size; +} + static u32 hfi_buffer_persist_h265d(u32 rpu_enabled) { return ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 + @@ -195,6 +283,13 @@ static u32 hfi_buffer_persist_h265d(u32 rpu_enabled) DMA_ALIGNMENT); } +static u32 hfi_buffer_persist_h265d_ar50lt(void) +{ + return ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 + + H265_NUM_TILE * sizeof(u32) + NUM_HW_PIC_BUF * SIZE_SEI_USERDATA), + DMA_ALIGNMENT); +} + static inline u32 hfi_iris3_vp9d_comv_size(void) { @@ -212,6 +307,13 @@ static u32 hfi_buffer_persist_vp9d(void) HDR10_HIST_EXTRADATA_SIZE; } +static u32 hfi_buffer_persist_vp9d_ar50lt(void) +{ + return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE, DMA_ALIGNMENT) + + ALIGN(hfi_iris3_vp9d_comv_size(), DMA_ALIGNMENT) + + ALIGN(MAX_SUPERFRAME_HEADER_LEN, DMA_ALIGNMENT); +} + static u32 size_h264d_vpp_cmd_buf(u32 frame_height) { u32 size, height = ALIGN(frame_height, 32); @@ -222,6 +324,16 @@ static u32 size_h264d_vpp_cmd_buf(u32 frame_height) return size > VPP_CMD_MAX_SIZE ? VPP_CMD_MAX_SIZE : size; } +static u32 size_h264d_vpp_cmd_buf_ar50lt(u32 frame_height) +{ + u32 size, height = ALIGN(frame_height, 32); + + size = min_t(u32, (DIV_ROUND_UP(height, 16) * 12), H264D_MAX_SLICE) * + SIZE_H264D_VPP_CMD_PER_BUF; + + return size > VPP_CMD_MAX_SIZE ? VPP_CMD_MAX_SIZE : size; +} + static u32 hfi_buffer_persist_h264d(void) { return ALIGN(SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 + @@ -230,6 +342,11 @@ static u32 hfi_buffer_persist_h264d(void) DMA_ALIGNMENT); } +static u32 hfi_buffer_persist_h264d_ar50lt(void) +{ + return ALIGN((SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264), DMA_ALIGNMENT); +} + static u32 hfi_buffer_persist_av1d(u32 max_width, u32 max_height, u32 total_ref_count) { u32 comv_size, size; @@ -255,6 +372,17 @@ static u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height, u32 num_ return ALIGN(size, DMA_ALIGNMENT); } +static u32 hfi_buffer_non_comv_h264d_ar50lt(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 size_bse = size_h264d_bse_cmd_buf_ar50lt(frame_height); + u32 size_vpp = size_h264d_vpp_cmd_buf_ar50lt(frame_height); + u32 size = ALIGN(size_bse, DMA_ALIGNMENT) + + ALIGN(size_vpp, DMA_ALIGNMENT) + + ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT); + + return ALIGN(size, DMA_ALIGNMENT); +} + static u32 size_h265d_vpp_cmd_buf(u32 frame_width, u32 frame_height) { u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * @@ -269,6 +397,20 @@ static u32 size_h265d_vpp_cmd_buf(u32 frame_width, u32 frame_height) return _size; } +static u32 size_h265d_vpp_cmd_buf_ar50lt(u32 frame_width, u32 frame_height) +{ + u32 _size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) * + NUM_HW_PIC_BUF, DMA_ALIGNMENT); + _size = min_t(u32, _size, H265D_MAX_SLICE_AR50LT + 1); + _size = ALIGN(_size, 4); + _size = 2 * _size * SIZE_H265D_VPP_CMD_PER_BUF_AR50LT; + if (_size > VPP_CMD_MAX_SIZE) + _size = VPP_CMD_MAX_SIZE; + + return _size; +} + static u32 hfi_buffer_non_comv_h265d(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) { u32 _size_bse = size_h265d_bse_cmd_buf(frame_width, frame_height); @@ -285,6 +427,20 @@ static u32 hfi_buffer_non_comv_h265d(u32 frame_width, u32 frame_height, u32 num_ return ALIGN(_size, DMA_ALIGNMENT); } +static u32 hfi_buffer_non_comv_h265d_ar50lt(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + u32 _size_bse = size_h265d_bse_cmd_buf_ar50lt(frame_width, frame_height); + u32 _size_vpp = size_h265d_vpp_cmd_buf_ar50lt(frame_width, frame_height); + u32 _size = ALIGN(_size_bse, DMA_ALIGNMENT) + + ALIGN(_size_vpp, DMA_ALIGNMENT) + + ALIGN(2 * sizeof(u16) * + (ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) * + (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS), DMA_ALIGNMENT) + + ALIGN(SIZE_HW_PIC(SIZE_H265D_HW_PIC_T), DMA_ALIGNMENT); + + return ALIGN(_size, DMA_ALIGNMENT); +} + static u32 size_vpss_lb(u32 frame_width, u32 frame_height) { u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size; @@ -317,6 +473,13 @@ u32 size_h265d_lb_fe_top_data(u32 frame_width, u32 frame_height) (ALIGN(frame_width, 64) + 8) * 2; } +static inline +u32 size_h265d_lb_fe_top_data_ar50lt(u32 frame_width, u32 frame_height) +{ + return ALIGN(MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * + (ALIGN(frame_width, 64) + 8), DMA_ALIGNMENT) * 2; +} + static inline u32 size_h265d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height) { @@ -348,6 +511,17 @@ u32 size_h265d_lb_se_left_ctrl(u32 frame_width, u32 frame_height) MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)); } +static inline +u32 size_h265d_lb_se_left_ctrl_ar50lt(u32 frame_width, u32 frame_height) +{ + return max_t(u32, ((frame_height + 16 - 1) / 8) * + MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE_AR50LT, + max_t(u32, ((frame_height + 32 - 1) / 8) * + MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE_AR50LT, + ((frame_height + 64 - 1) / 8) * + MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE_AR50LT)); +} + static inline u32 size_h265d_lb_pe_top_data(u32 frame_width, u32 frame_height) { @@ -355,6 +529,13 @@ u32 size_h265d_lb_pe_top_data(u32 frame_width, u32 frame_height) (ALIGN(frame_width, LCU_MIN_SIZE_PELS) / LCU_MIN_SIZE_PELS); } +static inline +u32 size_h265d_lb_pe_top_data_ar50lt(u32 frame_width, u32 frame_height) +{ + return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE_AR50LT * + (ALIGN(frame_width, LCU_MIN_SIZE_PELS) / LCU_MIN_SIZE_PELS); +} + static inline u32 size_h265d_lb_vsp_top(u32 frame_width, u32 frame_height) { @@ -404,6 +585,29 @@ u32 hfi_buffer_line_h265d(u32 frame_width, u32 frame_height, bool is_opb, u32 nu return ALIGN((_size + vpss_lb_size), DMA_ALIGNMENT); } +static inline +u32 hfi_buffer_line_h265d_ar50lt(u32 frame_width, u32 frame_height, bool is_opb, u32 num_vpp_pipes) +{ + u32 size; + + size = ALIGN(size_h265d_lb_fe_top_data_ar50lt(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_fe_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_fe_left_ctrl(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_h265d_lb_se_left_ctrl_ar50lt(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_h265d_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_pe_top_data_ar50lt(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_h265d_lb_vsp_left(frame_width, frame_height), + DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_h265d_lb_recon_dma_metadata_wr(frame_width, frame_height), + DMA_ALIGNMENT) * 4 + + ALIGN(size_h265d_qp(frame_width, frame_height), DMA_ALIGNMENT); + + return ALIGN(size, DMA_ALIGNMENT); +} + static inline u32 size_vpxd_lb_fe_left_ctrl(u32 frame_width, u32 frame_height) { @@ -438,6 +642,17 @@ u32 size_vpxd_lb_se_left_ctrl(u32 frame_width, u32 frame_height) MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE)); } +static inline +u32 size_vpxd_lb_se_left_ctrl_ar50lt(u32 frame_width, u32 frame_height) +{ + return max_t(u32, ((frame_height + 15) >> 4) * + MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE_AR50LT, + max_t(u32, ((frame_height + 31) >> 5) * + MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE_AR50LT, + ((frame_height + 63) >> 6) * + MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE_AR50LT)); +} + static inline u32 size_vpxd_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height) { @@ -492,6 +707,19 @@ u32 hfi_iris3_vp9d_lb_size(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) ALIGN(size_vp9d_qp(frame_width, frame_height), DMA_ALIGNMENT); } +static inline +u32 hfi_ar50lt_vp9d_lb_size(u32 frame_width, u32 frame_height, u32 num_vpp_pipes) +{ + return ALIGN(size_vpxd_lb_fe_left_ctrl(frame_width, frame_height), DMA_ALIGNMENT) * + num_vpp_pipes + + ALIGN(size_vpxd_lb_se_left_ctrl_ar50lt(frame_width, frame_height), DMA_ALIGNMENT) * + num_vpp_pipes + + ALIGN(size_vp9d_lb_vsp_top(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_vp9d_lb_pe_top_data(frame_width, frame_height), DMA_ALIGNMENT) + + ALIGN(size_vp9d_lb_fe_top_data(frame_width, frame_height), DMA_ALIGNMENT); +} + static inline u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_min, bool is_opb, u32 num_vpp_pipes) @@ -507,6 +735,13 @@ u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_mi return _lb_size + vpss_lb_size + 4096; } +static inline +u32 hfi_buffer_line_vp9d_ar50lt(u32 frame_width, u32 frame_height, u32 _yuv_bufcount_min, + bool is_opb, u32 num_vpp_pipes) +{ + return hfi_ar50lt_vp9d_lb_size(frame_width, frame_height, num_vpp_pipes); +} + static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height, bool is_opb, u32 num_vpp_pipes) { @@ -529,6 +764,25 @@ static u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height, return ALIGN((size + vpss_lb_size), DMA_ALIGNMENT); } +static u32 hfi_buffer_line_h264d_ar50lt(u32 frame_width, u32 frame_height, + bool is_opb, u32 num_vpp_pipes) +{ + u32 size; + + size = ALIGN(size_h264d_lb_fe_top_data_ar50lt(frame_width), DMA_ALIGNMENT) + + ALIGN(size_h264d_lb_fe_top_ctrl_ar50lt(frame_width), DMA_ALIGNMENT) + + ALIGN(size_h264d_lb_fe_left_ctrl(frame_height), DMA_ALIGNMENT) * num_vpp_pipes + + ALIGN(size_h264d_lb_se_top_ctrl_ar50lt(frame_width), DMA_ALIGNMENT) + + ALIGN(size_h264d_lb_se_left_ctrl_ar50lt(frame_height), DMA_ALIGNMENT) * + num_vpp_pipes + + ALIGN(size_h264d_lb_pe_top_data_ar50lt(frame_width), DMA_ALIGNMENT) + + ALIGN(size_h264d_lb_vsp_top(frame_width), DMA_ALIGNMENT) + + ALIGN(size_h264d_lb_recon_dma_metadata_wr(frame_height), DMA_ALIGNMENT) * 2 + + ALIGN(size_h264d_qp(frame_width, frame_height), DMA_ALIGNMENT); + + return ALIGN(size, DMA_ALIGNMENT); +} + static u32 size_av1d_lb_opb_wr1_nv12_ubwc(u32 frame_width, u32 frame_height) { u32 size, y_width, y_width_a = 128; @@ -724,6 +978,23 @@ static u32 iris_vpu_dec_bin_size(struct iris_inst *inst) return 0; } +static u32 iris_vpu_ar50lt_dec_bin_size(struct iris_inst *inst) +{ + u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; + struct v4l2_format *f = inst->fmt_src; + u32 height = f->fmt.pix_mp.height; + u32 width = f->fmt.pix_mp.width; + + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_bin_h264d_ar50lt(width, height, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_bin_h265d_ar50lt(width, height, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_buffer_bin_vp9d_ar50lt(width, height, num_vpp_pipes); + + return 0; +} + static u32 iris_vpu_dec_comv_size(struct iris_inst *inst) { u32 num_comv = VIDEO_MAX_FRAME; @@ -767,6 +1038,18 @@ static u32 iris_vpu_dec_persist_size(struct iris_inst *inst) return 0; } +static u32 iris_vpu_ar50lt_dec_persist_size(struct iris_inst *inst) +{ + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_persist_h264d_ar50lt(); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_persist_h265d_ar50lt(); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_buffer_persist_vp9d_ar50lt(); + + return 0; +} + static u32 iris_vpu_dec_dpb_size(struct iris_inst *inst) { if (iris_split_mode_enabled(inst)) @@ -790,6 +1073,21 @@ static u32 iris_vpu_dec_non_comv_size(struct iris_inst *inst) return 0; } +static u32 iris_vpu_ar50lt_dec_non_comv_size(struct iris_inst *inst) +{ + u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; + struct v4l2_format *f = inst->fmt_src; + u32 height = f->fmt.pix_mp.height; + u32 width = f->fmt.pix_mp.width; + + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_non_comv_h264d_ar50lt(width, height, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_non_comv_h265d_ar50lt(width, height, num_vpp_pipes); + + return 0; +} + static u32 iris_vpu_dec_line_size(struct iris_inst *inst) { u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; @@ -815,6 +1113,29 @@ static u32 iris_vpu_dec_line_size(struct iris_inst *inst) return 0; } +static u32 iris_vpu_ar50lt_dec_line_size(struct iris_inst *inst) +{ + u32 num_vpp_pipes = inst->core->iris_platform_data->num_vpp_pipe; + struct v4l2_format *f = inst->fmt_src; + u32 height = f->fmt.pix_mp.height; + u32 width = f->fmt.pix_mp.width; + bool is_opb = false; + u32 out_min_count = inst->buffers[BUF_OUTPUT].min_count; + + if (iris_split_mode_enabled(inst)) + is_opb = true; + + if (inst->codec == V4L2_PIX_FMT_H264) + return hfi_buffer_line_h264d_ar50lt(width, height, is_opb, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_HEVC) + return hfi_buffer_line_h265d_ar50lt(width, height, is_opb, num_vpp_pipes); + else if (inst->codec == V4L2_PIX_FMT_VP9) + return hfi_buffer_line_vp9d_ar50lt(width, height, out_min_count, is_opb, + num_vpp_pipes); + + return 0; +} + static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst) { return iris_vpu_dec_comv_size(inst) + @@ -822,6 +1143,13 @@ static u32 iris_vpu_dec_scratch1_size(struct iris_inst *inst) iris_vpu_dec_line_size(inst); } +static u32 iris_vpu_ar50lt_dec_scratch1_size(struct iris_inst *inst) +{ + return iris_vpu_dec_comv_size(inst) + + iris_vpu_ar50lt_dec_non_comv_size(inst) + + iris_vpu_ar50lt_dec_line_size(inst); +} + static inline u32 iris_vpu_enc_get_bitstream_width(struct iris_inst *inst) { if (is_rotation_90_or_270(inst)) @@ -1410,6 +1738,15 @@ u32 hfi_buffer_dpb_enc(u32 frame_width, u32 frame_height, bool is_ten_bit) return size; } +static inline +u32 hfi_buffer_dpb_enc_ar50lt(u32 frame_width, u32 frame_height, bool is_ten_bit) +{ + if (!is_ten_bit) + return size_enc_ref_buffer(frame_width, frame_height); + else + return size_enc_ten_bit_ref_buffer(frame_width, frame_height); +} + static u32 iris_vpu_enc_arp_size(struct iris_inst *inst) { return HFI_BUFFER_ARP_ENC; @@ -1434,6 +1771,16 @@ u32 hfi_buffer_vpss_enc(u32 dswidth, u32 dsheight, bool ds_enable, return 0; } +static inline +u32 hfi_buffer_vpss_enc_ar50lt(u32 dswidth, u32 dsheight, bool ds_enable, + u32 blur, bool is_ten_bit) +{ + if (ds_enable || blur) + return hfi_buffer_dpb_enc_ar50lt(dswidth, dsheight, is_ten_bit); + + return 0; +} + static inline u32 hfi_buffer_scratch1_enc(u32 frame_width, u32 frame_height, u32 lcu_size, u32 num_ref, bool ten_bit, u32 num_vpp_pipes, @@ -1693,6 +2040,16 @@ static u32 iris_vpu_enc_vpss_size(struct iris_inst *inst) return hfi_buffer_vpss_enc(width, height, ds_enable, 0, 0); } +static u32 iris_vpu_ar50lt_enc_vpss_size(struct iris_inst *inst) +{ + u32 ds_enable = is_scaling_enabled(inst); + struct v4l2_format *f = inst->fmt_dst; + u32 height = f->fmt.pix_mp.height; + u32 width = f->fmt.pix_mp.width; + + return hfi_buffer_vpss_enc_ar50lt(width, height, ds_enable, 0, 0); +} + static inline u32 size_dpb_opb(u32 height, u32 lcu_size) { u32 max_tile_height = ((height + lcu_size - 1) / lcu_size) * lcu_size + 8; @@ -2135,6 +2492,51 @@ u32 iris_vpu4x_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_typ return size; } +u32 iris_vpu_ar50lt_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type) +{ + const struct iris_vpu_buf_type_handle *buf_type_handle_arr = NULL; + u32 size = 0, buf_type_handle_size = 0, i; + + static const struct iris_vpu_buf_type_handle dec_internal_buf_type_handle[] = { + {BUF_BIN, iris_vpu_ar50lt_dec_bin_size }, + {BUF_COMV, iris_vpu_dec_comv_size }, + {BUF_NON_COMV, iris_vpu_ar50lt_dec_non_comv_size }, + {BUF_LINE, iris_vpu_ar50lt_dec_line_size }, + {BUF_PERSIST, iris_vpu_ar50lt_dec_persist_size }, + {BUF_DPB, iris_vpu_dec_dpb_size }, + {BUF_SCRATCH_1, iris_vpu_ar50lt_dec_scratch1_size }, + {BUF_PARTIAL, iris_vpu_dec_partial_size }, + }; + + static const struct iris_vpu_buf_type_handle enc_internal_buf_type_handle[] = { + {BUF_BIN, iris_vpu_enc_bin_size }, + {BUF_COMV, iris_vpu_enc_comv_size }, + {BUF_NON_COMV, iris_vpu_enc_non_comv_size }, + {BUF_LINE, iris_vpu_enc_line_size }, + {BUF_ARP, iris_vpu_enc_arp_size }, + {BUF_VPSS, iris_vpu_ar50lt_enc_vpss_size }, + {BUF_SCRATCH_1, iris_vpu_enc_scratch1_size }, + {BUF_SCRATCH_2, iris_vpu_enc_scratch2_size }, + }; + + if (inst->domain == DECODER) { + buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle); + buf_type_handle_arr = dec_internal_buf_type_handle; + } else if (inst->domain == ENCODER) { + buf_type_handle_size = ARRAY_SIZE(enc_internal_buf_type_handle); + buf_type_handle_arr = enc_internal_buf_type_handle; + } + + for (i = 0; i < buf_type_handle_size; i++) { + if (buf_type_handle_arr[i].type == buffer_type) { + size = buf_type_handle_arr[i].handle(inst); + break; + } + } + + return size; +} + static u32 internal_buffer_count(struct iris_inst *inst, enum iris_buffer_type buffer_type) { diff --git a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h index 8c0d6b7b5de85..9b98476b18d6a 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_buffer.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_buffer.h @@ -61,17 +61,26 @@ struct iris_inst; #define MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE 64 #define MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE (128 / 8) #define MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE (128 / 8) +#define MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE_AR50LT (8 / 8) +#define MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE_AR50LT (16 / 8) +#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE_AR50LT (32 / 8) #define VP9_UDC_HEADER_BUF_SIZE (3 * 128) #define SIZE_SEI_USERDATA 4096 #define SIZE_DOLBY_RPU_METADATA (41 * 1024) #define H264_CABAC_HDR_RATIO_HD_TOT 1 #define H264_CABAC_RES_RATIO_HD_TOT 3 +#define H264_CABAC_HDR_RATIO_SM_TOT 1 +#define H264_CABAC_RES_RATIO_SM_TOT 2 #define H265D_MAX_SLICE 3600 +#define H265D_MAX_SLICE_AR50LT 600 #define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T #define H265_CABAC_HDR_RATIO_HD_TOT 2 #define H265_CABAC_RES_RATIO_HD_TOT 2 +#define H265_CABAC_HDR_RATIO_SM_TOT 1 +#define H265_CABAC_RES_RATIO_SM_TOT 6 #define SIZE_H265D_VPP_CMD_PER_BUF (256) +#define SIZE_H265D_VPP_CMD_PER_BUF_AR50LT (192) #define SIZE_THREE_DIMENSION_USERDATA 768 #define SIZE_H265D_ARP 9728 @@ -81,6 +90,7 @@ struct iris_inst; #define VPX_DECODER_FRAME_BIN_DENOMINATOR 2 #define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO (3 / 2) +#define VPX_DECODER_FRAME_BIN_BUFFER_SIZE (1024 * 1024) #define SIZE_H264D_HW_PIC_T (BIT(11)) @@ -99,6 +109,7 @@ struct iris_inst; #define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64 #define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 16 #define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE 384 +#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE_AR50LT 176 #define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640 #define AV1_CABAC_HDR_RATIO_HD_TOT 2 @@ -155,11 +166,21 @@ static inline u32 size_h264d_lb_fe_top_data(u32 frame_width) return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3; } +static inline u32 size_h264d_lb_fe_top_data_ar50lt(u32 frame_width) +{ + return 16 * ALIGN(frame_width, 16) * 2; +} + static inline u32 size_h264d_lb_fe_top_ctrl(u32 frame_width) { return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16); } +static inline u32 size_h264d_lb_fe_top_ctrl_ar50lt(u32 frame_width) +{ + return 16 * DIV_ROUND_UP(frame_width, 16); +} + static inline u32 size_h264d_lb_fe_left_ctrl(u32 frame_height) { return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height, 16); @@ -170,16 +191,31 @@ static inline u32 size_h264d_lb_se_top_ctrl(u32 frame_width) return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16); } +static inline u32 size_h264d_lb_se_top_ctrl_ar50lt(u32 frame_width) +{ + return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE_AR50LT * DIV_ROUND_UP(frame_width, 16); +} + static inline u32 size_h264d_lb_se_left_ctrl(u32 frame_height) { return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_height, 16); } +static inline u32 size_h264d_lb_se_left_ctrl_ar50lt(u32 frame_height) +{ + return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE_AR50LT * DIV_ROUND_UP(frame_height, 16); +} + static inline u32 size_h264d_lb_pe_top_data(u32 frame_width) { return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE * DIV_ROUND_UP(frame_width, 16); } +static inline u32 size_h264d_lb_pe_top_data_ar50lt(u32 frame_width) +{ + return 64 * DIV_ROUND_UP(frame_width, 16); +} + static inline u32 size_h264d_lb_vsp_top(u32 frame_width) { return (DIV_ROUND_UP(frame_width, 16) << 7); @@ -288,6 +324,7 @@ static inline u32 size_av1d_qp(u32 frame_width, u32 frame_height) u32 iris_vpu_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); u32 iris_vpu33_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); u32 iris_vpu4x_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); +u32 iris_vpu_ar50lt_buf_size(struct iris_inst *inst, enum iris_buffer_type buffer_type); int iris_vpu_buf_count(struct iris_inst *inst, enum iris_buffer_type buffer_type); #endif From 4790e714eaf21ace619f867fbf3b9248a64b4e42 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Tue, 17 Mar 2026 21:08:03 +0530 Subject: [PATCH 37/41] media: iris: Add qcm2290 DT compatible and platform data Add support for the qcm2290 SoC by introducing a new compatible string for the AR50LT core and the corresponding platform data. This change: - Adds qcm2290 as a supported compatible for the AR50LT core. - Introduces AR50LT-specific platform data describing VPU configuration. - Adds a qcm2290-specific header describing firmware capabilities. Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/iris/Makefile | 1 + .../media/platform/qcom/iris/iris_hfi_gen2.c | 55 ++ .../platform/qcom/iris/iris_platform_common.h | 2 + .../qcom/iris/iris_platform_qcm2290.h | 576 ++++++++++++++++++ .../qcom/iris/iris_platform_vpu_ar50lt.c | 123 ++++ drivers/media/platform/qcom/iris/iris_probe.c | 4 + 6 files changed, 761 insertions(+) create mode 100644 drivers/media/platform/qcom/iris/iris_platform_qcm2290.h create mode 100644 drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile index 49a90e1622b39..f7c94ffa1e449 100644 --- a/drivers/media/platform/qcom/iris/Makefile +++ b/drivers/media/platform/qcom/iris/Makefile @@ -15,6 +15,7 @@ qcom-iris-objs += iris_buffer.o \ iris_platform_vpu2.o \ iris_platform_vpu3x.o \ iris_platform_vpu4x.o \ + iris_platform_vpu_ar50lt.o \ iris_power.o \ iris_probe.o \ iris_resources.o \ diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c index ce8490d64854c..0745507879ac1 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c @@ -8,6 +8,7 @@ #include "iris_hfi_gen2.h" #include "iris_hfi_gen2_defines.h" #include "iris_platform_common.h" +#include "iris_platform_qcm2290.h" #include "iris_vpu_buffer.h" #define VIDEO_ARCH_LX 1 @@ -894,3 +895,57 @@ const struct iris_firmware_data iris_hfi_gen2_data = { .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; + +const struct iris_firmware_data iris_hfi_gen2_ar50lt_data = { + .init_hfi_ops = iris_hfi_gen2_sys_ops_init, + + .core_arch = VIDEO_ARCH_LX, + + .inst_fw_caps_dec = inst_fw_cap_qcm2290_dec, + .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_qcm2290_dec), + .inst_fw_caps_enc = inst_fw_cap_qcm2290_enc, + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_qcm2290_enc), + .dec_input_config_params_default = + sm8550_vdec_input_config_params_default, + .dec_input_config_params_default_size = + ARRAY_SIZE(sm8550_vdec_input_config_params_default), + .dec_input_config_params_hevc = + sm8550_vdec_input_config_param_hevc, + .dec_input_config_params_hevc_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_hevc), + .dec_input_config_params_vp9 = + sm8550_vdec_input_config_param_vp9, + .dec_input_config_params_vp9_size = + ARRAY_SIZE(sm8550_vdec_input_config_param_vp9), + .dec_output_config_params = + sm8550_vdec_output_config_params, + .dec_output_config_params_size = + ARRAY_SIZE(sm8550_vdec_output_config_params), + .enc_input_config_params = + sm8550_venc_input_config_params, + .enc_input_config_params_size = + ARRAY_SIZE(sm8550_venc_input_config_params), + .enc_output_config_params = + sm8550_venc_output_config_params, + .enc_output_config_params_size = + ARRAY_SIZE(sm8550_venc_output_config_params), + .dec_input_prop = sm8550_vdec_subscribe_input_properties, + .dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_subscribe_input_properties), + .dec_output_prop_avc = sm8550_vdec_subscribe_output_properties_avc, + .dec_output_prop_avc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_avc), + .dec_output_prop_hevc = sm8550_vdec_subscribe_output_properties_hevc, + .dec_output_prop_hevc_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_hevc), + .dec_output_prop_vp9 = sm8550_vdec_subscribe_output_properties_vp9, + .dec_output_prop_vp9_size = + ARRAY_SIZE(sm8550_vdec_subscribe_output_properties_vp9), + .dec_ip_int_buf_tbl = qcm2290_dec_ip_int_buf_tbl, + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(qcm2290_dec_ip_int_buf_tbl), + .dec_op_int_buf_tbl = sm8550_dec_op_int_buf_tbl, + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_dec_op_int_buf_tbl), + .enc_ip_int_buf_tbl = sm8550_enc_ip_int_buf_tbl, + .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_ip_int_buf_tbl), + .enc_op_int_buf_tbl = sm8550_enc_op_int_buf_tbl, + .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), +}; diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 1f334a6f3faef..8f6a28fe3a791 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -42,8 +42,10 @@ enum pipe_type { extern const struct iris_firmware_data iris_hfi_gen1_data; extern const struct iris_firmware_data iris_hfi_gen2_data; +extern const struct iris_firmware_data iris_hfi_gen2_ar50lt_data; extern const struct iris_platform_data kaanapali_data; +extern const struct iris_platform_data qcm2290_data; extern const struct iris_platform_data qcs8300_data; extern const struct iris_platform_data sc7280_data; extern const struct iris_platform_data sm8250_data; diff --git a/drivers/media/platform/qcom/iris/iris_platform_qcm2290.h b/drivers/media/platform/qcom/iris/iris_platform_qcm2290.h new file mode 100644 index 0000000000000..5505f276c0df0 --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_qcm2290.h @@ -0,0 +1,576 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "iris_platform_common.h" + +#define BITRATE_MAX_AR50LT 100000000 +#define BITRATE_DEFAULT_AR50LT 20000000 +#define MIN_QP_8BIT_AR50LT 0 + +static const struct platform_inst_fw_cap inst_fw_cap_qcm2290_dec[] = { + { + .cap_id = PROFILE_H264, + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH), + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = PROFILE_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE), + .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = PROFILE_VP9, + .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .max = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0), + .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = LEVEL_H264, + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + .max = V4L2_MPEG_VIDEO_H264_LEVEL_4_2, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2), + .value = V4L2_MPEG_VIDEO_H264_LEVEL_4_2, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = LEVEL_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1), + .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = LEVEL_VP9, + .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0, + .max = V4L2_MPEG_VIDEO_VP9_LEVEL_4_1, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1), + .value = V4L2_MPEG_VIDEO_VP9_LEVEL_4_1, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = TIER, + .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) | + BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH), + .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, + .hfi_id = HFI_PROP_TIER, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_u32_enum, + }, + { + .cap_id = INPUT_BUF_HOST_MAX_COUNT, + .min = DEFAULT_MAX_HOST_BUF_COUNT, + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT, + .step_or_mask = 1, + .value = DEFAULT_MAX_HOST_BUF_COUNT, + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT, + .flags = CAP_FLAG_INPUT_PORT, + .set = iris_set_u32, + }, + { + .cap_id = STAGE, + .min = STAGE_1, + .max = STAGE_2, + .step_or_mask = 1, + .value = STAGE_2, + .hfi_id = HFI_PROP_STAGE, + .set = iris_set_stage, + }, + { + .cap_id = PIPE, + /* .max, .min and .value are set via platform data */ + .step_or_mask = 1, + .hfi_id = HFI_PROP_PIPE, + .set = iris_set_pipe, + }, + { + .cap_id = POC, + .min = 0, + .max = 2, + .step_or_mask = 1, + .value = 1, + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE, + }, + { + .cap_id = CODED_FRAMES, + .min = CODED_FRAMES_PROGRESSIVE, + .max = CODED_FRAMES_PROGRESSIVE, + .step_or_mask = 0, + .value = CODED_FRAMES_PROGRESSIVE, + .hfi_id = HFI_PROP_CODED_FRAMES, + }, + { + .cap_id = BIT_DEPTH, + .min = BIT_DEPTH_8, + .max = BIT_DEPTH_8, + .step_or_mask = 1, + .value = BIT_DEPTH_8, + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH, + }, + { + .cap_id = RAP_FRAME, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 1, + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME, + .flags = CAP_FLAG_INPUT_PORT, + .set = iris_set_u32, + }, +}; + +static const struct platform_inst_fw_cap inst_fw_cap_qcm2290_enc[] = { + { + .cap_id = PROFILE_H264, + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH), + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_profile, + }, + { + .cap_id = PROFILE_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | + BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE), + .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, + .hfi_id = HFI_PROP_PROFILE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_profile, + }, + { + .cap_id = LEVEL_H264, + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, + .max = V4L2_MPEG_VIDEO_H264_LEVEL_4_2, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2), + .value = V4L2_MPEG_VIDEO_H264_LEVEL_4_2, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_level, + }, + { + .cap_id = LEVEL_HEVC, + .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, + .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | + BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1), + .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1, + .hfi_id = HFI_PROP_LEVEL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_level, + }, + { + .cap_id = STAGE, + .min = STAGE_1, + .max = STAGE_2, + .step_or_mask = 1, + .value = STAGE_2, + .hfi_id = HFI_PROP_STAGE, + .set = iris_set_stage, + }, + { + .cap_id = HEADER_MODE, + .min = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE, + .max = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) | + BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME), + .value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, + .hfi_id = HFI_PROP_SEQ_HEADER_MODE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_header_mode_gen2, + }, + { + .cap_id = PREPEND_SPSPPS_TO_IDR, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 0, + }, + { + .cap_id = BITRATE, + .min = 1, + .max = BITRATE_MAX_AR50LT, + .step_or_mask = 1, + .value = BITRATE_DEFAULT_AR50LT, + .hfi_id = HFI_PROP_TOTAL_BITRATE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_bitrate, + }, + { + .cap_id = BITRATE_PEAK, + .min = 1, + .max = BITRATE_MAX_AR50LT, + .step_or_mask = 1, + .value = BITRATE_DEFAULT_AR50LT, + .hfi_id = HFI_PROP_TOTAL_PEAK_BITRATE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_peak_bitrate, + }, + { + .cap_id = BITRATE_MODE, + .min = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, + .max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) | + BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR), + .value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, + .hfi_id = HFI_PROP_RATE_CONTROL, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_bitrate_mode_gen2, + }, + { + .cap_id = FRAME_SKIP_MODE, + .min = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED, + .max = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) | + BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT) | + BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT), + .value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + }, + { + .cap_id = FRAME_RC_ENABLE, + .min = 0, + .max = 1, + .step_or_mask = 1, + .value = 1, + }, + { + .cap_id = GOP_SIZE, + .min = 0, + .max = INT_MAX, + .step_or_mask = 1, + .value = 2 * DEFAULT_FPS - 1, + .hfi_id = HFI_PROP_MAX_GOP_FRAMES, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_u32, + }, + { + .cap_id = ENTROPY_MODE, + .min = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, + .max = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) | + BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC), + .value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, + .hfi_id = HFI_PROP_CABAC_SESSION, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_entropy_mode_gen2, + }, + { + .cap_id = MIN_FRAME_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + .hfi_id = HFI_PROP_MIN_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT, + .set = iris_set_min_qp, + }, + { + .cap_id = MIN_FRAME_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + .hfi_id = HFI_PROP_MIN_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT, + .set = iris_set_min_qp, + }, + { + .cap_id = MAX_FRAME_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + .hfi_id = HFI_PROP_MAX_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT, + .set = iris_set_max_qp, + }, + { + .cap_id = MAX_FRAME_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + .hfi_id = HFI_PROP_MAX_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT, + .set = iris_set_max_qp, + }, + { + .cap_id = I_FRAME_MIN_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + }, + { + .cap_id = I_FRAME_MIN_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + }, + { + .cap_id = P_FRAME_MIN_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + }, + { + .cap_id = P_FRAME_MIN_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + }, + { + .cap_id = B_FRAME_MIN_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + }, + { + .cap_id = B_FRAME_MIN_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MIN_QP_8BIT_AR50LT, + }, + { + .cap_id = I_FRAME_MAX_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + }, + { + .cap_id = I_FRAME_MAX_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + }, + { + .cap_id = P_FRAME_MAX_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + }, + { + .cap_id = P_FRAME_MAX_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + }, + { + .cap_id = B_FRAME_MAX_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + }, + { + .cap_id = B_FRAME_MAX_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = MAX_QP, + }, + { + .cap_id = I_FRAME_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = DEFAULT_QP, + .hfi_id = HFI_PROP_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_frame_qp, + }, + { + .cap_id = I_FRAME_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = DEFAULT_QP, + .hfi_id = HFI_PROP_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_frame_qp, + }, + { + .cap_id = P_FRAME_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = DEFAULT_QP, + .hfi_id = HFI_PROP_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_frame_qp, + }, + { + .cap_id = P_FRAME_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = DEFAULT_QP, + .hfi_id = HFI_PROP_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_frame_qp, + }, + { + .cap_id = B_FRAME_QP_H264, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = DEFAULT_QP, + .hfi_id = HFI_PROP_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_frame_qp, + }, + { + .cap_id = B_FRAME_QP_HEVC, + .min = MIN_QP_8BIT_AR50LT, + .max = MAX_QP, + .step_or_mask = 1, + .value = DEFAULT_QP, + .hfi_id = HFI_PROP_QP_PACKED, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_frame_qp, + }, + { + .cap_id = INPUT_BUF_HOST_MAX_COUNT, + .min = DEFAULT_MAX_HOST_BUF_COUNT, + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT, + .step_or_mask = 1, + .value = DEFAULT_MAX_HOST_BUF_COUNT, + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT, + .flags = CAP_FLAG_INPUT_PORT, + .set = iris_set_u32, + }, + { + .cap_id = OUTPUT_BUF_HOST_MAX_COUNT, + .min = DEFAULT_MAX_HOST_BUF_COUNT, + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT, + .step_or_mask = 1, + .value = DEFAULT_MAX_HOST_BUF_COUNT, + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT, + .flags = CAP_FLAG_OUTPUT_PORT, + .set = iris_set_u32, + }, + { + .cap_id = IR_TYPE, + .min = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM, + .max = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM, + .step_or_mask = BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM), + .value = V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + }, + { + .cap_id = IR_PERIOD, + .min = 0, + .max = INT_MAX, + .step_or_mask = 1, + .value = 0, + .flags = CAP_FLAG_OUTPUT_PORT | + CAP_FLAG_DYNAMIC_ALLOWED, + .set = iris_set_ir_period, + }, +}; + +static const u32 qcm2290_dec_ip_int_buf_tbl[] = { + BUF_BIN, + BUF_COMV, + BUF_NON_COMV, + BUF_LINE, +}; diff --git a/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c new file mode 100644 index 0000000000000..eed9a560fa094 --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_vpu_ar50lt.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "iris_core.h" +#include "iris_ctrls.h" +#include "iris_hfi_gen2.h" +#include "iris_hfi_gen2_defines.h" +#include "iris_platform_common.h" +#include "iris_vpu_buffer.h" +#include "iris_vpu_common.h" + +#define WRAPPER_INTR_STATUS_A2HWD_BMSK 0x10 + +const struct iris_firmware_desc iris_vpu_ar50lt_p1_gen2_s6_desc = { + .firmware_data = &iris_hfi_gen2_ar50lt_data, + .get_vpu_buffer_size = iris_vpu_ar50lt_buf_size, + /* Kept the name as placeholder + * Update it later, if required, based on the discussion with FW team + */ + .fwname = "qcom/vpu/ar50lt_p1_gen2_s6.mbn", +}; + +static struct iris_fmt iris_fmts_ar50lt[] = { + [IRIS_FMT_H264] = { + .pixfmt = V4L2_PIX_FMT_H264, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_HEVC] = { + .pixfmt = V4L2_PIX_FMT_HEVC, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_VP9] = { + .pixfmt = V4L2_PIX_FMT_VP9, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + +static const struct bw_info iris_bw_table_dec_ar50lt[] = { + { ((1920 * 1080) / 256) * 60, 1564000, }, + { ((1920 * 1080) / 256) * 30, 791000, }, + { ((1280 * 720) / 256) * 60, 688000, }, + { ((1280 * 720) / 256) * 30, 347000, }, +}; + +static const struct icc_info iris_icc_info_ar50lt[] = { + { "cpu-cfg", 1000, 1000 }, + { "video-mem", 1000, 6500000 }, +}; + +static const char * const iris_pmdomain_table_ar50lt[] = { "venus", "vcodec0" }; + +static const char * const iris_opp_pd_table_ar50lt[] = { "cx" }; + +static const struct platform_clk_data iris_clk_table_ar50lt[] = { + {IRIS_CTRL_CLK, "core" }, + {IRIS_AXI_CLK, "iface" }, + {IRIS_AHB_CLK, "bus" }, + {IRIS_HW_CLK, "vcodec0_core" }, + {IRIS_HW_AHB_CLK, "vcodec0_bus" }, + {IRIS_THROTTLE_CLK, "throttle" }, +}; + +static const char * const iris_opp_clk_table_ar50lt[] = { + "vcodec0_core", + NULL, +}; + +static const struct tz_cp_config tz_cp_config_ar50lt[] = { + { + .cp_start = 0, + .cp_size = 0x25800000, + .cp_nonpixel_start = 0x01000000, + .cp_nonpixel_size = 0x24800000, + }, +}; + +static struct platform_inst_caps platform_inst_cap_ar50lt = { + .min_frame_width = 128, + .max_frame_width = 1920, + .min_frame_height = 128, + .max_frame_height = 1920, + .max_mbpf = (1920 * 1088) / 256, + .mb_cycles_vpp = 440, + .mb_cycles_fw = 733003, + .mb_cycles_fw_vpp = 225975, + .num_comv = 0, + .max_frame_rate = 120, + .max_operating_rate = 120, +}; + +const struct iris_platform_data qcm2290_data = { + .firmware_desc = &iris_vpu_ar50lt_p1_gen2_s6_desc, + .vpu_ops = &iris_vpu_ar50lt_ops, + .icc_tbl = iris_icc_info_ar50lt, + .icc_tbl_size = ARRAY_SIZE(iris_icc_info_ar50lt), + .bw_tbl_dec = iris_bw_table_dec_ar50lt, + .bw_tbl_dec_size = ARRAY_SIZE(iris_bw_table_dec_ar50lt), + .pmdomain_tbl = iris_pmdomain_table_ar50lt, + .pmdomain_tbl_size = ARRAY_SIZE(iris_pmdomain_table_ar50lt), + .opp_pd_tbl = iris_opp_pd_table_ar50lt, + .opp_pd_tbl_size = ARRAY_SIZE(iris_opp_pd_table_ar50lt), + .clk_tbl = iris_clk_table_ar50lt, + .clk_tbl_size = ARRAY_SIZE(iris_clk_table_ar50lt), + .opp_clk_tbl = iris_opp_clk_table_ar50lt, + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .inst_iris_fmts = iris_fmts_ar50lt, + .inst_iris_fmts_size = ARRAY_SIZE(iris_fmts_ar50lt), + .inst_caps = &platform_inst_cap_ar50lt, + .tz_cp_config_data = tz_cp_config_ar50lt, + .tz_cp_config_data_size = ARRAY_SIZE(tz_cp_config_ar50lt), + .num_vpp_pipe = 1, + .no_rpmh = true, + .wd_intr_mask = WRAPPER_INTR_STATUS_A2HWD_BMSK, + .icc_ib_multiplier = 2, + .max_session_count = 8, + .max_core_mbpf = ((1920 * 1088) / 256) * 4, + /* Concurrency: 1080p@30 decode + 1080p@30 encode */ + /* Concurrency: 3 * 1080p@30 decode */ + .max_core_mbps = (((1920 * 1088) / 256) * 90), +}; diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index 5ef4e26df0c4b..9f1ce540e7055 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -376,6 +376,10 @@ static const struct of_device_id iris_dt_match[] = { .compatible = "qcom,kaanapali-iris", .data = &kaanapali_data, }, + { + .compatible = "qcom,qcm2290-venus", + .data = &qcm2290_data, + }, { .compatible = "qcom,qcs8300-iris", .data = &qcs8300_data, From 84d903cde542d4bfb1f056fe6be361683b3bf55e Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 9 Apr 2026 16:11:55 +0530 Subject: [PATCH 38/41] dt-bindings: media: qcom,qcm2290-venus: document shikra Iris compatible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the Iris video accelerator used on Shikra platforms by adding the qcom,shikra-iris compatible. Although QCM2290 and Shikra share the same video hardware and overall integration, their SMMU programming differs. QCM2290 exposes separate Stream IDs for the video hardware and the Xtensa path, requiring two explicit IOMMU entries, whereas Shikra uses a masked SMR to collapse equivalent Stream IDs into a single mapping. Due to QCM2290’s SID layout and Xtensa isolation requirements, such SMR masking is not applicable on QCM2290 platforms. Since Shikra uses the same video hardware as QCM2290 and shares the same programming model and capabilities, it is added as a fallback compatible to qcom,qcm2290-venus, with conditional handling to allow either one or two IOMMU entries. Signed-off-by: Dikshita Agarwal --- .../bindings/media/qcom,qcm2290-venus.yaml | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml b/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml index 7e6dc410c2d2b..10713164c2d80 100644 --- a/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml +++ b/Documentation/devicetree/bindings/media/qcom,qcm2290-venus.yaml @@ -15,10 +15,27 @@ description: allOf: - $ref: qcom,venus-common.yaml# + - if: + properties: + compatible: + contains: + const: qcom,shikra-iris + then: + properties: + iommus: + maxItems: 1 + else: + properties: + iommus: + maxItems: 2 properties: compatible: - const: qcom,qcm2290-venus + oneOf: + - items: + - const: qcom,shikra-iris + - const: qcom,qcm2290-venus + - const: qcom,qcm2290-venus power-domains: maxItems: 3 @@ -41,9 +58,6 @@ properties: - const: vcodec0_core - const: vcodec0_bus - iommus: - maxItems: 2 - interconnects: maxItems: 2 From 20b81012aed71d360e9d9d87fe10b6a865caf810 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Fri, 17 Apr 2026 18:43:44 +0530 Subject: [PATCH 39/41] media: venus: prefer iris driver for qcm2290 when IRIS is enabled QCM2290 is currently supported by the Venus driver using HFI Gen1. However, support for this platform is being added to the Iris driver, where it will be preferred going forward, initially using HFI Gen2 and eventually providing support for both Gen1 and Gen2. As part of early enablement for the Shikra platform, which reuses the qcm2290 compatible as a fallback, it is necessary to allow the Iris driver to bind to this hardware instead of Venus when Iris support is enabled in the kernel configuration. Introduce a configuration-based guard to prevent the Venus driver from registering qcm2290 support when CONFIG_VIDEO_QCOM_IRIS is enabled. This ensures that the Iris driver is selected for QCM2290/Shikra platforms in early development kernels, without changing the default behavior when Iris is not enabled. This change is intended as an intermediate step for early bring-up. Full HFI Gen1 support in the Iris driver will be added before posting the final upstream series. Signed-off-by: Dikshita Agarwal --- drivers/media/platform/qcom/venus/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 45ce57406a4e5..3734d4f797139 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -1070,7 +1070,6 @@ static const struct venus_resources sc7280_res = { .dec_nodename = "video-decoder", .enc_nodename = "video-encoder", }; -#endif static const struct bw_tbl qcm2290_bw_table_dec[] = { { 352800, 597000, 0, 746000, 0 }, /* 1080p@30 + 720p@30 */ @@ -1120,12 +1119,15 @@ static const struct venus_resources qcm2290_res = { .enc_nodename = "video-encoder", .min_fw = &min_fw, }; +#endif static const struct of_device_id venus_dt_match[] = { { .compatible = "qcom,msm8916-venus", .data = &msm8916_res, }, { .compatible = "qcom,msm8996-venus", .data = &msm8996_res, }, { .compatible = "qcom,msm8998-venus", .data = &msm8998_res, }, +#if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) { .compatible = "qcom,qcm2290-venus", .data = &qcm2290_res, }, +#endif { .compatible = "qcom,sc7180-venus", .data = &sc7180_res, }, #if (!IS_ENABLED(CONFIG_VIDEO_QCOM_IRIS)) { .compatible = "qcom,sc7280-venus", .data = &sc7280_res, }, From 9b8da707cf638edb0150d437e31d171347d866e4 Mon Sep 17 00:00:00 2001 From: Sachin Kumar Garg Date: Mon, 25 May 2026 11:16:38 +0530 Subject: [PATCH 40/41] media: iris: Add support for multi_slice in iris encoder Add multi-slice encoding support with MAX_MB and MAX_BYTES modes. Clients can enable slice mode using V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE control and configure slice size via V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB or V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES controls. Signed-off-by: Sachin Kumar Garg --- drivers/media/platform/qcom/iris/iris_ctrls.c | 89 +++++++++++++++++++ drivers/media/platform/qcom/iris/iris_ctrls.h | 1 + .../media/platform/qcom/iris/iris_hfi_gen2.c | 31 +++++++ .../qcom/iris/iris_hfi_gen2_defines.h | 2 + .../platform/qcom/iris/iris_platform_common.h | 3 + 5 files changed, 126 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c index ef7adac3764d7..987fde9db23aa 100644 --- a/drivers/media/platform/qcom/iris/iris_ctrls.c +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c @@ -13,6 +13,15 @@ #define CABAC_MAX_BITRATE 160000000 #define CAVLC_MAX_BITRATE 220000000 +#define MAX_SLICES_PER_FRAME 10 +#define MAX_SLICES_FRAME_RATE 60 +#define MAX_MB_SLICE_WIDTH 4096 +#define MAX_MB_SLICE_HEIGHT 2160 +#define MAX_BYTES_SLICE_WIDTH 1920 +#define MAX_BYTES_SLICE_HEIGHT 1088 +#define MIN_HEVC_SLICE_WIDTH 384 +#define MIN_AVC_SLICE_WIDTH 192 +#define MIN_SLICE_HEIGHT 128 static inline bool iris_valid_cap_id(enum platform_inst_fw_cap_type cap_id) { @@ -112,6 +121,12 @@ static enum platform_inst_fw_cap_type iris_get_cap_id(u32 id) return IR_TYPE; case V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD: return IR_PERIOD; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE: + return SLICE_MODE; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES: + return SLICE_MAX_BYTES; + case V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB: + return SLICE_MAX_MB; default: return INST_FW_CAP_MAX; } @@ -213,6 +228,12 @@ static u32 iris_get_v4l2_id(enum platform_inst_fw_cap_type cap_id) return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE; case IR_PERIOD: return V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD; + case SLICE_MODE: + return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; + case SLICE_MAX_BYTES: + return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + case SLICE_MAX_MB: + return V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; default: return 0; } @@ -996,6 +1017,74 @@ int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type ca &ir_period, sizeof(u32)); } +int iris_set_slice_count(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id) +{ + const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; + u32 slice_mode = inst->fw_caps[SLICE_MODE].value; + u32 bitrate = inst->fw_caps[BITRATE].value; + u32 rc_type = inst->fw_caps[BITRATE_MODE].value; + u32 fps = inst->frame_rate; + u32 output_width = inst->fmt_dst->fmt.pix_mp.width; + u32 output_height = inst->fmt_dst->fmt.pix_mp.height; + u32 mbpf = NUM_MBS_PER_FRAME(output_height, output_width); + u32 max_width, max_height, min_width, min_height; + u32 max_avg_slicesize, hfi_value, hfi_id; + + if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) { + dev_dbg(inst->core->dev, "slice mode is: %u, ignore setting to fw\n", slice_mode); + return 0; + } + if (!fps) { + dev_err(inst->core->dev, "Invalid frame rate %d\n", fps); + return -EINVAL; + } + if (fps > MAX_SLICES_FRAME_RATE || + (rc_type != HFI_RC_OFF && rc_type != HFI_RC_CBR_CFR && + rc_type != HFI_RC_CBR_VFR)) { + dev_err(inst->core->dev, "slice unsupported, fps: %u, rc_type: %#x\n", + fps, rc_type); + return -EINVAL; + } + + max_width = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ? + MAX_MB_SLICE_WIDTH : MAX_BYTES_SLICE_WIDTH; + max_height = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ? + MAX_MB_SLICE_HEIGHT : MAX_BYTES_SLICE_HEIGHT; + min_width = (inst->codec == V4L2_PIX_FMT_HEVC) ? + MIN_HEVC_SLICE_WIDTH : MIN_AVC_SLICE_WIDTH; + min_height = MIN_SLICE_HEIGHT; + + if (output_width < min_width || output_height < min_height || + output_width > max_width || output_height > max_height) { + dev_err(inst->core->dev, "slice unsupported, codec: %#x wxh: [%dx%d]\n", + inst->codec, output_width, output_height); + return -EINVAL; + } + + if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) { + hfi_value = inst->fw_caps[SLICE_MAX_MB].value; + hfi_value = max(hfi_value, mbpf / MAX_SLICES_PER_FRAME); + if (inst->codec == V4L2_PIX_FMT_HEVC) + hfi_value = (hfi_value + 3) / 4; + hfi_id = inst->fw_caps[SLICE_MAX_MB].hfi_id; + } else if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) { + hfi_value = inst->fw_caps[SLICE_MAX_BYTES].value; + if (rc_type != HFI_RC_OFF) { + max_avg_slicesize = ((bitrate / fps) / 8) / MAX_SLICES_PER_FRAME; + hfi_value = max(hfi_value, max_avg_slicesize); + } + hfi_id = inst->fw_caps[SLICE_MAX_BYTES].hfi_id; + } else { + return -EINVAL; + } + + return hfi_ops->session_set_property(inst, hfi_id, + HFI_HOST_FLAGS_NONE, + iris_get_port_info(inst, cap_id), + HFI_PAYLOAD_U32, + &hfi_value, sizeof(u32)); +} + int iris_set_properties(struct iris_inst *inst, u32 plane) { const struct iris_hfi_session_ops *hfi_ops = inst->hfi_session_ops; diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.h b/drivers/media/platform/qcom/iris/iris_ctrls.h index 9518803577bc3..5280ee00d9a02 100644 --- a/drivers/media/platform/qcom/iris/iris_ctrls.h +++ b/drivers/media/platform/qcom/iris/iris_ctrls.h @@ -35,6 +35,7 @@ int iris_set_qp_range(struct iris_inst *inst, enum platform_inst_fw_cap_type cap int iris_set_rotation(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); int iris_set_flip(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); int iris_set_ir_period(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); +int iris_set_slice_count(struct iris_inst *inst, enum platform_inst_fw_cap_type cap_id); int iris_set_properties(struct iris_inst *inst, u32 plane); #endif diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c index 0745507879ac1..65ae63c782a2c 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.c @@ -13,6 +13,8 @@ #define VIDEO_ARCH_LX 1 #define BITRATE_MAX 245000000 +#define MAX_SLICE_MB_SIZE \ + (((4096 + 15) >> 4) * ((2304 + 15) >> 4)) static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { { @@ -716,6 +718,35 @@ static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = { CAP_FLAG_DYNAMIC_ALLOWED, .set = iris_set_ir_period, }, + { + .cap_id = SLICE_MODE, + .min = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + .max = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) | + BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) | + BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES), + .value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_slice_count, + }, + { + .cap_id = SLICE_MAX_BYTES, + .min = 512, + .max = BITRATE_MAX >> 3, + .step_or_mask = 1, + .value = 512, + .hfi_id = HFI_PROP_MULTI_SLICE_BYTES_COUNT, + .flags = CAP_FLAG_OUTPUT_PORT, + }, + { + .cap_id = SLICE_MAX_MB, + .min = 1, + .max = MAX_SLICE_MB_SIZE, + .step_or_mask = 1, + .value = 1, + .hfi_id = HFI_PROP_MULTI_SLICE_MB_COUNT, + .flags = CAP_FLAG_OUTPUT_PORT, + }, }; static const u32 sm8550_vdec_input_config_params_default[] = { diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h index cecf771c55dd3..8a27f246e1149 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h @@ -71,6 +71,8 @@ enum hfi_rate_control { #define HFI_PROP_MIN_QP_PACKED 0x0300012f #define HFI_PROP_MAX_QP_PACKED 0x03000130 #define HFI_PROP_IR_RANDOM_PERIOD 0x03000131 +#define HFI_PROP_MULTI_SLICE_MB_COUNT 0x03000132 +#define HFI_PROP_MULTI_SLICE_BYTES_COUNT 0x03000133 #define HFI_PROP_TOTAL_BITRATE 0x0300013b #define HFI_PROP_MAX_GOP_FRAMES 0x03000146 #define HFI_PROP_MAX_B_FRAMES 0x03000147 diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 8f6a28fe3a791..849b641723c44 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -165,6 +165,9 @@ enum platform_inst_fw_cap_type { VFLIP, IR_TYPE, IR_PERIOD, + SLICE_MODE, + SLICE_MAX_BYTES, + SLICE_MAX_MB, INST_FW_CAP_MAX, }; From 0e200cfcd87e3ac6e8f9d680e4df40e575ba8c1e Mon Sep 17 00:00:00 2001 From: Sachin Kumar Garg Date: Mon, 25 May 2026 11:25:35 +0530 Subject: [PATCH 41/41] media: iris: Add multi slice support for qcm2290 Add multi slice support for qcm2290 soc. Signed-off-by: Sachin Kumar Garg --- .../qcom/iris/iris_platform_qcm2290.h | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/media/platform/qcom/iris/iris_platform_qcm2290.h b/drivers/media/platform/qcom/iris/iris_platform_qcm2290.h index 5505f276c0df0..37531934ff648 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_qcm2290.h +++ b/drivers/media/platform/qcom/iris/iris_platform_qcm2290.h @@ -8,6 +8,8 @@ #define BITRATE_MAX_AR50LT 100000000 #define BITRATE_DEFAULT_AR50LT 20000000 #define MIN_QP_8BIT_AR50LT 0 +#define MAX_SLICE_MB_SIZE \ + (((4096 + 15) >> 4) * ((2304 + 15) >> 4)) static const struct platform_inst_fw_cap inst_fw_cap_qcm2290_dec[] = { { @@ -566,6 +568,35 @@ static const struct platform_inst_fw_cap inst_fw_cap_qcm2290_enc[] = { CAP_FLAG_DYNAMIC_ALLOWED, .set = iris_set_ir_period, }, + { + .cap_id = SLICE_MODE, + .min = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + .max = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES, + .step_or_mask = BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) | + BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) | + BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES), + .value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE, + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, + .set = iris_set_slice_count, + }, + { + .cap_id = SLICE_MAX_BYTES, + .min = 512, + .max = BITRATE_MAX_AR50LT >> 3, + .step_or_mask = 1, + .value = 512, + .hfi_id = HFI_PROP_MULTI_SLICE_BYTES_COUNT, + .flags = CAP_FLAG_OUTPUT_PORT, + }, + { + .cap_id = SLICE_MAX_MB, + .min = 1, + .max = MAX_SLICE_MB_SIZE, + .step_or_mask = 1, + .value = 1, + .hfi_id = HFI_PROP_MULTI_SLICE_MB_COUNT, + .flags = CAP_FLAG_OUTPUT_PORT, + }, }; static const u32 qcm2290_dec_ip_int_buf_tbl[] = {