mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 15:11:48 -04:00
msm: camera: isp: Add per request reg dump to command buffer
For debugging, user space may request a specified register range values to be dumped to a command buffer every request. Add support for reg dump every request during cdm callback. Add debugfs flag for making sure per request dump is not enabled by mistake. CRs-Fixed: 2501003 Change-Id: I01a0f3bb00dd122b8037d513ec331c5c08fdf372 Signed-off-by: Mukund Madhusudan Atre <matre@codeaurora.org>
This commit is contained in:
parent
e4be9ecbfe
commit
4329af66bd
4 changed files with 157 additions and 111 deletions
|
|
@ -58,6 +58,117 @@ static int cam_ife_hw_mgr_event_handler(
|
|||
uint32_t evt_id,
|
||||
void *evt_info);
|
||||
|
||||
static int cam_ife_mgr_regspace_data_cb(uint32_t reg_base_type,
|
||||
void *hw_mgr_ctx, struct cam_hw_soc_info **soc_info_ptr,
|
||||
uint32_t *reg_base_idx)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_ife_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_ife_hw_mgr_res *hw_mgr_res_temp;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_ife_hw_mgr_ctx *ctx =
|
||||
(struct cam_ife_hw_mgr_ctx *) hw_mgr_ctx;
|
||||
|
||||
*soc_info_ptr = NULL;
|
||||
list_for_each_entry_safe(hw_mgr_res, hw_mgr_res_temp,
|
||||
&ctx->res_list_ife_src, list) {
|
||||
if (hw_mgr_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF)
|
||||
continue;
|
||||
|
||||
switch (reg_base_type) {
|
||||
case CAM_REG_DUMP_BASE_TYPE_CAMNOC:
|
||||
case CAM_REG_DUMP_BASE_TYPE_ISP_LEFT:
|
||||
if (!hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT])
|
||||
continue;
|
||||
|
||||
rc = hw_mgr_res->hw_res[
|
||||
CAM_ISP_HW_SPLIT_LEFT]->process_cmd(
|
||||
hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT],
|
||||
CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, &soc_info,
|
||||
sizeof(void *));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed in regspace data query split idx: %d rc : %d",
|
||||
CAM_ISP_HW_SPLIT_LEFT, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (reg_base_type == CAM_REG_DUMP_BASE_TYPE_ISP_LEFT)
|
||||
*reg_base_idx = 0;
|
||||
else
|
||||
*reg_base_idx = 1;
|
||||
|
||||
*soc_info_ptr = soc_info;
|
||||
break;
|
||||
case CAM_REG_DUMP_BASE_TYPE_ISP_RIGHT:
|
||||
if (!hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT])
|
||||
continue;
|
||||
|
||||
rc = hw_mgr_res->hw_res[
|
||||
CAM_ISP_HW_SPLIT_RIGHT]->process_cmd(
|
||||
hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT],
|
||||
CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, &soc_info,
|
||||
sizeof(void *));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed in regspace data query split idx: %d rc : %d",
|
||||
CAM_ISP_HW_SPLIT_RIGHT, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*reg_base_idx = 0;
|
||||
*soc_info_ptr = soc_info;
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Unrecognized reg base type: %u",
|
||||
reg_base_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_handle_reg_dump(struct cam_ife_hw_mgr_ctx *ctx,
|
||||
struct cam_cmd_buf_desc *reg_dump_buf_desc, uint32_t num_reg_dump_buf,
|
||||
uint32_t meta_type)
|
||||
{
|
||||
int rc = 0, i;
|
||||
|
||||
if (!num_reg_dump_buf || !reg_dump_buf_desc) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Invalid args for reg dump req_id: [%llu] ctx idx: [%u] meta_type: [%u]",
|
||||
ctx->applied_req_id, ctx->ctx_index, meta_type);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!atomic_read(&ctx->cdm_done))
|
||||
CAM_WARN_RATE_LIMIT(CAM_ISP,
|
||||
"Reg dump values might be from more than one request");
|
||||
|
||||
for (i = 0; i < num_reg_dump_buf; i++) {
|
||||
CAM_DBG(CAM_ISP, "Reg dump cmd meta data: %u req_type: %u",
|
||||
reg_dump_buf_desc[i].meta_data, meta_type);
|
||||
if (reg_dump_buf_desc[i].meta_data == meta_type) {
|
||||
rc = cam_soc_util_reg_dump_to_cmd_buf(ctx,
|
||||
®_dump_buf_desc[i],
|
||||
ctx->applied_req_id,
|
||||
cam_ife_mgr_regspace_data_cb);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Reg dump failed at idx: %d, rc: %d req_id: %llu meta type: %u",
|
||||
i, rc, ctx->applied_req_id, meta_type);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_notify_safe_lut_scm(bool safe_trigger)
|
||||
{
|
||||
uint32_t camera_hw_version, rc = 0;
|
||||
|
|
@ -2289,6 +2400,7 @@ err:
|
|||
void cam_ife_cam_cdm_callback(uint32_t handle, void *userdata,
|
||||
enum cam_cdm_cb_status status, uint64_t cookie)
|
||||
{
|
||||
struct cam_isp_prepare_hw_update_data *hw_update_data = NULL;
|
||||
struct cam_ife_hw_mgr_ctx *ctx = NULL;
|
||||
|
||||
if (!userdata) {
|
||||
|
|
@ -2296,11 +2408,18 @@ void cam_ife_cam_cdm_callback(uint32_t handle, void *userdata,
|
|||
return;
|
||||
}
|
||||
|
||||
ctx = userdata;
|
||||
hw_update_data = (struct cam_isp_prepare_hw_update_data *)userdata;
|
||||
ctx = (struct cam_ife_hw_mgr_ctx *)hw_update_data->ife_mgr_ctx;
|
||||
|
||||
if (status == CAM_CDM_CB_STATUS_BL_SUCCESS) {
|
||||
complete_all(&ctx->config_done_complete);
|
||||
atomic_set(&ctx->cdm_done, 1);
|
||||
if (g_ife_hw_mgr.debug_cfg.per_req_reg_dump)
|
||||
cam_ife_mgr_handle_reg_dump(ctx,
|
||||
hw_update_data->reg_dump_buf_desc,
|
||||
hw_update_data->num_reg_dump_buf,
|
||||
CAM_ISP_PACKET_META_REG_DUMP_PER_REQUEST);
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Called by CDM hdl=%x, udata=%pK, status=%d, cookie=%llu ctx_index=%d",
|
||||
handle, userdata, status, cookie, ctx->ctx_index);
|
||||
|
|
@ -3237,6 +3356,7 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
|
|||
return -EINVAL;
|
||||
|
||||
hw_update_data = (struct cam_isp_prepare_hw_update_data *) cfg->priv;
|
||||
hw_update_data->ife_mgr_ctx = ctx;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Ctx[%pK][%d] : Applying Req %lld",
|
||||
ctx, ctx->ctx_index, cfg->request_id);
|
||||
|
|
@ -3282,7 +3402,7 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
|
|||
cdm_cmd->cmd_arrary_count = cfg->num_hw_update_entries;
|
||||
cdm_cmd->type = CAM_CDM_BL_CMD_TYPE_MEM_HANDLE;
|
||||
cdm_cmd->flag = true;
|
||||
cdm_cmd->userdata = ctx;
|
||||
cdm_cmd->userdata = hw_update_data;
|
||||
cdm_cmd->cookie = cfg->request_id;
|
||||
|
||||
for (i = 0 ; i <= cfg->num_hw_update_entries; i++) {
|
||||
|
|
@ -5374,8 +5494,18 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
|
|||
}
|
||||
|
||||
goto end;
|
||||
} else
|
||||
} else {
|
||||
prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_UPDATE_DEV;
|
||||
prepare_hw_data->num_reg_dump_buf = prepare->num_reg_dump_buf;
|
||||
if ((prepare_hw_data->num_reg_dump_buf) &&
|
||||
(prepare_hw_data->num_reg_dump_buf <
|
||||
CAM_REG_DUMP_MAX_BUF_ENTRIES)) {
|
||||
memcpy(prepare_hw_data->reg_dump_buf_desc,
|
||||
prepare->reg_dump_buf_desc,
|
||||
sizeof(struct cam_cmd_buf_desc) *
|
||||
prepare_hw_data->num_reg_dump_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* add reg update commands */
|
||||
for (i = 0; i < ctx->num_base; i++) {
|
||||
|
|
@ -5529,112 +5659,6 @@ static void cam_ife_mgr_print_io_bufs(struct cam_packet *packet,
|
|||
}
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_regspace_data_cb(uint32_t reg_base_type,
|
||||
void *hw_mgr_ctx, struct cam_hw_soc_info **soc_info_ptr,
|
||||
uint32_t *reg_base_idx)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_ife_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
struct cam_ife_hw_mgr_ctx *ctx =
|
||||
(struct cam_ife_hw_mgr_ctx *) hw_mgr_ctx;
|
||||
|
||||
*soc_info_ptr = NULL;
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_src, list) {
|
||||
if (hw_mgr_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF)
|
||||
continue;
|
||||
|
||||
switch (reg_base_type) {
|
||||
case CAM_REG_DUMP_BASE_TYPE_CAMNOC:
|
||||
case CAM_REG_DUMP_BASE_TYPE_ISP_LEFT:
|
||||
if (!hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT])
|
||||
continue;
|
||||
|
||||
rc = hw_mgr_res->hw_res[
|
||||
CAM_ISP_HW_SPLIT_LEFT]->process_cmd(
|
||||
hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_LEFT],
|
||||
CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, &soc_info,
|
||||
sizeof(void *));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed in regspace data query split idx: %d rc : %d",
|
||||
CAM_ISP_HW_SPLIT_LEFT, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (reg_base_type == CAM_REG_DUMP_BASE_TYPE_ISP_LEFT)
|
||||
*reg_base_idx = 0;
|
||||
else
|
||||
*reg_base_idx = 1;
|
||||
|
||||
*soc_info_ptr = soc_info;
|
||||
break;
|
||||
case CAM_REG_DUMP_BASE_TYPE_ISP_RIGHT:
|
||||
if (!hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT])
|
||||
continue;
|
||||
|
||||
rc = hw_mgr_res->hw_res[
|
||||
CAM_ISP_HW_SPLIT_RIGHT]->process_cmd(
|
||||
hw_mgr_res->hw_res[CAM_ISP_HW_SPLIT_RIGHT],
|
||||
CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA, &soc_info,
|
||||
sizeof(void *));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed in regspace data query split idx: %d rc : %d",
|
||||
CAM_ISP_HW_SPLIT_RIGHT, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*reg_base_idx = 0;
|
||||
*soc_info_ptr = soc_info;
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Unrecognized reg base type: %d",
|
||||
reg_base_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_handle_reg_dump(struct cam_ife_hw_mgr_ctx *ctx,
|
||||
uint32_t meta_type)
|
||||
{
|
||||
int rc, i;
|
||||
|
||||
if (!ctx->num_reg_dump_buf) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Zero command buffers for reg dump req_id: [%llu] ctx idx: [%llu] meta_type: %d",
|
||||
ctx->applied_req_id, ctx->ctx_index, meta_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!atomic_read(&ctx->cdm_done))
|
||||
CAM_WARN_RATE_LIMIT(CAM_ISP,
|
||||
"Reg dump values might be from more than one request");
|
||||
|
||||
for (i = 0; i < ctx->num_reg_dump_buf; i++) {
|
||||
CAM_DBG(CAM_ISP, "Reg dump cmd meta data: %d req_type: %d",
|
||||
ctx->reg_dump_buf_desc[i].meta_data, meta_type);
|
||||
if (ctx->reg_dump_buf_desc[i].meta_data == meta_type) {
|
||||
rc = cam_soc_util_reg_dump_to_cmd_buf(ctx,
|
||||
&ctx->reg_dump_buf_desc[i],
|
||||
ctx->applied_req_id,
|
||||
cam_ife_mgr_regspace_data_cb);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Reg dump failed at idx: %d, rc: %d req_id: %llu meta type: %d",
|
||||
i, rc, ctx->applied_req_id, meta_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -5713,7 +5737,8 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
|||
}
|
||||
|
||||
ctx->last_dump_flush_req_id = ctx->applied_req_id;
|
||||
rc = cam_ife_mgr_handle_reg_dump(ctx,
|
||||
rc = cam_ife_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc,
|
||||
ctx->num_reg_dump_buf,
|
||||
CAM_ISP_PACKET_META_REG_DUMP_ON_FLUSH);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
|
|
@ -5728,7 +5753,8 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
|
|||
return 0;
|
||||
|
||||
ctx->last_dump_err_req_id = ctx->applied_req_id;
|
||||
rc = cam_ife_mgr_handle_reg_dump(ctx,
|
||||
rc = cam_ife_mgr_handle_reg_dump(ctx, ctx->reg_dump_buf_desc,
|
||||
ctx->num_reg_dump_buf,
|
||||
CAM_ISP_PACKET_META_REG_DUMP_ON_ERROR);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
|
|
@ -6544,6 +6570,15 @@ static int cam_ife_hw_mgr_debug_register(void)
|
|||
CAM_ERR(CAM_ISP, "failed to create cam_ife_camif_debug");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!debugfs_create_bool("per_req_reg_dump",
|
||||
0644,
|
||||
g_ife_hw_mgr.debug_cfg.dentry,
|
||||
&g_ife_hw_mgr.debug_cfg.per_req_reg_dump)) {
|
||||
CAM_ERR(CAM_ISP, "failed to create per_req_reg_dump entry");
|
||||
goto err;
|
||||
}
|
||||
|
||||
g_ife_hw_mgr.debug_cfg.enable_recovery = 0;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ struct ctx_base_info {
|
|||
* @enable_recovery: enable recovery
|
||||
* @enable_diag_sensor_status: enable sensor diagnosis status
|
||||
* @enable_req_dump: Enable request dump on HW errors
|
||||
* @per_req_reg_dump: Enable per request reg dump
|
||||
*
|
||||
*/
|
||||
struct cam_ife_hw_mgr_debug {
|
||||
|
|
@ -91,6 +92,7 @@ struct cam_ife_hw_mgr_debug {
|
|||
uint32_t enable_recovery;
|
||||
uint32_t camif_debug;
|
||||
bool enable_req_dump;
|
||||
bool per_req_reg_dump;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -422,6 +422,7 @@ int cam_isp_add_command_buffers(
|
|||
break;
|
||||
case CAM_ISP_PACKET_META_REG_DUMP_ON_FLUSH:
|
||||
case CAM_ISP_PACKET_META_REG_DUMP_ON_ERROR:
|
||||
case CAM_ISP_PACKET_META_REG_DUMP_PER_REQUEST:
|
||||
if (split_id == CAM_ISP_HW_SPLIT_LEFT) {
|
||||
if (prepare->num_reg_dump_buf >=
|
||||
CAM_REG_DUMP_MAX_BUF_ENTRIES) {
|
||||
|
|
@ -430,6 +431,7 @@ int cam_isp_add_command_buffers(
|
|||
prepare->num_reg_dump_buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
prepare->reg_dump_buf_desc[
|
||||
prepare->num_reg_dump_buf] =
|
||||
cmd_desc[i];
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ struct cam_isp_bw_config_internal {
|
|||
/**
|
||||
* struct cam_isp_prepare_hw_update_data - hw prepare data
|
||||
*
|
||||
* @ife_mgr_ctx: IFE HW manager Context for current request
|
||||
* @packet_opcode_type: Packet header opcode in the packet header
|
||||
* this opcode defines, packet is init packet or
|
||||
* update packet
|
||||
|
|
@ -123,14 +124,20 @@ struct cam_isp_bw_config_internal {
|
|||
* @bw_config_v2: BW config info for AXI bw voting v2
|
||||
* @bw_config_valid: Flag indicating whether the bw_config at the index
|
||||
* is valid or not
|
||||
* @reg_dump_buf_desc: cmd buffer descriptors for reg dump
|
||||
* @num_reg_dump_buf: Count of descriptors in reg_dump_buf_desc
|
||||
*
|
||||
*/
|
||||
struct cam_isp_prepare_hw_update_data {
|
||||
struct cam_ife_hw_mgr_ctx *ife_mgr_ctx;
|
||||
uint32_t packet_opcode_type;
|
||||
uint32_t bw_config_version;
|
||||
struct cam_isp_bw_config_internal bw_config[CAM_IFE_HW_NUM_MAX];
|
||||
struct cam_isp_bw_config_internal_v2 bw_config_v2[CAM_IFE_HW_NUM_MAX];
|
||||
bool bw_config_valid[CAM_IFE_HW_NUM_MAX];
|
||||
struct cam_cmd_buf_desc reg_dump_buf_desc[
|
||||
CAM_REG_DUMP_MAX_BUF_ENTRIES];
|
||||
uint32_t num_reg_dump_buf;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue