msm: camera: isp: Add per frame support for scratch buffers
If CRM skips applying settings on a given frame, in case of sHDR program scratch buffers along with RUP/AUP to ensure continuity with respect to sensor frames. CRs-Fixed: 2841729 Change-Id: I296dbc713f49db54681043415b6ad1499dc13de4 Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
131c340861
commit
fa9a698aa1
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_HW_MGR_INTF_H_
|
||||
@@ -113,9 +113,8 @@ struct cam_hw_done_event_data {
|
||||
* @acquire_info: Acquired resource array pointer
|
||||
* @ctxt_to_hw_map: HW context (returned)
|
||||
* @hw_mgr_ctx_id HWMgr context id(returned)
|
||||
* @custom_enabled: ctx has custom enabled
|
||||
* @use_frame_header_ts: Use frame header for qtimer ts
|
||||
* @support_consumed_addr: The platform has last consumed addr register
|
||||
* @op_flags: Used as bitwise params from hw_mgr to ctx
|
||||
* See xxx_hw_mgr_intf.h for definitions
|
||||
* @acquired_hw_id: Acquired hardware mask
|
||||
* @acquired_hw_path: Acquired path mask for an input
|
||||
* if input splits into multiple paths,
|
||||
@@ -132,9 +131,7 @@ struct cam_hw_acquire_args {
|
||||
uintptr_t acquire_info;
|
||||
void *ctxt_to_hw_map;
|
||||
uint32_t hw_mgr_ctx_id;
|
||||
bool custom_enabled;
|
||||
bool use_frame_header_ts;
|
||||
bool support_consumed_addr;
|
||||
uint32_t op_flags;
|
||||
|
||||
uint32_t acquired_hw_id[CAM_MAX_ACQ_RES];
|
||||
uint32_t acquired_hw_path[CAM_MAX_ACQ_RES][CAM_MAX_HW_SPLIT];
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
@@ -3275,6 +3275,32 @@ static int __cam_isp_ctx_apply_req_in_bubble(
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_isp_ctx_apply_default_req_settings(
|
||||
struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_isp_context *isp_ctx =
|
||||
(struct cam_isp_context *) ctx->ctx_priv;
|
||||
struct cam_hw_cmd_args hw_cmd_args;
|
||||
struct cam_isp_hw_cmd_args isp_hw_cmd_args;
|
||||
|
||||
hw_cmd_args.ctxt_to_hw_map = isp_ctx->hw_ctx;
|
||||
hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
|
||||
isp_hw_cmd_args.cmd_type =
|
||||
CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG;
|
||||
hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
|
||||
|
||||
rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv,
|
||||
&hw_cmd_args);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed to apply default settings rc %d", rc);
|
||||
else
|
||||
CAM_DBG(CAM_ISP, "Applied default settings rc %d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_isp_ctx_dump_req_info(
|
||||
struct cam_context *ctx,
|
||||
struct cam_ctx_request *req,
|
||||
@@ -3670,6 +3696,8 @@ static struct cam_ctx_ops
|
||||
.ioctl_ops = {},
|
||||
.crm_ops = {
|
||||
.apply_req = __cam_isp_ctx_apply_req_in_sof,
|
||||
.notify_frame_skip =
|
||||
__cam_isp_ctx_apply_default_req_settings,
|
||||
},
|
||||
.irq_ops = NULL,
|
||||
},
|
||||
@@ -3684,6 +3712,8 @@ static struct cam_ctx_ops
|
||||
.ioctl_ops = {},
|
||||
.crm_ops = {
|
||||
.apply_req = __cam_isp_ctx_apply_req_in_epoch,
|
||||
.notify_frame_skip =
|
||||
__cam_isp_ctx_apply_default_req_settings,
|
||||
},
|
||||
.irq_ops = NULL,
|
||||
},
|
||||
@@ -3692,6 +3722,8 @@ static struct cam_ctx_ops
|
||||
.ioctl_ops = {},
|
||||
.crm_ops = {
|
||||
.apply_req = __cam_isp_ctx_apply_req_in_bubble,
|
||||
.notify_frame_skip =
|
||||
__cam_isp_ctx_apply_default_req_settings,
|
||||
},
|
||||
.irq_ops = NULL,
|
||||
},
|
||||
@@ -4306,6 +4338,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
|
||||
ctx->last_flush_req = 0;
|
||||
ctx_isp->custom_enabled = false;
|
||||
ctx_isp->use_frame_header_ts = false;
|
||||
ctx_isp->use_default_apply = false;
|
||||
ctx_isp->frame_id = 0;
|
||||
ctx_isp->active_req_cnt = 0;
|
||||
ctx_isp->reported_req_id = 0;
|
||||
@@ -4928,7 +4961,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx,
|
||||
}
|
||||
|
||||
ctx_isp->support_consumed_addr =
|
||||
param.support_consumed_addr;
|
||||
(param.op_flags & CAM_IFE_CTX_FRAME_HEADER_EN);
|
||||
|
||||
/* Query the context has rdi only resource */
|
||||
hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
|
||||
@@ -5077,13 +5110,18 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
|
||||
goto free_res;
|
||||
}
|
||||
|
||||
/* Set custom flag if applicable
|
||||
/*
|
||||
* Set feature flag if applicable
|
||||
* custom hw is supported only on v2
|
||||
*/
|
||||
ctx_isp->custom_enabled = param.custom_enabled;
|
||||
ctx_isp->use_frame_header_ts = param.use_frame_header_ts;
|
||||
ctx_isp->custom_enabled =
|
||||
(param.op_flags & CAM_IFE_CTX_CUSTOM_EN);
|
||||
ctx_isp->use_frame_header_ts =
|
||||
(param.op_flags & CAM_IFE_CTX_FRAME_HEADER_EN);
|
||||
ctx_isp->use_default_apply =
|
||||
(param.op_flags & CAM_IFE_CTX_APPLY_DEFAULT_CFG);
|
||||
ctx_isp->support_consumed_addr =
|
||||
param.support_consumed_addr;
|
||||
(param.op_flags & CAM_IFE_CTX_CONSUME_ADDR_EN);
|
||||
|
||||
/* Query the context has rdi only resource */
|
||||
hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map;
|
||||
@@ -5761,6 +5799,39 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_isp_ctx_apply_default_settings(
|
||||
struct cam_context *ctx,
|
||||
struct cam_req_mgr_apply_request *apply)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_ctx_ops *ctx_ops = NULL;
|
||||
struct cam_isp_context *ctx_isp =
|
||||
(struct cam_isp_context *) ctx->ctx_priv;
|
||||
|
||||
if (!ctx_isp->use_default_apply)
|
||||
return 0;
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Enter: apply req in Substate %d request _id:%lld",
|
||||
ctx_isp->substate_activated, apply->request_id);
|
||||
|
||||
ctx_ops = &ctx_isp->substate_machine[
|
||||
ctx_isp->substate_activated];
|
||||
if (ctx_ops->crm_ops.notify_frame_skip) {
|
||||
rc = ctx_ops->crm_ops.notify_frame_skip(ctx, apply);
|
||||
} else {
|
||||
CAM_WARN_RATE_LIMIT(CAM_ISP,
|
||||
"No handle function in activated substate %d",
|
||||
ctx_isp->substate_activated);
|
||||
rc = -EFAULT;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
CAM_WARN_RATE_LIMIT(CAM_ISP,
|
||||
"Apply default failed in active substate %d rc %d",
|
||||
ctx_isp->substate_activated, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int __cam_isp_ctx_handle_irq_in_activated(void *context,
|
||||
@@ -5878,6 +5949,8 @@ static struct cam_ctx_ops
|
||||
.crm_ops = {
|
||||
.unlink = __cam_isp_ctx_unlink_in_activated,
|
||||
.apply_req = __cam_isp_ctx_apply_req,
|
||||
.notify_frame_skip =
|
||||
__cam_isp_ctx_apply_default_settings,
|
||||
.flush_req = __cam_isp_ctx_flush_req_in_top_state,
|
||||
.process_evt = __cam_isp_ctx_process_evt,
|
||||
.dump_req = __cam_isp_ctx_dump_in_top_state,
|
||||
@@ -6078,6 +6151,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
|
||||
ctx->frame_id = 0;
|
||||
ctx->custom_enabled = false;
|
||||
ctx->use_frame_header_ts = false;
|
||||
ctx->use_default_apply = false;
|
||||
ctx->active_req_cnt = 0;
|
||||
ctx->reported_req_id = 0;
|
||||
ctx->bubble_frame_cnt = 0;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_ISP_CONTEXT_H_
|
||||
@@ -270,6 +270,7 @@ struct cam_isp_context_event_record {
|
||||
* @use_frame_header_ts: Use frame header for qtimer ts
|
||||
* @support_consumed_addr: Indicate whether HW has last consumed addr reg
|
||||
* @apply_in_progress Whether request apply is in progress
|
||||
* @use_default_apply: Use default settings in case of frame skip
|
||||
* @init_timestamp: Timestamp at which this context is initialized
|
||||
* @isp_device_type: ISP device type
|
||||
* @rxd_epoch: Indicate whether epoch has been received. Used to
|
||||
@@ -318,6 +319,7 @@ struct cam_isp_context {
|
||||
bool use_frame_header_ts;
|
||||
bool support_consumed_addr;
|
||||
atomic_t apply_in_progress;
|
||||
bool use_default_apply;
|
||||
unsigned int init_timestamp;
|
||||
uint32_t isp_device_type;
|
||||
atomic_t rxd_epoch;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
@@ -4047,6 +4047,9 @@ skip_csid_pxl:
|
||||
}
|
||||
}
|
||||
|
||||
if (in_port->dynamic_sensor_switch_en)
|
||||
ife_ctx->ctx_config |= CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
/* release resource at the acquire entry funciton */
|
||||
@@ -4357,7 +4360,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
||||
}
|
||||
|
||||
cam_cpas_get_cpas_hw_version(&ife_ctx->hw_version);
|
||||
ife_ctx->custom_config = 0;
|
||||
ife_ctx->ctx_config = 0;
|
||||
ife_ctx->cdm_handle = 0;
|
||||
ife_ctx->ctx_type = CAM_IFE_CTX_TYPE_NONE;
|
||||
|
||||
@@ -4420,10 +4423,10 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
||||
if (in_port[i].cust_node) {
|
||||
ife_ctx->ctx_type = CAM_IFE_CTX_TYPE_CUSTOM;
|
||||
/* These can be obtained from uapi */
|
||||
ife_ctx->custom_config |=
|
||||
CAM_IFE_CUSTOM_CFG_FRAME_HEADER_TS;
|
||||
ife_ctx->custom_config |=
|
||||
CAM_IFE_CUSTOM_CFG_SW_SYNC_ON;
|
||||
ife_ctx->ctx_config |=
|
||||
CAM_IFE_CTX_CFG_FRAME_HEADER_TS;
|
||||
ife_ctx->ctx_config |=
|
||||
CAM_IFE_CTX_CFG_SW_SYNC_ON;
|
||||
} else if (in_port[i].sfe_in_path_type) {
|
||||
ife_ctx->ctx_type = CAM_IFE_CTX_TYPE_SFE;
|
||||
}
|
||||
@@ -4517,16 +4520,26 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
||||
atomic_set(&ife_ctx->cdm_done, 1);
|
||||
ife_ctx->last_cdm_done_req = 0;
|
||||
|
||||
acquire_args->support_consumed_addr =
|
||||
g_ife_hw_mgr.support_consumed_addr;
|
||||
if (g_ife_hw_mgr.support_consumed_addr)
|
||||
acquire_args->op_flags |=
|
||||
CAM_IFE_CTX_CONSUME_ADDR_EN;
|
||||
|
||||
if ((ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) &&
|
||||
ife_ctx->is_fe_enabled) {
|
||||
ife_ctx->ctx_config |= CAM_IFE_CTX_CFG_SFE_FE_MODE;
|
||||
acquire_args->op_flags |=
|
||||
CAM_IFE_CTX_APPLY_DEFAULT_CFG;
|
||||
}
|
||||
|
||||
acquire_args->ctxt_to_hw_map = ife_ctx;
|
||||
acquire_args->custom_enabled = false;
|
||||
if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_CUSTOM)
|
||||
acquire_args->custom_enabled = true;
|
||||
acquire_args->use_frame_header_ts =
|
||||
(ife_ctx->custom_config &
|
||||
CAM_IFE_CUSTOM_CFG_FRAME_HEADER_TS);
|
||||
acquire_args->op_flags |= CAM_IFE_CTX_CUSTOM_EN;
|
||||
|
||||
if (ife_ctx->ctx_config &
|
||||
CAM_IFE_CTX_CFG_FRAME_HEADER_TS)
|
||||
acquire_args->op_flags |=
|
||||
CAM_IFE_CTX_FRAME_HEADER_EN;
|
||||
|
||||
ife_ctx->ctx_in_use = 1;
|
||||
ife_ctx->num_reg_dump_buf = 0;
|
||||
memset(&ife_ctx->scratch_config, 0,
|
||||
@@ -5374,7 +5387,7 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
|
||||
}
|
||||
|
||||
if (cfg->init_packet || hw_update_data->mup_en ||
|
||||
(ctx->custom_config & CAM_IFE_CUSTOM_CFG_SW_SYNC_ON)) {
|
||||
(ctx->ctx_config & CAM_IFE_CTX_CFG_SW_SYNC_ON)) {
|
||||
rem_jiffies = wait_for_completion_timeout(
|
||||
&ctx->config_done_complete,
|
||||
msecs_to_jiffies(60));
|
||||
@@ -6272,7 +6285,7 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
|
||||
ctx->cdm_ops = NULL;
|
||||
ctx->num_reg_dump_buf = 0;
|
||||
ctx->ctx_type = CAM_IFE_CTX_TYPE_NONE;
|
||||
ctx->custom_config = 0;
|
||||
ctx->ctx_config = 0;
|
||||
ctx->num_reg_dump_buf = 0;
|
||||
ctx->is_dual = false;
|
||||
ctx->dsp_enabled = false;
|
||||
@@ -8313,6 +8326,21 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
|
||||
CAM_ERR(CAM_ISP, "FS Update Failed rc: %d", rc);
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_DYNAMIC_MODE_SWITCH: {
|
||||
struct cam_isp_mode_switch_info *mup_config;
|
||||
|
||||
if (blob_size < sizeof(struct cam_isp_mode_switch_info)) {
|
||||
CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
|
||||
blob_size,
|
||||
sizeof(struct cam_isp_mode_switch_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mup_config = (struct cam_isp_mode_switch_info *)blob_data;
|
||||
ife_mgr_ctx->scratch_config.curr_num_exp =
|
||||
mup_config->num_expoures;
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_HFR_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_CLOCK_CONFIG:
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG:
|
||||
@@ -8350,7 +8378,7 @@ static int cam_isp_sfe_send_scratch_buf_upd(
|
||||
|
||||
memset(io_addr, 0, sizeof(io_addr));
|
||||
update_buf.res = hw_res;
|
||||
update_buf.cmd_type = CAM_ISP_HW_CMD_GET_BUF_UPDATE;
|
||||
update_buf.cmd_type = cmd_type;
|
||||
update_buf.cmd.cmd_buf_addr = cpu_addr;
|
||||
update_buf.use_scratch_cfg = true;
|
||||
|
||||
@@ -8380,7 +8408,11 @@ static int cam_isp_sfe_send_scratch_buf_upd(
|
||||
CAM_DBG(CAM_ISP, "Scratch buf configured for: 0x%x",
|
||||
hw_res->res_id);
|
||||
|
||||
/* Update used bytes if update is via CDM */
|
||||
if ((cmd_type == CAM_ISP_HW_CMD_GET_BUF_UPDATE) ||
|
||||
(cmd_type == CAM_ISP_HW_CMD_GET_BUF_UPDATE_RM))
|
||||
*used_bytes = update_buf.cmd.used_bytes;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -8441,6 +8473,14 @@ static int cam_isp_sfe_add_scratch_buffer_cfg(
|
||||
}
|
||||
|
||||
res_id = hw_mgr_res->hw_res[j]->res_id;
|
||||
|
||||
/* check for num exposures */
|
||||
if ((ctx->ctx_config &
|
||||
CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) &&
|
||||
((res_id - CAM_ISP_SFE_OUT_RES_RDI_0) >=
|
||||
ctx->scratch_config.curr_num_exp))
|
||||
continue;
|
||||
|
||||
cpu_addr = kmd_buf_info->cpu_addr +
|
||||
kmd_buf_info->used_bytes / 4 +
|
||||
io_cfg_used_bytes / 4;
|
||||
@@ -8487,6 +8527,14 @@ static int cam_isp_sfe_add_scratch_buffer_cfg(
|
||||
}
|
||||
|
||||
res_id = hw_mgr_res->hw_res[j]->res_id;
|
||||
|
||||
/* check for num exposures */
|
||||
if ((ctx->ctx_config &
|
||||
CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) &&
|
||||
((res_id - CAM_ISP_HW_SFE_IN_RD0) >=
|
||||
ctx->scratch_config.curr_num_exp))
|
||||
continue;
|
||||
|
||||
cpu_addr = kmd_buf_info->cpu_addr +
|
||||
kmd_buf_info->used_bytes / 4 +
|
||||
io_cfg_used_bytes / 4;
|
||||
@@ -8707,7 +8755,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (ctx->custom_config & CAM_IFE_CUSTOM_CFG_FRAME_HEADER_TS) {
|
||||
if (ctx->ctx_config & CAM_IFE_CTX_CFG_FRAME_HEADER_TS) {
|
||||
rc = cam_ife_mgr_util_insert_frame_header(&kmd_buf,
|
||||
prepare_hw_data);
|
||||
if (rc)
|
||||
@@ -8825,7 +8873,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
}
|
||||
|
||||
sfe_fe_chk_cfg.sfe_fe_enabled = false;
|
||||
if ((ctx->is_fe_enabled) &&
|
||||
if ((!ctx->is_offline) && (ctx->is_fe_enabled) &&
|
||||
(ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE)) {
|
||||
sfe_fe_chk_cfg.sfe_fe_enabled = true;
|
||||
sfe_fe_chk_cfg.sfe_rdi_cfg_mask = 0;
|
||||
@@ -8899,7 +8947,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
}
|
||||
|
||||
/* Check if frame header was enabled for any WM */
|
||||
if ((ctx->custom_config & CAM_IFE_CUSTOM_CFG_FRAME_HEADER_TS) &&
|
||||
if ((ctx->ctx_config & CAM_IFE_CTX_CFG_FRAME_HEADER_TS) &&
|
||||
(prepare->num_out_map_entries) &&
|
||||
(!prepare_hw_data->frame_header_res_id)) {
|
||||
CAM_ERR(CAM_ISP, "Failed to configure frame header");
|
||||
@@ -9290,6 +9338,159 @@ outportlog:
|
||||
|
||||
}
|
||||
|
||||
int cam_isp_config_csid_rup_aup(
|
||||
struct cam_ife_hw_mgr_ctx *ctx)
|
||||
{
|
||||
int rc = 0, i, j, hw_idx;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct list_head *res_list;
|
||||
struct cam_isp_resource_node *res;
|
||||
struct cam_isp_csid_reg_update_args
|
||||
rup_args[CAM_IFE_CSID_HW_NUM_MAX] = {0};
|
||||
|
||||
res_list = &ctx->res_list_ife_csid;
|
||||
for (j = 0; j < ctx->num_base; j++) {
|
||||
if (ctx->base[j].hw_type != CAM_ISP_HW_TYPE_CSID)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(hw_mgr_res, res_list, list) {
|
||||
if (hw_mgr_res->res_type == CAM_ISP_RESOURCE_UNINT)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (!hw_mgr_res->hw_res[i])
|
||||
continue;
|
||||
|
||||
res = hw_mgr_res->hw_res[i];
|
||||
if (res->hw_intf->hw_idx != ctx->base[j].idx)
|
||||
continue;
|
||||
|
||||
hw_idx = res->hw_intf->hw_idx;
|
||||
rup_args[hw_idx].res[rup_args[hw_idx].num_res] = res;
|
||||
rup_args[hw_idx].num_res++;
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Reg update for res %d hw_id %d cdm_idx %d",
|
||||
res->res_id, res->hw_intf->hw_idx, ctx->base[j].idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
|
||||
if (!rup_args[i].num_res)
|
||||
continue;
|
||||
|
||||
rup_args[i].cmd.cmd_buf_addr = NULL;
|
||||
rup_args[i].cmd.size = 0;
|
||||
rup_args[i].reg_write = true;
|
||||
res = rup_args[i].res[0];
|
||||
|
||||
rc = res->hw_intf->hw_ops.process_cmd(
|
||||
res->hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_GET_REG_UPDATE, &rup_args[i],
|
||||
sizeof(struct cam_isp_csid_reg_update_args));
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Reg update for res %d hw_id %d ",
|
||||
res->res_id, res->hw_intf->hw_idx);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scratch buffer is for sHDR usescases involing SFE RDI0-2
|
||||
* There is no possibility of dual in this case, hence
|
||||
* using the scratch buffer provided during INIT corresponding
|
||||
* to each left RDIs
|
||||
*/
|
||||
static int cam_ife_mgr_prog_default_settings(
|
||||
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;
|
||||
|
||||
res_list_in_rd = &ctx->res_list_ife_in_rd;
|
||||
res_list_sfe_out = ctx->res_list_sfe_out;
|
||||
|
||||
for (i = 0; i < CAM_SFE_FE_RDI_NUM_MAX; i++) {
|
||||
hw_mgr_res = &res_list_sfe_out[i];
|
||||
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;
|
||||
|
||||
res_id = hw_mgr_res->hw_res[j]->res_id;
|
||||
/* check for num exposures */
|
||||
if ((ctx->ctx_config &
|
||||
CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) &&
|
||||
((res_id - CAM_ISP_SFE_OUT_RES_RDI_0) >=
|
||||
ctx->scratch_config.curr_num_exp))
|
||||
continue;
|
||||
|
||||
buf_info = &ctx->scratch_config.buf_info[
|
||||
res_id - CAM_ISP_SFE_OUT_RES_RDI_0];
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"RDI%d res_id 0x%x idx %u io_addr %pK",
|
||||
i,
|
||||
hw_mgr_res->hw_res[j]->res_id,
|
||||
(res_id - CAM_ISP_SFE_OUT_RES_RDI_0),
|
||||
buf_info->io_addr);
|
||||
|
||||
rc = cam_isp_sfe_send_scratch_buf_upd(0x0,
|
||||
CAM_ISP_HW_CMD_BUF_UPDATE,
|
||||
hw_mgr_res->hw_res[j], buf_info,
|
||||
NULL, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(hw_mgr_res, res_list_in_rd, list) {
|
||||
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
|
||||
if (!hw_mgr_res->hw_res[j])
|
||||
continue;
|
||||
|
||||
res_id = hw_mgr_res->hw_res[j]->res_id;
|
||||
|
||||
/* check for num exposures */
|
||||
if ((ctx->ctx_config &
|
||||
CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) &&
|
||||
((res_id - CAM_ISP_HW_SFE_IN_RD0) >=
|
||||
ctx->scratch_config.curr_num_exp))
|
||||
continue;
|
||||
|
||||
buf_info = &ctx->scratch_config.buf_info
|
||||
[res_id - CAM_ISP_HW_SFE_IN_RD0];
|
||||
CAM_DBG(CAM_ISP,
|
||||
"RD res_id 0x%x idx %u io_addr %pK",
|
||||
hw_mgr_res->hw_res[j]->res_id,
|
||||
(res_id - CAM_ISP_HW_SFE_IN_RD0),
|
||||
buf_info->io_addr);
|
||||
rc = cam_isp_sfe_send_scratch_buf_upd(0x0,
|
||||
CAM_ISP_HW_CMD_BUF_UPDATE_RM,
|
||||
hw_mgr_res->hw_res[j], buf_info,
|
||||
NULL, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Program rup & aup */
|
||||
rc = cam_isp_config_csid_rup_aup(ctx);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP,
|
||||
"RUP/AUP update failed for scratch buffers");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -9359,6 +9560,9 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
||||
isp_hw_cmd_args->u.last_cdm_done =
|
||||
ctx->last_cdm_done_req;
|
||||
break;
|
||||
case CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG:
|
||||
rc = cam_ife_mgr_prog_default_settings(ctx);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
|
||||
hw_cmd_args->cmd_type);
|
||||
@@ -10248,8 +10452,8 @@ static int cam_ife_hw_mgr_handle_hw_sof(
|
||||
case CAM_ISP_HW_VFE_IN_CAMIF:
|
||||
case CAM_ISP_HW_VFE_IN_RD:
|
||||
/* if frame header is enabled reset qtimer ts */
|
||||
if (ife_hw_mgr_ctx->custom_config &
|
||||
CAM_IFE_CUSTOM_CFG_FRAME_HEADER_TS) {
|
||||
if (ife_hw_mgr_ctx->ctx_config &
|
||||
CAM_IFE_CTX_CFG_FRAME_HEADER_TS) {
|
||||
sof_done_event_data.timestamp = 0x0;
|
||||
ktime_get_boottime_ts64(&ts);
|
||||
sof_done_event_data.boot_time =
|
||||
@@ -10417,7 +10621,8 @@ static int cam_ife_hw_mgr_handle_hw_buf_done(
|
||||
buf_done_event_data.last_consumed_addr[0] =
|
||||
event_info->reg_val;
|
||||
|
||||
if ((ife_hw_mgr_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) &&
|
||||
if ((!ife_hw_mgr_ctx->is_offline) &&
|
||||
(ife_hw_mgr_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) &&
|
||||
(ife_hw_mgr_ctx->is_fe_enabled)) {
|
||||
rc = cam_ife_hw_mgr_check_rdi_scratch_buf_done(
|
||||
ife_hw_mgr_ctx, event_info->res_id,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_IFE_HW_MGR_H_
|
||||
@@ -33,9 +33,11 @@ enum cam_ife_ctx_master_type {
|
||||
#define CAM_SFE_HW_OUT_RES_MAX (CAM_ISP_SFE_OUT_RES_MAX & 0xFF)
|
||||
#define CAM_IFE_HW_RES_POOL_MAX 64
|
||||
|
||||
/* IFE_HW_MGR custom config */
|
||||
#define CAM_IFE_CUSTOM_CFG_FRAME_HEADER_TS BIT(0)
|
||||
#define CAM_IFE_CUSTOM_CFG_SW_SYNC_ON BIT(1)
|
||||
/* IFE_HW_MGR ctx config */
|
||||
#define CAM_IFE_CTX_CFG_FRAME_HEADER_TS BIT(0)
|
||||
#define CAM_IFE_CTX_CFG_SW_SYNC_ON BIT(1)
|
||||
#define CAM_IFE_CTX_CFG_SFE_FE_MODE BIT(2)
|
||||
#define CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON BIT(3)
|
||||
|
||||
#define CAM_IFE_UBWC_COMP_EN BIT(1)
|
||||
|
||||
@@ -89,12 +91,14 @@ struct cam_sfe_scratch_buf_info {
|
||||
*
|
||||
* @config_done: To indicate if stream received it's scratch cfg
|
||||
* @num_configs: Number of buffer configs [max of 3 currently]
|
||||
* @curr_num_exp: Current num of exposures
|
||||
* @buf_info: Info on each of the buffers
|
||||
*
|
||||
*/
|
||||
struct cam_sfe_scratch_buf_cfg {
|
||||
bool config_done;
|
||||
uint32_t num_config;
|
||||
uint32_t curr_num_exp;
|
||||
struct cam_sfe_scratch_buf_info buf_info[
|
||||
CAM_SFE_FE_RDI_NUM_MAX];
|
||||
};
|
||||
@@ -212,7 +216,7 @@ struct cam_ife_hw_mgr_ctx {
|
||||
bool is_fe_enabled;
|
||||
bool is_dual;
|
||||
enum cam_ife_ctx_master_type ctx_type;
|
||||
uint32_t custom_config;
|
||||
uint32_t ctx_config;
|
||||
struct timespec64 ts;
|
||||
bool is_tpg;
|
||||
bool is_offline;
|
||||
|
@@ -2037,8 +2037,9 @@ static int cam_tfe_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
||||
tfe_ctx->ctx_in_use = 1;
|
||||
tfe_ctx->num_reg_dump_buf = 0;
|
||||
|
||||
acquire_args->support_consumed_addr =
|
||||
g_tfe_hw_mgr.support_consumed_addr;
|
||||
if (g_tfe_hw_mgr.support_consumed_addr)
|
||||
acquire_args->op_flags |=
|
||||
CAM_IFE_CTX_CONSUME_ADDR_EN;
|
||||
|
||||
cam_tfe_hw_mgr_put_ctx(&tfe_hw_mgr->used_ctx_list, &tfe_ctx);
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <media/cam_defs.h>
|
||||
@@ -1723,6 +1723,7 @@ int cam_isp_add_csid_reg_update(
|
||||
kmd_buf_info->used_bytes/4 +
|
||||
reg_update_size/4;
|
||||
rup_args->cmd.size = kmd_buf_remain_size;
|
||||
rup_args->reg_write = false;
|
||||
res = rup_args->res[0];
|
||||
|
||||
rc = res->hw_intf->hw_ops.process_cmd(
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_ISP_HW_MGR_INTF_H_
|
||||
@@ -32,6 +32,12 @@
|
||||
/* Appliacble vote paths for dual ife, based on no. of UAPI definitions */
|
||||
#define CAM_ISP_MAX_PER_PATH_VOTES 40
|
||||
|
||||
/* Output params for acquire from hw_mgr to ctx */
|
||||
#define CAM_IFE_CTX_CUSTOM_EN BIT(0)
|
||||
#define CAM_IFE_CTX_FRAME_HEADER_EN BIT(1)
|
||||
#define CAM_IFE_CTX_CONSUME_ADDR_EN BIT(2)
|
||||
#define CAM_IFE_CTX_APPLY_DEFAULT_CFG BIT(3)
|
||||
|
||||
/**
|
||||
* enum cam_isp_hw_event_type - Collection of the ISP hardware events
|
||||
*/
|
||||
@@ -240,6 +246,7 @@ enum cam_isp_hw_mgr_command {
|
||||
CAM_ISP_HW_MGR_CMD_CTX_TYPE,
|
||||
CAM_ISP_HW_MGR_GET_PACKET_OPCODE,
|
||||
CAM_ISP_HW_MGR_GET_LAST_CDM_DONE,
|
||||
CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG,
|
||||
CAM_ISP_HW_MGR_CMD_MAX,
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
@@ -3334,6 +3334,7 @@ static int cam_ife_csid_ver2_reg_update(
|
||||
struct cam_isp_csid_reg_update_args *rup_args = cmd_args;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops;
|
||||
struct cam_ife_csid_ver2_reg_info *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t size, i;
|
||||
uint32_t reg_val_pair[2];
|
||||
uint32_t rup_aup_mask = 0;
|
||||
@@ -3366,7 +3367,7 @@ static int cam_ife_csid_ver2_reg_update(
|
||||
|
||||
size = cdm_util_ops->cdm_required_size_reg_random(1);
|
||||
/* since cdm returns dwords, we need to convert it into bytes */
|
||||
if ((size * 4) > rup_args->cmd.size) {
|
||||
if ((!rup_args->reg_write) && ((size * 4) > rup_args->cmd.size)) {
|
||||
CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d",
|
||||
rup_args->cmd.size, (size*4));
|
||||
return -EINVAL;
|
||||
@@ -3420,10 +3421,16 @@ static int cam_ife_csid_ver2_reg_update(
|
||||
csid_hw->hw_intf->hw_idx,
|
||||
reg_val_pair[1], reg_val_pair[0]);
|
||||
|
||||
if (rup_args->reg_write) {
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
cam_io_w_mb(reg_val_pair[1],
|
||||
soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base +
|
||||
reg_val_pair[0]);
|
||||
} else {
|
||||
cdm_util_ops->cdm_write_regrandom(rup_args->cmd.cmd_buf_addr,
|
||||
1, reg_val_pair);
|
||||
|
||||
rup_args->cmd.used_bytes = size * 4;
|
||||
}
|
||||
|
||||
return rc;
|
||||
err:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CSID_HW_INTF_H_
|
||||
@@ -353,11 +353,13 @@ struct cam_ife_csid_dual_sync_args {
|
||||
* @cmd: cmd buf update args
|
||||
* @node_res: Node res pointer
|
||||
* @num_res: Num of resources
|
||||
* @reg_write: if set use AHB to config rup/aup
|
||||
*/
|
||||
struct cam_isp_csid_reg_update_args {
|
||||
struct cam_isp_hw_cmd_buf_update cmd;
|
||||
struct cam_isp_resource_node *res[CAM_IFE_PIX_PATH_RES_MAX];
|
||||
uint32_t num_res;
|
||||
bool reg_write;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_ISP_HW_H_
|
||||
@@ -145,6 +145,8 @@ enum cam_isp_hw_cmd_type {
|
||||
CAM_IFE_CSID_PROGRAM_OFFLINE_CMD,
|
||||
CAM_IFE_CSID_SET_DUAL_SYNC_CONFIG,
|
||||
CAM_ISP_HW_CMD_CSID_MUP_UPDATE,
|
||||
CAM_ISP_HW_CMD_BUF_UPDATE,
|
||||
CAM_ISP_HW_CMD_BUF_UPDATE_RM,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
@@ -327,6 +327,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE:
|
||||
case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
|
||||
case CAM_ISP_HW_CMD_STRIPE_UPDATE:
|
||||
case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE:
|
||||
@@ -337,6 +338,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_HFR_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD:
|
||||
rc = core_info->sfe_bus_rd->hw_ops.process_cmd(
|
||||
core_info->sfe_bus_rd->bus_priv, cmd_type,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/ratelimit.h>
|
||||
@@ -1118,6 +1118,88 @@ static int cam_sfe_bus_deinit_sfe_bus_rd_resource(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* API similar to cam_sfe_bus_rd_update_rm() with the
|
||||
* only change being config is done via AHB instead of CDM
|
||||
*/
|
||||
static int cam_sfe_bus_rd_config_rm(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_sfe_bus_rd_priv *bus_priv;
|
||||
struct cam_isp_hw_get_cmd_update *update_buf;
|
||||
struct cam_sfe_bus_rd_data *sfe_bus_rd_data = NULL;
|
||||
struct cam_sfe_bus_rd_rm_resource_data *rm_data = NULL;
|
||||
uint32_t width = 0, height = 0, stride = 0;
|
||||
uint32_t i;
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_rd_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
|
||||
sfe_bus_rd_data = (struct cam_sfe_bus_rd_data *)
|
||||
update_buf->res->res_priv;
|
||||
|
||||
if (!sfe_bus_rd_data || !sfe_bus_rd_data->cdm_util_ops) {
|
||||
CAM_ERR(CAM_SFE, "Failed! Invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_SFE, "num of RM: %d scratch_buf_cfg: %s",
|
||||
sfe_bus_rd_data->num_rm,
|
||||
update_buf->use_scratch_cfg ? "true" : "false");
|
||||
if (update_buf->rm_update->num_buf != sfe_bus_rd_data->num_rm) {
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Failed! Invalid number buffers:%d required:%d",
|
||||
update_buf->rm_update->num_buf,
|
||||
sfe_bus_rd_data->num_rm);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sfe_bus_rd_data->num_rm; i++) {
|
||||
rm_data = sfe_bus_rd_data->rm_res[i]->res_priv;
|
||||
|
||||
stride = update_buf->rm_update->stride;
|
||||
width = update_buf->rm_update->width;
|
||||
height = update_buf->rm_update->height;
|
||||
|
||||
/* update size register */
|
||||
cam_sfe_bus_rd_pxls_to_bytes(width,
|
||||
rm_data->unpacker_cfg, &rm_data->width);
|
||||
rm_data->height = height;
|
||||
|
||||
cam_io_w_mb(rm_data->width,
|
||||
rm_data->common_data->mem_base +
|
||||
rm_data->hw_regs->buf_width);
|
||||
cam_io_w_mb(rm_data->height,
|
||||
rm_data->common_data->mem_base +
|
||||
rm_data->hw_regs->buf_height);
|
||||
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d width:0x%X height:0x%X",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, rm_data->width,
|
||||
rm_data->height);
|
||||
|
||||
rm_data->stride = stride;
|
||||
cam_io_w_mb(stride,
|
||||
rm_data->common_data->mem_base +
|
||||
rm_data->hw_regs->stride);
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d image_stride:0x%X",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, stride);
|
||||
|
||||
cam_io_w_mb(update_buf->rm_update->image_buf[i],
|
||||
rm_data->common_data->mem_base +
|
||||
rm_data->hw_regs->image_addr);
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d image_address:0x%X",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index,
|
||||
update_buf->rm_update->image_buf[i]);
|
||||
rm_data->img_addr =
|
||||
update_buf->rm_update->image_buf[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_rd_update_rm(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
@@ -1320,6 +1402,9 @@ static int cam_sfe_bus_rd_process_cmd(
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE_RM:
|
||||
rc = cam_sfe_bus_rd_update_rm(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE_RM:
|
||||
rc = cam_sfe_bus_rd_config_rm(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_SECURE_MODE:
|
||||
rc = cam_sfe_bus_rd_get_secure_mode(priv, cmd_args, arg_size);
|
||||
break;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
@@ -2074,6 +2074,121 @@ static int cam_sfe_bus_wr_update_wm(void *priv, void *cmd_args,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* API similar to cam_sfe_bus_wr_update_wm() with the
|
||||
* only change being config is done via AHB instead of CDM
|
||||
*/
|
||||
static int cam_sfe_bus_wr_config_wm(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_sfe_bus_wr_priv *bus_priv;
|
||||
struct cam_isp_hw_get_cmd_update *update_buf;
|
||||
struct cam_sfe_bus_wr_out_data *sfe_out_data = NULL;
|
||||
struct cam_sfe_bus_wr_wm_resource_data *wm_data = NULL;
|
||||
uint32_t i, k;
|
||||
uint32_t frame_inc = 0, val;
|
||||
uint32_t loop_size = 0, stride = 0, slice_h = 0;
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_wr_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
|
||||
sfe_out_data = (struct cam_sfe_bus_wr_out_data *)
|
||||
update_buf->res->res_priv;
|
||||
|
||||
if (!sfe_out_data || !sfe_out_data->cdm_util_ops) {
|
||||
CAM_ERR(CAM_SFE, "Failed! Invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (update_buf->wm_update->num_buf != sfe_out_data->num_wm) {
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Failed! Invalid number buffers:%d required:%d",
|
||||
update_buf->wm_update->num_buf, sfe_out_data->num_wm);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sfe_out_data->num_wm; i++) {
|
||||
wm_data = (struct cam_sfe_bus_wr_wm_resource_data *)
|
||||
sfe_out_data->wm_res[i].res_priv;
|
||||
|
||||
val = (wm_data->height << 16) | wm_data->width;
|
||||
cam_io_w_mb(val,
|
||||
wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->image_cfg_0);
|
||||
CAM_DBG(CAM_SFE, "WM:%d image height and width 0x%X",
|
||||
wm_data->index, val);
|
||||
|
||||
/* For initial configuration program all bus registers */
|
||||
stride = update_buf->wm_update->stride;
|
||||
slice_h = update_buf->wm_update->slice_height;
|
||||
|
||||
val = stride;
|
||||
CAM_DBG(CAM_SFE, "before stride %d", val);
|
||||
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_SFE, "WM:%d image stride 0x%X",
|
||||
wm_data->index, val);
|
||||
}
|
||||
|
||||
frame_inc = stride * slice_h;
|
||||
|
||||
if (!(wm_data->en_cfg & (0x3 << 16))) {
|
||||
cam_io_w_mb(wm_data->h_init,
|
||||
wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->image_cfg_1);
|
||||
CAM_DBG(CAM_SFE, "WM:%d h_init 0x%X",
|
||||
wm_data->index, wm_data->h_init);
|
||||
}
|
||||
|
||||
if (wm_data->index > 7)
|
||||
loop_size = wm_data->irq_subsample_period + 1;
|
||||
else
|
||||
loop_size = 1;
|
||||
|
||||
/* WM Image address */
|
||||
for (k = 0; k < loop_size; k++) {
|
||||
if (wm_data->en_cfg & (0x3 << 16))
|
||||
cam_io_w_mb((update_buf->wm_update->image_buf[i] +
|
||||
wm_data->offset + k * frame_inc),
|
||||
wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->image_addr);
|
||||
else
|
||||
cam_io_w_mb((update_buf->wm_update->image_buf[i] +
|
||||
k * frame_inc),
|
||||
wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->image_addr);
|
||||
}
|
||||
|
||||
cam_io_w_mb(frame_inc,
|
||||
wm_data->common_data->mem_base +
|
||||
wm_data->hw_regs->frame_incr);
|
||||
CAM_DBG(CAM_SFE, "WM:%d frame_inc %d",
|
||||
wm_data->index, frame_inc);
|
||||
|
||||
/* 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_SFE, "WM:%d en_cfg 0x%X",
|
||||
wm_data->index, wm_data->en_cfg);
|
||||
|
||||
/* set initial configuration done */
|
||||
if (!wm_data->init_cfg_done)
|
||||
wm_data->init_cfg_done = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_wr_update_hfr(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
@@ -2330,6 +2445,9 @@ static int cam_sfe_bus_wr_process_cmd(
|
||||
case CAM_ISP_HW_CMD_GET_BUF_UPDATE:
|
||||
rc = cam_sfe_bus_wr_update_wm(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE:
|
||||
rc = cam_sfe_bus_wr_config_wm(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_GET_HFR_UPDATE:
|
||||
rc = cam_sfe_bus_wr_update_hfr(priv, cmd_args, arg_size);
|
||||
break;
|
||||
|
Reference in New Issue
Block a user