diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 556c24784b63..69713cc8fd6a 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -4005,6 +4005,36 @@ static int cam_ife_mgr_reset_vfe_hw(struct cam_ife_hw_mgr *hw_mgr, return 0; } +static int cam_ife_mgr_unmask_bus_wr_irq(struct cam_ife_hw_mgr *hw_mgr, + uint32_t hw_idx) +{ + uint32_t i = 0, dummy_args = 0; + struct cam_hw_intf *vfe_hw_intf; + + if (!hw_mgr) { + CAM_DBG(CAM_ISP, "Invalid arguments"); + return -EINVAL; + } + + for (i = 0; i < CAM_VFE_HW_NUM_MAX; i++) { + if (hw_idx != hw_mgr->ife_devices[i]->hw_idx) + continue; + + CAM_DBG(CAM_ISP, "Unmask VFE:%d BUS_WR IRQ", hw_idx); + + vfe_hw_intf = hw_mgr->ife_devices[i]; + + vfe_hw_intf->hw_ops.process_cmd(vfe_hw_intf->hw_priv, + CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ, + &dummy_args, + sizeof(dummy_args)); + + break; + } + + return 0; +} + static int cam_ife_mgr_restart_hw(void *start_hw_args) { int rc = -1; @@ -4124,8 +4154,18 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args) cam_tasklet_start(ctx->common.tasklet_info); - if (ctx->init_done && start_isp->start_only) + if (ctx->init_done && start_isp->start_only) { + /* Unmask BUS_WR bit in VFE top */ + for (i = 0; i < ctx->num_base; i++) { + rc = cam_ife_mgr_unmask_bus_wr_irq(hw_mgr_priv, + ctx->base[i].idx); + if (rc) + CAM_ERR(CAM_ISP, + "Failed to unmask VFE:%d BUS_WR IRQ rc:%d", + ctx->base[i].idx, rc); + } goto start_only; + } /* set current csid debug information to CSID HW */ for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h index 2f00b1476986..b55af3ec2ef0 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h @@ -115,6 +115,7 @@ enum cam_isp_hw_cmd_type { CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP, CAM_ISP_HW_CMD_DUMP_HW, CAM_ISP_HW_CMD_FE_TRIGGER_CMD, + CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ, CAM_ISP_HW_CMD_MAX, }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c index 7281e98ba94c..13e3263ff26b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c @@ -608,6 +608,7 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type, case CAM_ISP_HW_CMD_UBWC_UPDATE_V2: case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE: case CAM_ISP_HW_CMD_GET_SECURE_MODE: + case CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ: rc = core_info->vfe_bus->hw_ops.process_cmd( core_info->vfe_bus->bus_priv, cmd_type, cmd_args, arg_size); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h index 63df625221cc..07d821871b5e 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe170.h @@ -265,6 +265,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_bus_hw_info = { .addr_sync_no_sync = 0x00002084, .debug_status_cfg = 0x0000226C, .debug_status_0 = 0x00002270, + .top_irq_mask_0 = 0x0000005C, }, .num_client = 20, .bus_client_reg = { @@ -849,6 +850,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe170_bus_hw_info = { .max_height = -1, }, }, + .top_irq_shift = 9, }; struct cam_vfe_hw_info cam_vfe170_hw_info = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h index 4e9a1e232860..ccc771c993c2 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175.h @@ -331,6 +331,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_bus_hw_info = { .addr_sync_no_sync = 0x00002084, .debug_status_cfg = 0x0000226C, .debug_status_0 = 0x00002270, + .top_irq_mask_0 = 0x0000005C, }, .num_client = 24, .bus_client_reg = { @@ -1019,6 +1020,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_bus_hw_info = { .max_height = 1080, }, }, + .top_irq_shift = 9, }; struct cam_vfe_hw_info cam_vfe175_hw_info = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h index 946ac2267d95..7573407af078 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h @@ -433,6 +433,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_130_bus_hw_info = { .addr_sync_no_sync = 0x00002084, .debug_status_cfg = 0x0000226C, .debug_status_0 = 0x00002270, + .top_irq_mask_0 = 0x0000005C, }, .num_client = 24, .bus_client_reg = { @@ -1125,6 +1126,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe175_130_bus_hw_info = { .max_height = 1080, }, }, + .top_irq_shift = 9, }; struct cam_vfe_hw_info cam_vfe175_130_hw_info = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h index 18a0071bf0b0..359c43ae0c6f 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h @@ -404,6 +404,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .debug_status_top_cfg = 0x0000AAD4, .debug_status_top = 0x0000AAD8, .test_bus_ctrl = 0x0000AADC, + .top_irq_mask_0 = 0x0000003C, .irq_reg_info = { .num_registers = 2, .irq_reg_set = vfe480_bus_irq_reg, diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h index aab38c791637..be6d1ada950d 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h @@ -153,6 +153,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe17x_bus_hw_info = { .addr_sync_cfg = 0x0000207C, .addr_sync_frame_hdr = 0x00002080, .addr_sync_no_sync = 0x00002084, + .top_irq_mask_0 = 0x0000005C, }, .num_client = 4, .bus_client_reg = { @@ -322,6 +323,7 @@ static struct cam_vfe_bus_ver2_hw_info vfe17x_bus_hw_info = { .max_height = -1, }, }, + .top_irq_shift = 9, }; static struct cam_vfe_hw_info cam_vfe_lite17x_hw_info = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h index c19ade50bec9..09da6810fd4b 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h @@ -239,6 +239,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = { .debug_status_top_cfg = 0x00001AD4, .debug_status_top = 0x00001AD8, .test_bus_ctrl = 0x00001ADC, + .top_irq_mask_0 = 0x00000028, .irq_reg_info = { .num_registers = 2, .irq_reg_set = vfe48x_bus_irq_reg, diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c index 401b49b6f073..aeb154482d17 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c @@ -183,6 +183,7 @@ struct cam_vfe_bus_ver2_priv { struct cam_vfe_bus_ver2_common_data common_data; uint32_t num_client; uint32_t num_out; + uint32_t top_irq_shift; struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS]; struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX]; @@ -3424,7 +3425,7 @@ static int cam_vfe_bus_init_hw(void *hw_priv, if (bus_priv->common_data.hw_init) return 0; - top_irq_reg_mask[0] = (1 << 9); + top_irq_reg_mask[0] = (1 << bus_priv->top_irq_shift); bus_priv->irq_handle = cam_irq_controller_subscribe_irq( bus_priv->common_data.vfe_irq_controller, @@ -3539,6 +3540,7 @@ static int cam_vfe_bus_process_cmd( { int rc = -EINVAL; struct cam_vfe_bus_ver2_priv *bus_priv; + uint32_t top_mask_0 = 0; if (!priv || !cmd_args) { CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments"); @@ -3574,6 +3576,14 @@ static int cam_vfe_bus_process_cmd( case CAM_ISP_HW_CMD_UBWC_UPDATE_V2: rc = cam_vfe_bus_update_ubwc_config_v2(cmd_args); break; + case CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ: + bus_priv = (struct cam_vfe_bus_ver2_priv *) priv; + top_mask_0 = cam_io_r_mb(bus_priv->common_data.mem_base + + bus_priv->common_data.common_reg->top_irq_mask_0); + top_mask_0 |= (1 << bus_priv->top_irq_shift); + cam_io_w_mb(top_mask_0, bus_priv->common_data.mem_base + + bus_priv->common_data.common_reg->top_irq_mask_0); + break; default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d", cmd_type); @@ -3624,6 +3634,7 @@ int cam_vfe_bus_ver2_init( bus_priv->num_client = ver2_hw_info->num_client; bus_priv->num_out = ver2_hw_info->num_out; + bus_priv->top_irq_shift = ver2_hw_info->top_irq_shift; bus_priv->common_data.num_sec_out = 0; bus_priv->common_data.secure_mode = CAM_SECURE_MODE_NON_SECURE; bus_priv->common_data.core_index = soc_info->index; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h index fc1608315330..e611113bedd2 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ #ifndef _CAM_VFE_BUS_VER2_H_ @@ -83,6 +83,7 @@ struct cam_vfe_bus_ver2_reg_offset_common { uint32_t addr_sync_no_sync; uint32_t debug_status_cfg; uint32_t debug_status_0; + uint32_t top_irq_mask_0; }; /* @@ -177,6 +178,7 @@ struct cam_vfe_bus_ver2_vfe_out_hw_info { * @bus_client_reg: Bus client register info * @comp_reg_grp: Composite group register info * @vfe_out_hw_info: VFE output capability + * @top_irq_shift: Mask shift for top level BUS WR irq */ struct cam_vfe_bus_ver2_hw_info { struct cam_vfe_bus_ver2_reg_offset_common common_reg; @@ -188,6 +190,7 @@ struct cam_vfe_bus_ver2_hw_info { uint32_t num_out; struct cam_vfe_bus_ver2_vfe_out_hw_info vfe_out_hw_info[CAM_VFE_BUS_VER2_VFE_OUT_MAX]; + uint32_t top_irq_shift; }; /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c index eecd6926cced..87a0b72f1dfc 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c @@ -3693,6 +3693,7 @@ static int cam_vfe_bus_ver3_process_cmd( { int rc = -EINVAL; struct cam_vfe_bus_ver3_priv *bus_priv; + uint32_t top_mask_0 = 0; if (!priv || !cmd_args) { CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid input arguments"); @@ -3729,6 +3730,14 @@ static int cam_vfe_bus_ver3_process_cmd( case CAM_ISP_HW_CMD_WM_CONFIG_UPDATE: rc = cam_vfe_bus_ver3_update_wm_config(cmd_args); break; + case CAM_ISP_HW_CMD_UNMASK_BUS_WR_IRQ: + bus_priv = (struct cam_vfe_bus_ver3_priv *) priv; + top_mask_0 = cam_io_r_mb(bus_priv->common_data.mem_base + + bus_priv->common_data.common_reg->top_irq_mask_0); + top_mask_0 |= (1 << bus_priv->top_irq_shift); + cam_io_w_mb(top_mask_0, bus_priv->common_data.mem_base + + bus_priv->common_data.common_reg->top_irq_mask_0); + break; default: CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d", cmd_type); @@ -3750,6 +3759,7 @@ int cam_vfe_bus_ver3_init( struct cam_vfe_bus *vfe_bus_local; struct cam_vfe_bus_ver3_hw_info *ver3_hw_info = bus_hw_info; struct cam_vfe_soc_private *soc_private = NULL; + static const char rup_controller_name[] = "vfe_bus_rup"; CAM_DBG(CAM_ISP, "Enter"); @@ -3815,7 +3825,7 @@ int cam_vfe_bus_ver3_init( goto free_bus_priv; } - rc = cam_irq_controller_init("vfe_bus_rup", + rc = cam_irq_controller_init(rup_controller_name, bus_priv->common_data.mem_base, &ver3_hw_info->common_reg.irq_reg_info, &bus_priv->common_data.rup_irq_controller, false); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h index c5b4ab69fa9f..f2430c5f2f8e 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. */ @@ -95,6 +95,7 @@ struct cam_vfe_bus_ver3_reg_offset_common { uint32_t debug_status_top_cfg; uint32_t debug_status_top; uint32_t test_bus_ctrl; + uint32_t top_irq_mask_0; struct cam_irq_controller_reg_info irq_reg_info; };