From c59fbf2bb80ed1e9cfca837cf9f35a08d6b4129c Mon Sep 17 00:00:00 2001
From: Hung-Te Lin <hungte@chromium.org>
Date: Wed, 7 Aug 2019 08:00:58 +0800
Subject: soc/mediatek: Create common DSI driver from mt8173

The DSI initialization is almost the same for 8173 and 8183, so we want
to move most of common functions into common/dsi.c.

The major board-specific functions left are:
 - reset (controller register has different format)
 - pin_drv_ctrl (8183 does not need this)

BUG=b:80501386,b:117254947
TEST=make -j # board=oak (mt8173)

Change-Id: I8d4369a3c84db551287a9c9d1b22f552c5f7518d
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/34769
Reviewed-by: Julius Werner <jwerner@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
---
 src/soc/mediatek/common/dsi.c                    | 192 ++++++++++++++
 src/soc/mediatek/common/include/soc/dsi_common.h | 312 +++++++++++++++++++++++
 src/soc/mediatek/mt8173/Makefile.inc             |   2 +-
 src/soc/mediatek/mt8173/dsi.c                    | 177 +------------
 src/soc/mediatek/mt8173/include/soc/dsi.h        | 287 +--------------------
 5 files changed, 511 insertions(+), 459 deletions(-)
 create mode 100644 src/soc/mediatek/common/dsi.c
 create mode 100644 src/soc/mediatek/common/include/soc/dsi_common.h

(limited to 'src/soc/mediatek')

diff --git a/src/soc/mediatek/common/dsi.c b/src/soc/mediatek/common/dsi.c
new file mode 100644
index 0000000000..3d003ec94f
--- /dev/null
+++ b/src/soc/mediatek/common/dsi.c
@@ -0,0 +1,192 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/mmio.h>
+#include <console/console.h>
+#include <device/mmio.h>
+#include <delay.h>
+#include <edid.h>
+#include <soc/dsi.h>
+#include <timer.h>
+
+static void mtk_dsi_phy_timconfig(u32 data_rate)
+{
+	u32 timcon0, timcon1, timcon2, timcon3;
+	u32 cycle_time, ui, lpx;
+
+	ui = 1000 / data_rate + 0x01;
+	cycle_time = 8000 / data_rate + 0x01;
+	lpx = 5;
+
+	timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
+	timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
+		  (4 * lpx);
+	timcon2 = ((DIV_ROUND_UP(0x64, cycle_time) + 0xa) << 24) |
+		  (DIV_ROUND_UP(0x150, cycle_time) << 16);
+	timcon3 = (2 * lpx) << 16 |
+		  DIV_ROUND_UP(80 + 52 * ui, cycle_time) << 8 |
+		  DIV_ROUND_UP(0x40, cycle_time);
+
+	write32(&dsi0->dsi_phy_timecon0, timcon0);
+	write32(&dsi0->dsi_phy_timecon1, timcon1);
+	write32(&dsi0->dsi_phy_timecon2, timcon2);
+	write32(&dsi0->dsi_phy_timecon3, timcon3);
+}
+
+static void mtk_dsi_clk_hs_mode_enable(void)
+{
+	setbits_le32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
+}
+
+static void mtk_dsi_clk_hs_mode_disable(void)
+{
+	clrbits_le32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
+}
+
+static void mtk_dsi_set_mode(u32 mode_flags)
+{
+	u32 tmp_reg1 = 0;
+
+	if (mode_flags & MIPI_DSI_MODE_VIDEO) {
+		tmp_reg1 = SYNC_PULSE_MODE;
+
+		if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+			tmp_reg1 = BURST_MODE;
+
+		if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+			tmp_reg1 = SYNC_PULSE_MODE;
+	}
+
+	write32(&dsi0->dsi_mode_ctrl, tmp_reg1);
+}
+
+static void mtk_dsi_rxtx_control(u32 mode_flags, u32 lanes)
+{
+	u32 tmp_reg = 0;
+
+	switch (lanes) {
+	case 1:
+		tmp_reg = 1 << 2;
+		break;
+	case 2:
+		tmp_reg = 3 << 2;
+		break;
+	case 3:
+		tmp_reg = 7 << 2;
+		break;
+	case 4:
+	default:
+		tmp_reg = 0xf << 2;
+		break;
+	}
+
+	tmp_reg |= (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) << 6;
+	tmp_reg |= (mode_flags & MIPI_DSI_MODE_EOT_PACKET) >> 3;
+
+	write32(&dsi0->dsi_txrx_ctrl, tmp_reg);
+}
+
+static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format,
+				      const struct edid *edid)
+{
+	u32 hsync_active_byte;
+	u32 hbp_byte;
+	u32 hfp_byte;
+	u32 vbp_byte;
+	u32 vfp_byte;
+	u32 bpp;
+	u32 packet_fmt;
+	u32 hactive;
+
+	if (format == MIPI_DSI_FMT_RGB565)
+		bpp = 2;
+	else
+		bpp = 3;
+
+	vbp_byte = edid->mode.vbl - edid->mode.vso - edid->mode.vspw -
+		   edid->mode.vborder;
+	vfp_byte = edid->mode.vso - edid->mode.vborder;
+
+	write32(&dsi0->dsi_vsa_nl, edid->mode.vspw);
+	write32(&dsi0->dsi_vbp_nl, vbp_byte);
+	write32(&dsi0->dsi_vfp_nl, vfp_byte);
+	write32(&dsi0->dsi_vact_nl, edid->mode.va);
+
+	if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+		hbp_byte = (edid->mode.hbl - edid->mode.hso - edid->mode.hspw -
+			    edid->mode.hborder) * bpp - 10;
+	else
+		hbp_byte = (edid->mode.hbl - edid->mode.hso -
+			    edid->mode.hborder) * bpp - 10;
+
+	hsync_active_byte = edid->mode.hspw * bpp - 10;
+	hfp_byte = (edid->mode.hso - edid->mode.hborder) * bpp - 12;
+
+	write32(&dsi0->dsi_hsa_wc, hsync_active_byte);
+	write32(&dsi0->dsi_hbp_wc, hbp_byte);
+	write32(&dsi0->dsi_hfp_wc, hfp_byte);
+
+	switch (format) {
+	case MIPI_DSI_FMT_RGB888:
+		packet_fmt = PACKED_PS_24BIT_RGB888;
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		packet_fmt = LOOSELY_PS_18BIT_RGB666;
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+		packet_fmt = PACKED_PS_18BIT_RGB666;
+		break;
+	case MIPI_DSI_FMT_RGB565:
+		packet_fmt = PACKED_PS_16BIT_RGB565;
+		break;
+	default:
+		packet_fmt = PACKED_PS_24BIT_RGB888;
+		break;
+	}
+
+	hactive = edid->mode.ha;
+	packet_fmt |= (hactive * bpp) & DSI_PS_WC;
+
+	write32(&dsi0->dsi_psctrl, packet_fmt);
+}
+
+static void mtk_dsi_start(void)
+{
+	write32(&dsi0->dsi_start, 0);
+	/* Only start master DSI */
+	write32(&dsi0->dsi_start, 1);
+}
+
+int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid)
+{
+	int data_rate;
+
+	data_rate = mtk_dsi_phy_clk_setting(format, lanes, edid);
+
+	if (data_rate < 0)
+		return -1;
+
+	mtk_dsi_reset();
+	mtk_dsi_phy_timconfig(data_rate);
+	mtk_dsi_rxtx_control(mode_flags, lanes);
+	mtk_dsi_clk_hs_mode_disable();
+	mtk_dsi_config_vdo_timing(mode_flags, format, edid);
+	mtk_dsi_set_mode(mode_flags);
+	mtk_dsi_clk_hs_mode_enable();
+
+	mtk_dsi_start();
+
+	return 0;
+}
diff --git a/src/soc/mediatek/common/include/soc/dsi_common.h b/src/soc/mediatek/common/include/soc/dsi_common.h
new file mode 100644
index 0000000000..cebf9af701
--- /dev/null
+++ b/src/soc/mediatek/common/include/soc/dsi_common.h
@@ -0,0 +1,312 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2015 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef SOC_MEDIATEK_DSI_COMMON_H
+#define SOC_MEDIATEK_DSI_COMMON_H
+
+#include <edid.h>
+#include <types.h>
+#include <soc/addressmap.h>
+
+enum mipi_dsi_pixel_format {
+	MIPI_DSI_FMT_RGB888,
+	MIPI_DSI_FMT_RGB666,
+	MIPI_DSI_FMT_RGB666_PACKED,
+	MIPI_DSI_FMT_RGB565
+};
+
+/* video mode */
+enum {
+	MIPI_DSI_MODE_VIDEO = BIT(0),
+	/* video burst mode */
+	MIPI_DSI_MODE_VIDEO_BURST = BIT(1),
+	/* video pulse mode */
+	MIPI_DSI_MODE_VIDEO_SYNC_PULSE = BIT(2),
+	/* enable auto vertical count mode */
+	MIPI_DSI_MODE_VIDEO_AUTO_VERT = BIT(3),
+	/* enable hsync-end packets in vsync-pulse and v-porch area */
+	MIPI_DSI_MODE_VIDEO_HSE = BIT(4),
+	/* disable hfront-porch area */
+	MIPI_DSI_MODE_VIDEO_HFP = BIT(5),
+	/* disable hback-porch area */
+	MIPI_DSI_MODE_VIDEO_HBP = BIT(6),
+	/* disable hsync-active area */
+	MIPI_DSI_MODE_VIDEO_HSA = BIT(7),
+	/* flush display FIFO on vsync pulse */
+	MIPI_DSI_MODE_VSYNC_FLUSH = BIT(8),
+	/* disable EoT packets in HS mode */
+	MIPI_DSI_MODE_EOT_PACKET = BIT(9),
+	/* device supports non-continuous clock behavior (DSI spec 5.6.1) */
+	MIPI_DSI_CLOCK_NON_CONTINUOUS = BIT(10),
+	/* transmit data in low power */
+	MIPI_DSI_MODE_LPM = BIT(11)
+};
+
+struct dsi_regs {
+	u32 dsi_start;
+	u8 reserved0[4];
+	u32 dsi_inten;
+	u32 dsi_intsta;
+	u32 dsi_con_ctrl;
+	u32 dsi_mode_ctrl;
+	u32 dsi_txrx_ctrl;
+	u32 dsi_psctrl;
+	u32 dsi_vsa_nl;
+	u32 dsi_vbp_nl;
+	u32 dsi_vfp_nl;
+	u32 dsi_vact_nl;
+	u8 reserved1[32];
+	u32 dsi_hsa_wc;
+	u32 dsi_hbp_wc;
+	u32 dsi_hfp_wc;
+	u32 dsi_bllp_wc;
+	u32 dsi_cmdq_size;
+	u32 dsi_hstx_cklp_wc;
+	u8 reserved2[156];
+	u32 dsi_phy_lccon;
+	u32 dsi_phy_ld0con;
+	u8 reserved3[4];
+	u32 dsi_phy_timecon0;
+	u32 dsi_phy_timecon1;
+	u32 dsi_phy_timecon2;
+	u32 dsi_phy_timecon3;
+	u8 reserved4[16];
+	u32 dsi_vm_cmd_con;
+	u8 reserved5[204];
+	u32 dsi_cmdq0;
+};
+static struct dsi_regs *const dsi0 = (void *)DSI0_BASE;
+
+check_member(dsi_regs, dsi_phy_lccon, 0x104);
+check_member(dsi_regs, dsi_phy_timecon3, 0x11c);
+check_member(dsi_regs, dsi_vm_cmd_con, 0x130);
+check_member(dsi_regs, dsi_cmdq0, 0x200);
+
+/* DSI_INTSTA */
+enum {
+	LPRX_RD_RDY_INT_FLAG = BIT(0),
+	CMD_DONE_INT_FLAG    = BIT(1),
+	TE_RDY_INT_FLAG      = BIT(2),
+	VM_DONE_INT_FLAG     = BIT(3),
+	EXT_TE_RDY_INT_FLAG  = BIT(4),
+	DSI_BUSY             = BIT(31),
+};
+
+/* DSI_CON_CTRL */
+enum {
+	DSI_RESET = BIT(0),
+	DSI_EN = BIT(1),
+	DSI_DUAL = BIT(4),
+};
+
+/* DSI_MODE_CTRL */
+enum {
+	MODE = 3,
+	CMD_MODE = 0,
+	SYNC_PULSE_MODE = 1,
+	SYNC_EVENT_MODE = 2,
+	BURST_MODE = 3,
+	FRM_MODE = BIT(16),
+	MIX_MODE = BIT(17)
+};
+
+/* DSI_PSCTRL */
+enum {
+	DSI_PS_WC = 0x3fff,
+	DSI_PS_SEL = (3 << 16),
+	PACKED_PS_16BIT_RGB565 = (0 << 16),
+	LOOSELY_PS_18BIT_RGB666 = (1 << 16),
+	PACKED_PS_18BIT_RGB666 = (2 << 16),
+	PACKED_PS_24BIT_RGB888 = (3 << 16)
+};
+
+/* DSI_CMDQ_SIZE */
+enum {
+	CMDQ_SIZE = 0x3f,
+};
+
+/* DSI_PHY_LCCON */
+enum {
+	LC_HS_TX_EN = BIT(0),
+	LC_ULPM_EN = BIT(1),
+	LC_WAKEUP_EN = BIT(2)
+};
+
+/*DSI_PHY_LD0CON */
+enum {
+	LD0_RM_TRIG_EN = BIT(0),
+	LD0_ULPM_EN = BIT(1),
+	LD0_WAKEUP_EN = BIT(2)
+};
+
+enum {
+	LPX = (0xff << 0),
+	HS_PRPR = (0xff << 8),
+	HS_ZERO = (0xff << 16),
+	HS_TRAIL = (0xff << 24)
+};
+
+enum {
+	TA_GO = (0xff << 0),
+	TA_SURE = (0xff << 8),
+	TA_GET = (0xff << 16),
+	DA_HS_EXIT = (0xff << 24)
+};
+
+enum {
+	CONT_DET = (0xff << 0),
+	CLK_ZERO = (0xf << 16),
+	CLK_TRAIL = (0xff << 24)
+};
+
+enum {
+	CLK_HS_PRPR = (0xff << 0),
+	CLK_HS_POST = (0xff << 8),
+	CLK_HS_EXIT = (0xf << 16)
+};
+
+/* DSI_VM_CMD_CON */
+enum {
+	VM_CMD_EN = BIT(0),
+	TS_VFP_EN = BIT(5),
+};
+
+/* DSI_CMDQ0 */
+enum {
+	CONFIG         = (0xff << 0),
+	SHORT_PACKET   = 0,
+	LONG_PACKET    = 2,
+	BTA            = BIT(2),
+	DATA_ID        = (0xff << 8),
+	DATA_0         = (0xff << 16),
+	DATA_1         = (0xff << 24),
+};
+
+/* MIPI DSI Processor-to-Peripheral transaction types */
+enum {
+	MIPI_DSI_V_SYNC_START				= 0x01,
+	MIPI_DSI_V_SYNC_END				= 0x11,
+	MIPI_DSI_H_SYNC_START				= 0x21,
+	MIPI_DSI_H_SYNC_END				= 0x31,
+
+	MIPI_DSI_COLOR_MODE_OFF				= 0x02,
+	MIPI_DSI_COLOR_MODE_ON				= 0x12,
+	MIPI_DSI_SHUTDOWN_PERIPHERAL			= 0x22,
+	MIPI_DSI_TURN_ON_PERIPHERAL			= 0x32,
+
+	MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM		= 0x03,
+	MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM		= 0x13,
+	MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM		= 0x23,
+
+	MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM		= 0x04,
+	MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM		= 0x14,
+	MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM		= 0x24,
+
+	MIPI_DSI_DCS_SHORT_WRITE			= 0x05,
+	MIPI_DSI_DCS_SHORT_WRITE_PARAM			= 0x15,
+
+	MIPI_DSI_DCS_READ				= 0x06,
+
+	MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE		= 0x37,
+
+	MIPI_DSI_END_OF_TRANSMISSION			= 0x08,
+
+	MIPI_DSI_NULL_PACKET				= 0x09,
+	MIPI_DSI_BLANKING_PACKET			= 0x19,
+	MIPI_DSI_GENERIC_LONG_WRITE			= 0x29,
+	MIPI_DSI_DCS_LONG_WRITE				= 0x39,
+
+	MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20	= 0x0c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24		= 0x1c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16		= 0x2c,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_30			= 0x0d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_36			= 0x1d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12		= 0x3d,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_16			= 0x0e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_18			= 0x1e,
+	MIPI_DSI_PIXEL_STREAM_3BYTE_18			= 0x2e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_24			= 0x3e,
+};
+
+/* MIPI DSI Peripheral-to-Processor transaction types */
+enum {
+	MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT	= 0x02,
+	MIPI_DSI_RX_END_OF_TRANSMISSION			= 0x08,
+	MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE	= 0x11,
+	MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE	= 0x12,
+	MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE		= 0x1a,
+	MIPI_DSI_RX_DCS_LONG_READ_RESPONSE		= 0x1c,
+	MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE	= 0x21,
+	MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE	= 0x22,
+};
+
+/* MIPI DCS commands */
+enum {
+	MIPI_DCS_NOP			= 0x00,
+	MIPI_DCS_SOFT_RESET		= 0x01,
+	MIPI_DCS_GET_DISPLAY_ID		= 0x04,
+	MIPI_DCS_GET_RED_CHANNEL	= 0x06,
+	MIPI_DCS_GET_GREEN_CHANNEL	= 0x07,
+	MIPI_DCS_GET_BLUE_CHANNEL	= 0x08,
+	MIPI_DCS_GET_DISPLAY_STATUS	= 0x09,
+	MIPI_DCS_GET_POWER_MODE		= 0x0A,
+	MIPI_DCS_GET_ADDRESS_MODE	= 0x0B,
+	MIPI_DCS_GET_PIXEL_FORMAT	= 0x0C,
+	MIPI_DCS_GET_DISPLAY_MODE	= 0x0D,
+	MIPI_DCS_GET_SIGNAL_MODE	= 0x0E,
+	MIPI_DCS_GET_DIAGNOSTIC_RESULT	= 0x0F,
+	MIPI_DCS_ENTER_SLEEP_MODE	= 0x10,
+	MIPI_DCS_EXIT_SLEEP_MODE	= 0x11,
+	MIPI_DCS_ENTER_PARTIAL_MODE	= 0x12,
+	MIPI_DCS_ENTER_NORMAL_MODE	= 0x13,
+	MIPI_DCS_EXIT_INVERT_MODE	= 0x20,
+	MIPI_DCS_ENTER_INVERT_MODE	= 0x21,
+	MIPI_DCS_SET_GAMMA_CURVE	= 0x26,
+	MIPI_DCS_SET_DISPLAY_OFF	= 0x28,
+	MIPI_DCS_SET_DISPLAY_ON		= 0x29,
+	MIPI_DCS_SET_COLUMN_ADDRESS	= 0x2A,
+	MIPI_DCS_SET_PAGE_ADDRESS	= 0x2B,
+	MIPI_DCS_WRITE_MEMORY_START	= 0x2C,
+	MIPI_DCS_WRITE_LUT		= 0x2D,
+	MIPI_DCS_READ_MEMORY_START	= 0x2E,
+	MIPI_DCS_SET_PARTIAL_AREA	= 0x30,
+	MIPI_DCS_SET_SCROLL_AREA	= 0x33,
+	MIPI_DCS_SET_TEAR_OFF		= 0x34,
+	MIPI_DCS_SET_TEAR_ON		= 0x35,
+	MIPI_DCS_SET_ADDRESS_MODE	= 0x36,
+	MIPI_DCS_SET_SCROLL_START	= 0x37,
+	MIPI_DCS_EXIT_IDLE_MODE		= 0x38,
+	MIPI_DCS_ENTER_IDLE_MODE	= 0x39,
+	MIPI_DCS_SET_PIXEL_FORMAT	= 0x3A,
+	MIPI_DCS_WRITE_MEMORY_CONTINUE	= 0x3C,
+	MIPI_DCS_READ_MEMORY_CONTINUE	= 0x3E,
+	MIPI_DCS_SET_TEAR_SCANLINE	= 0x44,
+	MIPI_DCS_GET_SCANLINE		= 0x45,
+	MIPI_DCS_READ_DDB_START		= 0xA1,
+	MIPI_DCS_READ_DDB_CONTINUE	= 0xA8,
+};
+
+/* Functions that each SOC should provide. */
+void mtk_dsi_reset(void);
+/* mtk_dsi_phy_clk_setting should return the data rate in Mbps. */
+int mtk_dsi_phy_clk_setting(u32 format, u32 lanes, const struct edid *edid);
+
+/* Public API provided in common/dsi.c */
+int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes,
+		 const struct edid *edid);
+
+#endif /* SOC_MEDIATEK_DSI_COMMON_H */
diff --git a/src/soc/mediatek/mt8173/Makefile.inc b/src/soc/mediatek/mt8173/Makefile.inc
index 510fbf0cc5..21a0c73ae3 100644
--- a/src/soc/mediatek/mt8173/Makefile.inc
+++ b/src/soc/mediatek/mt8173/Makefile.inc
@@ -83,7 +83,7 @@ ramstage-y += ../common/rtc.c rtc.c
 ramstage-y += ../common/usb.c usb.c
 
 ramstage-y += ../common/ddp.c ddp.c
-ramstage-y += dsi.c
+ramstage-y += ../common/dsi.c dsi.c
 
 ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += bl31_plat_params.c
 
diff --git a/src/soc/mediatek/mt8173/dsi.c b/src/soc/mediatek/mt8173/dsi.c
index 5b96a582b7..e2e843e19d 100644
--- a/src/soc/mediatek/mt8173/dsi.c
+++ b/src/soc/mediatek/mt8173/dsi.c
@@ -16,12 +16,11 @@
 #include <device/mmio.h>
 #include <console/console.h>
 #include <delay.h>
-#include <soc/addressmap.h>
+#include <edid.h>
 #include <soc/dsi.h>
 #include <timer.h>
 
-static int mtk_dsi_phy_clk_setting(u32 format, u32 lanes,
-				   const struct edid *edid)
+int mtk_dsi_phy_clk_setting(u32 format, u32 lanes, const struct edid *edid)
 {
 	u32 txdiv0, txdiv1;
 	u64 pcw;
@@ -133,182 +132,12 @@ static int mtk_dsi_phy_clk_setting(u32 format, u32 lanes,
 	return mipi_tx_rate;
 }
 
-static void mtk_dsi_phy_timconfig(u32 data_rate)
-{
-	u32 timcon0, timcon1, timcon2, timcon3;
-	u32 cycle_time, ui, lpx;
-
-	ui = 1000 / data_rate + 0x01;
-	cycle_time = 8000 / data_rate + 0x01;
-	lpx = 5;
-
-	timcon0 = (8 << 24) | (0xa << 16) | (0x6 << 8) | lpx;
-	timcon1 = (7 << 24) | (5 * lpx << 16) | ((3 * lpx) / 2) << 8 |
-		  (4 * lpx);
-	timcon2 = ((DIV_ROUND_UP(0x64, cycle_time) + 0xa) << 24) |
-		  (DIV_ROUND_UP(0x150, cycle_time) << 16);
-	timcon3 = (2 * lpx) << 16 |
-		  DIV_ROUND_UP(80 + 52 * ui, cycle_time) << 8 |
-		  DIV_ROUND_UP(0x40, cycle_time);
-
-	write32(&dsi0->dsi_phy_timecon0, timcon0);
-	write32(&dsi0->dsi_phy_timecon1, timcon1);
-	write32(&dsi0->dsi_phy_timecon2, timcon2);
-	write32(&dsi0->dsi_phy_timecon3, timcon3);
-}
-
-static void mtk_dsi_reset(void)
+void mtk_dsi_reset(void)
 {
 	setbits_le32(&dsi0->dsi_con_ctrl, 3);
 	clrbits_le32(&dsi0->dsi_con_ctrl, 1);
 }
 
-static void mtk_dsi_clk_hs_mode_enable(void)
-{
-	setbits_le32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
-}
-
-static void mtk_dsi_clk_hs_mode_disable(void)
-{
-	clrbits_le32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN);
-}
-
-static void mtk_dsi_set_mode(u32 mode_flags)
-{
-	u32 tmp_reg1 = 0;
-
-	if (mode_flags & MIPI_DSI_MODE_VIDEO) {
-		tmp_reg1 = SYNC_PULSE_MODE;
-
-		if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
-			tmp_reg1 = BURST_MODE;
-
-		if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
-			tmp_reg1 = SYNC_PULSE_MODE;
-	}
-
-	write32(&dsi0->dsi_mode_ctrl, tmp_reg1);
-}
-
-static void mtk_dsi_rxtx_control(u32 mode_flags, u32 lanes)
-{
-	u32 tmp_reg = 0;
-
-	switch (lanes) {
-	case 1:
-		tmp_reg = 1 << 2;
-		break;
-	case 2:
-		tmp_reg = 3 << 2;
-		break;
-	case 3:
-		tmp_reg = 7 << 2;
-		break;
-	case 4:
-	default:
-		tmp_reg = 0xf << 2;
-		break;
-	}
-
-	tmp_reg |= (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) << 6;
-	tmp_reg |= (mode_flags & MIPI_DSI_MODE_EOT_PACKET) >> 3;
-
-	write32(&dsi0->dsi_txrx_ctrl, tmp_reg);
-}
-
-static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format,
-				      const struct edid *edid)
-{
-	u32 hsync_active_byte;
-	u32 hbp_byte;
-	u32 hfp_byte;
-	u32 vbp_byte;
-	u32 vfp_byte;
-	u32 bpp;
-	u32 packet_fmt;
-	u32 hactive;
-
-	if (format == MIPI_DSI_FMT_RGB565)
-		bpp = 2;
-	else
-		bpp = 3;
-
-	vbp_byte = edid->mode.vbl - edid->mode.vso - edid->mode.vspw -
-		   edid->mode.vborder;
-	vfp_byte = edid->mode.vso - edid->mode.vborder;
-
-	write32(&dsi0->dsi_vsa_nl, edid->mode.vspw);
-	write32(&dsi0->dsi_vbp_nl, vbp_byte);
-	write32(&dsi0->dsi_vfp_nl, vfp_byte);
-	write32(&dsi0->dsi_vact_nl, edid->mode.va);
-
-	if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
-		hbp_byte = (edid->mode.hbl - edid->mode.hso - edid->mode.hspw -
-			    edid->mode.hborder) * bpp - 10;
-	else
-		hbp_byte = (edid->mode.hbl - edid->mode.hso -
-			    edid->mode.hborder) * bpp - 10;
-
-	hsync_active_byte = edid->mode.hspw * bpp - 10;
-	hfp_byte = (edid->mode.hso - edid->mode.hborder) * bpp - 12;
-
-	write32(&dsi0->dsi_hsa_wc, hsync_active_byte);
-	write32(&dsi0->dsi_hbp_wc, hbp_byte);
-	write32(&dsi0->dsi_hfp_wc, hfp_byte);
-
-	switch (format) {
-	case MIPI_DSI_FMT_RGB888:
-		packet_fmt = PACKED_PS_24BIT_RGB888;
-		break;
-	case MIPI_DSI_FMT_RGB666:
-		packet_fmt = LOOSELY_PS_18BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB666_PACKED:
-		packet_fmt = PACKED_PS_18BIT_RGB666;
-		break;
-	case MIPI_DSI_FMT_RGB565:
-		packet_fmt = PACKED_PS_16BIT_RGB565;
-		break;
-	default:
-		packet_fmt = PACKED_PS_24BIT_RGB888;
-		break;
-	}
-
-	hactive = edid->mode.ha;
-	packet_fmt |= (hactive * bpp) & DSI_PS_WC;
-
-	write32(&dsi0->dsi_psctrl, packet_fmt);
-}
-
-static void mtk_dsi_start(void)
-{
-	write32(&dsi0->dsi_start, 0);
-	/* Only start master DSI */
-	write32(&dsi0->dsi_start, 1);
-}
-
-int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid)
-{
-	int data_rate;
-
-	data_rate = mtk_dsi_phy_clk_setting(format, lanes, edid);
-
-	if (data_rate < 0)
-		return -1;
-
-	mtk_dsi_reset();
-	mtk_dsi_phy_timconfig(data_rate);
-	mtk_dsi_rxtx_control(mode_flags, lanes);
-	mtk_dsi_clk_hs_mode_disable();
-	mtk_dsi_config_vdo_timing(mode_flags, format, edid);
-	mtk_dsi_set_mode(mode_flags);
-	mtk_dsi_clk_hs_mode_enable();
-
-	mtk_dsi_start();
-
-	return 0;
-}
-
 void mtk_dsi_pin_drv_ctrl(void)
 {
 	struct stopwatch sw;
diff --git a/src/soc/mediatek/mt8173/include/soc/dsi.h b/src/soc/mediatek/mt8173/include/soc/dsi.h
index 967ed4d27e..f7c622745d 100644
--- a/src/soc/mediatek/mt8173/include/soc/dsi.h
+++ b/src/soc/mediatek/mt8173/include/soc/dsi.h
@@ -16,183 +16,9 @@
 #ifndef _DSI_REG_H_
 #define _DSI_REG_H_
 
-#include <edid.h>
-#include <types.h>
+#include <soc/dsi_common.h>
 
-enum mipi_dsi_pixel_format {
-	MIPI_DSI_FMT_RGB888,
-	MIPI_DSI_FMT_RGB666,
-	MIPI_DSI_FMT_RGB666_PACKED,
-	MIPI_DSI_FMT_RGB565
-};
-
-/* video mode */
-enum {
-	MIPI_DSI_MODE_VIDEO = BIT(0),
-	/* video burst mode */
-	MIPI_DSI_MODE_VIDEO_BURST = BIT(1),
-	/* video pulse mode */
-	MIPI_DSI_MODE_VIDEO_SYNC_PULSE = BIT(2),
-	/* enable auto vertical count mode */
-	MIPI_DSI_MODE_VIDEO_AUTO_VERT = BIT(3),
-	/* enable hsync-end packets in vsync-pulse and v-porch area */
-	MIPI_DSI_MODE_VIDEO_HSE = BIT(4),
-	/* disable hfront-porch area */
-	MIPI_DSI_MODE_VIDEO_HFP = BIT(5),
-	/* disable hback-porch area */
-	MIPI_DSI_MODE_VIDEO_HBP = BIT(6),
-	/* disable hsync-active area */
-	MIPI_DSI_MODE_VIDEO_HSA = BIT(7),
-	/* flush display FIFO on vsync pulse */
-	MIPI_DSI_MODE_VSYNC_FLUSH = BIT(8),
-	/* disable EoT packets in HS mode */
-	MIPI_DSI_MODE_EOT_PACKET = BIT(9),
-	/* device supports non-continuous clock behavior (DSI spec 5.6.1) */
-	MIPI_DSI_CLOCK_NON_CONTINUOUS = BIT(10),
-	/* transmit data in low power */
-	MIPI_DSI_MODE_LPM = BIT(11)
-};
-
-struct dsi_regs {
-	u32 dsi_start;
-	u8 reserved0[4];
-	u32 dsi_inten;
-	u32 dsi_intsta;
-	u32 dsi_con_ctrl;
-	u32 dsi_mode_ctrl;
-	u32 dsi_txrx_ctrl;
-	u32 dsi_psctrl;
-	u32 dsi_vsa_nl;
-	u32 dsi_vbp_nl;
-	u32 dsi_vfp_nl;
-	u32 dsi_vact_nl;
-	u8 reserved1[32];
-	u32 dsi_hsa_wc;
-	u32 dsi_hbp_wc;
-	u32 dsi_hfp_wc;
-	u32 dsi_bllp_wc;
-	u32 dsi_cmdq_size;
-	u32 dsi_hstx_cklp_wc;
-	u8 reserved2[156];
-	u32 dsi_phy_lccon;
-	u32 dsi_phy_ld0con;
-	u8 reserved3[4];
-	u32 dsi_phy_timecon0;
-	u32 dsi_phy_timecon1;
-	u32 dsi_phy_timecon2;
-	u32 dsi_phy_timecon3;
-	u8 reserved4[16];
-	u32 dsi_vm_cmd_con;
-	u8 reserved5[204];
-	u32 dsi_cmdq0;
-};
-
-check_member(dsi_regs, dsi_phy_lccon, 0x104);
-check_member(dsi_regs, dsi_phy_timecon3, 0x11c);
-check_member(dsi_regs, dsi_vm_cmd_con, 0x130);
-check_member(dsi_regs, dsi_cmdq0, 0x200);
-static struct dsi_regs *const dsi0 = (void *)DSI0_BASE;
-static struct dsi_regs *const dsi1 = (void *)DSI1_BASE;
-
-/* DSI_INTSTA */
-enum {
-	LPRX_RD_RDY_INT_FLAG = BIT(0),
-	CMD_DONE_INT_FLAG    = BIT(1),
-	TE_RDY_INT_FLAG      = BIT(2),
-	VM_DONE_INT_FLAG     = BIT(3),
-	EXT_TE_RDY_INT_FLAG  = BIT(4),
-	DSI_BUSY             = BIT(31),
-};
-
-/* DSI_CON_CTRL */
-enum {
-	DSI_RESET = BIT(0),
-	DSI_EN = BIT(1),
-	DSI_DUAL = BIT(4),
-};
-
-/* DSI_MODE_CTRL */
-enum {
-	MODE = 3,
-	CMD_MODE = 0,
-	SYNC_PULSE_MODE = 1,
-	SYNC_EVENT_MODE = 2,
-	BURST_MODE = 3,
-	FRM_MODE = BIT(16),
-	MIX_MODE = BIT(17)
-};
-
-/* DSI_PSCTRL */
-enum {
-	DSI_PS_WC = 0x3fff,
-	DSI_PS_SEL = (3 << 16),
-	PACKED_PS_16BIT_RGB565 = (0 << 16),
-	LOOSELY_PS_18BIT_RGB666 = (1 << 16),
-	PACKED_PS_18BIT_RGB666 = (2 << 16),
-	PACKED_PS_24BIT_RGB888 = (3 << 16)
-};
-
-/* DSI_CMDQ_SIZE */
-enum {
-	CMDQ_SIZE = 0x3f,
-};
-
-/* DSI_PHY_LCCON */
-enum {
-	LC_HS_TX_EN = BIT(0),
-	LC_ULPM_EN = BIT(1),
-	LC_WAKEUP_EN = BIT(2)
-};
-
-/*DSI_PHY_LD0CON */
-enum {
-	LD0_RM_TRIG_EN = BIT(0),
-	LD0_ULPM_EN = BIT(1),
-	LD0_WAKEUP_EN = BIT(2)
-};
-
-enum {
-	LPX = (0xff << 0),
-	HS_PRPR = (0xff << 8),
-	HS_ZERO = (0xff << 16),
-	HS_TRAIL = (0xff << 24)
-};
-
-enum {
-	TA_GO = (0xff << 0),
-	TA_SURE = (0xff << 8),
-	TA_GET = (0xff << 16),
-	DA_HS_EXIT = (0xff << 24)
-};
-
-enum {
-	CONT_DET = (0xff << 0),
-	CLK_ZERO = (0xf << 16),
-	CLK_TRAIL = (0xff << 24)
-};
-
-enum {
-	CLK_HS_PRPR = (0xff << 0),
-	CLK_HS_POST = (0xff << 8),
-	CLK_HS_EXIT = (0xf << 16)
-};
-
-/* DSI_VM_CMD_CON */
-enum {
-	VM_CMD_EN = BIT(0),
-	TS_VFP_EN = BIT(5),
-};
-
-/* DSI_CMDQ0 */
-enum {
-	CONFIG         = (0xff << 0),
-	SHORT_PACKET   = 0,
-	LONG_PACKET    = 2,
-	BTA            = BIT(2),
-	DATA_ID        = (0xff << 8),
-	DATA_0         = (0xff << 16),
-	DATA_1         = (0xff << 24),
-};
+/* MIPITX is SOC specific and cannot live in common. */
 
 /* MIPITX_REG */
 struct mipi_tx_regs {
@@ -336,114 +162,7 @@ enum {
 	RG_DA_LVDSTX_PWR_ON = BIT(9)
 };
 
-/* MIPI DSI Processor-to-Peripheral transaction types */
-enum {
-	MIPI_DSI_V_SYNC_START				= 0x01,
-	MIPI_DSI_V_SYNC_END				= 0x11,
-	MIPI_DSI_H_SYNC_START				= 0x21,
-	MIPI_DSI_H_SYNC_END				= 0x31,
-
-	MIPI_DSI_COLOR_MODE_OFF				= 0x02,
-	MIPI_DSI_COLOR_MODE_ON				= 0x12,
-	MIPI_DSI_SHUTDOWN_PERIPHERAL			= 0x22,
-	MIPI_DSI_TURN_ON_PERIPHERAL			= 0x32,
-
-	MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM		= 0x03,
-	MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM		= 0x13,
-	MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM		= 0x23,
-
-	MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM		= 0x04,
-	MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM		= 0x14,
-	MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM		= 0x24,
-
-	MIPI_DSI_DCS_SHORT_WRITE			= 0x05,
-	MIPI_DSI_DCS_SHORT_WRITE_PARAM			= 0x15,
-
-	MIPI_DSI_DCS_READ				= 0x06,
-
-	MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE		= 0x37,
-
-	MIPI_DSI_END_OF_TRANSMISSION			= 0x08,
-
-	MIPI_DSI_NULL_PACKET				= 0x09,
-	MIPI_DSI_BLANKING_PACKET			= 0x19,
-	MIPI_DSI_GENERIC_LONG_WRITE			= 0x29,
-	MIPI_DSI_DCS_LONG_WRITE				= 0x39,
-
-	MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20	= 0x0c,
-	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24		= 0x1c,
-	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16		= 0x2c,
-
-	MIPI_DSI_PACKED_PIXEL_STREAM_30			= 0x0d,
-	MIPI_DSI_PACKED_PIXEL_STREAM_36			= 0x1d,
-	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12		= 0x3d,
-
-	MIPI_DSI_PACKED_PIXEL_STREAM_16			= 0x0e,
-	MIPI_DSI_PACKED_PIXEL_STREAM_18			= 0x1e,
-	MIPI_DSI_PIXEL_STREAM_3BYTE_18			= 0x2e,
-	MIPI_DSI_PACKED_PIXEL_STREAM_24			= 0x3e,
-};
-
-/* MIPI DSI Peripheral-to-Processor transaction types */
-enum {
-	MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT	= 0x02,
-	MIPI_DSI_RX_END_OF_TRANSMISSION			= 0x08,
-	MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE	= 0x11,
-	MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE	= 0x12,
-	MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE		= 0x1a,
-	MIPI_DSI_RX_DCS_LONG_READ_RESPONSE		= 0x1c,
-	MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE	= 0x21,
-	MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE	= 0x22,
-};
-
-/* MIPI DCS commands */
-enum {
-	MIPI_DCS_NOP			= 0x00,
-	MIPI_DCS_SOFT_RESET		= 0x01,
-	MIPI_DCS_GET_DISPLAY_ID		= 0x04,
-	MIPI_DCS_GET_RED_CHANNEL	= 0x06,
-	MIPI_DCS_GET_GREEN_CHANNEL	= 0x07,
-	MIPI_DCS_GET_BLUE_CHANNEL	= 0x08,
-	MIPI_DCS_GET_DISPLAY_STATUS	= 0x09,
-	MIPI_DCS_GET_POWER_MODE		= 0x0A,
-	MIPI_DCS_GET_ADDRESS_MODE	= 0x0B,
-	MIPI_DCS_GET_PIXEL_FORMAT	= 0x0C,
-	MIPI_DCS_GET_DISPLAY_MODE	= 0x0D,
-	MIPI_DCS_GET_SIGNAL_MODE	= 0x0E,
-	MIPI_DCS_GET_DIAGNOSTIC_RESULT	= 0x0F,
-	MIPI_DCS_ENTER_SLEEP_MODE	= 0x10,
-	MIPI_DCS_EXIT_SLEEP_MODE	= 0x11,
-	MIPI_DCS_ENTER_PARTIAL_MODE	= 0x12,
-	MIPI_DCS_ENTER_NORMAL_MODE	= 0x13,
-	MIPI_DCS_EXIT_INVERT_MODE	= 0x20,
-	MIPI_DCS_ENTER_INVERT_MODE	= 0x21,
-	MIPI_DCS_SET_GAMMA_CURVE	= 0x26,
-	MIPI_DCS_SET_DISPLAY_OFF	= 0x28,
-	MIPI_DCS_SET_DISPLAY_ON		= 0x29,
-	MIPI_DCS_SET_COLUMN_ADDRESS	= 0x2A,
-	MIPI_DCS_SET_PAGE_ADDRESS	= 0x2B,
-	MIPI_DCS_WRITE_MEMORY_START	= 0x2C,
-	MIPI_DCS_WRITE_LUT		= 0x2D,
-	MIPI_DCS_READ_MEMORY_START	= 0x2E,
-	MIPI_DCS_SET_PARTIAL_AREA	= 0x30,
-	MIPI_DCS_SET_SCROLL_AREA	= 0x33,
-	MIPI_DCS_SET_TEAR_OFF		= 0x34,
-	MIPI_DCS_SET_TEAR_ON		= 0x35,
-	MIPI_DCS_SET_ADDRESS_MODE	= 0x36,
-	MIPI_DCS_SET_SCROLL_START	= 0x37,
-	MIPI_DCS_EXIT_IDLE_MODE		= 0x38,
-	MIPI_DCS_ENTER_IDLE_MODE	= 0x39,
-	MIPI_DCS_SET_PIXEL_FORMAT	= 0x3A,
-	MIPI_DCS_WRITE_MEMORY_CONTINUE	= 0x3C,
-	MIPI_DCS_READ_MEMORY_CONTINUE	= 0x3E,
-	MIPI_DCS_SET_TEAR_SCANLINE	= 0x44,
-	MIPI_DCS_GET_SCANLINE		= 0x45,
-	MIPI_DCS_READ_DDB_START		= 0xA1,
-	MIPI_DCS_READ_DDB_CONTINUE	= 0xA8,
-};
-
-int mtk_dsi_init(u32 mode_flags, enum mipi_dsi_pixel_format format, u32 lanes,
-		 const struct edid *edid);
+/* SOC specific functions */
 void mtk_dsi_pin_drv_ctrl(void);
 
 #endif
-- 
cgit v1.2.3