From 5619d4e93e494efe57361e433d0cc3a6ea647f5c Mon Sep 17 00:00:00 2001 From: Venkat Chinta Date: Thu, 19 Dec 2019 15:46:17 -0800 Subject: [PATCH] msm: camera: ife: Unmask top level bus write IRQ bit During VFE reset we mask all bits apart from reset done. Since the top level bus write IRQ bit is common to all output ports it is set during the initialize hardware sequence. However since initialize hardware is not invoked in start only case that follows flush, we must set it again. CRs-Fixed: 2590331 Change-Id: I73f09e552779bd65f472178c1025594be03025fb Signed-off-by: Venkat Chinta --- drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c | 42 ++++++++++++++++++- .../isp_hw_mgr/isp_hw/include/cam_isp_hw.h | 1 + .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c | 1 + .../isp_hw/vfe_hw/vfe17x/cam_vfe170.h | 2 + .../isp_hw/vfe_hw/vfe17x/cam_vfe175.h | 2 + .../isp_hw/vfe_hw/vfe17x/cam_vfe175_130.h | 2 + .../isp_hw/vfe_hw/vfe17x/cam_vfe480.h | 1 + .../isp_hw/vfe_hw/vfe17x/cam_vfe_lite17x.h | 2 + .../isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h | 1 + .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c | 13 +++++- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.h | 5 ++- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c | 12 +++++- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h | 3 +- 13 files changed, 82 insertions(+), 5 deletions(-) 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; };