Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 06/12
* commit '6e4bb1a37af305e7d4d1aa4eb124140133cf6fc0':
msm: camera: sensor: Increase the eeprom map buffer count
msm: camera: reqmgr: Reset previous skipped slot if valid request
msm: camera: crm: Increasing the device handles to 128
msm: camera: Adding device type to track device handles
msm: camera: isp: Add support for initial frame drop
msm: camera: cpas: Check the HW state before accessing register
msm: camera: cci: Add rd_done to handle read done operation
msm: camera: crm: Increase the device handles to 128
msm: camera: fd: Remove duplicate "qcom,fd501" property
msm: camera: reqmgr: Fix CRM shift one req issue
msm: camera: icp: Mapping fw error numbers with error names
msm: camera: csiphy: correct DPHY bring up sequence (Merged)
msm: camera: Fix cpas axi clk rate overflow (Merged)
msm: camera: reqmgr: Skip reset if no request from UMD
msm: camera: sync: Dump fence info in case of fence exhaust
msm: camera: Add uapi changes for axi bw voting v2
msm: camera: isp: Handle Dual VFE incase of event mismatch
msm: camera: icp: Get GDSC control prior to IPE/BPS reset
Change-Id: I813060ef4d332f8d782b60b1beac81a638855da3
Signed-off-by: Raja Mallik <rmallik@codeaurora.org>
diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
index 3304912..7600cbb 100644
--- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
+++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c
@@ -574,7 +574,7 @@
req_hdl_param.media_entity_flag = 0;
req_hdl_param.priv = ctx;
req_hdl_param.ops = ctx->crm_ctx_intf;
-
+ req_hdl_param.dev_id = ctx->dev_id;
ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
if (ctx->dev_hdl <= 0) {
rc = -EFAULT;
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
index a05901a..4276b35 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c
@@ -568,7 +568,7 @@
struct cam_cpas_axi_port *curr_axi_port = NULL;
struct cam_cpas_axi_port *temp_axi_port = NULL;
uint64_t required_camnoc_bw = 0;
- int32_t clk_rate = 0;
+ int64_t clk_rate = 0;
list_for_each_entry_safe(curr_axi_port, temp_axi_port,
&cpas_core->axi_ports_list_head, sibling_port) {
@@ -596,13 +596,13 @@
clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width;
- CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %d",
+ CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %lld",
required_camnoc_bw, clk_rate);
rc = cam_soc_util_set_src_clk_rate(soc_info, clk_rate);
if (rc)
CAM_ERR(CAM_CPAS,
- "Failed in setting camnoc axi clk %llu %d %d",
+ "Failed in setting camnoc axi clk %llu %lld %d",
required_camnoc_bw, clk_rate, rc);
}
diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
index 49774f2..719fb12 100644
--- a/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
+++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cpas_top/cam_cpastop_hw.c
@@ -415,6 +415,12 @@
return;
}
+ mutex_lock(&cpas_hw->hw_mutex);
+ if (cpas_hw->hw_state == CAM_HW_STATE_POWER_DOWN) {
+ CAM_ERR(CAM_CPAS, "CPAS CORE is off");
+ mutex_unlock(&cpas_hw->hw_mutex);
+ return;
+ }
for (i = 0; i < camnoc_info->irq_err_size; i++) {
if ((payload->irq_status & camnoc_info->irq_err[i].sbm_port) &&
(camnoc_info->irq_err[i].enable)) {
@@ -460,6 +466,7 @@
~camnoc_info->irq_err[i].sbm_port;
}
}
+ mutex_unlock(&cpas_hw->hw_mutex);
atomic_dec(&cpas_core->irq_count);
wake_up(&cpas_core->irq_count_wq);
CAM_DBG(CAM_CPAS, "irq_count=%d\n", atomic_read(&cpas_core->irq_count));
diff --git a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c
index d4c9326..083041c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_dev.c
@@ -206,10 +206,6 @@
.compatible = "qcom,fd501",
.data = &cam_fd_wrapper200_core501_info,
},
- {
- .compatible = "qcom,fd501",
- .data = &cam_fd_wrapper200_core501_info,
- },
{}
};
MODULE_DEVICE_TABLE(of, cam_fd_hw_dt_match);
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h b/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h
index 311886f..d60a25e 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/fw_inc/hfi_sys_defs.h
@@ -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
@@ -215,6 +215,27 @@
#define HFI_DEV_VERSION_MAX 0x5
+/* General errors and HFI Specific errors. */
+enum hfi_errors {
+ CAMERAICP_SUCCESS,
+ CAMERAICP_EFAILED,
+ CAMERAICP_ENOMEMORY,
+ CAMERAICP_EBADSTATE,
+ CAMERAICP_EBADPARM,
+ CAMERAICP_EBADITEM,
+ CAMERAICP_EINVALIDFORMAT,
+ CAMERAICP_EUNSUPPORTED,
+ CAMERAICP_EOUTOFBOUND,
+ CAMERAICP_ETIMEDOUT,
+ CAMERAICP_EABORTED,
+ CAMERAICP_EHWVIOLATION,
+ CAMERAICP_ECDMERROR,
+ CAMERAICP_HFI_ERR_COMMAND_SIZE = 1000,
+ CAMERAICP_HFI_ERR_MESSAGE_SIZE,
+ CAMERAICP_HFI_QUEUE_EMPTY,
+ CAMERAICP_HFI_QUEUE_FULL,
+};
+
/**
* start of sys command packet types
* These commands are used to get system level information
diff --git a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index ca10a3a..2b764d1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -1293,6 +1293,44 @@
return rc;
}
+static int cam_icp_mgr_ipe_bps_get_gdsc_control(
+ struct cam_icp_hw_mgr *hw_mgr)
+{
+ int rc = 0;
+ struct cam_hw_intf *ipe0_dev_intf = NULL;
+ struct cam_hw_intf *ipe1_dev_intf = NULL;
+ struct cam_hw_intf *bps_dev_intf = NULL;
+
+ ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
+ ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
+ bps_dev_intf = hw_mgr->bps_dev_intf;
+
+ if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
+ CAM_ERR(CAM_ICP, "dev intfs are wrong");
+ return -EINVAL;
+ }
+
+ if (icp_hw_mgr.ipe_bps_pc_flag) {
+ rc = bps_dev_intf->hw_ops.process_cmd(
+ bps_dev_intf->hw_priv,
+ CAM_ICP_BPS_CMD_POWER_COLLAPSE,
+ NULL, 0);
+
+ rc = ipe0_dev_intf->hw_ops.process_cmd(
+ ipe0_dev_intf->hw_priv,
+ CAM_ICP_IPE_CMD_POWER_COLLAPSE, NULL, 0);
+
+ if (ipe1_dev_intf) {
+ rc = ipe1_dev_intf->hw_ops.process_cmd(
+ ipe1_dev_intf->hw_priv,
+ CAM_ICP_IPE_CMD_POWER_COLLAPSE,
+ NULL, 0);
+ }
+ }
+
+ return rc;
+}
+
static int cam_icp_set_dbg_default_clk(void *data, u64 val)
{
icp_hw_mgr.icp_debug_clk = val;
@@ -1563,7 +1601,69 @@
return 0;
}
+static const char *cam_icp_error_handle_id_to_type(
+ uint32_t error_handle)
+{
+ const char *name = NULL;
+ switch (error_handle) {
+ case CAMERAICP_SUCCESS:
+ name = "SUCCESS";
+ break;
+ case CAMERAICP_EFAILED:
+ name = "EFAILED";
+ break;
+ case CAMERAICP_ENOMEMORY:
+ name = "ENOMEMORY";
+ break;
+ case CAMERAICP_EBADSTATE:
+ name = "EBADSTATE";
+ break;
+ case CAMERAICP_EBADPARM:
+ name = "EBADPARM";
+ break;
+ case CAMERAICP_EBADITEM:
+ name = "EBADITEM";
+ break;
+ case CAMERAICP_EINVALIDFORMAT:
+ name = "EINVALIDFORMAT";
+ break;
+ case CAMERAICP_EUNSUPPORTED:
+ name = "EUNSUPPORTED";
+ break;
+ case CAMERAICP_EOUTOFBOUND:
+ name = "EOUTOFBOUND";
+ break;
+ case CAMERAICP_ETIMEDOUT:
+ name = "ETIMEDOUT";
+ break;
+ case CAMERAICP_EABORTED:
+ name = "EABORTED";
+ break;
+ case CAMERAICP_EHWVIOLATION:
+ name = "EHWVIOLATION";
+ break;
+ case CAMERAICP_ECDMERROR:
+ name = "ECDMERROR";
+ break;
+ case CAMERAICP_HFI_ERR_COMMAND_SIZE:
+ name = "HFI_ERR_COMMAND_SIZE";
+ break;
+ case CAMERAICP_HFI_ERR_MESSAGE_SIZE:
+ name = "HFI_ERR_MESSAGE_SIZE";
+ break;
+ case CAMERAICP_HFI_QUEUE_EMPTY:
+ name = "HFI_QUEUE_EMPTY";
+ break;
+ case CAMERAICP_HFI_QUEUE_FULL:
+ name = "HFI_QUEUE_FULL";
+ break;
+ default:
+ name = NULL;
+ break;
+ }
+ return name;
+}
static int cam_icp_mgr_process_msg_frame_process(uint32_t *msg_ptr)
{
struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
@@ -1576,8 +1676,11 @@
ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
if (ioconfig_ack->err_type != HFI_ERR_SYS_NONE) {
- CAM_ERR(CAM_ICP, "failed with error : %u",
- ioconfig_ack->err_type);
+ CAM_ERR(CAM_ICP,
+ "failed with err_no= [%u] err_type= [%s]",
+ ioconfig_ack->err_type,
+ cam_icp_error_handle_id_to_type(
+ ioconfig_ack->err_type));
cam_icp_mgr_handle_frame_process(msg_ptr,
ICP_FRAME_PROCESS_FAILURE);
return -EIO;
@@ -1617,8 +1720,12 @@
ipe_config_ack =
(struct hfi_msg_ipe_config *)(ioconfig_ack->msg_data);
if (ipe_config_ack->rc) {
- CAM_ERR(CAM_ICP, "rc = %d err = %u",
- ipe_config_ack->rc, ioconfig_ack->err_type);
+ CAM_ERR(CAM_ICP, "rc = %d failed with\n"
+ "err_no = [%u] err_type = [%s]",
+ ipe_config_ack->rc,
+ ioconfig_ack->err_type,
+ cam_icp_error_handle_id_to_type(
+ ioconfig_ack->err_type));
return -EIO;
}
ctx_data = (struct cam_icp_hw_ctx_data *)
@@ -1783,9 +1890,13 @@
(struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
if (ctx_data->state != CAM_ICP_CTX_STATE_FREE)
complete(&ctx_data->wait_complete);
- CAM_DBG(CAM_ICP,
- "received IPE/BPS MAP ACK:ctx_state =%d err_status =%u",
- ctx_data->state, ioconfig_ack->err_type);
+ CAM_DBG(CAM_ICP, "received IPE/BPS\n"
+ "MAP ACK:ctx_state =%d\n"
+ "failed with err_no = [%u] err_type = [%s]",
+ ctx_data->state,
+ ioconfig_ack->err_type,
+ cam_icp_error_handle_id_to_type(
+ ioconfig_ack->err_type));
break;
case HFI_IPEBPS_CMD_OPCODE_MEM_UNMAP:
ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
@@ -1793,9 +1904,13 @@
(struct cam_icp_hw_ctx_data *)ioconfig_ack->user_data1;
if (ctx_data->state != CAM_ICP_CTX_STATE_FREE)
complete(&ctx_data->wait_complete);
- CAM_DBG(CAM_ICP,
- "received IPE/BPS UNMAP ACK:ctx_state =%d err_status =%u",
- ctx_data->state, ioconfig_ack->err_type);
+ CAM_DBG(CAM_ICP,
+ "received IPE/BPS UNMAP ACK:ctx_state =%d\n"
+ "failed with err_no = [%u] err_type = [%s]",
+ ctx_data->state,
+ ioconfig_ack->err_type,
+ cam_icp_error_handle_id_to_type(
+ ioconfig_ack->err_type));
break;
default:
CAM_ERR(CAM_ICP, "Invalid opcode : %u",
@@ -1817,27 +1932,31 @@
ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
bps_dev_intf = hw_mgr->bps_dev_intf;
- rc = bps_dev_intf->hw_ops.process_cmd(
- bps_dev_intf->hw_priv,
- CAM_ICP_BPS_CMD_RESET,
- NULL, 0);
- if (rc)
- CAM_ERR(CAM_ICP, "bps reset failed");
+ if (hw_mgr->bps_ctxt_cnt) {
+ rc = bps_dev_intf->hw_ops.process_cmd(
+ bps_dev_intf->hw_priv,
+ CAM_ICP_BPS_CMD_RESET,
+ NULL, 0);
+ if (rc)
+ CAM_ERR(CAM_ICP, "bps reset failed");
+ }
- rc = ipe0_dev_intf->hw_ops.process_cmd(
- ipe0_dev_intf->hw_priv,
- CAM_ICP_IPE_CMD_RESET,
- NULL, 0);
- if (rc)
- CAM_ERR(CAM_ICP, "ipe0 reset failed");
-
- if (ipe1_dev_intf) {
- rc = ipe1_dev_intf->hw_ops.process_cmd(
- ipe1_dev_intf->hw_priv,
+ if (hw_mgr->ipe_ctxt_cnt) {
+ rc = ipe0_dev_intf->hw_ops.process_cmd(
+ ipe0_dev_intf->hw_priv,
CAM_ICP_IPE_CMD_RESET,
NULL, 0);
if (rc)
- CAM_ERR(CAM_ICP, "ipe1 reset failed");
+ CAM_ERR(CAM_ICP, "ipe0 reset failed");
+
+ if (ipe1_dev_intf) {
+ rc = ipe1_dev_intf->hw_ops.process_cmd(
+ ipe1_dev_intf->hw_priv,
+ CAM_ICP_IPE_CMD_RESET,
+ NULL, 0);
+ if (rc)
+ CAM_ERR(CAM_ICP, "ipe1 reset failed");
+ }
}
return 0;
@@ -1858,6 +1977,7 @@
sfr_buffer = (struct sfr_buf *)icp_hw_mgr.hfi_mem.sfr_buf.kva;
CAM_WARN(CAM_ICP, "SFR:%s", sfr_buffer->msg);
+ cam_icp_mgr_ipe_bps_get_gdsc_control(hw_mgr);
cam_icp_ipebps_reset(hw_mgr);
atomic_set(&hw_mgr->recovery, 1);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
index 2982ce0..57375c4 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c
@@ -2875,7 +2875,7 @@
req_hdl_param.media_entity_flag = 0;
req_hdl_param.ops = ctx->crm_ctx_intf;
req_hdl_param.priv = ctx;
-
+ req_hdl_param.dev_id = CAM_ISP;
CAM_DBG(CAM_ISP, "get device handle form bridge");
ctx->dev_hdl = cam_create_device_hdl(&req_hdl_param);
if (ctx->dev_hdl <= 0) {
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 177538a..fe3d2f1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -2984,6 +2984,7 @@
}
}
+ ctx->dual_ife_irq_mismatch_cnt = 0;
/* Start IFE root node: do nothing */
CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index);
@@ -3066,6 +3067,7 @@
ctx->is_rdi_only_context = 0;
ctx->cdm_handle = 0;
ctx->cdm_ops = NULL;
+ ctx->dual_ife_irq_mismatch_cnt = 0;
atomic_set(&ctx->overflow_pending, 0);
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
ctx->sof_cnt[i] = 0;
@@ -3573,6 +3575,38 @@
}
}
+static int cam_isp_blob_init_frame_drop(
+ struct cam_isp_init_frame_drop_config *frame_drop_cfg,
+ struct cam_hw_prepare_update_args *prepare)
+{
+ struct cam_ife_hw_mgr_ctx *ctx = NULL;
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ struct cam_hw_intf *hw_intf;
+ uint32_t hw_idx = UINT_MAX;
+ uint32_t i;
+ int rc = 0;
+
+ ctx = prepare->ctxt_to_hw_map;
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_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_idx == hw_idx)
+ continue;
+
+ rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+ CAM_IFE_CSID_SET_INIT_FRAME_DROP,
+ frame_drop_cfg,
+ sizeof(
+ struct cam_isp_init_frame_drop_config *));
+ hw_idx = hw_intf->hw_idx;
+ }
+ }
+ return rc;
+}
+
static int cam_isp_packet_generic_blob_handler(void *user_data,
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
{
@@ -3818,7 +3852,22 @@
CAM_ERR(CAM_ISP, "FS Update Failed rc: %d", rc);
}
break;
+ case CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP: {
+ struct cam_isp_init_frame_drop_config *frame_drop_cfg =
+ (struct cam_isp_init_frame_drop_config *)blob_data;
+ if (blob_size < sizeof(struct cam_isp_init_frame_drop_config)) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+ blob_size,
+ sizeof(struct cam_isp_init_frame_drop_config));
+ return -EINVAL;
+ }
+
+ rc = cam_isp_blob_init_frame_drop(frame_drop_cfg, prepare);
+ if (rc)
+ CAM_ERR(CAM_ISP, "Init Frame drop Update Failed");
+ }
+ break;
default:
CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
break;
@@ -4101,6 +4150,36 @@
}
}
+static void cam_ife_mgr_ctx_irq_dump(struct cam_ife_hw_mgr_ctx *ctx)
+{
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ struct cam_hw_intf *hw_intf;
+ struct cam_isp_hw_get_cmd_update cmd_update;
+ int i = 0;
+
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+ if (hw_mgr_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT)
+ continue;
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i])
+ continue;
+ switch (hw_mgr_res->hw_res[i]->res_id) {
+ case CAM_ISP_HW_VFE_IN_CAMIF:
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ cmd_update.res = hw_mgr_res->hw_res[i];
+ cmd_update.cmd_type =
+ CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP;
+ hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+ CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
+ &cmd_update, sizeof(cmd_update));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
{
int rc = 0;
@@ -4771,11 +4850,26 @@
(event_cnt[core_idx1] &&
(event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) {
+ if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt > 10) {
+ rc = -1;
+ return rc;
+ }
+
CAM_ERR_RATE_LIMIT(CAM_ISP,
"One of the VFE could not generate hw event %d",
hw_event_type);
- rc = -1;
- return rc;
+ if (event_cnt[core_idx0] >= 2) {
+ event_cnt[core_idx0]--;
+ ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
+ }
+ if (event_cnt[core_idx1] >= 2) {
+ event_cnt[core_idx1]--;
+ ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt++;
+ }
+
+ if (ife_hw_mgr_ctx->dual_ife_irq_mismatch_cnt == 1)
+ cam_ife_mgr_ctx_irq_dump(ife_hw_mgr_ctx);
+ rc = 0;
}
CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d",
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
index bf5f152..0e6d79b 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
@@ -102,38 +102,42 @@
/**
* struct cam_vfe_hw_mgr_ctx - IFE HW manager Context object
*
- * @list: used by the ctx list.
- * @common: common acquired context data
- * @ctx_index: acquired context id.
- * @hw_mgr: IFE hw mgr which owns this context
- * @ctx_in_use: flag to tell whether context is active
- * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be
- * one.
- * @res_list_csid: CSID resource list
- * @res_list_ife_src: IFE input resource list
- * @res_list_ife_in_rd IFE input resource list for read path
- * @res_list_ife_out: IFE output resoruces array
- * @free_res_list: Free resources list for the branch node
- * @res_pool: memory storage for the free resource list
- * @irq_status0_mask: irq_status0_mask for the context
- * @irq_status1_mask: irq_status1_mask for the context
- * @base device base index array contain the all IFE HW
- * instance associated with this context.
- * @num_base number of valid base data in the base array
- * @cdm_handle cdm hw acquire handle
- * @cdm_ops cdm util operation pointer for building
- * cdm commands
- * @cdm_cmd cdm base and length request pointer
- * @sof_cnt sof count value per core, used for dual VFE
- * @epoch_cnt epoch count value per core, used for dual VFE
- * @eof_cnt eof count value per core, used for dual VFE
- * @overflow_pending flat to specify the overflow is pending for the
- * context
- * @is_rdi_only_context flag to specify the context has only rdi resource
- * @config_done_complete indicator for configuration complete
- * @init_done indicate whether init hw is done
- * @is_fe_enable indicate whether fetch engine\read path is enabled
- * @res_bitmap fill resource bitmap for which rup to be set
+ * @list: used by the ctx list.
+ * @common: common acquired context data
+ * @ctx_index: acquired context id.
+ * @hw_mgr: IFE hw mgr which owns this context
+ * @ctx_in_use: flag to tell whether context is active
+ * @res_list_ife_in: Starting resource(TPG,PHY0, PHY1...) Can only be
+ * one.
+ * @res_list_csid: CSID resource list
+ * @res_list_ife_src: IFE input resource list
+ * @res_list_ife_in_rd IFE input resource list for read path
+ * @res_list_ife_out: IFE output resoruces array
+ * @free_res_list: Free resources list for the branch node
+ * @res_pool: memory storage for the free resource list
+ * @irq_status0_mask: irq_status0_mask for the context
+ * @irq_status1_mask: irq_status1_mask for the context
+ * @base device base index array contain the all IFE HW
+ * instance associated with this context.
+ * @num_base number of valid base data in the base array
+ * @cdm_handle cdm hw acquire handle
+ * @cdm_ops cdm util operation pointer for building
+ * cdm commands
+ * @cdm_cmd cdm base and length request pointer
+ * @sof_cnt sof count value per core, used for dual VFE
+ * @epoch_cnt epoch count value per core, used for dual VFE
+ * @eof_cnt eof count value per core, used for dual VFE
+ * @overflow_pending flat to specify the overflow is pending
+ * for the context
+ * @is_rdi_only_context flag to specify the context has only rdi
+ * resource
+ * @config_done_complete indicator for configuration complete
+ * @init_done indicate whether init hw is done
+ * @is_fe_enable indicate whether fetch engine\read path
+ * is enabled
+ * @res_bitmap fill resource bitmap for which rup to be set
+ * @dual_ife_irq_mismatch_cnt irq mismatch count value per core, used for
+ * dual VFE
*/
struct cam_ife_hw_mgr_ctx {
struct list_head list;
@@ -171,6 +175,7 @@
bool init_done;
bool is_fe_enable;
unsigned long res_bitmap;
+ uint32_t dual_ife_irq_mismatch_cnt;
};
/**
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index 8fba017..5610f6d 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -468,6 +468,9 @@
csid_hw->hw_intf->hw_idx, val);
csid_hw->error_irq_count = 0;
+ for (i = 0 ; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
+ csid_hw->res_sof_cnt[i] = 0;
+
return rc;
}
@@ -838,7 +841,6 @@
return rc;
}
-
static int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
struct cam_csid_hw_reserve_resource_args *reserve)
{
@@ -953,7 +955,7 @@
path_data->height = reserve->in_port->height;
path_data->start_line = reserve->in_port->line_start;
path_data->end_line = reserve->in_port->line_stop;
-
+ path_data->usage_type = reserve->in_port->usage_type;
/* Enable RDI crop for single ife use case only */
switch (reserve->res_id) {
case CAM_IFE_PIX_PATH_RES_RDI_0:
@@ -1119,6 +1121,7 @@
static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
{
int rc = -EINVAL;
+ uint32_t i;
struct cam_hw_soc_info *soc_info;
const struct cam_ife_csid_reg_offset *csid_reg;
unsigned long flags;
@@ -1159,12 +1162,95 @@
spin_lock_irqsave(&csid_hw->lock_state, flags);
csid_hw->device_enabled = 0;
spin_unlock_irqrestore(&csid_hw->lock_state, flags);
+ for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
+ csid_hw->res_sof_cnt[i] = 0;
+
csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
csid_hw->error_irq_count = 0;
return rc;
}
+static int cam_ife_csid_check_path_active(struct cam_ife_csid_hw *csid_hw)
+{
+ struct cam_hw_soc_info *soc_info;
+ const struct cam_ife_csid_reg_offset *csid_reg;
+ uint32_t i, path_status = 1;
+
+ csid_reg = csid_hw->csid_info->csid_reg;
+ soc_info = &csid_hw->hw_info->soc_info;
+
+ /* check the IPP path status */
+ if (csid_reg->cmn_reg->num_pix) {
+ path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_pxl_status_addr);
+ CAM_DBG(CAM_ISP, "CSID:%d IPP path status:%d",
+ csid_hw->hw_intf->hw_idx, path_status);
+ /* if status is 0 then it is active */
+ if (!path_status)
+ goto end;
+ }
+
+ if (csid_reg->cmn_reg->num_ppp) {
+ path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ppp_reg->csid_pxl_status_addr);
+ CAM_DBG(CAM_ISP, "CSID:%d PPP path status:%d",
+ csid_hw->hw_intf->hw_idx, path_status);
+ /* if status is 0 then it is active */
+ if (!path_status)
+ goto end;
+ }
+
+ /* Check the RDI path status */
+ for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
+ path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[i]->csid_rdi_status_addr);
+ CAM_DBG(CAM_ISP, "CSID:%d RDI:%d path status:%d",
+ csid_hw->hw_intf->hw_idx, i, path_status);
+ /* if status is 0 then it is active */
+ if (!path_status)
+ goto end;
+ }
+
+end:
+ return path_status;
+}
+
+static void cam_ife_csid_reset_init_frame_drop(
+ struct cam_ife_csid_hw *csid_hw)
+{
+ const struct cam_ife_csid_reg_offset *csid_reg;
+ uint32_t i = 0;
+
+ /*
+ * Reset CSID init frame drop value only if all resources are
+ * released
+ */
+ csid_reg = csid_hw->csid_info->csid_reg;
+ if (csid_reg->cmn_reg->num_pix) {
+ if (csid_hw->ipp_res.res_state !=
+ CAM_ISP_RESOURCE_STATE_AVAILABLE)
+ goto end;
+ }
+
+ if (csid_reg->cmn_reg->num_ppp) {
+ if (csid_hw->ppp_res.res_state !=
+ CAM_ISP_RESOURCE_STATE_AVAILABLE)
+ goto end;
+ }
+
+ for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
+ if (csid_hw->rdi_res[i].res_state !=
+ CAM_ISP_RESOURCE_STATE_AVAILABLE)
+ goto end;
+ }
+
+ /* All CSID resources are available reset the init frame drop */
+ csid_hw->init_frame_drop = 0;
+end:
+ return;
+
+}
static int cam_ife_csid_tpg_start(struct cam_ife_csid_hw *csid_hw,
struct cam_isp_resource_node *res)
@@ -1724,7 +1810,7 @@
struct cam_ife_csid_path_cfg *path_data;
const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL;
bool is_ipp;
- uint32_t val = 0;
+ uint32_t val = 0, path_status;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -1767,14 +1853,15 @@
/* Default is internal halt mode */
val = 0;
- /*
- * Resume at frame boundary if Master or No Sync.
- * Slave will get resume command from Master.
- */
- if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
- path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
- val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
-
+ /* Resume at frame boundary */
+ path_status = cam_ife_csid_check_path_active(csid_hw);
+ if (!csid_hw->init_frame_drop ||
+ (csid_hw->init_frame_drop && !path_status)) {
+ CAM_DBG(CAM_ISP, "start pixel path");
+ if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
+ path_data->sync_mode == CAM_ISP_HW_SYNC_NONE)
+ val |= CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
+ }
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_ctrl_addr);
@@ -1788,8 +1875,10 @@
if (pxl_reg->ccif_violation_en)
val |= CSID_PATH_ERROR_CCIF_VIOLATION;
- if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
+ if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) ||
+ (csid_hw->init_frame_drop && path_status))
val |= CSID_PATH_INFO_INPUT_SOF;
+
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
val |= CSID_PATH_INFO_INPUT_EOF;
@@ -2086,8 +2175,10 @@
{
const struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
- uint32_t id, val;
+ struct cam_ife_csid_path_cfg *path_data;
+ uint32_t id, val, path_status;
+ path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
id = res->res_id;
@@ -2102,19 +2193,28 @@
return -EINVAL;
}
- /*resume at frame boundary */
- cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
- soc_info->reg_map[0].mem_base +
- csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
+ if (path_data->usage_type)
+ path_data->init_frame_drop = csid_hw->init_frame_drop + 1;
+ /*resume at frame boundary */
+ path_status = cam_ife_csid_check_path_active(csid_hw);
+ if (!path_data->init_frame_drop ||
+ (path_data->init_frame_drop && !path_status)) {
+ CAM_DBG(CAM_ISP, "Start RDI:%d path", id);
+ cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+ soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_ctrl_addr);
+ }
/* Enable the required RDI interrupts */
val = CSID_PATH_INFO_RST_DONE | CSID_PATH_ERROR_FIFO_OVERFLOW;
if (csid_reg->rdi_reg[id]->ccif_violation_en)
val |= CSID_PATH_ERROR_CCIF_VIOLATION;
- if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ)
+ if ((csid_hw->csid_debug & CSID_DEBUG_ENABLE_SOF_IRQ) ||
+ (path_data->init_frame_drop && path_status))
val |= CSID_PATH_INFO_INPUT_SOF;
+
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
val |= CSID_PATH_INFO_INPUT_EOF;
@@ -2374,6 +2474,19 @@
return 0;
}
+static int cam_ife_csid_set_init_frame_drop(struct cam_ife_csid_hw *csid_hw,
+ void *cmd_args)
+{
+ struct cam_isp_init_frame_drop_config *frame_drop_cfg;
+
+ frame_drop_cfg = (struct cam_isp_init_frame_drop_config *) cmd_args;
+ csid_hw->init_frame_drop = frame_drop_cfg->init_frame_drop;
+ CAM_DBG(CAM_ISP, "CSID:%d set init frame drop:%d",
+ csid_hw->hw_intf->hw_idx, csid_hw->init_frame_drop);
+
+ return 0;
+}
+
static int cam_ife_csid_get_hw_caps(void *hw_priv,
void *get_hw_cap_args, uint32_t arg_size)
{
@@ -2550,6 +2663,7 @@
break;
case CAM_ISP_RESOURCE_PIX_PATH:
res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
+ cam_ife_csid_reset_init_frame_drop(csid_hw);
break;
default:
CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
@@ -3014,6 +3128,9 @@
case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE:
rc = cam_ife_csid_set_csid_clock(csid_hw, cmd_args);
break;
+ case CAM_IFE_CSID_SET_INIT_FRAME_DROP:
+ rc = cam_ife_csid_set_init_frame_drop(csid_hw, cmd_args);
+ break;
default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type);
@@ -3031,6 +3148,9 @@
struct cam_hw_soc_info *soc_info;
const struct cam_ife_csid_reg_offset *csid_reg;
const struct cam_ife_csid_csi2_rx_reg_offset *csi2_reg;
+ struct cam_ife_csid_path_cfg *path_data;
+ const struct cam_ife_csid_pxl_reg_offset *pxl_reg;
+ const struct cam_ife_csid_rdi_reg_offset *rdi_reg;
uint32_t i, irq_status_top, irq_status_rx, irq_status_ipp = 0;
uint32_t irq_status_rdi[4] = {0, 0, 0, 0};
uint32_t val, irq_status_ppp = 0;
@@ -3262,6 +3382,53 @@
csid_hw->irq_debug_cnt++;
}
+ if ((irq_status_ipp & CSID_PATH_INFO_INPUT_SOF) &&
+ (csid_hw->init_frame_drop) &&
+ (csid_hw->ipp_res.res_state ==
+ CAM_ISP_RESOURCE_STATE_STREAMING)) {
+ csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP]++;
+ CAM_DBG(CAM_ISP,
+ "CSID:%d IPP SOF cnt:%d init_frame_drop:%d",
+ csid_hw->hw_intf->hw_idx,
+ csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP],
+ csid_hw->init_frame_drop);
+ if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_IPP] ==
+ csid_hw->init_frame_drop) {
+ pxl_reg = csid_reg->ipp_reg;
+ path_data = csid_hw->ipp_res.res_priv;
+ if (path_data->sync_mode ==
+ CAM_ISP_HW_SYNC_MASTER) {
+ val = cam_io_r_mb(
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_ctrl_addr);
+
+ val |=
+ CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
+ cam_io_w_mb(val,
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_ctrl_addr);
+
+ } else if (path_data->sync_mode ==
+ CAM_ISP_HW_SYNC_NONE) {
+ cam_io_w_mb(
+ CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_ctrl_addr);
+ }
+
+ if (!(csid_hw->csid_debug &
+ CSID_DEBUG_ENABLE_SOF_IRQ)) {
+ val = cam_io_r_mb(
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_irq_mask_addr);
+ val &= ~(CSID_PATH_INFO_INPUT_SOF);
+ cam_io_w_mb(val,
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_irq_mask_addr);
+ }
+ }
+ }
+
if ((irq_status_ipp & CSID_PATH_INFO_INPUT_EOF) &&
(csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received",
@@ -3297,6 +3464,52 @@
csid_hw->irq_debug_cnt++;
}
+ if ((irq_status_ppp & CSID_PATH_INFO_INPUT_SOF) &&
+ (csid_hw->init_frame_drop) &&
+ (csid_hw->ppp_res.res_state ==
+ CAM_ISP_RESOURCE_STATE_STREAMING)) {
+ csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP]++;
+ CAM_DBG(CAM_ISP,
+ "CSID:%d PPP SOF cnt:%d init_frame_drop:%d",
+ csid_hw->hw_intf->hw_idx,
+ csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP],
+ csid_hw->init_frame_drop);
+ if (csid_hw->res_sof_cnt[CAM_IFE_PIX_PATH_RES_PPP] ==
+ csid_hw->init_frame_drop) {
+ path_data = csid_hw->ppp_res.res_priv;
+ pxl_reg = csid_reg->ppp_reg;
+ if (path_data->sync_mode ==
+ CAM_ISP_HW_SYNC_MASTER) {
+ val = cam_io_r_mb(
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_ctrl_addr);
+
+ val |=
+ CAM_CSID_RESUME_AT_FRAME_BOUNDARY;
+ cam_io_w_mb(val,
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_ctrl_addr);
+ } else if (path_data->sync_mode ==
+ CAM_ISP_HW_SYNC_NONE) {
+ cam_io_w_mb(
+ CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_ctrl_addr);
+ }
+
+ if (!(csid_hw->csid_debug &
+ CSID_DEBUG_ENABLE_SOF_IRQ)) {
+ val = cam_io_r_mb(
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_irq_mask_addr);
+ val &= ~(CSID_PATH_INFO_INPUT_SOF);
+ cam_io_w_mb(val,
+ soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_irq_mask_addr);
+ }
+ }
+ }
+
if ((irq_status_ppp & CSID_PATH_INFO_INPUT_EOF) &&
(csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received",
@@ -3317,6 +3530,9 @@
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
+ path_data = (struct cam_ife_csid_path_cfg *)
+ csid_hw->rdi_res[i].res_priv;
+ rdi_reg = csid_reg->rdi_reg[i];
if (irq_status_rdi[i] &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
complete(&csid_hw->csid_rdin_complete[i]);
@@ -3330,6 +3546,35 @@
csid_hw->irq_debug_cnt++;
}
+ if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_SOF) &&
+ (path_data->init_frame_drop) &&
+ (csid_hw->rdi_res[i].res_state ==
+ CAM_ISP_RESOURCE_STATE_STREAMING)) {
+ csid_hw->res_sof_cnt[i]++;
+ CAM_DBG(CAM_ISP,
+ "CSID:%d RDI:%d SOF cnt:%d init_frame_drop:%d",
+ csid_hw->hw_intf->hw_idx, i,
+ csid_hw->res_sof_cnt[i],
+ path_data->init_frame_drop);
+ if (csid_hw->res_sof_cnt[i] ==
+ path_data->init_frame_drop) {
+ cam_io_w_mb(CAM_CSID_RESUME_AT_FRAME_BOUNDARY,
+ soc_info->reg_map[0].mem_base +
+ rdi_reg->csid_rdi_ctrl_addr);
+
+ if (!(csid_hw->csid_debug &
+ CSID_DEBUG_ENABLE_SOF_IRQ)) {
+ val = cam_io_r_mb(
+ soc_info->reg_map[0].mem_base +
+ rdi_reg->csid_rdi_irq_mask_addr);
+ val &= ~(CSID_PATH_INFO_INPUT_SOF);
+ cam_io_w_mb(val,
+ soc_info->reg_map[0].mem_base +
+ rdi_reg->csid_rdi_irq_mask_addr);
+ }
+ }
+ }
+
if ((irq_status_rdi[i] & CSID_PATH_INFO_INPUT_EOF) &&
(csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ))
CAM_INFO_RATE_LIMIT(CAM_ISP,
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
index 3a093d2..600deb2 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
@@ -419,6 +419,9 @@
* @master_idx: For Slave reservation, Give master IFE instance Index.
* Slave will synchronize with master Start and stop operations
* @clk_rate Clock rate
+ * @usage_type Usage type ie dual or single ife usecase
+ * @init_frame_drop init frame drop value. In dual ife case rdi need to drop one
+ * more frame than pix.
*
*/
struct cam_ife_csid_path_cfg {
@@ -437,6 +440,8 @@
enum cam_isp_hw_sync_mode sync_mode;
uint32_t master_idx;
uint64_t clk_rate;
+ uint32_t usage_type;
+ uint32_t init_frame_drop;
};
/**
@@ -468,6 +473,13 @@
* @irq_debug_cnt: Counter to track sof irq's when above flag is set.
* @error_irq_count Error IRQ count, if continuous error irq comes
* need to stop the CSID and mask interrupts.
+ * @device_enabled Device enabled will set once CSID powered on and
+ * initial configuration are done.
+ * @lock_state csid spin lock
+ * @dual_usage usage type, dual ife or single ife
+ * @init_frame_drop Initial frame drop number
+ * @res_sof_cnt path resource sof count value. it used for initial
+ * frame drop
*
*/
struct cam_ife_csid_hw {
@@ -496,6 +508,9 @@
uint32_t error_irq_count;
uint32_t device_enabled;
spinlock_t lock_state;
+ uint32_t dual_usage;
+ uint32_t init_frame_drop;
+ uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX];
};
int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
index 58818fb..0c45bd1 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
@@ -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
@@ -157,6 +157,7 @@
CAM_IFE_CSID_CMD_GET_TIME_STAMP,
CAM_IFE_CSID_SET_CSID_DEBUG,
CAM_IFE_CSID_SOF_IRQ_DEBUG,
+ CAM_IFE_CSID_SET_INIT_FRAME_DROP,
CAM_IFE_CSID_CMD_MAX,
};
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index 6154256..b230147 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -104,6 +104,7 @@
CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE,
CAM_ISP_HW_CMD_FE_UPDATE_IN_RD,
CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD,
+ CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
CAM_ISP_HW_CMD_MAX,
};
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 2bd6db9..a26c112 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -760,6 +760,7 @@
case CAM_ISP_HW_CMD_CLOCK_UPDATE:
case CAM_ISP_HW_CMD_BW_UPDATE:
case CAM_ISP_HW_CMD_BW_CONTROL:
+ case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
rc = core_info->vfe_top->hw_ops.process_cmd(
core_info->vfe_top->top_priv, cmd_type, cmd_args,
arg_size);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index c409365..4e9a975 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -421,6 +421,40 @@
return 0;
}
+static int cam_vfe_camif_irq_reg_dump(
+ struct cam_isp_resource_node *camif_res)
+{
+ struct cam_vfe_mux_camif_data *camif_priv;
+ struct cam_vfe_soc_private *soc_private;
+ int rc = 0;
+
+ if (!camif_res) {
+ CAM_ERR(CAM_ISP, "Error! Invalid input arguments\n");
+ return -EINVAL;
+ }
+
+ if ((camif_res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) ||
+ (camif_res->res_state == CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
+ CAM_ERR(CAM_ISP, "Error! Invalid state\n");
+ return 0;
+ }
+
+ camif_priv = (struct cam_vfe_mux_camif_data *)camif_res->res_priv;
+ soc_private = camif_priv->soc_info->soc_private;
+
+ CAM_INFO(CAM_ISP,
+ "Core Id =%d Mask reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
+ camif_priv->hw_intf->hw_idx,
+ 0x5c, cam_io_r_mb(camif_priv->mem_base + 0x5c),
+ 0x60, cam_io_r_mb(camif_priv->mem_base + 0x60));
+ CAM_INFO(CAM_ISP,
+ "Core Id =%d Status reg: offset 0x%x val 0x%x offset 0x%x val 0x%x",
+ camif_priv->hw_intf->hw_idx,
+ 0x6c, cam_io_r_mb(camif_priv->mem_base + 0x6c),
+ 0x70, cam_io_r_mb(camif_priv->mem_base + 0x70));
+ return rc;
+}
+
static int cam_vfe_camif_resource_stop(
struct cam_isp_resource_node *camif_res)
{
@@ -508,6 +542,9 @@
(struct cam_vfe_mux_camif_data *)rsrc_node->res_priv;
camif_priv->camif_debug = *((uint32_t *)cmd_args);
break;
+ case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+ rc = cam_vfe_camif_irq_reg_dump(rsrc_node);
+ break;
default:
CAM_ERR(CAM_ISP,
"unsupported process command:%d", cmd_type);
diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index c5acbe5..b0ac94b 100644
--- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -438,6 +438,19 @@
return -EINVAL;
}
+static int cam_vfe_get_irq_register_dump(
+ struct cam_vfe_top_ver2_priv *top_priv,
+ void *cmd_args, uint32_t arg_size)
+{
+ struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args;
+
+ if (cmd_update->res->process_cmd)
+ cmd_update->res->process_cmd(cmd_update->res,
+ CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, cmd_args, arg_size);
+
+ return 0;
+}
+
int cam_vfe_top_get_hw_caps(void *device_priv,
void *get_hw_cap_args, uint32_t arg_size)
{
@@ -723,6 +736,10 @@
case CAM_ISP_HW_CMD_BW_CONTROL:
rc = cam_vfe_top_bw_control(top_priv, cmd_args, arg_size);
break;
+ case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+ rc = cam_vfe_get_irq_register_dump(top_priv,
+ cmd_args, arg_size);
+ break;
default:
rc = -EINVAL;
CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type);
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
index f1b3cce..c8e2a02 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.c
@@ -348,10 +348,12 @@
struct cam_req_mgr_req_queue *in_q = link->req.in_q;
slot = &in_q->slot[idx];
- CAM_DBG(CAM_CRM, "RESET: idx: %d: slot->status %d", idx, slot->status);
+ CAM_DBG(CAM_CRM, "RESET: last applied idx %d: idx %d: slot->status %d",
+ in_q->last_applied_idx, idx, slot->status);
/* Check if CSL has already pushed new request*/
- if (slot->status == CRM_SLOT_STATUS_REQ_ADDED)
+ if (slot->status == CRM_SLOT_STATUS_REQ_ADDED ||
+ in_q->last_applied_idx == idx)
return;
/* Reset input queue slot */
@@ -512,9 +514,11 @@
}
if (link->req.apply_data[pd].skip_idx ||
link->req.apply_data[pd].req_id < 0) {
- CAM_DBG(CAM_CRM, "skip %d req_id %lld",
+ CAM_DBG(CAM_CRM,
+ "skip %d req_id %lld pd %d dev_name %s",
link->req.apply_data[pd].skip_idx,
- link->req.apply_data[pd].req_id);
+ link->req.apply_data[pd].req_id,
+ pd, dev->dev_info.name);
continue;
}
if (!(dev->dev_info.trigger & trigger))
@@ -893,6 +897,7 @@
int64_t req_id = 0;
int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
int32_t sync_num_slots = 0;
+ bool ready = true, sync_ready = true;
if (!link->sync_link) {
CAM_ERR(CAM_CRM, "Sync link null");
@@ -921,17 +926,7 @@
CAM_DBG(CAM_CRM,
"Skip Process Req: %lld on link: %x",
req_id, link->link_hdl);
- link->sync_link_sof_skip = true;
- return rc;
- }
-
- rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true);
- if (rc) {
- CAM_DBG(CAM_CRM,
- "Req: %lld [My link] not ready on link: %x, rc=%d",
- req_id, link->link_hdl, rc);
- link->sync_link_sof_skip = true;
- return rc;
+ ready = false;
}
sync_slot_idx = __cam_req_mgr_find_slot_for_req(
@@ -939,8 +934,7 @@
if (sync_slot_idx == -1) {
CAM_DBG(CAM_CRM, "Req: %lld not found on link: %x [other link]",
req_id, sync_link->link_hdl);
- link->sync_link_sof_skip = true;
- return -EINVAL;
+ sync_ready = false;
}
sync_rd_idx = sync_link->req.in_q->rd_idx;
@@ -956,14 +950,38 @@
return -EAGAIN;
}
+ rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true);
+ if (rc) {
+ CAM_DBG(CAM_CRM,
+ "Req: %lld [My link] not ready on link: %x, rc=%d",
+ req_id, link->link_hdl, rc);
+ ready = false;
+ }
+
rc = __cam_req_mgr_check_link_is_ready(sync_link, sync_slot_idx, true);
if (rc && (sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
"Req: %lld not ready on [other link] link: %x, rc=%d",
req_id, sync_link->link_hdl, rc);
+ sync_ready = false;
+ }
+
+ /*
+ * If both of them are ready or not ready, then just
+ * skip this sof and don't skip sync link next SOF.
+ */
+ if (sync_ready != ready) {
+ CAM_DBG(CAM_CRM,
+ "Req: %lld ready %d sync_ready %d, ignore sync link next SOF",
+ req_id, ready, sync_ready);
link->sync_link_sof_skip = true;
- return rc;
+ return -EINVAL;
+ } else if (ready == false) {
+ CAM_DBG(CAM_CRM,
+ "Req: %lld not ready on link: %x",
+ req_id, link->link_hdl);
+ return -EINVAL;
}
CAM_DBG(CAM_REQ,
@@ -995,7 +1013,7 @@
static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
uint32_t trigger)
{
- int rc = 0, idx;
+ int rc = 0, idx, last_app_idx;
int reset_step = 0;
struct cam_req_mgr_slot *slot = NULL;
struct cam_req_mgr_req_queue *in_q;
@@ -1129,6 +1147,7 @@
slot->req_id,
link->link_hdl);
idx = in_q->rd_idx;
+
reset_step = link->max_delay;
if (link->sync_link) {
if ((link->in_msync_mode) &&
@@ -1136,6 +1155,25 @@
reset_step =
link->sync_link->max_delay;
}
+
+ /* This is to handle a rare scenario of scheduling
+ * issue. If ISP sends multiple sofs due to scheduling
+ * issue, it is required to retain last applied index
+ * to help recover.
+ * In this case, ISP goes into Bubble, asking to reapply
+ * the bubbled request which has already been reset by
+ * CRM. Below code retains the last applied request.
+ */
+
+ if (slot->req_id > 0) {
+ last_app_idx = in_q->last_applied_idx;
+ in_q->last_applied_idx = idx;
+ if (abs(last_app_idx - idx) >=
+ reset_step + 1)
+ __cam_req_mgr_reset_req_slot(link,
+ last_app_idx);
+ }
+
__cam_req_mgr_dec_idx(
&idx, reset_step + 1,
in_q->num_slots);
@@ -2359,18 +2397,24 @@
*
*/
static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
- struct cam_req_mgr_link_info *link_info)
+ struct cam_req_mgr_ver_info *link_info)
{
- int rc = 0, i = 0;
+ int rc = 0, i = 0, num_devices = 0;
struct cam_req_mgr_core_dev_link_setup link_data;
struct cam_req_mgr_connected_device *dev;
struct cam_req_mgr_req_tbl *pd_tbl;
enum cam_pipeline_delay max_delay;
uint32_t subscribe_event = 0;
-
- if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES)
- return -EPERM;
-
+ if (link_info->version == VERSION_1) {
+ if (link_info->u.link_info_v1.num_devices >
+ CAM_REQ_MGR_MAX_HANDLES)
+ return -EPERM;
+ }
+ else if (link_info->version == VERSION_2) {
+ if (link_info->u.link_info_v2.num_devices >
+ CAM_REQ_MGR_MAX_HANDLES_V2)
+ return -EPERM;
+ }
mutex_init(&link->req.lock);
CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock);
link->req.num_tbl = 0;
@@ -2380,11 +2424,21 @@
return rc;
max_delay = CAM_PIPELINE_DELAY_0;
- for (i = 0; i < link_info->num_devices; i++) {
+ if (link_info->version == VERSION_1)
+ num_devices = link_info->u.link_info_v1.num_devices;
+ else if (link_info->version == VERSION_2)
+ num_devices = link_info->u.link_info_v2.num_devices;
+ for (i = 0; i < num_devices; i++) {
dev = &link->l_dev[i];
/* Using dev hdl, get ops ptr to communicate with device */
- dev->ops = (struct cam_req_mgr_kmd_ops *)
- cam_get_device_ops(link_info->dev_hdls[i]);
+ if (link_info->version == VERSION_1)
+ dev->ops = (struct cam_req_mgr_kmd_ops *)
+ cam_get_device_ops(
+ link_info->u.link_info_v1.dev_hdls[i]);
+ else if (link_info->version == VERSION_2)
+ dev->ops = (struct cam_req_mgr_kmd_ops *)
+ cam_get_device_ops(
+ link_info->u.link_info_v2.dev_hdls[i]);
if (!dev->ops ||
!dev->ops->get_dev_info ||
!dev->ops->link_setup) {
@@ -2392,18 +2446,29 @@
rc = -ENXIO;
goto error;
}
- dev->dev_hdl = link_info->dev_hdls[i];
+ if (link_info->version == VERSION_1)
+ dev->dev_hdl = link_info->u.link_info_v1.dev_hdls[i];
+ else if (link_info->version == VERSION_2)
+ dev->dev_hdl = link_info->u.link_info_v2.dev_hdls[i];
dev->parent = (void *)link;
dev->dev_info.dev_hdl = dev->dev_hdl;
rc = dev->ops->get_dev_info(&dev->dev_info);
trace_cam_req_mgr_connect_device(link, &dev->dev_info);
-
- CAM_DBG(CAM_CRM,
- "%x: connected: %s, id %d, delay %d, trigger %x",
- link_info->session_hdl, dev->dev_info.name,
- dev->dev_info.dev_id, dev->dev_info.p_delay,
- dev->dev_info.trigger);
+ if (link_info->version == VERSION_1)
+ CAM_DBG(CAM_CRM,
+ "%x: connected: %s, id %d, delay %d, trigger %x",
+ link_info->u.link_info_v1.session_hdl,
+ dev->dev_info.name,
+ dev->dev_info.dev_id, dev->dev_info.p_delay,
+ dev->dev_info.trigger);
+ else if (link_info->version == VERSION_2)
+ CAM_DBG(CAM_CRM,
+ "%x: connected: %s, id %d, delay %d, trigger %x",
+ link_info->u.link_info_v2.session_hdl,
+ dev->dev_info.name,
+ dev->dev_info.dev_id, dev->dev_info.p_delay,
+ dev->dev_info.trigger);
if (rc < 0 ||
dev->dev_info.p_delay >=
CAM_PIPELINE_DELAY_MAX ||
@@ -2412,10 +2477,18 @@
CAM_ERR(CAM_CRM, "get device info failed");
goto error;
} else {
- CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
- link_info->session_hdl,
- dev->dev_info.name,
- dev->dev_info.p_delay);
+ if (link_info->version == VERSION_1) {
+ CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
+ link_info->u.link_info_v1.session_hdl,
+ dev->dev_info.name,
+ dev->dev_info.p_delay);
+ }
+ else if (link_info->version == VERSION_2) {
+ CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d",
+ link_info->u.link_info_v2.session_hdl,
+ dev->dev_info.name,
+ dev->dev_info.p_delay);
+ }
if (dev->dev_info.p_delay > max_delay)
max_delay = dev->dev_info.p_delay;
@@ -2430,7 +2503,7 @@
link_data.max_delay = max_delay;
link_data.subscribe_event = subscribe_event;
- for (i = 0; i < link_info->num_devices; i++) {
+ for (i = 0; i < num_devices; i++) {
dev = &link->l_dev[i];
link_data.dev_hdl = dev->dev_hdl;
@@ -2473,7 +2546,7 @@
if (link->max_delay < dev->dev_info.p_delay)
link->max_delay = dev->dev_info.p_delay;
}
- link->num_devs = link_info->num_devices;
+ link->num_devs = num_devices;
/* Assign id for pd tables */
__cam_req_mgr_tbl_set_id(link->req.l_tbl, &link->req);
@@ -2631,7 +2704,7 @@
return rc;
}
-int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info)
+int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info)
{
int rc = 0;
int wq_flag = 0;
@@ -2644,9 +2717,9 @@
CAM_DBG(CAM_CRM, "NULL pointer");
return -EINVAL;
}
- if (link_info->num_devices > CAM_REQ_MGR_MAX_HANDLES) {
+ if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) {
CAM_ERR(CAM_CRM, "Invalid num devices %d",
- link_info->num_devices);
+ link_info->u.link_info_v1.num_devices);
return -EINVAL;
}
@@ -2654,7 +2727,7 @@
/* session hdl's priv data is cam session struct */
cam_session = (struct cam_req_mgr_core_session *)
- cam_get_device_priv(link_info->session_hdl);
+ cam_get_device_priv(link_info->u.link_info_v1.session_hdl);
if (!cam_session) {
CAM_DBG(CAM_CRM, "NULL pointer");
mutex_unlock(&g_crm_core_dev->crm_lock);
@@ -2671,9 +2744,9 @@
CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);
memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
- root_dev.session_hdl = link_info->session_hdl;
+ root_dev.session_hdl = link_info->u.link_info_v1.session_hdl;
root_dev.priv = (void *)link;
-
+ root_dev.dev_id = CAM_CRM;
mutex_lock(&link->lock);
/* Create unique dev handle for link */
link->link_hdl = cam_create_device_hdl(&root_dev);
@@ -2683,12 +2756,12 @@
rc = link->link_hdl;
goto link_hdl_fail;
}
- link_info->link_hdl = link->link_hdl;
+ link_info->u.link_info_v1.link_hdl = link->link_hdl;
link->last_flush_id = 0;
/* Allocate memory to hold data of all linked devs */
rc = __cam_req_mgr_create_subdevs(&link->l_dev,
- link_info->num_devices);
+ link_info->u.link_info_v1.num_devices);
if (rc < 0) {
CAM_ERR(CAM_CRM,
"Insufficient memory to create new crm subdevs");
@@ -2706,7 +2779,7 @@
/* Create worker for current link */
snprintf(buf, sizeof(buf), "%x-%x",
- link_info->session_hdl, link->link_hdl);
+ link_info->u.link_info_v1.session_hdl, link->link_hdl);
wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL;
rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
&link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
@@ -2731,7 +2804,7 @@
__cam_req_mgr_destroy_subdev(link->l_dev);
create_subdev_failed:
cam_destroy_device_hdl(link->link_hdl);
- link_info->link_hdl = -1;
+ link_info->u.link_info_v1.link_hdl = -1;
link_hdl_fail:
mutex_unlock(&link->lock);
__cam_req_mgr_unreserve_link(cam_session, link);
@@ -2739,6 +2812,116 @@
return rc;
}
+int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info)
+{
+ int rc = 0;
+ int wq_flag = 0;
+ char buf[128];
+ struct cam_create_dev_hdl root_dev;
+ struct cam_req_mgr_core_session *cam_session;
+ struct cam_req_mgr_core_link *link;
+
+ if (!link_info) {
+ CAM_DBG(CAM_CRM, "NULL pointer");
+ return -EINVAL;
+ }
+ if (link_info->u.link_info_v2.num_devices >
+ CAM_REQ_MGR_MAX_HANDLES_V2) {
+ CAM_ERR(CAM_CRM, "Invalid num devices %d",
+ link_info->u.link_info_v2.num_devices);
+ return -EINVAL;
+ }
+
+ mutex_lock(&g_crm_core_dev->crm_lock);
+
+ /* session hdl's priv data is cam session struct */
+ cam_session = (struct cam_req_mgr_core_session *)
+ cam_get_device_priv(link_info->u.link_info_v2.session_hdl);
+ if (!cam_session) {
+ CAM_DBG(CAM_CRM, "NULL pointer");
+ mutex_unlock(&g_crm_core_dev->crm_lock);
+ return -EINVAL;
+ }
+
+ /* Allocate link struct and map it with session's request queue */
+ link = __cam_req_mgr_reserve_link(cam_session);
+ if (!link) {
+ CAM_ERR(CAM_CRM, "failed to reserve new link");
+ mutex_unlock(&g_crm_core_dev->crm_lock);
+ return -EINVAL;
+ }
+ CAM_DBG(CAM_CRM, "link reserved %pK %x", link, link->link_hdl);
+
+ memset(&root_dev, 0, sizeof(struct cam_create_dev_hdl));
+ root_dev.session_hdl = link_info->u.link_info_v2.session_hdl;
+ root_dev.priv = (void *)link;
+
+ mutex_lock(&link->lock);
+ /* Create unique dev handle for link */
+ link->link_hdl = cam_create_device_hdl(&root_dev);
+ if (link->link_hdl < 0) {
+ CAM_ERR(CAM_CRM,
+ "Insufficient memory to create new device handle");
+ rc = link->link_hdl;
+ goto link_hdl_fail;
+ }
+ link_info->u.link_info_v2.link_hdl = link->link_hdl;
+ link->last_flush_id = 0;
+
+ /* Allocate memory to hold data of all linked devs */
+ rc = __cam_req_mgr_create_subdevs(&link->l_dev,
+ link_info->u.link_info_v2.num_devices);
+ if (rc < 0) {
+ CAM_ERR(CAM_CRM,
+ "Insufficient memory to create new crm subdevs");
+ goto create_subdev_failed;
+ }
+
+ /* Using device ops query connected devs, prepare request tables */
+ rc = __cam_req_mgr_setup_link_info(link, link_info);
+ if (rc < 0)
+ goto setup_failed;
+
+ spin_lock_bh(&link->link_state_spin_lock);
+ link->state = CAM_CRM_LINK_STATE_READY;
+ spin_unlock_bh(&link->link_state_spin_lock);
+
+ /* Create worker for current link */
+ snprintf(buf, sizeof(buf), "%x-%x",
+ link_info->u.link_info_v2.session_hdl, link->link_hdl);
+ wq_flag = CAM_WORKQ_FLAG_HIGH_PRIORITY | CAM_WORKQ_FLAG_SERIAL;
+ rc = cam_req_mgr_workq_create(buf, CRM_WORKQ_NUM_TASKS,
+ &link->workq, CRM_WORKQ_USAGE_NON_IRQ, wq_flag);
+ if (rc < 0) {
+ CAM_ERR(CAM_CRM, "FATAL: unable to create worker");
+ __cam_req_mgr_destroy_link_info(link);
+ goto setup_failed;
+ }
+
+ /* Assign payload to workqueue tasks */
+ rc = __cam_req_mgr_setup_payload(link->workq);
+ if (rc < 0) {
+ __cam_req_mgr_destroy_link_info(link);
+ cam_req_mgr_workq_destroy(&link->workq);
+ goto setup_failed;
+ }
+
+ mutex_unlock(&link->lock);
+ mutex_unlock(&g_crm_core_dev->crm_lock);
+ return rc;
+setup_failed:
+ __cam_req_mgr_destroy_subdev(link->l_dev);
+create_subdev_failed:
+ cam_destroy_device_hdl(link->link_hdl);
+ link_info->u.link_info_v2.link_hdl = -1;
+link_hdl_fail:
+ mutex_unlock(&link->lock);
+ __cam_req_mgr_unreserve_link(cam_session, link);
+ mutex_unlock(&g_crm_core_dev->crm_lock);
+ return rc;
+}
+
+
int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info)
{
int rc = 0;
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
index 9bff66b..05fe086 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_core.h
@@ -36,6 +36,9 @@
#define MAXIMUM_LINKS_PER_SESSION 4
+#define VERSION_1 1
+#define VERSION_2 2
+
/**
* enum crm_workq_task_type
* @codes: to identify which type of task is present
@@ -233,12 +236,14 @@
* @slot : request slot holding incoming request id and bubble info.
* @rd_idx : indicates slot index currently in process.
* @wr_idx : indicates slot index to hold new upcoming req.
+ * @last_applied_idx : indicates slot index last applied successfully.
*/
struct cam_req_mgr_req_queue {
int32_t num_slots;
struct cam_req_mgr_slot slot[MAX_REQ_SLOTS];
int32_t rd_idx;
int32_t wr_idx;
+ int32_t last_applied_idx;
};
/**
@@ -411,7 +416,9 @@
* a unique link handle for the link and is specific to a
* session. Returns link handle
*/
-int cam_req_mgr_link(struct cam_req_mgr_link_info *link_info);
+int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info);
+int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info);
+
/**
* cam_req_mgr_unlink()
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c
index 5cf1d84..31607ac 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_dev.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-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
@@ -268,27 +268,50 @@
break;
case CAM_REQ_MGR_LINK: {
- struct cam_req_mgr_link_info link_info;
+ struct cam_req_mgr_ver_info ver_info;
- if (k_ioctl->size != sizeof(link_info))
+ if (k_ioctl->size != sizeof(ver_info.u.link_info_v1))
return -EINVAL;
- if (copy_from_user(&link_info,
+ if (copy_from_user(&ver_info.u.link_info_v1,
u64_to_user_ptr(k_ioctl->handle),
sizeof(struct cam_req_mgr_link_info))) {
return -EFAULT;
}
-
- rc = cam_req_mgr_link(&link_info);
+ ver_info.version = VERSION_1;
+ rc = cam_req_mgr_link(&ver_info);
if (!rc)
if (copy_to_user(
u64_to_user_ptr(k_ioctl->handle),
- &link_info,
+ &ver_info.u.link_info_v1,
sizeof(struct cam_req_mgr_link_info)))
rc = -EFAULT;
}
break;
+ case CAM_REQ_MGR_LINK_V2: {
+ struct cam_req_mgr_ver_info ver_info;
+
+ if (k_ioctl->size != sizeof(ver_info.u.link_info_v2))
+ return -EINVAL;
+
+ if (copy_from_user(&ver_info.u.link_info_v2,
+ u64_to_user_ptr(k_ioctl->handle),
+ sizeof(struct cam_req_mgr_link_info_v2))) {
+ return -EFAULT;
+ }
+ ver_info.version = VERSION_2;
+ rc = cam_req_mgr_link_v2(&ver_info);
+ if (!rc)
+ if (copy_to_user(
+ u64_to_user_ptr(k_ioctl->handle),
+ &ver_info.u.link_info_v2,
+ sizeof(struct
+ cam_req_mgr_link_info_v2)))
+ rc = -EFAULT;
+ }
+ break;
+
case CAM_REQ_MGR_UNLINK: {
struct cam_req_mgr_unlink_info unlink_info;
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c
index dda04f8..d531fdc 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.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
@@ -128,6 +128,21 @@
return idx;
}
+void cam_dump_tbl_info(void)
+{
+ int i;
+
+ for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES; i++)
+ CAM_INFO(CAM_CRM, "session_hdl=%x hdl_value=%x\n"
+ "type=%d state=%d dev_id=%lld",
+ hdl_tbl->hdl[i].session_hdl,
+ hdl_tbl->hdl[i].hdl_value,
+ hdl_tbl->hdl[i].type,
+ hdl_tbl->hdl[i].state,
+ hdl_tbl->hdl[i].dev_id);
+
+}
+
int32_t cam_create_session_hdl(void *priv)
{
int idx;
@@ -144,6 +159,7 @@
idx = cam_get_free_handle_index();
if (idx < 0) {
CAM_ERR(CAM_CRM, "Unable to create session handle");
+ cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock);
return idx;
}
@@ -177,6 +193,7 @@
idx = cam_get_free_handle_index();
if (idx < 0) {
CAM_ERR(CAM_CRM, "Unable to create device handle");
+ cam_dump_tbl_info();
spin_unlock_bh(&hdl_tbl_lock);
return idx;
}
@@ -189,6 +206,7 @@
hdl_tbl->hdl[idx].state = HDL_ACTIVE;
hdl_tbl->hdl[idx].priv = hdl_data->priv;
hdl_tbl->hdl[idx].ops = hdl_data->ops;
+ hdl_tbl->hdl[idx].dev_id = hdl_data->dev_id;
spin_unlock_bh(&hdl_tbl_lock);
pr_debug("%s: handle = %x", __func__, handle);
diff --git a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h
index 7b8e3e6..50d6f30 100644
--- a/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h
+++ b/drivers/media/platform/msm/camera_v3/cam_req_mgr/cam_req_mgr_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-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
@@ -50,6 +50,7 @@
uint32_t hdl_value;
enum hdl_type type;
enum hdl_state state;
+ uint64_t dev_id;
void *ops;
void *priv;
};
@@ -80,6 +81,7 @@
int32_t v4l2_sub_dev_flag;
int32_t media_entity_flag;
int32_t reserved;
+ uint64_t dev_id;
void *ops;
void *priv;
};
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c
index 1262db7..3837aac 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_actuator/cam_actuator_core.c
@@ -786,7 +786,7 @@
bridge_params.v4l2_sub_dev_flag = 0;
bridge_params.media_entity_flag = 0;
bridge_params.priv = a_ctrl;
-
+ bridge_params.dev_id = CAM_ACTUATOR;
actuator_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c
index f41cb475..a06a4c6 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_core.c
@@ -1094,7 +1094,7 @@
* RD_DONE exclusively.
*/
rem_jiffies = wait_for_completion_timeout(
- &cci_dev->cci_master_info[master].reset_complete,
+ &cci_dev->cci_master_info[master].rd_done,
CCI_TIMEOUT);
if (!rem_jiffies) {
rc = -ETIMEDOUT;
@@ -1275,10 +1275,11 @@
val = 1 << ((master * 2) + queue);
cam_io_w_mb(val, base + CCI_QUEUE_START_ADDR);
CAM_DBG(CAM_CCI,
- "waiting_for_rd_done [exp_words: %d]", exp_words);
+ "waiting_for_rd_done [exp_words: %d]",
+ ((read_cfg->num_byte / 4) + 1));
rc = wait_for_completion_timeout(
- &cci_dev->cci_master_info[master].reset_complete, CCI_TIMEOUT);
+ &cci_dev->cci_master_info[master].rd_done, CCI_TIMEOUT);
if (rc <= 0) {
#ifdef DUMP_CCI_REGISTERS
cam_cci_dump_registers(cci_dev, master, queue);
@@ -1692,14 +1693,19 @@
struct cam_cci_ctrl *cci_ctrl)
{
int32_t rc = 0;
-
+ struct cci_device *cci_dev = v4l2_get_subdevdata(sd);
CAM_DBG(CAM_CCI, "cmd %d", cci_ctrl->cmd);
+
switch (cci_ctrl->cmd) {
case MSM_CCI_INIT:
+ mutex_lock(&cci_dev->init_mutex);
rc = cam_cci_init(sd, cci_ctrl);
+ mutex_unlock(&cci_dev->init_mutex);
break;
case MSM_CCI_RELEASE:
+ mutex_lock(&cci_dev->init_mutex);
rc = cam_cci_release(sd);
+ mutex_unlock(&cci_dev->init_mutex);
break;
case MSM_CCI_I2C_READ:
rc = cam_cci_read_bytes(sd, cci_ctrl);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c
index 7934aa5..69b5af0 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.c
@@ -71,20 +71,26 @@
irq_status0 = cam_io_r_mb(base + CCI_IRQ_STATUS_0_ADDR);
irq_status1 = cam_io_r_mb(base + CCI_IRQ_STATUS_1_ADDR);
+ CAM_DBG(CAM_CCI, "BASE: %pK", base);
CAM_DBG(CAM_CCI, "irq0:%x irq1:%x", irq_status0, irq_status1);
if (irq_status0 & CCI_IRQ_STATUS_0_RST_DONE_ACK_BMSK) {
+ struct cam_cci_master_info *cci_master_info;
if (cci_dev->cci_master_info[MASTER_0].reset_pending == TRUE) {
+ cci_master_info = &cci_dev->cci_master_info[MASTER_0];
cci_dev->cci_master_info[MASTER_0].reset_pending =
FALSE;
- complete(
- &cci_dev->cci_master_info[MASTER_0].reset_complete);
+ if (!cci_master_info->status)
+ complete(&cci_master_info->reset_complete);
+ cci_master_info->status = 0;
}
if (cci_dev->cci_master_info[MASTER_1].reset_pending == TRUE) {
+ cci_master_info = &cci_dev->cci_master_info[MASTER_1];
cci_dev->cci_master_info[MASTER_1].reset_pending =
FALSE;
- complete(
- &cci_dev->cci_master_info[MASTER_1].reset_complete);
+ if (!cci_master_info->status)
+ complete(&cci_master_info->reset_complete);
+ cci_master_info->status = 0;
}
}
@@ -93,7 +99,7 @@
cci_dev->cci_master_info[MASTER_0].status = 0;
rd_done_th_assert = true;
complete(&cci_dev->cci_master_info[MASTER_0].th_complete);
- complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+ complete(&cci_dev->cci_master_info[MASTER_0].rd_done);
}
if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK) &&
(!rd_done_th_assert)) {
@@ -102,7 +108,7 @@
if (cci_dev->is_burst_read)
complete(
&cci_dev->cci_master_info[MASTER_0].th_complete);
- complete(&cci_dev->cci_master_info[MASTER_0].reset_complete);
+ complete(&cci_dev->cci_master_info[MASTER_0].rd_done);
}
if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD) &&
(!rd_done_th_assert)) {
@@ -149,7 +155,7 @@
cci_dev->cci_master_info[MASTER_1].status = 0;
rd_done_th_assert = true;
complete(&cci_dev->cci_master_info[MASTER_1].th_complete);
- complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+ complete(&cci_dev->cci_master_info[MASTER_1].rd_done);
}
if ((irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE_BMSK) &&
(!rd_done_th_assert)) {
@@ -158,7 +164,7 @@
if (cci_dev->is_burst_read)
complete(
&cci_dev->cci_master_info[MASTER_1].th_complete);
- complete(&cci_dev->cci_master_info[MASTER_1].reset_complete);
+ complete(&cci_dev->cci_master_info[MASTER_1].rd_done);
}
if ((irq_status1 & CCI_IRQ_STATUS_1_I2C_M1_RD_THRESHOLD) &&
(!rd_done_th_assert)) {
@@ -217,16 +223,33 @@
}
if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK) {
cci_dev->cci_master_info[MASTER_0].status = -EINVAL;
- cam_io_w_mb(CCI_M0_HALT_REQ_RMSK,
- base + CCI_HALT_REQ_ADDR);
- CAM_DBG(CAM_CCI, "MASTER_0 error 0x%x", irq_status0);
+ if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK)
+ CAM_ERR(CAM_CCI, "Base:%pK, M0 NACK ERROR: 0x%x",
+ base, irq_status0);
+ if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK)
+ CAM_ERR(CAM_CCI,
+ "Base:%pK, M0 QUEUE_OVER/UNDER_FLOW OR CMD ERR: 0x%x",
+ base, irq_status0);
+ if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK)
+ CAM_ERR(CAM_CCI,
+ "Base: %pK, M0 RD_OVER/UNDER_FLOW ERROR: 0x%x",
+ base, irq_status0);
+ cam_io_w_mb(CCI_M0_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR);
}
if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK) {
cci_dev->cci_master_info[MASTER_1].status = -EINVAL;
- cam_io_w_mb(CCI_M1_HALT_REQ_RMSK,
- base + CCI_HALT_REQ_ADDR);
- CAM_DBG(CAM_CCI, "MASTER_1 error 0x%x", irq_status0);
-
+ if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK)
+ CAM_ERR(CAM_CCI, "Base:%pK, M1 NACK ERROR: 0x%x",
+ base, irq_status0);
+ if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK)
+ CAM_ERR(CAM_CCI,
+ "Base:%pK, M1 QUEUE_OVER_UNDER_FLOW OR CMD ERROR:0x%x",
+ base, irq_status0);
+ if (irq_status0 & CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK)
+ CAM_ERR(CAM_CCI,
+ "Base:%pK, M1 RD_OVER/UNDER_FLOW ERROR: 0x%x",
+ base, irq_status0);
+ cam_io_w_mb(CCI_M1_HALT_REQ_RMSK, base + CCI_HALT_REQ_ADDR);
}
cam_io_w_mb(irq_status0, base + CCI_IRQ_CLEAR_0_ADDR);
@@ -402,7 +425,8 @@
}
g_cci_subdev[soc_info->index] = &new_cci_dev->v4l2_dev_str.sd;
- CAM_ERR(CAM_CCI, "Device Type :%d", soc_info->index);
+ mutex_init(&(new_cci_dev->init_mutex));
+ CAM_INFO(CAM_CCI, "Device Type :%d", soc_info->index);
cam_register_subdev_fops(&cci_v4l2_subdev_fops);
cci_v4l2_subdev_fops.unlocked_ioctl = cam_cci_subdev_fops_ioctl;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h
index 349effc..54eed83 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_dev.h
@@ -140,6 +140,7 @@
uint8_t reset_pending;
struct mutex mutex;
struct completion reset_complete;
+ struct completion rd_done;
struct completion th_complete;
struct mutex mutex_q[NUM_QUEUES];
struct completion report_q[NUM_QUEUES];
@@ -171,41 +172,41 @@
};
/**
- * struct cci_device
- * @pdev: Platform device
- * @subdev: V4L2 sub device
- * @base: Base address of CCI device
- * @hw_version: Hardware version
- * @ref_count: Reference Count
- * @cci_state: CCI state machine
- * @num_clk: Number of CCI clock
- * @cci_clk: CCI clock structure
- * @cci_clk_info: CCI clock information
- * @cam_cci_i2c_queue_info: CCI queue information
- * @i2c_freq_mode: I2C frequency of operations
- * @cci_clk_params: CCI hw clk params
- * @cci_gpio_tbl: CCI GPIO table
- * @cci_gpio_tbl_size: GPIO table size
- * @cci_pinctrl: Pinctrl structure
- * @cci_pinctrl_status: CCI pinctrl status
- * @cci_clk_src: CCI clk src rate
- * @cci_vreg: CCI regulator structure
- * @cci_reg_ptr: CCI individual regulator structure
- * @regulator_count: Regulator count
- * @support_seq_write:
- * Set this flag when sequential write is enabled
- * @write_wq: Work queue structure
- * @valid_sync: Is it a valid sync with CSID
- * @v4l2_dev_str: V4L2 device structure
- * @cci_wait_sync_cfg: CCI sync config
- * @cycles_per_us: Cycles per micro sec
- * @payload_size: CCI packet payload size
- * @irq_status1: Store irq_status1 to be cleared after
- * draining FIFO buffer for burst read
- * @lock_status: to protect changes to irq_status1
- * @is_burst_read: Flag to determine if we are performing
- * a burst read operation or not
- * @irqs_disabled: Mask for IRQs that are disabled
+ * @pdev: Platform device
+ * @subdev: V4L2 sub device
+ * @base: Base address of CCI device
+ * @hw_version: Hardware version
+ * @ref_count: Reference Count
+ * @cci_state: CCI state machine
+ * @num_clk: Number of CCI clock
+ * @cci_clk: CCI clock structure
+ * @cci_clk_info: CCI clock information
+ * @cam_cci_i2c_queue_info: CCI queue information
+ * @i2c_freq_mode: I2C frequency of operations
+ * @cci_clk_params: CCI hw clk params
+ * @cci_gpio_tbl: CCI GPIO table
+ * @cci_gpio_tbl_size: GPIO table size
+ * @cci_pinctrl: Pinctrl structure
+ * @cci_pinctrl_status: CCI pinctrl status
+ * @cci_clk_src: CCI clk src rate
+ * @cci_vreg: CCI regulator structure
+ * @cci_reg_ptr: CCI individual regulator structure
+ * @regulator_count: Regulator count
+ * @support_seq_write: Set this flag when sequential write is enabled
+ * @write_wq: Work queue structure
+ * @valid_sync: Is it a valid sync with CSID
+ * @v4l2_dev_str: V4L2 device structure
+ * @cci_wait_sync_cfg: CCI sync config
+ * @cycles_per_us: Cycles per micro sec
+ * @payload_size: CCI packet payload size
+ * @irq_status1: Store irq_status1 to be cleared after
+ * draining FIFO buffer for burst read
+ * @lock_status: to protect changes to irq_status1
+ * @is_burst_read: Flag to determine if we are performing
+ * a burst read operation or not
+ * @irqs_disabled: Mask for IRQs that are disabled
+ * @init_mutex: Mutex for maintaining refcount for attached
+ * devices to cci during init/deinit.
*/
struct cci_device {
struct v4l2_subdev subdev;
@@ -234,6 +235,7 @@
spinlock_t lock_status;
bool is_burst_read;
uint32_t irqs_disabled;
+ struct mutex init_mutex;
};
enum cam_cci_i2c_cmd_type {
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h
index 027a050..ead18af 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_hwreg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, 2017-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015, 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
@@ -61,6 +61,12 @@
#define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT_BMSK 0x10
#define CCI_IRQ_STATUS_0_I2C_M0_ERROR_BMSK 0x18000EE6
#define CCI_IRQ_STATUS_0_I2C_M1_ERROR_BMSK 0x60EE6000
+#define CCI_IRQ_STATUS_0_I2C_M0_NACK_ERROR_BMSK 0x18000000
+#define CCI_IRQ_STATUS_0_I2C_M1_NACK_ERROR_BMSK 0x60000000
+#define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_ERROR_BMSK 0xEE0
+#define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_ERROR_BMSK 0xEE0000
+#define CCI_IRQ_STATUS_0_I2C_M0_RD_ERROR_BMSK 0x6
+#define CCI_IRQ_STATUS_0_I2C_M1_RD_ERROR_BMSK 0x6000
#define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE_BMSK 0x1
#define CCI_IRQ_STATUS_1_I2C_M0_RD_THRESHOLD 0x10000
#define CCI_IRQ_STATUS_1_I2C_M0_RD_PAUSE 0x20000
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
index fa290c0..0181a4d 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_cci/cam_cci_soc.c
@@ -19,7 +19,7 @@
uint8_t i = 0, j = 0;
int32_t rc = 0;
struct cci_device *cci_dev;
- enum cci_i2c_master_t master = MASTER_0;
+ enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote;
struct cam_hw_soc_info *soc_info = NULL;
@@ -47,7 +47,6 @@
if (cci_dev->ref_count++) {
CAM_DBG(CAM_CCI, "ref_count %d", cci_dev->ref_count);
- master = c_ctrl->cci_info->cci_i2c_master;
CAM_DBG(CAM_CCI, "master %d", master);
if (master < MASTER_MAX && master >= 0) {
mutex_lock(&cci_dev->cci_master_info[master].mutex);
@@ -55,6 +54,8 @@
/* Re-initialize the completion */
reinit_completion(
&cci_dev->cci_master_info[master].reset_complete);
+ reinit_completion(
+ &cci_dev->cci_master_info[master].rd_done);
for (i = 0; i < NUM_QUEUES; i++)
reinit_completion(
&cci_dev->cci_master_info[master].report_q[i]);
@@ -93,6 +94,7 @@
/* Re-initialize the completion */
reinit_completion(&cci_dev->cci_master_info[master].reset_complete);
+ reinit_completion(&cci_dev->cci_master_info[master].rd_done);
for (i = 0; i < NUM_QUEUES; i++)
reinit_completion(
&cci_dev->cci_master_info[master].report_q[i]);
@@ -128,12 +130,12 @@
}
}
- cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
+ cci_dev->cci_master_info[master].reset_pending = TRUE;
cam_io_w_mb(CCI_RESET_CMD_RMSK, base +
CCI_RESET_CMD_ADDR);
cam_io_w_mb(0x1, base + CCI_RESET_CMD_ADDR);
rc = wait_for_completion_timeout(
- &cci_dev->cci_master_info[MASTER_0].reset_complete,
+ &cci_dev->cci_master_info[master].reset_complete,
CCI_TIMEOUT);
if (rc <= 0) {
CAM_ERR(CAM_CCI, "wait_for_completion_timeout");
@@ -205,6 +207,8 @@
&new_cci_dev->cci_master_info[i].reset_complete);
init_completion(
&new_cci_dev->cci_master_info[i].th_complete);
+ init_completion(
+ &new_cci_dev->cci_master_info[i].rd_done);
for (j = 0; j < NUM_QUEUES; j++) {
mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 318ea55..8074ecd 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -725,7 +725,7 @@
bridge_params.v4l2_sub_dev_flag = 0;
bridge_params.media_entity_flag = 0;
bridge_params.priv = csiphy_dev;
-
+ bridge_params.dev_id = CAM_CSIPHY;
if (csiphy_acq_params.combo_mode >= 2) {
CAM_ERR(CAM_CSIPHY, "Invalid combo_mode %d",
csiphy_acq_params.combo_mode);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
index 67653e8..edde070 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
@@ -21,7 +21,7 @@
.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
.csiphy_common_array_size = 6,
.csiphy_reset_array_size = 5,
- .csiphy_2ph_config_array_size = 21,
+ .csiphy_2ph_config_array_size = 22,
.csiphy_3ph_config_array_size = 38,
.csiphy_2ph_clock_lane = 0x1,
.csiphy_2ph_combo_ck_ln = 0x10,
@@ -78,10 +78,11 @@
{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -105,6 +106,7 @@
{0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -128,6 +130,7 @@
{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -151,6 +154,7 @@
{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -174,6 +178,7 @@
{0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
},
};
@@ -197,10 +202,11 @@
{0x0000, 0x91, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0008, 0x04, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x0008, 0x10, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
},
{
{0x0730, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -224,6 +230,7 @@
{0x070c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
},
{
{0x0230, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -247,6 +254,7 @@
{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
},
{
{0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -270,6 +278,7 @@
{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
},
{
{0x0630, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -293,6 +302,7 @@
{0x060c, 0xFF, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
},
};
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
index a04d971..8f59ca3 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
@@ -357,7 +357,7 @@
bridge_params.v4l2_sub_dev_flag = 0;
bridge_params.media_entity_flag = 0;
bridge_params.priv = e_ctrl;
-
+ bridge_params.dev_id = CAM_EEPROM;
eeprom_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h
index 7ffafc3..9c36134 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h
@@ -35,7 +35,7 @@
#define PROPERTY_MAXSIZE 32
#define MSM_EEPROM_MEMORY_MAP_MAX_SIZE 80
-#define MSM_EEPROM_MAX_MEM_MAP_CNT 8
+#define MSM_EEPROM_MAX_MEM_MAP_CNT 16
#define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT 8
enum cam_eeprom_state {
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c
index 1a0edb8..f4c9d25 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_flash/cam_flash_dev.c
@@ -71,7 +71,7 @@
bridge_params.v4l2_sub_dev_flag = 0;
bridge_params.media_entity_flag = 0;
bridge_params.priv = fctrl;
-
+ bridge_params.dev_id = CAM_FLASH;
flash_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
fctrl->bridge_intf.device_hdl =
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c
index a5c7039..711077c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_ois/cam_ois_core.c
@@ -90,7 +90,7 @@
bridge_params.v4l2_sub_dev_flag = 0;
bridge_params.media_entity_flag = 0;
bridge_params.priv = o_ctrl;
-
+ bridge_params.dev_id = CAM_OIS;
ois_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 111f121..a2a738d 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -776,7 +776,7 @@
bridge_params.v4l2_sub_dev_flag = 0;
bridge_params.media_entity_flag = 0;
bridge_params.priv = s_ctrl;
-
+ bridge_params.dev_id = CAM_SENSOR;
sensor_acq_dev.device_handle =
cam_create_device_hdl(&bridge_params);
s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle;
diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
index d3f62d6..d4487ef 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
+++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c
@@ -29,6 +29,20 @@
*/
static bool trigger_cb_without_switch;
+void cam_sync_print_fence_table(void)
+{
+ int cnt;
+
+ for (cnt = 0; cnt < CAM_SYNC_MAX_OBJS; cnt++) {
+ CAM_INFO(CAM_SYNC, "%d, %s, %d, %d, %d",
+ sync_dev->sync_table[cnt].sync_id,
+ sync_dev->sync_table[cnt].name,
+ sync_dev->sync_table[cnt].type,
+ sync_dev->sync_table[cnt].state,
+ atomic_read(&sync_dev->sync_table[cnt].ref_cnt));
+ }
+}
+
int cam_sync_create(int32_t *sync_obj, const char *name)
{
int rc;
@@ -37,8 +51,15 @@
do {
idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
- if (idx >= CAM_SYNC_MAX_OBJS)
+ if (idx >= CAM_SYNC_MAX_OBJS) {
+ CAM_ERR(CAM_SYNC,
+ "Error: Unable to Create Sync Idx = %ld Reached Max!!",
+ idx);
+ sync_dev->err_cnt++;
+ if (sync_dev->err_cnt == 1)
+ cam_sync_print_fence_table();
return -ENOMEM;
+ }
CAM_DBG(CAM_SYNC, "Index location available at idx: %ld", idx);
bit = test_and_set_bit(idx, sync_dev->bitmap);
} while (bit);
@@ -765,6 +786,7 @@
CAM_ERR(CAM_SYNC, "Sync device NULL");
return -ENODEV;
}
+ sync_dev->err_cnt = 0;
mutex_lock(&sync_dev->table_lock);
if (sync_dev->open_cnt >= 1) {
@@ -797,6 +819,7 @@
rc = -ENODEV;
return rc;
}
+ sync_dev->err_cnt = 0;
mutex_lock(&sync_dev->table_lock);
sync_dev->open_cnt--;
if (!sync_dev->open_cnt) {
@@ -972,6 +995,7 @@
if (!sync_dev)
return -ENOMEM;
+ sync_dev->err_cnt = 0;
mutex_init(&sync_dev->table_lock);
spin_lock_init(&sync_dev->cam_sync_eventq_lock);
diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h
index eb2fb34..c3cb345 100644
--- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h
+++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_private.h
@@ -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
@@ -184,6 +184,7 @@
* @work_queue : Work queue used for dispatching kernel callbacks
* @cam_sync_eventq : Event queue used to dispatch user payloads to user space
* @bitmap : Bitmap representation of all sync objects
+ * @err_cnt : Error counter to dump fence table
*/
struct sync_device {
struct video_device *vdev;
@@ -197,6 +198,7 @@
struct v4l2_fh *cam_sync_eventq;
spinlock_t cam_sync_eventq_lock;
DECLARE_BITMAP(bitmap, CAM_SYNC_MAX_OBJS);
+ int err_cnt;
};
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
index f3af619..36e6e1c 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.c
@@ -77,7 +77,7 @@
static char debugfs_dir_name[64];
static int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info,
- int32_t src_clk_idx, int32_t clk_rate)
+ int32_t src_clk_idx, int64_t clk_rate)
{
int i;
long clk_rate_round;
@@ -92,7 +92,7 @@
for (i = 0; i < CAM_MAX_VOTE; i++) {
if (soc_info->clk_rate[i][src_clk_idx] >= clk_rate_round) {
CAM_DBG(CAM_UTIL,
- "soc = %d round rate = %ld actual = %d",
+ "soc = %d round rate = %ld actual = %lld",
soc_info->clk_rate[i][src_clk_idx],
clk_rate_round, clk_rate);
return i;
@@ -441,7 +441,7 @@
* @return: Success or failure
*/
static int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name,
- int32_t clk_rate)
+ int64_t clk_rate)
{
int rc = 0;
long clk_rate_round;
@@ -449,7 +449,7 @@
if (!clk || !clk_name)
return -EINVAL;
- CAM_DBG(CAM_UTIL, "set %s, rate %d", clk_name, clk_rate);
+ CAM_DBG(CAM_UTIL, "set %s, rate %lld", clk_name, clk_rate);
if (clk_rate > 0) {
clk_rate_round = clk_round_rate(clk, clk_rate);
CAM_DBG(CAM_UTIL, "new_rate %ld", clk_rate_round);
@@ -485,7 +485,7 @@
}
int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info,
- int32_t clk_rate)
+ int64_t clk_rate)
{
int32_t src_clk_idx;
struct clk *clk = NULL;
@@ -506,7 +506,7 @@
if (soc_info->cam_cx_ipeak_enable && clk_rate >= 0) {
apply_level = cam_soc_util_get_clk_level(soc_info, src_clk_idx,
clk_rate);
- CAM_DBG(CAM_UTIL, "set %s, rate %d dev_name = %s\n"
+ CAM_DBG(CAM_UTIL, "set %s, rate %lld dev_name = %s\n"
"apply level = %d",
soc_info->clk_name[src_clk_idx], clk_rate,
soc_info->dev_name, apply_level);
diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h
index ee07f0e..859fee7 100644
--- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h
+++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_soc_util.h
@@ -397,7 +397,7 @@
* @return: success or failure
*/
int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info,
- int32_t clk_rate);
+ int64_t clk_rate);
/**
* cam_soc_util_get_option_clk_by_name()
diff --git a/include/uapi/media/cam_cpas.h b/include/uapi/media/cam_cpas.h
index c5cbac8..371b74c 100644
--- a/include/uapi/media/cam_cpas.h
+++ b/include/uapi/media/cam_cpas.h
@@ -6,6 +6,40 @@
#define CAM_FAMILY_CAMERA_SS 1
#define CAM_FAMILY_CPAS_SS 2
+/* AXI BW Voting Version */
+#define CAM_AXI_BW_VOTING_V2 2
+
+/* AXI BW Voting Transaction Type */
+#define CAM_AXI_TRANSACTION_READ 0
+#define CAM_AXI_TRANSACTION_WRITE 1
+
+/* AXI BW Voting Path Data Type */
+#define CAM_AXI_PATH_DATA_IFE_START_OFFSET 0
+#define CAM_AXI_PATH_DATA_IFE_LINEAR (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 0)
+#define CAM_AXI_PATH_DATA_IFE_VID (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 1)
+#define CAM_AXI_PATH_DATA_IFE_DISP (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 2)
+#define CAM_AXI_PATH_DATA_IFE_STATS (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 3)
+#define CAM_AXI_PATH_DATA_IFE_RDI0 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 4)
+#define CAM_AXI_PATH_DATA_IFE_RDI1 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 5)
+#define CAM_AXI_PATH_DATA_IFE_RDI2 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 6)
+#define CAM_AXI_PATH_DATA_IFE_RDI3 (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 7)
+#define CAM_AXI_PATH_DATA_IFE_PDAF (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 8)
+#define CAM_AXI_PATH_DATA_IFE_PIXEL_RAW \
+ (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 9)
+#define CAM_AXI_PATH_DATA_IFE_MAX_OFFSET \
+ (CAM_AXI_PATH_DATA_IFE_START_OFFSET + 31)
+
+#define CAM_AXI_PATH_DATA_IPE_START_OFFSET 32
+#define CAM_AXI_PATH_DATA_IPE_RD_IN (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 0)
+#define CAM_AXI_PATH_DATA_IPE_RD_REF (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 1)
+#define CAM_AXI_PATH_DATA_IPE_WR_VID (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 2)
+#define CAM_AXI_PATH_DATA_IPE_WR_DISP (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 3)
+#define CAM_AXI_PATH_DATA_IPE_WR_REF (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 4)
+#define CAM_AXI_PATH_DATA_IPE_MAX_OFFSET \
+ (CAM_AXI_PATH_DATA_IPE_START_OFFSET + 31)
+
+#define CAM_AXI_PATH_DATA_ALL 256
+
/**
* struct cam_cpas_query_cap - CPAS query device capability payload
*
@@ -22,4 +56,29 @@
struct cam_hw_version cpas_version;
};
+/**
+ * struct cam_axi_per_path_bw_vote - Per path bandwidth vote information
+ *
+ * @usage_data client usage data (left/right/rdi)
+ * @transac_type Transaction type on the path (read/write)
+ * @path_data_type Path for which vote is given (video, display, rdi)
+ * @reserved Reserved for alignment
+ * @camnoc_bw CAMNOC bw for this path
+ * @mnoc_ab_bw MNOC AB bw for this path
+ * @mnoc_ib_bw MNOC IB bw for this path
+ * @ddr_ab_bw DDR AB bw for this path
+ * @ddr_ib_bw DDR IB bw for this path
+ */
+struct cam_axi_per_path_bw_vote {
+ uint32_t usage_data;
+ uint32_t transac_type;
+ uint32_t path_data_type;
+ uint32_t reserved;
+ uint64_t camnoc_bw;
+ uint64_t mnoc_ab_bw;
+ uint64_t mnoc_ib_bw;
+ uint64_t ddr_ab_bw;
+ uint64_t ddr_ib_bw;
+};
+
#endif /* __UAPI_CAM_CPAS_H__ */
diff --git a/include/uapi/media/cam_icp.h b/include/uapi/media/cam_icp.h
index f2c1c91..5b4a604 100644
--- a/include/uapi/media/cam_icp.h
+++ b/include/uapi/media/cam_icp.h
@@ -2,6 +2,7 @@
#define __UAPI_CAM_ICP_H__
#include "cam_defs.h"
+#include "cam_cpas.h"
/* icp, ipe, bps, cdm(ipe/bps) are used in querycap */
#define CAM_ICP_DEV_TYPE_A5 1
@@ -66,6 +67,26 @@
#define CAM_ICP_CMD_GENERIC_BLOB_CFG_IO 0x2
#define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_MAP 0x3
#define CAM_ICP_CMD_GENERIC_BLOB_FW_MEM_UNMAP 0x4
+#define CAM_ICP_CMD_GENERIC_BLOB_CLK_V2 0x5
+
+/**
+ * struct cam_icp_clk_bw_request_v2
+ *
+ * @budget_ns: Time required to process frame
+ * @frame_cycles: Frame cycles needed to process the frame
+ * @rt_flag: Flag to indicate real time stream
+ * @reserved: For memory alignment
+ * @num_paths: Number of axi paths in bw request
+ * @axi_path: Per path vote info for IPE/BPS
+ */
+struct cam_icp_clk_bw_request_v2 {
+ uint64_t budget_ns;
+ uint32_t frame_cycles;
+ uint32_t rt_flag;
+ uint32_t reserved;
+ uint32_t num_paths;
+ struct cam_axi_per_path_bw_vote axi_path[1];
+};
/**
* struct cam_icp_clk_bw_request
diff --git a/include/uapi/media/cam_isp.h b/include/uapi/media/cam_isp.h
index 995d6ec..7489b72 100644
--- a/include/uapi/media/cam_isp.h
+++ b/include/uapi/media/cam_isp.h
@@ -4,7 +4,7 @@
#include "cam_defs.h"
#include "cam_isp_vfe.h"
#include "cam_isp_ife.h"
-
+#include "cam_cpas.h"
/* ISP driver name */
#define CAM_ISP_DEV_NAME "cam-isp"
@@ -91,6 +91,13 @@
#define CAM_ISP_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG 4
#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5
#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 6
+#define CAM_ISP_GENERIC_BLOB_TYPE_INIT_FRAME_DROP 10
+
+/* Per Path Usage Data */
+#define CAM_ISP_USAGE_INVALID 0
+#define CAM_ISP_USAGE_LEFT_PX 1
+#define CAM_ISP_USAGE_RIGHT_PX 2
+#define CAM_ISP_USAGE_RDI 3
/* Query devices */
/**
@@ -362,7 +369,6 @@
* @cam_bw_bps: Bandwidth vote for CAMNOC
* @ext_bw_bps: Bandwidth vote for path-to-DDR after CAMNOC
*/
-
struct cam_isp_bw_vote {
uint32_t resource_id;
uint32_t reserved;
@@ -379,7 +385,6 @@
* @right_pix_vote: Bandwidth vote for right ISP
* @rdi_vote: RDI bandwidth requirements
*/
-
struct cam_isp_bw_config {
uint32_t usage_type;
uint32_t num_rdi;
@@ -408,6 +413,19 @@
} __attribute__((packed));
/**
+ * struct cam_isp_bw_config_v2 - Bandwidth configuration
+ *
+ * @usage_type: Usage type (Single/Dual)
+ * @num_paths: Number of axi data paths
+ * @axi_path Per path vote info
+ */
+struct cam_isp_bw_config_v2 {
+ uint32_t usage_type;
+ uint32_t num_paths;
+ struct cam_axi_per_path_bw_vote axi_path[1];
+} __attribute__((packed));
+
+/**
* struct cam_fe_config - Fetch Engine configuration
*
* @version: fetch engine veriosn
@@ -479,4 +497,14 @@
#define CAM_ISP_ACQUIRE_OUT_VER0 0x3000
+/**
+ * struct cam_isp_init_frame_drop_config - init frame drop configuration
+ *
+ * @init_frame_drop: Initial number of frames needs to drop
+ */
+
+struct cam_isp_init_frame_drop_config {
+ uint32_t init_frame_drop;
+} __attribute__((packed));
+
#endif /* __UAPI_CAM_ISP_H__ */
diff --git a/include/uapi/media/cam_req_mgr.h b/include/uapi/media/cam_req_mgr.h
index 5341d62..defed87 100644
--- a/include/uapi/media/cam_req_mgr.h
+++ b/include/uapi/media/cam_req_mgr.h
@@ -36,6 +36,7 @@
* It includes both session and device handles
*/
#define CAM_REQ_MGR_MAX_HANDLES 64
+#define CAM_REQ_MGR_MAX_HANDLES_V2 128
#define MAX_LINKS_PER_SESSION 2
/* V4L event type which user space will subscribe to */
@@ -122,6 +123,20 @@
int32_t link_hdl;
};
+struct cam_req_mgr_link_info_v2 {
+ int32_t session_hdl;
+ uint32_t num_devices;
+ int32_t dev_hdls[CAM_REQ_MGR_MAX_HANDLES_V2];
+ int32_t link_hdl;
+};
+
+struct cam_req_mgr_ver_info {
+ uint32_t version;
+ union {
+ struct cam_req_mgr_link_info link_info_v1;
+ struct cam_req_mgr_link_info_v2 link_info_v2;
+ } u;
+};
/**
* struct cam_req_mgr_unlink_info
* @session_hdl: input param - session handle
@@ -231,6 +246,7 @@
#define CAM_REQ_MGR_RELEASE_BUF (CAM_COMMON_OPCODE_MAX + 11)
#define CAM_REQ_MGR_CACHE_OPS (CAM_COMMON_OPCODE_MAX + 12)
#define CAM_REQ_MGR_LINK_CONTROL (CAM_COMMON_OPCODE_MAX + 13)
+#define CAM_REQ_MGR_LINK_V2 (CAM_COMMON_OPCODE_MAX + 14)
/* end of cam_req_mgr opcodes */
#define CAM_MEM_FLAG_HW_READ_WRITE (1<<0)