docs: Add 24.12 release notes
[coreboot2.git] / src / soc / rockchip / rk3399 / display.c
blobf0b78713033614f4abbbea170e9a925cc86057bc
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/mmu.h>
4 #include <device/mmio.h>
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <delay.h>
8 #include <edid.h>
9 #include <gpio.h>
10 #include <stdint.h>
11 #include <soc/addressmap.h>
12 #include <soc/clock.h>
13 #include <soc/display.h>
14 #include <soc/edp.h>
15 #include <soc/grf.h>
16 #include <soc/mmu_operations.h>
17 #include <soc/mipi.h>
18 #include <soc/soc.h>
19 #include <soc/vop.h>
20 #include <framebuffer_info.h>
22 #include "chip.h"
24 static void reset_edp(void)
26 /* rst edp */
27 write32(&cru_ptr->softrst_con[17],
28 RK_SETBITS(1 << 12 | 1 << 13));
29 udelay(1);
30 write32(&cru_ptr->softrst_con[17],
31 RK_CLRBITS(1 << 12 | 1 << 13));
32 printk(BIOS_WARNING, "Retrying EDP initialization.\n");
35 void rk_display_init(struct device *dev)
37 struct edid edid;
38 struct soc_rockchip_rk3399_config *conf = dev->chip_info;
39 enum vop_modes detected_mode = VOP_MODE_UNKNOWN;
40 const struct mipi_panel_data *panel_data = NULL;
41 int retry_count_init = 0;
42 int retry_count_edp_prepare = 0;
44 /* let's use vop0 in rk3399 */
45 uint32_t vop_id = 0;
47 switch (conf->vop_mode) {
48 case VOP_MODE_NONE:
49 return;
50 case VOP_MODE_EDP:
51 printk(BIOS_DEBUG, "Attempting to set up EDP display.\n");
52 rkclk_configure_vop_aclk(vop_id, 200 * MHz);
53 rkclk_configure_edp(25 * MHz);
55 /* select edp signal from vop0 */
56 write32(&rk3399_grf->soc_con20, RK_CLRBITS(1 << 5));
58 /* select edp clk from SoC internal 24M crystal, otherwise,
59 * it will source from edp's 24M clock (that depends on
60 * edp vendor, could be unstable)
62 write32(&rk3399_grf->soc_con25, RK_SETBITS(1 << 11));
64 retry_edp:
65 /* Reset in case code jumped here. */
66 retry_count_init = 0;
67 while (retry_count_init++ < 3) {
68 rk_edp_init();
69 if (rk_edp_get_edid(&edid) == 0) {
70 detected_mode = VOP_MODE_EDP;
71 break;
73 if (retry_count_init == 3) {
74 printk(BIOS_WARNING, "EDP initialization failed.\n");
75 return;
76 } else {
77 reset_edp();
80 break;
81 case VOP_MODE_MIPI:
82 printk(BIOS_DEBUG, "Attempting to setup MIPI display.\n");
84 rkclk_configure_mipi();
85 rkclk_configure_vop_aclk(vop_id, 200 * MHz);
88 * disable tx0 turnrequest, turndisable,
89 * forcetxstop, forcerxmode
91 write32(&rk3399_grf->soc_con22, RK_CLRBITS(0xffff));
93 /* disable tx1 turndisable, forcetxstop, forcerxmode */
94 write32(&rk3399_grf->soc_con23, RK_CLRBITS(0xfff0));
97 * enable dphy_tx1rx1_masterslavez,
98 * clear dphy_tx1rx1_enableclk,
99 * clear dphy_tx1rx1_basedir,
100 * disable tx1 turnrequest
102 write32(&rk3399_grf->soc_con24,
103 RK_CLRSETBITS(1 << 7 | 1 << 6 | 1 << 5 | 0xf,
104 1 << 7 | 0 << 6 | 0 << 5 | 0 << 0));
106 /* dphy_tx1rx1_enable */
107 write32(&rk3399_grf->soc_con23, RK_SETBITS(0xf));
109 /* select mipi-dsi0 and mipi-dsi1 signal from vop0 */
110 write32(&rk3399_grf->soc_con20,
111 RK_CLRBITS((1 << 0) | (1 << 4)));
113 panel_data = mainboard_get_mipi_mode(&edid.mode);
114 if (panel_data) {
115 if (panel_data->mipi_num > 1)
116 detected_mode = VOP_MODE_DUAL_MIPI;
117 else
118 detected_mode = VOP_MODE_MIPI;
119 } else {
120 printk(BIOS_WARNING, "Can not get mipi panel data\n");
121 return;
123 break;
124 default:
125 printk(BIOS_WARNING, "Unsupported vop_mode, aborting.\n");
126 return;
129 if (rkclk_configure_vop_dclk(vop_id,
130 edid.mode.pixel_clock * KHz)) {
131 printk(BIOS_WARNING, "config vop err\n");
132 return;
135 edid_set_framebuffer_bits_per_pixel(&edid,
136 conf->framebuffer_bits_per_pixel, 0);
137 rkvop_mode_set(vop_id, &edid, detected_mode);
139 rkvop_prepare(vop_id, &edid);
141 switch (detected_mode) {
142 case VOP_MODE_MIPI:
143 case VOP_MODE_DUAL_MIPI:
144 rk_mipi_prepare(&edid, panel_data);
145 break;
146 case VOP_MODE_EDP:
147 /* will enable edp in depthcharge */
148 if (rk_edp_prepare()) {
149 if (retry_count_edp_prepare++ < 3) {
150 reset_edp();
151 /* Rerun entire init sequence */
152 goto retry_edp;
154 printk(BIOS_ERR, "EDP preparation failed.");
155 return;
157 break;
158 default:
159 break;
161 mainboard_power_on_backlight();
162 fb_new_framebuffer_info_from_edid(&edid, (uintptr_t)0);