Merge "disp: msm: sde: modify SDE_DBG_DUMP to use blk_mask instead of blk_name"

This commit is contained in:
qctecmdr
2021-03-25 14:22:21 -07:00
committed by Gerrit - the friendly Code Review server
melakukan 19e9831a45
10 mengubah file dengan 197 tambahan dan 357 penghapusan

Melihat File

@@ -23,12 +23,7 @@
#define DEFAULT_PANIC 1
#define DEFAULT_REGDUMP SDE_DBG_DUMP_IN_MEM
#define DEFAULT_DBGBUS_SDE SDE_DBG_DUMP_IN_MEM
#define DEFAULT_DBGBUS_VBIFRT SDE_DBG_DUMP_IN_MEM
#define DEFAULT_DBGBUS_DSI SDE_DBG_DUMP_IN_MEM
#define DEFAULT_DBGBUS_RSC SDE_DBG_DUMP_IN_MEM
#define DEFAULT_DBGBUS_LUTDMA SDE_DBG_DUMP_IN_MEM
#define DEFAULT_DBGBUS_DP SDE_DBG_DUMP_IN_MEM
#define DEFAULT_DBGBUS_DUMP SDE_DBG_DUMP_IN_MEM
#define DEFAULT_BASE_REG_CNT DEFAULT_MDSS_HW_BLOCK_SIZE
#define GROUP_BYTES 4
#define ROW_BYTES 16
@@ -164,6 +159,7 @@ struct sde_dbg_reg_range {
* @reg_dump: address for the mem dump if no ranges used
* @cb: callback for external dump function, null if not defined
* @cb_ptr: private pointer to callback function
* @blk_id: id indicate the HW block
*/
struct sde_dbg_reg_base {
struct list_head reg_base_head;
@@ -178,6 +174,7 @@ struct sde_dbg_reg_base {
u32 *reg_dump;
void (*cb)(void *ptr);
void *cb_ptr;
u64 blk_id;
};
struct sde_debug_bus_entry {
@@ -198,13 +195,12 @@ struct sde_dbg_dsi_ctrl_list_entry {
struct sde_dbg_debug_bus_common {
char *name;
u32 enable_mask;
bool include_in_deferred_work;
u32 entries_size;
u32 limited_entries_size;
u32 *dumped_content;
u32 content_idx;
u32 content_size;
u64 blk_id;
};
struct sde_dbg_sde_debug_bus {
@@ -246,13 +242,14 @@ struct sde_dbg_regbuf {
* @dump_work: work struct for deferring register dump work to separate thread
* @work_panic: panic after dump if internal user passed "panic" special region
* @enable_reg_dump: whether to dump registers into memory, kernel log, or both
* @enable_dbgbus_dump: whether to dump dbgbus into memory, kernel log, or both
* @dbgbus_sde: debug bus structure for the sde
* @dbgbus_vbif_rt: debug bus structure for the realtime vbif
* @dbgbus_dsi: debug bus structure for the dsi
* @dbgbus_rsc: debug bus structure for rscc
* @dbgbus_lutdma: debug bus structure for the lutdma hw
* @dbgbus_dp: debug bus structure for dp
* @dump_all: dump all entries in register dump
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
* @dump_secure: dump entries excluding few as it is in secure-session
* @regbuf: buffer data to track the register dumping in hw recovery
* @cur_evt_index: index used for tracking event logs dump in hw recovery
@@ -271,6 +268,7 @@ static struct sde_dbg_base {
struct work_struct dump_work;
bool work_panic;
u32 enable_reg_dump;
u32 enable_dbgbus_dump;
struct sde_dbg_sde_debug_bus dbgbus_sde;
struct sde_dbg_sde_debug_bus dbgbus_vbif_rt;
@@ -278,7 +276,7 @@ static struct sde_dbg_base {
struct sde_dbg_sde_debug_bus dbgbus_rsc;
struct sde_dbg_sde_debug_bus dbgbus_lutdma;
struct sde_dbg_sde_debug_bus dbgbus_dp;
bool dump_all;
u64 dump_blk_mask;
bool dump_secure;
u32 debugfs_ctrl;
@@ -465,7 +463,6 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
u32 *dump_addr = NULL;
char *end_addr;
int i;
int rc;
if (!len_bytes || !dump_mem)
return;
@@ -489,14 +486,6 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
dump_addr = *dump_mem;
SDE_DBG_LOG_DUMP_ADDR(dump_name, dump_addr, len_padded, (unsigned long)(addr - base_addr));
if (_sde_power_check(sde_dbg_base.dump_mode)) {
rc = pm_runtime_get_sync(sde_dbg_base.dev);
if (rc < 0) {
pr_err("failed to enable power %d\n", rc);
return;
}
}
for (i = 0; i < len_align; i++) {
u32 x0, x4, x8, xc;
@@ -517,9 +506,6 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
addr += REG_DUMP_ALIGN;
}
if (_sde_power_check(sde_dbg_base.dump_mode))
pm_runtime_put_sync(sde_dbg_base.dev);
}
/**
@@ -582,10 +568,8 @@ static bool is_block_exclude(char **modules, char *name)
* _sde_dump_reg_by_ranges - dump ranges or full range of the register blk base
* @dbg: register blk base structure
* @reg_dump_flag: dump target, memory, kernel log, or both
* @dump_secure: flag to indicate dumping in secure-session
*/
static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg,
u32 reg_dump_flag, bool dump_secure)
static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg, u32 reg_dump_flag)
{
char *addr;
size_t len;
@@ -604,81 +588,48 @@ static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg,
/* sort the list by start address first */
list_sort(NULL, &dbg->sub_range_list, _sde_dump_reg_range_cmp);
list_for_each_entry(range_node, &dbg->sub_range_list, head) {
len = _sde_dbg_get_dump_range(&range_node->offset,
dbg->max_offset);
len = _sde_dbg_get_dump_range(&range_node->offset, dbg->max_offset);
addr = dbg->base + range_node->offset.start;
if (dump_secure &&
is_block_exclude((char**)exclude_modules,
range_node->range_name))
continue;
pr_debug("%s: range_base=0x%pK start=0x%x end=0x%x\n",
range_node->range_name,
addr, range_node->offset.start,
range_node->range_name, addr, range_node->offset.start,
range_node->offset.end);
_sde_dump_reg(range_node->range_name, reg_dump_flag,
dbg->base, addr, len,
&range_node->reg_dump);
dbg->base, addr, len, &range_node->reg_dump);
}
} else {
/* If there is no list to dump ranges, dump all registers */
dev_info(sde_dbg_base.dev,
"Ranges not found, will dump full registers\n");
dev_info(sde_dbg_base.dev, "Ranges not found, will dump full registers\n");
SDE_DBG_LOG_DUMP_ADDR("base", dbg->base, dbg->max_offset, 0);
addr = dbg->base;
len = dbg->max_offset;
_sde_dump_reg(dbg->name, reg_dump_flag, dbg->base, addr, len,
&dbg->reg_dump);
_sde_dump_reg(dbg->name, reg_dump_flag, dbg->base, addr, len, &dbg->reg_dump);
}
}
/**
* _sde_dump_reg_by_blk - dump a named register base region
* @blk_name: register blk name
* _sde_dump_reg_mask - dump register regions based on mask
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
* @dump_secure: flag to indicate dumping in secure-session
*/
static void _sde_dump_reg_by_blk(const char *blk_name, bool dump_secure)
static void _sde_dump_reg_mask(u64 dump_blk_mask, bool dump_secure)
{
struct sde_dbg_base *dbg_base = &sde_dbg_base;
struct sde_dbg_reg_base *blk_base;
if (!dbg_base)
return;
list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head) {
if (strlen(blk_base->name) &&
!strcmp(blk_base->name, blk_name)) {
_sde_dump_reg_by_ranges(blk_base,
dbg_base->enable_reg_dump, dump_secure);
break;
}
}
}
/**
* _sde_dump_reg_all - dump all register regions
*/
static void _sde_dump_reg_all(bool dump_secure)
{
struct sde_dbg_base *dbg_base = &sde_dbg_base;
struct sde_dbg_reg_base *blk_base;
if (!dbg_base)
if (!dump_blk_mask)
return;
list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head) {
if (!strlen(blk_base->name))
if ((!(blk_base->blk_id & dump_blk_mask)) || (!strlen(blk_base->name)))
continue;
if (dump_secure &&
is_block_exclude((char **)exclude_modules,
blk_base->name))
if (dump_secure && is_block_exclude((char **)exclude_modules, blk_base->name))
continue;
_sde_dump_reg_by_blk(blk_base->name, dump_secure);
_sde_dump_reg_by_ranges(blk_base, dbg_base->enable_reg_dump);
}
}
@@ -854,7 +805,7 @@ static bool _is_dbg_bus_limited_valid(struct sde_dbg_sde_debug_bus *bus,
static void _sde_dbg_dump_bus_entry(struct sde_dbg_sde_debug_bus *bus,
struct sde_debug_bus_entry *entries, u32 bus_size,
void __iomem *mem_base, u32 *dump_addr)
void __iomem *mem_base, u32 *dump_addr, u32 enable_mask)
{
u32 status = 0;
int i, j, k;
@@ -864,9 +815,9 @@ static void _sde_dbg_dump_bus_entry(struct sde_dbg_sde_debug_bus *bus,
if (!bus->read_tp || !bus->clear_tp)
return;
in_mem = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_MEM);
in_log = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_LOG);
in_log_limited = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_LOG_LIMITED);
in_mem = (enable_mask & SDE_DBG_DUMP_IN_MEM);
in_log = (enable_mask & SDE_DBG_DUMP_IN_LOG);
in_log_limited = (enable_mask & SDE_DBG_DUMP_IN_LOG_LIMITED);
for (k = 0; k < bus_size; k++) {
entry = entries + k;
@@ -899,7 +850,7 @@ static void _sde_dbg_dump_bus_entry(struct sde_dbg_sde_debug_bus *bus,
}
}
static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus, u32 enable_mask)
{
bool in_mem;
u32 **dump_mem = NULL;
@@ -939,7 +890,7 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
snprintf(name, sizeof(name), "%s-debugbus", bus->cmn.name);
SDE_DBG_LOG_MARKER(name, SDE_DBG_LOG_START);
in_mem = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_MEM);
in_mem = (enable_mask & SDE_DBG_DUMP_IN_MEM);
if (in_mem && (!(*dump_mem))) {
*dump_mem = devm_kzalloc(sde_dbg_base.dev, list_size, GFP_KERNEL);
bus->cmn.content_size = list_size / sizeof(u32);
@@ -947,12 +898,12 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
dump_addr = *dump_mem;
SDE_DBG_LOG_DUMP_ADDR(bus->cmn.name, dump_addr, list_size, 0);
_sde_dbg_dump_bus_entry(bus, entries, bus_size, mem_base, dump_addr);
_sde_dbg_dump_bus_entry(bus, entries, bus_size, mem_base, dump_addr, enable_mask);
SDE_DBG_LOG_MARKER(name, SDE_DBG_LOG_END);
}
static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus, u32 enable_mask)
{
struct sde_dbg_dsi_ctrl_list_entry *ctl_entry;
struct list_head *list;
@@ -982,7 +933,7 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
SDE_DBG_LOG_MARKER(name, SDE_DBG_LOG_START);
mutex_lock(&sde_dbg_dsi_mutex);
in_mem = (bus->cmn.enable_mask & SDE_DBG_DUMP_IN_MEM);
in_mem = (enable_mask & SDE_DBG_DUMP_IN_MEM);
if (in_mem && (!(*dump_mem))) {
*dump_mem = devm_kzalloc(sde_dbg_base.dev, list_size, GFP_KERNEL);
bus->cmn.content_size = list_size / sizeof(u32);
@@ -992,7 +943,8 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
list_for_each_entry(ctl_entry, &sde_dbg_dsi_list, list) {
SDE_DBG_LOG_DUMP_ADDR(ctl_entry->name, dump_addr, list_size / dsi_count, 0);
_sde_dbg_dump_bus_entry(bus, entries, bus_size, ctl_entry->base, dump_addr);
_sde_dbg_dump_bus_entry(bus, entries, bus_size, ctl_entry->base,
dump_addr, enable_mask);
}
mutex_unlock(&sde_dbg_dsi_mutex);
@@ -1001,42 +953,23 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
/**
* _sde_dump_array - dump array of register bases
* @blk_arr: array of register base pointers
* @len: length of blk_arr
* @do_panic: whether to trigger a panic after dumping
* @name: string indicating origin of dump
* @dump_dbgbus_sde: whether to dump the sde debug bus
* @dump_dbgbus_vbif_rt: whether to dump the vbif rt debug bus
* @dump_dbgbus_dsi: whether to dump the dsi debug bus
* @dump_dbgbus_dp: whether to dump the dp debug bus
* @dump_all: dump evtlog + regs
* @dump_secure: flag to indicate dumping in secure-session
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
*/
static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
u32 len, bool do_panic, const char *name, bool dump_dbgbus_sde, bool dump_dbgbus_vbif_rt,
bool dump_dbgbus_dsi, bool dump_dbgbus_dp, bool dump_all, bool dump_secure)
static void _sde_dump_array(bool do_panic, const char *name, bool dump_secure, u64 dump_blk_mask)
{
int i, rc;
int rc;
ktime_t start, end;
struct sde_dbg_base *dbg_base = &sde_dbg_base;
mutex_lock(&sde_dbg_base.mutex);
mutex_lock(&dbg_base->mutex);
if (dump_all)
sde_evtlog_dump_all(sde_dbg_base.evtlog);
sde_evtlog_dump_all(dbg_base->evtlog);
if (dump_all || !blk_arr || !len) {
_sde_dump_reg_all(dump_secure);
} else {
for (i = 0; i < len; i++) {
if (blk_arr[i] != NULL)
_sde_dump_reg_by_ranges(blk_arr[i],
sde_dbg_base.enable_reg_dump,
dump_secure);
}
}
if (_sde_power_check(sde_dbg_base.dump_mode)) {
rc = pm_runtime_get_sync(sde_dbg_base.dev);
if (_sde_power_check(dbg_base->dump_mode)) {
rc = pm_runtime_get_sync(dbg_base->dev);
if (rc < 0) {
pr_err("failed to enable power %d\n", rc);
return;
@@ -1044,33 +977,43 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
}
start = ktime_get();
if (dump_dbgbus_sde) {
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_sde);
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_lutdma);
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_rsc);
}
_sde_dump_reg_mask(dump_blk_mask, dump_secure);
end = ktime_get();
dev_info(dbg_base->dev,
"reg-dump logging time start_us:%llu, end_us:%llu , duration_us:%llu\n",
ktime_to_us(start), ktime_to_us(end), ktime_us_delta(end, start));
if (dump_dbgbus_vbif_rt)
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_vbif_rt);
start = ktime_get();
if (dump_blk_mask & SDE_DBG_SDE_DBGBUS)
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_sde, dbg_base->enable_dbgbus_dump);
if (dump_dbgbus_dsi)
_sde_dbg_dump_dsi_dbg_bus(&sde_dbg_base.dbgbus_dsi);
if (dump_blk_mask & SDE_DBG_LUTDMA_DBGBUS)
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_lutdma, dbg_base->enable_dbgbus_dump);
if (dump_dbgbus_dp)
_sde_dbg_dump_sde_dbg_bus(&sde_dbg_base.dbgbus_dp);
if (dump_blk_mask & SDE_DBG_RSC_DBGBUS)
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_rsc, dbg_base->enable_dbgbus_dump);
if (dump_blk_mask & SDE_DBG_VBIF_RT_DBGBUS)
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_vbif_rt, dbg_base->enable_dbgbus_dump);
if (dump_blk_mask & SDE_DBG_DSI_DBGBUS)
_sde_dbg_dump_dsi_dbg_bus(&dbg_base->dbgbus_dsi, dbg_base->enable_dbgbus_dump);
if (dump_blk_mask & SDE_DBG_DP_DBGBUS)
_sde_dbg_dump_sde_dbg_bus(&dbg_base->dbgbus_dp, dbg_base->enable_dbgbus_dump);
end = ktime_get();
dev_info(sde_dbg_base.dev,
dev_info(dbg_base->dev,
"debug-bus logging time start_us:%llu, end_us:%llu , duration_us:%llu\n",
ktime_to_us(start), ktime_to_us(end), ktime_us_delta(end , start));
ktime_to_us(start), ktime_to_us(end), ktime_us_delta(end, start));
if (_sde_power_check(sde_dbg_base.dump_mode))
pm_runtime_put_sync(sde_dbg_base.dev);
if (_sde_power_check(dbg_base->dump_mode))
pm_runtime_put_sync(dbg_base->dev);
if (do_panic && sde_dbg_base.panic_on_err)
if (do_panic && dbg_base->panic_on_err)
panic(name);
mutex_unlock(&sde_dbg_base.mutex);
mutex_unlock(&dbg_base->mutex);
}
/**
@@ -1079,87 +1022,36 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
*/
static void _sde_dump_work(struct work_struct *work)
{
_sde_dump_array(sde_dbg_base.req_dump_blks,
ARRAY_SIZE(sde_dbg_base.req_dump_blks),
sde_dbg_base.work_panic, "evtlog_workitem",
sde_dbg_base.dbgbus_sde.cmn.include_in_deferred_work,
sde_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work,
sde_dbg_base.dbgbus_dsi.cmn.include_in_deferred_work,
sde_dbg_base.dbgbus_dp.cmn.include_in_deferred_work,
sde_dbg_base.dump_all, sde_dbg_base.dump_secure);
_sde_dump_array(sde_dbg_base.work_panic, "evtlog_workitem",
sde_dbg_base.dump_secure, sde_dbg_base.dump_blk_mask);
}
void sde_dbg_dump(enum sde_dbg_dump_context dump_mode, const char *name, ...)
void sde_dbg_dump(enum sde_dbg_dump_context dump_mode, const char *name, u64 dump_blk_mask, ...)
{
int i, index = 0;
int i = 0;
bool do_panic = false;
bool dump_dbgbus_sde = false;
bool dump_dbgbus_vbif_rt = false;
bool dump_dbgbus_dsi = false;
bool dump_dbgbus_dp = false;
bool dump_all = false;
bool dump_secure = false;
va_list args;
char *blk_name = NULL;
struct sde_dbg_reg_base *blk_base = NULL;
struct sde_dbg_reg_base **blk_arr;
u32 blk_len;
char *str = NULL;
if (!sde_evtlog_is_enabled(sde_dbg_base.evtlog, SDE_EVTLOG_ALWAYS))
return;
if ((dump_mode == SDE_DBG_DUMP_IRQ_CTX) &&
work_pending(&sde_dbg_base.dump_work))
if ((dump_mode == SDE_DBG_DUMP_IRQ_CTX) && work_pending(&sde_dbg_base.dump_work))
return;
blk_arr = &sde_dbg_base.req_dump_blks[0];
blk_len = ARRAY_SIZE(sde_dbg_base.req_dump_blks);
memset(sde_dbg_base.req_dump_blks, 0,
sizeof(sde_dbg_base.req_dump_blks));
sde_dbg_base.dump_all = false;
sde_dbg_base.dump_mode = dump_mode;
va_start(args, name);
i = 0;
while ((blk_name = va_arg(args, char*))) {
va_start(args, dump_blk_mask);
while ((str = va_arg(args, char*))) {
if (i++ >= SDE_EVTLOG_MAX_DATA) {
pr_err("could not parse all dump arguments\n");
break;
}
if (IS_ERR_OR_NULL(blk_name))
break;
blk_base = _sde_dump_get_blk_addr(blk_name);
if (blk_base) {
if (index < blk_len) {
blk_arr[index] = blk_base;
index++;
} else {
pr_err("insufficient space to to dump %s\n",
blk_name);
}
}
if (!strcmp(blk_name, "all"))
dump_all = true;
if (!strcmp(blk_name, "dbg_bus"))
dump_dbgbus_sde = true;
if (!strcmp(blk_name, "vbif_dbg_bus"))
dump_dbgbus_vbif_rt = true;
if (!strcmp(blk_name, "dsi_dbg_bus"))
dump_dbgbus_dsi = true;
if (!strcmp(blk_name, "dp_dbg_bus"))
dump_dbgbus_dp = true;
if (!strcmp(blk_name, "panic"))
if (!strcmp(str, "panic"))
do_panic = true;
if (!strcmp(blk_name, "secure"))
else if (!strcmp(str, "secure"))
dump_secure = true;
}
va_end(args);
@@ -1167,17 +1059,10 @@ void sde_dbg_dump(enum sde_dbg_dump_context dump_mode, const char *name, ...)
if (dump_mode == SDE_DBG_DUMP_IRQ_CTX) {
/* schedule work to dump later */
sde_dbg_base.work_panic = do_panic;
sde_dbg_base.dbgbus_sde.cmn.include_in_deferred_work = dump_dbgbus_sde;
sde_dbg_base.dbgbus_vbif_rt.cmn.include_in_deferred_work = dump_dbgbus_vbif_rt;
sde_dbg_base.dbgbus_dsi.cmn.include_in_deferred_work = dump_dbgbus_dsi;
sde_dbg_base.dbgbus_rsc.cmn.include_in_deferred_work = dump_dbgbus_sde;
sde_dbg_base.dbgbus_dp.cmn.include_in_deferred_work = dump_dbgbus_dp;
sde_dbg_base.dump_all = dump_all;
sde_dbg_base.dump_blk_mask = dump_blk_mask;
schedule_work(&sde_dbg_base.dump_work);
} else {
_sde_dump_array(blk_arr, blk_len, do_panic, name, dump_dbgbus_sde,
dump_dbgbus_vbif_rt, dump_dbgbus_dsi, dump_dbgbus_dp,
dump_all, dump_secure);
_sde_dump_array(do_panic, name, dump_secure, dump_blk_mask);
}
}
@@ -1203,23 +1088,19 @@ void sde_dbg_ctrl(const char *name, ...)
break;
if (!strcmp(blk_name, "stop_ftrace") &&
sde_dbg_base.debugfs_ctrl &
DBG_CTRL_STOP_FTRACE) {
sde_dbg_base.debugfs_ctrl & DBG_CTRL_STOP_FTRACE) {
pr_debug("tracing off\n");
tracing_off();
}
if (!strcmp(blk_name, "panic_underrun") &&
sde_dbg_base.debugfs_ctrl &
DBG_CTRL_PANIC_UNDERRUN) {
sde_dbg_base.debugfs_ctrl & DBG_CTRL_PANIC_UNDERRUN) {
pr_err("panic underrun\n");
SDE_DBG_DUMP_WQ("all", "dbg_bus", "vbif_dbg_bus",
"panic");
SDE_DBG_DUMP_WQ(SDE_DBG_BUILT_IN_ALL, "panic");
}
if (!strcmp(blk_name, "reset_hw_panic") &&
sde_dbg_base.debugfs_ctrl &
DBG_CTRL_RESET_HW_PANIC) {
sde_dbg_base.debugfs_ctrl & DBG_CTRL_RESET_HW_PANIC) {
pr_debug("reset hw panic\n");
panic("reset_hw");
}
@@ -1326,8 +1207,8 @@ static ssize_t sde_evtlog_dump_read(struct file *file, char __user *buff,
static ssize_t sde_evtlog_dump_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
_sde_dump_array(NULL, 0, sde_dbg_base.panic_on_err, "dump_debugfs",
true, true, true, true, true, false);
_sde_dump_array(sde_dbg_base.panic_on_err, "dump_debugfs", false,
sde_dbg_base.dump_blk_mask);
return count;
}
@@ -2146,106 +2027,61 @@ int sde_dbg_debugfs_register(struct device *dev)
struct drm_device *ddev = platform_get_drvdata(pdev);
struct msm_drm_private *priv = NULL;
if (!ddev) {
if (!ddev || !ddev->dev_private) {
pr_err("Invalid drm device node\n");
return -EINVAL;
}
priv = ddev->dev_private;
if (!priv) {
pr_err("Invalid msm drm private node\n");
return -EINVAL;
}
debugfs_root = debugfs_create_dir("debug",
ddev->primary->debugfs_root);
debugfs_root = debugfs_create_dir("debug", ddev->primary->debugfs_root);
if (IS_ERR_OR_NULL(debugfs_root)) {
pr_err("debugfs_root create_dir fail, error %ld\n",
PTR_ERR(debugfs_root));
pr_err("debugfs_root create_dir fail, error %ld\n", PTR_ERR(debugfs_root));
priv->debug_root = NULL;
return -EINVAL;
}
priv->debug_root = debugfs_root;
debugfs_create_file("dbg_ctrl", 0600, debugfs_root, NULL,
&sde_dbg_ctrl_fops);
debugfs_create_file("dump", 0600, debugfs_root, NULL,
&sde_evtlog_fops);
debugfs_create_u32("enable", 0600, debugfs_root,
&(sde_dbg_base.evtlog->enable));
debugfs_create_u32("panic", 0600, debugfs_root,
&sde_dbg_base.panic_on_err);
debugfs_create_u32("reg_dump", 0600, debugfs_root,
&sde_dbg_base.enable_reg_dump);
debugfs_create_file("recovery_reg", 0400, debugfs_root, NULL,
&sde_recovery_reg_fops);
debugfs_create_file("dbg_ctrl", 0600, debugfs_root, NULL, &sde_dbg_ctrl_fops);
debugfs_create_file("dump", 0600, debugfs_root, NULL, &sde_evtlog_fops);
debugfs_create_file("recovery_reg", 0400, debugfs_root, NULL, &sde_recovery_reg_fops);
if (dbg->dbgbus_sde.entries) {
debugfs_create_u32("enable", 0600, debugfs_root, &(sde_dbg_base.evtlog->enable));
debugfs_create_u32("panic", 0600, debugfs_root, &sde_dbg_base.panic_on_err);
debugfs_create_u32("reg_dump", 0600, debugfs_root, &sde_dbg_base.enable_reg_dump);
debugfs_create_u32("dbgbus_dump", 0600, debugfs_root, &sde_dbg_base.enable_dbgbus_dump);
debugfs_create_u64("reg_dump_blk_mask", 0600, debugfs_root, &sde_dbg_base.dump_blk_mask);
if (dbg->dbgbus_sde.entries)
debugfs_create_file("recovery_dbgbus", 0400, debugfs_root, NULL,
&sde_recovery_dbgbus_fops);
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
dbg->dbgbus_sde.cmn.name);
debugfs_create_u32(debug_name, 0600, debugfs_root,
&dbg->dbgbus_sde.cmn.enable_mask);
}
if (dbg->dbgbus_vbif_rt.entries) {
if (dbg->dbgbus_vbif_rt.entries)
debugfs_create_file("recovery_vbif_dbgbus", 0400, debugfs_root,
NULL, &sde_recovery_vbif_dbgbus_fops);
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
dbg->dbgbus_vbif_rt.cmn.name);
debugfs_create_u32(debug_name, 0600, debugfs_root,
&dbg->dbgbus_vbif_rt.cmn.enable_mask);
}
if (dbg->dbgbus_dsi.entries) {
if (dbg->dbgbus_dsi.entries)
debugfs_create_file("recovery_dsi_dbgbus", 0400, debugfs_root,
NULL, &sde_recovery_dsi_dbgbus_fops);
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
dbg->dbgbus_dsi.cmn.name);
debugfs_create_u32(debug_name, 0600, debugfs_root,
&dbg->dbgbus_dsi.cmn.enable_mask);
}
if (dbg->dbgbus_rsc.entries) {
if (dbg->dbgbus_rsc.entries)
debugfs_create_file("recovery_rsc_dbgbus", 0400, debugfs_root,
NULL, &sde_recovery_rsc_dbgbus_fops);
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
dbg->dbgbus_rsc.cmn.name);
debugfs_create_u32(debug_name, 0600, debugfs_root,
&dbg->dbgbus_rsc.cmn.enable_mask);
}
if (dbg->dbgbus_lutdma.entries) {
debugfs_create_file("recovery_lutdma_dbgbus", 0400,
debugfs_root, NULL,
&sde_recovery_lutdma_dbgbus_fops);
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
dbg->dbgbus_lutdma.cmn.name);
debugfs_create_u32(debug_name, 0600, debugfs_root,
&dbg->dbgbus_lutdma.cmn.enable_mask);
}
if (dbg->dbgbus_lutdma.entries)
debugfs_create_file("recovery_lutdma_dbgbus", 0400, debugfs_root,
NULL, &sde_recovery_lutdma_dbgbus_fops);
if (dbg->dbgbus_dp.entries) {
if (dbg->dbgbus_dp.entries)
debugfs_create_file("recovery_dp_dbgbus", 0400, debugfs_root,
NULL, &sde_recovery_dp_dbgbus_fops);
snprintf(debug_name, sizeof(debug_name), "%s_dbgbus",
dbg->dbgbus_dp.cmn.name);
debugfs_create_u32(debug_name, 0600, debugfs_root,
&dbg->dbgbus_dp.cmn.enable_mask);
}
list_for_each_entry(blk_base, &dbg->reg_base_list, reg_base_head) {
snprintf(debug_name, sizeof(debug_name), "%s_off",
blk_base->name);
debugfs_create_file(debug_name, 0600, debugfs_root, blk_base,
&sde_off_fops);
snprintf(debug_name, sizeof(debug_name), "%s_off", blk_base->name);
debugfs_create_file(debug_name, 0600, debugfs_root, blk_base, &sde_off_fops);
snprintf(debug_name, sizeof(debug_name), "%s_reg",
blk_base->name);
debugfs_create_file(debug_name, 0400, debugfs_root, blk_base,
&sde_reg_fops);
snprintf(debug_name, sizeof(debug_name), "%s_reg", blk_base->name);
debugfs_create_file(debug_name, 0400, debugfs_root, blk_base, &sde_reg_fops);
}
return 0;
@@ -2279,7 +2115,7 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
dbg->dbgbus_sde.limited_entries = dbg_bus_sde_limited;
dbg->dbgbus_sde.cmn.limited_entries_size = ARRAY_SIZE(dbg_bus_sde_limited);
dbg->dbgbus_sde.cmn.name = DBGBUS_NAME_SDE;
dbg->dbgbus_sde.cmn.enable_mask = DEFAULT_DBGBUS_SDE;
dbg->dbgbus_sde.cmn.blk_id = SDE_DBG_SDE_DBGBUS;
dbg->dbgbus_sde.read_tp = _sde_dbg_sde_read_test_point;
dbg->dbgbus_sde.clear_tp = _sde_dbg_sde_clear_test_point;
@@ -2288,7 +2124,7 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
dbg->dbgbus_vbif_rt.limited_entries = vbif_dbg_bus_limited;
dbg->dbgbus_vbif_rt.cmn.limited_entries_size = ARRAY_SIZE(vbif_dbg_bus_limited);
dbg->dbgbus_vbif_rt.cmn.name = DBGBUS_NAME_VBIF_RT;
dbg->dbgbus_vbif_rt.cmn.enable_mask = DEFAULT_DBGBUS_VBIFRT;
dbg->dbgbus_vbif_rt.cmn.blk_id = SDE_DBG_VBIF_RT_DBGBUS;
dbg->dbgbus_vbif_rt.read_tp = _sde_dbg_vbif_read_test_point;
dbg->dbgbus_vbif_rt.clear_tp = _sde_dbg_vbif_clear_test_point;
dbg->dbgbus_vbif_rt.disable_block = _sde_dbg_vbif_disable_block;
@@ -2296,33 +2132,30 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
dbg->dbgbus_dsi.entries = dsi_dbg_bus;
dbg->dbgbus_dsi.cmn.entries_size = ARRAY_SIZE(dsi_dbg_bus);
dbg->dbgbus_dsi.cmn.name = DBGBUS_NAME_DSI;
dbg->dbgbus_dsi.cmn.enable_mask = DEFAULT_DBGBUS_DSI;
dbg->dbgbus_dsi.cmn.blk_id = SDE_DBG_DSI_DBGBUS;
dbg->dbgbus_dsi.read_tp = _sde_dbg_dsi_read_test_point;
dbg->dbgbus_dsi.clear_tp = _sde_dbg_cmn_clear_test_point;
dbg->dbgbus_rsc.entries = rsc_dbg_bus;
dbg->dbgbus_rsc.cmn.entries_size = ARRAY_SIZE(rsc_dbg_bus);
dbg->dbgbus_rsc.cmn.name = DBGBUS_NAME_RSC;
dbg->dbgbus_rsc.cmn.enable_mask = DEFAULT_DBGBUS_RSC;
dbg->dbgbus_rsc.cmn.blk_id = SDE_DBG_RSC_DBGBUS;
dbg->dbgbus_rsc.read_tp = _sde_dbg_rsc_read_test_point;
dbg->dbgbus_rsc.clear_tp = _sde_dbg_cmn_clear_test_point;
dbg->dbgbus_dp.entries = dp_dbg_bus;
dbg->dbgbus_dp.cmn.entries_size = ARRAY_SIZE(dp_dbg_bus);
dbg->dbgbus_dp.cmn.name = DBGBUS_NAME_DP;
dbg->dbgbus_dp.cmn.enable_mask = DEFAULT_DBGBUS_DP;
dbg->dbgbus_dp.cmn.blk_id = SDE_DBG_DP_DBGBUS;
dbg->dbgbus_dp.read_tp = _sde_dbg_dp_read_test_point;
dbg->dbgbus_dp.clear_tp = _sde_dbg_cmn_clear_test_point;
if (SDE_HW_REV_MAJOR(hwversion) >= 0x7) {
dbg->dbgbus_lutdma.entries = dbg_bus_lutdma;
dbg->dbgbus_lutdma.cmn.name = DBGBUS_NAME_LUTDMA;
dbg->dbgbus_lutdma.cmn.entries_size = ARRAY_SIZE(dbg_bus_lutdma);
dbg->dbgbus_lutdma.cmn.enable_mask = DEFAULT_DBGBUS_LUTDMA;
dbg->dbgbus_lutdma.cmn.include_in_deferred_work = true;
dbg->dbgbus_lutdma.read_tp = _sde_dbg_lutdma_read_test_point;
dbg->dbgbus_lutdma.clear_tp = _sde_dbg_cmn_clear_test_point;
}
dbg->dbgbus_lutdma.entries = dbg_bus_lutdma;
dbg->dbgbus_lutdma.cmn.name = DBGBUS_NAME_LUTDMA;
dbg->dbgbus_lutdma.cmn.blk_id = SDE_DBG_LUTDMA_DBGBUS;
dbg->dbgbus_lutdma.cmn.entries_size = ARRAY_SIZE(dbg_bus_lutdma);
dbg->dbgbus_lutdma.read_tp = _sde_dbg_lutdma_read_test_point;
dbg->dbgbus_lutdma.clear_tp = _sde_dbg_cmn_clear_test_point;
}
int sde_dbg_init(struct device *dev)
@@ -2346,6 +2179,8 @@ int sde_dbg_init(struct device *dev)
sde_dbg_base.work_panic = false;
sde_dbg_base.panic_on_err = DEFAULT_PANIC;
sde_dbg_base.enable_reg_dump = DEFAULT_REGDUMP;
sde_dbg_base.enable_dbgbus_dump = DEFAULT_DBGBUS_DUMP;
sde_dbg_base.dump_blk_mask = SDE_DBG_BUILT_IN_ALL;
memset(&sde_dbg_base.regbuf, 0, sizeof(sde_dbg_base.regbuf));
pr_info("evtlog_status: enable:%d, panic:%d, dump:%d\n",
@@ -2422,8 +2257,7 @@ int sde_dbg_dsi_ctrl_register(void __iomem *base, const char *name)
return 0;
}
int sde_dbg_reg_register_base(const char *name, void __iomem *base,
size_t max_offset)
int sde_dbg_reg_register_base(const char *name, void __iomem *base, size_t max_offset, u64 blk_id)
{
struct sde_dbg_base *dbg_base = &sde_dbg_base;
struct sde_dbg_reg_base *reg_base;
@@ -2443,6 +2277,7 @@ int sde_dbg_reg_register_base(const char *name, void __iomem *base,
reg_base->off = 0;
reg_base->cnt = DEFAULT_BASE_REG_CNT;
reg_base->reg_dump = NULL;
reg_base->blk_id = blk_id;
/* Initialize list to make sure check for null list will be valid */
INIT_LIST_HEAD(&reg_base->sub_range_list);