Procházet zdrojové kódy

msm: camera: icp: Domain-id support for non secure FW loads

For non secure FW loads, ICP domain mask config registers will
not be protected and is accessible from HLOS, so we are to
program these registers with the correct mask values. These
will then be validated with the domain id value passed over
from userland.

CRs-Fixed: 3249982
Change-Id: I1440dde67f6e7a4b58b482d6c3964d19cdb33967
Signed-off-by: Li Sha Lim <[email protected]>
Li Sha Lim před 3 roky
rodič
revize
53b771ccfe

+ 54 - 7
drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c

@@ -315,6 +315,13 @@ static int __cam_icp_v2_power_collapse(struct cam_hw_info *icp_v2_info)
 
 	core_info = icp_v2_info->core_info;
 	sys_base_idx = core_info->reg_base_idx[ICP_V2_SYS_BASE];
+
+	if (sys_base_idx < 0) {
+		CAM_ERR(CAM_ICP, "No reg base idx found for ICP_SYS: %d",
+			sys_base_idx);
+		return -EINVAL;
+	}
+
 	base = icp_v2_info->soc_info.reg_map[sys_base_idx].mem_base;
 
 	/**
@@ -334,11 +341,11 @@ static int __cam_icp_v2_power_collapse(struct cam_hw_info *icp_v2_info)
 	return 0;
 }
 
-/* Used if ICP_SYS is not protected */
+/* Used if ICP_SYS and ICP_DOM_MASK are not protected */
 static int __cam_icp_v2_power_resume(struct cam_hw_info *icp_v2_info)
 {
-	int32_t sys_base_idx;
-	void __iomem *base;
+	int32_t sys_base_idx, dom_mask_base_idx;
+	void __iomem *sys_base, *dom_mask_base;
 	struct cam_icp_soc_info     *soc_priv;
 	struct cam_hw_soc_info      *soc_info;
 	struct cam_icp_v2_core_info *core_info = NULL;
@@ -352,16 +359,38 @@ static int __cam_icp_v2_power_resume(struct cam_hw_info *icp_v2_info)
 	core_info = icp_v2_info->core_info;
 	soc_priv = soc_info->soc_private;
 	sys_base_idx = core_info->reg_base_idx[ICP_V2_SYS_BASE];
-	base = icp_v2_info->soc_info.reg_map[sys_base_idx].mem_base;
+	dom_mask_base_idx = core_info->reg_base_idx[ICP_V2_DOM_MASK_BASE];
+
+	if (sys_base_idx < 0) {
+		CAM_ERR(CAM_ICP, "No reg base idx found for ICP_SYS: %d",
+			sys_base_idx);
+		return -EINVAL;
+	}
+
+	sys_base = icp_v2_info->soc_info.reg_map[sys_base_idx].mem_base;
 
 	cam_io_w_mb(ICP_V2_FUNC_RESET,
-		base + ICP_V2_SYS_RESET);
+		sys_base + ICP_V2_SYS_RESET);
 
 	if (soc_priv->qos_val)
-		cam_io_w_mb(soc_priv->qos_val, base + ICP_V2_SYS_ACCESS);
+		cam_io_w_mb(soc_priv->qos_val, sys_base + ICP_V2_SYS_ACCESS);
+
+	/* Program domain ID reg mask values if reg base is available */
+	if (dom_mask_base_idx >= 0) {
+		dom_mask_base = icp_v2_info->soc_info.reg_map[dom_mask_base_idx].mem_base;
+
+		CAM_DBG(CAM_ICP, "domain_cfg0, offset: 0x%x: 0x%x, domain_cfg1, offset: 0x%x: 0x%x",
+			ICP_V2_DOM_0_CFG_OFFSET, ICP_V2_DOMAIN_MASK_CFG_0,
+			ICP_V2_DOM_1_CFG_OFFSET, ICP_V2_DOMAIN_MASK_CFG_1);
+
+		cam_io_w_mb(ICP_V2_DOMAIN_MASK_CFG_0,
+			dom_mask_base + ICP_V2_DOM_0_CFG_OFFSET);
+		cam_io_w_mb(ICP_V2_DOMAIN_MASK_CFG_1,
+			dom_mask_base + ICP_V2_DOM_1_CFG_OFFSET);
+	}
 
 	cam_io_w_mb(ICP_V2_EN_CPU,
-		base + ICP_V2_SYS_CONTROL);
+		sys_base + ICP_V2_SYS_CONTROL);
 
 	return 0;
 }
@@ -672,6 +701,12 @@ static int cam_icp_v2_shutdown(struct cam_hw_info *icp_v2_info)
 		int32_t sys_base_idx = core_info->reg_base_idx[ICP_V2_SYS_BASE];
 		void __iomem *base;
 
+		if (sys_base_idx < 0) {
+			CAM_ERR(CAM_ICP, "No reg base idx found for ICP_SYS: %d",
+				sys_base_idx);
+			return -EINVAL;
+		}
+
 		base = icp_v2_info->soc_info.reg_map[sys_base_idx].mem_base;
 		cam_io_w_mb(0x0, base + ICP_V2_SYS_CONTROL);
 	}
@@ -1110,6 +1145,18 @@ static int cam_icp_v2_setup_register_base_indexes(
 		regbase_index[ICP_V2_SYS_BASE] = -1;
 	}
 
+	/* optional - for non secure FW loading */
+	rc = cam_common_util_get_string_index(soc_info->mem_block_name,
+		soc_info->num_mem_block, "icp_dom_mask", &index);
+	if ((rc == 0) && (index < num_reg_map)) {
+		regbase_index[ICP_V2_DOM_MASK_BASE] = index;
+	} else {
+		CAM_DBG(CAM_ICP,
+			"Failed to get index for icp_dom_mask, rc: %d index: %u num_reg_map: %u",
+			rc, index, num_reg_map);
+		regbase_index[ICP_V2_DOM_MASK_BASE] = -1;
+	}
+
 	return 0;
 }
 

+ 5 - 0
drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.h

@@ -15,11 +15,16 @@
 #define UNSUPPORTED_PROC_PAS_ID   30
 #define CAM_FW_PAS_ID             33
 
+/* Domain ID masks */
+#define ICP_V2_DOMAIN_MASK_CFG_0 0x00FF00FF
+#define ICP_V2_DOMAIN_MASK_CFG_1 0xFF00FF00
+
 enum cam_icp_v2_reg_base {
 	ICP_V2_CSR_BASE,
 	ICP_V2_CIRQ_BASE,
 	ICP_V2_WD0_BASE,
 	ICP_V2_SYS_BASE,
+	ICP_V2_DOM_MASK_BASE,
 	ICP_V2_BASE_MAX,
 };
 

+ 4 - 0
drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_reg.h

@@ -37,6 +37,10 @@ struct cam_icp_v2_hw_info {
 #define ICP_V2_WD_CTRL        0x8
 #define ICP_V2_WD_INTCLR      0xC
 
+/* ICP DOM_MASK reg space */
+#define ICP_V2_DOM_0_CFG_OFFSET    0x0
+#define ICP_V2_DOM_1_CFG_OFFSET    0x20
+
 /* These bitfields are shared by OB_MASK, OB_CLEAR, OB_STATUS */
 #define ICP_V2_WDT_BITE_WS1       (1 << 6)
 #define ICP_V2_WDT_BARK_WS1       (1 << 5)