From 4d077838dd699149a58708e2756af44982f1f6a5 Mon Sep 17 00:00:00 2001 From: mcc45tr Date: Tue, 1 Sep 2026 20:13:36 +0300 Subject: [PATCH 30/30] media: qcom: adapt current Nabu Iris overlay to Linux 7.2.2 Synchronize the CFM880/nabu-iris overlay at ea39fff onto the 6.17-derived port, enable its composable Iris and Iris-camera DTBs, and adapt the V4L2 file-handle API used by Linux 7.2.2. Original work: ChengFangming Source: https://github.com/CFM880/nabu-iris Source revision: ea39fff3811e6f3c05d735b147bfb5eca90ec03f --- arch/arm64/boot/dts/qcom/Makefile | 2 + drivers/media/platform/qcom/iris/Kconfig | 3 +- .../platform/qcom/iris/iris_hfi_common.c | 10 +- .../platform/qcom/iris/iris_hfi_common.h | 16 +- .../media/platform/qcom/iris/iris_hfi_gen1.h | 6 +- .../media/platform/qcom/iris/iris_hfi_gen2.h | 5 +- .../platform/qcom/iris/iris_hfi_gen2_packet.c | 18 +-- .../qcom/iris/iris_hfi_gen2_response.c | 72 ++------- .../media/platform/qcom/iris/iris_resources.c | 18 +-- .../media/platform/qcom/iris/iris_resources.h | 1 - drivers/media/platform/qcom/iris/iris_vidc.c | 14 +- drivers/media/platform/qcom/iris/iris_vpu3x.c | 142 +++++++++--------- .../platform/qcom/iris/iris_vpu_common.h | 16 -- .../qcom/iris/iris_vpu_register_defines.h | 61 -------- drivers/media/platform/qcom/venus/core.c | 34 ++--- drivers/media/platform/qcom/venus/core.h | 43 +----- drivers/media/platform/qcom/venus/firmware.c | 61 +++----- drivers/media/platform/qcom/venus/hfi_venus.c | 32 +--- senemos/configs/nabu-minimal.config | 1 + 19 files changed, 169 insertions(+), 386 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index b21bd83a0b6f..f633fc6c2007 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -356,6 +356,8 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8150-sony-xperia-kumano-bahamut.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8150-sony-xperia-kumano-griffin.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8150-xiaomi-nabu.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8150-xiaomi-nabu-camera.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm8150-xiaomi-nabu-iris.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm8150-xiaomi-nabu-iris-camera.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8250-hdk.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8250-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8250-samsung-r8q.dtb diff --git a/drivers/media/platform/qcom/iris/Kconfig b/drivers/media/platform/qcom/iris/Kconfig index af78a1775937..3c803a05305a 100644 --- a/drivers/media/platform/qcom/iris/Kconfig +++ b/drivers/media/platform/qcom/iris/Kconfig @@ -3,9 +3,8 @@ config VIDEO_QCOM_IRIS depends on VIDEO_DEV depends on ARCH_QCOM || COMPILE_TEST select V4L2_MEM2MEM_DEV - select QCOM_MDT_LOADER + select QCOM_MDT_LOADER if ARCH_QCOM select QCOM_SCM - select QCOM_UBWC_CONFIG select VIDEOBUF2_DMA_CONTIG help This is a V4L2 driver for Qualcomm iris video accelerator diff --git a/drivers/media/platform/qcom/iris/iris_hfi_common.c b/drivers/media/platform/qcom/iris/iris_hfi_common.c index a4c35c773411..1b591bc40631 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_sys_ops *hfi_ops = core->hfi_sys_ops; + const struct iris_hfi_command_ops *hfi_ops = core->hfi_ops; int ret; /* @@ -132,7 +132,7 @@ irqreturn_t iris_hfi_isr_handler(int irq, void *data) iris_vpu_clear_interrupt(core); mutex_unlock(&core->lock); - core->hfi_sys_ops->sys_hfi_response_handler(core); + core->hfi_response_ops->hfi_response_handler(core); if (!iris_vpu_watchdog(core, core->intr_status)) enable_irq(irq); @@ -168,7 +168,7 @@ int iris_hfi_pm_suspend(struct iris_core *core) int iris_hfi_pm_resume(struct iris_core *core) { - const struct iris_hfi_sys_ops *ops = core->hfi_sys_ops; + const struct iris_hfi_command_ops *ops = core->hfi_ops; int ret; ret = iris_vpu_power_on(core); @@ -183,10 +183,6 @@ 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_hfi_common.h b/drivers/media/platform/qcom/iris/iris_hfi_common.h index a27447eb2519..b51471fb32c7 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_common.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_common.h @@ -105,18 +105,11 @@ struct iris_hfi_prop_type_handle { int (*handle)(struct iris_inst *inst, u32 plane); }; -struct iris_hfi_sys_ops { +struct iris_hfi_command_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_inst *(*sys_get_instance)(void); -}; - -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, @@ -133,6 +126,10 @@ 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]; @@ -144,9 +141,6 @@ struct hfi_subscription_params { u32 profile; u32 level; u32 tier; - u32 drap; - u32 film_grain; - u32 super_block; }; u32 iris_hfi_get_v4l2_color_primaries(u32 hfi_primaries); diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h index c37adf65055a..19b8e9054a75 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1.h @@ -7,8 +7,10 @@ #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); +void iris_hfi_gen1_command_ops_init(struct iris_core *core); +void iris_hfi_gen1_response_ops_init(struct iris_core *core); +struct iris_inst *iris_hfi_gen1_get_instance(void); #endif diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h index 21ab58e0aa84..b9d3749a10ef 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2.h @@ -34,7 +34,8 @@ struct iris_inst_hfi_gen2 { struct hfi_subscription_params dst_subcr_params; }; -void iris_hfi_gen2_sys_ops_init(struct iris_core *core); -void iris_hfi_gen2_response_handler(struct iris_core *core); +void iris_hfi_gen2_command_ops_init(struct iris_core *core); +void iris_hfi_gen2_response_ops_init(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_packet.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c index 0d05dd2afc07..d77fa29f44fc 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_packet.c @@ -3,9 +3,6 @@ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ -#include -#include - #include "iris_hfi_common.h" #include "iris_hfi_gen2.h" #include "iris_hfi_gen2_packet.h" @@ -123,7 +120,6 @@ static void iris_hfi_gen2_create_packet(struct iris_hfi_header *hdr, u32 pkt_typ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_header *hdr) { - const struct qcom_ubwc_cfg_data *ubwc = core->ubwc_cfg; u32 payload = 0; iris_hfi_gen2_create_header(hdr, 0, core->header_id++); @@ -140,7 +136,7 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); - payload = qcom_ubwc_macrotile_mode(ubwc) ? 8 : 4; + payload = core->iris_platform_data->ubwc_config->max_channels; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_MAX_CHANNELS, HFI_HOST_FLAGS_NONE, @@ -150,7 +146,7 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); - payload = qcom_ubwc_min_acc_length_64b(ubwc) ? 64 : 32; + payload = core->iris_platform_data->ubwc_config->mal_length; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_MAL_LENGTH, HFI_HOST_FLAGS_NONE, @@ -160,7 +156,7 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); - payload = ubwc->highest_bank_bit; + payload = core->iris_platform_data->ubwc_config->highest_bank_bit; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_HBB, HFI_HOST_FLAGS_NONE, @@ -170,7 +166,7 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); - payload = !!(qcom_ubwc_swizzle(ubwc) & UBWC_SWIZZLE_ENABLE_LVL1); + payload = core->iris_platform_data->ubwc_config->bank_swzl_level; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_BANK_SWZL_LEVEL1, HFI_HOST_FLAGS_NONE, @@ -180,7 +176,7 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); - payload = !!(qcom_ubwc_swizzle(ubwc) & UBWC_SWIZZLE_ENABLE_LVL2); + payload = core->iris_platform_data->ubwc_config->bank_swz2_level; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_BANK_SWZL_LEVEL2, HFI_HOST_FLAGS_NONE, @@ -190,7 +186,7 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); - payload = !!(qcom_ubwc_swizzle(ubwc) & UBWC_SWIZZLE_ENABLE_LVL3); + payload = core->iris_platform_data->ubwc_config->bank_swz3_level; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_BANK_SWZL_LEVEL3, HFI_HOST_FLAGS_NONE, @@ -200,7 +196,7 @@ void iris_hfi_gen2_packet_sys_init(struct iris_core *core, struct iris_hfi_heade &payload, sizeof(u32)); - payload = qcom_ubwc_bank_spread(ubwc); + payload = core->iris_platform_data->ubwc_config->bank_spreading; iris_hfi_gen2_create_packet(hdr, HFI_PROP_UBWC_BANK_SPREADING, HFI_HOST_FLAGS_NONE, 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 25162ae71357..2f1f118eae4f 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_response.c @@ -54,10 +54,6 @@ static u32 iris_hfi_gen2_buf_type_to_driver(struct iris_inst *inst, return BUF_SCRATCH_2; case HFI_BUFFER_PERSIST: return BUF_PERSIST; - case HFI_BUFFER_PARTIAL_DATA: - return BUF_PARTIAL; - case HFI_BUFFER_VPSS: - return BUF_VPSS; default: return 0; } @@ -76,7 +72,6 @@ static bool iris_hfi_gen2_is_valid_hfi_buffer_type(u32 buffer_type) case HFI_BUFFER_DPB: case HFI_BUFFER_PERSIST: case HFI_BUFFER_VPSS: - case HFI_BUFFER_PARTIAL_DATA: return true; default: return false; @@ -542,33 +537,9 @@ static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) pixmp_ip->width = width; pixmp_ip->height = height; - if (subsc_params.bit_depth == BIT_DEPTH_8 && - pixmp_op->pixelformat != V4L2_PIX_FMT_NV12 && - pixmp_op->pixelformat != V4L2_PIX_FMT_QC08C) - pixmp_op->pixelformat = V4L2_PIX_FMT_NV12; - else if (subsc_params.bit_depth == BIT_DEPTH_10 && - pixmp_op->pixelformat != V4L2_PIX_FMT_P010 && - pixmp_op->pixelformat != V4L2_PIX_FMT_QC10C) - pixmp_op->pixelformat = V4L2_PIX_FMT_P010; - - switch (pixmp_op->pixelformat) { - case V4L2_PIX_FMT_P010: - pixmp_op->width = ALIGN(width, 128); - pixmp_op->height = ALIGN(height, 32); - pixmp_op->plane_fmt[0].bytesperline = ALIGN(width * 2, 256); - break; - case V4L2_PIX_FMT_QC10C: - pixmp_op->width = roundup(width, 192); - pixmp_op->height = ALIGN(height, 16); - pixmp_op->plane_fmt[0].bytesperline = ALIGN(pixmp_op->width * 4 / 3, 256); - break; - case V4L2_PIX_FMT_NV12: - case V4L2_PIX_FMT_QC08C: - pixmp_op->width = ALIGN(width, 128); - pixmp_op->height = ALIGN(height, 32); - pixmp_op->plane_fmt[0].bytesperline = pixmp_op->width; - break; - } + pixmp_op->width = ALIGN(width, 128); + pixmp_op->height = ALIGN(height, 32); + pixmp_op->plane_fmt[0].bytesperline = ALIGN(width, 128); pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT); matrix_coeff = subsc_params.color_info & 0xFF; @@ -625,32 +596,18 @@ static void iris_hfi_gen2_read_input_subcr_params(struct iris_inst *inst) inst->fw_caps[PROFILE_H264].value = subsc_params.profile; inst->fw_caps[LEVEL_H264].value = subsc_params.level; break; - case V4L2_PIX_FMT_AV1: - inst->fw_caps[PROFILE_AV1].value = subsc_params.profile; - inst->fw_caps[LEVEL_AV1].value = subsc_params.level; - break; } inst->fw_caps[POC].value = subsc_params.pic_order_cnt; inst->fw_caps[TIER].value = subsc_params.tier; - if (subsc_params.bit_depth == BIT_DEPTH_8) - inst->fw_caps[BIT_DEPTH].value = BIT_DEPTH_8; - else - inst->fw_caps[BIT_DEPTH].value = BIT_DEPTH_10; - - if ((subsc_params.bit_depth != BIT_DEPTH_8 && subsc_params.bit_depth != BIT_DEPTH_10) || + if (subsc_params.bit_depth != BIT_DEPTH_8 || !(subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)) { dev_err(core->dev, "unsupported content, bit depth: %x, pic_struct = %x\n", subsc_params.bit_depth, subsc_params.coded_frames); iris_inst_change_state(inst, IRIS_INST_ERROR); } - if (inst->codec == V4L2_PIX_FMT_AV1) { - inst->fw_caps[FILM_GRAIN].value = subsc_params.film_grain; - inst->fw_caps[SUPER_BLOCK].value = subsc_params.super_block; - } - inst->fw_min_count = subsc_params.fw_min_count; inst->buffers[BUF_OUTPUT].min_count = iris_vpu_buf_count(inst, BUF_OUTPUT); inst->buffers[BUF_OUTPUT].size = pixmp_op->plane_fmt[0].sizeimage; @@ -754,12 +711,6 @@ static int iris_hfi_gen2_handle_session_property(struct iris_inst *inst, case HFI_PROP_NO_OUTPUT: inst_hfi_gen2->hfi_frame_info.no_output = 1; break; - case HFI_PROP_AV1_FILM_GRAIN_PRESENT: - inst_hfi_gen2->src_subcr_params.film_grain = pkt->payload[0]; - break; - case HFI_PROP_AV1_SUPER_BLOCK_ENABLED: - inst_hfi_gen2->src_subcr_params.super_block = pkt->payload[0]; - break; case HFI_PROP_QUALITY_MODE: case HFI_PROP_STAGE: case HFI_PROP_PIPE: @@ -890,10 +841,6 @@ static void iris_hfi_gen2_init_src_change_param(struct iris_inst *inst) subsc_params->profile = inst->fw_caps[PROFILE_H264].value; subsc_params->level = inst->fw_caps[LEVEL_H264].value; break; - case V4L2_PIX_FMT_AV1: - subsc_params->profile = inst->fw_caps[PROFILE_AV1].value; - subsc_params->level = inst->fw_caps[LEVEL_AV1].value; - break; } subsc_params->pic_order_cnt = inst->fw_caps[POC].value; @@ -1006,7 +953,7 @@ static void iris_hfi_gen2_flush_debug_queue(struct iris_core *core, u8 *packet) } } -void iris_hfi_gen2_response_handler(struct iris_core *core) +static 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}; @@ -1026,3 +973,12 @@ 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_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c index 8d8ddd398eea..98957a74b936 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.c +++ b/drivers/media/platform/qcom/iris/iris_resources.c @@ -4,7 +4,6 @@ */ #include -#include #include #include #include @@ -67,22 +66,11 @@ int iris_unset_icc_bw(struct iris_core *core) return icc_bulk_set_bw(core->icc_count, core->icc_tbl); } -int iris_opp_set_rate(struct device *dev, unsigned long freq) -{ - struct dev_pm_opp *opp __free(put_opp); - - opp = devfreq_recommended_opp(dev, &freq, 0); - if (IS_ERR(opp)) - return PTR_ERR(opp); - - return dev_pm_opp_set_opp(dev, opp); -} - int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev) { int ret; - ret = iris_opp_set_rate(core->dev, ULONG_MAX); + ret = dev_pm_opp_set_rate(core->dev, ULONG_MAX); if (ret) return ret; @@ -97,7 +85,7 @@ int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev) { int ret; - ret = iris_opp_set_rate(core->dev, 0); + ret = dev_pm_opp_set_rate(core->dev, 0); if (ret) return ret; @@ -133,7 +121,7 @@ int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk clock = iris_get_clk_by_type(core, clk_type); if (!clock) - return -ENOENT; + return -EINVAL; ret = clk_prepare_enable(clock); if (!ret) diff --git a/drivers/media/platform/qcom/iris/iris_resources.h b/drivers/media/platform/qcom/iris/iris_resources.h index 6bfbd2dc6db0..f723dfe5bd81 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.h +++ b/drivers/media/platform/qcom/iris/iris_resources.h @@ -8,7 +8,6 @@ struct iris_core; -int iris_opp_set_rate(struct device *dev, unsigned long freq); int iris_enable_power_domains(struct iris_core *core, struct device *pd_dev); int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev); int iris_unset_icc_bw(struct iris_core *core); diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index 8351b45369e9..d029acd6994a 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -174,19 +174,19 @@ static long iris_vidioc_default(struct file *file, void *fh, bool valid_prio, return ret; } -static void iris_v4l2_fh_init(struct iris_inst *inst) +static void iris_v4l2_fh_init(struct iris_inst *inst, struct file *filp) { if (inst->domain == ENCODER) v4l2_fh_init(&inst->fh, inst->core->vdev_enc); else if (inst->domain == DECODER) v4l2_fh_init(&inst->fh, inst->core->vdev_dec); inst->fh.ctrl_handler = &inst->ctrl_handler; - v4l2_fh_add(&inst->fh); + v4l2_fh_add(&inst->fh, filp); } -static void iris_v4l2_fh_deinit(struct iris_inst *inst) +static void iris_v4l2_fh_deinit(struct iris_inst *inst, struct file *filp) { - v4l2_fh_del(&inst->fh); + v4l2_fh_del(&inst->fh, filp); inst->fh.ctrl_handler = NULL; v4l2_fh_exit(&inst->fh); } @@ -320,7 +320,7 @@ int iris_open(struct file *filp) init_completion(&inst->completion); init_completion(&inst->flush_completion); - iris_v4l2_fh_init(inst); + iris_v4l2_fh_init(inst, filp); inst->m2m_dev = v4l2_m2m_init(&iris_m2m_ops); if (IS_ERR_OR_NULL(inst->m2m_dev)) { @@ -353,7 +353,7 @@ int iris_open(struct file *filp) fail_m2m_release: v4l2_m2m_release(inst->m2m_dev); fail_v4l2_fh_deinit: - iris_v4l2_fh_deinit(inst); + iris_v4l2_fh_deinit(inst, filp); mutex_destroy(&inst->ctx_q_lock); mutex_destroy(&inst->lock); kfree(inst); @@ -414,7 +414,7 @@ int iris_close(struct file *filp) v4l2_m2m_release(inst->m2m_dev); mutex_lock(&inst->lock); iris_hfi_session_close(inst); - iris_v4l2_fh_deinit(inst); + iris_v4l2_fh_deinit(inst, filp); iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c index 3dad47be78b5..9b7c9a1495ee 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. - * Copyright (c) 2025 Linaro Ltd */ #include @@ -11,6 +10,43 @@ #include "iris_vpu_common.h" #include "iris_vpu_register_defines.h" +#define WRAPPER_TZ_BASE_OFFS 0x000C0000 +#define AON_BASE_OFFS 0x000E0000 +#define AON_MVP_NOC_RESET 0x0001F000 + +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54) +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58) +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C) +#define REQ_POWER_DOWN_PREP BIT(0) +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60) +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88) +#define CORE_CLK_RUN 0x0 + +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14) +#define CTL_AXI_CLK_HALT BIT(0) +#define CTL_CLK_HALT BIT(1) + +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18) +#define RESET_HIGH BIT(0) + +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160) +#define CORE_BRIDGE_SW_RESET BIT(0) +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1) + +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) +#define MSK_SIGNAL_FROM_TENSILICA BIT(0) +#define MSK_CORE_POWER_ON BIT(1) + +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000) +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1)) + +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004) + +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70) + +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) + #define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18) #define SW_RESET BIT(0) #define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20) @@ -73,9 +109,7 @@ static void iris_vpu3_power_off_hardware(struct iris_core *core) static void iris_vpu33_power_off_hardware(struct iris_core *core) { - bool handshake_done = false, handshake_busy = false; u32 reg_val = 0, value, i; - u32 count = 0; int ret; if (iris_vpu3x_hw_power_collapsed(core)) @@ -94,36 +128,13 @@ static void iris_vpu33_power_off_hardware(struct iris_core *core) goto disable_power; } - /* Retry up to 1000 times as recommended by hardware documentation */ - do { - /* set MNoC to low power */ - writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); - - udelay(15); - - value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS); - - handshake_done = value & NOC_LPI_STATUS_DONE; - handshake_busy = value & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE); - - if (handshake_done || !handshake_busy) - break; - - writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); - - udelay(15); - - } while (++count < 1000); - - if (!handshake_done && handshake_busy) - dev_err(core->dev, "LPI handshake timeout\n"); - ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, reg_val, reg_val & BIT(0), 200, 2000); if (ret) goto disable_power; - writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */ + writel(BIT(0), core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); @@ -214,70 +225,51 @@ static int iris_vpu33_power_off_controller(struct iris_core *core) return 0; } -static int iris_vpu35_power_on_hw(struct iris_core *core) +static u64 iris_vpu3x_calculate_frequency(struct iris_inst *inst, size_t data_size) { - int ret; + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; + struct v4l2_format *inp_f = inst->fmt_src; + u32 height, width, mbs_per_second, mbpf; + u64 fw_cycles, fw_vpp_cycles; + u64 vsp_cycles, vpp_cycles; + u32 fps = DEFAULT_FPS; - 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_AXI_CLK); - if (ret) - goto err_disable_power; + width = max(inp_f->fmt.pix_mp.width, inst->crop.width); + height = max(inp_f->fmt.pix_mp.height, inst->crop.height); - ret = iris_prepare_enable_clock(core, IRIS_HW_FREERUN_CLK); - if (ret) - goto err_disable_axi_clk; + mbpf = NUM_MBS_PER_FRAME(height, width); + mbs_per_second = mbpf * fps; - ret = iris_prepare_enable_clock(core, IRIS_HW_CLK); - if (ret) - goto err_disable_hw_free_clk; + fw_cycles = fps * caps->mb_cycles_fw; + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp; - return 0; + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value); + /* 21 / 20 is minimum overhead factor */ + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles); -err_disable_hw_free_clk: - iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK); -err_disable_axi_clk: - iris_disable_unprepare_clock(core, IRIS_AXI_CLK); -err_disable_power: - iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); + /* 1.059 is multi-pipe overhead */ + if (inst->fw_caps[PIPE].value > 1) + vpp_cycles += div_u64(vpp_cycles * 59, 1000); - return ret; -} + vsp_cycles = fps * data_size * 8; + vsp_cycles = div_u64(vsp_cycles, 2); + /* VSP FW overhead 1.05 */ + vsp_cycles = div_u64(vsp_cycles * 21, 20); -static void iris_vpu35_power_off_hw(struct iris_core *core) -{ - iris_vpu33_power_off_hardware(core); + if (inst->fw_caps[STAGE].value == STAGE_1) + vsp_cycles = vsp_cycles * 3; - iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK); - iris_disable_unprepare_clock(core, IRIS_AXI_CLK); + return max3(vpp_cycles, vsp_cycles, fw_cycles); } const struct vpu_ops iris_vpu3_ops = { .power_off_hw = iris_vpu3_power_off_hardware, - .power_on_hw = iris_vpu_power_on_hw, .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, + .calc_freq = iris_vpu3x_calculate_frequency, }; const struct vpu_ops iris_vpu33_ops = { .power_off_hw = iris_vpu33_power_off_hardware, - .power_on_hw = iris_vpu_power_on_hw, .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 = { - .power_off_hw = iris_vpu35_power_off_hw, - .power_on_hw = iris_vpu35_power_on_hw, - .power_off_controller = iris_vpu35_vpu4x_power_off_controller, - .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, + .calc_freq = iris_vpu3x_calculate_frequency, }; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h index 09799a375c14..93b7fa27be3b 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h @@ -11,17 +11,11 @@ struct iris_core; extern const struct vpu_ops iris_vpu2_ops; 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; struct vpu_ops { void (*power_off_hw)(struct iris_core *core); - int (*power_on_hw)(struct iris_core *core); int (*power_off_controller)(struct iris_core *core); - 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); @@ -29,19 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core); void iris_vpu_clear_interrupt(struct iris_core *core); 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); void iris_vpu_power_off(struct iris_core *core); -int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core); -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 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 72168b9ffa73..fe8a39e5e5a3 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h +++ b/drivers/media/platform/qcom/iris/iris_vpu_register_defines.h @@ -7,72 +7,11 @@ #define __IRIS_VPU_REGISTER_DEFINES_H__ #define VCODEC_BASE_OFFS 0x00000000 -#define AON_MVP_NOC_RESET 0x0001F000 #define CPU_BASE_OFFS 0x000A0000 #define WRAPPER_BASE_OFFS 0x000B0000 -#define WRAPPER_TZ_BASE_OFFS 0x000C0000 -#define AON_BASE_OFFS 0x000E0000 - -#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70) - -#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000) -#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1)) - -#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004) #define CPU_CS_BASE_OFFS (CPU_BASE_OFFS) -#define CPU_IC_BASE_OFFS (CPU_BASE_OFFS) - -#define CPU_CS_A2HSOFTINTCLR (CPU_CS_BASE_OFFS + 0x1C) -#define CLEAR_XTENSA2HOST_INTR BIT(0) - -#define CPU_CS_H2XSOFTINTEN (CPU_CS_BASE_OFFS + 0x148) -#define HOST2XTENSA_INTR_ENABLE BIT(0) - -#define CPU_IC_SOFTINT (CPU_IC_BASE_OFFS + 0x150) -#define CPU_IC_SOFTINT_H2A_SHFT 0x0 - -#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160) -#define CORE_BRIDGE_SW_RESET BIT(0) -#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1) - -#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) -#define MSK_SIGNAL_FROM_TENSILICA BIT(0) -#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) -#define WRAPPER_INTR_MASK_A2HWD_BMSK BIT(3) -#define WRAPPER_INTR_MASK_A2HCPU_BMSK BIT(2) - -#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54) -#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58) -#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C) -#define REQ_POWER_DOWN_PREP BIT(0) - -#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60) -#define NOC_LPI_STATUS_DONE BIT(0) /* Indicates the NOC handshake is complete */ -#define NOC_LPI_STATUS_DENY BIT(1) /* Indicates the NOC handshake is denied */ -#define NOC_LPI_STATUS_ACTIVE BIT(2) /* Indicates the NOC is active */ - -#define WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0 (WRAPPER_BASE_OFFS + 0x78) #define WRAPPER_CORE_POWER_STATUS (WRAPPER_BASE_OFFS + 0x80) -#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88) -#define CORE_CLK_RUN 0x0 - -#define WRAPPER_TZ_CPU_STATUS (WRAPPER_TZ_BASE_OFFS + 0x10) - -#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14) -#define CTL_AXI_CLK_HALT BIT(0) -#define CTL_CLK_HALT BIT(1) - -#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18) -#define RESET_HIGH BIT(0) - -#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) -#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) #endif diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 0a41eed4a999..a8c40576f3a2 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -429,21 +429,21 @@ static int venus_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&core->work, venus_sys_error_handler); init_waitqueue_head(&core->sys_err_done); - ret = hfi_create(core, &venus_core_ops); - if (ret) - goto err_core_put; - ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, venus_isr_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "venus", core); if (ret) goto err_core_put; + ret = hfi_create(core, &venus_core_ops); + if (ret) + goto err_core_put; + venus_assign_register_offsets(core); ret = v4l2_device_register(dev, &core->v4l2_dev); if (ret) - goto err_hfi_destroy; + goto err_core_deinit; platform_set_drvdata(pdev, core); @@ -491,25 +491,25 @@ static int venus_probe(struct platform_device *pdev) stage = "enumerate decoder codecs"; ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC); if (ret) - goto err_core_deinit; + goto err_venus_shutdown; stage = "enumerate encoder codecs"; ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC); if (ret) - goto err_core_deinit; + goto err_venus_shutdown; ret = pm_runtime_put_sync(dev); if (ret) { pm_runtime_get_noresume(dev); - goto err_core_deinit; + goto err_dev_unregister; } venus_dbgfs_init(core); return 0; -err_core_deinit: - hfi_core_deinit(core, false); +err_dev_unregister: + v4l2_device_unregister(&core->v4l2_dev); err_venus_shutdown: venus_shutdown(core); err_firmware_deinit: @@ -522,9 +522,9 @@ static int venus_probe(struct platform_device *pdev) pm_runtime_put_noidle(dev); pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - v4l2_device_unregister(&core->v4l2_dev); -err_hfi_destroy: hfi_destroy(core); +err_core_deinit: + hfi_core_deinit(core, false); err_core_put: if (core->pm_ops->core_put) core->pm_ops->core_put(core); @@ -726,11 +726,11 @@ static const struct venus_resources msm8996_res = { }; static const struct freq_tbl msm8998_freq_table[] = { - { 1728000, 533000000 }, /* 4k UHD @ 60 (decode only) */ - { 1036800, 444000000 }, /* 2k @ 120 */ - { 829440, 355200000 }, /* 4k @ 44 */ - { 489600, 269330000 },/* 4k @ 30 */ - { 108000, 200000000 }, /* 1080p @ 60 */ + { 1944000, 465000000 }, /* 4k UHD @ 60 (decode only) */ + { 972000, 465000000 }, /* 4k UHD @ 30 */ + { 489600, 360000000 }, /* 1080p @ 60 */ + { 244800, 186000000 }, /* 1080p @ 30 */ + { 108000, 100000000 }, /* 720p @ 30 */ }; static const struct reg_val msm8998_reg_preset[] = { diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 165f11d1eb52..721fa7648f11 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -28,8 +28,6 @@ #define VIDC_RESETS_NUM_MAX 4 #define VIDC_MAX_HIER_CODING_LAYER 6 -#define VENUS_MAX_FPS 240 - extern int venus_fw_debug; struct freq_tbl { @@ -54,16 +52,8 @@ 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 { - u32 major; - u32 minor; - u32 rev; }; struct venus_resources { @@ -79,17 +69,13 @@ struct venus_resources { const struct hfi_ubwc_config *ubwc_conf; const char * const clks[VIDC_CLKS_NUM_MAX]; unsigned int clks_num; - const char * const vcodec_clks[VIDC_VCODEC_CLKS_NUM_MAX]; const char * const vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX]; const char * const vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX]; unsigned int vcodec_clks_num; const char **vcodec_pmdomains; unsigned int vcodec_pmdomains_num; const char **opp_pmdomain; - unsigned int opp_pmdomain_num; unsigned int vcodec_num; - const u32 dec_codec_blacklist; - const u32 enc_codec_blacklist; const char * const resets[VIDC_RESETS_NUM_MAX]; unsigned int resets_num; enum hfi_version hfi_version; @@ -106,7 +92,6 @@ struct venus_resources { const char *fwname; const char *enc_nodename; const char *dec_nodename; - const struct firmware_version *min_fw; }; enum venus_fmt { @@ -146,7 +131,6 @@ struct venus_format { * @aon_base: AON base address * @irq: Venus irq * @clks: an array of struct clk pointers - * @vcodec_clks: an array of vcodec struct clk pointers * @vcodec0_clks: an array of vcodec0 struct clk pointers * @vcodec1_clks: an array of vcodec1 struct clk pointers * @video_path: an interconnect handle to video to/from memory path @@ -188,7 +172,6 @@ struct venus_format { * @venus_ver: the venus firmware version * @dump_core: a flag indicating that a core dump is required * @ocs: OF changeset pointer - * @hwmode_dev: a flag indicating that HW_CTRL_TRIGGER is used in clock driver */ struct venus_core { void __iomem *base; @@ -201,7 +184,6 @@ struct venus_core { void __iomem *aon_base; int irq; struct clk *clks[VIDC_CLKS_NUM_MAX]; - struct clk *vcodec_clks[VIDC_VCODEC_CLKS_NUM_MAX]; struct clk *vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX]; struct clk *vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX]; struct icc_path *video_path; @@ -246,10 +228,13 @@ struct venus_core { unsigned int core0_usage_count; unsigned int core1_usage_count; struct dentry *root; - struct firmware_version venus_ver; + struct venus_img_version { + u32 major; + u32 minor; + u32 rev; + } venus_ver; unsigned long dump_core; struct of_changeset *ocs; - bool hwmode_dev; }; struct vdec_controls { @@ -533,34 +518,20 @@ 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) (((void)(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) (((void)(core), 0)) -#define IS_IRIS2_1(core) (((void)(core), 0)) -#endif - -static inline bool is_lite(struct venus_core *core) -{ - return IS_AR50_LITE(core); -} #define ctrl_to_inst(ctrl) \ container_of((ctrl)->handler, struct venus_inst, ctrl_handler) static inline struct venus_inst *to_inst(struct file *filp) { - return container_of(file_to_v4l2_fh(filp), struct venus_inst, fh); + return container_of(filp->private_data, struct venus_inst, fh); } static inline void *to_hfi_priv(struct venus_core *core) @@ -598,5 +569,5 @@ is_fw_rev_or_older(struct venus_core *core, u32 vmajor, u32 vminor, u32 vrev) (core)->venus_ver.rev <= vrev); } -void venus_close_common(struct venus_inst *inst, struct file *filp); +void venus_close_common(struct venus_inst *inst); #endif diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index 9eaba13536ab..76dc63f6b3fd 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,7 @@ static void venus_reset_cpu(struct venus_core *core) u32 fw_size = core->fw.mapped_mem_size; void __iomem *wrapper_base; - if (IS_IRIS2(core) || IS_IRIS2_1(core)) + if (IS_IRIS2_1(core)) wrapper_base = core->wrapper_tz_base; else wrapper_base = core->wrapper_base; @@ -41,7 +42,7 @@ static void venus_reset_cpu(struct venus_core *core) writel(fw_size, wrapper_base + WRAPPER_NONPIX_START_ADDR); writel(fw_size, wrapper_base + WRAPPER_NONPIX_END_ADDR); - if (IS_IRIS2(core) || IS_IRIS2_1(core)) { + if (IS_IRIS2_1(core)) { /* Bring XTSS out of reset */ writel(0, wrapper_base + WRAPPER_TZ_XTSS_SW_RESET); } else { @@ -67,7 +68,7 @@ int venus_set_hw_state(struct venus_core *core, bool resume) if (resume) { venus_reset_cpu(core); } else { - if (IS_IRIS2(core) || IS_IRIS2_1(core)) + if (IS_IRIS2_1(core)) writel(WRAPPER_XTSS_SW_RESET_BIT, core->wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET); else @@ -82,7 +83,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, phys_addr_t *mem_phys, size_t *mem_size) { const struct firmware *mdt; - struct resource res; + struct reserved_mem *rmem; + struct device_node *node; struct device *dev; ssize_t fw_size; void *mem_va; @@ -92,8 +94,15 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, *mem_size = 0; dev = core->dev; - ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res); - if (ret) { + node = of_parse_phandle(dev->of_node, "memory-region", 0); + if (!node) { + dev_err(dev, "no memory-region specified\n"); + return -EINVAL; + } + + rmem = of_reserved_mem_lookup(node); + of_node_put(node); + if (!rmem) { dev_err(dev, "failed to lookup reserved memory-region\n"); return -EINVAL; } @@ -108,8 +117,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, goto err_release_fw; } - *mem_phys = res.start; - *mem_size = resource_size(&res); + *mem_phys = rmem->base; + *mem_size = rmem->size; if (*mem_size < fw_size || fw_size > VENUS_FW_MEM_SIZE) { ret = -EINVAL; @@ -127,8 +136,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID, mem_va, *mem_phys, *mem_size, NULL); else - ret = qcom_mdt_load_no_init(dev, mdt, fwname, mem_va, - *mem_phys, *mem_size, NULL); + ret = qcom_mdt_load_no_init(dev, mdt, fwname, VENUS_PAS_ID, + mem_va, *mem_phys, *mem_size, NULL); memunmap(mem_va); err_release_fw: @@ -172,7 +181,7 @@ static int venus_shutdown_no_tz(struct venus_core *core) void __iomem *wrapper_base = core->wrapper_base; void __iomem *wrapper_tz_base = core->wrapper_tz_base; - if (IS_IRIS2(core) || IS_IRIS2_1(core)) { + if (IS_IRIS2_1(core)) { /* Assert the reset to XTSS */ reg = readl(wrapper_tz_base + WRAPPER_TZ_XTSS_SW_RESET); reg |= WRAPPER_XTSS_SW_RESET_BIT; @@ -198,16 +207,6 @@ static int venus_shutdown_no_tz(struct venus_core *core) return 0; } -int venus_firmware_cfg(struct venus_core *core) -{ - void __iomem *cpu_cs_base = core->cpu_cs_base; - - if (IS_AR50_LITE(core)) - writel(CPU_CS_VCICMD_ARP_OFF, cpu_cs_base + CPU_CS_VCICMD); - - return 0; -} - int venus_boot(struct venus_core *core) { struct device *dev = core->dev; @@ -289,26 +288,6 @@ int venus_shutdown(struct venus_core *core) return ret; } -int venus_firmware_check(struct venus_core *core) -{ - const struct firmware_version *req = core->res->min_fw; - const struct firmware_version *run = &core->venus_ver; - - if (!req) - return 0; - - if (!is_fw_rev_or_newer(core, req->major, req->minor, req->rev)) - goto error; - - return 0; -error: - dev_err(core->dev, "Firmware v%d.%d.%d < v%d.%d.%d\n", - run->major, run->minor, run->rev, - req->major, req->minor, req->rev); - - return -EINVAL; -} - int venus_firmware_init(struct venus_core *core) { struct platform_device_info info; diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index c36ce32cc6b0..efa3237d7f84 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -239,7 +239,6 @@ static int venus_write_queue(struct venus_hfi_device *hdev, static int venus_read_queue(struct venus_hfi_device *hdev, struct iface_queue *queue, void *pkt, u32 *tx_req) { - struct hfi_pkt_hdr *pkt_hdr = NULL; struct hfi_queue_header *qhdr; u32 dwords, new_rd_idx; u32 rd_idx, wr_idx, type, qsize; @@ -305,9 +304,6 @@ static int venus_read_queue(struct venus_hfi_device *hdev, memcpy(pkt, rd_ptr, len); memcpy(pkt + len, queue->qmem.kva, new_rd_idx << 2); } - pkt_hdr = (struct hfi_pkt_hdr *)(pkt); - if ((pkt_hdr->size >> 2) != dwords) - return -EINVAL; } else { /* bad packet received, dropping */ new_rd_idx = qhdr->write_idx; @@ -380,7 +376,7 @@ static void venus_soft_int(struct venus_hfi_device *hdev) void __iomem *cpu_ic_base = hdev->core->cpu_ic_base; u32 clear_bit; - if (IS_V6(hdev->core) || (IS_V4(hdev->core) && is_lite(hdev->core))) + if (IS_V6(hdev->core)) clear_bit = BIT(CPU_IC_SOFTINT_H2A_SHIFT_V6); else clear_bit = BIT(CPU_IC_SOFTINT_H2A_SHIFT); @@ -506,11 +502,9 @@ static int venus_boot_core(struct venus_hfi_device *hdev) if (count >= max_tries) ret = -ETIMEDOUT; - if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core)) { + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) { writel(0x1, cpu_cs_base + CPU_CS_H2XSOFTINTEN_V6); - - if (!IS_AR50_LITE(hdev->core)) - writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6); + writel(0x0, cpu_cs_base + CPU_CS_X2RPMH_V6); } return ret; @@ -576,9 +570,6 @@ static int venus_halt_axi(struct venus_hfi_device *hdev) u32 mask_val; int ret; - if (IS_AR50_LITE(hdev->core)) - return 0; - if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) { writel(0x3, cpu_cs_base + CPU_CS_X2RPMH_V6); @@ -1153,13 +1144,7 @@ static irqreturn_t venus_isr(struct venus_core *core) wrapper_base = hdev->core->wrapper_base; status = readl(wrapper_base + WRAPPER_INTR_STATUS); - - if (IS_AR50_LITE(core)) { - if (status & WRAPPER_INTR_STATUS_A2H_MASK || - status & WRAPPER_INTR_STATUS_A2HWD_MASK_V4_LITE || - status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK) - hdev->irq_status = status; - } else if (IS_IRIS2(core) || IS_IRIS2_1(core)) { + if (IS_IRIS2(core) || IS_IRIS2_1(core)) { if (status & WRAPPER_INTR_STATUS_A2H_MASK || status & WRAPPER_INTR_STATUS_A2HWD_MASK_V6 || status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK) @@ -1171,7 +1156,7 @@ static irqreturn_t venus_isr(struct venus_core *core) hdev->irq_status = status; } writel(1, cpu_cs_base + CPU_CS_A2HSOFTINTCLR); - if (!(IS_IRIS2(core) || IS_IRIS2_1(core) || IS_AR50_LITE(core))) + if (!(IS_IRIS2(core) || IS_IRIS2_1(core))) writel(status, wrapper_base + WRAPPER_INTR_CLEAR); return IRQ_WAKE_THREAD; @@ -1556,7 +1541,7 @@ static bool venus_cpu_and_video_core_idle(struct venus_hfi_device *hdev) void __iomem *cpu_cs_base = hdev->core->cpu_cs_base; u32 ctrl_status, cpu_status; - if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core)) + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6); else cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS); @@ -1576,7 +1561,7 @@ static bool venus_cpu_idle_and_pc_ready(struct venus_hfi_device *hdev) void __iomem *cpu_cs_base = hdev->core->cpu_cs_base; u32 ctrl_status, cpu_status; - if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core) || IS_AR50_LITE(hdev->core)) + if (IS_IRIS2(hdev->core) || IS_IRIS2_1(hdev->core)) cpu_status = readl(wrapper_tz_base + WRAPPER_TZ_CPU_STATUS_V6); else cpu_status = readl(wrapper_base + WRAPPER_CPU_STATUS); @@ -1703,7 +1688,6 @@ void venus_hfi_destroy(struct venus_core *core) venus_interface_queues_release(hdev); mutex_destroy(&hdev->lock); kfree(hdev); - disable_irq(core->irq); core->ops = NULL; } @@ -1712,7 +1696,7 @@ int venus_hfi_create(struct venus_core *core) struct venus_hfi_device *hdev; int ret; - hdev = kzalloc_obj(*hdev); + hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); if (!hdev) return -ENOMEM; diff --git a/senemos/configs/nabu-minimal.config b/senemos/configs/nabu-minimal.config index 4dc8f3187cd3..5a14e11d10b1 100644 --- a/senemos/configs/nabu-minimal.config +++ b/senemos/configs/nabu-minimal.config @@ -98,6 +98,7 @@ CONFIG_VIDEO_CN3927=m CONFIG_CMA_SIZE_MBYTES=256 # SM8150 Iris1/Venus hardware video decoder. +CONFIG_VIDEO_QCOM_IRIS=m # Fedora-compatible module packaging. CONFIG_MODULES=y -- 2.55.0