Răsfoiți Sursa

Merge "msm: camera: icp: Adapt HFI to processor specific irq management" into camera-kernel.lnx.4.0

Camera Software Integration 4 ani în urmă
părinte
comite
6272ed41ba

+ 15 - 3
drivers/cam_icp/fw_inc/hfi_intf.h

@@ -49,6 +49,16 @@ struct hfi_mem_info {
 	void __iomem *icp_base;
 };
 
+/**
+ * struct hfi_ops
+ * @irq_raise: called to raise H2ICP interrupt
+ * @irq_enable: called to enable interrupts from ICP
+ */
+struct hfi_ops {
+	void (*irq_raise)(void *data);
+	void (*irq_enable)(void *data);
+};
+
 /**
  * hfi_write_cmd() - function for hfi write
  * @cmd_ptr: pointer to command data for hfi write
@@ -70,14 +80,16 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, uint32_t *words_read);
 
 /**
  * hfi_init() - function initialize hfi after firmware download
- * @event_driven_mode: event mode
  * @hfi_mem: hfi memory info
+ * @hfi_ops: processor-specific hfi ops
+ * @priv: device private data
+ * @event_driven_mode: event mode
  * @icp_base: icp base address
  *
  * Returns success(zero)/failure(non zero)
  */
-int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
-	void *__iomem icp_base);
+int cam_hfi_init(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
+		void *priv, uint8_t event_driven_mode, void *__iomem icp_base);
 
 /**
  * hfi_get_hw_caps() - hardware capabilities from firmware

+ 4 - 15
drivers/cam_icp/fw_inc/hfi_reg.h

@@ -11,8 +11,6 @@
 
 /* start of ICP CSR registers */
 #define HFI_REG_A5_HW_VERSION                   0x0
-#define HFI_REG_A5_CSR_A2HOSTINTEN              0x10
-#define HFI_REG_A5_CSR_HOST2ICPINT              0x30
 
 /* general purpose registers from */
 #define HFI_REG_FW_VERSION                      0x44
@@ -97,19 +95,6 @@ enum reg_settings {
 	SET_WM = 1024
 };
 
-/**
- * @INTR_DISABLE: Disable interrupt
- * @INTR_ENABLE: Enable interrupt
- * @INTR_ENABLE_WD0: Enable WD0
- * @INTR_ENABLE_WD1: Enable WD1
- */
-enum intr_status {
-	INTR_DISABLE,
-	INTR_ENABLE,
-	INTR_ENABLE_WD0,
-	INTR_ENABLE_WD1 = 0x4
-};
-
 /**
  * @ICP_INIT_RESP_RESET: reset init state
  * @ICP_INIT_RESP_SUCCESS: init success
@@ -284,6 +269,7 @@ struct hfi_qtbl {
 /**
  * struct hfi_info
  * @map: Hfi shared memory info
+ * @ops: processor-specific ops
  * @smem_size: Shared memory size
  * @uncachedheap_size: uncached heap size
  * @msgpacket_buf: message buffer
@@ -293,9 +279,11 @@ struct hfi_qtbl {
  * @mutex msg_q_lock: Lock for message queue
  * @msg_q_state: State of message queue
  * @csr_base: CSR base address
+ * @priv: device private data
  */
 struct hfi_info {
 	struct hfi_mem_info map;
+	struct hfi_ops ops;
 	uint32_t smem_size;
 	uint32_t uncachedheap_size;
 	uint32_t msgpacket_buf[ICP_HFI_MAX_MSG_SIZE_IN_WORDS];
@@ -305,6 +293,7 @@ struct hfi_info {
 	struct mutex msg_q_lock;
 	bool msg_q_state;
 	void __iomem *csr_base;
+	void *priv;
 };
 
 #endif /* _CAM_HFI_REG_H_ */

+ 27 - 8
drivers/cam_icp/hfi.c

@@ -39,6 +39,18 @@ unsigned int g_icp_mmu_hdl;
 static DEFINE_MUTEX(hfi_cmd_q_mutex);
 static DEFINE_MUTEX(hfi_msg_q_mutex);
 
+static void hfi_irq_raise(struct hfi_info *hfi)
+{
+	if (hfi->ops.irq_raise)
+		hfi->ops.irq_raise(hfi->priv);
+}
+
+static void hfi_irq_enable(struct hfi_info *hfi)
+{
+	if (hfi->ops.irq_enable)
+		hfi->ops.irq_enable(hfi->priv);
+}
+
 void cam_hfi_queue_dump(void)
 {
 	struct hfi_qtbl *qtbl;
@@ -160,8 +172,7 @@ int hfi_write_cmd(void *cmd_ptr)
 	 * firmware to process
 	 */
 	wmb();
-	cam_io_w_mb((uint32_t)INTR_ENABLE,
-		g_hfi->csr_base + HFI_REG_A5_CSR_HOST2ICPINT);
+	hfi_irq_raise(g_hfi);
 err:
 	mutex_unlock(&hfi_cmd_q_mutex);
 	return rc;
@@ -554,8 +565,7 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem, void __iomem *icp_base)
 		return -ETIMEDOUT;
 	}
 
-	cam_io_w_mb((uint32_t)(INTR_ENABLE|INTR_ENABLE_WD0),
-		icp_base + HFI_REG_A5_CSR_A2HOSTINTEN);
+	hfi_irq_enable(g_hfi);
 
 	fw_version = cam_io_r(icp_base + HFI_REG_FW_VERSION);
 	CAM_DBG(CAM_HFI, "fw version : [%x]", fw_version);
@@ -592,8 +602,8 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem, void __iomem *icp_base)
 	return rc;
 }
 
-int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
-		void __iomem *icp_base)
+int cam_hfi_init(struct hfi_mem_info *hfi_mem, struct hfi_ops *hfi_ops,
+		void *priv, uint8_t event_driven_mode, void __iomem *icp_base)
 {
 	int rc = 0;
 	struct hfi_qtbl *qtbl;
@@ -602,6 +612,13 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
 	uint32_t hw_version, fw_version, status = 0;
 	struct sfr_buf *sfr_buffer;
 
+	if (!hfi_mem || !hfi_ops || !priv) {
+		CAM_ERR(CAM_HFI,
+			"invalid arg: hfi_mem=%pK hfi_ops=%pK priv=%pK",
+			hfi_mem, hfi_ops, priv);
+		return -EINVAL;
+	}
+
 	mutex_lock(&hfi_cmd_q_mutex);
 	mutex_lock(&hfi_msg_q_mutex);
 
@@ -784,8 +801,10 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
 	g_hfi->hfi_state = HFI_READY;
 	g_hfi->cmd_q_state = true;
 	g_hfi->msg_q_state = true;
-	cam_io_w_mb((uint32_t)(INTR_ENABLE|INTR_ENABLE_WD0),
-		icp_base + HFI_REG_A5_CSR_A2HOSTINTEN);
+	g_hfi->ops = *hfi_ops;
+	g_hfi->priv = priv;
+
+	hfi_irq_enable(g_hfi);
 
 	mutex_unlock(&hfi_cmd_q_mutex);
 	mutex_unlock(&hfi_msg_q_mutex);

+ 28 - 0
drivers/cam_icp/icp_hw/a5_hw/a5_core.c

@@ -485,6 +485,34 @@ irqreturn_t cam_a5_irq(int irq_num, void *data)
 	return IRQ_HANDLED;
 }
 
+void cam_a5_irq_raise(void *priv)
+{
+	struct cam_hw_info *a5_info = priv;
+
+	if (!a5_info) {
+		CAM_ERR(CAM_ICP, "invalid A5 device info");
+		return;
+	}
+
+	cam_io_w_mb(A5_HOSTINT,
+		a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base +
+		ICP_SIERRA_A5_CSR_HOST2ICPINT);
+}
+
+void cam_a5_irq_enable(void *priv)
+{
+	struct cam_hw_info *a5_info = priv;
+
+	if (!a5_info) {
+		CAM_ERR(CAM_ICP, "invalid A5 device info");
+		return;
+	}
+
+	cam_io_w_mb(A5_WDT_WS0EN | A5_A2HOSTINTEN,
+		a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base +
+		ICP_SIERRA_A5_CSR_A2HOSTINTEN);
+}
+
 int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
 	void *cmd_args, uint32_t arg_size)
 {

+ 4 - 1
drivers/cam_icp/icp_hw/a5_hw/a5_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_A5_CORE_H
@@ -81,6 +81,9 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
 
 irqreturn_t cam_a5_irq(int irq_num, void *data);
 
+void cam_a5_irq_raise(void *priv);
+void cam_a5_irq_enable(void *priv);
+
 /**
  * @brief : API to register a5 hw to platform framework.
  * @return struct platform_device pointer on on success, or ERR_PTR() on error.

+ 8 - 0
drivers/cam_icp/icp_hw/a5_hw/a5_reg.h

@@ -23,6 +23,14 @@
 				A5_CSR_WAKE_UP_EN | \
 				A5_CSR_EN_CLKGATE_WFI)
 
+#define ICP_SIERRA_A5_CSR_A2HOSTINTEN   0x10
+#define A5_WDT_WS1EN                    (1 << 2)
+#define A5_WDT_WS0EN                    (1 << 1)
+#define A5_A2HOSTINTEN                  (1 << 0)
+
+#define ICP_SIERRA_A5_CSR_HOST2ICPINT   0x30
+#define A5_HOSTINT                      (1 << 0)
+
 #define ICP_SIERRA_A5_CSR_A5_STATUS     0x200
 #define A5_CSR_A5_STANDBYWFI            (1 << 7)
 

+ 6 - 2
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -3624,6 +3624,7 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
 	struct cam_hw_intf *a5_dev_intf = NULL;
 	struct cam_hw_info *a5_dev = NULL;
 	struct hfi_mem_info hfi_mem;
+	struct hfi_ops hfi_ops;
 
 	a5_dev_intf = hw_mgr->a5_dev_intf;
 	if (!a5_dev_intf) {
@@ -3688,8 +3689,11 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
 		hfi_mem.io_mem2.len = 0x0;
 	}
 
-	return cam_hfi_init(0, &hfi_mem,
-		a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
+	hfi_ops.irq_raise = cam_a5_irq_raise;
+	hfi_ops.irq_enable = cam_a5_irq_enable;
+
+	return cam_hfi_init(&hfi_mem, &hfi_ops, a5_dev, 0,
+			a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base);
 }
 
 static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)