From 38b660d92f2a0129eeb4e0475a13d48d2818aeed Mon Sep 17 00:00:00 2001 From: Pavan Kumar Chilamkurthi Date: Fri, 30 Oct 2020 02:39:03 -0700 Subject: [PATCH] msm: camera: cpas: Enhance cpas dump with more info 1. Add more triggers to save cpas state info. IFE EOF, ReqBufDone 2. Save camnoc fill levels in each cpas log state 3. Print camnoc QoS settings in cpas state dump for debug purpose. Though these are static settings, printing will help in making sure correct settings are applied. CRs-Fixed: 2814346 Change-Id: Ic3018c5f7fdeaac3a123c6d046eb5e6a34a675e7 Signed-off-by: Pavan Kumar Chilamkurthi --- drivers/cam_cpas/cam_cpas_hw.c | 74 +++++++++++++++++-- drivers/cam_cpas/cam_cpas_hw.h | 8 +- drivers/cam_cpas/camss_top/cam_camsstop_hw.c | 1 + drivers/cam_cpas/cpas_top/cam_cpastop_hw.c | 36 +++++++++ drivers/cam_isp/cam_isp_context.c | 3 + .../vfe_hw/vfe_top/cam_vfe_camif_ver3.c | 2 + 6 files changed, 118 insertions(+), 6 deletions(-) diff --git a/drivers/cam_cpas/cam_cpas_hw.c b/drivers/cam_cpas/cam_cpas_hw.c index c5f3653de497..56bea71d400b 100644 --- a/drivers/cam_cpas/cam_cpas_hw.c +++ b/drivers/cam_cpas/cam_cpas_hw.c @@ -77,6 +77,30 @@ static void cam_cpas_process_bw_overrides( bus_client->common_data.name, *ab, *ib, curr_ab, curr_ib); } +int cam_cpas_util_reg_read(struct cam_hw_info *cpas_hw, + enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info) +{ + struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; + struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info; + uint32_t value; + int reg_base_index; + + if (!reg_info->enable) + return 0; + + reg_base_index = cpas_core->regbase_index[reg_base]; + if (reg_base_index == -1) + return -EINVAL; + + value = cam_io_r_mb( + soc_info->reg_map[reg_base_index].mem_base + reg_info->offset); + + CAM_INFO(CAM_CPAS, "Base[%d] Offset[0x%08x] Value[0x%08x]", + reg_base, reg_info->offset, value); + + return 0; +} + int cam_cpas_util_reg_update(struct cam_hw_info *cpas_hw, enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info) { @@ -1089,10 +1113,6 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw, cam_cpas_dump_axi_vote_info(cpas_core->cpas_client[client_indx], "Translated Vote", axi_vote); - /* Log an entry whenever there is an AXI update - before updating */ - cam_cpas_update_monitor_array(cpas_hw, "CPAS AXI pre-update", - client_indx); - rc = cam_cpas_util_apply_client_axi_vote(cpas_hw, cpas_core->cpas_client[client_indx], axi_vote); @@ -1917,6 +1937,11 @@ static int cam_cpas_log_vote(struct cam_hw_info *cpas_hw) cam_cpas_dump_monitor_array(cpas_core); + if (cpas_core->internal_ops.print_poweron_settings) + cpas_core->internal_ops.print_poweron_settings(cpas_hw); + else + CAM_DBG(CAM_CPAS, "No ops for print_poweron_settings"); + return 0; } @@ -1930,6 +1955,7 @@ static void cam_cpas_update_monitor_array(struct cam_hw_info *cpas_hw, struct cam_cpas_monitor *entry; int iterator; int i; + int reg_camnoc = cpas_core->regbase_index[CAM_CPAS_REG_CAMNOC]; CAM_CPAS_INC_MONITOR_HEAD(&cpas_core->monitor_head, &iterator); @@ -1985,6 +2011,20 @@ static void cam_cpas_update_monitor_array(struct cam_hw_info *cpas_hw, entry->be_ddr = cam_io_r_mb(rpmh_base + be_ddr_offset); entry->be_mnoc = cam_io_r_mb(rpmh_base + be_mnoc_offset); } + + entry->camnoc_fill_level[0] = cam_io_r_mb( + soc_info->reg_map[reg_camnoc].mem_base + 0xA20); + entry->camnoc_fill_level[1] = cam_io_r_mb( + soc_info->reg_map[reg_camnoc].mem_base + 0x1420); + entry->camnoc_fill_level[2] = cam_io_r_mb( + soc_info->reg_map[reg_camnoc].mem_base + 0x1A20); + + if (cpas_hw->soc_info.hw_version == CAM_CPAS_TITAN_580_V100) { + entry->camnoc_fill_level[3] = cam_io_r_mb( + soc_info->reg_map[reg_camnoc].mem_base + 0x7620); + entry->camnoc_fill_level[4] = cam_io_r_mb( + soc_info->reg_map[reg_camnoc].mem_base + 0x7420); + } } static void cam_cpas_dump_monitor_array( @@ -1995,6 +2035,7 @@ static void cam_cpas_dump_monitor_array( uint32_t index, num_entries, oldest_entry; uint64_t ms, tmp, hrs, min, sec; struct cam_cpas_monitor *entry; + struct timespec64 curr_timestamp; if (!cpas_core->full_state_dump) return; @@ -2013,7 +2054,17 @@ static void cam_cpas_dump_monitor_array( CAM_CPAS_MONITOR_MAX_ENTRIES, &oldest_entry); } - CAM_INFO(CAM_CPAS, "======== Dumping monitor information ==========="); + + ktime_get_real_ts64(&curr_timestamp); + tmp = curr_timestamp.tv_sec; + ms = (curr_timestamp.tv_nsec) / 1000000; + sec = do_div(tmp, 60); + min = do_div(tmp, 60); + hrs = do_div(tmp, 24); + + CAM_INFO(CAM_CPAS, + "**** %llu:%llu:%llu.%llu : ======== Dumping monitor information ===========", + hrs, min, sec, ms); index = oldest_entry; @@ -2048,6 +2099,19 @@ static void cam_cpas_dump_monitor_array( entry->be_ddr, entry->be_mnoc); } + CAM_INFO(CAM_CPAS, + "CAMNOC REG[Queued Pending] linear[%d %d] rdi0_wr[%d %d] ubwc_stats0[%d %d] ubwc_stats1[%d %d] rdi1_wr[%d %d]", + (entry->camnoc_fill_level[0] & 0x7FF), + (entry->camnoc_fill_level[0] & 0x7F0000) >> 16, + (entry->camnoc_fill_level[1] & 0x7FF), + (entry->camnoc_fill_level[1] & 0x7F0000) >> 16, + (entry->camnoc_fill_level[2] & 0x7FF), + (entry->camnoc_fill_level[2] & 0x7F0000) >> 16, + (entry->camnoc_fill_level[3] & 0x7FF), + (entry->camnoc_fill_level[3] & 0x7F0000) >> 16, + (entry->camnoc_fill_level[4] & 0x7FF), + (entry->camnoc_fill_level[4] & 0x7F0000) >> 16); + index = (index + 1) % CAM_CPAS_MONITOR_MAX_ENTRIES; } } diff --git a/drivers/cam_cpas/cam_cpas_hw.h b/drivers/cam_cpas/cam_cpas_hw.h index 3301cdbff82d..1c25d0f56203 100644 --- a/drivers/cam_cpas/cam_cpas_hw.h +++ b/drivers/cam_cpas/cam_cpas_hw.h @@ -45,7 +45,7 @@ #define CAM_RPMH_BCM_MNOC_INDEX 4 #define CAM_RPMH_BCM_INFO_MAX 5 -#define CAM_CPAS_MONITOR_MAX_ENTRIES 20 +#define CAM_CPAS_MONITOR_MAX_ENTRIES 60 #define CAM_CPAS_INC_MONITOR_HEAD(head, ret) \ div_u64_rem(atomic64_add_return(1, head),\ CAM_CPAS_MONITOR_MAX_ENTRIES, (ret)) @@ -69,6 +69,7 @@ enum cam_cpas_access_type { * @power_on: Function pointer for hw core specific power on settings * @power_off: Function pointer for hw core specific power off settings * @setup_qos_settings: Function pointer for hw to select a specific qos header + * @print_poweron_settings: Function pointer for hw to print poweron settings * */ struct cam_cpas_internal_ops { @@ -83,6 +84,7 @@ struct cam_cpas_internal_ops { int (*power_off)(struct cam_hw_info *cpas_hw); int (*setup_qos_settings)(struct cam_hw_info *cpas_hw, uint32_t selection_mask); + int (*print_poweron_settings)(struct cam_hw_info *cpas_hw); }; /** @@ -212,6 +214,7 @@ struct cam_cpas_axi_port_debug_info { * This indicates requested clock plan * @be_mnoc: RPMH MNOC BCM BE (back-end) status register value. * This indicates actual current clock plan + * @camnoc_fill_level: Camnoc fill level register info */ struct cam_cpas_monitor { struct timespec64 timestamp; @@ -224,6 +227,7 @@ struct cam_cpas_monitor { uint32_t be_ddr; uint32_t fe_mnoc; uint32_t be_mnoc; + uint32_t camnoc_fill_level[5]; }; /** @@ -284,6 +288,8 @@ int cam_cpastop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops); int cam_cpas_util_reg_update(struct cam_hw_info *cpas_hw, enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info); +int cam_cpas_util_reg_read(struct cam_hw_info *cpas_hw, + enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info); int cam_cpas_util_client_cleanup(struct cam_hw_info *cpas_hw); diff --git a/drivers/cam_cpas/camss_top/cam_camsstop_hw.c b/drivers/cam_cpas/camss_top/cam_camsstop_hw.c index 32415b0baf5d..23f8542cdd87 100644 --- a/drivers/cam_cpas/camss_top/cam_camsstop_hw.c +++ b/drivers/cam_cpas/camss_top/cam_camsstop_hw.c @@ -78,6 +78,7 @@ int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops) internal_ops->power_on = NULL; internal_ops->power_off = NULL; internal_ops->setup_qos_settings = NULL; + internal_ops->print_poweron_settings = NULL; return 0; } diff --git a/drivers/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/cam_cpas/cpas_top/cam_cpastop_hw.c index 0bef0a434343..c5bbcbb79013 100644 --- a/drivers/cam_cpas/cpas_top/cam_cpastop_hw.c +++ b/drivers/cam_cpas/cpas_top/cam_cpastop_hw.c @@ -683,6 +683,40 @@ done: return IRQ_HANDLED; } +static int cam_cpastop_print_poweron_settings(struct cam_hw_info *cpas_hw) +{ + int i; + + for (i = 0; i < camnoc_info->specific_size; i++) { + if (camnoc_info->specific[i].enable) { + CAM_INFO(CAM_CPAS, "Reading QoS settings for %d", + camnoc_info->specific[i].port_type); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].priority_lut_low); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].priority_lut_high); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].urgency); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].danger_lut); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].safe_lut); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].ubwc_ctl); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].flag_out_set0_low); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].qosgen_mainctl); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].qosgen_shaping_low); + cam_cpas_util_reg_read(cpas_hw, CAM_CPAS_REG_CAMNOC, + &camnoc_info->specific[i].qosgen_shaping_high); + } + } + + return 0; +} + static int cam_cpastop_poweron(struct cam_hw_info *cpas_hw) { int i; @@ -899,6 +933,8 @@ int cam_cpastop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops) internal_ops->power_on = cam_cpastop_poweron; internal_ops->power_off = cam_cpastop_poweroff; internal_ops->setup_qos_settings = cam_cpastop_setup_qos_settings; + internal_ops->print_poweron_settings = + cam_cpastop_print_poweron_settings; return 0; } diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 890520c78e19..65a282d2e741 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -20,6 +20,7 @@ #include "cam_isp_context.h" #include "cam_common_util.h" #include "cam_req_mgr_debug.h" +#include "cam_cpas_api.h" static const char isp_dev_name[] = "cam-isp"; @@ -862,6 +863,8 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list( ctx_isp->req_info.last_bufdone_req_id = req->request_id; } + cam_cpas_notify_event("IFE BufDone", buf_done_req_id); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_DONE, buf_done_req_id); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c index 49e76452c165..2c215fbacce8 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c @@ -1468,6 +1468,8 @@ static int cam_vfe_camif_ver3_handle_irq_bottom_half(void *handler_priv, camif_priv->eof_ts.tv_usec = payload->ts.mono_time.tv_usec; + cam_cpas_notify_event("IFE EOF", evt_info.hw_idx); + if (camif_priv->event_cb) camif_priv->event_cb(camif_priv->priv, CAM_ISP_HW_EVENT_EOF, (void *)&evt_info);