coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
dsi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <mipi/dsi.h>
4 #include <mipi/panel.h>
5 #include <device/mmio.h>
6 #include <console/console.h>
7 #include <assert.h>
8 #include <edid.h>
9 #include <delay.h>
10 #include <symbols.h>
11 #include <types.h>
12 #include <string.h>
13 #include <soc/display/mipi_dsi.h>
14 #include <soc/display/mdssreg.h>
15 #include <soc/display/dsi_phy.h>
16 
17 #define DSI_DMA_STREAM1 0x0
18 #define DSI_EMBED_MODE1 0x1
19 #define DSI_POWER_MODE2 0x1
20 #define DSI_PACK_TYPE1 0x0
21 #define DSI_VC1 0x0
22 #define DSI_DT1 0x0
23 #define DSI_WC1 0x0
24 #define DSI_EOF_BLLP_PWR 0x9
25 #define DSI_DMA_TRIGGER_SEL 0x4
26 #define TRAFFIC_MODE 0x1
27 
28 #define DSI_EN 0x1
29 #define DSI_CLKLN_EN 0x1
30 #define DSI_VIDEO_EN 0x1
31 
32 #define HS_TX_TO 0xEA60
33 #define TIMER_RESOLUTION 0x4
34 #define DSI_PAYLOAD_BYTE_BOUND 256
35 #define DSI_PAYLOAD_SIZE_ALIGN 4
36 #define DSI_CMD_DMA_TPG_EN BIT(1)
37 #define DSI_TPG_DMA_FIFO_MODE BIT(2)
38 #define DSI_CMD_DMA_PATTERN_SEL (BIT(16) | BIT(17))
39 
40 static void mdss_dsi_host_init(int num_of_lanes)
41 {
42  uint8_t dlnx_en;
43  uint32_t ctrl_mode = BIT(8) | BIT(0); /* Enable DSI and CLKlane. */
44 
45  switch (num_of_lanes) {
46  default:
47  case 1:
48  dlnx_en = 1;
49  break;
50 
51  case 2:
52  dlnx_en = 3;
53  break;
54 
55  case 3:
56  dlnx_en = 7;
57  break;
58 
59  case 4:
60  dlnx_en = 0x0F;
61  break;
62  }
63 
64  /*
65  * Need to send pixel data before sending the ON commands
66  * so need to configure controller to VIDEO MODE.
67  */
68  ctrl_mode |= BIT(1);
69 
72  write32(&dsi0->ctrl, dlnx_en << 4 | ctrl_mode);
74  DSI_EMBED_MODE1 << 28 | DSI_POWER_MODE2 << 26 |
75  DSI_PACK_TYPE1 << 24 | DSI_VC1 << 22 | DSI_DT1 << 16 | DSI_WC1);
77 }
78 
79 static void mdss_dsi_reset(void)
80 {
81  /*
82  * Disable DSI Controller, DSI lane states,
83  * DSI command-mode and DSI video-mode engines
84  */
85  write32(&dsi0->ctrl, 0x0);
86 
87  /* DSI soft reset */
88  write32(&dsi0->soft_reset, 0x1);
89  write32(&dsi0->soft_reset, 0x0);
90 
91  /* set hs timer count speed */
93 
94  /* dma fifo reset */
97 }
98 
100 {
101  uint16_t dst_format;
102  uint8_t lane_en = 15; /* Enable 4 lanes by default */
103 
104  switch (bpp) {
105  case 16:
106  dst_format = DSI_VIDEO_DST_FORMAT_RGB565;
107  break;
108  case 18:
109  dst_format = DSI_VIDEO_DST_FORMAT_RGB666;
110  break;
111  case 24:
112  default:
113  dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
114  break;
115  }
116 
118  ((edid->mode.ha + edid->mode.hbl - edid->mode.hso) << 16) |
119  (edid->mode.hbl - edid->mode.hso));
120 
122  ((edid->mode.va + edid->mode.vbl - edid->mode.vso) << 16) |
123  (edid->mode.vbl - edid->mode.vso));
124 
126  ((edid->mode.va + edid->mode.vbl - 1) << 16) |
127  (edid->mode.ha + edid->mode.hbl - 1));
128 
132 
134  DSI_EOF_BLLP_PWR << 12 | dst_format << 4 | TRAFFIC_MODE << 8);
135 
137 
138  write32(&dsi0->ctrl, lane_en << 4 | DSI_VIDEO_EN << 1 | DSI_EN | DSI_CLKLN_EN << 8);
139 }
140 
141 enum cb_err mdss_dsi_config(struct edid *edid, uint32_t num_of_lanes, uint32_t bpp)
142 {
143  mdss_dsi_reset();
144  if ((mdss_dsi_phy_10nm_init(edid, num_of_lanes, bpp)) != 0) {
145  printk(BIOS_ERR, "dsi phy setup returned error\n");
146  return CB_ERR;
147  }
148 
149  mdss_dsi_host_init(num_of_lanes);
150 
151  return CB_SUCCESS;
152 }
153 
155 {
156  /* Clock for AHI Bus Master, for DMA out from memory */
157  write32(&dsi0->clk_ctrl, 0);
159 
160  /* Clock for MDP/DSI, for DMA out from MDP */
162 
163  /* Clock for rest of DSI */
166 }
167 
168 static void mdss_dsi_set_intr(void)
169 {
170  write32(&dsi0->int_ctrl, 0x0);
171 
172  /* Enable all HW interrupts. */
175 }
176 
178 {
179  uint32_t read_value;
180  uint32_t count = 0;
181  int status = 0;
182 
185  dsb();
186 
187  read_value = read32(&dsi0->int_ctrl) & 0x1;
188 
189  while (read_value != 0x1) {
190  read_value = read32(&dsi0->int_ctrl) & 0x1;
191  count++;
192  if (count > 0xffff) {
193  status = -1;
195  "Panel CMD: count :%d command mode dma test failed\n", count);
197  "Panel CMD: read value = %x, addr=%p\n",
198  read_value, (&dsi0->int_ctrl));
199  return status;
200  }
201  }
202 
203  write32(&dsi0->int_ctrl, (read32(&dsi0->int_ctrl) | 0x01000001));
204  return status;
205 }
206 
207 static enum cb_err mdss_dsi_send_init_cmd(enum mipi_dsi_transaction type, const u8 *body,
208  u8 len)
209 {
210  uint8_t *pload = _dma_coherent;
211  uint32_t size;
212  enum cb_err ret = CB_SUCCESS;
213  int data = 0;
214  uint32_t *bp = NULL;
215 
216  if (len > 2) {
217  pload[0] = len;
218  pload[1] = 0;
219  pload[2] = type;
220  pload[3] = BIT(7) | BIT(6);
221 
222  /* The payload size has to be a multiple of 4 */
223  memcpy(pload + 4, body, len);
224  size = ALIGN_UP(len + 4, DSI_PAYLOAD_SIZE_ALIGN);
225  memset(pload + 4 + len, 0, size - 4 - len);
227  } else {
228  pload[0] = body[0];
229  pload[1] = len > 1 ? body[1] : 0;
230  pload[2] = type;
231  pload[3] = BIT(7);
232  size = 4;
233  }
234 
235  bp = (uint32_t *)pload;
236 
237  /* Enable custom pattern stored in TPG DMA FIFO */
239 
240  /* select CMD_DMA_FIFO_MODE to 1 */
241  data |= DSI_TPG_DMA_FIFO_MODE;
242  data |= DSI_CMD_DMA_TPG_EN;
243 
245  for (int j = 0; j < size; j += 4) {
247  bp++;
248  }
249 
250  if ((size % 8) != 0)
252 
253  write32(&dsi0->dma_cmd_length, size);
256  ret = CB_ERR;
257 
258  /* Reset the DMA TPG FIFO */
261 
262  /* Disable CMD_DMA_TPG */
264 
265  udelay(80);
266 
267  return ret;
268 }
269 
270 static void mdss_dsi_clear_intr(void)
271 {
272  write32(&dsi0->int_ctrl, 0x0);
273 
274  /* Clear all the hardware interrupts */
277  write32(&dsi0->err_int_mask0, 0x13FF3BFF);
278 }
279 
280 enum cb_err mdss_dsi_panel_initialize(const u8 *init_cmds)
281 {
282  uint32_t ctrl_mode = 0;
283 
284  assert(init_cmds != NULL);
285  ctrl_mode = read32(&dsi0->ctrl);
286 
287  /* Enable command mode before sending the commands */
288  write32(&dsi0->ctrl, ctrl_mode | 0x04);
289 
291  write32(&dsi0->ctrl, ctrl_mode);
293 
294  return ret;
295 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
#define dsb()
Definition: barrier.h:16
#define assert(statement)
Definition: assert.h:74
#define ALIGN_UP(x, a)
Definition: helpers.h:17
cb_err
coreboot error codes
Definition: cb_err.h:15
@ CB_ERR
Generic error code.
Definition: cb_err.h:17
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
#define printk(level,...)
Definition: stdlib.h:16
static struct dsi_regs *const dsi0
Definition: dsi_common.h:87
enum cb_err mdss_dsi_phy_10nm_init(struct edid *edid, uint32_t num_of_lanes, uint32_t bpp)
Definition: dsi_phy.c:755
#define BIT(nr)
Definition: ec_commands.h:45
#define setbits32(addr, set)
Definition: mmio.h:21
mipi_dsi_transaction
Definition: dsi.h:7
unsigned int type
Definition: edid.c:57
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
@ DSI_VIDEO_MODE_DONE_MASK
Definition: mdssreg.h:416
@ DSI_CMD_MODE_MDP_DONE_MASK
Definition: mdssreg.h:410
@ DSI_CMD_MODE_MDP_DONE_AK
Definition: mdssreg.h:408
@ DSI_BTA_DONE_MASK
Definition: mdssreg.h:419
@ DSI_CMD_MODE_DMA_DONE_AK
Definition: mdssreg.h:405
@ DSI_CMD_MODE_DMA_DONE_MASK
Definition: mdssreg.h:407
@ DSI_ERROR_MASK
Definition: mdssreg.h:422
@ DSI_ERROR_AK
Definition: mdssreg.h:420
@ DSI_BTA_DONE_AK
Definition: mdssreg.h:417
@ DSI_VIDEO_MODE_DONE_AK
Definition: mdssreg.h:414
@ DSI_AHBS_HCLK_ON
Definition: mdssreg.h:385
@ DSI_ESCCLK_ON
Definition: mdssreg.h:390
@ DSI_AHBM_SCLK_ON
Definition: mdssreg.h:386
@ DSI_FORCE_ON_DYN_AHBM_HCLK
Definition: mdssreg.h:392
@ DSI_PCLK_ON
Definition: mdssreg.h:387
@ DSI_DSICLK_ON
Definition: mdssreg.h:388
@ DSI_BYTECLK_ON
Definition: mdssreg.h:389
enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func)
Definition: panel.c:7
void mdss_dsi_video_mode_config(struct edid *edid, uint32_t bpp)
Definition: dsi.c:99
#define DSI_VIDEO_EN
Definition: dsi.c:30
static void mdss_dsi_set_intr(void)
Definition: dsi.c:168
#define DSI_PAYLOAD_SIZE_ALIGN
Definition: dsi.c:35
static void mdss_dsi_reset(void)
Definition: dsi.c:79
#define TIMER_RESOLUTION
Definition: dsi.c:33
static enum cb_err mdss_dsi_send_init_cmd(enum mipi_dsi_transaction type, const u8 *body, u8 len)
Definition: dsi.c:207
#define DSI_DMA_TRIGGER_SEL
Definition: dsi.c:25
#define DSI_EN
Definition: dsi.c:28
#define DSI_PAYLOAD_BYTE_BOUND
Definition: dsi.c:34
#define DSI_DMA_STREAM1
Definition: dsi.c:17
#define DSI_TPG_DMA_FIFO_MODE
Definition: dsi.c:37
static void mdss_dsi_host_init(int num_of_lanes)
Definition: dsi.c:40
#define DSI_EMBED_MODE1
Definition: dsi.c:18
#define DSI_POWER_MODE2
Definition: dsi.c:19
#define DSI_EOF_BLLP_PWR
Definition: dsi.c:24
static int mdss_dsi_cmd_dma_trigger_for_panel(void)
Definition: dsi.c:177
enum cb_err mdss_dsi_panel_initialize(const u8 *init_cmds)
Definition: dsi.c:280
#define DSI_CMD_DMA_PATTERN_SEL
Definition: dsi.c:38
#define DSI_PACK_TYPE1
Definition: dsi.c:20
#define DSI_DT1
Definition: dsi.c:22
void mdss_dsi_clock_config(void)
Definition: dsi.c:154
#define DSI_VC1
Definition: dsi.c:21
#define TRAFFIC_MODE
Definition: dsi.c:26
#define DSI_WC1
Definition: dsi.c:23
#define DSI_CMD_DMA_TPG_EN
Definition: dsi.c:36
#define DSI_CLKLN_EN
Definition: dsi.c:29
static void mdss_dsi_clear_intr(void)
Definition: dsi.c:270
enum cb_err mdss_dsi_config(struct edid *edid, uint32_t num_of_lanes, uint32_t bpp)
Definition: dsi.c:141
#define HS_TX_TO
Definition: dsi.c:32
#define DSI_VIDEO_DST_FORMAT_RGB666
Definition: mipi_dsi.h:13
#define DSI_VIDEO_DST_FORMAT_RGB565
Definition: mipi_dsi.h:12
#define DSI_VIDEO_DST_FORMAT_RGB888
Definition: mipi_dsi.h:15
#define NULL
Definition: stddef.h:19
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
uint32_t video_mode_active_h
Definition: mdssreg.h:14
uint32_t ctrl
Definition: mdssreg.h:10
uint32_t int_ctrl
Definition: mdssreg.h:47
uint32_t video_mode_active_vsync_vpos
Definition: mdssreg.h:19
uint32_t video_mode_active_v
Definition: mdssreg.h:15
uint32_t dma_cmd_length
Definition: mdssreg.h:24
uint32_t tpg_dma_fifo_reset
Definition: mdssreg.h:58
uint32_t video_mode_active_total
Definition: mdssreg.h:16
uint32_t trig_ctrl
Definition: mdssreg.h:31
uint32_t video_mode_active_vsync
Definition: mdssreg.h:18
uint32_t test_pattern_gen_ctrl
Definition: mdssreg.h:52
uint32_t cmd_mode_dma_sw_trigger
Definition: mdssreg.h:33
uint32_t hs_timer_ctrl
Definition: mdssreg.h:40
uint32_t soft_reset
Definition: mdssreg.h:49
uint32_t eot_packet_ctrl
Definition: mdssreg.h:44
uint32_t video_mode_ctrl
Definition: mdssreg.h:12
uint32_t test_pattern_gen_cmd_dma_init_val
Definition: mdssreg.h:54
uint32_t err_int_mask0
Definition: mdssreg.h:46
uint32_t video_mode_active_hsync
Definition: mdssreg.h:17
uint32_t clk_ctrl
Definition: mdssreg.h:50
uint32_t cmd_mode_dma_ctrl
Definition: mdssreg.h:20
unsigned int hbl
Definition: edid.h:26
unsigned int va
Definition: edid.h:30
unsigned int vspw
Definition: edid.h:33
unsigned int ha
Definition: edid.h:25
unsigned int vso
Definition: edid.h:32
unsigned int hso
Definition: edid.h:27
unsigned int hspw
Definition: edid.h:28
unsigned int vbl
Definition: edid.h:31
Definition: edid.h:49
struct edid_mode mode
Definition: edid.h:72
void udelay(uint32_t us)
Definition: udelay.c:15
#define count