diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 3a8ca9bf99..8abe89f8f7 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -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_DS16: return "TFE_DS_16"; 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 */ default: return "Invalid_Resource_Type"; } diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c index 4994afcca4..d1b6e07cb5 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c @@ -239,6 +239,20 @@ static int cam_tfe_mgr_get_hw_caps(void *hw_mgr_priv, void *hw_caps_args) 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) { int rc = 0; @@ -1019,6 +1033,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out( switch (tfe_in_res->res_id) { 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, tfe_in_res, in_port); break; @@ -1046,7 +1061,8 @@ err: static int cam_tfe_hw_mgr_acquire_res_tfe_in( struct cam_tfe_hw_mgr_ctx *tfe_ctx, 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 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.priv = tfe_ctx; tfe_acquire.event_cb = cam_tfe_hw_mgr_event_handler; + tfe_acquire.tfe_in.lcr_enable = lcr_enable; switch (csid_res->res_id) { 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; 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: tfe_acquire.tfe_in.res_id = CAM_ISP_HW_TFE_IN_RDI0; 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( 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 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_isp_hw_mgr_res *csid_res; 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; struct cam_isp_hw_mgr_res *csid_res_temp, *csid_res_iterator; struct cam_isp_tfe_out_port_generic_info *out_port = NULL; tfe_hw_mgr = tfe_ctx->hw_mgr; /* get csid resource */ - path_res_id = CAM_TFE_CSID_PATH_RES_IPP; + if (is_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); if (rc) { @@ -1194,6 +1227,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl( csid_acquire.node_res = NULL; csid_acquire.event_cb_prv = tfe_ctx; csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler; + csid_acquire.crop_enable = crop_enable; if (in_port->num_out_res) 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; 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", - hw_intf->hw_idx); + hw_intf->hw_idx, + (is_ipp) ? "IPP" : "PPP"); 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. * 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) { CAM_ERR(CAM_ISP, - "Can not acquire left tfe csid path resource %d", - path_res_id); + "Can not acquire left tfe csid path resource %d (%s)", + path_res_id, + (is_ipp) ? "IPP" : "PPP"); goto put_res; } } else { @@ -1308,14 +1345,16 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_csid_pxl( if (i == -1 || !csid_acquire.node_res) { CAM_ERR(CAM_ISP, - "Can not acquire tfe csid path resource %d", - path_res_id); + "Can not acquire tfe csid path resource %d(%s)", + path_res_id, + (is_ipp) ? "IPP" : "PPP"); goto put_res; } } acquire_successful: - CAM_DBG(CAM_ISP, "CSID path left acquired success. is_dual %d", - in_port->usage_type); + CAM_DBG(CAM_ISP, "CSID path left acquired success. is_dual %d res %s", + in_port->usage_type, + (is_ipp) ? "IPP" : "PPP"); csid_res_temp->res_type = CAM_ISP_RESOURCE_PIX_PATH; csid_res_temp->res_id = path_res_id; @@ -1337,7 +1376,8 @@ acquire_successful: * Acquire Right if not already acquired. * 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)) { memset(&csid_acquire, 0, sizeof(csid_acquire)); csid_acquire.node_res = NULL; @@ -1349,6 +1389,7 @@ acquire_successful: csid_acquire.sync_mode = CAM_ISP_HW_SYNC_SLAVE; csid_acquire.node_res = NULL; csid_acquire.out_port = in_port->data; + csid_acquire.crop_enable = crop_enable; csid_acquire.event_cb_prv = tfe_ctx; csid_acquire.event_cb = cam_tfe_hw_mgr_event_handler; @@ -1370,14 +1411,16 @@ acquire_successful: if (j == CAM_TFE_CSID_HW_NUM_MAX) { 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; } csid_res_temp->hw_res[1] = csid_acquire.node_res; tfe_ctx->slave_hw_idx = csid_res_temp->hw_res[1]->hw_intf->hw_idx; - CAM_DBG(CAM_ISP, "CSID right acquired success is_dual %d", - in_port->usage_type); + CAM_DBG(CAM_ISP, "CSID right acquired success is_dual %d res %s", + in_port->usage_type, + (is_ipp) ? "IPP" : "PPP"); } 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_hw_intf *hw_intf; 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; 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, int *ipp_count, int *rdi_count, - int *pdaf_enable) + int *ppp_count, + int *pdaf_enable, + bool *lcr_enable) { int ipp_num = 0; int rdi_num = 0; + int pd_num = 0; bool rdi2_enable = false; uint32_t i; struct cam_isp_tfe_out_port_generic_info *out_port; @@ -1633,6 +1679,12 @@ static int cam_tfe_hw_mgr_preprocess_port( rdi_num++; if (out_port->res_id == CAM_ISP_TFE_OUT_RES_RDI_2) 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 { ipp_num++; 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; *rdi_count = rdi_num; + *ppp_count = pd_num; - CAM_DBG(CAM_ISP, "rdi: %d ipp: %d pdaf:%d", rdi_num, ipp_num, - *pdaf_enable); + CAM_DBG(CAM_ISP, "rdi: %d ipp: %d ppp: %d pdaf:%d", rdi_num, ipp_num, + *ppp_count, *pdaf_enable); 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_isp_tfe_in_port_generic_info *in_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 is_dual_isp = 0; int ipp_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; 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, "No PIX or RDI"); return -EINVAL; } - if (ipp_count) { + if (ipp_count || lcr_enable) { /* get tfe csid IPP resource */ 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) { CAM_ERR(CAM_ISP, "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) { CAM_ERR(CAM_ISP, "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_rdi_port += rdi_count; + *num_pd_port += ppp_count; return 0; 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; uint32_t num_pix_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 total_pix_port = 0; uint32_t total_rdi_port = 0; struct cam_isp_tfe_acquire_hw_info *acquire_hw_info = NULL; uint32_t input_size = 0; + bool lcr_enable = false; 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++) { 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_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); 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); 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; uint32_t num_pix_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 total_pix_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, &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); total_pix_port += num_pix_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; - 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 (*camif_l_bw_updated) return rc; @@ -3648,6 +3729,7 @@ static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args) break; case CAM_TFE_CSID_PATH_RES_IPP: + case CAM_TFE_CSID_PATH_RES_PPP: if (hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, @@ -3686,6 +3768,7 @@ static int cam_tfe_mgr_dump(void *hw_mgr_priv, void *args) break; case CAM_ISP_HW_TFE_IN_CAMIF: + case CAM_ISP_HW_TFE_IN_PDLIB: if (hw_intf->hw_ops.process_cmd) { rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, @@ -3995,7 +4078,8 @@ static int cam_isp_tfe_blob_clock_update( if (!hw_mgr_res->hw_res[i]) 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 (camif_l_clk_updated) continue; @@ -5934,6 +6018,8 @@ static int cam_tfe_hw_mgr_handle_hw_rup( CAM_ISP_HW_EVENT_REG_UPDATE, (void *)&rup_event_data); break; + case CAM_ISP_HW_TFE_IN_PDLIB: + break; default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d", 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_RDI1: case CAM_ISP_HW_TFE_IN_RDI2: + case CAM_ISP_HW_TFE_IN_PDLIB: break; default: @@ -6021,6 +6108,8 @@ static int cam_tfe_hw_mgr_handle_hw_sof( CAM_ISP_HW_EVENT_SOF, (void *)&sof_done_event_data); break; + case CAM_ISP_HW_TFE_IN_PDLIB: + break; default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d", 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); break; + case CAM_ISP_HW_TFE_IN_PDLIB: + break; + default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid res_id: %d", 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_tfe_hw_mgr_ctx *ctx_pool; 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; CAM_DBG(CAM_ISP, "Enter"); 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); 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; struct cam_hw_soc_info *soc_info = &tfe_hw->soc_info; - if (j == 0) + if (j == 0) { tfe_device->hw_ops.process_cmd( tfe_hw, CAM_ISP_HW_CMD_IS_CONSUMED_ADDR_SUPPORT, &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++; 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; + + 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 */ 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); diff --git a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h index c7649b5f2d..1db1070792 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h +++ b/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h @@ -190,6 +190,7 @@ struct cam_tfe_hw_mgr_ctx { * @tfe_dev_caps tfe device capability per core * @work q work queue for TFE hw manager * @debug_cfg debug configuration + * @path_port_map Mapping of outport to TFE mux * @support_consumed_addr indicate whether hw supports last consumed address * @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_req_mgr_core_workq *workq; struct cam_tfe_hw_mgr_debug debug_cfg; + struct cam_isp_hw_path_port_map path_port_map; bool support_consumed_addr; spinlock_t ctx_lock; }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h index 1f3d7af697..b73159cbb1 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_csid_hw_intf.h @@ -23,6 +23,7 @@ enum cam_tfe_csid_path_res_id { CAM_TFE_CSID_PATH_RES_RDI_1, CAM_TFE_CSID_PATH_RES_RDI_2, CAM_TFE_CSID_PATH_RES_IPP, + CAM_TFE_CSID_PATH_RES_PPP, 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_RX, TFE_CSID_IRQ_REG_IPP, + TFE_CSID_IRQ_REG_PPP, 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 * @num_rdis: number of rdis 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 * @minor_version: minor version * @version_incr: version increment @@ -106,6 +109,7 @@ struct cam_isp_tfe_in_port_generic_info { struct cam_tfe_csid_hw_caps { uint32_t num_rdis; uint32_t num_pix; + uint32_t num_ppp; uint32_t major_version; uint32_t minor_version; uint32_t version_incr; @@ -128,6 +132,7 @@ struct cam_tfe_csid_hw_caps { * @event_cb_prv: Context data * @event_cb: Callback function to hw mgr in case of hw events * @node_res : Reserved resource structure pointer + * @crop_enable : Flag to indicate CSID crop enable * */ struct cam_tfe_csid_hw_reserve_resource_args { @@ -141,6 +146,7 @@ struct cam_tfe_csid_hw_reserve_resource_args { void *event_cb_prv; cam_hw_mgr_event_cb_func event_cb; struct cam_isp_resource_node *node_res; + bool crop_enable; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h index b8fd2c1afd..7e381e7a1c 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_tfe_hw_intf.h @@ -19,6 +19,7 @@ enum cam_isp_hw_tfe_in { CAM_ISP_HW_TFE_IN_RDI0 = 1, CAM_ISP_HW_TFE_IN_RDI1 = 2, CAM_ISP_HW_TFE_IN_RDI2 = 3, + CAM_ISP_HW_TFE_IN_PDLIB = 4, 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 * @camif_pd_enable Camif pd enable or disable * @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_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; bool camif_pd_enable; uint32_t dual_tfe_sync_sel_idx; + bool lcr_enable; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c index 9931559e69..8cdad6c795 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c @@ -47,7 +47,7 @@ /* Max CSI Rx irq error count threshold value */ #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) { int rc = -EINVAL; @@ -170,7 +170,7 @@ static int cam_tfe_csid_get_format_rdi( 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 *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; } + /* 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 */ for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) { 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 + 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++) cam_io_w_mb(0, soc_info->reg_map[0].mem_base + 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 + 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++) cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, 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; } + 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++) { path_data = (struct cam_tfe_csid_path_cfg *) 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; cam_io_w_mb(val, soc_info->reg_map[0].mem_base + 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 { id = res->res_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; } - if (cam_tfe_csid_is_ipp_format_supported( + 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", @@ -841,6 +885,43 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw, 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_1: 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->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_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, "Res id: %d height:%d line_start %d line_end %d crop_en %d", 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 + 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++) cam_io_w_mb(csid_reg->cmn_reg->rdi_irq_mask_all, 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; } + 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++) { path_data = (struct cam_tfe_csid_path_cfg *) 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; soc_info = &csid_hw->hw_info->soc_info; - pxl_reg = csid_reg->ipp_reg; + if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) + pxl_reg = csid_reg->ipp_reg; + else + pxl_reg = csid_reg->ppp_reg; + if (!pxl_reg) { - CAM_ERR(CAM_ISP, "CSID:%d IPP :%d is not supported on HW", - csid_hw->hw_intf->hw_idx, res->res_id); + CAM_ERR(CAM_ISP, "CSID:%d %s :%d is not supported on HW", + csid_hw->hw_intf->hw_idx, + (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP", + res->res_id); return -EINVAL; } - CAM_DBG(CAM_ISP, "Config IPP Path"); - rc = cam_tfe_csid_get_format_ipp(path_data->in_format, + CAM_DBG(CAM_ISP, "Config %s Path", + (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); if (rc) return rc; @@ -1481,18 +1577,25 @@ static int cam_tfe_csid_deinit_pxl_path( csid_reg = csid_hw->csid_info->csid_reg; soc_info = &csid_hw->hw_info->soc_info; - pxl_reg = csid_reg->ipp_reg; + if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) + pxl_reg = csid_reg->ipp_reg; + else + pxl_reg = csid_reg->ppp_reg; + if (res->res_state != CAM_ISP_RESOURCE_STATE_INIT_HW) { 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, + (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP", res->res_type, res->res_id, res->res_state); rc = -EINVAL; } if (!pxl_reg) { - CAM_ERR(CAM_ISP, "CSID:%d IPP %d is not supported on HW", - csid_hw->hw_intf->hw_idx, res->res_id); + CAM_ERR(CAM_ISP, "CSID:%d %s %d is not supported on HW", + csid_hw->hw_intf->hw_idx, + (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) ? "IPP" : "PPP", + res->res_id); rc = -EINVAL; goto end; } @@ -1666,6 +1769,7 @@ static int cam_tfe_csid_disable_pxl_path( } pxl_reg = csid_reg->ipp_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); @@ -1718,6 +1822,164 @@ static int cam_tfe_csid_disable_pxl_path( 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( struct cam_tfe_csid_hw *csid_hw, struct cam_isp_resource_node *res) @@ -2032,6 +2294,14 @@ static int cam_tfe_csid_poll_stop_status( CAM_ISP_RESOURCE_STATE_STREAMING) 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 { csid_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, &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 { id = res->res_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); vbi = cam_io_r_mb(soc_info->reg_map[0].mem_base + 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) && (res->res_id <= CAM_TFE_CSID_PATH_RES_RDI_2)) { 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_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->minor_version = csid_reg->cmn_reg->minor_version; 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) 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); else 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); - 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); else 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: if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) 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 rc = cam_tfe_csid_enable_rdi_path(csid_hw, res); break; @@ -2756,6 +3049,9 @@ static int cam_tfe_csid_stop(void *hw_priv, if (res->res_id == CAM_TFE_CSID_PATH_RES_IPP) rc = cam_tfe_csid_disable_pxl_path(csid_hw, 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 rc = cam_tfe_csid_disable_rdi_path(csid_hw, 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++) { val = cam_io_r_mb(soc_info->reg_map[0].mem_base + 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); CAM_INFO(CAM_ISP, "offset 0x%x=0x08%x", 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 { id = res->res_id; 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); } + 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++) { if (evt_payload->irq_status[i] & TFE_CSID_PATH_INFO_INPUT_SOF) @@ -3330,13 +3672,14 @@ static int cam_tfe_csid_evt_bottom_half_handler( } } else { 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, evt_payload->evt_type, csid_hw->csi2_rx_cfg.phy_sel, 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_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_RDI1], 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; 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 *ppp_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_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; uint32_t sof_irq_debug_en = 0, log_en = 0; 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 + 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++) irq_status[i] = 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 + 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++) { cam_io_w_mb(irq_status[i], soc_info->reg_map[0].mem_base + @@ -3700,6 +4054,11 @@ handle_fatal_error: CAM_INFO_RATE_LIMIT(CAM_ISP, "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]) CAM_INFO_RATE_LIMIT(CAM_ISP, "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++) { if ((irq_status[i] & @@ -3860,13 +4290,14 @@ handle_fatal_error: } if (is_error_irq || log_en) { - CAM_ERR_RATE_LIMIT(CAM_ISP, - "CSID %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x", + CAM_ERR(CAM_ISP, + "CSID %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x PPP: 0x%x", csid_hw->hw_intf->hw_idx, irq_status[TFE_CSID_IRQ_REG_TOP], irq_status[TFE_CSID_IRQ_REG_RX], - irq_status[TFE_CSID_IRQ_REG_IPP]); - CAM_ERR_RATE_LIMIT(CAM_ISP, + irq_status[TFE_CSID_IRQ_REG_IPP], + irq_status[TFE_CSID_IRQ_REG_PPP]); + CAM_ERR(CAM_ISP, "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_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_csi2_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++) 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; } + /* 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 */ for (i = 0; i < tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; i++) { @@ -4077,6 +4527,8 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf, err: if (rc) { 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 < tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; 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 */ 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 < tfe_csid_hw->csid_info->csid_reg->cmn_reg->num_rdis; i++) { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h index f6dc91697a..8a77ae9794 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h @@ -58,9 +58,12 @@ #define TFE_CSID_PATH_IPP_ERROR_CCIF_VIOLATION BIT(15) #define TFE_CSID_PATH_IPP_FRAME_DROP BIT(16) #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_OVERFLOW_IRQ BIT(17) -#define TFE_CSID_PATH_RDI_ERROR_CCIF_VIOLATION BIT(18) /* * 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, }; +/* 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 * capture the timestamp @@ -470,6 +481,7 @@ struct cam_csid_evt_payload { * @csi2_rx_reserve_cnt: csi2 reservations count value * pxl_pipe_enable: flag to specify if the hardware has IPP * @ipp_res: image pixel path resource + * @ppp_res: PD pixel path resource * @rdi_res: raw dump image path resources * @cid_res: cid resources values * @csid_top_reset_complete: csid top reset completion @@ -510,11 +522,13 @@ struct cam_tfe_csid_hw { uint32_t csi2_reserve_cnt; uint32_t pxl_pipe_enable; 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_tfe_csid_cid_data cid_res[CAM_TFE_CSID_CID_MAX]; struct completion csid_top_complete; struct completion csid_csi2_complete; struct completion csid_ipp_complete; + struct completion csid_ppp_complete; struct completion csid_rdin_complete[CAM_TFE_CSID_RDI_MAX]; uint64_t csid_debug; uint64_t clk_rate; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c index bf2c05591b..665c53e732 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c @@ -81,6 +81,7 @@ struct cam_tfe_bus_common_data { uint32_t max_bw_counter_limit; uint32_t counter_limit_shift; uint32_t counter_limit_mask; + uint32_t pack_align_shift; }; 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_DS16: 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; 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; case CAM_ISP_TFE_OUT_RES_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: return CAM_TFE_BUS_TFE_OUT_MAX; } @@ -352,6 +362,17 @@ static int cam_tfe_bus_get_num_wm( 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: break; } @@ -553,6 +574,33 @@ static int cam_tfe_bus_get_wm_idx( 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: break; } @@ -868,6 +916,48 @@ static int cam_tfe_bus_acquire_wm( /*RS state packet format*/ if (rsrc_data->index == 15) 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 { CAM_ERR(CAM_ISP, "Invalid WM:%d requested", rsrc_data->index); return -EINVAL; @@ -1792,6 +1882,8 @@ static const char *cam_tfe_bus_rup_type( return "RDI1 RUP"; case CAM_ISP_HW_TFE_IN_RDI2: return "RDI2 RUP"; + case CAM_ISP_HW_TFE_IN_PDLIB: + return "PDLIB RUP"; default: 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.en_cfg_shift = hw_info->en_cfg_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++) bus_priv->bus_irq_error_mask[i] = diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h index b048c7b9c7..bea09d2be4 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h @@ -70,6 +70,7 @@ enum cam_tfe_bus_rup_grp_id { CAM_TFE_BUS_RUP_GRP_1, CAM_TFE_BUS_RUP_GRP_2, CAM_TFE_BUS_RUP_GRP_3, + CAM_TFE_BUS_RUP_GRP_4, 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_DS16, 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, }; @@ -202,6 +206,7 @@ struct cam_tfe_bus_tfe_out_hw_info { * @counter_limit_shift: Mask shift for BW counter limit * @counter_limit_mask: Default Mask of BW limit counter * @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_reg_offset_common common_reg; @@ -226,6 +231,7 @@ struct cam_tfe_bus_hw_info { uint32_t max_bw_counter_limit; uint32_t counter_limit_shift; uint32_t counter_limit_mask; + uint32_t pack_align_shift; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c index 10312e1403..cee8a1f91a 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c @@ -109,6 +109,23 @@ struct cam_tfe_rdi_data { 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) { 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_rdi_data *rdi_data; struct cam_tfe_top_reg_offset_common *common_reg; + struct cam_tfe_ppp_data *ppp_data; uint32_t i, val_0, val_1; 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->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 >= CAM_ISP_HW_TFE_IN_RDI0) || (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) 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) 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) 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) { CAM_INFO(CAM_ISP, "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) 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) CAM_INFO(CAM_ISP, "TFE %d DYNAMIC_SHDR_MODE_SWITCH_VIOLATION mup val %d", @@ -586,6 +638,84 @@ static int cam_tfe_rdi_irq_bottom_half( 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( struct cam_tfe_top_priv *top_priv, 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_camif_data *camif_priv; struct cam_tfe_rdi_data *rdi_priv; + struct cam_tfe_ppp_data *ppp_priv; cam_hw_mgr_event_cb_func event_cb = NULL; void *event_cb_priv = NULL; uint32_t i; @@ -719,6 +850,20 @@ static int cam_tfe_irq_bottom_half(void *handler_priv, &top_priv->in_rsrc[i], false, 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 >= CAM_ISP_HW_TFE_IN_RDI0) && (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, &top_priv->in_rsrc[i], true, 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 >= CAM_ISP_HW_TFE_IN_RDI0) && (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; 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; + } 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; @@ -1908,6 +2069,22 @@ int cam_tfe_set_top_debug(struct cam_tfe_hw_core_info *core_info, 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, 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_hw_tfe_in_acquire_args *acquire_args; struct cam_tfe_camif_data *camif_data; + struct cam_tfe_ppp_data *ppp_data; struct cam_tfe_rdi_data *rdi_data; uint32_t i; int rc = -EINVAL; @@ -1986,6 +2164,24 @@ int cam_tfe_top_reserve(void *device_priv, top_priv->in_rsrc[i].hw_intf->hw_idx, camif_data->pix_pattern, 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 { rdi_data = (struct cam_tfe_rdi_data *) top_priv->in_rsrc[i].res_priv; @@ -2212,6 +2408,45 @@ static int cam_tfe_camif_resource_start( 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, 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) { 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 && in_res->res_id <= CAM_ISP_HW_TFE_IN_RDI2) { 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_tfe_camif_data *camif_data; struct cam_tfe_rdi_data *rsrc_rdi_data; + struct cam_tfe_ppp_data *ppp_data; uint32_t val = 0; int i, rc = 0; @@ -2362,7 +2600,15 @@ int cam_tfe_top_stop(struct cam_tfe_hw_core_info *core_info, cam_io_w_mb(val, camif_data->mem_base + camif_data->common_reg->diag_config); } - } else if ((in_res->res_id >= CAM_ISP_HW_TFE_IN_RDI0) && + } 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) && (in_res->res_id <= CAM_ISP_HW_TFE_IN_RDI2)) { rsrc_rdi_data = (struct cam_tfe_rdi_data *) in_res->res_priv; cam_io_w_mb(0x0, rsrc_rdi_data->mem_base + @@ -2415,6 +2661,7 @@ int cam_tfe_top_init( struct cam_tfe_soc_private *soc_private = NULL; struct cam_tfe_camif_data *camif_priv = NULL; struct cam_tfe_rdi_data *rdi_priv = NULL; + struct cam_tfe_ppp_data *ppp_priv = NULL; int i, j, rc = 0; 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->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] == CAM_TFE_RDI_VER_1_0) { 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, arg_size); 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: CAM_ERR(CAM_ISP, "TFE:%d Invalid cmd type:%d", core_info->core_index, cmd_type); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h index 89b0d5ce99..c811b23606 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.h @@ -16,8 +16,9 @@ #define CAM_TFE_CAMIF_VER_1_0 0x10 #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_IN_PORT_MAX 4 +#define CAM_TFE_TOP_IN_PORT_MAX 5 #define CAM_TFE_RDI_MAX 4 #define CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS BIT(0) @@ -116,16 +117,20 @@ struct cam_tfe_top_reg_offset_common { /* error bit data */ uint32_t pp_camif_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 rdi1_camif_violation_bit; uint32_t rdi2_camif_violation_bit; uint32_t diag_violation_bit; uint32_t dyamanic_switch_violation_bit; uint32_t pp_frame_drop_bit; + uint32_t ppp_frame_drop_bit; uint32_t rdi0_frame_drop_bit; uint32_t rdi1_frame_drop_bit; uint32_t rdi2_frame_drop_bit; uint32_t pp_overflow_bit; + uint32_t ppp_overflow_bit; uint32_t rdi0_overflow_bit; uint32_t rdi1_overflow_bit; uint32_t rdi2_overflow_bit; @@ -237,6 +242,34 @@ struct cam_tfe_rdi_reg_data { 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 { uint8_t name[CAM_TFE_CLC_NAME_LENGTH_MAX]; 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_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_reg_offset_common *common_reg; 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_ppp_hw_info ppp_hw_info; uint32_t in_port[CAM_TFE_TOP_IN_PORT_MAX]; 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 {