Merge "disp: msm: sde: modify SDE_DBG_DUMP to use blk_mask instead of blk_name"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

melakukan
19e9831a45
413
msm/sde_dbg.c
413
msm/sde_dbg.c
@@ -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(®_base->sub_range_list);
|
||||
|
Reference in New Issue
Block a user