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

Commit a5efd1f0 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: sde: save register write logs in dump"

parents b080a9f0 9c588044
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -77,6 +77,8 @@ void sde_reg_write(struct sde_hw_blk_reg_map *c,
		SDE_DEBUG_DRIVER("[%s:0x%X] <= 0x%X\n",
				name, c->blk_off + reg_off, val);
	writel_relaxed(val, c->base_off + c->blk_off + reg_off);
	SDE_REG_LOG(c->log_mask ? ilog2(c->log_mask)+1 : 0,
			val, c->blk_off + reg_off);
}

int sde_reg_read(struct sde_hw_blk_reg_map *c, u32 reg_off)
+15 −0
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ struct sde_dbg_regbuf {
/**
 * struct sde_dbg_base - global sde debug base structure
 * @evtlog: event log instance
 * @reglog: reg log instance
 * @reg_base_list: list of register dumping regions
 * @dev: device pointer
 * @mutex: mutex to serialize access to serialze dumps, debugfs access
@@ -212,11 +213,13 @@ struct sde_dbg_regbuf {
 * @dsi_dbg_bus: dump dsi debug bus register
 * @regbuf: buffer data to track the register dumping in hw recovery
 * @cur_evt_index: index used for tracking event logs dump in hw recovery
 * @cur_reglog_index: index used for tracking register logs dump in hw recovery
 * @dbgbus_dump_idx: index used for tracking dbg-bus dump in hw recovery
 * @vbif_dbgbus_dump_idx: index for tracking vbif dumps in hw recovery
 */
static struct sde_dbg_base {
	struct sde_dbg_evtlog *evtlog;
	struct sde_dbg_reglog *reglog;
	struct list_head reg_base_list;
	void *reg_dump_addr;
	struct device *dev;
@@ -239,6 +242,7 @@ static struct sde_dbg_base {

	struct sde_dbg_regbuf regbuf;
	u32 cur_evt_index;
	u32 cur_reglog_index;
	u32 dbgbus_dump_idx;
	u32 vbif_dbgbus_dump_idx;
	enum sde_dbg_dump_context dump_mode;
@@ -247,6 +251,9 @@ static struct sde_dbg_base {
/* sde_dbg_base_evtlog - global pointer to main sde event log for macro use */
struct sde_dbg_evtlog *sde_dbg_base_evtlog;

/* sde_dbg_base_reglog - global pointer to main sde reg log for macro use */
struct sde_dbg_reglog *sde_dbg_base_reglog;

static void _sde_debug_bus_xbar_dump(void __iomem *mem_base,
		struct sde_debug_bus_entry *entry, u32 val)
{
@@ -4727,6 +4734,12 @@ int sde_dbg_init(struct device *dev)

	sde_dbg_base_evtlog = sde_dbg_base.evtlog;

	sde_dbg_base.reglog = sde_reglog_init();
	if (IS_ERR_OR_NULL(sde_dbg_base.reglog))
		return PTR_ERR(sde_dbg_base.reglog);

	sde_dbg_base_reglog = sde_dbg_base.reglog;

	INIT_WORK(&sde_dbg_base.dump_work, _sde_dump_work);
	sde_dbg_base.work_panic = false;
	sde_dbg_base.panic_on_err = DEFAULT_PANIC;
@@ -4771,6 +4784,8 @@ void sde_dbg_destroy(void)
	sde_dbg_base_evtlog = NULL;
	sde_evtlog_destroy(sde_dbg_base.evtlog);
	sde_dbg_base.evtlog = NULL;
	sde_reglog_destroy(sde_dbg_base.reglog);
	sde_dbg_base.reglog = NULL;
	sde_dbg_reg_base_destroy();
	mutex_destroy(&sde_dbg_base.mutex);
}
+92 −0
Original line number Diff line number Diff line
@@ -49,6 +49,34 @@ enum sde_dbg_dump_context {
	SDE_DBG_DUMP_CLK_ENABLED_CTX,
};

/*
 * Define blocks for register write logging.
 */
#define SDE_REG_LOG_DEFAULT  0
#define SDE_REG_LOG_NONE     1
#define SDE_REG_LOG_CDM      2
#define SDE_REG_LOG_DSPP     3
#define SDE_REG_LOG_INTF     4
#define SDE_REG_LOG_LM       5
#define SDE_REG_LOG_CTL      6
#define SDE_REG_LOG_PINGPONG 7
#define SDE_REG_LOG_SSPP     8
#define SDE_REG_LOG_WB       9
#define SDE_REG_LOG_TOP     10
#define SDE_REG_LOG_VBIF    11
#define SDE_REG_LOG_DSC     12
#define SDE_REG_LOG_ROT     13
#define SDE_REG_LOG_DS      14
#define SDE_REG_LOG_REGDMA  15
#define SDE_REG_LOG_UIDLE   16
#define SDE_REG_LOG_SID     16
#define SDE_REG_LOG_QDSS    17
/*
 * 0-32 are reserved for sde_reg_write due to log masks
 * Additional blocks are assigned from 33 to avoid conflict
 */
#define SDE_REG_LOG_RSCC    33

#define SDE_EVTLOG_DEFAULT_ENABLE (SDE_EVTLOG_CRITICAL | SDE_EVTLOG_IRQ | \
		SDE_EVTLOG_EXTERNAL)

@@ -103,6 +131,44 @@ struct sde_dbg_evtlog {

extern struct sde_dbg_evtlog *sde_dbg_base_evtlog;

/*
 * reglog keeps this number of entries in memory for debug purpose. This
 * number must be greater than number of possible writes in at least one
 * single commit.
 */
#define SDE_REGLOG_ENTRY 1024

struct sde_dbg_reglog_log {
	s64 time;
	u32 pid;
	u32 addr;
	u32 val;
	u8 blk_id;
};

/**
 * @last_dump: Index of last entry to be output during reglog dumps
 * @filter_list: Linked list of currently active filter strings
 */
struct sde_dbg_reglog {
	struct sde_dbg_reglog_log logs[SDE_REGLOG_ENTRY];
	u32 first;
	u32 last;
	u32 last_dump;
	u32 curr;
	u32 next;
	u32 enable;
	u32 enable_mask;
	spinlock_t spin_lock;
};

extern struct sde_dbg_reglog *sde_dbg_base_reglog;

/**
 * SDE_REG_LOG - Write register write to the register log
 */
#define SDE_REG_LOG(blk_id, val, addr) sde_reglog_log(blk_id, val, addr)

/**
 * SDE_EVT32 - Write a list of 32bit values to the event log, default area
 * ... - variable arguments
@@ -183,6 +249,12 @@ extern struct sde_dbg_evtlog *sde_dbg_base_evtlog;
 */
struct sde_dbg_evtlog *sde_evtlog_init(void);

/**
 * sde_reglog_init - allocate a new reg log object
 * Returns:	reglog or -ERROR
 */
struct sde_dbg_reglog *sde_reglog_init(void);

/**
 * sde_evtlog_destroy - destroy previously allocated event log
 * @evtlog:	pointer to evtlog
@@ -190,6 +262,13 @@ struct sde_dbg_evtlog *sde_evtlog_init(void);
 */
void sde_evtlog_destroy(struct sde_dbg_evtlog *evtlog);

/**
 * sde_reglog_destroy - destroy previously allocated reg log
 * @reglog:	pointer to reglog
 * Returns:	none
 */
void sde_reglog_destroy(struct sde_dbg_reglog *reglog);

/**
 * sde_evtlog_log - log an entry into the event log.
 *	log collection may be enabled/disabled entirely via debugfs
@@ -203,6 +282,15 @@ void sde_evtlog_destroy(struct sde_dbg_evtlog *evtlog);
void sde_evtlog_log(struct sde_dbg_evtlog *evtlog, const char *name, int line,
		int flag, ...);

/**
 * sde_reglog_log - log an entry into the reg log.
 *      log collection may be enabled/disabled entirely via debugfs
 *      log area collection may be filtered by user provided flags via debugfs.
 * @reglog:     pointer to evtlog
 * Returns:     none
 */
void sde_reglog_log(u8 blk_id, u32 val, u32 addr);

/**
 * sde_evtlog_dump_all - print all entries in event log to kernel log
 * @evtlog:	pointer to evtlog
@@ -386,6 +474,10 @@ static inline void sde_evtlog_log(struct sde_dbg_evtlog *evtlog,
{
}

static inline void sde_reglog_log(u8 blk_id, u32 val, u32 addr)
{
}

static inline void sde_evtlog_dump_all(struct sde_dbg_evtlog *evtlog)
{
}
+47 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"sde_dbg:[%s] " fmt, __func__
@@ -101,6 +101,31 @@ void sde_evtlog_log(struct sde_dbg_evtlog *evtlog, const char *name, int line,
	spin_unlock_irqrestore(&evtlog->spin_lock, flags);
}

void sde_reglog_log(u8 blk_id, u32 val, u32 addr)
{
	unsigned long flags;
	struct sde_dbg_reglog_log *log;
	struct sde_dbg_reglog *reglog = sde_dbg_base_reglog;

	if (!reglog)
		return;

	spin_lock_irqsave(&reglog->spin_lock, flags);

	log = &reglog->logs[reglog->curr];

	log->blk_id = blk_id;
	log->val = val;
	log->addr = addr;
	log->time = local_clock();
	log->pid = current->pid;

	reglog->curr = (reglog->curr + 1) % SDE_REGLOG_ENTRY;
	reglog->last++;

	spin_unlock_irqrestore(&reglog->spin_lock, flags);
}

/* always dump the last entries which are not dumped yet */
static bool _sde_evtlog_dump_calc_range(struct sde_dbg_evtlog *evtlog,
		bool update_last_entry, bool full_dump)
@@ -211,6 +236,19 @@ struct sde_dbg_evtlog *sde_evtlog_init(void)
	return evtlog;
}

struct sde_dbg_reglog *sde_reglog_init(void)
{
	struct sde_dbg_reglog *reglog;

	reglog = kzalloc(sizeof(*reglog), GFP_KERNEL);
	if (!reglog)
		return ERR_PTR(-ENOMEM);

	spin_lock_init(&reglog->spin_lock);

	return reglog;
}

int sde_evtlog_get_filter(struct sde_dbg_evtlog *evtlog, int index,
		char *buf, size_t bufsz)
{
@@ -312,3 +350,11 @@ void sde_evtlog_destroy(struct sde_dbg_evtlog *evtlog)
	}
	kfree(evtlog);
}

void sde_reglog_destroy(struct sde_dbg_reglog *reglog)
{
	if (!reglog)
		return;

	kfree(reglog);
}
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
#include <linux/sde_io_util.h>
#include "sde_dbg.h"

#define MAX_I2C_CMDS  16
void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug)
@@ -34,6 +35,7 @@ void dss_reg_w(struct dss_io_data *io, u32 offset, u32 value, u32 debug)
			(u32)(unsigned long)(io->base + offset),
			value, in_val);
	}
	SDE_REG_LOG(SDE_REG_LOG_RSCC, value, offset);
} /* dss_reg_w */
EXPORT_SYMBOL(dss_reg_w);