blob: 9f39ac7589b54e12583219d1a39dffa288336af5 [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>
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +02008#include <clk.h>
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03009#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 Ryhelab120e52024-07-30 13:35:45 +030024#include <asm/arch-tegra/clk_rst.h>
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030025
Svyatoslav Ryhel75fec412024-01-23 19:16:18 +020026#include "tegra-dc.h"
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020027#include "tegra-dsi.h"
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030028#include "mipi-phy.h"
29
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020030/* List of supported DSI bridges */
31enum {
32 DSI_V0,
33 DSI_V1,
34};
35
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030036struct tegra_dsi_priv {
37 struct mipi_dsi_host host;
38 struct mipi_dsi_device device;
39 struct mipi_dphy_timing dphy_timing;
40
41 struct udevice *panel;
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020042 struct udevice *mipi;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030043 struct display_timing timing;
44
45 struct dsi_ctlr *dsi;
46 struct udevice *avdd;
47
48 enum tegra_dsi_format format;
49
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +020050 struct clk *clk;
51 struct clk *clk_parent;
52
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030053 int video_fifo_depth;
54 int host_fifo_depth;
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020055
Svyatoslav Ryhel30cdefe2024-11-18 08:58:18 +020056 u32 calibration_pads;
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +020057 u32 version;
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +030058
59 /* for ganged-mode support */
60 struct udevice *master;
61 struct udevice *slave;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +030062};
63
64static void tegra_dc_enable_controller(struct udevice *dev)
65{
66 struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
67 struct dc_ctlr *dc = dc_plat->dc;
68 u32 value;
69
70 value = readl(&dc->disp.disp_win_opt);
71 value |= DSI_ENABLE;
72 writel(value, &dc->disp.disp_win_opt);
73
74 writel(GENERAL_UPDATE, &dc->cmd.state_ctrl);
75 writel(GENERAL_ACT_REQ, &dc->cmd.state_ctrl);
76}
77
78static const char * const error_report[16] = {
79 "SoT Error",
80 "SoT Sync Error",
81 "EoT Sync Error",
82 "Escape Mode Entry Command Error",
83 "Low-Power Transmit Sync Error",
84 "Peripheral Timeout Error",
85 "False Control Error",
86 "Contention Detected",
87 "ECC Error, single-bit",
88 "ECC Error, multi-bit",
89 "Checksum Error",
90 "DSI Data Type Not Recognized",
91 "DSI VC ID Invalid",
92 "Invalid Transmission Length",
93 "Reserved",
94 "DSI Protocol Violation",
95};
96
97static ssize_t tegra_dsi_read_response(struct dsi_misc_reg *misc,
98 const struct mipi_dsi_msg *msg,
99 size_t count)
100{
101 u8 *rx = msg->rx_buf;
102 unsigned int i, j, k;
103 size_t size = 0;
104 u16 errors;
105 u32 value;
106
107 /* read and parse packet header */
108 value = readl(&misc->dsi_rd_data);
109
110 switch (value & 0x3f) {
111 case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
112 errors = (value >> 8) & 0xffff;
113 printf("%s: Acknowledge and error report: %04x\n",
114 __func__, errors);
115 for (i = 0; i < ARRAY_SIZE(error_report); i++)
116 if (errors & BIT(i))
117 printf("%s: %2u: %s\n", __func__, i,
118 error_report[i]);
119 break;
120
121 case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
122 rx[0] = (value >> 8) & 0xff;
123 size = 1;
124 break;
125
126 case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
127 rx[0] = (value >> 8) & 0xff;
128 rx[1] = (value >> 16) & 0xff;
129 size = 2;
130 break;
131
132 case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
133 size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
134 break;
135
136 case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
137 size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
138 break;
139
140 default:
141 printf("%s: unhandled response type: %02x\n",
142 __func__, value & 0x3f);
143 return -EPROTO;
144 }
145
146 size = min(size, msg->rx_len);
147
148 if (msg->rx_buf && size > 0) {
149 for (i = 0, j = 0; i < count - 1; i++, j += 4) {
150 u8 *rx = msg->rx_buf + j;
151
152 value = readl(&misc->dsi_rd_data);
153
154 for (k = 0; k < 4 && (j + k) < msg->rx_len; k++)
155 rx[j + k] = (value >> (k << 3)) & 0xff;
156 }
157 }
158
159 return size;
160}
161
162static int tegra_dsi_transmit(struct dsi_misc_reg *misc,
163 unsigned long timeout)
164{
165 writel(DSI_TRIGGER_HOST, &misc->dsi_trigger);
166
167 while (timeout--) {
168 u32 value = readl(&misc->dsi_trigger);
169
170 if ((value & DSI_TRIGGER_HOST) == 0)
171 return 0;
172
173 udelay(1000);
174 }
175
176 debug("timeout waiting for transmission to complete\n");
177 return -ETIMEDOUT;
178}
179
180static int tegra_dsi_wait_for_response(struct dsi_misc_reg *misc,
181 unsigned long timeout)
182{
183 while (timeout--) {
184 u32 value = readl(&misc->dsi_status);
185 u8 count = value & 0x1f;
186
187 if (count > 0)
188 return count;
189
190 udelay(1000);
191 }
192
193 debug("peripheral returned no data\n");
194 return -ETIMEDOUT;
195}
196
197static void tegra_dsi_writesl(struct dsi_misc_reg *misc,
198 const void *buffer, size_t size)
199{
200 const u8 *buf = buffer;
201 size_t i, j;
202 u32 value;
203
204 for (j = 0; j < size; j += 4) {
205 value = 0;
206
207 for (i = 0; i < 4 && j + i < size; i++)
208 value |= buf[j + i] << (i << 3);
209
210 writel(value, &misc->dsi_wr_data);
211 }
212}
213
214static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
215 const struct mipi_dsi_msg *msg)
216{
217 struct udevice *dev = (struct udevice *)host->dev;
218 struct tegra_dsi_priv *priv = dev_get_priv(dev);
219 struct dsi_misc_reg *misc = &priv->dsi->misc;
220 struct mipi_dsi_packet packet;
221 const u8 *header;
222 size_t count;
223 ssize_t err;
224 u32 value;
225
226 err = mipi_dsi_create_packet(&packet, msg);
227 if (err < 0)
228 return err;
229
230 header = packet.header;
231
232 /* maximum FIFO depth is 1920 words */
233 if (packet.size > priv->video_fifo_depth * 4)
234 return -ENOSPC;
235
236 /* reset underflow/overflow flags */
237 value = readl(&misc->dsi_status);
238 if (value & (DSI_STATUS_UNDERFLOW | DSI_STATUS_OVERFLOW)) {
239 value = DSI_HOST_CONTROL_FIFO_RESET;
240 writel(value, &misc->host_dsi_ctrl);
241 udelay(10);
242 }
243
244 value = readl(&misc->dsi_pwr_ctrl);
245 value |= DSI_POWER_CONTROL_ENABLE;
246 writel(value, &misc->dsi_pwr_ctrl);
247
248 mdelay(5);
249
250 value = DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST |
251 DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
252
253 /*
254 * The host FIFO has a maximum of 64 words, so larger transmissions
255 * need to use the video FIFO.
256 */
257 if (packet.size > priv->host_fifo_depth * 4)
258 value |= DSI_HOST_CONTROL_FIFO_SEL;
259
260 writel(value, &misc->host_dsi_ctrl);
261
262 /*
263 * For reads and messages with explicitly requested ACK, generate a
264 * BTA sequence after the transmission of the packet.
265 */
266 if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
267 (msg->rx_buf && msg->rx_len > 0)) {
268 value = readl(&misc->host_dsi_ctrl);
269 value |= DSI_HOST_CONTROL_PKT_BTA;
270 writel(value, &misc->host_dsi_ctrl);
271 }
272
273 value = DSI_CONTROL_LANES(0) | DSI_CONTROL_HOST_ENABLE;
274 writel(value, &misc->dsi_ctrl);
275
276 /* write packet header, ECC is generated by hardware */
277 value = header[2] << 16 | header[1] << 8 | header[0];
278 writel(value, &misc->dsi_wr_data);
279
280 /* write payload (if any) */
281 if (packet.payload_length > 0)
282 tegra_dsi_writesl(misc, packet.payload,
283 packet.payload_length);
284
285 err = tegra_dsi_transmit(misc, 250);
286 if (err < 0)
287 return err;
288
289 if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
290 (msg->rx_buf && msg->rx_len > 0)) {
291 err = tegra_dsi_wait_for_response(misc, 250);
292 if (err < 0)
293 return err;
294
295 count = err;
296
297 value = readl(&misc->dsi_rd_data);
298 switch (value) {
299 case 0x84:
300 debug("%s: ACK\n", __func__);
301 break;
302
303 case 0x87:
304 debug("%s: ESCAPE\n", __func__);
305 break;
306
307 default:
308 printf("%s: unknown status: %08x\n", __func__, value);
309 break;
310 }
311
312 if (count > 1) {
313 err = tegra_dsi_read_response(misc, msg, count);
314 if (err < 0) {
315 printf("%s: failed to parse response: %zd\n",
316 __func__, err);
317 } else {
318 /*
319 * For read commands, return the number of
320 * bytes returned by the peripheral.
321 */
322 count = err;
323 }
324 }
325 } else {
326 /*
327 * For write commands, we have transmitted the 4-byte header
328 * plus the variable-length payload.
329 */
330 count = 4 + packet.payload_length;
331 }
332
333 return count;
334}
335
336struct mipi_dsi_host_ops tegra_dsi_bridge_host_ops = {
337 .transfer = tegra_dsi_host_transfer,
338};
339
340#define PKT_ID0(id) ((((id) & 0x3f) << 3) | (1 << 9))
341#define PKT_LEN0(len) (((len) & 0x07) << 0)
342#define PKT_ID1(id) ((((id) & 0x3f) << 13) | (1 << 19))
343#define PKT_LEN1(len) (((len) & 0x07) << 10)
344#define PKT_ID2(id) ((((id) & 0x3f) << 23) | (1 << 29))
345#define PKT_LEN2(len) (((len) & 0x07) << 20)
346
347#define PKT_LP BIT(30)
348#define NUM_PKT_SEQ 12
349
350/*
351 * non-burst mode with sync pulses
352 */
353static const u32 pkt_seq_video_non_burst_sync_pulses[NUM_PKT_SEQ] = {
354 [ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
355 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
356 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
357 PKT_LP,
358 [ 1] = 0,
359 [ 2] = PKT_ID0(MIPI_DSI_V_SYNC_END) | PKT_LEN0(0) |
360 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
361 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
362 PKT_LP,
363 [ 3] = 0,
364 [ 4] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
365 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
366 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
367 PKT_LP,
368 [ 5] = 0,
369 [ 6] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
370 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
371 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0),
372 [ 7] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(2) |
373 PKT_ID1(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN1(3) |
374 PKT_ID2(MIPI_DSI_BLANKING_PACKET) | PKT_LEN2(4),
375 [ 8] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
376 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
377 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
378 PKT_LP,
379 [ 9] = 0,
380 [10] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
381 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
382 PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0),
383 [11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(2) |
384 PKT_ID1(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN1(3) |
385 PKT_ID2(MIPI_DSI_BLANKING_PACKET) | PKT_LEN2(4),
386};
387
388/*
389 * non-burst mode with sync events
390 */
391static const u32 pkt_seq_video_non_burst_sync_events[NUM_PKT_SEQ] = {
392 [ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
393 PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
394 PKT_LP,
395 [ 1] = 0,
396 [ 2] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
397 PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
398 PKT_LP,
399 [ 3] = 0,
400 [ 4] = 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 [ 5] = 0,
404 [ 6] = 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 [ 7] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
408 [ 8] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
409 PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
410 PKT_LP,
411 [ 9] = 0,
412 [10] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
413 PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(2) |
414 PKT_ID2(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN2(3),
415 [11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
416};
417
418static const u32 pkt_seq_command_mode[NUM_PKT_SEQ] = {
419 [ 0] = 0,
420 [ 1] = 0,
421 [ 2] = 0,
422 [ 3] = 0,
423 [ 4] = 0,
424 [ 5] = 0,
425 [ 6] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(3) | PKT_LP,
426 [ 7] = 0,
427 [ 8] = 0,
428 [ 9] = 0,
429 [10] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(5) | PKT_LP,
430 [11] = 0,
431};
432
433static void tegra_dsi_get_muldiv(enum mipi_dsi_pixel_format format,
434 unsigned int *mulp, unsigned int *divp)
435{
436 switch (format) {
437 case MIPI_DSI_FMT_RGB666_PACKED:
438 case MIPI_DSI_FMT_RGB888:
439 *mulp = 3;
440 *divp = 1;
441 break;
442
443 case MIPI_DSI_FMT_RGB565:
444 *mulp = 2;
445 *divp = 1;
446 break;
447
448 case MIPI_DSI_FMT_RGB666:
449 *mulp = 9;
450 *divp = 4;
451 break;
452
453 default:
454 break;
455 }
456}
457
458static int tegra_dsi_get_format(enum mipi_dsi_pixel_format format,
459 enum tegra_dsi_format *fmt)
460{
461 switch (format) {
462 case MIPI_DSI_FMT_RGB888:
463 *fmt = TEGRA_DSI_FORMAT_24P;
464 break;
465
466 case MIPI_DSI_FMT_RGB666:
467 *fmt = TEGRA_DSI_FORMAT_18NP;
468 break;
469
470 case MIPI_DSI_FMT_RGB666_PACKED:
471 *fmt = TEGRA_DSI_FORMAT_18P;
472 break;
473
474 case MIPI_DSI_FMT_RGB565:
475 *fmt = TEGRA_DSI_FORMAT_16P;
476 break;
477
478 default:
479 return -EINVAL;
480 }
481
482 return 0;
483}
484
485static void tegra_dsi_pad_calibrate(struct dsi_pad_ctrl_reg *pad)
486{
487 u32 value;
488
489 /* start calibration */
490 value = DSI_PAD_CONTROL_PAD_LPUPADJ(0x1) |
491 DSI_PAD_CONTROL_PAD_LPDNADJ(0x1) |
492 DSI_PAD_CONTROL_PAD_PREEMP_EN(0x1) |
493 DSI_PAD_CONTROL_PAD_SLEWDNADJ(0x6) |
494 DSI_PAD_CONTROL_PAD_SLEWUPADJ(0x6) |
495 DSI_PAD_CONTROL_PAD_PDIO(0) |
496 DSI_PAD_CONTROL_PAD_PDIO_CLK(0) |
497 DSI_PAD_CONTROL_PAD_PULLDN_ENAB(0);
498 writel(value, &pad->pad_ctrl);
499
500 clock_enable(PERIPH_ID_VI);
501 clock_enable(PERIPH_ID_CSI);
502 udelay(2);
503 reset_set_enable(PERIPH_ID_VI, 0);
504 reset_set_enable(PERIPH_ID_CSI, 0);
505
506 value = MIPI_CAL_TERMOSA(0x4);
507 writel(value, TEGRA_VI_BASE + (CSI_CILA_MIPI_CAL_CONFIG_0 << 2));
508
509 value = MIPI_CAL_TERMOSB(0x4);
510 writel(value, TEGRA_VI_BASE + (CSI_CILB_MIPI_CAL_CONFIG_0 << 2));
511
512 value = MIPI_CAL_HSPUOSD(0x3) | MIPI_CAL_HSPDOSD(0x4);
513 writel(value, TEGRA_VI_BASE + (CSI_DSI_MIPI_CAL_CONFIG << 2));
514
515 value = PAD_DRIV_DN_REF(0x5) | PAD_DRIV_UP_REF(0x7);
516 writel(value, TEGRA_VI_BASE + (CSI_MIPIBIAS_PAD_CONFIG << 2));
517
518 value = PAD_CIL_PDVREG(0x0);
519 writel(value, TEGRA_VI_BASE + (CSI_CIL_PAD_CONFIG << 2));
520}
521
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200522static void tegra_dsi_mipi_calibrate(struct udevice *dev)
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200523{
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200524 struct tegra_dsi_priv *priv = dev_get_priv(dev);
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200525 struct dsi_pad_ctrl_reg *pad = &priv->dsi->pad;
526 u32 value;
527 int ret;
528
529 ret = misc_set_enabled(priv->mipi, true);
530 if (ret)
531 log_debug("%s: failed to enable MIPI calibration: %d\n",
532 __func__, ret);
533
534 writel(0, &pad->pad_ctrl);
535 writel(0, &pad->pad_ctrl_1);
536 writel(0, &pad->pad_ctrl_2);
537 writel(0, &pad->pad_ctrl_3);
538 writel(0, &pad->pad_ctrl_4);
539
540 /* DSI pad enable */
541 value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
542 writel(value, &pad->pad_ctrl);
543
544 value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
545 DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
546 DSI_PAD_OUT_CLK(0x0);
547 writel(value, &pad->pad_ctrl_2);
548
549 value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
550 DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
551 writel(value, &pad->pad_ctrl_3);
552
Svyatoslav Ryhel30cdefe2024-11-18 08:58:18 +0200553 ret = misc_write(priv->mipi, priv->calibration_pads, NULL, 0);
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200554 if (ret)
555 log_debug("%s: MIPI calibration failed %d\n", __func__, ret);
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200556
557 if (priv->slave)
558 tegra_dsi_mipi_calibrate(priv->slave);
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200559}
560
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200561static void tegra_dsi_set_timeout(struct udevice *dev,
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300562 unsigned long bclk,
563 unsigned int vrefresh)
564{
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200565 struct tegra_dsi_priv *priv = dev_get_priv(dev);
566 struct dsi_timeout_reg *rtimeout = &priv->dsi->timeout;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300567 unsigned int timeout;
568 u32 value;
569
570 /* one frame high-speed transmission timeout */
571 timeout = (bclk / vrefresh) / 512;
572 value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout);
573 writel(value, &rtimeout->dsi_timeout_0);
574
575 /* 2 ms peripheral timeout for panel */
576 timeout = 2 * bclk / 512 * 1000;
577 value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000);
578 writel(value, &rtimeout->dsi_timeout_1);
579
580 value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0);
581 writel(value, &rtimeout->dsi_to_tally);
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200582
583 if (priv->slave)
584 tegra_dsi_set_timeout(priv->slave, bclk, vrefresh);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300585}
586
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200587static void tegra_dsi_set_phy_timing(struct udevice *dev,
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300588 unsigned long period,
589 const struct mipi_dphy_timing *dphy_timing)
590{
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200591 struct tegra_dsi_priv *priv = dev_get_priv(dev);
592 struct dsi_timing_reg *ptiming = &priv->dsi->ptiming;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300593 u32 value;
594
595 value = DSI_TIMING_FIELD(dphy_timing->hsexit, period, 1) << 24 |
596 DSI_TIMING_FIELD(dphy_timing->hstrail, period, 0) << 16 |
597 DSI_TIMING_FIELD(dphy_timing->hszero, period, 3) << 8 |
598 DSI_TIMING_FIELD(dphy_timing->hsprepare, period, 1);
599 writel(value, &ptiming->dsi_phy_timing_0);
600
601 value = DSI_TIMING_FIELD(dphy_timing->clktrail, period, 1) << 24 |
602 DSI_TIMING_FIELD(dphy_timing->clkpost, period, 1) << 16 |
603 DSI_TIMING_FIELD(dphy_timing->clkzero, period, 1) << 8 |
604 DSI_TIMING_FIELD(dphy_timing->lpx, period, 1);
605 writel(value, &ptiming->dsi_phy_timing_1);
606
607 value = DSI_TIMING_FIELD(dphy_timing->clkprepare, period, 1) << 16 |
608 DSI_TIMING_FIELD(dphy_timing->clkpre, period, 1) << 8 |
609 DSI_TIMING_FIELD(0xff * period, period, 0) << 0;
610 writel(value, &ptiming->dsi_phy_timing_2);
611
612 value = DSI_TIMING_FIELD(dphy_timing->taget, period, 1) << 16 |
613 DSI_TIMING_FIELD(dphy_timing->tasure, period, 1) << 8 |
614 DSI_TIMING_FIELD(dphy_timing->tago, period, 1);
615 writel(value, &ptiming->dsi_bta_timing);
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200616
617 if (priv->slave)
618 tegra_dsi_set_phy_timing(priv->slave, period, dphy_timing);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300619}
620
Svyatoslav Ryhelf87af5a2025-02-26 09:51:09 +0200621static u32 tegra_dsi_get_lanes(struct udevice *dev)
622{
623 struct tegra_dsi_priv *priv = dev_get_priv(dev);
624 struct mipi_dsi_device *device = &priv->device;
625
626 if (priv->master) {
627 struct tegra_dsi_priv *mpriv = dev_get_priv(priv->master);
628 struct mipi_dsi_device *mdevice = &mpriv->device;
629
630 return mdevice->lanes + device->lanes;
631 }
632
633 if (priv->slave) {
634 struct tegra_dsi_priv *spriv = dev_get_priv(priv->slave);
635 struct mipi_dsi_device *sdevice = &spriv->device;
636
637 return device->lanes + sdevice->lanes;
638 }
639
640 return device->lanes;
641}
642
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300643static void tegra_dsi_ganged_enable(struct udevice *dev, unsigned int start,
644 unsigned int size)
645{
646 struct tegra_dsi_priv *priv = dev_get_priv(dev);
647 struct dsi_ganged_mode_reg *ganged = &priv->dsi->ganged;
648
649 writel(start, &ganged->ganged_mode_start);
650 writel(size << 16 | size, &ganged->ganged_mode_size);
651 writel(DSI_GANGED_MODE_CONTROL_ENABLE, &ganged->ganged_mode_ctrl);
652}
653
Svyatoslav Ryhel6a5efea2024-12-31 09:58:01 +0200654static void tegra_dsi_configure(struct udevice *dev, unsigned int pipe,
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300655 unsigned long mode_flags)
656{
657 struct tegra_dsi_priv *priv = dev_get_priv(dev);
658 struct mipi_dsi_device *device = &priv->device;
659 struct display_timing *timing = &priv->timing;
660
661 struct dsi_misc_reg *misc = &priv->dsi->misc;
662 struct dsi_pkt_seq_reg *pkt = &priv->dsi->pkt;
663 struct dsi_pkt_len_reg *len = &priv->dsi->len;
664
665 unsigned int hact, hsw, hbp, hfp, i, mul, div;
666 const u32 *pkt_seq;
667 u32 value;
668
669 tegra_dsi_get_muldiv(device->format, &mul, &div);
670
671 if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
672 printf("[DSI] Non-burst video mode with sync pulses\n");
673 pkt_seq = pkt_seq_video_non_burst_sync_pulses;
674 } else if (mode_flags & MIPI_DSI_MODE_VIDEO) {
675 printf("[DSI] Non-burst video mode with sync events\n");
676 pkt_seq = pkt_seq_video_non_burst_sync_events;
677 } else {
678 printf("[DSI] Command mode\n");
679 pkt_seq = pkt_seq_command_mode;
680 }
681
682 value = DSI_CONTROL_CHANNEL(0) |
683 DSI_CONTROL_FORMAT(priv->format) |
684 DSI_CONTROL_LANES(device->lanes - 1) |
Svyatoslav Ryhel6a5efea2024-12-31 09:58:01 +0200685 DSI_CONTROL_SOURCE(pipe);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300686 writel(value, &misc->dsi_ctrl);
687
688 writel(priv->video_fifo_depth, &misc->dsi_max_threshold);
689
690 value = DSI_HOST_CONTROL_HS;
691 writel(value, &misc->host_dsi_ctrl);
692
693 value = readl(&misc->dsi_ctrl);
694
695 if (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
696 value |= DSI_CONTROL_HS_CLK_CTRL;
697
698 value &= ~DSI_CONTROL_TX_TRIG(3);
699
700 /* enable DCS commands for command mode */
701 if (mode_flags & MIPI_DSI_MODE_VIDEO)
702 value &= ~DSI_CONTROL_DCS_ENABLE;
703 else
704 value |= DSI_CONTROL_DCS_ENABLE;
705
706 value |= DSI_CONTROL_VIDEO_ENABLE;
707 value &= ~DSI_CONTROL_HOST_ENABLE;
708 writel(value, &misc->dsi_ctrl);
709
710 for (i = 0; i < NUM_PKT_SEQ; i++)
711 writel(pkt_seq[i], &pkt->dsi_pkt_seq_0_lo + i);
712
713 if (mode_flags & MIPI_DSI_MODE_VIDEO) {
714 /* horizontal active pixels */
715 hact = timing->hactive.typ * mul / div;
716
717 /* horizontal sync width */
718 hsw = timing->hsync_len.typ * mul / div;
719
720 /* horizontal back porch */
721 hbp = timing->hback_porch.typ * mul / div;
722
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300723 /* horizontal front porch */
724 hfp = timing->hfront_porch.typ * mul / div;
725
Svyatoslav Ryhel10833fb2024-12-02 08:12:36 +0200726 if (priv->master || priv->slave) {
727 hact /= 2;
728 hsw /= 2;
729 hbp = hbp / 2 - 1;
730 hfp /= 2;
731 }
732
733 if ((mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) == 0)
734 hbp += hsw;
735
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300736 /* subtract packet overhead */
737 hsw -= 10;
738 hbp -= 14;
739 hfp -= 8;
740
741 writel(hsw << 16 | 0, &len->dsi_pkt_len_0_1);
742 writel(hact << 16 | hbp, &len->dsi_pkt_len_2_3);
743 writel(hfp, &len->dsi_pkt_len_4_5);
744 writel(0x0f0f << 16, &len->dsi_pkt_len_6_7);
745 } else {
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300746 if (priv->master || priv->slave) {
747 /*
748 * For ganged mode, assume symmetric left-right mode.
749 */
750 value = 1 + (timing->hactive.typ / 2) * mul / div;
751 } else {
752 /* 1 byte (DCS command) + pixel data */
753 value = 1 + timing->hactive.typ * mul / div;
754 }
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300755
756 writel(0, &len->dsi_pkt_len_0_1);
757 writel(value << 16, &len->dsi_pkt_len_2_3);
758 writel(value << 16, &len->dsi_pkt_len_4_5);
759 writel(0, &len->dsi_pkt_len_6_7);
760
761 value = MIPI_DCS_WRITE_MEMORY_START << 8 |
762 MIPI_DCS_WRITE_MEMORY_CONTINUE;
763 writel(value, &len->dsi_dcs_cmds);
Svyatoslav Ryhel18e4dcf2024-12-02 08:08:03 +0200764 }
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300765
Svyatoslav Ryhel18e4dcf2024-12-02 08:08:03 +0200766 /* set SOL delay */
767 if (priv->master || priv->slave) {
768 unsigned long delay, bclk, bclk_ganged;
Svyatoslav Ryhelf87af5a2025-02-26 09:51:09 +0200769 unsigned int lanes = tegra_dsi_get_lanes(dev);
Svyatoslav Ryhel18e4dcf2024-12-02 08:08:03 +0200770 unsigned long htotal = timing->hactive.typ + timing->hfront_porch.typ +
771 timing->hback_porch.typ + timing->hsync_len.typ;
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300772
Svyatoslav Ryhel18e4dcf2024-12-02 08:08:03 +0200773 /* SOL to valid, valid to FIFO and FIFO write delay */
774 delay = 4 + 4 + 2;
775 delay = DIV_ROUND_UP(delay * mul, div * lanes);
776 /* FIFO read delay */
777 delay = delay + 6;
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300778
Svyatoslav Ryhel18e4dcf2024-12-02 08:08:03 +0200779 bclk = DIV_ROUND_UP(htotal * mul, div * lanes);
780 bclk_ganged = DIV_ROUND_UP(bclk * lanes / 2, lanes);
781 value = bclk - bclk_ganged + delay + 20;
782 } else {
783 /* set SOL delay (for non-burst mode only) */
784 value = 8 * mul / div;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300785 }
786
Svyatoslav Ryhel18e4dcf2024-12-02 08:08:03 +0200787 writel(value, &misc->dsi_sol_delay);
788
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300789 if (priv->slave) {
Svyatoslav Ryhel6a5efea2024-12-31 09:58:01 +0200790 tegra_dsi_configure(priv->slave, pipe, mode_flags);
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300791 /*
792 * TODO: Support modes other than symmetrical left-right
793 * split.
794 */
795 tegra_dsi_ganged_enable(dev, 0, timing->hactive.typ / 2);
796 tegra_dsi_ganged_enable(priv->slave, timing->hactive.typ / 2,
797 timing->hactive.typ / 2);
798 }
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300799}
800
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200801static void tegra_dsi_enable(struct udevice *dev)
802{
803 struct tegra_dsi_priv *priv = dev_get_priv(dev);
804 struct dsi_misc_reg *misc = &priv->dsi->misc;
805 u32 value;
806
807 /* enable DSI controller */
808 value = readl(&misc->dsi_pwr_ctrl);
809 value |= DSI_POWER_CONTROL_ENABLE;
810 writel(value, &misc->dsi_pwr_ctrl);
811
812 if (priv->slave)
813 tegra_dsi_enable(priv->slave);
814}
815
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300816static int tegra_dsi_encoder_enable(struct udevice *dev)
817{
818 struct tegra_dsi_priv *priv = dev_get_priv(dev);
Svyatoslav Ryhel6a5efea2024-12-31 09:58:01 +0200819 struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300820 struct mipi_dsi_device *device = &priv->device;
821 struct display_timing *timing = &priv->timing;
822 struct dsi_misc_reg *misc = &priv->dsi->misc;
823 unsigned int mul, div;
824 unsigned long bclk, plld, period;
Svyatoslav Ryhelf87af5a2025-02-26 09:51:09 +0200825 u32 value, lanes;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300826 int ret;
827
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200828 /* If for some reasone DSI is enabled then it needs to
829 * be disabled in order for the panel initialization
830 * commands to be properly sent.
831 */
832 value = readl(&misc->dsi_pwr_ctrl);
833
834 if (value & DSI_POWER_CONTROL_ENABLE) {
835 value = readl(&misc->dsi_pwr_ctrl);
836 value &= ~DSI_POWER_CONTROL_ENABLE;
837 writel(value, &misc->dsi_pwr_ctrl);
838 }
839
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300840 /* Disable interrupt */
841 writel(0, &misc->int_enable);
842
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200843 if (priv->version)
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200844 tegra_dsi_mipi_calibrate(dev);
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +0200845 else
846 tegra_dsi_pad_calibrate(&priv->dsi->pad);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300847
848 tegra_dsi_get_muldiv(device->format, &mul, &div);
849
850 /* compute byte clock */
Svyatoslav Ryhelf87af5a2025-02-26 09:51:09 +0200851 lanes = tegra_dsi_get_lanes(dev);
852 bclk = (timing->pixelclock.typ * mul) / (div * lanes);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300853
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200854 tegra_dsi_set_timeout(dev, bclk, 60);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300855
856 /*
857 * Compute bit clock and round up to the next MHz.
858 */
859 plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC) * USEC_PER_SEC;
860 period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, plld);
861
862 ret = mipi_dphy_timing_get_default(&priv->dphy_timing, period);
863 if (ret < 0) {
864 printf("%s: failed to get D-PHY timing: %d\n", __func__, ret);
865 return ret;
866 }
867
868 ret = mipi_dphy_timing_validate(&priv->dphy_timing, period);
869 if (ret < 0) {
870 printf("%s: failed to validate D-PHY timing: %d\n", __func__, ret);
871 return ret;
872 }
873
874 /*
875 * The D-PHY timing fields are expressed in byte-clock cycles, so
876 * multiply the period by 8.
877 */
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200878 tegra_dsi_set_phy_timing(dev, period * 8, &priv->dphy_timing);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300879
880 /* Perform panel HW setup */
881 ret = panel_enable_backlight(priv->panel);
882 if (ret)
883 return ret;
884
Svyatoslav Ryhel6a5efea2024-12-31 09:58:01 +0200885 tegra_dsi_configure(dev, dc_plat->pipe, device->mode_flags);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300886
887 tegra_dc_enable_controller(dev);
888
Svyatoslav Ryhel8e50b622024-12-31 09:50:03 +0200889 tegra_dsi_enable(dev);
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300890
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300891 return 0;
892}
893
894static int tegra_dsi_bridge_set_panel(struct udevice *dev, int percent)
895{
Jonas Schwöbeldea5d962024-01-23 19:16:33 +0200896 struct tegra_dsi_priv *priv = dev_get_priv(dev);
897
898 /* Turn on/off backlight */
899 return panel_set_backlight(priv->panel, percent);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300900}
901
902static int tegra_dsi_panel_timings(struct udevice *dev,
903 struct display_timing *timing)
904{
905 struct tegra_dsi_priv *priv = dev_get_priv(dev);
906
907 memcpy(timing, &priv->timing, sizeof(*timing));
908
909 return 0;
910}
911
912static void tegra_dsi_init_clocks(struct udevice *dev)
913{
914 struct tegra_dsi_priv *priv = dev_get_priv(dev);
Svyatoslav Ryheld16c1052024-01-23 19:16:23 +0200915 struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300916 struct mipi_dsi_device *device = &priv->device;
Svyatoslav Ryhelf87af5a2025-02-26 09:51:09 +0200917 unsigned int mul, div, lanes;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300918 unsigned long bclk, plld;
919
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +0200920 /* Switch parents of DSI clocks in case of not standard parent */
921 if (priv->clk->id == PERIPH_ID_DSI &&
922 priv->clk_parent->id == CLOCK_ID_DISPLAY2) {
923 /* Change DSIA clock parent to PLLD2 */
924 struct clk_rst_ctlr *clkrst =
925 (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
926
927 /* DSIA_CLK_SRC */
928 setbits_le32(&clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_base,
929 BIT(25));
930 }
931
932 if (priv->clk->id == PERIPH_ID_DSIB &&
933 priv->clk_parent->id == CLOCK_ID_DISPLAY) {
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300934 /* Change DSIB clock parent to match DSIA */
935 struct clk_rst_ctlr *clkrst =
936 (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
937
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +0200938 /* DSIB_CLK_SRC */
939 clrbits_le32(&clkrst->plld2.pll_base, BIT(25));
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300940 }
941
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300942 tegra_dsi_get_muldiv(device->format, &mul, &div);
943
Svyatoslav Ryhelf87af5a2025-02-26 09:51:09 +0200944 lanes = tegra_dsi_get_lanes(dev);
945 bclk = (priv->timing.pixelclock.typ * mul) / (div * lanes);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300946
947 plld = DIV_ROUND_UP(bclk * 8, USEC_PER_SEC);
948
Svyatoslav Ryheld16c1052024-01-23 19:16:23 +0200949 dc_plat->scdiv = ((plld * USEC_PER_SEC +
950 priv->timing.pixelclock.typ / 2) /
951 priv->timing.pixelclock.typ) - 2;
952
953 /*
954 * BUG: If DISP1 is a PLLD/D2 child, it cannot go over 370MHz. The
955 * cause of this is not quite clear. This can be overcomed by
956 * halving the PLLD/D2 if the target rate is > 800MHz. This way
957 * DISP1 and DSI clocks will be equal.
958 */
959 if (plld > 800)
960 plld /= 2;
961
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300962 switch (clock_get_osc_freq()) {
963 case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
964 case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +0200965 clock_set_rate(priv->clk_parent->id, plld, 12, 0, 8);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300966 break;
967
968 case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +0200969 clock_set_rate(priv->clk_parent->id, plld, 26, 0, 8);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300970 break;
971
972 case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
973 case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +0200974 clock_set_rate(priv->clk_parent->id, plld, 13, 0, 8);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300975 break;
976
977 case CLOCK_OSC_FREQ_19_2:
978 case CLOCK_OSC_FREQ_38_4:
979 default:
980 /*
981 * These are not supported.
982 */
983 break;
984 }
985
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +0200986 clk_enable(priv->clk);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +0300987}
988
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +0300989static int tegra_dsi_ganged_probe(struct udevice *dev)
990{
991 struct tegra_dsi_priv *mpriv = dev_get_priv(dev);
992 struct udevice *gangster;
993
994 uclass_get_device_by_phandle(UCLASS_PANEL, dev,
995 "nvidia,ganged-mode", &gangster);
996 if (gangster) {
997 /* Ganged mode is set */
998 struct tegra_dsi_priv *spriv = dev_get_priv(gangster);
999
1000 mpriv->slave = gangster;
1001 spriv->master = dev;
1002 }
1003
1004 return 0;
1005}
1006
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001007static int tegra_dsi_bridge_probe(struct udevice *dev)
1008{
1009 struct tegra_dsi_priv *priv = dev_get_priv(dev);
1010 struct mipi_dsi_device *device = &priv->device;
1011 struct mipi_dsi_panel_plat *mipi_plat;
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +02001012 struct reset_ctl reset_ctl;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001013 int ret;
1014
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +02001015 priv->version = dev_get_driver_data(dev);
1016
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001017 priv->dsi = (struct dsi_ctlr *)dev_read_addr_ptr(dev);
1018 if (!priv->dsi) {
1019 printf("%s: No display controller address\n", __func__);
1020 return -EINVAL;
1021 }
1022
Svyatoslav Ryhel71f2c362024-11-24 14:26:08 +02001023 priv->clk = devm_clk_get(dev, NULL);
1024 if (IS_ERR(priv->clk)) {
1025 log_debug("%s: Could not get DSI clock: %ld\n",
1026 __func__, PTR_ERR(priv->clk));
1027 return PTR_ERR(priv->clk);
1028 }
1029
1030 priv->clk_parent = devm_clk_get(dev, "parent");
1031 if (IS_ERR(priv->clk_parent)) {
1032 log_debug("%s: Could not get DSI clock parent: %ld\n",
1033 __func__, PTR_ERR(priv->clk_parent));
1034 return PTR_ERR(priv->clk_parent);
1035 }
1036
Jonas Schwöbel0cccf902024-01-23 19:16:32 +02001037 priv->video_fifo_depth = 1920;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001038 priv->host_fifo_depth = 64;
1039
Svyatoslav Ryhelab120e52024-07-30 13:35:45 +03001040 tegra_dsi_ganged_probe(dev);
1041
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +02001042 ret = reset_get_by_name(dev, "dsi", &reset_ctl);
1043 if (ret) {
1044 log_debug("%s: reset_get_by_name() failed: %d\n",
1045 __func__, ret);
1046 return ret;
1047 }
1048
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001049 ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
1050 "avdd-dsi-csi-supply", &priv->avdd);
1051 if (ret)
1052 debug("%s: Cannot get avdd-dsi-csi-supply: error %d\n",
1053 __func__, ret);
1054
Svyatoslav Ryhelf6b2ab42024-11-24 09:38:03 +02001055 /* Check all DSI children */
1056 device_foreach_child(priv->panel, dev) {
1057 if (device_get_uclass_id(priv->panel) == UCLASS_PANEL)
1058 break;
1059 }
1060
1061 /* if loop exits without panel device return error */
1062 if (device_get_uclass_id(priv->panel) != UCLASS_PANEL) {
1063 log_debug("%s: panel not found, ret %d\n", __func__, ret);
1064 return -EINVAL;
1065 }
1066
1067 ret = uclass_get_device_by_ofnode(UCLASS_PANEL, dev_ofnode(priv->panel),
1068 &priv->panel);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001069 if (ret) {
Svyatoslav Ryhelf6b2ab42024-11-24 09:38:03 +02001070 log_debug("%s: Cannot get panel: error %d\n", __func__, ret);
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001071 return log_ret(ret);
1072 }
1073
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +02001074 if (priv->version) {
1075 ret = uclass_get_device_by_phandle(UCLASS_MISC, dev,
1076 "nvidia,mipi-calibrate",
1077 &priv->mipi);
1078 if (ret) {
1079 log_debug("%s: cannot get MIPI: error %d\n", __func__, ret);
1080 return ret;
1081 }
Svyatoslav Ryhel30cdefe2024-11-18 08:58:18 +02001082
1083 ret = dev_read_u32_index(dev, "nvidia,mipi-calibrate", 1,
1084 &priv->calibration_pads);
1085 if (ret) {
1086 log_debug("%s: cannot get calibration pads: error %d\n",
1087 __func__, ret);
1088 return ret;
1089 }
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +02001090 }
1091
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001092 panel_get_display_timing(priv->panel, &priv->timing);
1093
1094 mipi_plat = dev_get_plat(priv->panel);
1095 mipi_plat->device = device;
1096
1097 priv->host.dev = (struct device *)dev;
1098 priv->host.ops = &tegra_dsi_bridge_host_ops;
1099
1100 device->host = &priv->host;
1101 device->lanes = mipi_plat->lanes;
1102 device->format = mipi_plat->format;
1103 device->mode_flags = mipi_plat->mode_flags;
1104
1105 tegra_dsi_get_format(device->format, &priv->format);
1106
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +02001107 reset_assert(&reset_ctl);
1108
Svyatoslav Ryheldaab7d92023-10-03 09:25:34 +03001109 ret = regulator_set_enable_if_allowed(priv->avdd, true);
1110 if (ret && ret != -ENOSYS)
1111 return ret;
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001112
1113 tegra_dsi_init_clocks(dev);
1114
Svyatoslav Ryhelfe0a53a2024-01-23 19:16:30 +02001115 mdelay(2);
1116 reset_deassert(&reset_ctl);
1117
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001118 return 0;
1119}
1120
1121static const struct panel_ops tegra_dsi_bridge_ops = {
1122 .enable_backlight = tegra_dsi_encoder_enable,
1123 .set_backlight = tegra_dsi_bridge_set_panel,
1124 .get_display_timing = tegra_dsi_panel_timings,
1125};
1126
1127static const struct udevice_id tegra_dsi_bridge_ids[] = {
Svyatoslav Ryhel094d4f92024-01-23 19:16:29 +02001128 { .compatible = "nvidia,tegra30-dsi", .data = DSI_V0 },
1129 { .compatible = "nvidia,tegra114-dsi", .data = DSI_V1 },
Svyatoslav Ryhel5fa06e72024-11-18 08:58:18 +02001130 { .compatible = "nvidia,tegra124-dsi", .data = DSI_V1 },
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001131 { }
1132};
1133
1134U_BOOT_DRIVER(tegra_dsi) = {
1135 .name = "tegra_dsi",
1136 .id = UCLASS_PANEL,
1137 .of_match = tegra_dsi_bridge_ids,
1138 .ops = &tegra_dsi_bridge_ops,
Svyatoslav Ryhelf6b2ab42024-11-24 09:38:03 +02001139 .bind = dm_scan_fdt_dev,
Svyatoslav Ryhelfeddf9f2023-03-27 11:11:48 +03001140 .probe = tegra_dsi_bridge_probe,
1141 .plat_auto = sizeof(struct tegra_dc_plat),
1142 .priv_auto = sizeof(struct tegra_dsi_priv),
1143};