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

Commit ee40106f authored by Jeyaprakash Soundrapandian's avatar Jeyaprakash Soundrapandian Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: icp: Enable HFI debug queue" into dev/msm-4.9-camx

parents 23c4258c dac0b6c8
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -61,9 +61,9 @@ int hfi_write_cmd(void *cmd_ptr);
 * @pmsg: buffer to place read message for hfi queue
 * @q_id: queue id
 *
 * Returns success(zero)/failure(non zero)
 * Returns size read in words/failure(negative value)
 */
int hfi_read_message(uint32_t *pmsg, uint8_t q_id);
int64_t hfi_read_message(uint32_t *pmsg, uint8_t q_id);

/**
 * hfi_init() - function initialize hfi after firmware download
@@ -109,6 +109,11 @@ void cam_hfi_disable_cpu(void __iomem *icp_base);
 * cam_hfi_deinit() - cleanup HFI
 */
void cam_hfi_deinit(void);
/**
 * hfi_set_debug_level() - set debug level
 * @lvl: FW debug message level
 */
int hfi_set_debug_level(uint32_t lvl);

/**
 * hfi_enable_ipe_bps_pc() - Enable interframe pc
+4 −3
Original line number Diff line number Diff line
@@ -60,11 +60,11 @@

#define ICP_CMD_Q_SIZE_IN_BYTES                 4096
#define ICP_MSG_Q_SIZE_IN_BYTES                 4096
#define ICP_DBG_Q_SIZE_IN_BYTES                 8192
#define ICP_DBG_Q_SIZE_IN_BYTES                 102400

#define ICP_SHARED_MEM_IN_BYTES                 (1024 * 1024)
#define ICP_UNCACHED_HEAP_SIZE_IN_BYTES         (2 * 1024 * 1024)
#define ICP_HFI_MAX_MSG_SIZE_IN_WORDS           128
#define ICP_HFI_MAX_PKT_SIZE_IN_WORDS           25600

#define ICP_HFI_QTBL_HOSTID1                    0x01000000
#define ICP_HFI_QTBL_STATUS_ENABLED             0x00000001
@@ -109,7 +109,8 @@ enum hfi_state {
 */
enum reg_settings {
	RESET,
	SET
	SET,
	SET_WM = 1024
};

/**
+62 −23
Original line number Diff line number Diff line
@@ -119,13 +119,13 @@ int hfi_write_cmd(void *cmd_ptr)
	return rc;
}

int hfi_read_message(uint32_t *pmsg, uint8_t q_id)
int64_t hfi_read_message(uint32_t *pmsg, uint8_t q_id)
{
	struct hfi_qtbl *q_tbl_ptr;
	struct hfi_q_hdr *q;
	uint32_t new_read_idx, size_in_words, temp;
	uint32_t *read_q, *read_ptr;
	int rc = 0;
	uint32_t new_read_idx, size_in_words, word_diff, temp;
	uint32_t *read_q, *read_ptr, *write_ptr;
	int64_t rc = 0;

	if (!pmsg) {
		CAM_ERR(CAM_HFI, "Invalid msg");
@@ -168,10 +168,23 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id)
		read_q = (uint32_t *)g_hfi->map.dbg_q.kva;

	read_ptr = (uint32_t *)(read_q + q->qhdr_read_idx);
	write_ptr = (uint32_t *)(read_q + q->qhdr_write_idx);
	size_in_words = (*read_ptr) >> BYTE_WORD_SHIFT;

	if (write_ptr > read_ptr)
		size_in_words = write_ptr - read_ptr;
	else {
		word_diff = read_ptr - write_ptr;
		if (q_id == Q_MSG)
			size_in_words = (ICP_MSG_Q_SIZE_IN_BYTES >>
			BYTE_WORD_SHIFT) - word_diff;
		else
			size_in_words = (ICP_DBG_Q_SIZE_IN_BYTES >>
			BYTE_WORD_SHIFT) - word_diff;
	}

	if ((size_in_words == 0) ||
		(size_in_words > ICP_HFI_MAX_MSG_SIZE_IN_WORDS)) {
		(size_in_words > ICP_HFI_MAX_PKT_SIZE_IN_WORDS)) {
		CAM_ERR(CAM_HFI, "invalid HFI message packet size - 0x%08x",
			size_in_words << BYTE_WORD_SHIFT);
		q->qhdr_read_idx = q->qhdr_write_idx;
@@ -192,6 +205,7 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id)
	}

	q->qhdr_read_idx = new_read_idx;
	rc = size_in_words;
err:
	mutex_unlock(&hfi_msg_q_mutex);
	return rc;
@@ -223,6 +237,45 @@ int hfi_enable_ipe_bps_pc(bool enable)
	return 0;
}

int hfi_set_debug_level(uint32_t lvl)
{
	uint8_t *prop;
	struct hfi_cmd_prop *dbg_prop;
	uint32_t size = 0, val;

	val = HFI_DEBUG_MSG_LOW |
		HFI_DEBUG_MSG_MEDIUM |
		HFI_DEBUG_MSG_HIGH |
		HFI_DEBUG_MSG_ERROR |
		HFI_DEBUG_MSG_FATAL |
		HFI_DEBUG_MSG_PERF |
		HFI_DEBUG_CFG_WFI |
		HFI_DEBUG_CFG_ARM9WD;

	if (lvl > val)
		return -EINVAL;

	size = sizeof(struct hfi_cmd_prop) +
		sizeof(struct hfi_debug);

	prop = kzalloc(size, GFP_KERNEL);
	if (!prop)
		return -ENOMEM;

	dbg_prop = (struct hfi_cmd_prop *)prop;
	dbg_prop->size = size;
	dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
	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;

	hfi_write_cmd(prop);
	kfree(prop);

	return 0;
}

void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size)
{
	switch (type) {
@@ -456,8 +509,8 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,

		dbg_q_hdr->qhdr_type = Q_DBG;
		dbg_q_hdr->qhdr_rx_wm = SET;
		dbg_q_hdr->qhdr_tx_wm = SET;
		dbg_q_hdr->qhdr_rx_req = SET;
		dbg_q_hdr->qhdr_tx_wm = SET_WM;
		dbg_q_hdr->qhdr_rx_req = RESET;
		dbg_q_hdr->qhdr_tx_req = RESET;
		dbg_q_hdr->qhdr_rx_irq_status = RESET;
		dbg_q_hdr->qhdr_tx_irq_status = RESET;
@@ -495,8 +548,8 @@ int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
		dbg_q_hdr->qhdr_type = Q_DBG | TX_EVENT_DRIVEN_MODE_2 |
			RX_EVENT_DRIVEN_MODE_2;
		dbg_q_hdr->qhdr_rx_wm = SET;
		dbg_q_hdr->qhdr_tx_wm = SET;
		dbg_q_hdr->qhdr_rx_req = SET;
		dbg_q_hdr->qhdr_tx_wm = SET_WM;
		dbg_q_hdr->qhdr_rx_req = RESET;
		dbg_q_hdr->qhdr_tx_req = RESET;
		dbg_q_hdr->qhdr_rx_irq_status = RESET;
		dbg_q_hdr->qhdr_tx_irq_status = RESET;
@@ -574,17 +627,3 @@ void cam_hfi_deinit(void)
	mutex_unlock(&hfi_cmd_q_mutex);
	mutex_unlock(&hfi_msg_q_mutex);
}

void icp_enable_fw_debug(void)
{
	hfi_send_system_cmd(HFI_CMD_SYS_SET_PROPERTY,
		(uint64_t)HFI_PROP_SYS_DEBUG_CFG, 0);
}

int icp_ping_fw(void)
{
	hfi_send_system_cmd(HFI_CMD_SYS_PING,
		(uint64_t)0x12123434, 0);

	return 0;
}
+139 −29
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include "hfi_sys_defs.h"
#include "cam_debug_util.h"
#include "cam_soc_util.h"
#include "cam_trace.h"

#define ICP_WORKQ_TASK_CMD_TYPE 1
#define ICP_WORKQ_TASK_MSG_TYPE 2
@@ -790,6 +791,21 @@ DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_default_clk,
	cam_icp_get_dbg_default_clk,
	cam_icp_set_dbg_default_clk, "%16llu");

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

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

DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_fs, cam_icp_get_a5_dbg_lvl,
	cam_icp_set_a5_dbg_lvl, "%08llu");

static int cam_icp_hw_mgr_create_debugfs_entry(void)
{
	int rc = 0;
@@ -798,15 +814,6 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void)
	if (!icp_hw_mgr.dentry)
		return -ENOMEM;

	if (!debugfs_create_bool("a5_debug",
		0644,
		icp_hw_mgr.dentry,
		&icp_hw_mgr.a5_debug)) {
		debugfs_remove_recursive(icp_hw_mgr.dentry);
		rc = -ENOMEM;
		goto err;
	}

	if (!debugfs_create_bool("icp_pc",
		0644,
		icp_hw_mgr.dentry,
@@ -825,6 +832,32 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void)
		goto err;
	}

	if (!debugfs_create_bool("a5_jtag_debug",
		0644,
		icp_hw_mgr.dentry,
		&icp_hw_mgr.a5_jtag_debug)) {
		rc = -ENOMEM;
		goto err;
	}

	if (!debugfs_create_bool("a5_debug_q",
		0644,
		icp_hw_mgr.dentry,
		&icp_hw_mgr.a5_debug_q)) {
		CAM_ERR(CAM_ICP, "failed to create a5_debug_q\n");
		rc = -ENOMEM;
		goto err;
	}

	if (!debugfs_create_file("a5_debug_lvl",
		0644,
		icp_hw_mgr.dentry,
		NULL, &cam_icp_debug_fs)) {
		CAM_ERR(CAM_ICP, "failed to create a5_dbg_lvl\n");
		rc = -ENOMEM;
		goto err;
	}

	return rc;
err:
	debugfs_remove_recursive(icp_hw_mgr.dentry);
@@ -1091,56 +1124,81 @@ static int cam_icp_mgr_process_direct_ack_msg(uint32_t *msg_ptr)
	return rc;
}

static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
static void cam_icp_mgr_process_dbg_buf(void)
{
	int rc = 0;
	uint32_t *msg_ptr = NULL;
	struct hfi_msg_work_data *task_data;
	struct cam_icp_hw_mgr *hw_mgr;
	int read_len;
	uint32_t *msg_ptr = NULL, *pkt_ptr = NULL;
	struct hfi_msg_debug *dbg_msg;
	int64_t read_len, size_processed = 0;
	char *dbg_buf;

	if (!data || !priv) {
		CAM_ERR(CAM_ICP, "Invalid data");
		return -EINVAL;
	}

	task_data = data;
	hw_mgr = priv;
	read_len = hfi_read_message(icp_hw_mgr.dbg_buf, Q_DBG);
	if (read_len < 0)
		return;

	read_len = hfi_read_message(icp_hw_mgr.msg_buf, Q_MSG);
	if (read_len < 0) {
		CAM_DBG(CAM_ICP, "Unable to read msg q");
		return read_len;
	msg_ptr = (uint32_t *)icp_hw_mgr.dbg_buf;
	while (true) {
		pkt_ptr = msg_ptr;
		if (pkt_ptr[ICP_PACKET_TYPE] == HFI_MSG_SYS_DEBUG) {
			dbg_msg = (struct hfi_msg_debug *)pkt_ptr;
			dbg_buf = (char *)&dbg_msg->msg_data;
			trace_cam_icp_fw_dbg(dbg_buf);
		}
		size_processed += (pkt_ptr[ICP_PACKET_SIZE] >>
			BYTE_WORD_SHIFT);
		if (size_processed >= read_len)
			return;
		msg_ptr += (pkt_ptr[ICP_PACKET_SIZE] >>
		BYTE_WORD_SHIFT);
		pkt_ptr = NULL;
		dbg_msg = NULL;
		dbg_buf = NULL;
	}
}

	msg_ptr = (uint32_t *)icp_hw_mgr.msg_buf;
static int cam_icp_process_msg_pkt_type(
	struct cam_icp_hw_mgr *hw_mgr,
	uint32_t *msg_ptr)
{
	int rc = 0;
	int size_processed = 0;
	struct hfi_msg_ipebps_async_ack *async_ack = NULL;

	switch (msg_ptr[ICP_PACKET_TYPE]) {
	case HFI_MSG_SYS_INIT_DONE:
		CAM_DBG(CAM_ICP, "received SYS_INIT_DONE");
		complete(&hw_mgr->a5_complete);
		size_processed = sizeof(struct hfi_msg_init_done);
		break;

	case HFI_MSG_SYS_PING_ACK:
		CAM_DBG(CAM_ICP, "received SYS_PING_ACK");
		rc = cam_icp_mgr_process_msg_ping_ack(msg_ptr);
		size_processed = sizeof(struct hfi_msg_ping_ack);
		break;

	case HFI_MSG_IPEBPS_CREATE_HANDLE_ACK:
		CAM_DBG(CAM_ICP, "received IPEBPS_CREATE_HANDLE_ACK");
		rc = cam_icp_mgr_process_msg_create_handle(msg_ptr);
		size_processed = sizeof(struct hfi_msg_create_handle_ack);
		break;

	case HFI_MSG_IPEBPS_ASYNC_COMMAND_INDIRECT_ACK:
		CAM_DBG(CAM_ICP, "received ASYNC_INDIRECT_ACK");
		rc = cam_icp_mgr_process_indirect_ack_msg(msg_ptr);
		async_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
		size_processed = async_ack->size;
		async_ack = NULL;
		break;

	case  HFI_MSG_IPEBPS_ASYNC_COMMAND_DIRECT_ACK:
		CAM_DBG(CAM_ICP, "received ASYNC_DIRECT_ACK");
		rc = cam_icp_mgr_process_direct_ack_msg(msg_ptr);
		size_processed = sizeof(struct hfi_msg_ipebps_async_ack);
		break;

	case HFI_MSG_EVENT_NOTIFY:
		CAM_DBG(CAM_ICP, "received EVENT_NOTIFY");
		size_processed = sizeof(struct hfi_msg_event_notify);
		break;

	default:
@@ -1150,6 +1208,53 @@ static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
		break;
	}

	if (rc)
		return rc;

	return size_processed;
}

static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
{
	int64_t read_len, msg_processed_len;
	int rc = 0;
	uint32_t *msg_ptr = NULL;
	struct hfi_msg_work_data *task_data;
	struct cam_icp_hw_mgr *hw_mgr;

	if (!data || !priv) {
		CAM_ERR(CAM_ICP, "Invalid data");
		return -EINVAL;
	}

	task_data = data;
	hw_mgr = priv;

	read_len = hfi_read_message(icp_hw_mgr.msg_buf, Q_MSG);
	if (read_len < 0) {
		rc = read_len;
		CAM_DBG(CAM_ICP, "Unable to read msg q");
	} else {
		msg_ptr = (uint32_t *)icp_hw_mgr.msg_buf;
		while (true) {
			msg_processed_len = cam_icp_process_msg_pkt_type(
			hw_mgr, msg_ptr);
			if (msg_processed_len < 0) {
				rc = msg_processed_len;
				return rc;
			}

			read_len -= msg_processed_len;
			if (read_len > 0)
				msg_ptr += msg_processed_len;
			else
				break;
		}
	}

	if (icp_hw_mgr.a5_debug_q)
		cam_icp_mgr_process_dbg_buf();

	return rc;
}

@@ -1746,7 +1851,7 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)

	return cam_hfi_init(0, &hfi_mem,
		a5_dev->soc_info.reg_map[A5_SIERRA_BASE].mem_base,
		hw_mgr->a5_debug);
		hw_mgr->a5_jtag_debug);
}

static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)
@@ -1844,10 +1949,15 @@ static int cam_icp_mgr_download_fw(void *hw_mgr_priv, void *download_fw_args)
		NULL, 0);
	hw_mgr->fw_download = true;
	hw_mgr->ctxt_cnt = 0;
	mutex_unlock(&hw_mgr->hw_mgr_mutex);
	CAM_DBG(CAM_ICP, "FW download done successfully");

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

	mutex_unlock(&hw_mgr->hw_mgr_mutex);
	if (!download_fw_args)
		cam_icp_mgr_hw_close(hw_mgr, NULL);

	return rc;

fw_init_failed:
+10 −2
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@

#define ICP_FRAME_PROCESS_SUCCESS 0
#define ICP_FRAME_PROCESS_FAILURE 1
#define ICP_MSG_BUF_SIZE        256
#define ICP_DBG_BUF_SIZE        102400

#define ICP_CLK_HW_IPE          0x0
#define ICP_CLK_HW_BPS          0x1
@@ -230,6 +232,9 @@ struct cam_icp_clk_info {
 * @icp_default_clk: Set this clok if user doesn't supply
 * @clk_info: Clock info of hardware
 * @secure_mode: Flag to enable/disable secure camera
 * @a5_jtag_debug: entry to enable A5 JTAG debugging
 * @a5_debug_q : entry to enable FW debug message
 * @a5_dbg_lvl : debug level set to FW.
 */
struct cam_icp_hw_mgr {
	struct mutex hw_mgr_mutex;
@@ -245,8 +250,8 @@ struct cam_icp_hw_mgr {
	struct icp_hfi_mem_info hfi_mem;
	struct cam_req_mgr_core_workq *cmd_work;
	struct cam_req_mgr_core_workq *msg_work;
	uint32_t msg_buf[256];
	uint32_t dbg_buf[256];
	uint32_t msg_buf[ICP_MSG_BUF_SIZE];
	uint32_t dbg_buf[ICP_DBG_BUF_SIZE];
	struct completion a5_complete;
	struct hfi_cmd_work_data *cmd_work_data;
	struct hfi_msg_work_data *msg_work_data;
@@ -260,6 +265,9 @@ struct cam_icp_hw_mgr {
	uint64_t icp_default_clk;
	struct cam_icp_clk_info clk_info[ICP_CLK_HW_MAX];
	bool secure_mode;
	bool a5_jtag_debug;
	bool a5_debug_q;
	u64 a5_dbg_lvl;
};

static int cam_icp_mgr_hw_close(void *hw_priv, void *hw_close_args);
Loading