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

Commit 92e847bb authored by Sandeep Panda's avatar Sandeep Panda Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: add debug bus support for dsi block



Add support to dump dsi debug bus registers to memory
or print in xlog. This will be helpful in analyzing HW
behavior more precisely while debugging DSI stability
issues.

Change-Id: I7735897d9f24ca06e15015cf0d277bfe800b35bf
Signed-off-by: default avatarSandeep Panda <spanda@codeaurora.org>
parent ce87c901
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -44,6 +44,42 @@

#define INVALID_XIN_ID     0xFF

static u32 dsi_dbg_bus_sdm660[] = {
	0x0001, 0x1001, 0x0001, 0x0011,
	0x1021, 0x0021, 0x0031, 0x0041,
	0x0051, 0x0061, 0x3061, 0x0061,
	0x2061, 0x2061, 0x1061, 0x1061,
	0x1061, 0x0071, 0x0071, 0x0071,
	0x0081, 0x0081, 0x00A1, 0x00A1,
	0x10A1, 0x20A1, 0x30A1, 0x10A1,
	0x10A1, 0x30A1, 0x20A1, 0x00B1,
	0x00C1, 0x00C1, 0x10C1, 0x20C1,
	0x30C1, 0x00D1, 0x00D1, 0x20D1,
	0x30D1, 0x00E1, 0x00E1, 0x00E1,
	0x00F1, 0x00F1, 0x0101, 0x0101,
	0x1101, 0x2101, 0x3101, 0x0111,
	0x0141, 0x1141, 0x0141, 0x1141,
	0x1141, 0x0151, 0x0151, 0x1151,
	0x2151, 0x3151, 0x0161, 0x0161,
	0x1161, 0x0171, 0x0171, 0x0181,
	0x0181, 0x0191, 0x0191, 0x01A1,
	0x01A1, 0x01B1, 0x01B1, 0x11B1,
	0x21B1, 0x01C1, 0x01C1, 0x11C1,
	0x21C1, 0x31C1, 0x01D1, 0x01D1,
	0x01D1, 0x01D1, 0x11D1, 0x21D1,
	0x21D1, 0x01E1, 0x01E1, 0x01F1,
	0x01F1, 0x0201, 0x0201, 0x0211,
	0x0221, 0x0231, 0x0241, 0x0251,
	0x0281, 0x0291, 0x0281, 0x0291,
	0x02A1, 0x02B1, 0x02C1, 0x0321,
	0x0321, 0x1321, 0x2321, 0x3321,
	0x0331, 0x0331, 0x1331, 0x0341,
	0x0341, 0x1341, 0x2341, 0x3341,
	0x0351, 0x0361, 0x0361, 0x1361,
	0x2361, 0x0371, 0x0381, 0x0391,
	0x03C1, 0x03D1, 0x03E1, 0x03F1,
};

static DEFINE_MUTEX(mdss_debug_lock);

static char panel_reg[2] = {DEFAULT_READ_PANEL_POWER_MODE_REG, 0x00};
@@ -1788,6 +1824,24 @@ void mdss_misr_crc_collect(struct mdss_data_type *mdata, int block_id,

}

void mdss_dsi_debug_bus_init(struct mdss_dsi_data *sdata)
{
	if (!sdata)
		return;

	sdata->dbg_bus = NULL;
	sdata->dbg_bus_size = 0;

	switch (sdata->shared_data->hw_rev) {
	case MDSS_DSI_HW_REV_201:
		sdata->dbg_bus = dsi_dbg_bus_sdm660;
		sdata->dbg_bus_size = ARRAY_SIZE(dsi_dbg_bus_sdm660);
		break;
	default:
		break;
	}
}

int mdss_dump_misr_data(char **buf, u32 size)
{
	struct mdss_mdp_misr_map  *dsi0_map;
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -170,6 +170,7 @@ u32 get_dump_range(struct dump_offset *range_node, size_t max_offset);
void mdss_dump_reg(const char *dump_name, u32 reg_dump_flag, char *addr,
	int len, u32 **dump_mem, bool from_isr);
void mdss_mdp_debug_mid(u32 mid);
void mdss_dump_dsi_debug_bus(u32 bus_dump_flag, u32 **dump_mem);
#else
struct mdss_debug_base;
struct dump_offset;
+19 −4
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -32,6 +32,7 @@
#define XLOG_DEFAULT_REGDUMP 0x2 /* dump in RAM */
#define XLOG_DEFAULT_DBGBUSDUMP 0x2 /* dump in RAM */
#define XLOG_DEFAULT_VBIF_DBGBUSDUMP 0x2 /* dump in RAM */
#define XLOG_DEFAULT_DSI_DBGBUSDUMP 0x2 /* dump in RAM */

/*
 * xlog will print this number of entries when it is called through
@@ -73,14 +74,17 @@ struct mdss_dbg_xlog {
	u32 enable_reg_dump;
	u32 enable_dbgbus_dump;
	u32 enable_vbif_dbgbus_dump;
	u32 enable_dsi_dbgbus_dump;
	struct work_struct xlog_dump_work;
	struct mdss_debug_base *blk_arr[MDSS_DEBUG_BASE_MAX];
	bool work_panic;
	bool work_dbgbus;
	bool work_vbif_dbgbus;
	bool work_dsi_dbgbus;
	u32 *dbgbus_dump; /* address for the debug bus dump */
	u32 *vbif_dbgbus_dump; /* address for the vbif debug bus dump */
	u32 *nrt_vbif_dbgbus_dump; /* address for the nrt vbif debug bus dump */
	u32 *dsi_dbgbus_dump; /* address for the dsi debug bus dump */
} mdss_dbg_xlog;

static inline bool mdss_xlog_is_enabled(u32 flag)
@@ -579,7 +583,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[],
	u32 len, bool dead, const char *name, bool dump_dbgbus,
	bool dump_vbif_dbgbus)
	bool dump_vbif_dbgbus, bool dump_dsi_dbgbus)
{
	int i;

@@ -603,6 +607,10 @@ static void mdss_xlog_dump_array(struct mdss_debug_base *blk_arr[],
			&mdss_dbg_xlog.nrt_vbif_dbgbus_dump, false);
	}

	if (dump_dsi_dbgbus)
		mdss_dump_dsi_debug_bus(mdss_dbg_xlog.enable_dsi_dbgbus_dump,
			&mdss_dbg_xlog.dsi_dbgbus_dump);

	if (dead && mdss_dbg_xlog.panic_on_err)
		panic(name);
}
@@ -614,7 +622,8 @@ static void xlog_debug_work(struct work_struct *work)
		ARRAY_SIZE(mdss_dbg_xlog.blk_arr),
		mdss_dbg_xlog.work_panic, "xlog_workitem",
		mdss_dbg_xlog.work_dbgbus,
		mdss_dbg_xlog.work_vbif_dbgbus);
		mdss_dbg_xlog.work_vbif_dbgbus,
		mdss_dbg_xlog.work_dsi_dbgbus);
}

void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
@@ -622,6 +631,7 @@ void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
	int i, index = 0;
	bool dead = false;
	bool dump_dbgbus = false, dump_vbif_dbgbus = false;
	bool dump_dsi_dbgbus = false;
	va_list args;
	char *blk_name = NULL;
	struct mdss_debug_base *blk_base = NULL;
@@ -657,6 +667,9 @@ void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
		if (!strcmp(blk_name, "vbif_dbg_bus"))
			dump_vbif_dbgbus = true;

		if (!strcmp(blk_name, "dsi_dbg_bus"))
			dump_dsi_dbgbus = true;

		if (!strcmp(blk_name, "panic"))
			dead = true;
	}
@@ -667,10 +680,11 @@ void mdss_xlog_tout_handler_default(bool queue, const char *name, ...)
		mdss_dbg_xlog.work_panic = dead;
		mdss_dbg_xlog.work_dbgbus = dump_dbgbus;
		mdss_dbg_xlog.work_vbif_dbgbus = dump_vbif_dbgbus;
		mdss_dbg_xlog.work_dsi_dbgbus = dump_dsi_dbgbus;
		schedule_work(&mdss_dbg_xlog.xlog_dump_work);
	} else {
		mdss_xlog_dump_array(blk_arr, blk_len, dead, name, dump_dbgbus,
			dump_vbif_dbgbus);
			dump_vbif_dbgbus, dump_dsi_dbgbus);
	}
}

@@ -754,6 +768,7 @@ int mdss_create_xlog_debug(struct mdss_debug_data *mdd)
	mdss_dbg_xlog.enable_reg_dump = XLOG_DEFAULT_REGDUMP;
	mdss_dbg_xlog.enable_dbgbus_dump = XLOG_DEFAULT_DBGBUSDUMP;
	mdss_dbg_xlog.enable_vbif_dbgbus_dump = XLOG_DEFAULT_VBIF_DBGBUSDUMP;
	mdss_dbg_xlog.enable_dsi_dbgbus_dump = XLOG_DEFAULT_DSI_DBGBUSDUMP;

	pr_info("xlog_status: enable:%d, panic:%d, dump:%d\n",
		mdss_dbg_xlog.xlog_enable, mdss_dbg_xlog.panic_on_err,
+94 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/uaccess.h>
#include <linux/msm-bus.h>
#include <linux/pm_qos.h>
#include <linux/dma-buf.h>

#include "mdss.h"
#include "mdss_panel.h"
@@ -44,6 +45,97 @@ static struct mdss_dsi_data *mdss_dsi_res;

static struct pm_qos_request mdss_dsi_pm_qos_request;

void mdss_dump_dsi_debug_bus(u32 bus_dump_flag,
	u32 **dump_mem)
{
	struct mdss_dsi_data *sdata = mdss_dsi_res;
	struct mdss_dsi_ctrl_pdata *m_ctrl, *s_ctrl;
	bool in_log, in_mem;
	u32 *dump_addr = NULL;
	u32 status0 = 0, status1 = 0;
	phys_addr_t phys = 0;
	int list_size = 0;
	int i;
	bool dsi0_active = false, dsi1_active = false;

	if (!sdata || !sdata->dbg_bus || !sdata->dbg_bus_size)
		return;

	m_ctrl = sdata->ctrl_pdata[0];
	s_ctrl = sdata->ctrl_pdata[1];

	if (!m_ctrl)
		return;

	if (m_ctrl && m_ctrl->shared_data->dsi0_active)
		dsi0_active = true;
	if (s_ctrl && s_ctrl->shared_data->dsi1_active)
		dsi1_active = true;

	list_size = (sdata->dbg_bus_size * sizeof(sdata->dbg_bus[0]) * 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(&sdata->pdev->dev,
				list_size, &phys, GFP_KERNEL);

		if (*dump_mem) {
			dump_addr = *dump_mem;
			pr_info("%s: start_addr:0x%pK end_addr:0x%pK\n",
				__func__, dump_addr, dump_addr + list_size);
		} else {
			in_mem = false;
			pr_err("dump_mem: allocation fails\n");
		}
	}

	pr_info("========= Start DSI Debug Bus =========\n");

	mdss_dsi_clk_ctrl(m_ctrl, m_ctrl->dsi_clk_handle,
			  MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_ON);

	for (i = 0; i < sdata->dbg_bus_size; i++) {
		if (dsi0_active) {
			writel_relaxed(sdata->dbg_bus[i],
					m_ctrl->ctrl_base + 0x124);
			wmb(); /* ensure regsiter is committed */
		}
		if (dsi1_active) {
			writel_relaxed(sdata->dbg_bus[i],
					s_ctrl->ctrl_base + 0x124);
			wmb(); /* ensure register is committed */
		}

		if (dsi0_active) {
			status0 = readl_relaxed(m_ctrl->ctrl_base + 0x128);
			if (in_log)
				pr_err("CTRL:0 bus_ctrl: 0x%x status: 0x%x\n",
					sdata->dbg_bus[i], status0);
		}
		if (dsi1_active) {
			status1 = readl_relaxed(s_ctrl->ctrl_base + 0x128);
			if (in_log)
				pr_err("CTRL:1 bus_ctrl: 0x%x status: 0x%x\n",
					sdata->dbg_bus[i], status1);
		}

		if (dump_addr && in_mem) {
			dump_addr[i*4]     = sdata->dbg_bus[i];
			dump_addr[i*4 + 1] = status0;
			dump_addr[i*4 + 2] = status1;
			dump_addr[i*4 + 3] = 0x0;
		}
	}

	mdss_dsi_clk_ctrl(m_ctrl, m_ctrl->dsi_clk_handle,
			  MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_OFF);

	pr_info("========End DSI Debug Bus=========\n");
}

static void mdss_dsi_pm_qos_add_request(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	struct irq_info *irq_info;
@@ -3359,6 +3451,8 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
	else
		ctrl_pdata->shared_data->dsi1_active = true;

	mdss_dsi_debug_bus_init(mdss_dsi_res);

	return 0;

error_shadow_clk_deinit:
+4 −0
Original line number Diff line number Diff line
@@ -315,6 +315,8 @@ struct mdss_dsi_data {
	 * mutex, clocks, regulator information, setup information
	 */
	struct dsi_shared_data *shared_data;
	u32 *dbg_bus;
	int dbg_bus_size;
};

/*
@@ -705,6 +707,8 @@ void mdss_dsi_set_reg(struct mdss_dsi_ctrl_pdata *ctrl, int off,
	u32 mask, u32 val);
int mdss_dsi_phy_pll_reset_status(struct mdss_dsi_ctrl_pdata *ctrl);

void mdss_dsi_debug_bus_init(struct mdss_dsi_data *sdata);

static inline const char *__mdss_dsi_pm_name(enum dsi_pm_type module)
{
	switch (module) {
Loading