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

Commit 2a9da1c0 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: dp: fix register read/write delays"

parents 28022d54 9eb1b416
Loading
Loading
Loading
Loading
+398 −424

File changed.

Preview size limit exceeded, changes collapsed.

+27 −35
Original line number Diff line number Diff line
@@ -222,11 +222,29 @@ struct dp_catalog_panel {
};

struct dp_catalog;
struct dp_catalog_priv {
	void *data;
struct dp_catalog_sub {
	u32 (*read)(struct dp_catalog *dp_catalog,
		struct dp_io_data *io_data, u32 offset);
	void (*write)(struct dp_catalog *dp_catalog,
		struct dp_io_data *io_data, u32 offset, u32 data);

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

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_io_data *dp_p1;
	struct dp_io_data *dp_tcsr;
};

struct dp_catalog {
@@ -234,9 +252,10 @@ struct dp_catalog {
	struct dp_catalog_ctrl ctrl;
	struct dp_catalog_audio audio;
	struct dp_catalog_panel panel;
	struct dp_catalog_priv priv;
	struct dp_catalog_hpd hpd;

	struct dp_catalog_sub *sub;

	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);
@@ -307,40 +326,13 @@ static inline u8 dp_header_get_parity(u32 data)
	return parity_byte;
}

static inline u32 dp_read(char *exe_mode, struct dp_io_data *io_data,
				u32 offset)
{
	u32 data = 0;

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

	return data;
}

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

	if (!strcmp(exe_mode, "sw") || !strcmp(exe_mode, "all")) {
		if (io_data->buf)
			memcpy(io_data->buf + offset, &data, sizeof(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 *catalog,
		void *io);
struct dp_catalog_sub *dp_catalog_get_v420(struct device *dev,
			struct dp_catalog *catalog, struct dp_catalog_io *io);

int dp_catalog_get_v200(struct device *dev, struct dp_catalog *catalog,
		void *io);
struct dp_catalog_sub *dp_catalog_get_v200(struct device *dev,
			struct dp_catalog *catalog, struct dp_catalog_io *io);

#endif /* _DP_CATALOG_H_ */
+48 −79
Original line number Diff line number Diff line
@@ -10,35 +10,28 @@
#include "dp_debug.h"

#define dp_catalog_get_priv_v200(x) ({ \
	struct dp_catalog *dp_catalog; \
	dp_catalog = container_of(x, struct dp_catalog, x); \
	dp_catalog->priv.data; \
	struct dp_catalog *catalog; \
	catalog = container_of(x, struct dp_catalog, x); \
	container_of(catalog->sub, \
		struct dp_catalog_private_v200, sub); \
})

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_io_data *dp_p1;
	struct dp_io_data *dp_tcsr;
};
#define dp_read(x) ({ \
	catalog->sub.read(catalog->dpc, io_data, x); \
})

#define dp_write(x, y) ({ \
	catalog->sub.write(catalog->dpc, io_data, x, y); \
})

struct dp_catalog_private_v200 {
	struct device *dev;
	struct dp_catalog_io *io;

	char exe_mode[SZ_4];
	struct dp_catalog *dpc;
	struct dp_catalog_sub sub;
};

static void dp_catalog_aux_clear_hw_interrupts_v200(struct dp_catalog_aux *aux)
static void dp_catalog_aux_clear_hw_int_v200(struct dp_catalog_aux *aux)
{
	struct dp_catalog_private_v200 *catalog;
	struct dp_io_data *io_data;
@@ -52,17 +45,15 @@ static void dp_catalog_aux_clear_hw_interrupts_v200(struct dp_catalog_aux *aux)
	catalog = dp_catalog_get_priv_v200(aux);
	io_data = catalog->io->dp_phy;

	data = dp_read(catalog->exe_mode, io_data,
				DP_PHY_AUX_INTERRUPT_STATUS_V200);
	data = dp_read(DP_PHY_AUX_INTERRUPT_STATUS_V200);

	dp_write(catalog->exe_mode, io_data, DP_PHY_AUX_INTERRUPT_CLEAR_V200,
			0x1f);
	dp_write(DP_PHY_AUX_INTERRUPT_CLEAR_V200, 0x1f);
	wmb(); /* make sure 0x1f is written before next write */
	dp_write(catalog->exe_mode, io_data, DP_PHY_AUX_INTERRUPT_CLEAR_V200,
			0x9f);

	dp_write(DP_PHY_AUX_INTERRUPT_CLEAR_V200, 0x9f);
	wmb(); /* make sure 0x9f is written before next write */
	dp_write(catalog->exe_mode, io_data, DP_PHY_AUX_INTERRUPT_CLEAR_V200,
			0);

	dp_write(DP_PHY_AUX_INTERRUPT_CLEAR_V200, 0);
	wmb(); /* make sure register is cleared */
}

@@ -79,40 +70,38 @@ static void dp_catalog_aux_setup_v200(struct dp_catalog_aux *aux,
	}

	catalog = dp_catalog_get_priv_v200(aux);

	io_data = catalog->io->dp_ahb;
	sw_reset = dp_read(catalog->exe_mode, io_data, DP_SW_RESET);

	sw_reset = dp_read(DP_SW_RESET);

	sw_reset |= BIT(0);
	dp_write(catalog->exe_mode, io_data, DP_SW_RESET, sw_reset);
	dp_write(DP_SW_RESET, sw_reset);
	usleep_range(1000, 1010); /* h/w recommended delay */

	sw_reset &= ~BIT(0);
	dp_write(catalog->exe_mode, io_data, DP_SW_RESET, sw_reset);
	dp_write(DP_SW_RESET, sw_reset);

	dp_write(catalog->exe_mode, io_data, DP_PHY_CTRL, 0x4); /* bit 2 */
	dp_write(DP_PHY_CTRL, 0x4); /* bit 2 */
	udelay(1000);
	dp_write(catalog->exe_mode, io_data, DP_PHY_CTRL, 0x0); /* bit 2 */
	dp_write(DP_PHY_CTRL, 0x0); /* bit 2 */
	wmb(); /* make sure programming happened */

	io_data = catalog->io->dp_tcsr;
	dp_write(catalog->exe_mode, io_data, 0x4c, 0x1); /* bit 0 & 2 */
	dp_write(0x4c, 0x1); /* bit 0 & 2 */
	wmb(); /* make sure programming happened */

	io_data = catalog->io->dp_phy;
	dp_write(catalog->exe_mode, io_data, DP_PHY_PD_CTL, 0x3c);
	dp_write(DP_PHY_PD_CTL, 0x3c);
	wmb(); /* make sure PD programming happened */
	dp_write(catalog->exe_mode, io_data, DP_PHY_PD_CTL, 0x3d);
	dp_write(DP_PHY_PD_CTL, 0x3d);
	wmb(); /* make sure PD programming happened */

	/* DP AUX CFG register programming */
	io_data = catalog->io->dp_phy;
	for (i = 0; i < PHY_AUX_CFG_MAX; i++)
		dp_write(catalog->exe_mode, io_data, cfg[i].offset,
				cfg[i].lut[cfg[i].current_index]);
		dp_write(cfg[i].offset, cfg[i].lut[cfg[i].current_index]);

	dp_write(catalog->exe_mode, io_data, DP_PHY_AUX_INTERRUPT_MASK_V200,
			0x1F);
	dp_write(DP_PHY_AUX_INTERRUPT_MASK_V200, 0x1F);
	wmb(); /* make sure AUX configuration is done before enabling it */
}

@@ -146,10 +135,8 @@ static void dp_catalog_panel_config_msa_v200(struct dp_catalog_panel *panel,
		strm_reg_off = MMSS_DP_PIXEL1_M_V200 -
					MMSS_DP_PIXEL_M_V200;

	pixel_m = dp_read(catalog->exe_mode, io_data,
			MMSS_DP_PIXEL_M_V200 + strm_reg_off);
	pixel_n = dp_read(catalog->exe_mode, io_data,
			MMSS_DP_PIXEL_N_V200 + strm_reg_off);
	pixel_m = dp_read(MMSS_DP_PIXEL_M_V200 + strm_reg_off);
	pixel_n = dp_read(MMSS_DP_PIXEL_N_V200 + strm_reg_off);
	DP_DEBUG("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);

	mvid = (pixel_m & 0xFFFF) * 5;
@@ -182,10 +169,8 @@ static void dp_catalog_panel_config_msa_v200(struct dp_catalog_panel *panel,
	}

	DP_DEBUG("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
	dp_write(catalog->exe_mode, io_data, DP_SOFTWARE_MVID + mvid_reg_off,
			mvid);
	dp_write(catalog->exe_mode, io_data, DP_SOFTWARE_NVID + nvid_reg_off,
			nvid);
	dp_write(DP_SOFTWARE_MVID + mvid_reg_off, mvid);
	dp_write(DP_SOFTWARE_NVID + nvid_reg_off, nvid);
}

static void dp_catalog_ctrl_lane_mapping_v200(struct dp_catalog_ctrl *ctrl,
@@ -234,8 +219,7 @@ static void dp_catalog_ctrl_lane_mapping_v200(struct dp_catalog_ctrl *ctrl,
	lane_map_reg = ((l_map[3]&3)<<6)|((l_map[2]&3)<<4)|((l_map[1]&3)<<2)
			|(l_map[0]&3);

	dp_write(catalog->exe_mode, io_data, DP_LOGICAL2PHYSICAL_LANE_MAPPING,
			lane_map_reg);
	dp_write(DP_LOGICAL2PHYSICAL_LANE_MAPPING, lane_map_reg);
}

static void dp_catalog_ctrl_usb_reset_v200(struct dp_catalog_ctrl *ctrl,
@@ -247,48 +231,36 @@ static void dp_catalog_put_v200(struct dp_catalog *catalog)
{
	struct dp_catalog_private_v200 *catalog_priv;

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

	catalog_priv = catalog->priv.data;
	devm_kfree(catalog_priv->dev, catalog_priv);
}
	catalog_priv = container_of(catalog->sub,
			struct dp_catalog_private_v200, sub);

static void dp_catalog_set_exe_mode_v200(struct dp_catalog *catalog, char *mode)
{
	struct dp_catalog_private_v200 *catalog_priv;

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

	catalog_priv = catalog->priv.data;

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

int dp_catalog_get_v200(struct device *dev, struct dp_catalog *catalog,
				void *io)
struct dp_catalog_sub *dp_catalog_get_v200(struct device *dev,
		struct dp_catalog *catalog, struct dp_catalog_io *io)
{
	struct dp_catalog_private_v200 *catalog_priv;

	if (!dev || !catalog) {
		DP_ERR("invalid input\n");
		return -EINVAL;
		return ERR_PTR(-EINVAL);
	}

	catalog_priv = devm_kzalloc(dev, sizeof(*catalog_priv), GFP_KERNEL);
	if (!catalog_priv)
		return -ENOMEM;
		return ERR_PTR(-ENOMEM);

	catalog_priv->dev = dev;
	catalog_priv->io = io;
	catalog->priv.data = catalog_priv;
	catalog_priv->dpc = catalog;

	catalog->priv.put                = dp_catalog_put_v200;
	catalog->priv.set_exe_mode       = dp_catalog_set_exe_mode_v200;
	catalog_priv->sub.put = dp_catalog_put_v200;

	catalog->aux.clear_hw_interrupts =
				dp_catalog_aux_clear_hw_interrupts_v200;
	catalog->aux.clear_hw_interrupts = dp_catalog_aux_clear_hw_int_v200;
	catalog->aux.setup               = dp_catalog_aux_setup_v200;

	catalog->panel.config_msa        = dp_catalog_panel_config_msa_v200;
@@ -296,8 +268,5 @@ int dp_catalog_get_v200(struct device *dev, struct dp_catalog *catalog,
	catalog->ctrl.lane_mapping       = dp_catalog_ctrl_lane_mapping_v200;
	catalog->ctrl.usb_reset          = dp_catalog_ctrl_usb_reset_v200;

	/* Set the default execution mode to hardware mode */
	dp_catalog_set_exe_mode_v200(catalog, "hw");

	return 0;
	return &catalog_priv->sub;
}
+53 −86
Original line number Diff line number Diff line
@@ -9,9 +9,18 @@
#include "dp_debug.h"

#define dp_catalog_get_priv_v420(x) ({ \
	struct dp_catalog *dp_catalog; \
	dp_catalog = container_of(x, struct dp_catalog, x); \
	dp_catalog->priv.data; \
	struct dp_catalog *catalog; \
	catalog = container_of(x, struct dp_catalog, x); \
	container_of(catalog->sub, \
		struct dp_catalog_private_v420, sub); \
})

#define dp_read(x) ({ \
	catalog->sub.read(catalog->dpc, io_data, x); \
})

#define dp_write(x, y) ({ \
	catalog->sub.write(catalog->dpc, io_data, x, y); \
})

#define MAX_VOLTAGE_LEVELS 4
@@ -60,26 +69,11 @@ static u8 const dp_swing_hbr_rbr[MAX_VOLTAGE_LEVELS][MAX_PRE_EMP_LEVELS] = {
	{0x1F, 0xFF, 0xFF, 0xFF}  /* sw1, 1.2v */
};

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_io_data *dp_p1;
};

struct dp_catalog_private_v420 {
	struct device *dev;
	struct dp_catalog_sub sub;
	struct dp_catalog_io *io;

	char exe_mode[SZ_4];
	struct dp_catalog *dpc;
};

static void dp_catalog_aux_setup_v420(struct dp_catalog_aux *aux,
@@ -97,13 +91,12 @@ static void dp_catalog_aux_setup_v420(struct dp_catalog_aux *aux,
	catalog = dp_catalog_get_priv_v420(aux);

	io_data = catalog->io->dp_phy;
	dp_write(catalog->exe_mode, io_data, DP_PHY_PD_CTL, 0x67);
	dp_write(DP_PHY_PD_CTL, 0x67);
	wmb(); /* make sure PD programming happened */

	/* Turn on BIAS current for PHY/PLL */
	io_data = catalog->io->dp_pll;
	dp_write(catalog->exe_mode, io_data, QSERDES_COM_BIAS_EN_CLKBUFLR_EN,
			0x17);
	dp_write(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x17);
	wmb(); /* make sure BIAS programming happened */

	io_data = catalog->io->dp_phy;
@@ -112,16 +105,14 @@ static void dp_catalog_aux_setup_v420(struct dp_catalog_aux *aux,
		DP_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->exe_mode, io_data, cfg[i].offset,
			cfg[i].lut[cfg[i].current_index]);
		dp_write(cfg[i].offset, cfg[i].lut[cfg[i].current_index]);
	}
	wmb(); /* make sure DP AUX CFG programming happened */

	dp_write(catalog->exe_mode, io_data, DP_PHY_AUX_INTERRUPT_MASK_V420,
			0x1F);
	dp_write(DP_PHY_AUX_INTERRUPT_MASK_V420, 0x1F);
}

static void dp_catalog_aux_clear_hw_interrupts_v420(struct dp_catalog_aux *aux)
static void dp_catalog_aux_clear_hw_int_v420(struct dp_catalog_aux *aux)
{
	struct dp_catalog_private_v420 *catalog;
	struct dp_io_data *io_data;
@@ -135,17 +126,15 @@ static void dp_catalog_aux_clear_hw_interrupts_v420(struct dp_catalog_aux *aux)
	catalog = dp_catalog_get_priv_v420(aux);
	io_data = catalog->io->dp_phy;

	data = dp_read(catalog->exe_mode, io_data,
		DP_PHY_AUX_INTERRUPT_STATUS_V420);
	data = dp_read(DP_PHY_AUX_INTERRUPT_STATUS_V420);

	dp_write(catalog->exe_mode, io_data,
		DP_PHY_AUX_INTERRUPT_CLEAR_V420, 0x1f);
	dp_write(DP_PHY_AUX_INTERRUPT_CLEAR_V420, 0x1f);
	wmb(); /* make sure 0x1f is written before next write */
	dp_write(catalog->exe_mode, io_data,
		DP_PHY_AUX_INTERRUPT_CLEAR_V420, 0x9f);

	dp_write(DP_PHY_AUX_INTERRUPT_CLEAR_V420, 0x9f);
	wmb(); /* make sure 0x9f is written before next write */
	dp_write(catalog->exe_mode, io_data,
		DP_PHY_AUX_INTERRUPT_CLEAR_V420, 0);

	dp_write(DP_PHY_AUX_INTERRUPT_CLEAR_V420, 0);
	wmb(); /* make sure register is cleared */
}

@@ -176,10 +165,8 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
	if (panel->stream_id == DP_STREAM_1)
		reg_off = MMSS_DP_PIXEL1_M_V420 - MMSS_DP_PIXEL_M_V420;

	pixel_m = dp_read(catalog->exe_mode, io_data,
			MMSS_DP_PIXEL_M_V420 + reg_off);
	pixel_n = dp_read(catalog->exe_mode, io_data,
			MMSS_DP_PIXEL_N_V420 + reg_off);
	pixel_m = dp_read(MMSS_DP_PIXEL_M_V420 + reg_off);
	pixel_n = dp_read(MMSS_DP_PIXEL_N_V420 + reg_off);
	DP_DEBUG("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);

	mvid = (pixel_m & 0xFFFF) * 5;
@@ -212,8 +199,8 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
	}

	DP_DEBUG("mvid=0x%x, nvid=0x%x\n", mvid, nvid);
	dp_write(catalog->exe_mode, io_data, DP_SOFTWARE_MVID + mvid_off, mvid);
	dp_write(catalog->exe_mode, io_data, DP_SOFTWARE_NVID + nvid_off, nvid);
	dp_write(DP_SOFTWARE_MVID + mvid_off, mvid);
	dp_write(DP_SOFTWARE_NVID + nvid_off, nvid);
}

static void dp_catalog_ctrl_phy_lane_cfg_v420(struct dp_catalog_ctrl *ctrl,
@@ -221,8 +208,8 @@ 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;
	u8 orientation = BIT(!!flipped);

	if (!ctrl) {
		DP_ERR("invalid input\n");
@@ -236,7 +223,7 @@ static void dp_catalog_ctrl_phy_lane_cfg_v420(struct dp_catalog_ctrl *ctrl,
	info |= ((orientation & 0x0F) << 4);
	DP_DEBUG("Shared Info = 0x%x\n", info);

	dp_write(catalog->exe_mode, io_data, DP_PHY_SPARE0_V420, info);
	dp_write(DP_PHY_SPARE0_V420, info);
}

static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
@@ -258,7 +245,7 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
	catalog = dp_catalog_get_priv_v420(ctrl);

	io_data = catalog->io->dp_ahb;
	version = dp_read(catalog->exe_mode, io_data, DP_HW_VERSION);
	version = dp_read(DP_HW_VERSION);

	if (version == 0x10020003) {
		if (high) {
@@ -275,12 +262,12 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,

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

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

	/* Enable MUX to use Cursor values from these registers */
	value0 |= BIT(5);
@@ -289,16 +276,12 @@ 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) {
		io_data = catalog->io->dp_ln_tx0;
		dp_write(catalog->exe_mode, io_data, TXn_TX_DRV_LVL_V420,
				value0);
		dp_write(catalog->exe_mode, io_data, TXn_TX_EMP_POST1_LVL,
				value1);
		dp_write(TXn_TX_DRV_LVL_V420, value0);
		dp_write(TXn_TX_EMP_POST1_LVL, value1);

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

		DP_DEBUG("hw: vx_value=0x%x px_value=0x%x\n",
			value0, value1);
@@ -326,66 +309,50 @@ static void dp_catalog_ctrl_lane_pnswap_v420(struct dp_catalog_ctrl *ctrl,
	cfg1 |= ((ln_pnswap >> 3) & 0x1) << 2;

	io_data = catalog->io->dp_ln_tx0;
	dp_write(catalog->exe_mode, io_data, TXn_TX_POL_INV_V420, cfg0);
	dp_write(TXn_TX_POL_INV_V420, cfg0);

	io_data = catalog->io->dp_ln_tx1;
	dp_write(catalog->exe_mode, io_data, TXn_TX_POL_INV_V420, cfg1);
	dp_write(TXn_TX_POL_INV_V420, cfg1);
}

static void dp_catalog_put_v420(struct dp_catalog *catalog)
{
	struct dp_catalog_private_v420 *catalog_priv;

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

	catalog_priv = catalog->priv.data;
	catalog_priv = container_of(catalog->sub,
			struct dp_catalog_private_v420, sub);
	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,
		void *io)
struct dp_catalog_sub *dp_catalog_get_v420(struct device *dev,
		struct dp_catalog *catalog, struct dp_catalog_io *io)
{
	struct dp_catalog_private_v420 *catalog_priv;

	if (!dev || !catalog) {
		DP_ERR("invalid input\n");
		return -EINVAL;
		return ERR_PTR(-EINVAL);
	}

	catalog_priv = devm_kzalloc(dev, sizeof(*catalog_priv), GFP_KERNEL);
	if (!catalog_priv)
		return -ENOMEM;
		return ERR_PTR(-ENOMEM);

	catalog_priv->dev = dev;
	catalog_priv->io = io;
	catalog->priv.data = catalog_priv;
	catalog_priv->dpc = catalog;

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

	catalog->aux.setup         = dp_catalog_aux_setup_v420;
	catalog->aux.clear_hw_interrupts =
				dp_catalog_aux_clear_hw_interrupts_v420;
	catalog->aux.clear_hw_interrupts = dp_catalog_aux_clear_hw_int_v420;
	catalog->panel.config_msa  = dp_catalog_panel_config_msa_v420;
	catalog->ctrl.phy_lane_cfg = dp_catalog_ctrl_phy_lane_cfg_v420;
	catalog->ctrl.update_vx_px = dp_catalog_ctrl_update_vx_px_v420;
	catalog->ctrl.lane_pnswap = dp_catalog_ctrl_lane_pnswap_v420;

	/* Set the default execution mode to hardware mode */
	dp_catalog_set_exe_mode_v420(catalog, "hw");

	return 0;
	return &catalog_priv->sub;
}