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:
@@ -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++;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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_ */
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -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,
|
||||||
|
@@ -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);
|
||||||
|
Referens i nytt ärende
Block a user