msm: camera: isp: Add PID MID support for SFE

This commit adds support for printing PID and MID in case
of page faults on SFE.

CRs-Fixed: 3040816
Change-Id: I99f8c6de6049802f7c67a72daf6c3fb24c3defb1
Signed-off-by: Gaurav Jindal <gjindal@codeaurora.org>
This commit is contained in:
Gaurav Jindal
2021-09-16 20:49:54 +05:30
parent c8ac17dee6
commit 8b1c004eac
9 changed files with 215 additions and 109 deletions

View File

@@ -95,7 +95,7 @@ static int cam_ife_mgr_finish_clk_bw_update(
clk_bw_args.hw_intf = g_ife_hw_mgr.ife_devices[ctx->base[i].idx]->hw_intf; clk_bw_args.hw_intf = g_ife_hw_mgr.ife_devices[ctx->base[i].idx]->hw_intf;
else if ((ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) && else if ((ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE) &&
(ctx->num_acq_sfe_out || (!list_empty(&ctx->res_list_ife_in_rd)))) (ctx->num_acq_sfe_out || (!list_empty(&ctx->res_list_ife_in_rd))))
clk_bw_args.hw_intf = g_ife_hw_mgr.sfe_devices[ctx->base[i].idx]; clk_bw_args.hw_intf = g_ife_hw_mgr.sfe_devices[ctx->base[i].idx]->hw_intf;
else else
continue; continue;
@@ -618,7 +618,7 @@ static int cam_ife_hw_mgr_notify_overflow(
if (hw_mgr_ctx->base[i].idx != evt->in_core_idx) if (hw_mgr_ctx->base[i].idx != evt->in_core_idx)
continue; continue;
hw_if = g_ife_hw_mgr.sfe_devices[evt->in_core_idx]; hw_if = g_ife_hw_mgr.sfe_devices[evt->in_core_idx]->hw_intf;
res_id = sfe_res_id; res_id = sfe_res_id;
} else { } else {
continue; continue;
@@ -2336,7 +2336,7 @@ static int cam_ife_hw_mgr_acquire_sfe_hw(
if (!ife_hw_mgr->sfe_devices[i]) if (!ife_hw_mgr->sfe_devices[i])
continue; continue;
hw_intf = ife_hw_mgr->sfe_devices[i]; hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
sfe_acquire, sfe_acquire,
sizeof(struct cam_sfe_acquire_args)); sizeof(struct cam_sfe_acquire_args));
@@ -2354,7 +2354,7 @@ static int cam_ife_hw_mgr_acquire_sfe_hw(
if (!ife_hw_mgr->sfe_devices[i]) if (!ife_hw_mgr->sfe_devices[i])
continue; continue;
hw_intf = ife_hw_mgr->sfe_devices[i]; hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
sfe_acquire, sfe_acquire,
sizeof(struct cam_sfe_acquire_args)); sizeof(struct cam_sfe_acquire_args));
@@ -2698,7 +2698,7 @@ static int cam_ife_hw_mgr_acquire_sfe_bus_rd(
if (!ife_hw_mgr->sfe_devices[i]) if (!ife_hw_mgr->sfe_devices[i])
continue; continue;
hw_intf = ife_hw_mgr->sfe_devices[i]; hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
&sfe_acquire, sizeof(struct cam_sfe_acquire_args)); &sfe_acquire, sizeof(struct cam_sfe_acquire_args));
if (rc) if (rc)
@@ -2739,7 +2739,7 @@ acquire_successful:
if (i == sfe_rd_res->hw_res[0]->hw_intf->hw_idx) if (i == sfe_rd_res->hw_res[0]->hw_intf->hw_idx)
continue; continue;
hw_intf = ife_hw_mgr->sfe_devices[i]; hw_intf = ife_hw_mgr->sfe_devices[i]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
&sfe_acquire, sizeof(sfe_acquire)); &sfe_acquire, sizeof(sfe_acquire));
if (rc) if (rc)
@@ -3928,7 +3928,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_sfe(
sfe_acquire.sfe_in.res_id = CAM_ISP_HW_SFE_IN_PIX; sfe_acquire.sfe_in.res_id = CAM_ISP_HW_SFE_IN_PIX;
hw_intf = ife_hw_mgr->sfe_devices[ hw_intf = ife_hw_mgr->sfe_devices[
sfe_bus_rd_res->hw_res[i]->hw_intf->hw_idx]; sfe_bus_rd_res->hw_res[i]->hw_intf->hw_idx]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire, rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire,
sizeof(struct cam_sfe_acquire_args)); sizeof(struct cam_sfe_acquire_args));
@@ -3953,7 +3953,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_sfe(
sfe_acquire.sfe_in.rsrc_node = NULL; sfe_acquire.sfe_in.rsrc_node = NULL;
hw_intf = ife_hw_mgr->sfe_devices[ hw_intf = ife_hw_mgr->sfe_devices[
sfe_bus_rd_res->hw_res[++i]->hw_intf->hw_idx]; sfe_bus_rd_res->hw_res[++i]->hw_intf->hw_idx]->hw_intf;
rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire, rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv, &sfe_acquire,
sizeof(struct cam_sfe_acquire_args)); sizeof(struct cam_sfe_acquire_args));
@@ -6406,8 +6406,8 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
debug_cfg.u.dbg_cfg.sfe_debug_cfg = g_ife_hw_mgr.debug_cfg.sfe_debug; debug_cfg.u.dbg_cfg.sfe_debug_cfg = g_ife_hw_mgr.debug_cfg.sfe_debug;
debug_cfg.u.dbg_cfg.sfe_sensor_sel = g_ife_hw_mgr.debug_cfg.sfe_sensor_diag_cfg; debug_cfg.u.dbg_cfg.sfe_sensor_sel = g_ife_hw_mgr.debug_cfg.sfe_sensor_diag_cfg;
if (g_ife_hw_mgr.sfe_devices[i]) { if (g_ife_hw_mgr.sfe_devices[i]) {
rc = g_ife_hw_mgr.sfe_devices[i]->hw_ops.process_cmd( rc = g_ife_hw_mgr.sfe_devices[i]->hw_intf->hw_ops.process_cmd(
g_ife_hw_mgr.sfe_devices[i]->hw_priv, g_ife_hw_mgr.sfe_devices[i]->hw_intf->hw_priv,
CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG, CAM_ISP_HW_CMD_SET_SFE_DEBUG_CFG,
&debug_cfg, &debug_cfg,
sizeof(debug_cfg)); sizeof(debug_cfg));
@@ -7855,7 +7855,7 @@ static int cam_isp_blob_sfe_core_cfg_update(
!ife_hw_mgr->sfe_devices[idx]) !ife_hw_mgr->sfe_devices[idx])
continue; continue;
hw_intf = ife_hw_mgr->sfe_devices[idx]; hw_intf = ife_hw_mgr->sfe_devices[idx]->hw_intf;
if (hw_intf && hw_intf->hw_ops.process_cmd) { if (hw_intf && hw_intf->hw_ops.process_cmd) {
memcpy(&sfe_core_config.core_config, memcpy(&sfe_core_config.core_config,
core_config, core_config,
@@ -10454,19 +10454,51 @@ static void cam_ife_mgr_pf_dump(uint32_t res_id,
} }
} }
static void cam_ife_mgr_pf_dump_mid_info(
struct cam_ife_hw_mgr_ctx *ctx,
struct cam_hw_cmd_args *hw_cmd_args,
struct cam_isp_hw_intf_data *hw_intf_data)
{
struct cam_packet *packet;
struct cam_isp_hw_get_cmd_update cmd_update;
struct cam_isp_hw_get_res_for_mid get_res;
int rc = 0;
packet = hw_cmd_args->u.pf_args.pf_data.packet;
get_res.mid = hw_cmd_args->u.pf_args.mid;
cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID;
cmd_update.data = (void *) &get_res;
/* get resource id for given mid */
rc = hw_intf_data->hw_intf->hw_ops.process_cmd(hw_intf_data->hw_intf->hw_priv,
cmd_update.cmd_type, &cmd_update, sizeof(struct cam_isp_hw_get_cmd_update));
if (rc) {
CAM_ERR(CAM_ISP,
"getting mid port resource id failed ctx id:%d req id:%lld",
ctx->ctx_index, packet->header.request_id);
return;
}
*(hw_cmd_args->u.pf_args.resource_type) = get_res.out_res_id;
ctx->flags.pf_mid_found = true;
ctx->pf_info.mid = get_res.mid;
ctx->pf_info.out_port_id = get_res.out_res_id;
CAM_ERR(CAM_ISP,
"Page fault on resource id:(0x%x) ctx id:%d req id:%lld",
get_res.out_res_id, ctx->ctx_index, packet->header.request_id);
}
static void cam_ife_mgr_dump_pf_data( static void cam_ife_mgr_dump_pf_data(
struct cam_ife_hw_mgr *hw_mgr, struct cam_ife_hw_mgr *hw_mgr,
struct cam_hw_cmd_args *hw_cmd_args) struct cam_hw_cmd_args *hw_cmd_args)
{ {
struct cam_ife_hw_mgr_ctx *ctx; struct cam_ife_hw_mgr_ctx *ctx;
struct cam_isp_hw_mgr_res *hw_mgr_res;
struct cam_isp_hw_get_cmd_update cmd_update;
struct cam_isp_hw_get_res_for_mid get_res;
struct cam_packet *packet; struct cam_packet *packet;
uint32_t hw_id; struct cam_isp_hw_intf_data *hw_intf_data;
uint32_t *resource_type; uint32_t *resource_type;
bool *ctx_found, hw_id_found = false; bool *ctx_found;
int i, j, rc = 0; int i, j;
ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map; ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
@@ -10480,93 +10512,49 @@ static void cam_ife_mgr_dump_pf_data(
if (ctx->flags.pf_mid_found) if (ctx->flags.pf_mid_found)
goto outportlog; goto outportlog;
if (!g_ife_hw_mgr.hw_pid_support) for (i = 0; i < ctx->num_base; i++) {
goto mid_check; if (ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE)
hw_intf_data = g_ife_hw_mgr.ife_devices[ctx->base[i].idx];
for (i = 0; i < CAM_IFE_HW_NUM_MAX; i++) { else if (ctx->base[i].hw_type == CAM_ISP_HW_TYPE_SFE)
if (!hw_mgr->ife_devices[i]) hw_intf_data = g_ife_hw_mgr.sfe_devices[ctx->base[i].idx];
else
continue; continue;
for (j = 0; j < g_ife_hw_mgr.ife_devices[i]->num_hw_pid; j++) { /*
if (g_ife_hw_mgr.ife_devices[i]->hw_pid[j] == * Few old targets do not have support for PID, for such targets,
hw_cmd_args->u.pf_args.pid) { * we need to print mid for all the bases, SFE enabled targets
hw_id_found = true; * are expected to have PID support.
hw_id = i; */
if (!g_ife_hw_mgr.hw_pid_support) {
if (ctx->base[i].split_id == CAM_ISP_HW_SPLIT_LEFT)
cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data);
continue;
}
for (j = 0; j < hw_intf_data->num_hw_pid; j++) {
if (hw_intf_data->hw_pid[j] == hw_cmd_args->u.pf_args.pid) {
*ctx_found = true;
CAM_ERR(CAM_ISP, "PF found for %s%d pid: %u",
ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE ? "VFE" : "SFE",
ctx->base[i].idx, hw_cmd_args->u.pf_args.pid);
cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data);
break; break;
} }
} }
if (hw_id_found)
if (*ctx_found)
break; break;
} }
if (i == CAM_IFE_HW_NUM_MAX) { if (g_ife_hw_mgr.hw_pid_support && (i == ctx->num_base || !*ctx_found))
CAM_INFO(CAM_ISP, CAM_INFO(CAM_ISP,
"PID:%d is not matching with any IFE HW PIDs ctx id:%d", "This context does not cause pf:pid:%d ctx_id:%d",
hw_cmd_args->u.pf_args.pid, ctx->ctx_index); hw_cmd_args->u.pf_args.pid, ctx->ctx_index);
return; cam_ife_mgr_pf_dump(ctx->pf_info.out_port_id, ctx);
}
for (i = 0; i < ctx->num_base; i++) {
if (ctx->base[i].idx == hw_id) {
*ctx_found = true;
break;
}
}
if (!(*ctx_found)) {
CAM_INFO(CAM_ISP,
"This context does not cause pf:pid:%d hw id:%d ctx_id:%d",
hw_cmd_args->u.pf_args.pid, hw_id, ctx->ctx_index);
return;
}
mid_check:
for (i = 0; i < max_ife_out_res; i++) {
hw_mgr_res = &ctx->res_list_ife_out[i];
if (!hw_mgr_res->hw_res[0])
continue;
break;
}
if (i >= max_ife_out_res) {
CAM_ERR(CAM_ISP,
"NO valid outport resources ctx id:%d req id:%lld",
ctx->ctx_index, packet->header.request_id);
return;
}
get_res.mid = hw_cmd_args->u.pf_args.mid;
cmd_update.res = hw_mgr_res->hw_res[0];
cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID;
cmd_update.data = (void *) &get_res;
/* get resource id for given mid */
rc = hw_mgr_res->hw_res[0]->hw_intf->hw_ops.process_cmd(
hw_mgr_res->hw_res[0]->hw_intf->hw_priv,
cmd_update.cmd_type, &cmd_update,
sizeof(struct cam_isp_hw_get_cmd_update));
if (rc) {
CAM_ERR(CAM_ISP,
"getting mid port resource id failed ctx id:%d req id:%lld",
ctx->ctx_index, packet->header.request_id);
return;
}
CAM_ERR(CAM_ISP,
"Page fault on resource id:(0x%x) ctx id:%d req id:%lld",
get_res.out_res_id, ctx->ctx_index, packet->header.request_id);
*resource_type = get_res.out_res_id;
ctx->flags.pf_mid_found = true;
ctx->pf_info.mid = get_res.mid;
ctx->pf_info.out_port_id = get_res.out_res_id;
cam_ife_mgr_pf_dump(get_res.out_res_id, ctx);
outportlog: outportlog:
cam_ife_mgr_print_io_bufs(hw_mgr, *resource_type, packet, cam_ife_mgr_print_io_bufs(hw_mgr, *resource_type, packet,
ctx_found, ctx); ctx_found, ctx);
} }
int cam_isp_config_csid_rup_aup( int cam_isp_config_csid_rup_aup(
@@ -12086,7 +12074,7 @@ static int cam_ife_set_sfe_cache_debug(void *data, u64 val)
hw_idx = val & 0xF; hw_idx = val & 0xF;
for (i = 0; i < CAM_SFE_HW_NUM_MAX; i++) { for (i = 0; i < CAM_SFE_HW_NUM_MAX; i++) {
if ((g_ife_hw_mgr.sfe_devices[i]) && (i == hw_idx)) { if ((g_ife_hw_mgr.sfe_devices[i]) && (i == hw_idx)) {
hw_intf = g_ife_hw_mgr.sfe_devices[i]; hw_intf = g_ife_hw_mgr.sfe_devices[i]->hw_intf;
debug_cfg.u.cache_cfg.sfe_cache_dbg = (val >> 4); debug_cfg.u.cache_cfg.sfe_cache_dbg = (val >> 4);
g_ife_hw_mgr.debug_cfg.sfe_cache_debug[i] = g_ife_hw_mgr.debug_cfg.sfe_cache_debug[i] =
@@ -12473,7 +12461,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
if (!rc) { if (!rc) {
if (j == 0) { if (j == 0) {
struct cam_hw_intf *sfe_device = struct cam_hw_intf *sfe_device =
g_ife_hw_mgr.sfe_devices[i]; g_ife_hw_mgr.sfe_devices[i]->hw_intf;
struct cam_hw_info *sfe_hw = struct cam_hw_info *sfe_hw =
(struct cam_hw_info *) (struct cam_hw_info *)
sfe_device->hw_priv; sfe_device->hw_priv;
@@ -12488,6 +12476,9 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
if (!rc) if (!rc)
g_ife_hw_mgr.isp_bus_caps.max_sfe_out_res_type = g_ife_hw_mgr.isp_bus_caps.max_sfe_out_res_type =
isp_bus_cap.max_out_res_type; isp_bus_cap.max_out_res_type;
if (g_ife_hw_mgr.sfe_devices[i]->num_hw_pid)
g_ife_hw_mgr.hw_pid_support = true;
} }
j++; j++;
} }

View File

@@ -350,7 +350,7 @@ struct cam_ife_hw_mgr {
struct cam_isp_hw_mgr mgr_common; struct cam_isp_hw_mgr mgr_common;
struct cam_hw_intf *csid_devices[CAM_IFE_CSID_HW_NUM_MAX]; struct cam_hw_intf *csid_devices[CAM_IFE_CSID_HW_NUM_MAX];
struct cam_isp_hw_intf_data *ife_devices[CAM_IFE_HW_NUM_MAX]; struct cam_isp_hw_intf_data *ife_devices[CAM_IFE_HW_NUM_MAX];
struct cam_hw_intf *sfe_devices[CAM_SFE_HW_NUM_MAX]; struct cam_isp_hw_intf_data *sfe_devices[CAM_SFE_HW_NUM_MAX];
struct cam_soc_reg_map *cdm_reg_map[CAM_IFE_HW_NUM_MAX]; struct cam_soc_reg_map *cdm_reg_map[CAM_IFE_HW_NUM_MAX];
struct mutex ctx_mutex; struct mutex ctx_mutex;

View File

@@ -354,7 +354,7 @@ struct cam_sfe_acquire_args {
* successful initialization * successful initialization
* @hw_idx: Index of SFE HW * @hw_idx: Index of SFE HW
*/ */
int cam_sfe_hw_init(struct cam_hw_intf **sfe_hw, uint32_t hw_idx); int cam_sfe_hw_init(struct cam_isp_hw_intf_data **sfe_hw, uint32_t hw_idx);
#endif /* _CAM_SFE_HW_INTF_H_ */ #endif /* _CAM_SFE_HW_INTF_H_ */

View File

@@ -360,7 +360,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
core_info->sfe_top->hw_ops.process_cmd( core_info->sfe_top->hw_ops.process_cmd(
core_info->sfe_top->top_priv, cmd_type, core_info->sfe_top->top_priv, cmd_type,
cmd_args, arg_size); cmd_args, arg_size);
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
/* propagate to SFE bus wr */ /* propagate to SFE bus wr */
core_info->sfe_bus_wr->hw_ops.process_cmd( core_info->sfe_bus_wr->hw_ops.process_cmd(
core_info->sfe_bus_wr->bus_priv, cmd_type, core_info->sfe_bus_wr->bus_priv, cmd_type,

View File

@@ -15,7 +15,7 @@
#include "cam_debug_util.h" #include "cam_debug_util.h"
#include "camera_main.h" #include "camera_main.h"
static struct cam_hw_intf *cam_sfe_hw_list[CAM_SFE_HW_NUM_MAX]; static struct cam_isp_hw_intf_data cam_sfe_hw_list[CAM_SFE_HW_NUM_MAX];
static int cam_sfe_component_bind(struct device *dev, static int cam_sfe_component_bind(struct device *dev,
struct device *master_dev, void *data) struct device *master_dev, void *data)
@@ -27,7 +27,8 @@ static int cam_sfe_component_bind(struct device *dev,
struct cam_sfe_hw_core_info *core_info = NULL; struct cam_sfe_hw_core_info *core_info = NULL;
struct cam_sfe_hw_info *hw_info = NULL; struct cam_sfe_hw_info *hw_info = NULL;
struct platform_device *pdev = NULL; struct platform_device *pdev = NULL;
int rc = 0; struct cam_sfe_soc_private *soc_priv;
int i, rc = 0;
pdev = to_platform_device(dev); pdev = to_platform_device(dev);
sfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL); sfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
@@ -106,7 +107,13 @@ static int cam_sfe_component_bind(struct device *dev,
init_completion(&sfe_info->hw_complete); init_completion(&sfe_info->hw_complete);
if (sfe_hw_intf->hw_idx < CAM_SFE_HW_NUM_MAX) if (sfe_hw_intf->hw_idx < CAM_SFE_HW_NUM_MAX)
cam_sfe_hw_list[sfe_hw_intf->hw_idx] = sfe_hw_intf; cam_sfe_hw_list[sfe_hw_intf->hw_idx].hw_intf = sfe_hw_intf;
soc_priv = sfe_info->soc_info.soc_private;
cam_sfe_hw_list[sfe_hw_intf->hw_idx].num_hw_pid = soc_priv->num_pid;
for (i = 0; i < soc_priv->num_pid; i++)
cam_sfe_hw_list[sfe_hw_intf->hw_idx].hw_pid[i] =
soc_priv->pid[i];
CAM_DBG(CAM_SFE, "SFE%d bound successfully", CAM_DBG(CAM_SFE, "SFE%d bound successfully",
sfe_hw_intf->hw_idx); sfe_hw_intf->hw_idx);
@@ -147,7 +154,7 @@ static void cam_sfe_component_unbind(struct device *dev,
sfe_hw_intf->hw_type, sfe_hw_intf->hw_idx); sfe_hw_intf->hw_type, sfe_hw_intf->hw_idx);
if (sfe_hw_intf->hw_idx < CAM_SFE_HW_NUM_MAX) if (sfe_hw_intf->hw_idx < CAM_SFE_HW_NUM_MAX)
cam_sfe_hw_list[sfe_hw_intf->hw_idx] = NULL; cam_sfe_hw_list[sfe_hw_intf->hw_idx].hw_intf = NULL;
sfe_info = sfe_hw_intf->hw_priv; sfe_info = sfe_hw_intf->hw_priv;
if (!sfe_info) { if (!sfe_info) {
@@ -206,12 +213,12 @@ int cam_sfe_remove(struct platform_device *pdev)
return 0; return 0;
} }
int cam_sfe_hw_init(struct cam_hw_intf **sfe_hw, uint32_t hw_idx) int cam_sfe_hw_init(struct cam_isp_hw_intf_data **sfe_hw, uint32_t hw_idx)
{ {
int rc = 0; int rc = 0;
if (cam_sfe_hw_list[hw_idx]) { if (cam_sfe_hw_list[hw_idx].hw_intf) {
*sfe_hw = cam_sfe_hw_list[hw_idx]; *sfe_hw = &cam_sfe_hw_list[hw_idx];
rc = 0; rc = 0;
} else { } else {
*sfe_hw = NULL; *sfe_hw = NULL;

View File

@@ -10,12 +10,30 @@
static int cam_sfe_get_dt_properties(struct cam_hw_soc_info *soc_info) static int cam_sfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
{ {
int rc = 0; struct cam_sfe_soc_private *soc_private = soc_info->soc_private;
struct platform_device *pdev = soc_info->pdev;
uint32_t num_pid = 0;
int i, rc = 0;
rc = cam_soc_util_get_dt_properties(soc_info); rc = cam_soc_util_get_dt_properties(soc_info);
if (rc) if (rc) {
CAM_ERR(CAM_SFE, "Error get DT properties failed rc=%d", rc); CAM_ERR(CAM_SFE, "Error get DT properties failed rc=%d", rc);
goto end;
}
soc_private->num_pid = 0;
num_pid = of_property_count_u32_elems(pdev->dev.of_node, "cam_hw_pid");
CAM_DBG(CAM_SFE, "sfe:%d pid count %d", soc_info->index, num_pid);
if (num_pid <= 0 || num_pid > CAM_ISP_HW_MAX_PID_VAL)
goto end;
for (i = 0; i < num_pid; i++)
of_property_read_u32_index(pdev->dev.of_node, "cam_hw_pid", i,
&soc_private->pid[i]);
soc_private->num_pid = num_pid;
end:
return rc; return rc;
} }

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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.
*/ */
#ifndef _CAM_SFE_SOC_H_ #ifndef _CAM_SFE_SOC_H_
@@ -18,10 +18,14 @@
* This handle is used for all further interface * This handle is used for all further interface
* with CPAS. * with CPAS.
* @cpas_version: CPAS version * @cpas_version: CPAS version
* @num_pid: Number of pids of sfe
* @pid: SFE pid values list
*/ */
struct cam_sfe_soc_private { struct cam_sfe_soc_private {
uint32_t cpas_handle; uint32_t cpas_handle;
uint32_t cpas_version; uint32_t cpas_version;
uint32_t num_pid;
uint32_t pid[CAM_ISP_HW_MAX_PID_VAL];
}; };
/* /*

View File

@@ -128,7 +128,7 @@ struct cam_sfe_bus_rd_priv {
CAM_SFE_BUS_RD_MAX_CLIENTS]; CAM_SFE_BUS_RD_MAX_CLIENTS];
struct cam_isp_resource_node sfe_bus_rd[ struct cam_isp_resource_node sfe_bus_rd[
CAM_SFE_BUS_RD_MAX]; CAM_SFE_BUS_RD_MAX];
struct cam_sfe_bus_rd_hw_info *bus_rd_hw_info;
int irq_handle; int irq_handle;
int error_irq_handle; int error_irq_handle;
void *tasklet_info; void *tasklet_info;
@@ -1524,6 +1524,46 @@ static int cam_sfe_bus_rd_update_rm_core_cfg(
return 0; return 0;
} }
static int cam_sfe_bus_rd_get_res_for_mid(
struct cam_sfe_bus_rd_priv *bus_priv,
void *cmd_args, uint32_t arg_size)
{
struct cam_sfe_bus_rd_hw_info *hw_info;
struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args;
struct cam_isp_hw_get_res_for_mid *get_res = NULL;
int i, j;
get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
if (!get_res) {
CAM_ERR(CAM_SFE,
"invalid get resource for mid paramas");
return -EINVAL;
}
hw_info = bus_priv->bus_rd_hw_info;
for (i = 0; i < bus_priv->num_bus_rd_resc; i++) {
for (j = 0; j < CAM_SFE_BUS_MAX_MID_PER_PORT; j++) {
if (hw_info->sfe_bus_rd_info[i].mid[j] == get_res->mid)
goto end;
}
}
/*
* Do not update out_res_id in case of no match.
* Correct value will be dumped in hw mgr
*/
if (i == bus_priv->num_bus_rd_resc) {
CAM_INFO(CAM_SFE, "mid:%d does not match with any out resource", get_res->mid);
return 0;
}
end:
CAM_INFO(CAM_SFE, "match mid :%d out resource: 0x%x found",
get_res->mid, bus_priv->sfe_bus_rd[i].res_id);
get_res->out_res_id = bus_priv->sfe_bus_rd[i].res_id;
return 0;
}
static int cam_sfe_bus_init_hw(void *hw_priv, static int cam_sfe_bus_init_hw(void *hw_priv,
void *init_hw_args, uint32_t arg_size) void *init_hw_args, uint32_t arg_size)
{ {
@@ -1668,6 +1708,9 @@ static int cam_sfe_bus_rd_process_cmd(
case CAM_ISP_HW_CMD_RM_ENABLE_DISABLE: case CAM_ISP_HW_CMD_RM_ENABLE_DISABLE:
rc = cam_sfe_bus_rd_update_rm_core_cfg(priv, cmd_args, arg_size); rc = cam_sfe_bus_rd_update_rm_core_cfg(priv, cmd_args, arg_size);
break; break;
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
rc = cam_sfe_bus_rd_get_res_for_mid(priv, cmd_args, arg_size);
break;
default: default:
CAM_ERR_RATE_LIMIT(CAM_SFE, CAM_ERR_RATE_LIMIT(CAM_SFE,
"Invalid SFE BUS RD command type: %d", "Invalid SFE BUS RD command type: %d",
@@ -1727,6 +1770,7 @@ int cam_sfe_bus_rd_init(
bus_priv->common_data.common_reg = &bus_rd_hw_info->common_reg; bus_priv->common_data.common_reg = &bus_rd_hw_info->common_reg;
bus_priv->top_irq_shift = bus_rd_hw_info->top_irq_shift; bus_priv->top_irq_shift = bus_rd_hw_info->top_irq_shift;
bus_priv->latency_buf_allocation = bus_rd_hw_info->latency_buf_allocation; bus_priv->latency_buf_allocation = bus_rd_hw_info->latency_buf_allocation;
bus_priv->bus_rd_hw_info = bus_rd_hw_info;
rc = cam_irq_controller_init(drv_name, rc = cam_irq_controller_init(drv_name,
bus_priv->common_data.mem_base, bus_priv->common_data.mem_base,

View File

@@ -2940,6 +2940,45 @@ add_reg_pair:
return 0; return 0;
} }
static int cam_sfe_bus_wr_get_res_for_mid(
struct cam_sfe_bus_wr_priv *bus_priv,
void *cmd_args, uint32_t arg_size)
{
struct cam_isp_hw_get_cmd_update *cmd_update = cmd_args;
struct cam_isp_hw_get_res_for_mid *get_res = NULL;
int i, j;
get_res = (struct cam_isp_hw_get_res_for_mid *)cmd_update->data;
if (!get_res) {
CAM_ERR(CAM_SFE,
"invalid get resource for mid paramas");
return -EINVAL;
}
for (i = 0; i < bus_priv->num_out; i++) {
for (j = 0; j < CAM_SFE_BUS_MAX_MID_PER_PORT; j++) {
if (bus_priv->sfe_out_hw_info[i].mid[j] == get_res->mid)
goto end;
}
}
/*
* Do not update out_res_id in case of no match.
* Correct value will be dumped in hw mgr
*/
if (i == bus_priv->num_out) {
CAM_INFO(CAM_SFE, "mid:%d does not match with any out resource", get_res->mid);
return 0;
}
end:
CAM_INFO(CAM_SFE, "match mid :%d out resource: %s 0x%x found",
get_res->mid, bus_priv->sfe_out_hw_info[i].name,
bus_priv->sfe_out[i].res_id);
get_res->out_res_id = bus_priv->sfe_out[i].res_id;
return 0;
}
static int cam_sfe_bus_wr_start_hw(void *hw_priv, static int cam_sfe_bus_wr_start_hw(void *hw_priv,
void *start_hw_args, uint32_t arg_size) void *start_hw_args, uint32_t arg_size)
{ {
@@ -3092,6 +3131,9 @@ static int cam_sfe_bus_wr_process_cmd(
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG: case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
rc = cam_sfe_bus_wr_update_bw_limiter(priv, cmd_args, arg_size); rc = cam_sfe_bus_wr_update_bw_limiter(priv, cmd_args, arg_size);
break; break;
case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
rc = cam_sfe_bus_wr_get_res_for_mid(priv, cmd_args, arg_size);
break;
default: default:
CAM_ERR_RATE_LIMIT(CAM_SFE, "Invalid HW command type:%d", CAM_ERR_RATE_LIMIT(CAM_SFE, "Invalid HW command type:%d",
cmd_type); cmd_type);