summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorLloyd Atkinson <latkinso@codeaurora.org>2017-03-23 11:43:48 -0700
committerAbhinav Kumar <abhinavk@codeaurora.org>2017-08-26 00:34:14 -0700
commit9deb0a5c0154104d75d98148166134eb58d98392 (patch)
tree1c1d9b7a3347678e3a35be075dd98609a7eee7ed /drivers/gpu
parent53b888583f335ae6984e3646c8c1a3907aaddd4b (diff)
drm/msm/sde: fix register debug range printing
Add checks to sde debug facility to reject poorly formed register block ranges. Add names for dsc and vbif register blocks. Register the vbif hw block under the vbif base register. Fix the names of the printed register blocks to be 0 based as expected. Fix the DSC register length initialization. Sort register ranges before printing. Register mdp top block address before dumping the sde debug bus. Change-Id: I0179d59543de52537937abcc7d556f79569e9c55 Signed-off-by: Lloyd Atkinson <latkinso@codeaurora.org> Signed-off-by: Abhinav Kumar <abhinavk@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_catalog.c67
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_sspp.c5
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_top.c1
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_vbif.c3
-rw-r--r--drivers/gpu/drm/msm/sde_dbg.c136
-rw-r--r--drivers/gpu/drm/msm/sde_dbg.h9
6 files changed, 153 insertions, 68 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
index 30ca1bca1e48..1a563ea5f50c 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
@@ -695,7 +695,8 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
sblk->format_list = plane_formats_yuv;
sspp->id = SSPP_VIG0 + *vig_count;
- snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u", sspp->id);
+ snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
+ sspp->id - SSPP_VIG0);
sspp->clk_ctrl = SDE_CLK_CTRL_VIG0 + *vig_count;
sspp->type = SSPP_TYPE_VIG;
set_bit(SDE_SSPP_QOS, &sspp->features);
@@ -712,7 +713,7 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
VIG_QSEED_LEN, 0);
snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_scaler%u", sspp->id);
+ "sspp_scaler%u", sspp->id - SSPP_VIG0);
} else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3) {
set_bit(SDE_SSPP_SCALER_QSEED3, &sspp->features);
sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED3;
@@ -721,12 +722,12 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
VIG_QSEED_LEN, 0);
snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_scaler%u", sspp->id);
+ "sspp_scaler%u", sspp->id - SSPP_VIG0);
}
sblk->csc_blk.id = SDE_SSPP_CSC;
snprintf(sblk->csc_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_csc%u", sspp->id);
+ "sspp_csc%u", sspp->id - SSPP_VIG0);
if (sde_cfg->csc_type == SDE_SSPP_CSC) {
set_bit(SDE_SSPP_CSC, &sspp->features);
sblk->csc_blk.base = PROP_VALUE_ACCESS(prop_value,
@@ -739,7 +740,7 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
sblk->hsic_blk.id = SDE_SSPP_HSIC;
snprintf(sblk->hsic_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_hsic%u", sspp->id);
+ "sspp_hsic%u", sspp->id - SSPP_VIG0);
if (prop_exists[VIG_HSIC_PROP]) {
sblk->hsic_blk.base = PROP_VALUE_ACCESS(prop_value,
VIG_HSIC_PROP, 0);
@@ -751,7 +752,7 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
sblk->memcolor_blk.id = SDE_SSPP_MEMCOLOR;
snprintf(sblk->memcolor_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_memcolor%u", sspp->id);
+ "sspp_memcolor%u", sspp->id - SSPP_VIG0);
if (prop_exists[VIG_MEMCOLOR_PROP]) {
sblk->memcolor_blk.base = PROP_VALUE_ACCESS(prop_value,
VIG_MEMCOLOR_PROP, 0);
@@ -763,7 +764,7 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg,
sblk->pcc_blk.id = SDE_SSPP_PCC;
snprintf(sblk->pcc_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_pcc%u", sspp->id);
+ "sspp_pcc%u", sspp->id - SSPP_VIG0);
if (prop_exists[VIG_PCC_PROP]) {
sblk->pcc_blk.base = PROP_VALUE_ACCESS(prop_value,
VIG_PCC_PROP, 0);
@@ -783,7 +784,8 @@ static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
sblk->maxdwnscale = MAX_SSPP_DOWNSCALE;
sblk->format_list = plane_formats;
sspp->id = SSPP_RGB0 + *rgb_count;
- snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u", sspp->id);
+ snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
+ sspp->id - SSPP_VIG0);
sspp->clk_ctrl = SDE_CLK_CTRL_RGB0 + *rgb_count;
sspp->type = SSPP_TYPE_RGB;
set_bit(SDE_SSPP_QOS, &sspp->features);
@@ -800,7 +802,7 @@ static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
RGB_SCALER_LEN, 0);
snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_scaler%u", sspp->id);
+ "sspp_scaler%u", sspp->id - SSPP_VIG0);
} else if (sde_cfg->qseed_type == SDE_SSPP_SCALER_QSEED3) {
set_bit(SDE_SSPP_SCALER_RGB, &sspp->features);
sblk->scaler_blk.id = SDE_SSPP_SCALER_QSEED3;
@@ -809,7 +811,7 @@ static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg,
sblk->scaler_blk.len = PROP_VALUE_ACCESS(prop_value,
SSPP_SCALE_SIZE, 0);
snprintf(sblk->scaler_blk.name, SDE_HW_BLK_NAME_LEN,
- "sspp_scaler%u", sspp->id);
+ "sspp_scaler%u", sspp->id - SSPP_VIG0);
}
sblk->pcc_blk.id = SDE_SSPP_PCC;
@@ -833,7 +835,8 @@ static void _sde_sspp_setup_cursor(struct sde_mdss_cfg *sde_cfg,
sblk->maxdwnscale = SSPP_UNITY_SCALE;
sblk->format_list = cursor_formats;
sspp->id = SSPP_CURSOR0 + *cursor_count;
- snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u", sspp->id);
+ snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
+ sspp->id - SSPP_VIG0);
sspp->clk_ctrl = SDE_CLK_CTRL_CURSOR0 + *cursor_count;
sspp->type = SSPP_TYPE_CURSOR;
(*cursor_count)++;
@@ -850,7 +853,8 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg,
sspp->id = SSPP_DMA0 + *dma_count;
sspp->clk_ctrl = SDE_CLK_CTRL_DMA0 + *dma_count;
sspp->type = SSPP_TYPE_DMA;
- snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u", sspp->id);
+ snprintf(sspp->name, SDE_HW_BLK_NAME_LEN, "sspp_%u",
+ sspp->id - SSPP_VIG0);
set_bit(SDE_SSPP_QOS, &sspp->features);
(*dma_count)++;
snprintf(sspp->name, sizeof(sspp->name), "dma%d", *dma_count-1);
@@ -954,8 +958,6 @@ static int sde_sspp_parse_dt(struct device_node *np,
set_bit(SDE_SSPP_SRC, &sspp->features);
sblk->src_blk.id = SDE_SSPP_SRC;
- snprintf(sblk->src_blk.name, SDE_HW_BLK_NAME_LEN, "sspp_src_%u",
- sblk->src_blk.id);
of_property_read_string_index(np,
sspp_prop[SSPP_TYPE].prop_name, i, &type);
@@ -979,6 +981,9 @@ static int sde_sspp_parse_dt(struct device_node *np,
goto end;
}
+ snprintf(sblk->src_blk.name, SDE_HW_BLK_NAME_LEN, "sspp_src_%u",
+ sspp->id - SSPP_VIG0);
+
sblk->maxhdeciexp = MAX_HORZ_DECIMATION;
sblk->maxvdeciexp = MAX_VERT_DECIMATION;
@@ -1070,7 +1075,8 @@ static int sde_ctl_parse_dt(struct device_node *np,
ctl->base = PROP_VALUE_ACCESS(prop_value, HW_OFF, i);
ctl->len = PROP_VALUE_ACCESS(prop_value, HW_LEN, 0);
ctl->id = CTL_0 + i;
- snprintf(ctl->name, SDE_HW_BLK_NAME_LEN, "ctl_%u", ctl->id);
+ snprintf(ctl->name, SDE_HW_BLK_NAME_LEN, "ctl_%u",
+ ctl->id - CTL_0);
if (i < MAX_SPLIT_DISPLAY_CTL)
set_bit(SDE_CTL_SPLIT_DISPLAY, &ctl->features);
@@ -1162,7 +1168,8 @@ static int sde_mixer_parse_dt(struct device_node *np,
mixer->base = PROP_VALUE_ACCESS(prop_value, MIXER_OFF, i);
mixer->len = PROP_VALUE_ACCESS(prop_value, MIXER_LEN, 0);
mixer->id = LM_0 + i;
- snprintf(mixer->name, SDE_HW_BLK_NAME_LEN, "lm_%u", mixer->id);
+ snprintf(mixer->name, SDE_HW_BLK_NAME_LEN, "lm_%u",
+ mixer->id - LM_0);
if (!prop_exists[MIXER_LEN])
mixer->len = DEFAULT_SDE_HW_BLOCK_LEN;
@@ -1250,7 +1257,8 @@ static int sde_intf_parse_dt(struct device_node *np,
intf->base = PROP_VALUE_ACCESS(prop_value, INTF_OFF, i);
intf->len = PROP_VALUE_ACCESS(prop_value, INTF_LEN, 0);
intf->id = INTF_0 + i;
- snprintf(intf->name, SDE_HW_BLK_NAME_LEN, "intf_%u", intf->id);
+ snprintf(intf->name, SDE_HW_BLK_NAME_LEN, "intf_%u",
+ intf->id - INTF_0);
if (!prop_exists[INTF_LEN])
intf->len = DEFAULT_SDE_HW_BLOCK_LEN;
@@ -1331,7 +1339,8 @@ static int sde_wb_parse_dt(struct device_node *np,
wb->base = PROP_VALUE_ACCESS(prop_value, WB_OFF, i);
wb->id = WB_0 + PROP_VALUE_ACCESS(prop_value, WB_ID, i);
- snprintf(wb->name, SDE_HW_BLK_NAME_LEN, "wb_%u", wb->id);
+ snprintf(wb->name, SDE_HW_BLK_NAME_LEN, "wb_%u",
+ wb->id - WB_0);
wb->clk_ctrl = SDE_CLK_CTRL_WB0 +
PROP_VALUE_ACCESS(prop_value, WB_ID, i);
wb->xin_id = PROP_VALUE_ACCESS(prop_value, WB_XIN_ID, i);
@@ -1559,7 +1568,8 @@ static int sde_dspp_parse_dt(struct device_node *np,
dspp->base = PROP_VALUE_ACCESS(prop_value, DSPP_OFF, i);
dspp->len = PROP_VALUE_ACCESS(prop_value, DSPP_SIZE, 0);
dspp->id = DSPP_0 + i;
- snprintf(dspp->name, SDE_HW_BLK_NAME_LEN, "dspp_%u", dspp->id);
+ snprintf(dspp->name, SDE_HW_BLK_NAME_LEN, "dspp_%u",
+ dspp->id - DSPP_0);
sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
if (!sblk) {
@@ -1629,7 +1639,8 @@ static int sde_cdm_parse_dt(struct device_node *np,
cdm = sde_cfg->cdm + i;
cdm->base = PROP_VALUE_ACCESS(prop_value, HW_OFF, i);
cdm->id = CDM_0 + i;
- snprintf(cdm->name, SDE_HW_BLK_NAME_LEN, "cdm_%u", cdm->id);
+ snprintf(cdm->name, SDE_HW_BLK_NAME_LEN, "cdm_%u",
+ cdm->id - CDM_0);
cdm->len = PROP_VALUE_ACCESS(prop_value, HW_LEN, 0);
/* intf3 and wb2 for cdm block */
@@ -1695,6 +1706,8 @@ static int sde_vbif_parse_dt(struct device_node *np,
vbif->base = PROP_VALUE_ACCESS(prop_value, VBIF_OFF, i);
vbif->len = vbif_len;
vbif->id = VBIF_0 + PROP_VALUE_ACCESS(prop_value, VBIF_ID, i);
+ snprintf(vbif->name, SDE_HW_BLK_NAME_LEN, "vbif_%u",
+ vbif->id - VBIF_0);
SDE_DEBUG("vbif:%d\n", vbif->id - VBIF_0);
@@ -1822,19 +1835,21 @@ static int sde_pp_parse_dt(struct device_node *np,
pp->base = PROP_VALUE_ACCESS(prop_value, PP_OFF, i);
pp->id = PINGPONG_0 + i;
- snprintf(pp->name, SDE_HW_BLK_NAME_LEN, "pingpong_%u", pp->id);
+ snprintf(pp->name, SDE_HW_BLK_NAME_LEN, "pingpong_%u",
+ pp->id - PINGPONG_0);
pp->len = PROP_VALUE_ACCESS(prop_value, PP_LEN, 0);
sblk->te.base = PROP_VALUE_ACCESS(prop_value, TE_OFF, i);
sblk->te.id = SDE_PINGPONG_TE;
- snprintf(sblk->te.name, SDE_HW_BLK_NAME_LEN, "te_%u", pp->id);
+ snprintf(sblk->te.name, SDE_HW_BLK_NAME_LEN, "te_%u",
+ pp->id - PINGPONG_0);
set_bit(SDE_PINGPONG_TE, &pp->features);
sblk->te2.base = PROP_VALUE_ACCESS(prop_value, TE2_OFF, i);
if (sblk->te2.base) {
sblk->te2.id = SDE_PINGPONG_TE2;
snprintf(sblk->te2.name, SDE_HW_BLK_NAME_LEN, "te2_%u",
- pp->id);
+ pp->id - PINGPONG_0);
set_bit(SDE_PINGPONG_TE2, &pp->features);
set_bit(SDE_PINGPONG_SPLIT, &pp->features);
}
@@ -1846,7 +1861,7 @@ static int sde_pp_parse_dt(struct device_node *np,
if (sblk->dsc.base) {
sblk->dsc.id = SDE_PINGPONG_DSC;
snprintf(sblk->dsc.name, SDE_HW_BLK_NAME_LEN, "dsc_%u",
- pp->id);
+ sblk->dsc.id - PINGPONG_0);
set_bit(SDE_PINGPONG_DSC, &pp->features);
}
}
@@ -1978,12 +1993,12 @@ static int sde_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
cfg->mdss[0].base = MDSS_BASE_OFFSET;
cfg->mdss[0].id = MDP_TOP;
snprintf(cfg->mdss[0].name, SDE_HW_BLK_NAME_LEN, "mdss_%u",
- cfg->mdss[0].id);
+ cfg->mdss[0].id - MDP_TOP);
cfg->mdp_count = 1;
cfg->mdp[0].id = MDP_TOP;
snprintf(cfg->mdp[0].name, SDE_HW_BLK_NAME_LEN, "top_%u",
- cfg->mdp[0].id);
+ cfg->mdp[0].id - MDP_TOP);
cfg->mdp[0].base = PROP_VALUE_ACCESS(prop_value, SDE_OFF, 0);
cfg->mdp[0].len = PROP_VALUE_ACCESS(prop_value, SDE_LEN, 0);
if (!prop_exists[SDE_LEN])
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
index d5c50079afe9..be620aebf850 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
@@ -946,8 +946,9 @@ struct sde_hw_pipe *sde_hw_sspp_init(enum sde_sspp idx,
if (cfg->sblk->scaler_blk.len)
sde_dbg_reg_register_dump_range(SDE_DBG_NAME,
cfg->sblk->scaler_blk.name,
- cfg->sblk->scaler_blk.base,
- cfg->sblk->scaler_blk.base + cfg->sblk->scaler_blk.len,
+ hw_pipe->hw.blk_off + cfg->sblk->scaler_blk.base,
+ hw_pipe->hw.blk_off + cfg->sblk->scaler_blk.base +
+ cfg->sblk->scaler_blk.len,
hw_pipe->hw.xin_id);
return hw_pipe;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_top.c b/drivers/gpu/drm/msm/sde/sde_hw_top.c
index d4fb57b3ca2c..218797e623a2 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_top.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_top.c
@@ -263,6 +263,7 @@ struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx,
sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name,
mdp->hw.blk_off, mdp->hw.blk_off + mdp->hw.length,
mdp->hw.xin_id);
+ sde_dbg_set_sde_top_offset(mdp->hw.blk_off);
return mdp;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_vbif.c b/drivers/gpu/drm/msm/sde/sde_hw_vbif.c
index e9f54d0ccd6b..048ec47d7c72 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_vbif.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_vbif.c
@@ -158,8 +158,7 @@ struct sde_hw_vbif *sde_hw_vbif_init(enum sde_vbif idx,
c->cap = cfg;
_setup_vbif_ops(&c->ops, c->cap->features);
- sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off,
- c->hw.blk_off + c->hw.length, c->hw.xin_id);
+ /* no need to register sub-range in sde dbg, dump entire vbif io base */
return c;
}
diff --git a/drivers/gpu/drm/msm/sde_dbg.c b/drivers/gpu/drm/msm/sde_dbg.c
index 97ec6e247da8..b87bc75f17ea 100644
--- a/drivers/gpu/drm/msm/sde_dbg.c
+++ b/drivers/gpu/drm/msm/sde_dbg.c
@@ -19,6 +19,7 @@
#include <linux/uaccess.h>
#include <linux/dma-buf.h>
#include <linux/slab.h>
+#include <linux/list_sort.h>
#include "sde_dbg.h"
#include "sde/sde_hw_catalog.h"
@@ -41,7 +42,7 @@
#define DBGBUS_NAME_SDE "sde"
#define DBGBUS_NAME_VBIF_RT "vbif_rt"
-/* offsets from sde_base address for the debug buses */
+/* offsets from sde top address for the debug buses */
#define DBGBUS_SSPP0 0x188
#define DBGBUS_SSPP1 0x298
#define DBGBUS_DSPP 0x348
@@ -54,6 +55,9 @@
#define MMSS_VBIF_TEST_BUS_OUT_CTRL 0x210
#define MMSS_VBIF_TEST_BUS_OUT 0x230
+/* print debug ranges in groups of 4 u32s */
+#define REG_DUMP_ALIGN 16
+
/**
* struct sde_dbg_reg_offset - tracking for start and end of region
* @start: start offset
@@ -135,6 +139,7 @@ struct sde_dbg_debug_bus_common {
struct sde_dbg_sde_debug_bus {
struct sde_dbg_debug_bus_common cmn;
struct sde_debug_bus_entry *entries;
+ u32 top_blk_off;
};
struct sde_dbg_vbif_debug_bus {
@@ -978,16 +983,17 @@ static inline void _sde_dbg_enable_power(int enable)
* _sde_dump_reg - helper function for dumping rotator register set content
* @dump_name: register set name
* @reg_dump_flag: dumping flag controlling in-log/memory dump location
+ * @base_addr: starting address of io region for calculating offsets to print
* @addr: starting address offset for dumping
* @len_bytes: range of the register set
* @dump_mem: output buffer for memory dump location option
* @from_isr: whether being called from isr context
*/
static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
- char __iomem *addr, size_t len_bytes, u32 **dump_mem,
- bool from_isr)
+ char __iomem *base_addr, char __iomem *addr, size_t len_bytes,
+ u32 **dump_mem, bool from_isr)
{
- u32 in_log, in_mem, len_align_16, len_bytes_aligned;
+ u32 in_log, in_mem, len_align, len_padded;
u32 *dump_addr = NULL;
char __iomem *end_addr;
int i;
@@ -998,28 +1004,33 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
in_log = (reg_dump_flag & SDE_DBG_DUMP_IN_LOG);
in_mem = (reg_dump_flag & SDE_DBG_DUMP_IN_MEM);
- pr_debug("reg_dump_flag=%d in_log=%d in_mem=%d\n",
- reg_dump_flag, in_log, in_mem);
+ pr_debug("%s: reg_dump_flag=%d in_log=%d in_mem=%d\n",
+ dump_name, reg_dump_flag, in_log, in_mem);
if (!in_log && !in_mem)
return;
- len_align_16 = (len_bytes + 15) / 16;
- len_bytes_aligned = len_align_16 * 16;
+ if (in_log)
+ dev_info(sde_dbg_base.dev, "%s: start_offset 0x%lx len 0x%zx\n",
+ dump_name, addr - base_addr, len_bytes);
+
+ len_align = (len_bytes + REG_DUMP_ALIGN - 1) / REG_DUMP_ALIGN;
+ len_padded = len_align * REG_DUMP_ALIGN;
end_addr = addr + len_bytes;
if (in_mem) {
if (dump_mem && !(*dump_mem)) {
phys_addr_t phys = 0;
*dump_mem = dma_alloc_coherent(sde_dbg_base.dev,
- len_bytes_aligned, &phys, GFP_KERNEL);
+ len_padded, &phys, GFP_KERNEL);
}
if (dump_mem && *dump_mem) {
dump_addr = *dump_mem;
- pr_info("%s: start_addr:0x%pK end_addr:0x%pK reg_addr=0x%pK\n",
- dump_name, dump_addr,
- dump_addr + len_bytes_aligned, addr);
+ dev_info(sde_dbg_base.dev,
+ "%s: start_addr:0x%pK len:0x%x reg_offset=0x%lx\n",
+ dump_name, dump_addr, len_padded,
+ addr - base_addr);
} else {
in_mem = 0;
pr_err("dump_mem: kzalloc fails!\n");
@@ -1029,7 +1040,7 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
if (!from_isr)
_sde_dbg_enable_power(true);
- for (i = 0; i < len_align_16; i++) {
+ for (i = 0; i < len_align; i++) {
u32 x0, x4, x8, xc;
x0 = (addr < end_addr) ? readl_relaxed(addr + 0x0) : 0;
@@ -1038,8 +1049,9 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
xc = (addr + 0xc < end_addr) ? readl_relaxed(addr + 0xc) : 0;
if (in_log)
- pr_info("%pK : %08x %08x %08x %08x\n", addr, x0, x4, x8,
- xc);
+ dev_info(sde_dbg_base.dev,
+ "0x%lx : %08x %08x %08x %08x\n",
+ addr - base_addr, x0, x4, x8, xc);
if (dump_addr) {
dump_addr[i * 4] = x0;
@@ -1048,7 +1060,7 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
dump_addr[i * 4 + 3] = xc;
}
- addr += 16;
+ addr += REG_DUMP_ALIGN;
}
if (!from_isr)
@@ -1077,6 +1089,20 @@ static u32 _sde_dbg_get_dump_range(struct sde_dbg_reg_offset *range_node,
return length;
}
+static int _sde_dump_reg_range_cmp(void *priv, struct list_head *a,
+ struct list_head *b)
+{
+ struct sde_dbg_reg_range *ar, *br;
+
+ if (!a || !b)
+ return 0;
+
+ ar = container_of(a, struct sde_dbg_reg_range, head);
+ br = container_of(b, struct sde_dbg_reg_range, head);
+
+ return ar->offset.start - br->offset.start;
+}
+
/**
* _sde_dump_reg_by_ranges - dump ranges or full range of the register blk base
* @dbg: register blk base structure
@@ -1094,10 +1120,13 @@ static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg,
return;
}
- pr_info("%s:=========%s DUMP=========\n", __func__, dbg->name);
+ dev_info(sde_dbg_base.dev, "%s:=========%s DUMP=========\n", __func__,
+ dbg->name);
/* If there is a list to dump the registers by ranges, use the ranges */
if (!list_empty(&dbg->sub_range_list)) {
+ /* 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);
@@ -1107,18 +1136,20 @@ static void _sde_dump_reg_by_ranges(struct sde_dbg_reg_base *dbg,
addr, range_node->offset.start,
range_node->offset.end);
- _sde_dump_reg((const char *)range_node->range_name,
- reg_dump_flag, addr, len, &range_node->reg_dump,
- false);
+ _sde_dump_reg(range_node->range_name, reg_dump_flag,
+ dbg->base, addr, len,
+ &range_node->reg_dump, false);
}
} else {
/* If there is no list to dump ranges, dump all registers */
- pr_info("Ranges not found, will dump full registers\n");
- pr_info("base:0x%pK len:0x%zx\n", dbg->base, dbg->max_offset);
+ dev_info(sde_dbg_base.dev,
+ "Ranges not found, will dump full registers\n");
+ dev_info(sde_dbg_base.dev, "base:0x%pK len:0x%zx\n", dbg->base,
+ dbg->max_offset);
addr = dbg->base;
len = dbg->max_offset;
- _sde_dump_reg((const char *)dbg->name, reg_dump_flag, addr,
- len, &dbg->reg_dump, false);
+ _sde_dump_reg(dbg->name, reg_dump_flag, dbg->base, addr, len,
+ &dbg->reg_dump, false);
}
}
@@ -1198,7 +1229,7 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
reg_base_head)
if (strlen(reg_base->name) &&
!strcmp(reg_base->name, bus->cmn.name))
- mem_base = reg_base->base;
+ mem_base = reg_base->base + bus->top_blk_off;
if (!mem_base) {
pr_err("unable to find mem_base for %s\n", bus->cmn.name);
@@ -1216,7 +1247,8 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
if (!in_log && !in_mem)
return;
- pr_info("======== start %s dump =========\n", bus->cmn.name);
+ dev_info(sde_dbg_base.dev, "======== start %s dump =========\n",
+ bus->cmn.name);
if (in_mem) {
if (!(*dump_mem))
@@ -1225,8 +1257,9 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
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);
+ dev_info(sde_dbg_base.dev,
+ "%s: start_addr:0x%pK len:0x%x\n",
+ __func__, dump_addr, list_size);
} else {
in_mem = false;
pr_err("dump_mem: allocation fails\n");
@@ -1248,9 +1281,10 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
status = readl_relaxed(mem_base + offset);
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);
+ dev_info(sde_dbg_base.dev,
+ "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;
@@ -1265,7 +1299,8 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus)
}
_sde_dbg_enable_power(false);
- pr_info("======== end %s dump =========\n", bus->cmn.name);
+ dev_info(sde_dbg_base.dev, "======== end %s dump =========\n",
+ bus->cmn.name);
}
static void _sde_dbg_dump_vbif_debug_bus_entry(
@@ -1295,7 +1330,8 @@ static void _sde_dbg_dump_vbif_debug_bus_entry(
*dump_addr++ = val;
}
if (in_log)
- pr_err("testpoint:%x arb/xin id=%d index=%d val=0x%x\n",
+ dev_info(sde_dbg_base.dev,
+ "testpoint:%x arb/xin id=%d index=%d val=0x%x\n",
head->block_bus_addr, i, j, val);
}
}
@@ -1334,7 +1370,8 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
list_size = bus->cmn.entries_size;
dump_mem = &bus->cmn.dumped_content;
- pr_info("======== start %s dump =========\n", bus->cmn.name);
+ dev_info(sde_dbg_base.dev, "======== start %s dump =========\n",
+ bus->cmn.name);
if (!dump_mem || !dbg_bus || !bus_size || !list_size)
return;
@@ -1361,8 +1398,9 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
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);
+ dev_info(sde_dbg_base.dev,
+ "%s: start_addr:0x%pK len:0x%x\n",
+ __func__, dump_addr, list_size);
} else {
in_mem = false;
pr_err("dump_mem: allocation fails\n");
@@ -1393,7 +1431,8 @@ static void _sde_dbg_dump_vbif_dbg_bus(struct sde_dbg_vbif_debug_bus *bus)
_sde_dbg_enable_power(false);
- pr_info("======== end %s dump =========\n", bus->cmn.name);
+ dev_info(sde_dbg_base.dev, "======== end %s dump =========\n",
+ bus->cmn.name);
}
/**
@@ -1995,6 +2034,21 @@ void sde_dbg_reg_register_dump_range(const char *base_name,
return;
}
+ if (!range_name || strlen(range_name) == 0) {
+ pr_err("%pS: bad range name, base_name %s, offset_start 0x%X, end 0x%X\n",
+ __builtin_return_address(0), base_name,
+ offset_start, offset_end);
+ return;
+ }
+
+ if (offset_end - offset_start < REG_DUMP_ALIGN ||
+ offset_start > offset_end) {
+ pr_err("%pS: bad range, base_name %s, range_name %s, offset_start 0x%X, end 0x%X\n",
+ __builtin_return_address(0), base_name,
+ range_name, offset_start, offset_end);
+ return;
+ }
+
range = kzalloc(sizeof(*range), GFP_KERNEL);
if (!range)
return;
@@ -2005,6 +2059,12 @@ void sde_dbg_reg_register_dump_range(const char *base_name,
range->xin_id = xin_id;
list_add_tail(&range->head, &reg_base->sub_range_list);
- pr_debug("%s start: 0x%X end: 0x%X\n", range->range_name,
+ pr_debug("base %s, range %s, start 0x%X, end 0x%X\n",
+ base_name, range->range_name,
range->offset.start, range->offset.end);
}
+
+void sde_dbg_set_sde_top_offset(u32 blk_off)
+{
+ sde_dbg_base.dbgbus_sde.top_blk_off = blk_off;
+}
diff --git a/drivers/gpu/drm/msm/sde_dbg.h b/drivers/gpu/drm/msm/sde_dbg.h
index 59da9fd63268..74fd4c94b490 100644
--- a/drivers/gpu/drm/msm/sde_dbg.h
+++ b/drivers/gpu/drm/msm/sde_dbg.h
@@ -240,6 +240,12 @@ void sde_dbg_reg_register_dump_range(const char *base_name,
const char *range_name, u32 offset_start, u32 offset_end,
uint32_t xin_id);
+/**
+ * sde_dbg_set_sde_top_offset - set the target specific offset from mdss base
+ * address of the top registers. Used for accessing debug bus controls.
+ * @blk_off: offset from mdss base of the top block
+ */
+void sde_dbg_set_sde_top_offset(u32 blk_off);
#else
static inline struct sde_dbg_evtlog *sde_evtlog_init(void)
{
@@ -301,6 +307,9 @@ static inline void sde_dbg_reg_register_dump_range(const char *base_name,
{
}
+void sde_dbg_set_sde_top_offset(u32 blk_off)
+{
+}
#endif /* defined(CONFIG_DEBUG_FS) */