coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
display.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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/gpio.h>
16 #include <soc/grf.h>
17 #include <soc/mmu_operations.h>
18 #include <soc/mipi.h>
19 #include <soc/soc.h>
20 #include <soc/vop.h>
21 #include <framebuffer_info.h>
22 
23 #include "chip.h"
24 
25 static 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));
33  printk(BIOS_WARNING, "Retrying EDP initialization.\n");
34 }
35 
36 void rk_display_init(struct device *dev)
37 {
38  struct edid edid;
39  struct soc_rockchip_rk3399_config *conf = dev->chip_info;
40  enum vop_modes detected_mode = VOP_MODE_UNKNOWN;
41  const struct mipi_panel_data *panel_data = NULL;
42  int retry_count_init = 0;
43  int retry_count_edp_prepare = 0;
44 
45  /* let's use vop0 in rk3399 */
46  uint32_t vop_id = 0;
47 
48  switch (conf->vop_mode) {
49  case VOP_MODE_NONE:
50  return;
51  case VOP_MODE_EDP:
52  printk(BIOS_DEBUG, "Attempting to set up EDP display.\n");
53  rkclk_configure_vop_aclk(vop_id, 200 * MHz);
55 
56  /* select edp signal from vop0 */
58 
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  */
64 
65 retry_edp:
66  /* Reset in case code jumped here. */
67  retry_count_init = 0;
68  while (retry_count_init++ < 3) {
69  rk_edp_init();
70  if (rk_edp_get_edid(&edid) == 0) {
71  detected_mode = VOP_MODE_EDP;
72  break;
73  }
74  if (retry_count_init == 3) {
75  printk(BIOS_WARNING, "EDP initialization failed.\n");
76  return;
77  } else {
78  reset_edp();
79  }
80  }
81  break;
82  case VOP_MODE_MIPI:
83  printk(BIOS_DEBUG, "Attempting to setup MIPI display.\n");
84 
86  rkclk_configure_vop_aclk(vop_id, 200 * MHz);
87 
88  /*
89  * disable tx0 turnrequest, turndisable,
90  * forcetxstop, forcerxmode
91  */
93 
94  /* disable tx1 turndisable, forcetxstop, forcerxmode */
96 
97  /*
98  * enable dphy_tx1rx1_masterslavez,
99  * clear dphy_tx1rx1_enableclk,
100  * clear dphy_tx1rx1_basedir,
101  * disable tx1 turnrequest
102  */
104  RK_CLRSETBITS(1 << 7 | 1 << 6 | 1 << 5 | 0xf,
105  1 << 7 | 0 << 6 | 0 << 5 | 0 << 0));
106 
107  /* dphy_tx1rx1_enable */
109 
110  /* select mipi-dsi0 and mipi-dsi1 signal from vop0 */
112  RK_CLRBITS((1 << 0) | (1 << 4)));
113 
114  panel_data = mainboard_get_mipi_mode(&edid.mode);
115  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  }
124  break;
125  default:
126  printk(BIOS_WARNING, "Unsupported vop_mode, aborting.\n");
127  return;
128  }
129 
130  if (rkclk_configure_vop_dclk(vop_id,
131  edid.mode.pixel_clock * KHz)) {
132  printk(BIOS_WARNING, "config vop err\n");
133  return;
134  }
135 
137  conf->framebuffer_bits_per_pixel, 0);
138  rkvop_mode_set(vop_id, &edid, detected_mode);
139 
140  rkvop_prepare(vop_id, &edid);
141 
142  switch (detected_mode) {
143  case VOP_MODE_MIPI:
144  case VOP_MODE_DUAL_MIPI:
145  rk_mipi_prepare(&edid, panel_data);
146  break;
147  case VOP_MODE_EDP:
148  /* will enable edp in depthcharge */
149  if (rk_edp_prepare()) {
150  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;
157  }
158  break;
159  default:
160  break;
161  }
164 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
#define MHz
Definition: helpers.h:80
#define KHz
Definition: helpers.h:79
#define printk(level,...)
Definition: stdlib.h:16
int rk_edp_prepare(void)
Definition: edp.c:969
int rk_edp_get_edid(struct edid *edid)
Definition: edp.c:954
void rk_edp_init(void)
Definition: edp.c:994
struct fb_info * fb_new_framebuffer_info_from_edid(const struct edid *edid, uintptr_t fb_addr)
Definition: edid_fill_fb.c:162
void mainboard_power_on_backlight(void)
Definition: mainboard.c:356
const struct mipi_panel_data * mainboard_get_mipi_mode(struct edid_mode *edid_mode)
Definition: mainboard.c:660
void edid_set_framebuffer_bits_per_pixel(struct edid *edid, int fb_bpp, int row_byte_alignment)
Definition: edid.c:1667
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
static struct rk3399_grf_regs *const rk3399_grf
Definition: grf.h:319
#define RK_CLRBITS(clr)
Definition: soc.h:10
#define RK_SETBITS(set)
Definition: soc.h:9
#define RK_CLRSETBITS(clr, set)
Definition: soc.h:8
void rk_mipi_prepare(const struct edid *edid, const struct mipi_panel_data *panel_data)
Definition: mipi.c:676
static struct rk3288_cru_reg *const cru_ptr
Definition: clock.c:50
void rkclk_configure_vop_aclk(u32 vop_id, u32 aclk_hz)
Definition: clock.c:587
void rkclk_configure_edp(void)
Definition: clock.c:565
int rkclk_configure_vop_dclk(u32 vop_id, u32 dclk_hz)
Definition: clock.c:610
void rk_display_init(struct device *dev, u32 lcdbase, unsigned long fb_size)
Definition: display.c:24
void rkclk_configure_mipi(void)
Definition: clock.c:945
static void reset_edp(void)
Definition: display.c:25
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
Definition: device.h:107
DEVTREE_CONST void * chip_info
Definition: device.h:164
unsigned int pixel_clock
Definition: edid.h:22
Definition: edid.h:49
struct edid_mode mode
Definition: edid.h:72
u32 soc_con20
Definition: grf.h:65
u32 soc_con24
Definition: grf.h:69
u32 soc_con22
Definition: grf.h:67
u32 soc_con23
Definition: grf.h:68
u32 soc_con25
Definition: grf.h:70
u32 framebuffer_bits_per_pixel
Definition: chip.h:10
void udelay(uint32_t us)
Definition: udelay.c:15
vop_modes
Definition: vop.h:102
@ VOP_MODE_NONE
Definition: vop.h:111
@ VOP_MODE_DUAL_MIPI
Definition: vop.h:110
@ VOP_MODE_EDP
Definition: vop.h:107
@ VOP_MODE_MIPI
Definition: vop.h:109
@ VOP_MODE_UNKNOWN
Definition: vop.h:113
void rkvop_mode_set(u32 vop_id, const struct edid *edid, u32 mode)
Definition: vop.c:83
void rkvop_prepare(u32 vop_id, const struct edid *edid)
Definition: vop.c:26