diff options
Diffstat (limited to 'drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c')
-rw-r--r-- | drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 236 |
1 files changed, 197 insertions, 39 deletions
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index aab323eac67b..e8e9aa1890b3 100644 --- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,6 +28,8 @@ #include "cam_packet_util.h" #include "cam_debug_util.h" #include "cam_cpas_api.h" +#include "cam_mem_mgr_api.h" +#include "cam_common_util.h" #define CAM_IFE_HW_ENTRIES_MAX 20 @@ -94,7 +96,8 @@ static int cam_ife_mgr_get_hw_caps(void *hw_mgr_priv, CAM_DBG(CAM_ISP, "enter"); - if (copy_from_user(&query_isp, (void __user *)query->caps_handle, + if (copy_from_user(&query_isp, + u64_to_user_ptr(query->caps_handle), sizeof(struct cam_isp_query_cap_cmd))) { rc = -EFAULT; return rc; @@ -113,8 +116,8 @@ static int cam_ife_mgr_get_hw_caps(void *hw_mgr_priv, query_isp.dev_caps[i].hw_version.reserved = 0; } - if (copy_to_user((void __user *)query->caps_handle, &query_isp, - sizeof(struct cam_isp_query_cap_cmd))) + if (copy_to_user(u64_to_user_ptr(query->caps_handle), + &query_isp, sizeof(struct cam_isp_query_cap_cmd))) rc = -EFAULT; CAM_DBG(CAM_ISP, "exit rc :%d", rc); @@ -712,7 +715,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_rdi( ife_out_res->hw_res[0] = vfe_acquire.vfe_out.rsrc_node; ife_out_res->is_dual_vfe = 0; ife_out_res->res_id = vfe_out_res_id; - ife_out_res->res_type = CAM_ISP_RESOURCE_VFE_OUT; + ife_out_res->res_type = (enum cam_ife_hw_mgr_res_type) + CAM_ISP_RESOURCE_VFE_OUT; ife_src_res->child[ife_src_res->num_children++] = ife_out_res; return 0; @@ -762,6 +766,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( if (!ife_src_res->hw_res[j]) continue; + hw_intf = ife_src_res->hw_res[j]->hw_intf; + if (j == CAM_ISP_HW_SPLIT_LEFT) { vfe_acquire.vfe_out.split_id = CAM_ISP_HW_SPLIT_LEFT; @@ -769,7 +775,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( /*TBD */ vfe_acquire.vfe_out.is_master = 1; vfe_acquire.vfe_out.dual_slave_core = - 1; + (hw_intf->hw_idx == 0) ? 1 : 0; } else { vfe_acquire.vfe_out.is_master = 0; vfe_acquire.vfe_out.dual_slave_core = @@ -779,10 +785,10 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( vfe_acquire.vfe_out.split_id = CAM_ISP_HW_SPLIT_RIGHT; vfe_acquire.vfe_out.is_master = 0; - vfe_acquire.vfe_out.dual_slave_core = 0; + vfe_acquire.vfe_out.dual_slave_core = + (hw_intf->hw_idx == 0) ? 1 : 0; } - hw_intf = ife_src_res->hw_res[j]->hw_intf; rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &vfe_acquire, sizeof(struct cam_vfe_acquire_args)); @@ -800,7 +806,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel( ife_out_res->hw_res[j]->res_id); } - ife_out_res->res_type = CAM_ISP_RESOURCE_VFE_OUT; + ife_out_res->res_type = (enum cam_ife_hw_mgr_res_type) + CAM_ISP_RESOURCE_VFE_OUT; ife_out_res->res_id = out_port->res_type; ife_out_res->parent = ife_src_res; ife_src_res->child[ife_src_res->num_children++] = ife_out_res; @@ -913,7 +920,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_src( CAM_ERR(CAM_ISP, "Wrong IFE CSID Resource Node"); goto err; } - ife_src_res->res_type = vfe_acquire.rsrc_type; + ife_src_res->res_type = (enum cam_ife_hw_mgr_res_type) + vfe_acquire.rsrc_type; ife_src_res->res_id = vfe_acquire.vfe_in.res_id; ife_src_res->is_dual_vfe = csid_res->is_dual_vfe; @@ -1038,7 +1046,7 @@ static int cam_ife_mgr_acquire_cid_res( } /* Acquire Left if not already acquired */ - for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { + for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) { if (!ife_hw_mgr->csid_devices[i]) continue; @@ -1054,7 +1062,7 @@ static int cam_ife_mgr_acquire_cid_res( } } - if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) { + if (i == -1 || !csid_acquire.node_res) { CAM_ERR(CAM_ISP, "Can not acquire ife cid resource for path %d", csid_path); goto put_res; @@ -1145,7 +1153,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_ipp( goto end; } - csid_res->res_type = CAM_ISP_RESOURCE_PIX_PATH; + csid_res->res_type = (enum cam_ife_hw_mgr_res_type) + CAM_ISP_RESOURCE_PIX_PATH; csid_res->res_id = CAM_IFE_PIX_PATH_RES_IPP; if (in_port->usage_type) @@ -1559,9 +1568,18 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, goto free_res; } - in_port = memdup_user((void __user *)isp_resource[i].res_hdl, + in_port = memdup_user( + u64_to_user_ptr(isp_resource[i].res_hdl), isp_resource[i].length); if (!IS_ERR(in_port)) { + if (in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) { + CAM_ERR(CAM_ISP, "too many output res %d", + in_port->num_out_res); + rc = -EINVAL; + kfree(in_port); + goto free_res; + } + in_port_length = sizeof(struct cam_isp_in_port_info) + (in_port->num_out_res - 1) * sizeof(struct cam_isp_out_port_info); @@ -2159,7 +2177,8 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) struct cam_isp_stop_args stop_isp; struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_res *hw_mgr_res; - uint32_t i; + struct cam_isp_resource_node *rsrc_node = NULL; + uint32_t i, camif_debug; if (!hw_mgr_priv || !start_isp) { CAM_ERR(CAM_ISP, "Invalid arguments"); @@ -2193,6 +2212,24 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) sizeof(g_ife_hw_mgr.debug_cfg.csid_debug)); } + camif_debug = g_ife_hw_mgr.debug_cfg.camif_debug; + list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + + rsrc_node = hw_mgr_res->hw_res[i]; + if (rsrc_node->process_cmd && (rsrc_node->res_id == + CAM_ISP_HW_VFE_IN_CAMIF)) { + rc = hw_mgr_res->hw_res[i]->process_cmd( + hw_mgr_res->hw_res[i], + CAM_ISP_HW_CMD_SET_CAMIF_DEBUG, + &camif_debug, + sizeof(camif_debug)); + } + } + } + rc = cam_ife_hw_mgr_init_hw(ctx); if (rc) { CAM_ERR(CAM_ISP, "Init failed"); @@ -2804,45 +2841,133 @@ static int cam_ife_mgr_sof_irq_debug( return rc; } +static void cam_ife_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) +{ + uint64_t iova_addr; + size_t src_buf_size; + int i; + int j; + int rc = 0; + int32_t mmu_hdl; + + struct cam_buf_io_cfg *io_cfg = NULL; + + if (mem_found) + *mem_found = false; + + 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 (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: %d mem %x fd: %x", + io_cfg[i].resource_type, + io_cfg[i].mem_handle[j], + pf_buf_info); + if (mem_found) + *mem_found = true; + } + + CAM_INFO(CAM_ISP, "port: %d f: %u format: %d dir %d", + io_cfg[i].resource_type, + io_cfg[i].fence, + io_cfg[i].format, + io_cfg[i].direction); + + 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"); + continue; + } + if (iova_addr >> 32) { + CAM_ERR(CAM_ISP, "Invalid mapped address"); + rc = -EINVAL; + continue; + } + + CAM_INFO(CAM_ISP, + "pln %d w %d h %d size %d addr 0x%x offset 0x%x memh %x", + j, io_cfg[i].planes[j].width, + io_cfg[i].planes[j].height, + (int32_t)src_buf_size, + (unsigned int)iova_addr, + io_cfg[i].offsets[j], + io_cfg[i].mem_handle[j]); + } + } +} + static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; - struct cam_isp_hw_cmd_args *hw_cmd_args = cmd_args; - struct cam_ife_hw_mgr_ctx *ctx; + struct cam_hw_cmd_args *hw_cmd_args = cmd_args; + struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv; + struct cam_ife_hw_mgr_ctx *ctx = (struct cam_ife_hw_mgr_ctx *) + hw_cmd_args->ctxt_to_hw_map; if (!hw_mgr_priv || !cmd_args) { CAM_ERR(CAM_ISP, "Invalid arguments"); return -EINVAL; } - ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map; if (!ctx || !ctx->ctx_in_use) { CAM_ERR(CAM_ISP, "Fatal: Invalid context is used"); return -EPERM; } switch (hw_cmd_args->cmd_type) { - case CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT: - if (ctx->is_rdi_only_context) - hw_cmd_args->u.is_rdi_only_context = 1; - else - hw_cmd_args->u.is_rdi_only_context = 0; - - break; - case CAM_ISP_HW_MGR_CMD_PAUSE_HW: - cam_ife_mgr_pause_hw(ctx); - break; - case CAM_ISP_HW_MGR_CMD_RESUME_HW: - cam_ife_mgr_resume_hw(ctx); + case CAM_HW_MGR_CMD_INTERNAL: { + struct cam_isp_hw_cmd_args *isp_hw_cmd_args = + (struct cam_isp_hw_cmd_args *)hw_cmd_args-> + u.internal_args; + + switch (isp_hw_cmd_args->cmd_type) { + case CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT: + if (ctx->is_rdi_only_context) + isp_hw_cmd_args->u.is_rdi_only_context = 1; + else + isp_hw_cmd_args->u.is_rdi_only_context = 0; + break; + case CAM_ISP_HW_MGR_CMD_PAUSE_HW: + cam_ife_mgr_pause_hw(ctx); + break; + case CAM_ISP_HW_MGR_CMD_RESUME_HW: + cam_ife_mgr_resume_hw(ctx); + break; + case CAM_ISP_HW_MGR_CMD_SOF_DEBUG: + cam_ife_mgr_sof_irq_debug(ctx, + isp_hw_cmd_args->u.sof_irq_enable); + break; + default: + CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x", + hw_cmd_args->cmd_type); + rc = -EINVAL; + break; + } break; - case CAM_ISP_HW_MGR_CMD_SOF_DEBUG: - cam_ife_mgr_sof_irq_debug(ctx, hw_cmd_args->u.sof_irq_enable); + } + case CAM_HW_MGR_CMD_DUMP_PF_INFO: + cam_ife_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); break; default: - CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x", - hw_cmd_args->cmd_type); - rc = -EINVAL; - break; + CAM_ERR(CAM_ISP, "Invalid cmd"); } return rc; @@ -4038,8 +4163,8 @@ int cam_ife_mgr_do_tasklet_buf_done(void *handler_priv, evt_payload = evt_payload_priv; ife_hwr_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)evt_payload->ctx; - CAM_DBG(CAM_ISP, "addr of evt_payload = %llx core index:0x%x", - (uint64_t)evt_payload, evt_payload->core_index); + CAM_DBG(CAM_ISP, "addr of evt_payload = %pK core index:0x%x", + evt_payload, evt_payload->core_index); CAM_DBG(CAM_ISP, "bus_irq_status_0: = %x", evt_payload->irq_reg_val[0]); CAM_DBG(CAM_ISP, "bus_irq_status_1: = %x", evt_payload->irq_reg_val[1]); CAM_DBG(CAM_ISP, "bus_irq_status_2: = %x", evt_payload->irq_reg_val[2]); @@ -4174,6 +4299,28 @@ DEFINE_SIMPLE_ATTRIBUTE(cam_ife_csid_debug, cam_ife_get_csid_debug, cam_ife_set_csid_debug, "%16llu"); +static int cam_ife_set_camif_debug(void *data, u64 val) +{ + g_ife_hw_mgr.debug_cfg.camif_debug = val; + CAM_DBG(CAM_ISP, + "Set camif enable_diag_sensor_status value :%lld", val); + return 0; +} + +static int cam_ife_get_camif_debug(void *data, u64 *val) +{ + *val = g_ife_hw_mgr.debug_cfg.camif_debug; + CAM_DBG(CAM_ISP, + "Set camif enable_diag_sensor_status value :%lld", + g_ife_hw_mgr.debug_cfg.csid_debug); + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(cam_ife_camif_debug, + cam_ife_get_camif_debug, + cam_ife_set_camif_debug, "%16llu"); + static int cam_ife_hw_mgr_debug_register(void) { g_ife_hw_mgr.debug_cfg.dentry = debugfs_create_dir("camera_ife", @@ -4199,6 +4346,14 @@ static int cam_ife_hw_mgr_debug_register(void) CAM_ERR(CAM_ISP, "failed to create enable_recovery"); goto err; } + + if (!debugfs_create_file("ife_camif_debug", + 0644, + g_ife_hw_mgr.debug_cfg.dentry, NULL, + &cam_ife_camif_debug)) { + CAM_ERR(CAM_ISP, "failed to create cam_ife_camif_debug"); + goto err; + } g_ife_hw_mgr.debug_cfg.enable_recovery = 0; return 0; @@ -4208,7 +4363,7 @@ err: return -ENOMEM; } -int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf) +int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl) { int rc = -EFAULT; int i, j; @@ -4380,6 +4535,9 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf) hw_mgr_intf->hw_config = cam_ife_mgr_config_hw; hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd; + if (iommu_hdl) + *iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl; + cam_ife_hw_mgr_debug_register(); CAM_DBG(CAM_ISP, "Exit"); |