blob: 13dae37806f1fcc92b1194a2c35ffdbe05e8741e [file] [log] [blame]
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2013 NVIDIA Corporation
4 * Copyright (c) 2022 Svyatoslav Ryhel <clamor95@gmail.com>
5 */
6
7#include <common.h>
8#include <dm.h>
9#include <log.h>
10#include <misc.h>
11#include <mipi_display.h>
12#include <mipi_dsi.h>
13#include <backlight.h>
14#include <panel.h>
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +020015#include <reset.h>
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030016#include <linux/delay.h>
17#include <linux/err.h>
Igor Prusovc3421ea2023-11-09 20:10:04 +030018#include <linux/time.h>
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030019#include <power/regulator.h>
20
21#include <asm/gpio.h>
22#include <asm/io.h>
23#include <asm/arch/clock.h>
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030024
Svyatoslav Ryhel75fec412024-01-23 19:16:18 +020025#include "tegra-dc.h"
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020026#include "tegra-dsi.h"
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030027#include "mipi-phy.h"
28
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020029/* List of supported DSI bridges */
30enum {
31 DSI_V0,
32 DSI_V1,
33};
34
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030035struct tegra_dsi_priv {
36 struct mipi_dsi_host host;
37 struct mipi_dsi_device device;
38 struct mipi_dphy_timing dphy_timing;
39
40 struct udevice *panel;
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020041 struct udevice *mipi;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030042 struct display_timing timing;
43
44 struct dsi_ctlr *dsi;
45 struct udevice *avdd;
46
47 enum tegra_dsi_format format;
48
49 int dsi_clk;
50 int video_fifo_depth;
51 int host_fifo_depth;
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020052
53 u32 version;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030054};
55
56static void tegra_dc_enable_controller(struct udevice *dev)
57{
58 struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
59 struct dc_ctlr *dc = dc_plat->dc;
60 u32 value;
61
62 value = readl(&dc->disp.disp_win_opt);
63 value |= DSI_ENABLE;
64 writel(value, &dc->disp.disp_win_opt);
65
66 writel(GENERAL_UPDATE, &dc->cmd.state_ctrl);
67 writel(GENERAL_ACT_REQ, &dc->cmd.state_ctrl);
68}
69
70static const char * const error_report[16] = {
71 "SoT Error",
72 "SoT Sync Error",
73 "EoT Sync Error",
74 "Escape Mode Entry Command Error",
75 "Low-Power Transmit Sync Error",
76 "Peripheral Timeout Error",
77 "False Control Error",
78 "Contention Detected",
79 "ECC Error, single-bit",
80 "ECC Error, multi-bit",
81 "Checksum Error",
82 "DSI Data Type Not Recognized",
83 "DSI VC ID Invalid",
84 "Invalid Transmission Length",
85 "Reserved",
86 "DSI Protocol Violation",
87};
88
89static ssize_t tegra_dsi_read_response(struct dsi_misc_reg *misc,
90 const struct mipi_dsi_msg *msg,
91 size_t count)
92{
93 u8 *rx = msg->rx_buf;
94 unsigned int i, j, k;
95 size_t size = 0;
96 u16 errors;
97 u32 value;
98
99 /* read and parse packet header */
100 value = readl(&misc->dsi_rd_data);
101
102 switch (value & 0x3f) {
103 case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
104 errors = (value >> 8) & 0xffff;
105 printf("%s: Acknowledge and error report: %04x\n",
106 __func__, errors);
107 for (i = 0; i < ARRAY_SIZE(error_report); i++)
108 if (errors & BIT(i))
109 printf("%s: %2u: %s\n", __func__, i,
110 error_report[i]);
111 break;
112
113 case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
114 rx[0] = (value >> 8) & 0xff;
115 size = 1;
116 break;
117
118 case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
119 rx[0] = (value >> 8) & 0xff;
120 rx[1] = (value >> 16) & 0xff;
121 size = 2;
122 break;
123
124 case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
125 size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
126 break;
127
128 case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
129 size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
130 break;
131
132 default:
133 printf("%s: unhandled response type: %02x\n",
134 __func__, value & 0x3f);
135 return -EPROTO;
136 }
137
138 size = min(size, msg->rx_len);
139
140 if (msg->rx_buf && size > 0) {
141 for (i = 0, j = 0; i < count - 1; i++, j += 4) {
142 u8 *rx = msg->rx_buf + j;
143
144 value = readl(&misc->dsi_rd_data);
145
146 for (k = 0; k < 4 && (j + k) < msg->rx_len; k++)
147 rx[j + k] = (value >> (k << 3)) & 0xff;
148 }
149 }
150
151 return size;
152}
153
154static int tegra_dsi_transmit(struct dsi_misc_reg *misc,
155 unsigned long timeout)
156{
157 writel(DSI_TRIGGER_HOST, &misc->dsi_trigger);
158
159 while (timeout--) {
160 u32 value = readl(&misc->dsi_trigger);
161
162 if ((value & DSI_TRIGGER_HOST) == 0)
163 return 0;
164
165 udelay(1000);
166 }
167
168 debug("timeout waiting for transmission to complete\n");
169 return -ETIMEDOUT;
170}
171
172static int tegra_dsi_wait_for_response(struct dsi_misc_reg *misc,
173 unsigned long timeout)
174{
175 while (timeout--) {
176 u32 value = readl(&misc->dsi_status);
177 u8 count = value & 0x1f;
178
179 if (count > 0)
180 return count;
181
182 udelay(1000);
183 }
184
185 debug("peripheral returned no data\n");
186 return -ETIMEDOUT;
187}
188
189static void tegra_dsi_writesl(struct dsi_misc_reg *misc,
190 const void *buffer, size_t size)
191{
192 const u8 *buf = buffer;
193 size_t i, j;
194 u32 value;
195
196 for (j = 0; j < size; j += 4) {
197 value = 0;
198
199 for (i = 0; i < 4 && j + i < size; i++)
200 value |= buf[j + i] << (i << 3);
201
202 writel(value, &misc->dsi_wr_data);
203 }
204}
205
206static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
207 const struct mipi_dsi_msg *msg)
208{
209 struct udevice *dev = (struct udevice *)host->dev;
210 struct tegra_dsi_priv *priv = dev_get_priv(dev);
211 struct dsi_misc_reg *misc = &priv->dsi->misc;
212 struct mipi_dsi_packet packet;
213 const u8 *header;
214 size_t count;
215 ssize_t err;
216 u32 value;
217
218 err = mipi_dsi_create_packet(&packet, msg);
219 if (err < 0)
220 return err;
221
222 header = packet.header;
223
224 /* maximum FIFO depth is 1920 words */
225 if (packet.size > priv->video_fifo_depth * 4)
226 return -ENOSPC;
227
228 /* reset underflow/overflow flags */
229 value = readl(&misc->dsi_status);
230 if (value & (DSI_STATUS_UNDERFLOW | DSI_STATUS_OVERFLOW)) {
231 value = DSI_HOST_CONTROL_FIFO_RESET;
232 writel(value, &misc->host_dsi_ctrl);
233 udelay(10);
234 }
235
236 value = readl(&misc->dsi_pwr_ctrl);
237 value |= DSI_POWER_CONTROL_ENABLE;
238 writel(value, &misc->dsi_pwr_ctrl);
239
240 mdelay(5);
241
242 value = DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST |
243 DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
244
245 /*
246 * The host FIFO has a maximum of 64 words, so larger transmissions
247 * need to use the video FIFO.
248 */
249 if (packet.size > priv->host_fifo_depth * 4)
250 value |= DSI_HOST_CONTROL_FIFO_SEL;
251
252 writel(value, &misc->host_dsi_ctrl);
253
254 /*
255 * For reads and messages with explicitly requested ACK, generate a
256 * BTA sequence after the transmission of the packet.
257 */
258 if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
259 (msg->rx_buf && msg->rx_len > 0)) {
260 value = readl(&misc->host_dsi_ctrl);
261 value |= DSI_HOST_CONTROL_PKT_BTA;
262 writel(value, &misc->host_dsi_ctrl);
263 }
264
265 value = DSI_CONTROL_LANES(0) | DSI_CONTROL_HOST_ENABLE;
266 writel(value, &misc->dsi_ctrl);
267
268 /* write packet header, ECC is generated by hardware */
269 value = header[2] << 16 | header[1] << 8 | header[0];
270 writel(value, &misc->dsi_wr_data);
271
272 /* write payload (if any) */
273 if (packet.payload_length > 0)
274 tegra_dsi_writesl(misc, packet.payload,
275 packet.payload_length);
276
277 err = tegra_dsi_transmit(misc, 250);
278 if (err < 0)
279 return err;
280
281 if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
282 (msg->rx_buf && msg->rx_len > 0)) {
283 err = tegra_dsi_wait_for_response(misc, 250);
284 if (err < 0)
285 return err;
286
287 count = err;
288
289 value = readl(&misc->dsi_rd_data);
290 switch (value) {
291 case 0x84:
292 debug("%s: ACK\n", __func__);
293 break;
294
295 case 0x87:
296 debug("%s: ESCAPE\n", __func__);
297 break;
298
299 default:
300 printf("%s: unknown status: %08x\n", __func__, value);
301 break;
302 }
303
304 if (count > 1) {
305 err = tegra_dsi_read_response(misc, msg, count);
306 if (err < 0) {
307 printf("%s: failed to parse response: %zd\n",
308 __func__, err);
309 } else {
310 /*
311 * For read commands, return the number of
312 * bytes returned by the peripheral.
313 */
314 count = err;
315 }
316 }
317 } else {
318 /*
319 * For write commands, we have transmitted the 4-byte header
320 * plus the variable-length payload.
321 */
322 count = 4 + packet.payload_length;
323 }
324
325 return count;
326}
327
328struct mipi_dsi_host_ops tegra_dsi_bridge_host_ops = {
329 .transfer = tegra_dsi_host_transfer,
330};
331
332#define PKT_ID0(id) ((((id) & 0x3f) << 3) | (1 << 9))
333#define PKT_LEN0(len) (((len) & 0x07) << 0)
334#define PKT_ID1(id) ((((id) & 0x3f) << 13) | (1 << 19))
335#define PKT_LEN1(len) (((len) & 0x07) << 10)
336#define PKT_ID2(id) ((((id) & 0x3f) << 23) | (1 << 29))
337#define PKT_LEN2(len) (((len) & 0x07) << 20)
338
339#define PKT_LP BIT(30)
340#define NUM_PKT_SEQ 12
341
342/*
343 * non-burst mode with sync pulses
344 */
345static const u32 pkt_seq_video_non_burst_sync_pulses[NUM_PKT_SEQ] = {
346 [ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
347 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
348 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
349 PKT_LP,
350 [ 1] = 0,
351 [ 2] = PKT_ID0(MIPI_DSI_V_SYNC_END) | PKT_LEN0(0) |
352 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
353 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
354 PKT_LP,
355 [ 3] = 0,
356 [ 4] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
357 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
358 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
359 PKT_LP,
360 [ 5] = 0,
361 [ 6] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
362 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
363 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0),
364 [ 7] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(2) |
365 PKT_ID1(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN1(3) |
366 PKT_ID2(MIPI_DSI_BLANKING_PACKET) | PKT_LEN2(4),
367 [ 8] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
368 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
369 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
370 PKT_LP,
371 [ 9] = 0,
372 [10] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
373 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
374 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0),
375 [11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(2) |
376 PKT_ID1(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN1(3) |
377 PKT_ID2(MIPI_DSI_BLANKING_PACKET) | PKT_LEN2(4),
378};
379
380/*
381 * non-burst mode with sync events
382 */
383static const u32 pkt_seq_video_non_burst_sync_events[NUM_PKT_SEQ] = {
384 [ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
385 PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
386 PKT_LP,
387 [ 1] = 0,
388 [ 2] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
389 PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
390 PKT_LP,
391 [ 3] = 0,
392 [ 4] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
393 PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
394 PKT_LP,
395 [ 5] = 0,
396 [ 6] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
397 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(2) |
398 PKT_ID2(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN2(3),
399 [ 7] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
400 [ 8] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
401 PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
402 PKT_LP,
403 [ 9] = 0,
404 [10] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
405 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(2) |
406 PKT_ID2(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN2(3),
407 [11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
408};
409
410static const u32 pkt_seq_command_mode[NUM_PKT_SEQ] = {
411 [ 0] = 0,
412 [ 1] = 0,
413 [ 2] = 0,
414 [ 3] = 0,
415 [ 4] = 0,
416 [ 5] = 0,
417 [ 6] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(3) | PKT_LP,
418 [ 7] = 0,
419 [ 8] = 0,
420 [ 9] = 0,
421 [10] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(5) | PKT_LP,
422 [11] = 0,
423};
424
425static void tegra_dsi_get_muldiv(enum mipi_dsi_pixel_format format,
426 unsigned int *mulp, unsigned int *divp)
427{
428 switch (format) {
429 case MIPI_DSI_FMT_RGB666_PACKED:
430 case MIPI_DSI_FMT_RGB888:
431 *mulp = 3;
432 *divp = 1;
433 break;
434
435 case MIPI_DSI_FMT_RGB565:
436 *mulp = 2;
437 *divp = 1;
438 break;
439
440 case MIPI_DSI_FMT_RGB666:
441 *mulp = 9;
442 *divp = 4;
443 break;
444
445 default:
446 break;
447 }
448}
449
450static int tegra_dsi_get_format(enum mipi_dsi_pixel_format format,
451 enum tegra_dsi_format *fmt)
452{
453 switch (format) {
454 case MIPI_DSI_FMT_RGB888:
455 *fmt = TEGRA_DSI_FORMAT_24P;
456 break;
457
458 case MIPI_DSI_FMT_RGB666:
459 *fmt = TEGRA_DSI_FORMAT_18NP;
460 break;
461
462 case MIPI_DSI_FMT_RGB666_PACKED:
463 *fmt = TEGRA_DSI_FORMAT_18P;
464 break;
465
466 case MIPI_DSI_FMT_RGB565:
467 *fmt = TEGRA_DSI_FORMAT_16P;
468 break;
469
470 default:
471 return -EINVAL;
472 }
473
474 return 0;
475}
476
477static void tegra_dsi_pad_calibrate(struct dsi_pad_ctrl_reg *pad)
478{
479 u32 value;
480
481 /* start calibration */
482 value = DSI_PAD_CONTROL_PAD_LPUPADJ(0x1) |
483 DSI_PAD_CONTROL_PAD_LPDNADJ(0x1) |
484 DSI_PAD_CONTROL_PAD_PREEMP_EN(0x1) |
485 DSI_PAD_CONTROL_PAD_SLEWDNADJ(0x6) |
486 DSI_PAD_CONTROL_PAD_SLEWUPADJ(0x6) |
487 DSI_PAD_CONTROL_PAD_PDIO(0) |
488 DSI_PAD_CONTROL_PAD_PDIO_CLK(0) |
489 DSI_PAD_CONTROL_PAD_PULLDN_ENAB(0);
490 writel(value, &pad->pad_ctrl);
491
492 clock_enable(PERIPH_ID_VI);
493 clock_enable(PERIPH_ID_CSI);
494 udelay(2);
495 reset_set_enable(PERIPH_ID_VI, 0);
496 reset_set_enable(PERIPH_ID_CSI, 0);
497
498 value = MIPI_CAL_TERMOSA(0x4);
499 writel(value, TEGRA_VI_BASE + (CSI_CILA_MIPI_CAL_CONFIG_0 << 2));
500
501 value = MIPI_CAL_TERMOSB(0x4);
502 writel(value, TEGRA_VI_BASE + (CSI_CILB_MIPI_CAL_CONFIG_0 << 2));
503
504 value = MIPI_CAL_HSPUOSD(0x3) | MIPI_CAL_HSPDOSD(0x4);
505 writel(value, TEGRA_VI_BASE + (CSI_DSI_MIPI_CAL_CONFIG << 2));
506
507 value = PAD_DRIV_DN_REF(0x5) | PAD_DRIV_UP_REF(0x7);
508 writel(value, TEGRA_VI_BASE + (CSI_MIPIBIAS_PAD_CONFIG << 2));
509
510 value = PAD_CIL_PDVREG(0x0);
511 writel(value, TEGRA_VI_BASE + (CSI_CIL_PAD_CONFIG << 2));
512}
513
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200514static void tegra_dsi_mipi_calibrate(struct tegra_dsi_priv *priv)
515{
516 struct dsi_pad_ctrl_reg *pad = &priv->dsi->pad;
517 u32 value;
518 int ret;
519
520 ret = misc_set_enabled(priv->mipi, true);
521 if (ret)
522 log_debug("%s: failed to enable MIPI calibration: %d\n",
523 __func__, ret);
524
525 writel(0, &pad->pad_ctrl);
526 writel(0, &pad->pad_ctrl_1);
527 writel(0, &pad->pad_ctrl_2);
528 writel(0, &pad->pad_ctrl_3);
529 writel(0, &pad->pad_ctrl_4);
530
531 /* DSI pad enable */
532 value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
533 writel(value, &pad->pad_ctrl);
534
535 value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
536 DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
537 DSI_PAD_OUT_CLK(0x0);
538 writel(value, &pad->pad_ctrl_2);
539
540 value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
541 DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
542 writel(value, &pad->pad_ctrl_3);
543
544 ret = misc_write(priv->mipi, 0, NULL, 0);
545 if (ret)
546 log_debug("%s: MIPI calibration failed %d\n", __func__, ret);
547}
548
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300549static void tegra_dsi_set_timeout(struct dsi_timeout_reg *rtimeout,
550 unsigned long bclk,
551 unsigned int vrefresh)
552{
553 unsigned int timeout;
554 u32 value;
555
556 /* one frame high-speed transmission timeout */
557 timeout = (bclk / vrefresh) / 512;
558 value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout);
559 writel(value, &rtimeout->dsi_timeout_0);
560
561 /* 2 ms peripheral timeout for panel */
562 timeout = 2 * bclk / 512 * 1000;
563 value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000);
564 writel(value, &rtimeout->dsi_timeout_1);
565
566 value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0);
567 writel(value, &rtimeout->dsi_to_tally);
568}
569
570static void tegra_dsi_set_phy_timing(struct dsi_timing_reg *ptiming,
571 unsigned long period,
572 const struct mipi_dphy_timing *dphy_timing)
573{
574 u32 value;
575
576 value = DSI_TIMING_FIELD(dphy_timing->hsexit, period, 1) << 24 |
577 DSI_TIMING_FIELD(dphy_timing->hstrail, period, 0) << 16 |
578 DSI_TIMING_FIELD(dphy_timing->hszero, period, 3) << 8 |
579 DSI_TIMING_FIELD(dphy_timing->hsprepare, period, 1);
580 writel(value, &ptiming->dsi_phy_timing_0);
581
582 value = DSI_TIMING_FIELD(dphy_timing->clktrail, period, 1) << 24 |
583 DSI_TIMING_FIELD(dphy_timing->clkpost, period, 1) << 16 |
584 DSI_TIMING_FIELD(dphy_timing->clkzero, period, 1) << 8 |
585 DSI_TIMING_FIELD(dphy_timing->lpx, period, 1);
586 writel(value, &ptiming->dsi_phy_timing_1);
587
588 value = DSI_TIMING_FIELD(dphy_timing->clkprepare, period, 1) << 16 |
589 DSI_TIMING_FIELD(dphy_timing->clkpre, period, 1) << 8 |
590 DSI_TIMING_FIELD(0xff * period, period, 0) << 0;
591 writel(value, &ptiming->dsi_phy_timing_2);
592
593 value = DSI_TIMING_FIELD(dphy_timing->taget, period, 1) << 16 |
594 DSI_TIMING_FIELD(dphy_timing->tasure, period, 1) << 8 |
595 DSI_TIMING_FIELD(dphy_timing->tago, period, 1);
596 writel(value, &ptiming->dsi_bta_timing);
597}
598
599static void tegra_dsi_configure(struct udevice *dev,
600 unsigned long mode_flags)
601{
602 struct tegra_dsi_priv *priv = dev_get_priv(dev);
603 struct mipi_dsi_device *device = &priv->device;
604 struct display_timing *timing = &priv->timing;
605
606 struct dsi_misc_reg *misc = &priv->dsi->misc;
607 struct dsi_pkt_seq_reg *pkt = &priv->dsi->pkt;
608 struct dsi_pkt_len_reg *len = &priv->dsi->len;
609
610 unsigned int hact, hsw, hbp, hfp, i, mul, div;
611 const u32 *pkt_seq;
612 u32 value;
613
614 tegra_dsi_get_muldiv(device->format, &mul, &div);
615
616 if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
617 printf("[DSI] Non-burst video mode with sync pulses\n");
618 pkt_seq = pkt_seq_video_non_burst_sync_pulses;
619 } else if (mode_flags & MIPI_DSI_MODE_VIDEO) {
620 printf("[DSI] Non-burst video mode with sync events\n");
621 pkt_seq = pkt_seq_video_non_burst_sync_events;
622 } else {
623 printf("[DSI] Command mode\n");
624 pkt_seq = pkt_seq_command_mode;
625 }
626
627 value = DSI_CONTROL_CHANNEL(0) |
628 DSI_CONTROL_FORMAT(priv->format) |
629 DSI_CONTROL_LANES(device->lanes - 1) |
630 DSI_CONTROL_SOURCE(0);
631 writel(value, &misc->dsi_ctrl);
632
633 writel(priv->video_fifo_depth, &misc->dsi_max_threshold);
634
635 value = DSI_HOST_CONTROL_HS;
636 writel(value, &misc->host_dsi_ctrl);
637
638 value = readl(&misc->dsi_ctrl);
639
640 if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
641 value |= DSI_CONTROL_HS_CLK_CTRL;
642
643 value &= ~DSI_CONTROL_TX_TRIG(3);
644
645 /* enable DCS commands for command mode */
646 if (mode_flags & MIPI_DSI_MODE_VIDEO)
647 value &= ~DSI_CONTROL_DCS_ENABLE;
648 else
649 value |= DSI_CONTROL_DCS_ENABLE;
650
651 value |= DSI_CONTROL_VIDEO_ENABLE;
652 value &= ~DSI_CONTROL_HOST_ENABLE;
653 writel(value, &misc->dsi_ctrl);
654
655 for (i = 0; i < NUM_PKT_SEQ; i++)
656 writel(pkt_seq[i], &pkt->dsi_pkt_seq_0_lo + i);
657
658 if (mode_flags & MIPI_DSI_MODE_VIDEO) {
659 /* horizontal active pixels */
660 hact = timing->hactive.typ * mul / div;
661
662 /* horizontal sync width */
663 hsw = timing->hsync_len.typ * mul / div;
664
665 /* horizontal back porch */
666 hbp = timing->hback_porch.typ * mul / div;
667
668 if ((mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) == 0)
669 hbp += hsw;
670
671 /* horizontal front porch */
672 hfp = timing->hfront_porch.typ * mul / div;
673
674 /* subtract packet overhead */
675 hsw -= 10;
676 hbp -= 14;
677 hfp -= 8;
678
679 writel(hsw << 16 | 0, &len->dsi_pkt_len_0_1);
680 writel(hact << 16 | hbp, &len->dsi_pkt_len_2_3);
681 writel(hfp, &len->dsi_pkt_len_4_5);
682 writel(0x0f0f << 16, &len->dsi_pkt_len_6_7);
683 } else {
684 /* 1 byte (DCS command) + pixel data */
685 value = 1 + timing->hactive.typ * mul / div;
686
687 writel(0, &len->dsi_pkt_len_0_1);
688 writel(value << 16, &len->dsi_pkt_len_2_3);
689 writel(value << 16, &len->dsi_pkt_len_4_5);
690 writel(0, &len->dsi_pkt_len_6_7);
691
692 value = MIPI_DCS_WRITE_MEMORY_START << 8 |
693 MIPI_DCS_WRITE_MEMORY_CONTINUE;
694 writel(value, &len->dsi_dcs_cmds);
695 }
696
697 /* set SOL delay (for non-burst mode only) */
698 writel(8 * mul / div, &misc->dsi_sol_delay);
699}
700
701static int tegra_dsi_encoder_enable(struct udevice *dev)
702{
703 struct tegra_dsi_priv *priv = dev_get_priv(dev);
704 struct mipi_dsi_device *device = &priv->device;
705 struct display_timing *timing = &priv->timing;
706 struct dsi_misc_reg *misc = &priv->dsi->misc;
707 unsigned int mul, div;
708 unsigned long bclk, plld, period;
709 u32 value;
710 int ret;
711
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200712 /* If for some reasone DSI is enabled then it needs to
713 * be disabled in order for the panel initialization
714 * commands to be properly sent.
715 */
716 value = readl(&misc->dsi_pwr_ctrl);
717
718 if (value & DSI_POWER_CONTROL_ENABLE) {
719 value = readl(&misc->dsi_pwr_ctrl);
720 value &= ~DSI_POWER_CONTROL_ENABLE;
721 writel(value, &misc->dsi_pwr_ctrl);
722 }
723
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300724 /* Disable interrupt */
725 writel(0, &misc->int_enable);
726
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200727 if (priv->version)
728 tegra_dsi_mipi_calibrate(priv);
729 else
730 tegra_dsi_pad_calibrate(&priv->dsi->pad);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300731
732 tegra_dsi_get_muldiv(device->format, &mul, &div);
733
734 /* compute byte clock */
735 bclk = (timing->pixelclock.typ * mul) / (div * device->lanes);
736
737 tegra_dsi_set_timeout(&priv->dsi->timeout, bclk, 60);
738
739 /*
740 * Compute bit clock and round up to the next MHz.
741 */
742 plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC) * USEC_PER_SEC;
743 period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, plld);
744
745 ret = mipi_dphy_timing_get_default(&priv->dphy_timing, period);
746 if (ret < 0) {
747 printf("%s: failed to get D-PHY timing: %d\n", __func__, ret);
748 return ret;
749 }
750
751 ret = mipi_dphy_timing_validate(&priv->dphy_timing, period);
752 if (ret < 0) {
753 printf("%s: failed to validate D-PHY timing: %d\n", __func__, ret);
754 return ret;
755 }
756
757 /*
758 * The D-PHY timing fields are expressed in byte-clock cycles, so
759 * multiply the period by 8.
760 */
761 tegra_dsi_set_phy_timing(&priv->dsi->ptiming,
762 period * 8, &priv->dphy_timing);
763
764 /* Perform panel HW setup */
765 ret = panel_enable_backlight(priv->panel);
766 if (ret)
767 return ret;
768
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300769 tegra_dsi_configure(dev, device->mode_flags);
770
771 tegra_dc_enable_controller(dev);
772
773 /* enable DSI controller */
774 value = readl(&misc->dsi_pwr_ctrl);
775 value |= DSI_POWER_CONTROL_ENABLE;
776 writel(value, &misc->dsi_pwr_ctrl);
777
778 return 0;
779}
780
781static int tegra_dsi_bridge_set_panel(struct udevice *dev, int percent)
782{
Jonas Schwöbeldea5d962024-01-23 19:16:33 +0200783 struct tegra_dsi_priv *priv = dev_get_priv(dev);
784
785 /* Turn on/off backlight */
786 return panel_set_backlight(priv->panel, percent);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300787}
788
789static int tegra_dsi_panel_timings(struct udevice *dev,
790 struct display_timing *timing)
791{
792 struct tegra_dsi_priv *priv = dev_get_priv(dev);
793
794 memcpy(timing, &priv->timing, sizeof(*timing));
795
796 return 0;
797}
798
799static void tegra_dsi_init_clocks(struct udevice *dev)
800{
801 struct tegra_dsi_priv *priv = dev_get_priv(dev);
Svyatoslav Ryheld16c1052024-01-23 19:16:23 +0200802 struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300803 struct mipi_dsi_device *device = &priv->device;
804 unsigned int mul, div;
805 unsigned long bclk, plld;
806
807 tegra_dsi_get_muldiv(device->format, &mul, &div);
808
809 bclk = (priv->timing.pixelclock.typ * mul) /
810 (div * device->lanes);
811
812 plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC);
813
Svyatoslav Ryheld16c1052024-01-23 19:16:23 +0200814 dc_plat->scdiv = ((plld * USEC_PER_SEC +
815 priv->timing.pixelclock.typ / 2) /
816 priv->timing.pixelclock.typ) - 2;
817
818 /*
819 * BUG: If DISP1 is a PLLD/D2 child, it cannot go over 370MHz. The
820 * cause of this is not quite clear. This can be overcomed by
821 * halving the PLLD/D2 if the target rate is > 800MHz. This way
822 * DISP1 and DSI clocks will be equal.
823 */
824 if (plld > 800)
825 plld /= 2;
826
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300827 switch (clock_get_osc_freq()) {
828 case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
829 case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
830 clock_set_rate(CLOCK_ID_DISPLAY, plld, 12, 0, 8);
831 break;
832
833 case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
834 clock_set_rate(CLOCK_ID_DISPLAY, plld, 26, 0, 8);
835 break;
836
837 case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
838 case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
839 clock_set_rate(CLOCK_ID_DISPLAY, plld, 13, 0, 8);
840 break;
841
842 case CLOCK_OSC_FREQ_19_2:
843 case CLOCK_OSC_FREQ_38_4:
844 default:
845 /*
846 * These are not supported.
847 */
848 break;
849 }
850
851 priv->dsi_clk = clock_decode_periph_id(dev);
852
853 clock_enable(priv->dsi_clk);
854 udelay(2);
855 reset_set_enable(priv->dsi_clk, 0);
856}
857
858static int tegra_dsi_bridge_probe(struct udevice *dev)
859{
860 struct tegra_dsi_priv *priv = dev_get_priv(dev);
861 struct mipi_dsi_device *device = &priv->device;
862 struct mipi_dsi_panel_plat *mipi_plat;
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +0200863 struct reset_ctl reset_ctl;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300864 int ret;
865
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200866 priv->version = dev_get_driver_data(dev);
867
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300868 priv->dsi = (struct dsi_ctlr *)dev_read_addr_ptr(dev);
869 if (!priv->dsi) {
870 printf("%s: No display controller address\n", __func__);
871 return -EINVAL;
872 }
873
Jonas Schwöbel0cccf902024-01-23 19:16:32 +0200874 priv->video_fifo_depth = 1920;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300875 priv->host_fifo_depth = 64;
876
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +0200877 ret = reset_get_by_name(dev, "dsi", &reset_ctl);
878 if (ret) {
879 log_debug("%s: reset_get_by_name() failed: %d\n",
880 __func__, ret);
881 return ret;
882 }
883
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300884 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
885 "avdd-dsi-csi-supply", &priv->avdd);
886 if (ret)
887 debug("%s: Cannot get avdd-dsi-csi-supply: error %d\n",
888 __func__, ret);
889
890 ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev,
891 "panel", &priv->panel);
892 if (ret) {
893 printf("%s: Cannot get panel: error %d\n", __func__, ret);
894 return log_ret(ret);
895 }
896
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200897 if (priv->version) {
898 ret = uclass_get_device_by_phandle(UCLASS_MISC, dev,
899 "nvidia,mipi-calibrate",
900 &priv->mipi);
901 if (ret) {
902 log_debug("%s: cannot get MIPI: error %d\n", __func__, ret);
903 return ret;
904 }
905 }
906
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300907 panel_get_display_timing(priv->panel, &priv->timing);
908
909 mipi_plat = dev_get_plat(priv->panel);
910 mipi_plat->device = device;
911
912 priv->host.dev = (struct device *)dev;
913 priv->host.ops = &tegra_dsi_bridge_host_ops;
914
915 device->host = &priv->host;
916 device->lanes = mipi_plat->lanes;
917 device->format = mipi_plat->format;
918 device->mode_flags = mipi_plat->mode_flags;
919
920 tegra_dsi_get_format(device->format, &priv->format);
921
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +0200922 reset_assert(&reset_ctl);
923
Svyatoslav Ryheldaab7d92023-10-03 09:25:34 +0300924 ret = regulator_set_enable_if_allowed(priv->avdd, true);
925 if (ret && ret != -ENOSYS)
926 return ret;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300927
928 tegra_dsi_init_clocks(dev);
929
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +0200930 mdelay(2);
931 reset_deassert(&reset_ctl);
932
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300933 return 0;
934}
935
936static const struct panel_ops tegra_dsi_bridge_ops = {
937 .enable_backlight = tegra_dsi_encoder_enable,
938 .set_backlight = tegra_dsi_bridge_set_panel,
939 .get_display_timing = tegra_dsi_panel_timings,
940};
941
942static const struct udevice_id tegra_dsi_bridge_ids[] = {
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200943 { .compatible = "nvidia,tegra30-dsi", .data = DSI_V0 },
944 { .compatible = "nvidia,tegra114-dsi", .data = DSI_V1 },
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300945 { }
946};
947
948U_BOOT_DRIVER(tegra_dsi) = {
949 .name = "tegra_dsi",
950 .id = UCLASS_PANEL,
951 .of_match = tegra_dsi_bridge_ids,
952 .ops = &tegra_dsi_bridge_ops,
953 .probe = tegra_dsi_bridge_probe,
954 .plat_auto = sizeof(struct tegra_dc_plat),
955 .priv_auto = sizeof(struct tegra_dsi_priv),
956};