浏览代码

msm: camera: isp: Add path to port mapping

The VFE path for some output ports varies for every hardware version. By
querying for these exceptions from VFE top, we can make these mappings
more generic.

CRs-Fixed: 2918424
Change-Id: I597cb423251a722cbd09587eb23adb76c5613421
Signed-off-by: Anand Ravi <[email protected]>
Anand Ravi 4 年之前
父节点
当前提交
59c5cc8c25

+ 38 - 18
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -987,6 +987,20 @@ static const char *cam_ife_hw_mgr_get_res_state(
 	}
 }
 
+static inline bool cam_ife_hw_mgr_check_path_port_compat(
+	uint32_t in_type, uint32_t out_type)
+{
+	int i;
+	const struct cam_isp_hw_path_port_map *map = &g_ife_hw_mgr.path_port_map;
+
+	for (i = 0; i < map->num_entries; i++) {
+		if (map->entry[i][1] == out_type)
+			return (map->entry[i][0] == in_type);
+	}
+
+	return (in_type == CAM_ISP_HW_VFE_IN_CAMIF);
+}
+
 static void cam_ife_hw_mgr_dump_all_ctx(void)
 {
 	uint32_t i;
@@ -1684,8 +1698,7 @@ err:
 static int cam_ife_hw_mgr_acquire_res_ife_out_pixel(
 	struct cam_ife_hw_mgr_ctx           *ife_ctx,
 	struct cam_isp_hw_mgr_res           *ife_src_res,
-	struct cam_isp_in_port_generic_info *in_port,
-	bool                                 acquire_lcr)
+	struct cam_isp_in_port_generic_info *in_port)
 {
 	int rc = -1;
 	uint32_t  i, j, k;
@@ -1706,16 +1719,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel(
 		if (cam_ife_hw_mgr_is_rdi_res(out_port->res_type))
 			continue;
 
-		if ((acquire_lcr &&
-			out_port->res_type != CAM_ISP_IFE_OUT_RES_LCR) ||
-			(!acquire_lcr &&
-			out_port->res_type == CAM_ISP_IFE_OUT_RES_LCR))
-			continue;
-
-		if ((out_port->res_type == CAM_ISP_IFE_OUT_RES_2PD &&
-			ife_src_res->res_id != CAM_ISP_HW_VFE_IN_PDLIB) ||
-			(ife_src_res->res_id == CAM_ISP_HW_VFE_IN_PDLIB &&
-			out_port->res_type != CAM_ISP_IFE_OUT_RES_2PD))
+		if (!cam_ife_hw_mgr_check_path_port_compat(ife_src_res->res_id,
+			out_port->res_type))
 			continue;
 
 		CAM_DBG(CAM_ISP, "res_type 0x%x", out_port->res_type);
@@ -2033,12 +2038,9 @@ static int cam_ife_hw_mgr_acquire_res_ife_out(
 		case CAM_ISP_HW_VFE_IN_CAMIF:
 		case CAM_ISP_HW_VFE_IN_PDLIB:
 		case CAM_ISP_HW_VFE_IN_RD:
-			rc = cam_ife_hw_mgr_acquire_res_ife_out_pixel(ife_ctx,
-				ife_src_res, in_port, false);
-			break;
 		case CAM_ISP_HW_VFE_IN_LCR:
 			rc = cam_ife_hw_mgr_acquire_res_ife_out_pixel(ife_ctx,
-				ife_src_res, in_port, true);
+				ife_src_res, in_port);
 			break;
 		case CAM_ISP_HW_VFE_IN_RDI0:
 		case CAM_ISP_HW_VFE_IN_RDI1:
@@ -3679,9 +3681,11 @@ static int cam_ife_hw_mgr_preprocess_port(
 		}
 		else if (cam_ife_hw_mgr_is_sfe_rdi_res(out_port->res_type))
 			in_port->rdi_count++;
-		else if (out_port->res_type == CAM_ISP_IFE_OUT_RES_2PD)
+		else if (cam_ife_hw_mgr_check_path_port_compat(CAM_ISP_HW_VFE_IN_PDLIB,
+				out_port->res_type))
 			in_port->ppp_count++;
-		else if (out_port->res_type == CAM_ISP_IFE_OUT_RES_LCR)
+		else if (cam_ife_hw_mgr_check_path_port_compat(CAM_ISP_HW_VFE_IN_LCR,
+				out_port->res_type))
 			in_port->lcr_count++;
 		else {
 			CAM_DBG(CAM_ISP, "out_res_type %d",
@@ -11195,9 +11199,11 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 	struct cam_ife_hw_mgr_ctx *ctx_pool;
 	struct cam_isp_hw_mgr_res *res_list_ife_out;
 	struct cam_isp_hw_bus_cap isp_bus_cap = {0};
+	struct cam_isp_hw_path_port_map path_port_map;
 	struct cam_isp_hw_mgr_res *res_list_sfe_out;
 
 	memset(&g_ife_hw_mgr, 0, sizeof(g_ife_hw_mgr));
+	memset(&path_port_map, 0, sizeof(path_port_map));
 
 	mutex_init(&g_ife_hw_mgr.ctx_mutex);
 	spin_lock_init(&g_ife_hw_mgr.ctx_lock);
@@ -11226,6 +11232,14 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 					sizeof(struct cam_isp_hw_bus_cap));
 				CAM_DBG(CAM_ISP, "max VFE out resources: 0x%x",
 					isp_bus_cap.max_out_res_type);
+
+				ife_device->hw_ops.process_cmd(
+					vfe_hw,
+					CAM_ISP_HW_CMD_GET_PATH_PORT_MAP,
+					&path_port_map,
+					sizeof(struct cam_isp_hw_path_port_map));
+				CAM_DBG(CAM_ISP, "received %d path-port mappings",
+					path_port_map.num_entries);
 			}
 
 			j++;
@@ -11255,6 +11269,12 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 		g_ife_hw_mgr.isp_bus_caps.max_vfe_out_res_type & 0xFF;
 	memset(&isp_bus_cap, 0x0, sizeof(struct cam_isp_hw_bus_cap));
 
+	for (i = 0; i < path_port_map.num_entries; i++) {
+		g_ife_hw_mgr.path_port_map.entry[i][0] = path_port_map.entry[i][0];
+		g_ife_hw_mgr.path_port_map.entry[i][1] = path_port_map.entry[i][1];
+	}
+	g_ife_hw_mgr.path_port_map.num_entries = path_port_map.num_entries;
+
 	/* fill csid hw intf information */
 	for (i = 0, j = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
 		rc = cam_ife_csid_hw_init(&g_ife_hw_mgr.csid_devices[i], i);

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -277,6 +277,7 @@ struct cam_isp_bus_hw_caps {
  * @csid_rup_en            Reg update at CSID side
  * @csid_global_reset_en   CSID global reset enable
  * @isp_bus_caps           Capability of underlying SFE/IFE bus HW
+ * @path_port_map          Mapping of outport to IFE mux
  */
 struct cam_ife_hw_mgr {
 	struct cam_isp_hw_mgr          mgr_common;
@@ -302,6 +303,7 @@ struct cam_ife_hw_mgr {
 	bool                           csid_rup_en;
 	bool                           csid_global_reset_en;
 	struct cam_isp_bus_hw_caps     isp_bus_caps;
+	struct cam_isp_hw_path_port_map   path_port_map;
 };
 
 /**

+ 18 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -18,6 +18,8 @@
 #define CAM_ISP_HW_DUMP_TAG_MAX_LEN 32
 /* Max isp hw pid values number */
 #define CAM_ISP_HW_MAX_PID_VAL      4
+/* Maximum number of output ports that map to an architecture specific input path */
+#define CAM_ISP_HW_PATH_PORT_MAP_MAX    3
 
 /*
  * MAX len of ISP Resource Name
@@ -153,6 +155,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_CMD_BUF_UPDATE_RM,
 	CAM_ISP_HW_NOTIFY_OVERFLOW,
 	CAM_ISP_HW_CMD_IS_PDAF_RDI2_MUX_EN,
+	CAM_ISP_HW_CMD_GET_PATH_PORT_MAP,
 	CAM_ISP_HW_CMD_MAX,
 };
 
@@ -419,4 +422,19 @@ struct cam_isp_hw_bus_cap {
 	uint32_t                max_out_res_type;
 };
 
+/**
+ * struct cam_isp_hw_path_port_map:
+ *
+ * @Brief:         ISP hw bus capabilities
+ *
+ * @num_entries:  Number of entries
+ * @entry:        Each row is an entry with the following structure:
+ *                col #1: VFE IN path type
+ *                col #2: ISP OUT resource type
+ */
+struct cam_isp_hw_path_port_map {
+	uint32_t                num_entries;
+	uint32_t                entry[CAM_ISP_HW_PATH_PORT_MAP_MAX][2];
+};
+
 #endif /* _CAM_ISP_HW_H_ */

+ 3 - 13
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c

@@ -513,6 +513,8 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_CAMIF_DATA:
 	case CAM_ISP_HW_NOTIFY_OVERFLOW:
 	case CAM_ISP_HW_CMD_BLANKING_UPDATE:
+	case CAM_ISP_HW_CMD_FE_UPDATE_IN_RD:
+	case CAM_ISP_HW_CMD_GET_PATH_PORT_MAP:
 		rc = core_info->vfe_top->hw_ops.process_cmd(
 			core_info->vfe_top->top_priv, cmd_type, cmd_args,
 			arg_size);
@@ -535,23 +537,11 @@ int cam_vfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 		break;
 	case CAM_ISP_HW_CMD_GET_HFR_UPDATE_RM:
 	case CAM_ISP_HW_CMD_GET_BUF_UPDATE_RM:
-		if (core_info->vfe_rd_bus)
-			rc = core_info->vfe_rd_bus->hw_ops.process_cmd(
-				core_info->vfe_rd_bus->bus_priv, cmd_type,
-				cmd_args, arg_size);
-		break;
-
-	case CAM_ISP_HW_CMD_FE_UPDATE_IN_RD:
-		rc = core_info->vfe_top->hw_ops.process_cmd(
-			core_info->vfe_top->top_priv, cmd_type, cmd_args,
-			arg_size);
-		break;
 	case CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD:
-		if (core_info->vfe_rd_bus) {
+		if (core_info->vfe_rd_bus)
 			rc = core_info->vfe_rd_bus->hw_ops.process_cmd(
 				core_info->vfe_rd_bus->bus_priv, cmd_type,
 				cmd_args, arg_size);
-		}
 		break;
 	case CAM_ISP_HW_CMD_QUERY_REGSPACE_DATA:
 		*((struct cam_hw_soc_info **)cmd_args) = soc_info;

+ 5 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h

@@ -314,6 +314,11 @@ static struct cam_vfe_top_ver3_hw_info vfe480_top_hw_info = {
 		CAM_VFE_PDLIB_VER_1_0,
 		CAM_VFE_LCR_VER_1_0,
 	},
+	.num_path_port_map = 2,
+	.path_port_map = {
+		{CAM_ISP_HW_VFE_IN_LCR, CAM_ISP_IFE_OUT_RES_LCR},
+		{CAM_ISP_HW_VFE_IN_PDLIB, CAM_ISP_IFE_OUT_RES_2PD},
+	},
 };
 
 static struct cam_irq_register_set vfe480_bus_irq_reg[2] = {

+ 6 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe580.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 
@@ -103,6 +103,11 @@ static struct cam_vfe_top_ver3_hw_info vfe580_top_hw_info = {
 		CAM_VFE_PDLIB_VER_1_0,
 		CAM_VFE_LCR_VER_1_0,
 	},
+	.num_path_port_map = 2,
+	.path_port_map = {
+		{CAM_ISP_HW_VFE_IN_LCR, CAM_ISP_IFE_OUT_RES_LCR},
+		{CAM_ISP_HW_VFE_IN_PDLIB, CAM_ISP_IFE_OUT_RES_2PD},
+	},
 };
 
 static struct cam_vfe_hw_info cam_vfe580_hw_info = {

+ 5 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe680.h

@@ -580,6 +580,11 @@ static struct cam_vfe_top_ver4_hw_info vfe680_top_hw_info = {
 		CAM_VFE_RDI_VER_1_0,
 		CAM_VFE_PDLIB_VER_1_0,
 	},
+	.num_path_port_map = 2,
+	.path_port_map = {
+		{CAM_ISP_HW_VFE_IN_PDLIB, CAM_ISP_IFE_OUT_RES_2PD},
+		{CAM_ISP_HW_VFE_IN_PDLIB, CAM_ISP_IFE_OUT_RES_PREPROCESS_2PD}
+	}
 };
 
 static struct cam_irq_register_set vfe680_bus_irq_reg[2] = {

+ 22 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c

@@ -19,6 +19,7 @@
 #define CAM_CDM_WAIT_COMP_EVENT_BIT           0x2
 
 struct cam_vfe_top_ver3_common_data {
+	struct cam_vfe_top_ver3_hw_info            *hw_info;
 	struct cam_hw_soc_info                     *soc_info;
 	struct cam_hw_intf                         *hw_intf;
 	struct cam_vfe_top_ver3_reg_offset_common  *common_reg;
@@ -32,6 +33,22 @@ struct cam_vfe_top_ver3_priv {
 	struct cam_vfe_top_priv_common      top_common;
 };
 
+static int cam_vfe_top_ver3_get_path_port_map(struct cam_vfe_top_ver3_priv *top_priv,
+	void *cmd_args, uint32_t arg_size)
+{
+	struct cam_isp_hw_path_port_map *arg = cmd_args;
+	struct cam_vfe_top_ver3_hw_info *hw_info = top_priv->common_data.hw_info;
+	int i;
+
+	for (i = 0; i < hw_info->num_path_port_map; i++) {
+		arg->entry[i][0] = hw_info->path_port_map[i][0];
+		arg->entry[i][1] = hw_info->path_port_map[i][1];
+	}
+	arg->num_entries = hw_info->num_path_port_map;
+
+	return 0;
+}
+
 static int cam_vfe_top_ver3_mux_get_base(struct cam_vfe_top_ver3_priv *top_priv,
 	void *cmd_args, uint32_t arg_size)
 {
@@ -792,6 +809,10 @@ int cam_vfe_top_ver3_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_vfe_top_ver3_blanking_update(cmd_type,
 			cmd_args, arg_size);
 		break;
+	case CAM_ISP_HW_CMD_GET_PATH_PORT_MAP:
+		rc = cam_vfe_top_ver3_get_path_port_map(top_priv, cmd_args,
+			arg_size);
+		break;
 	default:
 		rc = -EINVAL;
 		CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type);
@@ -838,6 +859,7 @@ int cam_vfe_top_ver3_init(
 	}
 
 	top_priv->top_common.num_mux = ver3_hw_info->num_mux;
+	top_priv->common_data.hw_info = top_hw_info;
 
 	for (i = 0, j = 0; i < top_priv->top_common.num_mux &&
 		j < CAM_VFE_RDI_VER2_MAX; i++) {

+ 3 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_VFE_TOP_VER3_H_
@@ -86,7 +86,9 @@ struct cam_vfe_top_ver3_hw_info {
 	struct cam_vfe_camif_lite_ver3_hw_info      lcr_hw_info;
 	struct cam_vfe_fe_ver1_hw_info              fe_hw_info;
 	uint32_t                                    num_mux;
+	uint32_t                                    num_path_port_map;
 	uint32_t mux_type[CAM_VFE_TOP_MUX_MAX];
+	uint32_t path_port_map[CAM_ISP_HW_PATH_PORT_MAP_MAX][2];
 };
 
 int cam_vfe_top_ver3_init(struct cam_hw_soc_info     *soc_info,

+ 20 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

@@ -671,6 +671,22 @@ static const struct cam_vfe_top_debug_info vfe_dbg_list[][8] = {
 	},
 };
 
+static int cam_vfe_top_ver4_get_path_port_map(struct cam_vfe_top_ver4_priv *top_priv,
+	void *cmd_args, uint32_t arg_size)
+{
+	struct cam_isp_hw_path_port_map *arg = cmd_args;
+	struct cam_vfe_top_ver4_hw_info *hw_info = top_priv->common_data.hw_info;
+	int i;
+
+	for (i = 0; i < hw_info->num_path_port_map; i++) {
+		arg->entry[i][0] = hw_info->path_port_map[i][0];
+		arg->entry[i][1] = hw_info->path_port_map[i][1];
+	}
+	arg->num_entries = hw_info->num_path_port_map;
+
+	return 0;
+}
+
 static int cam_vfe_top_ver4_mux_get_base(struct cam_vfe_top_ver4_priv *top_priv,
 	void *cmd_args, uint32_t arg_size)
 {
@@ -1491,6 +1507,10 @@ int cam_vfe_top_ver4_process_cmd(void *device_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_CORE_CONFIG:
 		rc = cam_vfe_core_config_control(top_priv, cmd_args, arg_size);
 		break;
+	case CAM_ISP_HW_CMD_GET_PATH_PORT_MAP:
+		rc = cam_vfe_top_ver4_get_path_port_map(top_priv, cmd_args,
+			arg_size);
+		break;
 	default:
 		rc = -EINVAL;
 		CAM_ERR(CAM_ISP, "Error, Invalid cmd:%d", cmd_type);

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.h

@@ -99,7 +99,9 @@ struct cam_vfe_top_ver4_hw_info {
 	struct cam_vfe_top_camnoc_debug_data       *camnoc_debug_data;
 	uint32_t                                    num_reg;
 	uint32_t                                    num_mux;
+	uint32_t                                    num_path_port_map;
 	uint32_t mux_type[CAM_VFE_TOP_MUX_MAX];
+	uint32_t path_port_map[CAM_ISP_HW_PATH_PORT_MAP_MAX][2];
 };
 
 struct cam_vfe_ver4_path_reg_data {