浏览代码

msm: camera: isp: Add support for PHY TPG

This change adds support for PHY TPG version
102 hardware.

CRs-Fixed: 2608550
Change-Id: I92387b08e8a91bb0c6a77b5301ebc30c7cb6f252
Signed-off-by: Vishalsingh Hajeri <[email protected]>
Signed-off-by: Venkat Chinta <[email protected]>
Signed-off-by: Mukund Madhusudan Atre <[email protected]>
Venkat Chinta 5 年之前
父节点
当前提交
131b4115d5

+ 8 - 1
drivers/Makefile

@@ -85,6 +85,11 @@ camera-$(CONFIG_SPECTRA_ISP) += \
 	cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.o \
 	cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.o \
 	cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe.o \
+	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_dev.o \
+	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.o \
+	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.o \
+	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.o \
+	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.o \
 	cam_isp/isp_hw_mgr/cam_isp_hw_mgr.o \
 	cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \
 	cam_isp/cam_isp_dev.o \
@@ -197,7 +202,9 @@ camera-$(CONFIG_SPECTRA_CAMERA) += \
 	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_dev.o \
 	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.o \
 	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.o \
-	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_v1.o
+	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.o \
+	cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.o
+
 
 camera-y += camera_main.o
 

+ 92 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -424,6 +424,17 @@ static int cam_ife_hw_mgr_init_hw(
 	struct cam_isp_hw_mgr_res *hw_mgr_res;
 	int rc = 0, i;
 
+	if (ctx->is_tpg) {
+		CAM_DBG(CAM_ISP, "INIT TPG ... in ctx id:%d",
+			ctx->ctx_index);
+		rc = cam_ife_hw_mgr_init_hw_res(&ctx->res_list_tpg);
+		if (rc) {
+			CAM_ERR(CAM_ISP, "Can not INIT TFE TPG(id :%d)",
+				ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx);
+			goto deinit;
+		}
+	}
+
 	CAM_DBG(CAM_ISP, "INIT IFE CID ... in ctx id:%d",
 		ctx->ctx_index);
 	/* INIT IFE CID */
@@ -840,6 +851,10 @@ static int cam_ife_hw_mgr_release_hw_for_ctx(
 		cam_ife_hw_mgr_put_res(&ife_ctx->free_res_list, &hw_mgr_res);
 	}
 
+	/* ife phy tpg resource */
+	if (ife_ctx->is_tpg)
+		cam_ife_hw_mgr_free_hw_res(&ife_ctx->res_list_tpg);
+
 	/* ife root node */
 	if (ife_ctx->res_list_ife_in.res_type != CAM_ISP_RESOURCE_UNINT)
 		cam_ife_hw_mgr_free_hw_res(&ife_ctx->res_list_ife_in);
@@ -1862,6 +1877,48 @@ end:
 
 }
 
+static int cam_ife_hw_mgr_acquire_tpg(
+	struct cam_ife_hw_mgr_ctx               *ife_ctx,
+	struct cam_isp_in_port_generic_info     *in_port,
+	uint32_t                                 num_inport)
+{
+	int rc = -EINVAL;
+	uint32_t i;
+	struct cam_ife_hw_mgr *ife_hw_mgr;
+	struct cam_hw_intf *hw_intf;
+	struct cam_top_tpg_ver2_reserve_args tpg_reserve;
+
+	ife_hw_mgr = ife_ctx->hw_mgr;
+
+	for (i = 0; i < CAM_TOP_TPG_HW_NUM_MAX; i++) {
+		if (!ife_hw_mgr->tpg_devices[i])
+			continue;
+
+		hw_intf = ife_hw_mgr->tpg_devices[i];
+		tpg_reserve.num_inport = num_inport;
+		tpg_reserve.node_res = NULL;
+		tpg_reserve.in_port = in_port;
+
+		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
+			&tpg_reserve, sizeof(tpg_reserve));
+		if (!rc)
+			break;
+	}
+
+	if (i == CAM_TOP_TPG_HW_NUM_MAX || !tpg_reserve.node_res) {
+		CAM_ERR(CAM_ISP, "Can not acquire IFE TPG");
+		rc = -EINVAL;
+		goto end;
+	}
+
+	ife_ctx->res_list_tpg.res_type = in_port->res_type;
+	ife_ctx->res_list_tpg.hw_res[0] = tpg_reserve.node_res;
+	ife_ctx->is_tpg = true;
+
+end:
+	return rc;
+}
+
 static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl(
 	struct cam_ife_hw_mgr_ctx           *ife_ctx,
 	struct cam_isp_in_port_generic_info *in_port,
@@ -2755,6 +2812,16 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 			ife_ctx->use_frame_header_ts = true;
 		}
 
+		if ((in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) ||
+			(in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1))
+			rc  = cam_ife_hw_mgr_acquire_tpg(ife_ctx, in_port,
+				acquire_hw_info->num_inputs);
+
+		if (rc) {
+			CAM_ERR(CAM_ISP, "can not acquire TPG resource");
+			goto free_mem;
+		}
+
 		rc = cam_ife_mgr_acquire_hw_for_ctx(ife_ctx, in_port,
 			&num_pix_port_per_in, &num_rdi_port_per_in,
 			&acquire_args->acquired_hw_id[i],
@@ -3752,6 +3819,9 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
 	if (cam_cdm_stream_off(ctx->cdm_handle))
 		CAM_ERR(CAM_ISP, "CDM stream off failed %d", ctx->cdm_handle);
 
+	if (ctx->is_tpg)
+		cam_ife_hw_mgr_stop_hw_res(&ctx->res_list_tpg);
+
 	cam_ife_hw_mgr_deinit_hw(ctx);
 	CAM_DBG(CAM_ISP,
 		"Stop success for ctx id:%d rc :%d", ctx->ctx_index, rc);
@@ -4077,6 +4147,17 @@ start_only:
 		}
 	}
 
+	if (ctx->is_tpg) {
+		CAM_DBG(CAM_ISP, "START TPG HW ... in ctx id:%d",
+			ctx->ctx_index);
+		rc = cam_ife_hw_mgr_start_hw_res(&ctx->res_list_tpg, ctx);
+		if (rc) {
+			CAM_ERR(CAM_ISP, "Can not start IFE TPG (%d)",
+				ctx->res_list_tpg.res_id);
+			goto err;
+		}
+	}
+
 	/* Start IFE root node: do nothing */
 	CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index);
 
@@ -7100,6 +7181,16 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 		return -EINVAL;
 	}
 
+	/* fill tpg hw intf information */
+	for (i = 0, j = 0; i < CAM_TOP_TPG_HW_NUM_MAX; i++) {
+		rc = cam_top_tpg_hw_init(&g_ife_hw_mgr.tpg_devices[i], i);
+		if (!rc)
+			j++;
+	}
+	if (!j)
+		CAM_ERR(CAM_ISP, "no valid IFE TPG HW");
+
+
 	cam_ife_hw_mgr_sort_dev_with_caps(&g_ife_hw_mgr);
 
 	/* setup ife context list */
@@ -7146,6 +7237,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 			sizeof(g_ife_hw_mgr.ctx_pool[i]));
 		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].list);
 
+		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_tpg.list);
 		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_in.list);
 		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_cid);
 		INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_csid);

+ 6 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -11,6 +11,7 @@
 #include "cam_isp_hw_mgr.h"
 #include "cam_vfe_hw_intf.h"
 #include "cam_ife_csid_hw_intf.h"
+#include "cam_top_tpg_hw_intf.h"
 #include "cam_tasklet_util.h"
 
 /* IFE resource constants */
@@ -48,6 +49,7 @@ struct cam_ife_hw_mgr_debug {
  * @slave_hw_idx:           hw index for slave core
  * @hw_mgr:                 IFE hw mgr which owns this context
  * @ctx_in_use:             flag to tell whether context is active
+ * @res_list_tpg:           TPG resource list
  * @res_list_ife_in:        Starting resource(TPG,PHY0, PHY1...) Can only be
  *                          one.
  * @res_list_csid:          CSID resource list
@@ -85,6 +87,7 @@ struct cam_ife_hw_mgr_debug {
  * @custom_enabled          update the flag if context is connected to custom HW
  * @use_frame_header_ts     obtain qtimer ts using frame header
  * @ts                      captured timestamp when the ctx is acquired
+ * @is_tpg                  indicate whether context is using PHY TPG
  */
 struct cam_ife_hw_mgr_ctx {
 	struct list_head                list;
@@ -97,6 +100,7 @@ struct cam_ife_hw_mgr_ctx {
 	uint32_t                        ctx_in_use;
 
 	struct cam_isp_hw_mgr_res       res_list_ife_in;
+	struct cam_isp_hw_mgr_res       res_list_tpg;
 	struct list_head                res_list_ife_cid;
 	struct list_head                res_list_ife_csid;
 	struct list_head                res_list_ife_src;
@@ -134,6 +138,7 @@ struct cam_ife_hw_mgr_ctx {
 	bool                            custom_enabled;
 	bool                            use_frame_header_ts;
 	struct timespec64               ts;
+	bool                            is_tpg;
 };
 
 /**
@@ -155,6 +160,7 @@ struct cam_ife_hw_mgr_ctx {
  */
 struct cam_ife_hw_mgr {
 	struct cam_isp_hw_mgr          mgr_common;
+	struct cam_hw_intf            *tpg_devices[CAM_TOP_TPG_HW_NUM_MAX];
 	struct cam_hw_intf            *csid_devices[CAM_IFE_CSID_HW_NUM_MAX];
 	struct cam_hw_intf            *ife_devices[CAM_IFE_HW_NUM_MAX];
 	struct cam_soc_reg_map        *cdm_reg_map[CAM_IFE_HW_NUM_MAX];

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -1350,7 +1350,7 @@ static int cam_tfe_hw_mgr_acquire_tpg(
 	uint32_t i, j = 0;
 	struct cam_tfe_hw_mgr                        *tfe_hw_mgr;
 	struct cam_hw_intf                           *hw_intf;
-	struct cam_top_tpg_hw_reserve_resource_args   tpg_reserve;
+	struct cam_top_tpg_ver1_reserve_args          tpg_reserve;
 
 	tfe_hw_mgr = tfe_ctx->hw_mgr;
 

+ 15 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c

@@ -25,6 +25,10 @@
 #define CAM_IFE_CSID_TPG_VC_VAL                        0xA
 #define CAM_IFE_CSID_TPG_DT_VAL                        0x2B
 
+/* CSIPHY TPG VC/DT values */
+#define CAM_IFE_CSI_TPG_VC_VAL                         0x0
+#define CAM_IFE_CSI_TPG_DT_VAL                         0x2B
+
 /* Timeout values in usec */
 #define CAM_IFE_CSID_TIMEOUT_SLEEP_US                  1000
 #define CAM_IFE_CSID_TIMEOUT_ALL_US                    100000
@@ -957,6 +961,12 @@ int cam_ife_csid_cid_reserve(struct cam_ife_csid_hw *csid_hw,
 				csid_hw->tpg_cfg.height);
 
 			cid_data->tpg_set = 1;
+		} else if (cid_reserv->in_port->res_type ==
+			CAM_ISP_IFE_IN_RES_CPHY_TPG_0) {
+			csid_hw->csi2_rx_cfg.phy_sel = 0;
+		} else if (cid_reserv->in_port->res_type ==
+			CAM_ISP_IFE_IN_RES_CPHY_TPG_1) {
+			csid_hw->csi2_rx_cfg.phy_sel = 1;
 		} else {
 			csid_hw->csi2_rx_cfg.phy_sel =
 				(cid_reserv->in_port->res_type & 0xFF) - 1;
@@ -1129,9 +1139,10 @@ int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw,
 		reserve->in_port->line_start, reserve->in_port->line_stop,
 		path_data->crop_enable);
 
-	if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) {
-		path_data->dt = CAM_IFE_CSID_TPG_DT_VAL;
-		path_data->vc = CAM_IFE_CSID_TPG_VC_VAL;
+	if ((reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) ||
+		(reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1)) {
+		path_data->dt = CAM_IFE_CSI_TPG_DT_VAL;
+		path_data->vc = CAM_IFE_CSI_TPG_VC_VAL;
 	} else {
 		path_data->dt = reserve->in_port->dt[0];
 		path_data->vc = reserve->in_port->vc[0];
@@ -4459,6 +4470,7 @@ int cam_ife_csid_hw_probe_init(struct cam_hw_intf  *csid_hw_intf,
 	num_paths = ife_csid_hw->csid_info->csid_reg->cmn_reg->num_pix +
 		ife_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis +
 		ife_csid_hw->csid_info->csid_reg->cmn_reg->num_udis;
+
 	/* Initialize the CID resource */
 	for (i = 0; i < num_paths; i++) {
 		ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;

+ 17 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h

@@ -8,6 +8,7 @@
 
 #include "cam_isp_hw.h"
 #include "cam_hw_intf.h"
+#include "cam_ife_csid_hw_intf.h"
 
 /* Max top tpg instance */
 #define CAM_TOP_TPG_HW_NUM_MAX                        2
@@ -37,7 +38,7 @@ struct cam_top_tpg_hw_caps {
 };
 
 /**
- * struct cam_tfe_csid_hw_reserve_resource_args- hw reserve
+ * struct cam_top_tpg_ver1_reserve_args- hw reserve
  * @num_inport:   number of inport
  *                TPG support 4 dt types, each different dt comes in different
  *                in port.
@@ -45,12 +46,26 @@ struct cam_top_tpg_hw_caps {
  * @node_res :    Reserved resource structure pointer
  *
  */
-struct cam_top_tpg_hw_reserve_resource_args {
+struct cam_top_tpg_ver1_reserve_args {
 	uint32_t                          num_inport;
 	struct cam_isp_tfe_in_port_info  *in_port[CAM_TOP_TPG_MAX_SUPPORTED_DT];
 	struct cam_isp_resource_node     *node_res;
 };
 
+/**
+ * struct cam_top_tpg_ver2_reserve_args
+ * @num_inport:   number of inport
+ *                TPG supports 1 VC/DT
+ * @in_port :     Input port resource info structure pointer
+ * @node_res :    Reserved resource structure pointer
+ *
+ */
+struct cam_top_tpg_ver2_reserve_args {
+	uint32_t                                  num_inport;
+	struct cam_isp_in_port_generic_info      *in_port;
+	struct cam_isp_resource_node             *node_res;
+};
+
 /**
  * cam_top_tpg_hw_init()
  *

+ 0 - 15
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/Makefile

@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_core
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_cdm/
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_cpas/include
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/include
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/include
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/include
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_smmu/
-ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_req_mgr/
-
-obj-$(CONFIG_SPECTRA_CAMERA) += cam_top_tpg_dev.o cam_top_tpg_soc.o cam_top_tpg_core.o
-obj-$(CONFIG_SPECTRA_CAMERA) += cam_top_tpg_v1.o

+ 48 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.c

@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include "cam_top_tpg101.h"
+#include "cam_top_tpg102.h"
+#include "cam_top_tpg_core.h"
+#include "cam_top_tpg_dev.h"
+#include "camera_main.h"
+
+static const struct of_device_id cam_top_tpg_dt_match[] = {
+	{
+		.compatible = "qcom,tpg101",
+		.data = &cam_top_tpg101_hw_info,
+	},
+	{
+		.compatible = "qcom,tpg102",
+		.data = &cam_top_tpg102_hw_info,
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, cam_top_tpg_dt_match);
+
+struct platform_driver cam_top_tpg_driver = {
+	.probe = cam_top_tpg_probe,
+	.remove = cam_top_tpg_remove,
+	.driver = {
+		.name = "cam_top_tpg",
+		.of_match_table = cam_top_tpg_dt_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+int cam_top_tpg_init_module(void)
+{
+	return platform_driver_register(&cam_top_tpg_driver);
+}
+
+void cam_top_tpg_exit_module(void)
+{
+	platform_driver_unregister(&cam_top_tpg_driver);
+}
+
+MODULE_DESCRIPTION("CAM TOP TPG driver");
+MODULE_LICENSE("GPL v2");

+ 12 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.h

@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CAM_TOP_TPG_H_
+#define _CAM_TOP_TPG_H_
+
+int cam_top_tpg_init_module(void);
+void cam_top_tpg_exit_module(void);
+
+#endif /*_CAM_TOP_TPG_H_ */

+ 11 - 6
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_v1.h → drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg101.h

@@ -3,12 +3,13 @@
  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
-#ifndef _CAM_TOP_TPG_V1_H_
-#define _CAM_TOP_TPG_V1_H_
+#ifndef _CAM_TOP_TPG101_H_
+#define _CAM_TOP_TPG101_H_
 
+#include "cam_top_tpg_ver1.h"
 #include "cam_top_tpg_core.h"
 
-static struct cam_top_tpg_reg_offset   cam_top_tpg_v1_reg_offset = {
+static struct cam_top_tpg_ver1_reg_offset cam_top_tpg101_reg = {
 	.tpg_hw_version = 0x0,
 	.tpg_hw_status = 0x4,
 	.tpg_ctrl = 0x60,
@@ -50,7 +51,11 @@ static struct cam_top_tpg_reg_offset   cam_top_tpg_v1_reg_offset = {
 	.top_mux_reg_offset = 0x1C,
 };
 
-int cam_top_tpg_v1_init_module(void);
-void cam_top_tpg_v1_exit_module(void);
+struct cam_top_tpg_hw_info cam_top_tpg101_hw_info = {
+	.tpg_reg = &cam_top_tpg101_reg,
+	.hw_dts_version = CAM_TOP_TPG_VERSION_1,
+	.csid_max_clk = 426400000,
+	.phy_max_clk = 384000000,
+};
 
-#endif /*_CAM_TOP_TPG_V1_H_ */
+#endif /* _CAM_TOP_TPG101_H_ */

+ 50 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg102.h

@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CAM_TOP_TPG102_H_
+#define _CAM_TOP_TPG102_H_
+
+#include "cam_top_tpg_ver2.h"
+#include "cam_top_tpg_core.h"
+
+static struct cam_top_tpg_ver2_reg_offset cam_top_tpg102_reg = {
+	.tpg_hw_version = 0x0,
+	.tpg_hw_status = 0x4,
+	.tpg_module_cfg = 0x60,
+	.tpg_cfg_0 = 0x68,
+	.tpg_cfg_1 = 0x6C,
+	.tpg_cfg_2 = 0x70,
+	.tpg_cfg_3 = 0x74,
+	.tpg_spare = 0xFC,
+	.top_mux_sel = 0x90,
+	/* configurations */
+	.major_version = 1,
+	.minor_version = 0,
+	.version_incr = 0,
+	.tpg_module_en = 1,
+	.tpg_mux_sel_en = 1,
+	.tpg_mux_sel_tpg_0_shift = 0,
+	.tpg_mux_sel_tpg_1_shift = 8,
+	.tpg_en_shift_val = 0,
+	.tpg_phy_sel_shift_val = 3,
+	.tpg_num_active_lines_shift = 4,
+	.tpg_fe_pkt_en_shift = 2,
+	.tpg_fs_pkt_en_shift = 1,
+	.tpg_line_interleaving_mode_shift = 10,
+	.tpg_num_dts_shift_val = 8,
+	.tpg_v_blank_cnt_shift = 12,
+	.tpg_dt_encode_format_shift = 16,
+	.tpg_payload_mode_color = 0x8,
+	.tpg_split_en_shift = 5,
+};
+
+struct cam_top_tpg_hw_info cam_top_tpg102_hw_info = {
+	.tpg_reg = &cam_top_tpg102_reg,
+	.hw_dts_version = CAM_TOP_TPG_VERSION_2,
+	.csid_max_clk = 426400000,
+	.phy_max_clk = 384000000,
+};
+
+#endif /* _CAM_TOP_TPG102_H_ */

+ 14 - 369
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c

@@ -13,210 +13,8 @@
 #include "cam_io_util.h"
 #include "cam_debug_util.h"
 #include "cam_cpas_api.h"
-
-
-static uint32_t tpg_num_dt_map[CAM_TOP_TPG_MAX_SUPPORTED_DT] = {
-	0,
-	3,
-	1,
-	2
-};
-
-static int cam_top_tpg_get_format(uint32_t in_format,
-	uint32_t *tpg_encode_format)
-{
-	int rc = 0;
-
-	switch (in_format) {
-	case CAM_FORMAT_MIPI_RAW_6:
-		*tpg_encode_format = 0;
-		break;
-	case CAM_FORMAT_MIPI_RAW_8:
-		*tpg_encode_format = 1;
-		break;
-	case CAM_FORMAT_MIPI_RAW_10:
-		*tpg_encode_format = 2;
-		break;
-	case CAM_FORMAT_MIPI_RAW_12:
-		*tpg_encode_format = 3;
-		break;
-	case CAM_FORMAT_MIPI_RAW_14:
-		*tpg_encode_format = 4;
-		break;
-	case CAM_FORMAT_MIPI_RAW_16:
-		*tpg_encode_format = 4;
-		break;
-	default:
-		CAM_ERR(CAM_ISP, "Unsupported input encode format %d",
-			in_format);
-		rc = -EINVAL;
-	}
-	return rc;
-}
-
-static int cam_top_tpg_get_hw_caps(void *hw_priv,
-	void *get_hw_cap_args, uint32_t arg_size)
-{
-	int rc = 0;
-	struct cam_top_tpg_hw_caps           *hw_caps;
-	struct cam_top_tpg_hw                *tpg_hw;
-	struct cam_hw_info                   *tpg_hw_info;
-
-	if (!hw_priv || !get_hw_cap_args) {
-		CAM_ERR(CAM_ISP, "TPG: Invalid args");
-		return -EINVAL;
-	}
-
-	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
-	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
-	hw_caps = (struct cam_top_tpg_hw_caps *) get_hw_cap_args;
-
-	hw_caps->major_version = tpg_hw->tpg_info->tpg_reg->major_version;
-	hw_caps->minor_version = tpg_hw->tpg_info->tpg_reg->minor_version;
-	hw_caps->version_incr = tpg_hw->tpg_info->tpg_reg->version_incr;
-
-	CAM_DBG(CAM_ISP,
-		"TPG:%d major:%d minor:%d ver :%d",
-		tpg_hw->hw_intf->hw_idx, hw_caps->major_version,
-		hw_caps->minor_version, hw_caps->version_incr);
-
-	return rc;
-}
-
-static int cam_top_tpg_reserve(void *hw_priv,
-	void *reserve_args, uint32_t arg_size)
-{
-	int rc = 0;
-	struct cam_top_tpg_hw                        *tpg_hw;
-	struct cam_hw_info                           *tpg_hw_info;
-	struct cam_top_tpg_hw_reserve_resource_args  *reserv;
-	struct cam_top_tpg_cfg                       *tpg_data;
-	uint32_t                                      encode_format = 0;
-	uint32_t i;
-
-	if (!hw_priv || !reserve_args || (arg_size !=
-		sizeof(struct cam_top_tpg_hw_reserve_resource_args))) {
-		CAM_ERR(CAM_ISP, "TPG: Invalid args");
-		return -EINVAL;
-	}
-
-	tpg_hw_info = (struct cam_hw_info *)hw_priv;
-	tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
-	reserv = (struct cam_top_tpg_hw_reserve_resource_args  *)reserve_args;
-
-	if (reserv->num_inport <= 0 ||
-		reserv->num_inport > CAM_TOP_TPG_MAX_SUPPORTED_DT) {
-		CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG: %u invalid input num port:%d",
-			tpg_hw->hw_intf->hw_idx, reserv->num_inport);
-		return -EINVAL;
-	}
-
-	mutex_lock(&tpg_hw->hw_info->hw_mutex);
-	if (tpg_hw->tpg_res.res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
-		mutex_unlock(&tpg_hw->hw_info->hw_mutex);
-		return -EINVAL;
-	}
-
-	if ((reserv->in_port[0]->vc > 0xF) ||
-		(reserv->in_port[0]->lane_num <= 0 ||
-		reserv->in_port[0]->lane_num > 4) ||
-		(reserv->in_port[0]->pix_pattern > 4) ||
-		(reserv->in_port[0]->lane_type >= 2)) {
-		CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG:%u invalid input %d %d %d %d",
-			tpg_hw->hw_intf->hw_idx, reserv->in_port[0]->vc,
-			reserv->in_port[0]->lane_num,
-			reserv->in_port[0]->pix_pattern,
-			reserv->in_port[0]->lane_type);
-		mutex_unlock(&tpg_hw->hw_info->hw_mutex);
-		return -EINVAL;
-	}
-	rc = cam_top_tpg_get_format(reserv->in_port[0]->format,
-		&encode_format);
-	if (rc)
-		goto error;
-
-	CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx);
-
-	tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
-	tpg_data->vc_num = reserv->in_port[0]->vc;
-	tpg_data->phy_sel = reserv->in_port[0]->lane_type;
-	tpg_data->num_active_lanes = reserv->in_port[0]->lane_num;
-	tpg_data->h_blank_count = reserv->in_port[0]->sensor_hbi;
-	tpg_data->v_blank_count = reserv->in_port[0]->sensor_vbi;
-	tpg_data->pix_pattern = reserv->in_port[0]->pix_pattern;
-	tpg_data->dt_cfg[0].data_type = reserv->in_port[0]->dt;
-	tpg_data->dt_cfg[0].frame_height = reserv->in_port[0]->height;
-	if (reserv->in_port[0]->usage_type)
-		tpg_data->dt_cfg[0].frame_width =
-			((reserv->in_port[0]->right_end -
-				reserv->in_port[0]->left_start) + 1);
-	else
-		tpg_data->dt_cfg[0].frame_width =
-			reserv->in_port[0]->left_width;
-	tpg_data->dt_cfg[0].encode_format = encode_format;
-	tpg_data->num_active_dts = 1;
-
-	CAM_DBG(CAM_ISP,
-		"TPG:%u vc_num:%d dt:%d phy:%d lines:%d pattern:%d format:%d",
-		tpg_hw->hw_intf->hw_idx,
-		tpg_data->vc_num, tpg_data->dt_cfg[0].data_type,
-		tpg_data->phy_sel, tpg_data->num_active_lanes,
-		tpg_data->pix_pattern,
-		tpg_data->dt_cfg[0].encode_format);
-
-	CAM_DBG(CAM_ISP, "TPG:%u height:%d width:%d h blank:%d v blank:%d",
-		tpg_hw->hw_intf->hw_idx,
-		tpg_data->dt_cfg[0].frame_height,
-		tpg_data->dt_cfg[0].frame_width,
-		tpg_data->h_blank_count,
-		tpg_data->v_blank_count);
-
-	if (reserv->num_inport == 1)
-		goto end;
-
-	for (i = 1; i < reserv->num_inport; i++) {
-		if ((tpg_data->vc_num != reserv->in_port[i]->vc) ||
-			(tpg_data->phy_sel != reserv->in_port[i]->lane_type) ||
-			(tpg_data->num_active_lanes !=
-				reserv->in_port[i]->lane_num) ||
-			(tpg_data->pix_pattern !=
-			reserv->in_port[i]->pix_pattern)) {
-			CAM_ERR_RATE_LIMIT(CAM_ISP,
-				"TPG: %u invalid DT config for tpg",
-				tpg_hw->hw_intf->hw_idx);
-			rc = -EINVAL;
-			goto error;
-		}
-		rc = cam_top_tpg_get_format(reserv->in_port[0]->format,
-			&encode_format);
-		if (rc)
-			return rc;
-
-		tpg_data->dt_cfg[i].data_type = reserv->in_port[i]->dt;
-		tpg_data->dt_cfg[i].frame_height =
-			reserv->in_port[i]->height;
-		tpg_data->dt_cfg[i].frame_width =
-			reserv->in_port[i]->left_width;
-		tpg_data->dt_cfg[i].encode_format = encode_format;
-		tpg_data->num_active_dts++;
-
-		CAM_DBG(CAM_ISP, "TPG:%u height:%d width:%d dt:%d format:%d",
-			tpg_hw->hw_intf->hw_idx,
-			tpg_data->dt_cfg[i].frame_height,
-			tpg_data->dt_cfg[i].frame_width,
-			tpg_data->dt_cfg[i].data_type,
-			tpg_data->dt_cfg[i].encode_format);
-
-	}
-end:
-	reserv->node_res = &tpg_hw->tpg_res;
-	tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
-error:
-	mutex_unlock(&tpg_hw->hw_info->hw_mutex);
-	CAM_DBG(CAM_ISP, "exit rc %u", rc);
-
-	return rc;
-}
+#include "cam_top_tpg_ver1.h"
+#include "cam_top_tpg_ver2.h"
 
 static int cam_top_tpg_release(void *hw_priv,
 	void *release_args, uint32_t arg_size)
@@ -266,9 +64,8 @@ static int cam_top_tpg_init_hw(void *hw_priv,
 	struct cam_top_tpg_hw                  *tpg_hw;
 	struct cam_hw_info                     *tpg_hw_info;
 	struct cam_isp_resource_node           *tpg_res;
-	const struct cam_top_tpg_reg_offset    *tpg_reg;
 	struct cam_hw_soc_info                 *soc_info;
-	uint32_t val, clk_lvl;
+	uint32_t clk_lvl;
 
 	if (!hw_priv || !init_args ||
 		(arg_size != sizeof(struct cam_isp_resource_node))) {
@@ -278,8 +75,7 @@ static int cam_top_tpg_init_hw(void *hw_priv,
 
 	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
 	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
-	tpg_res      = (struct cam_isp_resource_node *)init_args;
-	tpg_reg = tpg_hw->tpg_info->tpg_reg;
+	tpg_res = (struct cam_isp_resource_node *)init_args;
 	soc_info = &tpg_hw->hw_info->soc_info;
 
 	if (tpg_res->res_type != CAM_ISP_RESOURCE_TPG) {
@@ -321,11 +117,6 @@ static int cam_top_tpg_init_hw(void *hw_priv,
 
 	tpg_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
 
-	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
-			tpg_reg->tpg_hw_version);
-	CAM_DBG(CAM_ISP, "TPG:%d TPG HW version: 0x%x",
-		tpg_hw->hw_intf->hw_idx, val);
-
 	mutex_unlock(&tpg_hw->hw_info->hw_mutex);
 	return rc;
 
@@ -389,148 +180,6 @@ end:
 	return rc;
 }
 
-static int cam_top_tpg_start(void *hw_priv, void *start_args,
-			uint32_t arg_size)
-{
-	int rc = 0;
-	struct cam_top_tpg_hw                  *tpg_hw;
-	struct cam_hw_info                     *tpg_hw_info;
-	struct cam_hw_soc_info                 *soc_info;
-	struct cam_isp_resource_node           *tpg_res;
-	const struct cam_top_tpg_reg_offset    *tpg_reg;
-	struct cam_top_tpg_cfg                 *tpg_data;
-	uint32_t i, val;
-
-	if (!hw_priv || !start_args ||
-		(arg_size != sizeof(struct cam_isp_resource_node))) {
-		CAM_ERR(CAM_ISP, "TPG: Invalid args");
-		return -EINVAL;
-	}
-
-	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
-	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
-	tpg_reg = tpg_hw->tpg_info->tpg_reg;
-	tpg_res = (struct cam_isp_resource_node *)start_args;
-	tpg_data = (struct cam_top_tpg_cfg  *)tpg_res->res_priv;
-	soc_info = &tpg_hw->hw_info->soc_info;
-
-	if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
-		(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
-		CAM_ERR(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
-			tpg_hw->hw_intf->hw_idx,
-			tpg_res->res_type, tpg_res->res_state);
-		rc = -EINVAL;
-		goto end;
-	}
-	cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
-		tpg_reg->tpg_lfsr_seed);
-
-	for (i = 0; i < tpg_data->num_active_dts; i++) {
-		val = (((tpg_data->dt_cfg[i].frame_width & 0xFFFF) << 16) |
-			(tpg_data->dt_cfg[i].frame_height & 0x3FFF));
-		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
-			tpg_reg->tpg_dt_0_cfg_0 + 0x10 * i);
-		cam_io_w_mb(tpg_data->dt_cfg[i].data_type,
-			soc_info->reg_map[0].mem_base +
-			tpg_reg->tpg_dt_0_cfg_1 + 0x10 * i);
-		val = ((tpg_data->dt_cfg[i].encode_format & 0xF) <<
-			tpg_reg->tpg_dt_encode_format_shift) |
-			tpg_reg->tpg_payload_mode_color;
-		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
-			tpg_reg->tpg_dt_0_cfg_2 + 0x10 * i);
-	}
-
-	val = (tpg_num_dt_map[tpg_data->num_active_dts-1] <<
-		 tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num;
-	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg0);
-
-	/*
-	 * if hblank is notset configureHBlank count 500 and
-	 * V blank count is 600
-	 */
-
-	if (tpg_data->h_blank_count)
-		cam_io_w_mb(tpg_data->h_blank_count,
-			soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg1);
-	else
-		cam_io_w_mb(0x2581F4,
-		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg1);
-
-	val = (1 << tpg_reg->tpg_split_en_shift);
-	cam_io_w_mb(tpg_data->pix_pattern, soc_info->reg_map[0].mem_base +
-		tpg_reg->tpg_common_gen_cfg);
-
-	/* if VBI is notset configureVBI to 0xAFF */
-	if (tpg_data->v_blank_count)
-		cam_io_w_mb(tpg_data->v_blank_count,
-			soc_info->reg_map[0].mem_base + tpg_reg->tpg_vbi_cfg);
-	else
-		cam_io_w_mb(0xAFFF,
-			soc_info->reg_map[0].mem_base + tpg_reg->tpg_vbi_cfg);
-
-	/* Set the TOP tpg mux sel*/
-	cam_io_w_mb((1 << tpg_hw->hw_intf->hw_idx),
-		soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
-
-	val = ((tpg_data->num_active_lanes - 1) <<
-		tpg_reg->tpg_num_active_lines_shift) |
-		(1 << tpg_reg->tpg_fe_pkt_en_shift) |
-		(1 << tpg_reg->tpg_fs_pkt_en_shift) |
-		(tpg_data->phy_sel << tpg_reg->tpg_phy_sel_shift_val) |
-		(1 << tpg_reg->tpg_en_shift_val);
-	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
-
-	tpg_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
-
-	CAM_DBG(CAM_ISP, "TPG:%d started", tpg_hw->hw_intf->hw_idx);
-
-end:
-	return rc;
-}
-
-static int cam_top_tpg_stop(void *hw_priv,
-	void *stop_args, uint32_t arg_size)
-{
-	int rc = 0;
-	struct cam_top_tpg_hw                  *tpg_hw;
-	struct cam_hw_info                     *tpg_hw_info;
-	struct cam_hw_soc_info                 *soc_info;
-	struct cam_isp_resource_node           *tpg_res;
-	const struct cam_top_tpg_reg_offset    *tpg_reg;
-	struct cam_top_tpg_cfg                 *tpg_data;
-
-	if (!hw_priv || !stop_args ||
-		(arg_size != sizeof(struct cam_isp_resource_node))) {
-		CAM_ERR(CAM_ISP, "TPG: Invalid args");
-		return -EINVAL;
-	}
-
-	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
-	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
-	tpg_reg = tpg_hw->tpg_info->tpg_reg;
-	tpg_res = (struct cam_isp_resource_node  *) stop_args;
-	tpg_data = (struct cam_top_tpg_cfg  *)tpg_res->res_state;
-	soc_info = &tpg_hw->hw_info->soc_info;
-
-	if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
-		(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)) {
-		CAM_DBG(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
-			tpg_hw->hw_intf->hw_idx,
-			tpg_res->res_type, tpg_res->res_state);
-		rc = -EINVAL;
-		goto end;
-	}
-
-	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
-		tpg_reg->tpg_ctrl);
-
-	tpg_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
-
-	CAM_DBG(CAM_ISP, "TPG:%d stopped", tpg_hw->hw_intf->hw_idx);
-end:
-	return rc;
-}
-
 static int cam_top_tpg_read(void *hw_priv,
 	void *read_args, uint32_t arg_size)
 {
@@ -592,14 +241,14 @@ static int cam_top_tpg_process_cmd(void *hw_priv,
 	return 0;
 }
 
-int cam_top_tpg_hw_probe_init(struct cam_hw_intf  *tpg_hw_intf,
+int cam_top_tpg_probe_init(struct cam_hw_intf  *tpg_hw_intf,
 	uint32_t tpg_idx)
 {
 	int rc = -EINVAL;
 	struct cam_top_tpg_cfg             *tpg_data;
 	struct cam_hw_info                 *tpg_hw_info;
 	struct cam_top_tpg_hw              *tpg_hw = NULL;
-	uint32_t val = 0;
+	uint32_t hw_version = 0;
 
 	if (tpg_idx >= CAM_TOP_TPG_HW_NUM_MAX) {
 		CAM_ERR(CAM_ISP, "Invalid tpg index:%d", tpg_idx);
@@ -620,7 +269,6 @@ int cam_top_tpg_hw_probe_init(struct cam_hw_intf  *tpg_hw_intf,
 	spin_lock_init(&tpg_hw->hw_info->hw_lock);
 	spin_lock_init(&tpg_hw->lock_state);
 	init_completion(&tpg_hw->hw_info->hw_complete);
-
 	init_completion(&tpg_hw->tpg_complete);
 
 	rc = cam_top_tpg_init_soc_resources(&tpg_hw->hw_info->soc_info,
@@ -630,18 +278,20 @@ int cam_top_tpg_hw_probe_init(struct cam_hw_intf  *tpg_hw_intf,
 		goto err;
 	}
 
-	tpg_hw->hw_intf->hw_ops.get_hw_caps = cam_top_tpg_get_hw_caps;
 	tpg_hw->hw_intf->hw_ops.init        = cam_top_tpg_init_hw;
 	tpg_hw->hw_intf->hw_ops.deinit      = cam_top_tpg_deinit_hw;
 	tpg_hw->hw_intf->hw_ops.reset       = NULL;
-	tpg_hw->hw_intf->hw_ops.reserve     = cam_top_tpg_reserve;
 	tpg_hw->hw_intf->hw_ops.release     = cam_top_tpg_release;
-	tpg_hw->hw_intf->hw_ops.start       = cam_top_tpg_start;
-	tpg_hw->hw_intf->hw_ops.stop        = cam_top_tpg_stop;
 	tpg_hw->hw_intf->hw_ops.read        = cam_top_tpg_read;
 	tpg_hw->hw_intf->hw_ops.write       = cam_top_tpg_write;
 	tpg_hw->hw_intf->hw_ops.process_cmd = cam_top_tpg_process_cmd;
 
+	hw_version = tpg_hw->tpg_info->hw_dts_version;
+	if (hw_version == CAM_TOP_TPG_VERSION_1)
+		cam_top_tpg_ver1_init(tpg_hw);
+	else if (hw_version == CAM_TOP_TPG_VERSION_2)
+		cam_top_tpg_ver2_init(tpg_hw);
+
 	tpg_hw->tpg_res.res_type = CAM_ISP_RESOURCE_TPG;
 	tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
 	tpg_hw->tpg_res.hw_intf = tpg_hw->hw_intf;
@@ -655,18 +305,13 @@ int cam_top_tpg_hw_probe_init(struct cam_hw_intf  *tpg_hw_intf,
 	cam_top_tpg_enable_soc_resources(&tpg_hw->hw_info->soc_info,
 		CAM_SVS_VOTE);
 
-	val = cam_io_r_mb(tpg_hw->hw_info->soc_info.reg_map[0].mem_base +
-			tpg_hw->tpg_info->tpg_reg->tpg_hw_version);
-	CAM_DBG(CAM_ISP, "TPG:%d TPG HW version: 0x%x",
-		tpg_hw->hw_intf->hw_idx, val);
-
 	cam_top_tpg_disable_soc_resources(&tpg_hw->hw_info->soc_info);
-err:
 
+err:
 	return rc;
 }
 
-int cam_top_tpg_hw_deinit(struct cam_top_tpg_hw *top_tpg_hw)
+int cam_top_tpg_deinit(struct cam_top_tpg_hw *top_tpg_hw)
 {
 	int rc = -EINVAL;
 

+ 21 - 49
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h

@@ -3,13 +3,16 @@
  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  */
 
-#ifndef _CAM_TOP_TPG_HW_H_
-#define _CAM_TOP_TPG_HW_H_
+#ifndef _CAM_TOP_TPG_CORE_H_
+#define _CAM_TOP_TPG_CORE_H_
 
 #include "cam_hw.h"
 #include "cam_top_tpg_hw_intf.h"
 #include "cam_top_tpg_soc.h"
 
+#define CAM_TOP_TPG_VERSION_1             0x10000001
+#define CAM_TOP_TPG_VERSION_2             0x10000002
+
 enum cam_top_tpg_encode_format {
 	CAM_TOP_TPG_ENCODE_FORMAT_RAW6,
 	CAM_TOP_TPG_ENCODE_FORMAT_RAW8,
@@ -20,48 +23,6 @@ enum cam_top_tpg_encode_format {
 	CAM_TOP_TPG_ENCODE_FORMAT_MAX,
 };
 
-struct cam_top_tpg_reg_offset {
-	uint32_t tpg_hw_version;
-	uint32_t tpg_hw_status;
-	uint32_t tpg_ctrl;
-	uint32_t tpg_vc_cfg0;
-	uint32_t tpg_vc_cfg1;
-	uint32_t tpg_lfsr_seed;
-	uint32_t tpg_dt_0_cfg_0;
-	uint32_t tpg_dt_1_cfg_0;
-	uint32_t tpg_dt_2_cfg_0;
-	uint32_t tpg_dt_3_cfg_0;
-	uint32_t tpg_dt_0_cfg_1;
-	uint32_t tpg_dt_1_cfg_1;
-	uint32_t tpg_dt_2_cfg_1;
-	uint32_t tpg_dt_3_cfg_1;
-	uint32_t tpg_dt_0_cfg_2;
-	uint32_t tpg_dt_1_cfg_2;
-	uint32_t tpg_dt_2_cfg_2;
-	uint32_t tpg_dt_3_cfg_2;
-	uint32_t tpg_color_bar_cfg;
-	uint32_t tpg_common_gen_cfg;
-	uint32_t tpg_vbi_cfg;
-	uint32_t tpg_test_bus_crtl;
-	uint32_t tpg_spare;
-	/* configurations */
-	uint32_t major_version;
-	uint32_t minor_version;
-	uint32_t version_incr;
-	uint32_t tpg_en_shift_val;
-	uint32_t tpg_phy_sel_shift_val;
-	uint32_t tpg_num_active_lines_shift;
-	uint32_t tpg_fe_pkt_en_shift;
-	uint32_t tpg_fs_pkt_en_shift;
-	uint32_t tpg_line_interleaving_mode_shift;
-	uint32_t tpg_num_dts_shift_val;
-	uint32_t tpg_v_blank_cnt_shift;
-	uint32_t tpg_dt_encode_format_shift;
-	uint32_t tpg_payload_mode_color;
-	uint32_t tpg_split_en_shift;
-	uint32_t top_mux_reg_offset;
-};
-
 /**
  * struct cam_top_tpg_hw_info- tpg hardware info
  *
@@ -72,7 +33,7 @@ struct cam_top_tpg_reg_offset {
  *
  */
 struct cam_top_tpg_hw_info {
-	const struct cam_top_tpg_reg_offset    *tpg_reg;
+	void                                   *tpg_reg;
 	uint32_t                                hw_dts_version;
 	uint32_t                                csid_max_clk;
 	uint32_t                                phy_max_clk;
@@ -86,15 +47,24 @@ struct cam_top_tpg_hw_info {
  * @data_type:       data type(dt) value
  * @encode_format:   encode format for this data type
  * @payload_mode     payload data, such color bar, color box etc
+ * @bayer_pattern:   Bayer patter information
+ * @rotate_period:   period value for repeating color, 0 for no rotate
+ * @split_en:        enables split mode
+ * @unicolor_en:     enables unicolor value
+ * @unicolor_sel:    select color used in unicolor mode
  *
  */
-
 struct cam_top_tpg_dt_cfg {
 	uint32_t                               frame_width;
 	uint32_t                               frame_height;
 	uint32_t                               data_type;
 	uint32_t                               encode_format;
 	uint32_t                               payload_mode;
+	uint32_t                               bayer_pattern;
+	uint32_t                               rotate_period;
+	uint32_t                               split_en;
+	uint32_t                               unicolor_en;
+	uint32_t                               unicolor_sel;
 };
 
 /**
@@ -107,6 +77,7 @@ struct cam_top_tpg_dt_cfg {
  * @h_blank_count:   vertical blanking count value
  * @vbi_cnt:         vbi count
  * @num_active_dts:  number of active dts need to configure
+ * @num_frames:      number of output frames
  * @dt_cfg:          dt configuration values
  *
  */
@@ -119,6 +90,7 @@ struct cam_top_tpg_cfg {
 	uint32_t                        h_blank_count;
 	uint32_t                        vbi_cnt;
 	uint32_t                        num_active_dts;
+	uint32_t                        num_frames;
 	struct cam_top_tpg_dt_cfg       dt_cfg[4];
 };
 
@@ -145,9 +117,9 @@ struct cam_top_tpg_hw {
 	struct completion                tpg_complete;
 };
 
-int cam_top_tpg_hw_probe_init(struct cam_hw_intf  *tpg_hw_intf,
+int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf,
 	uint32_t tpg_idx);
 
-int cam_top_tpg_hw_deinit(struct cam_top_tpg_hw *top_tpg_hw);
+int cam_top_tpg_deinit(struct cam_top_tpg_hw *top_tpg_hw);
 
-#endif /* _CAM_TOP_TPG_HW_H_ */
+#endif /* _CAM_TOP_TPG_CORE_H_ */

+ 23 - 23
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_dev.c

@@ -21,10 +21,10 @@ static int cam_top_tpg_component_bind(struct device *dev,
 	struct device *master_dev, void *data)
 {
 	struct cam_hw_intf             *tpg_hw_intf;
-	struct cam_hw_info             *tpg_hw_info;
-	struct cam_top_tpg_hw          *tpg_dev = NULL;
+	struct cam_hw_info             *hw_info;
+	struct cam_top_tpg_hw          *tpg_hw = NULL;
 	const struct of_device_id      *match_dev = NULL;
-	struct cam_top_tpg_hw_info     *tpg_hw_data = NULL;
+	struct cam_top_tpg_hw_info     *tpg_hw_info = NULL;
 	uint32_t                        tpg_dev_idx;
 	int                             rc = 0;
 	struct platform_device *pdev = to_platform_device(dev);
@@ -37,14 +37,14 @@ static int cam_top_tpg_component_bind(struct device *dev,
 		goto err;
 	}
 
-	tpg_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
-	if (!tpg_hw_info) {
+	hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
+	if (!hw_info) {
 		rc = -ENOMEM;
 		goto free_hw_intf;
 	}
 
-	tpg_dev = kzalloc(sizeof(struct cam_top_tpg_hw), GFP_KERNEL);
-	if (!tpg_dev) {
+	tpg_hw = kzalloc(sizeof(struct cam_top_tpg_hw), GFP_KERNEL);
+	if (!tpg_hw) {
 		rc = -ENOMEM;
 		goto free_hw_info;
 	}
@@ -66,23 +66,23 @@ static int cam_top_tpg_component_bind(struct device *dev,
 
 	tpg_hw_intf->hw_idx = tpg_dev_idx;
 	tpg_hw_intf->hw_type = CAM_ISP_HW_TYPE_TPG;
-	tpg_hw_intf->hw_priv = tpg_hw_info;
+	tpg_hw_intf->hw_priv = hw_info;
 
-	tpg_hw_info->core_info = tpg_dev;
-	tpg_hw_info->soc_info.pdev = pdev;
-	tpg_hw_info->soc_info.dev = &pdev->dev;
-	tpg_hw_info->soc_info.dev_name = tpg_dev_name;
-	tpg_hw_info->soc_info.index = tpg_dev_idx;
+	hw_info->core_info = tpg_hw;
+	hw_info->soc_info.pdev = pdev;
+	hw_info->soc_info.dev = &pdev->dev;
+	hw_info->soc_info.dev_name = tpg_dev_name;
+	hw_info->soc_info.index = tpg_dev_idx;
 
-	tpg_hw_data = (struct cam_top_tpg_hw_info  *)match_dev->data;
+	tpg_hw_info = (struct cam_top_tpg_hw_info  *)match_dev->data;
 	/* need to setup the pdev before call the tfe hw probe init */
-	tpg_dev->tpg_info = tpg_hw_data;
+	tpg_hw->tpg_info = tpg_hw_info;
 
-	rc = cam_top_tpg_hw_probe_init(tpg_hw_intf, tpg_dev_idx);
+	rc = cam_top_tpg_probe_init(tpg_hw_intf, tpg_dev_idx);
 	if (rc)
 		goto free_dev;
 
-	platform_set_drvdata(pdev, tpg_dev);
+	platform_set_drvdata(pdev, tpg_hw);
 	CAM_DBG(CAM_ISP, "TPG: %d component binded successfully",
 		tpg_hw_intf->hw_idx);
 
@@ -94,9 +94,9 @@ static int cam_top_tpg_component_bind(struct device *dev,
 	return 0;
 
 free_dev:
-	kfree(tpg_dev);
+	kfree(tpg_hw);
 free_hw_info:
-	kfree(tpg_hw_info);
+	kfree(hw_info);
 free_hw_intf:
 	kfree(tpg_hw_intf);
 err:
@@ -108,19 +108,19 @@ static void cam_top_tpg_component_unbind(struct device *dev,
 {
 	struct cam_top_tpg_hw          *tpg_dev = NULL;
 	struct cam_hw_intf             *tpg_hw_intf;
-	struct cam_hw_info             *tpg_hw_info;
 	struct platform_device *pdev = to_platform_device(dev);
+	struct cam_hw_info             *hw_info;
 
 	tpg_dev = (struct cam_top_tpg_hw *)platform_get_drvdata(pdev);
 	tpg_hw_intf = tpg_dev->hw_intf;
-	tpg_hw_info = tpg_dev->hw_info;
+	hw_info = tpg_dev->hw_info;
 
 	CAM_DBG(CAM_ISP, "TPG:%d component unbound", tpg_dev->hw_intf->hw_idx);
-	cam_top_tpg_hw_deinit(tpg_dev);
+	cam_top_tpg_deinit(tpg_dev);
 
 	/*release the tpg device memory */
 	kfree(tpg_dev);
-	kfree(tpg_hw_info);
+	kfree(hw_info);
 	kfree(tpg_hw_intf);
 }
 

+ 0 - 54
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_v1.c

@@ -1,54 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
- */
-
-
-#include <linux/module.h>
-#include "cam_top_tpg_core.h"
-#include "cam_top_tpg_v1.h"
-#include "cam_top_tpg_dev.h"
-#include "camera_main.h"
-
-#define CAM_TOP_TPG_DRV_NAME                    "tpg_v1"
-#define CAM_TOP_TPG_VERSION_V1                  0x10000000
-
-static struct cam_top_tpg_hw_info cam_top_tpg_v1_hw_info = {
-	.tpg_reg = &cam_top_tpg_v1_reg_offset,
-	.hw_dts_version = CAM_TOP_TPG_VERSION_V1,
-	.csid_max_clk = 426400000,
-	.phy_max_clk = 384000000,
-};
-
-static const struct of_device_id cam_top_tpg_v1_dt_match[] = {
-	{
-		.compatible = "qcom,tpgv1",
-		.data = &cam_top_tpg_v1_hw_info,
-	},
-	{}
-};
-
-MODULE_DEVICE_TABLE(of, cam_top_tpg_v1_dt_match);
-
-struct platform_driver cam_top_tpg_v1_driver = {
-	.probe = cam_top_tpg_probe,
-	.remove = cam_top_tpg_remove,
-	.driver = {
-		.name = CAM_TOP_TPG_DRV_NAME,
-		.of_match_table = cam_top_tpg_v1_dt_match,
-		.suppress_bind_attrs = true,
-	},
-};
-
-int cam_top_tpg_v1_init_module(void)
-{
-	return platform_driver_register(&cam_top_tpg_v1_driver);
-}
-
-void cam_top_tpg_v1_exit_module(void)
-{
-	platform_driver_unregister(&cam_top_tpg_v1_driver);
-}
-
-MODULE_DESCRIPTION("CAM TOP TPG driver");
-MODULE_LICENSE("GPL v2");

+ 385 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c

@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+#include <media/cam_tfe.h>
+#include <media/cam_defs.h>
+
+#include "cam_top_tpg_core.h"
+#include "cam_soc_util.h"
+#include "cam_io_util.h"
+#include "cam_debug_util.h"
+#include "cam_top_tpg_ver1.h"
+
+static uint32_t tpg_num_dt_map[CAM_TOP_TPG_MAX_SUPPORTED_DT] = {
+	0,
+	3,
+	1,
+	2
+};
+
+static int cam_top_tpg_ver1_get_format(
+	uint32_t                                     in_format,
+	uint32_t                                    *tpg_encode_format)
+{
+	int                                          rc = 0;
+
+	switch (in_format) {
+	case CAM_FORMAT_MIPI_RAW_6:
+		*tpg_encode_format = 0;
+		break;
+	case CAM_FORMAT_MIPI_RAW_8:
+		*tpg_encode_format = 1;
+		break;
+	case CAM_FORMAT_MIPI_RAW_10:
+		*tpg_encode_format = 2;
+		break;
+	case CAM_FORMAT_MIPI_RAW_12:
+		*tpg_encode_format = 3;
+		break;
+	case CAM_FORMAT_MIPI_RAW_14:
+		*tpg_encode_format = 4;
+		break;
+	case CAM_FORMAT_MIPI_RAW_16:
+		*tpg_encode_format = 4;
+		break;
+	default:
+		CAM_ERR(CAM_ISP, "Unsupported input encode format %d",
+			in_format);
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+static int cam_top_tpg_ver1_get_hw_caps(
+	void                                         *hw_priv,
+	void                                         *get_hw_cap_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw_caps                   *hw_caps;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	const struct cam_top_tpg_ver1_reg_offset     *tpg_reg;
+	struct cam_hw_info                           *tpg_hw_info;
+
+	if (!hw_priv || !get_hw_cap_args) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
+	hw_caps = (struct cam_top_tpg_hw_caps *) get_hw_cap_args;
+	tpg_reg = tpg_hw->tpg_info->tpg_reg;
+
+	hw_caps->major_version = tpg_reg->major_version;
+	hw_caps->minor_version = tpg_reg->minor_version;
+	hw_caps->version_incr = tpg_reg->version_incr;
+
+	CAM_DBG(CAM_ISP,
+		"TPG:%d major:%d minor:%d ver :%d",
+		tpg_hw->hw_intf->hw_idx, hw_caps->major_version,
+		hw_caps->minor_version, hw_caps->version_incr);
+
+	return rc;
+}
+
+static int cam_top_tpg_ver1_reserve(
+	void                                         *hw_priv,
+	void                                         *reserve_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	struct cam_hw_info                           *tpg_hw_info;
+	struct cam_top_tpg_ver1_reserve_args         *reserv;
+	struct cam_top_tpg_cfg                       *tpg_data;
+	uint32_t                                      encode_format = 0;
+	uint32_t                                      i;
+
+	if (!hw_priv || !reserve_args || (arg_size !=
+		sizeof(struct cam_top_tpg_ver1_reserve_args))) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
+	reserv = (struct cam_top_tpg_ver1_reserve_args  *)reserve_args;
+
+	if (reserv->num_inport <= 0 ||
+		reserv->num_inport > CAM_TOP_TPG_MAX_SUPPORTED_DT) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG: %u invalid input num port:%d",
+			tpg_hw->hw_intf->hw_idx, reserv->num_inport);
+		return -EINVAL;
+	}
+
+	mutex_lock(&tpg_hw->hw_info->hw_mutex);
+	if (tpg_hw->tpg_res.res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
+		mutex_unlock(&tpg_hw->hw_info->hw_mutex);
+		return -EINVAL;
+	}
+
+	if ((reserv->in_port[0]->vc > 0xF) ||
+		(reserv->in_port[0]->lane_num <= 0 ||
+		reserv->in_port[0]->lane_num > 4) ||
+		(reserv->in_port[0]->pix_pattern > 4) ||
+		(reserv->in_port[0]->lane_type >= 2)) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG:%u invalid input %d %d %d %d",
+			tpg_hw->hw_intf->hw_idx, reserv->in_port[0]->vc,
+			reserv->in_port[0]->lane_num,
+			reserv->in_port[0]->pix_pattern,
+			reserv->in_port[0]->lane_type);
+		mutex_unlock(&tpg_hw->hw_info->hw_mutex);
+		return -EINVAL;
+	}
+	rc = cam_top_tpg_ver1_get_format(reserv->in_port[0]->format,
+		&encode_format);
+	if (rc)
+		goto error;
+
+	CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx);
+
+	tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
+	tpg_data->vc_num = reserv->in_port[0]->vc;
+	tpg_data->phy_sel = reserv->in_port[0]->lane_type;
+	tpg_data->num_active_lanes = reserv->in_port[0]->lane_num;
+	tpg_data->h_blank_count = reserv->in_port[0]->sensor_hbi;
+	tpg_data->v_blank_count = reserv->in_port[0]->sensor_vbi;
+	tpg_data->pix_pattern = reserv->in_port[0]->pix_pattern;
+	tpg_data->dt_cfg[0].data_type = reserv->in_port[0]->dt;
+	tpg_data->dt_cfg[0].frame_height = reserv->in_port[0]->height;
+	if (reserv->in_port[0]->usage_type)
+		tpg_data->dt_cfg[0].frame_width =
+			((reserv->in_port[0]->right_end -
+				reserv->in_port[0]->left_start) + 1);
+	else
+		tpg_data->dt_cfg[0].frame_width =
+			reserv->in_port[0]->left_width;
+	tpg_data->dt_cfg[0].encode_format = encode_format;
+	tpg_data->num_active_dts = 1;
+
+	CAM_DBG(CAM_ISP,
+		"TPG:%u vc_num:%d dt:%d phy:%d lines:%d pattern:%d format:%d",
+		tpg_hw->hw_intf->hw_idx,
+		tpg_data->vc_num, tpg_data->dt_cfg[0].data_type,
+		tpg_data->phy_sel, tpg_data->num_active_lanes,
+		tpg_data->pix_pattern,
+		tpg_data->dt_cfg[0].encode_format);
+
+	CAM_DBG(CAM_ISP, "TPG:%u height:%d width:%d h blank:%d v blank:%d",
+		tpg_hw->hw_intf->hw_idx,
+		tpg_data->dt_cfg[0].frame_height,
+		tpg_data->dt_cfg[0].frame_width,
+		tpg_data->h_blank_count,
+		tpg_data->v_blank_count);
+
+	if (reserv->num_inport == 1)
+		goto end;
+
+	for (i = 1; i < reserv->num_inport; i++) {
+		if ((tpg_data->vc_num != reserv->in_port[i]->vc) ||
+			(tpg_data->phy_sel != reserv->in_port[i]->lane_type) ||
+			(tpg_data->num_active_lanes !=
+				reserv->in_port[i]->lane_num) ||
+			(tpg_data->pix_pattern !=
+			reserv->in_port[i]->pix_pattern)) {
+			CAM_ERR_RATE_LIMIT(CAM_ISP,
+				"TPG: %u invalid DT config for tpg",
+				tpg_hw->hw_intf->hw_idx);
+			rc = -EINVAL;
+			goto error;
+		}
+		rc = cam_top_tpg_ver1_get_format(reserv->in_port[0]->format,
+			&encode_format);
+		if (rc)
+			return rc;
+
+		tpg_data->dt_cfg[i].data_type = reserv->in_port[i]->dt;
+		tpg_data->dt_cfg[i].frame_height =
+			reserv->in_port[i]->height;
+		tpg_data->dt_cfg[i].frame_width =
+			reserv->in_port[i]->left_width;
+		tpg_data->dt_cfg[i].encode_format = encode_format;
+		tpg_data->num_active_dts++;
+
+		CAM_DBG(CAM_ISP, "TPG:%u height:%d width:%d dt:%d format:%d",
+			tpg_hw->hw_intf->hw_idx,
+			tpg_data->dt_cfg[i].frame_height,
+			tpg_data->dt_cfg[i].frame_width,
+			tpg_data->dt_cfg[i].data_type,
+			tpg_data->dt_cfg[i].encode_format);
+
+	}
+end:
+	reserv->node_res = &tpg_hw->tpg_res;
+	tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+error:
+	mutex_unlock(&tpg_hw->hw_info->hw_mutex);
+	CAM_DBG(CAM_ISP, "exit rc %u", rc);
+
+	return rc;
+}
+
+static int cam_top_tpg_ver1_start(
+	void                                         *hw_priv,
+	void                                         *start_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	struct cam_hw_info                           *tpg_hw_info;
+	struct cam_hw_soc_info                       *soc_info;
+	struct cam_isp_resource_node                 *tpg_res;
+	struct cam_top_tpg_ver1_reg_offset           *tpg_reg;
+	struct cam_top_tpg_cfg                       *tpg_data;
+	uint32_t                                      i, val;
+
+	if (!hw_priv || !start_args ||
+		(arg_size != sizeof(struct cam_isp_resource_node))) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
+	tpg_reg = tpg_hw->tpg_info->tpg_reg;
+	tpg_res = (struct cam_isp_resource_node *)start_args;
+	tpg_data = (struct cam_top_tpg_cfg  *)tpg_res->res_priv;
+	soc_info = &tpg_hw->hw_info->soc_info;
+
+	if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
+		(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
+		CAM_ERR(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
+			tpg_hw->hw_intf->hw_idx,
+			tpg_res->res_type, tpg_res->res_state);
+		rc = -EINVAL;
+		goto end;
+	}
+	cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base +
+		tpg_reg->tpg_lfsr_seed);
+
+	for (i = 0; i < tpg_data->num_active_dts; i++) {
+		val = (((tpg_data->dt_cfg[i].frame_width & 0xFFFF) << 16) |
+			(tpg_data->dt_cfg[i].frame_height & 0x3FFF));
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_dt_0_cfg_0 + 0x10 * i);
+		cam_io_w_mb(tpg_data->dt_cfg[i].data_type,
+			soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_dt_0_cfg_1 + 0x10 * i);
+		val = ((tpg_data->dt_cfg[i].encode_format & 0xF) <<
+			tpg_reg->tpg_dt_encode_format_shift) |
+			tpg_reg->tpg_payload_mode_color;
+		cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
+			tpg_reg->tpg_dt_0_cfg_2 + 0x10 * i);
+	}
+
+	val = (tpg_num_dt_map[tpg_data->num_active_dts-1] <<
+		 tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num;
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg0);
+
+	/*
+	 * if hblank is notset configureHBlank count 500 and
+	 * V blank count is 600
+	 */
+
+	if (tpg_data->h_blank_count)
+		cam_io_w_mb(tpg_data->h_blank_count,
+			soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg1);
+	else
+		cam_io_w_mb(0x2581F4,
+		soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg1);
+
+	val = (1 << tpg_reg->tpg_split_en_shift);
+	cam_io_w_mb(tpg_data->pix_pattern, soc_info->reg_map[0].mem_base +
+		tpg_reg->tpg_common_gen_cfg);
+
+	/* if VBI is notset configureVBI to 0xAFF */
+	if (tpg_data->v_blank_count)
+		cam_io_w_mb(tpg_data->v_blank_count,
+			soc_info->reg_map[0].mem_base + tpg_reg->tpg_vbi_cfg);
+	else
+		cam_io_w_mb(0xAFFF,
+			soc_info->reg_map[0].mem_base + tpg_reg->tpg_vbi_cfg);
+
+	/* Set the TOP tpg mux sel*/
+	cam_io_w_mb((1 << tpg_hw->hw_intf->hw_idx),
+		soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
+
+	val = ((tpg_data->num_active_lanes - 1) <<
+		tpg_reg->tpg_num_active_lines_shift) |
+		(1 << tpg_reg->tpg_fe_pkt_en_shift) |
+		(1 << tpg_reg->tpg_fs_pkt_en_shift) |
+		(tpg_data->phy_sel << tpg_reg->tpg_phy_sel_shift_val) |
+		(1 << tpg_reg->tpg_en_shift_val);
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl);
+
+	tpg_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
+
+	val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
+		tpg_reg->tpg_hw_version);
+	CAM_DBG(CAM_ISP, "TPG:%d TPG HW version: 0x%x started",
+		tpg_hw->hw_intf->hw_idx, val);
+
+end:
+	return rc;
+}
+
+static int cam_top_tpg_ver1_stop(
+	void                                         *hw_priv,
+	void                                         *stop_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	struct cam_hw_info                           *tpg_hw_info;
+	struct cam_hw_soc_info                       *soc_info;
+	struct cam_isp_resource_node                 *tpg_res;
+	const struct cam_top_tpg_ver1_reg_offset     *tpg_reg;
+	struct cam_top_tpg_cfg                       *tpg_data;
+
+	if (!hw_priv || !stop_args ||
+		(arg_size != sizeof(struct cam_isp_resource_node))) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
+	tpg_reg = tpg_hw->tpg_info->tpg_reg;
+	tpg_res = (struct cam_isp_resource_node  *) stop_args;
+	tpg_data = (struct cam_top_tpg_cfg  *)tpg_res->res_state;
+	soc_info = &tpg_hw->hw_info->soc_info;
+
+	if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
+		(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)) {
+		CAM_DBG(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
+			tpg_hw->hw_intf->hw_idx,
+			tpg_res->res_type, tpg_res->res_state);
+		rc = -EINVAL;
+		goto end;
+	}
+
+	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+		tpg_reg->tpg_ctrl);
+
+	tpg_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+
+	CAM_DBG(CAM_ISP, "TPG:%d stopped", tpg_hw->hw_intf->hw_idx);
+end:
+	return rc;
+}
+
+int cam_top_tpg_ver1_init(
+	struct cam_top_tpg_hw                        *tpg_hw)
+{
+	tpg_hw->hw_intf->hw_ops.get_hw_caps = cam_top_tpg_ver1_get_hw_caps;
+	tpg_hw->hw_intf->hw_ops.reserve     = cam_top_tpg_ver1_reserve;
+	tpg_hw->hw_intf->hw_ops.start       = cam_top_tpg_ver1_start;
+	tpg_hw->hw_intf->hw_ops.stop        = cam_top_tpg_ver1_stop;
+
+	return 0;
+}

+ 55 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.h

@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CAM_TOP_TPG_VER1_H_
+#define _CAM_TOP_TPG_VER1_H_
+
+#include "cam_top_tpg_core.h"
+
+struct cam_top_tpg_ver1_reg_offset {
+	uint32_t tpg_hw_version;
+	uint32_t tpg_hw_status;
+	uint32_t tpg_ctrl;
+	uint32_t tpg_vc_cfg0;
+	uint32_t tpg_vc_cfg1;
+	uint32_t tpg_lfsr_seed;
+	uint32_t tpg_dt_0_cfg_0;
+	uint32_t tpg_dt_1_cfg_0;
+	uint32_t tpg_dt_2_cfg_0;
+	uint32_t tpg_dt_3_cfg_0;
+	uint32_t tpg_dt_0_cfg_1;
+	uint32_t tpg_dt_1_cfg_1;
+	uint32_t tpg_dt_2_cfg_1;
+	uint32_t tpg_dt_3_cfg_1;
+	uint32_t tpg_dt_0_cfg_2;
+	uint32_t tpg_dt_1_cfg_2;
+	uint32_t tpg_dt_2_cfg_2;
+	uint32_t tpg_dt_3_cfg_2;
+	uint32_t tpg_color_bar_cfg;
+	uint32_t tpg_common_gen_cfg;
+	uint32_t tpg_vbi_cfg;
+	uint32_t tpg_test_bus_crtl;
+	uint32_t tpg_spare;
+	/* configurations */
+	uint32_t major_version;
+	uint32_t minor_version;
+	uint32_t version_incr;
+	uint32_t tpg_en_shift_val;
+	uint32_t tpg_phy_sel_shift_val;
+	uint32_t tpg_num_active_lines_shift;
+	uint32_t tpg_fe_pkt_en_shift;
+	uint32_t tpg_fs_pkt_en_shift;
+	uint32_t tpg_line_interleaving_mode_shift;
+	uint32_t tpg_num_dts_shift_val;
+	uint32_t tpg_v_blank_cnt_shift;
+	uint32_t tpg_dt_encode_format_shift;
+	uint32_t tpg_payload_mode_color;
+	uint32_t tpg_split_en_shift;
+	uint32_t top_mux_reg_offset;
+};
+
+int cam_top_tpg_ver1_init(struct cam_top_tpg_hw *tpg_hw);
+
+#endif /* _CAM_TOP_TPG_VER1_H_ */

+ 242 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.c

@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/iopoll.h>
+#include <linux/slab.h>
+#include <media/cam_defs.h>
+
+#include "cam_top_tpg_core.h"
+#include "cam_soc_util.h"
+#include "cam_io_util.h"
+#include "cam_debug_util.h"
+#include "cam_top_tpg_ver2.h"
+
+#define CAM_TOP_TPG_VER2_MAX_SUPPORTED_DT 1
+
+static int cam_top_tpg_ver2_get_hw_caps(
+	void                                         *hw_priv,
+	void                                         *get_hw_cap_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw_caps                   *hw_caps;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	const struct cam_top_tpg_ver2_reg_offset     *tpg_reg;
+	struct cam_hw_info                           *tpg_hw_info;
+
+	if (!hw_priv || !get_hw_cap_args) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
+	hw_caps = (struct cam_top_tpg_hw_caps *) get_hw_cap_args;
+	tpg_reg = tpg_hw->tpg_info->tpg_reg;
+
+	hw_caps->major_version = tpg_reg->major_version;
+	hw_caps->minor_version = tpg_reg->minor_version;
+	hw_caps->version_incr = tpg_reg->version_incr;
+
+	CAM_DBG(CAM_ISP,
+		"TPG:%d major:%d minor:%d ver :%d",
+		tpg_hw->hw_intf->hw_idx, hw_caps->major_version,
+		hw_caps->minor_version, hw_caps->version_incr);
+
+	return rc;
+}
+
+static int cam_top_tpg_ver2_reserve(
+	void                                         *hw_priv,
+	void                                         *reserve_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	struct cam_hw_info                           *tpg_hw_info;
+	struct cam_top_tpg_ver2_reserve_args         *reserv;
+	struct cam_top_tpg_cfg                       *tpg_data;
+
+	if (!hw_priv || !reserve_args || (arg_size !=
+		sizeof(struct cam_top_tpg_ver2_reserve_args))) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
+	reserv = (struct cam_top_tpg_ver2_reserve_args  *)reserve_args;
+
+	if (reserv->num_inport <= 0 ||
+		reserv->num_inport > CAM_TOP_TPG_VER2_MAX_SUPPORTED_DT) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG: %u invalid input num port:%d",
+			tpg_hw->hw_intf->hw_idx, reserv->num_inport);
+		return -EINVAL;
+	}
+
+	mutex_lock(&tpg_hw->hw_info->hw_mutex);
+	if (tpg_hw->tpg_res.res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
+		CAM_ERR(CAM_ISP, "TPG:%d resource not available state:%d",
+			tpg_hw->hw_intf->hw_idx, tpg_hw->tpg_res.res_state);
+		mutex_unlock(&tpg_hw->hw_info->hw_mutex);
+		return -EINVAL;
+	}
+
+	tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv;
+	tpg_data->h_blank_count = reserv->in_port->hbi_cnt;
+	tpg_data->v_blank_count = 600;
+	tpg_data->dt_cfg[0].data_type = reserv->in_port->dt[0];
+	tpg_data->dt_cfg[0].frame_height = reserv->in_port->height;
+	if (reserv->in_port->usage_type)
+		tpg_data->dt_cfg[0].frame_width =
+			((reserv->in_port->right_stop -
+				reserv->in_port->left_start) + 1);
+	else
+		tpg_data->dt_cfg[0].frame_width =
+			reserv->in_port->left_width;
+	tpg_data->num_active_dts = 1;
+
+	CAM_DBG(CAM_ISP, "TPG:%u dt:0x%x h:%d w:%d hbi:%d vbi:%d reserved",
+		tpg_hw->hw_intf->hw_idx,
+		tpg_data->dt_cfg[0].data_type,
+		tpg_data->dt_cfg[0].frame_height,
+		tpg_data->dt_cfg[0].frame_width,
+		tpg_data->h_blank_count,
+		tpg_data->v_blank_count);
+
+	reserv->node_res = &tpg_hw->tpg_res;
+	tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+
+	mutex_unlock(&tpg_hw->hw_info->hw_mutex);
+
+	return rc;
+}
+
+static int cam_top_tpg_ver2_start(
+	void                                         *hw_priv,
+	void                                         *start_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	struct cam_hw_info                           *tpg_hw_info;
+	struct cam_hw_soc_info                       *soc_info;
+	struct cam_isp_resource_node                 *tpg_res;
+	struct cam_top_tpg_ver2_reg_offset           *tpg_reg;
+	struct cam_top_tpg_cfg                       *tpg_data;
+	uint32_t                                      val;
+	uint32_t                                      mux_sel_shift = 0;
+
+	if (!hw_priv || !start_args ||
+		(arg_size != sizeof(struct cam_isp_resource_node))) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
+	tpg_reg = tpg_hw->tpg_info->tpg_reg;
+	tpg_res = (struct cam_isp_resource_node *)start_args;
+	tpg_data = (struct cam_top_tpg_cfg  *)tpg_res->res_priv;
+	soc_info = &tpg_hw->hw_info->soc_info;
+
+	if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
+		(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) {
+		CAM_ERR(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
+			tpg_hw->hw_intf->hw_idx,
+			tpg_res->res_type, tpg_res->res_state);
+		rc = -EINVAL;
+		goto end;
+	}
+
+	if (tpg_hw->hw_intf->hw_idx == CAM_TOP_TPG_ID_0)
+		mux_sel_shift = tpg_reg->tpg_mux_sel_tpg_0_shift;
+	else if (tpg_hw->hw_intf->hw_idx == CAM_TOP_TPG_ID_1)
+		mux_sel_shift = tpg_reg->tpg_mux_sel_tpg_1_shift;
+
+	cam_io_w_mb((tpg_reg->tpg_mux_sel_en << mux_sel_shift),
+		soc_info->reg_map[1].mem_base + tpg_reg->top_mux_sel);
+
+	val = (((tpg_data->dt_cfg[0].frame_width & 0x3FFF) << 16) |
+		(tpg_data->dt_cfg[0].frame_height & 0x3FFF));
+
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_cfg_0);
+
+	val = (tpg_data->h_blank_count & 0x7FF) << 20;
+	val |= (tpg_data->v_blank_count & 0x3FFFF);
+
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_cfg_1);
+
+	val = tpg_data->dt_cfg[0].data_type << 11;
+	cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_cfg_2);
+
+	/* program number of frames */
+	cam_io_w_mb(1, soc_info->reg_map[0].mem_base + tpg_reg->tpg_cfg_3);
+
+	cam_io_w_mb(tpg_reg->tpg_module_en, soc_info->reg_map[0].mem_base +
+		tpg_reg->tpg_module_cfg);
+
+	tpg_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
+	CAM_DBG(CAM_ISP, "TPG:%d started", tpg_hw->hw_intf->hw_idx);
+
+end:
+	return rc;
+}
+
+static int cam_top_tpg_ver2_stop(
+	void                                         *hw_priv,
+	void                                         *stop_args,
+	uint32_t                                      arg_size)
+{
+	int                                           rc = 0;
+	struct cam_top_tpg_hw                        *tpg_hw;
+	struct cam_hw_info                           *tpg_hw_info;
+	struct cam_hw_soc_info                       *soc_info;
+	struct cam_isp_resource_node                 *tpg_res;
+	const struct cam_top_tpg_ver2_reg_offset     *tpg_reg;
+	struct cam_top_tpg_cfg                       *tpg_data;
+
+	if (!hw_priv || !stop_args ||
+		(arg_size != sizeof(struct cam_isp_resource_node))) {
+		CAM_ERR(CAM_ISP, "TPG: Invalid args");
+		return -EINVAL;
+	}
+
+	tpg_hw_info = (struct cam_hw_info  *)hw_priv;
+	tpg_hw = (struct cam_top_tpg_hw   *)tpg_hw_info->core_info;
+	tpg_reg = tpg_hw->tpg_info->tpg_reg;
+	tpg_res = (struct cam_isp_resource_node  *) stop_args;
+	tpg_data = (struct cam_top_tpg_cfg  *)tpg_res->res_state;
+	soc_info = &tpg_hw->hw_info->soc_info;
+
+	if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
+		(tpg_res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)) {
+		CAM_DBG(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d",
+			tpg_hw->hw_intf->hw_idx,
+			tpg_res->res_type, tpg_res->res_state);
+		rc = -EINVAL;
+		goto end;
+	}
+
+	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
+		tpg_reg->tpg_module_cfg);
+
+	tpg_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
+
+	CAM_DBG(CAM_ISP, "TPG:%d stopped", tpg_hw->hw_intf->hw_idx);
+end:
+	return rc;
+}
+
+int cam_top_tpg_ver2_init(
+	struct cam_top_tpg_hw                        *tpg_hw)
+{
+	tpg_hw->hw_intf->hw_ops.get_hw_caps = cam_top_tpg_ver2_get_hw_caps;
+	tpg_hw->hw_intf->hw_ops.reserve     = cam_top_tpg_ver2_reserve;
+	tpg_hw->hw_intf->hw_ops.start       = cam_top_tpg_ver2_start;
+	tpg_hw->hw_intf->hw_ops.stop        = cam_top_tpg_ver2_stop;
+
+	return 0;
+}

+ 44 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.h

@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _CAM_TOP_TPG_VER2_H_
+#define _CAM_TOP_TPG_VER2_H_
+
+#include "cam_top_tpg_core.h"
+
+struct cam_top_tpg_ver2_reg_offset {
+	uint32_t tpg_hw_version;
+	uint32_t tpg_hw_status;
+	uint32_t tpg_module_cfg;
+	uint32_t tpg_cfg_0;
+	uint32_t tpg_cfg_1;
+	uint32_t tpg_cfg_2;
+	uint32_t tpg_cfg_3;
+	uint32_t tpg_spare;
+	uint32_t top_mux_sel;
+	/* configurations */
+	uint32_t major_version;
+	uint32_t minor_version;
+	uint32_t version_incr;
+	uint32_t tpg_module_en;
+	uint32_t tpg_mux_sel_en;
+	uint32_t tpg_mux_sel_tpg_0_shift;
+	uint32_t tpg_mux_sel_tpg_1_shift;
+	uint32_t tpg_en_shift_val;
+	uint32_t tpg_phy_sel_shift_val;
+	uint32_t tpg_num_active_lines_shift;
+	uint32_t tpg_fe_pkt_en_shift;
+	uint32_t tpg_fs_pkt_en_shift;
+	uint32_t tpg_line_interleaving_mode_shift;
+	uint32_t tpg_num_dts_shift_val;
+	uint32_t tpg_v_blank_cnt_shift;
+	uint32_t tpg_dt_encode_format_shift;
+	uint32_t tpg_payload_mode_color;
+	uint32_t tpg_split_en_shift;
+};
+
+int cam_top_tpg_ver2_init(struct cam_top_tpg_hw *tpg_hw);
+
+#endif /* _CAM_TOP_TPG_VER2_H_ */

+ 5 - 3
drivers/camera_main.c

@@ -50,7 +50,7 @@
 
 #include "ope_dev_intf.h"
 
-#include "cam_top_tpg_v1.h"
+#include "cam_top_tpg.h"
 #include "cam_tfe_dev.h"
 #include "cam_tfe_csid530.h"
 #include "camera_main.h"
@@ -77,6 +77,7 @@ static const struct camera_submodule_component camera_base[] = {
 
 static const struct camera_submodule_component camera_isp[] = {
 #ifdef CONFIG_SPECTRA_ISP
+	{&cam_top_tpg_init_module, &cam_top_tpg_exit_module},
 	{&cam_ife_csid17x_init_module, &cam_ife_csid17x_exit_module},
 	{&cam_ife_csid_lite_init_module, &cam_ife_csid_lite_exit_module},
 	{&cam_vfe_init_module, &cam_vfe_exit_module},
@@ -86,7 +87,7 @@ static const struct camera_submodule_component camera_isp[] = {
 
 static const struct camera_submodule_component camera_tfe[] = {
 #if IS_ENABLED(CONFIG_SPECTRA_TFE)
-	{&cam_top_tpg_v1_init_module, &cam_top_tpg_v1_exit_module},
+	{&cam_top_tpg_init_module, &cam_top_tpg_exit_module},
 	{&cam_tfe_init_module, &cam_tfe_exit_module},
 	{&cam_tfe_csid530_init_module, &cam_tfe_csid530_exit_module},
 #endif
@@ -218,13 +219,14 @@ static struct platform_driver *const cam_component_drivers[] = {
 	&cam_cdm_intf_driver,
 	&cam_hw_cdm_driver,
 #ifdef CONFIG_SPECTRA_ISP
+	&cam_top_tpg_driver,
 	&cam_ife_csid17x_driver,
 	&cam_ife_csid_lite_driver,
 	&cam_vfe_driver,
 	&isp_driver,
 #endif
 #ifdef CONFIG_SPECTRA_TFE
-	&cam_top_tpg_v1_driver,
+	&cam_top_tpg_driver,
 	&cam_tfe_driver,
 	&cam_tfe_csid530_driver,
 #endif

+ 2 - 1
drivers/camera_main.h

@@ -15,13 +15,14 @@ extern struct platform_driver cam_cpas_driver;
 extern struct platform_driver cam_cdm_intf_driver;
 extern struct platform_driver cam_hw_cdm_driver;
 #ifdef CONFIG_SPECTRA_ISP
+extern struct platform_driver cam_top_tpg_driver;
 extern struct platform_driver cam_ife_csid17x_driver;
 extern struct platform_driver cam_ife_csid_lite_driver;
 extern struct platform_driver cam_vfe_driver;
 extern struct platform_driver isp_driver;
 #endif
 #ifdef CONFIG_SPECTRA_TFE
-extern struct platform_driver cam_top_tpg_v1_driver;
+extern struct platform_driver cam_top_tpg_driver;
 extern struct platform_driver cam_tfe_driver;
 extern struct platform_driver cam_tfe_csid530_driver;
 #endif

+ 4 - 2
include/uapi/camera/media/cam_isp_ife.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __UAPI_CAM_ISP_IFE_H__
@@ -49,6 +49,8 @@
 #define CAM_ISP_IFE_IN_RES_PHY_4               (CAM_ISP_IFE_IN_RES_BASE + 5)
 #define CAM_ISP_IFE_IN_RES_PHY_5               (CAM_ISP_IFE_IN_RES_BASE + 6)
 #define CAM_ISP_IFE_IN_RES_RD                  (CAM_ISP_IFE_IN_RES_BASE + 7)
-#define CAM_ISP_IFE_IN_RES_MAX                 (CAM_ISP_IFE_IN_RES_BASE + 8)
+#define CAM_ISP_IFE_IN_RES_CPHY_TPG_0          (CAM_ISP_IFE_IN_RES_BASE + 8)
+#define CAM_ISP_IFE_IN_RES_CPHY_TPG_1          (CAM_ISP_IFE_IN_RES_BASE + 9)
+#define CAM_ISP_IFE_IN_RES_MAX                 (CAM_ISP_IFE_IN_RES_BASE + 10)
 
 #endif /* __UAPI_CAM_ISP_IFE_H__ */