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

Commit b6a5cd80 authored by Samantha Tran's avatar Samantha Tran
Browse files

drm/msm/dp: add support for different execution modes



Add support for switching different execution modes like
hardware mode, software mode or both. In hardware mode,
DP works as normal. In software mode, DP driver works on
IO mapped buffers instead of hardware. This mode can be
used to simulate different variants of hardware.

CRs-Fixed: 2113611
Change-Id: I102b2e37220048d819131bcc4b6d5083499915ee
Signed-off-by: default avatarSamantha Tran <samtran@codeaurora.org>
parent d0edcda0
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -50,6 +50,33 @@ struct dp_aux_private {
	u8 *edid;
};

#ifdef CONFIG_DYNAMIC_DEBUG
static void dp_aux_hex_dump(struct drm_dp_aux *drm_aux,
		struct drm_dp_aux_msg *msg)
{
	DEFINE_DYNAMIC_DEBUG_METADATA(ddm, "dp aux tracker");

	if (unlikely(ddm.flags & _DPRINTK_FLAGS_PRINT)) {
		u8 buf[SZ_64];
		struct dp_aux_private *aux = container_of(drm_aux,
			struct dp_aux_private, drm_aux);

		snprintf(buf, SZ_64, "[drm-dp] %5s %5s %5xh(%2zu): ",
			aux->native ? "NATIVE" : "I2C",
			aux->read ? "READ" : "WRITE",
			msg->address, msg->size);

		print_hex_dump(KERN_DEBUG, buf, DUMP_PREFIX_NONE,
			8, 1, msg->buffer, msg->size, false);
	}
}
#else
static void dp_aux_hex_dump(struct drm_dp_aux *drm_aux,
		struct drm_dp_aux_msg *msg)
{
}
#endif

static char *dp_aux_get_error(u32 aux_error)
{
	switch (aux_error) {
@@ -444,7 +471,6 @@ static int dp_aux_transfer_ready(struct dp_aux_private *aux,
static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
		struct drm_dp_aux_msg *msg)
{
	u8 buf[SZ_64];
	u32 timeout;
	ssize_t ret;
	struct dp_aux_private *aux = container_of(drm_aux,
@@ -482,13 +508,7 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
	}

	if (aux->aux_error_num == DP_AUX_ERR_NONE) {
		snprintf(buf, SZ_64, "[drm-dp] dbg: %5s %5s %5xh(%2zu): ",
			aux->native ? "NATIVE" : "I2C",
			aux->read ? "READ" : "WRITE",
			msg->address, msg->size);

		print_hex_dump(KERN_DEBUG, buf,
			DUMP_PREFIX_NONE, 8, 1, msg->buffer, msg->size, false);
		dp_aux_hex_dump(drm_aux, msg);

		msg->reply = aux->native ?
			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
@@ -511,7 +531,6 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,
		struct drm_dp_aux_msg *msg)
{
	u8 buf[SZ_64];
	ssize_t ret;
	int const retry_count = 5;
	struct dp_aux_private *aux = container_of(drm_aux,
@@ -544,13 +563,7 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *drm_aux,
		if (aux->read)
			dp_aux_cmd_fifo_rx(aux, msg);

		snprintf(buf, SZ_64, "[drm-dp] %5s %5s %5xh(%2zu): ",
			aux->native ? "NATIVE" : "I2C",
			aux->read ? "READ" : "WRITE",
			msg->address, msg->size);

		print_hex_dump(KERN_DEBUG, buf,
			DUMP_PREFIX_NONE, 8, 1, msg->buffer, msg->size, false);
		dp_aux_hex_dump(drm_aux, msg);

		msg->reply = aux->native ?
			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+548 −342

File changed.

Preview size limit exceeded, changes collapsed.

+6 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2018, 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
@@ -181,6 +181,10 @@ struct dp_catalog {
	struct dp_catalog_ctrl ctrl;
	struct dp_catalog_audio audio;
	struct dp_catalog_panel panel;

	void (*set_exe_mode)(struct dp_catalog *dp_catalog, char *mode);
	int (*get_reg_dump)(struct dp_catalog *dp_catalog,
		char *mode, u8 **out_buf, u32 *out_buf_len);
};

static inline u8 dp_ecc_get_g0_value(u8 data)
@@ -248,7 +252,7 @@ static inline u8 dp_header_get_parity(u32 data)
	return parity_byte;
}

struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io);
struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser);
void dp_catalog_put(struct dp_catalog *catalog);

#endif /* _DP_CATALOG_H_ */
+131 −4
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

#include <linux/debugfs.h>

#include "dp_parser.h"
#include "dp_power.h"
#include "dp_catalog.h"
#include "dp_aux.h"
@@ -38,10 +37,14 @@ struct dp_debug_private {

	int vdo;

	char exe_mode[SZ_32];
	char reg_dump[SZ_32];

	struct dp_usbpd *usbpd;
	struct dp_link *link;
	struct dp_panel *panel;
	struct dp_aux *aux;
	struct dp_catalog *catalog;
	struct drm_connector **connector;
	struct device *dev;
	struct work_struct sim_work;
@@ -398,6 +401,36 @@ static ssize_t dp_debug_tpg_write(struct file *file,
	return len;
}

static ssize_t dp_debug_write_exe_mode(struct file *file,
		const char __user *user_buff, size_t count, loff_t *ppos)
{
	struct dp_debug_private *debug = file->private_data;
	char *buf;
	size_t len = 0;

	if (!debug)
		return -ENODEV;

	if (*ppos)
		return 0;

	len = min_t(size_t, count, SZ_32 - 1);
	buf = memdup_user(user_buff, len);
	buf[len] = '\0';

	if (sscanf(buf, "%3s", debug->exe_mode) != 1)
		goto end;

	if (strcmp(debug->exe_mode, "hw") &&
	    strcmp(debug->exe_mode, "sw") &&
	    strcmp(debug->exe_mode, "all"))
		goto end;

	debug->catalog->set_exe_mode(debug->catalog, debug->exe_mode);
end:
	return len;
}

static ssize_t dp_debug_read_connected(struct file *file,
		char __user *user_buff, size_t count, loff_t *ppos)
{
@@ -910,6 +943,71 @@ static ssize_t dp_debug_write_attention(struct file *file,
	return len;
}

static ssize_t dp_debug_write_dump(struct file *file,
		const char __user *user_buff, size_t count, loff_t *ppos)
{
	struct dp_debug_private *debug = file->private_data;
	char buf[SZ_32];
	size_t len = 0;

	if (!debug)
		return -ENODEV;

	if (*ppos)
		return 0;

	/* Leave room for termination char */
	len = min_t(size_t, count, SZ_32 - 1);
	if (copy_from_user(buf, user_buff, len))
		goto end;

	buf[len] = '\0';

	if (sscanf(buf, "%31s", debug->reg_dump) != 1)
		goto end;

	/* qfprom register dump not supported */
	if (!strcmp(debug->reg_dump, "qfprom_physical"))
		strlcpy(debug->reg_dump, "clear", sizeof(debug->reg_dump));
end:
	return len;
}

static ssize_t dp_debug_read_dump(struct file *file,
		char __user *user_buff, size_t count, loff_t *ppos)
{
	int rc = 0;
	struct dp_debug_private *debug = file->private_data;
	u8 *buf = NULL;
	u32 len = 0;
	char prefix[SZ_32];

	if (!debug)
		return -ENODEV;

	if (*ppos)
		return 0;

	if (!debug->usbpd->hpd_high || !strlen(debug->reg_dump))
		goto end;

	rc = debug->catalog->get_reg_dump(debug->catalog,
		debug->reg_dump, &buf, &len);
	if (rc)
		goto end;

	snprintf(prefix, sizeof(prefix), "%s: ", debug->reg_dump);
	print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_NONE,
		16, 4, buf, len, false);

	if (copy_to_user(user_buff, buf, len))
		return -EFAULT;

	*ppos += len;
end:
	return len;
}

static const struct file_operations dp_debug_fops = {
	.open = simple_open,
	.read = dp_debug_read_info,
@@ -947,6 +1045,10 @@ static const struct file_operations bw_code_fops = {
	.read = dp_debug_bw_code_read,
	.write = dp_debug_bw_code_write,
};
static const struct file_operations exe_mode_fops = {
	.open = simple_open,
	.write = dp_debug_write_exe_mode,
};

static const struct file_operations tpg_fops = {
	.open = simple_open,
@@ -970,6 +1072,12 @@ static const struct file_operations attention_fops = {
	.write = dp_debug_write_attention,
};

static const struct file_operations dump_fops = {
	.open = simple_open,
	.write = dp_debug_write_dump,
	.read = dp_debug_read_dump,
};

static int dp_debug_init(struct dp_debug *dp_debug)
{
	int rc = 0;
@@ -1032,7 +1140,14 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs max_bw_code failed, rc=%d\n",
		       DEBUG_NAME, rc);
		goto error_remove_dir;
	}

	file = debugfs_create_file("exe_mode", 0644, dir,
			debug, &exe_mode_fops);
	if (IS_ERR_OR_NULL(file)) {
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs register failed, rc=%d\n",
		       DEBUG_NAME, rc);
	}

	file = debugfs_create_file("edid", 0644, dir,
@@ -1092,6 +1207,16 @@ static int dp_debug_init(struct dp_debug *dp_debug)
		goto error_remove_dir;
	}

	file = debugfs_create_file("dump", 0644, dir,
		debug, &dump_fops);

	if (IS_ERR_OR_NULL(file)) {
		rc = PTR_ERR(file);
		pr_err("[%s] debugfs dump failed, rc=%d\n",
			DEBUG_NAME, rc);
		goto error_remove_dir;
	}

	return 0;

error_remove_dir:
@@ -1112,13 +1237,14 @@ static void dp_debug_sim_work(struct work_struct *work)

struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
			struct dp_usbpd *usbpd, struct dp_link *link,
			struct dp_aux *aux, struct drm_connector **connector)
			struct dp_aux *aux, struct drm_connector **connector,
			struct dp_catalog *catalog)
{
	int rc = 0;
	struct dp_debug_private *debug;
	struct dp_debug *dp_debug;

	if (!dev || !panel || !usbpd || !link) {
	if (!dev || !panel || !usbpd || !link || !catalog) {
		pr_err("invalid input\n");
		rc = -EINVAL;
		goto error;
@@ -1139,6 +1265,7 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
	debug->aux = aux;
	debug->dev = dev;
	debug->connector = connector;
	debug->catalog = catalog;

	dp_debug = &debug->dp_debug;
	dp_debug->vdisplay = 0;
+3 −1
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ struct dp_debug {
 * @usbpd: instance of usbpd module
 * @link: instance of link module
 * @connector: double pointer to display connector
 * @catalog: instance of catalog module
 * return: pointer to allocated debug module data
 *
 * This function sets up the debug module and provides a way
@@ -54,7 +55,8 @@ struct dp_debug {
 */
struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
			struct dp_usbpd *usbpd, struct dp_link *link,
			struct dp_aux *aux, struct drm_connector **connector);
			struct dp_aux *aux, struct drm_connector **connector,
			struct dp_catalog *catalog);
/**
 * dp_debug_put()
 *
Loading