From 7ece24634c4c5b360b515f63861361daee8f0537 Mon Sep 17 00:00:00 2001 From: Hung-Te Lin Date: Mon, 5 Aug 2019 03:08:57 +0800 Subject: soc/mediatek/mt8173: Refactor display driver to share common parts Move those will be shared by other MTK SOCs (for example, MT8183) to common/ddp.c. BUG=b:80501386,b:117254947 BRANCH=none TEST=Boots correctly on Oak Change-Id: Ie5709ab6e263caa21fdf7e799dc2ee884ffaf800 Signed-off-by: Yongqiang Niu Reviewed-on: https://review.coreboot.org/c/coreboot/+/34515 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/soc/mediatek/common/ddp.c | 82 ++++++++++++ src/soc/mediatek/common/include/soc/ddp_common.h | 157 +++++++++++++++++++++++ src/soc/mediatek/mt8173/Makefile.inc | 2 +- src/soc/mediatek/mt8173/ddp.c | 91 +------------ src/soc/mediatek/mt8173/include/soc/addressmap.h | 4 +- src/soc/mediatek/mt8173/include/soc/ddp.h | 138 +------------------- 6 files changed, 248 insertions(+), 226 deletions(-) create mode 100644 src/soc/mediatek/common/ddp.c create mode 100644 src/soc/mediatek/common/include/soc/ddp_common.h (limited to 'src/soc/mediatek') diff --git a/src/soc/mediatek/common/ddp.c b/src/soc/mediatek/common/ddp.c new file mode 100644 index 0000000000..173fa90cd7 --- /dev/null +++ b/src/soc/mediatek/common/ddp.c @@ -0,0 +1,82 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16) +#define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16) + +void ovl_set_roi(u32 idx, u32 width, u32 height, u32 color) +{ + write32(&disp_ovl[idx]->roi_size, height << 16 | width); + write32(&disp_ovl[idx]->roi_bgclr, color); +} + +void rdma_start(void) +{ + setbits_le32(&disp_rdma0->global_con, RDMA_ENGINE_EN); +} + +void rdma_config(u32 width, u32 height, u32 pixel_clk, u32 fifo_size) +{ + u32 threshold; + u32 reg; + + clrsetbits_le32(&disp_rdma0->size_con_0, 0x1FFF, width); + clrsetbits_le32(&disp_rdma0->size_con_1, 0xFFFFF, height); + + /* + * Enable FIFO underflow since DSI and DPI can't be blocked. Set the + * output threshold to 6 microseconds with 7/6 overhead to account for + * blanking, and with a pixel depth of 4 bytes: + */ + threshold = pixel_clk * 4 * 7 / 1000; + + if (threshold > fifo_size) + threshold = fifo_size; + + reg = RDMA_FIFO_UNDERFLOW_EN | RDMA_FIFO_PSEUDO_SIZE(fifo_size) | + RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold); + + write32(&disp_rdma0->fifo_con, reg); +} + +void color_start(u32 width, u32 height) +{ + + write32(&disp_color0->width, width); + write32(&disp_color0->height, height); + write32(&disp_color0->cfg_main, COLOR_BYPASS_ALL | COLOR_SEQ_SEL); + write32(&disp_color0->start, BIT(0)); +} + +void ovl_layer_config(u32 fmt, u32 bpp, u32 width, u32 height) +{ + struct disp_ovl_regs *const ovl0 = disp_ovl[0]; + write32(&ovl0->layer[0].con, fmt << 12); + write32(&ovl0->layer[0].src_size, height << 16 | width); + write32(&ovl0->layer[0].pitch, (width * bpp) & 0xFFFF); + + /* Enable layer */ + write32(&ovl0->rdma[0].ctrl, BIT(0)); + write32(&ovl0->rdma[0].mem_gmc_setting, RDMA_MEM_GMC); + + setbits_le32(&ovl0->src_con, BIT(0)); +} diff --git a/src/soc/mediatek/common/include/soc/ddp_common.h b/src/soc/mediatek/common/include/soc/ddp_common.h new file mode 100644 index 0000000000..6d00ea3c75 --- /dev/null +++ b/src/soc/mediatek/common/include/soc/ddp_common.h @@ -0,0 +1,157 @@ +/* + * 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. + */ + +#ifndef _DDP_COMMON_H_ +#define _DDP_COMMON_H_ + +#include +#include + + +struct disp_ovl_regs { + u32 sta; + u32 inten; + u32 intsta; + u32 en; + u32 trig; + u32 rst; + u8 reserved0[8]; + u32 roi_size; + u32 datapath_con; + u32 roi_bgclr; + u32 src_con; + struct { + u32 con; + u32 srckey; + u32 src_size; + u32 offset; + u32 reserved0; + u32 pitch; + u32 reserved1[2]; + } layer[4]; + u8 reserved8[16]; + struct { + u32 ctrl; + u32 mem_start_trig; + u32 mem_gmc_setting; + u32 mem_slow_con; + u32 fifo_ctrl; + u8 reserved[12]; + } rdma[4]; + u8 reserved12[148]; + u32 debug_mon_sel; + u8 reserved13[8]; + u32 rdma_mem_gmc_setting2[4]; + u8 reserved14[16]; + u32 dummy; + u8 reserved15[60]; + u32 flow_ctrl_dbg; + u32 addcon_dbg; + u32 outmux_dbg; + u32 rdma_dbg[4]; + u8 reserved16[3300]; + u32 l0_addr; + u8 reserved17[28]; + u32 l1_addr; + u8 reserved18[28]; + u32 l2_addr; + u8 reserved19[28]; + u32 l3_addr; +}; + +check_member(disp_ovl_regs, l3_addr, 0xFA0); +static struct disp_ovl_regs *const disp_ovl[2] = { + (void *)DISP_OVL0_BASE, (void *)DISP_OVL1_BASE +}; + +struct disp_rdma_regs { + u32 int_enable; + u32 int_status; + u8 reserved0[8]; + u32 global_con; + u32 size_con_0; + u32 size_con_1; + u32 target_line; + u8 reserved1[4]; + u32 mem_con; + u32 mem_start_addr; + u32 mem_src_pitch; + u32 mem_gmc_setting_0; + u32 mem_slow_con; + u32 mem_gmc_setting_1; + u8 reserved2[4]; + u32 fifo_con; + u8 reserved3[16]; + u32 cf[3][3]; + u32 cf_pre_add[3]; + u32 cf_post_add[3]; + u32 dummy; + u32 debug_out_sel; +}; + +enum { + RDMA_ENGINE_EN = BIT(0), + RDMA_FIFO_UNDERFLOW_EN = BIT(31), + RDMA_MEM_GMC = 0x40402020, +}; + +check_member(disp_rdma_regs, debug_out_sel, 0x94); +static struct disp_rdma_regs *const disp_rdma0 = (void *)DISP_RDMA0_BASE; + +struct disp_color_regs { + u8 reserved0[1024]; + u32 cfg_main; + u8 reserved1[2044]; + u32 start; + u8 reserved2[76]; + u32 width; + u32 height; +}; + +check_member(disp_color_regs, cfg_main, 0x400); +check_member(disp_color_regs, start, 0xC00); +check_member(disp_color_regs, width, 0xC50); +check_member(disp_color_regs, height, 0xC54); +static struct disp_color_regs *const disp_color0 = (void *)DISP_COLOR0_BASE; + + +enum { + COLOR_BYPASS_ALL = BIT(7), + COLOR_SEQ_SEL = BIT(13), +}; + +enum OVL_INPUT_FORMAT { + OVL_INFMT_RGB565 = 0, + OVL_INFMT_RGB888 = 1, + OVL_INFMT_RGBA8888 = 2, + OVL_INFMT_ARGB8888 = 3, + OVL_INFMT_UYVY = 4, + OVL_INFMT_YUYV = 5, + OVL_INFMT_UNKNOWN = 16, + + OVL_COLOR_BASE = 30, + OVL_INFMT_BGR565 = OVL_INFMT_RGB565 + OVL_COLOR_BASE, + OVL_INFMT_BGR888 = OVL_INFMT_RGB888 + OVL_COLOR_BASE, + OVL_INFMT_BGRA8888 = OVL_INFMT_RGBA8888 + OVL_COLOR_BASE, + OVL_INFMT_ABGR8888 = OVL_INFMT_ARGB8888 + OVL_COLOR_BASE, +}; + +void ovl_set_roi(u32 idx, u32 width, u32 height, u32 color); +void rdma_start(void); +void rdma_config(u32 width, u32 height, u32 pixel_clk, u32 fifo_size); +void color_start(u32 width, u32 height); +void ovl_layer_config(u32 fmt, u32 bpp, u32 width, u32 height); + +#endif diff --git a/src/soc/mediatek/mt8173/Makefile.inc b/src/soc/mediatek/mt8173/Makefile.inc index 1492dd1a17..510fbf0cc5 100644 --- a/src/soc/mediatek/mt8173/Makefile.inc +++ b/src/soc/mediatek/mt8173/Makefile.inc @@ -82,7 +82,7 @@ ramstage-y += ../common/rtc.c rtc.c ramstage-y += ../common/usb.c usb.c -ramstage-y += ddp.c +ramstage-y += ../common/ddp.c ddp.c ramstage-y += dsi.c ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += bl31_plat_params.c diff --git a/src/soc/mediatek/mt8173/ddp.c b/src/soc/mediatek/mt8173/ddp.c index d3d91ef96e..9f201fd0d4 100644 --- a/src/soc/mediatek/mt8173/ddp.c +++ b/src/soc/mediatek/mt8173/ddp.c @@ -21,9 +21,6 @@ #include #include -#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) { write32(&mmsys_cfg->disp_ovl0_mout_en, OVL0_MOUT_EN_COLOR0); @@ -42,52 +39,6 @@ static void disp_config_main_path_mutex(void) write32(&disp_mutex->mutex[0].en, BIT(0)); } -static void ovl_set_roi(u32 width, u32 height, u32 color) -{ - write32(&disp_ovl[0]->roi_size, height << 16 | width); - write32(&disp_ovl[0]->roi_bgclr, color); -} - -static void ovl_layer_enable(void) -{ - write32(&disp_ovl[0]->rdma[0].ctrl, BIT(0)); - write32(&disp_ovl[0]->rdma[0].mem_gmc_setting, RDMA_MEM_GMC); - - setbits_le32(&disp_ovl[0]->src_con, BIT(0)); -} - -static void rdma_start(void) -{ - setbits_le32(&disp_rdma[0]->global_con, RDMA_ENGINE_EN); -} - -static void rdma_config(u32 width, u32 height, u32 pixel_clk) -{ - u32 threshold; - u32 reg; - - /* Config width */ - clrsetbits_le32(&disp_rdma[0]->size_con_0, 0x1FFF, width); - - /* Config height */ - clrsetbits_le32(&disp_rdma[0]->size_con_1, 0xFFFFF, height); - - /* - * Enable FIFO underflow since DSI and DPI can't be blocked. Keep the - * FIFO pseudo size reset default of 8 KiB. Set the output threshold to - * 6 microseconds with 7/6 overhead to account for blanking, and with a - * pixel depth of 4 bytes: - */ - - threshold = pixel_clk * 4 * 7 / 1000; - - reg = RDMA_FIFO_UNDERFLOW_EN | - RDMA_FIFO_PSEUDO_SIZE(8 * KiB) | - RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold); - - write32(&disp_rdma[0]->fifo_con, reg); -} - static void od_start(u32 width, u32 height) { write32(&disp_od->size, width << 16 | height); @@ -96,49 +47,14 @@ static void od_start(u32 width, u32 height) write32(&disp_od->en, 1); } -static void ufoe_start(u32 width, u32 height) -{ - write32(&disp_ufoe->start, UFO_BYPASS); -} - -static void color_start(u32 width, u32 height) -{ - write32(&disp_color[0]->width, width); - write32(&disp_color[0]->height, height); - write32(&disp_color[0]->cfg_main, COLOR_BYPASS_ALL | COLOR_SEQ_SEL); - write32(&disp_color[0]->start, BIT(0)); -} - -static void ovl_layer_config(u32 fmt, u32 bpp, u32 width, u32 height) -{ - write32(&disp_ovl[0]->layer[0].con, fmt << 12); - write32(&disp_ovl[0]->layer[0].src_size, height << 16 | width); - write32(&disp_ovl[0]->layer[0].pitch, (width * bpp) & 0xFFFF); - - ovl_layer_enable(); -} - static void main_disp_path_setup(u32 width, u32 height, u32 pixel_clk) { - /* Setup OVL */ - ovl_set_roi(width, height, 0); - - /* Setup RDMA0 */ - rdma_config(width, height, pixel_clk); - - /* Setup OD */ + ovl_set_roi(0, width, height, 0); + rdma_config(width, height, pixel_clk, 8 * KiB); od_start(width, height); - - /* Setup UFOE */ - ufoe_start(width, height); - - /* Setup Color */ + write32(&disp_ufoe->start, UFO_BYPASS); color_start(width, height); - - /* Setup main path connection */ disp_config_main_path_connection(); - - /* Setup main path mutex */ disp_config_main_path_mutex(); } @@ -171,6 +87,5 @@ void mtk_ddp_mode_set(const struct edid *edid) edid->mode.pixel_clock); rdma_start(); - ovl_layer_config(fmt, bpp, edid->mode.ha, edid->mode.va); } diff --git a/src/soc/mediatek/mt8173/include/soc/addressmap.h b/src/soc/mediatek/mt8173/include/soc/addressmap.h index 0ebe3d1c6d..90834a3ca9 100644 --- a/src/soc/mediatek/mt8173/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8173/include/soc/addressmap.h @@ -56,8 +56,8 @@ enum { SSUSB_IPPC_BASE = IO_PHYS + 0x1280700, SSUSB_SIF_BASE = IO_PHYS + 0x1290800, MMSYS_BASE = IO_PHYS + 0x4000000, - DIS_OVL0_BASE = IO_PHYS + 0x400C000, - DIS_OVL1_BASE = IO_PHYS + 0x400D000, + DISP_OVL0_BASE = IO_PHYS + 0x400C000, + DISP_OVL1_BASE = IO_PHYS + 0x400D000, DISP_RDMA0_BASE = IO_PHYS + 0x400E000, DISP_RDMA1_BASE = IO_PHYS + 0x400F000, DISP_RDMA2_BASE = IO_PHYS + 0x4010000, diff --git a/src/soc/mediatek/mt8173/include/soc/ddp.h b/src/soc/mediatek/mt8173/include/soc/ddp.h index 2f154ddb67..dbac5f7fb9 100644 --- a/src/soc/mediatek/mt8173/include/soc/ddp.h +++ b/src/soc/mediatek/mt8173/include/soc/ddp.h @@ -13,10 +13,11 @@ * GNU General Public License for more details. */ -#ifndef _DDP_REG_H_ -#define _DDP_REG_H_ +#ifndef _MT8173_SOC_DDP_H_ +#define _MT8173_SOC_DDP_H_ #include +#include #include struct mmsys_cfg_regs { @@ -254,100 +255,6 @@ enum { MUTEX_MOD_DISP_UFOE | MUTEX_MOD_DISP_OD, }; -struct disp_ovl_regs { - u32 sta; - u32 inten; - u32 intsta; - u32 en; - u32 trig; - u32 rst; - u8 reserved0[8]; - u32 roi_size; - u32 datapath_con; - u32 roi_bgclr; - u32 src_con; - struct { - u32 con; - u32 srckey; - u32 src_size; - u32 offset; - u32 reserved0; - u32 pitch; - u32 reserved1[2]; - } layer[4]; - u8 reserved8[16]; - struct { - u32 ctrl; - u32 mem_start_trig; - u32 mem_gmc_setting; - u32 mem_slow_con; - u32 fifo_ctrl; - u8 reserved[12]; - } rdma[4]; - u8 reserved12[148]; - u32 debug_mon_sel; - u8 reserved13[8]; - u32 rdma_mem_gmc_setting2[4]; - u8 reserved14[16]; - u32 dummy; - u8 reserved15[60]; - u32 flow_ctrl_dbg; - u32 addcon_dbg; - u32 outmux_dbg; - u32 rdma_dbg[4]; - u8 reserved16[3300]; - u32 l0_addr; - u8 reserved17[28]; - u32 l1_addr; - u8 reserved18[28]; - u32 l2_addr; - u8 reserved19[28]; - u32 l3_addr; -}; - -check_member(disp_ovl_regs, l3_addr, 0xFA0); -static struct disp_ovl_regs *const disp_ovl[2] = { - (void *)DIS_OVL0_BASE, (void *)DIS_OVL1_BASE -}; - -struct disp_rdma_regs { - u32 int_enable; - u32 int_status; - u8 reserved0[8]; - u32 global_con; - u32 size_con_0; - u32 size_con_1; - u32 target_line; - u8 reserved1[4]; - u32 mem_con; - u32 mem_start_addr; - u32 mem_src_pitch; - u32 mem_gmc_setting_0; - u32 mem_slow_con; - u32 mem_gmc_setting_1; - u8 reserved2[4]; - u32 fifo_con; - u8 reserved3[16]; - u32 cf[3][3]; - u32 cf_pre_add[3]; - u32 cf_post_add[3]; - u32 dummy; - u32 debug_out_sel; -}; - -enum { - RDMA_ENGINE_EN = BIT(0), - RDMA_FIFO_UNDERFLOW_EN = BIT(31), - RDMA_MEM_GMC = 0x40402020, -}; - -check_member(disp_rdma_regs, debug_out_sel, 0x94); -static struct disp_rdma_regs *const disp_rdma[3] = { - (void *)DISP_RDMA0_BASE, - (void *)DISP_RDMA1_BASE, - (void *)DISP_RDMA2_BASE -}; - struct disp_od_regs { u32 en; u32 reset; @@ -407,45 +314,6 @@ enum { UFO_LR = BIT(3) | BIT(0), }; -struct disp_color_regs { - u8 reserved0[1024]; - u32 cfg_main; - u8 reserved1[2044]; - u32 start; - u8 reserved2[76]; - u32 width; - u32 height; -}; - -check_member(disp_color_regs, cfg_main, 0x400); -check_member(disp_color_regs, start, 0xC00); -check_member(disp_color_regs, width, 0xC50); -check_member(disp_color_regs, height, 0xC54); -static struct disp_color_regs *const disp_color[2] = { - (void *)DISP_COLOR0_BASE, (void *)DISP_COLOR1_BASE -}; - -enum { - COLOR_BYPASS_ALL = BIT(7), - COLOR_SEQ_SEL = BIT(13), -}; - -enum OVL_INPUT_FORMAT { - OVL_INFMT_RGB565 = 0, - OVL_INFMT_RGB888 = 1, - OVL_INFMT_RGBA8888 = 2, - OVL_INFMT_ARGB8888 = 3, - OVL_INFMT_UYVY = 4, - OVL_INFMT_YUYV = 5, - OVL_INFMT_UNKNOWN = 16, - - OVL_COLOR_BASE = 30, - OVL_INFMT_BGR565 = OVL_INFMT_RGB565 + OVL_COLOR_BASE, - OVL_INFMT_BGR888 = OVL_INFMT_RGB888 + OVL_COLOR_BASE, - OVL_INFMT_BGRA8888 = OVL_INFMT_RGBA8888 + OVL_COLOR_BASE, - OVL_INFMT_ABGR8888 = OVL_INFMT_ARGB8888 + OVL_COLOR_BASE, -}; - void mtk_ddp_init(void); void mtk_ddp_mode_set(const struct edid *edid); -- cgit v1.2.3