From 7c4bb220ce18c1f18b91739c11f0a858afa1d983 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Tue, 29 Sep 2020 17:54:38 +0530 Subject: [PATCH 1/5] msm: vidc: Add fn pointer for ar50lt bw calc Add ar50lt bw calc function pointer in core ops. Change-Id: I83cb81dde373a14b5b07594ca5af286bc01eefd1 Signed-off-by: Priyanka Gujjula --- msm/vidc/msm_vidc_clocks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_vidc_clocks.c b/msm/vidc/msm_vidc_clocks.c index 13a3bf130977..87aa76a65cc0 100644 --- a/msm/vidc/msm_vidc_clocks.c +++ b/msm/vidc/msm_vidc_clocks.c @@ -31,7 +31,7 @@ struct msm_vidc_core_ops core_ops_ar50_lt = { .decide_work_mode = msm_vidc_decide_work_mode_ar50_lt, .decide_core_and_power_mode = msm_vidc_decide_core_and_power_mode_ar50lt, - .calc_bw = NULL, + .calc_bw = calc_bw_ar50lt, }; struct msm_vidc_core_ops core_ops_iris2 = { From f033016e9e842c5b548b36d5785cc5e94a12c8e2 Mon Sep 17 00:00:00 2001 From: Dikshita Agarwal Date: Thu, 1 Oct 2020 16:32:22 +0530 Subject: [PATCH 2/5] msm-vidc: fix final BW voting to ICC Currently, Required BW is calculated in bytes per second but when setting it to ICC, kbps_to_icc macro is applied to calculated BW which again divides the value by 8 and resulting into less final vote to icc. Change-Id: I7a645478d05909308edea2170d7c5cb911cbf6f0 Signed-off-by: Dikshita Agarwal --- msm/vidc/hfi_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 915a7c6bf4e5..1ffdc65a27ad 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -888,7 +888,7 @@ static int __vote_bandwidth(struct bus_info *bus, int rc = 0; s_vpr_p(sid, "Voting bus %s to ab %llu kbps\n", bus->name, bw_kbps); - rc = icc_set_bw(bus->path, kbps_to_icc(bw_kbps), 0); + rc = icc_set_bw(bus->path, bw_kbps, 0); if (rc) s_vpr_e(sid, "Failed voting bus %s to ab %llu, rc=%d\n", bus->name, bw_kbps, rc); From cb1896477067d3b9f9451a0f64d6c5f20535d915 Mon Sep 17 00:00:00 2001 From: Priyanka Gujjula Date: Fri, 19 Jun 2020 12:37:47 +0530 Subject: [PATCH 3/5] msm: vidc: Add support for hw stability test Add support for noc error and vcodec hung HFI to test hardware stability via ssr_type and to input the sub client id and test address accordingly. ssr_type: 0-3 bits sub_client_id: 4-7 bits reserved: 8-31 bits test_addr: 32-63 bits Change-Id: I05970d3dc3e54da50688319eabccd5d11f8f55e2 Signed-off-by: Priyanka Gujjula lock); - rc = call_hfi_pkt_op(dev, ssr_cmd, type, &pkt); + rc = call_hfi_pkt_op(dev, ssr_cmd, &pkt, ssr_type, + sub_client_id, test_addr); if (rc) { d_vpr_e("core_ping: failed to create packet\n"); goto err_create_pkt; diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 30623ff31d5e..8518dc27018e 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -626,7 +626,7 @@ int create_pkt_cmd_session_set_property( static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) { - int rc = HFI_TEST_SSR_HW_WDOG_IRQ; + int rc = HFI_TEST_SSR_SW_ERR_FATAL; switch (type) { case SSR_ERR_FATAL: @@ -638,22 +638,37 @@ static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) case SSR_HW_WDOG_IRQ: rc = HFI_TEST_SSR_HW_WDOG_IRQ; break; + case SSR_NOC_ERROR: + rc = HFI_TEST_SSR_NOC_ERROR; + break; + case SSR_VCODEC_HUNG: + rc = HFI_TEST_SSR_VCODEC_HUNG; + break; default: d_vpr_e("SSR trigger type not recognized, using WDOG.\n"); } return rc; } -int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, - struct hfi_cmd_sys_test_ssr_packet *pkt) +int create_pkt_ssr_cmd(struct hfi_cmd_sys_test_ssr_packet *pkt, + enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, + u32 test_addr) { + struct hfi_ssr_payload payload; if (!pkt) { d_vpr_e("%s: invalid params\n", __func__); return -EINVAL; } - pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); + pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet) - sizeof(u32); pkt->packet_type = HFI_CMD_SYS_TEST_SSR; - pkt->trigger_type = get_hfi_ssr_type(type); + pkt->trigger_type = get_hfi_ssr_type(ssr_type); + if (pkt->trigger_type == HFI_TEST_SSR_NOC_ERROR || + pkt->trigger_type == HFI_TEST_SSR_VCODEC_HUNG) { + pkt->size += sizeof(struct hfi_ssr_payload); + payload.sub_client_id = sub_client_id; + payload.test_addr = test_addr; + memcpy(&pkt->rg_data[0], &payload, sizeof(struct hfi_ssr_payload)); + } return 0; } diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h index f77c4be243db..accce3144aa4 100644 --- a/msm/vidc/hfi_packetization.h +++ b/msm/vidc/hfi_packetization.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef __HFI_PACKETIZATION_H__ #define __HFI_PACKETIZATION_H__ @@ -36,8 +36,9 @@ struct hfi_packetization_ops { int (*sys_image_version)(struct hfi_cmd_sys_get_property_packet *pkt); int (*sys_ubwc_config)(struct hfi_cmd_sys_set_property_packet *pkt, struct msm_vidc_ubwc_config_data *ubwc_config); - int (*ssr_cmd)(enum hal_ssr_trigger_type type, - struct hfi_cmd_sys_test_ssr_packet *pkt); + int (*ssr_cmd)(struct hfi_cmd_sys_test_ssr_packet *pkt, + enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, + u32 test_addr); int (*session_init)( struct hfi_cmd_sys_session_init_packet *pkt, u32 sid, u32 session_domain, u32 session_codec); diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index f85fe2017c4d..4c71d3512441 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -25,6 +25,12 @@ static void msm_vidc_print_running_insts(struct msm_vidc_core *core); #define V4L2_VP9_LEVEL_61 V4L2_MPEG_VIDC_VIDEO_VP9_LEVEL_61 #define TIMESTAMPS_WINDOW_SIZE 32 +#define SSR_TYPE 0x0000000F +#define SSR_TYPE_SHIFT 0 +#define SSR_SUB_CLIENT_ID 0x000000F0 +#define SSR_SUB_CLIENT_ID_SHIFT 4 +#define SSR_ADDR_ID 0xFFFFFFFF00000000 +#define SSR_ADDR_SHIFT 32 int msm_comm_g_ctrl_for_id(struct msm_vidc_inst *inst, int id) { @@ -5644,13 +5650,25 @@ int msm_vidc_noc_error_info(struct msm_vidc_core *core) } int msm_vidc_trigger_ssr(struct msm_vidc_core *core, - enum hal_ssr_trigger_type type) + u64 trigger_ssr_val) { + struct msm_vidc_ssr *ssr; if (!core) { d_vpr_e("%s: Invalid parameters\n", __func__); return -EINVAL; } - core->ssr_type = type; + ssr = &core->ssr; + /* + * ssr_type: 0-3 bits + * sub_client_id: 4-7 bits + * reserved: 8-31 bits + * test_addr: 32-63 bits */ + ssr->ssr_type = (trigger_ssr_val & + (unsigned long)SSR_TYPE) >> SSR_TYPE_SHIFT; + ssr->sub_client_id = (trigger_ssr_val & + (unsigned long)SSR_SUB_CLIENT_ID) >> SSR_SUB_CLIENT_ID_SHIFT; + ssr->test_addr = (trigger_ssr_val & + (unsigned long)SSR_ADDR_ID) >> SSR_ADDR_SHIFT; schedule_work(&core->ssr_work); return 0; } @@ -5660,6 +5678,7 @@ void msm_vidc_ssr_handler(struct work_struct *work) int rc; struct msm_vidc_core *core; struct hfi_device *hdev; + struct msm_vidc_ssr *ssr; core = container_of(work, struct msm_vidc_core, ssr_work); if (!core || !core->device) { @@ -5667,10 +5686,11 @@ void msm_vidc_ssr_handler(struct work_struct *work) return; } hdev = core->device; + ssr = &core->ssr; mutex_lock(&core->lock); if (core->state == VIDC_CORE_INIT_DONE) { - d_vpr_e("%s: ssr type %d\n", __func__, core->ssr_type); + d_vpr_e("%s: ssr type %d\n", __func__, ssr->ssr_type); /* * In current implementation user-initiated SSR triggers * a fatal error from hardware. However, there is no way @@ -5679,7 +5699,8 @@ void msm_vidc_ssr_handler(struct work_struct *work) */ core->trigger_ssr = true; rc = call_hfi_op(hdev, core_trigger_ssr, - hdev->hfi_device_data, core->ssr_type); + hdev->hfi_device_data, ssr->ssr_type, + ssr->sub_client_id, ssr->test_addr); if (rc) { d_vpr_e("%s: trigger_ssr failed\n", __func__); core->trigger_ssr = false; diff --git a/msm/vidc/msm_vidc_debug.c b/msm/vidc/msm_vidc_debug.c index 4b0f6090de40..cd69a2ae161a 100644 --- a/msm/vidc/msm_vidc_debug.c +++ b/msm/vidc/msm_vidc_debug.c @@ -4,7 +4,7 @@ */ #define CREATE_TRACE_POINTS -#define MAX_SSR_STRING_LEN 10 +#define MAX_SSR_STRING_LEN 64 #define MAX_DEBUG_LEVEL_STRING_LEN 15 #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index b54f981e6017..2c1d1c4c7d41 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -467,6 +467,12 @@ struct msm_vidc_core_ops { int (*calc_bw)(struct vidc_bus_vote_data *vidc_data); }; +struct msm_vidc_ssr { + enum hal_ssr_trigger_type ssr_type; + u32 sub_client_id; + u32 test_addr; +}; + struct msm_vidc_core { struct list_head list; struct mutex lock; @@ -485,7 +491,7 @@ struct msm_vidc_core { struct delayed_work fw_unload_work; struct work_struct ssr_work; struct workqueue_struct *vidc_core_workq; - enum hal_ssr_trigger_type ssr_type; + struct msm_vidc_ssr ssr; bool smmu_fault_handled; bool trigger_ssr; unsigned long min_freq; @@ -605,7 +611,7 @@ struct msm_vidc_ctrl { void handle_cmd_response(enum hal_command_response cmd, void *data); int msm_vidc_trigger_ssr(struct msm_vidc_core *core, - enum hal_ssr_trigger_type type); + u64 trigger_ssr_val); int msm_vidc_noc_error_info(struct msm_vidc_core *core); int msm_vidc_check_session_supported(struct msm_vidc_inst *inst); int msm_vidc_check_scaling_supported(struct msm_vidc_inst *inst); diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 29c6c85b699c..9d2ab5d0dfe7 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -282,6 +282,11 @@ struct hfi_hybrid_hierp { u32 layers; }; +struct hfi_ssr_payload { + u32 sub_client_id; + u32 test_addr; +}; + #define HFI_PRIORITY_LOW 10 #define HFI_PRIOIRTY_MEDIUM 20 #define HFI_PRIORITY_HIGH 30 diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index 1193b227ca9f..ee86ad85f7be 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -133,6 +133,8 @@ enum hal_ssr_trigger_type { SSR_ERR_FATAL = 1, SSR_SW_DIV_BY_ZERO, SSR_HW_WDOG_IRQ, + SSR_NOC_ERROR, + SSR_VCODEC_HUNG, }; struct hal_profile_level { @@ -634,7 +636,9 @@ struct hfi_device { /*Add function pointers for all the hfi functions below*/ int (*core_init)(void *device); int (*core_release)(void *device); - int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type); + int (*core_trigger_ssr)(void *device, + enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, + u32 test_addr); int (*session_init)(void *device, void *inst_id, enum hal_domain session_type, enum hal_video_codec codec_type, void **new_session, u32 sid); diff --git a/msm/vidc/vidc_hfi_helper.h b/msm/vidc/vidc_hfi_helper.h index 7800ac795a6e..177069932797 100644 --- a/msm/vidc/vidc_hfi_helper.h +++ b/msm/vidc/vidc_hfi_helper.h @@ -833,6 +833,8 @@ struct hfi_aspect_ratio { #define HFI_TEST_SSR_SW_ERR_FATAL 0x1 #define HFI_TEST_SSR_SW_DIV_BY_ZERO 0x2 #define HFI_TEST_SSR_HW_WDOG_IRQ 0x3 +#define HFI_TEST_SSR_NOC_ERROR 0x4 +#define HFI_TEST_SSR_VCODEC_HUNG 0x5 struct vidc_hal_cmd_pkt_hdr { u32 size; @@ -1057,6 +1059,7 @@ struct hfi_cmd_sys_test_ssr_packet { u32 size; u32 packet_type; u32 trigger_type; + u32 rg_data[1]; }; struct hfi_hdr10_pq_sei { From 63b9cfe02d375ac6b27fd657acd1947a55560fbe Mon Sep 17 00:00:00 2001 From: Govindaraj Rajagopal Date: Fri, 9 Oct 2020 11:31:59 +0530 Subject: [PATCH 4/5] msm: vidc: enable mark_target and mark_data Currently firmware populates tag_data and produces FBD for all ETB's only if mark_target and mark_data is enabled. So sending dummy value as a WA. Change-Id: I93a80d59e4f0f52eac94391ff86afc341468677f Signed-off-by: Govindaraj Rajagopal --- msm/vidc/hfi_packetization.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 8518dc27018e..345638f86902 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -469,6 +469,8 @@ int create_pkt_cmd_session_etb_decoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; + pkt->mark_target = 0xff; + pkt->mark_data = 0xff; pkt->offset = input_frame->offset; pkt->alloc_len = input_frame->alloc_len; pkt->filled_len = input_frame->filled_len; @@ -504,6 +506,8 @@ int create_pkt_cmd_session_etb_encoder( pkt->time_stamp_hi = upper_32_bits(input_frame->timestamp); pkt->time_stamp_lo = lower_32_bits(input_frame->timestamp); pkt->flags = input_frame->flags; + pkt->mark_target = 0xff; + pkt->mark_data = 0xff; pkt->offset = input_frame->offset; pkt->alloc_len = input_frame->alloc_len; pkt->filled_len = input_frame->filled_len; From 48957371a423e5c729423bd20f92574ce58686e5 Mon Sep 17 00:00:00 2001 From: Vikash Garodia Date: Mon, 5 Oct 2020 23:24:09 +0530 Subject: [PATCH 5/5] msm: venc: fix the VUI timing info The timing info should represent the number of time units in one seconds, as per the timescale and time units per tick. Update the same while setting the HFI to video firmware. Change-Id: Ifb6bc34ad295e472715fb72813a236c851d4480f Signed-off-by: Vikash Garodia --- msm/vidc/msm_venc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/vidc/msm_venc.c b/msm/vidc/msm_venc.c index 5277fb34ca6a..9c603016add0 100644 --- a/msm/vidc/msm_venc.c +++ b/msm/vidc/msm_venc.c @@ -4199,7 +4199,7 @@ int msm_venc_set_vui_timing_info(struct msm_vidc_inst *inst) timing_info.enable = 1; timing_info.fixed_frame_rate = cfr; - timing_info.time_scale = NSEC_PER_SEC; + timing_info.time_scale = (inst->clk_data.frame_rate >> 16) * USEC_PER_SEC; s_vpr_h(inst->sid, "%s: %d %d\n", __func__, timing_info.enable, timing_info.fixed_frame_rate);