Merge "msm: camera: reqmgr: Skip reset if no request from UMD" into dev/msm-4.14-camx
diff --git a/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi b/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi
index 85a3974..baf25c4 100644
--- a/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdmmagpie-camera-sensor-idp.dtsi
@@ -33,6 +33,16 @@
switch-source = <&pm6150l_switch2 &pm6150l_switch2>;
status = "ok";
};
+
+ led_flash_rear_aux2: qcom,camera-flash@2 {
+ cell-index = <2>;
+ reg = <0x02 0x00>;
+ compatible = "qcom,camera-flash";
+ flash-source = <&pm6150l_flash0 &pm6150l_flash1>;
+ torch-source = <&pm6150l_torch0 &pm6150l_torch1>;
+ switch-source = <&pm6150l_switch2 &pm6150l_switch2>;
+ status = "ok";
+ };
};
&cam_cci0 {
@@ -525,11 +535,11 @@
compatible = "qcom,cam-sensor";
reg = <0x6>;
csiphy-sd-index = <2>;
- sensor-position-roll = <270>;
+ sensor-position-roll = <90>;
sensor-position-pitch = <0>;
- sensor-position-yaw = <0>;
+ sensor-position-yaw = <180>;
eeprom-src = <&eeprom_triple_uw>;
- led-flash-src = <&led_flash_rear_aux>;
+ led-flash-src = <&led_flash_rear_aux2>;
actuator-src = <&actuator_rear_aux>;
cam_vio-supply = <&pm8009_l7>;
cam_vana-supply = <&pm8009_l6>;
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
index ff8be35..178d33d 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.h
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm.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
@@ -251,6 +251,17 @@ struct cam_cdm_intf_mgr {
int32_t refcount;
};
+/**
+ * struct cam_cdm_debugfs_entry : debugfs entry struct
+ *
+ * @dentry : entry of debugfs
+ * @dump_register : flag to dump registers
+ */
+struct cam_cdm_debugfs_entry {
+ struct dentry *dentry;
+ bool dump_register;
+};
+
int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
uint32_t *index);
diff --git a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
index 19413d6..af83aba 100644
--- a/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
+++ b/drivers/media/platform/msm/camera/cam_cdm/cam_cdm_hw_core.c
@@ -38,6 +38,8 @@
static void cam_hw_cdm_work(struct work_struct *work);
+static struct cam_cdm_debugfs_entry debugfs_entry;
+
/* DT match table entry for all CDM variants*/
static const struct of_device_id msm_cam_hw_cdm_dt_match[] = {
{
@@ -69,6 +71,31 @@ int cam_hw_cdm_bl_fifo_pending_bl_rb(struct cam_hw_info *cdm_hw,
return rc;
}
+static int cam_hw_cdm_create_debugfs_entry(void)
+{
+ int rc = 0;
+
+ debugfs_entry.dentry = debugfs_create_dir("camera_cdm", NULL);
+ if (!debugfs_entry.dentry)
+ return -ENOMEM;
+
+ if (!debugfs_create_bool("dump_register",
+ 0644,
+ debugfs_entry.dentry,
+ &debugfs_entry.dump_register)) {
+ CAM_ERR(CAM_CDM,
+ "failed to create dump_register entry");
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ return rc;
+err:
+ debugfs_remove_recursive(debugfs_entry.dentry);
+ debugfs_entry.dentry = NULL;
+ return rc;
+}
+
static int cam_hw_cdm_enable_bl_done_irq(struct cam_hw_info *cdm_hw,
bool enable)
{
@@ -186,6 +213,9 @@ void cam_hw_cdm_dump_core_debug_registers(
{
uint32_t dump_reg, core_dbg, loop_cnt;
+ if (!debugfs_entry.dump_register)
+ return;
+
mutex_lock(&cdm_hw->hw_mutex);
cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_CORE_EN, &dump_reg);
CAM_ERR(CAM_CDM, "CDM HW core status=%x", dump_reg);
@@ -482,6 +512,14 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
if ((!rc) && (hw_vaddr_ptr) && (len) &&
(len >= cdm_cmd->cmd[i].offset)) {
+
+ if ((len - cdm_cmd->cmd[i].offset) <
+ cdm_cmd->cmd[i].len) {
+ CAM_ERR(CAM_CDM, "Not enough buffer");
+ rc = -EINVAL;
+ break;
+ }
+
CAM_DBG(CAM_CDM, "Got the HW VA");
if (core->bl_tag >=
(CAM_CDM_HWFIFO_SIZE - 1))
@@ -1012,6 +1050,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
}
cdm_hw->open_count--;
mutex_unlock(&cdm_hw->hw_mutex);
+ cam_hw_cdm_create_debugfs_entry();
CAM_DBG(CAM_CDM, "CDM%d probe successful", cdm_hw_intf->hw_idx);
diff --git a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
index 54f82ee..b2838b4 100644
--- a/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c
@@ -596,6 +596,15 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl,
return -ENOMEM;
}
+ if (io_cfg[i].offsets[plane] >= size) {
+ CAM_ERR(CAM_FD,
+ "Invalid cpu buf %d %d %d",
+ io_cfg[i].direction,
+ io_cfg[i].resource_type, plane);
+ rc = -EINVAL;
+ goto rel_cpu_buf;
+ }
+
io_addr[plane] += io_cfg[i].offsets[plane];
}
diff --git a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
index fa9b442..41d1751 100644
--- a/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
+++ b/drivers/media/platform/msm/camera/cam_icp/cam_icp_context.c
@@ -45,6 +45,14 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
return -EINVAL;
}
+ mutex_lock(&ctx->ctx_mutex);
+
+ if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) {
+ CAM_ERR(CAM_ICP, "Invalid state icp ctx %d state %d",
+ ctx->ctx_id, ctx->state);
+ goto end;
+ }
+
CAM_INFO(CAM_ICP, "iommu fault for icp ctx %d state %d",
ctx->ctx_id, ctx->state);
@@ -63,6 +71,8 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
req->request_id, rc);
}
+end:
+ mutex_unlock(&ctx->ctx_mutex);
return rc;
}
@@ -137,6 +147,12 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
return rc;
}
+ if ((len < sizeof(struct cam_packet)) ||
+ (cmd->offset >= (len - sizeof(struct cam_packet)))) {
+ CAM_ERR(CAM_CTXT, "Not enough buf");
+ return -EINVAL;
+ }
+
packet = (struct cam_packet *) ((uint8_t *)packet_addr +
(uint32_t)cmd->offset);
diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
index 8c83cbc..eec56c7 100644
--- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
@@ -64,6 +64,37 @@ static struct cam_icp_hw_mgr icp_hw_mgr;
static void cam_icp_mgr_process_dbg_buf(unsigned int debug_lvl);
+static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data,
+ int32_t buf_handle)
+{
+ uintptr_t vaddr_ptr;
+ uint32_t *ptr;
+ size_t len;
+ int rc, i;
+ char buf[512];
+ int used = 0;
+
+ rc = cam_mem_get_cpu_buf(buf_handle, &vaddr_ptr, &len);
+ if (rc) {
+ CAM_ERR(CAM_ICP, "Unable to get io_cfg buf address for %d",
+ ctx_data->ctx_id);
+ return rc;
+ }
+
+ len = len / sizeof(uint32_t);
+ ptr = (uint32_t *)vaddr_ptr;
+ for (i = 0; i < len; i++) {
+ used += snprintf(buf + used,
+ sizeof(buf) - used, "0X%08X-", ptr[i]);
+ if (!(i % 8)) {
+ CAM_INFO(CAM_ICP, "%s: %s", __func__, buf);
+ used = 0;
+ }
+ }
+
+ return rc;
+}
+
static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr)
{
struct cam_hw_intf *a5_dev_intf = NULL;
@@ -1262,6 +1293,44 @@ static int cam_icp_mgr_ipe_bps_power_collapse(struct cam_icp_hw_mgr *hw_mgr,
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;
@@ -1786,27 +1855,31 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr)
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;
@@ -1827,6 +1900,7 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr)
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);
@@ -1854,6 +1928,10 @@ static int cam_icp_mgr_process_fatal_error(
if (event_notify->event_id == HFI_EVENT_SYS_ERROR) {
CAM_INFO(CAM_ICP, "received HFI_EVENT_SYS_ERROR");
+ if (event_notify->event_data1 == HFI_ERR_SYS_FATAL) {
+ CAM_ERR(CAM_ICP, "received HFI_ERR_SYS_FATAL");
+ BUG();
+ }
rc = cam_icp_mgr_trigger_recovery(hw_mgr);
cam_icp_mgr_process_dbg_buf(icp_hw_mgr.a5_dbg_lvl);
}
@@ -3445,6 +3523,17 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
goto rel_cmd_buf;
}
*fw_cmd_buf_iova_addr = addr;
+
+ if (cmd_desc[i].offset >= len ||
+ ((len - cmd_desc[i].offset) <
+ cmd_desc[i].size)){
+ CAM_ERR(CAM_ICP,
+ "Invalid offset/length, i %d offset 0x%x len 0x%x size 0x%x",
+ i, cmd_desc[i].offset,
+ len, cmd_desc[i].size);
+ goto rel_cmd_buf;
+ }
+
*fw_cmd_buf_iova_addr =
(*fw_cmd_buf_iova_addr + cmd_desc[i].offset);
rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
@@ -4048,8 +4137,12 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
packet = prepare_args->packet;
- if (cam_packet_util_validate_packet(packet, prepare_args->remain_len))
+ if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) {
+ mutex_unlock(&ctx_data->ctx_mutex);
+ CAM_ERR(CAM_ICP, "ctx id: %u packet req id %lld validate fail",
+ ctx_data->ctx_id, packet->header.request_id);
return -EINVAL;
+ }
rc = cam_icp_mgr_pkt_validation(packet);
if (rc) {
@@ -4670,6 +4763,8 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
rc = cam_icp_mgr_send_config_io(ctx_data, io_buf_addr);
if (rc) {
CAM_ERR(CAM_ICP, "IO Config command failed %d", rc);
+ cam_icp_dump_io_cfg(ctx_data,
+ icp_dev_acquire_info->io_config_cmd_handle);
goto ioconfig_failed;
}
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index ff2f68d..5f23e87 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -2984,6 +2984,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
}
}
+ 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 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
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;
@@ -4078,6 +4080,36 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
}
}
+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;
@@ -4748,11 +4780,26 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe(
(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/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
index bf5f152..0e6d79b 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
@@ -102,38 +102,42 @@ struct cam_ife_hw_mgr_debug {
/**
* 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 @@ struct cam_ife_hw_mgr_ctx {
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/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index cd91334..ea0b01f 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -46,7 +46,7 @@
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12
/* Max CSI Rx irq error count threshold value */
-#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 100
+#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT 5
static int cam_ife_csid_is_ipp_ppp_format_supported(
uint32_t in_format)
@@ -1479,15 +1479,13 @@ static void cam_ife_csid_halt_csi2(
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
- CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx",
- csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);
/* Disable the CSI2 rx inerrupts */
- cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ cam_io_w(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
/* Reset the Rx CFG registers */
- cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ cam_io_w(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
@@ -3093,13 +3091,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
- CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top);
- CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
- CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
- CAM_DBG(CAM_ISP, "irq_status_ppp = 0x%x", irq_status_ppp);
- CAM_DBG(CAM_ISP, "irq_status_rdi0= 0x%x", irq_status_rdi[0]);
- CAM_DBG(CAM_ISP, "irq_status_rdi1= 0x%x", irq_status_rdi[1]);
- CAM_DBG(CAM_ISP, "irq_status_rdi2= 0x%x", irq_status_rdi[2]);
+ CAM_DBG(CAM_ISP,
+ "CSID %d irq status 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_top,
+ irq_status_rx, irq_status_ipp, irq_status_ppp,
+ irq_status_rdi[0], irq_status_rdi[1], irq_status_rdi[2]);
if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
CAM_DBG(CAM_ISP, "csi rx reset complete");
@@ -3109,71 +3105,38 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
spin_lock_irqsave(&csid_hw->lock_state, flags);
if (csid_hw->device_enabled == 1) {
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
- csid_hw->hw_intf->hw_idx);
fatal_err_detected = true;
+ goto handle_fatal_error;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d CPHY_EOT_RECEPTION",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d CPHY_SOT_RECEPTION",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
- if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC",
- csid_hw->hw_intf->hw_idx);
- }
- if (irq_status_rx & CSID_CSI2_RX_ERROR_CRC) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC",
- csid_hw->hw_intf->hw_idx);
- }
- if (irq_status_rx & CSID_CSI2_RX_ERROR_ECC) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC",
- csid_hw->hw_intf->hw_idx);
- }
- if (irq_status_rx & CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT",
- csid_hw->hw_intf->hw_idx);
- }
if (irq_status_rx & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
- CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d ERROR_STREAM_UNDERFLOW",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
if (irq_status_rx & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
- CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME",
- csid_hw->hw_intf->hw_idx);
csid_hw->error_irq_count++;
}
}
- spin_unlock_irqrestore(&csid_hw->lock_state, flags);
if (csid_hw->error_irq_count >
CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT) {
@@ -3181,8 +3144,15 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
csid_hw->error_irq_count = 0;
}
- if (fatal_err_detected)
+handle_fatal_error:
+ spin_unlock_irqrestore(&csid_hw->lock_state, flags);
+ if (fatal_err_detected) {
+ CAM_INFO(CAM_ISP,
+ "CSID: %d cnt: %d Halt csi2 rx irq_status_rx:0x%x",
+ csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt,
+ irq_status_rx);
cam_ife_csid_halt_csi2(csid_hw);
+ }
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
@@ -3283,7 +3253,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
/* IPP reset done bit */
if (irq_status_ipp &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
- CAM_DBG(CAM_ISP, "CSID IPP reset complete");
complete(&csid_hw->csid_ipp_complete);
}
@@ -3300,19 +3269,17 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received",
csid_hw->hw_intf->hw_idx);
- if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
- CAM_INFO_RATE_LIMIT(CAM_ISP,
- "CSID:%d IPP CCIF violation",
- csid_hw->hw_intf->hw_idx);
-
- if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+ (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d IPP fifo over flow",
- csid_hw->hw_intf->hw_idx);
- /* Stop IPP path immediately */
- cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
- soc_info->reg_map[0].mem_base +
- csid_reg->ipp_reg->csid_pxl_ctrl_addr);
+ "CSID:%d irq_status_ipp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ipp);
+ if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ /* Stop IPP path immediately */
+ cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
+ soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_pxl_ctrl_addr);
+ }
}
}
@@ -3321,7 +3288,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
/* PPP reset done bit */
if (irq_status_ppp &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
- CAM_DBG(CAM_ISP, "CSID PPP reset complete");
complete(&csid_hw->csid_ppp_complete);
}
@@ -3338,26 +3304,23 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received",
csid_hw->hw_intf->hw_idx);
- if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
- CAM_INFO_RATE_LIMIT(CAM_ISP,
- "CSID:%d PPP CCIF violation",
- csid_hw->hw_intf->hw_idx);
-
- if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ if ((irq_status_ppp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+ (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d PPP fifo over flow",
- csid_hw->hw_intf->hw_idx);
- /* Stop PPP path immediately */
- cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
- soc_info->reg_map[0].mem_base +
- csid_reg->ppp_reg->csid_pxl_ctrl_addr);
+ "CSID:%d irq_status_ppp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ppp);
+ if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ /* Stop PPP path immediately */
+ cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
+ soc_info->reg_map[0].mem_base +
+ csid_reg->ppp_reg->csid_pxl_ctrl_addr);
+ }
}
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
if (irq_status_rdi[i] &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
- CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
complete(&csid_hw->csid_rdin_complete[i]);
}
@@ -3374,14 +3337,14 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
CAM_INFO_RATE_LIMIT(CAM_ISP,
"CSID RDI:%d EOF received", i);
- if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION))
- CAM_INFO_RATE_LIMIT(CAM_ISP,
- "CSIDi RDI :%d CCIF violation", i);
-
- if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
+ if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION) ||
+ (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
- "CSID:%d RDI fifo over flow",
- csid_hw->hw_intf->hw_idx);
+ "CSID:%d irq_status_rdi[%d]:0x%x",
+ csid_hw->hw_intf->hw_idx, i,
+ irq_status_rdi[i]);
+ }
+ if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
/* Stop RDI path immediately */
cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
soc_info->reg_map[0].mem_base +
diff --git a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index 6154256..b230147 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -104,6 +104,7 @@ enum cam_isp_hw_cmd_type {
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/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 6b123c8..a26c112 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.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
@@ -760,6 +760,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
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/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index 13b588f..3ed45ee 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -422,6 +422,40 @@ static int cam_vfe_camif_reg_dump_bh(
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)
{
@@ -509,6 +543,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node,
(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/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index 4dcad9c..d512128 100644
--- a/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -438,6 +438,19 @@ static int cam_vfe_top_mux_get_reg_update(
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 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type,
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/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
index 9e4578d..9ea8e3f 100644
--- a/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c
@@ -157,6 +157,12 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
cmd_buf_kaddr = (uint32_t *)kaddr;
+ if ((p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset /
+ sizeof(uint32_t)) >= cmd_buf_len) {
+ CAM_ERR(CAM_JPEG, "Not enough buf");
+ return -EINVAL;
+ }
+
cmd_buf_kaddr =
(cmd_buf_kaddr +
(p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
index cbb908c..35aa907 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_req_mgr_core.c
@@ -683,6 +683,7 @@ static int __cam_req_mgr_check_sync_for_mslave(
struct cam_req_mgr_slot *sync_slot = NULL;
int sync_slot_idx = 0, prev_idx, next_idx, rd_idx, sync_rd_idx, rc = 0;
int64_t req_id = 0, sync_req_id = 0;
+ int32_t sync_num_slots = 0;
if (!link->sync_link) {
CAM_ERR(CAM_CRM, "Sync link null");
@@ -691,6 +692,7 @@ static int __cam_req_mgr_check_sync_for_mslave(
sync_link = link->sync_link;
req_id = slot->req_id;
+ sync_num_slots = sync_link->req.in_q->num_slots;
sync_rd_idx = sync_link->req.in_q->rd_idx;
CAM_DBG(CAM_CRM,
@@ -768,7 +770,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED) &&
- ((sync_slot_idx - rd_idx) >= 1) &&
+ (((sync_slot_idx - rd_idx + sync_num_slots) %
+ sync_num_slots) >= 1) &&
(sync_link->req.in_q->slot[rd_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
@@ -834,7 +837,8 @@ static int __cam_req_mgr_check_sync_for_mslave(
if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED) &&
- ((sync_slot_idx - rd_idx) >= 1) &&
+ (((sync_slot_idx - rd_idx + sync_num_slots) %
+ sync_num_slots) >= 1) &&
(sync_link->req.in_q->slot[rd_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
@@ -891,6 +895,7 @@ static int __cam_req_mgr_check_sync_req_is_ready(
struct cam_req_mgr_core_link *sync_link = NULL;
int64_t req_id = 0;
int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0;
+ int32_t sync_num_slots = 0;
if (!link->sync_link) {
CAM_ERR(CAM_CRM, "Sync link null");
@@ -899,6 +904,7 @@ static int __cam_req_mgr_check_sync_req_is_ready(
sync_link = link->sync_link;
req_id = slot->req_id;
+ sync_num_slots = sync_link->req.in_q->num_slots;
CAM_DBG(CAM_REQ,
"link_hdl %x req %lld frame_skip_flag %d ",
@@ -943,7 +949,8 @@ static int __cam_req_mgr_check_sync_req_is_ready(
sync_rd_idx = sync_link->req.in_q->rd_idx;
if ((sync_link->req.in_q->slot[sync_slot_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED) &&
- ((sync_slot_idx - sync_rd_idx) >= 1) &&
+ (((sync_slot_idx - sync_rd_idx + sync_num_slots) %
+ sync_num_slots) >= 1) &&
(sync_link->req.in_q->slot[sync_rd_idx].status !=
CRM_SLOT_STATUS_REQ_APPLIED)) {
CAM_DBG(CAM_CRM,
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
index 1908e9d..5304b46 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
@@ -232,13 +232,18 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
csiphy_dev->csiphy_info.csiphy_3phase =
cam_cmd_csiphy_info->csiphy_3phase;
csiphy_dev->csiphy_info.combo_mode |= cam_cmd_csiphy_info->combo_mode;
- if (cam_cmd_csiphy_info->combo_mode == 1)
+ if (cam_cmd_csiphy_info->combo_mode == 1) {
csiphy_dev->csiphy_info.settle_time_combo_sensor =
cam_cmd_csiphy_info->settle_time;
- else
+ csiphy_dev->csiphy_info.data_rate_combo_sensor =
+ cam_cmd_csiphy_info->data_rate;
+ } else {
csiphy_dev->csiphy_info.settle_time =
cam_cmd_csiphy_info->settle_time;
- csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate;
+ csiphy_dev->csiphy_info.data_rate =
+ cam_cmd_csiphy_info->data_rate;
+ }
+
if (cam_cmd_csiphy_info->secure_mode == 1)
cam_csiphy_update_secure_info(csiphy_dev,
@@ -269,6 +274,65 @@ void cam_csiphy_cphy_irq_config(struct csiphy_device *csiphy_dev)
csiphy_dev->ctrl_reg->csiphy_irq_reg[i].reg_addr);
}
+void cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device)
+{
+ int i = 0, j = 0;
+ uint64_t phy_data_rate = 0;
+ void __iomem *csiphybase = NULL;
+ ssize_t num_table_entries = 0;
+ struct data_rate_settings_t *settings_table = NULL;
+
+ if ((csiphy_device == NULL) ||
+ (csiphy_device->ctrl_reg == NULL) ||
+ (csiphy_device->ctrl_reg->data_rates_settings_table == NULL)) {
+ CAM_DBG(CAM_CSIPHY,
+ "Data rate specific register table not found");
+ return;
+ }
+
+ phy_data_rate = csiphy_device->csiphy_info.data_rate;
+ csiphybase =
+ csiphy_device->soc_info.reg_map[0].mem_base;
+ settings_table =
+ csiphy_device->ctrl_reg->data_rates_settings_table;
+ num_table_entries =
+ settings_table->num_data_rate_settings;
+
+ CAM_DBG(CAM_CSIPHY, "required data rate : %llu", phy_data_rate);
+ for (i = 0; i < num_table_entries; i++) {
+ struct data_rate_reg_info_t *drate_settings =
+ settings_table->data_rate_settings;
+ uint64_t bandwidth =
+ drate_settings[i].bandwidth;
+ ssize_t num_reg_entries =
+ drate_settings[i].data_rate_reg_array_size;
+
+ if (phy_data_rate > bandwidth) {
+ CAM_DBG(CAM_CSIPHY,
+ "Skipping table [%d] %llu required: %llu",
+ i, bandwidth, phy_data_rate);
+ continue;
+ }
+
+ CAM_DBG(CAM_CSIPHY,
+ "table[%d] BW : %llu Selected", i, bandwidth);
+ for (j = 0; j < num_reg_entries; j++) {
+ uint32_t reg_addr =
+ drate_settings[i].csiphy_data_rate_regs[j].reg_addr;
+
+ uint32_t reg_data =
+ drate_settings[i].csiphy_data_rate_regs[j].reg_data;
+
+ CAM_DBG(CAM_CSIPHY,
+ "writing reg : %x val : %x",
+ reg_addr, reg_data);
+ cam_io_w_mb(reg_data,
+ csiphybase + reg_addr);
+ }
+ break;
+ }
+}
+
void cam_csiphy_cphy_irq_disable(struct csiphy_device *csiphy_dev)
{
int32_t i;
@@ -476,6 +540,9 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
lane_pos++;
}
+ if (csiphy_dev->csiphy_info.csiphy_3phase)
+ cam_csiphy_cphy_data_rate_config(csiphy_dev);
+
cam_csiphy_cphy_irq_config(csiphy_dev);
return rc;
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
index 51cf9e9..cf81924d 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
@@ -44,8 +44,10 @@
#define MAX_CSIPHY_REG_ARRAY 70
#define MAX_CSIPHY_CMN_REG_ARRAY 5
-#define MAX_LANES 5
-#define MAX_SETTINGS_PER_LANE 43
+#define MAX_LANES 5
+#define MAX_SETTINGS_PER_LANE 43
+#define MAX_DATA_RATES 3
+#define MAX_DATA_RATE_REGS 30
#define MAX_REGULATOR 5
#define CAMX_CSIPHY_DEV_NAME "cam-csiphy-driver"
@@ -155,6 +157,32 @@ struct csiphy_reg_t {
uint32_t csiphy_param_type;
};
+struct csiphy_device;
+
+/*
+ * struct data_rate_reg_info_t
+ * @bandwidth: max bandwidth supported by this reg settings
+ * @data_rate_reg_array_size: number of reg value pairs in the array
+ * @csiphy_data_rate_regs: array of data rate specific reg value pairs
+ */
+struct data_rate_reg_info_t {
+ uint64_t bandwidth;
+ ssize_t data_rate_reg_array_size;
+ struct csiphy_reg_t csiphy_data_rate_regs[MAX_DATA_RATE_REGS];
+};
+
+/**
+ * struct data_rate_settings_t
+ * @num_data_rate_settings: number of valid settings
+ * present in the data rate settings array
+ * @data_rate_settings: array of regsettings which are specific to
+ * data rate
+ */
+struct data_rate_settings_t {
+ ssize_t num_data_rate_settings;
+ struct data_rate_reg_info_t data_rate_settings[MAX_DATA_RATES];
+};
+
/**
* struct csiphy_ctrl_t
* @csiphy_reg: Register address
@@ -166,6 +194,12 @@ struct csiphy_reg_t {
* @csiphy_3ph_reg: 3phase register set
* @csiphy_2ph_3ph_mode_reg:
* 2 phase 3phase combo register set
+ * @getclockvoting: function pointer which
+ * is used to find the clock voting
+ * for the sensor output data rate
+ * @data_rate_settings_table:
+ * Table which maintains the resgister
+ * settings specific to data rate
*/
struct csiphy_ctrl_t {
struct csiphy_reg_parms_t csiphy_reg;
@@ -176,6 +210,8 @@ struct csiphy_ctrl_t {
struct csiphy_reg_t (*csiphy_2ph_combo_mode_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_3ph_reg)[MAX_SETTINGS_PER_LANE];
struct csiphy_reg_t (*csiphy_2ph_3ph_mode_reg)[MAX_SETTINGS_PER_LANE];
+ enum cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev);
+ struct data_rate_settings_t *data_rates_settings_table;
};
/**
@@ -190,6 +226,8 @@ struct csiphy_ctrl_t {
* @settle_time : Settling time in ms
* @settle_time_combo_sensor : Settling time in ms
* @data_rate : Data rate in mbps
+ * @data_rate_combo_sensor: data rate of combo sensor
+ * in the the same phy
*
*/
struct cam_csiphy_param {
@@ -202,6 +240,7 @@ struct cam_csiphy_param {
uint64_t settle_time;
uint64_t settle_time_combo_sensor;
uint64_t data_rate;
+ uint64_t data_rate_combo_sensor;
};
/**
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
index 0902601..0bf5aac 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.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
@@ -17,6 +17,9 @@
#include "include/cam_csiphy_1_2_hwreg.h"
#include "include/cam_csiphy_2_0_hwreg.h"
+#define CSIPHY_3PH_DIVISOR 16
+#define CSIPHY_3PH_DIVISOR_12 32
+#define CSIPHY_2PH_DIVISOR 8
#define BYTES_PER_REGISTER 4
#define NUM_REGISTER_PER_LINE 4
#define REG_OFFSET(__start, __i) ((__start) + ((__i) * BYTES_PER_REGISTER))
@@ -79,10 +82,62 @@ int32_t cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info)
return rc;
}
+enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev)
+{
+ CAM_DBG(CAM_CSIPHY, "voting for SVS");
+ return CAM_SVS_VOTE;
+}
+
+enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev)
+{
+ uint32_t cam_vote_level = 0;
+ uint32_t last_valid_vote = 0;
+ struct cam_hw_soc_info *soc_info;
+ uint64_t phy_data_rate = csiphy_dev->csiphy_info.data_rate;
+
+ soc_info = &csiphy_dev->soc_info;
+
+ if (csiphy_dev->is_acquired_dev_combo_mode)
+ phy_data_rate = max(phy_data_rate,
+ csiphy_dev->csiphy_info.data_rate_combo_sensor);
+
+ if (csiphy_dev->csiphy_info.csiphy_3phase) {
+ if (csiphy_dev->is_csiphy_3phase_hw == CSI_3PHASE_HW_12)
+ do_div(phy_data_rate, CSIPHY_3PH_DIVISOR_12);
+ else
+ do_div(phy_data_rate, CSIPHY_3PH_DIVISOR);
+ } else {
+ do_div(phy_data_rate, CSIPHY_2PH_DIVISOR);
+ }
+
+ /* round off to next integer */
+ phy_data_rate += 1;
+
+ for (cam_vote_level = 0;
+ cam_vote_level < CAM_MAX_VOTE; cam_vote_level++) {
+ if (soc_info->clk_level_valid[cam_vote_level] != true)
+ continue;
+
+ if (soc_info->clk_rate[cam_vote_level][0] >
+ phy_data_rate) {
+ CAM_DBG(CAM_CSIPHY,
+ "match detected %s : %llu:%d level : %d",
+ soc_info->clk_name[0],
+ phy_data_rate,
+ soc_info->clk_rate[cam_vote_level][0],
+ cam_vote_level);
+ return cam_vote_level;
+ }
+ last_valid_vote = cam_vote_level;
+ }
+ return last_valid_vote;
+}
+
int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
{
int32_t rc = 0;
struct cam_hw_soc_info *soc_info;
+ enum cam_vote_level vote_level = CAM_SVS_VOTE;
soc_info = &csiphy_dev->soc_info;
@@ -92,8 +147,9 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
return rc;
}
+ vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev);
rc = cam_soc_util_enable_platform_resource(soc_info, true,
- CAM_SVS_VOTE, ENABLE_IRQ);
+ vote_level, ENABLE_IRQ);
if (rc < 0) {
CAM_ERR(CAM_CSIPHY, "failed to enable platform resources %d",
rc);
@@ -174,9 +230,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_1_0;
csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_1_0;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_0;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
csiphy_dev->hw_version = CSIPHY_VERSION_V10;
csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
} else if (of_device_is_compatible(soc_info->dev->of_node,
"qcom,csiphy-v1.1")) {
csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_1_reg;
@@ -191,9 +249,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->ctrl_reg->csiphy_reset_reg =
csiphy_reset_reg_1_1;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_1;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
csiphy_dev->hw_version = CSIPHY_VERSION_V11;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
} else if (of_device_is_compatible(soc_info->dev->of_node,
"qcom,csiphy-v1.2")) {
csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_2_reg;
@@ -206,10 +266,13 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_common_reg_1_2;
csiphy_dev->ctrl_reg->csiphy_reset_reg =
csiphy_reset_reg_1_2;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_voting_dynamic;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_2;
- csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
+ csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW_12;
csiphy_dev->hw_version = CSIPHY_VERSION_V12;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table =
+ &data_rate_delta_table;
} else if (of_device_is_compatible(soc_info->dev->of_node,
"qcom,csiphy-v2.0")) {
csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v2_0_reg;
@@ -221,9 +284,11 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_2_0;
csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_2_0;
csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v2_0;
+ csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
csiphy_dev->hw_version = CSIPHY_VERSION_V20;
csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
csiphy_dev->clk_lane = 0;
+ csiphy_dev->ctrl_reg->data_rates_settings_table = NULL;
} else {
CAM_ERR(CAM_CSIPHY, "invalid hw version : 0x%x",
csiphy_dev->hw_version);
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
index 68ca68c..64d0561 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/cam_csiphy_soc.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
@@ -34,6 +34,7 @@
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#define CSI_3PHASE_HW 1
+#define CSI_3PHASE_HW_12 0x12
#define CSIPHY_VERSION_V35 0x35
#define CSIPHY_VERSION_V10 0x10
#define CSIPHY_VERSION_V11 0x11
diff --git a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
index 945910e..67653e8 100644
--- a/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
+++ b/drivers/media/platform/msm/camera/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_hwreg.h
@@ -19,10 +19,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
.mipi_csiphy_interrupt_status0_addr = 0x8B0,
.mipi_csiphy_interrupt_clear0_addr = 0x858,
.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
- .csiphy_common_array_size = 4,
+ .csiphy_common_array_size = 6,
.csiphy_reset_array_size = 5,
.csiphy_2ph_config_array_size = 21,
- .csiphy_3ph_config_array_size = 31,
+ .csiphy_3ph_config_array_size = 38,
.csiphy_2ph_clock_lane = 0x1,
.csiphy_2ph_combo_ck_ln = 0x10,
};
@@ -30,8 +30,10 @@ struct csiphy_reg_parms_t csiphy_v1_2 = {
struct csiphy_reg_t csiphy_common_reg_1_2[] = {
{0x0814, 0xd5, 0x00, CSIPHY_LANE_ENABLE},
{0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x081C, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x081C, 0x02, 0x00, CSIPHY_2PH_REGS},
+ {0x081C, 0x52, 0x00, CSIPHY_3PH_REGS},
+ {0x0800, 0x02, 0x00, CSIPHY_2PH_REGS},
+ {0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS},
};
struct csiphy_reg_t csiphy_reset_reg_1_2[] = {
@@ -297,7 +299,7 @@ struct csiphy_reg_t
struct
csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{
- {0x015C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x015C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0990, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0994, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0998, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -305,10 +307,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0994, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0998, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x098C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x016C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0168, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x016C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x010C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
{0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -321,27 +323,34 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0124, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0128, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0144, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09C0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09C4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09C8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x09B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x09B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
- {0x035C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x035C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0A90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0A94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0A8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x036C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A98, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A8C, 0xBF, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0368, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x036C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x030C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
{0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -354,16 +363,23 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0324, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0328, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0344, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0AB0, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0AB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
},
{
- {0x055C, 0x40, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x055C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -371,10 +387,10 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0B94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0B8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x056C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0568, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x056C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+ {0x050C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
{0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
{0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
@@ -387,14 +403,107 @@ csiphy_reg_t csiphy_3ph_v1_2_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
{0x0524, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0528, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0544, 0x30, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
- {0x0BB0, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0B84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x0BB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
},
};
+struct data_rate_settings_t data_rate_delta_table = {
+ .num_data_rate_settings = 3,
+ .data_rate_settings = {
+ {
+ /* (2.5 * 10**3 * 2.28) rounded value*/
+ .bandwidth = 5700000000,
+ .data_rate_reg_array_size = 12,
+ .csiphy_data_rate_regs = {
+ {0x15C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x35C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x55C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x16C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x36C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x56C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
+ }
+ },
+ {
+ /* (3.5 * 10**3 * 2.28) rounded value */
+ .bandwidth = 7980000000,
+ .data_rate_reg_array_size = 24,
+ .csiphy_data_rate_regs = {
+ {0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
+ },
+ },
+ {
+ /* (4.5 * 10**3 * 2.28) rounded value */
+ .bandwidth = 10260000000,
+ .data_rate_reg_array_size = 24,
+ .csiphy_data_rate_regs = {
+ {0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x16C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x36C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ {0x56C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
+ },
+ }
+ }
+};
#endif /* _CAM_CSIPHY_1_2_HWREG_H_ */
diff --git a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
index d3f62d6..84acb71 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
+++ b/drivers/media/platform/msm/camera/cam_sync/cam_sync.c
@@ -29,6 +29,20 @@ struct sync_device *sync_dev;
*/
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,
+ sync_dev->sync_table[cnt].ref_cnt);
+ }
+}
+
int cam_sync_create(int32_t *sync_obj, const char *name)
{
int rc;
@@ -37,8 +51,15 @@ int cam_sync_create(int32_t *sync_obj, const char *name)
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 = %d 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 @@ static int cam_sync_open(struct file *filep)
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 @@ static int cam_sync_close(struct file *filep)
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 @@ static int cam_sync_probe(struct platform_device *pdev)
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/cam_sync/cam_sync_private.h b/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
index eb2fb34..c3cb345 100644
--- a/drivers/media/platform/msm/camera/cam_sync/cam_sync_private.h
+++ b/drivers/media/platform/msm/camera/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 @@ struct cam_signalable_info {
* @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 sync_device {
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/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_cpas_query_cap {
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 5b920d5..f38aa84 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
@@ -67,6 +68,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 749d61e..de32a61 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"
@@ -92,6 +92,12 @@
#define CAM_ISP_GENERIC_BLOB_TYPE_FE_CONFIG 5
#define CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2 6
+/* 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 */
/**
* struct cam_isp_dev_cap_info - A cap info for particular hw type
@@ -362,7 +368,6 @@ struct cam_isp_csid_clock_config {
* @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 +384,6 @@ struct cam_isp_bw_vote {
* @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 +412,19 @@ struct cam_isp_bw_config_ab {
} __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