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

Commit 899cf5db authored by Ingrid Gallardo's avatar Ingrid Gallardo
Browse files

msm: mdss: debugfs: xlog: add support to dump registers by ranges



Current xlog dumps the entire registers ranges
mapped in memory. This entire range can be
reduced to only the meaningful offsets to help in
debugging and avoid overflows in the debug buffers.
This change adds support to only dump the registers
ranges specified.

Change-Id: Iecf7f5eaa909b0365ea599ae094c7f184c0ae8b8
Signed-off-by: default avatarIngrid Gallardo <ingridg@codeaurora.org>
parent e2f34d97
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -372,6 +372,22 @@ Optional properties:
				The offsets are calculated from the "mdp_phys" base address
				specified. The number of offsets should match the
				number of ping pong buffers available in the hardware.
- qcom,regs-dump-mdp:		This array represents the registers offsets that
				will be dumped from the mdp when the debug logging
				is enabled; each entry in the table is an start and
				end offset from the MDP addres "mdp_phys", the
				format of each entry is as follows:
				<start_offset end_offset>
				Ex:
				<0x01000 0x01404>
				Will dump the MDP registers
				from the address: "mdp_phys + 0x01000"
				to the address: "mdp_phys + 0x01404"
- qcom,regs-dump-names-mdp:	This array represents the tag that will be used
				for each of the entries defined within regs-dump.
				Note that each tag matches with one of the
				regs-dump entries in the same order as they
				are defined.

Fudge Factors:			Fudge factors are used to boost demand for
				resources like bus bandswidth, clk rate etc. to
+3 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 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
@@ -1444,7 +1444,8 @@ static int msm_dsi_debug_init(void)

	rc = mdss_debug_register_base("dsi0",
				dsi_host_private->dsi_base,
				dsi_host_private->dsi_reg_size);
				dsi_host_private->dsi_reg_size,
				NULL);

	return rc;
}
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
 * Copyright (C) 2007 Google Incorporated
 *
 * This software is licensed under the terms of the GNU General Public
@@ -1878,7 +1878,7 @@ static int mdp3_debug_init(struct platform_device *pdev)
				&mdp3_debug_dump_stats_fops);

	rc = mdss_debug_register_base(NULL, mdp3_res->mdp_base ,
					mdp3_res->mdp_reg_size);
					mdp3_res->mdp_reg_size, NULL);

	return rc;
}
+91 −1
Original line number Diff line number Diff line
@@ -233,7 +233,7 @@ static const struct file_operations mdss_reg_fops = {
};

int mdss_debug_register_base(const char *name, void __iomem *base,
			     size_t max_offset)
	size_t max_offset, struct mdss_debug_base **dbg_blk)
{
	struct mdss_data_type *mdata = mdss_res;
	struct mdss_debug_data *mdd;
@@ -242,6 +242,9 @@ int mdss_debug_register_base(const char *name, void __iomem *base,
	char dn[80] = "";
	int prefix_len = 0;

	if (dbg_blk)
		(*dbg_blk) = NULL;

	if (!mdata || !mdata->debug_inf.debug_data)
		return -ENODEV;

@@ -276,8 +279,14 @@ int mdss_debug_register_base(const char *name, void __iomem *base,
		goto reg_fail;
	}

	/* Initialize list to make sure check for null list will be valid */
	INIT_LIST_HEAD(&dbg->dump_list);

	list_add(&dbg->head, &mdd->base_list);

	if (dbg_blk)
		(*dbg_blk) = dbg;

	return 0;
reg_fail:
	debugfs_remove(ent_off);
@@ -286,6 +295,87 @@ off_fail:
	return -ENODEV;
}

static void parse_dump_range_name(struct device_node *node,
	int total_names, int index, char *range_name, u32 range_size,
	const char *name_prop)
{
	int rc = 0;
	const char *st = NULL;

	if ((total_names > 0) && (index < total_names)) {
		rc = of_property_read_string_index(node,
			name_prop, index, &st);
		if (rc) {
			pr_err("%s: error reading name. index=%d, rc=%d\n",
				__func__, index, rc);
			goto error;
		}
		snprintf(range_name, range_size, "%s", st);
		return;
	}

error:
	snprintf(range_name, range_size, "%s", "<no named range>");
}

static int parse_dt_xlog_dump_list(const u32 *arr, int count,
	struct list_head *xlog_dump_list, int total_names,
	struct platform_device *pdev, const char *name_prop)
{
	struct range_dump_node *xlog_node;
	u32 len;
	int i;

	for (i = 0, len = count * 2; i < len; i += 2) {
		xlog_node = kzalloc(sizeof(*xlog_node), GFP_KERNEL);
		if (!xlog_node)
			return -ENOMEM;

		xlog_node->offset.start = be32_to_cpu(arr[i]);
		xlog_node->offset.end = be32_to_cpu(arr[i + 1]);
		parse_dump_range_name(pdev->dev.of_node, total_names, i/2,
			xlog_node->range_name,
			ARRAY_SIZE(xlog_node->range_name), name_prop);

		list_add_tail(&xlog_node->head, xlog_dump_list);
	}

	return 0;
}

void mdss_debug_register_dump_range(struct platform_device *pdev,
	struct mdss_debug_base *blk_base, const char *ranges_prop,
	const char *name_prop)
{
	int total_dump_names, mdp_len;
	const u32 *mdp_arr;

	if (!blk_base || !ranges_prop || !name_prop)
		return;

	/* Get the property with the name of the ranges */
	total_dump_names = of_property_count_strings(pdev->dev.of_node,
		name_prop);
	if (total_dump_names < 0) {
		pr_warn("%s: dump names not found. rc=%d\n", __func__,
			total_dump_names);
		total_dump_names = 0;
	}

	mdp_arr = of_get_property(pdev->dev.of_node, ranges_prop,
			&mdp_len);
	if (!mdp_arr) {
		pr_warn("No xlog range dump found, continue\n");
		mdp_len = 0;
	} else {
		/* 2 is the number of entries per row to calculate the rows */
		mdp_len /= 2 * sizeof(u32);
		parse_dt_xlog_dump_list(mdp_arr, mdp_len,
			&blk_base->dump_list, total_dump_names, pdev,
				name_prop);
	}
}

static ssize_t mdss_debug_factor_write(struct file *file,
		    const char __user *user_buf, size_t count, loff_t *ppos)
{
+29 −6
Original line number Diff line number Diff line
@@ -67,7 +67,12 @@ enum mdss_dbg_xlog_flag {
	trace_mdp_trace_counter(current->tgid, name, value)

#ifdef CONFIG_DEBUG_FS

#define MDSS_DEBUG_BASE_MAX 10

struct mdss_debug_base {
	struct list_head head; /* head of this node */
	struct list_head dump_list; /* head to the list with dump ranges */
	struct mdss_debug_data *mdd;
	char name[80];
	void __iomem *base;
@@ -76,8 +81,7 @@ struct mdss_debug_base {
	size_t max_offset;
	char *buf;
	size_t buf_len;
	struct list_head head;
	u32 *reg_dump;
	u32 *reg_dump; /* address for the mem dump if no ranges used */
};

struct mdss_debug_data {
@@ -86,6 +90,18 @@ struct mdss_debug_data {
	struct list_head base_list;
};

struct dump_offset {
	u32 start;
	u32 end;
};

struct range_dump_node {
	struct list_head head; /* head of this node */
	u32 *reg_dump; /* address for the mem dump */
	char range_name[40]; /* name of this range */
	struct dump_offset offset; /* range to dump */
};

#define DEFINE_MDSS_DEBUGFS_SEQ_FOPS(__prefix)				\
static int __prefix ## _open(struct inode *inode, struct file *file)	\
{									\
@@ -102,7 +118,10 @@ static const struct file_operations __prefix ## _fops = { \
int mdss_debugfs_init(struct mdss_data_type *mdata);
int mdss_debugfs_remove(struct mdss_data_type *mdata);
int mdss_debug_register_base(const char *name, void __iomem *base,
				    size_t max_offset);
	size_t max_offset, struct mdss_debug_base **dbg_blk);
void mdss_debug_register_dump_range(struct platform_device *pdev,
	struct mdss_debug_base *blk_base, const char *ranges_prop,
	const char *name_prop);
int mdss_misr_set(struct mdss_data_type *mdata, struct mdp_misr *req,
			struct mdss_mdp_ctl *ctl);
int mdss_misr_get(struct mdss_data_type *mdata, struct mdp_misr *resp,
@@ -121,7 +140,10 @@ static inline int mdss_debugfs_remove(struct mdss_data_type *mdata)
	return 0;
}
static inline int mdss_debug_register_base(const char *name, void __iomem *base,
					size_t max_offset) { return 0; }
	size_t max_offset, struct mdss_debug_base **dbg_blk) { return 0; }
static inline void mdss_debug_register_dump_range(struct platform_device *pdev,
	struct mdss_debug_base *blk_base, const char *ranges_prop,
	const char *name_prop) { return 0; }
static inline int mdss_misr_set(struct mdss_data_type *mdata,
					struct mdp_misr *req,
					struct mdss_mdp_ctl *ctl)
@@ -143,9 +165,10 @@ static inline int mdss_xlog_tout_handler_iommu(struct iommu_domain *domain,
#endif

static inline int mdss_debug_register_io(const char *name,
		struct dss_io_data *io_data)
		struct dss_io_data *io_data, struct mdss_debug_base **dbg_blk)
{
	return mdss_debug_register_base(name, io_data->base, io_data->len);
	return mdss_debug_register_base(name, io_data->base, io_data->len,
		dbg_blk);
}

#endif /* MDSS_DEBUG_H */
Loading