msm: camera: isp: Add support for PDAF HW

This change add support for:
 - PDAF HW support handling in CSID and TFE driver
 - CSID PPP halt mode handling
 - Add support for new TFE PD ports (LCR, PD_PREPROCESSED
   PD_PARSED).

CRs-Fixed: 3387396
Change-Id: I56dc109138607fe7b342760a5c977e4126fe1676
Signed-off-by: Alok Chauhan <quic_alokc@quicinc.com>
This commit is contained in:
Alok Chauhan
2022-12-14 19:29:21 +05:30
parent 28aee302b2
commit b5d8386049
11 changed files with 1067 additions and 60 deletions

View File

@@ -1324,6 +1324,9 @@ static const char *__cam_isp_tfe_resource_handle_id_to_type(
case CAM_ISP_TFE_OUT_RES_DS4: return "TFE_DS_4"; case CAM_ISP_TFE_OUT_RES_DS4: return "TFE_DS_4";
case CAM_ISP_TFE_OUT_RES_DS16: return "TFE_DS_16"; case CAM_ISP_TFE_OUT_RES_DS16: return "TFE_DS_16";
case CAM_ISP_TFE_OUT_RES_AI: return "TFE_AI"; case CAM_ISP_TFE_OUT_RES_AI: return "TFE_AI";
case CAM_ISP_TFE_OUT_RES_PD_LCR_STATS: return "TFE_LCR_STATS";
case CAM_ISP_TFE_OUT_RES_PD_PREPROCESSED: return "TFE_PD_PREPROCESSED";
case CAM_ISP_TFE_OUT_RES_PD_PARSED: return "TFE_PD_PARSED";
/* Handle invalid type */ /* Handle invalid type */
default: return "Invalid_Resource_Type"; default: return "Invalid_Resource_Type";
} }

View File

@@ -239,6 +239,20 @@ static int cam_tfe_mgr_get_hw_caps(void *hw_mgr_priv, void *hw_caps_args)
return rc; return rc;
} }
static inline bool cam_tfe_hw_mgr_check_path_port_compat(
uint32_t in_type, uint32_t out_type)
{
int i;
const struct cam_isp_hw_path_port_map *map = &g_tfe_hw_mgr.path_port_map;
for (i = 0; i < map->num_entries; i++) {
if (map->entry[i][1] == out_type)
return (map->entry[i][0] == in_type);
}
return (in_type == CAM_ISP_HW_TFE_IN_CAMIF);
}
static int cam_tfe_hw_mgr_is_rdi_res(uint32_t res_id) static int cam_tfe_hw_mgr_is_rdi_res(uint32_t res_id)
{ {
int rc = 0; int rc = 0;
@@ -1019,6 +1033,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out(
switch (tfe_in_res->res_id) { switch (tfe_in_res->res_id) {
case CAM_ISP_HW_TFE_IN_CAMIF: case CAM_ISP_HW_TFE_IN_CAMIF:
case CAM_ISP_HW_TFE_IN_PDLIB:
rc = cam_tfe_hw_mgr_acquire_res_tfe_out_pixel(tfe_ctx, rc = cam_tfe_hw_mgr_acquire_res_tfe_out_pixel(tfe_ctx,
tfe_in_res, in_port); tfe_in_res, in_port);
break; break;
@@ -1046,7 +1061,8 @@ err:
static int cam_tfe_hw_mgr_acquire_res_tfe_in( static int cam_tfe_hw_mgr_acquire_res_tfe_in(
struct cam_tfe_hw_mgr_ctx *tfe_ctx, struct cam_tfe_hw_mgr_ctx *tfe_ctx,
struct cam_isp_tfe_in_port_generic_info *in_port, struct cam_isp_tfe_in_port_generic_info *in_port,
uint32_t *pdaf_enable) uint32_t *pdaf_enable,
bool lcr_enable)
{ {
int rc = -EINVAL; int rc = -EINVAL;
int i; int i;
@@ -1080,6 +1096,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_in(
tfe_acquire.tfe_in.camif_pd_enable = *pdaf_enable; tfe_acquire.tfe_in.camif_pd_enable = *pdaf_enable;
tfe_acquire.priv = tfe_ctx; tfe_acquire.priv = tfe_ctx;
tfe_acquire.event_cb = cam_tfe_hw_mgr_event_handler; tfe_acquire.event_cb = cam_tfe_hw_mgr_event_handler;
tfe_acquire.tfe_in.lcr_enable = lcr_enable;
switch (csid_res->res_id) { switch (csid_res->res_id) {
case CAM_TFE_CSID_PATH_RES_IPP: case CAM_TFE_CSID_PATH_RES_IPP:
@@ -1094,6 +1111,17 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_in(
CAM_ISP_HW_SYNC_NONE; CAM_ISP_HW_SYNC_NONE;
break; break;
case CAM_TFE_CSID_PATH_RES_PPP:
tfe_acquire.tfe_in.res_id =
CAM_ISP_HW_TFE_IN_PDLIB;
if (csid_res->is_dual_isp)
tfe_acquire.tfe_in.sync_mode =
CAM_ISP_HW_SYNC_MASTER;
else
tfe_acquire.tfe_in.sync_mode =
CAM_ISP_HW_SYNC_NONE;
break;
case CAM_TFE_CSID_PATH_RES_RDI_0: case CAM_TFE_CSID_PATH_RES_RDI_0:
tfe_acquire.tfe_in.res_id = CAM_ISP_HW_TFE_IN_RDI0; tfe_acquire.tfe_in.res_id = CAM_ISP_HW_TFE_IN_RDI0;
tfe_acquire.tfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE; tfe_acquire.tfe_in.sync_mode = CAM_ISP_HW_SYNC_NONE;
@@ -1162,7 +1190,9 @@ err:
static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl( static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
struct cam_tfe_hw_mgr_ctx *tfe_ctx, struct cam_tfe_hw_mgr_ctx *tfe_ctx,
struct cam_isp_tfe_in_port_generic_info *in_port) struct cam_isp_tfe_in_port_generic_info *in_port,
bool is_ipp,
bool crop_enable)
{ {
int rc = -EINVAL; int rc = -EINVAL;
int i, j; int i, j;
@@ -1170,14 +1200,17 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
struct cam_tfe_hw_mgr *tfe_hw_mgr; struct cam_tfe_hw_mgr *tfe_hw_mgr;
struct cam_isp_hw_mgr_res *csid_res; struct cam_isp_hw_mgr_res *csid_res;
struct cam_hw_intf *hw_intf; struct cam_hw_intf *hw_intf;
struct cam_tfe_csid_hw_reserve_resource_args csid_acquire; struct cam_tfe_csid_hw_reserve_resource_args csid_acquire = {0};
enum cam_tfe_csid_path_res_id path_res_id; enum cam_tfe_csid_path_res_id path_res_id;
struct cam_isp_hw_mgr_res *csid_res_temp, *csid_res_iterator; struct cam_isp_hw_mgr_res *csid_res_temp, *csid_res_iterator;
struct cam_isp_tfe_out_port_generic_info *out_port = NULL; struct cam_isp_tfe_out_port_generic_info *out_port = NULL;
tfe_hw_mgr = tfe_ctx->hw_mgr; tfe_hw_mgr = tfe_ctx->hw_mgr;
/* get csid resource */ /* get csid resource */
if (is_ipp)
path_res_id = CAM_TFE_CSID_PATH_RES_IPP; path_res_id = CAM_TFE_CSID_PATH_RES_IPP;
else
path_res_id = CAM_TFE_CSID_PATH_RES_PPP;
rc = cam_tfe_hw_mgr_get_res(&tfe_ctx->free_res_list, &csid_res); rc = cam_tfe_hw_mgr_get_res(&tfe_ctx->free_res_list, &csid_res);
if (rc) { if (rc) {
@@ -1194,6 +1227,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
csid_acquire.node_res = NULL; csid_acquire.node_res = NULL;
csid_acquire.event_cb_prv = tfe_ctx; csid_acquire.event_cb_prv = tfe_ctx;
csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler; csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler;
csid_acquire.crop_enable = crop_enable;
if (in_port->num_out_res) if (in_port->num_out_res)
out_port = &(in_port->data[0]); out_port = &(in_port->data[0]);
@@ -1232,12 +1266,14 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
csid_acquire.node_res; csid_acquire.node_res;
CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP,
"acquired from old csid(%s)=%d CSID rsrc successfully", "acquired from old csid(%s)=%d CSID rsrc %s successfully",
(i == 0) ? "left" : "right", (i == 0) ? "left" : "right",
hw_intf->hw_idx); hw_intf->hw_idx,
(is_ipp) ? "IPP" : "PPP");
if (in_port->usage_type && acquired_cnt == 1 && if (in_port->usage_type && acquired_cnt == 1 &&
path_res_id == CAM_TFE_CSID_PATH_RES_IPP) ((path_res_id == CAM_TFE_CSID_PATH_RES_IPP) ||
(path_res_id == CAM_TFE_CSID_PATH_RES_PPP)))
/* /*
* Continue to acquire Right for IPP. * Continue to acquire Right for IPP.
* Dual TFE for RDI is not currently * Dual TFE for RDI is not currently
@@ -1284,8 +1320,9 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
if (i == CAM_TFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) { if (i == CAM_TFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Can not acquire left tfe csid path resource %d", "Can not acquire left tfe csid path resource %d (%s)",
path_res_id); path_res_id,
(is_ipp) ? "IPP" : "PPP");
goto put_res; goto put_res;
} }
} else { } else {
@@ -1308,14 +1345,16 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(
if (i == -1 || !csid_acquire.node_res) { if (i == -1 || !csid_acquire.node_res) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Can not acquire tfe csid path resource %d", "Can not acquire tfe csid path resource %d(%s)",
path_res_id); path_res_id,
(is_ipp) ? "IPP" : "PPP");
goto put_res; goto put_res;
} }
} }
acquire_successful: acquire_successful:
CAM_DBG(CAM_ISP, "CSID path left acquired success. is_dual %d", CAM_DBG(CAM_ISP, "CSID path left acquired success. is_dual %d res %s",
in_port->usage_type); in_port->usage_type,
(is_ipp) ? "IPP" : "PPP");
csid_res_temp->res_type = CAM_ISP_RESOURCE_PIX_PATH; csid_res_temp->res_type = CAM_ISP_RESOURCE_PIX_PATH;
csid_res_temp->res_id = path_res_id; csid_res_temp->res_id = path_res_id;
@@ -1337,7 +1376,8 @@ acquire_successful:
* Acquire Right if not already acquired. * Acquire Right if not already acquired.
* Dual TFE for RDI is not currently supported. * Dual TFE for RDI is not currently supported.
*/ */
if (in_port->usage_type && (path_res_id == CAM_TFE_CSID_PATH_RES_IPP) if (in_port->usage_type && ((path_res_id == CAM_TFE_CSID_PATH_RES_IPP)
|| (path_res_id == CAM_TFE_CSID_PATH_RES_PPP))
&& (acquired_cnt == 1)) { && (acquired_cnt == 1)) {
memset(&csid_acquire, 0, sizeof(csid_acquire)); memset(&csid_acquire, 0, sizeof(csid_acquire));
csid_acquire.node_res = NULL; csid_acquire.node_res = NULL;
@@ -1349,6 +1389,7 @@ acquire_successful:
csid_acquire.sync_mode = CAM_ISP_HW_SYNC_SLAVE; csid_acquire.sync_mode = CAM_ISP_HW_SYNC_SLAVE;
csid_acquire.node_res = NULL; csid_acquire.node_res = NULL;
csid_acquire.out_port = in_port->data; csid_acquire.out_port = in_port->data;
csid_acquire.crop_enable = crop_enable;
csid_acquire.event_cb_prv = tfe_ctx; csid_acquire.event_cb_prv = tfe_ctx;
csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler; csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler;
@@ -1370,14 +1411,16 @@ acquire_successful:
if (j == CAM_TFE_CSID_HW_NUM_MAX) { if (j == CAM_TFE_CSID_HW_NUM_MAX) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Can not acquire tfe csid pixel resource"); "Can not acquire tfe csid pixel resource %s",
(is_ipp) ? "IPP" : "PPP");
goto end; goto end;
} }
csid_res_temp->hw_res[1] = csid_acquire.node_res; csid_res_temp->hw_res[1] = csid_acquire.node_res;
tfe_ctx->slave_hw_idx = tfe_ctx->slave_hw_idx =
csid_res_temp->hw_res[1]->hw_intf->hw_idx; csid_res_temp->hw_res[1]->hw_intf->hw_idx;
CAM_DBG(CAM_ISP, "CSID right acquired success is_dual %d", CAM_DBG(CAM_ISP, "CSID right acquired success is_dual %d res %s",
in_port->usage_type); in_port->usage_type,
(is_ipp) ? "IPP" : "PPP");
} }
return 0; return 0;
@@ -1427,7 +1470,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_rdi(
struct cam_isp_hw_mgr_res *csid_res; struct cam_isp_hw_mgr_res *csid_res;
struct cam_hw_intf *hw_intf; struct cam_hw_intf *hw_intf;
struct cam_isp_tfe_out_port_generic_info *out_port; struct cam_isp_tfe_out_port_generic_info *out_port;
struct cam_tfe_csid_hw_reserve_resource_args csid_acquire; struct cam_tfe_csid_hw_reserve_resource_args csid_acquire = {0};
struct cam_isp_hw_mgr_res *csid_res_iterator; struct cam_isp_hw_mgr_res *csid_res_iterator;
enum cam_tfe_csid_path_res_id path_res_id; enum cam_tfe_csid_path_res_id path_res_id;
@@ -1606,10 +1649,13 @@ static int cam_tfe_hw_mgr_preprocess_port(
struct cam_isp_tfe_in_port_generic_info *in_port, struct cam_isp_tfe_in_port_generic_info *in_port,
int *ipp_count, int *ipp_count,
int *rdi_count, int *rdi_count,
int *pdaf_enable) int *ppp_count,
int *pdaf_enable,
bool *lcr_enable)
{ {
int ipp_num = 0; int ipp_num = 0;
int rdi_num = 0; int rdi_num = 0;
int pd_num = 0;
bool rdi2_enable = false; bool rdi2_enable = false;
uint32_t i; uint32_t i;
struct cam_isp_tfe_out_port_generic_info *out_port; struct cam_isp_tfe_out_port_generic_info *out_port;
@@ -1633,6 +1679,12 @@ static int cam_tfe_hw_mgr_preprocess_port(
rdi_num++; rdi_num++;
if (out_port->res_id == CAM_ISP_TFE_OUT_RES_RDI_2) if (out_port->res_id == CAM_ISP_TFE_OUT_RES_RDI_2)
rdi2_enable = true; rdi2_enable = true;
} else if (cam_tfe_hw_mgr_check_path_port_compat(CAM_ISP_HW_TFE_IN_PDLIB,
out_port->res_id)) {
pd_num++;
if (out_port->res_id == CAM_ISP_TFE_OUT_RES_PD_LCR_STATS)
*lcr_enable = true;
} else { } else {
ipp_num++; ipp_num++;
if (out_port->res_id == CAM_ISP_TFE_OUT_RES_PDAF) if (out_port->res_id == CAM_ISP_TFE_OUT_RES_PDAF)
@@ -1648,9 +1700,10 @@ static int cam_tfe_hw_mgr_preprocess_port(
*ipp_count = ipp_num; *ipp_count = ipp_num;
*rdi_count = rdi_num; *rdi_count = rdi_num;
*ppp_count = pd_num;
CAM_DBG(CAM_ISP, "rdi: %d ipp: %d pdaf:%d", rdi_num, ipp_num, CAM_DBG(CAM_ISP, "rdi: %d ipp: %d ppp: %d pdaf:%d", rdi_num, ipp_num,
*pdaf_enable); *ppp_count, *pdaf_enable);
return 0; return 0;
} }
@@ -1659,28 +1712,51 @@ static int cam_tfe_mgr_acquire_hw_for_ctx(
struct cam_tfe_hw_mgr_ctx *tfe_ctx, struct cam_tfe_hw_mgr_ctx *tfe_ctx,
struct cam_isp_tfe_in_port_generic_info *in_port, struct cam_isp_tfe_in_port_generic_info *in_port,
uint32_t *num_pix_port, uint32_t *num_rdi_port, uint32_t *num_pix_port, uint32_t *num_rdi_port,
uint32_t *pdaf_enable) uint32_t *num_pd_port, uint32_t *pdaf_enable)
{ {
int rc = -EINVAL; int rc = -EINVAL;
int is_dual_isp = 0; int is_dual_isp = 0;
int ipp_count = 0; int ipp_count = 0;
int rdi_count = 0; int rdi_count = 0;
int ppp_count = 0;
bool lcr_enable = false;
bool crop_enable = true;
is_dual_isp = in_port->usage_type; is_dual_isp = in_port->usage_type;
cam_tfe_hw_mgr_preprocess_port(tfe_ctx, in_port, &ipp_count, cam_tfe_hw_mgr_preprocess_port(tfe_ctx, in_port, &ipp_count,
&rdi_count, pdaf_enable); &rdi_count, &ppp_count, pdaf_enable, &lcr_enable);
if (!ipp_count && !rdi_count) { if (!ipp_count && !rdi_count && !ppp_count) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"No PIX or RDI"); "No PIX or RDI");
return -EINVAL; return -EINVAL;
} }
if (ipp_count) { if (ipp_count || lcr_enable) {
/* get tfe csid IPP resource */ /* get tfe csid IPP resource */
rc = cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(tfe_ctx, rc = cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(tfe_ctx,
in_port); in_port, true, crop_enable);
if (rc) {
CAM_ERR(CAM_ISP,
"Acquire TFE CSID IPP resource Failed dual:%d",
in_port->usage_type);
goto err;
}
}
if (ppp_count) {
/* get ife csid PPP resource */
/* If both IPP and PPP paths are requested with the same vc dt
* it is implied that the sensor is a type 3 PD sensor. Crop
* must be enabled for this sensor on PPP path as well.
*/
if (!ipp_count)
crop_enable = false;
/* get tfe csid IPP resource */
rc = cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl(tfe_ctx,
in_port, false, crop_enable);
if (rc) { if (rc) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Acquire TFE CSID IPP resource Failed dual:%d", "Acquire TFE CSID IPP resource Failed dual:%d",
@@ -1700,7 +1776,7 @@ static int cam_tfe_mgr_acquire_hw_for_ctx(
} }
} }
rc = cam_tfe_hw_mgr_acquire_res_tfe_in(tfe_ctx, in_port, pdaf_enable); rc = cam_tfe_hw_mgr_acquire_res_tfe_in(tfe_ctx, in_port, pdaf_enable, lcr_enable);
if (rc) { if (rc) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Acquire TFE IN resource Failed dual:%d", in_port->usage_type); "Acquire TFE IN resource Failed dual:%d", in_port->usage_type);
@@ -1717,6 +1793,7 @@ static int cam_tfe_mgr_acquire_hw_for_ctx(
*num_pix_port += ipp_count; *num_pix_port += ipp_count;
*num_rdi_port += rdi_count; *num_rdi_port += rdi_count;
*num_pd_port += ppp_count;
return 0; return 0;
err: err:
@@ -2094,11 +2171,13 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
struct cam_cdm_acquire_data cdm_acquire; struct cam_cdm_acquire_data cdm_acquire;
uint32_t num_pix_port_per_in = 0; uint32_t num_pix_port_per_in = 0;
uint32_t num_rdi_port_per_in = 0; uint32_t num_rdi_port_per_in = 0;
uint32_t num_pd_port_per_in = 0;
uint32_t pdaf_enable = 0; uint32_t pdaf_enable = 0;
uint32_t total_pix_port = 0; uint32_t total_pix_port = 0;
uint32_t total_rdi_port = 0; uint32_t total_rdi_port = 0;
struct cam_isp_tfe_acquire_hw_info *acquire_hw_info = NULL; struct cam_isp_tfe_acquire_hw_info *acquire_hw_info = NULL;
uint32_t input_size = 0; uint32_t input_size = 0;
bool lcr_enable = false;
CAM_DBG(CAM_ISP, "Enter..."); CAM_DBG(CAM_ISP, "Enter...");
@@ -2186,7 +2265,7 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
for (i = 0; i < acquire_hw_info->num_inputs; i++) { for (i = 0; i < acquire_hw_info->num_inputs; i++) {
cam_tfe_hw_mgr_preprocess_port(tfe_ctx, &in_port[i], &num_pix_port_per_in, cam_tfe_hw_mgr_preprocess_port(tfe_ctx, &in_port[i], &num_pix_port_per_in,
&num_rdi_port_per_in, &pdaf_enable); &num_rdi_port_per_in, &num_pd_port_per_in, &pdaf_enable, &lcr_enable);
total_pix_port += num_pix_port_per_in; total_pix_port += num_pix_port_per_in;
total_rdi_port += num_rdi_port_per_in; total_rdi_port += num_rdi_port_per_in;
} }
@@ -2214,7 +2293,7 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
CAM_DBG(CAM_ISP, "in_res_id %x", in_port[i].res_id); CAM_DBG(CAM_ISP, "in_res_id %x", in_port[i].res_id);
rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx, &in_port[i], rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx, &in_port[i],
&num_pix_port_per_in, &num_rdi_port_per_in, &num_pix_port_per_in, &num_rdi_port_per_in, &num_pd_port_per_in,
&pdaf_enable); &pdaf_enable);
if (rc) { if (rc) {
@@ -2359,6 +2438,7 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
struct cam_cdm_acquire_data cdm_acquire; struct cam_cdm_acquire_data cdm_acquire;
uint32_t num_pix_port_per_in = 0; uint32_t num_pix_port_per_in = 0;
uint32_t num_rdi_port_per_in = 0; uint32_t num_rdi_port_per_in = 0;
uint32_t num_pd_port_per_in = 0;
uint32_t pdad_enable = 0; uint32_t pdad_enable = 0;
uint32_t total_pix_port = 0; uint32_t total_pix_port = 0;
uint32_t total_rdi_port = 0; uint32_t total_rdi_port = 0;
@@ -2478,7 +2558,7 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx, rc = cam_tfe_mgr_acquire_hw_for_ctx(tfe_ctx,
&gen_in_port[i], &gen_in_port[i],
&num_pix_port_per_in, &num_rdi_port_per_in, &num_pix_port_per_in, &num_rdi_port_per_in, &num_pd_port_per_in,
&pdad_enable); &pdad_enable);
total_pix_port += num_pix_port_per_in; total_pix_port += num_pix_port_per_in;
total_rdi_port += num_rdi_port_per_in; total_rdi_port += num_rdi_port_per_in;
@@ -2593,7 +2673,8 @@ static int cam_tfe_classify_vote_info(
{ {
int rc = 0, i, j = 0; int rc = 0, i, j = 0;
if (hw_mgr_res->res_id == CAM_ISP_HW_TFE_IN_CAMIF) { if ((hw_mgr_res->res_id == CAM_ISP_HW_TFE_IN_CAMIF) ||
(hw_mgr_res->res_id == CAM_ISP_HW_TFE_IN_PDLIB)) {
if (split_idx == CAM_ISP_HW_SPLIT_LEFT) { if (split_idx == CAM_ISP_HW_SPLIT_LEFT) {
if (*camif_l_bw_updated) if (*camif_l_bw_updated)
return rc; return rc;
@@ -3648,6 +3729,7 @@ static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args)
break; break;
case CAM_TFE_CSID_PATH_RES_IPP: case CAM_TFE_CSID_PATH_RES_IPP:
case CAM_TFE_CSID_PATH_RES_PPP:
if (hw_intf->hw_ops.process_cmd) { if (hw_intf->hw_ops.process_cmd) {
rc = hw_intf->hw_ops.process_cmd( rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv, hw_intf->hw_priv,
@@ -3686,6 +3768,7 @@ static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args)
break; break;
case CAM_ISP_HW_TFE_IN_CAMIF: case CAM_ISP_HW_TFE_IN_CAMIF:
case CAM_ISP_HW_TFE_IN_PDLIB:
if (hw_intf->hw_ops.process_cmd) { if (hw_intf->hw_ops.process_cmd) {
rc = hw_intf->hw_ops.process_cmd( rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv, hw_intf->hw_priv,
@@ -3995,7 +4078,8 @@ static int cam_isp_tfe_blob_clock_update(
if (!hw_mgr_res->hw_res[i]) if (!hw_mgr_res->hw_res[i])
continue; continue;
if (hw_mgr_res->res_id == CAM_ISP_HW_TFE_IN_CAMIF) { if ((hw_mgr_res->res_id == CAM_ISP_HW_TFE_IN_CAMIF) ||
(hw_mgr_res->res_id == CAM_ISP_HW_TFE_IN_PDLIB)) {
if (i == CAM_ISP_HW_SPLIT_LEFT) { if (i == CAM_ISP_HW_SPLIT_LEFT) {
if (camif_l_clk_updated) if (camif_l_clk_updated)
continue; continue;
@@ -5934,6 +6018,8 @@ static int cam_tfe_hw_mgr_handle_hw_rup(
CAM_ISP_HW_EVENT_REG_UPDATE, (void *)&rup_event_data); CAM_ISP_HW_EVENT_REG_UPDATE, (void *)&rup_event_data);
break; break;
case CAM_ISP_HW_TFE_IN_PDLIB:
break;
default: default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d", CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d",
event_info->res_id); event_info->res_id);
@@ -5969,6 +6055,7 @@ static int cam_tfe_hw_mgr_handle_hw_epoch(
case CAM_ISP_HW_TFE_IN_RDI0: case CAM_ISP_HW_TFE_IN_RDI0:
case CAM_ISP_HW_TFE_IN_RDI1: case CAM_ISP_HW_TFE_IN_RDI1:
case CAM_ISP_HW_TFE_IN_RDI2: case CAM_ISP_HW_TFE_IN_RDI2:
case CAM_ISP_HW_TFE_IN_PDLIB:
break; break;
default: default:
@@ -6021,6 +6108,8 @@ static int cam_tfe_hw_mgr_handle_hw_sof(
CAM_ISP_HW_EVENT_SOF, (void *)&sof_done_event_data); CAM_ISP_HW_EVENT_SOF, (void *)&sof_done_event_data);
break; break;
case CAM_ISP_HW_TFE_IN_PDLIB:
break;
default: default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d", CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d",
event_info->res_id); event_info->res_id);
@@ -6063,6 +6152,9 @@ static int cam_tfe_hw_mgr_handle_hw_eof(
CAM_ISP_HW_EVENT_EOF, (void *)&eof_done_event_data); CAM_ISP_HW_EVENT_EOF, (void *)&eof_done_event_data);
break; break;
case CAM_ISP_HW_TFE_IN_PDLIB:
break;
default: default:
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d", CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d",
event_info->res_id); event_info->res_id);
@@ -6305,11 +6397,13 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
struct cam_iommu_handle cdm_handles; struct cam_iommu_handle cdm_handles;
struct cam_tfe_hw_mgr_ctx *ctx_pool; struct cam_tfe_hw_mgr_ctx *ctx_pool;
struct cam_isp_hw_mgr_res *res_list_tfe_out; struct cam_isp_hw_mgr_res *res_list_tfe_out;
struct cam_isp_hw_path_port_map path_port_map;
bool support_consumed_addr = false; bool support_consumed_addr = false;
CAM_DBG(CAM_ISP, "Enter"); CAM_DBG(CAM_ISP, "Enter");
memset(&g_tfe_hw_mgr, 0, sizeof(g_tfe_hw_mgr)); memset(&g_tfe_hw_mgr, 0, sizeof(g_tfe_hw_mgr));
memset(&path_port_map, 0, sizeof(path_port_map));
mutex_init(&g_tfe_hw_mgr.ctx_mutex); mutex_init(&g_tfe_hw_mgr.ctx_mutex);
spin_lock_init(&g_tfe_hw_mgr.ctx_lock); spin_lock_init(&g_tfe_hw_mgr.ctx_lock);
@@ -6329,13 +6423,22 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
g_tfe_hw_mgr.tfe_devices[i]->hw_intf->hw_priv; g_tfe_hw_mgr.tfe_devices[i]->hw_intf->hw_priv;
struct cam_hw_soc_info *soc_info = &tfe_hw->soc_info; struct cam_hw_soc_info *soc_info = &tfe_hw->soc_info;
if (j == 0) if (j == 0) {
tfe_device->hw_ops.process_cmd( tfe_device->hw_ops.process_cmd(
tfe_hw, tfe_hw,
CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT, CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT,
&support_consumed_addr, &support_consumed_addr,
sizeof(support_consumed_addr)); sizeof(support_consumed_addr));
tfe_device->hw_ops.process_cmd(
tfe_hw,
CAM_ISP_HW_CMD_GET_PATH_PORT_MAP,
&path_port_map,
sizeof(struct cam_isp_hw_path_port_map));
CAM_DBG(CAM_ISP, "received %d path-port mappings",
path_port_map.num_entries);
}
j++; j++;
g_tfe_hw_mgr.cdm_reg_map[i] = &soc_info->reg_map[0]; g_tfe_hw_mgr.cdm_reg_map[i] = &soc_info->reg_map[0];
@@ -6353,6 +6456,13 @@ int cam_tfe_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
} }
g_tfe_hw_mgr.support_consumed_addr = support_consumed_addr; g_tfe_hw_mgr.support_consumed_addr = support_consumed_addr;
for (i = 0; i < path_port_map.num_entries; i++) {
g_tfe_hw_mgr.path_port_map.entry[i][0] = path_port_map.entry[i][0];
g_tfe_hw_mgr.path_port_map.entry[i][1] = path_port_map.entry[i][1];
}
g_tfe_hw_mgr.path_port_map.num_entries = path_port_map.num_entries;
/* fill csid hw intf information */ /* fill csid hw intf information */
for (i = 0, j = 0; i < CAM_TFE_CSID_HW_NUM_MAX; i++) { for (i = 0, j = 0; i < CAM_TFE_CSID_HW_NUM_MAX; i++) {
rc = cam_tfe_csid_hw_init(&g_tfe_hw_mgr.csid_devices[i], i); rc = cam_tfe_csid_hw_init(&g_tfe_hw_mgr.csid_devices[i], i);

View File

@@ -190,6 +190,7 @@ struct cam_tfe_hw_mgr_ctx {
* @tfe_dev_caps tfe device capability per core * @tfe_dev_caps tfe device capability per core
* @work q work queue for TFE hw manager * @work q work queue for TFE hw manager
* @debug_cfg debug configuration * @debug_cfg debug configuration
* @path_port_map Mapping of outport to TFE mux
* @support_consumed_addr indicate whether hw supports last consumed address * @support_consumed_addr indicate whether hw supports last consumed address
* @ctx_lock Spinlock for HW manager * @ctx_lock Spinlock for HW manager
*/ */
@@ -209,6 +210,7 @@ struct cam_tfe_hw_mgr {
struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX]; struct cam_tfe_hw_get_hw_cap tfe_dev_caps[CAM_TFE_HW_NUM_MAX];
struct cam_req_mgr_core_workq *workq; struct cam_req_mgr_core_workq *workq;
struct cam_tfe_hw_mgr_debug debug_cfg; struct cam_tfe_hw_mgr_debug debug_cfg;
struct cam_isp_hw_path_port_map path_port_map;
bool support_consumed_addr; bool support_consumed_addr;
spinlock_t ctx_lock; spinlock_t ctx_lock;
}; };

View File

@@ -23,6 +23,7 @@ enum cam_tfe_csid_path_res_id {
CAM_TFE_CSID_PATH_RES_RDI_1, CAM_TFE_CSID_PATH_RES_RDI_1,
CAM_TFE_CSID_PATH_RES_RDI_2, CAM_TFE_CSID_PATH_RES_RDI_2,
CAM_TFE_CSID_PATH_RES_IPP, CAM_TFE_CSID_PATH_RES_IPP,
CAM_TFE_CSID_PATH_RES_PPP,
CAM_TFE_CSID_PATH_RES_MAX, CAM_TFE_CSID_PATH_RES_MAX,
}; };
@@ -36,6 +37,7 @@ enum cam_tfe_csid_irq_reg {
TFE_CSID_IRQ_REG_TOP, TFE_CSID_IRQ_REG_TOP,
TFE_CSID_IRQ_REG_RX, TFE_CSID_IRQ_REG_RX,
TFE_CSID_IRQ_REG_IPP, TFE_CSID_IRQ_REG_IPP,
TFE_CSID_IRQ_REG_PPP,
TFE_CSID_IRQ_REG_MAX, TFE_CSID_IRQ_REG_MAX,
}; };
@@ -96,6 +98,7 @@ struct cam_isp_tfe_in_port_generic_info {
* struct cam_tfe_csid_hw_caps- get the CSID hw capability * struct cam_tfe_csid_hw_caps- get the CSID hw capability
* @num_rdis: number of rdis supported by CSID HW device * @num_rdis: number of rdis supported by CSID HW device
* @num_pix: number of pxl paths supported by CSID HW device * @num_pix: number of pxl paths supported by CSID HW device
* @num_ppp: number of ppp paths supported by CSID HW device
* @major_version : major version * @major_version : major version
* @minor_version: minor version * @minor_version: minor version
* @version_incr: version increment * @version_incr: version increment
@@ -106,6 +109,7 @@ struct cam_isp_tfe_in_port_generic_info {
struct cam_tfe_csid_hw_caps { struct cam_tfe_csid_hw_caps {
uint32_t num_rdis; uint32_t num_rdis;
uint32_t num_pix; uint32_t num_pix;
uint32_t num_ppp;
uint32_t major_version; uint32_t major_version;
uint32_t minor_version; uint32_t minor_version;
uint32_t version_incr; uint32_t version_incr;
@@ -128,6 +132,7 @@ struct cam_tfe_csid_hw_caps {
* @event_cb_prv: Context data * @event_cb_prv: Context data
* @event_cb: Callback function to hw mgr in case of hw events * @event_cb: Callback function to hw mgr in case of hw events
* @node_res : Reserved resource structure pointer * @node_res : Reserved resource structure pointer
* @crop_enable : Flag to indicate CSID crop enable
* *
*/ */
struct cam_tfe_csid_hw_reserve_resource_args { struct cam_tfe_csid_hw_reserve_resource_args {
@@ -141,6 +146,7 @@ struct cam_tfe_csid_hw_reserve_resource_args {
void *event_cb_prv; void *event_cb_prv;
cam_hw_mgr_event_cb_func event_cb; cam_hw_mgr_event_cb_func event_cb;
struct cam_isp_resource_node *node_res; struct cam_isp_resource_node *node_res;
bool crop_enable;
}; };
/** /**

View File

@@ -19,6 +19,7 @@ enum cam_isp_hw_tfe_in {
CAM_ISP_HW_TFE_IN_RDI0 = 1, CAM_ISP_HW_TFE_IN_RDI0 = 1,
CAM_ISP_HW_TFE_IN_RDI1 = 2, CAM_ISP_HW_TFE_IN_RDI1 = 2,
CAM_ISP_HW_TFE_IN_RDI2 = 3, CAM_ISP_HW_TFE_IN_RDI2 = 3,
CAM_ISP_HW_TFE_IN_PDLIB = 4,
CAM_ISP_HW_TFE_IN_MAX, CAM_ISP_HW_TFE_IN_MAX,
}; };
@@ -120,6 +121,7 @@ struct cam_tfe_hw_tfe_out_acquire_args {
* @in_port: Input port details to acquire * @in_port: Input port details to acquire
* @camif_pd_enable Camif pd enable or disable * @camif_pd_enable Camif pd enable or disable
* @dual_tfe_sync_sel_idx Dual tfe master hardware index * @dual_tfe_sync_sel_idx Dual tfe master hardware index
* @lcr_enable LCR enable field
*/ */
struct cam_tfe_hw_tfe_in_acquire_args { struct cam_tfe_hw_tfe_in_acquire_args {
struct cam_isp_resource_node *rsrc_node; struct cam_isp_resource_node *rsrc_node;
@@ -129,6 +131,7 @@ struct cam_tfe_hw_tfe_in_acquire_args {
enum cam_isp_hw_sync_mode sync_mode; enum cam_isp_hw_sync_mode sync_mode;
bool camif_pd_enable; bool camif_pd_enable;
uint32_t dual_tfe_sync_sel_idx; uint32_t dual_tfe_sync_sel_idx;
bool lcr_enable;
}; };
/* /*

View File

@@ -47,7 +47,7 @@
/* Max CSI Rx irq error count threshold value */ /* Max CSI Rx irq error count threshold value */
#define CAM_TFE_CSID_MAX_IRQ_ERROR_COUNT 5 #define CAM_TFE_CSID_MAX_IRQ_ERROR_COUNT 5
static int cam_tfe_csid_is_ipp_format_supported( static int cam_tfe_csid_is_ipp_ppp_format_supported(
uint32_t in_format) uint32_t in_format)
{ {
int rc = -EINVAL; int rc = -EINVAL;
@@ -170,7 +170,7 @@ static int cam_tfe_csid_get_format_rdi(
return rc; return rc;
} }
static int cam_tfe_csid_get_format_ipp( static int cam_tfe_csid_get_format_ipp_ppp(
uint32_t in_format, uint32_t in_format,
uint32_t *decode_fmt, uint32_t *plain_fmt) uint32_t *decode_fmt, uint32_t *plain_fmt)
{ {
@@ -341,6 +341,17 @@ static bool cam_tfe_csid_check_path_active(struct cam_tfe_csid_hw *csid_hw)
goto end; goto end;
} }
/* check the PPP path status */
if (csid_reg->cmn_reg->num_ppp) {
path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_status_addr);
CAM_DBG(CAM_ISP, "CSID:%d PPP path status:%d",
csid_hw->hw_intf->hw_idx, path_status);
/* if status is 0 then it is active */
if (!path_status)
goto end;
}
/* Check the RDI path status */ /* Check the RDI path status */
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base + path_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -461,6 +472,10 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_csid_hw *csid_hw)
cam_io_w_mb(0, soc_info->reg_map[0].mem_base + cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_irq_mask_addr); csid_reg->ipp_reg->csid_pxl_irq_mask_addr);
if (csid_reg->cmn_reg->num_ppp)
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_mask_addr);
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++)
cam_io_w_mb(0, soc_info->reg_map[0].mem_base + cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr); csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
@@ -478,6 +493,11 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_csid_hw *csid_hw)
soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_irq_clear_addr); csid_reg->ipp_reg->csid_pxl_irq_clear_addr);
if (csid_reg->cmn_reg->num_ppp)
cam_io_w_mb(csid_reg->cmn_reg->ppp_irq_mask_all,
soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_clear_addr);
for (i = 0 ; i < csid_reg->cmn_reg->num_rdis; i++) for (i = 0 ; i < csid_reg->cmn_reg->num_rdis; i++)
cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base +
@@ -541,6 +561,12 @@ static int cam_tfe_csid_global_reset(struct cam_tfe_csid_hw *csid_hw)
path_data->res_sof_cnt = 0; path_data->res_sof_cnt = 0;
} }
if (csid_reg->cmn_reg->num_ppp) {
path_data = (struct cam_tfe_csid_path_cfg *)
csid_hw->ppp_res.res_priv;
path_data->res_sof_cnt = 0;
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
path_data = (struct cam_tfe_csid_path_cfg *) path_data = (struct cam_tfe_csid_path_cfg *)
csid_hw->rdi_res[i].res_priv; csid_hw->rdi_res[i].res_priv;
@@ -599,6 +625,24 @@ static int cam_tfe_csid_path_reset(struct cam_tfe_csid_hw *csid_hw,
val |= TFE_CSID_PATH_INFO_RST_DONE; val |= TFE_CSID_PATH_INFO_RST_DONE;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_irq_mask_addr); csid_reg->ipp_reg->csid_pxl_irq_mask_addr);
} else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP) {
if (!csid_reg->ppp_reg) {
CAM_ERR(CAM_ISP, "CSID:%d PPP not supported :%d",
csid_hw->hw_intf->hw_idx,
res->res_id);
return -EINVAL;
}
reset_strb_addr = csid_reg->ppp_reg->csid_pxl_rst_strobes_addr;
complete = &csid_hw->csid_ppp_complete;
reset_strb_val = csid_reg->cmn_reg->ppp_path_rst_stb_all;
/* Enable path reset done interrupt */
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_mask_addr);
val |= TFE_CSID_PATH_INFO_RST_DONE;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_mask_addr);
} else { } else {
id = res->res_id; id = res->res_id;
if (!csid_reg->rdi_reg[id]) { if (!csid_reg->rdi_reg[id]) {
@@ -820,7 +864,7 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
goto end; goto end;
} }
if (cam_tfe_csid_is_ipp_format_supported( if (cam_tfe_csid_is_ipp_ppp_format_supported(
reserve->in_port->format)) { reserve->in_port->format)) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d res id:%d un support format %d", "CSID:%d res id:%d un support format %d",
@@ -841,6 +885,43 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
break; break;
case CAM_TFE_CSID_PATH_RES_PPP:
if (csid_hw->ppp_res.res_state !=
CAM_ISP_RESOURCE_STATE_AVAILABLE) {
CAM_DBG(CAM_ISP,
"CSID:%d PPP resource not available %d",
csid_hw->hw_intf->hw_idx,
csid_hw->ppp_res.res_state);
rc = -EINVAL;
goto end;
}
if (cam_tfe_csid_is_ipp_ppp_format_supported(
reserve->in_port->format)) {
CAM_ERR(CAM_ISP,
"CSID:%d res id:%d un support format %d",
csid_hw->hw_intf->hw_idx, reserve->res_id,
reserve->in_port->format);
rc = -EINVAL;
goto end;
}
rc = cam_tfe_csid_cid_reserve(csid_hw, reserve, &cid_value);
if (rc) {
CAM_ERR(CAM_ISP,
"CSID:%d res id:%d invalid cid %d",
csid_hw->hw_intf->hw_idx, reserve->res_id, cid_value);
goto end;
}
/* assign the PPP resource */
res = &csid_hw->ppp_res;
CAM_DBG(CAM_ISP,
"CSID:%d PPP resource:%d acquired successfully",
csid_hw->hw_intf->hw_idx, res->res_id);
break;
case CAM_TFE_CSID_PATH_RES_RDI_0: case CAM_TFE_CSID_PATH_RES_RDI_0:
case CAM_TFE_CSID_PATH_RES_RDI_1: case CAM_TFE_CSID_PATH_RES_RDI_1:
case CAM_TFE_CSID_PATH_RES_RDI_2: case CAM_TFE_CSID_PATH_RES_RDI_2:
@@ -899,6 +980,7 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
path_data->bayer_bin = reserve->in_port->bayer_bin; path_data->bayer_bin = reserve->in_port->bayer_bin;
path_data->qcfa_bin = reserve->in_port->qcfa_bin; path_data->qcfa_bin = reserve->in_port->qcfa_bin;
path_data->crop_enable = reserve->crop_enable;
csid_hw->event_cb = reserve->event_cb; csid_hw->event_cb = reserve->event_cb;
csid_hw->event_cb_priv = reserve->event_cb_prv; csid_hw->event_cb_priv = reserve->event_cb_prv;
@@ -912,10 +994,6 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
} }
} }
/* Enable crop only for ipp */
if (reserve->res_id == CAM_TFE_CSID_PATH_RES_IPP)
path_data->crop_enable = true;
CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP,
"Res id: %d height:%d line_start %d line_end %d crop_en %d", "Res id: %d height:%d line_start %d line_end %d crop_en %d",
reserve->res_id, reserve->in_port->height, reserve->res_id, reserve->in_port->height,
@@ -1177,6 +1255,11 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw *csid_hw)
soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_irq_clear_addr); csid_reg->ipp_reg->csid_pxl_irq_clear_addr);
if (csid_reg->cmn_reg->num_ppp)
cam_io_w_mb(csid_reg->cmn_reg->ipp_irq_mask_all,
soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_clear_addr);
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++)
cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all,
soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base +
@@ -1207,6 +1290,12 @@ static int cam_tfe_csid_enable_hw(struct cam_tfe_csid_hw *csid_hw)
path_data->res_sof_cnt = 0; path_data->res_sof_cnt = 0;
} }
if (csid_reg->cmn_reg->num_ppp) {
path_data = (struct cam_tfe_csid_path_cfg *)
csid_hw->ppp_res.res_priv;
path_data->res_sof_cnt = 0;
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
path_data = (struct cam_tfe_csid_path_cfg *) path_data = (struct cam_tfe_csid_path_cfg *)
csid_hw->rdi_res[i].res_priv; csid_hw->rdi_res[i].res_priv;
@@ -1294,15 +1383,22 @@ static int cam_tfe_csid_init_config_pxl_path(
csid_reg = csid_hw->csid_info->csid_reg; csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info; soc_info = &csid_hw->hw_info->soc_info;
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP)
pxl_reg = csid_reg->ipp_reg; pxl_reg = csid_reg->ipp_reg;
else
pxl_reg = csid_reg->ppp_reg;
if (!pxl_reg) { if (!pxl_reg) {
CAM_ERR(CAM_ISP, "CSID:%d IPP :%d is not supported on HW", CAM_ERR(CAM_ISP, "CSID:%d %s :%d is not supported on HW",
csid_hw->hw_intf->hw_idx, res->res_id); csid_hw->hw_intf->hw_idx,
(res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP",
res->res_id);
return -EINVAL; return -EINVAL;
} }
CAM_DBG(CAM_ISP, "Config IPP Path"); CAM_DBG(CAM_ISP, "Config %s Path",
rc = cam_tfe_csid_get_format_ipp(path_data->in_format, (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP");
rc = cam_tfe_csid_get_format_ipp_ppp(path_data->in_format,
&decode_format, &plain_format); &decode_format, &plain_format);
if (rc) if (rc)
return rc; return rc;
@@ -1481,18 +1577,25 @@ static int cam_tfe_csid_deinit_pxl_path(
csid_reg = csid_hw->csid_info->csid_reg; csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info; soc_info = &csid_hw->hw_info->soc_info;
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP)
pxl_reg = csid_reg->ipp_reg; pxl_reg = csid_reg->ipp_reg;
else
pxl_reg = csid_reg->ppp_reg;
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID:%d IPP Res type %d res_id:%d in wrong state %d", "CSID:%d %s Res type %d res_id:%d in wrong state %d",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx,
(res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP",
res->res_type, res->res_id, res->res_state); res->res_type, res->res_id, res->res_state);
rc = -EINVAL; rc = -EINVAL;
} }
if (!pxl_reg) { if (!pxl_reg) {
CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW", CAM_ERR(CAM_ISP, "CSID:%d %s %d is not supported on HW",
csid_hw->hw_intf->hw_idx, res->res_id); csid_hw->hw_intf->hw_idx,
(res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP",
res->res_id);
rc = -EINVAL; rc = -EINVAL;
goto end; goto end;
} }
@@ -1666,6 +1769,7 @@ static int cam_tfe_csid_disable_pxl_path(
} }
pxl_reg = csid_reg->ipp_reg; pxl_reg = csid_reg->ipp_reg;
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) { if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_DBG(CAM_ISP, "CSID:%d IPP path Res:%d Invalid state%d", CAM_DBG(CAM_ISP, "CSID:%d IPP path Res:%d Invalid state%d",
csid_hw->hw_intf->hw_idx, res->res_id, res->res_state); csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
@@ -1718,6 +1822,164 @@ static int cam_tfe_csid_disable_pxl_path(
return rc; return rc;
} }
static int cam_tfe_csid_enable_ppp_path(
struct cam_tfe_csid_hw *csid_hw,
struct cam_isp_resource_node *res)
{
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
struct cam_tfe_csid_path_cfg *path_data;
const struct cam_tfe_csid_pxl_reg_offset *ppp_reg = NULL;
uint32_t val = 0;
path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
ppp_reg = csid_reg->ppp_reg;
if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) {
CAM_ERR(CAM_ISP,
"CSID:%d PPP path res type:%d res_id:%d Invalid state%d",
csid_hw->hw_intf->hw_idx,
res->res_type, res->res_id, res->res_state);
return -EINVAL;
}
if (!ppp_reg) {
CAM_ERR(CAM_ISP, "CSID:%d PPP resid: %d not supported on HW",
csid_hw->hw_intf->hw_idx, res->res_id);
return -EINVAL;
}
CAM_DBG(CAM_ISP, "CSID:%d Enable PPP path", csid_hw->hw_intf->hw_idx);
/* Set master or slave path */
if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER)
/* Set halt mode as master */
val = (TFE_CSID_HALT_MODE_SLAVE << ppp_reg->halt_mode_shift) |
(ppp_reg->halt_master_sel_master_val <<
ppp_reg->halt_master_sel_shift);
else if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)
/* Set halt mode as slave and set master idx */
val = (TFE_CSID_HALT_MODE_SLAVE << ppp_reg->halt_mode_shift) |
(ppp_reg->halt_master_sel_slave_val <<
ppp_reg->halt_master_sel_shift);
else
/* Default is internal halt mode */
val = 0;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + ppp_reg->csid_pxl_ctrl_addr);
CAM_DBG(CAM_ISP, "CSID:%d PPP Ctrl val: 0x%x", csid_hw->hw_intf->hw_idx, val);
/* Enable the required ppp path interrupts */
val = TFE_CSID_PATH_INFO_RST_DONE | TFE_CSID_PATH_ERROR_FIFO_OVERFLOW |
TFE_CSID_PATH_PPP_ERROR_CCIF_VIOLATION | TFE_CSID_PATH_PPP_OVERFLOW_IRQ;
if (csid_reg->cmn_reg->format_measure_support)
val |= TFE_CSID_PATH_ERROR_PIX_COUNT | TFE_CSID_PATH_ERROR_LINE_COUNT;
if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)
val |= TFE_CSID_PATH_INFO_INPUT_SOF;
if (csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)
val |= TFE_CSID_PATH_INFO_INPUT_EOF;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base + ppp_reg->csid_pxl_irq_mask_addr);
CAM_DBG(CAM_ISP, "CSID:%d Enable PPP IRQ mask 0x%x", csid_hw->hw_intf->hw_idx, val);
res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
return 0;
}
static int cam_tfe_csid_disable_ppp_path(
struct cam_tfe_csid_hw *csid_hw,
struct cam_isp_resource_node *res,
enum cam_tfe_csid_halt_cmd stop_cmd)
{
int rc = 0;
uint32_t val = 0;
const struct cam_tfe_csid_reg_offset *csid_reg;
struct cam_hw_soc_info *soc_info;
struct cam_tfe_csid_path_cfg *path_data;
const struct cam_tfe_csid_pxl_reg_offset *ppp_reg;
path_data = (struct cam_tfe_csid_path_cfg *) res->res_priv;
csid_reg = csid_hw->csid_info->csid_reg;
soc_info = &csid_hw->hw_info->soc_info;
if (res->res_id >= CAM_TFE_CSID_PATH_RES_MAX) {
CAM_DBG(CAM_ISP, "CSID:%d Invalid res id%d",
csid_hw->hw_intf->hw_idx, res->res_id);
return -EINVAL;
}
if (res->res_state == CAM_ISP_RESOURCE_STATE_INIT_HW ||
res->res_state == CAM_ISP_RESOURCE_STATE_RESERVED) {
CAM_DBG(CAM_ISP, "CSID:%d Res:%d already in stopped state:%d",
csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
return rc;
}
ppp_reg = csid_reg->ppp_reg;
if (res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING) {
CAM_DBG(CAM_ISP, "CSID:%d IPP path Res:%d Invalid state%d",
csid_hw->hw_intf->hw_idx, res->res_id, res->res_state);
return -EINVAL;
}
if (!ppp_reg) {
CAM_ERR(CAM_ISP, "CSID:%d PPP %d is not supported on HW",
csid_hw->hw_intf->hw_idx, res->res_id);
return -EINVAL;
}
if (stop_cmd != CAM_TFE_CSID_HALT_AT_FRAME_BOUNDARY &&
stop_cmd != CAM_TFE_CSID_HALT_IMMEDIATELY) {
CAM_ERR(CAM_ISP,
"CSID:%d PPP path un supported stop command:%d",
csid_hw->hw_intf->hw_idx, stop_cmd);
return -EINVAL;
}
CAM_DBG(CAM_ISP, "CSID:%d res_id:%d PPP path",
csid_hw->hw_intf->hw_idx, res->res_id);
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
ppp_reg->csid_pxl_irq_mask_addr);
if (path_data->sync_mode == CAM_ISP_HW_SYNC_MASTER ||
path_data->sync_mode == CAM_ISP_HW_SYNC_NONE) {
/* configure Halt */
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
ppp_reg->csid_pxl_ctrl_addr);
val &= ~0x3F;
val |= (TFE_CSID_HALT_MODE_SLAVE << ppp_reg->halt_mode_shift);
val |= (ppp_reg->halt_master_sel_master_val <<
ppp_reg->halt_master_sel_shift);
val |= stop_cmd;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
ppp_reg->csid_pxl_ctrl_addr);
}
if (path_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE &&
stop_cmd == CAM_TFE_CSID_HALT_IMMEDIATELY) {
/* configure Halt for slave */
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
ppp_reg->csid_pxl_ctrl_addr);
val &= ~0x3F;
val |= (TFE_CSID_HALT_MODE_SLAVE << ppp_reg->halt_mode_shift);
val |= (ppp_reg->halt_master_sel_slave_val <<
ppp_reg->halt_master_sel_shift);
val |= stop_cmd;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
ppp_reg->csid_pxl_ctrl_addr);
}
return rc;
}
static int cam_tfe_csid_init_config_rdi_path( static int cam_tfe_csid_init_config_rdi_path(
struct cam_tfe_csid_hw *csid_hw, struct cam_tfe_csid_hw *csid_hw,
struct cam_isp_resource_node *res) struct cam_isp_resource_node *res)
@@ -2032,6 +2294,14 @@ static int cam_tfe_csid_poll_stop_status(
CAM_ISP_RESOURCE_STATE_STREAMING) CAM_ISP_RESOURCE_STATE_STREAMING)
continue; continue;
} else if (res_id == CAM_TFE_CSID_PATH_RES_PPP) {
csid_status_addr =
csid_reg->ppp_reg->csid_pxl_status_addr;
if (csid_hw->ppp_res.res_state !=
CAM_ISP_RESOURCE_STATE_STREAMING)
continue;
} else { } else {
csid_status_addr = csid_status_addr =
csid_reg->rdi_reg[res_id]->csid_rdi_status_addr; csid_reg->rdi_reg[res_id]->csid_rdi_status_addr;
@@ -2129,6 +2399,19 @@ static int cam_tfe_csid_get_time_stamp(
csid_reg->ipp_reg->csid_pxl_timestamp_perv0_sof_addr, csid_reg->ipp_reg->csid_pxl_timestamp_perv0_sof_addr,
&time_stamp->prev_time_stamp_val); &time_stamp->prev_time_stamp_val);
} }
} else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP) {
torn = __cam_tfe_csid_read_timestamp(
soc_info->reg_map[0].mem_base,
csid_reg->ppp_reg->csid_pxl_timestamp_curr1_sof_addr,
csid_reg->ppp_reg->csid_pxl_timestamp_curr0_sof_addr,
&time_stamp->time_stamp_val);
if (time_stamp->get_prev_timestamp) {
prev_torn = __cam_tfe_csid_read_timestamp(
soc_info->reg_map[0].mem_base,
csid_reg->ppp_reg->csid_pxl_timestamp_perv1_sof_addr,
csid_reg->ppp_reg->csid_pxl_timestamp_perv0_sof_addr,
&time_stamp->prev_time_stamp_val);
}
} else { } else {
id = res->res_id; id = res->res_id;
rdi_reg = csid_reg->rdi_reg[id]; rdi_reg = csid_reg->rdi_reg[id];
@@ -2229,6 +2512,11 @@ static int cam_tfe_csid_print_hbi_vbi(
csid_reg->ipp_reg->csid_pxl_format_measure1_addr); csid_reg->ipp_reg->csid_pxl_format_measure1_addr);
vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_format_measure2_addr); csid_reg->ipp_reg->csid_pxl_format_measure2_addr);
} else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP) {
hbi = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_format_measure1_addr);
vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_format_measure2_addr);
} else if ((res->res_id >= CAM_TFE_CSID_PATH_RES_RDI_0) && } else if ((res->res_id >= CAM_TFE_CSID_PATH_RES_RDI_0) &&
(res->res_id <= CAM_TFE_CSID_PATH_RES_RDI_2)) { (res->res_id <= CAM_TFE_CSID_PATH_RES_RDI_2)) {
rdi_reg = csid_reg->rdi_reg[res->res_id]; rdi_reg = csid_reg->rdi_reg[res->res_id];
@@ -2286,6 +2574,7 @@ static int cam_tfe_csid_get_hw_caps(void *hw_priv,
hw_caps->num_rdis = csid_reg->cmn_reg->num_rdis; hw_caps->num_rdis = csid_reg->cmn_reg->num_rdis;
hw_caps->num_pix = csid_hw->pxl_pipe_enable; hw_caps->num_pix = csid_hw->pxl_pipe_enable;
hw_caps->num_ppp = csid_reg->cmn_reg->num_ppp;
hw_caps->major_version = csid_reg->cmn_reg->major_version; hw_caps->major_version = csid_reg->cmn_reg->major_version;
hw_caps->minor_version = csid_reg->cmn_reg->minor_version; hw_caps->minor_version = csid_reg->cmn_reg->minor_version;
hw_caps->version_incr = csid_reg->cmn_reg->version_incr; hw_caps->version_incr = csid_reg->cmn_reg->version_incr;
@@ -2551,7 +2840,8 @@ static int cam_tfe_csid_init_hw(void *hw_priv,
if (rc) if (rc)
goto end; goto end;
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) if ((res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ||
(res->res_id == CAM_TFE_CSID_PATH_RES_PPP))
rc = cam_tfe_csid_init_config_pxl_path(csid_hw, res); rc = cam_tfe_csid_init_config_pxl_path(csid_hw, res);
else else
rc = cam_tfe_csid_init_config_rdi_path(csid_hw, res); rc = cam_tfe_csid_init_config_rdi_path(csid_hw, res);
@@ -2607,7 +2897,8 @@ static int cam_tfe_csid_deinit_hw(void *hw_priv,
CAM_DBG(CAM_ISP, "De-Init IPP Path: %d", res->res_id); CAM_DBG(CAM_ISP, "De-Init IPP Path: %d", res->res_id);
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) if ((res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ||
(res->res_id == CAM_TFE_CSID_PATH_RES_PPP))
rc = cam_tfe_csid_deinit_pxl_path(csid_hw, res); rc = cam_tfe_csid_deinit_pxl_path(csid_hw, res);
else else
rc = cam_tfe_csid_deinit_rdi_path(csid_hw, res); rc = cam_tfe_csid_deinit_rdi_path(csid_hw, res);
@@ -2662,6 +2953,8 @@ static int cam_tfe_csid_start(void *hw_priv, void *start_args,
case CAM_ISP_RESOURCE_PIX_PATH: case CAM_ISP_RESOURCE_PIX_PATH:
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP)
rc = cam_tfe_csid_enable_pxl_path(csid_hw, res); rc = cam_tfe_csid_enable_pxl_path(csid_hw, res);
else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP)
rc = cam_tfe_csid_enable_ppp_path(csid_hw, res);
else else
rc = cam_tfe_csid_enable_rdi_path(csid_hw, res); rc = cam_tfe_csid_enable_rdi_path(csid_hw, res);
break; break;
@@ -2756,6 +3049,9 @@ static int cam_tfe_csid_stop(void *hw_priv,
if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP)
rc = cam_tfe_csid_disable_pxl_path(csid_hw, rc = cam_tfe_csid_disable_pxl_path(csid_hw,
res, csid_stop->stop_cmd); res, csid_stop->stop_cmd);
else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP)
rc = cam_tfe_csid_disable_ppp_path(csid_hw,
res, csid_stop->stop_cmd);
else else
rc = cam_tfe_csid_disable_rdi_path(csid_hw, rc = cam_tfe_csid_disable_rdi_path(csid_hw,
res, csid_stop->stop_cmd); res, csid_stop->stop_cmd);
@@ -2835,6 +3131,22 @@ static int cam_tfe_csid_sof_irq_debug(
} }
} }
if (csid_reg->ppp_reg) {
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_mask_addr);
if (val) {
if (sof_irq_enable)
val |= TFE_CSID_PATH_INFO_INPUT_SOF;
else
val &= ~TFE_CSID_PATH_INFO_INPUT_SOF;
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_mask_addr);
val = 0;
}
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
val = cam_io_r_mb(soc_info->reg_map[0].mem_base + val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr); csid_reg->rdi_reg[i]->csid_rdi_irq_mask_addr);
@@ -2984,6 +3296,29 @@ static int cam_tfe_csid_get_regdump(struct cam_tfe_csid_hw *csid_hw,
csid_reg->ipp_reg->csid_pxl_vcrop_addr); csid_reg->ipp_reg->csid_pxl_vcrop_addr);
CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x", CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x",
csid_reg->ipp_reg->csid_pxl_vcrop_addr, val); csid_reg->ipp_reg->csid_pxl_vcrop_addr, val);
} else if (res->res_id == CAM_TFE_CSID_PATH_RES_PPP) {
CAM_INFO(CAM_ISP, "Dumping CSID:%d PPP registers ",
csid_hw->hw_intf->hw_idx);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_cfg0_addr);
CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x",
csid_reg->ppp_reg->csid_pxl_cfg0_addr, val);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_cfg1_addr);
CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x",
csid_reg->ppp_reg->csid_pxl_cfg1_addr, val);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_ctrl_addr);
CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x",
csid_reg->ppp_reg->csid_pxl_ctrl_addr, val);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_hcrop_addr);
CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x",
csid_reg->ppp_reg->csid_pxl_hcrop_addr, val);
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_vcrop_addr);
CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x",
csid_reg->ppp_reg->csid_pxl_vcrop_addr, val);
} else { } else {
id = res->res_id; id = res->res_id;
CAM_INFO(CAM_ISP, "Dumping CSID:%d RDI:%d registers ", CAM_INFO(CAM_ISP, "Dumping CSID:%d RDI:%d registers ",
@@ -3321,6 +3656,13 @@ static int cam_tfe_csid_evt_bottom_half_handler(
csid_hw->hw_intf->hw_idx); csid_hw->hw_intf->hw_idx);
} }
if (evt_payload->irq_status[TFE_CSID_IRQ_REG_PPP] &
TFE_CSID_PATH_INFO_INPUT_SOF) {
CAM_INFO_RATE_LIMIT(CAM_ISP,
"CSID:%d PPP SOF received",
csid_hw->hw_intf->hw_idx);
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
if (evt_payload->irq_status[i] & if (evt_payload->irq_status[i] &
TFE_CSID_PATH_INFO_INPUT_SOF) TFE_CSID_PATH_INFO_INPUT_SOF)
@@ -3330,13 +3672,14 @@ static int cam_tfe_csid_evt_bottom_half_handler(
} }
} else { } else {
CAM_ERR_RATE_LIMIT(CAM_ISP, CAM_ERR_RATE_LIMIT(CAM_ISP,
"CSID %d err %d phy %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x", "CSID %d err %d phy %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x PPP: 0x%x RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx,
evt_payload->evt_type, evt_payload->evt_type,
csid_hw->csi2_rx_cfg.phy_sel, csid_hw->csi2_rx_cfg.phy_sel,
evt_payload->irq_status[TFE_CSID_IRQ_REG_TOP], evt_payload->irq_status[TFE_CSID_IRQ_REG_TOP],
evt_payload->irq_status[TFE_CSID_IRQ_REG_RX], evt_payload->irq_status[TFE_CSID_IRQ_REG_RX],
evt_payload->irq_status[TFE_CSID_IRQ_REG_IPP], evt_payload->irq_status[TFE_CSID_IRQ_REG_IPP],
evt_payload->irq_status[TFE_CSID_IRQ_REG_PPP],
evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI0], evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI0],
evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI1], evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI1],
evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI2]); evt_payload->irq_status[TFE_CSID_IRQ_REG_RDI2]);
@@ -3421,10 +3764,11 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
struct cam_hw_soc_info *soc_info; struct cam_hw_soc_info *soc_info;
const struct cam_tfe_csid_reg_offset *csid_reg; const struct cam_tfe_csid_reg_offset *csid_reg;
const struct cam_tfe_csid_pxl_reg_offset *ipp_reg; const struct cam_tfe_csid_pxl_reg_offset *ipp_reg;
const struct cam_tfe_csid_pxl_reg_offset *ppp_reg;
const struct cam_tfe_csid_rdi_reg_offset *rdi_reg; const struct cam_tfe_csid_rdi_reg_offset *rdi_reg;
const struct cam_tfe_csid_common_reg_offset *cmn_reg; const struct cam_tfe_csid_common_reg_offset *cmn_reg;
const struct cam_tfe_csid_csi2_rx_reg_offset *csi2_reg; const struct cam_tfe_csid_csi2_rx_reg_offset *csi2_reg;
uint32_t irq_status[TFE_CSID_IRQ_REG_MAX]; uint32_t irq_status[TFE_CSID_IRQ_REG_MAX] = {0};
bool fatal_err_detected = false, is_error_irq = false; bool fatal_err_detected = false, is_error_irq = false;
uint32_t sof_irq_debug_en = 0, log_en = 0; uint32_t sof_irq_debug_en = 0, log_en = 0;
unsigned long flags; unsigned long flags;
@@ -3458,6 +3802,11 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
cam_io_r_mb(soc_info->reg_map[0].mem_base + cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_irq_status_addr); csid_reg->ipp_reg->csid_pxl_irq_status_addr);
if (csid_reg->cmn_reg->num_ppp)
irq_status[TFE_CSID_IRQ_REG_PPP] =
cam_io_r_mb(soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_status_addr);
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++)
irq_status[i] = irq_status[i] =
cam_io_r_mb(soc_info->reg_map[0].mem_base + cam_io_r_mb(soc_info->reg_map[0].mem_base +
@@ -3477,6 +3826,11 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base +
csid_reg->ipp_reg->csid_pxl_irq_clear_addr); csid_reg->ipp_reg->csid_pxl_irq_clear_addr);
if (csid_reg->cmn_reg->num_ppp)
cam_io_w_mb(irq_status[TFE_CSID_IRQ_REG_PPP],
soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_irq_clear_addr);
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
cam_io_w_mb(irq_status[i], cam_io_w_mb(irq_status[i],
soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base +
@@ -3700,6 +4054,11 @@ handle_fatal_error:
CAM_INFO_RATE_LIMIT(CAM_ISP, CAM_INFO_RATE_LIMIT(CAM_ISP,
"CSID IPP reset complete"); "CSID IPP reset complete");
if (irq_status[TFE_CSID_IRQ_REG_PPP] &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val))
CAM_INFO_RATE_LIMIT(CAM_ISP,
"CSID PPP reset complete");
if (irq_status[TFE_CSID_IRQ_REG_TOP]) if (irq_status[TFE_CSID_IRQ_REG_TOP])
CAM_INFO_RATE_LIMIT(CAM_ISP, CAM_INFO_RATE_LIMIT(CAM_ISP,
"CSID TOP reset complete"); "CSID TOP reset complete");
@@ -3781,6 +4140,77 @@ handle_fatal_error:
} }
/* read the PPP errors */
if (csid_reg->cmn_reg->num_ppp) {
/* PPP reset done bit */
if (irq_status[TFE_CSID_IRQ_REG_PPP] &
BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
CAM_DBG(CAM_ISP, "CSID PPP reset complete");
complete(&csid_hw->csid_ppp_complete);
}
if ((irq_status[TFE_CSID_IRQ_REG_PPP] &
TFE_CSID_PATH_INFO_INPUT_SOF) &&
(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_SOF_IRQ)) {
if (!csid_hw->sof_irq_triggered)
CAM_INFO_RATE_LIMIT(CAM_ISP,
"CSID:%d PPP SOF received",
csid_hw->hw_intf->hw_idx);
else
log_en = 1;
if (csid_hw->sof_irq_triggered)
csid_hw->irq_debug_cnt++;
}
if ((irq_status[TFE_CSID_IRQ_REG_PPP] &
TFE_CSID_PATH_INFO_INPUT_EOF) &&
(csid_hw->csid_debug & TFE_CSID_DEBUG_ENABLE_EOF_IRQ)) {
CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received",
csid_hw->hw_intf->hw_idx);
}
if (irq_status[TFE_CSID_IRQ_REG_PPP] &
TFE_CSID_PATH_ERROR_FIFO_OVERFLOW) {
/* Stop PPP path immediately */
cam_io_w_mb(CAM_TFE_CSID_HALT_IMMEDIATELY,
soc_info->reg_map[0].mem_base +
csid_reg->ppp_reg->csid_pxl_ctrl_addr);
is_error_irq = true;
}
if (irq_status[TFE_CSID_IRQ_REG_PPP] &
TFE_CSID_PATH_PPP_ERROR_CCIF_VIOLATION)
is_error_irq = true;
if ((irq_status[TFE_CSID_IRQ_REG_PPP] &
TFE_CSID_PATH_ERROR_PIX_COUNT) ||
(irq_status[TFE_CSID_IRQ_REG_PPP] &
TFE_CSID_PATH_ERROR_LINE_COUNT)) {
ppp_reg = csid_reg->ppp_reg;
cmn_reg = csid_reg->cmn_reg;
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
ppp_reg->csid_pxl_format_measure0_addr);
val1 = cam_io_r_mb(soc_info->reg_map[0].mem_base +
ppp_reg->csid_pxl_format_measure_cfg1_addr);
CAM_ERR(CAM_ISP,
"Pix/Line count error for CSID: %d PPP path, Expected:: height: %d, width: %d and Actual:: height: %d width %d",
csid_hw->hw_intf->hw_idx,
((val1 >>
cmn_reg->format_measure_height_shift_val) &
cmn_reg->format_measure_height_mask_val),
val1 &
cmn_reg->format_measure_width_mask_val,
((val >>
cmn_reg->format_measure_height_shift_val) &
cmn_reg->format_measure_height_mask_val),
val &
cmn_reg->format_measure_width_mask_val);
}
}
for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
if ((irq_status[i] & if ((irq_status[i] &
@@ -3860,13 +4290,14 @@ handle_fatal_error:
} }
if (is_error_irq || log_en) { if (is_error_irq || log_en) {
CAM_ERR_RATE_LIMIT(CAM_ISP, CAM_ERR(CAM_ISP,
"CSID %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x", "CSID %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x PPP: 0x%x",
csid_hw->hw_intf->hw_idx, csid_hw->hw_intf->hw_idx,
irq_status[TFE_CSID_IRQ_REG_TOP], irq_status[TFE_CSID_IRQ_REG_TOP],
irq_status[TFE_CSID_IRQ_REG_RX], irq_status[TFE_CSID_IRQ_REG_RX],
irq_status[TFE_CSID_IRQ_REG_IPP]); irq_status[TFE_CSID_IRQ_REG_IPP],
CAM_ERR_RATE_LIMIT(CAM_ISP, irq_status[TFE_CSID_IRQ_REG_PPP]);
CAM_ERR(CAM_ISP,
"RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x CSID clk:%d", "RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x CSID clk:%d",
irq_status[TFE_CSID_IRQ_REG_RDI0], irq_status[TFE_CSID_IRQ_REG_RDI0],
irq_status[TFE_CSID_IRQ_REG_RDI1], irq_status[TFE_CSID_IRQ_REG_RDI1],
@@ -3922,6 +4353,7 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
init_completion(&tfe_csid_hw->csid_top_complete); init_completion(&tfe_csid_hw->csid_top_complete);
init_completion(&tfe_csid_hw->csid_csi2_complete); init_completion(&tfe_csid_hw->csid_csi2_complete);
init_completion(&tfe_csid_hw->csid_ipp_complete); init_completion(&tfe_csid_hw->csid_ipp_complete);
init_completion(&tfe_csid_hw->csid_ppp_complete);
for (i = 0; i < CAM_TFE_CSID_RDI_MAX; i++) for (i = 0; i < CAM_TFE_CSID_RDI_MAX; i++)
init_completion(&tfe_csid_hw->csid_rdin_complete[i]); init_completion(&tfe_csid_hw->csid_rdin_complete[i]);
@@ -4010,6 +4442,24 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
tfe_csid_hw->pxl_pipe_enable = 1; tfe_csid_hw->pxl_pipe_enable = 1;
} }
/* Initialize the PPP resources */
if (tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_ppp) {
CAM_DBG(CAM_ISP, "initializing the ppp path");
tfe_csid_hw->ppp_res.res_type = CAM_ISP_RESOURCE_PIX_PATH;
tfe_csid_hw->ppp_res.res_id = CAM_TFE_CSID_PATH_RES_PPP;
tfe_csid_hw->ppp_res.res_state =
CAM_ISP_RESOURCE_STATE_AVAILABLE;
tfe_csid_hw->ppp_res.hw_intf = tfe_csid_hw->hw_intf;
path_data = kzalloc(sizeof(*path_data),
GFP_KERNEL);
if (!path_data) {
rc = -ENOMEM;
goto err;
}
tfe_csid_hw->ppp_res.res_priv = path_data;
}
/* Initialize the RDI resource */ /* Initialize the RDI resource */
for (i = 0; i < tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; for (i = 0; i < tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis;
i++) { i++) {
@@ -4077,6 +4527,8 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
err: err:
if (rc) { if (rc) {
kfree(tfe_csid_hw->ipp_res.res_priv); kfree(tfe_csid_hw->ipp_res.res_priv);
if (tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_ppp)
kfree(tfe_csid_hw->ppp_res.res_priv);
for (i = 0; i < for (i = 0; i <
tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis;
i++) i++)
@@ -4100,6 +4552,9 @@ int cam_tfe_csid_hw_deinit(struct cam_tfe_csid_hw *tfe_csid_hw)
/* release the privdate data memory from resources */ /* release the privdate data memory from resources */
kfree(tfe_csid_hw->ipp_res.res_priv); kfree(tfe_csid_hw->ipp_res.res_priv);
if (tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_ppp)
kfree(tfe_csid_hw->ppp_res.res_priv);
for (i = 0; i < for (i = 0; i <
tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis;
i++) { i++) {

View File

@@ -58,9 +58,12 @@
#define TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION BIT(15) #define TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION BIT(15)
#define TFE_CSID_PATH_IPP_FRAME_DROP BIT(16) #define TFE_CSID_PATH_IPP_FRAME_DROP BIT(16)
#define TFE_CSID_PATH_IPP_OVERFLOW_IRQ BIT(17) #define TFE_CSID_PATH_IPP_OVERFLOW_IRQ BIT(17)
#define TFE_CSID_PATH_PPP_ERROR_CCIF_VIOLATION BIT(15)
#define TFE_CSID_PATH_PPP_FRAME_DROP BIT(16)
#define TFE_CSID_PATH_PPP_OVERFLOW_IRQ BIT(17)
#define TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION BIT(15)
#define TFE_CSID_PATH_RDI_FRAME_DROP BIT(16) #define TFE_CSID_PATH_RDI_FRAME_DROP BIT(16)
#define TFE_CSID_PATH_RDI_OVERFLOW_IRQ BIT(17) #define TFE_CSID_PATH_RDI_OVERFLOW_IRQ BIT(17)
#define TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION BIT(18)
/* /*
* Debug values enable the corresponding interrupts and debug logs provide * Debug values enable the corresponding interrupts and debug logs provide
@@ -95,6 +98,14 @@ enum cam_tfe_csid_path_halt_mode {
TFE_CSID_HALT_MODE_SLAVE, TFE_CSID_HALT_MODE_SLAVE,
}; };
/* enum cam_csid_path_halt_master select the path halt master control */
enum cam_tfe_csid_path_halt_master_sel {
TFE_CSID_HALT_CMD_SOURCE_EXTERNAL,
TFE_CSID_HALT_CMD_SOURCE_NONE,
TFE_CSID_HALT_CMD_SOURCE_INTERNAL2,
TFE_CSID_HALT_CMD_SOURCE_INTERNAL1,
};
/** /**
*enum cam_csid_path_timestamp_stb_sel - select the sof/eof strobes used to *enum cam_csid_path_timestamp_stb_sel - select the sof/eof strobes used to
* capture the timestamp * capture the timestamp
@@ -470,6 +481,7 @@ struct cam_csid_evt_payload {
* @csi2_rx_reserve_cnt: csi2 reservations count value * @csi2_rx_reserve_cnt: csi2 reservations count value
* pxl_pipe_enable: flag to specify if the hardware has IPP * pxl_pipe_enable: flag to specify if the hardware has IPP
* @ipp_res: image pixel path resource * @ipp_res: image pixel path resource
* @ppp_res: PD pixel path resource
* @rdi_res: raw dump image path resources * @rdi_res: raw dump image path resources
* @cid_res: cid resources values * @cid_res: cid resources values
* @csid_top_reset_complete: csid top reset completion * @csid_top_reset_complete: csid top reset completion
@@ -510,11 +522,13 @@ struct cam_tfe_csid_hw {
uint32_t csi2_reserve_cnt; uint32_t csi2_reserve_cnt;
uint32_t pxl_pipe_enable; uint32_t pxl_pipe_enable;
struct cam_isp_resource_node ipp_res; struct cam_isp_resource_node ipp_res;
struct cam_isp_resource_node ppp_res;
struct cam_isp_resource_node rdi_res[CAM_TFE_CSID_RDI_MAX]; struct cam_isp_resource_node rdi_res[CAM_TFE_CSID_RDI_MAX];
struct cam_tfe_csid_cid_data cid_res[CAM_TFE_CSID_CID_MAX]; struct cam_tfe_csid_cid_data cid_res[CAM_TFE_CSID_CID_MAX];
struct completion csid_top_complete; struct completion csid_top_complete;
struct completion csid_csi2_complete; struct completion csid_csi2_complete;
struct completion csid_ipp_complete; struct completion csid_ipp_complete;
struct completion csid_ppp_complete;
struct completion csid_rdin_complete[CAM_TFE_CSID_RDI_MAX]; struct completion csid_rdin_complete[CAM_TFE_CSID_RDI_MAX];
uint64_t csid_debug; uint64_t csid_debug;
uint64_t clk_rate; uint64_t clk_rate;

View File

@@ -81,6 +81,7 @@ struct cam_tfe_bus_common_data {
uint32_t max_bw_counter_limit; uint32_t max_bw_counter_limit;
uint32_t counter_limit_shift; uint32_t counter_limit_shift;
uint32_t counter_limit_mask; uint32_t counter_limit_mask;
uint32_t pack_align_shift;
}; };
struct cam_tfe_bus_wm_resource_data { struct cam_tfe_bus_wm_resource_data {
@@ -188,6 +189,9 @@ static bool cam_tfe_bus_can_be_secure(uint32_t out_id)
case CAM_TFE_BUS_TFE_OUT_DS4: case CAM_TFE_BUS_TFE_OUT_DS4:
case CAM_TFE_BUS_TFE_OUT_DS16: case CAM_TFE_BUS_TFE_OUT_DS16:
case CAM_TFE_BUS_TFE_OUT_AI: case CAM_TFE_BUS_TFE_OUT_AI:
case CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS:
case CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED:
case CAM_TFE_BUS_TFE_OUT_PD_PARSED:
return true; return true;
case CAM_TFE_BUS_TFE_OUT_STATS_HDR_BE: case CAM_TFE_BUS_TFE_OUT_STATS_HDR_BE:
@@ -235,6 +239,12 @@ static enum cam_tfe_bus_tfe_out_id
return CAM_TFE_BUS_TFE_OUT_DS16; return CAM_TFE_BUS_TFE_OUT_DS16;
case CAM_ISP_TFE_OUT_RES_AI: case CAM_ISP_TFE_OUT_RES_AI:
return CAM_TFE_BUS_TFE_OUT_AI; return CAM_TFE_BUS_TFE_OUT_AI;
case CAM_ISP_TFE_OUT_RES_PD_LCR_STATS:
return CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS;
case CAM_ISP_TFE_OUT_RES_PD_PREPROCESSED:
return CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED;
case CAM_ISP_TFE_OUT_RES_PD_PARSED:
return CAM_TFE_BUS_TFE_OUT_PD_PARSED;
default: default:
return CAM_TFE_BUS_TFE_OUT_MAX; return CAM_TFE_BUS_TFE_OUT_MAX;
} }
@@ -352,6 +362,17 @@ static int cam_tfe_bus_get_num_wm(
break; break;
} }
break; break;
case CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS:
case CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED:
case CAM_TFE_BUS_TFE_OUT_PD_PARSED:
switch (format) {
case CAM_FORMAT_PLAIN16_16:
case CAM_FORMAT_PLAIN64:
return 1;
default:
break;
}
break;
default: default:
break; break;
} }
@@ -553,6 +574,33 @@ static int cam_tfe_bus_get_wm_idx(
break; break;
} }
break; break;
case CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS:
switch (plane) {
case PLANE_Y:
wm_idx = 16;
break;
default:
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED:
switch (plane) {
case PLANE_Y:
wm_idx = 17;
break;
default:
break;
}
break;
case CAM_TFE_BUS_TFE_OUT_PD_PARSED:
switch (plane) {
case PLANE_Y:
wm_idx = 18;
break;
default:
break;
}
break;
default: default:
break; break;
} }
@@ -868,6 +916,48 @@ static int cam_tfe_bus_acquire_wm(
/*RS state packet format*/ /*RS state packet format*/
if (rsrc_data->index == 15) if (rsrc_data->index == 15)
rsrc_data->pack_fmt = 0x9; rsrc_data->pack_fmt = 0x9;
} else if (rsrc_data->index == 16) {
/* LCR */
switch (rsrc_data->format) {
case CAM_FORMAT_PLAIN16_16:
rsrc_data->stride = ALIGNUP(rsrc_data->width * 2, 8);
rsrc_data->en_cfg = 0x1;
/* LSB aligned */
rsrc_data->pack_fmt |= (1 <<
bus_priv->common_data.pack_align_shift);
break;
default:
CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d index: %d",
rsrc_data->format, tfe_out_res_id, rsrc_data->index);
return -EINVAL;
}
} else if (rsrc_data->index == 17) {
/* PD_PREPROCESSED */
switch (rsrc_data->format) {
case CAM_FORMAT_PLAIN16_16:
rsrc_data->stride = ALIGNUP(rsrc_data->width * 2, 8);
rsrc_data->en_cfg = 0x1;
break;
default:
CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d index: %d",
rsrc_data->format, tfe_out_res_id, rsrc_data->index);
return -EINVAL;
}
} else if (rsrc_data->index == 18) {
/* PD PARSED */
switch (rsrc_data->format) {
case CAM_FORMAT_PLAIN16_16:
rsrc_data->stride = ALIGNUP(rsrc_data->width * 2, 8);
rsrc_data->en_cfg = 0x1;
/* LSB aligned */
rsrc_data->pack_fmt |= (1 <<
bus_priv->common_data.pack_align_shift);
break;
default:
CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d index: %d",
rsrc_data->format, tfe_out_res_id, rsrc_data->index);
return -EINVAL;
}
} else { } else {
CAM_ERR(CAM_ISP, "Invalid WM:%d requested", rsrc_data->index); CAM_ERR(CAM_ISP, "Invalid WM:%d requested", rsrc_data->index);
return -EINVAL; return -EINVAL;
@@ -1792,6 +1882,8 @@ static const char *cam_tfe_bus_rup_type(
return "RDI1 RUP"; return "RDI1 RUP";
case CAM_ISP_HW_TFE_IN_RDI2: case CAM_ISP_HW_TFE_IN_RDI2:
return "RDI2 RUP"; return "RDI2 RUP";
case CAM_ISP_HW_TFE_IN_PDLIB:
return "PDLIB RUP";
default: default:
return "invalid rup group"; return "invalid rup group";
} }
@@ -2734,6 +2826,7 @@ int cam_tfe_bus_init(
bus_priv->common_data.counter_limit_mask = hw_info->counter_limit_mask; bus_priv->common_data.counter_limit_mask = hw_info->counter_limit_mask;
bus_priv->common_data.en_cfg_shift = hw_info->en_cfg_shift; bus_priv->common_data.en_cfg_shift = hw_info->en_cfg_shift;
bus_priv->common_data.height_shift = hw_info->height_shift; bus_priv->common_data.height_shift = hw_info->height_shift;
bus_priv->common_data.pack_align_shift = hw_info->pack_align_shift;
for (i = 0; i < CAM_TFE_BUS_IRQ_REGISTERS_MAX; i++) for (i = 0; i < CAM_TFE_BUS_IRQ_REGISTERS_MAX; i++)
bus_priv->bus_irq_error_mask[i] = bus_priv->bus_irq_error_mask[i] =

View File

@@ -70,6 +70,7 @@ enum cam_tfe_bus_rup_grp_id {
CAM_TFE_BUS_RUP_GRP_1, CAM_TFE_BUS_RUP_GRP_1,
CAM_TFE_BUS_RUP_GRP_2, CAM_TFE_BUS_RUP_GRP_2,
CAM_TFE_BUS_RUP_GRP_3, CAM_TFE_BUS_RUP_GRP_3,
CAM_TFE_BUS_RUP_GRP_4,
CAM_TFE_BUS_RUP_GRP_MAX, CAM_TFE_BUS_RUP_GRP_MAX,
}; };
@@ -89,6 +90,9 @@ enum cam_tfe_bus_tfe_out_id {
CAM_TFE_BUS_TFE_OUT_DS4, CAM_TFE_BUS_TFE_OUT_DS4,
CAM_TFE_BUS_TFE_OUT_DS16, CAM_TFE_BUS_TFE_OUT_DS16,
CAM_TFE_BUS_TFE_OUT_AI, CAM_TFE_BUS_TFE_OUT_AI,
CAM_TFE_BUS_TFE_OUT_PD_LCR_STATS,
CAM_TFE_BUS_TFE_OUT_PD_PREPROCESSED,
CAM_TFE_BUS_TFE_OUT_PD_PARSED,
CAM_TFE_BUS_TFE_OUT_MAX, CAM_TFE_BUS_TFE_OUT_MAX,
}; };
@@ -202,6 +206,7 @@ struct cam_tfe_bus_tfe_out_hw_info {
* @counter_limit_shift: Mask shift for BW counter limit * @counter_limit_shift: Mask shift for BW counter limit
* @counter_limit_mask: Default Mask of BW limit counter * @counter_limit_mask: Default Mask of BW limit counter
* @en_cfg_shift: bus client frame based enable bit * @en_cfg_shift: bus client frame based enable bit
* @pack_align_shift: pack alignment shift
*/ */
struct cam_tfe_bus_hw_info { struct cam_tfe_bus_hw_info {
struct cam_tfe_bus_reg_offset_common common_reg; struct cam_tfe_bus_reg_offset_common common_reg;
@@ -226,6 +231,7 @@ struct cam_tfe_bus_hw_info {
uint32_t max_bw_counter_limit; uint32_t max_bw_counter_limit;
uint32_t counter_limit_shift; uint32_t counter_limit_shift;
uint32_t counter_limit_mask; uint32_t counter_limit_mask;
uint32_t pack_align_shift;
}; };
/* /*

View File

@@ -109,6 +109,23 @@ struct cam_tfe_rdi_data {
uint32_t last_line; uint32_t last_line;
}; };
struct cam_tfe_ppp_data {
void __iomem *mem_base;
struct cam_hw_intf *hw_intf;
struct cam_tfe_top_reg_offset_common *common_reg;
struct cam_tfe_ppp_reg *ppp_reg;
struct cam_tfe_ppp_reg_data *reg_data;
cam_hw_mgr_event_cb_func event_cb;
void *priv;
enum cam_isp_hw_sync_mode sync_mode;
uint32_t pix_pattern;
uint32_t left_first_pixel;
uint32_t left_last_pixel;
uint32_t first_line;
uint32_t last_line;
bool lcr_enable;
};
static int cam_tfe_validate_pix_pattern(uint32_t pattern) static int cam_tfe_validate_pix_pattern(uint32_t pattern)
{ {
int rc; int rc;
@@ -240,6 +257,7 @@ static void cam_tfe_log_tfe_in_debug_status(
struct cam_tfe_camif_data *camif_data; struct cam_tfe_camif_data *camif_data;
struct cam_tfe_rdi_data *rdi_data; struct cam_tfe_rdi_data *rdi_data;
struct cam_tfe_top_reg_offset_common *common_reg; struct cam_tfe_top_reg_offset_common *common_reg;
struct cam_tfe_ppp_data *ppp_data;
uint32_t i, val_0, val_1; uint32_t i, val_0, val_1;
mem_base = top_priv->common_data.soc_info->reg_map[0].mem_base; mem_base = top_priv->common_data.soc_info->reg_map[0].mem_base;
@@ -283,6 +301,28 @@ static void cam_tfe_log_tfe_in_debug_status(
camif_data->vbi_value, camif_data->vbi_value,
camif_data->hbi_value); camif_data->hbi_value);
} else if (top_priv->in_rsrc[i].res_id == CAM_ISP_HW_TFE_IN_PDLIB) {
ppp_data = (struct cam_tfe_ppp_data *)
top_priv->in_rsrc[i].res_priv;
val_0 = cam_io_r(mem_base +
ppp_data->ppp_reg->ppp_debug_0);
val_1 = cam_io_r(mem_base +
ppp_data->ppp_reg->ppp_debug_1);
CAM_INFO(CAM_ISP,
"PDLIB res id:%d debug1:0x%x Height:0x%x, width:0x%x",
top_priv->in_rsrc[i].res_id,
val_1, ((val_0 >> 16) & 0x1FFF),
(val_0 & 0x1FFF));
CAM_INFO(CAM_ISP,
"sync mode:%d left start pxl:0x%x end_pixel:0x%x",
ppp_data->sync_mode,
ppp_data->left_first_pixel,
ppp_data->left_last_pixel);
CAM_INFO(CAM_ISP,
"sync mode:%d line start:0x%x line end:0x%x",
ppp_data->sync_mode,
ppp_data->first_line,
ppp_data->last_line);
} else if ((top_priv->in_rsrc[i].res_id >= } else if ((top_priv->in_rsrc[i].res_id >=
CAM_ISP_HW_TFE_IN_RDI0) || CAM_ISP_HW_TFE_IN_RDI0) ||
(top_priv->in_rsrc[i].res_id <= (top_priv->in_rsrc[i].res_id <=
@@ -401,6 +441,9 @@ static void cam_tfe_log_error_irq_status(
if (evt_payload->irq_reg_val[0] & common_reg->rdi2_frame_drop_bit) if (evt_payload->irq_reg_val[0] & common_reg->rdi2_frame_drop_bit)
CAM_INFO(CAM_ISP, "TFE %d RDI2_FRAME_DROP", core_info->core_index); CAM_INFO(CAM_ISP, "TFE %d RDI2_FRAME_DROP", core_info->core_index);
if (evt_payload->irq_reg_val[0] & common_reg->ppp_frame_drop_bit)
CAM_INFO(CAM_ISP, "TFE %d PDAF_FRAME_DROP", core_info->core_index);
if (evt_payload->irq_reg_val[0] & common_reg->pp_overflow_bit) if (evt_payload->irq_reg_val[0] & common_reg->pp_overflow_bit)
CAM_INFO(CAM_ISP, "TFE %d PP_OVERFLOW", core_info->core_index); CAM_INFO(CAM_ISP, "TFE %d PP_OVERFLOW", core_info->core_index);
@@ -413,6 +456,9 @@ static void cam_tfe_log_error_irq_status(
if (evt_payload->irq_reg_val[0] & common_reg->rdi2_overflow_bit) if (evt_payload->irq_reg_val[0] & common_reg->rdi2_overflow_bit)
CAM_INFO(CAM_ISP, "TFE %d RDI2_OVERFLOW", core_info->core_index); CAM_INFO(CAM_ISP, "TFE %d RDI2_OVERFLOW", core_info->core_index);
if (evt_payload->irq_reg_val[0] & common_reg->ppp_overflow_bit)
CAM_INFO(CAM_ISP, "TFE %d PDAF_OVERFLOW", core_info->core_index);
if (evt_payload->irq_reg_val[0] & common_reg->out_of_sync_frame_drop_bit) { if (evt_payload->irq_reg_val[0] & common_reg->out_of_sync_frame_drop_bit) {
CAM_INFO(CAM_ISP, CAM_INFO(CAM_ISP,
"TFE %d SENSOR_SWITCH_OUT_OF_SYNC_FRAME_DROP mup: last %d curr %d", "TFE %d SENSOR_SWITCH_OUT_OF_SYNC_FRAME_DROP mup: last %d curr %d",
@@ -442,6 +488,12 @@ static void cam_tfe_log_error_irq_status(
if (evt_payload->irq_reg_val[2] & common_reg->diag_violation_bit) if (evt_payload->irq_reg_val[2] & common_reg->diag_violation_bit)
CAM_INFO(CAM_ISP, "TFE %d DIAG_VIOLATION", core_info->core_index); CAM_INFO(CAM_ISP, "TFE %d DIAG_VIOLATION", core_info->core_index);
if (evt_payload->irq_reg_val[2] & common_reg->ppp_camif_violation_bit)
CAM_INFO(CAM_ISP, "TFE %d PDAF_CAMIF_VIOLATION", core_info->core_index);
if (evt_payload->irq_reg_val[2] & common_reg->ppp_violation_bit)
CAM_INFO(CAM_ISP, "TFE %d PDAF_VIOLATION", core_info->core_index);
if (evt_payload->irq_reg_val[2] & common_reg->dyamanic_switch_violation_bit) if (evt_payload->irq_reg_val[2] & common_reg->dyamanic_switch_violation_bit)
CAM_INFO(CAM_ISP, CAM_INFO(CAM_ISP,
"TFE %d DYNAMIC_SHDR_MODE_SWITCH_VIOLATION mup val %d", "TFE %d DYNAMIC_SHDR_MODE_SWITCH_VIOLATION mup val %d",
@@ -586,6 +638,84 @@ static int cam_tfe_rdi_irq_bottom_half(
return 0; return 0;
} }
static int cam_tfe_ppp_irq_bottom_half(
struct cam_tfe_top_priv *top_priv,
struct cam_isp_resource_node *ppp_node,
bool epoch_process,
struct cam_tfe_irq_evt_payload *evt_payload)
{
struct cam_tfe_ppp_data *ppp_priv;
struct cam_isp_hw_event_info evt_info;
struct cam_hw_info *hw_info;
struct cam_tfe_top_reg_offset_common *common_reg;
uint32_t val, val2;
ppp_priv = (struct cam_tfe_ppp_data *)ppp_node->res_priv;
hw_info = ppp_node->hw_intf->hw_priv;
evt_info.hw_idx = ppp_node->hw_intf->hw_idx;
evt_info.res_id = ppp_node->res_id;
evt_info.res_type = ppp_node->res_type;
if ((!epoch_process) && (evt_payload->irq_reg_val[1] &
ppp_priv->reg_data->eof_irq_mask)) {
CAM_DBG(CAM_ISP, "Received EOF");
top_priv->eof_ts.tv_sec =
evt_payload->ts.mono_time.tv_sec;
top_priv->eof_ts.tv_nsec =
evt_payload->ts.mono_time.tv_nsec;
if (ppp_priv->event_cb)
ppp_priv->event_cb(ppp_priv->priv,
CAM_ISP_HW_EVENT_EOF, (void *)&evt_info);
}
if ((!epoch_process) && (evt_payload->irq_reg_val[1] &
ppp_priv->reg_data->sof_irq_mask)) {
CAM_DBG(CAM_ISP, "Received SOF");
top_priv->sof_ts.tv_sec =
evt_payload->ts.mono_time.tv_sec;
top_priv->sof_ts.tv_nsec =
evt_payload->ts.mono_time.tv_nsec;
if (ppp_priv->event_cb)
ppp_priv->event_cb(ppp_priv->priv,
CAM_ISP_HW_EVENT_SOF, (void *)&evt_info);
if (top_priv->top_debug &
CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS) {
common_reg = ppp_priv->common_reg;
val = cam_io_r(ppp_priv->mem_base +
common_reg->diag_sensor_status_0);
val2 = cam_io_r(ppp_priv->mem_base +
common_reg->diag_sensor_status_1);
CAM_INFO(CAM_ISP,
"TFE:%d diag sensor hbi min error:%d neq hbi:%d HBI:%d VBI:%d",
ppp_node->hw_intf->hw_idx,
((val >> common_reg->diag_min_hbi_error_shift)
& 0x1),
((val >> common_reg->diag_neq_hbi_shift) & 0x1),
(val & common_reg->diag_sensor_hbi_mask),
val2);
}
}
if (epoch_process && (evt_payload->irq_reg_val[1] &
ppp_priv->reg_data->epoch0_irq_mask)) {
CAM_DBG(CAM_ISP, "Received EPOCH0");
top_priv->epoch_ts.tv_sec =
evt_payload->ts.mono_time.tv_sec;
top_priv->epoch_ts.tv_nsec =
evt_payload->ts.mono_time.tv_nsec;
if (ppp_priv->event_cb)
ppp_priv->event_cb(ppp_priv->priv,
CAM_ISP_HW_EVENT_EPOCH, (void *)&evt_info);
}
return 0;
}
static int cam_tfe_camif_irq_bottom_half( static int cam_tfe_camif_irq_bottom_half(
struct cam_tfe_top_priv *top_priv, struct cam_tfe_top_priv *top_priv,
struct cam_isp_resource_node *camif_node, struct cam_isp_resource_node *camif_node,
@@ -687,6 +817,7 @@ static int cam_tfe_irq_bottom_half(void *handler_priv,
struct cam_tfe_irq_evt_payload *evt_payload; struct cam_tfe_irq_evt_payload *evt_payload;
struct cam_tfe_camif_data *camif_priv; struct cam_tfe_camif_data *camif_priv;
struct cam_tfe_rdi_data *rdi_priv; struct cam_tfe_rdi_data *rdi_priv;
struct cam_tfe_ppp_data *ppp_priv;
cam_hw_mgr_event_cb_func event_cb = NULL; cam_hw_mgr_event_cb_func event_cb = NULL;
void *event_cb_priv = NULL; void *event_cb_priv = NULL;
uint32_t i; uint32_t i;
@@ -719,6 +850,20 @@ static int cam_tfe_irq_bottom_half(void *handler_priv,
&top_priv->in_rsrc[i], false, &top_priv->in_rsrc[i], false,
evt_payload); evt_payload);
} else if ((top_priv->in_rsrc[i].res_id ==
CAM_ISP_HW_TFE_IN_PDLIB) &&
(top_priv->in_rsrc[i].res_state ==
CAM_ISP_RESOURCE_STATE_STREAMING)) {
ppp_priv = (struct cam_tfe_ppp_data *)
top_priv->in_rsrc[i].res_priv;
event_cb = ppp_priv->event_cb;
event_cb_priv = ppp_priv->priv;
if (ppp_priv->reg_data->subscribe_irq_mask[1] &
evt_payload->irq_reg_val[1])
cam_tfe_ppp_irq_bottom_half(top_priv,
&top_priv->in_rsrc[i], false,
evt_payload);
} else if ((top_priv->in_rsrc[i].res_id >= } else if ((top_priv->in_rsrc[i].res_id >=
CAM_ISP_HW_TFE_IN_RDI0) && CAM_ISP_HW_TFE_IN_RDI0) &&
(top_priv->in_rsrc[i].res_id <= (top_priv->in_rsrc[i].res_id <=
@@ -763,6 +908,17 @@ static int cam_tfe_irq_bottom_half(void *handler_priv,
cam_tfe_camif_irq_bottom_half(top_priv, cam_tfe_camif_irq_bottom_half(top_priv,
&top_priv->in_rsrc[i], true, &top_priv->in_rsrc[i], true,
evt_payload); evt_payload);
} else if ((top_priv->in_rsrc[i].res_id ==
CAM_ISP_HW_TFE_IN_PDLIB) &&
(top_priv->in_rsrc[i].res_state ==
CAM_ISP_RESOURCE_STATE_STREAMING)) {
ppp_priv = (struct cam_tfe_ppp_data *)
top_priv->in_rsrc[i].res_priv;
if (ppp_priv->reg_data->subscribe_irq_mask[1] &
evt_payload->irq_reg_val[1])
cam_tfe_ppp_irq_bottom_half(top_priv,
&top_priv->in_rsrc[i], true,
evt_payload);
} else if ((top_priv->in_rsrc[i].res_id >= } else if ((top_priv->in_rsrc[i].res_id >=
CAM_ISP_HW_TFE_IN_RDI0) && CAM_ISP_HW_TFE_IN_RDI0) &&
(top_priv->in_rsrc[i].res_id <= (top_priv->in_rsrc[i].res_id <=
@@ -1339,6 +1495,11 @@ static int cam_tfe_top_get_reg_update(
rdi_rsrc_data = in_res->res_priv; rdi_rsrc_data = in_res->res_priv;
reg_val_pair[0] = rdi_rsrc_data->rdi_reg->reg_update_cmd; reg_val_pair[0] = rdi_rsrc_data->rdi_reg->reg_update_cmd;
reg_val_pair[1] = rdi_rsrc_data->reg_data->reg_update_cmd_data; reg_val_pair[1] = rdi_rsrc_data->reg_data->reg_update_cmd_data;
} else if (in_res->res_id == CAM_ISP_HW_TFE_IN_PDLIB) {
/*REG CMD is not supported in PDLIB. PD CAMIF takes RUP from IPP CAMIF */
CAM_DBG(CAM_ISP, "Reg update not supported for res %d",
in_res->res_id);
return 0;
} }
common_reg = top_priv->common_data.common_reg; common_reg = top_priv->common_data.common_reg;
@@ -1908,6 +2069,22 @@ int cam_tfe_set_top_debug(struct cam_tfe_hw_core_info *core_info,
return 0; return 0;
} }
static int cam_tfe_bus_get_path_port_map(void *top_hw_info,
void *cmd_args, uint32_t arg_size)
{
struct cam_isp_hw_path_port_map *arg = cmd_args;
struct cam_tfe_top_hw_info *hw_info =
(struct cam_tfe_top_hw_info *)top_hw_info;
int i;
for (i = 0; i < hw_info->num_path_port_map; i++) {
arg->entry[i][0] = hw_info->path_port_map[i][0];
arg->entry[i][1] = hw_info->path_port_map[i][1];
}
arg->num_entries = hw_info->num_path_port_map;
return 0;
}
int cam_tfe_top_reserve(void *device_priv, int cam_tfe_top_reserve(void *device_priv,
void *reserve_args, uint32_t arg_size) void *reserve_args, uint32_t arg_size)
@@ -1916,6 +2093,7 @@ int cam_tfe_top_reserve(void *device_priv,
struct cam_tfe_acquire_args *args; struct cam_tfe_acquire_args *args;
struct cam_tfe_hw_tfe_in_acquire_args *acquire_args; struct cam_tfe_hw_tfe_in_acquire_args *acquire_args;
struct cam_tfe_camif_data *camif_data; struct cam_tfe_camif_data *camif_data;
struct cam_tfe_ppp_data *ppp_data;
struct cam_tfe_rdi_data *rdi_data; struct cam_tfe_rdi_data *rdi_data;
uint32_t i; uint32_t i;
int rc = -EINVAL; int rc = -EINVAL;
@@ -1986,6 +2164,24 @@ int cam_tfe_top_reserve(void *device_priv,
top_priv->in_rsrc[i].hw_intf->hw_idx, top_priv->in_rsrc[i].hw_intf->hw_idx,
camif_data->pix_pattern, camif_data->pix_pattern,
camif_data->dsp_mode); camif_data->dsp_mode);
} else if (acquire_args->res_id == CAM_ISP_HW_TFE_IN_PDLIB) {
ppp_data = (struct cam_tfe_ppp_data *)
top_priv->in_rsrc[i].res_priv;
ppp_data->pix_pattern =
acquire_args->in_port->pix_pattern;
ppp_data->sync_mode = acquire_args->sync_mode;
ppp_data->event_cb = args->event_cb;
ppp_data->priv = args->priv;
ppp_data->left_first_pixel =
acquire_args->in_port->left_start;
ppp_data->left_last_pixel =
acquire_args->in_port->left_end;
ppp_data->first_line =
acquire_args->in_port->line_start;
ppp_data->last_line =
acquire_args->in_port->line_end;
ppp_data->lcr_enable =
acquire_args->lcr_enable;
} else { } else {
rdi_data = (struct cam_tfe_rdi_data *) rdi_data = (struct cam_tfe_rdi_data *)
top_priv->in_rsrc[i].res_priv; top_priv->in_rsrc[i].res_priv;
@@ -2212,6 +2408,45 @@ static int cam_tfe_camif_resource_start(
return 0; return 0;
} }
static int cam_tfe_ppp_resource_start(
struct cam_tfe_hw_core_info *core_info,
struct cam_isp_resource_node *ppp_res)
{
struct cam_tfe_ppp_data *rsrc_data;
uint32_t val = 0;
if (!ppp_res || !core_info) {
CAM_ERR(CAM_ISP, "Error Invalid input arguments");
return -EINVAL;
}
if (ppp_res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED) {
CAM_ERR(CAM_ISP, "TFE:%d Error Invalid camif res res_state:%d",
core_info->core_index, ppp_res->res_state);
return -EINVAL;
}
rsrc_data = (struct cam_tfe_ppp_data *)ppp_res->res_priv;
/* Config tfe core */
val = (1 << rsrc_data->reg_data->pdaf_path_en_shift);
if (!rsrc_data->lcr_enable)
val = (1 << rsrc_data->reg_data->lcr_dis_en_shift);
if (rsrc_data->sync_mode != CAM_ISP_HW_SYNC_NONE)
val = (1 << rsrc_data->reg_data->lcr_dis_en_shift);
cam_io_w_mb(val, rsrc_data->mem_base +
rsrc_data->common_reg->core_cfg_0);
ppp_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
CAM_DBG(CAM_ISP, "TFE: %d Start PPP Done, core_cfg 0 val:0x%x",
core_info->core_index, val);
return 0;
}
int cam_tfe_top_start(struct cam_tfe_hw_core_info *core_info, int cam_tfe_top_start(struct cam_tfe_hw_core_info *core_info,
void *start_args, uint32_t arg_size) void *start_args, uint32_t arg_size)
{ {
@@ -2256,6 +2491,8 @@ int cam_tfe_top_start(struct cam_tfe_hw_core_info *core_info,
if (in_res->res_id == CAM_ISP_HW_TFE_IN_CAMIF) { if (in_res->res_id == CAM_ISP_HW_TFE_IN_CAMIF) {
cam_tfe_camif_resource_start(core_info, in_res); cam_tfe_camif_resource_start(core_info, in_res);
} else if (in_res->res_id == CAM_ISP_HW_TFE_IN_PDLIB) {
cam_tfe_ppp_resource_start(core_info, in_res);
} else if (in_res->res_id >= CAM_ISP_HW_TFE_IN_RDI0 && } else if (in_res->res_id >= CAM_ISP_HW_TFE_IN_RDI0 &&
in_res->res_id <= CAM_ISP_HW_TFE_IN_RDI2) { in_res->res_id <= CAM_ISP_HW_TFE_IN_RDI2) {
rsrc_rdi_data = (struct cam_tfe_rdi_data *) in_res->res_priv; rsrc_rdi_data = (struct cam_tfe_rdi_data *) in_res->res_priv;
@@ -2325,6 +2562,7 @@ int cam_tfe_top_stop(struct cam_tfe_hw_core_info *core_info,
struct cam_hw_info *hw_info = NULL; struct cam_hw_info *hw_info = NULL;
struct cam_tfe_camif_data *camif_data; struct cam_tfe_camif_data *camif_data;
struct cam_tfe_rdi_data *rsrc_rdi_data; struct cam_tfe_rdi_data *rsrc_rdi_data;
struct cam_tfe_ppp_data *ppp_data;
uint32_t val = 0; uint32_t val = 0;
int i, rc = 0; int i, rc = 0;
@@ -2362,6 +2600,14 @@ int cam_tfe_top_stop(struct cam_tfe_hw_core_info *core_info,
cam_io_w_mb(val, camif_data->mem_base + cam_io_w_mb(val, camif_data->mem_base +
camif_data->common_reg->diag_config); camif_data->common_reg->diag_config);
} }
} else if (in_res->res_id == CAM_ISP_HW_TFE_IN_PDLIB) {
ppp_data = (struct cam_tfe_ppp_data *)in_res->res_priv;
cam_io_w_mb(0, ppp_data->mem_base +
ppp_data->ppp_reg->ppp_module_config);
if (in_res->res_state == CAM_ISP_RESOURCE_STATE_STREAMING)
in_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
} else if ((in_res->res_id >= CAM_ISP_HW_TFE_IN_RDI0) && } else if ((in_res->res_id >= CAM_ISP_HW_TFE_IN_RDI0) &&
(in_res->res_id <= CAM_ISP_HW_TFE_IN_RDI2)) { (in_res->res_id <= CAM_ISP_HW_TFE_IN_RDI2)) {
rsrc_rdi_data = (struct cam_tfe_rdi_data *) in_res->res_priv; rsrc_rdi_data = (struct cam_tfe_rdi_data *) in_res->res_priv;
@@ -2415,6 +2661,7 @@ int cam_tfe_top_init(
struct cam_tfe_soc_private *soc_private = NULL; struct cam_tfe_soc_private *soc_private = NULL;
struct cam_tfe_camif_data *camif_priv = NULL; struct cam_tfe_camif_data *camif_priv = NULL;
struct cam_tfe_rdi_data *rdi_priv = NULL; struct cam_tfe_rdi_data *rdi_priv = NULL;
struct cam_tfe_ppp_data *ppp_priv = NULL;
int i, j, rc = 0; int i, j, rc = 0;
top_priv = kzalloc(sizeof(struct cam_tfe_top_priv), top_priv = kzalloc(sizeof(struct cam_tfe_top_priv),
@@ -2477,6 +2724,29 @@ int cam_tfe_top_init(
camif_priv->hw_intf = hw_intf; camif_priv->hw_intf = hw_intf;
camif_priv->soc_info = soc_info; camif_priv->soc_info = soc_info;
} else if (hw_info->in_port[i] == CAM_TFE_PDLIB_VER_1_0) {
top_priv->in_rsrc[i].res_id =
CAM_ISP_HW_TFE_IN_PDLIB;
ppp_priv = kzalloc(sizeof(struct cam_tfe_ppp_data),
GFP_KERNEL);
if (!ppp_priv) {
CAM_DBG(CAM_ISP,
"TFE:%d Error Failed to alloc for ppp_priv",
core_info->core_index);
goto deinit_resources;
}
top_priv->in_rsrc[i].res_priv = ppp_priv;
ppp_priv->mem_base =
soc_info->reg_map[TFE_CORE_BASE_IDX].mem_base;
ppp_priv->hw_intf = hw_intf;
ppp_priv->common_reg = hw_info->common_reg;
ppp_priv->ppp_reg =
hw_info->ppp_hw_info.ppp_reg;
ppp_priv->reg_data =
hw_info->ppp_hw_info.reg_data;
} else if (hw_info->in_port[i] == } else if (hw_info->in_port[i] ==
CAM_TFE_RDI_VER_1_0) { CAM_TFE_RDI_VER_1_0) {
top_priv->in_rsrc[i].res_id = top_priv->in_rsrc[i].res_id =
@@ -3025,6 +3295,10 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
core_info->tfe_bus->bus_priv, cmd_type, cmd_args, core_info->tfe_bus->bus_priv, cmd_type, cmd_args,
arg_size); arg_size);
break; break;
case CAM_ISP_HW_CMD_GET_PATH_PORT_MAP:
rc = cam_tfe_bus_get_path_port_map(hw_info->top_hw_info, cmd_args,
arg_size);
break;
default: default:
CAM_ERR(CAM_ISP, "TFE:%d Invalid cmd type:%d", CAM_ERR(CAM_ISP, "TFE:%d Invalid cmd type:%d",
core_info->core_index, cmd_type); core_info->core_index, cmd_type);

View File

@@ -16,8 +16,9 @@
#define CAM_TFE_CAMIF_VER_1_0 0x10 #define CAM_TFE_CAMIF_VER_1_0 0x10
#define CAM_TFE_RDI_VER_1_0 0x1000 #define CAM_TFE_RDI_VER_1_0 0x1000
#define CAM_TFE_PDLIB_VER_1_0 0x10000
#define CAM_TFE_TOP_1_0 0x1000 #define CAM_TFE_TOP_1_0 0x1000
#define CAM_TFE_TOP_IN_PORT_MAX 4 #define CAM_TFE_TOP_IN_PORT_MAX 5
#define CAM_TFE_RDI_MAX 4 #define CAM_TFE_RDI_MAX 4
#define CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS BIT(0) #define CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS BIT(0)
@@ -116,16 +117,20 @@ struct cam_tfe_top_reg_offset_common {
/* error bit data */ /* error bit data */
uint32_t pp_camif_violation_bit; uint32_t pp_camif_violation_bit;
uint32_t pp_violation_bit; uint32_t pp_violation_bit;
uint32_t ppp_camif_violation_bit;
uint32_t ppp_violation_bit;
uint32_t rdi0_camif_violation_bit; uint32_t rdi0_camif_violation_bit;
uint32_t rdi1_camif_violation_bit; uint32_t rdi1_camif_violation_bit;
uint32_t rdi2_camif_violation_bit; uint32_t rdi2_camif_violation_bit;
uint32_t diag_violation_bit; uint32_t diag_violation_bit;
uint32_t dyamanic_switch_violation_bit; uint32_t dyamanic_switch_violation_bit;
uint32_t pp_frame_drop_bit; uint32_t pp_frame_drop_bit;
uint32_t ppp_frame_drop_bit;
uint32_t rdi0_frame_drop_bit; uint32_t rdi0_frame_drop_bit;
uint32_t rdi1_frame_drop_bit; uint32_t rdi1_frame_drop_bit;
uint32_t rdi2_frame_drop_bit; uint32_t rdi2_frame_drop_bit;
uint32_t pp_overflow_bit; uint32_t pp_overflow_bit;
uint32_t ppp_overflow_bit;
uint32_t rdi0_overflow_bit; uint32_t rdi0_overflow_bit;
uint32_t rdi1_overflow_bit; uint32_t rdi1_overflow_bit;
uint32_t rdi2_overflow_bit; uint32_t rdi2_overflow_bit;
@@ -237,6 +242,34 @@ struct cam_tfe_rdi_reg_data {
uint32_t diag_sensor_shift; uint32_t diag_sensor_shift;
}; };
struct cam_tfe_ppp_reg {
uint32_t ppp_hw_version;
uint32_t ppp_hw_status;
uint32_t ppp_module_config;
uint32_t ppp_skip_period;
uint32_t ppp_irq_subsample_pattern;
uint32_t ppp_epoch_irq;
uint32_t ppp_debug_1;
uint32_t ppp_debug_0;
uint32_t ppp_test_bus_ctrl;
uint32_t ppp_spare;
uint32_t reg_update_cmd;
};
struct cam_tfe_ppp_reg_data {
uint32_t sof_irq_mask;
uint32_t epoch0_irq_mask;
uint32_t epoch1_irq_mask;
uint32_t eof_irq_mask;
uint32_t subscribe_irq_mask[CAM_TFE_TOP_IRQ_REG_NUM];
uint32_t enable_diagnostic_hw;
uint32_t diag_sensor_sel;
uint32_t diag_sensor_shift;
uint32_t pdaf_path_en_shift;
uint32_t lcr_dis_en_shift;
};
struct cam_tfe_clc_hw_status { struct cam_tfe_clc_hw_status {
uint8_t name[CAM_TFE_CLC_NAME_LENGTH_MAX]; uint8_t name[CAM_TFE_CLC_NAME_LENGTH_MAX];
uint32_t hw_status_reg; uint32_t hw_status_reg;
@@ -247,12 +280,20 @@ struct cam_tfe_rdi_hw_info {
struct cam_tfe_rdi_reg_data *reg_data; struct cam_tfe_rdi_reg_data *reg_data;
}; };
struct cam_tfe_ppp_hw_info {
struct cam_tfe_ppp_reg *ppp_reg;
struct cam_tfe_ppp_reg_data *reg_data;
};
struct cam_tfe_top_hw_info { struct cam_tfe_top_hw_info {
struct cam_tfe_top_reg_offset_common *common_reg; struct cam_tfe_top_reg_offset_common *common_reg;
struct cam_tfe_camif_hw_info camif_hw_info; struct cam_tfe_camif_hw_info camif_hw_info;
struct cam_tfe_rdi_hw_info rdi_hw_info[CAM_TFE_RDI_MAX]; struct cam_tfe_rdi_hw_info rdi_hw_info[CAM_TFE_RDI_MAX];
struct cam_tfe_ppp_hw_info ppp_hw_info;
uint32_t in_port[CAM_TFE_TOP_IN_PORT_MAX]; uint32_t in_port[CAM_TFE_TOP_IN_PORT_MAX];
struct cam_tfe_reg_dump_data reg_dump_data; struct cam_tfe_reg_dump_data reg_dump_data;
uint32_t num_path_port_map;
uint32_t path_port_map[CAM_ISP_HW_PATH_PORT_MAP_MAX][2];
}; };
struct cam_tfe_hw_info { struct cam_tfe_hw_info {