Browse Source

msm: camera: common: presil change for soc util

Add code to call presil apis related to IRQ and
reg base remap.

CRs-Fixed: 2932495
Change-Id: Ibe3c4da806bfe84c306bc71bfe2150e2caac55b1
Signed-off-by: Suraj Dongre <[email protected]>
Signed-off-by: Mukund Madhusudan Atre <[email protected]>
Suraj Dongre 4 years ago
parent
commit
d6e8c46024
1 changed files with 194 additions and 16 deletions
  1. 194 16
      drivers/cam_utils/cam_soc_util.c

+ 194 - 16
drivers/cam_utils/cam_soc_util.c

@@ -12,12 +12,17 @@
 #include "cam_debug_util.h"
 #include "cam_debug_util.h"
 #include "cam_cx_ipeak.h"
 #include "cam_cx_ipeak.h"
 #include "cam_mem_mgr.h"
 #include "cam_mem_mgr.h"
+#include "cam_presil_hw_access.h"
+
 
 
 #define CAM_TO_MASK(bitn)          (1 << (int)(bitn))
 #define CAM_TO_MASK(bitn)          (1 << (int)(bitn))
 #define CAM_IS_BIT_SET(mask, bit)  ((mask) & CAM_TO_MASK(bit))
 #define CAM_IS_BIT_SET(mask, bit)  ((mask) & CAM_TO_MASK(bit))
 #define CAM_SET_BIT(mask, bit)     ((mask) |= CAM_TO_MASK(bit))
 #define CAM_SET_BIT(mask, bit)     ((mask) |= CAM_TO_MASK(bit))
 #define CAM_CLEAR_BIT(mask, bit)   ((mask) &= ~CAM_TO_MASK(bit))
 #define CAM_CLEAR_BIT(mask, bit)   ((mask) &= ~CAM_TO_MASK(bit))
 
 
+#define CAM_SS_START_PRESIL 0x08c00000
+#define CAM_SS_START        0x0ac00000
+
 static uint skip_mmrm_set_rate;
 static uint skip_mmrm_set_rate;
 module_param(skip_mmrm_set_rate, uint, 0644);
 module_param(skip_mmrm_set_rate, uint, 0644);
 
 
@@ -1977,6 +1982,11 @@ static int cam_soc_util_get_dt_regulator_info
 	return rc;
 	return rc;
 }
 }
 
 
+#ifdef CONFIG_CAM_PRESIL
+static uint32_t next_dummy_irq_line_num = 0x000f;
+struct resource dummy_irq_line[512];
+#endif
+
 int cam_soc_util_get_dt_properties(struct cam_hw_soc_info *soc_info)
 int cam_soc_util_get_dt_properties(struct cam_hw_soc_info *soc_info)
 {
 {
 	struct device_node *of_node = NULL;
 	struct device_node *of_node = NULL;
@@ -2046,11 +2056,21 @@ int cam_soc_util_get_dt_properties(struct cam_hw_soc_info *soc_info)
 			IORESOURCE_IRQ, soc_info->irq_name);
 			IORESOURCE_IRQ, soc_info->irq_name);
 		if (!soc_info->irq_line) {
 		if (!soc_info->irq_line) {
 			CAM_ERR(CAM_UTIL, "no irq resource");
 			CAM_ERR(CAM_UTIL, "no irq resource");
+#ifndef CONFIG_CAM_PRESIL
 			rc = -ENODEV;
 			rc = -ENODEV;
 			return rc;
 			return rc;
+#else
+			/* Pre-sil for new devices not present on old */
+			soc_info->irq_line =
+				&dummy_irq_line[next_dummy_irq_line_num++];
+			CAM_DBG(CAM_PRESIL, "interrupt line for dev %s irq name %s number %d",
+				soc_info->dev_name, soc_info->irq_name,
+				soc_info->irq_line->start);
+#endif
 		}
 		}
 	}
 	}
 
 
+
 	rc = of_property_read_string_index(of_node, "compatible", 0,
 	rc = of_property_read_string_index(of_node, "compatible", 0,
 		(const char **)&soc_info->compatible);
 		(const char **)&soc_info->compatible);
 	if (rc) {
 	if (rc) {
@@ -2416,6 +2436,156 @@ disable_rgltr:
 	return rc;
 	return rc;
 }
 }
 
 
+static bool cam_soc_util_is_presil_address_space(unsigned long mem_block_start)
+{
+	if(mem_block_start >= CAM_SS_START_PRESIL && mem_block_start < CAM_SS_START)
+		return true;
+
+	return false;
+}
+
+#ifndef CONFIG_CAM_PRESIL
+void __iomem * cam_soc_util_get_mem_base(
+	unsigned long mem_block_start,
+	unsigned long mem_block_size,
+	const char *mem_block_name,
+	uint32_t reserve_mem)
+{
+	void __iomem * mem_base;
+
+	if (reserve_mem) {
+		if (!request_mem_region(mem_block_start,
+			mem_block_size,
+			mem_block_name)) {
+			CAM_ERR(CAM_UTIL,
+				"Error Mem region request Failed:%s",
+				mem_block_name);
+			return NULL;
+		}
+	}
+
+	mem_base = ioremap(mem_block_start, mem_block_size);
+
+	if (!mem_base) {
+		CAM_ERR(CAM_UTIL, "get mem base failed");
+	}
+
+	return mem_base;
+}
+
+int cam_soc_util_request_irq(struct device *dev,
+	unsigned int irq_line_start,
+	irq_handler_t handler,
+	unsigned long irqflags,
+	const char *irq_name,
+	void *irq_data,
+	unsigned long mem_block_start)
+{
+	int rc;
+
+	rc = devm_request_irq(dev,
+		irq_line_start,
+		handler,
+		IRQF_TRIGGER_RISING,
+		irq_name,
+		irq_data);
+	if (rc) {
+		CAM_ERR(CAM_UTIL, "irq request fail rc %d", rc);
+		return -EBUSY;
+	}
+
+	disable_irq(irq_line_start);
+
+	return rc;
+}
+
+#else
+void __iomem * cam_soc_util_get_mem_base(
+	unsigned long mem_block_start,
+	unsigned long mem_block_size,
+	const char *mem_block_name,
+	uint32_t reserve_mem)
+{
+	void __iomem * mem_base;
+
+	if(cam_soc_util_is_presil_address_space(mem_block_start))
+		mem_base = (void __iomem *)mem_block_start;
+	else {
+		if (reserve_mem) {
+			if (!request_mem_region(mem_block_start,
+				mem_block_size,
+				mem_block_name)) {
+				CAM_ERR(CAM_UTIL,
+					"Error Mem region request Failed:%s",
+					mem_block_name);
+				return NULL;
+			}
+		}
+
+		mem_base = ioremap(mem_block_start, mem_block_size);
+	}
+
+	if (!mem_base) {
+		CAM_ERR(CAM_UTIL, "get mem base failed");
+	}
+
+	return mem_base;
+}
+
+int cam_soc_util_request_irq(struct device *dev,
+	unsigned int irq_line_start,
+	irq_handler_t handler,
+	unsigned long irqflags,
+	const char *irq_name,
+	void *irq_data,
+	unsigned long mem_block_start)
+{
+	int rc;
+
+	if(cam_soc_util_is_presil_address_space(mem_block_start)) {
+		rc = devm_request_irq(dev,
+			irq_line_start,
+			handler,
+			irqflags,
+			irq_name,
+			irq_data);
+		if (rc) {
+			CAM_ERR(CAM_UTIL, "presil irq request fail");
+			return -EBUSY;
+		}
+
+		disable_irq(irq_line_start);
+
+		rc = !(cam_presil_subscribe_device_irq(irq_line_start,
+			handler, irq_data, irq_name));
+		CAM_DBG(CAM_PRESIL, "Subscribe presil IRQ: rc=%d NUM=%d Name=%s handler=0x%x",
+			rc, irq_line_start, irq_name, handler);
+		if (rc) {
+			CAM_ERR(CAM_UTIL, "presil irq request fail");
+			return -EBUSY;
+		}
+	} else {
+		rc = devm_request_irq(dev,
+			irq_line_start,
+			handler,
+			irqflags,
+			irq_name,
+			irq_data);
+		if (rc) {
+			CAM_ERR(CAM_UTIL, "irq request fail");
+			return -EBUSY;
+		}
+		disable_irq(irq_line_start);
+		CAM_INFO(CAM_UTIL, "Subscribe for non-presil IRQ success");
+	}
+
+	CAM_INFO(CAM_UTIL, "returning IRQ for mem_block_start 0x%0x rc %d",
+		mem_block_start, rc);
+
+	return rc;
+}
+#endif
+
 int cam_soc_util_request_platform_resource(
 int cam_soc_util_request_platform_resource(
 	struct cam_hw_soc_info *soc_info,
 	struct cam_hw_soc_info *soc_info,
 	irq_handler_t handler, void *irq_data)
 	irq_handler_t handler, void *irq_data)
@@ -2428,29 +2598,24 @@ int cam_soc_util_request_platform_resource(
 	}
 	}
 
 
 	for (i = 0; i < soc_info->num_mem_block; i++) {
 	for (i = 0; i < soc_info->num_mem_block; i++) {
-		if (soc_info->reserve_mem) {
-			if (!request_mem_region(soc_info->mem_block[i]->start,
-				resource_size(soc_info->mem_block[i]),
-				soc_info->mem_block_name[i])){
-				CAM_ERR(CAM_UTIL,
-					"Error Mem region request Failed:%s",
-					soc_info->mem_block_name[i]);
-				rc = -ENOMEM;
-				goto unmap_base;
-			}
-		}
-		soc_info->reg_map[i].mem_base = ioremap(
+
+		soc_info->reg_map[i].mem_base = cam_soc_util_get_mem_base(
 			soc_info->mem_block[i]->start,
 			soc_info->mem_block[i]->start,
-			resource_size(soc_info->mem_block[i]));
+			resource_size(soc_info->mem_block[i]),
+			soc_info->mem_block_name[i],
+			soc_info->reserve_mem);
+
 		if (!soc_info->reg_map[i].mem_base) {
 		if (!soc_info->reg_map[i].mem_base) {
 			CAM_ERR(CAM_UTIL, "i= %d base NULL", i);
 			CAM_ERR(CAM_UTIL, "i= %d base NULL", i);
 			rc = -ENOMEM;
 			rc = -ENOMEM;
 			goto unmap_base;
 			goto unmap_base;
 		}
 		}
+
 		soc_info->reg_map[i].mem_cam_base =
 		soc_info->reg_map[i].mem_cam_base =
 			soc_info->mem_block_cam_base[i];
 			soc_info->mem_block_cam_base[i];
 		soc_info->reg_map[i].size =
 		soc_info->reg_map[i].size =
 			resource_size(soc_info->mem_block[i]);
 			resource_size(soc_info->mem_block[i]);
+
 		soc_info->num_reg_map++;
 		soc_info->num_reg_map++;
 	}
 	}
 
 
@@ -2468,15 +2633,18 @@ int cam_soc_util_request_platform_resource(
 	}
 	}
 
 
 	if (soc_info->irq_line) {
 	if (soc_info->irq_line) {
-		rc = devm_request_irq(soc_info->dev, soc_info->irq_line->start,
+
+		rc = cam_soc_util_request_irq(soc_info->dev,
+			soc_info->irq_line->start,
 			handler, IRQF_TRIGGER_RISING,
 			handler, IRQF_TRIGGER_RISING,
-			soc_info->irq_name, irq_data);
+			soc_info->irq_name, irq_data,
+			soc_info->mem_block[0]->start);
 		if (rc) {
 		if (rc) {
 			CAM_ERR(CAM_UTIL, "irq request fail");
 			CAM_ERR(CAM_UTIL, "irq request fail");
 			rc = -EBUSY;
 			rc = -EBUSY;
 			goto put_regulator;
 			goto put_regulator;
 		}
 		}
-		disable_irq(soc_info->irq_line->start);
+
 		soc_info->irq_data = irq_data;
 		soc_info->irq_data = irq_data;
 	}
 	}
 
 
@@ -2604,6 +2772,7 @@ unmap_base:
 int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info)
 int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info)
 {
 {
 	int i;
 	int i;
+	bool b_ret = false;
 
 
 	if (!soc_info || !soc_info->dev) {
 	if (!soc_info || !soc_info->dev) {
 		CAM_ERR(CAM_UTIL, "Invalid parameter");
 		CAM_ERR(CAM_UTIL, "Invalid parameter");
@@ -2638,6 +2807,15 @@ int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info)
 	}
 	}
 
 
 	if (soc_info->irq_line) {
 	if (soc_info->irq_line) {
+		if (cam_presil_mode_enabled()) {
+			if (cam_soc_util_is_presil_address_space(soc_info->mem_block[0]->start)) {
+				b_ret = cam_presil_unsubscribe_device_irq(
+					soc_info->irq_line->start);
+				CAM_DBG(CAM_PRESIL, "UnSubscribe IRQ: Ret=%d NUM=%d Name=%s",
+					b_ret, soc_info->irq_line->start, soc_info->irq_name);
+			}
+		}
+
 		disable_irq(soc_info->irq_line->start);
 		disable_irq(soc_info->irq_line->start);
 		devm_free_irq(soc_info->dev,
 		devm_free_irq(soc_info->dev,
 			soc_info->irq_line->start, soc_info->irq_data);
 			soc_info->irq_line->start, soc_info->irq_data);