blob: 728f45d1a0e19db932a2e502d10f367299dd137b [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>
Patrick Rudolph8b56c8c2020-02-19 12:57:00 +010021#include <framebuffer_info.h>
Shunqian Zhengd1cec752016-05-04 16:21:36 +080022
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) {
Julius Wernere9665952022-01-21 17:06:20 -080075 printk(BIOS_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();
Patrick Rudolph8b56c8c2020-02-19 12:57:00 +0100163 fb_new_framebuffer_info_from_edid(&edid, (uintptr_t)0);
Shunqian Zhengd1cec752016-05-04 16:21:36 +0800164}