blob: 70e8c7c15d5293ba015cf231a1eb43aa1515e950 [file] [log] [blame]
Angel Ponsbbc99cf2020-04-04 18:51:23 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Shunqian Zhengd1cec752016-05-04 16:21:36 +08002
Shunqian Zhengd1cec752016-05-04 16:21:36 +08003#include <arch/mmu.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +08005#include <console/console.h>
6#include <device/device.h>
7#include <delay.h>
8#include <edid.h>
9#include <gpio.h>
Elyes HAOUAS0badea82020-07-10 10:43:24 +020010#include <stdint.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +080011#include <soc/addressmap.h>
12#include <soc/clock.h>
13#include <soc/display.h>
14#include <soc/edp.h>
15#include <soc/gpio.h>
16#include <soc/grf.h>
17#include <soc/mmu_operations.h>
Nickey Yangfe122d42017-04-27 09:38:06 +080018#include <soc/mipi.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +080019#include <soc/soc.h>
20#include <soc/vop.h>
21
22#include "chip.h"
23
Martin Rothe4b9af12016-11-29 10:50:52 -070024static void reset_edp(void)
25{
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));
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080032 printk(BIOS_WARNING, "Retrying EDP initialization.\n");
Martin Rothe4b9af12016-11-29 10:50:52 -070033}
34
Elyes HAOUASf3ca88b2018-05-25 09:52:45 +020035void rk_display_init(struct device *dev)
Shunqian Zhengd1cec752016-05-04 16:21:36 +080036{
37 struct edid edid;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080038 struct soc_rockchip_rk3399_config *conf = dev->chip_info;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080039 enum vop_modes detected_mode = VOP_MODE_UNKNOWN;
Lin Huang25fb09b2017-11-22 09:40:50 +080040 const struct mipi_panel_data *panel_data = NULL;
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080041 int retry_count_init = 0;
42 int retry_count_edp_prepare = 0;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080043
Lin Huang152e6752016-10-20 14:22:11 -070044 /* let's use vop0 in rk3399 */
45 uint32_t vop_id = 0;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080046
47 switch (conf->vop_mode) {
48 case VOP_MODE_NONE:
49 return;
Shunqian Zhengd1cec752016-05-04 16:21:36 +080050 case VOP_MODE_EDP:
51 printk(BIOS_DEBUG, "Attempting to set up EDP display.\n");
Julius Werner8e42bd1c2016-11-01 15:24:54 -070052 rkclk_configure_vop_aclk(vop_id, 200 * MHz);
Lin Huang4ecccff2017-01-18 09:44:34 +080053 rkclk_configure_edp(25 * MHz);
Shunqian Zhengd1cec752016-05-04 16:21:36 +080054
Lin Huang152e6752016-10-20 14:22:11 -070055 /* select edp signal from vop0 */
56 write32(&rk3399_grf->soc_con20, RK_CLRBITS(1 << 5));
Shunqian Zhengd1cec752016-05-04 16:21:36 +080057
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)
61 */
62 write32(&rk3399_grf->soc_con25, RK_SETBITS(1 << 11));
63
Lin Huang079b5c62016-11-21 17:35:20 +080064retry_edp:
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080065 /* Reset in case code jumped here. */
66 retry_count_init = 0;
67 while (retry_count_init++ < 3) {
Martin Rothe4b9af12016-11-29 10:50:52 -070068 rk_edp_init();
69 if (rk_edp_get_edid(&edid) == 0) {
70 detected_mode = VOP_MODE_EDP;
71 break;
72 }
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -080073 if (retry_count_init == 3) {
74 printk(BIOS_WARNING,
75 "Warning: EDP initialization failed.\n");
Martin Rothe4b9af12016-11-29 10:50:52 -070076 return;
77 } else {
78 reset_edp();
79 }
Shunqian Zhengd1cec752016-05-04 16:21:36 +080080 }
Martin Rothe4b9af12016-11-29 10:50:52 -070081 break;
Nickey Yangfe122d42017-04-27 09:38:06 +080082 case VOP_MODE_MIPI:
83 printk(BIOS_DEBUG, "Attempting to setup MIPI display.\n");
84
85 rkclk_configure_mipi();
86 rkclk_configure_vop_aclk(vop_id, 200 * MHz);
87
Lin Huang25fb09b2017-11-22 09:40:50 +080088 /*
89 * disable tx0 turnrequest, turndisable,
90 * forcetxstop, forcerxmode
91 */
Nickey Yangfe122d42017-04-27 09:38:06 +080092 write32(&rk3399_grf->soc_con22, RK_CLRBITS(0xffff));
Nickey Yangfe122d42017-04-27 09:38:06 +080093
Lin Huang25fb09b2017-11-22 09:40:50 +080094 /* disable tx1 turndisable, forcetxstop, forcerxmode */
95 write32(&rk3399_grf->soc_con23, RK_CLRBITS(0xfff0));
96
97 /*
98 * enable dphy_tx1rx1_masterslavez,
99 * clear dphy_tx1rx1_enableclk,
100 * clear dphy_tx1rx1_basedir,
101 * disable tx1 turnrequest
102 */
103 write32(&rk3399_grf->soc_con24,
104 RK_CLRSETBITS(1 << 7 | 1 << 6 | 1 << 5 | 0xf,
105 1 << 7 | 0 << 6 | 0 << 5 | 0 << 0));
106
107 /* dphy_tx1rx1_enable */
108 write32(&rk3399_grf->soc_con23, RK_SETBITS(0xf));
109
110 /* select mipi-dsi0 and mipi-dsi1 signal from vop0 */
111 write32(&rk3399_grf->soc_con20,
112 RK_CLRBITS((1 << 0) | (1 << 4)));
113
Lin Huangadd76662017-11-23 08:50:03 +0800114 panel_data = mainboard_get_mipi_mode(&edid.mode);
Lin Huang25fb09b2017-11-22 09:40:50 +0800115 if (panel_data) {
116 if (panel_data->mipi_num > 1)
117 detected_mode = VOP_MODE_DUAL_MIPI;
118 else
119 detected_mode = VOP_MODE_MIPI;
120 } else {
121 printk(BIOS_WARNING, "Can not get mipi panel data\n");
122 return;
123 }
Nickey Yangfe122d42017-04-27 09:38:06 +0800124 break;
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800125 default:
Nickey Yangfe122d42017-04-27 09:38:06 +0800126 printk(BIOS_WARNING, "Unsupported vop_mode, aborting.\n");
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800127 return;
128 }
129
Lin Huang152e6752016-10-20 14:22:11 -0700130 if (rkclk_configure_vop_dclk(vop_id,
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800131 edid.mode.pixel_clock * KHz)) {
132 printk(BIOS_WARNING, "config vop err\n");
133 return;
134 }
135
Julius Wernere74f5ea2016-10-17 18:14:41 -0700136 edid_set_framebuffer_bits_per_pixel(&edid,
137 conf->framebuffer_bits_per_pixel, 0);
Lin Huang152e6752016-10-20 14:22:11 -0700138 rkvop_mode_set(vop_id, &edid, detected_mode);
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800139
Lin Huang152e6752016-10-20 14:22:11 -0700140 rkvop_prepare(vop_id, &edid);
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800141
142 switch (detected_mode) {
Nickey Yangfe122d42017-04-27 09:38:06 +0800143 case VOP_MODE_MIPI:
Lin Huang25fb09b2017-11-22 09:40:50 +0800144 case VOP_MODE_DUAL_MIPI:
145 rk_mipi_prepare(&edid, panel_data);
Nickey Yangfe122d42017-04-27 09:38:06 +0800146 break;
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800147 case VOP_MODE_EDP:
Lin Huanga09b3382016-10-23 14:17:25 -0700148 /* will enable edp in depthcharge */
Martin Rothe4b9af12016-11-29 10:50:52 -0700149 if (rk_edp_prepare()) {
Ege Mihmanlibb9bdeb2018-01-07 18:03:07 -0800150 if (retry_count_edp_prepare++ < 3) {
151 reset_edp();
152 /* Rerun entire init sequence */
153 goto retry_edp;
154 }
155 printk(BIOS_ERR, "EDP preparation failed.");
156 return;
Martin Rothe4b9af12016-11-29 10:50:52 -0700157 }
Nickey Yangfe122d42017-04-27 09:38:06 +0800158 break;
159 default:
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800160 break;
161 }
Nickey Yangfe122d42017-04-27 09:38:06 +0800162 mainboard_power_on_backlight();
Lin Huang152e6752016-10-20 14:22:11 -0700163 set_vbe_mode_info_valid(&edid, (uintptr_t)0);
Nickey Yangfe122d42017-04-27 09:38:06 +0800164
Lin Huang079b5c62016-11-21 17:35:20 +0800165 return;
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800166}