Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b47e804 authored by Vishalsingh Hajeri's avatar Vishalsingh Hajeri Committed by Karthik Anantha Ram
Browse files

msm: camera: smmu: Add functions to map & unmap qdss memory



As part of the icp memory ctx qdss physical address needs to be
mapped by smmu and the mapped virtual address to be passed to FW.
Updated debugfs to allow users to either choose qdss or debug
queue.

For debug queue mode:
adb shell echo 1 > /sys/kernel/debug/camera_icp/a5_debug_type

QDSS mode:
adb shell echo 2 > /sys/kernel/debug/camera_icp/a5_debug_type

Change-Id: Ibc96d60c68012036484d3cc734691f71b698318e
Signed-off-by: default avatarKarthik Anantha Ram <kartanan@codeaurora.org>
Signed-off-by: default avatarVishalsingh Hajeri <vhajeri@codeaurora.org>
Signed-off-by: default avatarAbhilash Kumar <krabhi@codeaurora.org>
parent 4097ccbb
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ struct hfi_mem {
 * @msg_q: message queue hfi memory for firmware to host communication
 * @dbg_q: debug queue hfi memory for firmware debug information
 * @sec_heap: secondary heap hfi memory for firmware
 * @qdss: qdss mapped memory for fw
 * @icp_base: icp base address
 */
struct hfi_mem_info {
@@ -45,6 +46,7 @@ struct hfi_mem_info {
	struct hfi_mem dbg_q;
	struct hfi_mem sec_heap;
	struct hfi_mem shmem;
	struct hfi_mem qdss;
	void __iomem *icp_base;
};

@@ -113,9 +115,10 @@ void cam_hfi_disable_cpu(void __iomem *icp_base);
void cam_hfi_deinit(void __iomem *icp_base);
/**
 * hfi_set_debug_level() - set debug level
 * @a5_dbg_type: 1 for debug_q & 2 for qdss
 * @lvl: FW debug message level
 */
int hfi_set_debug_level(uint32_t lvl);
int hfi_set_debug_level(u64 a5_dbg_type, uint32_t lvl);

/**
 * hfi_enable_ipe_bps_pc() - Enable interframe pc
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@
#define HFI_REG_QTBL_PTR                        0x58
#define HFI_REG_UNCACHED_HEAP_PTR               0x5C
#define HFI_REG_UNCACHED_HEAP_SIZE              0x60
#define HFI_REG_QDSS_IOVA                       0x6C
#define HFI_REG_QDSS_IOVA_SIZE                  0x70
/* end of ICP CSR registers */

/* flags for ICP CSR registers */
+4 −6
Original line number Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -188,7 +188,8 @@
#define HFI_DEBUG_MODE_QUEUE     0x00000001
 /* Debug message output through QDSS. */
#define HFI_DEBUG_MODE_QDSS      0x00000002

 /* Number of debug modes available. */
#define NUM_HFI_DEBUG_MODE       0x00000002

#define HFI_DEBUG_MSG_LOW        0x00000001
#define HFI_DEBUG_MSG_MEDIUM     0x00000002
@@ -199,9 +200,6 @@
#define HFI_DEBUG_CFG_WFI        0x01000000
#define HFI_DEBUG_CFG_ARM9WD     0x10000000

#define HFI_DEBUG_MODE_QUEUE     0x00000001
#define HFI_DEBUG_MODE_QDSS      0x00000002

#define HFI_DEV_VERSION_MAX      0x5

/**
+11 −3
Original line number Diff line number Diff line
@@ -285,7 +285,7 @@ int hfi_enable_ipe_bps_pc(bool enable, uint32_t core_info)
	return 0;
}

int hfi_set_debug_level(uint32_t lvl)
int hfi_set_debug_level(u64 a5_dbg_type, uint32_t lvl)
{
	uint8_t *prop;
	struct hfi_cmd_prop *dbg_prop;
@@ -316,9 +316,9 @@ int hfi_set_debug_level(uint32_t lvl)
	dbg_prop->num_prop = 1;
	dbg_prop->prop_data[0] = HFI_PROP_SYS_DEBUG_CFG;
	dbg_prop->prop_data[1] = lvl;
	dbg_prop->prop_data[2] = HFI_DEBUG_MODE_QUEUE;

	dbg_prop->prop_data[2] = a5_dbg_type;
	hfi_write_cmd(prop);

	kfree(prop);

	return 0;
@@ -538,6 +538,10 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem,
		icp_base + HFI_REG_UNCACHED_HEAP_PTR);
	cam_io_w_mb((uint32_t)hfi_mem->sec_heap.len,
		icp_base + HFI_REG_UNCACHED_HEAP_SIZE);
	cam_io_w_mb((uint32_t)hfi_mem->qdss.iova,
		icp_base + HFI_REG_QDSS_IOVA);
	cam_io_w_mb((uint32_t)hfi_mem->qdss.len,
		icp_base + HFI_REG_QDSS_IOVA_SIZE);

	return rc;
}
@@ -715,6 +719,10 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
		icp_base + HFI_REG_UNCACHED_HEAP_SIZE);
	cam_io_w_mb((uint32_t)ICP_INIT_REQUEST_SET,
		icp_base + HFI_REG_HOST_ICP_INIT_REQUEST);
	cam_io_w_mb((uint32_t)hfi_mem->qdss.iova,
		icp_base + HFI_REG_QDSS_IOVA);
	cam_io_w_mb((uint32_t)hfi_mem->qdss.len,
		icp_base + HFI_REG_QDSS_IOVA_SIZE);

	hw_version = cam_io_r(icp_base + HFI_REG_A5_HW_VERSION);

+63 −10
Original line number Diff line number Diff line
@@ -1244,6 +1244,23 @@ static int cam_icp_get_a5_dbg_lvl(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_fs, cam_icp_get_a5_dbg_lvl,
	cam_icp_set_a5_dbg_lvl, "%08llu");

static int cam_icp_set_a5_dbg_type(void *data, u64 val)
{
	if (val <= NUM_HFI_DEBUG_MODE)
		icp_hw_mgr.a5_debug_type = val;
	return 0;
}

static int cam_icp_get_a5_dbg_type(void *data, u64 *val)
{
	*val = icp_hw_mgr.a5_debug_type;
	return 0;
}


DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_type_fs, cam_icp_get_a5_dbg_type,
	cam_icp_set_a5_dbg_type, "%08llu");

static int cam_icp_hw_mgr_create_debugfs_entry(void)
{
	int rc = 0;
@@ -1290,11 +1307,11 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void)
		goto err;
	}

	if (!debugfs_create_bool("a5_debug_q",
	if (!debugfs_create_file("a5_debug_type",
		0644,
		icp_hw_mgr.dentry,
		&icp_hw_mgr.a5_debug_q)) {
		CAM_ERR(CAM_ICP, "failed to create a5_debug_q\n");
		NULL, &cam_icp_debug_type_fs)) {
		CAM_ERR(CAM_ICP, "failed to create a5_debug_type\n");
		rc = -ENOMEM;
		goto err;
	}
@@ -1792,7 +1809,8 @@ static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
		}
	}

	if (icp_hw_mgr.a5_debug_q)
	if (icp_hw_mgr.a5_debug_type ==
		HFI_DEBUG_MODE_QUEUE)
		cam_icp_mgr_process_dbg_buf();

	return rc;
@@ -1833,6 +1851,8 @@ static void cam_icp_free_hfi_mem(void)
	rc = cam_mem_mgr_free_memory_region(&icp_hw_mgr.hfi_mem.sec_heap);
	if (rc)
		CAM_ERR(CAM_ICP, "failed to unreserve sec heap");

	cam_smmu_dealloc_qdss(icp_hw_mgr.iommu_hdl);
	cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
	cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.cmd_q);
	cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.msg_q);
@@ -1923,6 +1943,26 @@ static int cam_icp_allocate_fw_mem(void)
	return rc;
}

static int cam_icp_allocate_qdss_mem(void)
{
	int rc;
	size_t len;
	dma_addr_t iova;

	rc = cam_smmu_alloc_qdss(icp_hw_mgr.iommu_hdl,
		&iova, &len);
	if (rc)
		return rc;

	icp_hw_mgr.hfi_mem.qdss_buf.len = len;
	icp_hw_mgr.hfi_mem.qdss_buf.iova = iova;
	icp_hw_mgr.hfi_mem.qdss_buf.smmu_hdl = icp_hw_mgr.iommu_hdl;

	CAM_DBG(CAM_ICP, "iova: %llx, len: %zu", iova, len);

	return rc;
}

static int cam_icp_allocate_hfi_mem(void)
{
	int rc;
@@ -1941,6 +1981,12 @@ static int cam_icp_allocate_hfi_mem(void)
		return rc;
	}

	rc = cam_icp_allocate_qdss_mem();
	if (rc) {
		CAM_ERR(CAM_ICP, "Unable to allocate qdss memory");
		goto fw_alloc_failed;
	}

	rc = cam_icp_alloc_shared_mem(&icp_hw_mgr.hfi_mem.qtbl);
	if (rc) {
		CAM_ERR(CAM_ICP, "Unable to allocate qtbl memory");
@@ -1981,6 +2027,8 @@ static int cam_icp_allocate_hfi_mem(void)
cmd_q_alloc_failed:
	cam_mem_mgr_release_mem(&icp_hw_mgr.hfi_mem.qtbl);
qtbl_alloc_failed:
	cam_smmu_dealloc_qdss(icp_hw_mgr.iommu_hdl);
fw_alloc_failed:
	cam_smmu_dealloc_firmware(icp_hw_mgr.iommu_hdl);
	return rc;
}
@@ -2142,6 +2190,9 @@ static int cam_icp_mgr_hfi_resume(struct cam_icp_hw_mgr *hw_mgr)

	hfi_mem.shmem.iova = icp_hw_mgr.hfi_mem.shmem.iova_start;
	hfi_mem.shmem.len = icp_hw_mgr.hfi_mem.shmem.iova_len;

	hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
	hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;
	return cam_hfi_resume(&hfi_mem,
		a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
		hw_mgr->a5_jtag_debug);
@@ -2268,7 +2319,8 @@ static int cam_icp_mgr_destroy_handle(
		rc = -ETIMEDOUT;
		CAM_ERR(CAM_ICP, "FW response timeout: %d for %u",
			rc, ctx_data->ctx_id);
		if (icp_hw_mgr.a5_debug_q)
		if (icp_hw_mgr.a5_debug_type ==
			HFI_DEBUG_MODE_QUEUE)
			cam_icp_mgr_process_dbg_buf();
	}
	return rc;
@@ -2539,6 +2591,9 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
	hfi_mem.shmem.iova = icp_hw_mgr.hfi_mem.shmem.iova_start;
	hfi_mem.shmem.len = icp_hw_mgr.hfi_mem.shmem.iova_len;

	hfi_mem.qdss.iova = icp_hw_mgr.hfi_mem.qdss_buf.iova;
	hfi_mem.qdss.len = icp_hw_mgr.hfi_mem.qdss_buf.len;

	return cam_hfi_init(0, &hfi_mem,
		a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
		hw_mgr->a5_jtag_debug);
@@ -2665,9 +2720,6 @@ static int cam_icp_mgr_hw_open(void *hw_mgr_priv, void *download_fw_args)
	hw_mgr->ctxt_cnt = 0;
	hw_mgr->fw_download = true;

	if (icp_hw_mgr.a5_debug_q)
		hfi_set_debug_level(icp_hw_mgr.a5_dbg_lvl);

	mutex_unlock(&hw_mgr->hw_mgr_mutex);
	CAM_INFO(CAM_ICP, "FW download done successfully");

@@ -3743,8 +3795,9 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
			goto get_io_buf_failed;
		}

		if (icp_hw_mgr.a5_debug_q)
			hfi_set_debug_level(icp_hw_mgr.a5_dbg_lvl);
		if (icp_hw_mgr.a5_debug_type)
			hfi_set_debug_level(icp_hw_mgr.a5_debug_type,
				icp_hw_mgr.a5_dbg_lvl);

		rc = cam_icp_send_ubwc_cfg(hw_mgr);
		if (rc) {
Loading