msm: camera: cdm: Enable internal CDM

Add support to acquire IFE CDM instead of CPAS
CDM.

CRs-Fixed: 2571273
Change-Id: Iea3bcf236d00d39bf19e0997e6d21efcd5406a61
Signed-off-by: Jigar Agrawal <jigar@codeaurora.org>
Signed-off-by: Vishalsingh Hajeri <vhajeri@codeaurora.org>
This commit is contained in:
Vishalsingh Hajeri
2020-02-28 19:09:34 -08:00
parent d5c5960288
commit ca48923671
15 changed files with 1519 additions and 549 deletions

View File

@@ -1654,8 +1654,7 @@ static int cam_hw_cdm_component_bind(struct device *dev,
platform_set_drvdata(pdev, cdm_hw_intf); platform_set_drvdata(pdev, cdm_hw_intf);
snprintf(cdm_name, sizeof(cdm_name), "%s%d", snprintf(cdm_name, sizeof(cdm_name), "%s", cdm_hw->soc_info.label_name);
cdm_hw->soc_info.label_name, cdm_hw->soc_info.index);
rc = cam_smmu_get_handle(cdm_name, &cdm_core->iommu_hdl.non_secure); rc = cam_smmu_get_handle(cdm_name, &cdm_core->iommu_hdl.non_secure);
if (rc < 0) { if (rc < 0) {
@@ -1766,6 +1765,15 @@ static int cam_hw_cdm_component_bind(struct device *dev,
} }
cdm_hw->open_count++; cdm_hw->open_count++;
cdm_core->ops = cam_cdm_get_ops(cdm_core->hw_version, NULL,
false);
if (!cdm_core->ops) {
CAM_ERR(CAM_CDM, "Failed to util ops for hw");
rc = -EINVAL;
goto deinit;
}
if (!cam_cdm_set_cam_hw_version(cdm_core->hw_version, if (!cam_cdm_set_cam_hw_version(cdm_core->hw_version,
&cdm_core->version)) { &cdm_core->version)) {
CAM_ERR(CAM_CDM, "Failed to set cam hw version for hw"); CAM_ERR(CAM_CDM, "Failed to set cam hw version for hw");

View File

@@ -222,6 +222,14 @@ int cam_cdm_stream_off(uint32_t handle);
*/ */
int cam_cdm_reset_hw(uint32_t handle); int cam_cdm_reset_hw(uint32_t handle);
/**
* @brief : API to publish CDM ops to HW blocks like IFE
*
* @return : CDM operations
*
*/
struct cam_cdm_utils_ops *cam_cdm_publish_ops(void);
/** /**
* @brief : API to register CDM hw to platform framework. * @brief : API to register CDM hw to platform framework.
* @return struct platform_device pointer on on success, or ERR_PTR() on error. * @return struct platform_device pointer on on success, or ERR_PTR() on error.

View File

@@ -314,61 +314,71 @@ static int cam_isp_ctx_dump_req(
size_t *offset, size_t *offset,
bool dump_to_buff) bool dump_to_buff)
{ {
int i = 0, rc = 0; int i, j, rc = 0;
size_t len = 0; size_t len = 0;
uint32_t *buf_addr; uint32_t *buf_addr;
uint32_t *buf_start, *buf_end; uint32_t *buf_start, *buf_end;
size_t remain_len = 0; size_t remain_len = 0;
struct cam_cdm_cmd_buf_dump_info dump_info; struct cam_cdm_cmd_buf_dump_info dump_info;
uint32_t num_cfg;
struct cam_hw_update_entry *cfg;
for (i = 0; i < req_isp->num_cfg; i++) { for (j = 0; j < CAM_IFE_HW_NUM_MAX; j++) {
rc = cam_packet_util_get_cmd_mem_addr( num_cfg = req_isp->cfg_info[j].num_hw_entries;
req_isp->cfg[i].handle, &buf_addr, &len); cfg = req_isp->cfg_info[j].hw_entries;
if (rc) { for (i = 0; i < num_cfg; i++) {
CAM_ERR_RATE_LIMIT(CAM_ISP, rc = cam_packet_util_get_cmd_mem_addr(
"Failed to get_cmd_mem_addr, rc=%d", cfg[i].handle, &buf_addr, &len);
rc); if (rc) {
} else { CAM_ERR_RATE_LIMIT(CAM_ISP,
if (req_isp->cfg[i].offset >= ((uint32_t)len)) { "Failed to get_cmd_mem_addr, rc=%d",
CAM_ERR(CAM_ISP, rc);
"Invalid offset exp %u actual %u",
req_isp->cfg[i].offset, (uint32_t)len);
return rc;
}
remain_len = len - req_isp->cfg[i].offset;
if (req_isp->cfg[i].len >
((uint32_t)remain_len)) {
CAM_ERR(CAM_ISP,
"Invalid len exp %u remain_len %u",
req_isp->cfg[i].len,
(uint32_t)remain_len);
return rc;
}
buf_start = (uint32_t *)((uint8_t *) buf_addr +
req_isp->cfg[i].offset);
buf_end = (uint32_t *)((uint8_t *) buf_start +
req_isp->cfg[i].len - 1);
if (dump_to_buff) {
if (!cpu_addr || !offset || !buf_len) {
CAM_ERR(CAM_ISP, "Invalid args");
break;
}
dump_info.src_start = buf_start;
dump_info.src_end = buf_end;
dump_info.dst_start = cpu_addr;
dump_info.dst_offset = *offset;
dump_info.dst_max_size = buf_len;
rc = cam_cdm_util_dump_cmd_bufs_v2(&dump_info);
*offset = dump_info.dst_offset;
if (rc)
return rc;
} else { } else {
cam_cdm_util_dump_cmd_buf(buf_start, buf_end); if (cfg[i].offset >= ((uint32_t)len)) {
CAM_ERR(CAM_ISP,
"Invalid offset exp %u actual %u",
cfg[i].offset, (uint32_t)len);
return -EINVAL;
}
remain_len = len - cfg[i].offset;
if (req_isp->cfg_info[j].hw_entries[i].len >
((uint32_t)remain_len)) {
CAM_ERR(CAM_ISP,
"Invalid len exp %u remain_len %u",
cfg[i].len,
(uint32_t)remain_len);
return -EINVAL;
}
buf_start = (uint32_t *)((uint8_t *) buf_addr +
cfg[i].offset);
buf_end = (uint32_t *)((uint8_t *) buf_start +
cfg[i].len - 1);
if (dump_to_buff) {
if (!cpu_addr || !offset || !buf_len) {
CAM_ERR(CAM_ISP,
"Invalid args");
break;
}
dump_info.src_start = buf_start;
dump_info.src_end = buf_end;
dump_info.dst_start = cpu_addr;
dump_info.dst_offset = *offset;
dump_info.dst_max_size = buf_len;
rc = cam_cdm_util_dump_cmd_bufs_v2(
&dump_info);
*offset = dump_info.dst_offset;
if (rc)
return rc;
} else
cam_cdm_util_dump_cmd_buf(buf_start,
buf_end);
} }
} }
} }
return rc; return rc;
} }
@@ -419,13 +429,17 @@ static int __cam_isp_ctx_enqueue_request_in_order(
static int __cam_isp_ctx_enqueue_init_request( static int __cam_isp_ctx_enqueue_init_request(
struct cam_context *ctx, struct cam_ctx_request *req) struct cam_context *ctx, struct cam_ctx_request *req)
{ {
int rc = 0; int rc = 0, i = 0;
struct cam_ctx_request *req_old; struct cam_ctx_request *req_old;
struct cam_isp_ctx_req *req_isp_old; struct cam_isp_ctx_req *req_isp_old;
struct cam_isp_ctx_req *req_isp_new; struct cam_isp_ctx_req *req_isp_new;
struct cam_isp_prepare_hw_update_data *req_update_old; struct cam_isp_prepare_hw_update_data *req_update_old;
struct cam_isp_prepare_hw_update_data *req_update_new; struct cam_isp_prepare_hw_update_data *req_update_new;
struct cam_isp_prepare_hw_update_data *hw_update_data; struct cam_isp_prepare_hw_update_data *hw_update_data;
struct cam_hw_update_entry *cfg_old;
struct cam_hw_update_entry *cfg_new;
uint32_t num_cfg_old;
uint32_t num_cfg_new;
spin_lock_bh(&ctx->lock); spin_lock_bh(&ctx->lock);
if (list_empty(&ctx->pending_req_list)) { if (list_empty(&ctx->pending_req_list)) {
@@ -441,9 +455,12 @@ static int __cam_isp_ctx_enqueue_init_request(
req_isp_new = (struct cam_isp_ctx_req *) req->req_priv; req_isp_new = (struct cam_isp_ctx_req *) req->req_priv;
if (req_isp_old->hw_update_data.packet_opcode_type == if (req_isp_old->hw_update_data.packet_opcode_type ==
CAM_ISP_PACKET_INIT_DEV) { CAM_ISP_PACKET_INIT_DEV) {
if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >= if ((req_isp_old->total_num_cfg + req_isp_new->total_num_cfg) >=
CAM_ISP_CTX_CFG_MAX) { CAM_ISP_CTX_CFG_MAX) {
CAM_WARN(CAM_ISP, "Can not merge INIT pkt"); CAM_WARN(CAM_ISP,
"Can not merge INIT pkt total_num_cfgs = %d",
(req_isp_old->total_num_cfg +
req_isp_new->total_num_cfg));
rc = -ENOMEM; rc = -ENOMEM;
} }
@@ -468,11 +485,19 @@ static int __cam_isp_ctx_enqueue_init_request(
req_isp_old->num_fence_map_in = req_isp_old->num_fence_map_in =
req_isp_new->num_fence_map_in; req_isp_new->num_fence_map_in;
memcpy(&req_isp_old->cfg[req_isp_old->num_cfg], for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
req_isp_new->cfg, cfg_old = req_isp_old->cfg_info[i].hw_entries;
sizeof(req_isp_new->cfg[0])* cfg_new = req_isp_new->cfg_info[i].hw_entries;
req_isp_new->num_cfg); num_cfg_old =
req_isp_old->num_cfg += req_isp_new->num_cfg; req_isp_old->cfg_info[i].num_hw_entries;
num_cfg_new =
req_isp_old->cfg_info[i].num_hw_entries;
memcpy(&cfg_old[num_cfg_old],
cfg_new,
sizeof(cfg_new[0]) * num_cfg_new);
req_isp_old->cfg_info[i].num_hw_entries
+= num_cfg_new;
}
memcpy(&req_old->pf_data, &req->pf_data, memcpy(&req_old->pf_data, &req->pf_data,
sizeof(struct cam_hw_mgr_dump_pf_data)); sizeof(struct cam_hw_mgr_dump_pf_data));
@@ -1049,12 +1074,12 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
static int __cam_isp_ctx_apply_req_offline( static int __cam_isp_ctx_apply_req_offline(
void *priv, void *data) void *priv, void *data)
{ {
int rc = 0; int rc = 0, i = 0;
struct cam_context *ctx = NULL; struct cam_context *ctx = NULL;
struct cam_isp_context *ctx_isp = priv; struct cam_isp_context *ctx_isp = priv;
struct cam_ctx_request *req; struct cam_ctx_request *req;
struct cam_isp_ctx_req *req_isp; struct cam_isp_ctx_req *req_isp;
struct cam_hw_config_args cfg; struct cam_isp_hw_config_args cfg;
if (!ctx_isp) { if (!ctx_isp) {
CAM_ERR(CAM_ISP, "Invalid ctx_isp:%pK", ctx); CAM_ERR(CAM_ISP, "Invalid ctx_isp:%pK", ctx);
@@ -1088,8 +1113,12 @@ static int __cam_isp_ctx_apply_req_offline(
cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
cfg.request_id = req->request_id; cfg.request_id = req->request_id;
cfg.hw_update_entries = req_isp->cfg; for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
cfg.num_hw_update_entries = req_isp->num_cfg; cfg.hw_update_info[i].num_hw_entries =
req_isp->cfg_info[i].num_hw_entries;
cfg.hw_update_info[i].hw_entries =
req_isp->cfg_info[i].hw_entries;
}
cfg.priv = &req_isp->hw_update_data; cfg.priv = &req_isp->hw_update_data;
cfg.init_packet = 0; cfg.init_packet = 0;
@@ -2455,13 +2484,13 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, struct cam_context *ctx, struct cam_req_mgr_apply_request *apply,
enum cam_isp_ctx_activated_substate next_state) enum cam_isp_ctx_activated_substate next_state)
{ {
int rc = 0; int rc = 0, i;
struct cam_ctx_request *req; struct cam_ctx_request *req;
struct cam_ctx_request *active_req = NULL; struct cam_ctx_request *active_req = NULL;
struct cam_isp_ctx_req *req_isp; struct cam_isp_ctx_req *req_isp;
struct cam_isp_ctx_req *active_req_isp; struct cam_isp_ctx_req *active_req_isp;
struct cam_isp_context *ctx_isp = NULL; struct cam_isp_context *ctx_isp = NULL;
struct cam_hw_config_args cfg; struct cam_isp_hw_config_args isp_cfg;
if (list_empty(&ctx->pending_req_list)) { if (list_empty(&ctx->pending_req_list)) {
CAM_ERR(CAM_ISP, "No available request for Apply id %lld", CAM_ERR(CAM_ISP, "No available request for Apply id %lld",
@@ -2547,15 +2576,22 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
} }
req_isp->bubble_report = apply->report_if_bubble; req_isp->bubble_report = apply->report_if_bubble;
cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; memset(&isp_cfg, 0, sizeof(isp_cfg));
cfg.request_id = req->request_id;
cfg.hw_update_entries = req_isp->cfg;
cfg.num_hw_update_entries = req_isp->num_cfg;
cfg.priv = &req_isp->hw_update_data;
cfg.init_packet = 0;
cfg.reapply = req_isp->reapply;
rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); isp_cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
isp_cfg.request_id = req->request_id;
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
isp_cfg.hw_update_info[i].num_hw_entries =
req_isp->cfg_info[i].num_hw_entries;
isp_cfg.hw_update_info[i].hw_entries =
req_isp->cfg_info[i].hw_entries;
}
isp_cfg.priv = &req_isp->hw_update_data;
isp_cfg.init_packet = 0;
isp_cfg.reapply = req_isp->reapply;
rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv,
&isp_cfg);
if (rc) { if (rc) {
CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration"); CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
} else { } else {
@@ -3759,7 +3795,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
struct cam_packet *packet; struct cam_packet *packet;
size_t len = 0; size_t len = 0;
size_t remain_len = 0; size_t remain_len = 0;
struct cam_hw_prepare_update_args cfg; struct cam_isp_hw_update_args isp_cfg;
struct cam_req_mgr_add_request add_req; struct cam_req_mgr_add_request add_req;
struct cam_isp_context *ctx_isp = struct cam_isp_context *ctx_isp =
(struct cam_isp_context *) ctx->ctx_priv; (struct cam_isp_context *) ctx->ctx_priv;
@@ -3840,31 +3876,43 @@ static int __cam_isp_ctx_config_dev_in_top_state(
} }
/* preprocess the configuration */ /* preprocess the configuration */
memset(&cfg, 0, sizeof(cfg)); memset(&isp_cfg, 0, sizeof(isp_cfg));
cfg.packet = packet;
cfg.remain_len = remain_len; isp_cfg.packet = packet;
cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; isp_cfg.remain_len = remain_len;
cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX; isp_cfg.ctxt_to_hw_map = ctx_isp->hw_ctx;
cfg.hw_update_entries = req_isp->cfg; isp_cfg.max_hw_update_entries = CAM_ISP_CTX_CFG_MAX;
cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX; isp_cfg.max_out_map_entries = CAM_ISP_CTX_RES_MAX;
cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX; isp_cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX;
cfg.out_map_entries = req_isp->fence_map_out; isp_cfg.out_map_entries = req_isp->fence_map_out;
cfg.in_map_entries = req_isp->fence_map_in; isp_cfg.in_map_entries = req_isp->fence_map_in;
cfg.priv = &req_isp->hw_update_data; isp_cfg.priv = &req_isp->hw_update_data;
cfg.pf_data = &(req->pf_data); isp_cfg.pf_data = &(req->pf_data);
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++)
isp_cfg.hw_update_info[i].hw_entries
= req_isp->cfg_info[i].hw_entries;
CAM_DBG(CAM_ISP, "try to prepare config packet......"); CAM_DBG(CAM_ISP, "try to prepare config packet......");
rc = ctx->hw_mgr_intf->hw_prepare_update( rc = ctx->hw_mgr_intf->hw_prepare_update(
ctx->hw_mgr_intf->hw_mgr_priv, &cfg); ctx->hw_mgr_intf->hw_mgr_priv, &isp_cfg);
if (rc != 0) { if (rc != 0) {
CAM_ERR(CAM_ISP, "Prepare config packet failed in HW layer"); CAM_ERR(CAM_ISP, "Prepare config packet failed in HW layer");
rc = -EFAULT; rc = -EFAULT;
goto free_req; goto free_req;
} }
req_isp->num_cfg = cfg.num_hw_update_entries;
req_isp->num_fence_map_out = cfg.num_out_map_entries; req_isp->total_num_cfg = 0;
req_isp->num_fence_map_in = cfg.num_in_map_entries; for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
req_isp->cfg_info[i].num_hw_entries
= isp_cfg.hw_update_info[i].num_hw_entries;
req_isp->total_num_cfg +=
req_isp->cfg_info[i].num_hw_entries;
}
req_isp->num_fence_map_out = isp_cfg.num_out_map_entries;
req_isp->num_fence_map_in = isp_cfg.num_in_map_entries;
req_isp->num_acked = 0; req_isp->num_acked = 0;
req_isp->bubble_detected = false; req_isp->bubble_detected = false;
@@ -3878,7 +3926,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
} }
CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d", CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
req_isp->num_cfg, req_isp->num_fence_map_out, req_isp->total_num_cfg, req_isp->num_fence_map_out,
req_isp->num_fence_map_in); req_isp->num_fence_map_in);
req->request_id = packet->header.request_id; req->request_id = packet->header.request_id;
@@ -4604,8 +4652,14 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx; start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx;
start_isp.hw_config.request_id = req->request_id; start_isp.hw_config.request_id = req->request_id;
start_isp.hw_config.hw_update_entries = req_isp->cfg;
start_isp.hw_config.num_hw_update_entries = req_isp->num_cfg; for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) {
start_isp.hw_config.hw_update_info[i].hw_entries
= req_isp->cfg_info[i].hw_entries;
start_isp.hw_config.hw_update_info[i].num_hw_entries =
req_isp->cfg_info[i].num_hw_entries;
}
start_isp.hw_config.priv = &req_isp->hw_update_data; start_isp.hw_config.priv = &req_isp->hw_update_data;
start_isp.hw_config.init_packet = 1; start_isp.hw_config.init_packet = 1;
start_isp.hw_config.reapply = 0; start_isp.hw_config.reapply = 0;

View File

@@ -26,12 +26,6 @@
*/ */
#define CAM_ISP_CTX_RES_MAX 24 #define CAM_ISP_CTX_RES_MAX 24
/*
* Maximum configuration entry size - This is based on the
* worst case DUAL IFE use case plus some margin.
*/
#define CAM_ISP_CTX_CFG_MAX 22
/* /*
* Maximum entries in state monitoring array for error logging * Maximum entries in state monitoring array for error logging
*/ */
@@ -135,8 +129,8 @@ struct cam_isp_ctx_irq_ops {
* struct cam_isp_ctx_req - ISP context request object * struct cam_isp_ctx_req - ISP context request object
* *
* @base: Common request object ponter * @base: Common request object ponter
* @cfg: ISP hardware configuration array * @cfg_info: ISP hardware configuration array
* @num_cfg: Number of ISP hardware configuration entries * @total_num_cfg: Number of ISP hardware configuration entries
* @fence_map_out: Output fence mapping array * @fence_map_out: Output fence mapping array
* @num_fence_map_out: Number of the output fence map * @num_fence_map_out: Number of the output fence map
* @fence_map_in: Input fence mapping array * @fence_map_in: Input fence mapping array
@@ -153,9 +147,8 @@ struct cam_isp_ctx_irq_ops {
*/ */
struct cam_isp_ctx_req { struct cam_isp_ctx_req {
struct cam_ctx_request *base; struct cam_ctx_request *base;
struct cam_isp_hw_update_info cfg_info[CAM_IFE_HW_NUM_MAX];
struct cam_hw_update_entry cfg[CAM_ISP_CTX_CFG_MAX]; uint32_t total_num_cfg;
uint32_t num_cfg;
struct cam_hw_fence_map_entry fence_map_out struct cam_hw_fence_map_entry fence_map_out
[CAM_ISP_CTX_RES_MAX]; [CAM_ISP_CTX_RES_MAX];
uint32_t num_fence_map_out; uint32_t num_fence_map_out;

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,15 @@
#include "cam_ife_csid_hw_intf.h" #include "cam_ife_csid_hw_intf.h"
#include "cam_top_tpg_hw_intf.h" #include "cam_top_tpg_hw_intf.h"
#include "cam_tasklet_util.h" #include "cam_tasklet_util.h"
#include "cam_cdm_intf_api.h"
/* enum cam_ife_res_master_slave - HW resource master/slave */
enum cam_ife_res_master_slave {
CAM_IFE_RES_NONE,
CAM_IFE_RES_MASTER,
CAM_IFE_RES_SLAVE,
CAM_IFE_RES_MAX,
};
/* IFE resource constants */ /* IFE resource constants */
#define CAM_IFE_HW_IN_RES_MAX (CAM_ISP_IFE_IN_RES_MAX & 0xFF) #define CAM_IFE_HW_IN_RES_MAX (CAM_ISP_IFE_IN_RES_MAX & 0xFF)
@@ -90,6 +99,8 @@ struct cam_ife_hw_mgr_debug {
* @is_tpg indicate whether context is using PHY TPG * @is_tpg indicate whether context is using PHY TPG
* @is_offline Indicate whether context is for offline IFE * @is_offline Indicate whether context is for offline IFE
* @dsp_enabled Indicate whether dsp is enabled in this context * @dsp_enabled Indicate whether dsp is enabled in this context
* @hw_enabled Array to indicate active HW
* @internal_cdm Indicate whether context uses internal CDM
*/ */
struct cam_ife_hw_mgr_ctx { struct cam_ife_hw_mgr_ctx {
struct list_head list; struct list_head list;
@@ -117,7 +128,7 @@ struct cam_ife_hw_mgr_ctx {
uint32_t irq_status1_mask[CAM_IFE_HW_NUM_MAX]; uint32_t irq_status1_mask[CAM_IFE_HW_NUM_MAX];
struct cam_isp_ctx_base_info base[CAM_IFE_HW_NUM_MAX]; struct cam_isp_ctx_base_info base[CAM_IFE_HW_NUM_MAX];
uint32_t num_base; uint32_t num_base;
uint32_t cdm_handle; uint32_t cdm_handle[CAM_IFE_HW_NUM_MAX];
struct cam_cdm_utils_ops *cdm_ops; struct cam_cdm_utils_ops *cdm_ops;
struct cam_cdm_bl_request *cdm_cmd; struct cam_cdm_bl_request *cdm_cmd;
@@ -127,7 +138,10 @@ struct cam_ife_hw_mgr_ctx {
atomic_t overflow_pending; atomic_t overflow_pending;
atomic_t cdm_done; atomic_t cdm_done;
uint32_t is_rdi_only_context; uint32_t is_rdi_only_context;
struct completion config_done_complete; struct completion config_done_complete[
CAM_IFE_HW_NUM_MAX];
enum cam_ife_res_master_slave master_slave[CAM_IFE_HW_NUM_MAX];
uint32_t hw_version;
struct cam_cmd_buf_desc reg_dump_buf_desc[ struct cam_cmd_buf_desc reg_dump_buf_desc[
CAM_REG_DUMP_MAX_BUF_ENTRIES]; CAM_REG_DUMP_MAX_BUF_ENTRIES];
uint32_t num_reg_dump_buf; uint32_t num_reg_dump_buf;
@@ -143,6 +157,7 @@ struct cam_ife_hw_mgr_ctx {
bool is_tpg; bool is_tpg;
bool is_offline; bool is_offline;
bool dsp_enabled; bool dsp_enabled;
bool internal_cdm;
}; };
/** /**

View File

@@ -10,7 +10,7 @@
#include "cam_isp_hw_mgr_intf.h" #include "cam_isp_hw_mgr_intf.h"
#include "cam_tasklet_util.h" #include "cam_tasklet_util.h"
#include "cam_isp_hw.h" #include "cam_isp_hw.h"
#include "cam_cdm_intf_api.h"
#define CAM_ISP_HW_NUM_MAX 7 #define CAM_ISP_HW_NUM_MAX 7
@@ -91,5 +91,6 @@ struct cam_isp_hw_mgr_res {
struct cam_isp_ctx_base_info { struct cam_isp_ctx_base_info {
uint32_t idx; uint32_t idx;
enum cam_isp_hw_split_id split_id; enum cam_isp_hw_split_id split_id;
enum cam_cdm_id cdm_id;
}; };
#endif /* _CAM_ISP_HW_MGR_H_ */ #endif /* _CAM_ISP_HW_MGR_H_ */

View File

@@ -1759,6 +1759,8 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
goto err; goto err;
} }
memset(&tfe_ctx->cdm_handle, 0, sizeof(tfe_ctx->cdm_handle));
tfe_ctx->common.cb_priv = acquire_args->context_data; tfe_ctx->common.cb_priv = acquire_args->context_data;
for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++) for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++)
tfe_ctx->common.event_cb[i] = acquire_args->event_cb; tfe_ctx->common.event_cb[i] = acquire_args->event_cb;
@@ -1778,7 +1780,6 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
} }
cdm_acquire.base_array_cnt = j; cdm_acquire.base_array_cnt = j;
cdm_acquire.id = CAM_CDM_VIRTUAL; cdm_acquire.id = CAM_CDM_VIRTUAL;
cdm_acquire.cam_cdm_callback = cam_tfe_cam_cdm_callback; cdm_acquire.cam_cdm_callback = cam_tfe_cam_cdm_callback;
rc = cam_cdm_acquire(&cdm_acquire); rc = cam_cdm_acquire(&cdm_acquire);
@@ -1992,6 +1993,8 @@ static int cam_tfe_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
goto err; goto err;
} }
memset(&tfe_ctx->cdm_handle, 0, sizeof(tfe_ctx->cdm_handle));
tfe_ctx->common.cb_priv = acquire_args->context_data; tfe_ctx->common.cb_priv = acquire_args->context_data;
for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++) for (i = 0; i < CAM_ISP_HW_EVENT_MAX; i++)
tfe_ctx->common.event_cb[i] = acquire_args->event_cb; tfe_ctx->common.event_cb[i] = acquire_args->event_cb;
@@ -2322,14 +2325,15 @@ static int cam_isp_tfe_blob_bw_update(
static int cam_tfe_mgr_config_hw(void *hw_mgr_priv, static int cam_tfe_mgr_config_hw(void *hw_mgr_priv,
void *config_hw_args) void *config_hw_args)
{ {
int rc = -EINVAL, i, skip = 0; int rc = -EINVAL, i, j, k = 0, skip = 0;
struct cam_hw_config_args *cfg; struct cam_isp_hw_config_args *cfg;
struct cam_hw_update_entry *cmd; struct cam_hw_update_entry *cmd;
struct cam_cdm_bl_request *cdm_cmd; struct cam_cdm_bl_request *cdm_cmd;
struct cam_tfe_hw_mgr_ctx *ctx; struct cam_tfe_hw_mgr_ctx *ctx;
struct cam_isp_prepare_hw_update_data *hw_update_data; struct cam_isp_prepare_hw_update_data *hw_update_data;
uint32_t num_ent;
struct cam_hw_update_entry *cfg_info;
CAM_DBG(CAM_ISP, "Enter");
if (!hw_mgr_priv || !config_hw_args) { if (!hw_mgr_priv || !config_hw_args) {
CAM_ERR(CAM_ISP, "Invalid arguments"); CAM_ERR(CAM_ISP, "Invalid arguments");
return -EINVAL; return -EINVAL;
@@ -2373,68 +2377,79 @@ static int cam_tfe_mgr_config_hw(void *hw_mgr_priv,
} }
} }
CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP, "Enter ctx id:%d request id: %llu",
"Enter ctx id:%d num_hw_upd_entries %d request id: %llu", ctx->ctx_index, cfg->request_id);
ctx->ctx_index, cfg->num_hw_update_entries, cfg->request_id);
if (cfg->num_hw_update_entries > 0) { cdm_cmd = ctx->cdm_cmd;
cdm_cmd = ctx->cdm_cmd; cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries; cdm_cmd->flag = true;
cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE; cdm_cmd->userdata = hw_update_data;
cdm_cmd->flag = true; cdm_cmd->cookie = cfg->request_id;
cdm_cmd->userdata = hw_update_data; cdm_cmd->gen_irq_arb = false;
cdm_cmd->cookie = cfg->request_id; cdm_cmd->cmd_arrary_count = 0;
cdm_cmd->gen_irq_arb = false;
for (i = 0 ; i < cfg->num_hw_update_entries; i++) { for (i = 0; i < ctx->num_base; i++) {
cmd = (cfg->hw_update_entries + i); num_ent = cfg->hw_update_info[ctx->base[i].idx].num_hw_entries;
if (cfg->reapply && cmd->flags == CAM_ISP_IQ_BL) { cfg_info = cfg->hw_update_info[ctx->base[i].idx].hw_entries;
skip++; if (num_ent > 0) {
continue; for (j = 0 ; j < num_ent; j++) {
cmd = (cfg_info + j);
if (cfg->reapply &&
cmd->flags == CAM_ISP_IQ_BL) {
skip++;
continue;
}
if (cmd->flags == CAM_ISP_UNUSED_BL ||
cmd->flags >= CAM_ISP_BL_MAX)
CAM_ERR(CAM_ISP,
"Unexpected BL type %d",
cmd->flags);
cdm_cmd->cmd[j - skip + k].bl_addr.mem_handle =
cmd->handle;
cdm_cmd->cmd[j - skip + k].offset = cmd->offset;
cdm_cmd->cmd[j - skip + k].len = cmd->len;
cdm_cmd->cmd[j - skip + k].arbitrate = false;
} }
cdm_cmd->cmd_arrary_count += num_ent - skip;
if (cmd->flags == CAM_ISP_UNUSED_BL || k = cdm_cmd->cmd_arrary_count;
cmd->flags >= CAM_ISP_BL_MAX)
CAM_ERR(CAM_ISP, "Unexpected BL type %d",
cmd->flags);
cdm_cmd->cmd[i - skip].bl_addr.mem_handle = cmd->handle;
cdm_cmd->cmd[i - skip].offset = cmd->offset;
cdm_cmd->cmd[i - skip].len = cmd->len;
cdm_cmd->cmd[i - skip].arbitrate = false;
} }
cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries - skip; }
reinit_completion(&ctx->config_done_complete); ctx->applied_req_id = cfg->request_id;
ctx->applied_req_id = cfg->request_id; CAM_DBG(CAM_ISP, "Submit to CDM");
CAM_DBG(CAM_ISP, "Submit to CDM"); atomic_set(&ctx->cdm_done, 0);
atomic_set(&ctx->cdm_done, 0); reinit_completion(&ctx->config_done_complete);
rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd); rc = cam_cdm_submit_bls(ctx->cdm_handle, cdm_cmd);
if (rc) { if (rc) {
CAM_ERR(CAM_ISP, "Failed to apply the configs"); CAM_ERR(CAM_ISP,
return rc; "Failed to apply the configs for req %llu, rc %d",
cfg->request_id, rc);
return rc;
}
if (cfg->init_packet) {
rc = wait_for_completion_timeout(
&ctx->config_done_complete,
msecs_to_jiffies(
CAM_TFE_HW_CONFIG_TIMEOUT));
if (rc <= 0) {
CAM_ERR(CAM_ISP,
"config done completion timeout for req_id=%llu rc=%d ctx_index %d",
cfg->request_id, rc,
ctx->ctx_index);
if (rc == 0)
rc = -ETIMEDOUT;
} else {
rc = 0;
CAM_DBG(CAM_ISP,
"config done Success for req_id=%llu ctx_index %d",
cfg->request_id,
ctx->ctx_index);
} }
if (cfg->init_packet) {
rc = wait_for_completion_timeout(
&ctx->config_done_complete,
msecs_to_jiffies(CAM_TFE_HW_CONFIG_TIMEOUT));
if (rc <= 0) {
CAM_ERR(CAM_ISP,
"config done completion timeout for req_id=%llu rc=%d ctx_index %d",
cfg->request_id, rc, ctx->ctx_index);
if (rc == 0)
rc = -ETIMEDOUT;
} else {
rc = 0;
CAM_DBG(CAM_ISP,
"config done Success for req_id=%llu ctx_index %d",
cfg->request_id, ctx->ctx_index);
}
}
} else {
CAM_ERR(CAM_ISP, "No commands to config");
} }
CAM_DBG(CAM_ISP, "Exit: Config Done: %llu", cfg->request_id); CAM_DBG(CAM_ISP, "Exit: Config Done: %llu", cfg->request_id);
@@ -2642,7 +2657,8 @@ static int cam_tfe_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
cam_tfe_mgr_pause_hw(ctx); cam_tfe_mgr_pause_hw(ctx);
wait_for_completion(&ctx->config_done_complete); wait_for_completion_timeout(&ctx->config_done_complete,
msecs_to_jiffies(5));
if (stop_isp->stop_only) if (stop_isp->stop_only)
goto end; goto end;
@@ -3069,18 +3085,18 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
return rc; return rc;
} }
static int cam_isp_tfe_blob_hfr_update( static int cam_isp_tfe_blob_hfr_update(
uint32_t blob_type, uint32_t blob_type,
struct cam_isp_generic_blob_info *blob_info, struct cam_isp_generic_blob_info *blob_info,
struct cam_isp_tfe_resource_hfr_config *hfr_config, struct cam_isp_tfe_resource_hfr_config *hfr_config,
struct cam_hw_prepare_update_args *prepare) struct cam_isp_hw_update_args *prepare)
{ {
struct cam_isp_tfe_port_hfr_config *port_hfr_config; struct cam_isp_tfe_port_hfr_config *port_hfr_config;
struct cam_kmd_buf_info *kmd_buf_info; struct cam_kmd_buf_info *kmd_buf_info;
struct cam_tfe_hw_mgr_ctx *ctx = NULL; struct cam_tfe_hw_mgr_ctx *ctx = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_mgr_res *hw_mgr_res;
uint32_t res_id_out, i; struct cam_hw_update_entry *hw_entry;
uint32_t res_id_out, i, slot_idx = 0;
uint32_t total_used_bytes = 0; uint32_t total_used_bytes = 0;
uint32_t kmd_buf_remain_size; uint32_t kmd_buf_remain_size;
uint32_t *cmd_buf_addr; uint32_t *cmd_buf_addr;
@@ -3090,11 +3106,15 @@ static int cam_isp_tfe_blob_hfr_update(
ctx = prepare->ctxt_to_hw_map; ctx = prepare->ctxt_to_hw_map;
CAM_DBG(CAM_ISP, "num_ports= %d", hfr_config->num_ports); CAM_DBG(CAM_ISP, "num_ports= %d", hfr_config->num_ports);
slot_idx = blob_info->base_info->idx;
hw_entry = prepare->hw_update_info[slot_idx].hw_entries;
num_ent = prepare->hw_update_info[slot_idx].num_hw_entries;
/* Max one hw entries required for hfr config update */ /* Max one hw entries required for hfr config update */
if (prepare->num_hw_update_entries + 1 >= if (prepare->hw_update_info[slot_idx].num_hw_entries + 1 >=
prepare->max_hw_update_entries) { prepare->max_hw_update_entries) {
CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d",
prepare->num_hw_update_entries, prepare->hw_update_info[slot_idx].num_hw_entries,
prepare->max_hw_update_entries); prepare->max_hw_update_entries);
return -EINVAL; return -EINVAL;
} }
@@ -3150,17 +3170,17 @@ static int cam_isp_tfe_blob_hfr_update(
if (total_used_bytes) { if (total_used_bytes) {
/* Update the HW entries */ /* Update the HW entries */
num_ent = prepare->num_hw_update_entries; hw_entry[num_ent].handle =
prepare->hw_update_entries[num_ent].handle =
kmd_buf_info->handle; kmd_buf_info->handle;
prepare->hw_update_entries[num_ent].len = total_used_bytes; hw_entry[num_ent].len =
prepare->hw_update_entries[num_ent].offset = total_used_bytes;
hw_entry[num_ent].offset =
kmd_buf_info->offset; kmd_buf_info->offset;
num_ent++; num_ent++;
kmd_buf_info->used_bytes += total_used_bytes; kmd_buf_info->used_bytes += total_used_bytes;
kmd_buf_info->offset += total_used_bytes; kmd_buf_info->offset += total_used_bytes;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[slot_idx].num_hw_entries
= num_ent;
} }
return rc; return rc;
@@ -3170,7 +3190,7 @@ static int cam_isp_tfe_blob_csid_clock_update(
uint32_t blob_type, uint32_t blob_type,
struct cam_isp_generic_blob_info *blob_info, struct cam_isp_generic_blob_info *blob_info,
struct cam_isp_tfe_csid_clock_config *clock_config, struct cam_isp_tfe_csid_clock_config *clock_config,
struct cam_hw_prepare_update_args *prepare) struct cam_isp_hw_update_args *prepare)
{ {
struct cam_tfe_hw_mgr_ctx *ctx = NULL; struct cam_tfe_hw_mgr_ctx *ctx = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_mgr_res *hw_mgr_res;
@@ -3234,7 +3254,7 @@ static int cam_isp_tfe_blob_clock_update(
uint32_t blob_type, uint32_t blob_type,
struct cam_isp_generic_blob_info *blob_info, struct cam_isp_generic_blob_info *blob_info,
struct cam_isp_tfe_clock_config *clock_config, struct cam_isp_tfe_clock_config *clock_config,
struct cam_hw_prepare_update_args *prepare) struct cam_isp_hw_update_args *prepare)
{ {
struct cam_tfe_hw_mgr_ctx *ctx = NULL; struct cam_tfe_hw_mgr_ctx *ctx = NULL;
struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_mgr_res *hw_mgr_res;
@@ -3323,7 +3343,7 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
{ {
int rc = 0; int rc = 0;
struct cam_isp_generic_blob_info *blob_info = user_data; struct cam_isp_generic_blob_info *blob_info = user_data;
struct cam_hw_prepare_update_args *prepare = NULL; struct cam_isp_hw_update_args *prepare = NULL;
if (!blob_data || (blob_size == 0) || !blob_info) { if (!blob_data || (blob_size == 0) || !blob_info) {
CAM_ERR(CAM_ISP, "Invalid args data %pK size %d info %pK", CAM_ERR(CAM_ISP, "Invalid args data %pK size %d info %pK",
@@ -3524,7 +3544,7 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
} }
static int cam_tfe_update_dual_config( static int cam_tfe_update_dual_config(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct cam_cmd_buf_desc *cmd_desc, struct cam_cmd_buf_desc *cmd_desc,
uint32_t split_id, uint32_t split_id,
uint32_t base_idx, uint32_t base_idx,
@@ -3633,7 +3653,7 @@ end:
} }
int cam_tfe_add_command_buffers( int cam_tfe_add_command_buffers(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct cam_kmd_buf_info *kmd_buf_info, struct cam_kmd_buf_info *kmd_buf_info,
struct cam_isp_ctx_base_info *base_info, struct cam_isp_ctx_base_info *base_info,
cam_packet_generic_blob_handler blob_handler_cb, cam_packet_generic_blob_handler blob_handler_cb,
@@ -3645,12 +3665,13 @@ int cam_tfe_add_command_buffers(
uint32_t base_idx; uint32_t base_idx;
enum cam_isp_hw_split_id split_id; enum cam_isp_hw_split_id split_id;
struct cam_cmd_buf_desc *cmd_desc = NULL; struct cam_cmd_buf_desc *cmd_desc = NULL;
struct cam_hw_update_entry *hw_entry; struct cam_hw_update_entry *hw_entry = NULL;
struct cam_isp_hw_update_entry_info *hw_info;
hw_entry = prepare->hw_update_entries;
split_id = base_info->split_id; split_id = base_info->split_id;
base_idx = base_info->idx; base_idx = base_info->idx;
hw_entry = prepare->hw_update_info[base_idx].hw_entries;
hw_info = prepare->hw_update_info;
/* /*
* set the cmd_desc to point the first command descriptor in the * set the cmd_desc to point the first command descriptor in the
* packet * packet
@@ -3663,7 +3684,7 @@ int cam_tfe_add_command_buffers(
split_id, prepare->packet->num_cmd_buf); split_id, prepare->packet->num_cmd_buf);
for (i = 0; i < prepare->packet->num_cmd_buf; i++) { for (i = 0; i < prepare->packet->num_cmd_buf; i++) {
num_ent = prepare->num_hw_update_entries; num_ent = prepare->hw_update_info[base_idx].num_hw_entries;
if (!cmd_desc[i].length) if (!cmd_desc[i].length)
continue; continue;
@@ -3748,7 +3769,8 @@ int cam_tfe_add_command_buffers(
case CAM_ISP_TFE_PACKET_META_GENERIC_BLOB_COMMON: { case CAM_ISP_TFE_PACKET_META_GENERIC_BLOB_COMMON: {
struct cam_isp_generic_blob_info blob_info; struct cam_isp_generic_blob_info blob_info;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries =
num_ent;
blob_info.prepare = prepare; blob_info.prepare = prepare;
blob_info.base_info = base_info; blob_info.base_info = base_info;
blob_info.kmd_buf_info = kmd_buf_info; blob_info.kmd_buf_info = kmd_buf_info;
@@ -3763,7 +3785,7 @@ int cam_tfe_add_command_buffers(
return rc; return rc;
} }
hw_entry[num_ent].flags = CAM_ISP_IQ_BL; hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
num_ent = prepare->num_hw_update_entries; num_ent = hw_info[base_idx].num_hw_entries;
} }
break; break;
case CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_FLUSH: case CAM_ISP_TFE_PACKET_META_REG_DUMP_ON_FLUSH:
@@ -3791,7 +3813,8 @@ int cam_tfe_add_command_buffers(
cmd_meta_data); cmd_meta_data);
return -EINVAL; return -EINVAL;
} }
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries
= num_ent;
} }
return rc; return rc;
@@ -3801,8 +3824,8 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
void *prepare_hw_update_args) void *prepare_hw_update_args)
{ {
int rc = 0; int rc = 0;
struct cam_hw_prepare_update_args *prepare = struct cam_isp_hw_update_args *prepare =
(struct cam_hw_prepare_update_args *) prepare_hw_update_args; (struct cam_isp_hw_update_args *) prepare_hw_update_args;
struct cam_tfe_hw_mgr_ctx *ctx; struct cam_tfe_hw_mgr_ctx *ctx;
struct cam_tfe_hw_mgr *hw_mgr; struct cam_tfe_hw_mgr *hw_mgr;
struct cam_kmd_buf_info kmd_buf; struct cam_kmd_buf_info kmd_buf;
@@ -3843,7 +3866,6 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
return rc; return rc;
} }
prepare->num_hw_update_entries = 0;
prepare->num_in_map_entries = 0; prepare->num_in_map_entries = 0;
prepare->num_out_map_entries = 0; prepare->num_out_map_entries = 0;
prepare->num_reg_dump_buf = 0; prepare->num_reg_dump_buf = 0;

View File

@@ -10,9 +10,10 @@
#include "cam_vfe_hw_intf.h" #include "cam_vfe_hw_intf.h"
#include "cam_isp_packet_parser.h" #include "cam_isp_packet_parser.h"
#include "cam_debug_util.h" #include "cam_debug_util.h"
#include "cam_isp_hw_mgr_intf.h"
int cam_isp_add_change_base( int cam_isp_add_change_base(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src, struct list_head *res_list_isp_src,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info) struct cam_kmd_buf_info *kmd_buf_info)
@@ -24,8 +25,8 @@ int cam_isp_add_change_base(
struct cam_hw_update_entry *hw_entry; struct cam_hw_update_entry *hw_entry;
uint32_t num_ent, i; uint32_t num_ent, i;
hw_entry = prepare->hw_update_entries; hw_entry = prepare->hw_update_info[base_idx].hw_entries;
num_ent = prepare->num_hw_update_entries; num_ent = prepare->hw_update_info[base_idx].num_hw_entries;
/* Max one hw entries required for each base */ /* Max one hw entries required for each base */
if (num_ent + 1 >= prepare->max_hw_update_entries) { if (num_ent + 1 >= prepare->max_hw_update_entries) {
@@ -76,7 +77,8 @@ int cam_isp_add_change_base(
kmd_buf_info->used_bytes += get_base.cmd.used_bytes; kmd_buf_info->used_bytes += get_base.cmd.used_bytes;
kmd_buf_info->offset += get_base.cmd.used_bytes; kmd_buf_info->offset += get_base.cmd.used_bytes;
num_ent++; num_ent++;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries
= num_ent;
/* return success */ /* return success */
return 0; return 0;
@@ -87,7 +89,7 @@ int cam_isp_add_change_base(
} }
static int cam_isp_update_dual_config( static int cam_isp_update_dual_config(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct cam_cmd_buf_desc *cmd_desc, struct cam_cmd_buf_desc *cmd_desc,
uint32_t split_id, uint32_t split_id,
uint32_t base_idx, uint32_t base_idx,
@@ -241,7 +243,7 @@ int cam_isp_add_cmd_buf_update(
} }
int cam_isp_add_command_buffers( int cam_isp_add_command_buffers(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct cam_kmd_buf_info *kmd_buf_info, struct cam_kmd_buf_info *kmd_buf_info,
struct cam_isp_ctx_base_info *base_info, struct cam_isp_ctx_base_info *base_info,
cam_packet_generic_blob_handler blob_handler_cb, cam_packet_generic_blob_handler blob_handler_cb,
@@ -253,12 +255,13 @@ int cam_isp_add_command_buffers(
uint32_t base_idx; uint32_t base_idx;
enum cam_isp_hw_split_id split_id; enum cam_isp_hw_split_id split_id;
struct cam_cmd_buf_desc *cmd_desc = NULL; struct cam_cmd_buf_desc *cmd_desc = NULL;
struct cam_hw_update_entry *hw_entry; struct cam_hw_update_entry *hw_entry = NULL;
struct cam_isp_hw_update_entry_info *hw_info;
hw_entry = prepare->hw_update_entries;
split_id = base_info->split_id; split_id = base_info->split_id;
base_idx = base_info->idx; base_idx = base_info->idx;
hw_entry = prepare->hw_update_info[base_idx].hw_entries;
hw_info = prepare->hw_update_info;
/* /*
* set the cmd_desc to point the first command descriptor in the * set the cmd_desc to point the first command descriptor in the
* packet * packet
@@ -271,7 +274,8 @@ int cam_isp_add_command_buffers(
split_id, prepare->packet->num_cmd_buf); split_id, prepare->packet->num_cmd_buf);
for (i = 0; i < prepare->packet->num_cmd_buf; i++) { for (i = 0; i < prepare->packet->num_cmd_buf; i++) {
num_ent = prepare->num_hw_update_entries; num_ent =
prepare->hw_update_info[base_idx].num_hw_entries;
if (!cmd_desc[i].length) if (!cmd_desc[i].length)
continue; continue;
@@ -358,7 +362,8 @@ int cam_isp_add_command_buffers(
if (split_id == CAM_ISP_HW_SPLIT_LEFT) { if (split_id == CAM_ISP_HW_SPLIT_LEFT) {
struct cam_isp_generic_blob_info blob_info; struct cam_isp_generic_blob_info blob_info;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries
= num_ent;
blob_info.prepare = prepare; blob_info.prepare = prepare;
blob_info.base_info = base_info; blob_info.base_info = base_info;
blob_info.kmd_buf_info = kmd_buf_info; blob_info.kmd_buf_info = kmd_buf_info;
@@ -374,14 +379,15 @@ int cam_isp_add_command_buffers(
return rc; return rc;
} }
hw_entry[num_ent].flags = CAM_ISP_IQ_BL; hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
num_ent = prepare->num_hw_update_entries; num_ent = hw_info[base_idx].num_hw_entries;
} }
break; break;
case CAM_ISP_PACKET_META_GENERIC_BLOB_RIGHT: case CAM_ISP_PACKET_META_GENERIC_BLOB_RIGHT:
if (split_id == CAM_ISP_HW_SPLIT_RIGHT) { if (split_id == CAM_ISP_HW_SPLIT_RIGHT) {
struct cam_isp_generic_blob_info blob_info; struct cam_isp_generic_blob_info blob_info;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries
= num_ent;
blob_info.prepare = prepare; blob_info.prepare = prepare;
blob_info.base_info = base_info; blob_info.base_info = base_info;
blob_info.kmd_buf_info = kmd_buf_info; blob_info.kmd_buf_info = kmd_buf_info;
@@ -397,13 +403,14 @@ int cam_isp_add_command_buffers(
return rc; return rc;
} }
hw_entry[num_ent].flags = CAM_ISP_IQ_BL; hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
num_ent = prepare->num_hw_update_entries; num_ent = hw_info[base_idx].num_hw_entries;
} }
break; break;
case CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON: { case CAM_ISP_PACKET_META_GENERIC_BLOB_COMMON: {
struct cam_isp_generic_blob_info blob_info; struct cam_isp_generic_blob_info blob_info;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries =
num_ent;
blob_info.prepare = prepare; blob_info.prepare = prepare;
blob_info.base_info = base_info; blob_info.base_info = base_info;
blob_info.kmd_buf_info = kmd_buf_info; blob_info.kmd_buf_info = kmd_buf_info;
@@ -418,7 +425,7 @@ int cam_isp_add_command_buffers(
return rc; return rc;
} }
hw_entry[num_ent].flags = CAM_ISP_IQ_BL; hw_entry[num_ent].flags = CAM_ISP_IQ_BL;
num_ent = prepare->num_hw_update_entries; num_ent = hw_info[base_idx].num_hw_entries;
} }
break; break;
case CAM_ISP_PACKET_META_REG_DUMP_ON_FLUSH: case CAM_ISP_PACKET_META_REG_DUMP_ON_FLUSH:
@@ -448,7 +455,8 @@ int cam_isp_add_command_buffers(
cmd_meta_data); cmd_meta_data);
return -EINVAL; return -EINVAL;
} }
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries
= num_ent;
} }
return rc; return rc;
@@ -457,7 +465,7 @@ int cam_isp_add_command_buffers(
int cam_isp_add_io_buffers( int cam_isp_add_io_buffers(
int iommu_hdl, int iommu_hdl,
int sec_iommu_hdl, int sec_iommu_hdl,
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info, struct cam_kmd_buf_info *kmd_buf_info,
struct cam_isp_hw_mgr_res *res_list_isp_out, struct cam_isp_hw_mgr_res *res_list_isp_out,
@@ -473,6 +481,7 @@ int cam_isp_add_io_buffers(
struct cam_isp_hw_mgr_res *hw_mgr_res; struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_get_cmd_update update_buf; struct cam_isp_hw_get_cmd_update update_buf;
struct cam_isp_hw_get_wm_update wm_update; struct cam_isp_hw_get_wm_update wm_update;
struct cam_hw_update_entry *hw_entry;
struct cam_isp_hw_get_wm_update bus_rd_update; struct cam_isp_hw_get_wm_update bus_rd_update;
struct cam_hw_fence_map_entry *out_map_entries; struct cam_hw_fence_map_entry *out_map_entries;
struct cam_hw_fence_map_entry *in_map_entries; struct cam_hw_fence_map_entry *in_map_entries;
@@ -495,12 +504,14 @@ int cam_isp_add_io_buffers(
num_in_buf = 0; num_in_buf = 0;
io_cfg_used_bytes = 0; io_cfg_used_bytes = 0;
prepare->pf_data->packet = prepare->packet; prepare->pf_data->packet = prepare->packet;
hw_entry = prepare->hw_update_info[base_idx].hw_entries;
num_ent = prepare->hw_update_info[base_idx].num_hw_entries;
/* Max one hw entries required for each base */ /* Max one hw entries required for each base */
if (prepare->num_hw_update_entries + 1 >= if (num_ent + 1 >=
prepare->max_hw_update_entries) { prepare->max_hw_update_entries) {
CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d",
prepare->num_hw_update_entries, prepare->hw_update_info[base_idx].num_hw_entries,
prepare->max_hw_update_entries); prepare->max_hw_update_entries);
return -EINVAL; return -EINVAL;
} }
@@ -852,25 +863,21 @@ int cam_isp_add_io_buffers(
io_cfg_used_bytes, fill_fence); io_cfg_used_bytes, fill_fence);
if (io_cfg_used_bytes) { if (io_cfg_used_bytes) {
/* Update the HW entries */ /* Update the HW entries */
num_ent = prepare->num_hw_update_entries; hw_entry[num_ent].handle = kmd_buf_info->handle;
prepare->hw_update_entries[num_ent].handle = hw_entry[num_ent].len = io_cfg_used_bytes;
kmd_buf_info->handle; hw_entry[num_ent].offset = kmd_buf_info->offset;
prepare->hw_update_entries[num_ent].len = io_cfg_used_bytes; hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL;
prepare->hw_update_entries[num_ent].offset =
kmd_buf_info->offset;
prepare->hw_update_entries[num_ent].flags =
CAM_ISP_IOCFG_BL;
CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP,
"num_ent=%d handle=0x%x, len=%u, offset=%u", "num_ent=%d handle=0x%x, len=%u, offset=%u",
num_ent, num_ent,
prepare->hw_update_entries[num_ent].handle, hw_entry[num_ent].handle,
prepare->hw_update_entries[num_ent].len, hw_entry[num_ent].len,
prepare->hw_update_entries[num_ent].offset); hw_entry[num_ent].offset);
num_ent++; num_ent++;
kmd_buf_info->used_bytes += io_cfg_used_bytes; kmd_buf_info->used_bytes += io_cfg_used_bytes;
kmd_buf_info->offset += io_cfg_used_bytes; kmd_buf_info->offset += io_cfg_used_bytes;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries = num_ent;
} }
if (fill_fence) { if (fill_fence) {
@@ -881,9 +888,8 @@ int cam_isp_add_io_buffers(
return rc; return rc;
} }
int cam_isp_add_reg_update( int cam_isp_add_reg_update(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src, struct list_head *res_list_isp_src,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info) struct cam_kmd_buf_info *kmd_buf_info)
@@ -895,12 +901,13 @@ int cam_isp_add_reg_update(
struct cam_isp_hw_get_cmd_update get_regup; struct cam_isp_hw_get_cmd_update get_regup;
uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size; uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size;
hw_entry = prepare->hw_update_entries; hw_entry = prepare->hw_update_info[base_idx].hw_entries;
num_ent = prepare->hw_update_info[base_idx].num_hw_entries;
/* Max one hw entries required for each base */ /* Max one hw entries required for each base */
if (prepare->num_hw_update_entries + 1 >= if (num_ent + 1 >= prepare->max_hw_update_entries) {
prepare->max_hw_update_entries) {
CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d", CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d",
prepare->num_hw_update_entries, num_ent,
prepare->max_hw_update_entries); prepare->max_hw_update_entries);
return -EINVAL; return -EINVAL;
} }
@@ -946,35 +953,32 @@ int cam_isp_add_reg_update(
if (rc) if (rc)
return rc; return rc;
CAM_DBG(CAM_ISP, "Reg update added for res %d hw_id %d", CAM_DBG(CAM_ISP,
res->res_type, res->hw_intf->hw_idx); "Reg update added for res %d hw_id %d cdm_idx %d",
res->res_id, res->hw_intf->hw_idx, base_idx);
reg_update_size += get_regup.cmd.used_bytes; reg_update_size += get_regup.cmd.used_bytes;
} }
} }
if (reg_update_size) { if (reg_update_size) {
/* Update the HW entries */ /* Update the HW entries */
num_ent = prepare->num_hw_update_entries; hw_entry[num_ent].handle = kmd_buf_info->handle;
prepare->hw_update_entries[num_ent].handle = hw_entry[num_ent].len = reg_update_size;
kmd_buf_info->handle; hw_entry[num_ent].offset = kmd_buf_info->offset;
prepare->hw_update_entries[num_ent].len = reg_update_size;
prepare->hw_update_entries[num_ent].offset =
kmd_buf_info->offset;
/* Marking reg update as IOCFG to reapply on bubble */ /* Marking reg update as IOCFG to reapply on bubble */
prepare->hw_update_entries[num_ent].flags = hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL;
CAM_ISP_IOCFG_BL;
CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP,
"num_ent=%d handle=0x%x, len=%u, offset=%u", "num_ent=%d handle=0x%x, len=%u, offset=%u",
num_ent, num_ent,
prepare->hw_update_entries[num_ent].handle, hw_entry[num_ent].handle,
prepare->hw_update_entries[num_ent].len, hw_entry[num_ent].len,
prepare->hw_update_entries[num_ent].offset); hw_entry[num_ent].offset);
num_ent++; num_ent++;
kmd_buf_info->used_bytes += reg_update_size; kmd_buf_info->used_bytes += reg_update_size;
kmd_buf_info->offset += reg_update_size; kmd_buf_info->offset += reg_update_size;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries = num_ent;
/* reg update is success return status 0 */ /* reg update is success return status 0 */
rc = 0; rc = 0;
} }
@@ -983,7 +987,7 @@ int cam_isp_add_reg_update(
} }
int cam_isp_add_go_cmd( int cam_isp_add_go_cmd(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_rd, struct list_head *res_list_isp_rd,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info) struct cam_kmd_buf_info *kmd_buf_info)
@@ -995,11 +999,13 @@ int cam_isp_add_go_cmd(
struct cam_isp_hw_get_cmd_update get_regup; struct cam_isp_hw_get_cmd_update get_regup;
uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size; uint32_t kmd_buf_remain_size, num_ent, i, reg_update_size;
hw_entry = prepare->hw_update_entries; hw_entry = prepare->hw_update_info[base_idx].hw_entries;
if (prepare->num_hw_update_entries + 1 >= num_ent = prepare->hw_update_info[base_idx].num_hw_entries;
prepare->max_hw_update_entries) {
CAM_ERR(CAM_ISP, "Insufficient HW entries current: %d max: %d", /* Max one hw entries required for each base */
prepare->num_hw_update_entries, if (num_ent + 1 >= prepare->max_hw_update_entries) {
CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d",
num_ent,
prepare->max_hw_update_entries); prepare->max_hw_update_entries);
return -EINVAL; return -EINVAL;
} }
@@ -1052,26 +1058,236 @@ int cam_isp_add_go_cmd(
if (reg_update_size) { if (reg_update_size) {
/* Update the HW entries */ /* Update the HW entries */
num_ent = prepare->num_hw_update_entries; hw_entry[num_ent].handle = kmd_buf_info->handle;
prepare->hw_update_entries[num_ent].handle = hw_entry[num_ent].len = reg_update_size;
kmd_buf_info->handle; hw_entry[num_ent].offset = kmd_buf_info->offset;
prepare->hw_update_entries[num_ent].len = reg_update_size;
prepare->hw_update_entries[num_ent].offset =
kmd_buf_info->offset;
prepare->hw_update_entries[num_ent].flags = hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL;
CAM_ISP_IOCFG_BL;
CAM_DBG(CAM_ISP, CAM_DBG(CAM_ISP,
"num_ent=%d handle=0x%x, len=%u, offset=%u", "num_ent=%d handle=0x%x, len=%u, offset=%u",
num_ent, num_ent,
prepare->hw_update_entries[num_ent].handle, hw_entry[num_ent].handle,
prepare->hw_update_entries[num_ent].len, hw_entry[num_ent].len,
prepare->hw_update_entries[num_ent].offset); hw_entry[num_ent].offset);
num_ent++; num_ent++;
kmd_buf_info->used_bytes += reg_update_size; kmd_buf_info->used_bytes += reg_update_size;
kmd_buf_info->offset += reg_update_size; kmd_buf_info->offset += reg_update_size;
prepare->num_hw_update_entries = num_ent; prepare->hw_update_info[base_idx].num_hw_entries = num_ent;
rc = 0;
}
return rc;
}
int cam_isp_add_comp_wait(
struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info)
{
int rc = -EINVAL;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_hw_update_entry *hw_entry;
struct cam_isp_hw_get_cmd_update add_wait;
struct cam_hw_intf *hw_intf;
bool hw_res_valid = false;
uint32_t kmd_buf_remain_size, num_ent, add_wait_size;
hw_entry = prepare->hw_update_info[base_idx].hw_entries;
num_ent = prepare->hw_update_info[base_idx].num_hw_entries;
/* Max one hw entries required for each base */
if (num_ent >= prepare->max_hw_update_entries) {
CAM_ERR(CAM_ISP, "Insufficient HW entries");
return -EINVAL;
}
add_wait_size = 0;
list_for_each_entry(hw_mgr_res, res_list_isp_src, list) {
if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT)
continue;
if (hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT] &&
hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT]) {
hw_res_valid = true;
break;
}
}
if (!hw_mgr_res || !hw_res_valid) {
CAM_ERR(CAM_ISP, "No src with multi_vfe config");
return -EINVAL;
}
hw_intf = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT]->hw_intf;
if (kmd_buf_info->size > (kmd_buf_info->used_bytes +
add_wait_size)) {
kmd_buf_remain_size = kmd_buf_info->size -
(kmd_buf_info->used_bytes + add_wait_size);
} else {
CAM_ERR(CAM_ISP, "no free mem %d %d %d",
base_idx, kmd_buf_info->size,
kmd_buf_info->used_bytes +
add_wait_size);
rc = -EINVAL;
return rc;
}
add_wait.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
kmd_buf_info->used_bytes/4 +
add_wait_size/4;
add_wait.cmd.size = kmd_buf_remain_size;
add_wait.cmd_type = CAM_ISP_HW_CMD_ADD_WAIT;
add_wait.res = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT];
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_ADD_WAIT,
&add_wait,
sizeof(struct cam_isp_hw_get_cmd_update));
if (rc) {
CAM_ERR(CAM_ISP,
"wait_comp_event addition failed for dual vfe");
return rc;
}
add_wait_size += add_wait.cmd.used_bytes;
if (add_wait_size) {
/* Update the HW entries */
hw_entry[num_ent].handle =
kmd_buf_info->handle;
hw_entry[num_ent].len =
add_wait_size;
hw_entry[num_ent].offset =
kmd_buf_info->offset;
hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL;
CAM_DBG(CAM_ISP,
"num_ent=%d handle=0x%x, len=%u, offset=%u",
num_ent,
hw_entry[num_ent].handle,
hw_entry[num_ent].len,
hw_entry[num_ent].offset);
num_ent++;
kmd_buf_info->used_bytes += add_wait_size;
kmd_buf_info->offset += add_wait_size;
prepare->hw_update_info[base_idx].num_hw_entries
= num_ent;
/* add wait_comp_event is success return status 0 */
rc = 0;
}
return rc;
}
int cam_isp_add_wait_trigger(
struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info,
bool trigger_cdm_en)
{
int rc = -EINVAL;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_hw_update_entry *hw_entry;
struct cam_isp_hw_get_cmd_update add_trigger;
struct cam_hw_intf *hw_intf;
bool hw_res_valid = false;
uint32_t kmd_buf_remain_size, num_ent, add_trigger_size;
hw_entry = prepare->hw_update_info[base_idx].hw_entries;
num_ent = prepare->hw_update_info[base_idx].num_hw_entries;
/* Max one hw entries required for each base */
if (num_ent + 1 >=
prepare->max_hw_update_entries) {
CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d");
return -EINVAL;
}
add_trigger_size = 0;
list_for_each_entry(hw_mgr_res, res_list_isp_src, list) {
if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT)
continue;
if (hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT] &&
hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT]) {
hw_res_valid = true;
break;
}
}
if (!hw_mgr_res || !hw_res_valid) {
CAM_ERR(CAM_ISP, "No src with multi_vfe config");
return -EINVAL;
}
hw_intf = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT]->hw_intf;
if (kmd_buf_info->size > (kmd_buf_info->used_bytes +
add_trigger_size)) {
kmd_buf_remain_size = kmd_buf_info->size -
(kmd_buf_info->used_bytes + add_trigger_size);
} else {
CAM_ERR(CAM_ISP, "no free mem %d %d %d",
base_idx, kmd_buf_info->size,
kmd_buf_info->used_bytes +
add_trigger_size);
rc = -EINVAL;
return rc;
}
add_trigger.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
kmd_buf_info->used_bytes/4 +
add_trigger_size/4;
add_trigger.cmd.size = kmd_buf_remain_size;
add_trigger.cmd_type = CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER;
add_trigger.res = hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT];
if (trigger_cdm_en)
add_trigger.trigger_cdm_en = true;
else
add_trigger.trigger_cdm_en = false;
rc = hw_intf->hw_ops.process_cmd(
hw_intf->hw_priv,
CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER,
&add_trigger,
sizeof(struct cam_isp_hw_get_cmd_update));
if (rc) {
CAM_ERR(CAM_ISP,
"wait_trigger_event addition failed for dual vfe");
return rc;
}
add_trigger_size += add_trigger.cmd.used_bytes;
if (add_trigger_size) {
/* Update the HW entries */
hw_entry[num_ent].handle =
kmd_buf_info->handle;
hw_entry[num_ent].len =
add_trigger_size;
hw_entry[num_ent].offset =
kmd_buf_info->offset;
hw_entry[num_ent].flags = CAM_ISP_IOCFG_BL;
CAM_DBG(CAM_ISP,
"num_ent=%d handle=0x%x, len=%u, offset=%u",
num_ent,
hw_entry[num_ent].handle,
hw_entry[num_ent].len,
hw_entry[num_ent].offset);
num_ent++;
kmd_buf_info->used_bytes += add_trigger_size;
kmd_buf_info->offset += add_trigger_size;
prepare->hw_update_info[base_idx].num_hw_entries
= num_ent;
/* add wait trigger is success return status 0 */
rc = 0; rc = 0;
} }

View File

@@ -29,7 +29,7 @@ enum cam_isp_cdm_bl_type {
* @kmd_buf_info: Kmd buffer to store the custom cmd data * @kmd_buf_info: Kmd buffer to store the custom cmd data
*/ */
struct cam_isp_generic_blob_info { struct cam_isp_generic_blob_info {
struct cam_hw_prepare_update_args *prepare; struct cam_isp_hw_update_args *prepare;
struct cam_isp_ctx_base_info *base_info; struct cam_isp_ctx_base_info *base_info;
struct cam_kmd_buf_info *kmd_buf_info; struct cam_kmd_buf_info *kmd_buf_info;
}; };
@@ -59,12 +59,11 @@ struct cam_isp_frame_header_info {
* @base_idx: Base or dev index of the IFE/VFE HW instance for * @base_idx: Base or dev index of the IFE/VFE HW instance for
* which change change base need to be added * which change change base need to be added
* @kmd_buf_info: Kmd buffer to store the change base command * @kmd_buf_info: Kmd buffer to store the change base command
*
* @return: 0 for success * @return: 0 for success
* -EINVAL for Fail * -EINVAL for Fail
*/ */
int cam_isp_add_change_base( int cam_isp_add_change_base(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src, struct list_head *res_list_isp_src,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info); struct cam_kmd_buf_info *kmd_buf_info);
@@ -116,7 +115,7 @@ int cam_isp_add_cmd_buf_update(
* Negative for Failure * Negative for Failure
*/ */
int cam_isp_add_command_buffers( int cam_isp_add_command_buffers(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct cam_kmd_buf_info *kmd_buf_info, struct cam_kmd_buf_info *kmd_buf_info,
struct cam_isp_ctx_base_info *base_info, struct cam_isp_ctx_base_info *base_info,
cam_packet_generic_blob_handler blob_handler_cb, cam_packet_generic_blob_handler blob_handler_cb,
@@ -147,7 +146,7 @@ int cam_isp_add_command_buffers(
int cam_isp_add_io_buffers( int cam_isp_add_io_buffers(
int iommu_hdl, int iommu_hdl,
int sec_iommu_hdl, int sec_iommu_hdl,
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info, struct cam_kmd_buf_info *kmd_buf_info,
struct cam_isp_hw_mgr_res *res_list_isp_out, struct cam_isp_hw_mgr_res *res_list_isp_out,
@@ -171,11 +170,56 @@ int cam_isp_add_io_buffers(
* -EINVAL for Fail * -EINVAL for Fail
*/ */
int cam_isp_add_reg_update( int cam_isp_add_reg_update(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src, struct list_head *res_list_isp_src,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info); struct cam_kmd_buf_info *kmd_buf_info);
/*
* cam_isp_add_comp_wait()
*
* @brief Add reg update in the hw entries list
* processe the isp source list get the reg update from
* ISP HW instance
*
* @prepare: Contain the packet and HW update variables
* @res_list_isp_src: Resource list for IFE/VFE source
* @base_idx: Base or dev index of the IFE/VFE HW instance
* @kmd_buf_info: Kmd buffer to store the change base command
*
* @return: 0 for success
* -EINVAL for Fail
*/
int cam_isp_add_comp_wait(
struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info);
/*
* cam_isp_add_wait_trigger()
*
* @brief Add reg update in the hw entries list
* processe the isp source list get the reg update from
* ISP HW instance
*
* @prepare: Contain the packet and HW update variables
* @res_list_isp_src: Resource list for IFE/VFE source
* @base_idx: Base or dev index of the IFE/VFE HW instance
* @kmd_buf_info: Kmd buffer to store the change base command
* @trigger_cdm_en Used to reset and set trigger_cdm_events register
*
* @return: 0 for success
* -EINVAL for Fail
*/
int cam_isp_add_wait_trigger(
struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_src,
uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info,
bool trigger_cdm_en);
/* /*
* cam_isp_add_go_cmd() * cam_isp_add_go_cmd()
* *
@@ -189,10 +233,9 @@ int cam_isp_add_reg_update(
* -EINVAL for Fail * -EINVAL for Fail
*/ */
int cam_isp_add_go_cmd( int cam_isp_add_go_cmd(
struct cam_hw_prepare_update_args *prepare, struct cam_isp_hw_update_args *prepare,
struct list_head *res_list_isp_rd, struct list_head *res_list_isp_rd,
uint32_t base_idx, uint32_t base_idx,
struct cam_kmd_buf_info *kmd_buf_info); struct cam_kmd_buf_info *kmd_buf_info);
#endif /*_CAM_ISP_HW_PARSER_H */ #endif /*_CAM_ISP_HW_PARSER_H */

View File

@@ -22,6 +22,13 @@
/* Appliacble vote paths for dual ife, based on no. of UAPI definitions */ /* Appliacble vote paths for dual ife, based on no. of UAPI definitions */
#define CAM_ISP_MAX_PER_PATH_VOTES 30 #define CAM_ISP_MAX_PER_PATH_VOTES 30
/*
* Maximum configuration entry size - This is based on the
* worst case DUAL IFE use case plus some margin.
*/
#define CAM_ISP_CTX_CFG_MAX 25
/** /**
* enum cam_isp_hw_event_type - Collection of the ISP hardware events * enum cam_isp_hw_event_type - Collection of the ISP hardware events
*/ */
@@ -71,18 +78,7 @@ struct cam_isp_stop_args {
bool stop_only; bool stop_only;
}; };
/**
* struct cam_isp_start_args - isp hardware start arguments
*
* @config_args: Hardware configuration commands.
* @start_only Send start only to hw drivers. No init to
* be done.
*
*/
struct cam_isp_start_args {
struct cam_hw_config_args hw_config;
bool start_only;
};
/** /**
* struct cam_isp_bw_config_internal_v2 - Bandwidth configuration * struct cam_isp_bw_config_internal_v2 - Bandwidth configuration
@@ -261,6 +257,106 @@ struct cam_isp_hw_cmd_args {
} u; } u;
}; };
/**
* struct cam_isp_hw_update_entry_info - hardware config info
*
* @hw_update_entries Entry for hardware config
* @num_hw_update_entries: Number of IFE hw
*
*/
struct cam_isp_hw_update_entry_info {
struct cam_hw_update_entry *hw_entries;
uint32_t num_hw_entries;
};
/**
* struct cam_isp_hw_update_info - hardware config info
*
* @hw_update_entries Entry for hardware config
* @num_hw_update_entries: number of IFE hw
*
*/
struct cam_isp_hw_update_info {
struct cam_hw_update_entry hw_entries[CAM_ISP_CTX_CFG_MAX];
uint32_t num_hw_entries;
};
/**
* struct cam_isp_hw_update_args - Payload for prepare command
*
* @packet: CSL packet from user mode driver
* @remain_len Remaining length of CPU buffer after config offset
* @ctxt_to_hw_map: HW context from the acquire
* @max_hw_update_entries: Maximum hardware update entries supported
* @hw_update_info: Actual hardware update configuration (returned)
* @max_out_map_entries: Maximum output fence mapping supported
* @out_map_entries: Actual output fence mapping list (returned)
* @num_out_map_entries: Number of actual output fence mapping (returned)
* @max_in_map_entries: Maximum input fence mapping supported
* @in_map_entries: Actual input fence mapping list (returned)
* @num_in_map_entries: Number of acutal input fence mapping (returned)
* @priv: Private pointer of hw update
* @pf_data: Debug data for page fault
*
*/
struct cam_isp_hw_update_args {
struct cam_packet *packet;
uint32_t remain_len;
void *ctxt_to_hw_map;
uint32_t max_hw_update_entries;
struct cam_isp_hw_update_entry_info hw_update_info[CAM_IFE_HW_NUM_MAX];
uint32_t max_out_map_entries;
struct cam_hw_fence_map_entry *out_map_entries;
uint32_t num_out_map_entries;
uint32_t max_in_map_entries;
struct cam_hw_fence_map_entry *in_map_entries;
uint32_t num_in_map_entries;
void *priv;
struct cam_hw_mgr_dump_pf_data *pf_data;
struct cam_cmd_buf_desc reg_dump_buf_desc[
CAM_REG_DUMP_MAX_BUF_ENTRIES];
uint32_t num_reg_dump_buf;
};
/**
* struct cam_isp_hw_config_args - Payload for config command
*
* @ctxt_to_hw_map: HW context from the acquire
* @hw_update_info: Hardware update info for every IFE
* @out_map_entries: Out map info
* @num_out_map_entries: Number of out map entries
* @priv: Private pointer
* @request_id: Request ID
* @init_packet: check init packet or update packet
* @reapply: check if current req is reapplied
*
*/
struct cam_isp_hw_config_args {
void *ctxt_to_hw_map;
struct cam_isp_hw_update_entry_info hw_update_info[CAM_IFE_HW_NUM_MAX];
struct cam_hw_fence_map_entry *out_map_entries;
uint32_t num_out_map_entries;
void *priv;
uint64_t request_id;
bool init_packet;
bool reapply;
};
/**
* struct cam_isp_start_args - isp hardware start arguments
*
* @config_args: Hardware configuration commands.
* @start_only Send start only to hw drivers. No init to
* be done.
*
*/
struct cam_isp_start_args {
struct cam_isp_hw_config_args hw_config;
bool start_only;
};
/** /**
* cam_isp_hw_mgr_init() * cam_isp_hw_mgr_init()

View File

@@ -110,6 +110,8 @@ enum cam_isp_hw_cmd_type {
CAM_ISP_HW_CMD_CORE_CONFIG, CAM_ISP_HW_CMD_CORE_CONFIG,
CAM_ISP_HW_CMD_WM_CONFIG_UPDATE, CAM_ISP_HW_CMD_WM_CONFIG_UPDATE,
CAM_ISP_HW_CMD_CSID_QCFA_SUPPORTED, CAM_ISP_HW_CMD_CSID_QCFA_SUPPORTED,
CAM_ISP_HW_CMD_ADD_WAIT,
CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER,
CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA,
CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE, CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE,
CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
@@ -245,6 +247,7 @@ struct cam_isp_hw_get_cmd_update {
struct cam_isp_hw_get_wm_update *wm_update; struct cam_isp_hw_get_wm_update *wm_update;
struct cam_isp_hw_get_wm_update *rm_update; struct cam_isp_hw_get_wm_update *rm_update;
}; };
bool trigger_cdm_en;
}; };
/* /*

View File

@@ -596,6 +596,8 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
case CAM_ISP_HW_CMD_CORE_CONFIG: case CAM_ISP_HW_CMD_CORE_CONFIG:
case CAM_ISP_HW_CMD_BW_UPDATE_V2: case CAM_ISP_HW_CMD_BW_UPDATE_V2:
case CAM_ISP_HW_CMD_DUMP_HW: case CAM_ISP_HW_CMD_DUMP_HW:
case CAM_ISP_HW_CMD_ADD_WAIT:
case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER:
rc = core_info->vfe_top->hw_ops.process_cmd( rc = core_info->vfe_top->hw_ops.process_cmd(
core_info->vfe_top->top_priv, cmd_type, cmd_args, core_info->vfe_top->top_priv, cmd_type, cmd_args,
arg_size); arg_size);

View File

@@ -179,6 +179,92 @@ static int cam_vfe_top_mux_get_reg_update(
return -EINVAL; return -EINVAL;
} }
static int cam_vfe_top_wait_comp_event(struct cam_vfe_top_ver2_priv *top_priv,
void *cmd_args, uint32_t arg_size)
{
uint32_t size = 0;
struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
CAM_ERR(CAM_ISP, "Error! Invalid cmd size");
return -EINVAL;
}
if (!cdm_args || !cdm_args->res || !top_priv ||
!top_priv->common_data.soc_info) {
CAM_ERR(CAM_ISP, "Error! Invalid args");
return -EINVAL;
}
cdm_util_ops =
(struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops;
if (!cdm_util_ops) {
CAM_ERR(CAM_ISP, "Invalid CDM ops");
return -EINVAL;
}
size = cdm_util_ops->cdm_required_size_comp_wait();
/* since cdm returns dwords, we need to convert it into bytes */
if ((size * 4) > cdm_args->cmd.size) {
CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d",
cdm_args->cmd.size, size);
return -EINVAL;
}
cdm_util_ops->cdm_write_wait_comp_event(cdm_args->cmd.cmd_buf_addr,
0, 0x2);
cdm_args->cmd.used_bytes = (size * 4);
return 0;
}
static int cam_vfe_top_add_wait_trigger(struct cam_vfe_top_ver2_priv *top_priv,
void *cmd_args, uint32_t arg_size)
{
uint32_t size = 0;
uint32_t reg_val_pair[2];
struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
CAM_ERR(CAM_ISP, "Error! Invalid cmd size");
return -EINVAL;
}
if (!cdm_args || !cdm_args->res || !top_priv ||
!top_priv->common_data.soc_info) {
CAM_ERR(CAM_ISP, "Error! Invalid args");
return -EINVAL;
}
cdm_util_ops =
(struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops;
if (!cdm_util_ops) {
CAM_ERR(CAM_ISP, "Invalid CDM ops");
return -EINVAL;
}
size = cdm_util_ops->cdm_required_size_reg_random(1);
/* since cdm returns dwords, we need to convert it into bytes */
if ((size * 4) > cdm_args->cmd.size) {
CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d",
cdm_args->cmd.size, size);
return -EINVAL;
}
reg_val_pair[0] = 0x90;
reg_val_pair[1] = 0x1;
cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr,
1, reg_val_pair);
cdm_args->cmd.used_bytes = (size * 4);
return 0;
}
int cam_vfe_top_get_hw_caps(void *device_priv, int cam_vfe_top_get_hw_caps(void *device_priv,
void *get_hw_cap_args, uint32_t arg_size) void *get_hw_cap_args, uint32_t arg_size)
{ {
@@ -644,6 +730,12 @@ int cam_vfe_top_process_cmd(void *device_priv, uint32_t cmd_type,
rc = cam_vfe_hw_dump(top_priv, rc = cam_vfe_hw_dump(top_priv,
cmd_args, arg_size); cmd_args, arg_size);
break; break;
case CAM_ISP_HW_CMD_ADD_WAIT:
rc = cam_vfe_top_wait_comp_event(top_priv, cmd_args, arg_size);
break;
case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER:
rc = cam_vfe_top_add_wait_trigger(top_priv, cmd_args, arg_size);
break;
default: default:
rc = -EINVAL; rc = -EINVAL;
CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type); CAM_ERR(CAM_ISP, "Error! Invalid cmd:%d", cmd_type);

View File

@@ -16,6 +16,7 @@
#define CAM_VFE_HW_RESET_HW_VAL 0x00010000 #define CAM_VFE_HW_RESET_HW_VAL 0x00010000
#define CAM_VFE_LITE_HW_RESET_AND_REG_VAL 0x00000002 #define CAM_VFE_LITE_HW_RESET_AND_REG_VAL 0x00000002
#define CAM_VFE_LITE_HW_RESET_HW_VAL 0x00000001 #define CAM_VFE_LITE_HW_RESET_HW_VAL 0x00000001
#define CAM_CDM_WAIT_COMP_EVENT_BIT 0x2
struct cam_vfe_top_ver3_common_data { struct cam_vfe_top_ver3_common_data {
struct cam_hw_soc_info *soc_info; struct cam_hw_soc_info *soc_info;
@@ -212,6 +213,102 @@ static int cam_vfe_top_ver3_mux_get_reg_update(
return -EINVAL; return -EINVAL;
} }
static int cam_vfe_top_wait_comp_event(struct cam_vfe_top_ver3_priv *top_priv,
void *cmd_args, uint32_t arg_size)
{
uint32_t size = 0;
struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
CAM_ERR(CAM_ISP, "Error, Invalid arg size = %d expected = %d",
arg_size, sizeof(struct cam_isp_hw_get_cmd_update));
return -EINVAL;
}
if (!cdm_args || !cdm_args->res || !top_priv ||
!top_priv->common_data.soc_info) {
CAM_ERR(CAM_ISP, "Error, Invalid args");
return -EINVAL;
}
cdm_util_ops =
(struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops;
if (!cdm_util_ops) {
CAM_ERR(CAM_ISP, "Invalid CDM ops");
return -EINVAL;
}
size = cdm_util_ops->cdm_required_size_comp_wait();
/* since cdm returns dwords, we need to convert it into bytes */
if ((size * 4) > cdm_args->cmd.size) {
CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d",
cdm_args->cmd.size, size);
return -EINVAL;
}
cdm_util_ops->cdm_write_wait_comp_event(cdm_args->cmd.cmd_buf_addr,
0, CAM_CDM_WAIT_COMP_EVENT_BIT);
cdm_args->cmd.used_bytes = (size * 4);
return 0;
}
static int cam_vfe_top_add_wait_trigger(struct cam_vfe_top_ver3_priv *top_priv,
void *cmd_args, uint32_t arg_size)
{
uint32_t size = 0;
uint32_t reg_val_pair[2];
struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
struct cam_vfe_top_ver3_reg_offset_common *reg_common = NULL;
uint32_t set_cdm_trigger_event;
if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
CAM_ERR(CAM_ISP, "Error, Invalid arg size = %d expected = %d",
arg_size, sizeof(struct cam_isp_hw_get_cmd_update));
return -EINVAL;
}
if (!cdm_args || !cdm_args->res || !top_priv ||
!top_priv->common_data.soc_info) {
CAM_ERR(CAM_ISP, "Error, Invalid args");
return -EINVAL;
}
cdm_util_ops =
(struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops;
if (!cdm_util_ops) {
CAM_ERR(CAM_ISP, "Invalid CDM ops");
return -EINVAL;
}
size = cdm_util_ops->cdm_required_size_reg_random(1);
/* since cdm returns dwords, we need to convert it into bytes */
if ((size * 4) > cdm_args->cmd.size) {
CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d",
cdm_args->cmd.size, size);
return -EINVAL;
}
if (cdm_args->trigger_cdm_en == true)
set_cdm_trigger_event = 1;
else
set_cdm_trigger_event = 0;
reg_common = top_priv->common_data.common_reg;
reg_val_pair[0] = reg_common->trigger_cdm_events;
reg_val_pair[1] = set_cdm_trigger_event;
cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr,
1, reg_val_pair);
cdm_args->cmd.used_bytes = (size * 4);
return 0;
}
int cam_vfe_top_ver3_get_hw_caps(void *device_priv, int cam_vfe_top_ver3_get_hw_caps(void *device_priv,
void *get_hw_cap_args, uint32_t arg_size) void *get_hw_cap_args, uint32_t arg_size)
{ {
@@ -561,6 +658,12 @@ int cam_vfe_top_ver3_process_cmd(void *device_priv, uint32_t cmd_type,
case CAM_ISP_HW_CMD_CORE_CONFIG: case CAM_ISP_HW_CMD_CORE_CONFIG:
rc = cam_vfe_core_config_control(top_priv, cmd_args, arg_size); rc = cam_vfe_core_config_control(top_priv, cmd_args, arg_size);
break; break;
case CAM_ISP_HW_CMD_ADD_WAIT:
rc = cam_vfe_top_wait_comp_event(top_priv, cmd_args, arg_size);
break;
case CAM_ISP_HW_CMD_ADD_WAIT_TRIGGER:
rc = cam_vfe_top_add_wait_trigger(top_priv, cmd_args, arg_size);
break;
default: default:
rc = -EINVAL; rc = -EINVAL;
CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type); CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type);