blob: aed1fd16d752372f641dfee51a14c1b3fa58a3b4 [file] [log] [blame]
Angel Ponsbbc99cf2020-04-04 18:51:23 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Shunqian Zhengd1cec752016-05-04 16:21:36 +08003
Shunqian Zhengd1cec752016-05-04 16:21:36 +08004#include <arch/mmu.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +08006#include <console/console.h>
7#include <device/device.h>
8#include <delay.h>
9#include <edid.h>
10#include <gpio.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +080011#include <stddef.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +080012#include <soc/addressmap.h>
13#include <soc/clock.h>
14#include <soc/display.h>
15#include <soc/edp.h>
16#include <soc/gpio.h>
17#include <soc/grf.h>
18#include <soc/mmu_operations.h>
Nickey Yangfe122d42017-04-27 09:38:06 +080019#include <soc/mipi.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +080020#include <soc/soc.h>
21#include <soc/vop.h>
22
23#include "chip.h"
24
Martin Rothe4b9af12016-11-29 10:50:52 -070025static void reset_edp(void)
26{
27 /* rst edp */
28 write32(&cru_ptr->softrst_con[17],
29 RK_SETBITS(1 << 12 | 1 << 13));
30 udelay(1);
31 write32(&cru_ptr->softrst_con[17],
32 RK_CLRBITS(1 << 12 | 1 << 13));
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080033 printk(BIOS_WARNING, "Retrying EDP initialization.\n");
Martin Rothe4b9af12016-11-29 10:50:52 -070034}
35
Elyes HAOUASf3ca88b2018-05-25 09:52:45 +020036void rk_display_init(struct device *dev)
Shunqian Zhengd1cec752016-05-04 16:21:36 +080037{
38 struct edid edid;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080039 struct soc_rockchip_rk3399_config *conf = dev->chip_info;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080040 enum vop_modes detected_mode = VOP_MODE_UNKNOWN;
Lin Huang25fb09b2017-11-22 09:40:50 +080041 const struct mipi_panel_data *panel_data = NULL;
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080042 int retry_count_init = 0;
43 int retry_count_edp_prepare = 0;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080044
Lin Huang152e6752016-10-20 14:22:11 -070045 /* let's use vop0 in rk3399 */
46 uint32_t vop_id = 0;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080047
48 switch (conf->vop_mode) {
49 case VOP_MODE_NONE:
50 return;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080051 case VOP_MODE_EDP:
52 printk(BIOS_DEBUG, "Attempting to set up EDP display.\n");
Julius Werner8e42bd1c2016-11-01 15:24:54 -070053 rkclk_configure_vop_aclk(vop_id, 200 * MHz);
Lin Huang4ecccff2017-01-18 09:44:34 +080054 rkclk_configure_edp(25 * MHz);
Shunqian Zhengd1cec752016-05-04 16:21:36 +080055
Lin Huang152e6752016-10-20 14:22:11 -070056 /* select edp signal from vop0 */
57 write32(&rk3399_grf->soc_con20, RK_CLRBITS(1 << 5));
Shunqian Zhengd1cec752016-05-04 16:21:36 +080058
59 /* select edp clk from SoC internal 24M crystal, otherwise,
60 * it will source from edp's 24M clock (that depends on
61 * edp vendor, could be unstable)
62 */
63 write32(&rk3399_grf->soc_con25, RK_SETBITS(1 << 11));
64
Lin Huang079b5c62016-11-21 17:35:20 +080065retry_edp:
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080066 /* Reset in case code jumped here. */
67 retry_count_init = 0;
68 while (retry_count_init++ < 3) {
Martin Rothe4b9af12016-11-29 10:50:52 -070069 rk_edp_init();
70 if (rk_edp_get_edid(&edid) == 0) {
71 detected_mode = VOP_MODE_EDP;
72 break;
73 }
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080074 if (retry_count_init == 3) {
75 printk(BIOS_WARNING,
76 "Warning: EDP initialization failed.\n");
Martin Rothe4b9af12016-11-29 10:50:52 -070077 return;
78 } else {
79 reset_edp();
80 }
Shunqian Zhengd1cec752016-05-04 16:21:36 +080081 }
Martin Rothe4b9af12016-11-29 10:50:52 -070082 break;
Nickey Yangfe122d42017-04-27 09:38:06 +080083 case VOP_MODE_MIPI:
84 printk(BIOS_DEBUG, "Attempting to setup MIPI display.\n");
85
86 rkclk_configure_mipi();
87 rkclk_configure_vop_aclk(vop_id, 200 * MHz);
88
Lin Huang25fb09b2017-11-22 09:40:50 +080089 /*
90 * disable tx0 turnrequest, turndisable,
91 * forcetxstop, forcerxmode
92 */
Nickey Yangfe122d42017-04-27 09:38:06 +080093 write32(&rk3399_grf->soc_con22, RK_CLRBITS(0xffff));
Nickey Yangfe122d42017-04-27 09:38:06 +080094
Lin Huang25fb09b2017-11-22 09:40:50 +080095 /* disable tx1 turndisable, forcetxstop, forcerxmode */
96 write32(&rk3399_grf->soc_con23, RK_CLRBITS(0xfff0));
97
98 /*
99 * enable dphy_tx1rx1_masterslavez,
100 * clear dphy_tx1rx1_enableclk,
101 * clear dphy_tx1rx1_basedir,
102 * disable tx1 turnrequest
103 */
104 write32(&rk3399_grf->soc_con24,
105 RK_CLRSETBITS(1 << 7 | 1 << 6 | 1 << 5 | 0xf,
106 1 << 7 | 0 << 6 | 0 << 5 | 0 << 0));
107
108 /* dphy_tx1rx1_enable */
109 write32(&rk3399_grf->soc_con23, RK_SETBITS(0xf));
110
111 /* select mipi-dsi0 and mipi-dsi1 signal from vop0 */
112 write32(&rk3399_grf->soc_con20,
113 RK_CLRBITS((1 << 0) | (1 << 4)));
114
Lin Huangadd76662017-11-23 08:50:03 +0800115 panel_data = mainboard_get_mipi_mode(&edid.mode);
Lin Huang25fb09b2017-11-22 09:40:50 +0800116 if (panel_data) {
117 if (panel_data->mipi_num > 1)
118 detected_mode = VOP_MODE_DUAL_MIPI;
119 else
120 detected_mode = VOP_MODE_MIPI;
121 } else {
122 printk(BIOS_WARNING, "Can not get mipi panel data\n");
123 return;
124 }
Nickey Yangfe122d42017-04-27 09:38:06 +0800125 break;
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800126 default:
Nickey Yangfe122d42017-04-27 09:38:06 +0800127 printk(BIOS_WARNING, "Unsupported vop_mode, aborting.\n");
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800128 return;
129 }
130
Lin Huang152e6752016-10-20 14:22:11 -0700131 if (rkclk_configure_vop_dclk(vop_id,
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800132 edid.mode.pixel_clock * KHz)) {
133 printk(BIOS_WARNING, "config vop err\n");
134 return;
135 }
136
Julius Wernere74f5ea2016-10-17 18:14:41 -0700137 edid_set_framebuffer_bits_per_pixel(&edid,
138 conf->framebuffer_bits_per_pixel, 0);
Lin Huang152e6752016-10-20 14:22:11 -0700139 rkvop_mode_set(vop_id, &edid, detected_mode);
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800140
Lin Huang152e6752016-10-20 14:22:11 -0700141 rkvop_prepare(vop_id, &edid);
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800142
143 switch (detected_mode) {
Nickey Yangfe122d42017-04-27 09:38:06 +0800144 case VOP_MODE_MIPI:
Lin Huang25fb09b2017-11-22 09:40:50 +0800145 case VOP_MODE_DUAL_MIPI:
146 rk_mipi_prepare(&edid, panel_data);
Nickey Yangfe122d42017-04-27 09:38:06 +0800147 break;
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800148 case VOP_MODE_EDP:
Lin Huanga09b3382016-10-23 14:17:25 -0700149 /* will enable edp in depthcharge */
Martin Rothe4b9af12016-11-29 10:50:52 -0700150 if (rk_edp_prepare()) {
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -0800151 if (retry_count_edp_prepare++ < 3) {
152 reset_edp();
153 /* Rerun entire init sequence */
154 goto retry_edp;
155 }
156 printk(BIOS_ERR, "EDP preparation failed.");
157 return;
Martin Rothe4b9af12016-11-29 10:50:52 -0700158 }
Nickey Yangfe122d42017-04-27 09:38:06 +0800159 break;
160 default:
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800161 break;
162 }
Nickey Yangfe122d42017-04-27 09:38:06 +0800163 mainboard_power_on_backlight();
Lin Huang152e6752016-10-20 14:22:11 -0700164 set_vbe_mode_info_valid(&edid, (uintptr_t)0);
Nickey Yangfe122d42017-04-27 09:38:06 +0800165
Lin Huang079b5c62016-11-21 17:35:20 +0800166 return;
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800167}