msm: mdss: xlog: add support to dump MDP debug bus
Add support to dump the necessary registers from the MDP debug bus. And add support to dump this debug bus for 8994 chipset. Change-Id: I07f4a4833c8daffb35cd00e6a6c873f35ca2b0c0 Signed-off-by: Siddhartha Agrawal <agrawals@codeaurora.org> Signed-off-by: Ingrid Gallardo <ingridg@codeaurora.org> [cip@codeaurora.org: Resolved conflict on mdss_dump_reg] Signed-off-by: Clarence Ip <cip@codeaurora.org>
This commit is contained in:
parent
420bbb2659
commit
836f93ef82
6 changed files with 220 additions and 7 deletions
|
@ -382,6 +382,8 @@ struct mdss_data_type {
|
||||||
int iommu_attached;
|
int iommu_attached;
|
||||||
struct mdss_iommu_map_type *iommu_map;
|
struct mdss_iommu_map_type *iommu_map;
|
||||||
|
|
||||||
|
struct debug_bus *dbg_bus;
|
||||||
|
u32 dbg_bus_size;
|
||||||
struct mdss_debug_inf debug_inf;
|
struct mdss_debug_inf debug_inf;
|
||||||
bool mixer_switched;
|
bool mixer_switched;
|
||||||
struct mdss_panel_cfg pan_cfg;
|
struct mdss_panel_cfg pan_cfg;
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
#define MDSS_REG_BLOCK_NAME_LEN (5)
|
#define MDSS_REG_BLOCK_NAME_LEN (5)
|
||||||
|
|
||||||
enum mdss_dbg_reg_dump_flag {
|
enum mdss_dbg_reg_dump_flag {
|
||||||
MDSS_REG_DUMP_IN_LOG = BIT(0),
|
MDSS_DBG_DUMP_IN_LOG = BIT(0),
|
||||||
MDSS_REG_DUMP_IN_MEM = BIT(1),
|
MDSS_DBG_DUMP_IN_MEM = BIT(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mdss_dbg_xlog_flag {
|
enum mdss_dbg_xlog_flag {
|
||||||
|
@ -43,6 +43,13 @@ enum mdss_dbg_xlog_flag {
|
||||||
MDSS_XLOG_ALL = BIT(7)
|
MDSS_XLOG_ALL = BIT(7)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TEST_MASK(id, tp) ((id << 4) | (tp << 1) | BIT(0))
|
||||||
|
struct debug_bus {
|
||||||
|
u32 wr_addr;
|
||||||
|
u32 block_id;
|
||||||
|
u32 test_id;
|
||||||
|
};
|
||||||
|
|
||||||
#define MDSS_XLOG(...) mdss_xlog(__func__, __LINE__, MDSS_XLOG_DEFAULT, \
|
#define MDSS_XLOG(...) mdss_xlog(__func__, __LINE__, MDSS_XLOG_DEFAULT, \
|
||||||
##__VA_ARGS__, DATA_LIMITER)
|
##__VA_ARGS__, DATA_LIMITER)
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#define XLOG_DEFAULT_PANIC 1
|
#define XLOG_DEFAULT_PANIC 1
|
||||||
#define XLOG_DEFAULT_REGDUMP 0x2 /* dump in RAM */
|
#define XLOG_DEFAULT_REGDUMP 0x2 /* dump in RAM */
|
||||||
|
#define XLOG_DEFAULT_DBGBUSDUMP 0x3 /* dump in LOG & RAM */
|
||||||
|
|
||||||
#define MDSS_XLOG_ENTRY 256
|
#define MDSS_XLOG_ENTRY 256
|
||||||
#define MDSS_XLOG_MAX_DATA 6
|
#define MDSS_XLOG_MAX_DATA 6
|
||||||
|
@ -55,9 +56,12 @@ struct mdss_dbg_xlog {
|
||||||
u32 xlog_enable;
|
u32 xlog_enable;
|
||||||
u32 panic_on_err;
|
u32 panic_on_err;
|
||||||
u32 enable_reg_dump;
|
u32 enable_reg_dump;
|
||||||
|
u32 enable_dbgbus_dump;
|
||||||
struct work_struct xlog_dump_work;
|
struct work_struct xlog_dump_work;
|
||||||
struct mdss_debug_base *blk_arr[MDSS_DEBUG_BASE_MAX];
|
struct mdss_debug_base *blk_arr[MDSS_DEBUG_BASE_MAX];
|
||||||
bool work_panic;
|
bool work_panic;
|
||||||
|
bool work_dbgbus;
|
||||||
|
u32 *dbgbus_dump; /* address for the debug bus dump */
|
||||||
} mdss_dbg_xlog;
|
} mdss_dbg_xlog;
|
||||||
|
|
||||||
static inline bool mdss_xlog_is_enabled(u32 flag)
|
static inline bool mdss_xlog_is_enabled(u32 flag)
|
||||||
|
@ -203,6 +207,72 @@ u32 get_dump_range(struct dump_offset *range_node, size_t max_offset)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mdss_dump_debug_bus(u32 bus_dump_flag,
|
||||||
|
u32 **dump_mem)
|
||||||
|
{
|
||||||
|
struct mdss_data_type *mdata = mdss_mdp_get_mdata();
|
||||||
|
bool in_log, in_mem;
|
||||||
|
u32 *dump_addr = NULL;
|
||||||
|
u32 status = 0;
|
||||||
|
struct debug_bus *head;
|
||||||
|
phys_addr_t phys = 0;
|
||||||
|
int list_size = mdata->dbg_bus_size;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!(mdata->dbg_bus && list_size))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* will keep in memory 4 entries of 4 bytes each */
|
||||||
|
list_size = (list_size * 4 * 4);
|
||||||
|
|
||||||
|
in_log = (bus_dump_flag & MDSS_DBG_DUMP_IN_LOG);
|
||||||
|
in_mem = (bus_dump_flag & MDSS_DBG_DUMP_IN_MEM);
|
||||||
|
|
||||||
|
if (in_mem) {
|
||||||
|
if (!(*dump_mem))
|
||||||
|
*dump_mem = dma_alloc_coherent(&mdata->pdev->dev,
|
||||||
|
list_size, &phys, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (*dump_mem) {
|
||||||
|
dump_addr = *dump_mem;
|
||||||
|
pr_info("bus dump_addr:%p size:%d\n",
|
||||||
|
dump_addr, list_size);
|
||||||
|
} else {
|
||||||
|
in_mem = false;
|
||||||
|
pr_err("dump_mem: allocation fails\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_info("======== Debug bus DUMP =========\n");
|
||||||
|
|
||||||
|
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON);
|
||||||
|
for (i = 0; i < mdata->dbg_bus_size; i++) {
|
||||||
|
head = mdata->dbg_bus + i;
|
||||||
|
writel_relaxed(TEST_MASK(head->block_id, head->test_id),
|
||||||
|
mdss_res->mdp_base + head->wr_addr);
|
||||||
|
wmb(); /* make sure test bits were written */
|
||||||
|
status = readl_relaxed(mdss_res->mdp_base +
|
||||||
|
head->wr_addr + 0x4);
|
||||||
|
|
||||||
|
if (in_log)
|
||||||
|
pr_err("waddr=0x%x blk=%d tst=%d val=0x%x\n",
|
||||||
|
head->wr_addr, head->block_id, head->test_id,
|
||||||
|
status);
|
||||||
|
|
||||||
|
if (dump_addr && in_mem) {
|
||||||
|
dump_addr[i*4] = head->wr_addr;
|
||||||
|
dump_addr[i*4 + 1] = head->block_id;
|
||||||
|
dump_addr[i*4 + 2] = head->test_id;
|
||||||
|
dump_addr[i*4 + 3] = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
|
||||||
|
|
||||||
|
pr_info("========End Debug bus=========\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void mdss_dump_reg(u32 reg_dump_flag,
|
static void mdss_dump_reg(u32 reg_dump_flag,
|
||||||
char *addr, int len, u32 **dump_mem)
|
char *addr, int len, u32 **dump_mem)
|
||||||
{
|
{
|
||||||
|
@ -212,8 +282,8 @@ static void mdss_dump_reg(u32 reg_dump_flag,
|
||||||
phys_addr_t phys = 0;
|
phys_addr_t phys = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
in_log = (reg_dump_flag & MDSS_REG_DUMP_IN_LOG);
|
in_log = (reg_dump_flag & MDSS_DBG_DUMP_IN_LOG);
|
||||||
in_mem = (reg_dump_flag & MDSS_REG_DUMP_IN_MEM);
|
in_mem = (reg_dump_flag & MDSS_DBG_DUMP_IN_MEM);
|
||||||
|
|
||||||
pr_info("reg_dump_flag=%d in_log=%d in_mem=%d\n", reg_dump_flag, in_log,
|
pr_info("reg_dump_flag=%d in_log=%d in_mem=%d\n", reg_dump_flag, in_log,
|
||||||
in_mem);
|
in_mem);
|
||||||
|
@ -363,7 +433,7 @@ struct mdss_debug_base *get_dump_blk_addr(const char *blk_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mdss_xlog_dump_array(struct mdss_debug_base *blk_arr[],
|
static void mdss_xlog_dump_array(struct mdss_debug_base *blk_arr[],
|
||||||
u32 len, bool dead, const char *name)
|
u32 len, bool dead, const char *name, bool dump_dbgbus)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -375,6 +445,10 @@ static void mdss_xlog_dump_array(struct mdss_debug_base *blk_arr[],
|
||||||
|
|
||||||
mdss_xlog_dump_all();
|
mdss_xlog_dump_all();
|
||||||
|
|
||||||
|
if (dump_dbgbus)
|
||||||
|
mdss_dump_debug_bus(mdss_dbg_xlog.enable_dbgbus_dump,
|
||||||
|
&mdss_dbg_xlog.dbgbus_dump);
|
||||||
|
|
||||||
if (dead && mdss_dbg_xlog.panic_on_err)
|
if (dead && mdss_dbg_xlog.panic_on_err)
|
||||||
panic(name);
|
panic(name);
|
||||||
}
|
}
|
||||||
|
@ -384,13 +458,15 @@ static void xlog_debug_work(struct work_struct *work)
|
||||||
|
|
||||||
mdss_xlog_dump_array(mdss_dbg_xlog.blk_arr,
|
mdss_xlog_dump_array(mdss_dbg_xlog.blk_arr,
|
||||||
ARRAY_SIZE(mdss_dbg_xlog.blk_arr),
|
ARRAY_SIZE(mdss_dbg_xlog.blk_arr),
|
||||||
mdss_dbg_xlog.work_panic, "xlog_workitem");
|
mdss_dbg_xlog.work_panic, "xlog_workitem",
|
||||||
|
mdss_dbg_xlog.work_dbgbus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
|
void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
|
||||||
{
|
{
|
||||||
int i, index = 0;
|
int i, index = 0;
|
||||||
bool dead = false;
|
bool dead = false;
|
||||||
|
bool dump_dbgbus = false;
|
||||||
va_list args;
|
va_list args;
|
||||||
char *blk_name = NULL;
|
char *blk_name = NULL;
|
||||||
struct mdss_debug_base *blk_base = NULL;
|
struct mdss_debug_base *blk_base = NULL;
|
||||||
|
@ -420,6 +496,9 @@ void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(blk_name, "dbg_bus"))
|
||||||
|
dump_dbgbus = true;
|
||||||
|
|
||||||
if (!strcmp(blk_name, "panic"))
|
if (!strcmp(blk_name, "panic"))
|
||||||
dead = true;
|
dead = true;
|
||||||
}
|
}
|
||||||
|
@ -428,9 +507,10 @@ void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
|
||||||
if (queue) {
|
if (queue) {
|
||||||
/* schedule work to dump later */
|
/* schedule work to dump later */
|
||||||
mdss_dbg_xlog.work_panic = dead;
|
mdss_dbg_xlog.work_panic = dead;
|
||||||
|
mdss_dbg_xlog.work_dbgbus = dump_dbgbus;
|
||||||
schedule_work(&mdss_dbg_xlog.xlog_dump_work);
|
schedule_work(&mdss_dbg_xlog.xlog_dump_work);
|
||||||
} else {
|
} else {
|
||||||
mdss_xlog_dump_array(blk_arr, blk_len, dead, name);
|
mdss_xlog_dump_array(blk_arr, blk_len, dead, name, dump_dbgbus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,10 +579,13 @@ int mdss_create_xlog_debug(struct mdss_debug_data *mdd)
|
||||||
&mdss_dbg_xlog.panic_on_err);
|
&mdss_dbg_xlog.panic_on_err);
|
||||||
debugfs_create_u32("reg_dump", 0644, mdss_dbg_xlog.xlog,
|
debugfs_create_u32("reg_dump", 0644, mdss_dbg_xlog.xlog,
|
||||||
&mdss_dbg_xlog.enable_reg_dump);
|
&mdss_dbg_xlog.enable_reg_dump);
|
||||||
|
debugfs_create_u32("dbgbus_dump", 0644, mdss_dbg_xlog.xlog,
|
||||||
|
&mdss_dbg_xlog.enable_dbgbus_dump);
|
||||||
|
|
||||||
mdss_dbg_xlog.xlog_enable = XLOG_DEFAULT_ENABLE;
|
mdss_dbg_xlog.xlog_enable = XLOG_DEFAULT_ENABLE;
|
||||||
mdss_dbg_xlog.panic_on_err = XLOG_DEFAULT_PANIC;
|
mdss_dbg_xlog.panic_on_err = XLOG_DEFAULT_PANIC;
|
||||||
mdss_dbg_xlog.enable_reg_dump = XLOG_DEFAULT_REGDUMP;
|
mdss_dbg_xlog.enable_reg_dump = XLOG_DEFAULT_REGDUMP;
|
||||||
|
mdss_dbg_xlog.enable_dbgbus_dump = XLOG_DEFAULT_DBGBUSDUMP;
|
||||||
|
|
||||||
pr_info("xlog_status: enable:%d, panic:%d, dump:%d\n",
|
pr_info("xlog_status: enable:%d, panic:%d, dump:%d\n",
|
||||||
mdss_dbg_xlog.xlog_enable, mdss_dbg_xlog.panic_on_err,
|
mdss_dbg_xlog.xlog_enable, mdss_dbg_xlog.panic_on_err,
|
||||||
|
|
|
@ -1061,6 +1061,8 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
|
||||||
/* prevent disable of prefill calculations */
|
/* prevent disable of prefill calculations */
|
||||||
mdata->min_prefill_lines = 0xffff;
|
mdata->min_prefill_lines = 0xffff;
|
||||||
|
|
||||||
|
mdss_mdp_hw_rev_debug_caps_init(mdata);
|
||||||
|
|
||||||
switch (mdata->mdp_rev) {
|
switch (mdata->mdp_rev) {
|
||||||
case MDSS_MDP_HW_REV_107:
|
case MDSS_MDP_HW_REV_107:
|
||||||
mdss_set_quirk(mdata, MDSS_QUIRK_ROTCDP);
|
mdss_set_quirk(mdata, MDSS_QUIRK_ROTCDP);
|
||||||
|
|
|
@ -22,6 +22,123 @@
|
||||||
|
|
||||||
#define BUF_DUMP_LAST_N 10
|
#define BUF_DUMP_LAST_N 10
|
||||||
|
|
||||||
|
static struct debug_bus dbg_bus_8994[] = {
|
||||||
|
/* VIG QSEED */
|
||||||
|
{ 0x298, 4, 0},
|
||||||
|
{ 0x298, 4, 1},
|
||||||
|
{ 0x298, 24, 0},
|
||||||
|
{ 0x298, 24, 1},
|
||||||
|
{ 0x298, 42, 0},
|
||||||
|
{ 0x298, 42, 1},
|
||||||
|
{ 0x298, 88, 0},
|
||||||
|
{ 0x298, 88, 1},
|
||||||
|
/* RGB SCALE */
|
||||||
|
{ 0x298, 12, 0},
|
||||||
|
{ 0x298, 12, 1},
|
||||||
|
{ 0x298, 34, 0},
|
||||||
|
{ 0x298, 34, 1},
|
||||||
|
{ 0x298, 52, 0},
|
||||||
|
{ 0x298, 52, 1},
|
||||||
|
{ 0x298, 96, 0},
|
||||||
|
{ 0x298, 96, 1},
|
||||||
|
/* VIG CSC */
|
||||||
|
{ 0x298, 5, 0},
|
||||||
|
{ 0x298, 5, 1},
|
||||||
|
{ 0x298, 25, 0},
|
||||||
|
{ 0x298, 25, 1},
|
||||||
|
{ 0x298, 43, 0},
|
||||||
|
{ 0x298, 43, 1},
|
||||||
|
{ 0x298, 89, 0},
|
||||||
|
{ 0x298, 89, 1},
|
||||||
|
/* VIG SPA */
|
||||||
|
{ 0x298, 6, 0},
|
||||||
|
{ 0x298, 26, 0},
|
||||||
|
{ 0x298, 44, 0},
|
||||||
|
{ 0x298, 90, 0},
|
||||||
|
/* DSPP_PA */
|
||||||
|
{ 0x348, 13, 0},
|
||||||
|
{ 0x348, 19, 0},
|
||||||
|
{ 0x348, 25, 0},
|
||||||
|
{ 0x348, 3, 0},
|
||||||
|
/* VIG ISC */
|
||||||
|
{ 0x298, 7, 0},
|
||||||
|
{ 0x298, 7, 1},
|
||||||
|
{ 0x298, 7, 3},
|
||||||
|
{ 0x298, 27, 0},
|
||||||
|
{ 0x298, 27, 1},
|
||||||
|
{ 0x298, 27, 3},
|
||||||
|
{ 0x298, 45, 0},
|
||||||
|
{ 0x298, 45, 1},
|
||||||
|
{ 0x298, 45, 3},
|
||||||
|
{ 0x298, 91, 0},
|
||||||
|
{ 0x298, 91, 1},
|
||||||
|
{ 0x298, 91, 3},
|
||||||
|
/* RGB IGC */
|
||||||
|
{ 0x298, 13, 0},
|
||||||
|
{ 0x298, 13, 1},
|
||||||
|
{ 0x298, 13, 3},
|
||||||
|
{ 0x298, 35, 0},
|
||||||
|
{ 0x298, 35, 1},
|
||||||
|
{ 0x298, 35, 3},
|
||||||
|
{ 0x298, 53, 0},
|
||||||
|
{ 0x298, 53, 1},
|
||||||
|
{ 0x298, 53, 3},
|
||||||
|
{ 0x298, 97, 0},
|
||||||
|
{ 0x298, 97, 1},
|
||||||
|
{ 0x298, 97, 3},
|
||||||
|
/* DMA IGC */
|
||||||
|
{ 0x298, 58, 0},
|
||||||
|
{ 0x298, 58, 1},
|
||||||
|
{ 0x298, 58, 3},
|
||||||
|
{ 0x298, 65, 0},
|
||||||
|
{ 0x298, 65, 1},
|
||||||
|
{ 0x298, 65, 3},
|
||||||
|
/* DSPP IGC */
|
||||||
|
{ 0x348, 14, 0},
|
||||||
|
{ 0x348, 14, 1},
|
||||||
|
{ 0x348, 14, 3},
|
||||||
|
{ 0x348, 20, 0},
|
||||||
|
{ 0x348, 20, 1},
|
||||||
|
{ 0x348, 20, 3},
|
||||||
|
{ 0x348, 26, 0},
|
||||||
|
{ 0x348, 26, 1},
|
||||||
|
{ 0x348, 26, 3},
|
||||||
|
{ 0x348, 4, 0},
|
||||||
|
{ 0x348, 4, 1},
|
||||||
|
{ 0x348, 4, 3},
|
||||||
|
/* DSPP DITHER */
|
||||||
|
{ 0x348, 18, 1},
|
||||||
|
{ 0x348, 24, 1},
|
||||||
|
{ 0x348, 30, 1},
|
||||||
|
{ 0x348, 8, 1},
|
||||||
|
/*PPB 0*/
|
||||||
|
{ 0x348, 31, 0},
|
||||||
|
{ 0x348, 33, 0},
|
||||||
|
{ 0x348, 35, 0},
|
||||||
|
{ 0x348, 42, 0},
|
||||||
|
/*PPB 1*/
|
||||||
|
{ 0x348, 32, 0},
|
||||||
|
{ 0x348, 34, 0},
|
||||||
|
{ 0x348, 36, 0},
|
||||||
|
{ 0x348, 43, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
void mdss_mdp_hw_rev_debug_caps_init(struct mdss_data_type *mdata)
|
||||||
|
{
|
||||||
|
mdata->dbg_bus = NULL;
|
||||||
|
mdata->dbg_bus_size = 0;
|
||||||
|
|
||||||
|
switch (mdata->mdp_rev) {
|
||||||
|
case MDSS_MDP_HW_REV_105:
|
||||||
|
case MDSS_MDP_HW_REV_109:
|
||||||
|
mdata->dbg_bus = dbg_bus_8994;
|
||||||
|
mdata->dbg_bus_size = ARRAY_SIZE(dbg_bus_8994);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void __print_time(char *buf, u32 size, u64 ts)
|
static void __print_time(char *buf, u32 size, u64 ts)
|
||||||
{
|
{
|
||||||
unsigned long rem_ns = do_div(ts, NSEC_PER_SEC);
|
unsigned long rem_ns = do_div(ts, NSEC_PER_SEC);
|
||||||
|
|
|
@ -73,6 +73,8 @@ static inline const char *mdss_mdp_format2str(u32 format)
|
||||||
return strings[format];
|
return strings[format];
|
||||||
}
|
}
|
||||||
void mdss_mdp_dump(struct mdss_data_type *mdata);
|
void mdss_mdp_dump(struct mdss_data_type *mdata);
|
||||||
|
void mdss_mdp_hw_rev_debug_caps_init(struct mdss_data_type *mdata);
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_FS
|
#ifdef CONFIG_DEBUG_FS
|
||||||
int mdss_mdp_debugfs_init(struct mdss_data_type *mdata);
|
int mdss_mdp_debugfs_init(struct mdss_data_type *mdata);
|
||||||
|
|
Loading…
Add table
Reference in a new issue