aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsubrahmanya srinivasamurthy <subrs@codeaurora.org>2019-10-22 16:27:30 +0530
committersubrahmanya srinivasamurthy <subrs@codeaurora.org>2019-10-22 16:34:59 +0530
commit35460096d53a3194d2ebd6b3477383e853ed466a (patch)
tree353cb1e847f7407a05f037299dbad84da618f67d
parent36314f42649aba49a7225384190bf0a5f23bbec0 (diff)
Updating kernel ais in sync with 010.r1LA.AU.0.1.1.r1-01000-gen3meta.0
Change-Id: I92996ec1b0def47eedcf2732608eccb194f128fa Signed-off-by: subrahmanya srinivasamurthy <subrs@codeaurora.org>
-rw-r--r--drivers/media/platform/msm/ais/cam_core/cam_hw_mgr_intf.h12
-rw-r--r--drivers/media/platform/msm/ais/cam_cpas/cpas_top/cam_cpastop_hw.c12
-rw-r--r--drivers/media/platform/msm/ais/cam_cpas/cpas_top/cpastop_v150_110.h537
-rw-r--r--drivers/media/platform/msm/ais/cam_cpas/include/cam_cpas_api.h1
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c316
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/cam_isp_context.h11
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c369
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h20
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile1
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c58
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h32
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c395
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h103
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c147
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h22
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h4
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h4
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h4
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c291
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h21
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h13
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h5
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h11
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c3
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c17
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c26
-rw-r--r--drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c20
-rw-r--r--drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c19
-rw-r--r--drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_core.c13
29 files changed, 2308 insertions, 179 deletions
diff --git a/drivers/media/platform/msm/ais/cam_core/cam_hw_mgr_intf.h b/drivers/media/platform/msm/ais/cam_core/cam_hw_mgr_intf.h
index 50c38e712f36..d5822e17530f 100644
--- a/drivers/media/platform/msm/ais/cam_core/cam_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/ais/cam_core/cam_hw_mgr_intf.h
@@ -262,6 +262,16 @@ struct cam_hw_dump_pf_args {
bool *mem_found;
};
+/**
+ * struct cam_hw_reset_args -hw reset arguments
+ *
+ * @ctxt_to_hw_map: HW context from the acquire
+ *
+ */
+struct cam_hw_reset_args {
+ void *ctxt_to_hw_map;
+};
+
/* enum cam_hw_mgr_command - Hardware manager command type */
enum cam_hw_mgr_command {
CAM_HW_MGR_CMD_INTERNAL,
@@ -313,6 +323,7 @@ struct cam_hw_cmd_args {
* @hw_open: Function pointer for HW init
* @hw_close: Function pointer for HW deinit
* @hw_flush: Function pointer for HW flush
+ * @hw_reset: Function pointer for HW reset
*
*/
struct cam_hw_mgr_intf {
@@ -333,6 +344,7 @@ struct cam_hw_mgr_intf {
int (*hw_open)(void *hw_priv, void *fw_download_args);
int (*hw_close)(void *hw_priv, void *hw_close_args);
int (*hw_flush)(void *hw_priv, void *hw_flush_args);
+ int (*hw_reset)(void *hw_priv, void *hw_reset_args);
};
#endif /* _CAM_HW_MGR_INTF_H_ */
diff --git a/drivers/media/platform/msm/ais/cam_cpas/cpas_top/cam_cpastop_hw.c b/drivers/media/platform/msm/ais/cam_cpas/cpas_top/cam_cpastop_hw.c
index a21803ee5945..547b93a0f346 100644
--- a/drivers/media/platform/msm/ais/cam_cpas/cpas_top/cam_cpastop_hw.c
+++ b/drivers/media/platform/msm/ais/cam_cpas/cpas_top/cam_cpastop_hw.c
@@ -21,6 +21,7 @@
#include "cam_cpas_soc.h"
#include "cpastop100.h"
#include "cpastop_v150_100.h"
+#include "cpastop_v150_110.h"
#include "cpastop_v170_110.h"
#include "cpastop_v175_100.h"
#include "cpastop_v175_101.h"
@@ -107,6 +108,10 @@ static int cam_cpastop_get_hw_info(struct cam_hw_info *cpas_hw,
(hw_caps->cpas_version.incr == 1))
soc_info->hw_version = CAM_CPAS_TITAN_175_V101;
else if ((hw_caps->cpas_version.major == 1) &&
+ (hw_caps->cpas_version.minor == 1) &&
+ (hw_caps->cpas_version.incr == 1))
+ soc_info->hw_version = CAM_CPAS_TITAN_175_V101;
+ else if ((hw_caps->cpas_version.major == 1) &&
(hw_caps->cpas_version.minor == 2) &&
(hw_caps->cpas_version.incr == 0))
soc_info->hw_version = CAM_CPAS_TITAN_175_V120;
@@ -117,6 +122,10 @@ static int cam_cpastop_get_hw_info(struct cam_hw_info *cpas_hw,
(hw_caps->cpas_version.minor == 0) &&
(hw_caps->cpas_version.incr == 0))
soc_info->hw_version = CAM_CPAS_TITAN_150_V100;
+ else if ((hw_caps->cpas_version.major == 1) &&
+ (hw_caps->cpas_version.minor == 1) &&
+ (hw_caps->cpas_version.incr == 0))
+ soc_info->hw_version = CAM_CPAS_TITAN_150_V110;
}
CAM_DBG(CAM_CPAS, "CPAS HW VERSION %x", soc_info->hw_version);
@@ -603,6 +612,9 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
case CAM_CPAS_TITAN_150_V100:
camnoc_info = &cam150_cpas100_camnoc_info;
break;
+ case CAM_CPAS_TITAN_150_V110:
+ camnoc_info = &cam150_cpas110_camnoc_info;
+ break;
default:
CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d",
hw_caps->camera_version.major,
diff --git a/drivers/media/platform/msm/ais/cam_cpas/cpas_top/cpastop_v150_110.h b/drivers/media/platform/msm/ais/cam_cpas/cpas_top/cpastop_v150_110.h
new file mode 100644
index 000000000000..734f3784ef6c
--- /dev/null
+++ b/drivers/media/platform/msm/ais/cam_cpas/cpas_top/cpastop_v150_110.h
@@ -0,0 +1,537 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CPASTOP_V150_110_H_
+#define _CPASTOP_V150_110_H_
+
+#define TEST_IRQ_ENABLE 0
+
+static struct cam_camnoc_irq_sbm cam_cpas_v150_110_irq_sbm = {
+ .sbm_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2040, /* SBM_FAULTINEN0_LOW */
+ .value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
+ 0x2 | /* SBM_FAULTINEN0_LOW_PORT1_MASK */
+ 0x4 | /* SBM_FAULTINEN0_LOW_PORT2_MASK */
+ 0x8 | /* SBM_FAULTINEN0_LOW_PORT3_MASK */
+ 0x10 | /* SBM_FAULTINEN0_LOW_PORT4_MASK */
+ 0x20 | /* SBM_FAULTINEN0_LOW_PORT5_MASK */
+ (TEST_IRQ_ENABLE ?
+ 0x100 : /* SBM_FAULTINEN0_LOW_PORT8_MASK */
+ 0x0),
+ },
+ .sbm_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2048, /* SBM_FAULTINSTATUS0_LOW */
+ },
+ .sbm_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x2080, /* SBM_FLAGOUTCLR0_LOW */
+ .value = TEST_IRQ_ENABLE ? 0x6 : 0x2,
+ }
+};
+
+static struct cam_camnoc_irq_err
+ cam_cpas_v150_110_irq_err[] = {
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
+ .enable = true,
+ .sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x2718, /* ERRLOGGER_ERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IFE02_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT1_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x5a0, /* SPECIFIC_IFE02_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x590, /* SPECIFIC_IFE02_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x598, /* SPECIFIC_IFE02_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IFE13_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x4, /* SBM_FAULTINSTATUS0_LOW_PORT2_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x9a0, /* SPECIFIC_IFE13_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x990, /* SPECIFIC_IFE13_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x998, /* SPECIFIC_IFE13_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_DECODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x8, /* SBM_FAULTINSTATUS0_LOW_PORT3_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0xd20, /* SPECIFIC_IBL_RD_DECERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0xd10, /* SPECIFIC_IBL_RD_DECERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0xd18, /* SPECIFIC_IBL_RD_DECERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_IPE_BPS_UBWC_ENCODE_ERROR,
+ .enable = true,
+ .sbm_port = 0x10, /* SBM_FAULTINSTATUS0_LOW_PORT4_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x11a0, /* SPECIFIC_IBL_WR_ENCERREN_LOW */
+ .value = 1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x1190,
+ /* SPECIFIC_IBL_WR_ENCERRSTATUS_LOW */
+ },
+ .err_clear = {
+ .access_type = CAM_REG_TYPE_WRITE,
+ .enable = true,
+ .offset = 0x1198, /* SPECIFIC_IBL_WR_ENCERRCLR_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_AHB_TIMEOUT,
+ .enable = true,
+ .sbm_port = 0x20, /* SBM_FAULTINSTATUS0_LOW_PORT5_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
+ .value = 0x1,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
+ },
+ .err_clear = {
+ .enable = false,
+ },
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED1,
+ .enable = false,
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_RESERVED2,
+ .enable = false,
+ },
+ {
+ .irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
+ .enable = TEST_IRQ_ENABLE ? true : false,
+ .sbm_port = 0x100, /* SBM_FAULTINSTATUS0_LOW_PORT8_MASK */
+ .err_enable = {
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .enable = true,
+ .offset = 0x2088, /* SBM_FLAGOUTSET0_LOW */
+ .value = 0x5,
+ },
+ .err_status = {
+ .access_type = CAM_REG_TYPE_READ,
+ .enable = true,
+ .offset = 0x2090, /* SBM_FLAGOUTSTATUS0_LOW */
+ },
+ .err_clear = {
+ .enable = false,
+ },
+ },
+};
+
+static struct cam_camnoc_specific
+ cam_cpas_v150_110_camnoc_specific[] = {
+ {
+ .port_type = CAM_CAMNOC_CDM,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x30, /* SPECIFIC_CDM_PRIORITYLUT_LOW */
+ .value = 0x22222222,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x34, /* SPECIFIC_CDM_PRIORITYLUT_HIGH */
+ .value = 0x22222222,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x38, /* SPECIFIC_CDM_URGENCY_LOW */
+ .mask = 0x7, /* SPECIFIC_CDM_URGENCY_LOW_READ_MASK */
+ .shift = 0x0, /* SPECIFIC_CDM_URGENCY_LOW_READ_SHIFT */
+ .value = 0x2,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x40, /* SPECIFIC_CDM_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x48, /* SPECIFIC_CDM_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IFE02,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x430, /* SPECIFIC_IFE02_PRIORITYLUT_LOW */
+ .value = 0x66665433,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x434, /* SPECIFIC_IFE02_PRIORITYLUT_HIGH */
+ .value = 0x66666666,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x438, /* SPECIFIC_IFE02_URGENCY_LOW */
+ /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IFE02_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 0x30,
+ },
+ .danger_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x440, /* SPECIFIC_IFE02_DANGERLUT_LOW */
+ .value = 0xFFFFFF00,
+ },
+ .safe_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x448, /* SPECIFIC_IFE02_SAFELUT_LOW */
+ .value = 0x1,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IFE13,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x830, /* SPECIFIC_IFE13_PRIORITYLUT_LOW */
+ .value = 0x66665433,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x834, /* SPECIFIC_IFE13_PRIORITYLUT_HIGH */
+ .value = 0x66666666,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x838, /* SPECIFIC_IFE13_URGENCY_LOW */
+ /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IFE13_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 0x30,
+ },
+ .danger_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x840, /* SPECIFIC_IFE13_DANGERLUT_LOW */
+ .value = 0xFFFFFF00,
+ },
+ .safe_lut = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .offset = 0x848, /* SPECIFIC_IFE13_SAFELUT_LOW */
+ .value = 0x1,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IPE_BPS_LRME_READ,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc30, /* SPECIFIC_IBL_RD_PRIORITYLUT_LOW */
+ .value = 0x33333333,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc34, /* SPECIFIC_IBL_RD_PRIORITYLUT_HIGH */
+ .value = 0x33333333,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0xc38, /* SPECIFIC_IBL_RD_URGENCY_LOW */
+ /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_MASK */
+ .mask = 0x7,
+ /* SPECIFIC_IBL_RD_URGENCY_LOW_READ_SHIFT */
+ .shift = 0x0,
+ .value = 3,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc40, /* SPECIFIC_IBL_RD_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xc48, /* SPECIFIC_IBL_RD_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0xd08, /* SPECIFIC_IBL_RD_DECCTL_LOW */
+ .value = 1,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_IPE_BPS_LRME_WRITE,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1030, /* SPECIFIC_IBL_WR_PRIORITYLUT_LOW */
+ .value = 0x33333333,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1034, /* SPECIFIC_IBL_WR_PRIORITYLUT_HIGH */
+ .value = 0x33333333,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 1,
+ .offset = 0x1038, /* SPECIFIC_IBL_WR_URGENCY_LOW */
+ /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_MASK */
+ .mask = 0x70,
+ /* SPECIFIC_IBL_WR_URGENCY_LOW_WRITE_SHIFT */
+ .shift = 0x4,
+ .value = 0x30,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1040, /* SPECIFIC_IBL_WR_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1048, /* SPECIFIC_IBL_WR_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1188, /* SPECIFIC_IBL_WR_ENCCTL_LOW */
+ .value = 0x5,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_JPEG,
+ .enable = true,
+ .priority_lut_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1430, /* SPECIFIC_JPEG_PRIORITYLUT_LOW */
+ .value = 0x22222222,
+ },
+ .priority_lut_high = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1434, /* SPECIFIC_JPEG_PRIORITYLUT_HIGH */
+ .value = 0x22222222,
+ },
+ .urgency = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1438, /* SPECIFIC_JPEG_URGENCY_LOW */
+ .value = 0x22,
+ },
+ .danger_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1440, /* SPECIFIC_JPEG_DANGERLUT_LOW */
+ .value = 0x0,
+ },
+ .safe_lut = {
+ .enable = false,
+ .access_type = CAM_REG_TYPE_READ_WRITE,
+ .masked_value = 0,
+ .offset = 0x1448, /* SPECIFIC_JPEG_SAFELUT_LOW */
+ .value = 0x0,
+ },
+ .ubwc_ctl = {
+ .enable = false,
+ },
+ },
+ {
+ .port_type = CAM_CAMNOC_FD,
+ .enable = false,
+ },
+ {
+ .port_type = CAM_CAMNOC_ICP,
+ .enable = true,
+ .flag_out_set0_low = {
+ .enable = true,
+ .access_type = CAM_REG_TYPE_WRITE,
+ .masked_value = 0,
+ .offset = 0x2088,
+ .value = 0x100000,
+ },
+ },
+};
+
+static struct cam_camnoc_err_logger_info cam150_cpas110_err_logger_offsets = {
+ .mainctrl = 0x2708, /* ERRLOGGER_MAINCTL_LOW */
+ .errvld = 0x2710, /* ERRLOGGER_ERRVLD_LOW */
+ .errlog0_low = 0x2720, /* ERRLOGGER_ERRLOG0_LOW */
+ .errlog0_high = 0x2724, /* ERRLOGGER_ERRLOG0_HIGH */
+ .errlog1_low = 0x2728, /* ERRLOGGER_ERRLOG1_LOW */
+ .errlog1_high = 0x272c, /* ERRLOGGER_ERRLOG1_HIGH */
+ .errlog2_low = 0x2730, /* ERRLOGGER_ERRLOG2_LOW */
+ .errlog2_high = 0x2734, /* ERRLOGGER_ERRLOG2_HIGH */
+ .errlog3_low = 0x2738, /* ERRLOGGER_ERRLOG3_LOW */
+ .errlog3_high = 0x273c, /* ERRLOGGER_ERRLOG3_HIGH */
+};
+
+static struct cam_cpas_hw_errata_wa_list cam150_cpas110_errata_wa_list = {
+ .camnoc_flush_slave_pending_trans = {
+ .enable = false,
+ .data.reg_info = {
+ .access_type = CAM_REG_TYPE_READ,
+ .offset = 0x2100, /* SidebandManager_SenseIn0_Low */
+ .mask = 0xE0000, /* Bits 17, 18, 19 */
+ .value = 0, /* expected to be 0 */
+ },
+ },
+};
+
+static struct cam_camnoc_info cam150_cpas110_camnoc_info = {
+ .specific = &cam_cpas_v150_110_camnoc_specific[0],
+ .specific_size = sizeof(cam_cpas_v150_110_camnoc_specific) /
+ sizeof(cam_cpas_v150_110_camnoc_specific[0]),
+ .irq_sbm = &cam_cpas_v150_110_irq_sbm,
+ .irq_err = &cam_cpas_v150_110_irq_err[0],
+ .irq_err_size = sizeof(cam_cpas_v150_110_irq_err) /
+ sizeof(cam_cpas_v150_110_irq_err[0]),
+ .err_logger = &cam150_cpas110_err_logger_offsets,
+ .errata_wa_list = &cam150_cpas110_errata_wa_list,
+};
+
+#endif /* _CPASTOP_V150_110_H_ */
diff --git a/drivers/media/platform/msm/ais/cam_cpas/include/cam_cpas_api.h b/drivers/media/platform/msm/ais/cam_cpas/include/cam_cpas_api.h
index 868591636c09..9486deeaa992 100644
--- a/drivers/media/platform/msm/ais/cam_cpas/include/cam_cpas_api.h
+++ b/drivers/media/platform/msm/ais/cam_cpas/include/cam_cpas_api.h
@@ -42,6 +42,7 @@ enum cam_cpas_reg_base {
enum cam_cpas_hw_version {
CAM_CPAS_TITAN_NONE = 0,
CAM_CPAS_TITAN_150_V100 = 0x150100,
+ CAM_CPAS_TITAN_150_V110 = 0x150110,
CAM_CPAS_TITAN_170_V100 = 0x170100,
CAM_CPAS_TITAN_170_V110 = 0x170110,
CAM_CPAS_TITAN_170_V120 = 0x170120,
diff --git a/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c
index 54b0d57117a1..03a5e4416da8 100644
--- a/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c
+++ b/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.c
@@ -62,104 +62,6 @@ static void __cam_isp_ctx_update_state_monitor_array(
jiffies_to_msecs(jiffies);
}
-static const char *__cam_isp_ctx_substate_val_to_type(
- uint32_t type)
-{
- switch (type) {
- case CAM_ISP_CTX_ACTIVATED_SOF:
- return "SOF";
- case CAM_ISP_CTX_ACTIVATED_APPLIED:
- return "APPLIED";
- case CAM_ISP_CTX_ACTIVATED_EPOCH:
- return "EPOCH";
- case CAM_ISP_CTX_ACTIVATED_BUBBLE:
- return "BUBBLE";
- case CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED:
- return "BUBBLE_APPLIED";
- case CAM_ISP_CTX_ACTIVATED_HALT:
- return "HALT";
- default:
- return "CAM_ISP_CTX_INVALID_STATE";
- }
-}
-
-static const char *__cam_isp_hw_evt_val_to_type(
- uint32_t evt_id)
-{
- switch (evt_id) {
- case CAM_ISP_HW_EVENT_ERROR:
- return "ERROR";
- case CAM_ISP_HW_EVENT_SOF:
- return "SOF";
- case CAM_ISP_HW_EVENT_REG_UPDATE:
- return "REG_UPDATE";
- case CAM_ISP_HW_EVENT_EPOCH:
- return "EPOCH";
- case CAM_ISP_HW_EVENT_EOF:
- return "EOF";
- case CAM_ISP_HW_EVENT_DONE:
- return "DONE";
- default:
- return "CAM_ISP_EVENT_INVALID";
- }
-}
-
-static void __cam_isp_ctx_dump_state_monitor_array(
- struct cam_isp_context *ctx_isp, bool log_rate_limit)
-{
- int i = 0;
- uint64_t state_head = 0;
- uint64_t index;
- struct cam_isp_context_state_monitor *ctx_monitor;
-
- state_head = atomic64_read(&ctx_isp->state_monitor_head);
-
- ctx_monitor = ctx_isp->cam_isp_ctx_state_monitor;
-
- if (log_rate_limit)
- CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20,
- "Dumping state information for preceding requests");
- else
- CAM_INFO(CAM_ISP,
- "Dumping state information for preceding requests");
-
- for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0;
- i--) {
- index = (((state_head - i) +
- CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) %
- CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES);
-
- if (log_rate_limit) {
- CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20,
- "time[%lld] last reported req_id[%u] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]",
- ctx_monitor[index].evt_time_stamp,
- ctx_monitor[index].last_reported_id,
- ctx_monitor[index].frame_id,
- ctx_monitor[index].last_applied_req_id,
- __cam_isp_ctx_substate_val_to_type(
- ctx_monitor[index].curr_state),
- __cam_isp_ctx_substate_val_to_type(
- ctx_monitor[index].next_state),
- __cam_isp_hw_evt_val_to_type(
- ctx_monitor[index].hw_event));
-
- } else {
- CAM_INFO(CAM_ISP,
- "time[%lld] last reported req_id[%u] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]",
- ctx_monitor[index].evt_time_stamp,
- ctx_monitor[index].last_reported_id,
- ctx_monitor[index].frame_id,
- ctx_monitor[index].last_applied_req_id,
- __cam_isp_ctx_substate_val_to_type(
- ctx_monitor[index].curr_state),
- __cam_isp_ctx_substate_val_to_type(
- ctx_monitor[index].next_state),
- __cam_isp_hw_evt_val_to_type(
- ctx_monitor[index].hw_event));
- }
- }
-}
-
static void cam_isp_ctx_dump_req(struct cam_isp_ctx_req *req_isp)
{
int i = 0, rc = 0;
@@ -453,6 +355,14 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
trace_cam_buf_done("ISP", ctx, req);
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = done->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((done->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = done->irq_mono_boot_time;
+
for (i = 0; i < done->num_handles; i++) {
for (j = 0; j < req_isp->num_fence_map_out; j++) {
if (done->resource_handle[i] ==
@@ -566,6 +476,26 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
ctx_isp->substate_activated);
}
+ if (ctx_isp->active_req_cnt && ctx_isp->irq_delay_detect) {
+ CAM_ERR(CAM_ISP, "isp req[%lld] IRQ buf done got delayed",
+ req->request_id);
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+
+ for (j = 0; j < req_isp->num_fence_map_out; j++) {
+ rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
+ CAM_SYNC_STATE_SIGNALED_ERROR);
+ if (rc)
+ CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
+ rc);
+ req_isp->fence_map_out[j].sync_id = -1;
+ }
+ list_del_init(&req->list);
+ list_add_tail(&req->list, &ctx->free_req_list);
+ ctx_isp->active_req_cnt--;
+ }
+ ctx_isp->irq_delay_detect = false;
end:
return rc;
}
@@ -644,12 +574,47 @@ static void __cam_isp_ctx_send_sof_timestamp(
static int __cam_isp_ctx_reg_upd_in_epoch_state(
struct cam_isp_context *ctx_isp, void *evt_data)
{
- if (ctx_isp->frame_id == 1)
+ struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
+
+ struct cam_context *ctx = ctx_isp->base;
+ struct cam_ctx_request *req = NULL;
+ struct cam_isp_ctx_req *req_isp = NULL;
+
+ if (ctx_isp->frame_id == 1) {
CAM_DBG(CAM_ISP, "Reg update for early PCR");
- else
+ if (!list_empty(&ctx->active_req_list)) {
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ } else if (!list_empty(&ctx->wait_req_list)) {
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ }
+ } else {
+ if (!list_empty(&ctx->wait_req_list)) {
+ req = list_first_entry(&ctx->active_req_list,
+ struct cam_ctx_request, list);
+ req_isp = (struct cam_isp_ctx_req *) req->req_priv;
+ }
CAM_WARN(CAM_ISP,
"Unexpected reg update in activated substate:%d for frame_id:%lld",
ctx_isp->substate_activated, ctx_isp->frame_id);
+ }
+
+ if (req_isp && req_isp->hw_update_data.fps) {
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+ CAM_DBG(CAM_ISP, "req_isp %pK, Upadting ctx_isp->fps %d",
+ req_isp, ctx_isp->fps);
+ }
+
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
return 0;
}
@@ -659,7 +624,8 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
int rc = 0;
struct cam_ctx_request *req;
struct cam_context *ctx = ctx_isp->base;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
+ struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
if (list_empty(&ctx->wait_req_list)) {
CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request");
@@ -684,13 +650,22 @@ static int __cam_isp_ctx_reg_upd_in_activated_state(
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
}
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
/*
* This function only called directly from applied and bubble applied
* state so change substate here.
*/
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH;
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
end:
return rc;
}
@@ -747,7 +722,6 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
ctx->ctx_id, request_id,
ctx_isp->req_info.reported_req_id);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
}
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
@@ -818,6 +792,14 @@ static int __cam_isp_ctx_sof_in_activated_state(
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time;
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u",
ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id);
@@ -829,8 +811,9 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
{
int rc = 0;
struct cam_ctx_request *req = NULL;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_context *ctx = ctx_isp->base;
+ struct cam_isp_hw_reg_update_event_data *rup_event_data = evt_data;
if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
CAM_DBG(CAM_ISP, "invalid RUP");
@@ -853,6 +836,16 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
"receive rup in unexpected state");
}
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((rup_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = rup_event_data->irq_mono_boot_time;
end:
return rc;
}
@@ -861,9 +854,10 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
void *evt_data)
{
struct cam_ctx_request *req;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_context *ctx = ctx_isp->base;
uint64_t request_id = 0;
+ struct cam_isp_hw_epoch_event_data *epoch_hw_event_data = evt_data;
if (list_empty(&ctx->wait_req_list)) {
/*
@@ -871,7 +865,6 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
* The recovery is to go back to sof state
*/
CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
/* Send SOF event as empty frame*/
@@ -888,7 +881,6 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld",
ctx->ctx_id, req_isp->bubble_report, req->request_id);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify;
@@ -929,6 +921,15 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
ctx_isp->substate_activated);
end:
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps =
+ epoch_hw_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((epoch_hw_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = epoch_hw_event_data->irq_mono_boot_time;
+
return 0;
}
@@ -961,6 +962,14 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time;
+ if (ctx_isp->frame_id == 1)
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+ else if (ctx_isp->fps && ((sof_event_data->irq_mono_boot_time -
+ ctx_isp->irq_timestamps) > ((1000*1000)/ctx_isp->fps)))
+ ctx_isp->irq_delay_detect = true;
+
+ ctx_isp->irq_timestamps = sof_event_data->irq_mono_boot_time;
+
if (list_empty(&ctx->active_req_list))
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
else
@@ -1013,7 +1022,6 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
* Just go back to the bubble state.
*/
CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@@ -1027,7 +1035,6 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
req_isp->bubble_detected = true;
CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld",
ctx->ctx_id, req_isp->bubble_report, req->request_id);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
@@ -1102,7 +1109,7 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
struct cam_isp_ctx_req *req_isp = NULL;
struct cam_isp_ctx_req *req_isp_to_report = NULL;
struct cam_req_mgr_error_notify notify;
- uint64_t error_request_id;
+ uint64_t error_request_id = 0;
struct cam_hw_fence_map_entry *fence_map_out = NULL;
struct cam_req_mgr_message req_msg;
@@ -1443,7 +1450,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
{
int rc = 0;
struct cam_ctx_request *req = NULL;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_context *ctx = ctx_isp->base;
if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) {
@@ -1467,6 +1474,9 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
"receive rup in unexpected state");
}
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
end:
return rc;
}
@@ -1477,7 +1487,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
int rc = 0;
struct cam_ctx_request *req = NULL;
struct cam_context *ctx = ctx_isp->base;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_req_mgr_trigger_notify notify;
uint64_t request_id = 0;
@@ -1500,6 +1510,9 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
list_add_tail(&req->list, &ctx->free_req_list);
}
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
/*
* This function only called directly from applied and bubble applied
* state so change substate here.
@@ -1902,16 +1915,19 @@ static int __cam_isp_ctx_flush_req_in_top_state(
struct cam_req_mgr_flush_request *flush_req)
{
int rc = 0;
- struct cam_isp_context *ctx_isp;
-
- ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
+ struct cam_isp_context *ctx_isp =
+ (struct cam_isp_context *) ctx->ctx_priv;
+ struct cam_isp_stop_args stop_isp;
+ struct cam_hw_stop_args stop_args;
+ struct cam_isp_start_args start_isp;
+ struct cam_hw_reset_args reset_args;
if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
- CAM_INFO(CAM_ISP, "Last request id to flush is %lld",
- flush_req->req_id);
+ CAM_INFO(CAM_ISP, "ctx id:%d Last request id to flush is %lld",
+ ctx->ctx_id, flush_req->req_id);
ctx->last_flush_req = flush_req->req_id;
}
- CAM_DBG(CAM_ISP, "try to flush pending list");
+ CAM_DBG(CAM_ISP, "ctx id:%d try to flush pending list", ctx->ctx_id);
spin_lock_bh(&ctx->lock);
rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);
@@ -1929,11 +1945,61 @@ static int __cam_isp_ctx_flush_req_in_top_state(
ctx_isp->req_info.last_reported_id_time_stamp,
ctx_isp->req_info.last_bufdone_time_stamp);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
}
spin_unlock_bh(&ctx->lock);
atomic_set(&ctx_isp->process_bubble, 0);
+ if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
+ /* if active and wait list are empty, return */
+ spin_lock_bh(&ctx->lock);
+ if ((list_empty(&ctx->wait_req_list)) &&
+ (list_empty(&ctx->active_req_list))) {
+ spin_unlock_bh(&ctx->lock);
+ CAM_DBG(CAM_ISP, "ctx id:%d active,wait list are empty",
+ ctx->ctx_id);
+ goto end;
+ }
+ spin_unlock_bh(&ctx->lock);
+
+ /* Stop hw first before active list flush */
+ CAM_DBG(CAM_ISP, "ctx id:%d try to stop hw", ctx->ctx_id);
+ stop_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY;
+ stop_isp.stop_only = true;
+ stop_args.args = (void *)&stop_isp;
+ ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
+ &stop_args);
+
+ spin_lock_bh(&ctx->lock);
+ CAM_DBG(CAM_ISP, "try to flush wait list");
+ rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,
+ flush_req);
+ CAM_DBG(CAM_ISP, "try to flush active list");
+ rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
+ flush_req);
+ ctx_isp->active_req_cnt = 0;
+ spin_unlock_bh(&ctx->lock);
+
+ CAM_DBG(CAM_ISP, "try to reset hw");
+ /* Reset hw */
+ reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ rc = ctx->hw_mgr_intf->hw_reset(ctx->hw_mgr_intf->hw_mgr_priv,
+ &reset_args);
+ if (rc)
+ goto end;
+
+ CAM_DBG(CAM_ISP, "ctx id%d try to start hw", ctx->ctx_id);
+ /* Start hw */
+ start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx;
+ start_isp.start_only = true;
+ start_isp.hw_config.priv = NULL;
+
+ rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv,
+ &start_isp);
+ }
+
+end:
+ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
return rc;
}
@@ -2188,7 +2254,6 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
req_isp->bubble_detected = true;
CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld",
ctx->ctx_id, req_isp->bubble_report, req->request_id);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) {
@@ -2315,7 +2380,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
{
struct cam_ctx_request *req;
struct cam_context *ctx = ctx_isp->base;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
struct cam_req_mgr_trigger_notify notify;
uint64_t request_id = 0;
@@ -2370,6 +2435,9 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
jiffies_to_msecs(jiffies);
}
+ if (req_isp && req_isp->hw_update_data.fps)
+ ctx_isp->fps = req_isp->hw_update_data.fps;
+
__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS);
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
@@ -2645,7 +2713,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
{
int rc = 0, i;
struct cam_ctx_request *req = NULL;
- struct cam_isp_ctx_req *req_isp;
+ struct cam_isp_ctx_req *req_isp = NULL;
uintptr_t packet_addr;
struct cam_packet *packet;
size_t len = 0;
@@ -2734,6 +2802,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
rc = -EFAULT;
goto free_cpu_buf;
}
+
req_isp->num_cfg = cfg.num_hw_update_entries;
req_isp->num_fence_map_out = cfg.num_out_map_entries;
req_isp->num_fence_map_in = cfg.num_in_map_entries;
@@ -2790,6 +2859,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
CAM_ERR(CAM_ISP, "Recevied Update in wrong state");
}
}
+
if (rc)
goto put_ref;
@@ -3560,7 +3630,6 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
CAM_ERR_RATE_LIMIT(CAM_ISP,
"Ctx:%d No handle function in activated substate %d",
ctx->ctx_id, ctx_isp->substate_activated);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
rc = -EFAULT;
}
@@ -3571,8 +3640,6 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
return rc;
}
-
-
static int __cam_isp_ctx_handle_irq_in_activated(void *context,
uint32_t evt_id, void *evt_data)
{
@@ -3597,7 +3664,6 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context,
} else {
CAM_INFO(CAM_ISP, "Ctx:%d No handle function for substate %d",
ctx->ctx_id, ctx_isp->substate_activated);
- __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
}
if (evt_id != CAM_ISP_HW_EVENT_DONE)
__cam_isp_ctx_update_state_monitor_array(ctx_isp, evt_id,
diff --git a/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.h
index a4f4e5ae0ee9..cb73252363db 100644
--- a/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.h
+++ b/drivers/media/platform/msm/ais/cam_isp/cam_isp_context.h
@@ -35,6 +35,11 @@
#define CAM_ISP_CTX_CFG_MAX 22
/*
+ * Defalut fps value set to 30
+ */
+#define CAM_ISP_CTX_DEFAULT_FPS 30
+
+/*
* Maximum entries in state monitoring array for error logging
*/
#define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES 20
@@ -180,6 +185,9 @@ struct cam_isp_context_req_id_info {
* @hw_acquired: Indicate whether HW resources are acquired
* @init_received: Indicate whether init config packet is received
* @split_acquire: Indicate whether a separate acquire is expected
+ * @irq_delay_detect: Indicate whether a irq delay has detected or not
+ * @irq_timestamps: Timestamp from last handled IRQ
+ * @fps: Current FPS for the activated state.
*
*/
struct cam_isp_context {
@@ -209,6 +217,9 @@ struct cam_isp_context {
bool hw_acquired;
bool init_received;
bool split_acquire;
+ bool irq_delay_detect;
+ uint64_t irq_timestamps;
+ uint32_t fps;
};
/**
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
index 4bb272ec6329..ca8f26884f41 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
@@ -146,6 +146,74 @@ static int cam_ife_hw_mgr_is_rdi_res(uint32_t res_id)
return rc;
}
+static const char *cam_ife_hw_mgr_get_res_id(
+ enum cam_ife_pix_path_res_id csid_res_id)
+{
+ char *res_name = NULL;
+
+ switch (csid_res_id) {
+ case CAM_IFE_PIX_PATH_RES_RDI_0:
+ res_name = "RDI_0";
+ break;
+ case CAM_IFE_PIX_PATH_RES_RDI_1:
+ res_name = "RDI_1";
+ break;
+ case CAM_IFE_PIX_PATH_RES_RDI_2:
+ res_name = "RDI_2";
+ break;
+ case CAM_IFE_PIX_PATH_RES_RDI_3:
+ res_name = "RDI_3";
+ break;
+ case CAM_IFE_PIX_PATH_RES_IPP:
+ res_name = "IPP";
+ break;
+ case CAM_IFE_PIX_PATH_RES_PPP:
+ res_name = "PPP";
+ break;
+ case CAM_IFE_PIX_PATH_RES_MAX:
+ res_name = "Invalid Max res";
+ break;
+ default:
+ res_name = "Invalid";
+ break;
+ }
+ return res_name;
+}
+
+static const char *cam_ife_hw_mgr_get_res_type(
+ enum cam_isp_resource_type csid_res_type)
+{
+ char *res_type = NULL;
+
+ switch (csid_res_type) {
+ case CAM_ISP_RESOURCE_UNINT:
+ res_type = "Unint";
+ break;
+ case CAM_ISP_RESOURCE_SRC:
+ res_type = "Src";
+ break;
+ case CAM_ISP_RESOURCE_CID:
+ res_type = "Cid";
+ break;
+ case CAM_ISP_RESOURCE_PIX_PATH:
+ res_type = "Pix Path";
+ break;
+ case CAM_ISP_RESOURCE_VFE_IN:
+ res_type = "Vfe In";
+ break;
+ case CAM_ISP_RESOURCE_VFE_OUT:
+ res_type = "Vfe Out";
+ break;
+ case CAM_ISP_RESOURCE_MAX:
+ res_type = "Invalid Max res";
+ break;
+ default:
+ res_type = "Invalid";
+ break;
+ }
+ return res_type;
+}
+
static int cam_ife_hw_mgr_reset_csid_res(
struct cam_ife_hw_mgr_res *isp_hw_res)
{
@@ -599,6 +667,61 @@ static int cam_ife_hw_mgr_get_ctx(
return rc;
}
+static void cam_ife_hw_mgr_dump_all_ctx(
+ struct cam_ife_hw_mgr_ctx *ife_ctx)
+{
+ uint32_t i;
+ struct cam_ife_hw_mgr_ctx *ctx;
+ struct cam_ife_hw_mgr_res *hw_mgr;
+
+ mutex_lock(&g_ife_hw_mgr.ctx_mutex);
+ list_for_each_entry(ctx, &g_ife_hw_mgr.used_ctx_list, list) {
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "ctx id:%d dual:%d in src:%d num_base:%d rdi only:%d",
+ ctx->ctx_index,
+ ctx->res_list_ife_in.is_dual_vfe,
+ ctx->res_list_ife_in.res_id,
+ ctx->num_base, ctx->is_rdi_only_context);
+ list_for_each_entry(hw_mgr, &ctx->res_list_ife_csid,
+ list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr->hw_res[i])
+ continue;
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "csid:%d res_type:%s id:%s state:%d",
+ hw_mgr->hw_res[i]->hw_intf->hw_idx,
+ cam_ife_hw_mgr_get_res_type(
+ hw_mgr->hw_res[i]->res_type),
+ cam_ife_hw_mgr_get_res_id(
+ hw_mgr->hw_res[i]->res_id),
+ hw_mgr->hw_res[i]->res_state);
+ }
+ }
+ list_for_each_entry(hw_mgr, &ctx->res_list_ife_src,
+ list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr->hw_res[i])
+ continue;
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "Src IFE:%d res_type:%s id:%s state:%d",
+ hw_mgr->hw_res[i]->hw_intf->hw_idx,
+ cam_ife_hw_mgr_get_res_type(
+ hw_mgr->hw_res[i]->res_type),
+ cam_ife_hw_mgr_get_res_id(
+ hw_mgr->hw_res[i]->res_id),
+ hw_mgr->hw_res[i]->res_state);
+ }
+ }
+ }
+ CAM_ERR_RATE_LIMIT(CAM_ISP,
+ "Current ctx id:%d dual:%d in src:%d num_base:%d rdi only:%d",
+ ife_ctx->ctx_index,
+ ife_ctx->res_list_ife_in.is_dual_vfe,
+ ife_ctx->res_list_ife_in.res_id,
+ ife_ctx->num_base, ife_ctx->is_rdi_only_context);
+ mutex_unlock(&g_ife_hw_mgr.ctx_mutex);
+}
+
static void cam_ife_mgr_add_base_info(
struct cam_ife_hw_mgr_ctx *ctx,
enum cam_isp_hw_split_id split_id,
@@ -1493,8 +1616,9 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl(
&csid_acquire, sizeof(csid_acquire));
if (rc) {
CAM_ERR(CAM_ISP,
- "Cannot acquire ife csid pxl path rsrc %s",
- (is_ipp) ? "IPP" : "PPP");
+ "Cannot acquire ife csid pxl path rsrc %s, hw=%d rc=%d",
+ (is_ipp) ? "IPP" : "PPP",
+ hw_intf->hw_idx, rc);
goto put_res;
}
@@ -1606,7 +1730,6 @@ static int cam_ife_hw_mgr_acquire_res_ife_csid_rdi(
"CSID Path reserve failed hw=%d rc=%d cid=%d",
hw_intf->hw_idx, rc,
cid_res->hw_res[0]->res_id);
-
goto put_res;
}
@@ -2002,6 +2125,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
return 0;
free_res:
+ /*Dump all the current acquired resources */
+ cam_ife_hw_mgr_dump_all_ctx(ife_ctx);
cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx);
free_cdm:
cam_cdm_release(ife_ctx->cdm_handle);
@@ -2156,11 +2281,13 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
ife_ctx->ctx_in_use = 1;
cam_ife_hw_mgr_put_ctx(&ife_hw_mgr->used_ctx_list, &ife_ctx);
-
CAM_DBG(CAM_ISP, "Exit...(success)");
return 0;
+
free_res:
+ /*Dump all the current acquired resources */
+ cam_ife_hw_mgr_dump_all_ctx(ife_ctx);
cam_ife_hw_mgr_release_hw_for_ctx(ife_ctx);
cam_cdm_release(ife_ctx->cdm_handle);
free_ctx:
@@ -2406,7 +2533,7 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
if (cfg->init_packet) {
rc = wait_for_completion_timeout(
&ctx->config_done_complete,
- msecs_to_jiffies(30));
+ msecs_to_jiffies(50));
if (rc <= 0) {
CAM_ERR(CAM_ISP,
"config done completion timeout for req_id=%llu rc=%d ctx_index %d",
@@ -2556,6 +2683,11 @@ static int cam_ife_mgr_pause_hw(struct cam_ife_hw_mgr_ctx *ctx)
return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_EXCLUDE);
}
+static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx)
+{
+ return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE);
+}
+
/* entry function: stop_hw */
static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
{
@@ -2909,6 +3041,9 @@ start_only:
CAM_DBG(CAM_ISP, "START IFE OUT ... in ctx id:%d",
ctx->ctx_index);
+ if (start_isp->start_only)
+ cam_ife_mgr_resume_hw(ctx);
+
/* start the IFE out devices */
for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
rc = cam_ife_hw_mgr_start_hw_res(
@@ -3009,6 +3144,44 @@ static int cam_ife_mgr_write(void *hw_mgr_priv, void *write_args)
return -EPERM;
}
+static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args)
+{
+ struct cam_ife_hw_mgr *hw_mgr = hw_mgr_priv;
+ struct cam_hw_reset_args *reset_args = hw_reset_args;
+ struct cam_ife_hw_mgr_ctx *ctx;
+ struct cam_ife_hw_mgr_res *hw_mgr_res;
+ uint32_t i;
+ int rc = 0;
+
+ if (!hw_mgr_priv || !hw_reset_args) {
+ CAM_ERR(CAM_ISP, "Invalid arguments");
+ return -EINVAL;
+ }
+
+ ctx = (struct cam_ife_hw_mgr_ctx *)reset_args->ctxt_to_hw_map;
+ if (!ctx || !ctx->ctx_in_use) {
+ CAM_ERR(CAM_ISP, "Invalid context is used");
+ return -EPERM;
+ }
+
+ CAM_DBG(CAM_ISP, "reset csid and vfe hw");
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid,
+ list) {
+ rc = cam_ife_hw_mgr_reset_csid_res(hw_mgr_res);
+ if (rc) {
+ CAM_ERR(CAM_ISP, "Failed RESET (%d) rc:%d",
+ hw_mgr_res->res_id, rc);
+ goto end;
+ }
+ }
+
+ for (i = 0; i < ctx->num_base; i++)
+ rc = cam_ife_mgr_reset_vfe_hw(hw_mgr, ctx->base[i].idx);
+
+end:
+ return rc;
+}
+
static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
void *release_hw_args)
{
@@ -3136,6 +3309,54 @@ static int cam_isp_blob_fe_update(
return rc;
}
+static int cam_isp_blob_fps_config(
+ uint32_t blob_type,
+ struct cam_isp_generic_blob_info *blob_info,
+ struct cam_fps_config *fps_config,
+ 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;
+ struct cam_vfe_fps_config_args fps_config_args;
+ int rc = -EINVAL;
+ uint32_t i;
+
+ ctx = prepare->ctxt_to_hw_map;
+
+ list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
+ for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+ if (!hw_mgr_res->hw_res[i])
+ continue;
+
+ if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) {
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ if (hw_intf && hw_intf->hw_ops.process_cmd) {
+ fps_config_args.fps =
+ fps_config->fps;
+ fps_config_args.node_res =
+ hw_mgr_res->hw_res[i];
+
+ rc = hw_intf->hw_ops.process_cmd(
+ hw_intf->hw_priv,
+ CAM_ISP_HW_CMD_FPS_CONFIG,
+ &fps_config_args,
+ sizeof(
+ struct cam_vfe_fps_config_args)
+ );
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Failed fps config:%d",
+ fps_config->fps);
+ } else
+ CAM_WARN(CAM_ISP, "NULL hw_intf!");
+ }
+ }
+ }
+
+ return rc;
+}
+
static int cam_isp_blob_ubwc_update(
uint32_t blob_type,
struct cam_isp_generic_blob_info *blob_info,
@@ -3512,6 +3733,75 @@ static int cam_isp_blob_clock_update(
return rc;
}
+static int cam_isp_blob_sensor_config(
+ uint32_t blob_type,
+ struct cam_isp_generic_blob_info *blob_info,
+ struct cam_isp_sensor_config *dim_config,
+ 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;
+ struct cam_ife_sensor_dimension_update_args update_args;
+ int rc = -EINVAL, found = 0;
+ uint32_t i, j;
+ struct cam_isp_sensor_dimension *path_config;
+
+ 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;
+ found = 1;
+ hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
+ if (hw_intf && hw_intf->hw_ops.process_cmd) {
+ path_config = &(dim_config->ipp_path);
+ update_args.ipp_path.width =
+ path_config->width;
+ update_args.ipp_path.height =
+ path_config->height;
+ update_args.ipp_path.measure_enabled =
+ path_config->measure_enabled;
+ path_config = &(dim_config->ppp_path);
+ update_args.ppp_path.width =
+ path_config->width;
+ update_args.ppp_path.height =
+ path_config->height;
+ update_args.ppp_path.measure_enabled =
+ path_config->measure_enabled;
+ for (j = 0; j < CAM_IFE_RDI_NUM_MAX; j++) {
+ path_config =
+ &(dim_config->rdi_path[j]);
+ update_args.rdi_path[j].width =
+ path_config->width;
+ update_args.rdi_path[j].height =
+ path_config->height;
+ update_args.rdi_path[j].measure_enabled =
+ path_config->measure_enabled;
+ }
+ rc = hw_intf->hw_ops.process_cmd(
+ hw_intf->hw_priv,
+ CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
+ &update_args,
+ sizeof(
+ struct
+ cam_ife_sensor_dimension_update_args)
+ );
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Dimension Update failed");
+ } else
+ CAM_ERR(CAM_ISP, "hw_intf is NULL");
+ }
+ if (found)
+ break;
+ }
+
+ return rc;
+}
+
+
static void fill_res_bitmap(uint32_t resource_type, unsigned long *res_bitmap)
{
@@ -3852,6 +4142,49 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
CAM_ERR(CAM_ISP, "Init Frame drop Update Failed");
}
break;
+ case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_DIMENSION_CONFIG: {
+ struct cam_isp_sensor_config *csid_dim_config;
+
+ if (blob_size < sizeof(struct cam_isp_sensor_config)) {
+ CAM_ERR(CAM_ISP, "Invalid blob size %u expected %u",
+ blob_size,
+ sizeof(struct cam_isp_sensor_config));
+ return -EINVAL;
+ }
+
+ csid_dim_config =
+ (struct cam_isp_sensor_config *)blob_data;
+
+ rc = cam_isp_blob_sensor_config(blob_type, blob_info,
+ csid_dim_config, prepare);
+ if (rc)
+ CAM_ERR(CAM_ISP,
+ "Sensor Dimension Update Failed rc: %d", rc);
+ }
+ break;
+ case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG: {
+ struct cam_fps_config *fps_config;
+ struct cam_isp_prepare_hw_update_data *prepare_hw_data;
+
+ if (blob_size < sizeof(struct cam_fps_config)) {
+ CAM_ERR(CAM_ISP, "Invalid fps blob size %u expected %u",
+ blob_size, sizeof(struct cam_fps_config));
+ return -EINVAL;
+ }
+
+ fps_config = (struct cam_fps_config *)blob_data;
+ prepare_hw_data = (struct cam_isp_prepare_hw_update_data *)
+ prepare->priv;
+
+ prepare_hw_data->fps = fps_config->fps;
+
+ rc = cam_isp_blob_fps_config(blob_type, blob_info,
+ fps_config, prepare);
+ if (rc)
+ CAM_ERR(CAM_ISP, "FPS Update Failed rc: %d", rc);
+
+ }
+ break;
default:
CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
break;
@@ -4009,10 +4342,6 @@ end:
return rc;
}
-static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx)
-{
- return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE);
-}
static int cam_ife_mgr_sof_irq_debug(
struct cam_ife_hw_mgr_ctx *ctx,
@@ -4750,6 +5079,8 @@ static int cam_ife_hw_mgr_handle_reg_update(
break;
if (!rup_status) {
+ rup_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hwr_irq_rup_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_REG_UPDATE,
@@ -4779,6 +5110,8 @@ static int cam_ife_hw_mgr_handle_reg_update(
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
if (!rup_status) {
+ rup_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
/* Send the Reg update hw event */
ife_hwr_irq_rup_cb(
ife_hwr_mgr_ctx->common.cb_priv,
@@ -5138,6 +5471,8 @@ static int cam_ife_hw_mgr_handle_sof(
ife_hw_mgr_ctx,
&sof_done_event_data.timestamp,
&sof_done_event_data.boot_time);
+ sof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hw_irq_sof_cb(
ife_hw_mgr_ctx->common.cb_priv,
@@ -5161,6 +5496,8 @@ static int cam_ife_hw_mgr_handle_sof(
ife_hw_mgr_ctx,
&sof_done_event_data.timestamp,
&sof_done_event_data.boot_time);
+ sof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hw_irq_sof_cb(
ife_hw_mgr_ctx->common.cb_priv,
@@ -5246,13 +5583,15 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
if (atomic_read(
&ife_hwr_mgr_ctx->overflow_pending))
break;
- if (!eof_status)
+ if (!eof_status) {
+ eof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hwr_irq_eof_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_EOF,
&eof_done_event_data);
+ }
}
-
break;
/* Handling dual VFE Scenario */
case 1:
@@ -5293,11 +5632,14 @@ static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res(
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
- if (!rc)
+ if (!rc) {
+ eof_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
ife_hwr_irq_eof_cb(
ife_hwr_mgr_ctx->common.cb_priv,
CAM_ISP_HW_EVENT_EOF,
&eof_done_event_data);
+ }
break;
@@ -5397,6 +5739,8 @@ static int cam_ife_hw_mgr_handle_buf_done_for_hw_res(
if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending))
break;
+ buf_done_event_data.irq_mono_boot_time =
+ evt_payload->ts.time_usecs;
/* Report for Successful buf_done event if any */
if (buf_done_event_data.num_handles > 0 &&
ife_hwr_irq_wm_done_cb) {
@@ -5836,6 +6180,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
hw_mgr_intf->hw_prepare_update = cam_ife_mgr_prepare_hw_update;
hw_mgr_intf->hw_config = cam_ife_mgr_config_hw;
hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd;
+ hw_mgr_intf->hw_reset = cam_ife_mgr_reset;
if (iommu_hdl)
*iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl;
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
index 096e0f186bbf..1ab9361af1d1 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
@@ -130,6 +130,7 @@ struct cam_isp_bw_config_internal {
* @bw_config: BW config information
* @bw_config_valid: Flag indicating whether the bw_config at the index
* is valid or not
+ * @fps: fps vaue which has been updated in hw
*
*/
struct cam_isp_prepare_hw_update_data {
@@ -137,40 +138,47 @@ struct cam_isp_prepare_hw_update_data {
struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX];
struct cam_isp_bw_config_internal_ab bw_config_ab[CAM_IFE_HW_NUM_MAX];
bool bw_config_valid[CAM_IFE_HW_NUM_MAX];
+ uint32_t fps;
};
/**
* struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF
*
- * @timestamp: Time stamp for the sof event
- * @boot_time: Boot time stamp for the sof event
+ * @timestamp: Time stamp for the sof event
+ * @boot_time: Boot time stamp for the sof event
+ * @irq_mono_boot_time: Time stamp till the execution of IRQ wrt event started
*
*/
struct cam_isp_hw_sof_event_data {
uint64_t timestamp;
uint64_t boot_time;
+ uint64_t irq_mono_boot_time;
};
/**
* struct cam_isp_hw_reg_update_event_data - Event payload for
* CAM_HW_EVENT_REG_UPDATE
*
- * @timestamp: Time stamp for the reg update event
+ * @timestamp: Time stamp for the reg update event
+ * @irq_mono_boot_time: Time stamp till the execution of IRQ wrt event started
*
*/
struct cam_isp_hw_reg_update_event_data {
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
* struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH
*
- * @timestamp: Time stamp for the epoch event
+ * @timestamp: Time stamp for the epoch event
+ * @irq_mono_boot_time: Time stamp till the execution of this event started
*
*/
struct cam_isp_hw_epoch_event_data {
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
@@ -179,6 +187,7 @@ struct cam_isp_hw_epoch_event_data {
* @num_handles: Number of resource handeles
* @resource_handle: Resource handle array
* @timestamp: Timestamp for the buf done event
+ * @irq_mono_boot_time: Time stamp till the execution of this event started
*
*/
struct cam_isp_hw_done_event_data {
@@ -186,16 +195,19 @@ struct cam_isp_hw_done_event_data {
uint32_t resource_handle[
CAM_NUM_OUT_PER_COMP_IRQ_MAX];
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
* struct cam_isp_hw_eof_event_data - Event payload for CAM_HW_EVENT_EOF
*
* @timestamp: Timestamp for the eof event
+ * @irq_mono_boot_time: Time stamp till the execution of this event started
*
*/
struct cam_isp_hw_eof_event_data {
uint64_t timestamp;
+ uint64_t irq_mono_boot_time;
};
/**
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile
index 027d8d4b11eb..bac27015691c 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/Makefile
@@ -8,5 +8,6 @@ ccflags-y += -Idrivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include
ccflags-y += -Idrivers/media/platform/msm/ais/cam_smmu/
ccflags-y += -Idrivers/media/platform/msm/ais/cam_req_mgr/
+obj-$(CONFIG_MSM_AIS) += cam_csid_ppi_dev.o cam_csid_ppi_core.o cam_csid_ppi170.o
obj-$(CONFIG_MSM_AIS) += cam_ife_csid_dev.o cam_ife_csid_soc.o cam_ife_csid_core.o
obj-$(CONFIG_MSM_AIS) += cam_ife_csid17x.o cam_ife_csid_lite17x.o
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c
new file mode 100644
index 000000000000..2051292be5be
--- /dev/null
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.c
@@ -0,0 +1,58 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include "cam_csid_ppi_core.h"
+#include "cam_csid_ppi170.h"
+#include "cam_csid_ppi_dev.h"
+
+#define CAM_PPI_DRV_NAME "ppi_170"
+#define CAM_PPI_VERSION_V170 0x10070000
+
+static struct cam_csid_ppi_hw_info cam_csid_ppi170_hw_info = {
+ .ppi_reg = &cam_csid_ppi_170_reg_offset,
+};
+
+static const struct of_device_id cam_csid_ppi170_dt_match[] = {
+ {
+ .compatible = "qcom,ppi170",
+ .data = &cam_csid_ppi170_hw_info,
+ },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, cam_csid_ppi170_dt_match);
+
+static struct platform_driver cam_csid_ppi170_driver = {
+ .probe = cam_csid_ppi_probe,
+ .remove = cam_csid_ppi_remove,
+ .driver = {
+ .name = CAM_PPI_DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = cam_csid_ppi170_dt_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init cam_csid_ppi170_init_module(void)
+{
+ return platform_driver_register(&cam_csid_ppi170_driver);
+}
+
+static void __exit cam_csid_ppi170_exit_module(void)
+{
+ platform_driver_unregister(&cam_csid_ppi170_driver);
+}
+
+module_init(cam_csid_ppi170_init_module);
+MODULE_DESCRIPTION("CAM CSID_PPI170 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h
new file mode 100644
index 000000000000..0ec767204914
--- /dev/null
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi170.h
@@ -0,0 +1,32 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAM_CSID_PPI_170_H_
+#define _CAM_CSID_PPI_170_H_
+
+#include "cam_csid_ppi_core.h"
+
+static struct cam_csid_ppi_reg_offset cam_csid_ppi_170_reg_offset = {
+ .ppi_hw_version_addr = 0,
+ .ppi_module_cfg_addr = 0x60,
+ .ppi_irq_status_addr = 0x68,
+ .ppi_irq_mask_addr = 0x6c,
+ .ppi_irq_set_addr = 0x70,
+ .ppi_irq_clear_addr = 0x74,
+ .ppi_irq_cmd_addr = 0x78,
+ .ppi_rst_cmd_addr = 0x7c,
+ .ppi_test_bus_ctrl_addr = 0x1f4,
+ .ppi_debug_addr = 0x1f8,
+ .ppi_spare_addr = 0x1fc,
+};
+
+#endif /*_CAM_CSID_PPI_170_H_ */
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c
new file mode 100644
index 000000000000..3d521b747e96
--- /dev/null
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.c
@@ -0,0 +1,395 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+#include <uapi/media/cam_defs.h>
+
+#include "cam_csid_ppi_core.h"
+#include "cam_csid_ppi_dev.h"
+#include "cam_soc_util.h"
+#include "cam_debug_util.h"
+#include "cam_io_util.h"
+
+static int cam_csid_ppi_reset(struct cam_csid_ppi_hw *ppi_hw)
+{
+ struct cam_hw_soc_info *soc_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ int rc = 0;
+ uint32_t status;
+
+ soc_info = &ppi_hw->hw_info->soc_info;
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+
+ CAM_DBG(CAM_ISP, "PPI:%d reset", ppi_hw->hw_intf->hw_idx);
+
+ /* Mask all interrupts */
+ cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_mask_addr);
+ cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_set_addr);
+ cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_rst_cmd_addr);
+ cam_io_w_mb(PPI_IRQ_CMD_SET, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_cmd_addr);
+
+ rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_status_addr, status,
+ (status & 0x1) == 0x1, 1000, 500000);
+ CAM_DBG(CAM_ISP, "PPI:%d reset status %d", ppi_hw->hw_intf->hw_idx,
+ status);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d ppi_reset fail rc = %d status = %d",
+ ppi_hw->hw_intf->hw_idx, rc, status);
+ return rc;
+ }
+ cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_clear_addr);
+ cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_cmd_addr);
+
+ return 0;
+}
+
+static int cam_csid_ppi_enable_hw(struct cam_csid_ppi_hw *ppi_hw)
+{
+ int rc = 0;
+ uint32_t i;
+ uint64_t val;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ struct cam_hw_soc_info *soc_info;
+ uint32_t err_irq_mask;
+
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+ soc_info = &ppi_hw->hw_info->soc_info;
+
+ CAM_DBG(CAM_ISP, "PPI:%d init PPI HW", ppi_hw->hw_intf->hw_idx);
+
+ for (i = 0; i < soc_info->num_clk; i++) {
+ /* Passing zero in clk_rate results in setting no clk_rate */
+ rc = cam_soc_util_clk_enable(soc_info->clk[i],
+ soc_info->clk_name[i], 0);
+ if (rc)
+ goto clk_disable;
+ }
+
+ /* Reset PPI */
+ rc = cam_csid_ppi_reset(ppi_hw);
+ if (rc)
+ goto clk_disable;
+
+ err_irq_mask = PPI_IRQ_FIFO0_OVERFLOW | PPI_IRQ_FIFO1_OVERFLOW |
+ PPI_IRQ_FIFO2_OVERFLOW;
+ cam_io_w_mb(err_irq_mask, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_mask_addr);
+ rc = cam_soc_util_irq_enable(soc_info);
+ if (rc)
+ goto clk_disable;
+ /* Clear the RST done IRQ */
+ cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_clear_addr);
+ cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_cmd_addr);
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_hw_version_addr);
+ CAM_DBG(CAM_ISP, "PPI:%d PPI HW version: 0x%x",
+ ppi_hw->hw_intf->hw_idx, val);
+ ppi_hw->device_enabled = 1;
+
+ return 0;
+clk_disable:
+ for (--i; i >= 0; i--)
+ cam_soc_util_clk_disable(soc_info->clk[i],
+ soc_info->clk_name[i]);
+ return rc;
+}
+
+static int cam_csid_ppi_disable_hw(struct cam_csid_ppi_hw *ppi_hw)
+{
+ int rc = 0;
+ int i;
+ struct cam_hw_soc_info *soc_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ uint64_t ppi_cfg_val = 0;
+
+ CAM_DBG(CAM_ISP, "PPI:%d De-init PPI HW",
+ ppi_hw->hw_intf->hw_idx);
+
+ soc_info = &ppi_hw->hw_info->soc_info;
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+
+ CAM_DBG(CAM_ISP, "%s:Calling PPI Reset\n", __func__);
+ cam_csid_ppi_reset(ppi_hw);
+ CAM_DBG(CAM_ISP, "%s:PPI Reset Done\n", __func__);
+
+ /* disable the clocks */
+ for (i = 0; i < soc_info->num_clk; i++)
+ cam_soc_util_clk_disable(soc_info->clk[i],
+ soc_info->clk_name[i]);
+
+ /* disable the interrupt */
+ cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_mask_addr);
+ cam_soc_util_irq_disable(soc_info);
+
+ /* disable lanes */
+ for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
+ ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
+
+ cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_module_cfg_addr);
+
+ ppi_hw->device_enabled = 0;
+
+ return rc;
+}
+
+static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args,
+ uint32_t arg_size)
+{
+ int i, rc = 0;
+ uint32_t num_lanes;
+ uint32_t lanes[CAM_CSID_PPI_HW_MAX] = {0, 0, 0, 0};
+ uint32_t cphy;
+ bool dl0, dl1;
+ uint32_t ppi_cfg_val = 0;
+ struct cam_csid_ppi_hw *ppi_hw;
+ struct cam_hw_info *ppi_hw_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+ struct cam_hw_soc_info *soc_info;
+ struct cam_csid_ppi_cfg ppi_cfg;
+
+ if (!hw_priv || !init_args ||
+ (arg_size != sizeof(struct cam_csid_ppi_cfg))) {
+ CAM_ERR(CAM_ISP, "PPI: Invalid args");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ dl0 = dl1 = false;
+ ppi_hw_info = (struct cam_hw_info *)hw_priv;
+ ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+ ppi_cfg = *((struct cam_csid_ppi_cfg *)init_args);
+
+ /* Initialize the ppi hardware */
+ rc = cam_csid_ppi_enable_hw(ppi_hw);
+ if (rc)
+ goto end;
+
+ /* Do lane configuration here*/
+ num_lanes = ppi_cfg.lane_num;
+ /* lane_type = 1 refers to cphy */
+ cphy = ppi_cfg.lane_type;
+ CAM_DBG(CAM_ISP, "lane_cfg 0x%x | num_lanes 0x%x | lane_type 0x%x",
+ ppi_cfg.lane_cfg, num_lanes, cphy);
+
+ for (i = 0; i < num_lanes; i++) {
+ lanes[i] = (ppi_cfg.lane_cfg & (0x3 << (4 * i))) >> (4*i);
+ (lanes[i] < 2) ? (dl0 = true) : (dl1 = true);
+ CAM_DBG(CAM_ISP, "lanes[%d] %d", i, lanes[i]);
+ }
+
+ if (num_lanes) {
+ if (cphy) {
+ for (i = 0; i < num_lanes; i++) {
+ /* Select Cphy */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(lanes[i]);
+ /* Enable lane Cphy */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(lanes[i]);
+ }
+ } else {
+ if (dl0)
+ /* Enable lane 0 */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(0);
+ if (dl1)
+ /* Enable lane 1 */
+ ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(1);
+ }
+ } else {
+ CAM_ERR(CAM_ISP,
+ "Number of lanes to enable is cannot be zero");
+ rc = -1;
+ goto end;
+ }
+
+ CAM_DBG(CAM_ISP, "ppi_cfg_val 0x%x", ppi_cfg_val);
+ soc_info = &ppi_hw->hw_info->soc_info;
+ cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_module_cfg_addr);
+
+ CAM_DBG(CAM_ISP, "ppi cfg 0x%x",
+ cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_module_cfg_addr));
+end:
+ return rc;
+}
+
+static int cam_csid_ppi_deinit_hw(void *hw_priv, void *deinit_args,
+ uint32_t arg_size)
+{
+ int rc = 0;
+ struct cam_csid_ppi_hw *ppi_hw;
+ struct cam_hw_info *ppi_hw_info;
+
+ CAM_DBG(CAM_ISP, "Enter");
+
+ if (!hw_priv) {
+ CAM_ERR(CAM_ISP, "PPI:Invalid arguments");
+ rc = -EINVAL;
+ goto end;
+ }
+
+ ppi_hw_info = (struct cam_hw_info *)hw_priv;
+ ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
+
+ CAM_DBG(CAM_ISP, "Disabling PPI Hw\n");
+ rc = cam_csid_ppi_disable_hw(ppi_hw);
+ if (rc < 0)
+ CAM_DBG(CAM_ISP, "%s: Exit with %d\n", __func__, rc);
+end:
+ return rc;
+}
+
+int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
+ uint32_t ppi_idx)
+{
+ int rc = -EINVAL;
+ struct cam_hw_info *ppi_hw_info;
+ struct cam_csid_ppi_hw *csid_ppi_hw = NULL;
+
+ if (ppi_idx >= CAM_CSID_PPI_HW_MAX) {
+ CAM_ERR(CAM_ISP, "Invalid ppi index:%d", ppi_idx);
+ goto err;
+ }
+
+ ppi_hw_info = (struct cam_hw_info *) ppi_hw_intf->hw_priv;
+ csid_ppi_hw = (struct cam_csid_ppi_hw *) ppi_hw_info->core_info;
+
+ csid_ppi_hw->hw_intf = ppi_hw_intf;
+ csid_ppi_hw->hw_info = ppi_hw_info;
+
+ CAM_DBG(CAM_ISP, "type %d index %d",
+ csid_ppi_hw->hw_intf->hw_type, ppi_idx);
+
+ rc = cam_csid_ppi_init_soc_resources(&csid_ppi_hw->hw_info->soc_info,
+ cam_csid_ppi_irq, csid_ppi_hw);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d Failed to init_soc", ppi_idx);
+ goto err;
+ }
+
+ csid_ppi_hw->hw_intf->hw_ops.init = cam_csid_ppi_init_hw;
+ csid_ppi_hw->hw_intf->hw_ops.deinit = cam_csid_ppi_deinit_hw;
+ return 0;
+err:
+ return rc;
+}
+
+int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
+ irq_handler_t ppi_irq_handler, void *irq_data)
+{
+ int rc = 0;
+
+ rc = cam_soc_util_get_dt_properties(soc_info);
+ if (rc) {
+ CAM_ERR(CAM_ISP, "PPI: Failed to get dt properties");
+ goto end;
+ }
+
+ rc = cam_soc_util_request_platform_resource(soc_info, ppi_irq_handler,
+ irq_data);
+ if (rc) {
+ CAM_ERR(CAM_ISP,
+ "PPI: Error Request platform resources failed rc=%d",
+ rc);
+ goto err;
+ }
+end:
+ return rc;
+err:
+ cam_soc_util_release_platform_resource(soc_info);
+ return rc;
+}
+
+irqreturn_t cam_csid_ppi_irq(int irq_num, void *data)
+{
+ uint32_t irq_status = 0;
+ uint32_t i, ppi_cfg_val = 0;
+ bool fatal_err_detected = false;
+
+ struct cam_csid_ppi_hw *ppi_hw;
+ struct cam_hw_soc_info *soc_info;
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+
+ if (!data) {
+ CAM_ERR(CAM_ISP, "PPI: Invalid arguments");
+ return IRQ_HANDLED;
+ }
+
+ ppi_hw = (struct cam_csid_ppi_hw *)data;
+ ppi_reg = ppi_hw->ppi_info->ppi_reg;
+ soc_info = &ppi_hw->hw_info->soc_info;
+
+ /* read */
+ irq_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_status_addr);
+
+ /* clear */
+ cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_clear_addr);
+
+ cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_irq_cmd_addr);
+
+ CAM_DBG(CAM_ISP, "PPI %d irq status 0x%x", ppi_hw->hw_intf->hw_idx,
+ irq_status);
+
+ if (ppi_hw->device_enabled == 1) {
+ if (irq_status & PPI_IRQ_RST_DONE) {
+ CAM_DBG(CAM_ISP, "PPI Reset Done");
+ goto ret;
+ }
+ if ((irq_status & PPI_IRQ_FIFO0_OVERFLOW) ||
+ (irq_status & PPI_IRQ_FIFO1_OVERFLOW) ||
+ (irq_status & PPI_IRQ_FIFO2_OVERFLOW)) {
+ fatal_err_detected = true;
+ goto handle_fatal_error;
+ }
+ }
+
+handle_fatal_error:
+ if (fatal_err_detected) {
+ CAM_ERR(CAM_ISP, "PPI: %d irq_status:0x%x",
+ ppi_hw->hw_intf->hw_idx, irq_status);
+ /* disable lanes */
+ for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
+ ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
+
+ cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
+ ppi_reg->ppi_module_cfg_addr);
+ }
+ret:
+ CAM_DBG(CAM_ISP, "IRQ Handling exit");
+ return IRQ_HANDLED;
+}
+
+int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw)
+{
+ if (!csid_ppi_hw) {
+ CAM_ERR(CAM_ISP, "Invalid param");
+ return -EINVAL;
+ }
+ /* release the privdate data memory from resources */
+ return cam_soc_util_release_platform_resource(
+ &csid_ppi_hw->hw_info->soc_info);
+}
+
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h
new file mode 100644
index 000000000000..720ac4cd9a6b
--- /dev/null
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_core.h
@@ -0,0 +1,103 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAM_CSID_PPI_HW_H_
+#define _CAM_CSID_PPI_HW_H_
+
+#include "cam_hw.h"
+#include "cam_hw_intf.h"
+
+#define CAM_CSID_PPI_HW_MAX 4
+#define CAM_CSID_PPI_LANES_MAX 3
+
+#define PPI_IRQ_RST_DONE BIT(0)
+#define PPI_IRQ_FIFO0_OVERFLOW BIT(1)
+#define PPI_IRQ_FIFO1_OVERFLOW BIT(2)
+#define PPI_IRQ_FIFO2_OVERFLOW BIT(3)
+
+#define PPI_IRQ_CMD_SET BIT(1)
+
+#define PPI_IRQ_CMD_CLEAR BIT(0)
+
+#define PPI_RST_CONTROL BIT(0)
+/*
+ * Select the PHY (CPHY set '1' or DPHY set '0')
+ */
+#define PPI_CFG_CPHY_DLX_SEL(X) ((X < 2) ? BIT(X) : 0)
+
+#define PPI_CFG_CPHY_DLX_EN(X) BIT(4+X)
+
+struct cam_csid_ppi_reg_offset {
+ uint32_t ppi_hw_version_addr;
+ uint32_t ppi_module_cfg_addr;
+
+ uint32_t ppi_irq_status_addr;
+ uint32_t ppi_irq_mask_addr;
+ uint32_t ppi_irq_set_addr;
+ uint32_t ppi_irq_clear_addr;
+ uint32_t ppi_irq_cmd_addr;
+ uint32_t ppi_rst_cmd_addr;
+ uint32_t ppi_test_bus_ctrl_addr;
+ uint32_t ppi_debug_addr;
+ uint32_t ppi_spare_addr;
+};
+
+/**
+ * struct cam_csid_ppi_hw_info- ppi HW info
+ *
+ * @ppi_reg: ppi register offsets
+ *
+ */
+struct cam_csid_ppi_hw_info {
+ const struct cam_csid_ppi_reg_offset *ppi_reg;
+};
+
+/**
+ * struct cam_csid_ppi_hw- ppi hw device resources data
+ *
+ * @hw_intf: contain the ppi hw interface information
+ * @hw_info: ppi hw device information
+ * @ppi_info: ppi hw specific information
+ * @device_enabled Device enabled will set once ppi powered on and
+ * initial configuration are done.
+ * @lock_state ppi spin lock
+ *
+ */
+struct cam_csid_ppi_hw {
+ struct cam_hw_intf *hw_intf;
+ struct cam_hw_info *hw_info;
+ struct cam_csid_ppi_hw_info *ppi_info;
+ uint32_t device_enabled;
+};
+
+/**
+ * struct cam_csid_ppi_cfg - ppi lane configuration data
+ * @lane_type: lane type: c-phy or d-phy
+ * @lane_num : active lane number
+ * @lane_cfg: lane configurations: 4 bits per lane
+ *
+ */
+struct cam_csid_ppi_cfg {
+ uint32_t lane_type;
+ uint32_t lane_num;
+ uint32_t lane_cfg;
+};
+
+int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
+ uint32_t ppi_idx);
+int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw);
+int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
+ irq_handler_t ppi_irq_handler, void *irq_data);
+int cam_csid_ppi_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
+int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
+ uint32_t hw_idx);
+#endif /* _CAM_CSID_PPI_HW_H_ */
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c
new file mode 100644
index 000000000000..9bdfc5ff61b3
--- /dev/null
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.c
@@ -0,0 +1,147 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
+
+#include "cam_isp_hw.h"
+#include "cam_hw_intf.h"
+#include "cam_csid_ppi_core.h"
+#include "cam_csid_ppi_dev.h"
+#include "cam_debug_util.h"
+
+static struct cam_hw_intf *cam_csid_ppi_hw_list[CAM_CSID_PPI_HW_MAX] = {
+ NULL, NULL, NULL, NULL};
+static char ppi_dev_name[8];
+
+int cam_csid_ppi_probe(struct platform_device *pdev)
+{
+ struct cam_hw_intf *ppi_hw_intf;
+ struct cam_hw_info *ppi_hw_info;
+ struct cam_csid_ppi_hw *ppi_dev = NULL;
+ const struct of_device_id *match_dev = NULL;
+ struct cam_csid_ppi_hw_info *ppi_hw_data = NULL;
+ uint32_t ppi_dev_idx;
+ int rc = 0;
+
+ CAM_DBG(CAM_ISP, "PPI probe called");
+
+ ppi_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
+ if (!ppi_hw_intf) {
+ rc = -ENOMEM;
+ goto err;
+ }
+
+ ppi_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
+ if (!ppi_hw_info) {
+ rc = -ENOMEM;
+ goto free_hw_intf;
+ }
+
+ ppi_dev = kzalloc(sizeof(struct cam_csid_ppi_hw), GFP_KERNEL);
+ if (!ppi_dev) {
+ rc = -ENOMEM;
+ goto free_hw_info;
+ }
+
+ /* get csid ppi hw index */
+ of_property_read_u32(pdev->dev.of_node, "cell-index", &ppi_dev_idx);
+
+ /* get csid ppi hw information */
+ match_dev = of_match_device(pdev->dev.driver->of_match_table,
+ &pdev->dev);
+ if (!match_dev) {
+ CAM_ERR(CAM_ISP, "No matching table for the CSID PPI HW!");
+ rc = -EINVAL;
+ goto free_dev;
+ }
+
+ memset(ppi_dev_name, 0, sizeof(ppi_dev_name));
+ snprintf(ppi_dev_name, sizeof(ppi_dev_name), "ppi%1u", ppi_dev_idx);
+
+ ppi_hw_intf->hw_idx = ppi_dev_idx;
+ ppi_hw_intf->hw_priv = ppi_hw_info;
+
+ ppi_hw_info->core_info = ppi_dev;
+ ppi_hw_info->soc_info.pdev = pdev;
+ ppi_hw_info->soc_info.dev = &pdev->dev;
+ ppi_hw_info->soc_info.dev_name = ppi_dev_name;
+ ppi_hw_info->soc_info.index = ppi_dev_idx;
+
+ ppi_hw_data = (struct cam_csid_ppi_hw_info *)match_dev->data;
+ /* need to setup the pdev before call the csid ppi hw probe init */
+ ppi_dev->ppi_info = ppi_hw_data;
+
+ rc = cam_csid_ppi_hw_probe_init(ppi_hw_intf, ppi_dev_idx);
+ if (rc) {
+ CAM_ERR(CAM_ISP, "PPI: Probe init failed!");
+ goto free_dev;
+ }
+
+ platform_set_drvdata(pdev, ppi_dev);
+ CAM_DBG(CAM_ISP, "PPI:%d probe successful",
+ ppi_hw_intf->hw_idx);
+
+ if (ppi_hw_intf->hw_idx < CAM_CSID_PPI_HW_MAX)
+ cam_csid_ppi_hw_list[ppi_hw_intf->hw_idx] = ppi_hw_intf;
+ else
+ goto free_dev;
+
+ return 0;
+free_dev:
+ kfree(ppi_dev);
+free_hw_info:
+ kfree(ppi_hw_info);
+free_hw_intf:
+ kfree(ppi_hw_intf);
+err:
+ return rc;
+}
+
+int cam_csid_ppi_remove(struct platform_device *pdev)
+{
+ struct cam_csid_ppi_hw *ppi_dev = NULL;
+ struct cam_hw_intf *ppi_hw_intf;
+ struct cam_hw_info *ppi_hw_info;
+
+ ppi_dev = (struct cam_csid_ppi_hw *)platform_get_drvdata(pdev);
+ ppi_hw_intf = ppi_dev->hw_intf;
+ ppi_hw_info = ppi_dev->hw_info;
+
+ CAM_DBG(CAM_ISP, "PPI:%d remove", ppi_dev->hw_intf->hw_idx);
+
+ cam_csid_ppi_hw_deinit(ppi_dev);
+
+ /* release the ppi device memory */
+ kfree(ppi_dev);
+ kfree(ppi_hw_info);
+ kfree(ppi_hw_intf);
+ return 0;
+}
+
+int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
+ uint32_t hw_idx)
+{
+ int rc = 0;
+
+ if (cam_csid_ppi_hw_list[hw_idx]) {
+ *csid_ppi_hw = cam_csid_ppi_hw_list[hw_idx];
+ } else {
+ *csid_ppi_hw = NULL;
+ rc = -1;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(cam_csid_ppi_hw_init);
+
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h
new file mode 100644
index 000000000000..b2ebeaf92947
--- /dev/null
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_csid_ppi_dev.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CAM_CSID_PPI_DEV_H_
+#define _CAM_CSID_PPI_DEV_H_
+
+#include "cam_isp_hw.h"
+
+irqreturn_t cam_csid_ppi_irq(int irq_num, void *data);
+int cam_csid_ppi_probe(struct platform_device *pdev);
+int cam_csid_ppi_remove(struct platform_device *pdev);
+
+#endif /*_CAM_CSID_PPI_DEV_H_ */
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
index 576e8cb8d3b8..6254b97c436a 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid170.h
@@ -293,6 +293,10 @@ static struct cam_ife_csid_common_reg_offset
.ppp_irq_mask_all = 0x0,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
+ .format_measure_height_mask_val = 0xFFFF,
+ .format_measure_height_shift_val = 0x10,
+ .format_measure_width_mask_val = 0xFFFF,
+ .format_measure_width_shift_val = 0x0,
};
static struct cam_ife_csid_reg_offset cam_ife_csid_170_reg_offset = {
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h
index 8116cb452b35..680b641038cf 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175.h
@@ -334,6 +334,10 @@ static struct cam_ife_csid_common_reg_offset
.ppp_irq_mask_all = 0xFFFF,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
+ .format_measure_height_mask_val = 0xFFFF,
+ .format_measure_height_shift_val = 0x10,
+ .format_measure_width_mask_val = 0xFFFF,
+ .format_measure_width_shift_val = 0x0,
};
static struct cam_ife_csid_reg_offset cam_ife_csid_175_reg_offset = {
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h
index bc162b6b0a87..48570dad5f37 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid175_200.h
@@ -350,6 +350,10 @@ static struct cam_ife_csid_common_reg_offset
.ppp_irq_mask_all = 0xFFFF,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
+ .format_measure_height_mask_val = 0xFFFF,
+ .format_measure_height_shift_val = 0x10,
+ .format_measure_width_mask_val = 0xFFFF,
+ .format_measure_width_shift_val = 0x0,
};
static struct cam_ife_csid_reg_offset cam_ife_csid_175_200_reg_offset = {
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
index a15879f9d0d9..860b02b472e8 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c
@@ -16,6 +16,7 @@
#include <uapi/media/cam_defs.h>
#include "cam_ife_csid_core.h"
+#include "cam_csid_ppi_core.h"
#include "cam_isp_hw.h"
#include "cam_soc_util.h"
#include "cam_io_util.h"
@@ -78,7 +79,7 @@ static int cam_ife_csid_is_ipp_ppp_format_supported(
static int cam_ife_csid_get_format_rdi(
uint32_t in_format, uint32_t out_format,
- uint32_t *decode_fmt, uint32_t *plain_fmt)
+ uint32_t *decode_fmt, uint32_t *plain_fmt, uint32_t *in_bpp)
{
int rc = 0;
@@ -96,6 +97,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 6;
break;
case CAM_FORMAT_MIPI_RAW_8:
switch (out_format) {
@@ -111,6 +113,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 8;
break;
case CAM_FORMAT_MIPI_RAW_10:
switch (out_format) {
@@ -126,6 +129,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 10;
break;
case CAM_FORMAT_MIPI_RAW_12:
switch (out_format) {
@@ -140,6 +144,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 12;
break;
case CAM_FORMAT_MIPI_RAW_14:
switch (out_format) {
@@ -154,6 +159,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 14;
break;
case CAM_FORMAT_MIPI_RAW_16:
switch (out_format) {
@@ -168,6 +174,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 16;
break;
case CAM_FORMAT_MIPI_RAW_20:
switch (out_format) {
@@ -182,6 +189,7 @@ static int cam_ife_csid_get_format_rdi(
rc = -EINVAL;
break;
}
+ *in_bpp = 20;
break;
case CAM_FORMAT_DPCM_10_6_10:
*decode_fmt = 0x7;
@@ -566,10 +574,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
init_completion(complete);
reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;
- /* Enable the Test gen before reset */
- cam_io_w_mb(1, csid_hw->hw_info->soc_info.reg_map[0].mem_base +
- csid_reg->tpg_reg->csid_tpg_ctrl_addr);
-
/* Reset the corresponding ife csid path */
cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
reset_strb_addr);
@@ -584,10 +588,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
rc = -ETIMEDOUT;
}
- /* Disable Test Gen after reset*/
- cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
- csid_reg->tpg_reg->csid_tpg_ctrl_addr);
-
end:
return rc;
@@ -1166,6 +1166,11 @@ static int cam_ife_csid_disable_hw(struct cam_ife_csid_hw *csid_hw)
for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
csid_hw->res_sof_cnt[i] = 0;
+ csid_hw->ipp_path_config.measure_enabled = 0;
+ csid_hw->ppp_path_config.measure_enabled = 0;
+ for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++)
+ csid_hw->rdi_path_config[i].measure_enabled = 0;
+
csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
csid_hw->error_irq_count = 0;
csid_hw->first_sof_ts = 0;
@@ -1422,10 +1427,12 @@ static int cam_ife_csid_enable_csi2(
struct cam_isp_resource_node *res)
{
int rc = 0;
- const struct cam_ife_csid_reg_offset *csid_reg;
- struct cam_hw_soc_info *soc_info;
- struct cam_ife_csid_cid_data *cid_data;
+ const struct cam_ife_csid_reg_offset *csid_reg;
+ struct cam_hw_soc_info *soc_info;
+ struct cam_ife_csid_cid_data *cid_data;
+ struct cam_csid_ppi_cfg ppi_lane_cfg;
uint32_t val = 0;
+ uint32_t ppi_index = 0;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
@@ -1515,6 +1522,24 @@ static int cam_ife_csid_enable_csi2(
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
+ ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
+ if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
+ ppi_lane_cfg.lane_type = csid_hw->csi2_rx_cfg.lane_type;
+ ppi_lane_cfg.lane_num = csid_hw->csi2_rx_cfg.lane_num;
+ ppi_lane_cfg.lane_cfg = csid_hw->csi2_rx_cfg.lane_cfg;
+
+ CAM_DBG(CAM_ISP, "ppi_index to init %d", ppi_index);
+ rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.init(
+ csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
+ &ppi_lane_cfg,
+ sizeof(struct cam_csid_ppi_cfg));
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d Init Failed",
+ ppi_index);
+ return rc;
+ }
+ }
+
return 0;
}
@@ -1522,8 +1547,10 @@ static int cam_ife_csid_disable_csi2(
struct cam_ife_csid_hw *csid_hw,
struct cam_isp_resource_node *res)
{
- const struct cam_ife_csid_reg_offset *csid_reg;
- struct cam_hw_soc_info *soc_info;
+ int rc = 0;
+ const struct cam_ife_csid_reg_offset *csid_reg;
+ struct cam_hw_soc_info *soc_info;
+ uint32_t ppi_index = 0;
if (res->res_id >= CAM_IFE_CSID_CID_MAX) {
CAM_ERR(CAM_ISP, "CSID:%d Invalid res id :%d",
@@ -1554,6 +1581,19 @@ static int cam_ife_csid_disable_csi2(
res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+ ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
+ if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
+ /* De-Initialize the PPI bridge */
+ CAM_DBG(CAM_ISP, "ppi_index to de-init %d\n", ppi_index);
+ rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.deinit(
+ csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
+ NULL, 0);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI:%d De-Init Failed", ppi_index);
+ return rc;
+ }
+ }
+
return 0;
}
@@ -1588,6 +1628,7 @@ static int cam_ife_csid_init_config_pxl_path(
const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL;
bool is_ipp;
uint32_t decode_format = 0, plain_format = 0, val = 0;
+ struct cam_isp_sensor_dimension *path_config;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -1596,9 +1637,11 @@ static int cam_ife_csid_init_config_pxl_path(
if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
is_ipp = true;
pxl_reg = csid_reg->ipp_reg;
+ path_config = &(csid_hw->ipp_path_config);
} else {
is_ipp = false;
pxl_reg = csid_reg->ppp_reg;
+ path_config = &(csid_hw->ppp_path_config);
}
if (!pxl_reg) {
@@ -1667,6 +1710,24 @@ static int cam_ife_csid_init_config_pxl_path(
}
}
+ /* configure pixel format measure */
+ if (path_config->measure_enabled) {
+ val = (((path_config->height &
+ csid_reg->cmn_reg->format_measure_height_mask_val) <<
+ csid_reg->cmn_reg->format_measure_height_shift_val) |
+ (path_config->width &
+ csid_reg->cmn_reg->format_measure_width_mask_val));
+ CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x",
+ csid_hw->hw_intf->hw_idx, val);
+
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_format_measure_cfg1_addr);
+
+ /* enable pixel and line counter */
+ cam_io_w_mb(3, soc_info->reg_map[0].mem_base +
+ pxl_reg->csid_pxl_format_measure_cfg0_addr);
+ }
+
/* set frame drop pattern to 0 and period to 1 */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_frm_drop_period_addr);
@@ -1812,6 +1873,7 @@ static int cam_ife_csid_enable_pxl_path(
const struct cam_ife_csid_pxl_reg_offset *pxl_reg = NULL;
bool is_ipp;
uint32_t val = 0, path_status;
+ struct cam_isp_sensor_dimension *path_config;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
@@ -1820,9 +1882,11 @@ static int cam_ife_csid_enable_pxl_path(
if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP) {
is_ipp = true;
pxl_reg = csid_reg->ipp_reg;
+ path_config = &(csid_hw->ipp_path_config);
} else {
is_ipp = false;
pxl_reg = csid_reg->ppp_reg;
+ path_config = &(csid_hw->ppp_path_config);
}
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
@@ -1883,6 +1947,10 @@ static int cam_ife_csid_enable_pxl_path(
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
val |= CSID_PATH_INFO_INPUT_EOF;
+ if (path_config->measure_enabled)
+ val |= (CSID_PATH_ERROR_PIX_COUNT |
+ CSID_PATH_ERROR_LINE_COUNT);
+
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
pxl_reg->csid_pxl_irq_mask_addr);
@@ -1983,7 +2051,7 @@ static int cam_ife_csid_init_config_rdi_path(
struct cam_ife_csid_path_cfg *path_data;
const struct cam_ife_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
- uint32_t path_format = 0, plain_fmt = 0, val = 0, id;
+ uint32_t path_format = 0, plain_fmt = 0, val = 0, id, in_bpp = 0;
uint32_t format_measure_addr;
path_data = (struct cam_ife_csid_path_cfg *) res->res_priv;
@@ -1998,7 +2066,7 @@ static int cam_ife_csid_init_config_rdi_path(
}
rc = cam_ife_csid_get_format_rdi(path_data->in_format,
- path_data->out_format, &path_format, &plain_fmt);
+ path_data->out_format, &path_format, &plain_fmt, &in_bpp);
if (rc)
return rc;
@@ -2047,6 +2115,32 @@ static int cam_ife_csid_init_config_rdi_path(
CAM_DBG(CAM_ISP, "CSID:%d Vertical Crop config val: 0x%x",
csid_hw->hw_intf->hw_idx, val);
}
+
+ /* configure pixel format measure */
+ if (csid_hw->rdi_path_config[id].measure_enabled) {
+ val = ((csid_hw->rdi_path_config[id].height &
+ csid_reg->cmn_reg->format_measure_height_mask_val) <<
+ csid_reg->cmn_reg->format_measure_height_shift_val);
+
+ if (path_format == 0xF)
+ val |= (((csid_hw->rdi_path_config[id].width *
+ in_bpp) / 8) &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ else
+ val |= (csid_hw->rdi_path_config[id].width &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+
+ CAM_DBG(CAM_ISP, "CSID:%d format measure cfg1 value : 0x%x",
+ csid_hw->hw_intf->hw_idx, val);
+
+ cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg1_addr);
+
+ /* enable pixel and line counter */
+ cam_io_w_mb(3, soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[id]->csid_rdi_format_measure_cfg0_addr);
+ }
+
/* set frame drop pattern to 0 and period to 1 */
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_frm_drop_period_addr);
@@ -2219,6 +2313,10 @@ static int cam_ife_csid_enable_rdi_path(
if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOF_IRQ)
val |= CSID_PATH_INFO_INPUT_EOF;
+ if (csid_hw->rdi_path_config[id].measure_enabled)
+ val |= (CSID_PATH_ERROR_PIX_COUNT |
+ CSID_PATH_ERROR_LINE_COUNT);
+
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[id]->csid_rdi_irq_mask_addr);
@@ -2672,6 +2770,13 @@ static int cam_ife_csid_release(void *hw_priv,
case CAM_ISP_RESOURCE_PIX_PATH:
res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
cam_ife_csid_reset_init_frame_drop(csid_hw);
+ if (res->res_id == CAM_IFE_PIX_PATH_RES_IPP)
+ csid_hw->ipp_path_config.measure_enabled = 0;
+ else if (res->res_id == CAM_IFE_PIX_PATH_RES_PPP)
+ csid_hw->ppp_path_config.measure_enabled = 0;
+ else
+ csid_hw->rdi_path_config[res->res_id].measure_enabled
+ = 0;
break;
default:
CAM_ERR(CAM_ISP, "CSID:%d Invalid res type:%d res id%d",
@@ -2687,7 +2792,6 @@ end:
}
-
static int cam_ife_csid_reset_retain_sw_reg(
struct cam_ife_csid_hw *csid_hw)
{
@@ -2704,6 +2808,8 @@ static int cam_ife_csid_reset_retain_sw_reg(
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_irq_cmd_addr);
+ usleep_range(3000, 3010);
+
cam_io_w_mb(csid_reg->cmn_reg->csid_rst_stb,
soc_info->reg_map[0].mem_base +
csid_reg->cmn_reg->csid_rst_strobes_addr);
@@ -3107,6 +3213,57 @@ static int cam_ife_csid_set_csid_clock(
return 0;
}
+static int cam_ife_csid_set_sensor_dimension(
+ struct cam_ife_csid_hw *csid_hw, void *cmd_args)
+{
+ struct cam_ife_sensor_dimension_update_args *dimension_update = NULL;
+ uint32_t i;
+
+ if (!csid_hw)
+ return -EINVAL;
+
+ dimension_update =
+ (struct cam_ife_sensor_dimension_update_args *)cmd_args;
+ csid_hw->ipp_path_config.measure_enabled =
+ dimension_update->ipp_path.measure_enabled;
+ if (dimension_update->ipp_path.measure_enabled) {
+ csid_hw->ipp_path_config.width =
+ dimension_update->ipp_path.width;
+ csid_hw->ipp_path_config.height =
+ dimension_update->ipp_path.height;
+ CAM_DBG(CAM_ISP, "CSID ipp path width %d height %d",
+ csid_hw->ipp_path_config.width,
+ csid_hw->ipp_path_config.height);
+ }
+ csid_hw->ppp_path_config.measure_enabled =
+ dimension_update->ppp_path.measure_enabled;
+ if (dimension_update->ppp_path.measure_enabled) {
+ csid_hw->ppp_path_config.width =
+ dimension_update->ppp_path.width;
+ csid_hw->ppp_path_config.height =
+ dimension_update->ppp_path.height;
+ CAM_DBG(CAM_ISP, "CSID ppp path width %d height %d",
+ csid_hw->ppp_path_config.width,
+ csid_hw->ppp_path_config.height);
+ }
+ for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++) {
+ csid_hw->rdi_path_config[i].measure_enabled
+ = dimension_update->rdi_path[i].measure_enabled;
+ if (csid_hw->rdi_path_config[i].measure_enabled) {
+ csid_hw->rdi_path_config[i].width =
+ dimension_update->rdi_path[i].width;
+ csid_hw->rdi_path_config[i].height =
+ dimension_update->rdi_path[i].height;
+ CAM_DBG(CAM_ISP,
+ "CSID rdi path[%d] width %d height %d",
+ i, csid_hw->rdi_path_config[i].width,
+ csid_hw->rdi_path_config[i].height);
+ }
+ }
+
+ return 0;
+}
+
static int cam_ife_csid_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
@@ -3144,6 +3301,9 @@ static int cam_ife_csid_process_cmd(void *hw_priv,
case CAM_IFE_CSID_SET_INIT_FRAME_DROP:
rc = cam_ife_csid_set_init_frame_drop(csid_hw, cmd_args);
break;
+ case CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG:
+ rc = cam_ife_csid_set_sensor_dimension(csid_hw, cmd_args);
+ break;
default:
CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
csid_hw->hw_intf->hw_idx, cmd_type);
@@ -3166,20 +3326,19 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
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;
+ uint32_t val, val2, irq_status_ppp = 0;
bool fatal_err_detected = false;
uint32_t sof_irq_debug_en = 0;
unsigned long flags;
- csid_hw = (struct cam_ife_csid_hw *)data;
-
- CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
-
if (!data) {
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
return IRQ_HANDLED;
}
+ csid_hw = (struct cam_ife_csid_hw *)data;
+ CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
+
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
csi2_reg = csid_reg->csi2_reg;
@@ -3222,7 +3381,7 @@ 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,
+ CAM_ERR_RATE_LIMIT(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,
@@ -3459,6 +3618,25 @@ handle_fatal_error:
csid_reg->ipp_reg->csid_pxl_ctrl_addr);
}
}
+
+ if ((irq_status_ipp & CSID_PATH_ERROR_PIX_COUNT) ||
+ (irq_status_ipp & CSID_PATH_ERROR_LINE_COUNT)) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ipp_reg->csid_pxl_format_measure0_addr);
+
+ CAM_ERR(CAM_ISP,
+ "CSID:%d irq_status_ipp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ipp);
+ CAM_ERR(CAM_ISP,
+ "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x",
+ csid_hw->ipp_path_config.height,
+ csid_hw->ipp_path_config.width,
+ ((val >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ }
}
/*read PPP errors */
@@ -3540,6 +3718,25 @@ handle_fatal_error:
csid_reg->ppp_reg->csid_pxl_ctrl_addr);
}
}
+
+ if ((irq_status_ppp & CSID_PATH_ERROR_PIX_COUNT) ||
+ (irq_status_ppp & CSID_PATH_ERROR_LINE_COUNT)) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->ppp_reg->csid_pxl_format_measure0_addr);
+
+ CAM_ERR(CAM_ISP,
+ "CSID:%d irq_status_ppp:0x%x",
+ csid_hw->hw_intf->hw_idx, irq_status_ppp);
+ CAM_ERR(CAM_ISP,
+ "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x",
+ csid_hw->ppp_path_config.height,
+ csid_hw->ppp_path_config.width,
+ ((val >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ }
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
@@ -3606,6 +3803,31 @@ handle_fatal_error:
soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_ctrl_addr);
}
+
+ if ((irq_status_rdi[i] & CSID_PATH_ERROR_PIX_COUNT) ||
+ (irq_status_rdi[i] & CSID_PATH_ERROR_LINE_COUNT)) {
+ val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[i]->csid_rdi_format_measure0_addr);
+ val2 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+ csid_reg->rdi_reg[i]->csid_rdi_format_measure_cfg1_addr
+ );
+ CAM_ERR(CAM_ISP,
+ "CSID:%d irq_status_rdi[%d]:0x%x",
+ csid_hw->hw_intf->hw_idx, i,
+ irq_status_rdi[i]);
+ CAM_ERR(CAM_ISP,
+ "Expected sz 0x%x*0x%x actual sz 0x%x*0x%x",
+ ((val2 >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val2 &
+ csid_reg->cmn_reg->format_measure_width_mask_val,
+ ((val >>
+ csid_reg->cmn_reg->format_measure_height_shift_val) &
+ csid_reg->cmn_reg->format_measure_height_mask_val),
+ val &
+ csid_reg->cmn_reg->format_measure_width_mask_val);
+ }
}
if (csid_hw->irq_debug_cnt >= CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX) {
@@ -3642,7 +3864,6 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
CAM_DBG(CAM_ISP, "type %d index %d",
ife_csid_hw->hw_intf->hw_type, csid_idx);
-
ife_csid_hw->device_enabled = 0;
ife_csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
mutex_init(&ife_csid_hw->hw_info->hw_mutex);
@@ -3657,7 +3878,6 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
for (i = 0; i < CAM_IFE_CSID_RDI_MAX; i++)
init_completion(&ife_csid_hw->csid_rdin_complete[i]);
-
rc = cam_ife_csid_init_soc_resources(&ife_csid_hw->hw_info->soc_info,
cam_ife_csid_irq, ife_csid_hw);
if (rc < 0) {
@@ -3751,8 +3971,27 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
ife_csid_hw->csid_debug = 0;
ife_csid_hw->error_irq_count = 0;
ife_csid_hw->first_sof_ts = 0;
+ ife_csid_hw->ipp_path_config.measure_enabled = 0;
+ ife_csid_hw->ppp_path_config.measure_enabled = 0;
+ for (i = 0; i <= CAM_IFE_PIX_PATH_RES_RDI_3; i++)
+ ife_csid_hw->rdi_path_config[i].measure_enabled = 0;
- return 0;
+ /* Check if ppi bridge is present or not? */
+ ife_csid_hw->ppi_enable = of_property_read_bool(
+ csid_hw_info->soc_info.pdev->dev.of_node,
+ "ppi-enable");
+
+ if (!ife_csid_hw->ppi_enable)
+ return 0;
+
+ /* Initialize the PPI bridge */
+ for (i = 0; i < CAM_CSID_PPI_HW_MAX; i++) {
+ rc = cam_csid_ppi_hw_init(&ife_csid_hw->ppi_hw_intf[i], i);
+ if (rc < 0) {
+ CAM_ERR(CAM_ISP, "PPI init failed for PPI %d", i);
+ break;
+ }
+ }
err:
if (rc) {
kfree(ife_csid_hw->ipp_res.res_priv);
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
index 9b4d5c3d6add..f2173f13f0c4 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.h
@@ -16,6 +16,7 @@
#include "cam_hw.h"
#include "cam_ife_csid_hw_intf.h"
#include "cam_ife_csid_soc.h"
+#include "cam_csid_ppi_core.h"
#define CAM_IFE_CSID_HW_RES_MAX 4
#define CAM_IFE_CSID_CID_RES_MAX 4
@@ -309,6 +310,10 @@ struct cam_ife_csid_common_reg_offset {
uint32_t ppp_irq_mask_all;
uint32_t measure_en_hbi_vbi_cnt_mask;
uint32_t format_measure_en_val;
+ uint32_t format_measure_width_shift_val;
+ uint32_t format_measure_width_mask_val;
+ uint32_t format_measure_height_shift_val;
+ uint32_t format_measure_height_mask_val;
};
/**
@@ -468,6 +473,11 @@ struct cam_ife_csid_path_cfg {
* @csid_debug: csid debug information to enable the SOT, EOT,
* SOF, EOF, measure etc in the csid hw
* @clk_rate Clock rate
+ * @ipp_path ipp path configuration
+ * @ppp_path ppp path configuration
+ * @rdi_path RDI path configuration
+ * @hbi Horizontal blanking
+ * @vbi Vertical blanking
* @sof_irq_triggered: Flag is set on receiving event to enable sof irq
* incase of SOF freeze.
* @irq_debug_cnt: Counter to track sof irq's when above flag is set.
@@ -481,7 +491,9 @@ struct cam_ife_csid_path_cfg {
* @res_sof_cnt path resource sof count value. it used for initial
* frame drop
* @first_sof_ts flag to mark the first sof has been registered
- *
+ * @ppi_hw_intf interface to ppi hardware
+ * @ppi_enabled flag to specify if the hardware has ppi bridge
+ * or not
*/
struct cam_ife_csid_hw {
struct cam_hw_intf *hw_intf;
@@ -504,6 +516,11 @@ struct cam_ife_csid_hw {
struct completion csid_rdin_complete[CAM_IFE_CSID_RDI_MAX];
uint64_t csid_debug;
uint64_t clk_rate;
+ struct cam_isp_sensor_dimension ipp_path_config;
+ struct cam_isp_sensor_dimension ppp_path_config;
+ struct cam_isp_sensor_dimension rdi_path_config[4];
+ uint32_t hbi;
+ uint32_t vbi;
bool sof_irq_triggered;
uint32_t irq_debug_cnt;
uint32_t error_irq_count;
@@ -513,6 +530,8 @@ struct cam_ife_csid_hw {
uint32_t init_frame_drop;
uint32_t res_sof_cnt[CAM_IFE_PIX_PATH_RES_MAX];
uint32_t first_sof_ts;
+ struct cam_hw_intf *ppi_hw_intf[CAM_CSID_PPI_HW_MAX];
+ bool ppi_enable;
};
int cam_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
index 0c45bd1268b9..8d340207a0a1 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
@@ -158,6 +158,7 @@ enum cam_ife_csid_cmd_type {
CAM_IFE_CSID_SET_CSID_DEBUG,
CAM_IFE_CSID_SOF_IRQ_DEBUG,
CAM_IFE_CSID_SET_INIT_FRAME_DROP,
+ CAM_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
CAM_IFE_CSID_CMD_MAX,
};
@@ -181,5 +182,17 @@ struct cam_ife_csid_clock_update_args {
uint64_t clk_rate;
};
+/*
+ * struct cam_ife_sensor_dim_update_args:
+ *
+ * @ppp_path: expected ppp path configuration
+ * @ipp_path: expected ipp path configuration
+ * @rdi_path: expected rdi path configuration
+ */
+struct cam_ife_sensor_dimension_update_args {
+ struct cam_isp_sensor_dimension ppp_path;
+ struct cam_isp_sensor_dimension ipp_path;
+ struct cam_isp_sensor_dimension rdi_path[4];
+};
#endif /* _CAM_CSID_HW_INTF_H_ */
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
index 185d0f595673..54bdbbe1677f 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
@@ -19,17 +19,21 @@
#include "cam_soc_util.h"
#include "cam_irq_controller.h"
+#define CAM_ISP_FPS_60 60
+
/*
* struct cam_isp_timestamp:
*
* @mono_time: Monotonic boot time
* @vt_time: AV Timer time
* @ticks: Qtimer ticks
+ * @time_usecs: time in micro seconds
*/
struct cam_isp_timestamp {
struct timeval mono_time;
struct timeval vt_time;
uint64_t ticks;
+ uint64_t time_usecs;
};
/*
@@ -104,6 +108,7 @@ enum cam_isp_hw_cmd_type {
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_FPS_CONFIG,
CAM_ISP_HW_CMD_MAX,
};
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
index 9d6bcb71bb69..3bcedc948a18 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h
@@ -178,6 +178,17 @@ struct cam_vfe_clock_update_args {
};
/*
+ * struct cam_vfe_fps_config_args:
+ *
+ * @node_res: Resource to get the fps value
+ * @fps: FPS value to configure EPOCH
+ */
+struct cam_vfe_fps_config_args {
+ struct cam_isp_resource_node *node_res;
+ uint32_t fps;
+};
+
+/*
* struct cam_vfe_bw_update_args:
*
* @node_res: Resource to get the BW
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
index 43531c173f89..6088b9451061 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c
@@ -465,6 +465,8 @@ void cam_isp_hw_get_timestamp(struct cam_isp_timestamp *time_stamp)
get_monotonic_boottime(&ts);
time_stamp->mono_time.tv_sec = ts.tv_sec;
time_stamp->mono_time.tv_usec = ts.tv_nsec/1000;
+ time_stamp->time_usecs = ts.tv_sec * 1000000 +
+ time_stamp->mono_time.tv_usec;
}
static int cam_vfe_irq_top_half(uint32_t evt_id,
@@ -802,6 +804,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
case CAM_ISP_HW_CMD_BW_UPDATE:
case CAM_ISP_HW_CMD_BW_CONTROL:
case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
+ case CAM_ISP_HW_CMD_FPS_CONFIG:
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/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
index fc2b3ce5b545..6b764266ecf3 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c
@@ -165,6 +165,7 @@ struct cam_vfe_bus_ver2_wm_resource_data {
uint32_t en_cfg;
uint32_t is_dual;
uint32_t is_lite;
+ uint32_t is_streaming;
};
struct cam_vfe_bus_ver2_comp_grp_data {
@@ -1246,6 +1247,7 @@ static int cam_vfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
CAM_DBG(CAM_ISP, "enable WM res %d offset 0x%x val 0x%x",
rsrc_data->index, (uint32_t) rsrc_data->hw_regs->cfg,
rsrc_data->en_cfg);
+ rsrc_data->is_streaming = CAM_ISP_RESOURCE_STATE_STREAMING;
wm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
@@ -1274,6 +1276,7 @@ static int cam_vfe_bus_stop_wm(struct cam_isp_resource_node *wm_res)
wm_res->irq_handle);
wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+ rsrc_data->is_streaming = CAM_ISP_RESOURCE_STATE_RESERVED;
kfifo_reset(
&g_addr_fifo[rsrc_data->common_data->core_index][rsrc_data->index]);
@@ -3015,9 +3018,17 @@ static int cam_vfe_bus_update_wm(void *priv, void *cmd_args,
&output_image_buf,
sizeof(uint32_t));
- cam_io_w_mb(output_image_buf,
- bus_priv->common_data.mem_base +
- wm_data->hw_regs->image_addr);
+ if (wm_data->is_streaming ==
+ CAM_ISP_RESOURCE_STATE_STREAMING)
+ cam_io_w_mb(output_image_buf,
+ bus_priv->common_data.mem_base +
+ wm_data->hw_regs->image_addr);
+ else
+ CAM_VFE_ADD_REG_VAL_PAIR(
+ reg_val_pair,
+ j,
+ wm_data->hw_regs->image_addr,
+ output_image_buf);
kfifo_in(
&bus_priv->addr_fifo[wm_data->index],
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
index 3ed45ee530e8..112a2d680c30 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
@@ -44,6 +44,7 @@ struct cam_vfe_mux_camif_data {
bool enable_sof_irq_debug;
uint32_t irq_debug_cnt;
uint32_t camif_debug;
+ uint32_t fps;
};
static int cam_vfe_camif_validate_pix_pattern(uint32_t pattern)
@@ -269,9 +270,15 @@ static int cam_vfe_camif_resource_start(
rsrc_data->camif_reg->epoch_irq);
break;
default:
- epoch0_irq_mask = ((rsrc_data->last_line -
+ if (rsrc_data->fps == CAM_ISP_FPS_60) {
+ epoch0_irq_mask = ((rsrc_data->last_line -
rsrc_data->first_line) / 2) +
rsrc_data->first_line;
+ } else {
+ epoch0_irq_mask = (((rsrc_data->last_line -
+ rsrc_data->first_line) * 2) / 3) +
+ rsrc_data->first_line;
+ }
epoch1_irq_mask = rsrc_data->reg_data->epoch_line_cfg &
0xFFFF;
computed_epoch_line_cfg = (epoch0_irq_mask << 16) |
@@ -515,6 +522,20 @@ static int cam_vfe_camif_sof_irq_debug(
return 0;
}
+static int cam_vfe_camif_set_fps_config(
+ struct cam_isp_resource_node *rsrc_node, void *cmd_args)
+{
+ struct cam_vfe_mux_camif_data *camif_priv = NULL;
+ struct cam_vfe_fps_config_args *fps_args = cmd_args;
+
+ camif_priv =
+ (struct cam_vfe_mux_camif_data *)rsrc_node->res_priv;
+
+ camif_priv->fps = fps_args->fps;
+
+ return 0;
+
+}
static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
@@ -546,6 +567,9 @@ static int cam_vfe_camif_process_cmd(struct cam_isp_resource_node *rsrc_node,
case CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP:
rc = cam_vfe_camif_irq_reg_dump(rsrc_node);
break;
+ case CAM_ISP_HW_CMD_FPS_CONFIG:
+ rc = cam_vfe_camif_set_fps_config(rsrc_node, cmd_args);
+ break;
default:
CAM_ERR(CAM_ISP,
"unsupported process command:%d", cmd_type);
diff --git a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
index d512128b28e5..0461b0820b4f 100644
--- a/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
+++ b/drivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver2.c
@@ -283,6 +283,22 @@ static int cam_vfe_top_fs_update(
return 0;
}
+static int cam_vfe_top_fps_config(
+ struct cam_vfe_top_ver2_priv *top_priv,
+ void *cmd_args, uint32_t arg_size)
+{
+ struct cam_vfe_fps_config_args *cmd_update = NULL;
+
+ cmd_update =
+ (struct cam_vfe_fps_config_args *)cmd_args;
+
+ if (cmd_update->node_res->process_cmd)
+ return cmd_update->node_res->process_cmd(cmd_update->node_res,
+ CAM_ISP_HW_CMD_FPS_CONFIG, cmd_args, arg_size);
+
+ return 0;
+}
+
static int cam_vfe_top_clock_update(
struct cam_vfe_top_ver2_priv *top_priv,
void *cmd_args, uint32_t arg_size)
@@ -740,6 +756,10 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type,
rc = cam_vfe_get_irq_register_dump(top_priv,
cmd_args, arg_size);
break;
+ case CAM_ISP_HW_CMD_FPS_CONFIG:
+ rc = cam_vfe_top_fps_config(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/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
index 416cb2a9fa96..9bdb57529d8e 100644
--- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
+++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_csiphy/cam_csiphy_soc.c
@@ -274,6 +274,25 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
csiphy_dev->ctrl_reg->data_rates_settings_table =
&data_rate_delta_table_1_2;
} else if (of_device_is_compatible(soc_info->dev->of_node,
+ "qcom,csiphy-v1.2.2")) {
+ csiphy_dev->ctrl_reg->csiphy_2ph_reg = csiphy_2ph_v1_2_reg;
+ csiphy_dev->ctrl_reg->csiphy_2ph_combo_mode_reg =
+ csiphy_2ph_v1_2_combo_mode_reg;
+ csiphy_dev->ctrl_reg->csiphy_3ph_reg = csiphy_3ph_v1_2_reg;
+ csiphy_dev->ctrl_reg->csiphy_2ph_3ph_mode_reg = NULL;
+ csiphy_dev->ctrl_reg->csiphy_irq_reg = csiphy_irq_reg_1_2;
+ csiphy_dev->ctrl_reg->csiphy_common_reg =
+ 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_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_1_2;
+ } 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;
csiphy_dev->ctrl_reg->csiphy_2ph_combo_mode_reg =
diff --git a/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_core.c
index 1fa3ced0fb95..81a2f9f657b6 100644
--- a/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_core.c
+++ b/drivers/media/platform/msm/ais/cam_sensor_module/cam_sensor/cam_sensor_core.c
@@ -926,14 +926,13 @@ free_probe_cmd:
s_ctrl->sensor_state = CAM_SENSOR_ACQUIRE;
CAM_INFO(CAM_SENSOR,
- "CAM_ACQUIRE_DEV Success %d",
+ "SENSOR_POWER_UP Success %d",
s_ctrl->soc_info.index);
}
break;
case AIS_SENSOR_POWER_DOWN: {
- if ((s_ctrl->sensor_state == CAM_SENSOR_INIT) ||
- (s_ctrl->sensor_state == CAM_SENSOR_START)) {
+ if (s_ctrl->sensor_state == CAM_SENSOR_START) {
rc = -EINVAL;
CAM_WARN(CAM_SENSOR,
"Not in right state to release %d (%d)",
@@ -952,7 +951,7 @@ free_probe_cmd:
s_ctrl->sensor_state = CAM_SENSOR_INIT;
CAM_INFO(CAM_SENSOR,
- "CAM_RELEASE_DEV Success %d",
+ "SENSOR_POWER_DOWN Success %d",
s_ctrl->soc_info.index);
}
break;
@@ -1007,7 +1006,7 @@ free_probe_cmd:
goto release_mutex;
}
- CAM_WARN(CAM_SENSOR, "Read 0x%x : 0x%x <- 0x%x",
+ CAM_DBG(CAM_SENSOR, "Read 0x%x : 0x%x <- 0x%x",
i2c_read.i2c_config.slave_addr,
i2c_read.reg_addr, i2c_read.reg_data);
@@ -1052,7 +1051,7 @@ free_probe_cmd:
goto release_mutex;
}
- CAM_INFO(CAM_SENSOR,
+ CAM_DBG(CAM_SENSOR,
"Write 0x%x, 0x%x <- 0x%x [%d, %d]",
i2c_write.i2c_config.slave_addr,
i2c_write.wr_payload.reg_addr,
@@ -1166,7 +1165,7 @@ free_probe_cmd:
goto release_mutex;
}
- CAM_INFO(CAM_SENSOR,
+ CAM_DBG(CAM_SENSOR,
"Write 0x%x, %d regs [%d, %d]",
i2c_write.i2c_config.slave_addr,
i2c_write.count,