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