diff --git a/drivers/gpu/drm/bridge/tc358775.c b/drivers/gpu/drm/bridge/tc358775.c
index 7ae86e8d4c72..b7f15164e655 100644
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -16,6 +16,7 @@
 #include <linux/media-bus-format.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
@@ -238,7 +239,7 @@ enum tc3587x5_type {
 };
 
 struct tc_data {
-	struct i2c_client	*i2c;
+	struct regmap		*regmap;
 	struct device		*dev;
 
 	struct drm_bridge	bridge;
@@ -309,42 +310,6 @@ static void tc_bridge_post_disable(struct drm_bridge *bridge)
 	usleep_range(10000, 11000);
 }
 
-static void d2l_read(struct i2c_client *i2c, u16 addr, u32 *val)
-{
-	int ret;
-	u8 buf_addr[2];
-
-	put_unaligned_be16(addr, buf_addr);
-	ret = i2c_master_send(i2c, buf_addr, sizeof(buf_addr));
-	if (ret < 0)
-		goto fail;
-
-	ret = i2c_master_recv(i2c, (u8 *)val, sizeof(*val));
-	if (ret < 0)
-		goto fail;
-
-	pr_debug("d2l: I2C : addr:%04x value:%08x\n", addr, *val);
-	return;
-
-fail:
-	dev_err(&i2c->dev, "Error %d reading from subaddress 0x%x\n",
-		ret, addr);
-}
-
-static void d2l_write(struct i2c_client *i2c, u16 addr, u32 val)
-{
-	u8 data[6];
-	int ret;
-
-	put_unaligned_be16(addr, data);
-	put_unaligned_le32(val, data + 2);
-
-	ret = i2c_master_send(i2c, data, ARRAY_SIZE(data));
-	if (ret < 0)
-		dev_err(&i2c->dev, "Error %d writing to subaddress 0x%x\n",
-			ret, addr);
-}
-
 /* helper function to access bus_formats */
 static struct drm_connector *get_connector(struct drm_encoder *encoder)
 {
@@ -358,12 +323,33 @@ static struct drm_connector *get_connector(struct drm_encoder *encoder)
 	return NULL;
 }
 
+static const struct reg_sequence tc_lvmux_vesa24[] = {
+	{ LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3) },
+	{ LV_MX0407, LV_MX(LVI_R4, LVI_R7, LVI_R5, LVI_G0) },
+	{ LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_G6, LVI_G7) },
+	{ LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0) },
+	{ LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2) },
+	{ LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0) },
+	{ LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6) },
+};
+
+/* JEIDA-24/JEIDA-18 have the same mapping */
+static const struct reg_sequence tc_lvmux_jeida18_24[] = {
+	{ LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, LVI_R5) },
+	{ LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, LVI_G2) },
+	{ LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, LVI_G1) },
+	{ LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, LVI_B2) },
+	{ LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, LVI_B4) },
+	{ LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, LVI_L0) },
+	{ LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R0) },
+};
+
 static void tc_bridge_enable(struct drm_bridge *bridge)
 {
 	struct tc_data *tc = bridge_to_tc(bridge);
 	u32 hback_porch, hsync_len, hfront_porch, hactive, htime1, htime2;
 	u32 vback_porch, vsync_len, vfront_porch, vactive, vtime1, vtime2;
-	u32 val = 0;
+	unsigned int val = 0;
 	u16 dsiclk, clkdiv, byteclk, t1, t2, t3, vsdelay;
 	struct drm_display_mode *mode;
 	struct drm_connector *connector = get_connector(bridge->encoder);
@@ -386,28 +372,29 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
 	htime2 = (hfront_porch << 16) + hactive;
 	vtime2 = (vfront_porch << 16) + vactive;
 
-	d2l_read(tc->i2c, IDREG, &val);
+	regmap_read(tc->regmap, IDREG, &val);
 
 	dev_info(tc->dev, "DSI2LVDS Chip ID.%02x Revision ID. %02x **\n",
 		 (val >> 8) & 0xFF, val & 0xFF);
 
-	d2l_write(tc->i2c, SYSRST, SYS_RST_REG | SYS_RST_DSIRX | SYS_RST_BM |
-		  SYS_RST_LCD | SYS_RST_I2CM);
+	regmap_write(tc->regmap, SYSRST,
+		     SYS_RST_REG | SYS_RST_DSIRX | SYS_RST_BM | SYS_RST_LCD |
+		     SYS_RST_I2CM);
 	usleep_range(30000, 40000);
 
-	d2l_write(tc->i2c, PPI_TX_RX_TA, TTA_GET | TTA_SURE);
-	d2l_write(tc->i2c, PPI_LPTXTIMECNT, LPX_PERIOD);
-	d2l_write(tc->i2c, PPI_D0S_CLRSIPOCOUNT, 3);
-	d2l_write(tc->i2c, PPI_D1S_CLRSIPOCOUNT, 3);
-	d2l_write(tc->i2c, PPI_D2S_CLRSIPOCOUNT, 3);
-	d2l_write(tc->i2c, PPI_D3S_CLRSIPOCOUNT, 3);
+	regmap_write(tc->regmap, PPI_TX_RX_TA, TTA_GET | TTA_SURE);
+	regmap_write(tc->regmap, PPI_LPTXTIMECNT, LPX_PERIOD);
+	regmap_write(tc->regmap, PPI_D0S_CLRSIPOCOUNT, 3);
+	regmap_write(tc->regmap, PPI_D1S_CLRSIPOCOUNT, 3);
+	regmap_write(tc->regmap, PPI_D2S_CLRSIPOCOUNT, 3);
+	regmap_write(tc->regmap, PPI_D3S_CLRSIPOCOUNT, 3);
 
 	val = ((L0EN << tc->num_dsi_lanes) - L0EN) | DSI_CLEN_BIT;
-	d2l_write(tc->i2c, PPI_LANEENABLE, val);
-	d2l_write(tc->i2c, DSI_LANEENABLE, val);
+	regmap_write(tc->regmap, PPI_LANEENABLE, val);
+	regmap_write(tc->regmap, DSI_LANEENABLE, val);
 
-	d2l_write(tc->i2c, PPI_STARTPPI, PPI_START_FUNCTION);
-	d2l_write(tc->i2c, DSI_STARTDSI, DSI_RX_START);
+	regmap_write(tc->regmap, PPI_STARTPPI, PPI_START_FUNCTION);
+	regmap_write(tc->regmap, DSI_STARTDSI, DSI_RX_START);
 
 	/* Video event mode vs pulse mode bit, does not exist for tc358775 */
 	if (tc->type == TC358765)
@@ -431,42 +418,28 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
 	vsdelay = (clkdiv * (t1 + t3) / byteclk) - hback_porch - hsync_len - hactive;
 
 	val |= TC358775_VPCTRL_VSDELAY(vsdelay);
-	d2l_write(tc->i2c, VPCTRL, val);
+	regmap_write(tc->regmap, VPCTRL, val);
 
-	d2l_write(tc->i2c, HTIM1, htime1);
-	d2l_write(tc->i2c, VTIM1, vtime1);
-	d2l_write(tc->i2c, HTIM2, htime2);
-	d2l_write(tc->i2c, VTIM2, vtime2);
+	regmap_write(tc->regmap, HTIM1, htime1);
+	regmap_write(tc->regmap, VTIM1, vtime1);
+	regmap_write(tc->regmap, HTIM2, htime2);
+	regmap_write(tc->regmap, VTIM2, vtime2);
 
-	d2l_write(tc->i2c, VFUEN, VFUEN_EN);
-	d2l_write(tc->i2c, SYSRST, SYS_RST_LCD);
-	d2l_write(tc->i2c, LVPHY0, LV_PHY0_PRBS_ON(4) | LV_PHY0_ND(6));
+	regmap_write(tc->regmap, VFUEN, VFUEN_EN);
+	regmap_write(tc->regmap, SYSRST, SYS_RST_LCD);
+	regmap_write(tc->regmap, LVPHY0, LV_PHY0_PRBS_ON(4) | LV_PHY0_ND(6));
 
 	dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
 		connector->display_info.bus_formats[0],
 		tc->bpc);
-	if (connector->display_info.bus_formats[0] ==
-		MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
-		/* VESA-24 */
-		d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3));
-		d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_R7, LVI_R5, LVI_G0));
-		d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_G6, LVI_G7));
-		d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0));
-		d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2));
-		d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
-		d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6));
-	} else {
-		/* JEIDA-18 and JEIDA-24 */
-		d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, LVI_R5));
-		d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, LVI_G2));
-		d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, LVI_G1));
-		d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, LVI_B2));
-		d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, LVI_B4));
-		d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, LVI_L0));
-		d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R0));
-	}
+	if (connector->display_info.bus_formats[0] == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG)
+		regmap_multi_reg_write(tc->regmap, tc_lvmux_vesa24,
+				       ARRAY_SIZE(tc_lvmux_vesa24));
+	else
+		regmap_multi_reg_write(tc->regmap, tc_lvmux_jeida18_24,
+				       ARRAY_SIZE(tc_lvmux_jeida18_24));
 
-	d2l_write(tc->i2c, VFUEN, VFUEN_EN);
+	regmap_write(tc->regmap, VFUEN, VFUEN_EN);
 
 	val = LVCFG_LVEN_BIT;
 	if (tc->lvds_link == DUAL_LINK) {
@@ -475,7 +448,7 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
 	} else {
 		val |= TC358775_LVCFG_PCLKDIV(DIVIDE_BY_3);
 	}
-	d2l_write(tc->i2c, LVCFG, val);
+	regmap_write(tc->regmap, LVCFG, val);
 }
 
 /*
@@ -617,7 +590,7 @@ static const struct drm_bridge_funcs tc_bridge_funcs = {
 
 static int tc_attach_host(struct tc_data *tc)
 {
-	struct device *dev = &tc->i2c->dev;
+	struct device *dev = tc->dev;
 	struct mipi_dsi_host *host;
 	struct mipi_dsi_device *dsi;
 	int ret;
@@ -665,6 +638,14 @@ static int tc_attach_host(struct tc_data *tc)
 	return 0;
 }
 
+static const struct regmap_config tc358775_regmap_config = {
+	.reg_bits = 16,
+	.val_bits = 32,
+	.max_register = 0xffff,
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
 static int tc_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
@@ -679,6 +660,11 @@ static int tc_probe(struct i2c_client *client)
 	tc->i2c = client;
 	tc->type = (enum tc3587x5_type)(unsigned long)of_device_get_match_data(dev);
 
+	tc->regmap = devm_regmap_init_i2c(client, &tc358775_regmap_config);
+	if (IS_ERR(tc->regmap))
+		return dev_err_probe(dev, PTR_ERR(tc->regmap),
+				     "regmap i2c init failed\n");
+
 	tc->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node,
 						  TC358775_LVDS_OUT0, 0);
 	if (IS_ERR(tc->panel_bridge))
