diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 6450b5d37e..e8b016ae98 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -6689,7 +6689,6 @@ static void cam_ife_mgr_dump_pf_data( struct cam_hw_cmd_args *hw_cmd_args) { struct cam_ife_hw_mgr_ctx *ctx; - struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_get_cmd_update cmd_update; struct cam_isp_hw_get_res_for_mid get_res; diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c index 4f2c990e0f..e3618e858d 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c @@ -1105,7 +1105,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_in( continue; hw_intf = tfe_hw_mgr->tfe_devices[ - csid_res->hw_res[i]->hw_intf->hw_idx]; + csid_res->hw_res[i]->hw_intf->hw_idx]->hw_intf; /* fill in more acquire information as needed */ /* slave Camif resource, */ @@ -2782,10 +2782,10 @@ static int cam_tfe_mgr_reset_tfe_hw(struct cam_tfe_hw_mgr *hw_mgr, if (!hw_mgr->tfe_devices[i]) continue; - if (hw_idx != hw_mgr->tfe_devices[i]->hw_idx) + if (hw_idx != hw_mgr->tfe_devices[i]->hw_intf->hw_idx) continue; CAM_DBG(CAM_ISP, "TFE (id = %d) reset", hw_idx); - tfe_hw_intf = hw_mgr->tfe_devices[i]; + tfe_hw_intf = hw_mgr->tfe_devices[i]->hw_intf; tfe_hw_intf->hw_ops.reset(tfe_hw_intf->hw_priv, &tfe_reset_type, sizeof(tfe_reset_type)); break; @@ -3089,7 +3089,7 @@ static int cam_tfe_mgr_user_dump_hw( 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, + CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_ERROR, &soc_dump_args, true); if (rc) { @@ -4294,77 +4294,250 @@ static int cam_tfe_mgr_sof_irq_debug( return rc; } -static void cam_tfe_mgr_print_io_bufs(struct cam_packet *packet, - int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info, - bool *mem_found) +static void cam_tfe_mgr_print_io_bufs(struct cam_tfe_hw_mgr *hw_mgr, + uint32_t res_id, struct cam_packet *packet, + bool *ctx_found, struct cam_tfe_hw_mgr_ctx *ctx) { - dma_addr_t iova_addr; - size_t src_buf_size; - int i, j; - int rc = 0; - int32_t mmu_hdl; struct cam_buf_io_cfg *io_cfg = NULL; + int32_t mmu_hdl, iommu_hdl, sec_mmu_hdl; + dma_addr_t iova_addr; + size_t src_buf_size; + int i, j, rc = 0; - if (mem_found) - *mem_found = false; + iommu_hdl = hw_mgr->mgr_common.img_iommu_hdl; + sec_mmu_hdl = hw_mgr->mgr_common.img_iommu_hdl_secure; io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload + packet->io_configs_offset / 4); for (i = 0; i < packet->num_io_configs; i++) { - for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) - break; + if (io_cfg[i].resource_type != res_id) + continue; + else + break; + } - if (pf_buf_info && - GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == - GET_FD_FROM_HANDLE(pf_buf_info)) { - CAM_INFO(CAM_ISP, - "Found PF at port: 0x%x mem 0x%x fd: 0x%x", - io_cfg[i].resource_type, - io_cfg[i].mem_handle[j], - pf_buf_info); - if (mem_found) - *mem_found = true; - } + if (i == packet->num_io_configs) { + CAM_ERR(CAM_ISP, + "getting io port for mid resource id failed ctx id:%d req id:%lld res id:0x%x", + ctx->ctx_index, packet->header.request_id, + res_id); + return; + } - CAM_INFO(CAM_ISP, "port: 0x%x f: %u format: %d dir %d", - io_cfg[i].resource_type, - io_cfg[i].fence, - io_cfg[i].format, - io_cfg[i].direction); + for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { + if (!io_cfg[i].mem_handle[j]) + break; - mmu_hdl = cam_mem_is_secure_buf( - io_cfg[i].mem_handle[j]) ? sec_mmu_hdl : - iommu_hdl; - rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j], - mmu_hdl, &iova_addr, &src_buf_size); - if (rc < 0) { - CAM_ERR(CAM_ISP, - "get src buf address fail mem_handle 0x%x", - io_cfg[i].mem_handle[j]); - continue; - } - if ((iova_addr & 0xFFFFFFFF) != iova_addr) { - CAM_ERR(CAM_ISP, "Invalid mapped address"); - rc = -EINVAL; - continue; - } + CAM_INFO(CAM_ISP, "port: 0x%x f: %u format: %d dir %d", + io_cfg[i].resource_type, + io_cfg[i].fence, + io_cfg[i].format, + io_cfg[i].direction); - CAM_INFO(CAM_ISP, - "pln %d w %d h %d s %u size 0x%x addr 0x%x end_addr 0x%x offset %x memh %x", - j, io_cfg[i].planes[j].width, - io_cfg[i].planes[j].height, - io_cfg[i].planes[j].plane_stride, - (unsigned int)src_buf_size, - (unsigned int)iova_addr, - (unsigned int)iova_addr + - (unsigned int)src_buf_size, - io_cfg[i].offsets[j], + mmu_hdl = cam_mem_is_secure_buf( + io_cfg[i].mem_handle[j]) ? sec_mmu_hdl : + iommu_hdl; + rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j], + mmu_hdl, &iova_addr, &src_buf_size); + if (rc < 0) { + CAM_ERR(CAM_ISP, + "get src buf address fail mem_handle 0x%x", io_cfg[i].mem_handle[j]); + continue; + } + if ((iova_addr & 0xFFFFFFFF) != iova_addr) { + CAM_ERR(CAM_ISP, "Invalid mapped address"); + rc = -EINVAL; + continue; + } + + CAM_INFO(CAM_ISP, + "pln %d w %d h %d s %u size 0x%x addr 0x%x end_addr 0x%x offset %x memh %x", + j, io_cfg[i].planes[j].width, + io_cfg[i].planes[j].height, + io_cfg[i].planes[j].plane_stride, + (unsigned int)src_buf_size, + (unsigned int)iova_addr, + (unsigned int)iova_addr + + (unsigned int)src_buf_size, + io_cfg[i].offsets[j], + io_cfg[i].mem_handle[j]); + } +} + +static void cam_tfe_mgr_pf_dump(uint32_t res_id, + struct cam_tfe_hw_mgr_ctx *ctx) +{ + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_hw_intf *hw_intf; + struct cam_isp_hw_get_cmd_update cmd_update; + uint32_t res_id_out; + int i, rc = 0; + + /* dump the registers */ + 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, NULL, false); + if (rc) { + CAM_ERR(CAM_ISP, + "Reg dump on pf failed req id: %llu rc: %d", + ctx->applied_req_id, rc); + } + + /* dump the acquire data */ + list_for_each_entry(hw_mgr_res, &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; + if (hw_intf && hw_intf->hw_ops.process_cmd) { + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_TFE_CSID_LOG_ACQUIRE_DATA, + hw_mgr_res->hw_res[i], + sizeof(void *)); + if (rc) + CAM_ERR(CAM_ISP, + "acquire dump data failed"); + } else + CAM_ERR(CAM_ISP, "NULL hw_intf!"); } } + + res_id_out = res_id & 0xFF; + + if (res_id_out >= CAM_TFE_HW_OUT_RES_MAX) { + CAM_ERR(CAM_ISP, "Invalid out resource id :%x", + res_id); + return; + } + + hw_mgr_res = + &ctx->res_list_tfe_out[res_id_out]; + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + cmd_update.cmd_type = CAM_ISP_HW_CMD_DUMP_BUS_INFO; + cmd_update.res = hw_mgr_res->hw_res[i]; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_ops.process_cmd) { + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_DUMP_BUS_INFO, + (void *)&cmd_update, + sizeof(struct cam_isp_hw_get_cmd_update)); + } + } +} + +static void cam_tfe_mgr_dump_pf_data( + struct cam_tfe_hw_mgr *hw_mgr, + struct cam_hw_cmd_args *hw_cmd_args) +{ + struct cam_tfe_hw_mgr_ctx *ctx; + struct cam_isp_hw_mgr_res *hw_mgr_res; + struct cam_isp_hw_get_cmd_update cmd_update; + struct cam_isp_hw_get_res_for_mid get_res; + struct cam_packet *packet; + uint32_t *resource_type; + uint32_t hw_id; + bool *ctx_found, hw_id_found = false; + int i, j, rc = 0; + + ctx = (struct cam_tfe_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map; + + packet = hw_cmd_args->u.pf_args.pf_data.packet; + ctx_found = hw_cmd_args->u.pf_args.ctx_found; + resource_type = hw_cmd_args->u.pf_args.resource_type; + + if ((*ctx_found) && (*resource_type)) + goto outportlog; + + for (i = 0; i < CAM_TFE_HW_NUM_MAX; i++) { + if (!g_tfe_hw_mgr.tfe_devices[i]) + continue; + + for (j = 0; j < g_tfe_hw_mgr.tfe_devices[i]->num_hw_pid; j++) { + if (g_tfe_hw_mgr.tfe_devices[i]->hw_pid[j] == + hw_cmd_args->u.pf_args.pid) { + hw_id_found = true; + hw_id = i; + break; + } + } + if (hw_id_found) + break; + } + + if (i == CAM_TFE_HW_NUM_MAX) { + CAM_INFO(CAM_ISP, + "PID:%d is not matching with any TFE HW PIDs ctx id:%d", + hw_cmd_args->u.pf_args.pid, ctx->ctx_index); + return; + } + + for (i = 0; i < ctx->num_base; i++) { + if (ctx->base[i].idx == hw_id) { + *ctx_found = true; + break; + } + } + + if (!(*ctx_found)) { + CAM_INFO(CAM_ISP, + "This context does not cause pf:pid:%d hw id:%d ctx_id:%d", + hw_cmd_args->u.pf_args.pid, hw_id, ctx->ctx_index); + return; + } + + for (i = 0; i < CAM_TFE_HW_OUT_RES_MAX; i++) { + hw_mgr_res = &ctx->res_list_tfe_out[i]; + if (!hw_mgr_res->hw_res[0]) + continue; + + break; + } + + if (i >= CAM_TFE_HW_OUT_RES_MAX) { + CAM_ERR(CAM_ISP, + "NO valid outport resources ctx id:%d req id:%lld", + ctx->ctx_index, packet->header.request_id); + return; + } + + get_res.mid = hw_cmd_args->u.pf_args.mid; + cmd_update.res = hw_mgr_res->hw_res[0]; + cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID; + cmd_update.data = (void *) &get_res; + + /* get resource id for given mid */ + rc = hw_mgr_res->hw_res[0]->hw_intf->hw_ops.process_cmd( + hw_mgr_res->hw_res[0]->hw_intf->hw_priv, + cmd_update.cmd_type, &cmd_update, + sizeof(struct cam_isp_hw_get_cmd_update)); + + if (rc) { + CAM_ERR(CAM_ISP, + "getting mid port resource id failed ctx id:%d req id:%lld", + ctx->ctx_index, packet->header.request_id); + return; + } + CAM_ERR(CAM_ISP, + "Page fault on resource id:0x%x ctx id:%d req id:%lld", + get_res.out_res_id, ctx->ctx_index, packet->header.request_id); + *resource_type = get_res.out_res_id; + + cam_tfe_mgr_pf_dump(get_res.out_res_id, ctx); + +outportlog: + cam_tfe_mgr_print_io_bufs(hw_mgr, *resource_type, packet, + ctx_found, ctx); + + } static void cam_tfe_mgr_ctx_irq_dump(struct cam_tfe_hw_mgr_ctx *ctx) @@ -4463,12 +4636,7 @@ static int cam_tfe_mgr_cmd(void *hw_mgr_priv, void *cmd_args) } break; case CAM_HW_MGR_CMD_DUMP_PF_INFO: - cam_tfe_mgr_print_io_bufs( - hw_cmd_args->u.pf_args.pf_data.packet, - hw_mgr->mgr_common.img_iommu_hdl, - hw_mgr->mgr_common.img_iommu_hdl_secure, - hw_cmd_args->u.pf_args.buf_info, - hw_cmd_args->u.pf_args.mem_found); + cam_tfe_mgr_dump_pf_data(hw_mgr, hw_cmd_args); break; case CAM_HW_MGR_CMD_REG_DUMP_ON_FLUSH: if (ctx->last_dump_flush_req_id == ctx->applied_req_id) @@ -5277,9 +5445,10 @@ static int cam_tfe_hw_mgr_sort_dev_with_caps( for (i = 0; i < CAM_TFE_HW_NUM_MAX; i++) { if (!tfe_hw_mgr->tfe_devices[i]) continue; - if (tfe_hw_mgr->tfe_devices[i]->hw_ops.get_hw_caps) { - tfe_hw_mgr->tfe_devices[i]->hw_ops.get_hw_caps( - tfe_hw_mgr->tfe_devices[i]->hw_priv, + + if (tfe_hw_mgr->tfe_devices[i]->hw_intf->hw_ops.get_hw_caps) { + tfe_hw_mgr->tfe_devices[i]->hw_intf->hw_ops.get_hw_caps( + tfe_hw_mgr->tfe_devices[i]->hw_intf->hw_priv, &tfe_hw_mgr->tfe_dev_caps[i], sizeof(tfe_hw_mgr->tfe_dev_caps[i])); } @@ -5406,7 +5575,7 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) rc = cam_tfe_hw_init(&g_tfe_hw_mgr.tfe_devices[i], i); if (!rc) { struct cam_hw_info *tfe_hw = (struct cam_hw_info *) - g_tfe_hw_mgr.tfe_devices[i]->hw_priv; + g_tfe_hw_mgr.tfe_devices[i]->hw_intf->hw_priv; struct cam_hw_soc_info *soc_info = &tfe_hw->soc_info; j++; diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h index 971863d5b5..b074ab1b4b 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h @@ -152,7 +152,7 @@ struct cam_tfe_hw_mgr { struct cam_isp_hw_mgr mgr_common; struct cam_hw_intf *tpg_devices[CAM_TOP_TPG_HW_NUM_MAX]; struct cam_hw_intf *csid_devices[CAM_TFE_CSID_HW_NUM_MAX]; - struct cam_hw_intf *tfe_devices[CAM_TFE_HW_NUM_MAX]; + struct cam_isp_hw_intf_data *tfe_devices[CAM_TFE_HW_NUM_MAX]; struct cam_soc_reg_map *cdm_reg_map[CAM_TFE_HW_NUM_MAX]; struct mutex ctx_mutex; atomic_t active_ctx_cnt; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h index f93c606392..37094775db 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h @@ -179,6 +179,7 @@ enum cam_tfe_csid_cmd_type { CAM_TFE_CSID_SET_CSID_DEBUG, CAM_TFE_CSID_SOF_IRQ_DEBUG, CAM_TFE_CSID_CMD_GET_REG_DUMP, + CAM_TFE_CSID_LOG_ACQUIRE_DATA, CAM_TFE_CSID_CMD_MAX, }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h index cdbae72678..4b9dce38ca 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h @@ -248,6 +248,6 @@ struct cam_tfe_irq_evt_payload { * successful initialization * @hw_idx: Index of TFE HW */ -int cam_tfe_hw_init(struct cam_hw_intf **tfe_hw, uint32_t hw_idx); +int cam_tfe_hw_init(struct cam_isp_hw_intf_data **tfe_hw, uint32_t hw_idx); #endif /* _CAM_TFE_HW_INTF_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c index 0958b97900..931a54b61e 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c @@ -2530,6 +2530,53 @@ dump_bw: return 0; } +static int cam_tfe_csid_log_acquire_data( + struct cam_tfe_csid_hw *csid_hw, void *cmd_args) +{ + struct cam_isp_resource_node *res = + (struct cam_isp_resource_node *)cmd_args; + struct cam_tfe_csid_path_cfg *path_data; + struct cam_hw_soc_info *soc_info; + const struct cam_tfe_csid_reg_offset *csid_reg; + uint32_t byte_cnt_ping, byte_cnt_pong; + + path_data = (struct cam_tfe_csid_path_cfg *)res->res_priv; + csid_reg = csid_hw->csid_info->csid_reg; + soc_info = &csid_hw->hw_info->soc_info; + + if (res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE) { + CAM_ERR(CAM_ISP, + "CSID:%d invalid res id:%d res type: %d state:%d", + csid_hw->hw_intf->hw_idx, res->res_id, res->res_type, + res->res_state); + return -EINVAL; + } + + /* Dump all the acquire data for this */ + CAM_INFO(CAM_ISP, + "CSID:%d res id:%d type:%d state:%d in f:%d out f:%d st pix:%d end pix:%d st line:%d end line:%d", + csid_hw->hw_intf->hw_idx, res->res_id, res->res_type, + res->res_type, path_data->in_format, path_data->out_format, + path_data->start_pixel, path_data->end_pixel, + path_data->start_line, path_data->end_line); + + if (res->res_id >= CAM_TFE_CSID_PATH_RES_RDI_0 && + res->res_id <= CAM_TFE_CSID_PATH_RES_RDI_2) { + /* read total number of bytes transmitted through RDI */ + byte_cnt_ping = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[res->res_id]->csid_rdi_byte_cntr_ping_addr); + byte_cnt_pong = cam_io_r_mb(soc_info->reg_map[0].mem_base + + csid_reg->rdi_reg[res->res_id]->csid_rdi_byte_cntr_pong_addr); + CAM_INFO(CAM_ISP, + "CSID:%d res id:%d byte cnt val ping:%d pong:%d", + csid_hw->hw_intf->hw_idx, res->res_id, + byte_cnt_ping, byte_cnt_pong); + } + + return 0; + +} + static int cam_tfe_csid_process_cmd(void *hw_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -2567,6 +2614,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv, case CAM_ISP_HW_CMD_CSID_CHANGE_HALT_MODE: rc = cam_tfe_csid_halt(csid_hw, cmd_args); break; + case CAM_TFE_CSID_LOG_ACQUIRE_DATA: + rc = cam_tfe_csid_log_acquire_data(csid_hw, cmd_args); + break; default: CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d", csid_hw->hw_intf->hw_idx, cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h index 6be379a393..ae0be9d2c9 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h @@ -740,6 +740,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_5, .rup_group_id = CAM_TFE_BUS_RUP_GRP_1, + .mid = 23, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_RDI1, @@ -747,6 +748,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_6, .rup_group_id = CAM_TFE_BUS_RUP_GRP_2, + .mid = 24, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_RDI2, @@ -754,6 +756,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_7, .rup_group_id = CAM_TFE_BUS_RUP_GRP_3, + .mid = 25, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_FULL, @@ -761,6 +764,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = 4096, .composite_group = CAM_TFE_BUS_COMP_GRP_0, .rup_group_id = CAM_TFE_BUS_RUP_GRP_0, + .mid = 16, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_RAW_DUMP, @@ -768,6 +772,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = 4096, .composite_group = CAM_TFE_BUS_COMP_GRP_1, .rup_group_id = CAM_TFE_BUS_RUP_GRP_0, + .mid = 17, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_PDAF, @@ -775,6 +780,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = 4096, .composite_group = CAM_TFE_BUS_COMP_GRP_7, .rup_group_id = CAM_TFE_BUS_RUP_GRP_3, + .mid = 25, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_STATS_HDR_BE, @@ -782,6 +788,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_3, .rup_group_id = CAM_TFE_BUS_RUP_GRP_0, + .mid = 21, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_STATS_HDR_BHIST, @@ -789,6 +796,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_2, .rup_group_id = CAM_TFE_BUS_RUP_GRP_0, + .mid = 19, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_STATS_TL_BG, @@ -796,6 +804,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_2, .rup_group_id = CAM_TFE_BUS_RUP_GRP_0, + .mid = 18, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_STATS_AWB_BG, @@ -803,6 +812,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_3, .rup_group_id = CAM_TFE_BUS_RUP_GRP_0, + .mid = 20, }, { .tfe_out_id = CAM_TFE_BUS_TFE_OUT_STATS_BF, @@ -810,6 +820,7 @@ static struct cam_tfe_bus_hw_info tfe530_bus_hw_info = { .max_height = -1, .composite_group = CAM_TFE_BUS_COMP_GRP_4, .rup_group_id = CAM_TFE_BUS_RUP_GRP_0, + .mid = 22, }, }, .comp_done_shift = 8, diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c index 7d207060d3..cdc009429b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c @@ -145,6 +145,7 @@ struct cam_tfe_bus_tfe_out_data { uint32_t secure_mode; void *priv; cam_hw_mgr_event_cb_func event_cb; + uint32_t mid; }; struct cam_tfe_bus_priv { @@ -1544,6 +1545,7 @@ static int cam_tfe_bus_init_tfe_out_resource(uint32_t index, rsrc_data->max_height = hw_info->tfe_out_hw_info[index].max_height; rsrc_data->secure_mode = CAM_SECURE_MODE_NON_SECURE; + rsrc_data->mid = hw_info->tfe_out_hw_info[index].mid; tfe_out->hw_intf = bus_priv->common_data.hw_intf; @@ -2099,6 +2101,113 @@ static int cam_tfe_bus_update_stripe_cfg(void *priv, void *cmd_args, return 0; } +static int cam_tfe_bus_get_res_id_for_mid( + struct cam_tfe_bus_priv *bus_priv, + void *cmd_args, uint32_t arg_size) +{ + struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL; + struct cam_isp_hw_get_cmd_update *cmd_update = + (struct cam_isp_hw_get_cmd_update *)cmd_args; + struct cam_isp_hw_get_res_for_mid *get_res = NULL; + int i; + + get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data; + if (!get_res) { + CAM_ERR(CAM_ISP, + "invalid get resource for mid paramas"); + return -EINVAL; + } + + for (i = 0; i < bus_priv->num_out; i++) { + tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) + bus_priv->tfe_out[i].res_priv; + + if (!tfe_out_data) + continue; + + if (tfe_out_data->mid == get_res->mid) + goto end; + } + + if (i == bus_priv->num_out) { + CAM_ERR(CAM_ISP, + "mid:%d does not match with any out resource", + get_res->mid); + get_res->out_res_id = 0; + return -EINVAL; + } + +end: + CAM_INFO(CAM_ISP, "match mid :%d out resource:%d found", + get_res->mid, bus_priv->tfe_out[i].res_id); + get_res->out_res_id = bus_priv->tfe_out[i].res_id; + return 0; +} + +static int cam_tfe_bus_dump_bus_info( + struct cam_tfe_bus_priv *bus_priv, + void *cmd_args, uint32_t arg_size) +{ + struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL; + struct cam_isp_hw_get_cmd_update *cmd_update = + (struct cam_isp_hw_get_cmd_update *)cmd_args; + struct cam_tfe_bus_wm_resource_data *wm_data; + struct cam_tfe_bus_common_data *common_data; + uint32_t i, addr_status0, addr_status1, addr_status2, addr_status3; + + tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) + cmd_update->res->res_priv; + common_data = tfe_out_data->common_data; + + for (i = 0; i < tfe_out_data->num_wm; i++) { + wm_data = tfe_out_data->wm_res[i]->res_priv; + addr_status0 = cam_io_r_mb(common_data->mem_base + + wm_data->hw_regs->addr_status_0); + addr_status1 = cam_io_r_mb(common_data->mem_base + + wm_data->hw_regs->addr_status_1); + addr_status2 = cam_io_r_mb(common_data->mem_base + + wm_data->hw_regs->addr_status_2); + addr_status3 = cam_io_r_mb(common_data->mem_base + + wm_data->hw_regs->addr_status_3); + CAM_INFO(CAM_ISP, + "TFE:%d WM:%d %s last consumed addr:0x%x last frame addr:0x%x fifo cnt:0x%x cur clt addr:0x%x", + common_data->hw_intf->hw_idx, + wm_data->index, + wm_data->hw_regs->client_name, + addr_status0, + addr_status1, + addr_status2, + addr_status3); + + CAM_INFO(CAM_ISP, + "WM:%d %s width0x%x height:0x%x format:%d stride:0x%x offset:0x%x encfg:%x", + wm_data->index, + wm_data->hw_regs->client_name, + wm_data->acquired_width, + wm_data->acquired_height, + wm_data->format, + wm_data->acquired_stride, + wm_data->offset, + wm_data->en_cfg); + + CAM_INFO(CAM_ISP, + "WM:%d current width:0x%x height:0x%x stride:0x%x", + wm_data->index, + wm_data->width, + wm_data->height, + wm_data->stride); + } + + for (i = 0; i < CAM_TFE_BUS_MAX_CLIENTS; i++) { + wm_data = bus_priv->bus_client[i].res_priv; + /* disable WM */ + cam_io_w_mb(0, common_data->mem_base + + wm_data->hw_regs->cfg); + + } + return 0; +} + static int cam_tfe_bus_init_hw(void *hw_priv, void *init_hw_args, uint32_t arg_size) { @@ -2198,6 +2307,12 @@ static int cam_tfe_bus_process_cmd(void *priv, *support_consumed_addr = bus_priv->common_data.support_consumed_addr; break; + case CAM_ISP_HW_CMD_GET_RES_FOR_MID: + rc = cam_tfe_bus_get_res_id_for_mid(priv, cmd_args, arg_size); + break; + case CAM_ISP_HW_CMD_DUMP_BUS_INFO: + rc = cam_tfe_bus_dump_bus_info(priv, cmd_args, arg_size); + break; default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d", cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h index 2b2ca16ab1..98c12063c4 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h @@ -18,6 +18,7 @@ #define CAM_TFE_BUS_CLIENT_NAME_MAX_LENGTH 32 #define CAM_TFE_BUS_1_0 0x1000 +#define CAM_TFE_BUS_MAX_MID_PER_PORT 1 #define CAM_TFE_ADD_REG_VAL_PAIR(buf_array, index, offset, val) \ @@ -157,6 +158,7 @@ struct cam_tfe_bus_reg_offset_bus_client { * max_height Max height supported by outport * composite_group Out port composite group id * rup_group_id Reg update group of outport id + * mid: ouport mid value */ struct cam_tfe_bus_tfe_out_hw_info { enum cam_tfe_bus_tfe_out_id tfe_out_id; @@ -164,6 +166,7 @@ struct cam_tfe_bus_tfe_out_hw_info { uint32_t max_height; uint32_t composite_group; uint32_t rup_group_id; + uint32_t mid; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c index 088652dab4..60b456e44f 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c @@ -2811,6 +2811,8 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_STOP_BUS_ERR_IRQ: case CAM_ISP_HW_CMD_GET_SECURE_MODE: case CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT: + case CAM_ISP_HW_CMD_GET_RES_FOR_MID: + case CAM_ISP_HW_CMD_DUMP_BUS_INFO: rc = core_info->tfe_bus->hw_ops.process_cmd( core_info->tfe_bus->bus_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.c index 0f8c057b7b..3d932262db 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.c @@ -12,7 +12,7 @@ #include "cam_debug_util.h" #include "camera_main.h" -static struct cam_hw_intf *cam_tfe_hw_list[CAM_TFE_HW_NUM_MAX] = {0, 0, 0}; +static struct cam_isp_hw_intf_data cam_tfe_hw_list[CAM_TFE_HW_NUM_MAX]; static char tfe_dev_name[8]; @@ -24,8 +24,10 @@ static int cam_tfe_component_bind(struct device *dev, const struct of_device_id *match_dev = NULL; struct cam_tfe_hw_core_info *core_info = NULL; struct cam_tfe_hw_info *hw_info = NULL; + struct cam_tfe_soc_private *tfe_soc_priv; int rc = 0; struct platform_device *pdev = to_platform_device(dev); + uint32_t i; tfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL); if (!tfe_hw_intf) { @@ -108,7 +110,18 @@ static int cam_tfe_component_bind(struct device *dev, init_completion(&tfe_hw->hw_complete); if (tfe_hw_intf->hw_idx < CAM_TFE_HW_NUM_MAX) - cam_tfe_hw_list[tfe_hw_intf->hw_idx] = tfe_hw_intf; + cam_tfe_hw_list[tfe_hw_intf->hw_idx].hw_intf = tfe_hw_intf; + else { + CAM_ERR(CAM_ISP, "HW index:%d is wrong max HW idx:%d", + tfe_hw_intf->hw_idx, CAM_TFE_HW_NUM_MAX); + goto deinit_soc; + } + + tfe_soc_priv = tfe_hw->soc_info.soc_private; + cam_tfe_hw_list[tfe_hw_intf->hw_idx].num_hw_pid = tfe_soc_priv->num_pid; + for (i = 0; i < tfe_soc_priv->num_pid; i++) + cam_tfe_hw_list[tfe_hw_intf->hw_idx].hw_pid[i] = + tfe_soc_priv->pid[i]; cam_tfe_init_hw(tfe_hw, NULL, 0); cam_tfe_deinit_hw(tfe_hw, NULL, 0); @@ -149,7 +162,7 @@ static void cam_tfe_component_unbind(struct device *dev, tfe_hw_intf->hw_type, tfe_hw_intf->hw_idx); if (tfe_hw_intf->hw_idx < CAM_TFE_HW_NUM_MAX) - cam_tfe_hw_list[tfe_hw_intf->hw_idx] = NULL; + cam_tfe_hw_list[tfe_hw_intf->hw_idx].hw_intf = NULL; tfe_hw = tfe_hw_intf->hw_priv; if (!tfe_hw) { @@ -206,15 +219,16 @@ int cam_tfe_remove(struct platform_device *pdev) return 0; } -int cam_tfe_hw_init(struct cam_hw_intf **tfe_hw, uint32_t hw_idx) +int cam_tfe_hw_init(struct cam_isp_hw_intf_data **tfe_hw_intf, + uint32_t hw_idx) { int rc = 0; - if (cam_tfe_hw_list[hw_idx]) { - *tfe_hw = cam_tfe_hw_list[hw_idx]; + if (cam_tfe_hw_list[hw_idx].hw_intf) { + *tfe_hw_intf = &cam_tfe_hw_list[hw_idx]; rc = 0; } else { - *tfe_hw = NULL; + *tfe_hw_intf = NULL; rc = -ENODEV; } return rc; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.c index 6041c5e3f0..a28144a2a5 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.c @@ -25,9 +25,9 @@ static bool cam_tfe_cpas_cb(uint32_t client_handle, void *userdata, int cam_tfe_init_soc_resources(struct cam_hw_soc_info *soc_info, irq_handler_t tfe_irq_handler, void *irq_data) { - int rc = 0; struct cam_tfe_soc_private *soc_private; struct cam_cpas_register_params cpas_register_param; + int rc = 0, i = 0, num_pid = 0; soc_private = kzalloc(sizeof(struct cam_tfe_soc_private), GFP_KERNEL); @@ -43,6 +43,27 @@ int cam_tfe_init_soc_resources(struct cam_hw_soc_info *soc_info, goto free_soc_private; } + /* set some default values */ + soc_private->num_pid = 0; + + num_pid = of_property_count_u32_elems(soc_info->pdev->dev.of_node, + "cam_hw_pid"); + CAM_DBG(CAM_CPAS, "tfe:%d pid count %d", soc_info->index, num_pid); + + if (num_pid <= 0 || num_pid > CAM_ISP_HW_MAX_PID_VAL) + goto clk_option; + + for (i = 0; i < num_pid; i++) { + of_property_read_u32_index(soc_info->pdev->dev.of_node, + "cam_hw_pid", i, &soc_private->pid[i]); + CAM_INFO(CAM_CPAS, "tfe:%d I:%d pid %d", soc_info->index, + i, soc_private->pid[i]); + } + + soc_private->num_pid = num_pid; + +clk_option: + rc = cam_soc_util_get_option_clk_by_name(soc_info, CAM_TFE_DSP_CLK_NAME, &soc_private->dsp_clk, &soc_private->dsp_clk_index, &soc_private->dsp_clk_rate); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.h index 6e08a98fbb..5cb137142b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.h @@ -26,6 +26,8 @@ enum cam_cpas_handle_id { * This handle is used for all further interface * with CPAS. * @cpas_version: Has cpas version read from Hardware + * @num_pid: number of pids of tfe + * @pid: TFE pid value list */ struct cam_tfe_soc_private { uint32_t cpas_handle; @@ -33,6 +35,8 @@ struct cam_tfe_soc_private { struct clk *dsp_clk; int32_t dsp_clk_index; int32_t dsp_clk_rate; + uint32_t num_pid; + uint32_t pid[CAM_ISP_HW_MAX_PID_VAL]; }; /*