瀏覽代碼

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

Currently, for every DP hardware register read/write, there
is a string comparison to determine the execution mode. This
adds up an extra delay while powering up/down which does a
large number of register reads and writes. During stress
testing and automation, this can cause an issue resulting
in failures. Remove the unnecessary delays by using common
APIs for register reads and writes. Switch these APIs only
in case of execution mode change.

Change-Id: I9403873a29b3466c606297b2aa386d0885bb2dc7
Signed-off-by: Ajay Singh Parmar <[email protected]>
Ajay Singh Parmar 6 年之前
父節點
當前提交
9eb1b41671
共有 4 個文件被更改,包括 368 次插入448 次删除
  1. 240 248
      msm/dp/dp_catalog.c
  2. 27 35
      msm/dp/dp_catalog.h
  3. 48 79
      msm/dp/dp_catalog_v200.c
  4. 53 86
      msm/dp/dp_catalog_v420.c

文件差異過大導致無法顯示
+ 240 - 248
msm/dp/dp_catalog.c


+ 27 - 35
msm/dp/dp_catalog.h

@@ -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
msm/dp/dp_catalog_v200.c

@@ -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
msm/dp/dp_catalog_v420.c

@@ -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;
 }

部分文件因文件數量過多而無法顯示