From 3cf976e51a480ba19295c2aa04c548962a9d1ef4 Mon Sep 17 00:00:00 2001 From: Nancy Lin Date: Wed, 12 Nov 2025 13:39:17 +0800 Subject: [PATCH] soc/mediatek/mt8196: Add dual display pipe path Add dual display pipe path. Also change the original single pipe path with DSC engine configured in relay mode. TEST=build pass and test display logo ok BUG=b:424782827 Change-Id: I2373ea63a08bf25a7eef45b947d218b445b62130 Signed-off-by: Nancy Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/90039 Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/soc/mediatek/common/display.c | 3 + src/soc/mediatek/common/include/soc/display.h | 1 + src/soc/mediatek/mt8196/ddp.c | 263 ++++++++++++++---- .../mediatek/mt8196/include/soc/addressmap.h | 22 ++ src/soc/mediatek/mt8196/include/soc/ddp.h | 183 +++++++++--- 5 files changed, 377 insertions(+), 95 deletions(-) diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index 8e3979df26..f48cdaf215 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -191,6 +191,9 @@ int mtk_display_init(void) if (info) fb_set_orientation(info, panel->orientation); + if (panel->disp_path == DISP_PATH_DUAL_MIPI) + fb_set_dual_pipe_flag(info, true); + if (CONFIG(BMP_LOGO)) display_logo(panel, fb_addr, &edid); diff --git a/src/soc/mediatek/common/include/soc/display.h b/src/soc/mediatek/common/include/soc/display.h index fdcfcfdef2..f202c1d40e 100644 --- a/src/soc/mediatek/common/include/soc/display.h +++ b/src/soc/mediatek/common/include/soc/display.h @@ -11,6 +11,7 @@ enum disp_path_sel { DISP_PATH_NONE = 0, DISP_PATH_EDP, DISP_PATH_MIPI, + DISP_PATH_DUAL_MIPI, }; #define PANEL_QUIRK_FORCE_MAX_SWING BIT(0) diff --git a/src/soc/mediatek/mt8196/ddp.c b/src/soc/mediatek/mt8196/ddp.c index 6e57e78301..6e63b376cd 100644 --- a/src/soc/mediatek/mt8196/ddp.c +++ b/src/soc/mediatek/mt8196/ddp.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +#include #include #include #include @@ -7,6 +8,40 @@ #include #define SIZE(w, h) ((u32)(h) << 16 | (w)) +#define DUAL_PIPE(path) ((path) == DISP_PATH_DUAL_MIPI) + +struct disp_pipe_regs { + struct disp_mdp_rsz_regs *const mdp_rsz; + struct disp_tdshp_regs *const tdshp; + struct disp_ccorr_regs *const ccorr0; + struct disp_ccorr_regs *const ccorr1; + struct disp_gamma_regs *const gamma; + struct disp_postmask_regs *const postmask; + struct disp_dither_regs *const dither; + struct disp_dsc_regs *const dsc; +}; + +static const struct disp_pipe_regs disp_pipe0_regs = { + .mdp_rsz = disp_mdp_rsz0_reg, + .tdshp = disp_tdshp0_reg, + .ccorr0 = disp_ccorr0_reg, + .ccorr1 = disp_ccorr1_reg, + .gamma = disp_gamma0_reg, + .postmask = disp_postmask0_reg, + .dither = disp_dither0_reg, + .dsc = disp_dsc2_reg, +}; + +static const struct disp_pipe_regs disp_pipe1_regs = { + .mdp_rsz = disp_mdp_rsz1_reg, + .tdshp = disp_tdshp1_reg, + .ccorr0 = disp_ccorr2_reg, + .ccorr1 = disp_ccorr3_reg, + .gamma = disp_gamma1_reg, + .postmask = disp_postmask1_reg, + .dither = disp_dither1_reg, + .dsc = disp_dsc3_reg, +}; static void blender_config(struct blender *reg, u16 width, u16 height, enum mtk_disp_blender_layer type) @@ -121,19 +156,37 @@ static void dither_start(struct disp_dither_regs *reg) setbits32(®->en, BIT(0)); } +static void dsc_config(struct disp_dsc_regs *reg, u16 width, u16 height) +{ + write32(®->dsc_con, BIT(5)); + write32(®->pic_w, width); + write32(®->pic_h, height); + write32(®->chunk_size, width << 16); +} + +static void dsc_start(struct disp_dsc_regs *reg) +{ + setbits32(®->dsc_con, BIT(0)); +} + +static void ovlsys_path_connect(struct ovlsys_cfg *reg) +{ + setbits32(®->bypass_mux_shadow, BIT(0)); + write32(®->cb_con, 0xFF << 16); + setbits32(®->rsz_in_cb2, BIT(1)); + setbits32(®->exdma_out_cb3, BIT(2)); + setbits32(®->blender_out_cb4, BIT(0)); + setbits32(®->outproc_out_cb0, BIT(0)); +} + static void disp_config_main_path_connection(enum disp_path_sel path) { /* ovlsys */ - setbits32(&ovlsys_cfg->bypass_mux_shadow, BIT(0)); - write32(&ovlsys_cfg->cb_con, 0xFF << 16); - setbits32(&ovlsys_cfg->rsz_in_cb2, BIT(1)); - setbits32(&ovlsys_cfg->exdma_out_cb3, BIT(2)); - setbits32(&ovlsys_cfg->blender_out_cb4, BIT(0)); - setbits32(&ovlsys_cfg->outproc_out_cb0, BIT(0)); + ovlsys_path_connect(ovlsys_cfg); /* dispsys */ write32(&mmsys_cfg->bypass_mux_shadow, 0xFF << 16 | BIT(0)); - setbits32(&mmsys_cfg->pq_in_cb0, BIT(0)); + setbits32(&mmsys_cfg->pq_in_cb[0], BIT(0)); setbits32(&mmsys_cfg->disp_mdp_rsz0_mout, BIT(0)); write32(&mmsys_cfg->disp_tdshp0_sout, 0x2); write32(&mmsys_cfg->disp_ccorr0_sel, 0x2); @@ -142,45 +195,95 @@ static void disp_config_main_path_connection(enum disp_path_sel path) write32(&mmsys_cfg->disp_ccorr1_sout, 0x1); write32(&mmsys_cfg->disp_gamma0_sel, 0x1); write32(&mmsys_cfg->disp_postmask_sout, 0x0); - setbits32(&mmsys_cfg->pq_out_cb0, BIT(1)); + setbits32(&mmsys_cfg->pq_out_cb[0], BIT(1)); setbits32(&mmsys_cfg->panel_comp_out_cb1, BIT(1)); /* dispsys1 */ write32(&mmsys1_cfg->bypass_mux_shadow, 0xFF << 16 | BIT(0)); setbits32(&mmsys1_cfg->splitter_in_cb1, BIT(5)); - setbits32(&mmsys1_cfg->splitter_out_cb9, BIT(10)); - setbits32(&mmsys1_cfg->comp_out_cb6, BIT(0)); - if (path == DISP_PATH_EDP) + setbits32(&mmsys1_cfg->splitter_out_cb9, BIT(5)); + setbits32(&mmsys1_cfg->comp_out_cb3, BIT(0)); + + if (DUAL_PIPE(path)) { + /* ovlsys1 */ + ovlsys_path_connect(ovlsys1_cfg); + /* dispsys */ + setbits32(&mmsys_cfg->pq_in_cb[8], BIT(1)); + setbits32(&mmsys_cfg->disp_mdp_rsz1_mout, BIT(0)); + write32(&mmsys_cfg->disp_tdshp1_sout, 0x2); + write32(&mmsys_cfg->disp_ccorr2_sel, 0x2); + write32(&mmsys_cfg->disp_ccorr2_sout, 0x1); + write32(&mmsys_cfg->disp_ccorr3_sel, 0x1); + write32(&mmsys_cfg->disp_ccorr3_sout, 0x1); + write32(&mmsys_cfg->disp_gamma1_sel, 0x1); + write32(&mmsys_cfg->disp_postmask1_sout, 0x0); + setbits32(&mmsys_cfg->pq_out_cb[3], BIT(2)); + setbits32(&mmsys_cfg->panel_comp_out_cb2, BIT(2)); + + /* dispsys1 */ + setbits32(&mmsys1_cfg->splitter_in_cb2, BIT(8)); + setbits32(&mmsys1_cfg->splitter_out_cb12, BIT(7)); + setbits32(&mmsys1_cfg->comp_out_cb4, BIT(3)); + } + + if (path == DISP_PATH_EDP) { setbits32(&mmsys1_cfg->merge_out_cb0, BIT(9)); - else + } else if (path == DISP_PATH_MIPI) { setbits32(&mmsys1_cfg->merge_out_cb0, BIT(0)); + } else { + setbits32(&mmsys1_cfg->merge_out_cb0, BIT(0)); + setbits32(&mmsys1_cfg->merge_out_cb3, BIT(3)); + } } -static void async_config(u16 width, u16 height) +static void async_config(u16 width, u16 height, enum disp_path_sel path) { + u32 relay = BIT(30) | SIZE(width, height); + write32(&ovlsys_cfg->relay5_size, SIZE(width, height)); - write32(&mmsys_cfg->dl_in_relay0, BIT(30) | SIZE(width, height)); - write32(&mmsys_cfg->dl_out_relay1, BIT(30) | SIZE(width, height)); - write32(&mmsys1_cfg->dl_in_relay21, BIT(30) | SIZE(width, height)); + write32(&mmsys_cfg->dl_in_relay[0], relay); + write32(&mmsys_cfg->dl_out_relay[1], relay); + write32(&mmsys1_cfg->dl_in_relay21, relay); + + if (DUAL_PIPE(path)) { + write32(&ovlsys1_cfg->relay5_size, SIZE(width, height)); + write32(&mmsys_cfg->dl_in_relay[8], relay); + write32(&mmsys_cfg->dl_out_relay[2], relay); + write32(&mmsys1_cfg->dl_in_relay22, relay); + } } static void disp_config_main_path_mutex(enum disp_path_sel path) { - u32 val; + u32 val, val1; /* ovlsys mutex */ write32(&mmsys_mutex[OVL0]->mutex[0].mod, MUTEX_MOD_OVL_MAIN_PATH); write32(&mmsys_mutex[OVL0]->mutex[0].mod1, MUTEX_MOD1_OVL_MAIN_PATH); + if (DUAL_PIPE(path)) { + write32(&mmsys_mutex[OVL1]->mutex[0].mod, MUTEX_MOD_OVL_MAIN_PATH_DUAL); + write32(&mmsys_mutex[OVL1]->mutex[0].mod1, MUTEX_MOD1_OVL_MAIN_PATH_DUAL); + } + /* dispsys mutex */ - write32(&mmsys_mutex[DISP0]->mutex[0].mod, MUTEX_MOD_DISP_MAIN_PATH); - write32(&mmsys_mutex[DISP0]->mutex[0].mod1, MUTEX_MOD1_DISP_MAIN_PATH); + val = MUTEX_MOD_DISP_MAIN_PATH; + val1 = MUTEX_MOD1_DISP_MAIN_PATH; + if (DUAL_PIPE(path)) { + val |= MUTEX_MOD_DISP_MAIN_PATH_DUAL; + val1 |= MUTEX_MOD1_DISP_MAIN_PATH_DUAL; + } + write32(&mmsys_mutex[DISP0]->mutex[0].mod, val); + write32(&mmsys_mutex[DISP0]->mutex[0].mod1, val1); /* dispsys1 mutex */ if (path == DISP_PATH_EDP) - write32(&mmsys_mutex[DISP1]->mutex[0].mod, MUTEX_MOD_DISP1_MAIN_PATH_EDP); + val = MUTEX_MOD_DISP1_MAIN_PATH_EDP; + else if (path == DISP_PATH_MIPI) + val = MUTEX_MOD_DISP1_MAIN_PATH_DSI0; else - write32(&mmsys_mutex[DISP1]->mutex[0].mod, MUTEX_MOD_DISP1_MAIN_PATH_DSI0); + val = MUTEX_MOD_DISP1_MAIN_PATH_DUAL_DSI; + write32(&mmsys_mutex[DISP1]->mutex[0].mod, val); /* mutex source from DVO */ if (path == DISP_PATH_EDP) @@ -188,52 +291,81 @@ static void disp_config_main_path_mutex(enum disp_path_sel path) else val = MUTEX_SOF_DSI0 | (MUTEX_SOF_DSI0 << 7); write32(&mmsys_mutex[OVL0]->mutex[0].ctl, val); + if (DUAL_PIPE(path)) + write32(&mmsys_mutex[OVL1]->mutex[0].ctl, val); write32(&mmsys_mutex[DISP0]->mutex[0].ctl, val); write32(&mmsys_mutex[DISP1]->mutex[0].ctl, val); /* mutex enable */ write32(&mmsys_mutex[OVL0]->mutex[0].en, BIT(0)); + if (DUAL_PIPE(path)) + write32(&mmsys_mutex[OVL1]->mutex[0].en, BIT(0)); write32(&mmsys_mutex[DISP0]->mutex[0].en, BIT(0)); write32(&mmsys_mutex[DISP1]->mutex[0].en, BIT(0)); } -static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_path_sel path) +static void disp_config_blender(struct blender *const blenders[], size_t size, u16 width, + u16 height) { int i; - enum mtk_disp_blender_layer blender_type[ARRAY_SIZE(blenders)] = { + static const enum mtk_disp_blender_layer blender_type[] = { FIRST_BLENDER, OTHER_BLENDER, OTHER_BLENDER, LAST_BLENDER, }; + assert(size <= ARRAY_SIZE(blender_type)); + /* ovlsys config */ - for (i = 0; i < ARRAY_SIZE(blenders); i++) { + for (i = 0; i < size; i++) { blender_config(blenders[i], width, height, blender_type[i]); blender_start(blenders[i]); } +} - outproc_config(outproc0_reg, width, height); - outproc_start(outproc0_reg); +static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_path_sel path) +{ + u16 w = width; + size_t num_pipe = DUAL_PIPE(path) ? 2 : 1; + const struct disp_pipe_regs pipes[] = {disp_pipe0_regs, disp_pipe1_regs}; + + if (DUAL_PIPE(path)) + w /= 2; + + disp_config_blender(ovl_blenders, ARRAY_SIZE(ovl_blenders), w, height); + if (DUAL_PIPE(path)) + disp_config_blender(ovl1_blenders, ARRAY_SIZE(ovl1_blenders), w, height); + + outproc_config(ovl_outproc0_reg, w, height); + outproc_start(ovl_outproc0_reg); + if (DUAL_PIPE(path)) { + outproc_config(ovl1_outproc0_reg, w, height); + outproc_start(ovl1_outproc0_reg); + } /* disp config */ - mdp_rsz_config(disp_mdp_rsz0_reg, width, height); - mdp_rsz_start(disp_mdp_rsz0_reg); - tdshp_config(disp_tdshp0_reg, width, height); - tdshp_start(disp_tdshp0_reg); - ccorr_config(disp_ccorr0_reg, width, height); - ccorr_start(disp_ccorr0_reg); - ccorr_config(disp_ccorr1_reg, width, height); - ccorr_start(disp_ccorr1_reg); - gamma_config(disp_gamma0_reg, width, height); - gamma_start(disp_gamma0_reg); - postmask_config(disp_postmask0_reg, width, height); - postmask_start(disp_postmask0_reg); - dither_config(disp_dither0_reg, width, height); - dither_start(disp_dither0_reg); + for (int i = 0; i < num_pipe; i++) { + mdp_rsz_config(pipes[i].mdp_rsz, w, height); + mdp_rsz_start(pipes[i].mdp_rsz); + tdshp_config(pipes[i].tdshp, w, height); + tdshp_start(pipes[i].tdshp); + ccorr_config(pipes[i].ccorr0, w, height); + ccorr_start(pipes[i].ccorr0); + ccorr_config(pipes[i].ccorr1, w, height); + ccorr_start(pipes[i].ccorr1); + gamma_config(pipes[i].gamma, w, height); + gamma_start(pipes[i].gamma); + postmask_config(pipes[i].postmask, w, height); + postmask_start(pipes[i].postmask); + dither_config(pipes[i].dither, w, height); + dither_start(pipes[i].dither); + dsc_config(pipes[i].dsc, w, height); + dsc_start(pipes[i].dsc); + } /* async config */ - async_config(width, height); + async_config(w, height, path); /* path connect */ disp_config_main_path_connection(path); @@ -255,25 +387,40 @@ static void disp_clock_on(void) clrbits32(&ovlsys_cfg->mmsys_cg_con2, CG_CON_ALL); } -static void ovlsys_layer_config(u32 fmt, u32 bpp, u16 width, u16 height) +static void ovlsys_layer_config_pipe(struct exdma *exdma, struct blender *blender, + u32 fmt, u16 width, u16 height, u16 pitch) { /* exdma config */ - write32(&exdma2_reg->roi_size, SIZE(width, height)); - write32(&exdma2_reg->ovl_l_size, SIZE(width, height)); - write32(&exdma2_reg->pitch, (width * bpp) & 0xFFFF); - write32(&exdma2_reg->ovl_l_clrfmt, fmt); + write32(&exdma->roi_size, SIZE(width, height)); + write32(&exdma->ovl_l_size, SIZE(width, height)); + write32(&exdma->pitch, pitch & 0xFFFF); + write32(&exdma->ovl_l_clrfmt, fmt); /* exdma start */ - clrsetbits32(&exdma2_reg->rdma_burst_ctl, BIT(28) | BIT(30) | BIT(31), + clrsetbits32(&exdma->rdma_burst_ctl, BIT(28) | BIT(30) | BIT(31), BIT(28) | BIT(31)); - setbits32(&exdma2_reg->dummy, BIT(2) | BIT(3)); - setbits32(&exdma2_reg->datapath_con, BIT(0) | BIT(24) | BIT(25)); - clrsetbits32(&exdma2_reg->ovl_mout, BIT(0) | BIT(1), BIT(1)); - write32(&exdma2_reg->gdrdy_period, 0xFFFFFFFF); + setbits32(&exdma->dummy, BIT(2) | BIT(3)); + setbits32(&exdma->datapath_con, BIT(0) | BIT(24) | BIT(25)); + clrsetbits32(&exdma->ovl_mout, BIT(0) | BIT(1), BIT(1)); + write32(&exdma->gdrdy_period, 0xFFFFFFFF); /* Enable layer */ - setbits32(&exdma2_reg->rdma0_ctl, BIT(0)); - setbits32(&blenders[0]->bld_l_fmt, fmt); + setbits32(&exdma->rdma0_ctl, BIT(0)); + setbits32(&blender->bld_l_fmt, fmt); +} + +static void ovlsys_layer_config(u32 fmt, u32 bpp, u16 width, u16 height, + enum disp_path_sel path) +{ + u16 w = width; + + if (DUAL_PIPE(path)) + w /= 2; + + ovlsys_layer_config_pipe(ovl_exdma2_reg, ovl_blenders[0], fmt, w, height, width * bpp); + if (DUAL_PIPE(path)) + ovlsys_layer_config_pipe(ovl1_exdma2_reg, ovl1_blenders[0], fmt, w, height, + width * bpp); } void mtk_ddp_init(void) @@ -308,13 +455,13 @@ void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path) width, height, 0x1FFF); main_disp_path_setup(width, height, vrefresh, path); - ovlsys_layer_config(fmt, bpp, width, height); + ovlsys_layer_config(fmt, bpp, width, height, path); } void mtk_ddp_ovlsys_start(uintptr_t fb_addr) { - write32(&exdma2_reg->ovl_addr, fb_addr); - setbits32(&exdma2_reg->ovl_en, BIT(0)); - setbits32(&exdma2_reg->ovl_l_en, BIT(0)); - setbits32(&blenders[0]->bld_l_en, BIT(0)); + write32(&ovl_exdma2_reg->ovl_addr, fb_addr); + setbits32(&ovl_exdma2_reg->ovl_en, BIT(0)); + setbits32(&ovl_exdma2_reg->ovl_l_en, BIT(0)); + setbits32(&ovl_blenders[0]->bld_l_en, BIT(0)); } diff --git a/src/soc/mediatek/mt8196/include/soc/addressmap.h b/src/soc/mediatek/mt8196/include/soc/addressmap.h index 65257eb769..dd16892646 100644 --- a/src/soc/mediatek/mt8196/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8196/include/soc/addressmap.h @@ -196,25 +196,47 @@ enum { MMSYS_MUTEX_BASE = IO_PHYS + 0x22020000, DISP_CCORR0_BASE = IO_PHYS + 0x22090000, DISP_CCORR1_BASE = IO_PHYS + 0x220A0000, + DISP_CCORR2_BASE = IO_PHYS + 0x220B0000, + DISP_CCORR3_BASE = IO_PHYS + 0x220C0000, DISP_COLOR0_BASE = IO_PHYS + 0x220F0000, DISP_DITHER0_BASE = IO_PHYS + 0x22110000, + DISP_DITHER1_BASE = IO_PHYS + 0x22120000, DISP_GAMMA0_BASE = IO_PHYS + 0x22130000, + DISP_GAMMA1_BASE = IO_PHYS + 0x22140000, DISP_POSTMASK0_BASE = IO_PHYS + 0x22180000, + DISP_POSTMASK1_BASE = IO_PHYS + 0x22190000, DISP_MDP_RSZ0_BASE = IO_PHYS + 0x221A0000, + DISP_MDP_RSZ1_BASE = IO_PHYS + 0x221B0000, DISP_TDSHP0_BASE = IO_PHYS + 0x221E0000, + DISP_TDSHP1_BASE = IO_PHYS + 0x221F0000, MMSYS1_CONFIG_BASE = IO_PHYS + 0x22400000, MMSYS1_MUTEX_BASE = IO_PHYS + 0x22420000, + DSC2_BASE = IO_PHYS + 0x22470000, + DSC3_BASE = IO_PHYS + 0x22480000, DSI0_BASE = IO_PHYS + 0x22490000, DISP_DVO0 = IO_PHYS + 0x224C0000, OVLSYS_CONFIG_BASE = IO_PHYS + 0x22800000, OVLSYS_MUTEX_BASE = IO_PHYS + 0x22820000, OVLSYS_EXDMA2_BASE = IO_PHYS + 0x22850000, + OVLSYS_EXDMA6_BASE = IO_PHYS + 0x22890000, OVLSYS_BLENDER1_BASE = IO_PHYS + 0x228E0000, OVLSYS_BLENDER2_BASE = IO_PHYS + 0x228F0000, OVLSYS_BLENDER3_BASE = IO_PHYS + 0x22900000, OVLSYS_BLENDER4_BASE = IO_PHYS + 0x22910000, + OVLSYS_BLENDER5_BASE = IO_PHYS + 0x22920000, + OVLSYS_BLENDER6_BASE = IO_PHYS + 0x22930000, + OVLSYS_BLENDER7_BASE = IO_PHYS + 0x22940000, + OVLSYS_BLENDER8_BASE = IO_PHYS + 0x22950000, OVLSYS_OUTPROC0_BASE = IO_PHYS + 0x22970000, + OVLSYS_OUTPROC1_BASE = IO_PHYS + 0x22980000, OVLSYS1_CONFIG_BASE = IO_PHYS + 0x22C00000, + OVLSYS1_MUTEX_BASE = IO_PHYS + 0x22C20000, + OVLSYS1_EXDMA2_BASE = IO_PHYS + 0x22C50000, + OVLSYS1_BLENDER1_BASE = IO_PHYS + 0x22CE0000, + OVLSYS1_BLENDER2_BASE = IO_PHYS + 0x22CF0000, + OVLSYS1_BLENDER3_BASE = IO_PHYS + 0x22D00000, + OVLSYS1_BLENDER4_BASE = IO_PHYS + 0x22D10000, + OVLSYS1_OUTPROC0_BASE = IO_PHYS + 0x22D70000, DISP_VDISP_AO_CONFIG_BASE = IO_PHYS + 0x2E800000, EDP_CLK_BASE = IO_PHYS + 0x21B50000, EDP_BASE = IO_PHYS + 0x2EC40000, diff --git a/src/soc/mediatek/mt8196/include/soc/ddp.h b/src/soc/mediatek/mt8196/include/soc/ddp.h index c2fbbb36ee..2c91747345 100644 --- a/src/soc/mediatek/mt8196/include/soc/ddp.h +++ b/src/soc/mediatek/mt8196/include/soc/ddp.h @@ -24,7 +24,8 @@ struct ovlsys_cfg { u32 mmsys_cg_clr2; u32 reserved_0x12c[92]; u32 relay5_size; - u32 reserved_0x2a0[640]; + u32 relay6_size; + u32 reserved_0x2a4[639]; u32 bypass_mux_shadow; u32 reserved_0xca4; u32 reserved_0xca8; @@ -33,13 +34,15 @@ struct ovlsys_cfg { u32 blender_out_cb4; u32 reserved_0xe14; u32 reserved_0xe18; - u32 reserved_0xe1c[17]; - u32 reserved_0xe60; - u32 reserved_0xe64; + u32 reserved_0xe1c; + u32 blender_out_cb8; + u32 reserved_0xe24[17]; u32 exdma_out_cb3; - u32 reserved_0xe6c[41]; + u32 reserved_0xe6c[7]; + u32 exdma_out_cb7; + u32 reserved_0xe8c[33]; u32 outproc_out_cb0; - u32 reserved_0xf14; + u32 outproc_out_cb1; u32 reserved_0xf18[22]; u32 rsz_in_cb2; }; @@ -48,14 +51,19 @@ check_member(ovlsys_cfg, mmsys_cg_con0, 0x100); check_member(ovlsys_cfg, mmsys_cg_con1, 0x110); check_member(ovlsys_cfg, mmsys_cg_con2, 0x120); check_member(ovlsys_cfg, relay5_size, 0x29C); +check_member(ovlsys_cfg, relay6_size, 0x2A0); check_member(ovlsys_cfg, bypass_mux_shadow, 0xCA0); check_member(ovlsys_cfg, cb_con, 0xCAC); check_member(ovlsys_cfg, blender_out_cb4, 0xE10); +check_member(ovlsys_cfg, blender_out_cb8, 0xE20); check_member(ovlsys_cfg, exdma_out_cb3, 0xE68); +check_member(ovlsys_cfg, exdma_out_cb7, 0xE88); check_member(ovlsys_cfg, outproc_out_cb0, 0xF10); +check_member(ovlsys_cfg, outproc_out_cb1, 0xF14); check_member(ovlsys_cfg, rsz_in_cb2, 0xF70); static struct ovlsys_cfg *const ovlsys_cfg = (void *)OVLSYS_CONFIG_BASE; +static struct ovlsys_cfg *const ovlsys1_cfg = (void *)OVLSYS1_CONFIG_BASE; struct dispsys_cfg { u32 reserved_0x000[64]; @@ -71,50 +79,58 @@ struct dispsys_cfg { u32 mmsys_cg_set2; u32 mmsys_cg_clr2; u32 reserved_0x12c[53]; - u32 dl_in_relay0; - u32 reserved_0x204[25]; - u32 dl_out_relay1; - u32 reserved_0x26c[625]; + u32 dl_in_relay[9]; + u32 reserved_0x224[16]; + u32 dl_out_relay[9]; + u32 reserved_0x288[618]; u32 bypass_mux_shadow; u32 reserved_0xc34[61]; u32 disp_ccorr0_sel; u32 disp_ccorr0_sout; u32 disp_ccorr1_sel; u32 disp_ccorr1_sout; - u32 reserved_0xd38[8]; + u32 disp_ccorr2_sel; + u32 disp_ccorr2_sout; + u32 disp_ccorr3_sel; + u32 disp_ccorr3_sout; + u32 reserved_0xd48[4]; u32 disp_gamma0_sel; - u32 reserved_0xd5c[3]; + u32 disp_gamma1_sel; + u32 reserved_0xd60[2]; u32 disp_postmask_sout; - u32 reserved_0xd6c; + u32 disp_postmask1_sout; u32 disp_tdshp0_sout; - u32 reserved_0xd74; + u32 disp_tdshp1_sout; u32 disp_mdp_rsz0_mout; - u32 reserved_0xd7c[2]; + u32 disp_mdp_rsz1_mout; + u32 reserved_0xd80; u32 panel_comp_out_cb1; - u32 reserved_0xd88[18]; - u32 pq_in_cb0; - u32 reserved_0xdd4[26]; - u32 pq_out_cb0; - u32 pq_out_cb1; - u32 pq_out_cb2; - u32 reserved_0xe40[3]; - u32 pq_out_cb6; + u32 panel_comp_out_cb2; + u32 reserved_0xd8c[17]; + u32 pq_in_cb[9]; + u32 reserved_0xdf4[18]; + u32 pq_out_cb[7]; }; check_member(dispsys_cfg, mmsys_cg_con0, 0x100); check_member(dispsys_cfg, mmsys_cg_con1, 0x110); check_member(dispsys_cfg, mmsys_cg_con2, 0x120); -check_member(dispsys_cfg, dl_in_relay0, 0x200); -check_member(dispsys_cfg, dl_out_relay1, 0x268); +check_member(dispsys_cfg, dl_in_relay[0], 0x200); +check_member(dispsys_cfg, dl_out_relay[0], 0x264); check_member(dispsys_cfg, bypass_mux_shadow, 0xC30); check_member(dispsys_cfg, disp_ccorr0_sel, 0xD28); check_member(dispsys_cfg, disp_gamma0_sel, 0xD58); +check_member(dispsys_cfg, disp_gamma1_sel, 0xD5C); check_member(dispsys_cfg, disp_postmask_sout, 0xD68); +check_member(dispsys_cfg, disp_postmask1_sout, 0xD6C); check_member(dispsys_cfg, disp_tdshp0_sout, 0xD70); +check_member(dispsys_cfg, disp_tdshp1_sout, 0xD74); +check_member(dispsys_cfg, disp_mdp_rsz0_mout, 0xD78); +check_member(dispsys_cfg, disp_mdp_rsz1_mout, 0xD7C); check_member(dispsys_cfg, panel_comp_out_cb1, 0xD84); -check_member(dispsys_cfg, pq_in_cb0, 0xDD0); -check_member(dispsys_cfg, pq_out_cb0, 0xE3C); -check_member(dispsys_cfg, pq_out_cb6, 0xE54); +check_member(dispsys_cfg, panel_comp_out_cb2, 0xD88); +check_member(dispsys_cfg, pq_in_cb[0], 0xDD0); +check_member(dispsys_cfg, pq_out_cb[0], 0xE3C); static struct dispsys_cfg *const mmsys_cfg = (void *)MMSYS_CONFIG_BASE; @@ -133,27 +149,47 @@ struct dispsys1_cfg { u32 mmsys_cg_clr2; u32 reserved_0x12c[54]; u32 dl_in_relay21; - u32 reserved_0x208[700]; + u32 dl_in_relay22; + u32 reserved_0x20c[699]; u32 bypass_mux_shadow; - u32 reserved_0xcfc[13]; + u32 reserved_0xcfc[7]; + u32 comp_out_cb3; + u32 reserved_0xd1c; + u32 comp_out_cb4; + u32 reserved_0xd24[3]; u32 comp_out_cb6; - u32 reserved_0xd34[38]; + u32 reserved_0xd34; + u32 comp_out_cb7; + u32 reserved_0xd3c[36]; u32 merge_out_cb0; - u32 reserved_0xdd0[55]; + u32 reserved_0xdd0[5]; + u32 merge_out_cb3; + u32 reserved_0xde8[49]; u32 splitter_in_cb1; - u32 reserved_0xeb0[45]; + u32 reserved_0xeb0; + u32 splitter_in_cb2; + u32 reserved_0xeb8[43]; u32 splitter_out_cb9; + u32 reserved_0xf68[5]; + u32 splitter_out_cb12; }; check_member(dispsys1_cfg, mmsys_cg_con0, 0x100); check_member(dispsys1_cfg, mmsys_cg_con1, 0x110); check_member(dispsys1_cfg, mmsys_cg_con2, 0x120); check_member(dispsys1_cfg, dl_in_relay21, 0x204); +check_member(dispsys1_cfg, dl_in_relay22, 0x208); check_member(dispsys1_cfg, bypass_mux_shadow, 0xCF8); +check_member(dispsys1_cfg, comp_out_cb3, 0xD18); +check_member(dispsys1_cfg, comp_out_cb4, 0xD20); check_member(dispsys1_cfg, comp_out_cb6, 0xD30); +check_member(dispsys1_cfg, comp_out_cb7, 0xD38); check_member(dispsys1_cfg, merge_out_cb0, 0xDCC); +check_member(dispsys1_cfg, merge_out_cb3, 0xDE4); check_member(dispsys1_cfg, splitter_in_cb1, 0xEAC); +check_member(dispsys1_cfg, splitter_in_cb2, 0xEB4); check_member(dispsys1_cfg, splitter_out_cb9, 0xF64); +check_member(dispsys1_cfg, splitter_out_cb12, 0xF7C); static struct dispsys1_cfg *const mmsys1_cfg = (void *)MMSYS1_CONFIG_BASE; @@ -204,7 +240,8 @@ check_member(exdma, pitch, 0x2F4); check_member(exdma, ovl_addr, 0xF40); check_member(exdma, ovl_mout, 0xFF0); -static struct exdma *const exdma2_reg = (void *)OVLSYS_EXDMA2_BASE; +static struct exdma *const ovl_exdma2_reg = (void *)OVLSYS_EXDMA2_BASE; +static struct exdma *const ovl1_exdma2_reg = (void *)OVLSYS1_EXDMA2_BASE; struct blender { u32 reserved_0x000[4]; @@ -237,13 +274,20 @@ check_member(blender, bld_l_fmt, 0x050); check_member(blender, bg_clr, 0x104); check_member(blender, bld_l_con2, 0x200); -static struct blender *const blenders[] = { +static struct blender *const ovl_blenders[] = { (void *)OVLSYS_BLENDER1_BASE, (void *)OVLSYS_BLENDER2_BASE, (void *)OVLSYS_BLENDER3_BASE, (void *)OVLSYS_BLENDER4_BASE, }; +static struct blender *const ovl1_blenders[] = { + (void *)OVLSYS1_BLENDER1_BASE, + (void *)OVLSYS1_BLENDER2_BASE, + (void *)OVLSYS1_BLENDER3_BASE, + (void *)OVLSYS1_BLENDER4_BASE, +}; + struct outproc { u32 reserved_0x000[4]; u32 datapath_con; @@ -260,7 +304,8 @@ check_member(outproc, outproc_en, 0x020); check_member(outproc, shadow_ctl, 0x028); check_member(outproc, roi_size, 0x030); -static struct outproc *const outproc0_reg = (void *)OVLSYS_OUTPROC0_BASE; +static struct outproc *const ovl_outproc0_reg = (void *)OVLSYS_OUTPROC0_BASE; +static struct outproc *const ovl1_outproc0_reg = (void *)OVLSYS1_OUTPROC0_BASE; struct disp_mutex { u32 inten; @@ -282,12 +327,14 @@ enum mmsys { DISP0, DISP1, OVL0, + OVL1, }; static struct disp_mutex *const mmsys_mutex[] = { [DISP0] = (void *)MMSYS_MUTEX_BASE, [DISP1] = (void *)MMSYS1_MUTEX_BASE, [OVL0] = (void *)OVLSYS_MUTEX_BASE, + [OVL1] = (void *)OVLSYS1_MUTEX_BASE, }; enum { @@ -303,59 +350,98 @@ enum { /* OVLSYS mutex module */ enum { MUTEX_MOD_OVL_EXDMA2 = BIT(2), + MUTEX_MOD_OVL_EXDMA6 = BIT(6), MUTEX_MOD_OVL_BLENDER1 = BIT(11), MUTEX_MOD_OVL_BLENDER2 = BIT(12), MUTEX_MOD_OVL_BLENDER3 = BIT(13), MUTEX_MOD_OVL_BLENDER4 = BIT(14), + MUTEX_MOD_OVL_BLENDER5 = BIT(15), + MUTEX_MOD_OVL_BLENDER6 = BIT(16), + MUTEX_MOD_OVL_BLENDER7 = BIT(17), + MUTEX_MOD_OVL_BLENDER8 = BIT(18), MUTEX_MOD_OVL_OUTPROC0 = BIT(20), + MUTEX_MOD_OVL_OUTPROC1 = BIT(21), MUTEX_MOD_OVL_MAIN_PATH = MUTEX_MOD_OVL_EXDMA2 | MUTEX_MOD_OVL_BLENDER1 | MUTEX_MOD_OVL_BLENDER2 | MUTEX_MOD_OVL_BLENDER3 | MUTEX_MOD_OVL_BLENDER4 | MUTEX_MOD_OVL_OUTPROC0, + MUTEX_MOD_OVL_MAIN_PATH_DUAL = MUTEX_MOD_OVL_MAIN_PATH, }; enum { MUTEX_MOD1_OVL_DLO_ASYNC5 = BIT(16), + MUTEX_MOD1_OVL_DLO_ASYNC6 = BIT(17), MUTEX_MOD1_OVL_MAIN_PATH = MUTEX_MOD1_OVL_DLO_ASYNC5, + MUTEX_MOD1_OVL_MAIN_PATH_DUAL = MUTEX_MOD1_OVL_MAIN_PATH, }; /* DISPSYS mutex module */ enum { MUTEX_MOD_DISP_CCORR0 = BIT(6), MUTEX_MOD_DISP_CCORR1 = BIT(7), + MUTEX_MOD_DISP_CCORR2 = BIT(8), + MUTEX_MOD_DISP_CCORR3 = BIT(9), MUTEX_MOD_DISP_DITHER0 = BIT(14), + MUTEX_MOD_DISP_DITHER1 = BIT(15), MUTEX_MOD_DISP_DLI_ASYNC0 = BIT(16), + MUTEX_MOD_DISP_DLI_ASYNC1 = BIT(17), + MUTEX_MOD_DISP_DLI_ASYNC8 = BIT(24), MUTEX_MOD_DISP_MAIN_PATH = MUTEX_MOD_DISP_DLI_ASYNC0 | MUTEX_MOD_DISP_CCORR0 | MUTEX_MOD_DISP_CCORR1 | MUTEX_MOD_DISP_DITHER0, - + MUTEX_MOD_DISP_MAIN_PATH_DUAL = MUTEX_MOD_DISP_DLI_ASYNC8 | + MUTEX_MOD_DISP_CCORR2 | + MUTEX_MOD_DISP_CCORR3 | + MUTEX_MOD_DISP_DITHER1, }; enum { MUTEX_MOD1_DISP_DLO_ASYNC1 = BIT(1), + MUTEX_MOD1_DISP_DLO_ASYNC2 = BIT(2), MUTEX_MOD1_DISP_GAMMA0 = BIT(9), + MUTEX_MOD1_DISP_GAMMA1 = BIT(10), MUTEX_MOD1_DISP_POSTMASK0 = BIT(14), + MUTEX_MOD1_DISP_POSTMASK1 = BIT(15), MUTEX_MOD1_DISP_MDP_RSZ0 = BIT(18), + MUTEX_MOD1_DISP_MDP_RSZ1 = BIT(19), MUTEX_MOD1_DISP_TDSHP0 = BIT(21), + MUTEX_MOD1_DISP_TDSHP1 = BIT(22), MUTEX_MOD1_DISP_MAIN_PATH = MUTEX_MOD1_DISP_MDP_RSZ0 | MUTEX_MOD1_DISP_TDSHP0 | MUTEX_MOD1_DISP_GAMMA0 | MUTEX_MOD1_DISP_POSTMASK0 | MUTEX_MOD1_DISP_DLO_ASYNC1, + MUTEX_MOD1_DISP_MAIN_PATH_DUAL = MUTEX_MOD1_DISP_MDP_RSZ1 | + MUTEX_MOD1_DISP_TDSHP1 | + MUTEX_MOD1_DISP_GAMMA1 | + MUTEX_MOD1_DISP_POSTMASK1 | + MUTEX_MOD1_DISP_DLO_ASYNC2, }; /* DISPSYS1 mutex module */ enum { MUTEX_MOD_DISP1_DLI_ASYNC21 = BIT(1), + MUTEX_MOD_DISP1_DLI_ASYNC22 = BIT(2), + MUTEX_MOD_DISP1_DSC2 = BIT(19), + MUTEX_MOD_DISP1_DSC3 = BIT(21), MUTEX_MOD_DISP1_DSI0 = BIT(23), + MUTEX_MOD_DISP1_DSI1 = BIT(25), MUTEX_MOD_DISP1_DVO = BIT(29), MUTEX_MOD_DISP1_MAIN_PATH_EDP = MUTEX_MOD_DISP1_DLI_ASYNC21 | + MUTEX_MOD_DISP1_DSC2 | MUTEX_MOD_DISP1_DVO, MUTEX_MOD_DISP1_MAIN_PATH_DSI0 = MUTEX_MOD_DISP1_DLI_ASYNC21 | MUTEX_MOD_DISP1_DSI0, + MUTEX_MOD_DISP1_MAIN_PATH_DUAL_DSI + = MUTEX_MOD_DISP1_DLI_ASYNC21 | + MUTEX_MOD_DISP1_DLI_ASYNC22 | + MUTEX_MOD_DISP1_DSC2 | + MUTEX_MOD_DISP1_DSC3 | + MUTEX_MOD_DISP1_DSI0 | + MUTEX_MOD_DISP1_DSI1, }; enum { @@ -451,12 +537,35 @@ struct disp_postmask_regs { check_member(disp_postmask_regs, size, 0x30); +struct disp_dsc_regs { + u32 dsc_con; + u32 reserved0x4[5]; + u32 pic_w; + u32 pic_h; + u32 reserved0x20; + u32 reserved0x24; + u32 chunk_size; +}; +check_member(disp_dsc_regs, dsc_con, 0x0); +check_member(disp_dsc_regs, pic_w, 0x18); +check_member(disp_dsc_regs, pic_h, 0x1C); +check_member(disp_dsc_regs, chunk_size, 0x28); + static struct disp_mdp_rsz_regs *const disp_mdp_rsz0_reg = (void *)DISP_MDP_RSZ0_BASE; +static struct disp_mdp_rsz_regs *const disp_mdp_rsz1_reg = (void *)DISP_MDP_RSZ1_BASE; static struct disp_postmask_regs *const disp_postmask0_reg = (void *)DISP_POSTMASK0_BASE; +static struct disp_postmask_regs *const disp_postmask1_reg = (void *)DISP_POSTMASK1_BASE; static struct disp_tdshp_regs *const disp_tdshp0_reg = (void *)DISP_TDSHP0_BASE; +static struct disp_tdshp_regs *const disp_tdshp1_reg = (void *)DISP_TDSHP1_BASE; static struct disp_ccorr_regs *const disp_ccorr0_reg = (void *)DISP_CCORR0_BASE; static struct disp_ccorr_regs *const disp_ccorr1_reg = (void *)DISP_CCORR1_BASE; +static struct disp_ccorr_regs *const disp_ccorr2_reg = (void *)DISP_CCORR2_BASE; +static struct disp_ccorr_regs *const disp_ccorr3_reg = (void *)DISP_CCORR3_BASE; static struct disp_gamma_regs *const disp_gamma0_reg = (void *)DISP_GAMMA0_BASE; +static struct disp_gamma_regs *const disp_gamma1_reg = (void *)DISP_GAMMA1_BASE; static struct disp_dither_regs *const disp_dither0_reg = (void *)DISP_DITHER0_BASE; +static struct disp_dither_regs *const disp_dither1_reg = (void *)DISP_DITHER1_BASE; +static struct disp_dsc_regs *const disp_dsc2_reg = (void *)DSC2_BASE; +static struct disp_dsc_regs *const disp_dsc3_reg = (void *)DSC3_BASE; #endif