diff options
author | Hung-Te Lin <hungte@chromium.org> | 2019-08-07 10:58:36 +0800 |
---|---|---|
committer | Julius Werner <jwerner@chromium.org> | 2019-08-15 00:51:05 +0000 |
commit | 32ddc0d9f7186471c2f1ae8dc7279639dcaadb06 (patch) | |
tree | 7e4a73e02cdac26010f001b2c9c52e96c113142e /src | |
parent | 75e4314675cecf6faf7c02920a86f3157e6ba5c1 (diff) | |
download | coreboot-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')
-rw-r--r-- | src/soc/mediatek/common/dsi.c | 6 | ||||
-rw-r--r-- | src/soc/mediatek/common/include/soc/dsi_common.h | 23 | ||||
-rw-r--r-- | src/soc/mediatek/mt8173/include/soc/dsi.h | 1 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/dsi.c | 88 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/addressmap.h | 2 | ||||
-rw-r--r-- | src/soc/mediatek/mt8183/include/soc/dsi.h | 68 |
7 files changed, 187 insertions, 2 deletions
diff --git a/src/soc/mediatek/common/dsi.c b/src/soc/mediatek/common/dsi.c index fffe51f708..166bc17eee 100644 --- a/src/soc/mediatek/common/dsi.c +++ b/src/soc/mediatek/common/dsi.c @@ -248,6 +248,12 @@ static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, write32(&dsi0->dsi_psctrl, PIXEL_STREAM_CUSTOM_HEADER << DSI_PSCON_CUSTOM_HEADER_SHIFT | packet_fmt); + + /* Older systems like MT8173 do not support size_con. */ + if (MTK_DSI_HAVE_SIZE_CON) + write32(&dsi0->dsi_size_con, + edid->mode.va << DSI_SIZE_CON_HEIGHT_SHIFT | + hactive << DSI_SIZE_CON_WIDTH_SHIFT); } static void mtk_dsi_start(void) diff --git a/src/soc/mediatek/common/include/soc/dsi_common.h b/src/soc/mediatek/common/include/soc/dsi_common.h index 3f4a47d1b8..c684aaf940 100644 --- a/src/soc/mediatek/common/include/soc/dsi_common.h +++ b/src/soc/mediatek/common/include/soc/dsi_common.h @@ -67,7 +67,11 @@ struct dsi_regs { u32 dsi_vbp_nl; u32 dsi_vfp_nl; u32 dsi_vact_nl; - u8 reserved1[32]; + u32 dsi_lfr_con; /* Available since MT8183 */ + u32 dsi_lfr_sta; /* Available since MT8183 */ + u32 dsi_size_con; /* Available since MT8183 */ + u32 dsi_vfp_early_stop; /* Available since MT8183 */ + u32 reserved1[4]; u32 dsi_hsa_wc; u32 dsi_hbp_wc; u32 dsi_hfp_wc; @@ -84,7 +88,9 @@ struct dsi_regs { u32 dsi_phy_timecon3; u8 reserved4[16]; u32 dsi_vm_cmd_con; - u8 reserved5[204]; + u8 reserved5[92]; + u32 dsi_force_commit; /* Available since MT8183 */ + u8 reserved6[108]; u32 dsi_cmdq[128]; }; static struct dsi_regs *const dsi0 = (void *)DSI0_BASE; @@ -92,6 +98,7 @@ 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_force_commit, 0x190); check_member(dsi_regs, dsi_cmdq, 0x200); /* DSI_INTSTA */ @@ -134,6 +141,12 @@ enum { DSI_PSCON_CUSTOM_HEADER_SHIFT = 26, }; +/* DSI_SIZE_CON */ +enum { + DSI_SIZE_CON_HEIGHT_SHIFT = 16, + DSI_SIZE_CON_WIDTH_SHIFT = 0, +}; + /* DSI_CMDQ_SIZE */ enum { CMDQ_SIZE = 0x3f, @@ -196,6 +209,12 @@ enum { DATA_1 = (0xff << 24), }; +/* DSI_FORCE_COMMIT */ +enum { + DSI_FORCE_COMMIT_USE_MMSYS = BIT(0), + DSI_FORCE_COMMIT_ALWAYS = BIT(1), +}; + /* MIPI DSI Processor-to-Peripheral transaction types */ enum { MIPI_DSI_V_SYNC_START = 0x01, diff --git a/src/soc/mediatek/mt8173/include/soc/dsi.h b/src/soc/mediatek/mt8173/include/soc/dsi.h index 43cbdcb909..e7c1d28b1f 100644 --- a/src/soc/mediatek/mt8173/include/soc/dsi.h +++ b/src/soc/mediatek/mt8173/include/soc/dsi.h @@ -22,6 +22,7 @@ #define MTK_DSI_MIPI_RATIO_NUMERATOR 102 #define MTK_DSI_MIPI_RATIO_DENOMINATOR 100 #define MTK_DSI_DATA_RATE_MIN_MHZ 50 +#define MTK_DSI_HAVE_SIZE_CON 0 #define PIXEL_STREAM_CUSTOM_HEADER 0 /* MIPITX is SOC specific and cannot live in common. */ diff --git a/src/soc/mediatek/mt8183/Makefile.inc b/src/soc/mediatek/mt8183/Makefile.inc index 45276835af..cac793fc90 100644 --- a/src/soc/mediatek/mt8183/Makefile.inc +++ b/src/soc/mediatek/mt8183/Makefile.inc @@ -46,6 +46,7 @@ romstage-y += ../common/wdt.c ramstage-y += auxadc.c ramstage-y += ../common/cbmem.c emi.c ramstage-y += ../common/ddp.c ddp.c +ramstage-y += ../common/dsi.c dsi.c ramstage-y += ../common/gpio.c gpio.c ramstage-y += ../common/i2c.c i2c.c ramstage-y += ../common/mmu_operations.c mmu_operations.c 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); +} diff --git a/src/soc/mediatek/mt8183/include/soc/addressmap.h b/src/soc/mediatek/mt8183/include/soc/addressmap.h index bb44f9bb45..c267a1473e 100644 --- a/src/soc/mediatek/mt8183/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8183/include/soc/addressmap.h @@ -51,6 +51,7 @@ enum { IOCFG_RT_BASE = IO_PHYS + 0x01C50000, IOCFG_RM_BASE = IO_PHYS + 0x01D20000, IOCFG_RB_BASE = IO_PHYS + 0x01D30000, + MIPITX_BASE = IO_PHYS + 0x01E50000, IOCFG_LB_BASE = IO_PHYS + 0x01E70000, IOCFG_LM_BASE = IO_PHYS + 0x01E80000, IOCFG_BL_BASE = IO_PHYS + 0x01E90000, @@ -69,6 +70,7 @@ enum { DISP_AAL0_BASE = IO_PHYS + 0x04010000, DISP_GAMMA0_BASE = IO_PHYS + 0x04011000, DISP_DITHER0_BASE = IO_PHYS + 0x04012000, + DSI0_BASE = IO_PHYS + 0x04014000, DISP_MUTEX_BASE = IO_PHYS + 0x04016000, SMI_LARB0 = IO_PHYS + 0x04017000, SMI_BASE = IO_PHYS + 0x04019000, diff --git a/src/soc/mediatek/mt8183/include/soc/dsi.h b/src/soc/mediatek/mt8183/include/soc/dsi.h new file mode 100644 index 0000000000..8813f94982 --- /dev/null +++ b/src/soc/mediatek/mt8183/include/soc/dsi.h @@ -0,0 +1,68 @@ +/* + * 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_MT8183_DSI_H +#define SOC_MEDIATEK_MT8183_DSI_H + +#include <soc/dsi_common.h> + +/* DSI features */ +#define MTK_DSI_MIPI_RATIO_NUMERATOR 100 +#define MTK_DSI_MIPI_RATIO_DENOMINATOR 100 +#define MTK_DSI_DATA_RATE_MIN_MHZ 125 +#define MTK_DSI_HAVE_SIZE_CON 1 +#define PIXEL_STREAM_CUSTOM_HEADER 0xb + +/* MIPITX is SOC specific and cannot live in common. */ + +/* MIPITX_REG */ +struct mipi_tx_regs { + u32 reserved0[3]; + u32 lane_con; + u32 reserved1[6]; + u32 pll_pwr; + u32 pll_con0; + u32 pll_con1; + u32 pll_con2; + u32 pll_con3; + u32 pll_con4; + u32 reserved2[65]; + u32 d2_sw_ctl_en; + u32 reserved3[63]; + u32 d0_sw_ctl_en; + u32 reserved4[56]; + u32 ck_ckmode_en; + u32 reserved5[6]; + u32 ck_sw_ctl_en; + u32 reserved6[63]; + u32 d1_sw_ctl_en; + u32 reserved7[63]; + u32 d3_sw_ctl_en; +}; + +check_member(mipi_tx_regs, pll_con4, 0x3c); +check_member(mipi_tx_regs, d3_sw_ctl_en, 0x544); +static struct mipi_tx_regs *const mipi_tx = (void *)MIPITX_BASE; + +/* Register values */ +#define DSI_CK_CKMODE_EN BIT(0) +#define DSI_SW_CTL_EN BIT(0) +#define AD_DSI_PLL_SDM_PWR_ON BIT(0) +#define AD_DSI_PLL_SDM_ISO_EN BIT(1) + +#define RG_DSI_PLL_EN BIT(4) +#define RG_DSI_PLL_POSDIV (0x7 << 8) + +#endif |