Merge "msm: camera: isp: Add support for IFE scratch buffer" into camera-kernel.lnx.5.0
Bu işleme şunda yer alıyor:

işlemeyi yapan:
Gerrit - the friendly Code Review server

işleme
e8253ce8cd
@@ -4946,10 +4946,20 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
||||
ife_ctx->sfe_info.scratch_config =
|
||||
kzalloc(sizeof(struct cam_sfe_scratch_buf_cfg), GFP_KERNEL);
|
||||
if (!ife_ctx->sfe_info.scratch_config) {
|
||||
CAM_ERR(CAM_ISP, "Failed to allocate scratch config");
|
||||
CAM_ERR(CAM_ISP, "Failed to allocate SFE scratch config");
|
||||
rc = -ENOMEM;
|
||||
goto free_cdm_cmd;
|
||||
}
|
||||
|
||||
ife_ctx->sfe_info.ife_scratch_config =
|
||||
kzalloc(sizeof(struct cam_ife_scratch_buf_cfg), GFP_KERNEL);
|
||||
if (!ife_ctx->sfe_info.ife_scratch_config) {
|
||||
CAM_ERR(CAM_ISP, "Failed to allocate IFE scratch config");
|
||||
rc = -ENOMEM;
|
||||
kfree(ife_ctx->sfe_info.scratch_config);
|
||||
goto free_cdm_cmd;
|
||||
}
|
||||
|
||||
/* Set scratch by default at stream on */
|
||||
ife_ctx->sfe_info.skip_scratch_cfg_streamon = false;
|
||||
}
|
||||
@@ -6249,6 +6259,10 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
||||
if (ctx->sfe_info.scratch_config)
|
||||
memset(ctx->sfe_info.scratch_config, 0,
|
||||
sizeof(struct cam_sfe_scratch_buf_cfg));
|
||||
|
||||
if (ctx->sfe_info.ife_scratch_config)
|
||||
memset(ctx->sfe_info.ife_scratch_config, 0,
|
||||
sizeof(struct cam_ife_scratch_buf_cfg));
|
||||
}
|
||||
ctx->sfe_info.skip_scratch_cfg_streamon = false;
|
||||
|
||||
@@ -6903,7 +6917,9 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
|
||||
ctx->num_acq_sfe_out = 0;
|
||||
|
||||
kfree(ctx->sfe_info.scratch_config);
|
||||
kfree(ctx->sfe_info.ife_scratch_config);
|
||||
ctx->sfe_info.scratch_config = NULL;
|
||||
ctx->sfe_info.ife_scratch_config = NULL;
|
||||
|
||||
memset(&ctx->flags, 0, sizeof(struct cam_ife_hw_mgr_ctx_flags));
|
||||
atomic_set(&ctx->overflow_pending, 0);
|
||||
@@ -7265,32 +7281,125 @@ end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_scratch_buf_update_util(
|
||||
struct cam_isp_sfe_scratch_buf_info *buffer_info,
|
||||
struct cam_ife_sfe_scratch_buf_info *port_info)
|
||||
{
|
||||
int rc = 0;
|
||||
int mmu_hdl;
|
||||
size_t size;
|
||||
dma_addr_t io_addr;
|
||||
bool is_buf_secure;
|
||||
|
||||
is_buf_secure = cam_mem_is_secure_buf(buffer_info->mem_handle);
|
||||
if (is_buf_secure) {
|
||||
port_info->is_secure = true;
|
||||
mmu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl_secure;
|
||||
} else {
|
||||
port_info->is_secure = false;
|
||||
mmu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl;
|
||||
}
|
||||
|
||||
rc = cam_mem_get_io_buf(buffer_info->mem_handle,
|
||||
mmu_hdl, &io_addr, &size, NULL);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"no scratch buf addr for res: 0x%x",
|
||||
buffer_info->resource_type);
|
||||
rc = -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
port_info->res_id = buffer_info->resource_type;
|
||||
port_info->io_addr = io_addr + buffer_info->offset;
|
||||
port_info->width = buffer_info->width;
|
||||
port_info->height = buffer_info->height;
|
||||
port_info->stride = buffer_info->stride;
|
||||
port_info->slice_height = buffer_info->slice_height;
|
||||
port_info->offset = 0;
|
||||
port_info->config_done = true;
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"res_id: 0x%x w: 0x%x h: 0x%x s: 0x%x sh: 0x%x addr: 0x%x",
|
||||
port_info->res_id, port_info->width,
|
||||
port_info->height, port_info->stride,
|
||||
port_info->slice_height, port_info->io_addr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_blob_ife_scratch_buf_update(
|
||||
struct cam_isp_sfe_init_scratch_buf_config *scratch_config,
|
||||
struct cam_hw_prepare_update_args *prepare)
|
||||
{
|
||||
int rc = 0, i;
|
||||
uint32_t res_id_out;
|
||||
struct cam_ife_hw_mgr_ctx *ctx = NULL;
|
||||
struct cam_isp_sfe_scratch_buf_info *buffer_info;
|
||||
struct cam_ife_sfe_scratch_buf_info *port_info;
|
||||
struct cam_isp_hw_mgr_res *ife_out_res;
|
||||
struct cam_ife_hw_mgr *ife_hw_mgr;
|
||||
struct cam_ife_scratch_buf_cfg *ife_scratch_config;
|
||||
|
||||
ctx = prepare->ctxt_to_hw_map;
|
||||
ife_hw_mgr = ctx->hw_mgr;
|
||||
ife_scratch_config = ctx->sfe_info.ife_scratch_config;
|
||||
|
||||
for (i = 0; i < scratch_config->num_ports; i++) {
|
||||
buffer_info = &scratch_config->port_scratch_cfg[i];
|
||||
if (!cam_ife_hw_mgr_is_ife_out_port(buffer_info->resource_type))
|
||||
continue;
|
||||
|
||||
res_id_out = buffer_info->resource_type & 0xFF;
|
||||
|
||||
CAM_DBG(CAM_ISP, "scratch config idx: %d res: 0x%x",
|
||||
i, buffer_info->resource_type);
|
||||
|
||||
ife_out_res = &ctx->res_list_ife_out[res_id_out];
|
||||
if (!ife_out_res->hw_res[0]) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"IFE rsrc_type: 0x%x not acquired, failing scratch config",
|
||||
buffer_info->resource_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ife_scratch_config->num_config >= CAM_IFE_SCRATCH_NUM_MAX) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Incoming num of scratch buffers: %u exceeds max: %u",
|
||||
ife_scratch_config->num_config, CAM_IFE_SCRATCH_NUM_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
port_info = &ife_scratch_config->buf_info[ife_scratch_config->num_config++];
|
||||
rc = cam_isp_scratch_buf_update_util(buffer_info, port_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_blob_sfe_scratch_buf_update(
|
||||
struct cam_isp_sfe_init_scratch_buf_config *scratch_config,
|
||||
struct cam_hw_prepare_update_args *prepare)
|
||||
{
|
||||
int rc, i, mmu_hdl;
|
||||
int rc = 0, i;
|
||||
uint32_t res_id_out;
|
||||
bool is_buf_secure;
|
||||
dma_addr_t io_addr;
|
||||
size_t size;
|
||||
struct cam_ife_hw_mgr_ctx *ctx = NULL;
|
||||
struct cam_isp_sfe_scratch_buf_info *buffer_info;
|
||||
struct cam_sfe_scratch_buf_info *port_info;
|
||||
struct cam_ife_sfe_scratch_buf_info *port_info;
|
||||
struct cam_isp_hw_mgr_res *sfe_out_res;
|
||||
struct cam_ife_hw_mgr *ife_hw_mgr;
|
||||
|
||||
ctx = prepare->ctxt_to_hw_map;
|
||||
ife_hw_mgr = ctx->hw_mgr;
|
||||
if (scratch_config->num_ports != ctx->sfe_info.num_fetches)
|
||||
CAM_WARN(CAM_ISP,
|
||||
"Getting scratch buffer for %u ports on ctx: %u with num_fetches: %u",
|
||||
scratch_config->num_ports, ctx->ctx_index, ctx->sfe_info.num_fetches);
|
||||
|
||||
CAM_DBG(CAM_ISP, "num_ports: %u", scratch_config->num_ports);
|
||||
|
||||
for (i = 0; i < scratch_config->num_ports; i++) {
|
||||
buffer_info = &scratch_config->port_scratch_cfg[i];
|
||||
if (!cam_ife_hw_mgr_is_sfe_out_port(buffer_info->resource_type))
|
||||
continue;
|
||||
|
||||
res_id_out = buffer_info->resource_type & 0xFF;
|
||||
|
||||
CAM_DBG(CAM_ISP, "scratch config idx: %d res: 0x%x",
|
||||
@@ -7311,42 +7420,22 @@ static int cam_isp_blob_sfe_scratch_buf_update(
|
||||
}
|
||||
|
||||
port_info = &ctx->sfe_info.scratch_config->buf_info[res_id_out];
|
||||
is_buf_secure = cam_mem_is_secure_buf(buffer_info->mem_handle);
|
||||
if (is_buf_secure) {
|
||||
port_info->is_secure = true;
|
||||
mmu_hdl = ife_hw_mgr->mgr_common.img_iommu_hdl_secure;
|
||||
} else {
|
||||
port_info->is_secure = false;
|
||||
mmu_hdl = ife_hw_mgr->mgr_common.img_iommu_hdl;
|
||||
}
|
||||
rc = cam_isp_scratch_buf_update_util(buffer_info, port_info);
|
||||
if (rc)
|
||||
goto end;
|
||||
|
||||
rc = cam_mem_get_io_buf(buffer_info->mem_handle,
|
||||
mmu_hdl, &io_addr, &size, NULL);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"no scratch buf addr for res: 0x%x",
|
||||
buffer_info->resource_type);
|
||||
rc = -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
port_info->res_id = buffer_info->resource_type;
|
||||
port_info->io_addr = io_addr + buffer_info->offset;
|
||||
port_info->width = buffer_info->width;
|
||||
port_info->height = buffer_info->height;
|
||||
port_info->stride = buffer_info->stride;
|
||||
port_info->slice_height = buffer_info->slice_height;
|
||||
port_info->offset = 0;
|
||||
port_info->config_done = true;
|
||||
CAM_DBG(CAM_ISP,
|
||||
"res_id: 0x%x w: 0x%x h: 0x%x s: 0x%x sh: 0x%x addr: 0x%x",
|
||||
port_info->res_id, port_info->width,
|
||||
port_info->height, port_info->stride,
|
||||
port_info->slice_height, port_info->io_addr);
|
||||
ctx->sfe_info.scratch_config->num_config++;
|
||||
}
|
||||
|
||||
ctx->sfe_info.scratch_config->num_config = scratch_config->num_ports;
|
||||
return 0;
|
||||
if (ctx->sfe_info.scratch_config->num_config != ctx->sfe_info.num_fetches) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Mismatch in number of scratch buffers provided: %u expected: %u",
|
||||
ctx->sfe_info.scratch_config->num_config, ctx->sfe_info.num_fetches);
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int __cam_isp_sfe_send_cache_config(
|
||||
@@ -8244,7 +8333,7 @@ static int cam_ife_hw_mgr_update_scratch_offset(
|
||||
struct cam_isp_vfe_wm_config *wm_config)
|
||||
{
|
||||
uint32_t res_id;
|
||||
struct cam_sfe_scratch_buf_info *port_info;
|
||||
struct cam_ife_sfe_scratch_buf_info *port_info;
|
||||
|
||||
if ((wm_config->port_type - CAM_ISP_SFE_OUT_RES_RDI_0) >=
|
||||
ctx->sfe_info.num_fetches)
|
||||
@@ -8847,6 +8936,63 @@ static int cam_isp_blob_ife_init_config_update(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_validate_scratch_buffer_blob(
|
||||
uint32_t blob_size,
|
||||
struct cam_ife_hw_mgr_ctx *ife_mgr_ctx,
|
||||
struct cam_isp_sfe_init_scratch_buf_config *scratch_config)
|
||||
{
|
||||
if (!(ife_mgr_ctx->flags.is_sfe_fs ||
|
||||
ife_mgr_ctx->flags.is_sfe_shdr)) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Not SFE sHDR/FS context: %u scratch buf blob not supported",
|
||||
ife_mgr_ctx->ctx_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (blob_size <
|
||||
sizeof(struct cam_isp_sfe_init_scratch_buf_config)) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((scratch_config->num_ports >
|
||||
(CAM_SFE_FE_RDI_NUM_MAX + CAM_IFE_SCRATCH_NUM_MAX)) ||
|
||||
(scratch_config->num_ports == 0)) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Invalid num_ports %u in scratch buf config",
|
||||
scratch_config->num_ports);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check for integer overflow */
|
||||
if (scratch_config->num_ports != 1) {
|
||||
if (sizeof(struct cam_isp_sfe_scratch_buf_info) >
|
||||
((UINT_MAX -
|
||||
sizeof(struct cam_isp_sfe_init_scratch_buf_config)) /
|
||||
(scratch_config->num_ports - 1))) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Max size exceeded in scratch config num_ports: %u size per port: %lu",
|
||||
scratch_config->num_ports,
|
||||
sizeof(struct cam_isp_sfe_scratch_buf_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (blob_size <
|
||||
(sizeof(struct cam_isp_sfe_init_scratch_buf_config) +
|
||||
(scratch_config->num_ports - 1) *
|
||||
sizeof(struct cam_isp_sfe_scratch_buf_info))) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size: %u expected: %lu",
|
||||
blob_size,
|
||||
sizeof(struct cam_isp_sfe_init_scratch_buf_config) +
|
||||
(scratch_config->num_ports - 1) *
|
||||
sizeof(struct cam_isp_sfe_scratch_buf_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
|
||||
{
|
||||
@@ -9356,6 +9502,23 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "Discard initial frames update failed rc: %d", rc);
|
||||
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_SCRATCH_BUF_CFG: {
|
||||
struct cam_isp_sfe_init_scratch_buf_config *scratch_config;
|
||||
|
||||
scratch_config =
|
||||
(struct cam_isp_sfe_init_scratch_buf_config *)blob_data;
|
||||
|
||||
rc = cam_isp_validate_scratch_buffer_blob(blob_size,
|
||||
ife_mgr_ctx, scratch_config);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = cam_isp_blob_ife_scratch_buf_update(
|
||||
scratch_config, prepare);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "IFE scratch buffer update failed rc: %d", rc);
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_CLOCK_CONFIG:
|
||||
@@ -9363,7 +9526,6 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_OUT_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_HFR_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_FE_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_SCRATCH_BUF_CFG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_EXP_ORDER_CFG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_FPS_CONFIG:
|
||||
break;
|
||||
@@ -9720,65 +9882,18 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_SCRATCH_BUF_CFG: {
|
||||
struct cam_isp_sfe_init_scratch_buf_config *scratch_config;
|
||||
|
||||
if (!(ife_mgr_ctx->flags.is_sfe_fs ||
|
||||
ife_mgr_ctx->flags.is_sfe_shdr)) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Not SFE sHDR/FS context: %u scratch buf blob not supported",
|
||||
ife_mgr_ctx->ctx_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (blob_size <
|
||||
sizeof(struct cam_isp_sfe_init_scratch_buf_config)) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
scratch_config =
|
||||
(struct cam_isp_sfe_init_scratch_buf_config *)blob_data;
|
||||
|
||||
if (scratch_config->num_ports > CAM_SFE_FE_RDI_NUM_MAX ||
|
||||
scratch_config->num_ports == 0) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Invalid num_ports %u in scratch buf config",
|
||||
scratch_config->num_ports);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check for integer overflow */
|
||||
if (scratch_config->num_ports != 1) {
|
||||
if (sizeof(struct cam_isp_sfe_scratch_buf_info) >
|
||||
((UINT_MAX -
|
||||
sizeof(
|
||||
struct cam_isp_sfe_init_scratch_buf_config)) /
|
||||
(scratch_config->num_ports - 1))) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Max size exceeded in scratch config num_ports: %u size per port: %lu",
|
||||
scratch_config->num_ports,
|
||||
sizeof(
|
||||
struct cam_isp_sfe_scratch_buf_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (blob_size <
|
||||
(sizeof(struct cam_isp_sfe_init_scratch_buf_config) +
|
||||
(scratch_config->num_ports - 1) *
|
||||
sizeof(struct cam_isp_sfe_scratch_buf_info))) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size: %u expected: %lu",
|
||||
blob_size,
|
||||
sizeof(
|
||||
struct cam_isp_sfe_init_scratch_buf_config) +
|
||||
(scratch_config->num_ports - 1) *
|
||||
sizeof(
|
||||
struct cam_isp_sfe_scratch_buf_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = cam_isp_validate_scratch_buffer_blob(blob_size,
|
||||
ife_mgr_ctx, scratch_config);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = cam_isp_blob_sfe_scratch_buf_update(
|
||||
scratch_config, prepare);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP, "SFE scratch buffer update failed");
|
||||
CAM_ERR(CAM_ISP, "SFE scratch buffer update failed rc: %d", rc);
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_FE_CONFIG: {
|
||||
@@ -9952,14 +10067,14 @@ static inline bool cam_isp_sfe_validate_for_scratch_buf_config(
|
||||
}
|
||||
|
||||
static int cam_isp_sfe_send_scratch_buf_upd(
|
||||
uint32_t remaining_size,
|
||||
enum cam_isp_hw_cmd_type cmd_type,
|
||||
struct cam_isp_resource_node *hw_res,
|
||||
struct cam_sfe_scratch_buf_info *buf_info,
|
||||
uint32_t *cpu_addr,
|
||||
uint32_t *used_bytes)
|
||||
uint32_t remaining_size,
|
||||
enum cam_isp_hw_cmd_type cmd_type,
|
||||
struct cam_isp_resource_node *hw_res,
|
||||
struct cam_ife_sfe_scratch_buf_info *buf_info,
|
||||
uint32_t *cpu_addr,
|
||||
uint32_t *used_bytes)
|
||||
{
|
||||
int rc;
|
||||
int rc, i;
|
||||
struct cam_isp_hw_get_cmd_update update_buf;
|
||||
struct cam_isp_hw_get_wm_update wm_update;
|
||||
dma_addr_t io_addr[CAM_PACKET_MAX_PLANES];
|
||||
@@ -9971,7 +10086,14 @@ static int cam_isp_sfe_send_scratch_buf_upd(
|
||||
update_buf.use_scratch_cfg = true;
|
||||
|
||||
wm_update.num_buf = 1;
|
||||
io_addr[0] = buf_info->io_addr;
|
||||
/*
|
||||
* Update same scratch buffer for different planes,
|
||||
* when used for IFE clients, same scratch buffer
|
||||
* is configured to both per plane clients
|
||||
*/
|
||||
for (i = 0; i < CAM_PACKET_MAX_PLANES; i++)
|
||||
io_addr[i] = buf_info->io_addr;
|
||||
|
||||
wm_update.image_buf = io_addr;
|
||||
wm_update.width = buf_info->width;
|
||||
wm_update.height = buf_info->height;
|
||||
@@ -9987,13 +10109,12 @@ static int cam_isp_sfe_send_scratch_buf_upd(
|
||||
cmd_type, &update_buf,
|
||||
sizeof(struct cam_isp_hw_get_cmd_update));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "get buf cmd error:%d",
|
||||
hw_res->res_id);
|
||||
rc = -ENOMEM;
|
||||
CAM_ERR(CAM_ISP, "Failed to send cmd: %u res: %u rc: %d",
|
||||
cmd_type, hw_res->res_id, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP, "Scratch buf configured for: 0x%x",
|
||||
CAM_DBG(CAM_ISP, "Scratch buf configured for res: 0x%x",
|
||||
hw_res->res_id);
|
||||
|
||||
/* Update used bytes if update is via CDM */
|
||||
@@ -10017,8 +10138,8 @@ static int cam_isp_sfe_add_scratch_buffer_cfg(
|
||||
uint32_t used_bytes = 0, remain_size = 0;
|
||||
uint32_t io_cfg_used_bytes;
|
||||
uint32_t *cpu_addr = NULL;
|
||||
struct cam_sfe_scratch_buf_info *buf_info;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_ife_sfe_scratch_buf_info *buf_info;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
|
||||
if (prepare->num_hw_update_entries + 1 >=
|
||||
prepare->max_hw_update_entries) {
|
||||
@@ -10156,6 +10277,87 @@ static int cam_isp_sfe_add_scratch_buffer_cfg(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_isp_ife_add_scratch_buffer_cfg(
|
||||
uint32_t base_idx,
|
||||
uint32_t scratch_cfg_mask,
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct cam_kmd_buf_info *kmd_buf_info,
|
||||
struct cam_isp_hw_mgr_res *res_list_isp_out,
|
||||
struct cam_ife_hw_mgr_ctx *ctx)
|
||||
{
|
||||
int i, j, res_id, rc = 0;
|
||||
uint32_t used_bytes = 0, remain_size = 0, io_cfg_used_bytes;
|
||||
uint32_t *cpu_addr = NULL;
|
||||
struct cam_ife_sfe_scratch_buf_info *buf_info;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
|
||||
if (prepare->num_hw_update_entries + 1 >=
|
||||
prepare->max_hw_update_entries) {
|
||||
CAM_ERR(CAM_ISP, "Insufficient HW entries :%d %d",
|
||||
prepare->num_hw_update_entries,
|
||||
prepare->max_hw_update_entries);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
io_cfg_used_bytes = 0;
|
||||
|
||||
/* Update scratch buffer for IFE WMs */
|
||||
for (i = 0; i < ctx->sfe_info.ife_scratch_config->num_config; i++) {
|
||||
/*
|
||||
* Configure scratch only if the bit mask is not set for the given port,
|
||||
* this is determined after parsing all the IO config buffers
|
||||
*/
|
||||
if ((BIT(i) & scratch_cfg_mask))
|
||||
continue;
|
||||
|
||||
res_id = ctx->sfe_info.ife_scratch_config->buf_info[i].res_id & 0xFF;
|
||||
|
||||
hw_mgr_res = &res_list_isp_out[res_id];
|
||||
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
|
||||
if (!hw_mgr_res->hw_res[j])
|
||||
continue;
|
||||
|
||||
if (hw_mgr_res->hw_res[j]->hw_intf->hw_idx != base_idx)
|
||||
continue;
|
||||
|
||||
if ((kmd_buf_info->used_bytes + io_cfg_used_bytes) <
|
||||
kmd_buf_info->size) {
|
||||
remain_size = kmd_buf_info->size -
|
||||
(kmd_buf_info->used_bytes +
|
||||
io_cfg_used_bytes);
|
||||
} else {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"no free kmd memory for base %u",
|
||||
base_idx);
|
||||
rc = -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
cpu_addr = kmd_buf_info->cpu_addr +
|
||||
kmd_buf_info->used_bytes / 4 + io_cfg_used_bytes / 4;
|
||||
buf_info = &ctx->sfe_info.ife_scratch_config->buf_info[i];
|
||||
CAM_DBG(CAM_ISP, "WM res_id: 0x%x io_addr: %pK",
|
||||
hw_mgr_res->hw_res[j]->res_id, buf_info->io_addr);
|
||||
|
||||
rc = cam_isp_sfe_send_scratch_buf_upd(
|
||||
remain_size,
|
||||
CAM_ISP_HW_CMD_GET_BUF_UPDATE,
|
||||
hw_mgr_res->hw_res[j], buf_info,
|
||||
cpu_addr, &used_bytes);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
io_cfg_used_bytes += used_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (io_cfg_used_bytes)
|
||||
cam_ife_mgr_update_hw_entries_util(
|
||||
CAM_ISP_IOCFG_BL, io_cfg_used_bytes, kmd_buf_info, prepare);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_csid_add_reg_update(struct cam_ife_hw_mgr_ctx *ctx,
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct cam_kmd_buf_info *kmd_buf)
|
||||
@@ -10360,6 +10562,32 @@ static int cam_ife_hw_mgr_update_cmd_buffer(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cam_ife_hw_mgr_check_if_scratch_is_needed(
|
||||
struct cam_ife_hw_mgr_ctx *ctx,
|
||||
struct cam_isp_check_io_cfg_for_scratch *check_for_scratch)
|
||||
{
|
||||
/* Validate for scratch buffer use-cases sHDR/FS */
|
||||
if (!((ctx->flags.is_sfe_fs) || (ctx->flags.is_sfe_shdr)))
|
||||
return;
|
||||
|
||||
/* For SFE use number of fetches = number of scratch buffers needed */
|
||||
check_for_scratch->sfe_scratch_res_info.num_active_fe_rdis =
|
||||
ctx->sfe_info.num_fetches;
|
||||
check_for_scratch->validate_for_sfe = true;
|
||||
|
||||
/* Check if IFE has any scratch buffer */
|
||||
if (ctx->sfe_info.ife_scratch_config->num_config) {
|
||||
int i;
|
||||
|
||||
check_for_scratch->validate_for_ife = true;
|
||||
for (i = 0; i < ctx->sfe_info.ife_scratch_config->num_config; i++) {
|
||||
check_for_scratch->ife_scratch_res_info.ife_scratch_resources[i] =
|
||||
ctx->sfe_info.ife_scratch_config->buf_info[i].res_id;
|
||||
check_for_scratch->ife_scratch_res_info.num_ports++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
void *prepare_hw_update_args)
|
||||
{
|
||||
@@ -10377,8 +10605,8 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
|
||||
struct cam_isp_frame_header_info frame_header_info;
|
||||
struct list_head *res_list_ife_rd_tmp = NULL;
|
||||
struct cam_isp_check_sfe_fe_io_cfg sfe_fe_chk_cfg;
|
||||
struct cam_isp_cmd_buf_count cmd_buf_count = {0};
|
||||
struct cam_isp_check_io_cfg_for_scratch check_for_scratch = {0};
|
||||
|
||||
if (!hw_mgr_priv || !prepare_hw_update_args) {
|
||||
CAM_ERR(CAM_ISP, "Invalid args");
|
||||
@@ -10451,6 +10679,8 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
else
|
||||
prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_UPDATE_DEV;
|
||||
|
||||
cam_ife_hw_mgr_check_if_scratch_is_needed(ctx, &check_for_scratch);
|
||||
|
||||
for (i = 0; i < ctx->num_base; i++) {
|
||||
|
||||
memset(&frame_header_info, 0,
|
||||
@@ -10470,15 +10700,6 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
goto end;
|
||||
}
|
||||
|
||||
sfe_fe_chk_cfg.sfe_fe_enabled = false;
|
||||
if ((ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) &&
|
||||
((ctx->flags.is_sfe_fs) || (ctx->flags.is_sfe_shdr))) {
|
||||
sfe_fe_chk_cfg.sfe_fe_enabled = true;
|
||||
sfe_fe_chk_cfg.sfe_rdi_cfg_mask = 0;
|
||||
sfe_fe_chk_cfg.num_active_fe_rdis =
|
||||
ctx->sfe_info.num_fetches;
|
||||
}
|
||||
|
||||
/* get IO buffers */
|
||||
if (ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE)
|
||||
rc = cam_isp_add_io_buffers(
|
||||
@@ -10491,7 +10712,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
(CAM_ISP_IFE_OUT_RES_BASE + max_ife_out_res),
|
||||
fill_ife_fence,
|
||||
CAM_ISP_HW_TYPE_VFE, &frame_header_info,
|
||||
&sfe_fe_chk_cfg);
|
||||
&check_for_scratch);
|
||||
else if (ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE)
|
||||
rc = cam_isp_add_io_buffers(
|
||||
hw_mgr->mgr_common.img_iommu_hdl,
|
||||
@@ -10502,7 +10723,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
CAM_ISP_SFE_OUT_RES_BASE,
|
||||
CAM_ISP_SFE_OUT_RES_MAX, fill_sfe_fence,
|
||||
CAM_ISP_HW_TYPE_SFE, &frame_header_info,
|
||||
&sfe_fe_chk_cfg);
|
||||
&check_for_scratch);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed in io buffers, i=%d, rc=%d hw_type=%s",
|
||||
@@ -10511,33 +10732,27 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* fence map table entries need to fill only once in the loop */
|
||||
if ((ctx->base[i].hw_type ==
|
||||
CAM_ISP_HW_TYPE_SFE) &&
|
||||
fill_sfe_fence)
|
||||
fill_sfe_fence = false;
|
||||
else if ((ctx->base[i].hw_type ==
|
||||
CAM_ISP_HW_TYPE_VFE) &&
|
||||
fill_ife_fence)
|
||||
fill_ife_fence = false;
|
||||
|
||||
/*
|
||||
* Add scratch buffer if there no output buffer for RDI WMs/RMs
|
||||
* only for UPDATE packets. For INIT we could have ePCR enabled
|
||||
* based on that decide to configure scratch via AHB at
|
||||
* stream on or not
|
||||
*/
|
||||
if (sfe_fe_chk_cfg.sfe_fe_enabled) {
|
||||
if ((sfe_fe_chk_cfg.sfe_rdi_cfg_mask) !=
|
||||
if ((check_for_scratch.validate_for_sfe) &&
|
||||
(ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) && (fill_sfe_fence)) {
|
||||
struct cam_isp_sfe_scratch_buf_res_info *sfe_res_info =
|
||||
&check_for_scratch.sfe_scratch_res_info;
|
||||
|
||||
if ((sfe_res_info->sfe_rdi_cfg_mask) !=
|
||||
((1 << ctx->sfe_info.num_fetches) - 1)) {
|
||||
if (prepare_hw_data->packet_opcode_type ==
|
||||
CAM_ISP_PACKET_UPDATE_DEV) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Adding scratch buffer cfg_mask expected: 0x%x actual: 0x%x",
|
||||
"Adding SFE scratch buffer cfg_mask expected: 0x%x actual: 0x%x",
|
||||
((1 << ctx->sfe_info.num_fetches) - 1),
|
||||
sfe_fe_chk_cfg.sfe_rdi_cfg_mask);
|
||||
sfe_res_info->sfe_rdi_cfg_mask);
|
||||
rc = cam_isp_sfe_add_scratch_buffer_cfg(
|
||||
ctx->base[i].idx, sfe_fe_chk_cfg.sfe_rdi_cfg_mask,
|
||||
ctx->base[i].idx, sfe_res_info->sfe_rdi_cfg_mask,
|
||||
prepare, &kmd_buf, ctx->res_list_sfe_out,
|
||||
&ctx->res_list_ife_in_rd, ctx);
|
||||
if (rc)
|
||||
@@ -10549,7 +10764,36 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
}
|
||||
}
|
||||
|
||||
memset(&sfe_fe_chk_cfg, 0, sizeof(sfe_fe_chk_cfg));
|
||||
if ((check_for_scratch.validate_for_ife) &&
|
||||
(ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE) && (fill_ife_fence)) {
|
||||
struct cam_isp_ife_scratch_buf_res_info *ife_res_info =
|
||||
&check_for_scratch.ife_scratch_res_info;
|
||||
|
||||
/* Config IFE scratch only for update packets only */
|
||||
if ((ife_res_info->ife_scratch_cfg_mask) !=
|
||||
((1 << ife_res_info->num_ports) - 1)) {
|
||||
if (prepare_hw_data->packet_opcode_type ==
|
||||
CAM_ISP_PACKET_UPDATE_DEV) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Adding IFE scratch buffer cfg_mask expected: 0x%x actual: 0x%x",
|
||||
((1 << ife_res_info->num_ports) - 1),
|
||||
ife_res_info->ife_scratch_cfg_mask);
|
||||
rc = cam_isp_ife_add_scratch_buffer_cfg(
|
||||
ctx->base[i].idx,
|
||||
ife_res_info->ife_scratch_cfg_mask, prepare,
|
||||
&kmd_buf, ctx->res_list_ife_out, ctx);
|
||||
if (rc)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fence map table entries need to fill only once in the loop */
|
||||
if ((ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) && fill_sfe_fence)
|
||||
fill_sfe_fence = false;
|
||||
else if ((ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE) && fill_ife_fence)
|
||||
fill_ife_fence = false;
|
||||
|
||||
if (frame_header_info.frame_header_res_id &&
|
||||
frame_header_enable) {
|
||||
frame_header_enable = false;
|
||||
@@ -10997,6 +11241,45 @@ int cam_isp_config_csid_rup_aup(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_configure_scratch_for_ife(
|
||||
struct cam_ife_hw_mgr_ctx *ctx)
|
||||
{
|
||||
int i, j, rc = 0;
|
||||
uint32_t res_id;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_ife_sfe_scratch_buf_info *port_info;
|
||||
struct cam_ife_scratch_buf_cfg *ife_buf_info;
|
||||
struct cam_isp_hw_mgr_res *res_list_ife_out = NULL;
|
||||
|
||||
ife_buf_info = ctx->sfe_info.ife_scratch_config;
|
||||
res_list_ife_out = ctx->res_list_ife_out;
|
||||
|
||||
for (i = 0; i < ife_buf_info->num_config; i++) {
|
||||
res_id = ife_buf_info->buf_info[i].res_id & 0xFF;
|
||||
port_info = &ife_buf_info->buf_info[i];
|
||||
hw_mgr_res = &res_list_ife_out[res_id];
|
||||
|
||||
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
|
||||
/* j = 1 is not valid for this use-case */
|
||||
if (!hw_mgr_res->hw_res[j])
|
||||
continue;
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Configure scratch for IFE res: 0x%x io_addr %pK",
|
||||
ife_buf_info->buf_info[i].res_id, port_info->io_addr);
|
||||
|
||||
rc = cam_isp_sfe_send_scratch_buf_upd(0x0,
|
||||
CAM_ISP_HW_CMD_BUF_UPDATE,
|
||||
hw_mgr_res->hw_res[j], port_info,
|
||||
NULL, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scratch buffer is for sHDR/FS usescases involing SFE RDI0-2
|
||||
* There is no possibility of dual in this case, hence
|
||||
@@ -11007,10 +11290,10 @@ static int cam_ife_mgr_prog_default_settings(
|
||||
bool need_rup_aup, struct cam_ife_hw_mgr_ctx *ctx)
|
||||
{
|
||||
int i, j, res_id, rc = 0;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_sfe_scratch_buf_info *buf_info;
|
||||
struct list_head *res_list_in_rd = NULL;
|
||||
struct cam_isp_hw_mgr_res *res_list_sfe_out = NULL;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_ife_sfe_scratch_buf_info *buf_info;
|
||||
struct list_head *res_list_in_rd = NULL;
|
||||
struct cam_isp_hw_mgr_res *res_list_sfe_out = NULL;
|
||||
|
||||
res_list_in_rd = &ctx->res_list_ife_in_rd;
|
||||
res_list_sfe_out = ctx->res_list_sfe_out;
|
||||
@@ -11082,6 +11365,13 @@ static int cam_ife_mgr_prog_default_settings(
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for IFE scratch buffer */
|
||||
if (ctx->sfe_info.ife_scratch_config->num_config) {
|
||||
rc = cam_ife_mgr_configure_scratch_for_ife(ctx);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Program rup & aup only at run time */
|
||||
if (need_rup_aup) {
|
||||
rc = cam_isp_config_csid_rup_aup(ctx);
|
||||
@@ -12255,14 +12545,50 @@ static int cam_ife_hw_mgr_handle_hw_eof(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool cam_ife_hw_mgr_last_consumed_addr_check(
|
||||
uint32_t last_consumed_addr, struct cam_ife_sfe_scratch_buf_info *buf_info)
|
||||
{
|
||||
dma_addr_t final_addr;
|
||||
uint32_t cmp_addr = 0;
|
||||
|
||||
final_addr = buf_info->io_addr + buf_info->offset;
|
||||
cmp_addr = cam_smmu_is_expanded_memory() ?
|
||||
CAM_36BIT_INTF_GET_IOVA_BASE(final_addr) : final_addr;
|
||||
if (cmp_addr == last_consumed_addr)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_check_ife_scratch_buf_done(
|
||||
struct cam_ife_scratch_buf_cfg *scratch_cfg,
|
||||
uint32_t res_id, uint32_t last_consumed_addr)
|
||||
{
|
||||
int rc = 0, i;
|
||||
struct cam_ife_sfe_scratch_buf_info *buf_info;
|
||||
|
||||
for (i = 0; i < scratch_cfg->num_config; i++) {
|
||||
if (scratch_cfg->buf_info[i].res_id == res_id) {
|
||||
buf_info = &scratch_cfg->buf_info[i];
|
||||
|
||||
if (cam_ife_hw_mgr_last_consumed_addr_check(last_consumed_addr, buf_info)) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"IFE res:0x%x buf done for scratch - skip ctx notify",
|
||||
buf_info->res_id);
|
||||
rc = -EAGAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_check_rdi_scratch_buf_done(
|
||||
const uint32_t ctx_index, struct cam_sfe_scratch_buf_cfg *scratch_cfg,
|
||||
struct cam_sfe_scratch_buf_cfg *scratch_cfg,
|
||||
uint32_t res_id, uint32_t last_consumed_addr)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_sfe_scratch_buf_info *buf_info;
|
||||
dma_addr_t final_addr;
|
||||
uint32_t cmp_addr = 0;
|
||||
struct cam_ife_sfe_scratch_buf_info *buf_info;
|
||||
|
||||
switch (res_id) {
|
||||
case CAM_ISP_SFE_OUT_RES_RDI_0:
|
||||
@@ -12272,12 +12598,10 @@ static int cam_ife_hw_mgr_check_rdi_scratch_buf_done(
|
||||
if (!buf_info->config_done)
|
||||
return 0;
|
||||
|
||||
final_addr = buf_info->io_addr + buf_info->offset;
|
||||
cmp_addr = cam_smmu_is_expanded_memory() ?
|
||||
CAM_36BIT_INTF_GET_IOVA_BASE(final_addr) : final_addr;
|
||||
if (cmp_addr == last_consumed_addr) {
|
||||
CAM_DBG(CAM_ISP, "SFE RDI%u buf done for scratch - skip ctx notify",
|
||||
(res_id - CAM_ISP_SFE_OUT_RES_BASE));
|
||||
if (cam_ife_hw_mgr_last_consumed_addr_check(last_consumed_addr, buf_info)) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"SFE RDI: 0x%x buf done for scratch - skip ctx notify",
|
||||
buf_info->res_id);
|
||||
rc = -EAGAIN;
|
||||
}
|
||||
break;
|
||||
@@ -12288,6 +12612,32 @@ static int cam_ife_hw_mgr_check_rdi_scratch_buf_done(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_check_for_scratch_buf_done(
|
||||
struct cam_ife_hw_mgr_ctx *ife_hw_mgr_ctx,
|
||||
enum cam_isp_hw_type hw_type,
|
||||
uint32_t res_id, uint32_t last_consumed_addr)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
switch (hw_type) {
|
||||
case CAM_ISP_HW_TYPE_VFE:
|
||||
if (ife_hw_mgr_ctx->sfe_info.ife_scratch_config->num_config)
|
||||
rc = cam_ife_hw_mgr_check_ife_scratch_buf_done(
|
||||
ife_hw_mgr_ctx->sfe_info.ife_scratch_config,
|
||||
res_id, last_consumed_addr);
|
||||
break;
|
||||
case CAM_ISP_HW_TYPE_SFE:
|
||||
rc = cam_ife_hw_mgr_check_rdi_scratch_buf_done(
|
||||
ife_hw_mgr_ctx->sfe_info.scratch_config,
|
||||
res_id, last_consumed_addr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_hw_mgr_handle_hw_buf_done(
|
||||
struct cam_ife_hw_mgr_ctx *ife_hw_mgr_ctx,
|
||||
struct cam_isp_hw_event_info *event_info)
|
||||
@@ -12306,30 +12656,29 @@ static int cam_ife_hw_mgr_handle_hw_buf_done(
|
||||
|
||||
ife_hwr_irq_wm_done_cb = ife_hw_mgr_ctx->common.event_cb;
|
||||
compdone_evt_info = (struct cam_isp_hw_compdone_event_info *)event_info->event_data;
|
||||
buf_done_event_data.num_handles = compdone_evt_info->num_res;
|
||||
buf_done_event_data.num_handles = 0;
|
||||
|
||||
for (i = 0; i < compdone_evt_info->num_res; i++) {
|
||||
buf_done_event_data.resource_handle[i] =
|
||||
compdone_evt_info->res_id[i];
|
||||
buf_done_event_data.last_consumed_addr[i] =
|
||||
compdone_evt_info->last_consumed_addr[i];
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Buf done for %s: %d res_id: 0x%x last consumed addr: 0x%x ctx: %u",
|
||||
((event_info->hw_type == CAM_ISP_HW_TYPE_SFE) ? "SFE" : "IFE"),
|
||||
event_info->hw_idx, compdone_evt_info->res_id[i],
|
||||
compdone_evt_info->last_consumed_addr[i], ife_hw_mgr_ctx->ctx_index);
|
||||
|
||||
CAM_DBG(CAM_ISP, "Buf done for %s: %d res_id: 0x%x last consumed addr: 0x%x",
|
||||
((event_info->hw_type == CAM_ISP_HW_TYPE_SFE) ? "SFE" : "IFE"),
|
||||
event_info->hw_idx, compdone_evt_info->res_id[i],
|
||||
compdone_evt_info->last_consumed_addr[i]);
|
||||
|
||||
if (cam_ife_hw_mgr_is_shdr_fs_rdi_res(compdone_evt_info->res_id[i],
|
||||
ife_hw_mgr_ctx->flags.is_sfe_shdr,
|
||||
ife_hw_mgr_ctx->flags.is_sfe_fs)) {
|
||||
rc = cam_ife_hw_mgr_check_rdi_scratch_buf_done(
|
||||
ife_hw_mgr_ctx->ctx_index,
|
||||
ife_hw_mgr_ctx->sfe_info.scratch_config,
|
||||
compdone_evt_info->res_id[i],
|
||||
/* Check scratch for sHDR/FS use-cases */
|
||||
if (ife_hw_mgr_ctx->flags.is_sfe_fs || ife_hw_mgr_ctx->flags.is_sfe_shdr) {
|
||||
rc = cam_ife_hw_mgr_check_for_scratch_buf_done(ife_hw_mgr_ctx,
|
||||
event_info->hw_type, compdone_evt_info->res_id[i],
|
||||
compdone_evt_info->last_consumed_addr[i]);
|
||||
if (rc)
|
||||
goto end;
|
||||
continue;
|
||||
}
|
||||
|
||||
buf_done_event_data.resource_handle[buf_done_event_data.num_handles] =
|
||||
compdone_evt_info->res_id[i];
|
||||
buf_done_event_data.last_consumed_addr[buf_done_event_data.num_handles] =
|
||||
compdone_evt_info->last_consumed_addr[i];
|
||||
buf_done_event_data.num_handles++;
|
||||
}
|
||||
|
||||
|
||||
@@ -12337,12 +12686,13 @@ static int cam_ife_hw_mgr_handle_hw_buf_done(
|
||||
return 0;
|
||||
|
||||
if (buf_done_event_data.num_handles > 0 && ife_hwr_irq_wm_done_cb) {
|
||||
CAM_DBG(CAM_ISP, "Notify ISP context");
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Notify ISP context for %u handles in ctx: %u",
|
||||
buf_done_event_data.num_handles, ife_hw_mgr_ctx->ctx_index);
|
||||
ife_hwr_irq_wm_done_cb(ife_hw_mgr_ctx->common.cb_priv,
|
||||
CAM_ISP_HW_EVENT_DONE, (void *)&buf_done_event_data);
|
||||
}
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -81,7 +81,7 @@ struct cam_ife_hw_mgr_ctx_pf_info {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_sfe_scratch_buf_info - Scratch buf info
|
||||
* struct cam_ife_sfe_scratch_buf_info - Scratch buf info
|
||||
*
|
||||
* @width: Width in pixels
|
||||
* @height: Height in pixels
|
||||
@@ -93,7 +93,7 @@ struct cam_ife_hw_mgr_ctx_pf_info {
|
||||
* @config_done: To indicate if RDIx received scratch cfg
|
||||
* @is_secure: secure scratch buffer
|
||||
*/
|
||||
struct cam_sfe_scratch_buf_info {
|
||||
struct cam_ife_sfe_scratch_buf_info {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t stride;
|
||||
@@ -108,29 +108,45 @@ struct cam_sfe_scratch_buf_info {
|
||||
/**
|
||||
* struct cam_sfe_scratch_buf_cfg - Scratch buf info
|
||||
*
|
||||
* @num_configs: Number of buffer configs [max of 3 currently]
|
||||
* @num_configs : Total Number of scratch buffers provided
|
||||
* @curr_num_exp: Current num of exposures
|
||||
* @buf_info: Info on each of the buffers
|
||||
* @buf_info : Info on each of the buffers
|
||||
*
|
||||
*/
|
||||
struct cam_sfe_scratch_buf_cfg {
|
||||
uint32_t num_config;
|
||||
uint32_t curr_num_exp;
|
||||
struct cam_sfe_scratch_buf_info buf_info[
|
||||
uint32_t num_config;
|
||||
uint32_t curr_num_exp;
|
||||
struct cam_ife_sfe_scratch_buf_info buf_info[
|
||||
CAM_SFE_FE_RDI_NUM_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_sfe_scratch_buf_cfg - Scratch buf info
|
||||
*
|
||||
* @num_ports: Total Number of scratch buffers provided
|
||||
* @buf_info : Info on each of the buffers
|
||||
*
|
||||
*/
|
||||
struct cam_ife_scratch_buf_cfg {
|
||||
uint32_t num_config;
|
||||
struct cam_ife_sfe_scratch_buf_info buf_info[
|
||||
CAM_IFE_SCRATCH_NUM_MAX];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct cam_ife_hw_mgr_sfe_info - SFE info
|
||||
*
|
||||
* @skip_scratch_cfg_streamon: Determine if scratch cfg needs to be programmed at stream on
|
||||
* @num_fetches: Indicate number of SFE fetches for this stream
|
||||
* @scratch_config: Scratch buffer config if any for this stream
|
||||
* @scratch_config: Scratch buffer config if any for SFE ports
|
||||
* @ife_scratch_config: Scratch buffer config if any for IFE ports
|
||||
*/
|
||||
struct cam_ife_hw_mgr_sfe_info {
|
||||
bool skip_scratch_cfg_streamon;
|
||||
uint32_t num_fetches;
|
||||
struct cam_sfe_scratch_buf_cfg *scratch_config;
|
||||
struct cam_ife_scratch_buf_cfg *ife_scratch_config;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -678,20 +678,51 @@ int cam_sfe_add_command_buffers(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void cam_isp_validate_for_sfe_scratch(
|
||||
struct cam_isp_sfe_scratch_buf_res_info *sfe_res_info,
|
||||
uint32_t res_type, uint32_t out_base)
|
||||
{
|
||||
uint32_t res_id_out = res_type & 0xFF;
|
||||
|
||||
if ((res_id_out) < ((out_base & 0xFF) +
|
||||
sfe_res_info->num_active_fe_rdis)) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Buffer found for SFE port: 0x%x - skip scratch buffer",
|
||||
res_type);
|
||||
sfe_res_info->sfe_rdi_cfg_mask |= (1 << res_id_out);
|
||||
}
|
||||
}
|
||||
|
||||
static void cam_isp_validate_for_ife_scratch(
|
||||
struct cam_isp_ife_scratch_buf_res_info *ife_res_info,
|
||||
uint32_t res_type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ife_res_info->num_ports; i++) {
|
||||
if (res_type == ife_res_info->ife_scratch_resources[i]) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Buffer found for IFE port: 0x%x - skip scratch buffer",
|
||||
res_type);
|
||||
ife_res_info->ife_scratch_cfg_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cam_isp_add_io_buffers(
|
||||
int iommu_hdl,
|
||||
int sec_iommu_hdl,
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info,
|
||||
struct cam_isp_hw_mgr_res *res_list_isp_out,
|
||||
struct list_head *res_list_in_rd,
|
||||
uint32_t out_base,
|
||||
uint32_t out_max,
|
||||
bool fill_fence,
|
||||
enum cam_isp_hw_type hw_type,
|
||||
struct cam_isp_frame_header_info *frame_header_info,
|
||||
struct cam_isp_check_sfe_fe_io_cfg *check_sfe_fe_cfg)
|
||||
int iommu_hdl,
|
||||
int sec_iommu_hdl,
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info,
|
||||
struct cam_isp_hw_mgr_res *res_list_isp_out,
|
||||
struct list_head *res_list_in_rd,
|
||||
uint32_t out_base,
|
||||
uint32_t out_max,
|
||||
bool fill_fence,
|
||||
enum cam_isp_hw_type hw_type,
|
||||
struct cam_isp_frame_header_info *frame_header_info,
|
||||
struct cam_isp_check_io_cfg_for_scratch *scratch_check_cfg)
|
||||
{
|
||||
int rc = 0;
|
||||
dma_addr_t io_addr[CAM_PACKET_MAX_PLANES];
|
||||
@@ -750,14 +781,22 @@ int cam_isp_add_io_buffers(
|
||||
continue;
|
||||
|
||||
res_id_out = io_cfg[i].resource_type & 0xFF;
|
||||
if (check_sfe_fe_cfg->sfe_fe_enabled &&
|
||||
(res_id_out < ((out_base & 0xFF) +
|
||||
check_sfe_fe_cfg->num_active_fe_rdis))) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"SFE Write/Fetch engine cfg skip scratch buffer for res 0x%x",
|
||||
if ((hw_type == CAM_ISP_HW_TYPE_SFE) &&
|
||||
(scratch_check_cfg->validate_for_sfe)) {
|
||||
struct cam_isp_sfe_scratch_buf_res_info *sfe_res_info =
|
||||
&scratch_check_cfg->sfe_scratch_res_info;
|
||||
|
||||
cam_isp_validate_for_sfe_scratch(sfe_res_info,
|
||||
io_cfg[i].resource_type, out_base);
|
||||
}
|
||||
|
||||
if ((hw_type == CAM_ISP_HW_TYPE_VFE) &&
|
||||
(scratch_check_cfg->validate_for_ife)) {
|
||||
struct cam_isp_ife_scratch_buf_res_info *ife_res_info =
|
||||
&scratch_check_cfg->ife_scratch_res_info;
|
||||
|
||||
cam_isp_validate_for_ife_scratch(ife_res_info,
|
||||
io_cfg[i].resource_type);
|
||||
check_sfe_fe_cfg->sfe_rdi_cfg_mask |=
|
||||
1 << res_id_out;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
|
@@ -50,19 +50,46 @@ struct cam_isp_frame_header_info {
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_isp_check_sfe_fe_io_cfg
|
||||
*
|
||||
* @sfe_fe_enabled : True if SFE fetch engine is enabled
|
||||
* @num_active_fe_rdis : To indicate active RMs/RDIs
|
||||
* @sfe_rdi_cfg_mask : To indicate IO buf cfg for RDIs
|
||||
* struct cam_isp_sfe_scratch_buf_res_info
|
||||
*
|
||||
* @num_active_fe_rdis : To indicate active RMs/RDIs
|
||||
* @sfe_rdi_cfg_mask : Output mask to mark if the given RDI res has been
|
||||
* provided with IO cfg buffer
|
||||
*/
|
||||
struct cam_isp_check_sfe_fe_io_cfg {
|
||||
bool sfe_fe_enabled;
|
||||
struct cam_isp_sfe_scratch_buf_res_info {
|
||||
uint32_t num_active_fe_rdis;
|
||||
uint32_t sfe_rdi_cfg_mask;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_isp_ife_scratch_buf_res_info
|
||||
*
|
||||
* @num_ports : Number of ports for which scratch buffer is provided
|
||||
* @ife_scratch_resources : IFE resources that have been provided a scratch buffer
|
||||
* @ife_scratch_cfg_mask : Output mask to mark if the given client has been
|
||||
* provided with IO cfg buffer
|
||||
*/
|
||||
struct cam_isp_ife_scratch_buf_res_info {
|
||||
uint32_t num_ports;
|
||||
uint32_t ife_scratch_resources[CAM_IFE_SCRATCH_NUM_MAX];
|
||||
uint32_t ife_scratch_cfg_mask;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_isp_check_io_cfg_for_scratch
|
||||
*
|
||||
* @sfe_scratch_res_info : SFE scratch buffer validation info
|
||||
* @ife_scratch_res_info : IFE scratch buffer validation info
|
||||
* @validate_for_sfe : Validate for SFE clients, check if scratch is needed
|
||||
* @validate_for_ife : Validate for IFE clients, check if scratch is needed
|
||||
*/
|
||||
struct cam_isp_check_io_cfg_for_scratch {
|
||||
struct cam_isp_sfe_scratch_buf_res_info sfe_scratch_res_info;
|
||||
struct cam_isp_ife_scratch_buf_res_info ife_scratch_res_info;
|
||||
bool validate_for_sfe;
|
||||
bool validate_for_ife;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct cam_isp_change_base_args
|
||||
*
|
||||
@@ -209,24 +236,24 @@ int cam_isp_add_command_buffers(
|
||||
* @fill_fence: If true, Fence map table will be filled
|
||||
* @hw_type: HW type for this ctx base (IFE/SFE)
|
||||
* @frame_header_info: Frame header related params
|
||||
* @check_sfe_fe_cfg: Validate if sfe fetch received IO cfg
|
||||
* @scratch_check_cfg: Validate info for IFE/SFE scratch buffers
|
||||
* @return: 0 for success
|
||||
* -EINVAL for Fail
|
||||
*/
|
||||
int cam_isp_add_io_buffers(
|
||||
int iommu_hdl,
|
||||
int sec_iommu_hdl,
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info,
|
||||
struct cam_isp_hw_mgr_res *res_list_isp_out,
|
||||
struct list_head *res_list_ife_in_rd,
|
||||
uint32_t out_base,
|
||||
uint32_t out_max,
|
||||
bool fill_fence,
|
||||
enum cam_isp_hw_type hw_type,
|
||||
struct cam_isp_frame_header_info *frame_header_info,
|
||||
struct cam_isp_check_sfe_fe_io_cfg *check_sfe_fe_cfg);
|
||||
int iommu_hdl,
|
||||
int sec_iommu_hdl,
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info,
|
||||
struct cam_isp_hw_mgr_res *res_list_isp_out,
|
||||
struct list_head *res_list_ife_in_rd,
|
||||
uint32_t out_base,
|
||||
uint32_t out_max,
|
||||
bool fill_fence,
|
||||
enum cam_isp_hw_type hw_type,
|
||||
struct cam_isp_frame_header_info *frame_header_info,
|
||||
struct cam_isp_check_io_cfg_for_scratch *scratch_check_cfg);
|
||||
|
||||
/*
|
||||
* cam_isp_add_reg_update()
|
||||
|
@@ -13,15 +13,17 @@
|
||||
#include "cam_hw_mgr_intf.h"
|
||||
|
||||
/* MAX IFE instance */
|
||||
#define CAM_IFE_HW_NUM_MAX 8
|
||||
#define CAM_SFE_HW_NUM_MAX 2
|
||||
#define CAM_IFE_RDI_NUM_MAX 4
|
||||
#define CAM_SFE_RDI_NUM_MAX 5
|
||||
#define CAM_SFE_FE_RDI_NUM_MAX 3
|
||||
#define CAM_ISP_BW_CONFIG_V1 1
|
||||
#define CAM_ISP_BW_CONFIG_V2 2
|
||||
#define CAM_TFE_HW_NUM_MAX 3
|
||||
#define CAM_TFE_RDI_NUM_MAX 3
|
||||
#define CAM_IFE_HW_NUM_MAX 8
|
||||
#define CAM_SFE_HW_NUM_MAX 2
|
||||
#define CAM_IFE_RDI_NUM_MAX 4
|
||||
#define CAM_SFE_RDI_NUM_MAX 5
|
||||
#define CAM_SFE_FE_RDI_NUM_MAX 3
|
||||
#define CAM_ISP_BW_CONFIG_V1 1
|
||||
#define CAM_ISP_BW_CONFIG_V2 2
|
||||
#define CAM_TFE_HW_NUM_MAX 3
|
||||
#define CAM_TFE_RDI_NUM_MAX 3
|
||||
#define CAM_IFE_SCRATCH_NUM_MAX 2
|
||||
|
||||
|
||||
/* maximum context numbers for TFE */
|
||||
#define CAM_TFE_CTX_MAX 4
|
||||
|
@@ -537,6 +537,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
case CAM_ISP_HW_CMD_IFE_BUS_DEBUG_CFG:
|
||||
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||
case CAM_ISP_HW_BUS_MINI_DUMP:
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE:
|
||||
rc = core_info->vfe_bus->hw_ops.process_cmd(
|
||||
core_info->vfe_bus->bus_priv, cmd_type, cmd_args,
|
||||
arg_size);
|
||||
|
@@ -196,6 +196,7 @@ struct cam_vfe_bus_ver3_vfe_out_data {
|
||||
uint32_t secure_mode;
|
||||
void *priv;
|
||||
uint32_t mid[CAM_VFE_BUS_VER3_MAX_MID_PER_PORT];
|
||||
bool limiter_enabled;
|
||||
};
|
||||
|
||||
struct cam_vfe_bus_ver3_priv {
|
||||
@@ -1999,6 +2000,7 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args,
|
||||
out_acquire_args->disable_ubwc_comp;
|
||||
rsrc_data->priv = acq_args->priv;
|
||||
rsrc_data->bus_priv = ver3_bus_priv;
|
||||
rsrc_data->limiter_enabled = false;
|
||||
comp_acq_args.composite_mask = (1ULL << vfe_out_res_id);
|
||||
|
||||
/* for some hw versions, buf done is not received from vfe but
|
||||
@@ -3153,6 +3155,165 @@ end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_ver3_config_ubwc_regs(
|
||||
struct cam_vfe_bus_ver3_wm_resource_data *wm_data)
|
||||
{
|
||||
struct cam_vfe_bus_ver3_reg_offset_ubwc_client *ubwc_regs =
|
||||
(struct cam_vfe_bus_ver3_reg_offset_ubwc_client *)
|
||||
wm_data->hw_regs->ubwc_regs;
|
||||
|
||||
cam_io_w_mb(wm_data->packer_cfg, wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->packer_cfg);
|
||||
CAM_DBG(CAM_ISP, "WM:%d packer cfg:0x%x",
|
||||
wm_data->index, wm_data->packer_cfg);
|
||||
|
||||
cam_io_w_mb(wm_data->ubwc_meta_cfg,
|
||||
wm_data->common_data->mem_base + ubwc_regs->meta_cfg);
|
||||
CAM_DBG(CAM_ISP, "WM:%d meta stride:0x%x",
|
||||
wm_data->index, wm_data->ubwc_meta_cfg);
|
||||
|
||||
if (wm_data->common_data->disable_ubwc_comp) {
|
||||
wm_data->ubwc_mode_cfg &= ~ubwc_regs->ubwc_comp_en_bit;
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Force disable UBWC compression on VFE:%d WM:%d",
|
||||
wm_data->common_data->core_index, wm_data->index);
|
||||
}
|
||||
|
||||
cam_io_w_mb(wm_data->ubwc_mode_cfg,
|
||||
wm_data->common_data->mem_base + ubwc_regs->mode_cfg);
|
||||
CAM_DBG(CAM_ISP, "WM:%d ubwc_mode_cfg:0x%x",
|
||||
wm_data->index, wm_data->ubwc_mode_cfg);
|
||||
|
||||
cam_io_w_mb(wm_data->ubwc_ctrl_2,
|
||||
wm_data->common_data->mem_base + ubwc_regs->ctrl_2);
|
||||
CAM_DBG(CAM_ISP, "WM:%d ubwc_ctrl_2:0x%x",
|
||||
wm_data->index, wm_data->ubwc_ctrl_2);
|
||||
|
||||
cam_io_w_mb(wm_data->ubwc_lossy_threshold_0,
|
||||
wm_data->common_data->mem_base + ubwc_regs->lossy_thresh0);
|
||||
CAM_DBG(CAM_ISP, "WM:%d lossy_thresh0: 0x%x",
|
||||
wm_data->index, wm_data->ubwc_lossy_threshold_0);
|
||||
|
||||
cam_io_w_mb(wm_data->ubwc_lossy_threshold_1,
|
||||
wm_data->common_data->mem_base + ubwc_regs->lossy_thresh1);
|
||||
CAM_DBG(CAM_ISP, "WM:%d lossy_thresh0:0x%x",
|
||||
wm_data->index, wm_data->ubwc_lossy_threshold_1);
|
||||
|
||||
cam_io_w_mb(wm_data->ubwc_offset_lossy_variance,
|
||||
wm_data->common_data->mem_base + ubwc_regs->off_lossy_var);
|
||||
CAM_DBG(CAM_ISP, "WM:%d off_lossy_var:0x%x",
|
||||
wm_data->index, wm_data->ubwc_offset_lossy_variance);
|
||||
|
||||
/*
|
||||
* If limit value >= 0xFFFF, limit configured by
|
||||
* generic limiter blob
|
||||
*/
|
||||
if (wm_data->ubwc_bandwidth_limit < 0xFFFF) {
|
||||
cam_io_w_mb(wm_data->ubwc_bandwidth_limit,
|
||||
wm_data->common_data->mem_base + ubwc_regs->bw_limit);
|
||||
CAM_DBG(CAM_ISP, "WM:%d ubwc bw limit:0x%x",
|
||||
wm_data->index, wm_data->ubwc_bandwidth_limit);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_ver3_config_wm(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_vfe_bus_ver3_priv *bus_priv;
|
||||
struct cam_isp_hw_get_cmd_update *update_buf;
|
||||
struct cam_vfe_bus_ver3_vfe_out_data *vfe_out_data = NULL;
|
||||
struct cam_vfe_bus_ver3_wm_resource_data *wm_data = NULL;
|
||||
struct cam_vfe_bus_ver3_reg_offset_ubwc_client *ubwc_regs;
|
||||
uint32_t i, val, iova_addr, iova_offset, stride;
|
||||
dma_addr_t iova;
|
||||
|
||||
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
|
||||
vfe_out_data = (struct cam_vfe_bus_ver3_vfe_out_data *)
|
||||
update_buf->res->res_priv;
|
||||
if (!vfe_out_data) {
|
||||
CAM_ERR(CAM_ISP, "Invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!vfe_out_data->limiter_enabled)
|
||||
CAM_WARN(CAM_ISP,
|
||||
"Configuring scratch for VFE out_type: %u, with no BW limiter enabled",
|
||||
vfe_out_data->out_type);
|
||||
|
||||
for (i = 0; i < vfe_out_data->num_wm; i++) {
|
||||
wm_data = vfe_out_data->wm_res[i].res_priv;
|
||||
ubwc_regs = (struct cam_vfe_bus_ver3_reg_offset_ubwc_client *)
|
||||
wm_data->hw_regs->ubwc_regs;
|
||||
|
||||
stride = update_buf->wm_update->stride;
|
||||
val = stride;
|
||||
val = ALIGNUP(val, 16);
|
||||
if (val != stride &&
|
||||
val != wm_data->stride)
|
||||
CAM_WARN(CAM_SFE, "Warning stride %u expected %u",
|
||||
stride, val);
|
||||
|
||||
if (wm_data->stride != val || !wm_data->init_cfg_done) {
|
||||
cam_io_w_mb(stride, wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->image_cfg_2);
|
||||
wm_data->stride = val;
|
||||
CAM_DBG(CAM_ISP, "WM:%d image stride 0x%x",
|
||||
wm_data->index, stride);
|
||||
}
|
||||
|
||||
/* WM Image address */
|
||||
iova = update_buf->wm_update->image_buf[i];
|
||||
if (cam_smmu_is_expanded_memory()) {
|
||||
iova_addr = CAM_36BIT_INTF_GET_IOVA_BASE(iova);
|
||||
iova_offset = CAM_36BIT_INTF_GET_IOVA_OFFSET(iova);
|
||||
|
||||
cam_io_w_mb(iova_addr, wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->image_addr);
|
||||
cam_io_w_mb(iova_offset, wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->addr_cfg);
|
||||
|
||||
CAM_DBG(CAM_ISP, "WM:%d image address 0x%x 0x%x",
|
||||
wm_data->index, iova_addr, iova_offset);
|
||||
} else {
|
||||
iova_addr = iova;
|
||||
cam_io_w_mb(iova_addr, wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->image_addr);
|
||||
CAM_DBG(CAM_ISP, "WM:%d image address 0x%X",
|
||||
wm_data->index, iova_addr);
|
||||
}
|
||||
|
||||
if (wm_data->en_ubwc) {
|
||||
if (!wm_data->hw_regs->ubwc_regs) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"No UBWC register to configure for WM: %u",
|
||||
wm_data->index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wm_data->ubwc_updated) {
|
||||
wm_data->ubwc_updated = false;
|
||||
cam_vfe_bus_ver3_config_ubwc_regs(wm_data);
|
||||
}
|
||||
|
||||
cam_io_w_mb(iova_addr, wm_data->common_data->mem_base +
|
||||
ubwc_regs->meta_addr);
|
||||
CAM_DBG(CAM_ISP, "WM:%d meta address 0x%x",
|
||||
wm_data->index, iova_addr);
|
||||
}
|
||||
|
||||
/* enable the WM */
|
||||
cam_io_w_mb(wm_data->en_cfg, wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->cfg);
|
||||
CAM_DBG(CAM_ISP, "WM:%d en_cfg 0x%x", wm_data->index, wm_data->en_cfg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
@@ -3167,7 +3328,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
||||
uint32_t num_regval_pairs = 0;
|
||||
uint32_t i, j, size = 0;
|
||||
uint32_t frame_inc = 0, val;
|
||||
uint32_t iova_addr, iova_offset, image_buf_offset = 0;
|
||||
uint32_t iova_addr, iova_offset, image_buf_offset = 0, stride, slice_h;
|
||||
dma_addr_t iova;
|
||||
|
||||
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
|
||||
@@ -3181,7 +3342,8 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
||||
}
|
||||
|
||||
cdm_util_ops = vfe_out_data->cdm_util_ops;
|
||||
if (update_buf->wm_update->num_buf != vfe_out_data->num_wm) {
|
||||
if ((update_buf->wm_update->num_buf != vfe_out_data->num_wm) &&
|
||||
(!(update_buf->use_scratch_cfg))) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed! Invalid number buffers:%d required:%d",
|
||||
update_buf->wm_update->num_buf, vfe_out_data->num_wm);
|
||||
@@ -3189,7 +3351,17 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
||||
}
|
||||
|
||||
reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
|
||||
io_cfg = update_buf->wm_update->io_cfg;
|
||||
if (update_buf->use_scratch_cfg) {
|
||||
CAM_DBG(CAM_ISP, "Using scratch for IFE out_type: %u",
|
||||
vfe_out_data->out_type);
|
||||
|
||||
if (!vfe_out_data->limiter_enabled)
|
||||
CAM_WARN(CAM_ISP,
|
||||
"Configuring scratch for VFE out_type: %u, with no BW limiter enabled",
|
||||
vfe_out_data->out_type);
|
||||
} else {
|
||||
io_cfg = update_buf->wm_update->io_cfg;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < vfe_out_data->num_wm; i++) {
|
||||
if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
|
||||
@@ -3250,17 +3422,25 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
||||
wm_data->index, reg_val_pair[j-1]);
|
||||
|
||||
/* For initial configuration program all bus registers */
|
||||
val = io_cfg->planes[i].plane_stride;
|
||||
if (update_buf->use_scratch_cfg) {
|
||||
stride = update_buf->wm_update->stride;
|
||||
slice_h = update_buf->wm_update->slice_height;
|
||||
} else {
|
||||
stride = io_cfg->planes[i].plane_stride;
|
||||
slice_h = io_cfg->planes[i].slice_height;
|
||||
}
|
||||
|
||||
val = stride;
|
||||
CAM_DBG(CAM_ISP, "before stride %d", val);
|
||||
val = ALIGNUP(val, 16);
|
||||
if (val != io_cfg->planes[i].plane_stride)
|
||||
if (val != stride)
|
||||
CAM_DBG(CAM_ISP, "Warning stride %u expected %u",
|
||||
io_cfg->planes[i].plane_stride, val);
|
||||
stride, val);
|
||||
|
||||
if (wm_data->stride != val || !wm_data->init_cfg_done) {
|
||||
CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
wm_data->hw_regs->image_cfg_2,
|
||||
io_cfg->planes[i].plane_stride);
|
||||
stride);
|
||||
wm_data->stride = val;
|
||||
CAM_DBG(CAM_ISP, "WM:%d image stride 0x%X",
|
||||
wm_data->index, reg_val_pair[j-1]);
|
||||
@@ -3288,19 +3468,20 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
||||
update_buf->wm_update->image_buf[i]);
|
||||
}
|
||||
|
||||
frame_inc = stride * slice_h;
|
||||
if (wm_data->en_ubwc) {
|
||||
frame_inc = ALIGNUP(io_cfg->planes[i].plane_stride *
|
||||
io_cfg->planes[i].slice_height, 4096);
|
||||
frame_inc += io_cfg->planes[i].meta_size;
|
||||
CAM_DBG(CAM_ISP,
|
||||
"WM:%d frm %d: ht: %d stride %d meta: %d",
|
||||
wm_data->index, frame_inc,
|
||||
io_cfg->planes[i].slice_height,
|
||||
io_cfg->planes[i].plane_stride,
|
||||
io_cfg->planes[i].meta_size);
|
||||
} else {
|
||||
frame_inc = io_cfg->planes[i].plane_stride *
|
||||
io_cfg->planes[i].slice_height;
|
||||
frame_inc = ALIGNUP(stride *
|
||||
slice_h, 4096);
|
||||
|
||||
if (!update_buf->use_scratch_cfg) {
|
||||
frame_inc += io_cfg->planes[i].meta_size;
|
||||
CAM_DBG(CAM_ISP,
|
||||
"WM:%d frm %d: ht: %d stride %d meta: %d",
|
||||
wm_data->index, frame_inc,
|
||||
io_cfg->planes[i].slice_height,
|
||||
io_cfg->planes[i].plane_stride,
|
||||
io_cfg->planes[i].meta_size);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(wm_data->en_cfg & (0x3 << 16))) {
|
||||
@@ -3310,7 +3491,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args,
|
||||
wm_data->index, reg_val_pair[j-1]);
|
||||
}
|
||||
|
||||
if (wm_data->en_ubwc)
|
||||
if ((wm_data->en_ubwc) && (!update_buf->use_scratch_cfg))
|
||||
image_buf_offset = io_cfg->planes[i].meta_size;
|
||||
else if (wm_data->en_cfg & (0x3 << 16))
|
||||
image_buf_offset = wm_data->offset;
|
||||
@@ -3758,6 +3939,7 @@ static int cam_vfe_bus_update_bw_limiter(
|
||||
uint32_t counter_limit = 0, reg_val = 0;
|
||||
uint32_t *reg_val_pair, num_regval_pairs = 0;
|
||||
uint32_t i, j, size = 0;
|
||||
bool limiter_enabled = false;
|
||||
|
||||
bus_priv = (struct cam_vfe_bus_ver3_priv *) priv;
|
||||
wm_config_update = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
@@ -3813,6 +3995,7 @@ static int cam_vfe_bus_update_bw_limiter(
|
||||
if (wm_bw_limit_cfg->enable_limiter && counter_limit) {
|
||||
reg_val = 1;
|
||||
reg_val |= (counter_limit << 1);
|
||||
limiter_enabled = true;
|
||||
} else {
|
||||
reg_val = 0;
|
||||
}
|
||||
@@ -3853,6 +4036,7 @@ add_reg_pair:
|
||||
wm_config_update->cmd.used_bytes = 0;
|
||||
}
|
||||
|
||||
vfe_out_data->limiter_enabled = limiter_enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4063,6 +4247,9 @@ static int cam_vfe_bus_ver3_process_cmd(
|
||||
"disabled" : "enabled");
|
||||
rc = 0;
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE:
|
||||
rc = cam_vfe_bus_ver3_config_wm(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||
rc = cam_vfe_bus_update_bw_limiter(priv, cmd_args, arg_size);
|
||||
break;
|
||||
|
Yeni konuda referans
Bir kullanıcı engelle