drivers/mipi: Add support for KD_KD110N11_51IE panel
[coreboot2.git] / src / soc / mediatek / mt8186 / ddp.c
blob5a5f5447fffff7c2f38dabab6b7e72f5b619fb70
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /*
4 * This file is created based on MT8186 Functional Specification
5 * Chapter number: 6.9
6 */
8 #include <console/console.h>
9 #include <edid.h>
10 #include <soc/addressmap.h>
11 #include <soc/ddp.h>
13 static void disp_config_main_path_connection(void)
16 * Main path:
17 * OVL0->RDMA0->COLOR0->CCORR0->AAL0->GAMMA->POSTMASK0->DITHER->DSI0
19 SET32_BITFIELDS(&mmsys_cfg->disp_ovl0_mout_en,
20 DISP_OVL0_MOUT_EN, DISP_OVL0_MOUT_TO_RDMA0);
21 SET32_BITFIELDS(&mmsys_cfg->disp_rdma0_sel_in,
22 DISP_RDMA0_SEL_IN, DISP_RDMA0_FROM_OVL0);
23 SET32_BITFIELDS(&mmsys_cfg->mmsys_ovl_con,
24 DISP_MMSYS_OVL0_CON, DISP_OVL0_GO_BLEND);
25 SET32_BITFIELDS(&mmsys_cfg->disp_rdma0_sout_sel,
26 DISP_RDMA0_SOUT_SEL, DISP_RDMA0_SOUT_TO_COLOR0);
27 SET32_BITFIELDS(&mmsys_cfg->disp_dither0_mout_en,
28 DISP_DITHER0_MOUT_EN, DISP_DITHER0_MOUT_TO_DSI0);
29 SET32_BITFIELDS(&mmsys_cfg->disp_dsi0_sel_in,
30 DISP_DSI0_SEL_IN, DISP_DSI0_FROM_DITHER0);
33 static void disp_config_main_path_mutex(void)
35 write32(&disp_mutex->mutex[0].mod, MUTEX_MOD_MAIN_PATH);
37 /* Clock source from DSI0 */
38 write32(&disp_mutex->mutex[0].ctl,
39 MUTEX_SOF_DSI0 | (MUTEX_SOF_DSI0 << 6));
40 write32(&disp_mutex->mutex[0].en, BIT(0));
43 static void ovl_layer_smi_id_en(u32 idx)
45 SET32_BITFIELDS(&disp_ovl[idx]->datapath_con,
46 SMI_ID_EN, SMI_ID_EN_VAL);
49 static void ccorr_config(u32 width, u32 height)
51 struct disp_ccorr_regs *const regs = disp_ccorr;
53 write32(&regs->size, width << 16 | height);
55 /* Disable relay mode */
56 SET32_BITFIELDS(&regs->cfg, PQ_CFG_RELAY_MODE, 0);
57 SET32_BITFIELDS(&regs->cfg, PQ_CFG_ENGINE_EN, PQ_ENGINE_EN);
59 write32(&regs->en, PQ_EN);
62 static void aal_config(u32 width, u32 height)
64 struct disp_aal_regs *const regs = disp_aal;
66 write32(&regs->size, width << 16 | height);
67 write32(&regs->output_size, width << 16 | height);
69 /* Enable relay mode */
70 SET32_BITFIELDS(&regs->cfg, PQ_CFG_RELAY_MODE, PQ_RELAY_MODE);
71 SET32_BITFIELDS(&regs->cfg, PQ_CFG_ENGINE_EN, 0);
73 write32(&regs->en, PQ_EN);
76 static void gamma_config(u32 width, u32 height)
78 struct disp_gamma_regs *const regs = disp_gamma;
80 write32(&regs->size, width << 16 | height);
82 /* Disable relay mode */
83 SET32_BITFIELDS(&regs->cfg, PQ_CFG_RELAY_MODE, 0);
85 write32(&regs->en, PQ_EN);
88 static void postmask_config(u32 width, u32 height)
90 struct disp_postmask_regs *const regs = disp_postmask;
92 write32(&regs->size, width << 16 | height);
94 /* Enable relay mode */
95 SET32_BITFIELDS(&regs->cfg, PQ_CFG_RELAY_MODE, PQ_RELAY_MODE);
97 write32(&regs->en, PQ_EN);
100 static void dither_config(u32 width, u32 height)
102 struct disp_dither_regs *const regs = disp_dither;
104 write32(&regs->size, width << 16 | height);
106 /* Enable relay mode */
107 SET32_BITFIELDS(&regs->cfg, PQ_CFG_RELAY_MODE, PQ_RELAY_MODE);
109 write32(&regs->en, PQ_EN);
112 static void main_disp_path_setup(u32 width, u32 height, u32 vrefresh)
114 u32 pixel_clk = width * height * vrefresh;
116 /* One ovl in main path */
117 ovl_set_roi(0, width, height, 0xff0000ff);
118 ovl_layer_smi_id_en(0);
119 rdma_config(width, height, pixel_clk, 5 * KiB);
120 color_start(width, height);
121 ccorr_config(width, height);
122 aal_config(width, height);
123 gamma_config(width, height);
124 postmask_config(width, height);
125 dither_config(width, height);
126 disp_config_main_path_connection();
127 disp_config_main_path_mutex();
130 static void disp_clock_on(void)
132 clrbits32(&mmsys_cfg->mmsys_cg_con0, CG_CON0_DISP_ALL);
133 clrbits32(&mmsys_cfg->mmsys_cg_con2, CG_CON2_DISP_ALL);
136 void mtk_ddp_init(void)
138 disp_clock_on();
140 /* Turn off M4U port */
141 write32((void *)(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0), 0);
144 void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path)
146 u32 fmt = OVL_INFMT_RGBA8888;
147 u32 bpp = edid->framebuffer_bits_per_pixel / 8;
148 u32 width = edid->mode.ha;
149 u32 height = edid->mode.va;
150 u32 vrefresh = edid->mode.refresh;
152 printk(BIOS_INFO, "%s: display resolution: %ux%u@%u bpp %u\n",
153 __func__, width, height, vrefresh, bpp);
155 if (!vrefresh) {
156 vrefresh = 60;
157 printk(BIOS_INFO, "%s: invalid vrefresh; setting to %u\n",
158 __func__, vrefresh);
161 main_disp_path_setup(width, height, vrefresh);
162 rdma_start();
163 ovl_layer_config(fmt, bpp, width, height);