msm: camera: isp: Fix the logic to disable TFE WM clients dynamically
TFE disable WM client logic is broken due to ISP common framework changes and last consume address changes in ISP common framework. Fixed the logic to disable WM dynamically. This change add the fix for invalid pointer access in last consume address logic as well. CRs-Fixed: 3696470 Signed-off-by: Alok Chauhan <quic_alokc@quicinc.com> Change-Id: I31d06e0dfe17ef660e7ff023b41ada1d713ff92f
This commit is contained in:
@@ -901,17 +901,19 @@ static void cam_tfe_hw_mgr_dump_all_ctx(void)
|
|||||||
static void cam_tfe_mgr_add_base_info(
|
static void cam_tfe_mgr_add_base_info(
|
||||||
struct cam_tfe_hw_mgr_ctx *ctx,
|
struct cam_tfe_hw_mgr_ctx *ctx,
|
||||||
enum cam_isp_hw_split_id split_id,
|
enum cam_isp_hw_split_id split_id,
|
||||||
uint32_t base_idx)
|
uint32_t base_idx,
|
||||||
|
enum cam_isp_hw_type hw_type)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
if (!ctx->num_base) {
|
if (!ctx->num_base) {
|
||||||
ctx->base[0].split_id = split_id;
|
ctx->base[0].split_id = split_id;
|
||||||
ctx->base[0].idx = base_idx;
|
ctx->base[0].idx = base_idx;
|
||||||
|
ctx->base[0].hw_type = hw_type;
|
||||||
ctx->num_base++;
|
ctx->num_base++;
|
||||||
CAM_DBG(CAM_ISP,
|
CAM_DBG(CAM_ISP,
|
||||||
"Add split id = %d for base idx = %d num_base=%d",
|
"Add split id = %d for base idx = %d num_base=%d hw_type=%d",
|
||||||
split_id, base_idx, ctx->num_base);
|
split_id, base_idx, ctx->num_base, hw_type);
|
||||||
} else {
|
} else {
|
||||||
/*Check if base index already exists in the list */
|
/*Check if base index already exists in the list */
|
||||||
for (i = 0; i < ctx->num_base; i++) {
|
for (i = 0; i < ctx->num_base; i++) {
|
||||||
@@ -928,10 +930,11 @@ static void cam_tfe_mgr_add_base_info(
|
|||||||
if (i == ctx->num_base) {
|
if (i == ctx->num_base) {
|
||||||
ctx->base[ctx->num_base].split_id = split_id;
|
ctx->base[ctx->num_base].split_id = split_id;
|
||||||
ctx->base[ctx->num_base].idx = base_idx;
|
ctx->base[ctx->num_base].idx = base_idx;
|
||||||
|
ctx->base[ctx->num_base].hw_type = hw_type;
|
||||||
ctx->num_base++;
|
ctx->num_base++;
|
||||||
CAM_DBG(CAM_ISP,
|
CAM_DBG(CAM_ISP,
|
||||||
"Add split_id=%d for base idx=%d num_base=%d",
|
"Add split_id=%d for base idx=%d num_base=%d hw_type=%d",
|
||||||
split_id, base_idx, ctx->num_base);
|
split_id, base_idx, ctx->num_base, hw_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -959,12 +962,13 @@ static int cam_tfe_mgr_process_base_info(
|
|||||||
|
|
||||||
res = hw_mgr_res->hw_res[i];
|
res = hw_mgr_res->hw_res[i];
|
||||||
cam_tfe_mgr_add_base_info(ctx, i,
|
cam_tfe_mgr_add_base_info(ctx, i,
|
||||||
res->hw_intf->hw_idx);
|
res->hw_intf->hw_idx,
|
||||||
CAM_DBG(CAM_ISP, "add base info for hw %d",
|
CAM_ISP_HW_TYPE_TFE);
|
||||||
res->hw_intf->hw_idx);
|
CAM_DBG(CAM_ISP, "add base info for hw %d ctx_idx: %u",
|
||||||
|
res->hw_intf->hw_idx, ctx->ctx_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CAM_DBG(CAM_ISP, "ctx base num = %d", ctx->num_base);
|
CAM_DBG(CAM_ISP, "ctx base num = %d, ctx_idx: %u", ctx->num_base, ctx->ctx_index);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -5682,7 +5686,7 @@ static int cam_tfe_mgr_cmd_get_last_consumed_addr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
hw_mgr_res =
|
hw_mgr_res =
|
||||||
&ctx->res_list_tfe_out[res_id_out];
|
&ctx->res_list_tfe_out[ctx->tfe_out_map[res_id_out]];
|
||||||
|
|
||||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||||
if (!hw_mgr_res->hw_res[i])
|
if (!hw_mgr_res->hw_res[i])
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <media/cam_defs.h>
|
#include <media/cam_defs.h>
|
||||||
@@ -767,8 +767,8 @@ static int cam_isp_io_buf_get_entries_util(
|
|||||||
&buf_info->scratch_check_cfg->ife_scratch_res_info,
|
&buf_info->scratch_check_cfg->ife_scratch_res_info,
|
||||||
io_cfg->resource_type);
|
io_cfg->resource_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
*hw_mgr_res = &buf_info->res_list_isp_out[buf_info->out_map[res_id]];
|
*hw_mgr_res = &buf_info->res_list_isp_out[buf_info->out_map[res_id]];
|
||||||
|
|
||||||
if ((*hw_mgr_res)->res_type == CAM_ISP_RESOURCE_UNINT) {
|
if ((*hw_mgr_res)->res_type == CAM_ISP_RESOURCE_UNINT) {
|
||||||
CAM_ERR(CAM_ISP, "io res id:%d not valid",
|
CAM_ERR(CAM_ISP, "io res id:%d not valid",
|
||||||
io_cfg->resource_type);
|
io_cfg->resource_type);
|
||||||
@@ -1220,13 +1220,14 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
disabled_wm_mask = (prepare_hw_data->wm_bitmask ^ cfg_io_mask);
|
disabled_wm_mask = (prepare_hw_data->wm_bitmask ^ cfg_io_mask);
|
||||||
|
|
||||||
if ((io_info->base->hw_type == CAM_ISP_HW_TYPE_TFE) && disabled_wm_mask) {
|
if ((io_info->base->hw_type == CAM_ISP_HW_TYPE_TFE) && disabled_wm_mask) {
|
||||||
for (j = 0; j < io_info->out_max; j++) {
|
for (j = 0; j < io_info->out_max; j++) {
|
||||||
rc = cam_isp_add_disable_wm_update(io_info->prepare,
|
rc = cam_isp_add_disable_wm_update(io_info->prepare,
|
||||||
&io_info->res_list_isp_out[j],
|
&io_info->res_list_isp_out[io_info->out_map[j]],
|
||||||
io_info->base->idx, io_info->kmd_buf_info,
|
io_info->base->idx, io_info->kmd_buf_info,
|
||||||
disabled_wm_mask,
|
&disabled_wm_mask,
|
||||||
&io_info->kmd_buf_info->used_bytes);
|
io_info);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Disable out res %d failed",
|
CAM_ERR_RATE_LIMIT(CAM_ISP, "Disable out res %d failed",
|
||||||
j, rc);
|
j, rc);
|
||||||
@@ -1263,8 +1264,8 @@ int cam_isp_add_disable_wm_update(
|
|||||||
struct cam_isp_hw_mgr_res *isp_hw_res,
|
struct cam_isp_hw_mgr_res *isp_hw_res,
|
||||||
uint32_t base_idx,
|
uint32_t base_idx,
|
||||||
struct cam_kmd_buf_info *kmd_buf_info,
|
struct cam_kmd_buf_info *kmd_buf_info,
|
||||||
uint64_t wm_mask,
|
uint64_t *wm_mask,
|
||||||
uint32_t *io_cfg_used_bytes)
|
struct cam_isp_io_buf_info *io_info)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct cam_hw_intf *hw_intf;
|
struct cam_hw_intf *hw_intf;
|
||||||
@@ -1281,23 +1282,25 @@ int cam_isp_add_disable_wm_update(
|
|||||||
res = isp_hw_res->hw_res[i];
|
res = isp_hw_res->hw_res[i];
|
||||||
if (res->hw_intf->hw_idx != base_idx)
|
if (res->hw_intf->hw_idx != base_idx)
|
||||||
continue;
|
continue;
|
||||||
if (!(wm_mask & (1 << res->res_id))) {
|
if (!(*wm_mask & (1 << res->res_id))) {
|
||||||
CAM_DBG(CAM_ISP, "No need to disable out res %d", res->res_id);
|
CAM_DBG(CAM_ISP, "No need to disable out res %d", res->res_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (kmd_buf_info->size > (kmd_buf_info->used_bytes +
|
|
||||||
(*io_cfg_used_bytes))) {
|
*wm_mask &= ~BIT(res->res_id);
|
||||||
kmd_buf_remain_size = kmd_buf_info->size -
|
|
||||||
(kmd_buf_info->used_bytes +
|
if (kmd_buf_info->used_bytes < kmd_buf_info->size) {
|
||||||
(*io_cfg_used_bytes));
|
kmd_buf_remain_size = kmd_buf_info->size - kmd_buf_info->used_bytes;
|
||||||
} else {
|
} else {
|
||||||
CAM_ERR(CAM_ISP, "no free mem %d %d", kmd_buf_info->size,
|
CAM_ERR(CAM_ISP,
|
||||||
kmd_buf_info->used_bytes + (*io_cfg_used_bytes));
|
"no free kmd memory for base=%d bytes_used=%u buf_size=%u",
|
||||||
rc = -EINVAL;
|
base_idx, kmd_buf_info->used_bytes, kmd_buf_info->size);
|
||||||
return rc;
|
rc = -EINVAL;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
wm_update.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
|
wm_update.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
|
||||||
kmd_buf_info->used_bytes/4 + (*io_cfg_used_bytes)/4;
|
kmd_buf_info->used_bytes/4;
|
||||||
wm_update.cmd.size = kmd_buf_remain_size;
|
wm_update.cmd.size = kmd_buf_remain_size;
|
||||||
wm_update.cmd_type = CAM_ISP_HW_CMD_BUS_WM_DISABLE;
|
wm_update.cmd_type = CAM_ISP_HW_CMD_BUS_WM_DISABLE;
|
||||||
wm_update.res = res;
|
wm_update.res = res;
|
||||||
@@ -1311,9 +1314,11 @@ int cam_isp_add_disable_wm_update(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
CAM_DBG(CAM_ISP,
|
CAM_DBG(CAM_ISP,
|
||||||
"Out res %d disable update added hw_id %d cdm_idx %d",
|
"Out res %d disable update added hw_id %d cdm_idx %d split id: %d",
|
||||||
res->res_id, res->hw_intf->hw_idx, base_idx);
|
res->res_id, res->hw_intf->hw_idx, base_idx, i);
|
||||||
(*io_cfg_used_bytes) += wm_update.cmd.used_bytes;
|
|
||||||
|
io_info->kmd_buf_info->used_bytes += wm_update.cmd.used_bytes;
|
||||||
|
io_info->kmd_buf_info->offset += wm_update.cmd.used_bytes;
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CAM_ISP_HW_PARSER_H_
|
#ifndef _CAM_ISP_HW_PARSER_H_
|
||||||
@@ -288,7 +288,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info);
|
|||||||
* @base_idx: Base or dev index of the IFE/VFE HW instance
|
* @base_idx: Base or dev index of the IFE/VFE HW instance
|
||||||
* @kmd_buf_info: Kmd buffer to store the change base command
|
* @kmd_buf_info: Kmd buffer to store the change base command
|
||||||
* @wm_mask Bit mask of unconfigured resource
|
* @wm_mask Bit mask of unconfigured resource
|
||||||
* @io_cfg_used_bytes IO cfg size used in bytes
|
* @io_info IO buf info
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int cam_isp_add_disable_wm_update(
|
int cam_isp_add_disable_wm_update(
|
||||||
@@ -296,8 +296,8 @@ int cam_isp_add_disable_wm_update(
|
|||||||
struct cam_isp_hw_mgr_res *isp_hw_res,
|
struct cam_isp_hw_mgr_res *isp_hw_res,
|
||||||
uint32_t base_idx,
|
uint32_t base_idx,
|
||||||
struct cam_kmd_buf_info *kmd_buf_info,
|
struct cam_kmd_buf_info *kmd_buf_info,
|
||||||
uint64_t wm_mask,
|
uint64_t *wm_mask,
|
||||||
uint32_t *io_cfg_used_bytes);
|
struct cam_isp_io_buf_info *io_info);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cam_isp_add_reg_update()
|
* cam_isp_add_reg_update()
|
||||||
|
@@ -1988,13 +1988,15 @@ static uint32_t cam_tfe_bus_get_last_consumed_addr(
|
|||||||
struct cam_isp_resource_node *rsrc_node = NULL;
|
struct cam_isp_resource_node *rsrc_node = NULL;
|
||||||
struct cam_tfe_bus_tfe_out_data *rsrc_data = NULL;
|
struct cam_tfe_bus_tfe_out_data *rsrc_data = NULL;
|
||||||
struct cam_tfe_bus_wm_resource_data *wm_rsrc_data = NULL;
|
struct cam_tfe_bus_wm_resource_data *wm_rsrc_data = NULL;
|
||||||
|
enum cam_tfe_bus_tfe_out_id tfe_out_res_id;
|
||||||
|
|
||||||
if (out_id >= CAM_TFE_BUS_TFE_OUT_MAX) {
|
tfe_out_res_id = cam_tfe_bus_get_out_res_id(out_id);
|
||||||
|
if (tfe_out_res_id >= CAM_TFE_BUS_TFE_OUT_MAX) {
|
||||||
CAM_ERR(CAM_ISP, "invalid out_id:%u", out_id);
|
CAM_ERR(CAM_ISP, "invalid out_id:%u", out_id);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsrc_node = &bus_priv->tfe_out[out_id];
|
rsrc_node = &bus_priv->tfe_out[tfe_out_res_id];
|
||||||
rsrc_data = rsrc_node->res_priv;
|
rsrc_data = rsrc_node->res_priv;
|
||||||
wm_rsrc_data = rsrc_data->wm_res[PLANE_Y]->res_priv;
|
wm_rsrc_data = rsrc_data->wm_res[PLANE_Y]->res_priv;
|
||||||
|
|
||||||
@@ -2002,6 +2004,9 @@ static uint32_t cam_tfe_bus_get_last_consumed_addr(
|
|||||||
wm_rsrc_data->common_data->mem_base +
|
wm_rsrc_data->common_data->mem_base +
|
||||||
wm_rsrc_data->hw_regs->addr_status_0);
|
wm_rsrc_data->hw_regs->addr_status_0);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "TFE:%u res_type:0x%x res_id:0x%x last_consumed_addr:0x%x",
|
||||||
|
bus_priv->common_data.core_index, out_id, tfe_out_res_id, val);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2016,6 +2021,7 @@ static int cam_tfe_bus_bufdone_bottom_half(
|
|||||||
struct cam_tfe_bus_comp_grp_data *comp_rsrc_data;
|
struct cam_tfe_bus_comp_grp_data *comp_rsrc_data;
|
||||||
struct cam_isp_hw_bufdone_event_info bufdone_evt_info = {0};
|
struct cam_isp_hw_bufdone_event_info bufdone_evt_info = {0};
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
struct cam_tfe_bus_wm_resource_data *wm_rsrc_data = NULL;
|
||||||
|
|
||||||
common_data = &bus_priv->common_data;
|
common_data = &bus_priv->common_data;
|
||||||
|
|
||||||
@@ -2027,6 +2033,10 @@ static int cam_tfe_bus_bufdone_bottom_half(
|
|||||||
comp_rsrc_data = (struct cam_tfe_bus_comp_grp_data *)
|
comp_rsrc_data = (struct cam_tfe_bus_comp_grp_data *)
|
||||||
bus_priv->comp_grp[i].res_priv;
|
bus_priv->comp_grp[i].res_priv;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "i: %d irq: 0x%x comm_done: 0x%x com_grp: %d",
|
||||||
|
i, evt_payload->bus_irq_val[0], bus_priv->common_data.comp_done_shift,
|
||||||
|
comp_rsrc_data->comp_grp_id);
|
||||||
|
|
||||||
if (evt_payload->bus_irq_val[0] &
|
if (evt_payload->bus_irq_val[0] &
|
||||||
BIT(comp_rsrc_data->comp_grp_id +
|
BIT(comp_rsrc_data->comp_grp_id +
|
||||||
bus_priv->common_data.comp_done_shift)) {
|
bus_priv->common_data.comp_done_shift)) {
|
||||||
@@ -2037,10 +2047,10 @@ static int cam_tfe_bus_bufdone_bottom_half(
|
|||||||
evt_info.res_id = out_rsrc->res_id;
|
evt_info.res_id = out_rsrc->res_id;
|
||||||
bufdone_evt_info.res_id = out_rsrc->res_id;
|
bufdone_evt_info.res_id = out_rsrc->res_id;
|
||||||
bufdone_evt_info.comp_grp_id = comp_rsrc_data->comp_grp_id;
|
bufdone_evt_info.comp_grp_id = comp_rsrc_data->comp_grp_id;
|
||||||
bufdone_evt_info.last_consumed_addr =
|
wm_rsrc_data = out_rsrc_data->wm_res[PLANE_Y]->res_priv;
|
||||||
cam_tfe_bus_get_last_consumed_addr(
|
bufdone_evt_info.last_consumed_addr = cam_io_r_mb(
|
||||||
out_rsrc_data->bus_priv,
|
wm_rsrc_data->common_data->mem_base +
|
||||||
out_rsrc_data->out_id);
|
wm_rsrc_data->hw_regs->addr_status_0);
|
||||||
evt_info.event_data = (void *)&bufdone_evt_info;
|
evt_info.event_data = (void *)&bufdone_evt_info;
|
||||||
|
|
||||||
if (out_rsrc_data->event_cb)
|
if (out_rsrc_data->event_cb)
|
||||||
|
Reference in New Issue
Block a user