Loading drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +166 −7 Original line number Diff line number Diff line Loading @@ -118,7 +118,9 @@ static int cam_tfe_mgr_regspace_data_cb(uint32_t reg_base_type, static int cam_tfe_mgr_handle_reg_dump(struct cam_tfe_hw_mgr_ctx *ctx, struct cam_cmd_buf_desc *reg_dump_buf_desc, uint32_t num_reg_dump_buf, uint32_t meta_type) uint32_t meta_type, void *soc_dump_args, bool user_triggered_dump) { int rc = -EINVAL, i; Loading @@ -142,8 +144,8 @@ static int cam_tfe_mgr_handle_reg_dump(struct cam_tfe_hw_mgr_ctx *ctx, ®_dump_buf_desc[i], ctx->applied_req_id, cam_tfe_mgr_regspace_data_cb, NULL, false); soc_dump_args, user_triggered_dump); if (rc) { CAM_ERR(CAM_ISP, "Reg dump failed at idx: %d, rc: %d req_id: %llu meta type: %u", Loading @@ -153,7 +155,7 @@ static int cam_tfe_mgr_handle_reg_dump(struct cam_tfe_hw_mgr_ctx *ctx, } } return 0; return rc; } static int cam_tfe_mgr_get_hw_caps(void *hw_mgr_priv, Loading Loading @@ -1719,7 +1721,8 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata, cam_tfe_mgr_handle_reg_dump(ctx, hw_update_data->reg_dump_buf_desc, hw_update_data->num_reg_dump_buf, CAM_ISP_TFE_PACKET_META_REG_DUMP_PER_REQUEST); CAM_ISP_TFE_PACKET_META_REG_DUMP_PER_REQUEST, NULL, false); CAM_DBG(CAM_ISP, "Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu ctx_index=%d", handle, userdata, status, cookie, ctx->ctx_index); Loading Loading @@ -2979,6 +2982,159 @@ static int cam_tfe_mgr_write(void *hw_mgr_priv, void *write_args) return -EPERM; } static int cam_tfe_mgr_user_dump_hw( struct cam_tfe_hw_mgr_ctx *tfe_ctx, struct cam_hw_dump_args *dump_args) { int rc = 0; struct cam_hw_soc_dump_args soc_dump_args; if (!tfe_ctx || !dump_args) { CAM_ERR(CAM_ISP, "Invalid parameters %pK %pK", tfe_ctx, dump_args); return -EINVAL; } soc_dump_args.buf_handle = dump_args->buf_handle; soc_dump_args.request_id = dump_args->request_id; soc_dump_args.offset = dump_args->offset; rc = cam_tfe_mgr_handle_reg_dump(tfe_ctx, tfe_ctx->reg_dump_buf_desc, tfe_ctx->num_reg_dump_buf, CAM_ISP_PACKET_META_REG_DUMP_ON_ERROR, &soc_dump_args, true); if (rc) { CAM_DBG(CAM_ISP, "Dump failed req: %lld handle %u offset %u rc %d", dump_args->request_id, dump_args->buf_handle, dump_args->offset, rc); return rc; } dump_args->offset = soc_dump_args.offset; return rc; } static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args) { struct cam_isp_hw_dump_args isp_hw_dump_args; struct cam_hw_dump_args *dump_args = (struct cam_hw_dump_args *)args; struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_tfe_hw_mgr_ctx *tfe_ctx = (struct cam_tfe_hw_mgr_ctx *) dump_args->ctxt_to_hw_map; int i; int rc = 0; /* for some targets, information about the TFE registers to be dumped * is already submitted with the hw manager. In this case, we * can dump just the related registers and skip going to core files. * If dump to this buffer falis due to any reason, fallback to dump * to the LDAR buffer */ isp_hw_dump_args.is_dump_all = true; if (tfe_ctx->num_reg_dump_buf) { rc = cam_tfe_mgr_user_dump_hw(tfe_ctx, dump_args); if (!rc) isp_hw_dump_args.is_dump_all = false; } rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &isp_hw_dump_args.cpu_addr, &isp_hw_dump_args.buf_len); if (rc) { CAM_ERR(CAM_ISP, "Invalid handle %u rc %d", dump_args->buf_handle, rc); return rc; } isp_hw_dump_args.offset = dump_args->offset; isp_hw_dump_args.req_id = dump_args->request_id; list_for_each_entry(hw_mgr_res, &tfe_ctx->res_list_tfe_csid, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; hw_intf = hw_mgr_res->hw_res[i]->hw_intf; switch (hw_mgr_res->hw_res[i]->res_id) { case CAM_TFE_CSID_PATH_RES_RDI_0: case CAM_TFE_CSID_PATH_RES_RDI_1: case CAM_TFE_CSID_PATH_RES_RDI_2: if (tfe_ctx->is_rdi_only_context && hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; case CAM_TFE_CSID_PATH_RES_IPP: if (hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; default: CAM_DBG(CAM_ISP, "not a valid res %d", hw_mgr_res->res_id); break; } } } list_for_each_entry(hw_mgr_res, &tfe_ctx->res_list_tfe_in, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; hw_intf = hw_mgr_res->hw_res[i]->hw_intf; switch (hw_mgr_res->hw_res[i]->res_id) { case CAM_ISP_HW_TFE_IN_RDI0: case CAM_ISP_HW_TFE_IN_RDI1: case CAM_ISP_HW_TFE_IN_RDI2: if (tfe_ctx->is_rdi_only_context && hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; case CAM_ISP_HW_TFE_IN_CAMIF: if (hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; default: CAM_DBG(CAM_ISP, "not a valid res %d", hw_mgr_res->res_id); break; } } } dump_args->offset = isp_hw_dump_args.offset; CAM_DBG(CAM_ISP, "offset %u", dump_args->offset); return rc; } static int cam_tfe_mgr_reset(void *hw_mgr_priv, void *hw_reset_args) { struct cam_tfe_hw_mgr *hw_mgr = hw_mgr_priv; Loading Loading @@ -4226,7 +4382,8 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args) rc = cam_tfe_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc, ctx->num_reg_dump_buf, CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_FLUSH); CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_FLUSH, NULL, false); if (rc) { CAM_ERR(CAM_ISP, "Reg dump on flush failed req id: %llu num_reg_dump:0x%x rc: %d", Loading @@ -4242,7 +4399,8 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args) ctx->last_dump_err_req_id = ctx->applied_req_id; rc = cam_tfe_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc, ctx->num_reg_dump_buf, CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_ERROR); CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_ERROR, NULL, false); if (rc) { CAM_ERR(CAM_ISP, "Reg dump on error failed req id:%llu num_reg_dump:0x%x rc: %d", Loading Loading @@ -5309,6 +5467,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) hw_mgr_intf->hw_config = cam_tfe_mgr_config_hw; hw_mgr_intf->hw_cmd = cam_tfe_mgr_cmd; hw_mgr_intf->hw_reset = cam_tfe_mgr_reset; hw_mgr_intf->hw_dump = cam_tfe_mgr_dump; if (iommu_hdl) *iommu_hdl = g_tfe_hw_mgr.mgr_common.img_iommu_hdl; Loading drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +2 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ struct cam_isp_hw_dual_isp_update_args { * @ buf_len: buf len * @ offset: offset of buffer * @ ctxt_to_hw_map: ctx to hw map * @ is_dump_all: flag to indicate if all information or just bw/clk rate */ struct cam_isp_hw_dump_args { uint64_t req_id; Loading @@ -274,6 +275,7 @@ struct cam_isp_hw_dump_args { size_t buf_len; size_t offset; void *ctxt_to_hw_map; bool is_dump_all; }; /** Loading drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c +103 −0 Original line number Diff line number Diff line Loading @@ -2301,6 +2301,106 @@ static int cam_tfe_csid_get_regdump(struct cam_tfe_csid_hw *csid_hw, return 0; } static int cam_tfe_csid_dump_hw( struct cam_tfe_csid_hw *csid_hw, void *cmd_args) { int i; uint8_t *dst; uint32_t *addr, *start; uint64_t *clk_addr, *clk_start; uint32_t min_len; uint32_t num_reg; uint32_t reg_size = 0; size_t remain_len; struct cam_isp_hw_dump_header *hdr; struct cam_isp_hw_dump_args *dump_args = (struct cam_isp_hw_dump_args *)cmd_args; struct cam_hw_soc_info *soc_info; if (!dump_args) { CAM_ERR(CAM_ISP, "Invalid args"); return -EINVAL; } if (!dump_args->cpu_addr || !dump_args->buf_len) { CAM_ERR(CAM_ISP, "Invalid params %pK %zu", (void *)dump_args->cpu_addr, dump_args->buf_len); return -EINVAL; } if (dump_args->buf_len <= dump_args->offset) { CAM_WARN(CAM_ISP, "Dump offset overshoot offset %zu buf_len %zu", dump_args->offset, dump_args->buf_len); return -ENOSPC; } soc_info = &csid_hw->hw_info->soc_info; if (dump_args->is_dump_all) reg_size = soc_info->reg_map[0].size; min_len = reg_size + sizeof(struct cam_isp_hw_dump_header) + (sizeof(uint32_t) * CAM_TFE_CSID_DUMP_MISC_NUM_WORDS); remain_len = dump_args->buf_len - dump_args->offset; if (remain_len < min_len) { CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu, min %u", remain_len, min_len); return -ENOSPC; } mutex_lock(&csid_hw->hw_info->hw_mutex); if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d", csid_hw->hw_intf->hw_idx, csid_hw->hw_info->hw_state); mutex_unlock(&csid_hw->hw_info->hw_mutex); return -EINVAL; } if (!dump_args->is_dump_all) goto dump_bw; dst = (uint8_t *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "CSID_REG:"); addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; num_reg = soc_info->reg_map[0].size/4; hdr->word_size = sizeof(uint32_t); *addr = soc_info->index; addr++; for (i = 0; i < num_reg; i++) { addr[0] = soc_info->mem_block[0]->start + (i*4); addr[1] = cam_io_r(soc_info->reg_map[0].mem_base + (i*4)); addr += 2; } hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); dump_bw: dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "CSID_CLK_RATE:"); clk_addr = (uint64_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); clk_start = clk_addr; hdr->word_size = sizeof(uint64_t); *clk_addr++ = csid_hw->clk_rate; hdr->size = hdr->word_size * (clk_addr - clk_start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); CAM_DBG(CAM_ISP, "offset %zu", dump_args->offset); mutex_unlock(&csid_hw->hw_info->hw_mutex); return 0; } static int cam_tfe_csid_process_cmd(void *hw_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { Loading Loading @@ -2332,6 +2432,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv, case CAM_TFE_CSID_CMD_GET_REG_DUMP: rc = cam_tfe_csid_get_regdump(csid_hw, cmd_args); break; case CAM_ISP_HW_CMD_DUMP_HW: rc = cam_tfe_csid_dump_hw(csid_hw, cmd_args); break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); Loading drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h +6 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,12 @@ #define CAM_TFE_CSID_CID_MAX 4 /* Each word is taken as uint32_t, for dumping uint64_t count as 2 words * 1. soc_index * 2. clk_rate --> uint64_t -> 2 words */ #define CAM_TFE_CSID_DUMP_MISC_NUM_WORDS 3 #define TFE_CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED BIT(0) #define TFE_CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED BIT(1) #define TFE_CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED BIT(2) Loading drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c +232 −0 Original line number Diff line number Diff line Loading @@ -1490,6 +1490,234 @@ static int cam_tfe_top_get_reg_dump( return 0; } static int cam_tfe_hw_dump( struct cam_tfe_hw_core_info *core_info, void *cmd_args, uint32_t arg_size) { int i, j; uint8_t *dst; uint32_t reg_start_offset; uint32_t reg_dump_size = 0; uint32_t lut_dump_size = 0; uint32_t num_lut_dump_entries = 0; uint32_t num_reg; uint32_t lut_word_size, lut_size; uint32_t lut_bank_sel, lut_dmi_reg; uint32_t val; void __iomem *reg_base; void __iomem *mem_base; uint32_t *addr, *start; uint64_t *clk_waddr, *clk_wstart; size_t remain_len; uint32_t min_len; struct cam_hw_info *tfe_hw_info; struct cam_hw_soc_info *soc_info; struct cam_tfe_top_priv *top_priv; struct cam_tfe_soc_private *soc_private; struct cam_tfe_reg_dump_data *reg_dump_data; struct cam_isp_hw_dump_header *hdr; struct cam_isp_hw_dump_args *dump_args = (struct cam_isp_hw_dump_args *)cmd_args; if (!dump_args || !core_info) { CAM_ERR(CAM_ISP, "Invalid args"); return -EINVAL; } if (!dump_args->cpu_addr || !dump_args->buf_len) { CAM_ERR(CAM_ISP, "Invalid params %pK %zu", (void *)dump_args->cpu_addr, dump_args->buf_len); return -EINVAL; } if (dump_args->buf_len <= dump_args->offset) { CAM_WARN(CAM_ISP, "Dump offset overshoot offset %zu buf_len %zu", dump_args->offset, dump_args->buf_len); return -ENOSPC; } top_priv = (struct cam_tfe_top_priv *)core_info->top_priv; tfe_hw_info = (struct cam_hw_info *)(top_priv->common_data.hw_intf->hw_priv); reg_dump_data = top_priv->common_data.reg_dump_data; soc_info = top_priv->common_data.soc_info; soc_private = top_priv->common_data.soc_info->soc_private; mem_base = soc_info->reg_map[TFE_CORE_BASE_IDX].mem_base; if (dump_args->is_dump_all) { /*Dump registers size*/ for (i = 0; i < reg_dump_data->num_reg_dump_entries; i++) reg_dump_size += (reg_dump_data->reg_entry[i].end_offset - reg_dump_data->reg_entry[i].start_offset); /* * We dump the offset as well, so the total size dumped becomes * multiplied by 2 */ reg_dump_size *= 2; /* LUT dump size */ for (i = 0; i < reg_dump_data->num_lut_dump_entries; i++) lut_dump_size += ((reg_dump_data->lut_entry[i].lut_addr_size) * (reg_dump_data->lut_entry[i].lut_word_size/8)); num_lut_dump_entries = reg_dump_data->num_lut_dump_entries; } /*Minimum len comprises of: * lut_dump_size + reg_dump_size + sizeof dump_header + * (num_lut_dump_entries--> represents number of banks) + * (misc number of words) * sizeof(uint32_t) */ min_len = lut_dump_size + reg_dump_size + sizeof(struct cam_isp_hw_dump_header) + (num_lut_dump_entries * sizeof(uint32_t)) + (sizeof(uint32_t) * CAM_TFE_CORE_DUMP_MISC_NUM_WORDS); remain_len = dump_args->buf_len - dump_args->offset; if (remain_len < min_len) { CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu, min %u", remain_len, min_len); return -ENOSPC; } mutex_lock(&tfe_hw_info->hw_mutex); if (tfe_hw_info->hw_state != CAM_HW_STATE_POWER_UP) { CAM_ERR(CAM_ISP, "TFE:%d HW not powered up", core_info->core_index); mutex_unlock(&tfe_hw_info->hw_mutex); return -EPERM; } if (!dump_args->is_dump_all) goto dump_bw; dst = (uint8_t *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; hdr->word_size = sizeof(uint32_t); scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "TFE_REG:"); addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; *addr++ = soc_info->index; for (i = 0; i < reg_dump_data->num_reg_dump_entries; i++) { num_reg = (reg_dump_data->reg_entry[i].end_offset - reg_dump_data->reg_entry[i].start_offset)/4; reg_start_offset = reg_dump_data->reg_entry[i].start_offset; reg_base = mem_base + reg_start_offset; for (j = 0; j < num_reg; j++) { addr[0] = soc_info->mem_block[TFE_CORE_BASE_IDX]->start + reg_start_offset + (j*4); addr[1] = cam_io_r(reg_base + (j*4)); addr += 2; } } /*Dump bus top registers*/ num_reg = (reg_dump_data->bus_write_top_end_addr - reg_dump_data->bus_start_addr)/4; reg_base = mem_base + reg_dump_data->bus_start_addr; reg_start_offset = soc_info->mem_block[TFE_CORE_BASE_IDX]->start + reg_dump_data->bus_start_addr; for (i = 0; i < num_reg; i++) { addr[0] = reg_start_offset + (i*4); addr[1] = cam_io_r(reg_base + (i*4)); addr += 2; } /* Dump bus clients */ reg_base = mem_base + reg_dump_data->bus_client_start_addr; reg_start_offset = soc_info->mem_block[TFE_CORE_BASE_IDX]->start + reg_dump_data->bus_client_start_addr; for (j = 0; j < reg_dump_data->num_bus_clients; j++) { for (i = 0; i <= 0x3c; i += 4) { addr[0] = reg_start_offset + i; addr[1] = cam_io_r(reg_base + i); addr += 2; } for (i = 0x60; i <= 0x80; i += 4) { addr[0] = reg_start_offset + (i*4); addr[1] = cam_io_r(reg_base + (i*4)); addr += 2; } reg_base += reg_dump_data->bus_client_offset; reg_start_offset += reg_dump_data->bus_client_offset; } hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); /* Dump LUT entries */ for (i = 0; i < reg_dump_data->num_lut_dump_entries; i++) { lut_bank_sel = reg_dump_data->lut_entry[i].lut_bank_sel; lut_size = reg_dump_data->lut_entry[i].lut_addr_size; lut_word_size = reg_dump_data->lut_entry[i].lut_word_size; lut_dmi_reg = reg_dump_data->lut_entry[i].dmi_reg_offset; dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "LUT_REG:"); hdr->word_size = lut_word_size/8; addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; *addr++ = lut_bank_sel; cam_io_w_mb(lut_bank_sel, mem_base + lut_dmi_reg + 4); cam_io_w_mb(0, mem_base + 0xC28); for (j = 0; j < lut_size; j++) { *addr = cam_io_r_mb(mem_base + 0xc30); addr++; } hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); } cam_io_w_mb(0, mem_base + 0xC24); cam_io_w_mb(0, mem_base + 0xC28); dump_bw: dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "TFE_CLK_RATE_BW:"); clk_waddr = (uint64_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); clk_wstart = clk_waddr; hdr->word_size = sizeof(uint64_t); *clk_waddr++ = top_priv->hw_clk_rate; *clk_waddr++ = top_priv->total_bw_applied; hdr->size = hdr->word_size * (clk_waddr - clk_wstart); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "TFE_NIU_MAXWR:"); addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; hdr->word_size = sizeof(uint32_t); cam_cpas_reg_read(soc_private->cpas_handle, CAM_CPAS_REG_CAMNOC, 0x20, true, &val); *addr++ = val; hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); mutex_unlock(&tfe_hw_info->hw_mutex); CAM_DBG(CAM_ISP, "offset %zu", dump_args->offset); return 0; } static int cam_tfe_camif_irq_reg_dump( struct cam_tfe_hw_core_info *core_info, void *cmd_args, uint32_t arg_size) Loading Loading @@ -2570,6 +2798,10 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA: *((struct cam_hw_soc_info **)cmd_args) = soc_info; break; case CAM_ISP_HW_CMD_DUMP_HW: rc = cam_tfe_hw_dump(core_info, cmd_args, arg_size); break; case CAM_ISP_HW_CMD_GET_BUF_UPDATE: case CAM_ISP_HW_CMD_GET_HFR_UPDATE: case CAM_ISP_HW_CMD_STRIPE_UPDATE: Loading Loading
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +166 −7 Original line number Diff line number Diff line Loading @@ -118,7 +118,9 @@ static int cam_tfe_mgr_regspace_data_cb(uint32_t reg_base_type, static int cam_tfe_mgr_handle_reg_dump(struct cam_tfe_hw_mgr_ctx *ctx, struct cam_cmd_buf_desc *reg_dump_buf_desc, uint32_t num_reg_dump_buf, uint32_t meta_type) uint32_t meta_type, void *soc_dump_args, bool user_triggered_dump) { int rc = -EINVAL, i; Loading @@ -142,8 +144,8 @@ static int cam_tfe_mgr_handle_reg_dump(struct cam_tfe_hw_mgr_ctx *ctx, ®_dump_buf_desc[i], ctx->applied_req_id, cam_tfe_mgr_regspace_data_cb, NULL, false); soc_dump_args, user_triggered_dump); if (rc) { CAM_ERR(CAM_ISP, "Reg dump failed at idx: %d, rc: %d req_id: %llu meta type: %u", Loading @@ -153,7 +155,7 @@ static int cam_tfe_mgr_handle_reg_dump(struct cam_tfe_hw_mgr_ctx *ctx, } } return 0; return rc; } static int cam_tfe_mgr_get_hw_caps(void *hw_mgr_priv, Loading Loading @@ -1719,7 +1721,8 @@ void cam_tfe_cam_cdm_callback(uint32_t handle, void *userdata, cam_tfe_mgr_handle_reg_dump(ctx, hw_update_data->reg_dump_buf_desc, hw_update_data->num_reg_dump_buf, CAM_ISP_TFE_PACKET_META_REG_DUMP_PER_REQUEST); CAM_ISP_TFE_PACKET_META_REG_DUMP_PER_REQUEST, NULL, false); CAM_DBG(CAM_ISP, "Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu ctx_index=%d", handle, userdata, status, cookie, ctx->ctx_index); Loading Loading @@ -2979,6 +2982,159 @@ static int cam_tfe_mgr_write(void *hw_mgr_priv, void *write_args) return -EPERM; } static int cam_tfe_mgr_user_dump_hw( struct cam_tfe_hw_mgr_ctx *tfe_ctx, struct cam_hw_dump_args *dump_args) { int rc = 0; struct cam_hw_soc_dump_args soc_dump_args; if (!tfe_ctx || !dump_args) { CAM_ERR(CAM_ISP, "Invalid parameters %pK %pK", tfe_ctx, dump_args); return -EINVAL; } soc_dump_args.buf_handle = dump_args->buf_handle; soc_dump_args.request_id = dump_args->request_id; soc_dump_args.offset = dump_args->offset; rc = cam_tfe_mgr_handle_reg_dump(tfe_ctx, tfe_ctx->reg_dump_buf_desc, tfe_ctx->num_reg_dump_buf, CAM_ISP_PACKET_META_REG_DUMP_ON_ERROR, &soc_dump_args, true); if (rc) { CAM_DBG(CAM_ISP, "Dump failed req: %lld handle %u offset %u rc %d", dump_args->request_id, dump_args->buf_handle, dump_args->offset, rc); return rc; } dump_args->offset = soc_dump_args.offset; return rc; } static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args) { struct cam_isp_hw_dump_args isp_hw_dump_args; struct cam_hw_dump_args *dump_args = (struct cam_hw_dump_args *)args; struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_tfe_hw_mgr_ctx *tfe_ctx = (struct cam_tfe_hw_mgr_ctx *) dump_args->ctxt_to_hw_map; int i; int rc = 0; /* for some targets, information about the TFE registers to be dumped * is already submitted with the hw manager. In this case, we * can dump just the related registers and skip going to core files. * If dump to this buffer falis due to any reason, fallback to dump * to the LDAR buffer */ isp_hw_dump_args.is_dump_all = true; if (tfe_ctx->num_reg_dump_buf) { rc = cam_tfe_mgr_user_dump_hw(tfe_ctx, dump_args); if (!rc) isp_hw_dump_args.is_dump_all = false; } rc = cam_mem_get_cpu_buf(dump_args->buf_handle, &isp_hw_dump_args.cpu_addr, &isp_hw_dump_args.buf_len); if (rc) { CAM_ERR(CAM_ISP, "Invalid handle %u rc %d", dump_args->buf_handle, rc); return rc; } isp_hw_dump_args.offset = dump_args->offset; isp_hw_dump_args.req_id = dump_args->request_id; list_for_each_entry(hw_mgr_res, &tfe_ctx->res_list_tfe_csid, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; hw_intf = hw_mgr_res->hw_res[i]->hw_intf; switch (hw_mgr_res->hw_res[i]->res_id) { case CAM_TFE_CSID_PATH_RES_RDI_0: case CAM_TFE_CSID_PATH_RES_RDI_1: case CAM_TFE_CSID_PATH_RES_RDI_2: if (tfe_ctx->is_rdi_only_context && hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; case CAM_TFE_CSID_PATH_RES_IPP: if (hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; default: CAM_DBG(CAM_ISP, "not a valid res %d", hw_mgr_res->res_id); break; } } } list_for_each_entry(hw_mgr_res, &tfe_ctx->res_list_tfe_in, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i]) continue; hw_intf = hw_mgr_res->hw_res[i]->hw_intf; switch (hw_mgr_res->hw_res[i]->res_id) { case CAM_ISP_HW_TFE_IN_RDI0: case CAM_ISP_HW_TFE_IN_RDI1: case CAM_ISP_HW_TFE_IN_RDI2: if (tfe_ctx->is_rdi_only_context && hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; case CAM_ISP_HW_TFE_IN_CAMIF: if (hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_ISP_HW_CMD_DUMP_HW, &isp_hw_dump_args, sizeof(struct cam_isp_hw_dump_args)); } break; default: CAM_DBG(CAM_ISP, "not a valid res %d", hw_mgr_res->res_id); break; } } } dump_args->offset = isp_hw_dump_args.offset; CAM_DBG(CAM_ISP, "offset %u", dump_args->offset); return rc; } static int cam_tfe_mgr_reset(void *hw_mgr_priv, void *hw_reset_args) { struct cam_tfe_hw_mgr *hw_mgr = hw_mgr_priv; Loading Loading @@ -4226,7 +4382,8 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args) rc = cam_tfe_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc, ctx->num_reg_dump_buf, CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_FLUSH); CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_FLUSH, NULL, false); if (rc) { CAM_ERR(CAM_ISP, "Reg dump on flush failed req id: %llu num_reg_dump:0x%x rc: %d", Loading @@ -4242,7 +4399,8 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args) ctx->last_dump_err_req_id = ctx->applied_req_id; rc = cam_tfe_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc, ctx->num_reg_dump_buf, CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_ERROR); CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_ERROR, NULL, false); if (rc) { CAM_ERR(CAM_ISP, "Reg dump on error failed req id:%llu num_reg_dump:0x%x rc: %d", Loading Loading @@ -5309,6 +5467,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) hw_mgr_intf->hw_config = cam_tfe_mgr_config_hw; hw_mgr_intf->hw_cmd = cam_tfe_mgr_cmd; hw_mgr_intf->hw_reset = cam_tfe_mgr_reset; hw_mgr_intf->hw_dump = cam_tfe_mgr_dump; if (iommu_hdl) *iommu_hdl = g_tfe_hw_mgr.mgr_common.img_iommu_hdl; Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +2 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,7 @@ struct cam_isp_hw_dual_isp_update_args { * @ buf_len: buf len * @ offset: offset of buffer * @ ctxt_to_hw_map: ctx to hw map * @ is_dump_all: flag to indicate if all information or just bw/clk rate */ struct cam_isp_hw_dump_args { uint64_t req_id; Loading @@ -274,6 +275,7 @@ struct cam_isp_hw_dump_args { size_t buf_len; size_t offset; void *ctxt_to_hw_map; bool is_dump_all; }; /** Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c +103 −0 Original line number Diff line number Diff line Loading @@ -2301,6 +2301,106 @@ static int cam_tfe_csid_get_regdump(struct cam_tfe_csid_hw *csid_hw, return 0; } static int cam_tfe_csid_dump_hw( struct cam_tfe_csid_hw *csid_hw, void *cmd_args) { int i; uint8_t *dst; uint32_t *addr, *start; uint64_t *clk_addr, *clk_start; uint32_t min_len; uint32_t num_reg; uint32_t reg_size = 0; size_t remain_len; struct cam_isp_hw_dump_header *hdr; struct cam_isp_hw_dump_args *dump_args = (struct cam_isp_hw_dump_args *)cmd_args; struct cam_hw_soc_info *soc_info; if (!dump_args) { CAM_ERR(CAM_ISP, "Invalid args"); return -EINVAL; } if (!dump_args->cpu_addr || !dump_args->buf_len) { CAM_ERR(CAM_ISP, "Invalid params %pK %zu", (void *)dump_args->cpu_addr, dump_args->buf_len); return -EINVAL; } if (dump_args->buf_len <= dump_args->offset) { CAM_WARN(CAM_ISP, "Dump offset overshoot offset %zu buf_len %zu", dump_args->offset, dump_args->buf_len); return -ENOSPC; } soc_info = &csid_hw->hw_info->soc_info; if (dump_args->is_dump_all) reg_size = soc_info->reg_map[0].size; min_len = reg_size + sizeof(struct cam_isp_hw_dump_header) + (sizeof(uint32_t) * CAM_TFE_CSID_DUMP_MISC_NUM_WORDS); remain_len = dump_args->buf_len - dump_args->offset; if (remain_len < min_len) { CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu, min %u", remain_len, min_len); return -ENOSPC; } mutex_lock(&csid_hw->hw_info->hw_mutex); if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) { CAM_ERR(CAM_ISP, "CSID:%d Invalid HW State:%d", csid_hw->hw_intf->hw_idx, csid_hw->hw_info->hw_state); mutex_unlock(&csid_hw->hw_info->hw_mutex); return -EINVAL; } if (!dump_args->is_dump_all) goto dump_bw; dst = (uint8_t *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "CSID_REG:"); addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; num_reg = soc_info->reg_map[0].size/4; hdr->word_size = sizeof(uint32_t); *addr = soc_info->index; addr++; for (i = 0; i < num_reg; i++) { addr[0] = soc_info->mem_block[0]->start + (i*4); addr[1] = cam_io_r(soc_info->reg_map[0].mem_base + (i*4)); addr += 2; } hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); dump_bw: dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "CSID_CLK_RATE:"); clk_addr = (uint64_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); clk_start = clk_addr; hdr->word_size = sizeof(uint64_t); *clk_addr++ = csid_hw->clk_rate; hdr->size = hdr->word_size * (clk_addr - clk_start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); CAM_DBG(CAM_ISP, "offset %zu", dump_args->offset); mutex_unlock(&csid_hw->hw_info->hw_mutex); return 0; } static int cam_tfe_csid_process_cmd(void *hw_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { Loading Loading @@ -2332,6 +2432,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv, case CAM_TFE_CSID_CMD_GET_REG_DUMP: rc = cam_tfe_csid_get_regdump(csid_hw, cmd_args); break; case CAM_ISP_HW_CMD_DUMP_HW: rc = cam_tfe_csid_dump_hw(csid_hw, cmd_args); break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h +6 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,12 @@ #define CAM_TFE_CSID_CID_MAX 4 /* Each word is taken as uint32_t, for dumping uint64_t count as 2 words * 1. soc_index * 2. clk_rate --> uint64_t -> 2 words */ #define CAM_TFE_CSID_DUMP_MISC_NUM_WORDS 3 #define TFE_CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED BIT(0) #define TFE_CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED BIT(1) #define TFE_CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED BIT(2) Loading
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c +232 −0 Original line number Diff line number Diff line Loading @@ -1490,6 +1490,234 @@ static int cam_tfe_top_get_reg_dump( return 0; } static int cam_tfe_hw_dump( struct cam_tfe_hw_core_info *core_info, void *cmd_args, uint32_t arg_size) { int i, j; uint8_t *dst; uint32_t reg_start_offset; uint32_t reg_dump_size = 0; uint32_t lut_dump_size = 0; uint32_t num_lut_dump_entries = 0; uint32_t num_reg; uint32_t lut_word_size, lut_size; uint32_t lut_bank_sel, lut_dmi_reg; uint32_t val; void __iomem *reg_base; void __iomem *mem_base; uint32_t *addr, *start; uint64_t *clk_waddr, *clk_wstart; size_t remain_len; uint32_t min_len; struct cam_hw_info *tfe_hw_info; struct cam_hw_soc_info *soc_info; struct cam_tfe_top_priv *top_priv; struct cam_tfe_soc_private *soc_private; struct cam_tfe_reg_dump_data *reg_dump_data; struct cam_isp_hw_dump_header *hdr; struct cam_isp_hw_dump_args *dump_args = (struct cam_isp_hw_dump_args *)cmd_args; if (!dump_args || !core_info) { CAM_ERR(CAM_ISP, "Invalid args"); return -EINVAL; } if (!dump_args->cpu_addr || !dump_args->buf_len) { CAM_ERR(CAM_ISP, "Invalid params %pK %zu", (void *)dump_args->cpu_addr, dump_args->buf_len); return -EINVAL; } if (dump_args->buf_len <= dump_args->offset) { CAM_WARN(CAM_ISP, "Dump offset overshoot offset %zu buf_len %zu", dump_args->offset, dump_args->buf_len); return -ENOSPC; } top_priv = (struct cam_tfe_top_priv *)core_info->top_priv; tfe_hw_info = (struct cam_hw_info *)(top_priv->common_data.hw_intf->hw_priv); reg_dump_data = top_priv->common_data.reg_dump_data; soc_info = top_priv->common_data.soc_info; soc_private = top_priv->common_data.soc_info->soc_private; mem_base = soc_info->reg_map[TFE_CORE_BASE_IDX].mem_base; if (dump_args->is_dump_all) { /*Dump registers size*/ for (i = 0; i < reg_dump_data->num_reg_dump_entries; i++) reg_dump_size += (reg_dump_data->reg_entry[i].end_offset - reg_dump_data->reg_entry[i].start_offset); /* * We dump the offset as well, so the total size dumped becomes * multiplied by 2 */ reg_dump_size *= 2; /* LUT dump size */ for (i = 0; i < reg_dump_data->num_lut_dump_entries; i++) lut_dump_size += ((reg_dump_data->lut_entry[i].lut_addr_size) * (reg_dump_data->lut_entry[i].lut_word_size/8)); num_lut_dump_entries = reg_dump_data->num_lut_dump_entries; } /*Minimum len comprises of: * lut_dump_size + reg_dump_size + sizeof dump_header + * (num_lut_dump_entries--> represents number of banks) + * (misc number of words) * sizeof(uint32_t) */ min_len = lut_dump_size + reg_dump_size + sizeof(struct cam_isp_hw_dump_header) + (num_lut_dump_entries * sizeof(uint32_t)) + (sizeof(uint32_t) * CAM_TFE_CORE_DUMP_MISC_NUM_WORDS); remain_len = dump_args->buf_len - dump_args->offset; if (remain_len < min_len) { CAM_WARN(CAM_ISP, "Dump buffer exhaust remain %zu, min %u", remain_len, min_len); return -ENOSPC; } mutex_lock(&tfe_hw_info->hw_mutex); if (tfe_hw_info->hw_state != CAM_HW_STATE_POWER_UP) { CAM_ERR(CAM_ISP, "TFE:%d HW not powered up", core_info->core_index); mutex_unlock(&tfe_hw_info->hw_mutex); return -EPERM; } if (!dump_args->is_dump_all) goto dump_bw; dst = (uint8_t *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; hdr->word_size = sizeof(uint32_t); scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "TFE_REG:"); addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; *addr++ = soc_info->index; for (i = 0; i < reg_dump_data->num_reg_dump_entries; i++) { num_reg = (reg_dump_data->reg_entry[i].end_offset - reg_dump_data->reg_entry[i].start_offset)/4; reg_start_offset = reg_dump_data->reg_entry[i].start_offset; reg_base = mem_base + reg_start_offset; for (j = 0; j < num_reg; j++) { addr[0] = soc_info->mem_block[TFE_CORE_BASE_IDX]->start + reg_start_offset + (j*4); addr[1] = cam_io_r(reg_base + (j*4)); addr += 2; } } /*Dump bus top registers*/ num_reg = (reg_dump_data->bus_write_top_end_addr - reg_dump_data->bus_start_addr)/4; reg_base = mem_base + reg_dump_data->bus_start_addr; reg_start_offset = soc_info->mem_block[TFE_CORE_BASE_IDX]->start + reg_dump_data->bus_start_addr; for (i = 0; i < num_reg; i++) { addr[0] = reg_start_offset + (i*4); addr[1] = cam_io_r(reg_base + (i*4)); addr += 2; } /* Dump bus clients */ reg_base = mem_base + reg_dump_data->bus_client_start_addr; reg_start_offset = soc_info->mem_block[TFE_CORE_BASE_IDX]->start + reg_dump_data->bus_client_start_addr; for (j = 0; j < reg_dump_data->num_bus_clients; j++) { for (i = 0; i <= 0x3c; i += 4) { addr[0] = reg_start_offset + i; addr[1] = cam_io_r(reg_base + i); addr += 2; } for (i = 0x60; i <= 0x80; i += 4) { addr[0] = reg_start_offset + (i*4); addr[1] = cam_io_r(reg_base + (i*4)); addr += 2; } reg_base += reg_dump_data->bus_client_offset; reg_start_offset += reg_dump_data->bus_client_offset; } hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); /* Dump LUT entries */ for (i = 0; i < reg_dump_data->num_lut_dump_entries; i++) { lut_bank_sel = reg_dump_data->lut_entry[i].lut_bank_sel; lut_size = reg_dump_data->lut_entry[i].lut_addr_size; lut_word_size = reg_dump_data->lut_entry[i].lut_word_size; lut_dmi_reg = reg_dump_data->lut_entry[i].dmi_reg_offset; dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "LUT_REG:"); hdr->word_size = lut_word_size/8; addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; *addr++ = lut_bank_sel; cam_io_w_mb(lut_bank_sel, mem_base + lut_dmi_reg + 4); cam_io_w_mb(0, mem_base + 0xC28); for (j = 0; j < lut_size; j++) { *addr = cam_io_r_mb(mem_base + 0xc30); addr++; } hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); } cam_io_w_mb(0, mem_base + 0xC24); cam_io_w_mb(0, mem_base + 0xC28); dump_bw: dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "TFE_CLK_RATE_BW:"); clk_waddr = (uint64_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); clk_wstart = clk_waddr; hdr->word_size = sizeof(uint64_t); *clk_waddr++ = top_priv->hw_clk_rate; *clk_waddr++ = top_priv->total_bw_applied; hdr->size = hdr->word_size * (clk_waddr - clk_wstart); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); dst = (char *)dump_args->cpu_addr + dump_args->offset; hdr = (struct cam_isp_hw_dump_header *)dst; scnprintf(hdr->tag, CAM_ISP_HW_DUMP_TAG_MAX_LEN, "TFE_NIU_MAXWR:"); addr = (uint32_t *)(dst + sizeof(struct cam_isp_hw_dump_header)); start = addr; hdr->word_size = sizeof(uint32_t); cam_cpas_reg_read(soc_private->cpas_handle, CAM_CPAS_REG_CAMNOC, 0x20, true, &val); *addr++ = val; hdr->size = hdr->word_size * (addr - start); dump_args->offset += hdr->size + sizeof(struct cam_isp_hw_dump_header); mutex_unlock(&tfe_hw_info->hw_mutex); CAM_DBG(CAM_ISP, "offset %zu", dump_args->offset); return 0; } static int cam_tfe_camif_irq_reg_dump( struct cam_tfe_hw_core_info *core_info, void *cmd_args, uint32_t arg_size) Loading Loading @@ -2570,6 +2798,10 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA: *((struct cam_hw_soc_info **)cmd_args) = soc_info; break; case CAM_ISP_HW_CMD_DUMP_HW: rc = cam_tfe_hw_dump(core_info, cmd_args, arg_size); break; case CAM_ISP_HW_CMD_GET_BUF_UPDATE: case CAM_ISP_HW_CMD_GET_HFR_UPDATE: case CAM_ISP_HW_CMD_STRIPE_UPDATE: Loading