diff --git a/drivers/Makefile b/drivers/Makefile index dc5da51160..57e2929ab3 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -90,6 +90,7 @@ camera-$(CONFIG_SPECTRA_ISP) += \ cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.o \ cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.o \ cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver2.o \ + cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.o \ cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.o \ cam_isp/isp_hw_mgr/cam_isp_hw_mgr.o \ cam_isp/isp_hw_mgr/cam_ife_hw_mgr.o \ 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 bfdc76f930..87e947c93a 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 @@ -2946,7 +2946,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) } if ((in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) || - (in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1)) + (in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1) || + (in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_2)) rc = cam_ife_hw_mgr_acquire_tpg(ife_ctx, in_port, acquire_hw_info->num_inputs); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c index 66803e4310..b885cd17ba 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c @@ -1146,7 +1146,8 @@ int cam_ife_csid_path_reserve(struct cam_ife_csid_hw *csid_hw, path_data->crop_enable); if ((reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_0) || - (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1)) { + (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_1) || + (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_CPHY_TPG_2)) { path_data->dt = CAM_IFE_CPHY_TPG_DT_VAL; path_data->vc = CAM_IFE_CPHY_TPG_VC_VAL; } else if (reserve->in_port->res_type == CAM_ISP_IFE_IN_RES_TPG) { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h index fdbc6639bd..1aa9d26e11 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_top_tpg_hw_intf.h @@ -11,7 +11,7 @@ #include "cam_ife_csid_hw_intf.h" /* Max top tpg instance */ -#define CAM_TOP_TPG_HW_NUM_MAX 2 +#define CAM_TOP_TPG_HW_NUM_MAX 3 /* Max supported number of DT for TPG */ #define CAM_TOP_TPG_MAX_SUPPORTED_DT 4 @@ -21,6 +21,7 @@ enum cam_top_tpg_id { CAM_TOP_TPG_ID_0, CAM_TOP_TPG_ID_1, + CAM_TOP_TPG_ID_2, CAM_TFE_TPG_ID_MAX, }; @@ -55,7 +56,7 @@ struct cam_top_tpg_ver1_reserve_args { /** * struct cam_top_tpg_ver2_reserve_args * @num_inport: number of inport - * TPG supports 1 VC/DT + * TPG supports 1 VC/DT combo * @in_port : Input port resource info structure pointer * @node_res : Reserved resource structure pointer * @@ -66,6 +67,20 @@ struct cam_top_tpg_ver2_reserve_args { struct cam_isp_resource_node *node_res; }; +/** + * struct cam_top_tpg_ver2_reserve_args + * @num_inport: number of inport + * TPG supports 4 VC's and 4 DT's per VC + * @in_port : Input port resource info structure pointer + * @node_res : Reserved resource structure pointer + * + */ +struct cam_top_tpg_ver3_reserve_args { + uint32_t num_inport; + struct cam_isp_in_port_generic_info *in_port; + struct cam_isp_resource_node *node_res; +}; + /** * cam_top_tpg_hw_init() * diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.c index 9eafcf4da6..6d86970457 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg.c @@ -6,6 +6,7 @@ #include #include "cam_top_tpg101.h" #include "cam_top_tpg102.h" +#include "cam_top_tpg103.h" #include "cam_top_tpg_core.h" #include "cam_top_tpg_dev.h" #include "camera_main.h" @@ -19,6 +20,10 @@ static const struct of_device_id cam_top_tpg_dt_match[] = { .compatible = "qcom,tpg102", .data = &cam_top_tpg102_hw_info, }, + { + .compatible = "qcom,tpg103", + .data = &cam_top_tpg103_hw_info, + }, {} }; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg102.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg102.h index ce2f2c73a0..0a3a54bf61 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg102.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg102.h @@ -43,8 +43,8 @@ static struct cam_top_tpg_ver2_reg_offset cam_top_tpg102_reg = { struct cam_top_tpg_hw_info cam_top_tpg102_hw_info = { .tpg_reg = &cam_top_tpg102_reg, .hw_dts_version = CAM_TOP_TPG_VERSION_2, - .csid_max_clk = 426400000, - .phy_max_clk = 384000000, + .csid_max_clk = 400000000, + .phy_max_clk = 400000000, }; #endif /* _CAM_TOP_TPG102_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h new file mode 100644 index 0000000000..3966718527 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg103.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_TOP_TPG103_H_ +#define _CAM_TOP_TPG103_H_ + +#include "cam_top_tpg_ver3.h" +#include "cam_top_tpg_core.h" + +static struct cam_top_tpg_ver3_reg_offset cam_top_tpg103_reg = { + .tpg_hw_version = 0x0, + .tpg_hw_status = 0x4, + .tpg_ctrl = 0x64, + .tpg_vc0_cfg0 = 0x68, + .tpg_vc0_lfsr_seed = 0x6C, + .tpg_vc0_hbi_cfg = 0x70, + .tpg_vc0_vbi_cfg = 0x74, + .tpg_vc0_color_bar_cfg = 0x78, + .tpg_vc0_dt_0_cfg_0 = 0x7C, + .tpg_vc0_dt_0_cfg_1 = 0x80, + .tpg_vc0_dt_0_cfg_2 = 0x84, + .tpg_vc0_dt_1_cfg_0 = 0x88, + .tpg_vc0_dt_1_cfg_1 = 0x8C, + .tpg_vc0_dt_1_cfg_2 = 0x90, + .tpg_vc0_dt_2_cfg_0 = 0x94, + .tpg_vc0_dt_2_cfg_1 = 0x98, + .tpg_vc0_dt_2_cfg_2 = 0x9C, + .tpg_vc0_dt_3_cfg_0 = 0xA0, + .tpg_vc0_dt_3_cfg_1 = 0xA4, + .tpg_vc0_dt_3_cfg_2 = 0xA8, + + .tpg_vc1_cfg0 = 0xC8, + .tpg_vc1_lfsr_seed = 0xCC, + .tpg_vc1_hbi_cfg = 0xD0, + .tpg_vc1_vbi_cfg = 0xD4, + .tpg_vc1_color_bar_cfg = 0xD8, + .tpg_vc1_dt_0_cfg_0 = 0xDC, + .tpg_vc1_dt_0_cfg_1 = 0xE0, + .tpg_vc1_dt_0_cfg_2 = 0xE4, + .tpg_vc1_dt_1_cfg_0 = 0xE8, + .tpg_vc1_dt_1_cfg_1 = 0xEC, + .tpg_vc1_dt_1_cfg_2 = 0xF0, + .tpg_vc1_dt_2_cfg_0 = 0xF4, + .tpg_vc1_dt_2_cfg_1 = 0xF8, + .tpg_vc1_dt_2_cfg_2 = 0xFC, + .tpg_vc1_dt_3_cfg_0 = 0x100, + .tpg_vc1_dt_3_cfg_1 = 0x104, + .tpg_vc1_dt_3_cfg_2 = 0x108, + + .tpg_vc2_cfg0 = 0x128, + .tpg_vc2_lfsr_seed = 0x12C, + .tpg_vc2_hbi_cfg = 0x130, + .tpg_vc2_vbi_cfg = 0x134, + .tpg_vc2_color_bar_cfg = 0x138, + .tpg_vc2_dt_0_cfg_0 = 0x13C, + .tpg_vc2_dt_0_cfg_1 = 0x140, + .tpg_vc2_dt_0_cfg_2 = 0x144, + .tpg_vc2_dt_1_cfg_0 = 0x148, + .tpg_vc2_dt_1_cfg_1 = 0x14C, + .tpg_vc2_dt_1_cfg_2 = 0x150, + .tpg_vc2_dt_2_cfg_0 = 0x154, + .tpg_vc2_dt_2_cfg_1 = 0x158, + .tpg_vc2_dt_2_cfg_2 = 0x15C, + .tpg_vc2_dt_3_cfg_0 = 0x160, + .tpg_vc2_dt_3_cfg_1 = 0x164, + .tpg_vc2_dt_3_cfg_2 = 0x168, + + .tpg_vc3_cfg0 = 0x188, + .tpg_vc3_lfsr_seed = 0x18C, + .tpg_vc3_hbi_cfg = 0x190, + .tpg_vc3_vbi_cfg = 0x194, + .tpg_vc3_color_bar_cfg = 0x198, + .tpg_vc3_dt_0_cfg_0 = 0x19C, + .tpg_vc3_dt_0_cfg_1 = 0x1A0, + .tpg_vc3_dt_0_cfg_2 = 0x1A4, + .tpg_vc3_dt_1_cfg_0 = 0x1A8, + .tpg_vc3_dt_1_cfg_1 = 0x1AC, + .tpg_vc3_dt_1_cfg_2 = 0x1B0, + .tpg_vc3_dt_2_cfg_0 = 0x1B4, + .tpg_vc3_dt_2_cfg_1 = 0x1B8, + .tpg_vc3_dt_2_cfg_2 = 0x1BC, + .tpg_vc3_dt_3_cfg_0 = 0x1C0, + .tpg_vc3_dt_3_cfg_1 = 0x1C4, + .tpg_vc3_dt_3_cfg_2 = 0x1C8, + .tpg_throttle = 0x1CC, + .tpg_top_irq_status = 0x1E0, + .tpg_top_irq_mask = 0x1E4, + .tpg_top_irq_clear = 0x1E8, + .tpg_top_irq_set = 0x1EC, + .tpg_top_irq_cmd = 0x1F0, + .tpg_top_clear = 0x1F4, + .tpg_test_bus_crtl = 0x1F8, + .tpg_spare = 0x1FC, + + /* configurations */ + .major_version = 2, + .minor_version = 0, + .version_incr = 0, + .tpg_en_shift_val = 0, + .tpg_cphy_dphy_sel_shift_val = 3, + .tpg_num_active_lanes_shift = 4, + .tpg_fe_pkt_en_shift = 2, + .tpg_fs_pkt_en_shift = 1, + .tpg_line_interleaving_mode_shift = 10, + .tpg_num_dts_shift_val = 8, + .tpg_v_blank_cnt_shift = 12, + .tpg_dt_encode_format_shift = 20, + .tpg_payload_mode_color = 0x8, + .tpg_split_en_shift = 4, + .top_mux_reg_offset = 0x1C, + .tpg_vc_dt_pattern_id_shift = 6, + .tpg_num_active_vcs_shift = 30, +}; + +struct cam_top_tpg_hw_info cam_top_tpg103_hw_info = { + .tpg_reg = &cam_top_tpg103_reg, + .hw_dts_version = CAM_TOP_TPG_VERSION_3, + .csid_max_clk = 480000000, + .phy_max_clk = 480000000, +}; + +#endif /* _CAM_TOP_TPG103_H_ */ diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c index 64b776623d..23b62f6fdb 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.c @@ -15,6 +15,40 @@ #include "cam_cpas_api.h" #include "cam_top_tpg_ver1.h" #include "cam_top_tpg_ver2.h" +#include "cam_top_tpg_ver3.h" + +int cam_top_tpg_get_format( + uint32_t in_format, + uint32_t *tpg_encode_format) +{ + int rc = 0; + + switch (in_format) { + case CAM_FORMAT_MIPI_RAW_6: + *tpg_encode_format = 0; + break; + case CAM_FORMAT_MIPI_RAW_8: + *tpg_encode_format = 1; + break; + case CAM_FORMAT_MIPI_RAW_10: + *tpg_encode_format = 2; + break; + case CAM_FORMAT_MIPI_RAW_12: + *tpg_encode_format = 3; + break; + case CAM_FORMAT_MIPI_RAW_14: + *tpg_encode_format = 4; + break; + case CAM_FORMAT_MIPI_RAW_16: + *tpg_encode_format = 5; + break; + default: + CAM_ERR(CAM_ISP, "Unsupported input encode format %d", + in_format); + rc = -EINVAL; + } + return rc; +} static int cam_top_tpg_release(void *hw_priv, void *release_args, uint32_t arg_size) @@ -212,6 +246,42 @@ static int cam_top_tpg_set_phy_clock( return 0; } +irqreturn_t cam_top_tpg_irq(int irq_num, void *data) +{ + struct cam_top_tpg_hw *tpg_hw; + struct cam_hw_soc_info *soc_info; + struct cam_top_tpg_ver3_reg_offset *tpg_reg; + uint32_t irq_status_top; + unsigned long flags; + + if (!data) { + CAM_ERR(CAM_ISP, "TPG: Invalid arguments"); + return IRQ_HANDLED; + } + + + tpg_hw = (struct cam_top_tpg_hw *) data; + CAM_DBG(CAM_ISP, "CPHY TPG %d IRQ Handling", tpg_hw->hw_intf->hw_idx); + + soc_info = &tpg_hw->hw_info->soc_info; + tpg_reg = tpg_hw->tpg_info->tpg_reg; + + irq_status_top = cam_io_r_mb(soc_info->reg_map[0].mem_base + + tpg_reg->tpg_top_irq_status); + + spin_lock_irqsave(&tpg_hw->hw_info->hw_lock, flags); + /* clear */ + cam_io_w_mb(irq_status_top, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_top_irq_clear); + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_top_irq_cmd); + + spin_unlock_irqrestore(&tpg_hw->hw_info->hw_lock, flags); + + CAM_DBG(CAM_ISP, "TPG: irq_status_top = 0x%x", irq_status_top); + return IRQ_HANDLED; +} + static int cam_top_tpg_process_cmd(void *hw_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { @@ -272,7 +342,7 @@ int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf, init_completion(&tpg_hw->tpg_complete); rc = cam_top_tpg_init_soc_resources(&tpg_hw->hw_info->soc_info, - tpg_hw); + cam_top_tpg_irq, tpg_hw); if (rc < 0) { CAM_ERR(CAM_ISP, "TPG:%d Failed to init_soc", tpg_idx); goto err; @@ -291,6 +361,8 @@ int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf, cam_top_tpg_ver1_init(tpg_hw); else if (hw_version == CAM_TOP_TPG_VERSION_2) cam_top_tpg_ver2_init(tpg_hw); + else if (hw_version == CAM_TOP_TPG_VERSION_3) + cam_top_tpg_ver3_init(tpg_hw); tpg_hw->tpg_res.res_type = CAM_ISP_RESOURCE_TPG; tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h index 3dce37d94f..eb6e03a36c 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_core.h @@ -12,6 +12,8 @@ #define CAM_TOP_TPG_VERSION_1 0x10000001 #define CAM_TOP_TPG_VERSION_2 0x10000002 +#define CAM_TOP_TPG_VERSION_3 0x20000000 + enum cam_top_tpg_encode_format { CAM_TOP_TPG_ENCODE_FORMAT_RAW6, @@ -85,12 +87,13 @@ struct cam_top_tpg_cfg { uint32_t pix_pattern; uint32_t phy_sel; uint32_t num_active_lanes; - uint32_t vc_num; + uint32_t vc_num[4]; uint32_t v_blank_count; uint32_t h_blank_count; uint32_t vbi_cnt; uint32_t num_active_dts; uint32_t num_frames; + uint32_t vc_dt_pattern_id; struct cam_top_tpg_dt_cfg dt_cfg[4]; }; @@ -117,6 +120,8 @@ struct cam_top_tpg_hw { struct completion tpg_complete; }; +int cam_top_tpg_get_format(uint32_t in_format, uint32_t *tpg_encode_format); + int cam_top_tpg_probe_init(struct cam_hw_intf *tpg_hw_intf, uint32_t tpg_idx); diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.c index 206e91628f..2551458793 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.c @@ -8,7 +8,7 @@ #include "cam_debug_util.h" int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info, - void *irq_data) + irq_handler_t tpg_irq_handler, void *irq_data) { int rc = 0; struct cam_cpas_register_params cpas_register_param; @@ -26,7 +26,7 @@ int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info, return rc; /* Need to see if we want post process the clock list */ - rc = cam_soc_util_request_platform_resource(soc_info, NULL, + rc = cam_soc_util_request_platform_resource(soc_info, tpg_irq_handler, irq_data); if (rc < 0) { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.h index 9788409c99..faefb81eb0 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.h +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_soc.h @@ -37,11 +37,12 @@ struct cam_top_tpg_device_soc_info { * @brief: csid initialization function for the soc info * * @soc_info: soc info structure pointer + * @tpg_irq_handler: irq handler function to be registered * @irq_data: irq data for the callback function * */ int cam_top_tpg_init_soc_resources(struct cam_hw_soc_info *soc_info, - void *irq_data); + irq_handler_t tpg_irq_handler, void *irq_data); /** * cam_top_tpg_deinit_soc_resources() diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c index 24c930f125..8a657e7535 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver1.c @@ -21,39 +21,6 @@ static uint32_t tpg_num_dt_map[CAM_TOP_TPG_MAX_SUPPORTED_DT] = { 2 }; -static int cam_top_tpg_ver1_get_format( - uint32_t in_format, - uint32_t *tpg_encode_format) -{ - int rc = 0; - - switch (in_format) { - case CAM_FORMAT_MIPI_RAW_6: - *tpg_encode_format = 0; - break; - case CAM_FORMAT_MIPI_RAW_8: - *tpg_encode_format = 1; - break; - case CAM_FORMAT_MIPI_RAW_10: - *tpg_encode_format = 2; - break; - case CAM_FORMAT_MIPI_RAW_12: - *tpg_encode_format = 3; - break; - case CAM_FORMAT_MIPI_RAW_14: - *tpg_encode_format = 4; - break; - case CAM_FORMAT_MIPI_RAW_16: - *tpg_encode_format = 4; - break; - default: - CAM_ERR(CAM_ISP, "Unsupported input encode format %d", - in_format); - rc = -EINVAL; - } - return rc; -} - static int cam_top_tpg_ver1_get_hw_caps( void *hw_priv, void *get_hw_cap_args, @@ -136,7 +103,7 @@ static int cam_top_tpg_ver1_reserve( mutex_unlock(&tpg_hw->hw_info->hw_mutex); return -EINVAL; } - rc = cam_top_tpg_ver1_get_format(reserv->in_port[0]->format, + rc = cam_top_tpg_get_format(reserv->in_port[0]->format, &encode_format); if (rc) goto error; @@ -144,7 +111,7 @@ static int cam_top_tpg_ver1_reserve( CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx); tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv; - tpg_data->vc_num = reserv->in_port[0]->vc; + tpg_data->vc_num[0] = reserv->in_port[0]->vc; tpg_data->phy_sel = reserv->in_port[0]->lane_type; tpg_data->num_active_lanes = reserv->in_port[0]->lane_num; tpg_data->h_blank_count = reserv->in_port[0]->sensor_hbi; @@ -165,7 +132,7 @@ static int cam_top_tpg_ver1_reserve( CAM_DBG(CAM_ISP, "TPG:%u vc_num:%d dt:%d phy:%d lines:%d pattern:%d format:%d", tpg_hw->hw_intf->hw_idx, - tpg_data->vc_num, tpg_data->dt_cfg[0].data_type, + tpg_data->vc_num[0], tpg_data->dt_cfg[0].data_type, tpg_data->phy_sel, tpg_data->num_active_lanes, tpg_data->pix_pattern, tpg_data->dt_cfg[0].encode_format); @@ -181,7 +148,7 @@ static int cam_top_tpg_ver1_reserve( goto end; for (i = 1; i < reserv->num_inport; i++) { - if ((tpg_data->vc_num != reserv->in_port[i]->vc) || + if ((tpg_data->vc_num[0] != reserv->in_port[i]->vc) || (tpg_data->phy_sel != reserv->in_port[i]->lane_type) || (tpg_data->num_active_lanes != reserv->in_port[i]->lane_num) || @@ -193,7 +160,7 @@ static int cam_top_tpg_ver1_reserve( rc = -EINVAL; goto error; } - rc = cam_top_tpg_ver1_get_format(reserv->in_port[0]->format, + rc = cam_top_tpg_get_format(reserv->in_port[0]->format, &encode_format); if (rc) return rc; @@ -278,7 +245,7 @@ static int cam_top_tpg_ver1_start( } val = (tpg_num_dt_map[tpg_data->num_active_dts-1] << - tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num; + tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num[0]; cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg0); /* diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c new file mode 100644 index 0000000000..ee862e3db1 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.c @@ -0,0 +1,345 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include "cam_top_tpg_core.h" +#include "cam_soc_util.h" +#include "cam_io_util.h" +#include "cam_debug_util.h" +#include "cam_top_tpg_ver3.h" + +static int cam_top_tpg_ver3_get_hw_caps( + void *hw_priv, + void *get_hw_cap_args, + uint32_t arg_size) +{ + int rc = 0; + struct cam_top_tpg_hw_caps *hw_caps; + struct cam_top_tpg_hw *tpg_hw; + const struct cam_top_tpg_ver3_reg_offset *tpg_reg; + struct cam_hw_info *tpg_hw_info; + + if (!hw_priv || !get_hw_cap_args) { + CAM_ERR(CAM_ISP, "TPG: Invalid args"); + return -EINVAL; + } + + tpg_hw_info = (struct cam_hw_info *)hw_priv; + tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info; + hw_caps = (struct cam_top_tpg_hw_caps *) get_hw_cap_args; + tpg_reg = tpg_hw->tpg_info->tpg_reg; + + hw_caps->major_version = tpg_reg->major_version; + hw_caps->minor_version = tpg_reg->minor_version; + hw_caps->version_incr = tpg_reg->version_incr; + + CAM_DBG(CAM_ISP, + "TPG:%d major:%d minor:%d ver :%d", + tpg_hw->hw_intf->hw_idx, hw_caps->major_version, + hw_caps->minor_version, hw_caps->version_incr); + + return rc; +} + +static int cam_top_tpg_ver3_reserve( + void *hw_priv, + void *reserve_args, + uint32_t arg_size) +{ + int rc = 0; + struct cam_top_tpg_hw *tpg_hw; + struct cam_hw_info *tpg_hw_info; + struct cam_top_tpg_ver3_reserve_args *reserv; + struct cam_top_tpg_cfg *tpg_data; + uint32_t encode_format = 0; + uint32_t i; + + if (!hw_priv || !reserve_args || (arg_size != + sizeof(struct cam_top_tpg_ver3_reserve_args))) { + CAM_ERR(CAM_ISP, "TPG: Invalid args"); + return -EINVAL; + } + + tpg_hw_info = (struct cam_hw_info *)hw_priv; + tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info; + reserv = (struct cam_top_tpg_ver3_reserve_args *)reserve_args; + + if (reserv->num_inport <= 0 || + reserv->num_inport > CAM_TOP_TPG_MAX_SUPPORTED_DT) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG: %u invalid input num port:%d", + tpg_hw->hw_intf->hw_idx, reserv->num_inport); + return -EINVAL; + } + + mutex_lock(&tpg_hw->hw_info->hw_mutex); + if (tpg_hw->tpg_res.res_state != CAM_ISP_RESOURCE_STATE_AVAILABLE) { + rc = -EINVAL; + goto error; + } + + if ((reserv->in_port->lane_num <= 0 || + reserv->in_port->lane_num > 4) || + (reserv->in_port->lane_type >= 2)) { + CAM_ERR_RATE_LIMIT(CAM_ISP, "TPG:%u invalid input %d %d", + tpg_hw->hw_intf->hw_idx, + reserv->in_port->lane_num, + reserv->in_port->lane_type); + rc = -EINVAL; + goto error; + } + + tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv; + + for (i = 0; i < reserv->in_port->num_valid_vc_dt; i++) { + if (reserv->in_port->dt[i] > 0x3f || + reserv->in_port->vc[i] > 0x1f) { + CAM_ERR(CAM_ISP, "TPG:%u Invalid vc:%d dt %d", + tpg_hw->hw_intf->hw_idx, + reserv->in_port->vc[i], + reserv->in_port->dt[i]); + rc = -EINVAL; + goto error; + } + tpg_data->vc_num[i] = reserv->in_port->vc[i]; + tpg_data->dt_cfg[i].data_type = reserv->in_port->dt[i]; + } + + rc = cam_top_tpg_get_format(reserv->in_port->format, + &encode_format); + if (rc) + goto error; + + + CAM_DBG(CAM_ISP, "TPG: %u enter", tpg_hw->hw_intf->hw_idx); + + tpg_data = (struct cam_top_tpg_cfg *)tpg_hw->tpg_res.res_priv; + tpg_data->phy_sel = reserv->in_port->lane_type; + tpg_data->num_active_lanes = reserv->in_port->lane_num; + tpg_data->h_blank_count = reserv->in_port->hbi_cnt; + tpg_data->v_blank_count = 600; + tpg_data->num_active_dts = reserv->in_port->num_valid_vc_dt; + + for (i = 0; i < reserv->in_port->num_valid_vc_dt; i++) { + tpg_data->dt_cfg[i].encode_format = encode_format; + tpg_data->dt_cfg[i].frame_height = reserv->in_port->height; + + if (reserv->in_port->usage_type) + tpg_data->dt_cfg[i].frame_width = + ((reserv->in_port->right_stop - + reserv->in_port->left_start) + 1); + else + tpg_data->dt_cfg[i].frame_width = + reserv->in_port->left_width; + } + + CAM_DBG(CAM_ISP, + "TPG:%u vc_num:%d dt:%d phy:%d lines:%d pattern:%d format:%d", + tpg_hw->hw_intf->hw_idx, + tpg_data->vc_num, tpg_data->dt_cfg[0].data_type, + tpg_data->phy_sel, tpg_data->num_active_lanes, + tpg_data->pix_pattern, + tpg_data->dt_cfg[0].encode_format); + + CAM_DBG(CAM_ISP, "TPG:%u height:%d width:%d h blank:%d v blank:%d", + tpg_hw->hw_intf->hw_idx, + tpg_data->dt_cfg[0].frame_height, + tpg_data->dt_cfg[0].frame_width, + tpg_data->h_blank_count, + tpg_data->v_blank_count); + + reserv->node_res = &tpg_hw->tpg_res; + tpg_hw->tpg_res.res_state = CAM_ISP_RESOURCE_STATE_RESERVED; +error: + mutex_unlock(&tpg_hw->hw_info->hw_mutex); + CAM_DBG(CAM_ISP, "exit rc %u", rc); + + return rc; +} + +static int cam_top_tpg_ver3_start( + void *hw_priv, + void *start_args, + uint32_t arg_size) +{ + int rc = 0; + struct cam_top_tpg_hw *tpg_hw; + struct cam_hw_info *tpg_hw_info; + struct cam_hw_soc_info *soc_info; + struct cam_isp_resource_node *tpg_res; + struct cam_top_tpg_ver3_reg_offset *tpg_reg; + struct cam_top_tpg_cfg *tpg_data; + uint32_t i, val; + + if (!hw_priv || !start_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "TPG: Invalid args"); + return -EINVAL; + } + + tpg_hw_info = (struct cam_hw_info *)hw_priv; + tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info; + tpg_reg = tpg_hw->tpg_info->tpg_reg; + tpg_res = (struct cam_isp_resource_node *)start_args; + tpg_data = (struct cam_top_tpg_cfg *)tpg_res->res_priv; + soc_info = &tpg_hw->hw_info->soc_info; + + if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) || + (tpg_res->res_state != CAM_ISP_RESOURCE_STATE_RESERVED)) { + CAM_ERR(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d", + tpg_hw->hw_intf->hw_idx, + tpg_res->res_type, tpg_res->res_state); + rc = -EINVAL; + goto end; + } + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + tpg_reg->tpg_top_clear); + + for (i = 0; i < tpg_data->num_active_dts; i++) { + val = (((tpg_data->dt_cfg[i].frame_width & 0xFFFF) << 16) | + (tpg_data->dt_cfg[i].frame_height & 0xFFFF)); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_dt_0_cfg_0 + 0x60 * i); + + cam_io_w_mb(tpg_data->dt_cfg[i].data_type, + soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_dt_0_cfg_1 + 0x60 * i); + val = ((tpg_data->dt_cfg[i].encode_format & 0xF) << + tpg_reg->tpg_dt_encode_format_shift) | + tpg_reg->tpg_payload_mode_color; + + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_dt_0_cfg_2 + 0x60 * i); + + val = (1 << tpg_reg->tpg_split_en_shift); + val |= tpg_data->pix_pattern; + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_color_bar_cfg + 0x60 * i); + + /* + * if hblank is notset configureHBlank count 500 and + * V blank count is 600 + */ + + if (tpg_data->h_blank_count) + cam_io_w_mb(tpg_data->h_blank_count, + soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_hbi_cfg + 0x60 * i); + else + cam_io_w_mb(0x1F4, + soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_hbi_cfg + 0x60 * i); + + if (tpg_data->v_blank_count) + cam_io_w_mb(tpg_data->h_blank_count, + soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_vbi_cfg + 0x60 * i); + else + cam_io_w_mb(0x258, + soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_vbi_cfg + 0x60 * i); + + cam_io_w_mb(0x12345678, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_lfsr_seed + 0x60 * i); + + val = (((tpg_data->num_active_dts-1) << + tpg_reg->tpg_num_dts_shift_val) | tpg_data->vc_num[i]); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_vc0_cfg0 + 0x60 * i); + } + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_top_irq_mask); + + val = ((tpg_data->num_active_dts - 1) << + (tpg_reg->tpg_num_active_vcs_shift) | + (tpg_data->num_active_lanes - 1) << + tpg_reg->tpg_num_active_lanes_shift) | + (tpg_data->vc_dt_pattern_id) << + (tpg_reg->tpg_vc_dt_pattern_id_shift) | + (tpg_data->phy_sel << tpg_reg->tpg_cphy_dphy_sel_shift_val) | + (1 << tpg_reg->tpg_en_shift_val); + cam_io_w_mb(val, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl); + + + tpg_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING; + + val = cam_io_r_mb(soc_info->reg_map[0].mem_base + + tpg_reg->tpg_hw_version); + CAM_DBG(CAM_ISP, "TPG:%d TPG HW version: 0x%x started", + tpg_hw->hw_intf->hw_idx, val); + +end: + return rc; +} + +static int cam_top_tpg_ver3_stop( + void *hw_priv, + void *stop_args, + uint32_t arg_size) +{ + int rc = 0; + struct cam_top_tpg_hw *tpg_hw; + struct cam_hw_info *tpg_hw_info; + struct cam_hw_soc_info *soc_info; + struct cam_isp_resource_node *tpg_res; + const struct cam_top_tpg_ver3_reg_offset *tpg_reg; + struct cam_top_tpg_cfg *tpg_data; + + if (!hw_priv || !stop_args || + (arg_size != sizeof(struct cam_isp_resource_node))) { + CAM_ERR(CAM_ISP, "TPG: Invalid args"); + return -EINVAL; + } + + tpg_hw_info = (struct cam_hw_info *)hw_priv; + tpg_hw = (struct cam_top_tpg_hw *)tpg_hw_info->core_info; + tpg_reg = tpg_hw->tpg_info->tpg_reg; + tpg_res = (struct cam_isp_resource_node *) stop_args; + tpg_data = (struct cam_top_tpg_cfg *)tpg_res->res_state; + soc_info = &tpg_hw->hw_info->soc_info; + + if ((tpg_res->res_type != CAM_ISP_RESOURCE_TPG) || + (tpg_res->res_state != CAM_ISP_RESOURCE_STATE_STREAMING)) { + CAM_DBG(CAM_ISP, "TPG:%d Invalid Res type:%d res_state:%d", + tpg_hw->hw_intf->hw_idx, + tpg_res->res_type, tpg_res->res_state); + rc = -EINVAL; + goto end; + } + + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + tpg_reg->tpg_ctrl); + + cam_io_w_mb(0, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_top_irq_mask); + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_top_irq_clear); + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + + tpg_reg->tpg_top_irq_cmd); + + cam_io_w_mb(1, soc_info->reg_map[0].mem_base + tpg_reg->tpg_top_clear); + + tpg_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED; + + CAM_DBG(CAM_ISP, "TPG:%d stopped", tpg_hw->hw_intf->hw_idx); +end: + return rc; +} + +int cam_top_tpg_ver3_init( + struct cam_top_tpg_hw *tpg_hw) +{ + tpg_hw->hw_intf->hw_ops.get_hw_caps = cam_top_tpg_ver3_get_hw_caps; + tpg_hw->hw_intf->hw_ops.reserve = cam_top_tpg_ver3_reserve; + tpg_hw->hw_intf->hw_ops.start = cam_top_tpg_ver3_start; + tpg_hw->hw_intf->hw_ops.stop = cam_top_tpg_ver3_stop; + + return 0; +} diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h new file mode 100644 index 0000000000..b8853d6215 --- /dev/null +++ b/drivers/cam_isp/isp_hw_mgr/isp_hw/top_tpg/cam_top_tpg_ver3.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_TOP_TPG_VER3_H_ +#define _CAM_TOP_TPG_VER3_H_ + +#include "cam_top_tpg_core.h" + +struct cam_top_tpg_ver3_reg_offset { + uint32_t tpg_hw_version; + uint32_t tpg_hw_status; + uint32_t tpg_ctrl; + uint32_t tpg_vc0_cfg0; + uint32_t tpg_vc0_lfsr_seed; + uint32_t tpg_vc0_hbi_cfg; + uint32_t tpg_vc0_vbi_cfg; + uint32_t tpg_vc0_color_bar_cfg; + uint32_t tpg_vc0_dt_0_cfg_0; + uint32_t tpg_vc0_dt_0_cfg_1; + uint32_t tpg_vc0_dt_0_cfg_2; + uint32_t tpg_vc0_dt_1_cfg_0; + uint32_t tpg_vc0_dt_1_cfg_1; + uint32_t tpg_vc0_dt_1_cfg_2; + uint32_t tpg_vc0_dt_2_cfg_0; + uint32_t tpg_vc0_dt_2_cfg_1; + uint32_t tpg_vc0_dt_2_cfg_2; + uint32_t tpg_vc0_dt_3_cfg_0; + uint32_t tpg_vc0_dt_3_cfg_1; + uint32_t tpg_vc0_dt_3_cfg_2; + + uint32_t tpg_vc1_cfg0; + uint32_t tpg_vc1_lfsr_seed; + uint32_t tpg_vc1_hbi_cfg; + uint32_t tpg_vc1_vbi_cfg; + uint32_t tpg_vc1_color_bar_cfg; + uint32_t tpg_vc1_dt_0_cfg_0; + uint32_t tpg_vc1_dt_0_cfg_1; + uint32_t tpg_vc1_dt_0_cfg_2; + uint32_t tpg_vc1_dt_1_cfg_0; + uint32_t tpg_vc1_dt_1_cfg_1; + uint32_t tpg_vc1_dt_1_cfg_2; + uint32_t tpg_vc1_dt_2_cfg_0; + uint32_t tpg_vc1_dt_2_cfg_1; + uint32_t tpg_vc1_dt_2_cfg_2; + uint32_t tpg_vc1_dt_3_cfg_0; + uint32_t tpg_vc1_dt_3_cfg_1; + uint32_t tpg_vc1_dt_3_cfg_2; + + uint32_t tpg_vc2_cfg0; + uint32_t tpg_vc2_lfsr_seed; + uint32_t tpg_vc2_hbi_cfg; + uint32_t tpg_vc2_vbi_cfg; + uint32_t tpg_vc2_color_bar_cfg; + uint32_t tpg_vc2_dt_0_cfg_0; + uint32_t tpg_vc2_dt_0_cfg_1; + uint32_t tpg_vc2_dt_0_cfg_2; + uint32_t tpg_vc2_dt_1_cfg_0; + uint32_t tpg_vc2_dt_1_cfg_1; + uint32_t tpg_vc2_dt_1_cfg_2; + uint32_t tpg_vc2_dt_2_cfg_0; + uint32_t tpg_vc2_dt_2_cfg_1; + uint32_t tpg_vc2_dt_2_cfg_2; + uint32_t tpg_vc2_dt_3_cfg_0; + uint32_t tpg_vc2_dt_3_cfg_1; + uint32_t tpg_vc2_dt_3_cfg_2; + + uint32_t tpg_vc3_cfg0; + uint32_t tpg_vc3_lfsr_seed; + uint32_t tpg_vc3_hbi_cfg; + uint32_t tpg_vc3_vbi_cfg; + uint32_t tpg_vc3_color_bar_cfg; + uint32_t tpg_vc3_dt_0_cfg_0; + uint32_t tpg_vc3_dt_0_cfg_1; + uint32_t tpg_vc3_dt_0_cfg_2; + uint32_t tpg_vc3_dt_1_cfg_0; + uint32_t tpg_vc3_dt_1_cfg_1; + uint32_t tpg_vc3_dt_1_cfg_2; + uint32_t tpg_vc3_dt_2_cfg_0; + uint32_t tpg_vc3_dt_2_cfg_1; + uint32_t tpg_vc3_dt_2_cfg_2; + uint32_t tpg_vc3_dt_3_cfg_0; + uint32_t tpg_vc3_dt_3_cfg_1; + uint32_t tpg_vc3_dt_3_cfg_2; + uint32_t tpg_throttle; + uint32_t tpg_top_irq_status; + uint32_t tpg_top_irq_mask; + uint32_t tpg_top_irq_clear; + uint32_t tpg_top_irq_set; + uint32_t tpg_top_irq_cmd; + uint32_t tpg_top_clear; + uint32_t tpg_test_bus_crtl; + uint32_t tpg_spare; + + /* configurations */ + uint32_t major_version; + uint32_t minor_version; + uint32_t version_incr; + uint32_t tpg_en_shift_val; + uint32_t tpg_cphy_dphy_sel_shift_val; + uint32_t tpg_num_active_lanes_shift; + uint32_t tpg_fe_pkt_en_shift; + uint32_t tpg_fs_pkt_en_shift; + uint32_t tpg_line_interleaving_mode_shift; + uint32_t tpg_num_dts_shift_val; + uint32_t tpg_v_blank_cnt_shift; + uint32_t tpg_dt_encode_format_shift; + uint32_t tpg_payload_mode_color; + uint32_t tpg_split_en_shift; + uint32_t top_mux_reg_offset; + uint32_t tpg_vc_dt_pattern_id_shift; + uint32_t tpg_num_active_vcs_shift; +}; + +int cam_top_tpg_ver3_init(struct cam_top_tpg_hw *tpg_hw); + +#endif /* _CAM_TOP_TPG_VER3_H_ */ diff --git a/include/uapi/camera/media/cam_isp_ife.h b/include/uapi/camera/media/cam_isp_ife.h index f18a474bc7..28a21140d8 100644 --- a/include/uapi/camera/media/cam_isp_ife.h +++ b/include/uapi/camera/media/cam_isp_ife.h @@ -51,6 +51,7 @@ #define CAM_ISP_IFE_IN_RES_RD (CAM_ISP_IFE_IN_RES_BASE + 7) #define CAM_ISP_IFE_IN_RES_CPHY_TPG_0 (CAM_ISP_IFE_IN_RES_BASE + 8) #define CAM_ISP_IFE_IN_RES_CPHY_TPG_1 (CAM_ISP_IFE_IN_RES_BASE + 9) -#define CAM_ISP_IFE_IN_RES_MAX (CAM_ISP_IFE_IN_RES_BASE + 10) +#define CAM_ISP_IFE_IN_RES_CPHY_TPG_2 (CAM_ISP_IFE_IN_RES_BASE + 10) +#define CAM_ISP_IFE_IN_RES_MAX (CAM_ISP_IFE_IN_RES_BASE + 11) #endif /* __UAPI_CAM_ISP_IFE_H__ */