summaryrefslogtreecommitdiff
path: root/src/soc/mediatek/mt8173/ddp.c
diff options
context:
space:
mode:
authorJitao Shi <jitao.shi@mediatek.com>2017-02-07 08:51:01 +0800
committerJulius Werner <jwerner@chromium.org>2017-04-25 02:36:55 +0200
commitb927fe19549eaf045e9372f21d1ba19f65fc669f (patch)
treecd8883c534918e037499666eea8eb4d6bcdc3a4c /src/soc/mediatek/mt8173/ddp.c
parent2332adacaf9776f0eb8335c05bc0e65f9c1b2e3e (diff)
downloadcoreboot-b927fe19549eaf045e9372f21d1ba19f65fc669f.tar.xz
mediatek/mt8173: Add support for Dual DSI output
The MT817x display output pipeline can be configured to drive an 8-lane MIPI/DSI panel using "dual DSI" mode. For the "dual DSI" video data path, the UFO block is configured to reorder the data stream into left and right halves which are then sent by the SPLIT1 block to the DSI0 and DSI1 respectively. The DSI0 and DSI1 outputs are then synchronously clocked at half the nominal data rate by their respective MIPI_TX0/MIPI_TX1 phys. Also, update the call sites in oak mainboard to avoid build breakage. BRANCH=none BUG=b:35774871 TEST=Boot Rowan in developer mode and see output on the panel Change-Id: Id47dfd7d9e98689b54398fc8d9142336b41dc29f Signed-off-by: Jitao Shi <jitao.shi@mediatek.com> Signed-off-by: Daniel Kurtz <djkurtz@chromium.org> Reviewed-on: https://review.coreboot.org/19361 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'src/soc/mediatek/mt8173/ddp.c')
-rw-r--r--src/soc/mediatek/mt8173/ddp.c66
1 files changed, 51 insertions, 15 deletions
diff --git a/src/soc/mediatek/mt8173/ddp.c b/src/soc/mediatek/mt8173/ddp.c
index b7a8a6b670..977a9e5fe8 100644
--- a/src/soc/mediatek/mt8173/ddp.c
+++ b/src/soc/mediatek/mt8173/ddp.c
@@ -26,15 +26,22 @@
#define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16)
#define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16)
-static void disp_config_main_path_connection(void)
+static void disp_config_main_path_connection(bool dual_dsi_mode)
{
write32(&mmsys_cfg->disp_ovl0_mout_en, OVL0_MOUT_EN_COLOR0);
- write32(&mmsys_cfg->disp_od_mout_en, OD_MOUT_EN_RDMA0);
+ write32(&mmsys_cfg->disp_color0_sel_in, COLOR0_SEL_IN_OVL0);
- write32(&mmsys_cfg->disp_ufoe_mout_en, UFOE_MOUT_EN_DSI0);
+ write32(&mmsys_cfg->disp_od_mout_en, OD_MOUT_EN_RDMA0);
- write32(&mmsys_cfg->disp_color0_sel_in, COLOR0_SEL_IN_OVL0);
+ if (dual_dsi_mode) {
+ write32(&mmsys_cfg->disp_ufoe_mout_en, UFOE_MOUT_EN_SPLIT1);
+ write32(&mmsys_cfg->dsi0_sel_in, DSI0_SEL_IN_SPLIT1);
+ write32(&mmsys_cfg->dsi1_sel_in, DSI1_SEL_IN_SPLIT1);
+ } else {
+ write32(&mmsys_cfg->disp_ufoe_mout_en, UFOE_MOUT_EN_DSI0);
+ write32(&mmsys_cfg->dsi0_sel_in, DSI0_SEL_IN_UFOE);
+ }
}
static void disp_config_main_path_mutex(void)
@@ -100,9 +107,15 @@ static void od_start(u32 width, u32 height)
write32(&disp_od->en, 1);
}
-static void ufoe_start(void)
+static void ufoe_start(u32 width, u32 height, bool dual_dsi_mode)
{
- write32(&disp_ufoe->start, UFO_BYPASS);
+ if (dual_dsi_mode) {
+ write32(&disp_ufoe->frame_width, width);
+ write32(&disp_ufoe->frame_height, height);
+ write32(&disp_ufoe->start, UFO_LR);
+ } else {
+ write32(&disp_ufoe->start, UFO_BYPASS);
+ }
}
static void color_start(u32 width, u32 height)
@@ -113,6 +126,11 @@ static void color_start(u32 width, u32 height)
write32(&disp_color[0]->start, BIT(0));
}
+static void split_start(void)
+{
+ write32(&disp_split->start, 1);
+}
+
static void ovl_layer_config(u32 fmt, u32 bpp, u32 width, u32 height)
{
write32(&disp_ovl[0]->layer[0].con, fmt << 12);
@@ -122,7 +140,8 @@ static void ovl_layer_config(u32 fmt, u32 bpp, u32 width, u32 height)
ovl_layer_enable();
}
-static void main_disp_path_setup(u32 width, u32 height, u32 pixel_clk)
+static void main_disp_path_setup(u32 width, u32 height, u32 pixel_clk,
+ bool dual_dsi_mode)
{
/* Setup OVL */
ovl_set_roi(width, height, 0);
@@ -134,44 +153,61 @@ static void main_disp_path_setup(u32 width, u32 height, u32 pixel_clk)
od_start(width, height);
/* Setup UFOE */
- ufoe_start();
+ ufoe_start(width, height, dual_dsi_mode);
+
+ if (dual_dsi_mode)
+ split_start();
/* Setup Color */
color_start(width, height);
/* Setup main path connection */
- disp_config_main_path_connection();
+ disp_config_main_path_connection(dual_dsi_mode);
/* Setup main path mutex */
disp_config_main_path_mutex();
}
-static void disp_clock_on(void)
+static void disp_clock_on(bool dual_dsi_mode)
{
+ u32 dual_dsi_cg_con0;
+ u32 dual_dsi_cg_con1;
+
+ if (dual_dsi_mode) {
+ dual_dsi_cg_con0 = CG_CON0_DISP_SPLIT1;
+ dual_dsi_cg_con1 = CG_CON1_DSI1_ENGINE | CG_CON1_DSI1_DIGITAL;
+ } else {
+ dual_dsi_cg_con0 = 0;
+ dual_dsi_cg_con1 = 0;
+ }
+
clrbits_le32(&mmsys_cfg->mmsys_cg_con0, CG_CON0_SMI_COMMON |
CG_CON0_SMI_LARB0 |
CG_CON0_MUTEX_32K |
CG_CON0_DISP_OVL0 |
CG_CON0_DISP_RDMA0 |
CG_CON0_DISP_COLOR0 |
+ CG_CON0_DISP_UFOE |
+ dual_dsi_cg_con0 |
CG_CON0_DISP_OD);
clrbits_le32(&mmsys_cfg->mmsys_cg_con1, CG_CON1_DSI0_ENGINE |
- CG_CON1_DSI0_DIGITAL);
+ CG_CON1_DSI0_DIGITAL |
+ dual_dsi_cg_con1);
}
-void mtk_ddp_init(void)
+void mtk_ddp_init(bool dual_dsi_mode)
{
- disp_clock_on();
+ disp_clock_on(dual_dsi_mode);
}
-void mtk_ddp_mode_set(const struct edid *edid)
+void mtk_ddp_mode_set(const struct edid *edid, bool dual_dsi_mode)
{
u32 fmt = OVL_INFMT_RGBA8888;
u32 bpp = edid->framebuffer_bits_per_pixel / 8;
main_disp_path_setup(edid->mode.ha, edid->mode.va,
- edid->mode.pixel_clock);
+ edid->mode.pixel_clock, dual_dsi_mode);
rdma_start();