blob: bfb48b25187dcebe5e32f1096cdbfe3b538d8b74 [file] [log] [blame]
Svyatoslav Ryhel1f9a5cb2023-06-22 20:46:00 +03001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2013 NVIDIA Corporation
4 * Copyright (c) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
5 */
6
7#include <clk.h>
8#include <dm.h>
9#include <edid.h>
10#include <i2c.h>
11#include <log.h>
12#include <misc.h>
13#include <panel.h>
14#include <reset.h>
15#include <linux/delay.h>
16#include <linux/err.h>
17#include <linux/time.h>
18#include <power/regulator.h>
19#include <video_bridge.h>
20
21#include <asm/gpio.h>
22#include <asm/io.h>
23#include <asm/arch/clock.h>
24
Svyatoslav Ryhelead1d512025-03-29 17:00:20 +020025#include "dc.h"
26#include "hdmi.h"
Svyatoslav Ryhel1f9a5cb2023-06-22 20:46:00 +030027
28#define DDCCI_ENTRY_ADDR 0x37
29#define DDCCI_SOURSE_ADDR 0x51
30#define DDCCI_COMMAND_WRITE 0x03
31#define DDCCI_CTRL_BRIGHTNESS 0x10
32
33#define HDMI_EDID_I2C_ADDR 0x50
34#define HDMI_REKEY_DEFAULT 56
35
36static const char * const hdmi_supplies[] = {
37 "hdmi-supply", "pll-supply", "vdd-supply"
38};
39
40struct tmds_config {
41 unsigned int pclk;
42 u32 pll0;
43 u32 pll1;
44 u32 pe_current;
45 u32 drive_current;
46 u32 peak_current;
47};
48
49struct tegra_hdmi_config {
50 const struct tmds_config *tmds;
51 unsigned int num_tmds;
52 unsigned int max_pclk;
53
54 /* to be filled */
55};
56
57struct tegra_hdmi_priv {
58 struct hdmi_ctlr *hdmi_regmap;
59
60 struct udevice *supplies[ARRAY_SIZE(hdmi_supplies)];
61 struct udevice *hdmi_ddc;
62
63 struct gpio_desc hpd; /* hotplug detection gpio */
64 struct display_timing timing;
65
66 struct clk *clk;
67 struct clk *clk_parent;
68
69 int panel_bits_per_colourp;
70 const struct tegra_hdmi_config *config;
71};
72
73/* 1280x720p 60hz: EIA/CEA-861-B Format 4 */
74static struct display_timing default_720p_timing = {
75 .pixelclock.typ = 74250000,
76 .hactive.typ = 1280,
77 .hfront_porch.typ = 110,
78 .hback_porch.typ = 220,
79 .hsync_len.typ = 40,
80 .vactive.typ = 720,
81 .vfront_porch.typ = 5,
82 .vback_porch.typ = 20,
83 .vsync_len.typ = 5,
84 .flags = DISPLAY_FLAGS_HSYNC_HIGH |
85 DISPLAY_FLAGS_VSYNC_HIGH,
86};
87
88static const struct tmds_config tegra20_tmds_config[] = {
89 { /* slow pixel clock modes */
90 .pclk = 27000000,
91 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
92 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) |
93 SOR_PLL_TX_REG_LOAD(3),
94 .pll1 = SOR_PLL_TMDS_TERM_ENABLE,
95 .pe_current = PE_CURRENT0(PE_CURRENT_0_0_mA) |
96 PE_CURRENT1(PE_CURRENT_0_0_mA) |
97 PE_CURRENT2(PE_CURRENT_0_0_mA) |
98 PE_CURRENT3(PE_CURRENT_0_0_mA),
99 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
100 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
101 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
102 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
103 },
104 { /* high pixel clock modes */
105 .pclk = UINT_MAX,
106 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
107 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) |
108 SOR_PLL_TX_REG_LOAD(3),
109 .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
110 .pe_current = PE_CURRENT0(PE_CURRENT_6_0_mA) |
111 PE_CURRENT1(PE_CURRENT_6_0_mA) |
112 PE_CURRENT2(PE_CURRENT_6_0_mA) |
113 PE_CURRENT3(PE_CURRENT_6_0_mA),
114 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
115 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
116 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
117 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
118 },
119};
120
121static const struct tmds_config tegra30_tmds_config[] = {
122 { /* 480p modes */
123 .pclk = 27000000,
124 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
125 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) |
126 SOR_PLL_TX_REG_LOAD(0),
127 .pll1 = SOR_PLL_TMDS_TERM_ENABLE,
128 .pe_current = PE_CURRENT0(PE_CURRENT_0_0_mA) |
129 PE_CURRENT1(PE_CURRENT_0_0_mA) |
130 PE_CURRENT2(PE_CURRENT_0_0_mA) |
131 PE_CURRENT3(PE_CURRENT_0_0_mA),
132 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
133 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
134 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
135 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
136 }, { /* 720p modes */
137 .pclk = 74250000,
138 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
139 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) |
140 SOR_PLL_TX_REG_LOAD(0),
141 .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
142 .pe_current = PE_CURRENT0(PE_CURRENT_5_0_mA) |
143 PE_CURRENT1(PE_CURRENT_5_0_mA) |
144 PE_CURRENT2(PE_CURRENT_5_0_mA) |
145 PE_CURRENT3(PE_CURRENT_5_0_mA),
146 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
147 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
148 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
149 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
150 }, { /* 1080p modes */
151 .pclk = UINT_MAX,
152 .pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
153 SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(3) |
154 SOR_PLL_TX_REG_LOAD(0),
155 .pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
156 .pe_current = PE_CURRENT0(PE_CURRENT_5_0_mA) |
157 PE_CURRENT1(PE_CURRENT_5_0_mA) |
158 PE_CURRENT2(PE_CURRENT_5_0_mA) |
159 PE_CURRENT3(PE_CURRENT_5_0_mA),
160 .drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
161 DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
162 DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
163 DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
164 },
165};
166
167static void tegra_dc_enable_controller(struct udevice *dev)
168{
169 struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
170 struct dc_ctlr *dc = dc_plat->dc;
171 u32 value;
172
173 value = readl(&dc->disp.disp_win_opt);
174 value |= HDMI_ENABLE;
175 writel(value, &dc->disp.disp_win_opt);
176
177 writel(GENERAL_UPDATE, &dc->cmd.state_ctrl);
178 writel(GENERAL_ACT_REQ, &dc->cmd.state_ctrl);
179}
180
181static void tegra_hdmi_setup_tmds(struct tegra_hdmi_priv *priv,
182 const struct tmds_config *tmds)
183{
184 struct hdmi_ctlr *hdmi = priv->hdmi_regmap;
185 u32 value;
186
187 writel(tmds->pll0, &hdmi->nv_pdisp_sor_pll0);
188 writel(tmds->pll1, &hdmi->nv_pdisp_sor_pll1);
189 writel(tmds->pe_current, &hdmi->nv_pdisp_pe_current);
190
191 writel(tmds->drive_current, &hdmi->nv_pdisp_sor_lane_drive_current);
192
193 value = readl(&hdmi->nv_pdisp_sor_lane_drive_current);
194 value |= BIT(31);
195 writel(value, &hdmi->nv_pdisp_sor_lane_drive_current);
196}
197
198static int tegra_hdmi_encoder_enable(struct udevice *dev)
199{
200 struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
201 struct tegra_hdmi_priv *priv = dev_get_priv(dev);
202 struct dc_ctlr *dc = dc_plat->dc;
203 struct display_timing *dt = &priv->timing;
204 struct hdmi_ctlr *hdmi = priv->hdmi_regmap;
205 unsigned long rate, div82;
206 unsigned int pulse_start, rekey;
207 int retries = 1000;
208 u32 value;
209 int i;
210
211 /* power up sequence */
212 value = readl(&hdmi->nv_pdisp_sor_pll0);
213 value &= ~SOR_PLL_PDBG;
214 writel(value, &hdmi->nv_pdisp_sor_pll0);
215
216 udelay(20);
217
218 value = readl(&hdmi->nv_pdisp_sor_pll0);
219 value &= ~SOR_PLL_PWR;
220 writel(value, &hdmi->nv_pdisp_sor_pll0);
221
222 writel(VSYNC_H_POSITION(1), &dc->disp.disp_timing_opt);
223 writel(DITHER_CONTROL_DISABLE | BASE_COLOR_SIZE_888,
224 &dc->disp.disp_color_ctrl);
225
226 /* video_preamble uses h_pulse2 */
227 pulse_start = 1 + dt->hsync_len.typ + dt->hback_porch.typ - 10;
228
229 writel(H_PULSE2_ENABLE, &dc->disp.disp_signal_opt0);
230
231 value = PULSE_MODE_NORMAL | PULSE_POLARITY_HIGH |
232 PULSE_QUAL_VACTIVE | PULSE_LAST_END_A;
233 writel(value, &dc->disp.h_pulse[H_PULSE2].h_pulse_ctrl);
234
235 value = PULSE_START(pulse_start) | PULSE_END(pulse_start + 8);
236 writel(value, &dc->disp.h_pulse[H_PULSE2].h_pulse_pos[H_PULSE0_POSITION_A]);
237
238 value = VSYNC_WINDOW_END(0x210) | VSYNC_WINDOW_START(0x200) |
239 VSYNC_WINDOW_ENABLE;
240 writel(value, &hdmi->nv_pdisp_hdmi_vsync_window);
241
242 if (dc_plat->pipe)
243 value = HDMI_SRC_DISPLAYB;
244 else
245 value = HDMI_SRC_DISPLAYA;
246
247 if (dt->hactive.typ == 720 && (dt->vactive.typ == 480 ||
248 dt->vactive.typ == 576))
249 writel(value | ARM_VIDEO_RANGE_FULL,
250 &hdmi->nv_pdisp_input_control);
251 else
252 writel(value | ARM_VIDEO_RANGE_LIMITED,
253 &hdmi->nv_pdisp_input_control);
254
255 rate = clock_get_periph_rate(priv->clk->id, priv->clk_parent->id);
256 div82 = rate / USEC_PER_SEC * 4;
257 value = SOR_REFCLK_DIV_INT(div82 >> 2) | SOR_REFCLK_DIV_FRAC(div82);
258 writel(value, &hdmi->nv_pdisp_sor_refclk);
259
260 rekey = HDMI_REKEY_DEFAULT;
261 value = HDMI_CTRL_REKEY(rekey);
262 value |= HDMI_CTRL_MAX_AC_PACKET((dt->hsync_len.typ + dt->hback_porch.typ +
263 dt->hfront_porch.typ - rekey - 18) / 32);
264 writel(value, &hdmi->nv_pdisp_hdmi_ctrl);
265
266 /* TMDS CONFIG */
267 for (i = 0; i < priv->config->num_tmds; i++) {
268 if (dt->pixelclock.typ <= priv->config->tmds[i].pclk) {
269 tegra_hdmi_setup_tmds(priv, &priv->config->tmds[i]);
270 break;
271 }
272 }
273
274 writel(SOR_SEQ_PU_PC(0) | SOR_SEQ_PU_PC_ALT(0) | SOR_SEQ_PD_PC(8) |
275 SOR_SEQ_PD_PC_ALT(8), &hdmi->nv_pdisp_sor_seq_ctl);
276
277 value = SOR_SEQ_INST_WAIT_TIME(1) | SOR_SEQ_INST_WAIT_UNITS_VSYNC |
278 SOR_SEQ_INST_HALT | SOR_SEQ_INST_PIN_A_LOW |
279 SOR_SEQ_INST_PIN_B_LOW | SOR_SEQ_INST_DRIVE_PWM_OUT_LO;
280
281 writel(value, &hdmi->nv_pdisp_sor_seq_inst0);
282 writel(value, &hdmi->nv_pdisp_sor_seq_inst8);
283
284 value = readl(&hdmi->nv_pdisp_sor_cstm);
285
286 value &= ~SOR_CSTM_ROTCLK(~0);
287 value |= SOR_CSTM_ROTCLK(2);
288 value |= SOR_CSTM_PLLDIV;
289 value &= ~SOR_CSTM_LVDS_ENABLE;
290 value &= ~SOR_CSTM_MODE_MASK;
291 value |= SOR_CSTM_MODE_TMDS;
292
293 writel(value, &hdmi->nv_pdisp_sor_cstm);
294
295 /* start SOR */
296 writel(SOR_PWR_NORMAL_STATE_PU | SOR_PWR_NORMAL_START_NORMAL |
297 SOR_PWR_SAFE_STATE_PD | SOR_PWR_SETTING_NEW_TRIGGER,
298 &hdmi->nv_pdisp_sor_pwr);
299 writel(SOR_PWR_NORMAL_STATE_PU | SOR_PWR_NORMAL_START_NORMAL |
300 SOR_PWR_SAFE_STATE_PD | SOR_PWR_SETTING_NEW_DONE,
301 &hdmi->nv_pdisp_sor_pwr);
302
303 do {
304 if (--retries < 0)
305 return -ETIME;
306 value = readl(&hdmi->nv_pdisp_sor_pwr);
307 } while (value & SOR_PWR_SETTING_NEW_PENDING);
308
309 value = SOR_STATE_ASY_CRCMODE_COMPLETE |
310 SOR_STATE_ASY_OWNER_HEAD0 |
311 SOR_STATE_ASY_SUBOWNER_BOTH |
312 SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A |
313 SOR_STATE_ASY_DEPOL_POS;
314
315 /* setup sync polarities */
316 if (dt->flags & DISPLAY_FLAGS_HSYNC_HIGH)
317 value |= SOR_STATE_ASY_HSYNCPOL_POS;
318
319 if (dt->flags & DISPLAY_FLAGS_HSYNC_LOW)
320 value |= SOR_STATE_ASY_HSYNCPOL_NEG;
321
322 if (dt->flags & DISPLAY_FLAGS_VSYNC_HIGH)
323 value |= SOR_STATE_ASY_VSYNCPOL_POS;
324
325 if (dt->flags & DISPLAY_FLAGS_VSYNC_LOW)
326 value |= SOR_STATE_ASY_VSYNCPOL_NEG;
327
328 writel(value, &hdmi->nv_pdisp_sor_state2);
329
330 value = SOR_STATE_ASY_HEAD_OPMODE_AWAKE | SOR_STATE_ASY_ORMODE_NORMAL;
331 writel(value, &hdmi->nv_pdisp_sor_state1);
332
333 writel(0, &hdmi->nv_pdisp_sor_state0);
334 writel(SOR_STATE_UPDATE, &hdmi->nv_pdisp_sor_state0);
335 writel(value | SOR_STATE_ATTACHED,
336 &hdmi->nv_pdisp_sor_state1);
337 writel(0, &hdmi->nv_pdisp_sor_state0);
338
339 tegra_dc_enable_controller(dev);
340
341 return 0;
342}
343
344/* DDC/CI backlight control */
345static int tegra_hdmi_set_connector(struct udevice *dev, int percent)
346{
347 struct tegra_hdmi_priv *priv = dev_get_priv(dev);
348 struct udevice *ddc_entry;
349 struct i2c_msg msg[1];
350 u8 checksum = DDCCI_ENTRY_ADDR << 1;
351 int i, ret;
352
353 ret = dm_i2c_probe(priv->hdmi_ddc, DDCCI_ENTRY_ADDR, 0, &ddc_entry);
354 if (ret) {
355 log_debug("%s: cannot probe DDC/CI entry: error %d\n",
356 __func__, ret);
357 return 0;
358 }
359
360 /*
361 * payload[1] is length: hithest bit OR last 4 bits indicate
362 * the number of following bytes (excluding checksum)
363 */
364 u8 payload[7] = { DDCCI_SOURSE_ADDR, BIT(7) | (sizeof(payload) - 3),
365 DDCCI_COMMAND_WRITE, DDCCI_CTRL_BRIGHTNESS,
366 (u8)(percent & 0xff), (u8)(percent & 0xff), 0 };
367
368 /* DDC/CI checksum is a simple XOR of all preceding bytes */
369 for (i = 0; i < (sizeof(payload) - 1); i++)
370 checksum ^= payload[i];
371
372 payload[6] = checksum;
373
374 msg->addr = DDCCI_ENTRY_ADDR;
375 msg->flags = 0;
376 msg->len = sizeof(payload);
377 msg->buf = payload;
378
379 dm_i2c_xfer(ddc_entry, msg, 1);
380
381 return 0;
382}
383
384static int tegra_hdmi_timings(struct udevice *dev,
385 struct display_timing *timing)
386{
387 struct tegra_hdmi_priv *priv = dev_get_priv(dev);
388
389 memcpy(timing, &priv->timing, sizeof(*timing));
390
391 return 0;
392}
393
394static void tegra_hdmi_init_clocks(struct udevice *dev)
395{
396 struct tegra_hdmi_priv *priv = dev_get_priv(dev);
397 u32 n = priv->timing.pixelclock.typ * 2 / USEC_PER_SEC;
398
399 switch (clock_get_osc_freq()) {
400 case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
401 case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
402 clock_set_rate(priv->clk_parent->id, n, 12, 0, 8);
403 break;
404
405 case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
406 clock_set_rate(priv->clk_parent->id, n, 26, 0, 8);
407 break;
408
409 case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
410 case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
411 clock_set_rate(priv->clk_parent->id, n, 13, 0, 8);
412 break;
413
414 case CLOCK_OSC_FREQ_19_2:
415 case CLOCK_OSC_FREQ_38_4:
416 default:
417 /*
418 * These are not supported.
419 */
420 break;
421 }
422
423 clock_start_periph_pll(priv->clk->id, priv->clk_parent->id,
424 priv->timing.pixelclock.typ);
425}
426
427static bool tegra_hdmi_mode_valid(void *hdmi_priv, const struct display_timing *timing)
428{
429 struct tegra_hdmi_priv *priv = hdmi_priv;
430
431 if (timing->pixelclock.typ > priv->config->max_pclk)
432 return false;
433
434 return true;
435}
436
437static int tegra_hdmi_decode_edid(struct udevice *dev)
438{
439 struct tegra_hdmi_priv *priv = dev_get_priv(dev);
440 struct udevice *hdmi_edid;
441 uchar edid_buf[EDID_SIZE] = { 0 };
442 int i, ret;
443
444 /* Poll for 1 sec in case EDID is not ready right after hpd */
445 for (i = 0; i < 10; i++) {
446 ret = dm_i2c_probe(priv->hdmi_ddc, HDMI_EDID_I2C_ADDR, 0,
447 &hdmi_edid);
448 if (!ret)
449 break;
450
451 mdelay(100);
452 }
453 if (ret) {
454 log_debug("%s: cannot probe EDID: error %d\n",
455 __func__, ret);
456 return ret;
457 }
458
459 ret = dm_i2c_read(hdmi_edid, 0, edid_buf, sizeof(edid_buf));
460 if (ret) {
461 log_debug("%s: cannot dump EDID buffer: error %d\n",
462 __func__, ret);
463 return ret;
464 }
465
466 ret = edid_get_timing_validate(edid_buf, sizeof(edid_buf), &priv->timing,
467 &priv->panel_bits_per_colourp,
468 tegra_hdmi_mode_valid, priv);
469 if (ret) {
470 log_debug("%s: cannot decode EDID info: error %d\n",
471 __func__, ret);
472 return ret;
473 }
474
475 return 0;
476}
477
478static int tegra_hdmi_wait_hpd(struct tegra_hdmi_priv *priv)
479{
480 int i;
481
482 /* Poll 1 second for HPD signal */
483 for (i = 0; i < 10; i++) {
484 if (dm_gpio_get_value(&priv->hpd))
485 return 0;
486
487 mdelay(100);
488 }
489
490 return -ETIMEDOUT;
491}
492
493static int tegra_hdmi_probe(struct udevice *dev)
494{
495 struct tegra_hdmi_priv *priv = dev_get_priv(dev);
496 struct reset_ctl reset_ctl;
497 int i, ret;
498
499 priv->hdmi_regmap = (struct hdmi_ctlr *)dev_read_addr_ptr(dev);
500 if (!priv->hdmi_regmap) {
501 log_debug("%s: no display controller address\n", __func__);
502 return -EINVAL;
503 }
504
505 priv->config = (struct tegra_hdmi_config *)dev_get_driver_data(dev);
506
507 priv->clk = devm_clk_get(dev, NULL);
508 if (IS_ERR(priv->clk)) {
509 log_debug("%s: Could not get HDMI clock: %ld\n",
510 __func__, PTR_ERR(priv->clk));
511 return PTR_ERR(priv->clk);
512 }
513
514 priv->clk_parent = devm_clk_get(dev, "parent");
515 if (IS_ERR(priv->clk_parent)) {
516 log_debug("%s: Could not get HDMI clock parent: %ld\n",
517 __func__, PTR_ERR(priv->clk_parent));
518 return PTR_ERR(priv->clk_parent);
519 }
520
521 for (i = 0; i < ARRAY_SIZE(hdmi_supplies); i++) {
522 ret = device_get_supply_regulator(dev, hdmi_supplies[i],
523 &priv->supplies[i]);
524 if (ret) {
525 log_debug("%s: cannot get %s %d\n", __func__,
526 hdmi_supplies[i], ret);
527 if (ret != -ENOENT)
528 return log_ret(ret);
529 }
530
531 ret = regulator_set_enable_if_allowed(priv->supplies[i], true);
532 if (ret && ret != -ENOSYS) {
533 log_debug("%s: cannot enable %s: error %d\n",
534 __func__, hdmi_supplies[i], ret);
535 return ret;
536 }
537 }
538
539 ret = reset_get_by_name(dev, "hdmi", &reset_ctl);
540 if (ret) {
541 log_debug("%s: reset_get_by_name() failed: %d\n",
542 __func__, ret);
543 return ret;
544 }
545
546 ret = uclass_get_device_by_phandle(UCLASS_I2C, dev,
547 "nvidia,ddc-i2c-bus",
548 &priv->hdmi_ddc);
549 if (ret) {
550 log_debug("%s: cannot get hdmi ddc i2c bus: error %d\n",
551 __func__, ret);
552 return ret;
553 }
554
555 ret = gpio_request_by_name(dev, "nvidia,hpd-gpio", 0,
556 &priv->hpd, GPIOD_IS_IN);
557 if (ret) {
558 log_debug("%s: Could not decode hpd-gpios (%d)\n",
559 __func__, ret);
560 return ret;
561 }
562
563 /* wait for connector */
564 ret = tegra_hdmi_wait_hpd(priv);
565 if (ret) {
566 /* HPD failed, use default timings */
567 memcpy(&priv->timing, &default_720p_timing,
568 sizeof(default_720p_timing));
569 } else {
570 ret = tegra_hdmi_decode_edid(dev);
571 if (ret)
572 memcpy(&priv->timing, &default_720p_timing,
573 sizeof(default_720p_timing));
574 }
575
576 reset_assert(&reset_ctl);
577 tegra_hdmi_init_clocks(dev);
578
579 mdelay(2);
580 reset_deassert(&reset_ctl);
581
582 return 0;
583}
584
585static const struct tegra_hdmi_config tegra20_hdmi_config = {
586 .tmds = tegra20_tmds_config,
587 .num_tmds = ARRAY_SIZE(tegra20_tmds_config),
588 .max_pclk = 148500000, /* 1080p */
589};
590
591static const struct tegra_hdmi_config tegra30_hdmi_config = {
592 .tmds = tegra30_tmds_config,
593 .num_tmds = ARRAY_SIZE(tegra30_tmds_config),
594 .max_pclk = 148500000, /* 1080p */
595};
596
597static const struct video_bridge_ops tegra_hdmi_ops = {
598 .attach = tegra_hdmi_encoder_enable,
599 .set_backlight = tegra_hdmi_set_connector,
600 .get_display_timing = tegra_hdmi_timings,
601};
602
603static const struct udevice_id tegra_hdmi_ids[] = {
604 {
605 .compatible = "nvidia,tegra20-hdmi",
606 .data = (ulong)&tegra20_hdmi_config
607 }, {
608 .compatible = "nvidia,tegra30-hdmi",
609 .data = (ulong)&tegra30_hdmi_config
610 }, {
611 /* sentinel */
612 }
613};
614
615U_BOOT_DRIVER(tegra_hdmi) = {
616 .name = "tegra_hdmi",
617 .id = UCLASS_VIDEO_BRIDGE,
618 .of_match = tegra_hdmi_ids,
619 .ops = &tegra_hdmi_ops,
620 .probe = tegra_hdmi_probe,
621 .plat_auto = sizeof(struct tegra_dc_plat),
622 .priv_auto = sizeof(struct tegra_hdmi_priv),
623};