浏览代码

Merge "msm: camera: icp: hfi adaptation for presil mode" into camera-kernel.lnx.6.0

Camera Software Integration 3 年之前
父节点
当前提交
de4126c3a8

+ 123 - 2
drivers/cam_icp/hfi.c

@@ -12,6 +12,7 @@
 #include <media/cam_icp.h>
 #include <linux/iopoll.h>
 
+#include "cam_presil_hw_access.h"
 #include "cam_io_util.h"
 #include "hfi_reg.h"
 #include "hfi_sys_defs.h"
@@ -20,6 +21,7 @@
 #include "cam_icp_hw_mgr_intf.h"
 #include "cam_debug_util.h"
 #include "cam_compat.h"
+#include "cam_soc_util.h"
 
 #define HFI_VERSION_INFO_MAJOR_VAL  1
 #define HFI_VERSION_INFO_MINOR_VAL  1
@@ -42,11 +44,16 @@ unsigned int g_icp_mmu_hdl;
 static DEFINE_MUTEX(hfi_cmd_q_mutex);
 static DEFINE_MUTEX(hfi_msg_q_mutex);
 
+static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem);
+static int cam_hfi_presil_set_init_request(void);
+
+#ifndef CONFIG_CAM_PRESIL
 static void hfi_irq_raise(struct hfi_info *hfi)
 {
 	if (hfi->ops.irq_raise)
 		hfi->ops.irq_raise(hfi->priv);
 }
+#endif
 
 static void hfi_irq_enable(struct hfi_info *hfi)
 {
@@ -162,6 +169,7 @@ void cam_hfi_queue_dump(void)
 	hfi_queue_dump(dwords, num_dwords);
 }
 
+#ifndef CONFIG_CAM_PRESIL
 int hfi_write_cmd(void *cmd_ptr)
 {
 	uint32_t size_in_words, empty_space, new_write_idx, read_idx, temp;
@@ -348,6 +356,7 @@ err:
 	mutex_unlock(&hfi_msg_q_mutex);
 	return rc;
 }
+#endif /* #ifndef CONFIG_CAM_PRESIL */
 
 int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg)
 {
@@ -932,8 +941,6 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops,
 		icp_base + HFI_REG_FWUNCACHED_REGION_IOVA);
 	cam_io_w_mb((uint32_t)hfi_mem->fw_uncached.len,
 		icp_base + HFI_REG_FWUNCACHED_REGION_SIZE);
-	cam_io_w_mb((uint32_t)ICP_INIT_REQUEST_SET,
-		icp_base + HFI_REG_HOST_ICP_INIT_REQUEST);
 
 	CAM_DBG(CAM_HFI, "IO1 : [0x%x 0x%x] IO2 [0x%x 0x%x]",
 		hfi_mem->io_mem.iova, hfi_mem->io_mem.len,
@@ -951,6 +958,15 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops,
 		hfi_mem->qtbl.iova, hfi_mem->qtbl.len,
 		hfi_mem->sfr_buf.iova, hfi_mem->sfr_buf.len);
 
+	if (cam_presil_mode_enabled())
+		cam_hfi_presil_setup(hfi_mem);
+
+	cam_io_w_mb((uint32_t)ICP_INIT_REQUEST_SET,
+		icp_base + HFI_REG_HOST_ICP_INIT_REQUEST);
+
+	if (cam_presil_mode_enabled())
+		cam_hfi_presil_set_init_request();
+
 	if (cam_common_read_poll_timeout(icp_base +
 		    HFI_REG_ICP_HOST_INIT_RESPONSE,
 		    HFI_POLL_DELAY_US, HFI_POLL_TIMEOUT_US,
@@ -985,6 +1001,11 @@ alloc_fail:
 
 void cam_hfi_deinit(void)
 {
+	if (cam_presil_mode_enabled()) {
+		CAM_DBG(CAM_HFI, "SYS_RESET Needed in presil for back to back hfi_init success");
+		hfi_send_system_cmd(HFI_CMD_SYS_RESET, 0, 0);
+	}
+
 	mutex_lock(&hfi_cmd_q_mutex);
 	mutex_lock(&hfi_msg_q_mutex);
 
@@ -1003,3 +1024,103 @@ err:
 	mutex_unlock(&hfi_cmd_q_mutex);
 	mutex_unlock(&hfi_msg_q_mutex);
 }
+
+
+#ifdef CONFIG_CAM_PRESIL
+static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem)
+{
+	/**
+	 * The pchost maintains its own set of queue structures and
+	 * needs additional info to accomplish this. Use the set of
+	 * dummy registers to pass along this info.
+	 */
+	/**
+	 * IOVA region length for each queue is currently hardcoded in
+	 * pchost (except for SFR). No need to send for now.
+	 */
+	cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_CMD_Q_IOVA, hfi_mem->cmd_q.iova);
+	cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_MSG_Q_IOVA, hfi_mem->msg_q.iova);
+	cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_DBG_Q_IOVA, hfi_mem->dbg_q.iova);
+	cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_SFR_LEN, hfi_mem->sfr_buf.len);
+
+	return 0;
+}
+
+static int cam_hfi_presil_set_init_request(void)
+{
+	CAM_DBG(CAM_PRESIL, "notifying pchost to start HFI init...");
+	cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_A5_HW_VERSION_TO_START_HFI_INIT, 0xFF);
+	CAM_DBG(CAM_PRESIL, "got done with PCHOST HFI init...");
+
+	return 0;
+}
+
+int hfi_write_cmd(void *cmd_ptr)
+{
+	int presil_rc = CAM_PRESIL_BLOCKED;
+	int rc = 0;
+
+	if (!cmd_ptr) {
+		CAM_ERR(CAM_HFI, "command is null");
+		return -EINVAL;
+	}
+
+	mutex_lock(&hfi_cmd_q_mutex);
+
+	presil_rc = cam_presil_hfi_write_cmd(cmd_ptr, (*(uint32_t *)cmd_ptr));
+
+	if ((presil_rc != CAM_PRESIL_SUCCESS) && (presil_rc != CAM_PRESIL_BLOCKED)) {
+		CAM_ERR(CAM_HFI, "failed presil rc %d", presil_rc);
+		rc = -EINVAL;
+	} else {
+		CAM_DBG(CAM_HFI, "presil rc %d", presil_rc);
+	}
+
+	mutex_unlock(&hfi_cmd_q_mutex);
+	return rc;
+}
+
+int hfi_read_message(uint32_t *pmsg, uint8_t q_id,
+	uint32_t *words_read)
+{
+	int presil_rc = CAM_PRESIL_BLOCKED;
+	int rc = 0;
+
+	if (!pmsg) {
+		CAM_ERR(CAM_HFI, "Invalid msg");
+		return -EINVAL;
+	}
+
+	if (q_id > Q_DBG) {
+		CAM_ERR(CAM_HFI, "Invalid q :%u", q_id);
+		return -EINVAL;
+	}
+	mutex_lock(&hfi_msg_q_mutex);
+
+	memset(pmsg, 0x0, sizeof(uint32_t) * 256 /* ICP_MSG_BUF_SIZE */);
+	*words_read = 0;
+
+	presil_rc = cam_presil_hfi_read_message(pmsg, q_id, words_read);
+
+	if ((presil_rc != CAM_PRESIL_SUCCESS) && (presil_rc != CAM_PRESIL_BLOCKED)) {
+		CAM_ERR(CAM_HFI, "failed presil rc %d", presil_rc);
+		rc = -EINVAL;
+	} else {
+		CAM_DBG(CAM_HFI, "presil rc %d", presil_rc);
+	}
+
+	mutex_unlock(&hfi_msg_q_mutex);
+	return rc;
+}
+#else
+/* when presil mode not enabled */
+static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem)
+{
+	return 0;
+}
+
+static int cam_hfi_presil_set_init_request(void)
+{
+	return 0;
+}
+#endif /* #ifdef CONFIG_CAM_PRESIL */

+ 10 - 1
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -4064,6 +4064,11 @@ static int cam_icp_mgr_hw_open_u(void *hw_mgr_priv, void *download_fw_args)
 		return 0;
 	}
 
+	if (cam_presil_mode_enabled()) {
+		CAM_DBG(CAM_PRESIL, "hw_open from umd skipped for presil");
+		return 0;
+	}
+
 	mutex_lock(&hw_mgr->hw_mgr_mutex);
 	rc = cam_icp_mgr_hw_open(hw_mgr, download_fw_args);
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
@@ -4074,13 +4079,17 @@ static int cam_icp_mgr_hw_open_u(void *hw_mgr_priv, void *download_fw_args)
 static int cam_icp_mgr_hw_open_k(void *hw_mgr_priv, void *download_fw_args)
 {
 	struct cam_icp_hw_mgr *hw_mgr = hw_mgr_priv;
+	int rc;
 
 	if (!hw_mgr) {
 		CAM_ERR(CAM_ICP, "Null hw mgr");
 		return 0;
 	}
 
-	return cam_icp_mgr_hw_open(hw_mgr, download_fw_args);
+	rc = cam_icp_mgr_hw_open(hw_mgr, download_fw_args);
+	CAM_DBG(CAM_ICP, "hw_open from kmd done %d", rc);
+
+	return rc;
 }
 
 static int cam_icp_mgr_icp_resume(struct cam_icp_hw_mgr *hw_mgr)

+ 15 - 0
drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c

@@ -21,6 +21,7 @@
 #include "lx7_soc.h"
 #include "cam_common_util.h"
 #include "cam_compat.h"
+#include "cam_presil_hw_access.h"
 
 #define TZ_STATE_SUSPEND 0
 #define TZ_STATE_RESUME  1
@@ -387,6 +388,7 @@ static int __cam_lx7_power_resume(struct cam_hw_info *lx7_info)
 	return 0;
 }
 
+#ifndef CONFIG_CAM_PRESIL
 /* Used for non secure FW load */
 static int32_t __cam_non_sec_load_fw(void *device_priv)
 {
@@ -477,6 +479,19 @@ fw_download_failed:
 	release_firmware(core_info->fw_params.fw_elf);
 	return rc;
 }
+#else /* #ifndef CONFIG_CAM_PRESIL */
+static int __cam_non_sec_load_fw(struct cam_hw_info *lx7_info)
+{
+	if (!lx7_info) {
+		CAM_ERR(CAM_ICP, "invalid lx7 dev info");
+		return -EINVAL;
+	}
+
+	cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_ON_FIRST_REG_START_FW_DOWNLOAD, 0xFF);
+
+	return 0;
+}
+#endif /* #ifndef CONFIG_CAM_PRESIL */
 
 /* Used for non secure FW load */
 static int cam_lx7_non_sec_boot(

+ 24 - 0
drivers/cam_presil/inc/cam_presil_hw_access.h

@@ -8,6 +8,17 @@
 
 #include <linux/interrupt.h>
 
+/* presil events to carry shared values from HW-KMD to PC-HOST CSim Wrapper */
+#define CAM_PRESIL_EVENT_HFI_REG_BASE                             0x600
+#define CAM_PRESIL_EVENT_HFI_REG(n) (CAM_PRESIL_EVENT_HFI_REG_BASE + (n * 4))
+#define CAM_PRESIL_EVENT_HFI_REG_CMD_Q_IOVA                      CAM_PRESIL_EVENT_HFI_REG(1)
+#define CAM_PRESIL_EVENT_HFI_REG_MSG_Q_IOVA                      CAM_PRESIL_EVENT_HFI_REG(2)
+#define CAM_PRESIL_EVENT_HFI_REG_DBG_Q_IOVA                      CAM_PRESIL_EVENT_HFI_REG(3)
+#define CAM_PRESIL_EVENT_HFI_REG_SFR_LEN                         CAM_PRESIL_EVENT_HFI_REG(4)
+#define CAM_PRESIL_EVENT_HFI_REG_A5_HW_VERSION_TO_START_HFI_INIT CAM_PRESIL_EVENT_HFI_REG(13)
+#define CAM_PRESIL_EVENT_HFI_REG_ON_FIRST_REG_START_FW_DOWNLOAD    0x638   /* write FF to start */
+
+
 /*
  * enum cam_presil_err - return code from presil apis
  *
@@ -195,4 +206,17 @@ int cam_presil_hfi_read_message(uint32_t *pmsg, uint8_t q_id,
  * @return true or false.
  */
 bool cam_presil_mode_enabled(void);
+
+/*
+ *  cam_presil_send_event()
+ *
+ * @brief   :  send event to pchost.
+ *
+ * @event_id :  Event Id
+ * @value  :  Value with additional information
+ *
+ * @return:  Success or Failure
+ */
+int cam_presil_send_event(uint32_t event_id, uint32_t value);
+
 #endif /* _CAM_PRESIL_HW_ACCESS_H_ */

+ 6 - 0
drivers/cam_presil/stub/cam_presil_hw_access_stub.c

@@ -60,3 +60,9 @@ int cam_presil_hfi_read_message(uint32_t *pmsg, uint8_t q_id,
 {
 	return CAM_PRESIL_SUCCESS;
 }
+
+int cam_presil_send_event(uint32_t event_id, uint32_t value)
+{
+	return CAM_PRESIL_SUCCESS;
+}
+