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

Commit 1ad92324 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm: snapshot of msm/sde_ layer and include files"

parents a6dded6c 510f8a0d
Loading
Loading
Loading
Loading
+473 −12
Original line number Diff line number Diff line
@@ -67,6 +67,11 @@
#define DBG_CTRL_RESET_HW_PANIC	BIT(2)
#define DBG_CTRL_MAX			BIT(3)

#define DUMP_BUF_SIZE			(4096 * 512)
#define DUMP_CLMN_COUNT			4
#define DUMP_LINE_SIZE			256
#define DUMP_MAX_LINES_PER_BLK		512

/**
 * struct sde_dbg_reg_offset - tracking for start and end of region
 * @start: start offset
@@ -162,6 +167,29 @@ struct sde_dbg_vbif_debug_bus {
	struct vbif_debug_bus_entry *entries;
};

struct sde_dbg_dsi_debug_bus {
	u32 *entries;
	u32 size;
};

/**
 * struct sde_dbg_regbuf - wraps buffer and tracking params for register dumps
 * @buf: pointer to allocated memory for storing register dumps in hw recovery
 * @buf_size: size of the memory allocated
 * @len: size of the dump data valid in the buffer
 * @rpos: cursor points to the buffer position read by client
 * @dump_done: to indicate if dumping to user memory is complete
 * @cur_blk: points to the current sde_dbg_reg_base block
 */
struct sde_dbg_regbuf {
	char *buf;
	int buf_size;
	int len;
	int rpos;
	int dump_done;
	struct sde_dbg_reg_base *cur_blk;
};

/**
 * struct sde_dbg_base - global sde debug base structure
 * @evtlog: event log instance
@@ -178,6 +206,10 @@ struct sde_dbg_vbif_debug_bus {
 * @dbgbus_vbif_rt: debug bus structure for the realtime vbif
 * @dump_all: dump all entries in register dump
 * @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
 * @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;
@@ -195,9 +227,15 @@ static struct sde_dbg_base {

	struct sde_dbg_sde_debug_bus dbgbus_sde;
	struct sde_dbg_vbif_debug_bus dbgbus_vbif_rt;
	struct sde_dbg_dsi_debug_bus dbgbus_dsi;
	bool dump_all;
	bool dsi_dbg_bus;
	u32 debugfs_ctrl;

	struct sde_dbg_regbuf regbuf;
	u32 cur_evt_index;
	u32 dbgbus_dump_idx;
	u32 vbif_dbgbus_dump_idx;
} sde_dbg_base;

/* sde_dbg_base_evtlog - global pointer to main sde event log for macro use */
@@ -3292,6 +3330,42 @@ static struct vbif_debug_bus_entry vbif_dbg_bus_msm8998[] = {
	{0x21c, 0x214, 0, 14, 0, 0xc}, /* xin blocks - clock side */
};

static u32 dsi_dbg_bus_sdm845[] = {
	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,
};

/**
 * _sde_dbg_enable_power - use callback to turn power on for hw register access
 * @enable: whether to turn power on or off
@@ -3341,7 +3415,8 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,

	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);
				dump_name, (unsigned long)(addr - base_addr),
					len_bytes);

	len_align = (len_bytes + REG_DUMP_ALIGN - 1) / REG_DUMP_ALIGN;
	len_padded = len_align * REG_DUMP_ALIGN;
@@ -3359,7 +3434,7 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
			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);
				(unsigned long)(addr - base_addr));
		} else {
			in_mem = 0;
			pr_err("dump_mem: kzalloc fails!\n");
@@ -3385,7 +3460,8 @@ static void _sde_dump_reg(const char *dump_name, u32 reg_dump_flag,
		if (in_log)
			dev_info(sde_dbg_base.dev,
					"0x%lx : %08x %08x %08x %08x\n",
					addr - base_addr, x0, x4, x8, xc);
					(unsigned long)(addr - base_addr),
					x0, x4, x8, xc);

		if (dump_addr) {
			dump_addr[i * 4] = x0;
@@ -3412,11 +3488,12 @@ static u32 _sde_dbg_get_dump_range(struct sde_dbg_reg_offset *range_node,
{
	u32 length = 0;

	if ((range_node->start > range_node->end) ||
		(range_node->end > max_offset) || (range_node->start == 0
		&& range_node->end == 0)) {
	if (range_node->start == 0 && range_node->end == 0) {
		length = max_offset;
	} else {
	} else if (range_node->start < max_offset) {
		if (range_node->end > max_offset)
			length = max_offset - range_node->start;
		else if (range_node->start < range_node->end)
			length = range_node->end - range_node->start;
	}

@@ -3857,7 +3934,8 @@ static void _sde_dump_array(struct sde_dbg_reg_base *blk_arr[],
		_sde_dbg_dump_vbif_dbg_bus(&sde_dbg_base.dbgbus_vbif_rt);

	if (sde_dbg_base.dsi_dbg_bus || dump_all)
		dsi_ctrl_debug_dump();
		dsi_ctrl_debug_dump(sde_dbg_base.dbgbus_dsi.entries,
				    sde_dbg_base.dbgbus_dsi.size);

	if (do_panic && sde_dbg_base.panic_on_err)
		panic(name);
@@ -4018,6 +4096,12 @@ static int sde_dbg_debugfs_open(struct inode *inode, struct file *file)
	/* non-seekable */
	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
	file->private_data = inode->i_private;
	mutex_lock(&sde_dbg_base.mutex);
	sde_dbg_base.cur_evt_index = 0;
	sde_dbg_base.evtlog->first = sde_dbg_base.evtlog->curr + 1;
	sde_dbg_base.evtlog->last =
		sde_dbg_base.evtlog->first + SDE_EVTLOG_ENTRY;
	mutex_unlock(&sde_dbg_base.mutex);
	return 0;
}

@@ -4037,8 +4121,13 @@ static ssize_t sde_evtlog_dump_read(struct file *file, char __user *buff,
	if (!buff || !ppos)
		return -EINVAL;

	len = sde_evtlog_dump_to_buffer(sde_dbg_base.evtlog, evtlog_buf,
			SDE_EVTLOG_BUF_MAX, true);
	mutex_lock(&sde_dbg_base.mutex);
	len = sde_evtlog_dump_to_buffer(sde_dbg_base.evtlog,
			evtlog_buf, SDE_EVTLOG_BUF_MAX,
			!sde_dbg_base.cur_evt_index, true);
	sde_dbg_base.cur_evt_index++;
	mutex_unlock(&sde_dbg_base.mutex);

	if (len < 0 || len > count) {
		pr_err("len is more than user buffer size\n");
		return 0;
@@ -4228,6 +4317,329 @@ static const struct file_operations sde_evtlog_filter_fops = {
	.release =	seq_release
};

static int sde_recovery_regdump_open(struct inode *inode, struct file *file)
{
	if (!inode || !file)
		return -EINVAL;

	/* non-seekable */
	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
	file->private_data = inode->i_private;

	/* initialize to start position */
	sde_dbg_base.regbuf.rpos = 0;
	sde_dbg_base.regbuf.cur_blk = NULL;
	sde_dbg_base.regbuf.dump_done = false;

	return 0;
}

static ssize_t _sde_dbg_dump_reg_rows(u32 reg_start,
		void *start, int count, char *buf, int buflen)
{
	int i;
	int len = 0;
	u32 *addr;
	u32  reg_offset = 0;
	int rows = min(count / DUMP_CLMN_COUNT, DUMP_MAX_LINES_PER_BLK);

	if (!start || !buf) {
		pr_err("invalid address for dump\n");
		return len;
	}

	if (buflen < PAGE_SIZE) {
		pr_err("buffer too small for dump\n");
		return len;
	}

	for (i = 0; i < rows; i++) {
		addr = start + (i * DUMP_CLMN_COUNT * sizeof(u32));
		reg_offset = reg_start + (i * DUMP_CLMN_COUNT * sizeof(u32));
		if (buflen < (len + DUMP_LINE_SIZE))
			break;

		len += snprintf(buf + len, DUMP_LINE_SIZE,
				"0x%.8X | %.8X %.8X %.8X %.8X\n",
				reg_offset, addr[0], addr[1], addr[2], addr[3]);
	}

	return len;
}

static int  _sde_dbg_recovery_dump_sub_blk(struct sde_dbg_reg_range *sub_blk,
		char  *buf, int buflen)
{
	int count = 0;
	int len = 0;

	if (!sub_blk || (buflen < PAGE_SIZE)) {
		pr_err("invalid params buflen:%d subblk valid:%d\n",
				buflen, sub_blk != NULL);
		return len;
	}

	count = (sub_blk->offset.end - sub_blk->offset.start) / (sizeof(u32));
	if (count < DUMP_CLMN_COUNT) {
		pr_err("invalid count for register dumps :%d\n", count);
		return len;
	}

	len += snprintf(buf + len, DUMP_LINE_SIZE,
			"------------------------------------------\n");
	len += snprintf(buf + len, DUMP_LINE_SIZE,
			"**** sub block [%s] - size:%d ****\n",
			sub_blk->range_name, count);
	len += _sde_dbg_dump_reg_rows(sub_blk->offset.start, sub_blk->reg_dump,
			count, buf + len, buflen - len);

	return len;
}

static int  _sde_dbg_recovery_dump_reg_blk(struct sde_dbg_reg_base *blk,
		char *buf, int buf_size, int *out_len)
{
	int ret = 0;
	int len = 0;
	struct sde_dbg_reg_range *sub_blk;

	if (buf_size < PAGE_SIZE) {
		pr_err("buffer too small for dump\n");
		return len;
	}

	if (!blk || !strlen(blk->name)) {
		len += snprintf(buf + len, DUMP_LINE_SIZE,
			"Found one invalid block - skip dump\n");
		*out_len = len;
		return len;
	}

	len += snprintf(buf + len, DUMP_LINE_SIZE,
			"******************************************\n");
	len += snprintf(buf + len, DUMP_LINE_SIZE,
			"==========================================\n");
	len += snprintf(buf + len, DUMP_LINE_SIZE,
			"*********** DUMP of %s block *************\n",
			blk->name);
	len += snprintf(buf + len, DUMP_LINE_SIZE,
			"count:%ld max-off:0x%lx has_sub_blk:%d\n",
			blk->cnt, blk->max_offset,
			!list_empty(&blk->sub_range_list));

	if (list_empty(&blk->sub_range_list)) {
		len += _sde_dbg_dump_reg_rows(0, blk->reg_dump,
				blk->max_offset / sizeof(u32), buf + len,
				buf_size - len);
	} else {
		list_for_each_entry(sub_blk, &blk->sub_range_list, head)
			len += _sde_dbg_recovery_dump_sub_blk(sub_blk,
					buf + len, buf_size - len);
	}
	*out_len = len;

	return ret;
}

static ssize_t sde_recovery_regdump_read(struct file *file, char __user *ubuf,
		size_t count, loff_t *ppos)
{
	ssize_t len = 0;
	int usize = 0;
	struct sde_dbg_base *dbg_base = &sde_dbg_base;
	struct sde_dbg_regbuf *rbuf = &dbg_base->regbuf;

	mutex_lock(&sde_dbg_base.mutex);
	if (!rbuf->dump_done && !rbuf->cur_blk) {
		if (!rbuf->buf)
			rbuf->buf = kzalloc(DUMP_BUF_SIZE, GFP_KERNEL);
		if (!rbuf->buf) {
			len =  -ENOMEM;
			goto err;
		}
		rbuf->rpos = 0;
		rbuf->len = 0;
		rbuf->buf_size = DUMP_BUF_SIZE;

		rbuf->cur_blk = list_first_entry(&dbg_base->reg_base_list,
				struct sde_dbg_reg_base, reg_base_head);
		if (rbuf->cur_blk)
			_sde_dbg_recovery_dump_reg_blk(rbuf->cur_blk,
					rbuf->buf,
					rbuf->buf_size,
					&rbuf->len);
		pr_debug("dumping done for blk:%s len:%d\n", rbuf->cur_blk ?
				rbuf->cur_blk->name : "unknown", rbuf->len);
	} else if (rbuf->len == rbuf->rpos && rbuf->cur_blk) {
		rbuf->rpos = 0;
		rbuf->len = 0;
		rbuf->buf_size = DUMP_BUF_SIZE;

		if (rbuf->cur_blk == list_last_entry(&dbg_base->reg_base_list,
					struct sde_dbg_reg_base, reg_base_head))
			rbuf->cur_blk = NULL;
		else
			rbuf->cur_blk = list_next_entry(rbuf->cur_blk,
					reg_base_head);

		if (rbuf->cur_blk)
			_sde_dbg_recovery_dump_reg_blk(rbuf->cur_blk,
					rbuf->buf,
					rbuf->buf_size,
					&rbuf->len);
		pr_debug("dumping done for blk:%s len:%d\n", rbuf->cur_blk ?
				rbuf->cur_blk->name : "unknown", rbuf->len);
	}

	if ((rbuf->len - rbuf->rpos) > 0) {
		usize = ((rbuf->len - rbuf->rpos) > count) ?
			count  : rbuf->len - rbuf->rpos;
		if (copy_to_user(ubuf, rbuf->buf + rbuf->rpos, usize)) {
			len =  -EFAULT;
			goto err;
		}

		len = usize;
		rbuf->rpos += usize;
		*ppos += usize;
	}

	if (!len && rbuf->buf)
		rbuf->dump_done = true;
err:
	mutex_unlock(&sde_dbg_base.mutex);

	return len;
}

static const struct file_operations sde_recovery_reg_fops = {
	.open = sde_recovery_regdump_open,
	.read = sde_recovery_regdump_read,
};

static int sde_recovery_dbgbus_dump_open(struct inode *inode, struct file *file)
{
	if (!inode || !file)
		return -EINVAL;

	/* non-seekable */
	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
	file->private_data = inode->i_private;

	mutex_lock(&sde_dbg_base.mutex);
	sde_dbg_base.dbgbus_dump_idx = 0;
	mutex_unlock(&sde_dbg_base.mutex);

	return 0;
}

static ssize_t sde_recovery_dbgbus_dump_read(struct file *file,
		char __user *buff,
		size_t count, loff_t *ppos)
{
	ssize_t len = 0;
	char evtlog_buf[SDE_EVTLOG_BUF_MAX];
	u32 *data;
	struct sde_dbg_sde_debug_bus *bus;

	mutex_lock(&sde_dbg_base.mutex);
	bus = &sde_dbg_base.dbgbus_sde;
	if (!bus->cmn.dumped_content || !bus->cmn.entries_size)
		goto dump_done;

	if (sde_dbg_base.dbgbus_dump_idx <=
			((bus->cmn.entries_size - 1) * DUMP_CLMN_COUNT)) {
		data = &bus->cmn.dumped_content[
			sde_dbg_base.dbgbus_dump_idx];
		len = snprintf(evtlog_buf, SDE_EVTLOG_BUF_MAX,
				"0x%.8X | %.8X %.8X %.8X %.8X\n",
				sde_dbg_base.dbgbus_dump_idx,
				data[0], data[1], data[2], data[3]);
		sde_dbg_base.dbgbus_dump_idx += DUMP_CLMN_COUNT;
		if ((count < len) || copy_to_user(buff, evtlog_buf, len)) {
			len = -EFAULT;
			goto dump_done;
		}
		*ppos += len;
	}
dump_done:
	mutex_unlock(&sde_dbg_base.mutex);

	return len;
}

static const struct file_operations sde_recovery_dbgbus_fops = {
	.open = sde_recovery_dbgbus_dump_open,
	.read = sde_recovery_dbgbus_dump_read,
};

static int sde_recovery_vbif_dbgbus_dump_open(struct inode *inode,
		struct file *file)
{
	if (!inode || !file)
		return -EINVAL;

	/* non-seekable */
	file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
	file->private_data = inode->i_private;

	mutex_lock(&sde_dbg_base.mutex);
	sde_dbg_base.vbif_dbgbus_dump_idx = 0;
	mutex_unlock(&sde_dbg_base.mutex);

	return 0;
}

static ssize_t sde_recovery_vbif_dbgbus_dump_read(struct file *file,
		char __user *buff,
		size_t count, loff_t *ppos)
{
	ssize_t len = 0;
	char evtlog_buf[SDE_EVTLOG_BUF_MAX];
	int i;
	u32 *data;
	u32 list_size = 0;
	struct vbif_debug_bus_entry *head;
	struct sde_dbg_vbif_debug_bus *bus;

	mutex_lock(&sde_dbg_base.mutex);
	bus = &sde_dbg_base.dbgbus_vbif_rt;
	if (!bus->cmn.dumped_content || !bus->cmn.entries_size)
		goto dump_done;

	/* calculate total number of test point */
	for (i = 0; i < bus->cmn.entries_size; i++) {
		head = bus->entries + i;
		list_size += (head->block_cnt * head->test_pnt_cnt);
	}

	/* 4 entries for each test point*/
	list_size *= DUMP_CLMN_COUNT;
	if (sde_dbg_base.vbif_dbgbus_dump_idx < list_size) {
		data = &bus->cmn.dumped_content[
			sde_dbg_base.vbif_dbgbus_dump_idx];
		len = snprintf(evtlog_buf, SDE_EVTLOG_BUF_MAX,
				"0x%.8X | %.8X %.8X %.8X %.8X\n",
				sde_dbg_base.vbif_dbgbus_dump_idx,
				data[0], data[1], data[2], data[3]);
		sde_dbg_base.vbif_dbgbus_dump_idx += DUMP_CLMN_COUNT;
		if ((count < len) || copy_to_user(buff, evtlog_buf, len)) {
			len = -EFAULT;
			goto dump_done;
		}
		*ppos += len;
	}
dump_done:
	mutex_unlock(&sde_dbg_base.mutex);

	return len;
}

static const struct file_operations sde_recovery_vbif_dbgbus_fops = {
	.open = sde_recovery_vbif_dbgbus_dump_open,
	.read = sde_recovery_vbif_dbgbus_dump_read,
};

/**
 * sde_dbg_reg_base_release - release allocated reg dump file private data
 * @inode: debugfs inode
@@ -4256,6 +4668,37 @@ static int sde_dbg_reg_base_release(struct inode *inode, struct file *file)
	return 0;
}

/**
 * sde_dbg_reg_base_is_valid_range - verify if requested memory range is valid
 * @off: address offset in bytes
 * @cnt: memory size in bytes
 * Return: true if valid; false otherwise
 */
static bool sde_dbg_reg_base_is_valid_range(u32 off, u32 cnt)
{
	static struct sde_dbg_base *dbg_base = &sde_dbg_base;
	struct sde_dbg_reg_range *node;
	struct sde_dbg_reg_base *base;

	pr_debug("check offset=0x%x cnt=0x%x\n", off, cnt);

	list_for_each_entry(base, &dbg_base->reg_base_list, reg_base_head) {
		list_for_each_entry(node, &base->sub_range_list, head) {
			pr_debug("%s: start=0x%x end=0x%x\n", node->range_name,
					node->offset.start, node->offset.end);

			if (node->offset.start <= off
					&& off <= node->offset.end
					&& off + cnt <= node->offset.end) {
				pr_debug("valid range requested\n");
				return true;
			}
		}
	}

	pr_err("invalid range requested\n");
	return false;
}

/**
 * sde_dbg_reg_base_offset_write - set new offset and len to debugfs reg base
@@ -4302,6 +4745,9 @@ static ssize_t sde_dbg_reg_base_offset_write(struct file *file,
	if (cnt == 0)
		return -EINVAL;

	if (!sde_dbg_reg_base_is_valid_range(off, cnt))
		return -EINVAL;

	mutex_lock(&sde_dbg_base.mutex);
	dbg->off = off;
	dbg->cnt = cnt;
@@ -4556,6 +5002,12 @@ int sde_dbg_debugfs_register(struct dentry *debugfs_root)
			&sde_dbg_base.panic_on_err);
	debugfs_create_u32("reg_dump", 0600, debugfs_root,
			&sde_dbg_base.enable_reg_dump);
	debugfs_create_file("recovery_reg", 0400, debugfs_root, NULL,
			&sde_recovery_reg_fops);
	debugfs_create_file("recovery_dbgbus", 0400, debugfs_root, NULL,
			&sde_recovery_dbgbus_fops);
	debugfs_create_file("recovery_vbif_dbgbus", 0400, debugfs_root, NULL,
			&sde_recovery_vbif_dbgbus_fops);

	if (dbg->dbgbus_sde.entries) {
		dbg->dbgbus_sde.cmn.name = DBGBUS_NAME_SDE;
@@ -4609,6 +5061,8 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
		dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998;
		dbg->dbgbus_vbif_rt.cmn.entries_size =
				ARRAY_SIZE(vbif_dbg_bus_msm8998);
		dbg->dbgbus_dsi.entries = NULL;
		dbg->dbgbus_dsi.size = 0;
	} else if (IS_SDM845_TARGET(hwversion) || IS_SDM670_TARGET(hwversion)) {
		dbg->dbgbus_sde.entries = dbg_bus_sde_sdm845;
		dbg->dbgbus_sde.cmn.entries_size =
@@ -4619,7 +5073,9 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
		dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998;
		dbg->dbgbus_vbif_rt.cmn.entries_size =
				ARRAY_SIZE(vbif_dbg_bus_msm8998);
	} else if (IS_SM8150_TARGET(hwversion)) {
		dbg->dbgbus_dsi.entries = dsi_dbg_bus_sdm845;
		dbg->dbgbus_dsi.size = ARRAY_SIZE(dsi_dbg_bus_sdm845);
	} else if (IS_SM8150_TARGET(hwversion) || IS_SM6150_TARGET(hwversion)) {
		dbg->dbgbus_sde.entries = dbg_bus_sde_sm8150;
		dbg->dbgbus_sde.cmn.entries_size =
				ARRAY_SIZE(dbg_bus_sde_sm8150);
@@ -4628,6 +5084,8 @@ void sde_dbg_init_dbg_buses(u32 hwversion)
		dbg->dbgbus_vbif_rt.entries = vbif_dbg_bus_msm8998;
		dbg->dbgbus_vbif_rt.cmn.entries_size =
				ARRAY_SIZE(vbif_dbg_bus_msm8998);
		dbg->dbgbus_dsi.entries = NULL;
		dbg->dbgbus_dsi.size = 0;
	} else {
		pr_err("unsupported chipset id %X\n", hwversion);
	}
@@ -4655,6 +5113,7 @@ int sde_dbg_init(struct device *dev, struct sde_dbg_power_ctrl *power_ctrl)
	sde_dbg_base.work_panic = false;
	sde_dbg_base.panic_on_err = DEFAULT_PANIC;
	sde_dbg_base.enable_reg_dump = DEFAULT_REGDUMP;
	memset(&sde_dbg_base.regbuf, 0, sizeof(sde_dbg_base.regbuf));

	pr_info("evtlog_status: enable:%d, panic:%d, dump:%d\n",
		sde_dbg_base.evtlog->enable, sde_dbg_base.panic_on_err,
@@ -4688,6 +5147,8 @@ static void sde_dbg_reg_base_destroy(void)
 */
void sde_dbg_destroy(void)
{
	kfree(sde_dbg_base.regbuf.buf);
	memset(&sde_dbg_base.regbuf, 0, sizeof(sde_dbg_base.regbuf));
	_sde_dbg_debugfs_destroy();
	sde_dbg_base_evtlog = NULL;
	sde_evtlog_destroy(sde_dbg_base.evtlog);
+13 −4
Original line number Diff line number Diff line
@@ -201,11 +201,12 @@ bool sde_evtlog_is_enabled(struct sde_dbg_evtlog *evtlog, u32 flag);
 * @evtlog_buf:		target buffer to print into
 * @evtlog_buf_size:	size of target buffer
 * @update_last_entry:	whether or not to stop at most recent entry
 * @full_dump:          whether to dump full or to limit print entries
 * Returns:		number of bytes written to buffer
 */
ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
		char *evtlog_buf, ssize_t evtlog_buf_size,
		bool update_last_entry);
		bool update_last_entry, bool full_dump);

/**
 * sde_dbg_init_dbg_buses - initialize debug bus dumping support for the chipset
@@ -329,16 +330,24 @@ void sde_evtlog_set_filter(struct sde_dbg_evtlog *evtlog, char *filter);
int sde_evtlog_get_filter(struct sde_dbg_evtlog *evtlog, int index,
		char *buf, size_t bufsz);

#ifndef CONFIG_DRM_SDE_RSC
static inline void sde_rsc_debug_dump(u32 mux_sel)
{
}
#else
/**
 * sde_rsc_debug_dump - sde rsc debug dump status
 * @mux_sel:	select mux on rsc debug bus
 * @mux_sel:»       select mux on rsc debug bus
 */
void sde_rsc_debug_dump(u32 mux_sel);
#endif

/**
 * dsi_ctrl_debug_dump - dump dsi debug dump status
 * @entries:	array of debug bus control values
 * @size:	size of the debug bus control array
 */
void dsi_ctrl_debug_dump(void);
void dsi_ctrl_debug_dump(u32 *entries, u32 size);

#else
static inline struct sde_dbg_evtlog *sde_evtlog_init(void)
@@ -430,7 +439,7 @@ static inline void sde_rsc_debug_dump(u32 mux_sel)
{
}

static inline void dsi_ctrl_debug_dump(void)
static inline void dsi_ctrl_debug_dump(u32 entries, u32 size)
{
}

+8 −7
Original line number Diff line number Diff line
@@ -101,8 +101,10 @@ void sde_evtlog_log(struct sde_dbg_evtlog *evtlog, const char *name, int line,

/* always dump the last entries which are not dumped yet */
static bool _sde_evtlog_dump_calc_range(struct sde_dbg_evtlog *evtlog,
		bool update_last_entry)
		bool update_last_entry, bool full_dump)
{
	int max_entries = full_dump ? SDE_EVTLOG_ENTRY : SDE_EVTLOG_PRINT_ENTRY;

	if (!evtlog)
		return false;

@@ -120,12 +122,11 @@ static bool _sde_evtlog_dump_calc_range(struct sde_dbg_evtlog *evtlog,
			evtlog->last_dump += SDE_EVTLOG_ENTRY;
	}

	if ((evtlog->last_dump - evtlog->first) > SDE_EVTLOG_PRINT_ENTRY) {
	if ((evtlog->last_dump - evtlog->first) > max_entries) {
		pr_info("evtlog skipping %d entries, last=%d\n",
			evtlog->last_dump - evtlog->first -
			SDE_EVTLOG_PRINT_ENTRY,
			evtlog->last_dump - 1);
		evtlog->first = evtlog->last_dump - SDE_EVTLOG_PRINT_ENTRY;
			max_entries, evtlog->last_dump - 1);
		evtlog->first = evtlog->last_dump - max_entries;
	}
	evtlog->next = evtlog->first + 1;

@@ -134,7 +135,7 @@ static bool _sde_evtlog_dump_calc_range(struct sde_dbg_evtlog *evtlog,

ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
		char *evtlog_buf, ssize_t evtlog_buf_size,
		bool update_last_entry)
		bool update_last_entry, bool full_dump)
{
	int i;
	ssize_t off = 0;
@@ -147,7 +148,7 @@ ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
	spin_lock_irqsave(&evtlog->spin_lock, flags);

	/* update markers, exit if nothing to print */
	if (!_sde_evtlog_dump_calc_range(evtlog, update_last_entry))
	if (!_sde_evtlog_dump_calc_range(evtlog, update_last_entry, full_dump))
		goto exit;

	log = &evtlog->logs[evtlog->first % SDE_EVTLOG_ENTRY];
+5 −4
Original line number Diff line number Diff line
@@ -172,8 +172,9 @@ static const u8 *_sde_edid_find_block(const u8 *in_buf, u32 start_offset,
	 * * edid buffer 1, byte 2 being 0 means no non-DTD/DATA block
	 *   collection present and no DTD data present.
	 */

	if ((dbc_offset == 0) || (dbc_offset == 4)) {
		SDE_ERROR("EDID: no DTD or non-DTD data present\n");
		SDE_EDID_DEBUG("EDID: no DTD or non-DTD data present\n");
		return NULL;
	}

@@ -376,7 +377,7 @@ struct drm_connector *connector, struct sde_edid_ctrl *edid_ctrl)
	edid_ext = sde_find_cea_extension(edid_ctrl->edid);

	if (!edid_ext) {
		SDE_ERROR("no cea extension\n");
		SDE_DEBUG("no cea extension\n");
		return;
	}

@@ -545,7 +546,7 @@ int _sde_edid_update_modes(struct drm_connector *connector,

	SDE_EDID_DEBUG("%s +", __func__);
	if (edid_ctrl->edid) {
		drm_mode_connector_update_edid_property(connector,
		drm_connector_update_edid_property(connector,
			edid_ctrl->edid);

		rc = drm_add_edid_modes(connector, edid_ctrl->edid);
@@ -555,7 +556,7 @@ int _sde_edid_update_modes(struct drm_connector *connector,
		return rc;
	}

	drm_mode_connector_update_edid_property(connector, NULL);
	drm_connector_update_edid_property(connector, NULL);
	SDE_EDID_DEBUG("%s null edid -", __func__);
	return rc;
}
+7 −4
Original line number Diff line number Diff line
@@ -33,8 +33,9 @@ enum sde_hdcp_state {

enum sde_hdcp_version {
	HDCP_VERSION_NONE,
	HDCP_VERSION_1X,
	HDCP_VERSION_2P2
	HDCP_VERSION_1X = BIT(0),
	HDCP_VERSION_2P2 = BIT(1),
	HDCP_VERSION_MAX = BIT(2),
};

struct sde_hdcp_init_data {
@@ -64,6 +65,8 @@ struct sde_hdcp_ops {
	int (*reauthenticate)(void *input);
	int (*authenticate)(void *hdcp_ctrl);
	bool (*feature_supported)(void *input);
	void (*force_encryption)(void *input, bool enable);
	bool (*sink_support)(void *input);
	void (*off)(void *hdcp_ctrl);
};

@@ -90,8 +93,8 @@ static inline const char *sde_hdcp_version(enum sde_hdcp_version hdcp_version)

void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data);
void sde_hdcp_1x_deinit(void *input);
struct sde_hdcp_ops *sde_hdcp_1x_start(void *input);
struct sde_hdcp_ops *sde_hdcp_1x_get(void *input);
void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data);
void sde_dp_hdcp2p2_deinit(void *input);
struct sde_hdcp_ops *sde_dp_hdcp2p2_start(void *input);
struct sde_hdcp_ops *sde_dp_hdcp2p2_get(void *input);
#endif /* __SDE_HDCP_H__ */
Loading