msm: camera: isp: Remove TPG code from hw manager

In upcoming targets, TPG will be supported as a separate node.
This commit removes the tpg code from ife/tfe hw manager.

CRs-Fixed: 2973850
Change-Id: I031302756d85e004fc3a07f9864daf2c16dd837b
Signed-off-by: Gaurav Jindal <gjindal@codeaurora.org>
This commit is contained in:
Gaurav Jindal
2021-04-20 10:16:29 +05:30
parent c6903209f2
commit 52ac0ccc9f
30 changed files with 30 additions and 3328 deletions

7
Kbuild
View File

@@ -133,13 +133,6 @@ camera-$(CONFIG_SPECTRA_ISP) += \
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_fe_ver1.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_dev.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.o \
drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.o \
drivers/cam_isp/isp_hw_mgr/cam_isp_hw_mgr.o \
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \
drivers/cam_isp/cam_isp_dev.o \

View File

@@ -822,9 +822,6 @@ static void cam_ife_hw_mgr_deinit_hw(
hw_mgr = ctx->hw_mgr;
if (ctx->flags.is_tpg)
cam_ife_hw_mgr_deinit_hw_res(&ctx->res_list_tpg);
if (hw_mgr->csid_global_reset_en)
cam_ife_hw_mgr_reset_csid(ctx, CAM_IFE_CSID_RESET_GLOBAL);
@@ -881,17 +878,6 @@ static int cam_ife_hw_mgr_init_hw(
struct cam_ife_hw_mgr *hw_mgr;
int rc = 0, i;
if (ctx->flags.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;
}
}
/* INIT IFE SRC */
CAM_DBG(CAM_ISP, "INIT IFE SRC in ctx id:%d",
ctx->ctx_index);
@@ -1117,16 +1103,10 @@ static void cam_ife_hw_mgr_dump_all_ctx(void)
list_for_each_entry_safe(ctx, ctx_temp,
&g_ife_hw_mgr.used_ctx_list, list) {
CAM_INFO_RATE_LIMIT(CAM_ISP,
"ctx id:%d is_dual:%d is_tpg:%d num_base:%d rdi only:%d",
ctx->ctx_index, ctx->flags.is_dual, ctx->flags.is_tpg,
"ctx id:%d is_dual:%d num_base:%d rdi only:%d",
ctx->ctx_index, ctx->flags.is_dual,
ctx->num_base, ctx->flags.is_rdi_only_context);
if (ctx->res_list_tpg.res_type == CAM_ISP_RESOURCE_TPG) {
CAM_INFO_RATE_LIMIT(CAM_ISP,
"Acquired TPG HW:%d",
ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx);
}
list_for_each_entry_safe(hw_mgr_res, hw_mgr_res_temp,
&ctx->res_list_ife_csid, list) {
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
@@ -1239,9 +1219,6 @@ static void cam_ife_hw_mgr_print_acquire_info(
if (hw_mgr_ctx->flags.dsp_enabled)
len += scnprintf(log_info + len, (128 - len), " DSP: Y");
if (hw_mgr_ctx->flags.is_tpg)
len += scnprintf(log_info + len, (128 - len), " TPG: Y");
if (hw_mgr_ctx->flags.is_offline)
len += scnprintf(log_info + len, (128 - len), " OFFLINE: Y");
@@ -1516,10 +1493,6 @@ 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->flags.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);
@@ -3117,53 +3090,6 @@ acquire_successful:
return rc;
}
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 = 0;
struct cam_ife_hw_mgr *ife_hw_mgr;
struct cam_hw_intf *hw_intf;
struct cam_top_tpg_reserve_args tpg_reserve;
ife_hw_mgr = ife_ctx->hw_mgr;
tpg_reserve.num_inport = num_inport;
tpg_reserve.node_res = NULL;
if ((num_inport > 0) &&
(num_inport <= CAM_TOP_TPG_MAX_SUPPORTED_IN_PORTS)){
for (i = 0; i < num_inport; i++)
tpg_reserve.in_port[i] = (in_port + i);
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];
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:%d, num_inports:%u",
rc, num_inport);
rc = -EINVAL;
goto end;
}
ife_ctx->res_list_tpg.hw_res[0] = tpg_reserve.node_res;
ife_ctx->flags.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,
@@ -4724,18 +4650,6 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
if (total_lite_port == total_pix_port + total_rdi_port)
ife_ctx->flags.is_lite_context = true;
/* Acquire tpg HW */
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) ||
(in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_2))
rc = cam_ife_hw_mgr_acquire_tpg(ife_ctx, &in_port[0],
acquire_hw_info->num_inputs);
if (rc) {
CAM_ERR(CAM_ISP, "can not acquire TPG resource");
goto free_res;
}
/* acquire HW resources */
for (i = 0; i < acquire_hw_info->num_inputs; i++) {
CAM_DBG(CAM_ISP, "in_res_type %x", in_port[i].res_type);
@@ -4752,9 +4666,6 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
}
}
if (ife_ctx->flags.is_tpg)
ife_ctx->res_list_tpg.res_type = in_port[i].res_type;
CAM_DBG(CAM_ISP,
"in_res_type: 0x%x sfe_in_path_type: 0x%x sfe_ife_enable: 0x%x",
in_port[i].res_type, in_port[i].sfe_in_path_type,
@@ -6012,9 +5923,6 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
"config done completion timeout for last applied req_id=%llu ctx_index %",
ctx->applied_req_id, ctx->ctx_index);
if (ctx->flags.is_tpg)
cam_ife_hw_mgr_stop_hw_res(&ctx->res_list_tpg);
if (stop_isp->stop_only)
goto end;
@@ -6499,17 +6407,6 @@ start_only:
/* Start the IFE CSID HW devices */
cam_ife_mgr_csid_start_hw(ctx, primary_rdi_csid_res);
if (ctx->flags.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);
@@ -7908,37 +7805,6 @@ static int cam_isp_blob_sfe_clock_update(
return rc;
}
static int cam_isp_blob_tpg_config(
struct cam_isp_tpg_core_config *tpg_config,
struct cam_hw_prepare_update_args *prepare)
{
int i, rc = -EINVAL;
struct cam_ife_hw_mgr_ctx *ctx = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_hw_intf *hw_intf;
ctx = prepare->ctxt_to_hw_map;
hw_mgr_res = &ctx->res_list_tpg;
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
if (!hw_mgr_res->hw_res[i])
continue;
hw_intf = hw_mgr_res->hw_res[i]->hw_intf;
CAM_DBG(CAM_ISP, "TPG ctrl config for hw %u",
hw_intf->hw_idx);
if (hw_intf->hw_ops.process_cmd) {
rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD, tpg_config,
sizeof(struct cam_isp_tpg_core_config));
if (rc)
goto end;
}
}
end:
return rc;
}
static int cam_isp_blob_vfe_out_update(
uint32_t blob_type,
struct cam_isp_generic_blob_info *blob_info,
@@ -8710,25 +8576,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
"Epoch Configuration Update Failed rc:%d", rc);
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG: {
struct cam_isp_tpg_core_config *tpg_config;
if (blob_size < sizeof(struct cam_isp_tpg_core_config)) {
CAM_ERR(CAM_ISP, "Invalid blob size %zu expected %zu",
blob_size,
sizeof(struct cam_isp_tpg_core_config));
return -EINVAL;
}
tpg_config =
(struct cam_isp_tpg_core_config *)blob_data;
rc = cam_isp_blob_tpg_config(tpg_config, prepare);
if (rc)
CAM_ERR(CAM_ISP,
"TPG config failed rc: %d", rc);
}
break;
case CAM_ISP_GENERIC_BLOB_TYPE_DISCARD_INITIAL_FRAMES: {
struct cam_isp_discard_initial_frames *discard_config;
@@ -9268,7 +9115,6 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2:
case CAM_ISP_GENERIC_BLOB_TYPE_CSID_QCFA_CONFIG:
case CAM_ISP_GENERIC_BLOB_TYPE_SENSOR_BLANKING_CONFIG:
case CAM_ISP_GENERIC_BLOB_TYPE_TPG_CORE_CONFIG:
case CAM_ISP_GENERIC_BLOB_TYPE_DISCARD_INITIAL_FRAMES:
case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG:
break;
@@ -11975,15 +11821,6 @@ 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");
/* fill sfe hw intf info */
for (i = 0, j = 0; i < CAM_SFE_HW_NUM_MAX; i++) {
rc = cam_sfe_hw_init(&g_ife_hw_mgr.sfe_devices[i], i);
@@ -12062,7 +11899,6 @@ 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_csid);
INIT_LIST_HEAD(&g_ife_hw_mgr.ctx_pool[i].res_list_ife_src);

View File

@@ -11,7 +11,6 @@
#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"
#include "cam_cdm_intf_api.h"
@@ -126,7 +125,6 @@ struct cam_ife_hw_mgr_sfe_info {
* @init_done: indicate whether init hw is done
* @is_fe_enabled: indicate whether fetch engine\read path is enabled
* @is_dual: indicate whether context is in dual VFE mode
* @is_tpg: indicate whether context is using PHY TPG
* @is_offline: indicate whether context is for offline IFE
* @dsp_enabled: indicate whether dsp is enabled in this context
* @internal_cdm: indicate whether context uses internal CDM
@@ -149,7 +147,6 @@ struct cam_ife_hw_mgr_ctx_flags {
bool init_done;
bool is_fe_enabled;
bool is_dual;
bool is_tpg;
bool is_offline;
bool dsp_enabled;
bool internal_cdm;
@@ -173,9 +170,6 @@ struct cam_ife_hw_mgr_ctx_flags {
* @left_hw_idx: hw index for master core [left]
* @right_hw_idx: hw index for slave core [right]
* @hw_mgr: IFE hw mgr which owns this context
* @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
* @res_list_ife_src: IFE input resource list
* @res_list_sfe_src SFE input resource list
@@ -225,7 +219,6 @@ struct cam_ife_hw_mgr_ctx {
struct cam_ife_hw_mgr *hw_mgr;
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_csid;
struct list_head res_list_ife_src;
struct list_head res_list_sfe_src;
@@ -317,7 +310,6 @@ struct cam_isp_sys_cache_info {
*/
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_isp_hw_intf_data *ife_devices[CAM_IFE_HW_NUM_MAX];
struct cam_hw_intf *sfe_devices[CAM_SFE_HW_NUM_MAX];

View File

@@ -415,9 +415,6 @@ static void cam_tfe_hw_mgr_deinit_hw(
cam_tfe_hw_mgr_deinit_hw_res(hw_mgr_res);
}
if (ctx->is_tpg)
cam_tfe_hw_mgr_deinit_hw_res(&ctx->res_list_tpg);
ctx->init_done = false;
}
@@ -427,17 +424,6 @@ static int cam_tfe_hw_mgr_init_hw(
struct cam_isp_hw_mgr_res *hw_mgr_res;
int rc = 0;
if (ctx->is_tpg) {
CAM_DBG(CAM_ISP, "INIT TPG ... in ctx id:%d",
ctx->ctx_index);
rc = cam_tfe_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 TFE csid ... in ctx id:%d",
ctx->ctx_index);
/* INIT TFE csid */
@@ -624,10 +610,8 @@ static int cam_tfe_hw_mgr_release_hw_for_ctx(
struct cam_tfe_hw_mgr_ctx *tfe_ctx)
{
uint32_t i;
int rc = 0;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_mgr_res *hw_mgr_res_temp;
struct cam_hw_intf *hw_intf;
/* tfe out resource */
for (i = 0; i < CAM_TFE_HW_OUT_RES_MAX; i++)
@@ -647,21 +631,6 @@ static int cam_tfe_hw_mgr_release_hw_for_ctx(
cam_tfe_hw_mgr_put_res(&tfe_ctx->free_res_list, &hw_mgr_res);
}
/* release tpg resource */
if (tfe_ctx->is_tpg) {
hw_intf = tfe_ctx->res_list_tpg.hw_res[0]->hw_intf;
if (hw_intf->hw_ops.release) {
rc = hw_intf->hw_ops.release(hw_intf->hw_priv,
tfe_ctx->res_list_tpg.hw_res[0],
sizeof(struct cam_isp_resource_node));
if (rc)
CAM_ERR(CAM_ISP,
"TPG Release hw failed");
tfe_ctx->res_list_tpg.hw_res[0] = NULL;
} else
CAM_ERR(CAM_ISP, "TPG resource Release null");
}
/* clean up the callback function */
tfe_ctx->common.cb_priv = NULL;
tfe_ctx->common.event_cb = NULL;
@@ -719,16 +688,10 @@ static void cam_tfe_hw_mgr_dump_all_ctx(void)
mutex_lock(&g_tfe_hw_mgr.ctx_mutex);
list_for_each_entry(ctx, &g_tfe_hw_mgr.used_ctx_list, list) {
CAM_INFO_RATE_LIMIT(CAM_ISP,
"ctx id:%d is_dual:%d is_tpg:%d num_base:%d rdi only:%d",
ctx->ctx_index, ctx->is_dual, ctx->is_tpg,
"ctx id:%d is_dual:%d num_base:%d rdi only:%d",
ctx->ctx_index, ctx->is_dual,
ctx->num_base, ctx->is_rdi_only_context);
if (ctx->res_list_tpg.res_type == CAM_ISP_RESOURCE_TPG) {
CAM_INFO_RATE_LIMIT(CAM_ISP,
"Acquired TPG HW:%d",
ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx);
}
list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_csid,
list) {
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
@@ -1192,13 +1155,6 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
if (in_port->num_out_res)
out_port = &(in_port->data[0]);
if (tfe_ctx->is_tpg) {
if (tfe_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx == 0)
csid_acquire.phy_sel = CAM_ISP_TFE_IN_RES_PHY_0;
else
csid_acquire.phy_sel = CAM_ISP_TFE_IN_RES_PHY_1;
}
if (in_port->usage_type)
csid_acquire.sync_mode = CAM_ISP_HW_SYNC_MASTER;
else
@@ -1354,14 +1310,6 @@ acquire_successful:
csid_acquire.event_cb_prv = tfe_ctx;
csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler;
if (tfe_ctx->is_tpg) {
if (tfe_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx
== 0)
csid_acquire.phy_sel = CAM_ISP_TFE_IN_RES_PHY_0;
else
csid_acquire.phy_sel = CAM_ISP_TFE_IN_RES_PHY_1;
}
for (j = 0; j < CAM_TFE_CSID_HW_NUM_MAX; j++) {
if (!tfe_hw_mgr->csid_devices[j])
continue;
@@ -1397,48 +1345,6 @@ end:
return rc;
}
static int cam_tfe_hw_mgr_acquire_tpg(
struct cam_tfe_hw_mgr_ctx *tfe_ctx,
struct cam_isp_tfe_in_port_generic_info *in_port,
uint32_t num_inport)
{
int rc = -EINVAL;
uint32_t i, j = 0;
struct cam_tfe_hw_mgr *tfe_hw_mgr;
struct cam_hw_intf *hw_intf;
struct cam_top_tpg_ver1_reserve_args tpg_reserve;
tfe_hw_mgr = tfe_ctx->hw_mgr;
for (i = 0; i < CAM_TOP_TPG_HW_NUM_MAX; i++) {
if (!tfe_hw_mgr->tpg_devices[i])
continue;
hw_intf = tfe_hw_mgr->tpg_devices[i];
tpg_reserve.num_inport = num_inport;
tpg_reserve.node_res = NULL;
for (j = 0; j < num_inport; j++)
tpg_reserve.in_port[j] = &in_port[j];
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 tfe TPG");
rc = -EINVAL;
goto end;
}
tfe_ctx->res_list_tpg.res_type = CAM_ISP_RESOURCE_TPG;
tfe_ctx->res_list_tpg.hw_res[0] = tpg_reserve.node_res;
end:
return rc;
}
static enum cam_tfe_csid_path_res_id
cam_tfe_hw_mgr_get_tfe_csid_rdi_res_type(
uint32_t out_port_type)
@@ -1509,14 +1415,6 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_rdi(
csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler;
csid_acquire.event_cb_prv = tfe_ctx;
if (tfe_ctx->is_tpg) {
if (tfe_ctx->res_list_tpg.hw_res[0]->hw_intf->hw_idx ==
0)
csid_acquire.phy_sel = CAM_ISP_TFE_IN_RES_PHY_0;
else
csid_acquire.phy_sel = CAM_ISP_TFE_IN_RES_PHY_1;
}
/* Try acquiring CSID resource from previously acquired HW */
list_for_each_entry(csid_res_iterator,
&tfe_ctx->res_list_tfe_csid, list) {
@@ -2148,33 +2046,6 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
if (in_port[i].usage_type)
tfe_ctx->is_dual = true;
if (in_port[0].res_id == CAM_ISP_TFE_IN_RES_TPG) {
if (acquire_hw_info->num_inputs >
CAM_TOP_TPG_MAX_SUPPORTED_DT) {
CAM_ERR(CAM_ISP, "too many number inport:%d for TPG ",
acquire_hw_info->num_inputs);
rc = -EINVAL;
goto free_cdm;
}
for (i = 1; i < acquire_hw_info->num_inputs; i++) {
if (in_port[i].res_id != CAM_ISP_TFE_IN_RES_TPG) {
CAM_ERR(CAM_ISP, "Inval :%d inport res id:0x%x",
i, in_port[i].res_id);
rc = -EINVAL;
goto free_cdm;
}
}
rc = cam_tfe_hw_mgr_acquire_tpg(tfe_ctx, in_port,
acquire_hw_info->num_inputs);
if (rc)
goto free_cdm;
tfe_ctx->is_tpg = true;
}
/* acquire HW resources */
for (i = 0; i < acquire_hw_info->num_inputs; i++) {
@@ -2243,8 +2114,6 @@ free_res:
tfe_ctx->cdm_ops = NULL;
tfe_ctx->init_done = false;
tfe_ctx->is_dual = false;
tfe_ctx->is_tpg = false;
tfe_ctx->res_list_tpg.res_type = CAM_ISP_RESOURCE_MAX;
free_cdm:
cam_cdm_release(tfe_ctx->cdm_handle);
free_ctx:
@@ -3022,9 +2891,6 @@ static int cam_tfe_mgr_stop_hw_in_overflow(void *stop_hw_args)
for (i = 0; i < CAM_TFE_HW_OUT_RES_MAX; i++)
cam_tfe_hw_mgr_stop_hw_res(&ctx->res_list_tfe_out[i]);
if (ctx->is_tpg)
cam_tfe_hw_mgr_stop_hw_res(&ctx->res_list_tpg);
/* Stop tasklet for context */
cam_tasklet_stop(ctx->common.tasklet_info);
CAM_DBG(CAM_ISP, "Exit...ctx id:%d rc :%d",
@@ -3131,7 +2997,7 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
master_base_idx = ctx->base[0].idx;
/*Change slave mode*/
if (csid_halt_type == CAM_CSID_HALT_IMMEDIATELY)
if (csid_halt_type == CAM_TFE_CSID_HALT_IMMEDIATELY)
cam_tfe_mgr_csid_change_halt_mode(ctx,
CAM_TFE_CSID_HALT_MODE_INTERNAL);
@@ -3172,9 +3038,6 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
cam_common_wait_for_completion_timeout(&ctx->config_done_complete,
msecs_to_jiffies(5));
if (ctx->is_tpg)
cam_tfe_hw_mgr_stop_hw_res(&ctx->res_list_tpg);
if (stop_isp->stop_only)
goto end;
@@ -3476,17 +3339,6 @@ start_only:
}
}
if (ctx->is_tpg) {
CAM_DBG(CAM_ISP, "START TPG HW ... in ctx id:%d",
ctx->ctx_index);
rc = cam_tfe_hw_mgr_start_hw_res(&ctx->res_list_tpg, ctx);
if (rc) {
CAM_ERR(CAM_ISP, "Can not start TFE TPG (%d)",
ctx->res_list_tpg.res_id);
goto err;
}
}
return 0;
err:
@@ -3761,9 +3613,7 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
ctx->cdm_ops = NULL;
ctx->init_done = false;
ctx->is_dual = false;
ctx->is_tpg = false;
ctx->num_reg_dump_buf = 0;
ctx->res_list_tpg.res_type = CAM_ISP_RESOURCE_MAX;
ctx->last_cdm_done_req = 0;
atomic_set(&ctx->overflow_pending, 0);
@@ -3889,7 +3739,6 @@ static int cam_isp_tfe_blob_csid_clock_update(
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_hw_intf *hw_intf;
struct cam_tfe_csid_clock_update_args csid_clock_upd_args;
struct cam_top_tpg_clock_update_args tpg_clock_upd_args;
uint64_t clk_rate = 0;
int rc = -EINVAL;
uint32_t i;
@@ -3923,23 +3772,6 @@ static int cam_isp_tfe_blob_csid_clock_update(
}
}
if (ctx->res_list_tpg.res_type == CAM_ISP_RESOURCE_TPG) {
tpg_clock_upd_args.clk_rate = clock_config->phy_clock;
hw_intf = ctx->res_list_tpg.hw_res[0]->hw_intf;
if (hw_intf && hw_intf->hw_ops.process_cmd) {
CAM_DBG(CAM_ISP, "i= %d phy clk=%llu",
tpg_clock_upd_args.clk_rate);
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE,
&tpg_clock_upd_args,
sizeof(struct cam_top_tpg_clock_update_args));
if (rc)
CAM_ERR(CAM_ISP, "Clock Update failed");
} else
CAM_ERR(CAM_ISP, "NULL hw_intf!");
}
return rc;
}
@@ -6020,17 +5852,6 @@ int cam_tfe_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_tfe_hw_mgr.tpg_devices[i], i);
if (!rc)
j++;
}
if (!j) {
CAM_ERR(CAM_ISP, "no valid TFE TPG HW");
return -EINVAL;
}
cam_tfe_hw_mgr_sort_dev_with_caps(&g_tfe_hw_mgr);
/* setup tfe context list */

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TFE_HW_MGR_H_
@@ -11,7 +11,6 @@
#include "cam_isp_hw_mgr.h"
#include "cam_tfe_hw_intf.h"
#include "cam_tfe_csid_hw_intf.h"
#include "cam_top_tpg_hw_intf.h"
#include "cam_tasklet_util.h"
#include "cam_cdm_intf_api.h"
@@ -79,7 +78,6 @@ struct cam_tfe_hw_mgr_debug {
* @last_dump_err_req_id last req id for which reg dump on error was called
* @init_done indicate whether init hw is done
* @is_dual indicate whether context is in dual TFE mode
* @is_tpg indicate whether context use tpg
* @master_hw_idx master hardware index in dual tfe case
* @slave_hw_idx slave hardware index in dual tfe case
* @dual_tfe_irq_mismatch_cnt irq mismatch count value per core, used for
@@ -94,7 +92,6 @@ struct cam_tfe_hw_mgr_ctx {
struct cam_tfe_hw_mgr *hw_mgr;
uint32_t ctx_in_use;
struct cam_isp_hw_mgr_res res_list_tpg;
struct list_head res_list_tfe_csid;
struct list_head res_list_tfe_in;
struct cam_isp_hw_mgr_res
@@ -123,7 +120,6 @@ struct cam_tfe_hw_mgr_ctx {
uint64_t last_dump_err_req_id;
bool init_done;
bool is_dual;
bool is_tpg;
uint32_t master_hw_idx;
uint32_t slave_hw_idx;
uint32_t dual_tfe_irq_mismatch_cnt;
@@ -134,8 +130,6 @@ struct cam_tfe_hw_mgr_ctx {
* struct cam_tfe_hw_mgr - TFE HW Manager
*
* @mgr_common: common data for all HW managers
* @tpg_devices: tpg devices instacnce array. This will be filled by
* HW manager during the initialization.
* @csid_devices: csid device instances array. This will be filled by
* HW manager during the initialization.
* @tfe_devices: TFE device instances array. This will be filled by
@@ -155,7 +149,6 @@ struct cam_tfe_hw_mgr_ctx {
*/
struct cam_tfe_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_TFE_CSID_HW_NUM_MAX];
struct cam_isp_hw_intf_data *tfe_devices[CAM_TFE_HW_NUM_MAX];
struct cam_soc_reg_map *cdm_reg_map[CAM_TFE_HW_NUM_MAX];

View File

@@ -1,97 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG_HW_INTF_H_
#define _CAM_TOP_TPG_HW_INTF_H_
#include "cam_isp_hw.h"
#include "cam_hw_intf.h"
#include "cam_ife_csid_hw_intf.h"
#include "cam_tfe_csid_hw_intf.h"
/* Max top tpg instance */
#define CAM_TOP_TPG_HW_NUM_MAX 3
/* Max supported number of VC for TPG */
#define CAM_TOP_TPG_MAX_SUPPORTED_VC 4
/* Max supported number of DT for TPG */
#define CAM_TOP_TPG_MAX_SUPPORTED_DT 4
/* Max supported number of in_ports for TPG */
#define CAM_TOP_TPG_MAX_SUPPORTED_IN_PORTS 16
/**
* enum cam_top_tpg_id - top tpg hw instance id
*/
enum cam_top_tpg_id {
CAM_TOP_TPG_ID_0,
CAM_TOP_TPG_ID_1,
CAM_TOP_TPG_ID_2,
CAM_TFE_TPG_ID_MAX,
};
/**
* struct cam_top_tpg_hw_caps- Get the top tpg hw capability
* @major_version : Major version
* @minor_version: Minor version
* @version_incr: Version increment
*
*/
struct cam_top_tpg_hw_caps {
uint32_t major_version;
uint32_t minor_version;
uint32_t version_incr;
};
/**
* 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.
* @in_port : Input port resource info structure pointer
* @node_res : Reserved resource structure pointer
*
*/
struct cam_top_tpg_ver1_reserve_args {
uint32_t num_inport;
struct cam_isp_tfe_in_port_generic_info *in_port[CAM_TOP_TPG_MAX_SUPPORTED_DT];
struct cam_isp_resource_node *node_res;
};
/**
* struct cam_top_tpg_reserve_args
* TPGv2 supports 1 VC/DT combo
* TPGv3 supports 4 VC's and 4 DT's per VC
* @num_inport: number of inport
* @in_port : Input port resource info structure pointer
* @node_res : Reserved resource structure pointer
*
*/
struct cam_top_tpg_reserve_args {
uint32_t num_inport;
struct cam_isp_in_port_generic_info *in_port[
CAM_TOP_TPG_MAX_SUPPORTED_IN_PORTS];
struct cam_isp_resource_node *node_res;
};
/**
* cam_top_tpg_hw_init()
*
* @brief: Initialize function for the tpg hardware
*
* @top_tpg_hw: TPG hardware instance returned
* @hw_idex: TPG hardware instance id
*/
int cam_top_tpg_hw_init(struct cam_hw_intf **top_tpg_hw,
uint32_t hw_idx);
/*
* struct cam_top_tpg_clock_update_args:
*
* @clk_rate: phy rate requested
*/
struct cam_top_tpg_clock_update_args {
uint64_t clk_rate;
};
#endif /* _CAM_TOP_TPG_HW_INTF_H_ */

View File

@@ -160,6 +160,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.phy_tpg_base_id = 0,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,

View File

@@ -198,6 +198,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.phy_tpg_base_id = 0,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,

View File

@@ -637,6 +637,7 @@ static int cam_tfe_csid_cid_reserve(struct cam_tfe_csid_hw *csid_hw,
uint32_t *cid_value)
{
int i, rc = 0;
const struct cam_tfe_csid_reg_offset *csid_reg;
CAM_DBG(CAM_ISP,
"CSID:%d res_id:0x%x Lane type:%d lane_num:%d dt:%d vc:%d",
@@ -745,12 +746,24 @@ static int cam_tfe_csid_cid_reserve(struct cam_tfe_csid_hw *csid_hw,
csid_hw->csi2_rx_cfg.lane_num =
cid_reserv->in_port->lane_num;
if (cid_reserv->in_port->res_id != CAM_ISP_TFE_IN_RES_TPG)
switch (cid_reserv->in_port->res_id) {
case CAM_ISP_TFE_IN_RES_TPG:
csid_hw->csi2_rx_cfg.phy_sel = 0;
break;
case CAM_ISP_TFE_IN_RES_CPHY_TPG_0:
case CAM_ISP_TFE_IN_RES_CPHY_TPG_1:
case CAM_ISP_TFE_IN_RES_CPHY_TPG_2:
csid_reg = csid_hw->csid_info->csid_reg;
csid_hw->csi2_rx_cfg.phy_sel =
(cid_reserv->in_port->res_id & 0xFF) - 1;
else
((cid_reserv->in_port->res_id & 0xFF) -
CAM_ISP_TFE_IN_RES_CPHY_TPG_0) +
csid_reg->csi2_reg->phy_tpg_base_id;
break;
default:
csid_hw->csi2_rx_cfg.phy_sel =
(cid_reserv->phy_sel & 0xFF) - 1;
(cid_reserv->in_port->res_id & 0xFF) - 1;
break;
}
}
csid_hw->csi2_reserve_cnt++;

View File

@@ -216,6 +216,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset {
uint32_t csid_csi2_rx_total_crc_err_addr;
/*configurations */
uint32_t phy_tpg_base_id;
uint32_t csi2_rst_srb_all;
uint32_t csi2_rst_done_shift_val;
uint32_t csi2_irq_mask_all;

View File

@@ -1,53 +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_tpg101.h"
#include "cam_top_tpg102.h"
#include "cam_top_tpg103.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,
},
{
.compatible = "qcom,tpg103",
.data = &cam_top_tpg103_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

@@ -1,12 +0,0 @@
/* 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

@@ -1,61 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#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_ver1_reg_offset cam_top_tpg101_reg = {
.tpg_hw_version = 0x0,
.tpg_hw_status = 0x4,
.tpg_ctrl = 0x60,
.tpg_vc_cfg0 = 0x64,
.tpg_vc_cfg1 = 0x68,
.tpg_lfsr_seed = 0x6c,
.tpg_dt_0_cfg_0 = 0x70,
.tpg_dt_1_cfg_0 = 0x74,
.tpg_dt_2_cfg_0 = 0x78,
.tpg_dt_3_cfg_0 = 0x7C,
.tpg_dt_0_cfg_1 = 0x80,
.tpg_dt_1_cfg_1 = 0x84,
.tpg_dt_2_cfg_1 = 0x88,
.tpg_dt_3_cfg_1 = 0x8C,
.tpg_dt_0_cfg_2 = 0x90,
.tpg_dt_1_cfg_2 = 0x94,
.tpg_dt_2_cfg_2 = 0x98,
.tpg_dt_3_cfg_2 = 0x9C,
.tpg_color_bar_cfg = 0xA0,
.tpg_common_gen_cfg = 0xA4,
.tpg_vbi_cfg = 0xA8,
.tpg_test_bus_crtl = 0xF8,
.tpg_spare = 0xFC,
/* configurations */
.major_version = 1,
.minor_version = 0,
.version_incr = 0,
.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,
.top_mux_reg_offset = 0x1C,
};
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_TPG101_H_ */

View File

@@ -1,50 +0,0 @@
/* 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 = 400000000,
.phy_max_clk = 400000000,
};
#endif /* _CAM_TOP_TPG102_H_ */

View File

@@ -1,126 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG103_H_
#define _CAM_TOP_TPG103_H_
#include "cam_top_tpg_ver3.h"
#include "cam_top_tpg_core.h"
static struct cam_top_tpg_ver3_reg_offset cam_top_tpg103_reg = {
.tpg_hw_version = 0x0,
.tpg_hw_status = 0x4,
.tpg_ctrl = 0x64,
.tpg_vc0_cfg0 = 0x68,
.tpg_vc0_lfsr_seed = 0x6C,
.tpg_vc0_hbi_cfg = 0x70,
.tpg_vc0_vbi_cfg = 0x74,
.tpg_vc0_color_bar_cfg = 0x78,
.tpg_vc0_dt_0_cfg_0 = 0x7C,
.tpg_vc0_dt_0_cfg_1 = 0x80,
.tpg_vc0_dt_0_cfg_2 = 0x84,
.tpg_vc0_dt_1_cfg_0 = 0x88,
.tpg_vc0_dt_1_cfg_1 = 0x8C,
.tpg_vc0_dt_1_cfg_2 = 0x90,
.tpg_vc0_dt_2_cfg_0 = 0x94,
.tpg_vc0_dt_2_cfg_1 = 0x98,
.tpg_vc0_dt_2_cfg_2 = 0x9C,
.tpg_vc0_dt_3_cfg_0 = 0xA0,
.tpg_vc0_dt_3_cfg_1 = 0xA4,
.tpg_vc0_dt_3_cfg_2 = 0xA8,
.tpg_vc1_cfg0 = 0xC8,
.tpg_vc1_lfsr_seed = 0xCC,
.tpg_vc1_hbi_cfg = 0xD0,
.tpg_vc1_vbi_cfg = 0xD4,
.tpg_vc1_color_bar_cfg = 0xD8,
.tpg_vc1_dt_0_cfg_0 = 0xDC,
.tpg_vc1_dt_0_cfg_1 = 0xE0,
.tpg_vc1_dt_0_cfg_2 = 0xE4,
.tpg_vc1_dt_1_cfg_0 = 0xE8,
.tpg_vc1_dt_1_cfg_1 = 0xEC,
.tpg_vc1_dt_1_cfg_2 = 0xF0,
.tpg_vc1_dt_2_cfg_0 = 0xF4,
.tpg_vc1_dt_2_cfg_1 = 0xF8,
.tpg_vc1_dt_2_cfg_2 = 0xFC,
.tpg_vc1_dt_3_cfg_0 = 0x100,
.tpg_vc1_dt_3_cfg_1 = 0x104,
.tpg_vc1_dt_3_cfg_2 = 0x108,
.tpg_vc2_cfg0 = 0x128,
.tpg_vc2_lfsr_seed = 0x12C,
.tpg_vc2_hbi_cfg = 0x130,
.tpg_vc2_vbi_cfg = 0x134,
.tpg_vc2_color_bar_cfg = 0x138,
.tpg_vc2_dt_0_cfg_0 = 0x13C,
.tpg_vc2_dt_0_cfg_1 = 0x140,
.tpg_vc2_dt_0_cfg_2 = 0x144,
.tpg_vc2_dt_1_cfg_0 = 0x148,
.tpg_vc2_dt_1_cfg_1 = 0x14C,
.tpg_vc2_dt_1_cfg_2 = 0x150,
.tpg_vc2_dt_2_cfg_0 = 0x154,
.tpg_vc2_dt_2_cfg_1 = 0x158,
.tpg_vc2_dt_2_cfg_2 = 0x15C,
.tpg_vc2_dt_3_cfg_0 = 0x160,
.tpg_vc2_dt_3_cfg_1 = 0x164,
.tpg_vc2_dt_3_cfg_2 = 0x168,
.tpg_vc3_cfg0 = 0x188,
.tpg_vc3_lfsr_seed = 0x18C,
.tpg_vc3_hbi_cfg = 0x190,
.tpg_vc3_vbi_cfg = 0x194,
.tpg_vc3_color_bar_cfg = 0x198,
.tpg_vc3_dt_0_cfg_0 = 0x19C,
.tpg_vc3_dt_0_cfg_1 = 0x1A0,
.tpg_vc3_dt_0_cfg_2 = 0x1A4,
.tpg_vc3_dt_1_cfg_0 = 0x1A8,
.tpg_vc3_dt_1_cfg_1 = 0x1AC,
.tpg_vc3_dt_1_cfg_2 = 0x1B0,
.tpg_vc3_dt_2_cfg_0 = 0x1B4,
.tpg_vc3_dt_2_cfg_1 = 0x1B8,
.tpg_vc3_dt_2_cfg_2 = 0x1BC,
.tpg_vc3_dt_3_cfg_0 = 0x1C0,
.tpg_vc3_dt_3_cfg_1 = 0x1C4,
.tpg_vc3_dt_3_cfg_2 = 0x1C8,
.tpg_throttle = 0x1CC,
.tpg_top_irq_status = 0x1E0,
.tpg_top_irq_mask = 0x1E4,
.tpg_top_irq_clear = 0x1E8,
.tpg_top_irq_set = 0x1EC,
.tpg_top_irq_cmd = 0x1F0,
.tpg_top_clear = 0x1F4,
.tpg_test_bus_crtl = 0x1F8,
.tpg_spare = 0x1FC,
/* configurations */
.major_version = 2,
.minor_version = 0,
.version_incr = 0,
.tpg_en_shift_val = 0,
.tpg_cphy_dphy_sel_shift_val = 3,
.tpg_num_active_lanes_shift = 4,
.tpg_fe_pkt_en_shift = 2,
.tpg_fs_pkt_en_shift = 1,
.tpg_line_interleaving_mode_shift = 10,
.tpg_num_frames_shift_val = 16,
.tpg_num_dts_shift_val = 8,
.tpg_v_blank_cnt_shift = 12,
.tpg_dt_encode_format_shift = 20,
.tpg_payload_mode_color = 0x8,
.tpg_split_en_shift = 4,
.top_mux_reg_offset = 0x1C,
.tpg_vc_dt_pattern_id_shift = 6,
.tpg_num_active_vcs_shift = 30,
.tpg_color_bar_qcfa_en_shift = 3,
};
struct cam_top_tpg_hw_info cam_top_tpg103_hw_info = {
.tpg_reg = &cam_top_tpg103_reg,
.hw_dts_version = CAM_TOP_TPG_VERSION_3,
.csid_max_clk = 480000000,
.phy_max_clk = 480000000,
};
#endif /* _CAM_TOP_TPG103_H_ */

View File

@@ -1,379 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, 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_cpas_api.h"
#include "cam_top_tpg_ver1.h"
#include "cam_top_tpg_ver2.h"
#include "cam_top_tpg_ver3.h"
static struct cam_top_tpg_debugfs tpg_debug = {0};
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 = 5;
break;
default:
CAM_ERR(CAM_ISP, "Unsupported input encode format %d",
in_format);
rc = -EINVAL;
}
return rc;
}
int cam_top_tpg_debug_register(void)
{
int rc = 0;
struct dentry *dbgfileptr = NULL;
if (tpg_debug.root) {
CAM_DBG(CAM_ISP, "Debugfs root already created");
return 0;
}
dbgfileptr = debugfs_create_dir("camera_tpg", NULL);
if (!dbgfileptr) {
CAM_ERR(CAM_ISP, "DebugFS could not create directory!");
rc = -ENOENT;
goto end;
}
tpg_debug.root = dbgfileptr;
dbgfileptr = debugfs_create_bool("enable_vcdt_dump", 0644,
tpg_debug.root, &tpg_debug.enable_vcdt_dump);
if (IS_ERR(dbgfileptr)) {
if (PTR_ERR(dbgfileptr) == -ENODEV)
CAM_WARN(CAM_ISP, "DebugFS not enabled in kernel!");
else
rc = PTR_ERR(dbgfileptr);
}
end:
return rc;
}
const struct cam_top_tpg_debugfs* cam_top_tpg_get_debugfs(void)
{
return &tpg_debug;
}
static int cam_top_tpg_init_hw(void *hw_priv,
void *init_args, uint32_t arg_size)
{
int rc = 0;
struct cam_top_tpg_hw *tpg_hw;
struct cam_hw_info *tpg_hw_info;
struct cam_isp_resource_node *tpg_res;
struct cam_hw_soc_info *soc_info;
uint32_t clk_lvl;
if (!hw_priv || !init_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_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) {
CAM_ERR(CAM_ISP, "TPG:%d Invalid res type state %d",
tpg_hw->hw_intf->hw_idx,
tpg_res->res_type);
return -EINVAL;
}
CAM_DBG(CAM_ISP, "TPG:%d init HW res type :%d",
tpg_hw->hw_intf->hw_idx, tpg_res->res_type);
mutex_lock(&tpg_hw->hw_info->hw_mutex);
/* overflow check before increment */
if (tpg_hw->hw_info->open_count == UINT_MAX) {
CAM_ERR(CAM_ISP, "TPG:%d Open count reached max",
tpg_hw->hw_intf->hw_idx);
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
return -EINVAL;
}
/* Increment ref Count */
tpg_hw->hw_info->open_count++;
if (tpg_hw->hw_info->open_count > 1) {
CAM_DBG(CAM_ISP, "TPG hw has already been enabled");
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
return rc;
}
rc = cam_soc_util_get_clk_level(soc_info, tpg_hw->clk_rate,
soc_info->src_clk_idx, &clk_lvl);
CAM_DBG(CAM_ISP, "TPG phy clock level %u", clk_lvl);
rc = cam_top_tpg_enable_soc_resources(soc_info, clk_lvl);
if (rc) {
CAM_ERR(CAM_ISP, "TPG:%d Enable SOC failed",
tpg_hw->hw_intf->hw_idx);
goto err;
}
tpg_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
return rc;
err:
tpg_hw->hw_info->open_count--;
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
return rc;
}
static int cam_top_tpg_deinit_hw(void *hw_priv,
void *deinit_args, uint32_t arg_size)
{
int rc = 0;
struct cam_top_tpg_hw *tpg_hw;
struct cam_hw_info *tpg_hw_info;
struct cam_isp_resource_node *tpg_res;
struct cam_hw_soc_info *soc_info;
if (!hw_priv || !deinit_args ||
(arg_size != sizeof(struct cam_isp_resource_node))) {
CAM_ERR(CAM_ISP, "TPG:Invalid arguments");
return -EINVAL;
}
tpg_res = (struct cam_isp_resource_node *)deinit_args;
tpg_hw_info = (struct cam_hw_info *)hw_priv;
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
if (tpg_res->res_type != CAM_ISP_RESOURCE_TPG) {
CAM_ERR(CAM_ISP, "TPG:%d Invalid Res type %d",
tpg_hw->hw_intf->hw_idx,
tpg_res->res_type);
return -EINVAL;
}
mutex_lock(&tpg_hw->hw_info->hw_mutex);
/* Check for refcount */
if (!tpg_hw->hw_info->open_count) {
CAM_WARN(CAM_ISP, "Unbalanced disable_hw");
goto end;
}
/* Decrement ref Count */
tpg_hw->hw_info->open_count--;
if (tpg_hw->hw_info->open_count) {
rc = 0;
goto end;
}
soc_info = &tpg_hw->hw_info->soc_info;
rc = cam_top_tpg_disable_soc_resources(soc_info);
if (rc)
CAM_ERR(CAM_ISP, "TPG:%d Disable SOC failed",
tpg_hw->hw_intf->hw_idx);
tpg_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
CAM_DBG(CAM_ISP, "TPG:%d deint completed", tpg_hw->hw_intf->hw_idx);
end:
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
return rc;
}
static int cam_top_tpg_read(void *hw_priv,
void *read_args, uint32_t arg_size)
{
CAM_ERR(CAM_ISP, "TPG: un supported");
return -EINVAL;
}
static int cam_top_tpg_write(void *hw_priv,
void *write_args, uint32_t arg_size)
{
CAM_ERR(CAM_ISP, "TPG: un supported");
return -EINVAL;
}
int cam_top_tpg_set_phy_clock(
struct cam_top_tpg_hw *csid_hw, void *cmd_args)
{
struct cam_top_tpg_clock_update_args *clk_update = NULL;
if (!csid_hw)
return -EINVAL;
clk_update =
(struct cam_top_tpg_clock_update_args *)cmd_args;
csid_hw->clk_rate = clk_update->clk_rate;
CAM_DBG(CAM_ISP, "CSI PHY clock rate %llu", csid_hw->clk_rate);
return 0;
}
irqreturn_t cam_top_tpg_irq(int irq_num, void *data)
{
struct cam_top_tpg_hw *tpg_hw;
struct cam_hw_soc_info *soc_info;
struct cam_top_tpg_ver3_reg_offset *tpg_reg;
uint32_t irq_status_top;
unsigned long flags;
if (!data) {
CAM_ERR(CAM_ISP, "TPG: Invalid arguments");
return IRQ_HANDLED;
}
tpg_hw = (struct cam_top_tpg_hw *) data;
CAM_DBG(CAM_ISP, "CPHY TPG %d IRQ Handling", tpg_hw->hw_intf->hw_idx);
soc_info = &tpg_hw->hw_info->soc_info;
tpg_reg = tpg_hw->tpg_info->tpg_reg;
irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base +
tpg_reg->tpg_top_irq_status);
spin_lock_irqsave(&tpg_hw->hw_info->hw_lock, flags);
/* clear */
cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_top_irq_clear);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_top_irq_cmd);
spin_unlock_irqrestore(&tpg_hw->hw_info->hw_lock, flags);
CAM_DBG(CAM_ISP, "TPG: irq_status_top = 0x%x", irq_status_top);
return IRQ_HANDLED;
}
int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf,
uint32_t tpg_idx)
{
int rc = -EINVAL;
struct cam_hw_info *tpg_hw_info;
struct cam_top_tpg_hw *tpg_hw = NULL;
uint32_t hw_version = 0;
if (tpg_idx >= CAM_TOP_TPG_HW_NUM_MAX) {
CAM_ERR(CAM_ISP, "Invalid tpg index:%d", tpg_idx);
return rc;
}
tpg_hw_info = (struct cam_hw_info *)tpg_hw_intf->hw_priv;
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
tpg_hw->hw_intf = tpg_hw_intf;
tpg_hw->hw_info = tpg_hw_info;
CAM_DBG(CAM_ISP, "type %d index %d",
tpg_hw->hw_intf->hw_type, tpg_idx);
tpg_hw->hw_info->hw_state = CAM_HW_STATE_POWER_DOWN;
mutex_init(&tpg_hw->hw_info->hw_mutex);
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,
cam_top_tpg_irq, tpg_hw);
if (rc < 0) {
CAM_ERR(CAM_ISP, "TPG:%d Failed to init_soc", tpg_idx);
goto err;
}
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.read = cam_top_tpg_read;
tpg_hw->hw_intf->hw_ops.write = cam_top_tpg_write;
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);
else if (hw_version == CAM_TOP_TPG_VERSION_3)
cam_top_tpg_ver3_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;
if (hw_version < CAM_TOP_TPG_VERSION_3) {
tpg_hw->tpg_res.res_priv =
kzalloc(sizeof(struct cam_top_tpg_cfg), GFP_KERNEL);
if (!tpg_hw->tpg_res.res_priv) {
rc = -ENOMEM;
goto err;
}
} else {
tpg_hw->tpg_res.res_priv =
kzalloc(sizeof(struct cam_top_tpg_cfg_v2), GFP_KERNEL);
if (!tpg_hw->tpg_res.res_priv) {
rc = -ENOMEM;
goto err;
}
}
cam_top_tpg_enable_soc_resources(&tpg_hw->hw_info->soc_info,
CAM_SVS_VOTE);
cam_top_tpg_disable_soc_resources(&tpg_hw->hw_info->soc_info);
err:
return rc;
}
int cam_top_tpg_deinit(struct cam_top_tpg_hw *top_tpg_hw)
{
int rc = -EINVAL;
if (!top_tpg_hw) {
CAM_ERR(CAM_ISP, "Invalid param");
return rc;
}
/* release the privdate data memory from resources */
kfree(top_tpg_hw->tpg_res.res_priv);
cam_top_tpg_deinit_soc_resources(&top_tpg_hw->hw_info->soc_info);
debugfs_remove_recursive(tpg_debug.root);
tpg_debug.root = NULL;
return 0;
}

View File

@@ -1,188 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#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
#define CAM_TOP_TPG_VERSION_3 0x20000000
#define CAM_TPG_LFSR_SEED 0x12345678
enum cam_top_tpg_encode_format {
CAM_TOP_TPG_ENCODE_FORMAT_RAW6,
CAM_TOP_TPG_ENCODE_FORMAT_RAW8,
CAM_TOP_TPG_ENCODE_FORMAT_RAW10,
CAM_TOP_TPG_ENCODE_FORMAT_RAW12,
CAM_TOP_TPG_ENCODE_FORMAT_RAW14,
CAM_TOP_TPG_ENCODE_FORMAT_RAW16,
CAM_TOP_TPG_ENCODE_FORMAT_MAX,
};
/**
* struct cam_top_tpg_hw_info- tpg hardware info
*
* @tpg_reg: tpg register offsets
* @hw_dts_version: HW DTS version
* @csid_max_clk: maximum csid clock
* @phy_max_clk maximum phy clock
*
*/
struct cam_top_tpg_hw_info {
void *tpg_reg;
uint32_t hw_dts_version;
uint32_t csid_max_clk;
uint32_t phy_max_clk;
};
/**
* struct cam_top_tpg_dt_cfg- tpg data type(dt) configuration
*
* @frame_width: frame width in pixel
* @frame_height: frame height in pixel
* @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;
};
/**
* struct cam_top_tpg_cfg- tpg congiguration
* @pix_pattern : pixel pattern output of the tpg
* @phy_sel : phy selection 0:dphy or 1:cphy
* @num_active_lanes Number of active lines
* @vc_num: Virtual channel number
* @h_blank_count: horizontal blanking count value
* @v_blank_count: vertical blanking count value
* @num_active_dts: number of active dts need to configure
* @num_frames: number of output frames
* @qcfa_en: enable qcfa in color bar cfg
* @dt_cfg: dt configuration values
*
*/
struct cam_top_tpg_cfg {
uint32_t pix_pattern;
uint32_t phy_sel;
uint32_t num_active_lanes;
uint32_t vc_num[4];
uint32_t v_blank_count;
uint32_t h_blank_count;
uint32_t num_active_dts;
uint32_t num_frames;
uint32_t vc_dt_pattern_id;
uint32_t qcfa_en;
struct cam_top_tpg_dt_cfg dt_cfg[4];
};
/**
* struct cam_top_tpg_vc_dt_info- VC DT information for tpg HW
*
* @vc_num : Virtual channel number
* @h_blank_count : Horizontal blanking count value
* @h_blank_count : Vertical blanking count value
* @num_frames : Number of output frames
* @pix_pattern : Pixel pattern output of the tpg
* @qcfa_en : Enable qcfa in color bar cfg
* @num_active_dts : Number of active dts need to configure
* @dt_cfg : Dt configuration values
*/
struct cam_top_tpg_vc_dt_info {
uint32_t vc_num;
uint32_t v_blank_count;
uint32_t h_blank_count;
uint32_t num_frames;
uint32_t pix_pattern;
uint32_t qcfa_en;
uint32_t num_active_dts;
struct cam_top_tpg_dt_cfg dt_cfg[CAM_TOP_TPG_MAX_SUPPORTED_DT];
};
/**
* struct cam_top_tpg_cfg_v2- tpg congiguration
* @phy_sel : phy selection 0:dphy or 1:cphy
* @num_active_lanes : Number of active lines
* @num_active_vcs : number of currently configured vcs in tpg hw
* @throttle_pattern : Define bubble pattern in throttler
* @vc_dt : VC DT information that the TPG HW holds
*
*/
struct cam_top_tpg_cfg_v2 {
uint32_t phy_sel;
uint32_t num_active_lanes;
uint32_t vc_dt_pattern_id;
uint32_t num_active_vcs;
uint32_t throttle_pattern;
struct cam_top_tpg_vc_dt_info vc_dt[CAM_TOP_TPG_MAX_SUPPORTED_VC];
};
/**
* struct cam_top_tpg_hw- tpg hw device resources data
*
* @hw_intf: contain the tpg hw interface information
* @hw_info: tpg hw device information
* @tpg_info: tpg hw specific information
* @tpg_res: tpg resource
* @tpg_cfg: tpg configuration
* @clk_rate clock rate
* @lock_state lock state
* @tpg_complete tpg completion
*
*/
struct cam_top_tpg_hw {
struct cam_hw_intf *hw_intf;
struct cam_hw_info *hw_info;
struct cam_top_tpg_hw_info *tpg_info;
struct cam_isp_resource_node tpg_res;
uint64_t clk_rate;
spinlock_t lock_state;
struct completion tpg_complete;
};
/**
* struct cam_top_tpg_debugfs- debugfs structure for TPG
*
* @root: A pointer to a root directory for debugfs
* @enable_vcdt_dump: A flag to indicate if the VCDT dump is enabled
*
*/
struct cam_top_tpg_debugfs {
struct dentry *root;
bool enable_vcdt_dump;
};
int cam_top_tpg_debug_register(void);
const struct cam_top_tpg_debugfs* cam_top_tpg_get_debugfs(void);
int cam_top_tpg_get_format(uint32_t in_format, uint32_t *tpg_encode_format);
int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf,
uint32_t tpg_idx);
int cam_top_tpg_deinit(struct cam_top_tpg_hw *top_tpg_hw);
int cam_top_tpg_set_phy_clock(struct cam_top_tpg_hw *csid_hw, void *cmd_args);
#endif /* _CAM_TOP_TPG_CORE_H_ */

View File

@@ -1,157 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/of_device.h>
#include "cam_top_tpg_core.h"
#include "cam_top_tpg_dev.h"
#include "cam_top_tpg_hw_intf.h"
#include "cam_debug_util.h"
#include "camera_main.h"
static struct cam_hw_intf *cam_top_tpg_hw_list[CAM_TOP_TPG_HW_NUM_MAX] = {
0, 0};
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 *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_info = NULL;
uint32_t tpg_dev_idx;
int rc = 0;
struct platform_device *pdev = to_platform_device(dev);
CAM_DBG(CAM_ISP, "Binding TPG component");
tpg_hw_intf = kzalloc(sizeof(*tpg_hw_intf), GFP_KERNEL);
if (!tpg_hw_intf) {
rc = -ENOMEM;
goto err;
}
hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
if (!hw_info) {
rc = -ENOMEM;
goto free_hw_intf;
}
tpg_hw = kzalloc(sizeof(struct cam_top_tpg_hw), GFP_KERNEL);
if (!tpg_hw) {
rc = -ENOMEM;
goto free_hw_info;
}
/* get top tpg hw index */
of_property_read_u32(pdev->dev.of_node, "cell-index", &tpg_dev_idx);
/* get top tpg hw information */
match_dev = of_match_device(pdev->dev.driver->of_match_table,
&pdev->dev);
if (!match_dev) {
CAM_ERR(CAM_ISP, "No matching table for the top tpg hw");
rc = -EINVAL;
goto free_dev;
}
tpg_hw_intf->hw_idx = tpg_dev_idx;
tpg_hw_intf->hw_type = CAM_ISP_HW_TYPE_TPG;
tpg_hw_intf->hw_priv = hw_info;
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 = pdev->name;
hw_info->soc_info.index = tpg_dev_idx;
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_hw->tpg_info = tpg_hw_info;
rc = cam_top_tpg_probe_init(tpg_hw_intf, tpg_dev_idx);
if (rc)
goto free_dev;
platform_set_drvdata(pdev, tpg_hw);
CAM_DBG(CAM_ISP, "TPG: %d component binded successfully",
tpg_hw_intf->hw_idx);
if (tpg_hw_intf->hw_idx < CAM_TOP_TPG_HW_NUM_MAX)
cam_top_tpg_hw_list[tpg_hw_intf->hw_idx] = tpg_hw_intf;
else
goto free_dev;
return 0;
free_dev:
kfree(tpg_hw);
free_hw_info:
kfree(hw_info);
free_hw_intf:
kfree(tpg_hw_intf);
err:
return rc;
}
static void cam_top_tpg_component_unbind(struct device *dev,
struct device *master_dev, void *data)
{
struct cam_top_tpg_hw *tpg_dev = NULL;
struct cam_hw_intf *tpg_hw_intf;
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;
hw_info = tpg_dev->hw_info;
CAM_DBG(CAM_ISP, "TPG:%d component unbound", tpg_dev->hw_intf->hw_idx);
cam_top_tpg_deinit(tpg_dev);
/*release the tpg device memory */
kfree(tpg_dev);
kfree(hw_info);
kfree(tpg_hw_intf);
}
const static struct component_ops cam_top_tpg_component_ops = {
.bind = cam_top_tpg_component_bind,
.unbind = cam_top_tpg_component_unbind,
};
int cam_top_tpg_probe(struct platform_device *pdev)
{
int rc = 0;
CAM_DBG(CAM_ISP, "Adding TPG component");
rc = component_add(&pdev->dev, &cam_top_tpg_component_ops);
if (rc)
CAM_ERR(CAM_ISP, "failed to add component rc: %d", rc);
return rc;
}
int cam_top_tpg_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &cam_top_tpg_component_ops);
return 0;
}
int cam_top_tpg_hw_init(struct cam_hw_intf **top_tpg_hw,
uint32_t hw_idx)
{
int rc = 0;
if (cam_top_tpg_hw_list[hw_idx]) {
*top_tpg_hw = cam_top_tpg_hw_list[hw_idx];
} else {
*top_tpg_hw = NULL;
rc = -1;
}
return rc;
}

View File

@@ -1,12 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG_DEV_H_
#define _CAM_TOP_TPG_DEV_H_
int cam_top_tpg_probe(struct platform_device *pdev);
int cam_top_tpg_remove(struct platform_device *pdev);
#endif /*_CAM_TOP_TPG_DEV_H_ */

View File

@@ -1,152 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include "cam_top_tpg_soc.h"
#include "cam_cpas_api.h"
#include "cam_debug_util.h"
int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t tpg_irq_handler, void *irq_data)
{
int rc = 0;
struct cam_cpas_register_params cpas_register_param;
struct cam_top_tpg_soc_private *soc_private;
soc_private = kzalloc(sizeof(struct cam_top_tpg_soc_private),
GFP_KERNEL);
if (!soc_private)
return -ENOMEM;
soc_info->soc_private = soc_private;
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc < 0)
return rc;
/* Need to see if we want post process the clock list */
rc = cam_soc_util_request_platform_resource(soc_info, tpg_irq_handler,
irq_data);
if (rc < 0) {
CAM_ERR(CAM_ISP,
"Error Request platform resources failed rc=%d", rc);
goto free_soc_private;
}
memset(&cpas_register_param, 0, sizeof(cpas_register_param));
strlcpy(cpas_register_param.identifier, "tpg",
CAM_HW_IDENTIFIER_LENGTH);
cpas_register_param.cell_index = soc_info->index;
cpas_register_param.dev = soc_info->dev;
rc = cam_cpas_register_client(&cpas_register_param);
if (rc) {
CAM_ERR(CAM_ISP, "CPAS registration failed rc=%d", rc);
goto release_soc;
} else {
soc_private->cpas_handle = cpas_register_param.client_handle;
}
return rc;
release_soc:
cam_soc_util_release_platform_resource(soc_info);
free_soc_private:
kfree(soc_private);
return rc;
}
int cam_top_tpg_deinit_soc_resources(
struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct cam_top_tpg_soc_private *soc_private;
soc_private = soc_info->soc_private;
if (!soc_private) {
CAM_ERR(CAM_ISP, "Error soc_private NULL");
return -ENODEV;
}
rc = cam_cpas_unregister_client(soc_private->cpas_handle);
if (rc)
CAM_ERR(CAM_ISP, "CPAS unregistration failed rc=%d", rc);
rc = cam_soc_util_release_platform_resource(soc_info);
return rc;
}
int cam_top_tpg_enable_soc_resources(
struct cam_hw_soc_info *soc_info, enum cam_vote_level clk_level)
{
int rc = 0;
struct cam_top_tpg_soc_private *soc_private;
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote = {0};
soc_private = soc_info->soc_private;
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.num_paths = 1;
axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;
axi_vote.axi_path[0].camnoc_bw = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.axi_path[0].mnoc_ab_bw = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.axi_path[0].mnoc_ib_bw = CAM_CPAS_DEFAULT_AXI_BW;
CAM_DBG(CAM_ISP, "csid camnoc_bw:%lld mnoc_ab_bw:%lld mnoc_ib_bw:%lld ",
axi_vote.axi_path[0].camnoc_bw,
axi_vote.axi_path[0].mnoc_ab_bw,
axi_vote.axi_path[0].mnoc_ib_bw);
rc = cam_cpas_start(soc_private->cpas_handle, &ahb_vote, &axi_vote);
if (rc) {
CAM_ERR(CAM_ISP, "Error CPAS start failed");
rc = -EFAULT;
goto end;
}
rc = cam_soc_util_enable_platform_resource(soc_info, true,
clk_level, false);
if (rc) {
CAM_ERR(CAM_ISP, "enable platform failed");
goto stop_cpas;
}
return rc;
stop_cpas:
cam_cpas_stop(soc_private->cpas_handle);
end:
return rc;
}
int cam_top_tpg_disable_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct cam_top_tpg_soc_private *soc_private;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error Invalid params");
return -EINVAL;
}
soc_private = soc_info->soc_private;
rc = cam_soc_util_disable_platform_resource(soc_info, true, false);
if (rc)
CAM_ERR(CAM_ISP, "Disable platform failed");
rc = cam_cpas_stop(soc_private->cpas_handle);
if (rc) {
CAM_ERR(CAM_ISP, "Error CPAS stop failed rc=%d", rc);
return rc;
}
return rc;
}

View File

@@ -1,79 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG_SOC_H_
#define _CAM_TOP_TPG_SOC_H_
#include "cam_isp_hw.h"
/*
* struct cam_top_tpg_soc_private:
*
* @Brief: Private SOC data specific to TPG HW Driver
*
* @cpas_handle: Handle returned on registering with CPAS driver.
* This handle is used for all further interface
* with CPAS.
*/
struct cam_top_tpg_soc_private {
uint32_t cpas_handle;
};
/**
* struct cam_top_tpg_device_soc_info - tpg soc SOC info object
*
* @csi_vdd_voltage: csi vdd voltage value
*
*/
struct cam_top_tpg_device_soc_info {
int csi_vdd_voltage;
};
/**
* cam_top_tpg_init_soc_resources()
*
* @brief: csid initialization function for the soc info
*
* @soc_info: soc info structure pointer
* @tpg_irq_handler: irq handler function to be registered
* @irq_data: irq data for the callback function
*
*/
int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t tpg_irq_handler, void *irq_data);
/**
* cam_top_tpg_deinit_soc_resources()
*
* @brief: tpg de initialization function for the soc info
*
* @soc_info: soc info structure pointer
*
*/
int cam_top_tpg_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
/**
* cam_top_tpg_enable_soc_resources()
*
* @brief: tpg soc resource enable function
*
* @soc_info: soc info structure pointer
* @clk_lvl: vote level to start with
*
*/
int cam_top_tpg_enable_soc_resources(struct cam_hw_soc_info *soc_info,
uint32_t clk_lvl);
/**
* cam_top_tpg_disable_soc_resources()
*
* @brief: csid soc resource disable function
*
* @soc_info: soc info structure pointer
*
*/
int cam_top_tpg_disable_soc_resources(struct cam_hw_soc_info *soc_info);
#endif /* _CAM_TOP_TPG_SOC_H_ */

View File

@@ -1,446 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, 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_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_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
int rc = 0;
struct cam_top_tpg_hw *tpg_hw;
struct cam_hw_info *tpg_hw_info;
if (!hw_priv || !cmd_args) {
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
return -EINVAL;
}
tpg_hw_info = (struct cam_hw_info *)hw_priv;
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
switch (cmd_type) {
case CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE:
rc = cam_top_tpg_set_phy_clock(tpg_hw, cmd_args);
break;
case CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD:
CAM_DBG(CAM_ISP,
"CORE_CFG_CMD is not supported by tpg version:%u",
tpg_hw->tpg_info->hw_dts_version);
break;
default:
CAM_ERR(CAM_ISP, "TPG:%d unsupported cmd:%d",
tpg_hw->hw_intf->hw_idx, cmd_type);
rc = -EINVAL;
break;
}
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[0] > 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[0],
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[0] = reserv->in_port[0]->vc[0];
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[0];
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[0], 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[0] != reserv->in_port[i]->vc[0]) ||
(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[0];
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_release(void *hw_priv,
void *release_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_cfg *tpg_data;
struct cam_isp_resource_node *tpg_res;
if (!hw_priv || !release_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_res = (struct cam_isp_resource_node *)release_args;
mutex_lock(&tpg_hw->hw_info->hw_mutex);
if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
(tpg_res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
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_DBG(CAM_ISP, "TPG:%d res type :%d",
tpg_hw->hw_intf->hw_idx, tpg_res->res_type);
tpg_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
tpg_data = (struct cam_top_tpg_cfg *)tpg_res->res_priv;
memset(tpg_data, 0, sizeof(struct cam_top_tpg_cfg));
end:
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
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(CAM_TPG_LFSR_SEED, 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[0];
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*/
val = cam_io_r_mb(soc_info->reg_map[1].mem_base +
tpg_reg->top_mux_reg_offset);
val |= (1 << tpg_hw->hw_intf->hw_idx);
cam_io_w_mb(val,
soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
CAM_DBG(CAM_ISP, "TPG:%d Set top Mux: 0x%x",
tpg_hw->hw_intf->hw_idx, val);
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;
uint32_t val;
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);
/* Reset the TOP tpg mux sel*/
val = cam_io_r_mb(soc_info->reg_map[1].mem_base +
tpg_reg->top_mux_reg_offset);
val &= ~(1 << tpg_hw->hw_intf->hw_idx);
cam_io_w_mb(val,
soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
CAM_DBG(CAM_ISP, "TPG:%d Reset Top Mux: 0x%x",
tpg_hw->hw_intf->hw_idx, val);
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.process_cmd = cam_top_tpg_ver1_process_cmd;
tpg_hw->hw_intf->hw_ops.reserve = cam_top_tpg_ver1_reserve;
tpg_hw->hw_intf->hw_ops.release = cam_top_tpg_ver1_release;
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

@@ -1,55 +0,0 @@
/* 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

@@ -1,325 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, 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_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
int rc = 0;
struct cam_top_tpg_hw *tpg_hw;
struct cam_hw_info *tpg_hw_info;
if (!hw_priv || !cmd_args) {
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
return -EINVAL;
}
tpg_hw_info = (struct cam_hw_info *)hw_priv;
tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info;
switch (cmd_type) {
case CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE:
rc = cam_top_tpg_set_phy_clock(tpg_hw, cmd_args);
break;
case CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD:
CAM_DBG(CAM_ISP,
"CORE_CFG_CMD is not supported by tpg version:%u",
tpg_hw->tpg_info->hw_dts_version);
break;
default:
CAM_ERR(CAM_ISP, "TPG:%d unsupported cmd:%d",
tpg_hw->hw_intf->hw_idx, cmd_type);
rc = -EINVAL;
break;
}
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_reserve_args *reserv;
struct cam_top_tpg_cfg *tpg_data;
if (!hw_priv || !reserve_args || (arg_size !=
sizeof(struct cam_top_tpg_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_reserve_args *)reserve_args;
if (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 = 55000;
tpg_data->v_blank_count = 50688;
tpg_data->dt_cfg[0].data_type = reserv->in_port[0]->dt[0];
tpg_data->vc_num[0] = reserv->in_port[0]->vc[0];
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_stop -
reserv->in_port[0]->left_start) + 1);
else
tpg_data->dt_cfg[0].frame_width =
reserv->in_port[0]->left_width;
tpg_data->num_active_dts = 1;
CAM_DBG(CAM_ISP, "TPG:%u vc:0x%x dt:0x%x h:%d w:%d hbi:%d vbi:%d reserved",
tpg_hw->hw_intf->hw_idx,
tpg_data->vc_num[0],
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_release(void *hw_priv,
void *release_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_cfg *tpg_data;
struct cam_isp_resource_node *tpg_res;
if (!hw_priv || !release_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_res = (struct cam_isp_resource_node *)release_args;
mutex_lock(&tpg_hw->hw_info->hw_mutex);
if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
(tpg_res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
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_DBG(CAM_ISP, "TPG:%d res type :%d",
tpg_hw->hw_intf->hw_idx, tpg_res->res_type);
tpg_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
tpg_data = (struct cam_top_tpg_cfg *)tpg_res->res_priv;
memset(tpg_data, 0, sizeof(struct cam_top_tpg_cfg));
end:
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_state == CAM_ISP_RESOURCE_STATE_STREAMING)
goto end;
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(0xFFFFF, 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.process_cmd = cam_top_tpg_ver2_process_cmd;
tpg_hw->hw_intf->hw_ops.reserve = cam_top_tpg_ver2_reserve;
tpg_hw->hw_intf->hw_ops.release = cam_top_tpg_ver2_release;
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

@@ -1,44 +0,0 @@
/* 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

@@ -1,592 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020-2021, 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_ver3.h"
static int cam_top_tpg_ver3_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_ver3_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_ver3_print_reserved_vcdt(
struct cam_top_tpg_hw *tpg_hw)
{
struct cam_top_tpg_cfg_v2 *tpg_data;
int i, j;
if (!tpg_hw)
return -EINVAL;
tpg_data = (struct cam_top_tpg_cfg_v2 *)tpg_hw->tpg_res.res_priv;
CAM_INFO(CAM_ISP, "tpg:%d Active_VCs: %d",
tpg_hw->hw_intf->hw_idx, tpg_data->num_active_vcs);
for (i = 0; i < tpg_data->num_active_vcs; i++)
{
CAM_INFO(CAM_ISP, "VC[%d]: 0x%x", i, tpg_data->vc_dt[i].vc_num);
for (j = 0; j < tpg_data->vc_dt[i].num_active_dts; j++)
{
CAM_INFO(CAM_ISP, "\tDT[%d]: 0x%x", j,
tpg_data->vc_dt[i].dt_cfg[j].data_type);
}
}
return 0;
}
static int cam_top_tpg_ver3_process_cmd(void *hw_priv,
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
{
int rc = 0;
int i;
struct cam_top_tpg_hw *tpg_hw;
struct cam_hw_info *tpg_hw_info;
struct cam_isp_tpg_core_config *core_cfg;
struct cam_top_tpg_cfg_v2 *tpg_data;
if (!hw_priv || !cmd_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;
tpg_data = (struct cam_top_tpg_cfg_v2 *)tpg_hw->tpg_res.res_priv;
switch (cmd_type) {
case CAM_ISP_HW_CMD_TPG_CORE_CFG_CMD:
if (arg_size != sizeof(struct cam_isp_tpg_core_config)) {
CAM_ERR(CAM_ISP, "Invalid size %u expected %u",
arg_size,
sizeof(struct cam_isp_tpg_core_config));
rc = -EINVAL;
break;
}
core_cfg = (struct cam_isp_tpg_core_config *)cmd_args;
tpg_data->vc_dt_pattern_id = core_cfg->vc_dt_pattern_id;
tpg_data->throttle_pattern = core_cfg->throttle_pattern;
for (i = 0; i < tpg_data->num_active_vcs; i++) {
tpg_data->vc_dt[i].pix_pattern = core_cfg->pix_pattern;
tpg_data->vc_dt[i].qcfa_en = core_cfg->qcfa_en;
tpg_data->vc_dt[i].h_blank_count =
core_cfg->hbi_clk_cnt;
tpg_data->vc_dt[i].v_blank_count =
core_cfg->vbi_clk_cnt;
}
CAM_DBG(CAM_ISP,
"pattern_id: 0x%x pix_pattern: 0x%x qcfa_en: 0x%x hbi: 0x%x vbi: 0x%x throttle: 0x%x",
core_cfg->vc_dt_pattern_id, core_cfg->pix_pattern,
core_cfg->qcfa_en, core_cfg->hbi_clk_cnt,
core_cfg->vbi_clk_cnt, core_cfg->throttle_pattern);
break;
default:
CAM_ERR(CAM_ISP, "Invalid TPG cmd type %u", cmd_type);
rc = -EINVAL;
break;
}
return rc;
}
static int cam_top_tpg_ver3_add_append_vc_dt_info(uint32_t *num_active_vcs,
struct cam_top_tpg_vc_dt_info *tpg_vcdt,
struct cam_isp_in_port_generic_info *in_port)
{
bool is_dt_saved = false;
int i;
int j;
uint32_t *num_dts;
uint32_t encode_format;
int rc;
for (i = 0; i < in_port->num_valid_vc_dt; i++) {
if (in_port->dt[i] > 0x3f || in_port->vc[i] > 0x1f) {
CAM_ERR(CAM_ISP, "Invalid vc:%d dt %d",
in_port->vc[i],
in_port->dt[i]);
return -EINVAL;
}
rc = cam_top_tpg_get_format(in_port->format, &encode_format);
if (rc)
return rc;
for (j = 0; j < *num_active_vcs; j++) {
if (tpg_vcdt[j].vc_num == in_port->vc[i]) {
num_dts = &tpg_vcdt[j].num_active_dts;
if (*num_dts >=
CAM_TOP_TPG_MAX_SUPPORTED_DT) {
CAM_ERR(CAM_ISP,
"Cannot support more than 4 DTs per VC"
);
return -EINVAL;
}
tpg_vcdt[j].dt_cfg[*num_dts].data_type =
in_port->dt[i];
tpg_vcdt[j].dt_cfg[*num_dts].encode_format =
encode_format;
tpg_vcdt[j].dt_cfg[*num_dts].frame_height =
in_port->height;
if (in_port->usage_type)
tpg_vcdt[j].dt_cfg[*num_dts].frame_width
= ((in_port->right_stop -
in_port->left_start) + 1);
else
tpg_vcdt[j].dt_cfg[*num_dts].frame_width
= in_port->left_width;
CAM_DBG(CAM_ISP,
"vc:%d dt:%d format:%d height:%d width:%d",
in_port->vc[i], in_port->dt[i],
encode_format, in_port->height,
tpg_vcdt[j].dt_cfg[*num_dts].frame_width
);
*num_dts += 1;
is_dt_saved = true;
break;
}
}
if (is_dt_saved == false) {
if (*num_active_vcs >= CAM_TOP_TPG_MAX_SUPPORTED_VC) {
CAM_ERR(CAM_ISP,
"Cannot support more than 4 VCs");
return -EINVAL;
}
tpg_vcdt[*num_active_vcs].vc_num = in_port->vc[i];
tpg_vcdt[*num_active_vcs].num_frames = 0;
tpg_vcdt[*num_active_vcs].dt_cfg[0].data_type =
in_port->dt[i];
tpg_vcdt[*num_active_vcs].dt_cfg[0].encode_format =
encode_format;
tpg_vcdt[*num_active_vcs].dt_cfg[0].frame_height =
in_port->height;
if (in_port->usage_type)
tpg_vcdt[*num_active_vcs].dt_cfg[0].frame_width
= ((in_port->right_stop - in_port->left_start)
+ 1);
else
tpg_vcdt[*num_active_vcs].dt_cfg[0].frame_width
= in_port->left_width;
CAM_DBG(CAM_ISP,
"vc:0x%x dt:0x%x format:%d height:%d width:%d",
in_port->vc[i], in_port->dt[i],
encode_format, in_port->height,
tpg_vcdt[*num_active_vcs].dt_cfg[0].frame_width
);
tpg_vcdt[*num_active_vcs].num_active_dts++;
*num_active_vcs += 1;
} else {
is_dt_saved = false;
}
}
return 0;
}
static int cam_top_tpg_ver3_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_reserve_args *reserv;
struct cam_top_tpg_cfg_v2 *tpg_data;
struct cam_top_tpg_vc_dt_info
in_port_vc_dt[CAM_TOP_TPG_MAX_SUPPORTED_VC];
const struct cam_top_tpg_debugfs *tpg_debug = NULL;
uint32_t num_active_vcs = 0;
int i;
uint32_t phy_sel = 0;
uint32_t num_active_lanes = 0;
if (!hw_priv || !reserve_args || (arg_size !=
sizeof(struct cam_top_tpg_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_reserve_args *)reserve_args;
CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx);
mutex_lock(&tpg_hw->hw_info->hw_mutex);
tpg_debug = cam_top_tpg_get_debugfs();
if (tpg_hw->tpg_res.res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) {
CAM_ERR(CAM_ISP, "TPG:%d can not be reserved. State: %u",
tpg_hw->hw_intf->hw_idx,
tpg_hw->tpg_res.res_state);
rc = -EINVAL;
goto error;
}
if ((reserv->in_port[0]->lane_num <= 0 ||
reserv->in_port[0]->lane_num > 4) ||
(reserv->in_port[0]->lane_type >= 2)) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG:%u invalid input %d %d",
tpg_hw->hw_intf->hw_idx,
reserv->in_port[0]->lane_num,
reserv->in_port[0]->lane_type);
rc = -EINVAL;
goto error;
}
tpg_data = (struct cam_top_tpg_cfg_v2 *)tpg_hw->tpg_res.res_priv;
memcpy((void *)&in_port_vc_dt[0], (void *)&tpg_data->vc_dt[0],
CAM_TOP_TPG_MAX_SUPPORTED_VC *
sizeof(struct cam_top_tpg_vc_dt_info));
num_active_vcs = tpg_data->num_active_vcs;
phy_sel = tpg_data->phy_sel;
num_active_lanes = tpg_data->num_active_lanes;
for (i = 0; i < reserv->num_inport; i++) {
if (num_active_vcs) {
if ((phy_sel != reserv->in_port[i]->lane_type) ||
(num_active_lanes !=
reserv->in_port[i]->lane_num)) {
CAM_ERR_RATE_LIMIT(CAM_ISP,
"TPG: %u invalid DT config for tpg",
tpg_hw->hw_intf->hw_idx);
rc = -EINVAL;
goto error;
}
} else {
phy_sel = reserv->in_port[0]->lane_type;
num_active_lanes =
reserv->in_port[0]->lane_num;
}
rc = cam_top_tpg_ver3_add_append_vc_dt_info(
&num_active_vcs,
&in_port_vc_dt[0],
reserv->in_port[i]);
if (rc) {
rc = -EINVAL;
CAM_ERR(CAM_ISP,
"Failed to reserve TPG:%u for in_port: %u",
tpg_hw->hw_intf->hw_idx, i);
goto error;
}
}
tpg_data->phy_sel = phy_sel;
tpg_data->num_active_lanes = num_active_lanes;
tpg_data->num_active_vcs = num_active_vcs;
memcpy((void *)&tpg_data->vc_dt[0], (void *)&in_port_vc_dt[0],
CAM_TOP_TPG_MAX_SUPPORTED_VC *
sizeof(struct cam_top_tpg_vc_dt_info));
CAM_DBG(CAM_ISP, "TPG:%u phy:%d lines:%d", tpg_hw->hw_intf->hw_idx,
tpg_data->phy_sel, tpg_data->num_active_lanes);
reserv->node_res = &tpg_hw->tpg_res;
tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
error:
if ((tpg_debug != NULL) && tpg_debug->enable_vcdt_dump)
cam_top_tpg_ver3_print_reserved_vcdt(tpg_hw);
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
CAM_DBG(CAM_ISP, "exit rc %u", rc);
return rc;
}
static int cam_top_tpg_ver3_release(void *hw_priv,
void *release_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_cfg_v2 *tpg_data;
struct cam_isp_resource_node *tpg_res;
if (!hw_priv || !release_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_res = (struct cam_isp_resource_node *)release_args;
mutex_lock(&tpg_hw->hw_info->hw_mutex);
if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) ||
(tpg_res->res_state <= CAM_ISP_RESOURCE_STATE_AVAILABLE)) {
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_DBG(CAM_ISP, "TPG:%d res type :%d",
tpg_hw->hw_intf->hw_idx, tpg_res->res_type);
tpg_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
tpg_data = (struct cam_top_tpg_cfg_v2 *)tpg_res->res_priv;
memset(tpg_data, 0, sizeof(struct cam_top_tpg_cfg_v2));
end:
mutex_unlock(&tpg_hw->hw_info->hw_mutex);
return rc;
}
static int cam_top_tpg_ver3_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_ver3_reg_offset *tpg_reg;
struct cam_top_tpg_cfg_v2 *tpg_data;
struct cam_top_tpg_vc_dt_info *vc_dt;
uint32_t i, val, j;
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_v2 *)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(1, soc_info->reg_map[0].mem_base + tpg_reg->tpg_top_clear);
for (i = 0; i < tpg_data->num_active_vcs; i++) {
vc_dt = &tpg_data->vc_dt[i];
val = (1 << tpg_reg->tpg_split_en_shift);
val |= vc_dt->pix_pattern;
if (vc_dt->qcfa_en)
val |=
(1 << tpg_reg->tpg_color_bar_qcfa_en_shift);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_color_bar_cfg + (0x60 * i));
CAM_DBG(CAM_ISP, "vc%d_color_bar_cfg: 0x%x", i, val);
if (vc_dt->h_blank_count)
val = vc_dt->h_blank_count;
else
val = 0x40;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_hbi_cfg + (0x60 * i));
CAM_DBG(CAM_ISP, "vc%d_hbi_cfg: 0x%x", i, val);
if (vc_dt->v_blank_count)
val = vc_dt->v_blank_count;
else
val = 0xC600;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_vbi_cfg + (0x60 * i));
CAM_DBG(CAM_ISP, "vc%d_vbi_cgf: 0x%x", i, val);
cam_io_w_mb(CAM_TPG_LFSR_SEED,
soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_lfsr_seed + (0x60 * i));
val = ((vc_dt->num_frames
<< tpg_reg->tpg_num_frames_shift_val) |
((vc_dt->num_active_dts-1) <<
tpg_reg->tpg_num_dts_shift_val) |
vc_dt->vc_num);
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_cfg0 + (0x60 * i));
CAM_DBG(CAM_ISP, "vc%d_cfg0: 0x%x", i, val);
for (j = 0; j < vc_dt->num_active_dts; j++) {
val = (((vc_dt->dt_cfg[j].frame_width & 0xFFFF) << 16) |
(vc_dt->dt_cfg[j].frame_height & 0xFFFF));
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_dt_0_cfg_0 +
(0x60 * i) + (j * 0x0c));
CAM_DBG(CAM_ISP, "vc%d_dt%d_cfg_0: 0x%x", i, j, val);
cam_io_w_mb(vc_dt->dt_cfg[j].data_type,
soc_info->reg_map[0].mem_base +
tpg_reg->tpg_vc0_dt_0_cfg_1 +
(0x60 * i) + (j * 0x0c));
CAM_DBG(CAM_ISP, "vc%d_dt%d_cfg_1: 0x%x",
i, j, vc_dt->dt_cfg[j].data_type);
val = ((vc_dt->dt_cfg[j].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_vc0_dt_0_cfg_2 +
(0x60 * i) + (j * 0x0c));
CAM_DBG(CAM_ISP, "vc%d_dt%d_cfg_2: 0x%x", i, j, val);
}
}
if ((tpg_data->throttle_pattern > 0) &&
(tpg_data->throttle_pattern <= 0xFFFF))
val = tpg_data->throttle_pattern;
else
val = 0x1111;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_throttle);
CAM_DBG(CAM_ISP, "tpg_throttle: 0x%x", val);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_top_irq_mask);
val = ((tpg_data->num_active_vcs - 1) <<
(tpg_reg->tpg_num_active_vcs_shift) |
(tpg_data->num_active_lanes - 1) <<
tpg_reg->tpg_num_active_lanes_shift) |
(tpg_data->vc_dt_pattern_id) <<
(tpg_reg->tpg_vc_dt_pattern_id_shift) |
(tpg_data->phy_sel << tpg_reg->tpg_cphy_dphy_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);
CAM_DBG(CAM_ISP, "tpg_ctrl 0x%x", val);
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_ver3_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_ver3_reg_offset *tpg_reg;
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;
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);
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_top_irq_mask);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_top_irq_clear);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
tpg_reg->tpg_top_irq_cmd);
cam_io_w_mb(1, soc_info->reg_map[0].mem_base + tpg_reg->tpg_top_clear);
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_ver3_init(
struct cam_top_tpg_hw *tpg_hw)
{
tpg_hw->hw_intf->hw_ops.get_hw_caps = cam_top_tpg_ver3_get_hw_caps;
tpg_hw->hw_intf->hw_ops.reserve = cam_top_tpg_ver3_reserve;
tpg_hw->hw_intf->hw_ops.release = cam_top_tpg_ver3_release;
tpg_hw->hw_intf->hw_ops.start = cam_top_tpg_ver3_start;
tpg_hw->hw_intf->hw_ops.stop = cam_top_tpg_ver3_stop;
tpg_hw->hw_intf->hw_ops.process_cmd = cam_top_tpg_ver3_process_cmd;
cam_top_tpg_debug_register();
return 0;
}

View File

@@ -1,120 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
#ifndef _CAM_TOP_TPG_VER3_H_
#define _CAM_TOP_TPG_VER3_H_
#include "cam_top_tpg_core.h"
struct cam_top_tpg_ver3_reg_offset {
uint32_t tpg_hw_version;
uint32_t tpg_hw_status;
uint32_t tpg_ctrl;
uint32_t tpg_vc0_cfg0;
uint32_t tpg_vc0_lfsr_seed;
uint32_t tpg_vc0_hbi_cfg;
uint32_t tpg_vc0_vbi_cfg;
uint32_t tpg_vc0_color_bar_cfg;
uint32_t tpg_vc0_dt_0_cfg_0;
uint32_t tpg_vc0_dt_0_cfg_1;
uint32_t tpg_vc0_dt_0_cfg_2;
uint32_t tpg_vc0_dt_1_cfg_0;
uint32_t tpg_vc0_dt_1_cfg_1;
uint32_t tpg_vc0_dt_1_cfg_2;
uint32_t tpg_vc0_dt_2_cfg_0;
uint32_t tpg_vc0_dt_2_cfg_1;
uint32_t tpg_vc0_dt_2_cfg_2;
uint32_t tpg_vc0_dt_3_cfg_0;
uint32_t tpg_vc0_dt_3_cfg_1;
uint32_t tpg_vc0_dt_3_cfg_2;
uint32_t tpg_vc1_cfg0;
uint32_t tpg_vc1_lfsr_seed;
uint32_t tpg_vc1_hbi_cfg;
uint32_t tpg_vc1_vbi_cfg;
uint32_t tpg_vc1_color_bar_cfg;
uint32_t tpg_vc1_dt_0_cfg_0;
uint32_t tpg_vc1_dt_0_cfg_1;
uint32_t tpg_vc1_dt_0_cfg_2;
uint32_t tpg_vc1_dt_1_cfg_0;
uint32_t tpg_vc1_dt_1_cfg_1;
uint32_t tpg_vc1_dt_1_cfg_2;
uint32_t tpg_vc1_dt_2_cfg_0;
uint32_t tpg_vc1_dt_2_cfg_1;
uint32_t tpg_vc1_dt_2_cfg_2;
uint32_t tpg_vc1_dt_3_cfg_0;
uint32_t tpg_vc1_dt_3_cfg_1;
uint32_t tpg_vc1_dt_3_cfg_2;
uint32_t tpg_vc2_cfg0;
uint32_t tpg_vc2_lfsr_seed;
uint32_t tpg_vc2_hbi_cfg;
uint32_t tpg_vc2_vbi_cfg;
uint32_t tpg_vc2_color_bar_cfg;
uint32_t tpg_vc2_dt_0_cfg_0;
uint32_t tpg_vc2_dt_0_cfg_1;
uint32_t tpg_vc2_dt_0_cfg_2;
uint32_t tpg_vc2_dt_1_cfg_0;
uint32_t tpg_vc2_dt_1_cfg_1;
uint32_t tpg_vc2_dt_1_cfg_2;
uint32_t tpg_vc2_dt_2_cfg_0;
uint32_t tpg_vc2_dt_2_cfg_1;
uint32_t tpg_vc2_dt_2_cfg_2;
uint32_t tpg_vc2_dt_3_cfg_0;
uint32_t tpg_vc2_dt_3_cfg_1;
uint32_t tpg_vc2_dt_3_cfg_2;
uint32_t tpg_vc3_cfg0;
uint32_t tpg_vc3_lfsr_seed;
uint32_t tpg_vc3_hbi_cfg;
uint32_t tpg_vc3_vbi_cfg;
uint32_t tpg_vc3_color_bar_cfg;
uint32_t tpg_vc3_dt_0_cfg_0;
uint32_t tpg_vc3_dt_0_cfg_1;
uint32_t tpg_vc3_dt_0_cfg_2;
uint32_t tpg_vc3_dt_1_cfg_0;
uint32_t tpg_vc3_dt_1_cfg_1;
uint32_t tpg_vc3_dt_1_cfg_2;
uint32_t tpg_vc3_dt_2_cfg_0;
uint32_t tpg_vc3_dt_2_cfg_1;
uint32_t tpg_vc3_dt_2_cfg_2;
uint32_t tpg_vc3_dt_3_cfg_0;
uint32_t tpg_vc3_dt_3_cfg_1;
uint32_t tpg_vc3_dt_3_cfg_2;
uint32_t tpg_throttle;
uint32_t tpg_top_irq_status;
uint32_t tpg_top_irq_mask;
uint32_t tpg_top_irq_clear;
uint32_t tpg_top_irq_set;
uint32_t tpg_top_irq_cmd;
uint32_t tpg_top_clear;
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_cphy_dphy_sel_shift_val;
uint32_t tpg_num_active_lanes_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_frames_shift_val;
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;
uint32_t tpg_vc_dt_pattern_id_shift;
uint32_t tpg_num_active_vcs_shift;
uint32_t tpg_color_bar_qcfa_en_shift;
};
int cam_top_tpg_ver3_init(struct cam_top_tpg_hw *tpg_hw);
#endif /* _CAM_TOP_TPG_VER3_H_ */

View File

@@ -57,7 +57,6 @@
#include "ope_dev_intf.h"
#include "cre_dev_intf.h"
#include "cam_top_tpg.h"
#include "cam_tfe_dev.h"
#include "cam_tfe_csid.h"
#include "cam_csid_ppi100.h"
@@ -93,7 +92,6 @@ static const struct camera_submodule_component camera_tfe[] = {
static const struct camera_submodule_component camera_isp[] = {
#ifdef CONFIG_SPECTRA_ISP
{&cam_top_tpg_init_module, &cam_top_tpg_exit_module},
{&cam_ife_csid_init_module, &cam_ife_csid_exit_module},
{&cam_ife_csid_lite_init_module, &cam_ife_csid_lite_exit_module},
{&cam_vfe_init_module, &cam_vfe_exit_module},

View File

@@ -15,7 +15,6 @@ 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_csid_driver;
extern struct platform_driver cam_ife_csid_lite_driver;
extern struct platform_driver cam_vfe_driver;
@@ -91,7 +90,6 @@ static struct platform_driver *const cam_component_drivers[] = {
&cam_tfe_csid_driver,
#endif
#ifdef CONFIG_SPECTRA_ISP
&cam_top_tpg_driver,
&cam_ife_csid_driver,
&cam_ife_csid_lite_driver,
&cam_vfe_driver,

View File

@@ -35,6 +35,9 @@
#define CAM_ISP_TFE_IN_RES_PHY_1 (CAM_ISP_TFE_IN_RES_BASE + 2)
#define CAM_ISP_TFE_IN_RES_PHY_2 (CAM_ISP_TFE_IN_RES_BASE + 3)
#define CAM_ISP_TFE_IN_RES_PHY_3 (CAM_ISP_TFE_IN_RES_BASE + 4)
#define CAM_ISP_TFE_IN_RES_MAX (CAM_ISP_TFE_IN_RES_BASE + 5)
#define CAM_ISP_TFE_IN_RES_CPHY_TPG_0 (CAM_ISP_TFE_IN_RES_BASE + 8)
#define CAM_ISP_TFE_IN_RES_CPHY_TPG_1 (CAM_ISP_TFE_IN_RES_BASE + 9)
#define CAM_ISP_TFE_IN_RES_CPHY_TPG_2 (CAM_ISP_TFE_IN_RES_BASE + 10)
#define CAM_ISP_TFE_IN_RES_MAX (CAM_ISP_TFE_IN_RES_BASE + 11)
#endif /* __UAPI_CAM_ISP_TFE_H__ */