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

Commit 148f849c authored by Abhilash Kumar's avatar Abhilash Kumar Committed by Tony Lijo Jose
Browse files

msm: camera: icp: Add support for firmware hangdump



Created debugfs entry to support firmware hangdump with
three levels.
The three levels are to disable the dumping of data, to
enable the dump only during firmware failure and enable
dump for each frame.

For disabling:
adb shell echo 0 > /sys/kernel/debug/camera_icp/a5_fw_dump_lvl

For dump on failure:
adb shell echo 1 > /sys/kernel/debug/camera_icp/a5_fw_dump_lvl

For dump on each frame:
adb shell echo 2 > /sys/kernel/debug/camera_icp/a5_fw_dump_lvl

Change-Id: I2c6a2b92563196306bc2baded2d3316de054ecb2
Signed-off-by: default avatarAbhilash Kumar <krabhi@codeaurora.org>
Signed-off-by: default avatarTony Lijo Jose <tjose@codeaurora.org>
parent 0bb03714
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -120,6 +120,12 @@ void cam_hfi_deinit(void __iomem *icp_base);
 */
int hfi_set_debug_level(u64 a5_dbg_type, uint32_t lvl);

/**
 * hfi_set_fw_dump_level() - set firmware dump level
 * @lvl: level of firmware dump level
 */
int hfi_set_fw_dump_level(uint32_t lvl);

/**
 * hfi_enable_ipe_bps_pc() - Enable interframe pc
 * Host sends a command to firmware to enable interframe
+13 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@
#define HFI_PROP_SYS_IMAGE_VER         (HFI_PROPERTY_ICP_COMMON_START + 0x3)
#define HFI_PROP_SYS_SUPPORTED         (HFI_PROPERTY_ICP_COMMON_START + 0x4)
#define HFI_PROP_SYS_IPEBPS_PC         (HFI_PROPERTY_ICP_COMMON_START + 0x5)
#define HFI_PROP_SYS_FW_DUMP_CFG       (HFI_PROPERTY_ICP_COMMON_START + 0x8)

/* Capabilities reported at sys init */
#define HFI_CAPS_PLACEHOLDER_1         (HFI_COMMON_BASE + 0x1)
@@ -180,6 +181,18 @@
/* Disable ARM9 watchdog. */
#define  HFI_DEBUG_CFG_ARM9WD   0x10000000


/*
 * HFI_FW_DUMP levels
 * HFI_FW_DUMP_xx
 */
#define HFI_FW_DUMP_DISABLED    0x00000000
#define HFI_FW_DUMP_ON_FAILURE  0x00000001
#define HFI_FW_DUMP_ALWAYS      0x00000002

/* Number of available dump levels. */
#define NUM_HFI_DUMP_LVL        0x00000003

/* Debug Msg Communication types:
 * Section describes different modes (HFI_DEBUG_MODE_X)
 * available to communicate the debug messages
+36 −0
Original line number Diff line number Diff line
@@ -324,6 +324,42 @@ int hfi_set_debug_level(u64 a5_dbg_type, uint32_t lvl)
	return 0;
}

int hfi_set_fw_dump_level(uint32_t lvl)
{
	uint8_t *prop = NULL;
	struct hfi_cmd_prop *fw_dump_level_switch_prop = NULL;
	uint32_t size = 0;

	CAM_DBG(CAM_HFI, "fw dump ENTER");

	size = sizeof(struct hfi_cmd_prop) + sizeof(lvl);
	prop = kzalloc(size, GFP_KERNEL);
	if (!prop)
		return -ENOMEM;

	fw_dump_level_switch_prop = (struct hfi_cmd_prop *)prop;
	fw_dump_level_switch_prop->size = size;
	fw_dump_level_switch_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
	fw_dump_level_switch_prop->num_prop = 1;
	fw_dump_level_switch_prop->prop_data[0] = HFI_PROP_SYS_FW_DUMP_CFG;
	fw_dump_level_switch_prop->prop_data[1] = lvl;

	CAM_DBG(CAM_HFI, "prop->size = %d\n"
			 "prop->pkt_type = %d\n"
			 "prop->num_prop = %d\n"
			 "prop->prop_data[0] = %d\n"
			 "prop->prop_data[1] = %d\n",
			 fw_dump_level_switch_prop->size,
			 fw_dump_level_switch_prop->pkt_type,
			 fw_dump_level_switch_prop->num_prop,
			 fw_dump_level_switch_prop->prop_data[0],
			 fw_dump_level_switch_prop->prop_data[1]);

	hfi_write_cmd(prop);
	kfree(prop);
	return 0;
}

void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size)
{
	switch (type) {
+29 −2
Original line number Diff line number Diff line
@@ -1285,6 +1285,22 @@ static int cam_icp_get_a5_dbg_type(void *data, u64 *val)
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_set_a5_fw_dump_lvl(void *data, u64 val)
{
	if (val < NUM_HFI_DUMP_LVL)
		icp_hw_mgr.a5_fw_dump_lvl = val;
	return 0;
}

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

DEFINE_SIMPLE_ATTRIBUTE(cam_icp_debug_fw_dump, cam_icp_get_a5_fw_dump_lvl,
	cam_icp_set_a5_fw_dump_lvl, "%08llu");

static int cam_icp_hw_mgr_create_debugfs_entry(void)
{
	int rc = 0;
@@ -1335,7 +1351,7 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void)
		0644,
		icp_hw_mgr.dentry,
		NULL, &cam_icp_debug_type_fs)) {
		CAM_ERR(CAM_ICP, "failed to create a5_debug_type\n");
		CAM_ERR(CAM_ICP, "failed to create a5_debug_type");
		rc = -ENOMEM;
		goto err;
	}
@@ -1344,7 +1360,16 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void)
		0644,
		icp_hw_mgr.dentry,
		NULL, &cam_icp_debug_fs)) {
		CAM_ERR(CAM_ICP, "failed to create a5_dbg_lvl\n");
		CAM_ERR(CAM_ICP, "failed to create a5_dbg_lvl");
		rc = -ENOMEM;
		goto err;
	}

	if (!debugfs_create_file("a5_fw_dump_lvl",
		0644,
		icp_hw_mgr.dentry,
		NULL, &cam_icp_debug_fw_dump)) {
		CAM_ERR(CAM_ICP, "failed to create a5_fw_dump_lvl");
		rc = -ENOMEM;
		goto err;
	}
@@ -3866,6 +3891,8 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
			hfi_set_debug_level(icp_hw_mgr.a5_debug_type,
				icp_hw_mgr.a5_dbg_lvl);

		hfi_set_fw_dump_level(icp_hw_mgr.a5_fw_dump_lvl);

		rc = cam_icp_send_ubwc_cfg(hw_mgr);
		if (rc)
			goto ubwc_cfg_failed;
+2 −0
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ struct cam_icp_clk_info {
 * @a5_jtag_debug: entry to enable A5 JTAG debugging
 * @a5_debug_type : entry to enable FW debug message/qdss
 * @a5_dbg_lvl : debug level set to FW.
 * @a5_fw_dump_lvl : level set for dumping the FW data
 * @ipe0_enable: Flag for IPE0
 * @ipe1_enable: Flag for IPE1
 * @bps_enable: Flag for BPS
@@ -325,6 +326,7 @@ struct cam_icp_hw_mgr {
	bool a5_jtag_debug;
	u64 a5_debug_type;
	u64 a5_dbg_lvl;
	u64 a5_fw_dump_lvl;
	bool ipe0_enable;
	bool ipe1_enable;
	bool bps_enable;