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 <vhajeri@codeaurora.org>
Signed-off-by: Venkat Chinta <vchinta@codeaurora.org>
Signed-off-by: Mukund Madhusudan Atre <matre@codeaurora.org>
This commit is contained in:
Venkat Chinta
2020-01-30 12:43:55 -08:00
parent 381bb12c68
commit 131b4115d5
22 changed files with 1055 additions and 529 deletions

View File

@@ -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_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/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/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_isp_hw_mgr.o \
cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \ cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \
cam_isp/cam_isp_dev.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_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_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_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 camera-y += camera_main.o

View File

@@ -424,6 +424,17 @@ static int cam_ife_hw_mgr_init_hw(
struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_mgr_res *hw_mgr_res;
int rc = 0, i; 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", CAM_DBG(CAM_ISP, "INIT IFE CID ... in ctx id:%d",
ctx->ctx_index); ctx->ctx_index);
/* INIT IFE CID */ /* 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); 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 */ /* ife root node */
if (ife_ctx->res_list_ife_in.res_type != CAM_ISP_RESOURCE_UNINT) 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); 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( static int cam_ife_hw_mgr_acquire_res_ife_csid_pxl(
struct cam_ife_hw_mgr_ctx *ife_ctx, struct cam_ife_hw_mgr_ctx *ife_ctx,
struct cam_isp_in_port_generic_info *in_port, 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; 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, rc = cam_ife_mgr_acquire_hw_for_ctx(ife_ctx, in_port,
&num_pix_port_per_in, &num_rdi_port_per_in, &num_pix_port_per_in, &num_rdi_port_per_in,
&acquire_args->acquired_hw_id[i], &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)) if (cam_cdm_stream_off(ctx->cdm_handle))
CAM_ERR(CAM_ISP, "CDM stream off failed %d", 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_ife_hw_mgr_deinit_hw(ctx);
CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP,
"Stop success for ctx id:%d rc :%d", ctx->ctx_index, rc); "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 */ /* Start IFE root node: do nothing */
CAM_DBG(CAM_ISP, "Start success for ctx id:%d", ctx->ctx_index); 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; 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); cam_ife_hw_mgr_sort_dev_with_caps(&g_ife_hw_mgr);
/* setup ife context list */ /* 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])); 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].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_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_cid);
INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_csid); INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_csid);

View File

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

View File

@@ -1350,7 +1350,7 @@ static int cam_tfe_hw_mgr_acquire_tpg(
uint32_t i, j = 0; uint32_t i, j = 0;
struct cam_tfe_hw_mgr *tfe_hw_mgr; struct cam_tfe_hw_mgr *tfe_hw_mgr;
struct cam_hw_intf *hw_intf; 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; tfe_hw_mgr = tfe_ctx->hw_mgr;

View File

@@ -25,6 +25,10 @@
#define CAM_IFE_CSID_TPG_VC_VAL 0xA #define CAM_IFE_CSID_TPG_VC_VAL 0xA
#define CAM_IFE_CSID_TPG_DT_VAL 0x2B #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 */ /* Timeout values in usec */
#define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000 #define CAM_IFE_CSID_TIMEOUT_SLEEP_US 1000
#define CAM_IFE_CSID_TIMEOUT_ALL_US 100000 #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); csid_hw->tpg_cfg.height);
cid_data->tpg_set = 1; 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 { } else {
csid_hw->csi2_rx_cfg.phy_sel = csid_hw->csi2_rx_cfg.phy_sel =
(cid_reserv->in_port->res_type & 0xFF) - 1; (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, reserve->in_port->line_start, reserve->in_port->line_stop,
path_data->crop_enable); path_data->crop_enable);
if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) { if ((reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) ||
path_data->dt = CAM_IFE_CSID_TPG_DT_VAL; (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1)) {
path_data->vc = CAM_IFE_CSID_TPG_VC_VAL; path_data->dt = CAM_IFE_CSI_TPG_DT_VAL;
path_data->vc = CAM_IFE_CSI_TPG_VC_VAL;
} else { } else {
path_data->dt = reserve->in_port->dt[0]; path_data->dt = reserve->in_port->dt[0];
path_data->vc = reserve->in_port->vc[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 + 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_rdis +
ife_csid_hw->csid_info->csid_reg->cmn_reg->num_udis; ife_csid_hw->csid_info->csid_reg->cmn_reg->num_udis;
/* Initialize the CID resource */ /* Initialize the CID resource */
for (i = 0; i < num_paths; i++) { for (i = 0; i < num_paths; i++) {
ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID; ife_csid_hw->cid_res[i].res_type = CAM_ISP_RESOURCE_CID;

View File

@@ -8,6 +8,7 @@
#include "cam_isp_hw.h" #include "cam_isp_hw.h"
#include "cam_hw_intf.h" #include "cam_hw_intf.h"
#include "cam_ife_csid_hw_intf.h"
/* Max top tpg instance */ /* Max top tpg instance */
#define CAM_TOP_TPG_HW_NUM_MAX 2 #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 * @num_inport: number of inport
* TPG support 4 dt types, each different dt comes in different * TPG support 4 dt types, each different dt comes in different
* in port. * in port.
@@ -45,12 +46,26 @@ struct cam_top_tpg_hw_caps {
* @node_res : Reserved resource structure pointer * @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; uint32_t num_inport;
struct cam_isp_tfe_in_port_info *in_port[CAM_TOP_TPG_MAX_SUPPORTED_DT]; struct cam_isp_tfe_in_port_info *in_port[CAM_TOP_TPG_MAX_SUPPORTED_DT];
struct cam_isp_resource_node *node_res; 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() * cam_top_tpg_hw_init()
* *

View File

@@ -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

View File

@@ -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");

View File

@@ -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_ */

View File

@@ -3,12 +3,13 @@
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/ */
#ifndef _CAM_TOP_TPG_V1_H_ #ifndef _CAM_TOP_TPG101_H_
#define _CAM_TOP_TPG_V1_H_ #define _CAM_TOP_TPG101_H_
#include "cam_top_tpg_ver1.h"
#include "cam_top_tpg_core.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_version = 0x0,
.tpg_hw_status = 0x4, .tpg_hw_status = 0x4,
.tpg_ctrl = 0x60, .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, .top_mux_reg_offset = 0x1C,
}; };
int cam_top_tpg_v1_init_module(void); struct cam_top_tpg_hw_info cam_top_tpg101_hw_info = {
void cam_top_tpg_v1_exit_module(void); .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_ */

View File

@@ -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_ */

View File

@@ -13,210 +13,8 @@
#include "cam_io_util.h" #include "cam_io_util.h"
#include "cam_debug_util.h" #include "cam_debug_util.h"
#include "cam_cpas_api.h" #include "cam_cpas_api.h"
#include "cam_top_tpg_ver1.h"
#include "cam_top_tpg_ver2.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;
}
static int cam_top_tpg_release(void *hw_priv, static int cam_top_tpg_release(void *hw_priv,
void *release_args, uint32_t arg_size) 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_top_tpg_hw *tpg_hw;
struct cam_hw_info *tpg_hw_info; struct cam_hw_info *tpg_hw_info;
struct cam_isp_resource_node *tpg_res; struct cam_isp_resource_node *tpg_res;
const struct cam_top_tpg_reg_offset *tpg_reg;
struct cam_hw_soc_info *soc_info; struct cam_hw_soc_info *soc_info;
uint32_t val, clk_lvl; uint32_t clk_lvl;
if (!hw_priv || !init_args || if (!hw_priv || !init_args ||
(arg_size != sizeof(struct cam_isp_resource_node))) { (arg_size != sizeof(struct cam_isp_resource_node))) {
@@ -279,7 +76,6 @@ static int cam_top_tpg_init_hw(void *hw_priv,
tpg_hw_info = (struct cam_hw_info *)hw_priv; tpg_hw_info = (struct cam_hw_info *)hw_priv;
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info; tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
tpg_res = (struct cam_isp_resource_node *)init_args; tpg_res = (struct cam_isp_resource_node *)init_args;
tpg_reg = tpg_hw->tpg_info->tpg_reg;
soc_info = &tpg_hw->hw_info->soc_info; soc_info = &tpg_hw->hw_info->soc_info;
if (tpg_res->res_type != CAM_ISP_RESOURCE_TPG) { 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; 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); mutex_unlock(&tpg_hw->hw_info->hw_mutex);
return rc; return rc;
@@ -389,148 +180,6 @@ end:
return rc; 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, static int cam_top_tpg_read(void *hw_priv,
void *read_args, uint32_t arg_size) void *read_args, uint32_t arg_size)
{ {
@@ -592,14 +241,14 @@ static int cam_top_tpg_process_cmd(void *hw_priv,
return 0; 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) uint32_t tpg_idx)
{ {
int rc = -EINVAL; int rc = -EINVAL;
struct cam_top_tpg_cfg *tpg_data; struct cam_top_tpg_cfg *tpg_data;
struct cam_hw_info *tpg_hw_info; struct cam_hw_info *tpg_hw_info;
struct cam_top_tpg_hw *tpg_hw = NULL; 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) { if (tpg_idx >= CAM_TOP_TPG_HW_NUM_MAX) {
CAM_ERR(CAM_ISP, "Invalid tpg index:%d", tpg_idx); 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->hw_info->hw_lock);
spin_lock_init(&tpg_hw->lock_state); spin_lock_init(&tpg_hw->lock_state);
init_completion(&tpg_hw->hw_info->hw_complete); init_completion(&tpg_hw->hw_info->hw_complete);
init_completion(&tpg_hw->tpg_complete); init_completion(&tpg_hw->tpg_complete);
rc = cam_top_tpg_init_soc_resources(&tpg_hw->hw_info->soc_info, 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; 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.init = cam_top_tpg_init_hw;
tpg_hw->hw_intf->hw_ops.deinit = cam_top_tpg_deinit_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.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.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.read = cam_top_tpg_read;
tpg_hw->hw_intf->hw_ops.write = cam_top_tpg_write; tpg_hw->hw_intf->hw_ops.write = cam_top_tpg_write;
tpg_hw->hw_intf->hw_ops.process_cmd = cam_top_tpg_process_cmd; 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_type = CAM_ISP_RESOURCE_TPG;
tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
tpg_hw->tpg_res.hw_intf = tpg_hw->hw_intf; 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_top_tpg_enable_soc_resources(&tpg_hw->hw_info->soc_info,
CAM_SVS_VOTE); 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); cam_top_tpg_disable_soc_resources(&tpg_hw->hw_info->soc_info);
err:
err:
return rc; 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; int rc = -EINVAL;

View File

@@ -3,13 +3,16 @@
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/ */
#ifndef _CAM_TOP_TPG_HW_H_ #ifndef _CAM_TOP_TPG_CORE_H_
#define _CAM_TOP_TPG_HW_H_ #define _CAM_TOP_TPG_CORE_H_
#include "cam_hw.h" #include "cam_hw.h"
#include "cam_top_tpg_hw_intf.h" #include "cam_top_tpg_hw_intf.h"
#include "cam_top_tpg_soc.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 { enum cam_top_tpg_encode_format {
CAM_TOP_TPG_ENCODE_FORMAT_RAW6, CAM_TOP_TPG_ENCODE_FORMAT_RAW6,
CAM_TOP_TPG_ENCODE_FORMAT_RAW8, CAM_TOP_TPG_ENCODE_FORMAT_RAW8,
@@ -20,48 +23,6 @@ enum cam_top_tpg_encode_format {
CAM_TOP_TPG_ENCODE_FORMAT_MAX, 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 * 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 { 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 hw_dts_version;
uint32_t csid_max_clk; uint32_t csid_max_clk;
uint32_t phy_max_clk; uint32_t phy_max_clk;
@@ -86,15 +47,24 @@ struct cam_top_tpg_hw_info {
* @data_type: data type(dt) value * @data_type: data type(dt) value
* @encode_format: encode format for this data type * @encode_format: encode format for this data type
* @payload_mode payload data, such color bar, color box etc * @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 { struct cam_top_tpg_dt_cfg {
uint32_t frame_width; uint32_t frame_width;
uint32_t frame_height; uint32_t frame_height;
uint32_t data_type; uint32_t data_type;
uint32_t encode_format; uint32_t encode_format;
uint32_t payload_mode; 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 * @h_blank_count: vertical blanking count value
* @vbi_cnt: vbi count * @vbi_cnt: vbi count
* @num_active_dts: number of active dts need to configure * @num_active_dts: number of active dts need to configure
* @num_frames: number of output frames
* @dt_cfg: dt configuration values * @dt_cfg: dt configuration values
* *
*/ */
@@ -119,6 +90,7 @@ struct cam_top_tpg_cfg {
uint32_t h_blank_count; uint32_t h_blank_count;
uint32_t vbi_cnt; uint32_t vbi_cnt;
uint32_t num_active_dts; uint32_t num_active_dts;
uint32_t num_frames;
struct cam_top_tpg_dt_cfg dt_cfg[4]; struct cam_top_tpg_dt_cfg dt_cfg[4];
}; };
@@ -145,9 +117,9 @@ struct cam_top_tpg_hw {
struct completion tpg_complete; 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); 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_ */

View File

@@ -21,10 +21,10 @@ static int cam_top_tpg_component_bind(struct device *dev,
struct device *master_dev, void *data) struct device *master_dev, void *data)
{ {
struct cam_hw_intf *tpg_hw_intf; struct cam_hw_intf *tpg_hw_intf;
struct cam_hw_info *tpg_hw_info; struct cam_hw_info *hw_info;
struct cam_top_tpg_hw *tpg_dev = NULL; struct cam_top_tpg_hw *tpg_hw = NULL;
const struct of_device_id *match_dev = 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; uint32_t tpg_dev_idx;
int rc = 0; int rc = 0;
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
@@ -37,14 +37,14 @@ static int cam_top_tpg_component_bind(struct device *dev,
goto err; goto err;
} }
tpg_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
if (!tpg_hw_info) { if (!hw_info) {
rc = -ENOMEM; rc = -ENOMEM;
goto free_hw_intf; goto free_hw_intf;
} }
tpg_dev = kzalloc(sizeof(struct cam_top_tpg_hw), GFP_KERNEL); tpg_hw = kzalloc(sizeof(struct cam_top_tpg_hw), GFP_KERNEL);
if (!tpg_dev) { if (!tpg_hw) {
rc = -ENOMEM; rc = -ENOMEM;
goto free_hw_info; 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_idx = tpg_dev_idx;
tpg_hw_intf->hw_type = CAM_ISP_HW_TYPE_TPG; 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; hw_info->core_info = tpg_hw;
tpg_hw_info->soc_info.pdev = pdev; hw_info->soc_info.pdev = pdev;
tpg_hw_info->soc_info.dev = &pdev->dev; hw_info->soc_info.dev = &pdev->dev;
tpg_hw_info->soc_info.dev_name = tpg_dev_name; hw_info->soc_info.dev_name = tpg_dev_name;
tpg_hw_info->soc_info.index = tpg_dev_idx; 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 */ /* 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) if (rc)
goto free_dev; goto free_dev;
platform_set_drvdata(pdev, tpg_dev); platform_set_drvdata(pdev, tpg_hw);
CAM_DBG(CAM_ISP, "TPG: %d component binded successfully", CAM_DBG(CAM_ISP, "TPG: %d component binded successfully",
tpg_hw_intf->hw_idx); tpg_hw_intf->hw_idx);
@@ -94,9 +94,9 @@ static int cam_top_tpg_component_bind(struct device *dev,
return 0; return 0;
free_dev: free_dev:
kfree(tpg_dev); kfree(tpg_hw);
free_hw_info: free_hw_info:
kfree(tpg_hw_info); kfree(hw_info);
free_hw_intf: free_hw_intf:
kfree(tpg_hw_intf); kfree(tpg_hw_intf);
err: 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_top_tpg_hw *tpg_dev = NULL;
struct cam_hw_intf *tpg_hw_intf; struct cam_hw_intf *tpg_hw_intf;
struct cam_hw_info *tpg_hw_info;
struct platform_device *pdev = to_platform_device(dev); 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_dev = (struct cam_top_tpg_hw *)platform_get_drvdata(pdev);
tpg_hw_intf = tpg_dev->hw_intf; 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_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 */ /*release the tpg device memory */
kfree(tpg_dev); kfree(tpg_dev);
kfree(tpg_hw_info); kfree(hw_info);
kfree(tpg_hw_intf); kfree(tpg_hw_intf);
} }

View File

@@ -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");

View File

@@ -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;
}

View File

@@ -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_ */

View File

@@ -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;
}

View File

@@ -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_ */

View File

@@ -50,7 +50,7 @@
#include "ope_dev_intf.h" #include "ope_dev_intf.h"
#include "cam_top_tpg_v1.h" #include "cam_top_tpg.h"
#include "cam_tfe_dev.h" #include "cam_tfe_dev.h"
#include "cam_tfe_csid530.h" #include "cam_tfe_csid530.h"
#include "camera_main.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[] = { static const struct camera_submodule_component camera_isp[] = {
#ifdef CONFIG_SPECTRA_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_csid17x_init_module, &cam_ife_csid17x_exit_module},
{&cam_ife_csid_lite_init_module, &cam_ife_csid_lite_exit_module}, {&cam_ife_csid_lite_init_module, &cam_ife_csid_lite_exit_module},
{&cam_vfe_init_module, &cam_vfe_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[] = { static const struct camera_submodule_component camera_tfe[] = {
#if IS_ENABLED(CONFIG_SPECTRA_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_init_module, &cam_tfe_exit_module},
{&cam_tfe_csid530_init_module, &cam_tfe_csid530_exit_module}, {&cam_tfe_csid530_init_module, &cam_tfe_csid530_exit_module},
#endif #endif
@@ -218,13 +219,14 @@ static struct platform_driver *const cam_component_drivers[] = {
&cam_cdm_intf_driver, &cam_cdm_intf_driver,
&cam_hw_cdm_driver, &cam_hw_cdm_driver,
#ifdef CONFIG_SPECTRA_ISP #ifdef CONFIG_SPECTRA_ISP
&cam_top_tpg_driver,
&cam_ife_csid17x_driver, &cam_ife_csid17x_driver,
&cam_ife_csid_lite_driver, &cam_ife_csid_lite_driver,
&cam_vfe_driver, &cam_vfe_driver,
&isp_driver, &isp_driver,
#endif #endif
#ifdef CONFIG_SPECTRA_TFE #ifdef CONFIG_SPECTRA_TFE
&cam_top_tpg_v1_driver, &cam_top_tpg_driver,
&cam_tfe_driver, &cam_tfe_driver,
&cam_tfe_csid530_driver, &cam_tfe_csid530_driver,
#endif #endif

View File

@@ -15,13 +15,14 @@ extern struct platform_driver cam_cpas_driver;
extern struct platform_driver cam_cdm_intf_driver; extern struct platform_driver cam_cdm_intf_driver;
extern struct platform_driver cam_hw_cdm_driver; extern struct platform_driver cam_hw_cdm_driver;
#ifdef CONFIG_SPECTRA_ISP #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_csid17x_driver;
extern struct platform_driver cam_ife_csid_lite_driver; extern struct platform_driver cam_ife_csid_lite_driver;
extern struct platform_driver cam_vfe_driver; extern struct platform_driver cam_vfe_driver;
extern struct platform_driver isp_driver; extern struct platform_driver isp_driver;
#endif #endif
#ifdef CONFIG_SPECTRA_TFE #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_driver;
extern struct platform_driver cam_tfe_csid530_driver; extern struct platform_driver cam_tfe_csid530_driver;
#endif #endif

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* 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__ #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_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_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_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__ */ #endif /* __UAPI_CAM_ISP_IFE_H__ */