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

Commit 2d6d8a97 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm: add drm_connector as input to sde connector ops"

parents 5244cef7 6c3bc302
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;
+556 −341

File changed.

Preview size limit exceeded, changes collapsed.

+7 −2
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ struct dp_catalog_priv {
	void *data;

	void (*put)(struct dp_catalog *catalog);
	void (*set_exe_mode)(struct dp_catalog *dp_catalog, char *mode);
};

struct dp_catalog {
@@ -189,6 +190,10 @@ struct dp_catalog {
	struct dp_catalog_audio audio;
	struct dp_catalog_panel panel;
	struct dp_catalog_priv priv;

	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)
@@ -259,7 +264,7 @@ static inline u8 dp_header_get_parity(u32 data)
struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser);
void dp_catalog_put(struct dp_catalog *catalog);

int dp_catalog_get_v420(struct device *dev, struct dp_catalog *dp_catalog,
			struct dp_parser *parser);
int dp_catalog_get_v420(struct device *dev, struct dp_catalog *catalog,
		void *io);

#endif /* _DP_CATALOG_H_ */
+95 −31
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@
#include "dp_catalog.h"
#include "dp_reg.h"

#define dp_read(offset) readl_relaxed((offset))
#define dp_write(offset, data) writel_relaxed((data), (offset))

#define dp_catalog_get_priv_v420(x) ({ \
	struct dp_catalog *dp_catalog; \
	dp_catalog = container_of(x, struct dp_catalog, x); \
@@ -44,15 +41,62 @@ static u8 const vm_voltage_swing[MAX_VOLTAGE_LEVELS][MAX_PRE_EMP_LEVELS] = {
	{0xFF, 0xFF, 0xFF, 0xFF}  /* sw1, 1.2 v, optional */
};

struct dp_catalog_io {
	struct dp_io_data *dp_ahb;
	struct dp_io_data *dp_aux;
	struct dp_io_data *dp_link;
	struct dp_io_data *dp_p0;
	struct dp_io_data *dp_phy;
	struct dp_io_data *dp_ln_tx0;
	struct dp_io_data *dp_ln_tx1;
	struct dp_io_data *dp_mmss_cc;
	struct dp_io_data *dp_pll;
	struct dp_io_data *usb3_dp_com;
	struct dp_io_data *hdcp_physical;
};

struct dp_catalog_private_v420 {
	struct device *dev;
	struct dp_io *io;
	struct dp_catalog_io *io;

	char exe_mode[SZ_4];
};

static static u32 dp_read(struct dp_catalog_private_v420 *catalog,
		struct dp_io_data *io_data, u32 offset)
{
	u32 data = 0;

	if (!strcmp(catalog->exe_mode, "hw") ||
	    !strcmp(catalog->exe_mode, "all")) {
		data = readl_relaxed(io_data->io.base + offset);
	} else if (!strcmp(catalog->exe_mode, "sw")) {
		if (io_data->buf)
			memcpy(&data, io_data->buf + offset, sizeof(offset));
	}

	return data;
}

static void dp_write(struct dp_catalog_private_v420 *catalog,
		struct dp_io_data *io_data, u32 offset, u32 data)
{
	if (!strcmp(catalog->exe_mode, "hw") ||
	    !strcmp(catalog->exe_mode, "all"))
		writel_relaxed(data, io_data->io.base + offset);

	if (!strcmp(catalog->exe_mode, "sw") ||
	    !strcmp(catalog->exe_mode, "all")) {
		if (io_data->buf)
			memcpy(io_data->buf + offset, &data, sizeof(data));
	}
}

static void dp_catalog_aux_setup_v420(struct dp_catalog_aux *aux,
		struct dp_aux_cfg *cfg)
{
	struct dp_catalog_private_v420 *catalog;
	struct dp_io_data *io_data;
	int i = 0;

	if (!aux || !cfg) {
@@ -62,11 +106,12 @@ static void dp_catalog_aux_setup_v420(struct dp_catalog_aux *aux,

	catalog = dp_catalog_get_priv_v420(aux);

	dp_write(catalog->io->phy_io.base + DP_PHY_PD_CTL, 0x7D);
	io_data = catalog->io->dp_phy;
	dp_write(catalog, io_data, DP_PHY_PD_CTL, 0x7D);
	wmb(); /* make sure PD programming happened */

	/* Turn on BIAS current for PHY/PLL */
	dp_write(catalog->io->dp_pll_io.base +
	dp_write(catalog, io_data,
		QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3d);

	/* DP AUX CFG register programming */
@@ -74,12 +119,11 @@ static void dp_catalog_aux_setup_v420(struct dp_catalog_aux *aux,
		pr_debug("%s: offset=0x%08x, value=0x%08x\n",
			dp_phy_aux_config_type_to_string(i),
			cfg[i].offset, cfg[i].lut[cfg[i].current_index]);
		dp_write(catalog->io->phy_io.base + cfg[i].offset,
		dp_write(catalog, io_data, cfg[i].offset,
			cfg[i].lut[cfg[i].current_index]);
	}

	dp_write(catalog->io->phy_io.base + DP_PHY_AUX_INTERRUPT_MASK_V420,
		0x1F);
	dp_write(catalog, io_data, DP_PHY_AUX_INTERRUPT_MASK_V420, 0x1F);
}

static void dp_catalog_ctrl_config_msa_v420(struct dp_catalog_ctrl *ctrl,
@@ -93,7 +137,7 @@ static void dp_catalog_ctrl_config_msa_v420(struct dp_catalog_ctrl *ctrl,
	u32 const link_rate_hbr2 = 540000;
	u32 const link_rate_hbr3 = 810000;
	struct dp_catalog_private_v420 *catalog;
	void __iomem *base_cc, *base_ctrl;
	struct dp_io_data *io_data;

	if (!ctrl || !rate) {
		pr_err("invalid input\n");
@@ -121,10 +165,10 @@ static void dp_catalog_ctrl_config_msa_v420(struct dp_catalog_ctrl *ctrl,
		 */
		mvid = (u32) mvid_calc;
	} else {
		base_cc = catalog->io->dp_cc_io.base;
		io_data = catalog->io->dp_mmss_cc;

		pixel_m = dp_read(base_cc + MMSS_DP_PIXEL_M_V420);
		pixel_n = dp_read(base_cc + MMSS_DP_PIXEL_N_V420);
		pixel_m = dp_read(catalog, io_data, MMSS_DP_PIXEL_M_V420);
		pixel_n = dp_read(catalog, io_data, MMSS_DP_PIXEL_N_V420);
		pr_debug("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);

		mvid = (pixel_m & 0xFFFF) * 5;
@@ -139,10 +183,10 @@ static void dp_catalog_ctrl_config_msa_v420(struct dp_catalog_ctrl *ctrl,
			nvid *= 3;
	}

	base_ctrl = catalog->io->ctrl_io.base;
	io_data = catalog->io->dp_link;
	pr_debug("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
	dp_write(base_ctrl + DP_SOFTWARE_MVID, mvid);
	dp_write(base_ctrl + DP_SOFTWARE_NVID, nvid);
	dp_write(catalog, io_data, DP_SOFTWARE_MVID, mvid);
	dp_write(catalog, io_data, DP_SOFTWARE_NVID, nvid);
}

static void dp_catalog_ctrl_phy_lane_cfg_v420(struct dp_catalog_ctrl *ctrl,
@@ -151,6 +195,7 @@ static void dp_catalog_ctrl_phy_lane_cfg_v420(struct dp_catalog_ctrl *ctrl,
	u32 info = 0x0;
	struct dp_catalog_private_v420 *catalog;
	u8 orientation = BIT(!!flipped);
	struct dp_io_data *io_data;

	if (!ctrl) {
		pr_err("invalid input\n");
@@ -158,19 +203,20 @@ static void dp_catalog_ctrl_phy_lane_cfg_v420(struct dp_catalog_ctrl *ctrl,
	}

	catalog = dp_catalog_get_priv_v420(ctrl);
	io_data = catalog->io->dp_phy;

	info |= (ln_cnt & 0x0F);
	info |= ((orientation & 0x0F) << 4);
	pr_debug("Shared Info = 0x%x\n", info);

	dp_write(catalog->io->phy_io.base + DP_PHY_SPARE0_V420, info);
	dp_write(catalog, io_data, DP_PHY_SPARE0_V420, info);
}

static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
		u8 v_level, u8 p_level)
{
	struct dp_catalog_private_v420 *catalog;
	void __iomem *base0, *base1;
	struct dp_io_data *io_data;
	u8 value0, value1;

	if (!ctrl || !((v_level < MAX_VOLTAGE_LEVELS)
@@ -180,8 +226,6 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
	}

	catalog = dp_catalog_get_priv_v420(ctrl);
	base0 = catalog->io->ln_tx0_io.base;
	base1 = catalog->io->ln_tx1_io.base;

	pr_debug("hw: v=%d p=%d\n", v_level, p_level);

@@ -189,10 +233,13 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
	value1 = vm_pre_emphasis[v_level][p_level];

	/* program default setting first */
	dp_write(base0 + TXn_TX_DRV_LVL_V420, 0x2A);
	dp_write(base1 + TXn_TX_DRV_LVL_V420, 0x2A);
	dp_write(base0 + TXn_TX_EMP_POST1_LVL, 0x20);
	dp_write(base1 + TXn_TX_EMP_POST1_LVL, 0x20);
	io_data = catalog->io->dp_ln_tx0;
	dp_write(catalog, io_data, TXn_TX_DRV_LVL_V420, 0x2A);
	dp_write(catalog, io_data, TXn_TX_EMP_POST1_LVL, 0x20);

	io_data = catalog->io->dp_ln_tx1;
	dp_write(catalog, io_data, TXn_TX_DRV_LVL_V420, 0x2A);
	dp_write(catalog, io_data, TXn_TX_EMP_POST1_LVL, 0x20);

	/* Enable MUX to use Cursor values from these registers */
	value0 |= BIT(5);
@@ -200,10 +247,13 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,

	/* Configure host and panel only if both values are allowed */
	if (value0 != 0xFF && value1 != 0xFF) {
		dp_write(base0 + TXn_TX_DRV_LVL_V420, value0);
		dp_write(base1 + TXn_TX_DRV_LVL_V420, value0);
		dp_write(base0 + TXn_TX_EMP_POST1_LVL, value1);
		dp_write(base1 + TXn_TX_EMP_POST1_LVL, value1);
		io_data = catalog->io->dp_ln_tx0;
		dp_write(catalog, io_data, TXn_TX_DRV_LVL_V420, value0);
		dp_write(catalog, io_data, TXn_TX_EMP_POST1_LVL, value1);

		io_data = catalog->io->dp_ln_tx1;
		dp_write(catalog, io_data, TXn_TX_DRV_LVL_V420, value0);
		dp_write(catalog, io_data, TXn_TX_EMP_POST1_LVL, value1);

		pr_debug("hw: vx_value=0x%x px_value=0x%x\n",
			value0, value1);
@@ -224,12 +274,24 @@ static void dp_catalog_put_v420(struct dp_catalog *catalog)
	devm_kfree(catalog_priv->dev, catalog_priv);
}

static void dp_catalog_set_exe_mode_v420(struct dp_catalog *catalog, char *mode)
{
	struct dp_catalog_private_v420 *catalog_priv;

	if (!catalog || !catalog->priv.data)
		return;

	catalog_priv = catalog->priv.data;

	strlcpy(catalog_priv->exe_mode, mode, sizeof(catalog_priv->exe_mode));
}

int dp_catalog_get_v420(struct device *dev, struct dp_catalog *catalog,
			struct dp_parser *parser)
		void *io)
{
	struct dp_catalog_private_v420 *catalog_priv;

	if (!dev || !catalog || !parser) {
	if (!dev || !catalog) {
		pr_err("invalid input\n");
		return -EINVAL;
	}
@@ -239,10 +301,12 @@ int dp_catalog_get_v420(struct device *dev, struct dp_catalog *catalog,
		return -ENOMEM;

	catalog_priv->dev = dev;
	catalog_priv->io = &parser->io;
	catalog_priv->io = io;
	catalog->priv.data = catalog_priv;

	catalog->priv.put          = dp_catalog_put_v420;
	catalog->priv.set_exe_mode = dp_catalog_set_exe_mode_v420;

	catalog->aux.setup         = dp_catalog_aux_setup_v420;
	catalog->ctrl.config_msa   = dp_catalog_ctrl_config_msa_v420;
	catalog->ctrl.phy_lane_cfg = dp_catalog_ctrl_phy_lane_cfg_v420;
+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;
Loading