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

Commit e6a5872f authored by Huaibin Yang's avatar Huaibin Yang Committed by Ingrid Gallardo
Browse files

msm: mdss: debugfs: xlog: dump mdp registers to RAM



Currently xlog provides the capability of dumping mdp registers to
kernel log. This patch adds the option of dumping mdp regs to ram as
well.

echo 0x0 > <debugfs>/mdp/xlog/reg_dump -> disable mdp reg dump
echo 0x1 > <debugfs>/mdp/xlog/reg_dump -> enable mdp reg dump to log
echo 0x2 > <debugfs>/mdp/xlog/reg_dump -> enable mdp reg dump to ram
echo 0x3 > <debugfs>/mdp/xlog/reg_dump -> enable mdp reg dump to both

Change-Id: I767bbd956ac3b1c9e76800bd9d563fc80bd337db
Signed-off-by: default avatarHuaibin Yang <huaibiny@codeaurora.org>
parent af066937
Loading
Loading
Loading
Loading
+49 −4
Original line number Diff line number Diff line
@@ -257,6 +257,7 @@ int mdss_debug_register_base(const char *name, void __iomem *base,
	dbg->max_offset = max_offset;
	dbg->off = 0;
	dbg->cnt = DEFAULT_BASE_REG_CNT;
	dbg->reg_dump = NULL;

	if (name && strcmp(name, "mdp"))
		prefix_len = snprintf(dn, sizeof(dn), "%s_", name);
@@ -662,24 +663,68 @@ int mdss_debugfs_remove(struct mdss_data_type *mdata)
	return 0;
}

void mdss_dump_reg(char __iomem *base, int len)
void mdss_dump_reg(struct mdss_debug_base *dbg, u32 reg_dump_flag)
{
	char *addr;
	u32 x0, x4, x8, xc;
	u32 *dump_addr = NULL;
	int len;
	int i;
	bool in_log, in_mem;

	if (!dbg || !dbg->base) {
		pr_err("dbg base is null!\n");
		return;
	}

	in_log = (reg_dump_flag & MDSS_REG_DUMP_IN_LOG);
	in_mem = (reg_dump_flag & MDSS_REG_DUMP_IN_MEM);

	addr = dbg->base;
	len = dbg->max_offset;

	addr = base;
	if (len % 16)
		len += 16;
	len /= 16;

	pr_info("reg_dump_flag=%d in_log=%d in_mem=%d\n", reg_dump_flag, in_log,
		in_mem);
	pr_info("=========%s DUMP=========\n", dbg->name);

	if (in_mem) {
		if (!dbg->reg_dump)
			dbg->reg_dump = kzalloc(len * 16, GFP_KERNEL);

		if (dbg->reg_dump) {
			dump_addr = dbg->reg_dump;
			pr_info("start_addr:%p end_addr:%p reg_addr=%p\n",
				dump_addr, dump_addr + (u32)len * 16,
				addr);
		} else {
			in_mem = false;
			pr_err("reg_dump: kzalloc fails!\n");
		}
	}

	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
	for (i = 0; i < len; i++) {
		u32 x0, x4, x8, xc;

		x0 = readl_relaxed(addr+0x0);
		x4 = readl_relaxed(addr+0x4);
		x8 = readl_relaxed(addr+0x8);
		xc = readl_relaxed(addr+0xc);
		pr_info("%p : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc);

		if (in_log)
			pr_info("%p : %08x %08x %08x %08x\n", addr, x0, x4, x8,
				xc);

		if (dump_addr && in_mem) {
			dump_addr[i*4] = x0;
			dump_addr[i*4 + 1] = x4;
			dump_addr[i*4 + 2] = x8;
			dump_addr[i*4 + 3] = xc;
		}

		addr += 16;
	}
	mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
+9 −2
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@
#define XLOG_FUNC_EXIT	0x2222
#define MDSS_REG_BLOCK_NAME_LEN (5)

enum mdss_dbg_reg_dump_flag {
	MDSS_REG_DUMP_IN_LOG = BIT(0),
	MDSS_REG_DUMP_IN_MEM = BIT(1),
};

#define MDSS_XLOG(...) mdss_xlog(__func__, ##__VA_ARGS__, DATA_LIMITER)
#define MDSS_XLOG_TOUT_HANDLER(...)	\
	mdss_xlog_tout_handler(__func__, ##__VA_ARGS__, XLOG_TOUT_DATA_LIMITER)
@@ -53,6 +58,7 @@ struct mdss_debug_base {
	char *buf;
	size_t buf_len;
	struct list_head head;
	u32 *reg_dump;
};

struct mdss_debug_data {
@@ -87,7 +93,7 @@ void mdss_misr_crc_collect(struct mdss_data_type *mdata, int block_id);
int mdss_create_xlog_debug(struct mdss_debug_data *mdd);
void mdss_xlog(const char *name, ...);
void mdss_xlog_dump(void);
void mdss_dump_reg(char __iomem *base, int len);
void mdss_dump_reg(struct mdss_debug_base *dbg, u32 reg_dump_flag);
void mdss_xlog_tout_handler(const char *name, ...);
#else
static inline int mdss_debugfs_init(struct mdss_data_type *mdata) { return 0; }
@@ -111,7 +117,8 @@ static inline void mdss_misr_crc_collect(struct mdss_data_type *mdata,
static inline int create_xlog_debug(struct mdss_data_type *mdata) { return 0; }
static inline void mdss_xlog(const char *name, ...) { }
static inline void mdss_xlog_dump(void) { }
static inline void mdss_dump_reg(char __iomem *base, int len) { }
static inline void mdss_dump_reg(struct mdss_debug_base *dbg,
	u32 reg_dump_flag) { }
static inline void mdss_dsi_debug_check_te(struct mdss_panel_data *pdata) { }
static inline void mdss_xlog_tout_handler(const char *name, ...) { }
#endif
+5 −8
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ int mdss_create_xlog_debug(struct mdss_debug_data *mdd)
			    &mdss_dbg_xlog.xlog_enable);
	debugfs_create_bool("panic", 0644, mdss_dbg_xlog.xlog,
			    &mdss_dbg_xlog.panic_on_err);
	debugfs_create_bool("reg_dump_in_log", 0644, mdss_dbg_xlog.xlog,
	debugfs_create_u32("reg_dump", 0644, mdss_dbg_xlog.xlog,
			    &mdss_dbg_xlog.enable_reg_dump);
	return 0;
}
@@ -178,13 +178,10 @@ void mdss_xlog_tout_handler(const char *name, ...)
		list_for_each_entry_safe(blk_base, tmp, &mdd->base_list, head) {

			if (blk_base->name &&
				!strcmp(blk_base->name, blk_name) &&
				mdss_dbg_xlog.enable_reg_dump) {
				pr_info("\n%s  :   =========%s DUMP=========\n",
						__func__, blk_base->name);
				mdss_dump_reg(blk_base->base,
						blk_base->max_offset);
			}
				!strcmp(blk_base->name, blk_name))

				mdss_dump_reg(blk_base,
					mdss_dbg_xlog.enable_reg_dump);
		}
		if (!strcmp(blk_name, "panic"))
			dead = 1;