aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
diff options
context:
space:
mode:
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.c236
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");