From 1332b49e26da791e689c41d62cc1c91c6a91774e Mon Sep 17 00:00:00 2001 From: Mukund Madhusudan Atre Date: Wed, 13 May 2020 18:12:33 -0700 Subject: [PATCH] msm: camera: ife: Add support for camera v680 bus This change adds support for Waipio bus hardware. It also changes the bus private structure to be pointer based so that most of the information is filled from hardware specific headers. CRs-Fixed: 2794540 Change-Id: Ie9d30442246a896f372512b62bd54be32c4921ad Signed-off-by: Venkat Chinta Signed-off-by: Mukund Madhusudan Atre --- drivers/cam_isp/cam_isp_context.c | 14 + .../isp_hw/include/cam_vfe_hw_intf.h | 2 + .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h | 9 +- .../isp_hw/vfe_hw/vfe17x/cam_vfe480.h | 100 +- .../isp_hw/vfe_hw/vfe17x/cam_vfe680.h | 30 +- .../isp_hw/vfe_hw/vfe17x/cam_vfe_lite48x.h | 19 + .../isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h | 103 +- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c | 967 +++++++----------- .../isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.h | 11 +- 9 files changed, 639 insertions(+), 616 deletions(-) diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 8fd7cb0d0c43..890520c78e19 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -569,6 +569,20 @@ static const char *__cam_isp_resource_handle_id_to_type( return "RDI_RD"; case CAM_ISP_IFE_OUT_RES_LCR: return "LCR"; + case CAM_ISP_IFE_OUT_RES_AWB_BFW: + return "AWB_BFW"; + case CAM_ISP_IFE_OUT_RES_2PD_STATS: + return "2PD_STATS"; + case CAM_ISP_IFE_OUT_RES_STATS_AEC_BE: + return "STATS_AEC_BE"; + case CAM_ISP_IFE_OUT_RES_LTM_STATS: + return "LTM_STATS"; + case CAM_ISP_IFE_OUT_RES_STATS_GTM_BHIST: + return "STATS_GTM_BHIST"; + case CAM_ISP_IFE_LITE_OUT_RES_STATS_BE: + return "STATS_BE"; + case CAM_ISP_IFE_LITE_OUT_RES_GAMMA: + return "GAMMA"; default: return "CAM_ISP_Invalid_Resource_Type"; } diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h index 1caf997c8f6e..1cb9ec7d8c6e 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_vfe_hw_intf.h @@ -190,6 +190,7 @@ struct cam_vfe_hw_vfe_in_acquire_args { * with this resource. * @priv: Context data * @event_cb: Callback function to hw mgr in case of hw events + * @buf_done_controller: Buf done controller for isp * @vfe_out: Acquire args for VFE_OUT * @vfe_bus_rd Acquire args for VFE_BUS_READ * @vfe_in: Acquire args for VFE_IN @@ -199,6 +200,7 @@ struct cam_vfe_acquire_args { void *tasklet; void *priv; cam_hw_mgr_event_cb_func event_cb; + void *buf_done_controller; union { struct cam_vfe_hw_vfe_out_acquire_args vfe_out; struct cam_vfe_hw_vfe_bus_rd_acquire_args vfe_bus_rd; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h index 43afd0377057..928f01ebcea1 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.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_CORE_H_ @@ -12,6 +12,13 @@ #include "cam_vfe_bus.h" #include "cam_vfe_hw_intf.h" +#define CAM_VFE_HW_IRQ_CAP_SOF 0x1 +#define CAM_VFE_HW_IRQ_CAP_EPOCH_0 0x2 +#define CAM_VFE_HW_IRQ_CAP_EPOCH_1 0x4 +#define CAM_VFE_HW_IRQ_CAP_RUP 0x8 +#define CAM_VFE_HW_IRQ_CAP_BUF_DONE 0x10 +#define CAM_VFE_HW_IRQ_CAP_EOF 0x20 + struct cam_vfe_hw_info { struct cam_irq_controller_reg_info *irq_reg_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 7caa1eea1ee4..b70ad12bb26a 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 @@ -412,7 +412,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .global_clear_bitmask = 0x00000001, }, }, - .num_client = CAM_VFE_BUS_VER3_MAX_CLIENTS, + .num_client = CAM_VFE_BUS_VER3_480_MAX_CLIENTS, .bus_client_reg = { /* BUS Client 0 FULL Y */ { @@ -1177,6 +1177,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_3, .mid[0] = 8, + .num_wm = 1, + .wm_idx = { + 23, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI1, @@ -1184,6 +1188,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_4, .mid[0] = 9, + .num_wm = 1, + .wm_idx = { + 24, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI2, @@ -1191,6 +1199,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_5, .mid[0] = 10, + .num_wm = 1, + .wm_idx = { + 25, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_FULL, @@ -1201,6 +1213,11 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .mid[1] = 33, .mid[2] = 34, .mid[3] = 35, + .num_wm = 2, + .wm_idx = { + 0, + 1, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS4, @@ -1208,6 +1225,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = 1080, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 16, + .num_wm = 1, + .wm_idx = { + 2, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS16, @@ -1215,6 +1236,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = 1080, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 17, + .num_wm = 1, + .wm_idx = { + 3, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP, @@ -1223,6 +1248,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 11, .mid[1] = 12, + .num_wm = 1, + .wm_idx = { + 10, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_FD, @@ -1232,6 +1261,11 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .mid[0] = 20, .mid[1] = 21, .mid[2] = 22, + .num_wm = 2, + .wm_idx = { + 8, + 9, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_PDAF, @@ -1240,6 +1274,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 25, .mid[1] = 26, + .num_wm = 1, + .wm_idx = { + 11, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE, @@ -1247,6 +1285,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 40, + .num_wm = 1, + .wm_idx = { + 12, + } }, { .vfe_out_type = @@ -1255,6 +1297,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = 1080, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 41, + .num_wm = 1, + .wm_idx = { + 13, + } }, { .vfe_out_type = @@ -1263,6 +1309,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 42, + .num_wm = 1, + .wm_idx = { + 14, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF, @@ -1270,6 +1320,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 43, + .num_wm = 1, + .wm_idx = { + 20, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG, @@ -1277,6 +1331,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 44, + .num_wm = 1, + .wm_idx = { + 15, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST, @@ -1284,6 +1342,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 45, + .num_wm = 1, + .wm_idx = { + 16, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS, @@ -1291,6 +1353,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 46, + .num_wm = 1, + .wm_idx = { + 17, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS, @@ -1298,6 +1364,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 47, + .num_wm = 1, + .wm_idx = { + 18, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST, @@ -1305,6 +1375,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 48, + .num_wm = 1, + .wm_idx = { + 19, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP, @@ -1315,6 +1389,11 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .mid[1] = 37, .mid[2] = 38, .mid[3] = 39, + .num_wm = 2, + .wm_idx = { + 4, + 5, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP, @@ -1322,6 +1401,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = 1080, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 18, + .num_wm = 1, + .wm_idx = { + 6, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP, @@ -1329,6 +1412,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = 1080, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 19, + .num_wm = 1, + .wm_idx = { + 7, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_2PD, @@ -1337,6 +1424,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .source_group = CAM_VFE_BUS_VER3_SRC_GRP_1, .mid[0] = 23, .mid[1] = 24, + .num_wm = 1, + .wm_idx = { + 21, + } }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_LCR, @@ -1344,12 +1435,19 @@ static struct cam_vfe_bus_ver3_hw_info vfe480_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_2, .mid[0] = 27, + .num_wm = 1, + .wm_idx = { + 22, + } }, }, + .num_comp_grp = 14, .comp_done_shift = 6, .top_irq_shift = 7, .support_consumed_addr = true, .max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 25, + .supported_irq = CAM_VFE_HW_IRQ_CAP_BUF_DONE | CAM_VFE_HW_IRQ_CAP_RUP, + .comp_cfg_needed = true, }; static struct cam_irq_register_set vfe480_bus_rd_irq_reg[1] = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h index 2883d9ca6907..2f2fb4cb667e 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h @@ -1026,7 +1026,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = { .ubwc_regs = NULL, }, }, - .num_out = 25, + .num_out = 27, .vfe_out_hw_info = { { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI0, @@ -1179,7 +1179,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = { .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .num_wm = 1, .wm_idx = { - 17, + 12, }, }, { @@ -1273,6 +1273,16 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = { 22, }, }, + { + .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE, + .max_width = -1, + .max_height = -1, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, + .num_wm = 1, + .wm_idx = { + 11, + }, + }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS, .max_width = -1, @@ -1283,9 +1293,21 @@ static struct cam_vfe_bus_ver3_hw_info vfe680_bus_hw_info = { 27, }, }, + { + .vfe_out_type = + CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST, + .max_width = 1920, + .max_height = 1080, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, + .num_wm = 1, + .wm_idx = { + 17, + }, + }, }, - .comp_done_shift = 6, - .top_irq_shift = 7, + .num_comp_grp = 17, + .comp_done_shift = 0, + .top_irq_shift = 1, .max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 33, }; 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 c118c8020292..3f1efb1a70e7 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 @@ -374,6 +374,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, .mid[0] = 16, + .num_wm = 1, + .wm_idx = { + 0, + }, }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI1, @@ -381,6 +385,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_1, .mid[0] = 17, + .num_wm = 1, + .wm_idx = { + 1, + }, }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI2, @@ -388,6 +396,10 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_2, .mid[0] = 18, + .num_wm = 1, + .wm_idx = { + 2, + }, }, { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI3, @@ -395,12 +407,19 @@ static struct cam_vfe_bus_ver3_hw_info vfe48x_bus_hw_info = { .max_height = -1, .source_group = CAM_VFE_BUS_VER3_SRC_GRP_3, .mid[0] = 19, + .num_wm = 1, + .wm_idx = { + 3, + }, }, }, + .num_comp_grp = 4, .comp_done_shift = 4, .top_irq_shift = 4, .support_consumed_addr = true, .max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 25, + .supported_irq = CAM_VFE_HW_IRQ_CAP_BUF_DONE | CAM_VFE_HW_IRQ_CAP_RUP, + .comp_cfg_needed = true, }; static struct cam_vfe_hw_info cam_vfe_lite48x_hw_info = { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h index 1c53bf79e04f..b16857e91c58 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe_lite68x.h @@ -35,7 +35,6 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { 0x0000023C, 0x00000240, 0x00000244, - 0x00000248, }, .pwr_iso_cfg = 0x0000025C, .overflow_status_clear = 0x00000260, @@ -52,7 +51,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .global_clear_bitmask = 0x00000001, }, }, - .num_client = 4, + .num_client = 6, .bus_client_reg = { /* BUS Client 0 RDI0 */ { @@ -80,7 +79,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .debug_status_cfg = 0x00000480, .debug_status_0 = 0x00000484, .debug_status_1 = 0x00000488, - .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0, + .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1, .ubwc_regs = NULL, }, /* BUS Client 1 RDI1 */ @@ -109,7 +108,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .debug_status_cfg = 0x00000580, .debug_status_0 = 0x00000584, .debug_status_1 = 0x00000588, - .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_1, + .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_2, .ubwc_regs = NULL, }, /* BUS Client 2 RDI2 */ @@ -138,7 +137,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .debug_status_cfg = 0x00000680, .debug_status_0 = 0x00000684, .debug_status_1 = 0x00000688, - .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_2, + .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_3, .ubwc_regs = NULL, }, /* BUS Client 3 RDI3 */ @@ -167,17 +166,75 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .debug_status_cfg = 0x00000780, .debug_status_0 = 0x00000784, .debug_status_1 = 0x00000788, - .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_3, + .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_4, .ubwc_regs = NULL, }, + /* BUS Client 4 Gamma */ + { + .cfg = 0x00000800, + .image_addr = 0x00000804, + .frame_incr = 0x00000808, + .image_cfg_0 = 0x0000080C, + .image_cfg_1 = 0x00000810, + .image_cfg_2 = 0x00000814, + .packer_cfg = 0x00000818, + .frame_header_addr = 0x00000820, + .frame_header_incr = 0x00000824, + .frame_header_cfg = 0x00000828, + .irq_subsample_period = 0x00000830, + .irq_subsample_pattern = 0x00000834, + .framedrop_period = 0x00000838, + .framedrop_pattern = 0x0000083C, + .mmu_prefetch_cfg = 0x00000860, + .mmu_prefetch_max_offset = 0x00000864, + .system_cache_cfg = 0x00000868, + .addr_status_0 = 0x00000870, + .addr_status_1 = 0x00000874, + .addr_status_2 = 0x00000878, + .addr_status_3 = 0x0000087C, + .debug_status_cfg = 0x00000880, + .debug_status_0 = 0x00000884, + .debug_status_1 = 0x00000888, + .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0, + .ubwc_regs = NULL, + }, + /* BUS Client 5 Stats BE */ + { + .cfg = 0x00000900, + .image_addr = 0x00000904, + .frame_incr = 0x00000908, + .image_cfg_0 = 0x0000090C, + .image_cfg_1 = 0x00000910, + .image_cfg_2 = 0x00000914, + .packer_cfg = 0x00000918, + .frame_header_addr = 0x00000920, + .frame_header_incr = 0x00000924, + .frame_header_cfg = 0x00000928, + .irq_subsample_period = 0x00000930, + .irq_subsample_pattern = 0x00000934, + .framedrop_period = 0x00000938, + .framedrop_pattern = 0x0000093C, + .mmu_prefetch_cfg = 0x00000960, + .mmu_prefetch_max_offset = 0x00000964, + .system_cache_cfg = 0x00000968, + .addr_status_0 = 0x00000970, + .addr_status_1 = 0x00000974, + .addr_status_2 = 0x00000978, + .addr_status_3 = 0x0000097C, + .debug_status_cfg = 0x00000980, + .debug_status_0 = 0x00000984, + .debug_status_1 = 0x00000988, + .comp_group = CAM_VFE_BUS_VER3_COMP_GRP_0, + .ubwc_regs = NULL, + }, }, - .num_out = 4, + .num_out = 6, .vfe_out_hw_info = { { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI0, .max_width = -1, .max_height = -1, - .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_1, .num_wm = 1, .wm_idx = { 0, @@ -187,7 +244,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI1, .max_width = -1, .max_height = -1, - .source_group = CAM_VFE_BUS_VER3_SRC_GRP_1, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_2, .num_wm = 1, .wm_idx = { 1, @@ -197,7 +254,7 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI2, .max_width = -1, .max_height = -1, - .source_group = CAM_VFE_BUS_VER3_SRC_GRP_2, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_3, .num_wm = 1, .wm_idx = { 2, @@ -207,14 +264,36 @@ static struct cam_vfe_bus_ver3_hw_info vfe680x_bus_hw_info = { .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_RDI3, .max_width = -1, .max_height = -1, - .source_group = CAM_VFE_BUS_VER3_SRC_GRP_3, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_4, .num_wm = 1, .wm_idx = { 3, }, }, + { + .vfe_out_type = + CAM_VFE_BUS_VER3_VFE_OUT_GAMMA, + .max_width = 1920, + .max_height = 1080, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, + .num_wm = 1, + .wm_idx = { + 4, + }, + }, + { + .vfe_out_type = CAM_VFE_BUS_VER3_VFE_OUT_STATS_BE, + .max_width = -1, + .max_height = -1, + .source_group = CAM_VFE_BUS_VER3_SRC_GRP_0, + .num_wm = 1, + .wm_idx = { + 5, + }, + }, }, - .comp_done_shift = 6, + .num_comp_grp = 4, + .comp_done_shift = 0, .top_irq_shift = 1, .max_out_res = CAM_ISP_IFE_OUT_RES_BASE + 33, }; 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 4202fbfe17b2..5fa123654ef8 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 @@ -42,7 +42,7 @@ static const char drv_name[] = "vfe_bus"; (MAX_BUF_UPDATE_REG_NUM * 2 * CAM_PACKET_MAX_PLANES) static uint32_t bus_error_irq_mask[2] = { - 0xC0000000, + 0xD0000000, 0x00000000, }; @@ -62,6 +62,11 @@ enum cam_vfe_bus_ver3_packer_format { PACKER_FMT_VER3_MAX, }; +struct cam_vfe_bus_ver3_comp_grp_acquire_args { + enum cam_vfe_bus_ver3_comp_grp_type comp_grp_id; + uint32_t composite_mask; +}; + struct cam_vfe_bus_error_info { uint32_t bitmask; uint32_t vfe_output; @@ -75,6 +80,7 @@ struct cam_vfe_bus_ver3_common_data { void *bus_irq_controller; void *rup_irq_controller; void *vfe_irq_controller; + void *buf_done_controller; struct cam_vfe_bus_ver3_reg_offset_common *common_reg; uint32_t io_buf_update[ MAX_REG_VAL_PAIR_SIZE]; @@ -88,6 +94,8 @@ struct cam_vfe_bus_ver3_common_data { uint32_t num_sec_out; uint32_t addr_no_sync; uint32_t comp_done_shift; + uint32_t supported_irq; + bool comp_config_needed; bool is_lite; bool hw_init; bool support_consumed_addr; @@ -162,7 +170,7 @@ struct cam_vfe_bus_ver3_vfe_out_data { struct cam_vfe_bus_ver3_priv *bus_priv; uint32_t num_wm; - struct cam_isp_resource_node *wm_res[PLANE_MAX]; + struct cam_isp_resource_node *wm_res; struct cam_isp_resource_node *comp_grp; enum cam_isp_hw_sync_mode dual_comp_sync_mode; @@ -185,11 +193,12 @@ struct cam_vfe_bus_ver3_priv { struct cam_vfe_bus_ver3_common_data common_data; uint32_t num_client; uint32_t num_out; + uint32_t num_comp_grp; uint32_t top_irq_shift; - struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER3_MAX_CLIENTS]; - struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER3_COMP_GRP_MAX]; - struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER3_VFE_OUT_MAX]; + struct cam_isp_resource_node *bus_client; + struct cam_isp_resource_node *comp_grp; + struct cam_isp_resource_node *vfe_out; struct list_head free_comp_grp; struct list_head used_comp_grp; @@ -606,477 +615,122 @@ static enum cam_vfe_bus_ver3_vfe_out_type return CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP; case CAM_ISP_IFE_OUT_RES_LCR: return CAM_VFE_BUS_VER3_VFE_OUT_LCR; + case CAM_ISP_IFE_OUT_RES_AWB_BFW: + return CAM_VFE_BUS_VER3_VFE_OUT_AWB_BFW; + case CAM_ISP_IFE_OUT_RES_2PD_STATS: + return CAM_VFE_BUS_VER3_VFE_OUT_2PD_STATS; + case CAM_ISP_IFE_OUT_RES_STATS_AEC_BE: + return CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE; + case CAM_ISP_IFE_OUT_RES_LTM_STATS: + return CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS; + case CAM_ISP_IFE_OUT_RES_STATS_GTM_BHIST: + return CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST; + case CAM_ISP_IFE_LITE_OUT_RES_STATS_BE: + return CAM_VFE_BUS_VER3_VFE_OUT_STATS_BE; + case CAM_ISP_IFE_LITE_OUT_RES_GAMMA: + return CAM_VFE_BUS_VER3_VFE_OUT_GAMMA; default: return CAM_VFE_BUS_VER3_VFE_OUT_MAX; } } -static int cam_vfe_bus_ver3_get_num_wm( - enum cam_vfe_bus_ver3_vfe_out_type res_type, - uint32_t format) -{ - switch (res_type) { - case CAM_VFE_BUS_VER3_VFE_OUT_RDI0: - case CAM_VFE_BUS_VER3_VFE_OUT_RDI1: - case CAM_VFE_BUS_VER3_VFE_OUT_RDI2: - case CAM_VFE_BUS_VER3_VFE_OUT_RDI3: - switch (format) { - case CAM_FORMAT_MIPI_RAW_8: - case CAM_FORMAT_MIPI_RAW_10: - case CAM_FORMAT_MIPI_RAW_12: - case CAM_FORMAT_MIPI_RAW_14: - case CAM_FORMAT_MIPI_RAW_16: - case CAM_FORMAT_MIPI_RAW_20: - case CAM_FORMAT_DPCM_10_6_10: - case CAM_FORMAT_DPCM_10_8_10: - case CAM_FORMAT_DPCM_12_6_12: - case CAM_FORMAT_DPCM_12_8_12: - case CAM_FORMAT_DPCM_14_8_14: - case CAM_FORMAT_DPCM_14_10_14: - case CAM_FORMAT_PLAIN8: - case CAM_FORMAT_PLAIN16_10: - case CAM_FORMAT_PLAIN16_12: - case CAM_FORMAT_PLAIN16_14: - case CAM_FORMAT_PLAIN16_16: - case CAM_FORMAT_PLAIN32_20: - case CAM_FORMAT_PLAIN128: - return 1; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_FULL: - case CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP: - switch (format) { - case CAM_FORMAT_NV21: - case CAM_FORMAT_NV12: - case CAM_FORMAT_MIPI_RAW_8: - case CAM_FORMAT_PLAIN8: - case CAM_FORMAT_TP10: - case CAM_FORMAT_UBWC_NV12: - case CAM_FORMAT_UBWC_NV12_4R: - case CAM_FORMAT_UBWC_TP10: - case CAM_FORMAT_UBWC_P010: - case CAM_FORMAT_PLAIN16_10: - return 2; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_FD: - switch (format) { - case CAM_FORMAT_NV21: - case CAM_FORMAT_NV12: - case CAM_FORMAT_PLAIN8: - case CAM_FORMAT_TP10: - case CAM_FORMAT_PLAIN16_10: - return 2; - case CAM_FORMAT_Y_ONLY: - return 1; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_DS4: - case CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP: - case CAM_VFE_BUS_VER3_VFE_OUT_DS16: - case CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP: - switch (format) { - case CAM_FORMAT_PD8: - case CAM_FORMAT_PD10: - return 1; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP: - switch (format) { - case CAM_FORMAT_ARGB_14: - case CAM_FORMAT_PLAIN8: - case CAM_FORMAT_PLAIN16_10: - case CAM_FORMAT_PLAIN16_12: - case CAM_FORMAT_PLAIN16_14: - return 1; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_2PD: - switch (format) { - case CAM_FORMAT_PLAIN16_8: - case CAM_FORMAT_PLAIN16_10: - case CAM_FORMAT_PLAIN16_12: - case CAM_FORMAT_PLAIN16_14: - case CAM_FORMAT_PLAIN16_16: - case CAM_FORMAT_PLAIN64: - return 1; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE: - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BHIST: - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_TL_BG: - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF: - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG: - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST: - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS: - switch (format) { - case CAM_FORMAT_PLAIN64: - return 1; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS: - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST: - switch (format) { - case CAM_FORMAT_PLAIN16_16: - return 1; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_LCR: - return 1; - default: - break; - } - - CAM_ERR(CAM_ISP, "Unsupported format %u for out_type:0x%X", - format, res_type); - - return -EINVAL; -} - -static int cam_vfe_bus_ver3_get_wm_idx( - enum cam_vfe_bus_ver3_vfe_out_type vfe_out_res_id, - enum cam_vfe_bus_plane_type plane, - bool is_lite) -{ - int wm_idx = -1; - - switch (vfe_out_res_id) { - case CAM_VFE_BUS_VER3_VFE_OUT_RDI0: - switch (plane) { - case PLANE_Y: - if (is_lite) - wm_idx = 0; - else - wm_idx = 23; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_RDI1: - switch (plane) { - case PLANE_Y: - if (is_lite) - wm_idx = 1; - else - wm_idx = 24; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_RDI2: - switch (plane) { - case PLANE_Y: - if (is_lite) - wm_idx = 2; - else - wm_idx = 25; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_RDI3: - switch (plane) { - case PLANE_Y: - wm_idx = 3; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_FULL: - switch (plane) { - case PLANE_Y: - wm_idx = 0; - break; - case PLANE_C: - wm_idx = 1; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_DS4: - switch (plane) { - case PLANE_Y: - wm_idx = 2; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_DS16: - switch (plane) { - case PLANE_Y: - wm_idx = 3; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_FD: - switch (plane) { - case PLANE_Y: - wm_idx = 8; - break; - case PLANE_C: - wm_idx = 9; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP: - switch (plane) { - case PLANE_Y: - wm_idx = 10; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_2PD: - switch (plane) { - case PLANE_Y: - wm_idx = 21; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE: - switch (plane) { - case PLANE_Y: - wm_idx = 12; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BHIST: - switch (plane) { - case PLANE_Y: - wm_idx = 13; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_TL_BG: - switch (plane) { - case PLANE_Y: - wm_idx = 14; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF: - switch (plane) { - case PLANE_Y: - wm_idx = 20; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG: - switch (plane) { - case PLANE_Y: - wm_idx = 15; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST: - switch (plane) { - case PLANE_Y: - wm_idx = 16; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS: - switch (plane) { - case PLANE_Y: - wm_idx = 17; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS: - switch (plane) { - case PLANE_Y: - wm_idx = 18; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST: - switch (plane) { - case PLANE_Y: - wm_idx = 19; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP: - switch (plane) { - case PLANE_Y: - wm_idx = 4; - break; - case PLANE_C: - wm_idx = 5; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP: - switch (plane) { - case PLANE_Y: - wm_idx = 6; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP: - switch (plane) { - case PLANE_Y: - wm_idx = 7; - break; - default: - break; - } - break; - case CAM_VFE_BUS_VER3_VFE_OUT_LCR: - switch (plane) { - case PLANE_Y: - wm_idx = 22; - break; - default: - break; - } - default: - break; - } - - return wm_idx; -} - static int cam_vfe_bus_ver3_get_comp_vfe_out_res_id_list( - uint32_t comp_mask, uint32_t *out_list, int *num_out, bool is_lite) + uint32_t comp_mask, uint32_t *out_list, int *num_out) { int count = 0; - if (is_lite) - goto vfe_lite; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI0)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_0; - if (comp_mask & 0x3) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI1)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_1; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI2)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_2; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RDI3)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_3; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_FULL)) out_list[count++] = CAM_ISP_IFE_OUT_RES_FULL; - if (comp_mask & 0x4) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_DS4)) out_list[count++] = CAM_ISP_IFE_OUT_RES_DS4; - if (comp_mask & 0x8) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_DS16)) out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16; - if (comp_mask & 0x30) - out_list[count++] = CAM_ISP_IFE_OUT_RES_FULL_DISP; - - if (comp_mask & 0x40) - out_list[count++] = CAM_ISP_IFE_OUT_RES_DS4_DISP; - - if (comp_mask & 0x80) - out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16_DISP; - - if (comp_mask & 0x300) - out_list[count++] = CAM_ISP_IFE_OUT_RES_FD; - - if (comp_mask & 0x400) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP)) out_list[count++] = CAM_ISP_IFE_OUT_RES_RAW_DUMP; - if (comp_mask & 0x1000) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_FD)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_FD; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_PDAF)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_PDAF; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE)) out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_HDR_BE; - if (comp_mask & 0x2000) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BHIST)) out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST; - if (comp_mask & 0x4000) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_TL_BG)) out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_TL_BG; - if (comp_mask & 0x8000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_AWB_BG; - - if (comp_mask & 0x10000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BHIST; - - if (comp_mask & 0x20000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_RS; - - if (comp_mask & 0x40000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_CS; - - if (comp_mask & 0x80000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_IHIST; - - if (comp_mask & 0x100000) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF)) out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BF; - if (comp_mask & 0x200000) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_AWB_BG)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_AWB_BG; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_BHIST)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_BHIST; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_RS)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_RS; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_CS)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_CS; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_IHIST; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_FULL_DISP; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_DS4_DISP; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16_DISP; + + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_2PD)) out_list[count++] = CAM_ISP_IFE_OUT_RES_2PD; - if (comp_mask & 0x400000) + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_LCR)) out_list[count++] = CAM_ISP_IFE_OUT_RES_LCR; - if (comp_mask & 0x800000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_0; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_AWB_BFW)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_AWB_BFW; - if (comp_mask & 0x1000000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_1; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_2PD_STATS)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_2PD_STATS; - if (comp_mask & 0x2000000) - out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_2; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_AEC_BE; - *num_out = count; - return 0; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_LTM_STATS; -vfe_lite: - if (comp_mask & 0x1) - out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_0; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST)) + out_list[count++] = CAM_ISP_IFE_OUT_RES_STATS_GTM_BHIST; - if (comp_mask & 0x2) - out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_1; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_STATS_BE)) + out_list[count++] = CAM_ISP_IFE_LITE_OUT_RES_STATS_BE; - if (comp_mask & 0x4) - out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_2; - - if (comp_mask & 0x8) - out_list[count++] = CAM_ISP_IFE_OUT_RES_RDI_3; + if (comp_mask & (1 << CAM_VFE_BUS_VER3_VFE_OUT_GAMMA)) + out_list[count++] = CAM_ISP_IFE_LITE_OUT_RES_GAMMA; *num_out = count; return 0; @@ -1347,39 +1001,26 @@ static int cam_vfe_bus_ver3_acquire_wm( void *tasklet, enum cam_vfe_bus_ver3_vfe_out_type vfe_out_res_id, enum cam_vfe_bus_plane_type plane, - struct cam_isp_resource_node **wm_res, - uint32_t *client_done_mask, + struct cam_isp_resource_node *wm_res, uint32_t is_dual, enum cam_vfe_bus_ver3_comp_grp_type *comp_grp_id) { int32_t wm_idx = 0; - struct cam_isp_resource_node *wm_res_local = NULL; struct cam_vfe_bus_ver3_wm_resource_data *rsrc_data = NULL; + char wm_mode[50]; - *wm_res = NULL; + memset(wm_mode, '\0', sizeof(wm_mode)); - /* VFE OUT to WM is fixed. */ - wm_idx = cam_vfe_bus_ver3_get_wm_idx(vfe_out_res_id, plane, - ver3_bus_priv->common_data.is_lite); - if (wm_idx < 0 || wm_idx >= ver3_bus_priv->num_client || - plane > PLANE_C) { - CAM_ERR(CAM_ISP, - "Unsupported VFE out_type:0x%X plane:%d wm_idx:%d max_idx:%d", - vfe_out_res_id, plane, wm_idx, - ver3_bus_priv->num_client - 1); - return -EINVAL; - } - - wm_res_local = &ver3_bus_priv->bus_client[wm_idx]; - if (wm_res_local->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) { + if (wm_res->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) { CAM_ERR(CAM_ISP, "WM:%d not available state:%d", - wm_idx, wm_res_local->res_state); + wm_idx, wm_res->res_state); return -EALREADY; } - wm_res_local->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; - wm_res_local->tasklet_info = tasklet; + wm_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + wm_res->tasklet_info = tasklet; - rsrc_data = wm_res_local->res_priv; + rsrc_data = wm_res->res_priv; + wm_idx = rsrc_data->index; rsrc_data->format = out_port_info->format; rsrc_data->pack_fmt = cam_vfe_bus_ver3_get_packer_fmt(rsrc_data->format, wm_idx); @@ -1394,9 +1035,10 @@ static int cam_vfe_bus_ver3_acquire_wm( CAM_DBG(CAM_ISP, "WM:%d width %d height %d", rsrc_data->index, rsrc_data->width, rsrc_data->height); - if (ver3_bus_priv->common_data.is_lite || (rsrc_data->index > 22)) { + if ((vfe_out_res_id >= CAM_VFE_BUS_VER3_VFE_OUT_RDI0) && + (vfe_out_res_id <= CAM_VFE_BUS_VER3_VFE_OUT_RDI3)) { + rsrc_data->pack_fmt = 0x0; - /* WM 23-25 refers to RDI 0/ RDI 1/RDI 2 */ switch (rsrc_data->format) { case CAM_FORMAT_MIPI_RAW_6: case CAM_FORMAT_MIPI_RAW_8: @@ -1434,13 +1076,18 @@ static int cam_vfe_bus_ver3_acquire_wm( rsrc_data->format); return -EINVAL; } - } else if ((rsrc_data->index < 2) || - (rsrc_data->index == 8) || (rsrc_data->index == 9) || - (rsrc_data->index == 4) || (rsrc_data->index == 5)) { - /* - * WM 0-1 FULL_OUT, WM 8-9 FD_OUT, - * WM 4-5 FULL_DISP - */ + + } else if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_RAW_DUMP) { + + rsrc_data->stride = rsrc_data->width; + rsrc_data->en_cfg = 0x1; + /* LSB aligned */ + rsrc_data->pack_fmt |= 0x10; + + } else if ((vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_FULL) || + (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_FD) || + (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_FULL_DISP)) { + switch (rsrc_data->format) { case CAM_FORMAT_UBWC_NV12_4R: rsrc_data->en_ubwc = 1; @@ -1510,33 +1157,33 @@ static int cam_vfe_bus_ver3_acquire_wm( } break; default: - CAM_ERR(CAM_ISP, "Invalid format %d", - rsrc_data->format); + CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d", + rsrc_data->format, vfe_out_res_id); return -EINVAL; } rsrc_data->en_cfg = 0x1; - } else if (rsrc_data->index == 20) { - /* WM 20 stats BAF */ + + } else if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_STATS_BF) { + rsrc_data->en_cfg = (0x1 << 16) | 0x1; - } else if (rsrc_data->index > 11 && rsrc_data->index < 20) { - /* WM 12-19 stats */ + + } else if ((vfe_out_res_id >= CAM_VFE_BUS_VER3_VFE_OUT_STATS_HDR_BE) && + (vfe_out_res_id <= CAM_VFE_BUS_VER3_VFE_OUT_STATS_IHIST)) { + rsrc_data->width = 0; rsrc_data->height = 0; rsrc_data->stride = 1; rsrc_data->en_cfg = (0x1 << 16) | 0x1; - } else if (rsrc_data->index == 21) { - /* WM 21 PD */ + + } else if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_2PD) { + rsrc_data->width = 0; rsrc_data->height = 0; rsrc_data->stride = 1; rsrc_data->en_cfg = (0x1 << 16) | 0x1; - } else if (rsrc_data->index == 10) { - /* WM 10 Raw dump */ - rsrc_data->stride = rsrc_data->width; - rsrc_data->en_cfg = 0x1; - /* LSB aligned */ - rsrc_data->pack_fmt |= 0x10; - } else if (rsrc_data->index == 22) { + + } else if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_LCR) { + switch (rsrc_data->format) { case CAM_FORMAT_PLAIN16_16: rsrc_data->stride = ALIGNUP(rsrc_data->width * 2, 8); @@ -1545,32 +1192,114 @@ static int cam_vfe_bus_ver3_acquire_wm( rsrc_data->pack_fmt |= 0x10; break; default: - CAM_ERR(CAM_ISP, "Invalid format %d", - rsrc_data->format); + CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d", + rsrc_data->format, vfe_out_res_id); return -EINVAL; } - } else if ((rsrc_data->index == 2) || (rsrc_data->index == 3) || - (rsrc_data->index == 6) || (rsrc_data->index == 7)) { - /* Write master 2-3 and 6-7 DS ports */ + + } else if ((vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_DS4) || + (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_DS16) || + (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_DS4_DISP) || + (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_DS16_DISP)) { rsrc_data->height = rsrc_data->height / 2; rsrc_data->width = rsrc_data->width / 2; rsrc_data->en_cfg = 0x1; + } else if ((vfe_out_res_id >= CAM_VFE_BUS_VER3_VFE_OUT_AWB_BFW) && + (vfe_out_res_id <= CAM_VFE_BUS_VER3_VFE_OUT_2PD_STATS)) { + switch (rsrc_data->format) { + case CAM_FORMAT_PLAIN64: + rsrc_data->width = 0; + rsrc_data->height = 0; + rsrc_data->stride = 1; + rsrc_data->en_cfg = (0x1 << 16) | 0x1; + break; + default: + CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d", + rsrc_data->format, vfe_out_res_id); + return -EINVAL; + } + + } else if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS) { + switch (rsrc_data->format) { + case CAM_FORMAT_PLAIN32: + rsrc_data->width = 0; + rsrc_data->height = 0; + rsrc_data->stride = 1; + rsrc_data->en_cfg = (0x1 << 16) | 0x1; + break; + default: + CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d", + rsrc_data->format, vfe_out_res_id); + return -EINVAL; + } + + } else if ((vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE) || + (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST)) { + rsrc_data->width = 0; + rsrc_data->height = 0; + rsrc_data->stride = 1; + rsrc_data->en_cfg = (0x1 << 16) | 0x1; + } else if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_STATS_BE) { + switch (rsrc_data->format) { + case CAM_FORMAT_MIPI_RAW_8: + case CAM_FORMAT_MIPI_RAW_10: + case CAM_FORMAT_MIPI_RAW_12: + case CAM_FORMAT_PLAIN8: + case CAM_FORMAT_PLAIN16_8: + case CAM_FORMAT_PLAIN16_10: + case CAM_FORMAT_PLAIN16_12: + rsrc_data->width = 0; + rsrc_data->height = 0; + rsrc_data->stride = 1; + rsrc_data->en_cfg = (0x1 << 16) | 0x1; + break; + default: + CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d", + rsrc_data->format, vfe_out_res_id); + return -EINVAL; + } + + } else if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_GAMMA) { + switch (rsrc_data->format) { + case CAM_FORMAT_PLAIN64: + rsrc_data->width = 0; + rsrc_data->height = 0; + rsrc_data->stride = 1; + rsrc_data->en_cfg = (0x1 << 16) | 0x1; + break; + default: + CAM_ERR(CAM_ISP, "Invalid format %d out_type:%d", + rsrc_data->format, vfe_out_res_id); + return -EINVAL; + } + } else { - CAM_ERR(CAM_ISP, "Invalid WM:%d requested", rsrc_data->index); + CAM_ERR(CAM_ISP, "Invalid out_type:%d requested", + vfe_out_res_id); return -EINVAL; } - *wm_res = wm_res_local; *comp_grp_id = rsrc_data->hw_regs->comp_group; - *client_done_mask |= (1 << wm_idx); + + switch (rsrc_data->en_cfg) { + case 0x1: + strlcpy(wm_mode, "line-based", sizeof(wm_mode)); + break; + case ((0x1 << 16) | 0x1): + strlcpy(wm_mode, "frame-based", sizeof(wm_mode)); + break; + case ((0x2 << 16) | 0x1): + strlcpy(wm_mode, "index-based", sizeof(wm_mode)); + break; + } CAM_DBG(CAM_ISP, - "VFE:%d WM:%d processed width:%d height:%d format:0x%X en_ubwc:%d", + "VFE:%d WM:%d processed width:%d height:%d format:0x%X en_ubwc:%d %s", rsrc_data->common_data->core_index, rsrc_data->index, rsrc_data->width, rsrc_data->height, rsrc_data->format, - rsrc_data->en_ubwc); + rsrc_data->en_ubwc, wm_mode); return 0; } @@ -1758,15 +1487,6 @@ static int cam_vfe_bus_ver3_deinit_wm_resource( return 0; } -static void cam_vfe_bus_ver3_add_wm_to_comp_grp( - struct cam_isp_resource_node *comp_grp, - uint32_t composite_mask) -{ - struct cam_vfe_bus_ver3_comp_grp_data *rsrc_data = comp_grp->res_priv; - - rsrc_data->composite_mask |= composite_mask; -} - static bool cam_vfe_bus_ver3_match_comp_grp( struct cam_vfe_bus_ver3_priv *ver3_bus_priv, struct cam_isp_resource_node **comp_grp, @@ -1804,28 +1524,24 @@ static bool cam_vfe_bus_ver3_match_comp_grp( static int cam_vfe_bus_ver3_acquire_comp_grp( struct cam_vfe_bus_ver3_priv *ver3_bus_priv, - struct cam_isp_out_port_generic_info *out_port_info, void *tasklet, uint32_t is_dual, uint32_t is_master, - enum cam_vfe_bus_ver3_vfe_core_id dual_slave_core, struct cam_isp_resource_node **comp_grp, - enum cam_vfe_bus_ver3_comp_grp_type comp_grp_id) + struct cam_vfe_bus_ver3_comp_grp_acquire_args *comp_acq_args) { int rc = 0; struct cam_isp_resource_node *comp_grp_local = NULL; struct cam_vfe_bus_ver3_comp_grp_data *rsrc_data = NULL; bool previously_acquired = false; - if (comp_grp_id >= CAM_VFE_BUS_VER3_COMP_GRP_0 && - comp_grp_id <= CAM_VFE_BUS_VER3_COMP_GRP_13) { - /* Check if matching comp_grp has already been acquired */ - previously_acquired = cam_vfe_bus_ver3_match_comp_grp( - ver3_bus_priv, &comp_grp_local, comp_grp_id); - } + /* Check if matching comp_grp has already been acquired */ + previously_acquired = cam_vfe_bus_ver3_match_comp_grp( + ver3_bus_priv, &comp_grp_local, comp_acq_args->comp_grp_id); if (!comp_grp_local) { - CAM_ERR(CAM_ISP, "Invalid comp_grp:%d", comp_grp_id); + CAM_ERR(CAM_ISP, "Invalid comp_grp:%d", + comp_acq_args->comp_grp_id); return -ENODEV; } @@ -1860,6 +1576,7 @@ static int cam_vfe_bus_ver3_acquire_comp_grp( rsrc_data->common_data->core_index, rsrc_data->comp_grp_type); rsrc_data->acquire_dev_cnt++; + rsrc_data->composite_mask |= comp_acq_args->composite_mask; *comp_grp = comp_grp_local; return rc; @@ -1944,6 +1661,9 @@ static int cam_vfe_bus_ver3_start_comp_grp( if (comp_grp->res_state == CAM_ISP_RESOURCE_STATE_STREAMING) return 0; + if (!common_data->comp_config_needed) + goto skip_comp_cfg; + if (rsrc_data->is_dual) { if (rsrc_data->is_master) { val = cam_io_r_mb(common_data->mem_base + @@ -1981,6 +1701,8 @@ static int cam_vfe_bus_ver3_start_comp_grp( } } +skip_comp_cfg: + if (rsrc_data->ubwc_static_ctrl) { val = cam_io_r_mb(common_data->mem_base + common_data->common_reg->ubwc_static_ctrl); @@ -2151,15 +1873,13 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, int i; enum cam_vfe_bus_ver3_vfe_out_type vfe_out_res_id; uint32_t format; - int num_wm; struct cam_vfe_bus_ver3_priv *ver3_bus_priv = bus_priv; struct cam_vfe_acquire_args *acq_args = acquire_args; struct cam_vfe_hw_vfe_out_acquire_args *out_acquire_args; struct cam_isp_resource_node *rsrc_node = NULL; struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = NULL; uint32_t secure_caps = 0, mode; - enum cam_vfe_bus_ver3_comp_grp_type comp_grp_id; - uint32_t client_done_mask = 0; + struct cam_vfe_bus_ver3_comp_grp_acquire_args comp_acq_args = {0}; if (!bus_priv || !acquire_args) { CAM_ERR(CAM_ISP, "Invalid Param"); @@ -2178,10 +1898,6 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, if (vfe_out_res_id == CAM_VFE_BUS_VER3_VFE_OUT_MAX) return -ENODEV; - num_wm = cam_vfe_bus_ver3_get_num_wm(vfe_out_res_id, format); - if (num_wm < 1) - return -EINVAL; - rsrc_node = &ver3_bus_priv->vfe_out[vfe_out_res_id]; if (rsrc_node->res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) { CAM_ERR(CAM_ISP, @@ -2195,6 +1911,16 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, rsrc_data->common_data->event_cb = acq_args->event_cb; rsrc_data->priv = acq_args->priv; rsrc_data->bus_priv = ver3_bus_priv; + comp_acq_args.composite_mask = (1 << vfe_out_res_id); + + /* for some hw versions, buf done is not received from vfe but + * from IP external to VFE. In such case, we get the controller + * from hw manager and assign it here + */ + if (!(ver3_bus_priv->common_data.supported_irq & + CAM_VFE_HW_IRQ_CAP_BUF_DONE)) + rsrc_data->common_data->buf_done_controller = + acq_args->buf_done_controller; secure_caps = cam_vfe_bus_ver3_can_be_secure( rsrc_data->out_type); @@ -2224,24 +1950,27 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, mutex_unlock(&rsrc_data->common_data->bus_mutex); ver3_bus_priv->tasklet_info = acq_args->tasklet; - rsrc_data->num_wm = num_wm; rsrc_node->rdi_only_ctx = 0; rsrc_node->res_id = out_acquire_args->out_port_info->res_type; rsrc_node->tasklet_info = acq_args->tasklet; rsrc_node->cdm_ops = out_acquire_args->cdm_ops; rsrc_data->cdm_util_ops = out_acquire_args->cdm_ops; + rsrc_data->format = out_acquire_args->out_port_info->format; + + if ((rsrc_data->out_type == CAM_VFE_BUS_VER3_VFE_OUT_FD) && + (rsrc_data->format == CAM_FORMAT_Y_ONLY)) + rsrc_data->num_wm = 1; /* Acquire WM and retrieve COMP GRP ID */ - for (i = 0; i < num_wm; i++) { + for (i = 0; i < rsrc_data->num_wm; i++) { rc = cam_vfe_bus_ver3_acquire_wm(ver3_bus_priv, out_acquire_args->out_port_info, acq_args->tasklet, vfe_out_res_id, i, &rsrc_data->wm_res[i], - &client_done_mask, out_acquire_args->is_dual, - &comp_grp_id); + &comp_acq_args.comp_grp_id); if (rc) { CAM_ERR(CAM_ISP, "Failed to acquire WM VFE:%d out_type:%d rc:%d", @@ -2251,15 +1980,14 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, } } + /* Acquire composite group using COMP GRP ID */ rc = cam_vfe_bus_ver3_acquire_comp_grp(ver3_bus_priv, - out_acquire_args->out_port_info, acq_args->tasklet, out_acquire_args->is_dual, out_acquire_args->is_master, - out_acquire_args->dual_slave_core, &rsrc_data->comp_grp, - comp_grp_id); + &comp_acq_args); if (rc) { CAM_ERR(CAM_ISP, "Failed to acquire comp_grp VFE:%d out_typp:%d rc:%d", @@ -2271,9 +1999,6 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, rsrc_data->is_dual = out_acquire_args->is_dual; rsrc_data->is_master = out_acquire_args->is_master; - cam_vfe_bus_ver3_add_wm_to_comp_grp(rsrc_data->comp_grp, - client_done_mask); - rsrc_node->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; out_acquire_args->rsrc_node = rsrc_node; @@ -2283,7 +2008,7 @@ static int cam_vfe_bus_ver3_acquire_vfe_out(void *bus_priv, void *acquire_args, release_wm: for (i--; i >= 0; i--) cam_vfe_bus_ver3_release_wm(ver3_bus_priv, - rsrc_data->wm_res[i]); + &rsrc_data->wm_res[i]); cam_vfe_bus_ver3_release_comp_grp(ver3_bus_priv, rsrc_data->comp_grp); @@ -2315,8 +2040,11 @@ static int cam_vfe_bus_ver3_release_vfe_out(void *bus_priv, void *release_args, } for (i = 0; i < rsrc_data->num_wm; i++) - cam_vfe_bus_ver3_release_wm(bus_priv, rsrc_data->wm_res[i]); - rsrc_data->num_wm = 0; + cam_vfe_bus_ver3_release_wm(bus_priv, &rsrc_data->wm_res[i]); + + if ((rsrc_data->out_type == CAM_VFE_BUS_VER3_VFE_OUT_FD) && + (rsrc_data->format == CAM_FORMAT_Y_ONLY)) + rsrc_data->num_wm = 2; if (rsrc_data->comp_grp) cam_vfe_bus_ver3_release_comp_grp(bus_priv, @@ -2390,7 +2118,7 @@ static int cam_vfe_bus_ver3_start_vfe_out( } for (i = 0; i < rsrc_data->num_wm; i++) - rc = cam_vfe_bus_ver3_start_wm(rsrc_data->wm_res[i]); + rc = cam_vfe_bus_ver3_start_wm(&rsrc_data->wm_res[i]); memset(bus_irq_reg_mask, 0, sizeof(bus_irq_reg_mask)); rc = cam_vfe_bus_ver3_start_comp_grp(rsrc_data->comp_grp, @@ -2400,7 +2128,7 @@ static int cam_vfe_bus_ver3_start_vfe_out( goto end; vfe_out->irq_handle = cam_irq_controller_subscribe_irq( - common_data->bus_irq_controller, + common_data->buf_done_controller, CAM_IRQ_PRIORITY_1, bus_irq_reg_mask, vfe_out, @@ -2420,7 +2148,8 @@ static int cam_vfe_bus_ver3_start_vfe_out( && !vfe_out->rdi_only_ctx) goto end; - if (!common_data->rup_irq_handle[source_group]) { + if ((common_data->supported_irq & CAM_VFE_HW_IRQ_CAP_RUP) && + (!common_data->rup_irq_handle[source_group])) { memset(rup_irq_reg_mask, 0, sizeof(rup_irq_reg_mask)); rup_irq_reg_mask[CAM_VFE_BUS_VER3_IRQ_REG0] |= 0x1 << source_group; @@ -2479,7 +2208,7 @@ static int cam_vfe_bus_ver3_stop_vfe_out( rc = cam_vfe_bus_ver3_stop_comp_grp(rsrc_data->comp_grp); for (i = 0; i < rsrc_data->num_wm; i++) - rc = cam_vfe_bus_ver3_stop_wm(rsrc_data->wm_res[i]); + rc = cam_vfe_bus_ver3_stop_wm(&rsrc_data->wm_res[i]); if (common_data->rup_irq_handle[rsrc_data->source_group]) { rc = cam_irq_controller_unsubscribe_irq( @@ -2580,7 +2309,7 @@ static uint32_t cam_vfe_bus_ver3_get_last_consumed_addr( rsrc_node = &bus_priv->vfe_out[res_id]; 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; val = cam_io_r_mb( wm_rsrc_data->common_data->mem_base + @@ -2619,8 +2348,7 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half( evt_info.hw_idx = vfe_out->hw_intf->hw_idx; rc = cam_vfe_bus_ver3_get_comp_vfe_out_res_id_list( - comp_mask, out_list, &num_out, - rsrc_data->common_data->is_lite); + comp_mask, out_list, &num_out); for (i = 0; i < num_out; i++) { evt_info.res_id = out_list[i]; evt_info.reg_val = @@ -2647,7 +2375,7 @@ static int cam_vfe_bus_ver3_init_vfe_out_resource(uint32_t index, { struct cam_isp_resource_node *vfe_out = NULL; struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = NULL; - int rc = 0, i; + int rc = 0, i = 0; int32_t vfe_out_type = ver3_hw_info->vfe_out_hw_info[index].vfe_out_type; @@ -2689,6 +2417,26 @@ static int cam_vfe_bus_ver3_init_vfe_out_resource(uint32_t index, rsrc_data->max_height = ver3_hw_info->vfe_out_hw_info[index].max_height; rsrc_data->secure_mode = CAM_SECURE_MODE_NON_SECURE; + rsrc_data->num_wm = ver3_hw_info->vfe_out_hw_info[index].num_wm; + + rsrc_data->wm_res = kzalloc((sizeof(struct cam_isp_resource_node) * + rsrc_data->num_wm), GFP_KERNEL); + if (!rsrc_data->wm_res) { + CAM_ERR(CAM_ISP, "Failed to alloc for wm_res"); + return -ENOMEM; + } + + for (i = 0; i < rsrc_data->num_wm; i++) { + rc = cam_vfe_bus_ver3_init_wm_resource( + ver3_hw_info->vfe_out_hw_info[index].wm_idx[i], + ver3_bus_priv, ver3_hw_info, + &rsrc_data->wm_res[i]); + if (rc < 0) { + CAM_ERR(CAM_ISP, "VFE:%d init WM:%d failed rc:%d", + ver3_bus_priv->common_data.core_index, i, rc); + return rc; + } + } vfe_out->start = cam_vfe_bus_ver3_start_vfe_out; vfe_out->stop = cam_vfe_bus_ver3_stop_vfe_out; @@ -2711,6 +2459,7 @@ static int cam_vfe_bus_ver3_deinit_vfe_out_resource( struct cam_isp_resource_node *vfe_out) { struct cam_vfe_bus_ver3_vfe_out_data *rsrc_data = vfe_out->res_priv; + int rc = 0, i = 0; if (vfe_out->res_state == CAM_ISP_RESOURCE_STATE_UNAVAILABLE) { /* @@ -2733,6 +2482,16 @@ static int cam_vfe_bus_ver3_deinit_vfe_out_resource( if (!rsrc_data) return -ENOMEM; + + for (i = 0; i < rsrc_data->num_wm; i++) { + rc = cam_vfe_bus_ver3_deinit_wm_resource(&rsrc_data->wm_res[i]); + if (rc < 0) + CAM_ERR(CAM_ISP, + "VFE:%d deinit WM:%d failed rc:%d", + rsrc_data->common_data->core_index, i, rc); + } + + rsrc_data->wm_res = NULL; kfree(rsrc_data); return 0; @@ -2752,8 +2511,7 @@ static int cam_vfe_bus_ver3_print_dimensions( rsrc_node = &bus_priv->vfe_out[vfe_out_res_id]; rsrc_data = rsrc_node->res_priv; for (i = 0; i < rsrc_data->num_wm; i++) { - wm_idx = cam_vfe_bus_ver3_get_wm_idx(vfe_out_res_id, i, - bus_priv->common_data.is_lite); + wm_idx = 0; if (wm_idx < 0 || wm_idx >= bus_priv->num_client) { CAM_ERR(CAM_ISP, "Unsupported VFE out %d", vfe_out_res_id); @@ -3073,7 +2831,7 @@ static int cam_vfe_bus_ver3_update_wm(void *priv, void *cmd_args, return -ENOMEM; } - wm_data = vfe_out_data->wm_res[i]->res_priv; + wm_data = vfe_out_data->wm_res[i].res_priv; ubwc_client = wm_data->hw_regs->ubwc_regs; /* Disable frame header in case it was previously enabled */ @@ -3273,7 +3031,7 @@ static int cam_vfe_bus_ver3_update_hfr(void *priv, void *cmd_args, return -ENOMEM; } - wm_data = vfe_out_data->wm_res[i]->res_priv; + wm_data = vfe_out_data->wm_res[i].res_priv; if (((!bus_priv->common_data.is_lite && wm_data->index > 22) || bus_priv->common_data.is_lite) && @@ -3383,7 +3141,7 @@ static int cam_vfe_bus_ver3_update_ubwc_config_v2(void *cmd_args) for (i = 0; i < vfe_out_data->num_wm; i++) { - wm_data = vfe_out_data->wm_res[i]->res_priv; + wm_data = vfe_out_data->wm_res[i].res_priv; ubwc_generic_plane_cfg = &ubwc_generic_cfg->ubwc_plane_cfg[i]; if (!wm_data->hw_regs->ubwc_regs) { @@ -3505,7 +3263,7 @@ static int cam_vfe_bus_ver3_update_stripe_cfg(void *priv, void *cmd_args, (stripe_args->dual_cfg->num_ports * CAM_PACKET_MAX_PLANES)) + (outport_id * CAM_PACKET_MAX_PLANES); for (i = 0; i < vfe_out_data->num_wm; i++) { - wm_data = vfe_out_data->wm_res[i]->res_priv; + wm_data = vfe_out_data->wm_res[i].res_priv; stripe_config = (struct cam_isp_dual_stripe_config *) &stripe_args->dual_cfg->stripes[ports_plane_idx + i]; wm_data->width = stripe_config->width; @@ -3556,7 +3314,7 @@ static int cam_vfe_bus_ver3_update_wm_config( } for (i = 0; i < vfe_out_data->num_wm; i++) { - wm_data = vfe_out_data->wm_res[i]->res_priv; + wm_data = vfe_out_data->wm_res[i].res_priv; if (wm_config->wm_mode > 0x2) { CAM_ERR(CAM_ISP, "Invalid wm_mode: 0x%X WM:%d", @@ -3625,20 +3383,22 @@ static int cam_vfe_bus_ver3_init_hw(void *hw_priv, return -EFAULT; } - bus_priv->rup_irq_handle = cam_irq_controller_subscribe_irq( - bus_priv->common_data.vfe_irq_controller, - CAM_IRQ_PRIORITY_2, - top_irq_reg_mask, - bus_priv, - cam_vfe_bus_ver3_handle_rup_irq, - NULL, - NULL, - NULL); + if (bus_priv->common_data.supported_irq & CAM_VFE_HW_IRQ_CAP_RUP) { + bus_priv->rup_irq_handle = cam_irq_controller_subscribe_irq( + bus_priv->common_data.vfe_irq_controller, + CAM_IRQ_PRIORITY_2, + top_irq_reg_mask, + bus_priv, + cam_vfe_bus_ver3_handle_rup_irq, + NULL, + NULL, + NULL); - if (bus_priv->rup_irq_handle < 1) { - CAM_ERR(CAM_ISP, "Failed to subscribe BUS (rup) IRQ"); - bus_priv->rup_irq_handle = 0; - return -EFAULT; + if (bus_priv->rup_irq_handle < 1) { + CAM_ERR(CAM_ISP, "Failed to subscribe BUS (rup) IRQ"); + bus_priv->rup_irq_handle = 0; + return -EFAULT; + } } if (bus_priv->tasklet_info != NULL) { @@ -3659,6 +3419,13 @@ static int cam_vfe_bus_ver3_init_hw(void *hw_priv, } } + /* We take the controller only if the buf done is supported on vfe side + * for some hw, it is taken from IP extenal to VFE like CSID + */ + if ((bus_priv->common_data.supported_irq & CAM_VFE_HW_IRQ_CAP_BUF_DONE)) + bus_priv->common_data.buf_done_controller = + bus_priv->common_data.bus_irq_controller; + /* no clock gating at bus input */ CAM_DBG(CAM_ISP, "Overriding clock gating at bus input"); cam_io_w_mb(0x3FFFFFF, bus_priv->common_data.mem_base + @@ -3911,6 +3678,7 @@ int cam_vfe_bus_ver3_init( bus_priv->num_client = ver3_hw_info->num_client; bus_priv->num_out = ver3_hw_info->num_out; + bus_priv->num_comp_grp = ver3_hw_info->num_comp_grp; bus_priv->top_irq_shift = ver3_hw_info->top_irq_shift; bus_priv->max_out_res = ver3_hw_info->max_out_res; bus_priv->common_data.num_sec_out = 0; @@ -3929,6 +3697,25 @@ int cam_vfe_bus_ver3_init( bus_priv->common_data.support_consumed_addr = ver3_hw_info->support_consumed_addr; bus_priv->common_data.disable_ubwc_comp = false; + bus_priv->common_data.supported_irq = ver3_hw_info->supported_irq; + bus_priv->common_data.comp_config_needed = + ver3_hw_info->comp_cfg_needed; + + bus_priv->comp_grp = kzalloc((sizeof(struct cam_isp_resource_node) * + bus_priv->num_comp_grp), GFP_KERNEL); + if (!bus_priv->comp_grp) { + CAM_ERR(CAM_ISP, "Failed to alloc for bus comp groups"); + rc = -ENOMEM; + goto free_bus_priv; + } + + bus_priv->vfe_out = kzalloc((sizeof(struct cam_isp_resource_node) * + bus_priv->num_out), GFP_KERNEL); + if (!bus_priv->vfe_out) { + CAM_ERR(CAM_ISP, "Failed to alloc for bus out res"); + rc = -ENOMEM; + goto free_comp_grp; + } for (i = 0; i < CAM_VFE_BUS_VER3_SRC_GRP_MAX; i++) bus_priv->common_data.rup_irq_handle[i] = 0; @@ -3940,32 +3727,24 @@ int cam_vfe_bus_ver3_init( &bus_priv->common_data.bus_irq_controller, false); if (rc) { CAM_ERR(CAM_ISP, "Init bus_irq_controller failed"); - goto free_bus_priv; + goto free_vfe_out; } - rc = cam_irq_controller_init("vfe_bus_rup", - bus_priv->common_data.mem_base, - &ver3_hw_info->common_reg.irq_reg_info, - &bus_priv->common_data.rup_irq_controller, false); - if (rc) { - CAM_ERR(CAM_ISP, "Init rup_irq_controller failed"); - goto free_bus_priv; + if (bus_priv->common_data.supported_irq & CAM_VFE_HW_IRQ_CAP_RUP) { + rc = cam_irq_controller_init("vfe_bus_rup", + bus_priv->common_data.mem_base, + &ver3_hw_info->common_reg.irq_reg_info, + &bus_priv->common_data.rup_irq_controller, false); + if (rc) { + CAM_ERR(CAM_ISP, "Init rup_irq_controller failed"); + goto free_vfe_out; + } } INIT_LIST_HEAD(&bus_priv->free_comp_grp); INIT_LIST_HEAD(&bus_priv->used_comp_grp); - for (i = 0; i < bus_priv->num_client; i++) { - rc = cam_vfe_bus_ver3_init_wm_resource(i, bus_priv, bus_hw_info, - &bus_priv->bus_client[i]); - if (rc < 0) { - CAM_ERR(CAM_ISP, "VFE:%d init WM:%d failed rc:%d", - bus_priv->common_data.core_index, i, rc); - goto deinit_wm; - } - } - - for (i = 0; i < CAM_VFE_BUS_VER3_COMP_GRP_MAX; i++) { + for (i = 0; i < bus_priv->num_comp_grp; i++) { rc = cam_vfe_bus_ver3_init_comp_grp(i, soc_info, bus_priv, bus_hw_info, &bus_priv->comp_grp[i]); @@ -4018,15 +3797,15 @@ deinit_vfe_out: deinit_comp_grp: if (i < 0) - i = CAM_VFE_BUS_VER3_COMP_GRP_MAX; + i = bus_priv->num_comp_grp; for (--i; i >= 0; i--) cam_vfe_bus_ver3_deinit_comp_grp(&bus_priv->comp_grp[i]); -deinit_wm: - if (i < 0) - i = bus_priv->num_client; - for (--i; i >= 0; i--) - cam_vfe_bus_ver3_deinit_wm_resource(&bus_priv->bus_client[i]); +free_vfe_out: + kfree(bus_priv->vfe_out); + +free_comp_grp: + kfree(bus_priv->comp_grp); free_bus_priv: kfree(vfe_bus_local->bus_priv); @@ -4066,15 +3845,6 @@ int cam_vfe_bus_ver3_deinit( bus_priv->common_data.hw_init = false; spin_unlock_irqrestore(&bus_priv->common_data.spin_lock, flags); - for (i = 0; i < bus_priv->num_client; i++) { - rc = cam_vfe_bus_ver3_deinit_wm_resource( - &bus_priv->bus_client[i]); - if (rc < 0) - CAM_ERR(CAM_ISP, - "VFE:%d deinit WM:%d failed rc:%d", - bus_priv->common_data.core_index, i, rc); - } - for (i = 0; i < CAM_VFE_BUS_VER3_COMP_GRP_MAX; i++) { rc = cam_vfe_bus_ver3_deinit_comp_grp(&bus_priv->comp_grp[i]); if (rc < 0) @@ -4107,6 +3877,9 @@ int cam_vfe_bus_ver3_deinit( CAM_ERR(CAM_ISP, "Deinit RUP IRQ Controller failed rc=%d", rc); + kfree(bus_priv->comp_grp); + kfree(bus_priv->vfe_out); + mutex_destroy(&bus_priv->common_data.bus_mutex); kfree(vfe_bus_local->bus_priv); 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 fd00b852888e..50fd2e42443c 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 @@ -10,7 +10,6 @@ #include "cam_irq_controller.h" #include "cam_vfe_bus.h" -#define CAM_VFE_BUS_VER3_MAX_CLIENTS 26 #define CAM_VFE_BUS_VER3_MAX_SUB_GRPS 6 #define CAM_VFE_BUS_VER3_MAX_MID_PER_PORT 4 #define CAM_VFE_BUS_VER3_480_MAX_CLIENTS 26 @@ -80,7 +79,11 @@ enum cam_vfe_bus_ver3_vfe_out_type { CAM_VFE_BUS_VER3_VFE_OUT_LCR, CAM_VFE_BUS_VER3_VFE_OUT_AWB_BFW, CAM_VFE_BUS_VER3_VFE_OUT_2PD_STATS, + CAM_VFE_BUS_VER3_VFE_OUT_STATS_AEC_BE, CAM_VFE_BUS_VER3_VFE_OUT_LTM_STATS, + CAM_VFE_BUS_VER3_VFE_OUT_STATS_GTM_BHIST, + CAM_VFE_BUS_VER3_VFE_OUT_STATS_BE, + CAM_VFE_BUS_VER3_VFE_OUT_GAMMA, CAM_VFE_BUS_VER3_VFE_OUT_MAX, }; @@ -185,10 +188,13 @@ struct cam_vfe_bus_ver3_vfe_out_hw_info { * @num_client: Total number of write clients * @bus_client_reg: Bus client register info * @vfe_out_hw_info: VFE output capability + * @num_comp_grp: Number of composite groups * @comp_done_shift: Mask shift for comp done mask * @top_irq_shift: Mask shift for top level BUS WR irq * @support_consumed_addr: Indicate if bus support consumed address * @max_out_res: Max vfe out resource value supported for hw + * @supported_irq: Mask to indicate the IRQ supported + * @comp_cfg_needed: Composite group config is needed for hw */ struct cam_vfe_bus_ver3_hw_info { struct cam_vfe_bus_ver3_reg_offset_common common_reg; @@ -198,10 +204,13 @@ struct cam_vfe_bus_ver3_hw_info { uint32_t num_out; struct cam_vfe_bus_ver3_vfe_out_hw_info vfe_out_hw_info[CAM_VFE_BUS_VER3_VFE_OUT_MAX]; + uint32_t num_comp_grp; uint32_t comp_done_shift; uint32_t top_irq_shift; bool support_consumed_addr; uint32_t max_out_res; + uint32_t supported_irq; + bool comp_cfg_needed; }; /*