summaryrefslogtreecommitdiff
path: root/src/soc/mediatek/mt8183/dsi.c
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2019-08-07 10:58:36 +0800
committerJulius Werner <jwerner@chromium.org>2019-08-15 00:51:05 +0000
commit32ddc0d9f7186471c2f1ae8dc7279639dcaadb06 (patch)
tree7e4a73e02cdac26010f001b2c9c52e96c113142e /src/soc/mediatek/mt8183/dsi.c
parent75e4314675cecf6faf7c02920a86f3157e6ba5c1 (diff)
downloadcoreboot-32ddc0d9f7186471c2f1ae8dc7279639dcaadb06.tar.xz
soc/mediatek/mt8183: Add DSI driver
The MT8183 display serial interface (DSI) is based on MIPI Alliance Specification, supporting high-speed serial data transfer between host processor and peripheral devices such as display modules. DSI supports both video mode and command mode data transfer defined in MIPI spec, and it also provides bidirectional transmission with low-power mode to receive messages from the peripheral. Reference: MT8183 Application Processor Functional Spec, 6.7 Display Serial Interface (DSI) BUG=b:80501386,b:117254947 BRANCH=none TEST=Boots correctly on Kukui Change-Id: Ic413f524ca0b36f0b01f723a71fe9745e2710cd2 Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/31591 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'src/soc/mediatek/mt8183/dsi.c')
-rw-r--r--src/soc/mediatek/mt8183/dsi.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/soc/mediatek/mt8183/dsi.c b/src/soc/mediatek/mt8183/dsi.c
new file mode 100644
index 0000000000..daa06caeae
--- /dev/null
+++ b/src/soc/mediatek/mt8183/dsi.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2019 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 <assert.h>
+#include <device/mmio.h>
+#include <console/console.h>
+#include <delay.h>
+#include <soc/dsi.h>
+#include <soc/pll.h>
+
+void mtk_dsi_configure_mipi_tx(int data_rate, u32 lanes)
+{
+ unsigned int txdiv, txdiv0, txdiv1;
+ u64 pcw;
+
+ if (data_rate >= 2000) {
+ txdiv = 1;
+ txdiv0 = 0;
+ txdiv1 = 0;
+ } else if (data_rate >= 1000) {
+ txdiv = 2;
+ txdiv0 = 1;
+ txdiv1 = 0;
+ } else if (data_rate >= 500) {
+ txdiv = 4;
+ txdiv0 = 2;
+ txdiv1 = 0;
+ } else if (data_rate > 250) {
+ /* Be aware that 250 is a special case that must use txdiv=4. */
+ txdiv = 8;
+ txdiv0 = 3;
+ txdiv1 = 0;
+ } else {
+ /* MIN = 125 */
+ assert(data_rate >= MTK_DSI_DATA_RATE_MIN_MHZ);
+ txdiv = 16;
+ txdiv0 = 4;
+ txdiv1 = 0;
+ }
+
+ clrbits_le32(&mipi_tx->pll_con4, BIT(11) | BIT(10));
+ setbits_le32(&mipi_tx->pll_pwr, AD_DSI_PLL_SDM_PWR_ON);
+ udelay(30);
+ clrbits_le32(&mipi_tx->pll_pwr, AD_DSI_PLL_SDM_ISO_EN);
+
+ pcw = (u64)data_rate * (1 << txdiv0) * (1 << txdiv1);
+ pcw <<= 24;
+ pcw /= CLK26M_HZ / MHz;
+
+ write32(&mipi_tx->pll_con0, pcw);
+ clrsetbits_le32(&mipi_tx->pll_con1, RG_DSI_PLL_POSDIV, txdiv0 << 8);
+ udelay(30);
+ setbits_le32(&mipi_tx->pll_con1, RG_DSI_PLL_EN);
+
+ /* BG_LPF_EN / BG_CORE_EN */
+ write32(&mipi_tx->lane_con, 0x3fff0180);
+ udelay(40);
+ write32(&mipi_tx->lane_con, 0x3fff00c0);
+
+ /* Switch OFF each Lane */
+ clrbits_le32(&mipi_tx->d0_sw_ctl_en, DSI_SW_CTL_EN);
+ clrbits_le32(&mipi_tx->d1_sw_ctl_en, DSI_SW_CTL_EN);
+ clrbits_le32(&mipi_tx->d2_sw_ctl_en, DSI_SW_CTL_EN);
+ clrbits_le32(&mipi_tx->d3_sw_ctl_en, DSI_SW_CTL_EN);
+ clrbits_le32(&mipi_tx->ck_sw_ctl_en, DSI_SW_CTL_EN);
+
+ setbits_le32(&mipi_tx->ck_ckmode_en, DSI_CK_CKMODE_EN);
+}
+
+void mtk_dsi_reset(void)
+{
+ write32(&dsi0->dsi_force_commit,
+ DSI_FORCE_COMMIT_USE_MMSYS | DSI_FORCE_COMMIT_ALWAYS);
+ write32(&dsi0->dsi_con_ctrl, 1);
+ write32(&dsi0->dsi_con_ctrl, 0);
+}