diff options
Diffstat (limited to 'msm/sde_dbg.c')
-rw-r--r-- | msm/sde_dbg.c | 94 |
1 files changed, 90 insertions, 4 deletions
diff --git a/msm/sde_dbg.c b/msm/sde_dbg.c index 6178e1bf..2723d01c 100644 --- a/msm/sde_dbg.c +++ b/msm/sde_dbg.c @@ -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,12 +213,15 @@ 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; struct mutex mutex; @@ -238,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; @@ -246,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) { @@ -2922,6 +2930,7 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag, char *base_addr, char *addr, size_t len_bytes, u32 **dump_mem) { u32 in_log, in_mem, len_align, len_padded; + struct sde_dbg_base *dbg_base = &sde_dbg_base; u32 *dump_addr = NULL; char *end_addr; int i; @@ -2950,9 +2959,8 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag, if (in_mem) { if (dump_mem && !(*dump_mem)) { - phys_addr_t phys = 0; - *dump_mem = dma_alloc_coherent(sde_dbg_base.dev, - len_padded, &phys, GFP_KERNEL); + *dump_mem = dbg_base->reg_dump_addr; + dbg_base->reg_dump_addr += len_padded; } if (dump_mem && *dump_mem) { @@ -3026,6 +3034,49 @@ static u32 _sde_dbg_get_dump_range(struct sde_dbg_reg_offset *range_node, return length; } +static u32 _sde_dbg_get_reg_blk_size(struct sde_dbg_reg_base *dbg) +{ + u32 len, len_align, len_padded; + u32 size = 0; + struct sde_dbg_reg_range *range_node; + + if (!dbg || !dbg->base) { + pr_err("dbg base is null!\n"); + return 0; + } + + if (!list_empty(&dbg->sub_range_list)) { + list_for_each_entry(range_node, &dbg->sub_range_list, head) { + len = _sde_dbg_get_dump_range(&range_node->offset, + dbg->max_offset); + len_align = (len + REG_DUMP_ALIGN - 1) / REG_DUMP_ALIGN; + len_padded = len_align * REG_DUMP_ALIGN; + size += REG_BASE_NAME_LEN + RANGE_NAME_LEN + len_padded; + } + } else { + len = dbg->max_offset; + len_align = (len + REG_DUMP_ALIGN - 1) / REG_DUMP_ALIGN; + len_padded = len_align * REG_DUMP_ALIGN; + size += REG_BASE_NAME_LEN + RANGE_NAME_LEN + len_padded; + } + return size; +} + +static u32 _sde_dbg_get_reg_dump_size(void) +{ + struct sde_dbg_base *dbg_base = &sde_dbg_base; + struct sde_dbg_reg_base *blk_base; + u32 size = 0; + + if (!dbg_base) + return 0; + + list_for_each_entry(blk_base, &dbg_base->reg_base_list, reg_base_head) { + size += _sde_dbg_get_reg_blk_size(blk_base); + } + return size; +} + static int _sde_dump_reg_range_cmp(void *priv, struct list_head *a, struct list_head *b) { @@ -3071,6 +3122,7 @@ static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg, char *addr; size_t len; struct sde_dbg_reg_range *range_node; + struct sde_dbg_base *dbg_base = &sde_dbg_base; if (!dbg || !(dbg->base || dbg->cb)) { pr_err("dbg base is null!\n"); @@ -3100,6 +3152,12 @@ static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg, addr, range_node->offset.start, range_node->offset.end); + scnprintf(dbg_base->reg_dump_addr, REG_BASE_NAME_LEN, + dbg->name); + dbg_base->reg_dump_addr += REG_BASE_NAME_LEN; + scnprintf(dbg_base->reg_dump_addr, REG_BASE_NAME_LEN, + range_node->range_name); + dbg_base->reg_dump_addr += RANGE_NAME_LEN; _sde_dump_reg(range_node->range_name, reg_dump_flag, dbg->base, addr, len, &range_node->reg_dump); @@ -3112,6 +3170,10 @@ static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg, dbg->max_offset); addr = dbg->base; len = dbg->max_offset; + scnprintf(dbg_base->reg_dump_addr, REG_BASE_NAME_LEN, + dbg->name); + dbg_base->reg_dump_addr += REG_BASE_NAME_LEN; + dbg_base->reg_dump_addr += RANGE_NAME_LEN; _sde_dump_reg(dbg->name, reg_dump_flag, dbg->base, addr, len, &dbg->reg_dump); } @@ -3478,9 +3540,16 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[], bool dump_dbgbus_vbif_rt, bool dump_all, bool dump_secure) { int i; + u32 reg_dump_size; + struct sde_dbg_base *dbg_base = &sde_dbg_base; + phys_addr_t phys = 0; mutex_lock(&sde_dbg_base.mutex); + reg_dump_size = _sde_dbg_get_reg_dump_size(); + dbg_base->reg_dump_addr = dma_alloc_coherent(sde_dbg_base.dev, + reg_dump_size, &phys, GFP_KERNEL); + if (dump_all) sde_evtlog_dump_all(sde_dbg_base.evtlog); @@ -3658,7 +3727,7 @@ void sde_dbg_ctrl(const char *name, ...) va_end(args); } - +#ifdef CONFIG_DEBUG_FS /* * sde_dbg_debugfs_open - debugfs open handler for evtlog dump * @inode: debugfs inode @@ -4600,6 +4669,15 @@ int sde_dbg_debugfs_register(struct device *dev) return 0; } +#else + +int sde_dbg_debugfs_register(struct device *dev) +{ + return 0; +} + +#endif + static void _sde_dbg_debugfs_destroy(void) { } @@ -4665,6 +4743,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; @@ -4709,6 +4793,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); } |