xref: /openbmc/u-boot/drivers/video/tegra124/sor.c (revision da4cfa6b)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2011-2013, NVIDIA Corporation.
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <malloc.h>
10 #include <panel.h>
11 #include <syscon.h>
12 #include <video_bridge.h>
13 #include <asm/io.h>
14 #include <asm/arch/clock.h>
15 #include <asm/arch-tegra/dc.h>
16 #include "displayport.h"
17 #include "sor.h"
18 
19 #define DEBUG_SOR 0
20 
21 #define APBDEV_PMC_DPD_SAMPLE				0x20
22 #define APBDEV_PMC_DPD_SAMPLE_ON_DISABLE		0
23 #define APBDEV_PMC_DPD_SAMPLE_ON_ENABLE			1
24 #define APBDEV_PMC_SEL_DPD_TIM				0x1c8
25 #define APBDEV_PMC_SEL_DPD_TIM_SEL_DPD_TIM_DEFAULT	0x7f
26 #define APBDEV_PMC_IO_DPD2_REQ				0x1c0
27 #define APBDEV_PMC_IO_DPD2_REQ_LVDS_SHIFT		25
28 #define APBDEV_PMC_IO_DPD2_REQ_LVDS_OFF			(0 << 25)
29 #define APBDEV_PMC_IO_DPD2_REQ_LVDS_ON			(1 << 25)
30 #define APBDEV_PMC_IO_DPD2_REQ_CODE_SHIFT               30
31 #define APBDEV_PMC_IO_DPD2_REQ_CODE_DEFAULT_MASK        (0x3 << 30)
32 #define APBDEV_PMC_IO_DPD2_REQ_CODE_IDLE                (0 << 30)
33 #define APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_OFF             (1 << 30)
34 #define APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_ON              (2 << 30)
35 #define APBDEV_PMC_IO_DPD2_STATUS			0x1c4
36 #define APBDEV_PMC_IO_DPD2_STATUS_LVDS_SHIFT		25
37 #define APBDEV_PMC_IO_DPD2_STATUS_LVDS_OFF		(0 << 25)
38 #define APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON		(1 << 25)
39 
40 struct tegra_dc_sor_data {
41 	void *base;
42 	void *pmc_base;
43 	u8 portnum;	/* 0 or 1 */
44 	int power_is_up;
45 	struct udevice *panel;
46 };
47 
48 static inline u32 tegra_sor_readl(struct tegra_dc_sor_data *sor, u32 reg)
49 {
50 	return readl((u32 *)sor->base + reg);
51 }
52 
53 static inline void tegra_sor_writel(struct tegra_dc_sor_data *sor, u32 reg,
54 				    u32 val)
55 {
56 	writel(val, (u32 *)sor->base + reg);
57 }
58 
59 static inline void tegra_sor_write_field(struct tegra_dc_sor_data *sor,
60 	u32 reg, u32 mask, u32 val)
61 {
62 	u32 reg_val = tegra_sor_readl(sor, reg);
63 	reg_val &= ~mask;
64 	reg_val |= val;
65 	tegra_sor_writel(sor, reg, reg_val);
66 }
67 
68 void tegra_dp_disable_tx_pu(struct udevice *dev)
69 {
70 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
71 
72 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
73 			      DP_PADCTL_TX_PU_MASK, DP_PADCTL_TX_PU_DISABLE);
74 }
75 
76 void tegra_dp_set_pe_vs_pc(struct udevice *dev, u32 mask, u32 pe_reg,
77 			   u32 vs_reg, u32 pc_reg, u8 pc_supported)
78 {
79 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
80 
81 	tegra_sor_write_field(sor, PR(sor->portnum), mask, pe_reg);
82 	tegra_sor_write_field(sor, DC(sor->portnum), mask, vs_reg);
83 	if (pc_supported) {
84 		tegra_sor_write_field(sor, POSTCURSOR(sor->portnum), mask,
85 				      pc_reg);
86 	}
87 }
88 
89 static int tegra_dc_sor_poll_register(struct tegra_dc_sor_data *sor, u32 reg,
90 				      u32 mask, u32 exp_val,
91 				      int poll_interval_us, int timeout_ms)
92 {
93 	u32 reg_val = 0;
94 	ulong start;
95 
96 	start = get_timer(0);
97 	do {
98 		reg_val = tegra_sor_readl(sor, reg);
99 		if (((reg_val & mask) == exp_val))
100 			return 0;
101 		udelay(poll_interval_us);
102 	} while (get_timer(start) < timeout_ms);
103 
104 	debug("sor_poll_register 0x%x: timeout, (reg_val)0x%08x & (mask)0x%08x != (exp_val)0x%08x\n",
105 	      reg, reg_val, mask, exp_val);
106 
107 	return -ETIMEDOUT;
108 }
109 
110 int tegra_dc_sor_set_power_state(struct udevice *dev, int pu_pd)
111 {
112 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
113 	u32 reg_val;
114 	u32 orig_val;
115 
116 	orig_val = tegra_sor_readl(sor, PWR);
117 
118 	reg_val = pu_pd ? PWR_NORMAL_STATE_PU :
119 		PWR_NORMAL_STATE_PD; /* normal state only */
120 
121 	if (reg_val == orig_val)
122 		return 0;	/* No update needed */
123 
124 	reg_val |= PWR_SETTING_NEW_TRIGGER;
125 	tegra_sor_writel(sor, PWR, reg_val);
126 
127 	/* Poll to confirm it is done */
128 	if (tegra_dc_sor_poll_register(sor, PWR,
129 				       PWR_SETTING_NEW_DEFAULT_MASK,
130 				       PWR_SETTING_NEW_DONE,
131 				       100, TEGRA_SOR_TIMEOUT_MS)) {
132 		debug("dc timeout waiting for SOR_PWR = NEW_DONE\n");
133 		return -EFAULT;
134 	}
135 
136 	return 0;
137 }
138 
139 void tegra_dc_sor_set_dp_linkctl(struct udevice *dev, int ena,
140 				 u8 training_pattern,
141 				 const struct tegra_dp_link_config *link_cfg)
142 {
143 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
144 	u32 reg_val;
145 
146 	reg_val = tegra_sor_readl(sor, DP_LINKCTL(sor->portnum));
147 
148 	if (ena)
149 		reg_val |= DP_LINKCTL_ENABLE_YES;
150 	else
151 		reg_val &= DP_LINKCTL_ENABLE_NO;
152 
153 	reg_val &= ~DP_LINKCTL_TUSIZE_MASK;
154 	reg_val |= (link_cfg->tu_size << DP_LINKCTL_TUSIZE_SHIFT);
155 
156 	if (link_cfg->enhanced_framing)
157 		reg_val |= DP_LINKCTL_ENHANCEDFRAME_ENABLE;
158 
159 	tegra_sor_writel(sor, DP_LINKCTL(sor->portnum), reg_val);
160 
161 	switch (training_pattern) {
162 	case training_pattern_1:
163 		tegra_sor_writel(sor, DP_TPG, 0x41414141);
164 		break;
165 	case training_pattern_2:
166 	case training_pattern_3:
167 		reg_val = (link_cfg->link_bw == SOR_LINK_SPEED_G5_4) ?
168 			0x43434343 : 0x42424242;
169 		tegra_sor_writel(sor, DP_TPG, reg_val);
170 		break;
171 	default:
172 		tegra_sor_writel(sor, DP_TPG, 0x50505050);
173 		break;
174 	}
175 }
176 
177 static int tegra_dc_sor_enable_lane_sequencer(struct tegra_dc_sor_data *sor,
178 					      int pu, int is_lvds)
179 {
180 	u32 reg_val;
181 
182 	/* SOR lane sequencer */
183 	if (pu) {
184 		reg_val = LANE_SEQ_CTL_SETTING_NEW_TRIGGER |
185 			LANE_SEQ_CTL_SEQUENCE_DOWN |
186 			LANE_SEQ_CTL_NEW_POWER_STATE_PU;
187 	} else {
188 		reg_val = LANE_SEQ_CTL_SETTING_NEW_TRIGGER |
189 			LANE_SEQ_CTL_SEQUENCE_UP |
190 			LANE_SEQ_CTL_NEW_POWER_STATE_PD;
191 	}
192 
193 	if (is_lvds)
194 		reg_val |= 15 << LANE_SEQ_CTL_DELAY_SHIFT;
195 	else
196 		reg_val |= 1 << LANE_SEQ_CTL_DELAY_SHIFT;
197 
198 	tegra_sor_writel(sor, LANE_SEQ_CTL, reg_val);
199 
200 	if (tegra_dc_sor_poll_register(sor, LANE_SEQ_CTL,
201 				       LANE_SEQ_CTL_SETTING_MASK,
202 				       LANE_SEQ_CTL_SETTING_NEW_DONE,
203 				       100, TEGRA_SOR_TIMEOUT_MS)) {
204 		debug("dp: timeout while waiting for SOR lane sequencer to power down lanes\n");
205 		return -1;
206 	}
207 
208 	return 0;
209 }
210 
211 static int tegra_dc_sor_power_dplanes(struct udevice *dev,
212 				      u32 lane_count, int pu)
213 {
214 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
215 	u32 reg_val;
216 
217 	reg_val = tegra_sor_readl(sor, DP_PADCTL(sor->portnum));
218 
219 	if (pu) {
220 		switch (lane_count) {
221 		case 4:
222 			reg_val |= (DP_PADCTL_PD_TXD_3_NO |
223 				DP_PADCTL_PD_TXD_2_NO);
224 			/* fall through */
225 		case 2:
226 			reg_val |= DP_PADCTL_PD_TXD_1_NO;
227 		case 1:
228 			reg_val |= DP_PADCTL_PD_TXD_0_NO;
229 			break;
230 		default:
231 			debug("dp: invalid lane number %d\n", lane_count);
232 			return -1;
233 		}
234 
235 		tegra_sor_writel(sor, DP_PADCTL(sor->portnum), reg_val);
236 		tegra_dc_sor_set_lane_count(dev, lane_count);
237 	}
238 
239 	return tegra_dc_sor_enable_lane_sequencer(sor, pu, 0);
240 }
241 
242 void tegra_dc_sor_set_panel_power(struct udevice *dev, int power_up)
243 {
244 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
245 	u32 reg_val;
246 
247 	reg_val = tegra_sor_readl(sor, DP_PADCTL(sor->portnum));
248 
249 	if (power_up)
250 		reg_val |= DP_PADCTL_PAD_CAL_PD_POWERUP;
251 	else
252 		reg_val &= ~DP_PADCTL_PAD_CAL_PD_POWERUP;
253 
254 	tegra_sor_writel(sor, DP_PADCTL(sor->portnum), reg_val);
255 }
256 
257 static void tegra_dc_sor_config_pwm(struct tegra_dc_sor_data *sor, u32 pwm_div,
258 				    u32 pwm_dutycycle)
259 {
260 	tegra_sor_writel(sor, PWM_DIV, pwm_div);
261 	tegra_sor_writel(sor, PWM_CTL,
262 			 (pwm_dutycycle & PWM_CTL_DUTY_CYCLE_MASK) |
263 			 PWM_CTL_SETTING_NEW_TRIGGER);
264 
265 	if (tegra_dc_sor_poll_register(sor, PWM_CTL,
266 				       PWM_CTL_SETTING_NEW_SHIFT,
267 				       PWM_CTL_SETTING_NEW_DONE,
268 				       100, TEGRA_SOR_TIMEOUT_MS)) {
269 		debug("dp: timeout while waiting for SOR PWM setting\n");
270 	}
271 }
272 
273 static void tegra_dc_sor_set_dp_mode(struct udevice *dev,
274 				const struct tegra_dp_link_config *link_cfg)
275 {
276 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
277 	u32 reg_val;
278 
279 	tegra_dc_sor_set_link_bandwidth(dev, link_cfg->link_bw);
280 
281 	tegra_dc_sor_set_dp_linkctl(dev, 1, training_pattern_none, link_cfg);
282 	reg_val = tegra_sor_readl(sor, DP_CONFIG(sor->portnum));
283 	reg_val &= ~DP_CONFIG_WATERMARK_MASK;
284 	reg_val |= link_cfg->watermark;
285 	reg_val &= ~DP_CONFIG_ACTIVESYM_COUNT_MASK;
286 	reg_val |= (link_cfg->active_count <<
287 		DP_CONFIG_ACTIVESYM_COUNT_SHIFT);
288 	reg_val &= ~DP_CONFIG_ACTIVESYM_FRAC_MASK;
289 	reg_val |= (link_cfg->active_frac <<
290 		DP_CONFIG_ACTIVESYM_FRAC_SHIFT);
291 	if (link_cfg->activepolarity)
292 		reg_val |= DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE;
293 	else
294 		reg_val &= ~DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE;
295 	reg_val |= (DP_CONFIG_ACTIVESYM_CNTL_ENABLE |
296 		DP_CONFIG_RD_RESET_VAL_NEGATIVE);
297 
298 	tegra_sor_writel(sor, DP_CONFIG(sor->portnum), reg_val);
299 
300 	/* program h/vblank sym */
301 	tegra_sor_write_field(sor, DP_AUDIO_HBLANK_SYMBOLS,
302 			      DP_AUDIO_HBLANK_SYMBOLS_MASK,
303 			      link_cfg->hblank_sym);
304 
305 	tegra_sor_write_field(sor, DP_AUDIO_VBLANK_SYMBOLS,
306 			      DP_AUDIO_VBLANK_SYMBOLS_MASK,
307 			      link_cfg->vblank_sym);
308 }
309 
310 static inline void tegra_dc_sor_super_update(struct tegra_dc_sor_data *sor)
311 {
312 	tegra_sor_writel(sor, SUPER_STATE0, 0);
313 	tegra_sor_writel(sor, SUPER_STATE0, 1);
314 	tegra_sor_writel(sor, SUPER_STATE0, 0);
315 }
316 
317 static inline void tegra_dc_sor_update(struct tegra_dc_sor_data *sor)
318 {
319 	tegra_sor_writel(sor, STATE0, 0);
320 	tegra_sor_writel(sor, STATE0, 1);
321 	tegra_sor_writel(sor, STATE0, 0);
322 }
323 
324 static int tegra_dc_sor_io_set_dpd(struct tegra_dc_sor_data *sor, int up)
325 {
326 	u32 reg_val;
327 	void *pmc_base = sor->pmc_base;
328 
329 	if (up) {
330 		writel(APBDEV_PMC_DPD_SAMPLE_ON_ENABLE,
331 		       pmc_base + APBDEV_PMC_DPD_SAMPLE);
332 		writel(10, pmc_base + APBDEV_PMC_SEL_DPD_TIM);
333 	}
334 
335 	reg_val = readl(pmc_base + APBDEV_PMC_IO_DPD2_REQ);
336 	reg_val &= ~(APBDEV_PMC_IO_DPD2_REQ_LVDS_ON ||
337 			APBDEV_PMC_IO_DPD2_REQ_CODE_DEFAULT_MASK);
338 
339 	reg_val = up ? APBDEV_PMC_IO_DPD2_REQ_LVDS_ON |
340 			APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_OFF :
341 			APBDEV_PMC_IO_DPD2_REQ_LVDS_OFF |
342 			APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_ON;
343 
344 	writel(reg_val, pmc_base + APBDEV_PMC_IO_DPD2_REQ);
345 
346 	/* Polling */
347 	u32 temp = 10 * 1000;
348 	do {
349 		udelay(20);
350 		reg_val = readl(pmc_base + APBDEV_PMC_IO_DPD2_STATUS);
351 		if (temp > 20)
352 			temp -= 20;
353 		else
354 			break;
355 	} while ((reg_val & APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON) != 0);
356 
357 	if ((reg_val & APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON) != 0) {
358 		debug("PMC_IO_DPD2 polling failed (0x%x)\n", reg_val);
359 		return -EIO;
360 	}
361 
362 	if (up) {
363 		writel(APBDEV_PMC_DPD_SAMPLE_ON_DISABLE,
364 		       pmc_base + APBDEV_PMC_DPD_SAMPLE);
365 	}
366 
367 	return 0;
368 }
369 
370 void tegra_dc_sor_set_internal_panel(struct udevice *dev, int is_int)
371 {
372 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
373 	u32 reg_val;
374 
375 	reg_val = tegra_sor_readl(sor, DP_SPARE(sor->portnum));
376 	if (is_int)
377 		reg_val |= DP_SPARE_PANEL_INTERNAL;
378 	else
379 		reg_val &= ~DP_SPARE_PANEL_INTERNAL;
380 
381 	reg_val |= DP_SPARE_SOR_CLK_SEL_MACRO_SORCLK |
382 		DP_SPARE_SEQ_ENABLE_YES;
383 	tegra_sor_writel(sor, DP_SPARE(sor->portnum), reg_val);
384 }
385 
386 void tegra_dc_sor_read_link_config(struct udevice *dev, u8 *link_bw,
387 				   u8 *lane_count)
388 {
389 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
390 	u32 reg_val;
391 
392 	reg_val = tegra_sor_readl(sor, CLK_CNTRL);
393 	*link_bw = (reg_val & CLK_CNTRL_DP_LINK_SPEED_MASK)
394 		>> CLK_CNTRL_DP_LINK_SPEED_SHIFT;
395 	reg_val = tegra_sor_readl(sor,
396 		DP_LINKCTL(sor->portnum));
397 
398 	switch (reg_val & DP_LINKCTL_LANECOUNT_MASK) {
399 	case DP_LINKCTL_LANECOUNT_ZERO:
400 		*lane_count = 0;
401 		break;
402 	case DP_LINKCTL_LANECOUNT_ONE:
403 		*lane_count = 1;
404 		break;
405 	case DP_LINKCTL_LANECOUNT_TWO:
406 		*lane_count = 2;
407 		break;
408 	case DP_LINKCTL_LANECOUNT_FOUR:
409 		*lane_count = 4;
410 		break;
411 	default:
412 		printf("Unknown lane count\n");
413 	}
414 }
415 
416 void tegra_dc_sor_set_link_bandwidth(struct udevice *dev, u8 link_bw)
417 {
418 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
419 
420 	tegra_sor_write_field(sor, CLK_CNTRL,
421 			      CLK_CNTRL_DP_LINK_SPEED_MASK,
422 			      link_bw << CLK_CNTRL_DP_LINK_SPEED_SHIFT);
423 }
424 
425 void tegra_dc_sor_set_lane_count(struct udevice *dev, u8 lane_count)
426 {
427 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
428 	u32 reg_val;
429 
430 	reg_val = tegra_sor_readl(sor, DP_LINKCTL(sor->portnum));
431 	reg_val &= ~DP_LINKCTL_LANECOUNT_MASK;
432 	switch (lane_count) {
433 	case 0:
434 		break;
435 	case 1:
436 		reg_val |= DP_LINKCTL_LANECOUNT_ONE;
437 		break;
438 	case 2:
439 		reg_val |= DP_LINKCTL_LANECOUNT_TWO;
440 		break;
441 	case 4:
442 		reg_val |= DP_LINKCTL_LANECOUNT_FOUR;
443 		break;
444 	default:
445 		/* 0 should be handled earlier. */
446 		printf("dp: Invalid lane count %d\n", lane_count);
447 		return;
448 	}
449 	tegra_sor_writel(sor, DP_LINKCTL(sor->portnum), reg_val);
450 }
451 
452 /*
453  * The SOR power sequencer does not work for t124 so SW has to
454  *  go through the power sequence manually
455  * Power up steps from spec:
456  * STEP	PDPORT	PDPLL	PDBG	PLLVCOD	PLLCAPD	E_DPD	PDCAL
457  * 1	1	1	1	1	1	1	1
458  * 2	1	1	1	1	1	0	1
459  * 3	1	1	0	1	1	0	1
460  * 4	1	0	0	0	0	0	1
461  * 5	0	0	0	0	0	0	1
462  */
463 static int tegra_dc_sor_power_up(struct udevice *dev, int is_lvds)
464 {
465 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
466 	u32 reg;
467 	int ret;
468 
469 	if (sor->power_is_up)
470 		return 0;
471 
472 	/*
473 	 * If for some reason it is already powered up, don't do it again.
474 	 * This can happen if U-Boot is the secondary boot loader.
475 	 */
476 	reg = tegra_sor_readl(sor, DP_PADCTL(sor->portnum));
477 	if (reg & DP_PADCTL_PD_TXD_0_NO)
478 		return 0;
479 
480 	/* Set link bw */
481 	tegra_dc_sor_set_link_bandwidth(dev, is_lvds ?
482 					CLK_CNTRL_DP_LINK_SPEED_LVDS :
483 					CLK_CNTRL_DP_LINK_SPEED_G1_62);
484 
485 	/* step 1 */
486 	tegra_sor_write_field(sor, PLL2,
487 			      PLL2_AUX7_PORT_POWERDOWN_MASK | /* PDPORT */
488 			      PLL2_AUX6_BANDGAP_POWERDOWN_MASK | /* PDBG */
489 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK, /* PLLCAPD */
490 			      PLL2_AUX7_PORT_POWERDOWN_ENABLE |
491 			      PLL2_AUX6_BANDGAP_POWERDOWN_ENABLE |
492 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_ENABLE);
493 	tegra_sor_write_field(sor, PLL0, PLL0_PWR_MASK | /* PDPLL */
494 			      PLL0_VCOPD_MASK, /* PLLVCOPD */
495 			      PLL0_PWR_OFF | PLL0_VCOPD_ASSERT);
496 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
497 			      DP_PADCTL_PAD_CAL_PD_POWERDOWN, /* PDCAL */
498 			      DP_PADCTL_PAD_CAL_PD_POWERDOWN);
499 
500 	/* step 2 */
501 	ret = tegra_dc_sor_io_set_dpd(sor, 1);
502 	if (ret)
503 		return ret;
504 	udelay(15);
505 
506 	/* step 3 */
507 	tegra_sor_write_field(sor, PLL2,
508 			      PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
509 			      PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
510 	udelay(25);
511 
512 	/* step 4 */
513 	tegra_sor_write_field(sor, PLL0,
514 			      PLL0_PWR_MASK | /* PDPLL */
515 			      PLL0_VCOPD_MASK, /* PLLVCOPD */
516 			      PLL0_PWR_ON | PLL0_VCOPD_RESCIND);
517 	/* PLLCAPD */
518 	tegra_sor_write_field(sor, PLL2,
519 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
520 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
521 	udelay(225);
522 
523 	/* step 5 PDPORT */
524 	tegra_sor_write_field(sor, PLL2,
525 			      PLL2_AUX7_PORT_POWERDOWN_MASK,
526 			      PLL2_AUX7_PORT_POWERDOWN_DISABLE);
527 
528 	sor->power_is_up = 1;
529 
530 	return 0;
531 }
532 
533 #if DEBUG_SOR
534 static void dump_sor_reg(struct tegra_dc_sor_data *sor)
535 {
536 #define DUMP_REG(a) printk(BIOS_INFO, \
537 		"%-32s  %03x  %08x\n",		\
538 		#a, a, tegra_sor_readl(sor, a));
539 
540 	DUMP_REG(SUPER_STATE0);
541 	DUMP_REG(SUPER_STATE1);
542 	DUMP_REG(STATE0);
543 	DUMP_REG(STATE1);
544 	DUMP_REG(NV_HEAD_STATE0(0));
545 	DUMP_REG(NV_HEAD_STATE0(1));
546 	DUMP_REG(NV_HEAD_STATE1(0));
547 	DUMP_REG(NV_HEAD_STATE1(1));
548 	DUMP_REG(NV_HEAD_STATE2(0));
549 	DUMP_REG(NV_HEAD_STATE2(1));
550 	DUMP_REG(NV_HEAD_STATE3(0));
551 	DUMP_REG(NV_HEAD_STATE3(1));
552 	DUMP_REG(NV_HEAD_STATE4(0));
553 	DUMP_REG(NV_HEAD_STATE4(1));
554 	DUMP_REG(NV_HEAD_STATE5(0));
555 	DUMP_REG(NV_HEAD_STATE5(1));
556 	DUMP_REG(CRC_CNTRL);
557 	DUMP_REG(CLK_CNTRL);
558 	DUMP_REG(CAP);
559 	DUMP_REG(PWR);
560 	DUMP_REG(TEST);
561 	DUMP_REG(PLL0);
562 	DUMP_REG(PLL1);
563 	DUMP_REG(PLL2);
564 	DUMP_REG(PLL3);
565 	DUMP_REG(CSTM);
566 	DUMP_REG(LVDS);
567 	DUMP_REG(CRCA);
568 	DUMP_REG(CRCB);
569 	DUMP_REG(SEQ_CTL);
570 	DUMP_REG(LANE_SEQ_CTL);
571 	DUMP_REG(SEQ_INST(0));
572 	DUMP_REG(SEQ_INST(1));
573 	DUMP_REG(SEQ_INST(2));
574 	DUMP_REG(SEQ_INST(3));
575 	DUMP_REG(SEQ_INST(4));
576 	DUMP_REG(SEQ_INST(5));
577 	DUMP_REG(SEQ_INST(6));
578 	DUMP_REG(SEQ_INST(7));
579 	DUMP_REG(SEQ_INST(8));
580 	DUMP_REG(PWM_DIV);
581 	DUMP_REG(PWM_CTL);
582 	DUMP_REG(MSCHECK);
583 	DUMP_REG(XBAR_CTRL);
584 	DUMP_REG(DP_LINKCTL(0));
585 	DUMP_REG(DP_LINKCTL(1));
586 	DUMP_REG(DC(0));
587 	DUMP_REG(DC(1));
588 	DUMP_REG(LANE_DRIVE_CURRENT(0));
589 	DUMP_REG(PR(0));
590 	DUMP_REG(LANE4_PREEMPHASIS(0));
591 	DUMP_REG(POSTCURSOR(0));
592 	DUMP_REG(DP_CONFIG(0));
593 	DUMP_REG(DP_CONFIG(1));
594 	DUMP_REG(DP_MN(0));
595 	DUMP_REG(DP_MN(1));
596 	DUMP_REG(DP_PADCTL(0));
597 	DUMP_REG(DP_PADCTL(1));
598 	DUMP_REG(DP_DEBUG(0));
599 	DUMP_REG(DP_DEBUG(1));
600 	DUMP_REG(DP_SPARE(0));
601 	DUMP_REG(DP_SPARE(1));
602 	DUMP_REG(DP_TPG);
603 
604 	return;
605 }
606 #endif
607 
608 static void tegra_dc_sor_config_panel(struct tegra_dc_sor_data *sor,
609 			int is_lvds,
610 			const struct tegra_dp_link_config *link_cfg,
611 			const struct display_timing *timing)
612 {
613 	const int	head_num = 0;
614 	u32		reg_val	 = STATE1_ASY_OWNER_HEAD0 << head_num;
615 	u32		vtotal, htotal;
616 	u32		vsync_end, hsync_end;
617 	u32		vblank_end, hblank_end;
618 	u32		vblank_start, hblank_start;
619 
620 	reg_val |= is_lvds ? STATE1_ASY_PROTOCOL_LVDS_CUSTOM :
621 		STATE1_ASY_PROTOCOL_DP_A;
622 	reg_val |= STATE1_ASY_SUBOWNER_NONE |
623 		STATE1_ASY_CRCMODE_COMPLETE_RASTER;
624 
625 	reg_val |= STATE1_ASY_HSYNCPOL_NEGATIVE_TRUE;
626 	reg_val |= STATE1_ASY_VSYNCPOL_NEGATIVE_TRUE;
627 	reg_val |= (link_cfg->bits_per_pixel > 18) ?
628 		STATE1_ASY_PIXELDEPTH_BPP_24_444 :
629 		STATE1_ASY_PIXELDEPTH_BPP_18_444;
630 
631 	tegra_sor_writel(sor, STATE1, reg_val);
632 
633 	/*
634 	 * Skipping programming NV_HEAD_STATE0, assuming:
635 	 * interlacing: PROGRESSIVE, dynamic range: VESA, colorspace: RGB
636 	 */
637 	vtotal = timing->vsync_len.typ + timing->vback_porch.typ +
638 		timing->vactive.typ + timing->vfront_porch.typ;
639 	htotal = timing->hsync_len.typ + timing->hback_porch.typ +
640 		timing->hactive.typ + timing->hfront_porch.typ;
641 
642 	tegra_sor_writel(sor, NV_HEAD_STATE1(head_num),
643 			 vtotal << NV_HEAD_STATE1_VTOTAL_SHIFT |
644 			 htotal << NV_HEAD_STATE1_HTOTAL_SHIFT);
645 
646 	vsync_end = timing->vsync_len.typ - 1;
647 	hsync_end = timing->hsync_len.typ - 1;
648 	tegra_sor_writel(sor, NV_HEAD_STATE2(head_num),
649 			 vsync_end << NV_HEAD_STATE2_VSYNC_END_SHIFT |
650 			 hsync_end << NV_HEAD_STATE2_HSYNC_END_SHIFT);
651 
652 	vblank_end = vsync_end + timing->vback_porch.typ;
653 	hblank_end = hsync_end + timing->hback_porch.typ;
654 	tegra_sor_writel(sor, NV_HEAD_STATE3(head_num),
655 			 vblank_end << NV_HEAD_STATE3_VBLANK_END_SHIFT |
656 			 hblank_end << NV_HEAD_STATE3_HBLANK_END_SHIFT);
657 
658 	vblank_start = vblank_end + timing->vactive.typ;
659 	hblank_start = hblank_end + timing->hactive.typ;
660 	tegra_sor_writel(sor, NV_HEAD_STATE4(head_num),
661 			 vblank_start << NV_HEAD_STATE4_VBLANK_START_SHIFT |
662 			 hblank_start << NV_HEAD_STATE4_HBLANK_START_SHIFT);
663 
664 	/* TODO: adding interlace mode support */
665 	tegra_sor_writel(sor, NV_HEAD_STATE5(head_num), 0x1);
666 
667 	tegra_sor_write_field(sor, CSTM,
668 			      CSTM_ROTCLK_DEFAULT_MASK |
669 			      CSTM_LVDS_EN_ENABLE,
670 			      2 << CSTM_ROTCLK_SHIFT |
671 			      is_lvds ? CSTM_LVDS_EN_ENABLE :
672 			      CSTM_LVDS_EN_DISABLE);
673 
674 	 tegra_dc_sor_config_pwm(sor, 1024, 1024);
675 }
676 
677 static void tegra_dc_sor_enable_dc(struct dc_ctlr *disp_ctrl)
678 {
679 	u32 reg_val = readl(&disp_ctrl->cmd.state_access);
680 
681 	writel(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
682 	writel(VSYNC_H_POSITION(1), &disp_ctrl->disp.disp_timing_opt);
683 
684 	/* Enable DC now - otherwise pure text console may not show. */
685 	writel(CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT,
686 	       &disp_ctrl->cmd.disp_cmd);
687 	writel(reg_val, &disp_ctrl->cmd.state_access);
688 }
689 
690 int tegra_dc_sor_enable_dp(struct udevice *dev,
691 			   const struct tegra_dp_link_config *link_cfg)
692 {
693 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
694 	int ret;
695 
696 	tegra_sor_write_field(sor, CLK_CNTRL,
697 			      CLK_CNTRL_DP_CLK_SEL_MASK,
698 			      CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK);
699 
700 	tegra_sor_write_field(sor, PLL2,
701 			      PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
702 			      PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
703 	udelay(25);
704 
705 	tegra_sor_write_field(sor, PLL3,
706 			      PLL3_PLLVDD_MODE_MASK,
707 			      PLL3_PLLVDD_MODE_V3_3);
708 	tegra_sor_writel(sor, PLL0,
709 			 0xf << PLL0_ICHPMP_SHFIT |
710 			 0x3 << PLL0_VCOCAP_SHIFT |
711 			 PLL0_PLLREG_LEVEL_V45 |
712 			 PLL0_RESISTORSEL_EXT |
713 			 PLL0_PWR_ON | PLL0_VCOPD_RESCIND);
714 	tegra_sor_write_field(sor, PLL2,
715 			      PLL2_AUX1_SEQ_MASK |
716 			      PLL2_AUX9_LVDSEN_OVERRIDE |
717 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
718 			      PLL2_AUX1_SEQ_PLLCAPPD_OVERRIDE |
719 			      PLL2_AUX9_LVDSEN_OVERRIDE |
720 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
721 	tegra_sor_writel(sor, PLL1, PLL1_TERM_COMPOUT_HIGH |
722 			 PLL1_TMDS_TERM_ENABLE);
723 
724 	if (tegra_dc_sor_poll_register(sor, PLL2,
725 				       PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
726 				       PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE,
727 				       100, TEGRA_SOR_TIMEOUT_MS)) {
728 		printf("DP failed to lock PLL\n");
729 		return -EIO;
730 	}
731 
732 	tegra_sor_write_field(sor, PLL2, PLL2_AUX2_MASK |
733 			      PLL2_AUX7_PORT_POWERDOWN_MASK,
734 			      PLL2_AUX2_OVERRIDE_POWERDOWN |
735 			      PLL2_AUX7_PORT_POWERDOWN_DISABLE);
736 
737 	ret = tegra_dc_sor_power_up(dev, 0);
738 	if (ret) {
739 		debug("DP failed to power up\n");
740 		return ret;
741 	}
742 
743 	/* re-enable SOR clock */
744 	clock_sor_enable_edp_clock();
745 
746 	/* Power up lanes */
747 	tegra_dc_sor_power_dplanes(dev, link_cfg->lane_count, 1);
748 
749 	tegra_dc_sor_set_dp_mode(dev, link_cfg);
750 	debug("%s ret\n", __func__);
751 
752 	return 0;
753 }
754 
755 int tegra_dc_sor_attach(struct udevice *dc_dev, struct udevice *dev,
756 			const struct tegra_dp_link_config *link_cfg,
757 			const struct display_timing *timing)
758 {
759 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
760 	struct dc_ctlr *disp_ctrl;
761 	u32 reg_val;
762 
763 	/* Use the first display controller */
764 	debug("%s\n", __func__);
765 	disp_ctrl = (struct dc_ctlr *)dev_read_addr(dc_dev);
766 
767 	tegra_dc_sor_enable_dc(disp_ctrl);
768 	tegra_dc_sor_config_panel(sor, 0, link_cfg, timing);
769 
770 	writel(0x9f00, &disp_ctrl->cmd.state_ctrl);
771 	writel(0x9f, &disp_ctrl->cmd.state_ctrl);
772 
773 	writel(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
774 	       PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
775 	       &disp_ctrl->cmd.disp_pow_ctrl);
776 
777 	reg_val = tegra_sor_readl(sor, TEST);
778 	if (reg_val & TEST_ATTACHED_TRUE)
779 		return -EEXIST;
780 
781 	tegra_sor_writel(sor, SUPER_STATE1,
782 			 SUPER_STATE1_ATTACHED_NO);
783 
784 	/*
785 	 * Enable display2sor clock at least 2 cycles before DC start,
786 	 * to clear sor internal valid signal.
787 	 */
788 	writel(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
789 	writel(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
790 	writel(0, &disp_ctrl->disp.disp_win_opt);
791 	writel(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
792 
793 	/* Attach head */
794 	tegra_dc_sor_update(sor);
795 	tegra_sor_writel(sor, SUPER_STATE1,
796 			 SUPER_STATE1_ATTACHED_YES);
797 	tegra_sor_writel(sor, SUPER_STATE1,
798 			 SUPER_STATE1_ATTACHED_YES |
799 			 SUPER_STATE1_ASY_HEAD_OP_AWAKE |
800 			 SUPER_STATE1_ASY_ORMODE_NORMAL);
801 	tegra_dc_sor_super_update(sor);
802 
803 	/* Enable dc */
804 	reg_val = readl(&disp_ctrl->cmd.state_access);
805 	writel(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
806 	writel(CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT,
807 	       &disp_ctrl->cmd.disp_cmd);
808 	writel(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
809 	writel(reg_val, &disp_ctrl->cmd.state_access);
810 
811 	if (tegra_dc_sor_poll_register(sor, TEST,
812 				       TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
813 				       TEST_ACT_HEAD_OPMODE_AWAKE,
814 				       100,
815 				       TEGRA_SOR_ATTACH_TIMEOUT_MS)) {
816 		printf("dc timeout waiting for OPMOD = AWAKE\n");
817 		return -ETIMEDOUT;
818 	} else {
819 		debug("%s: sor is attached\n", __func__);
820 	}
821 
822 #if DEBUG_SOR
823 	dump_sor_reg(sor);
824 #endif
825 	debug("%s: ret=%d\n", __func__, 0);
826 
827 	return 0;
828 }
829 
830 void tegra_dc_sor_set_lane_parm(struct udevice *dev,
831 		const struct tegra_dp_link_config *link_cfg)
832 {
833 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
834 
835 	tegra_sor_writel(sor, LANE_DRIVE_CURRENT(sor->portnum),
836 			 link_cfg->drive_current);
837 	tegra_sor_writel(sor, PR(sor->portnum),
838 			 link_cfg->preemphasis);
839 	tegra_sor_writel(sor, POSTCURSOR(sor->portnum),
840 			 link_cfg->postcursor);
841 	tegra_sor_writel(sor, LVDS, 0);
842 
843 	tegra_dc_sor_set_link_bandwidth(dev, link_cfg->link_bw);
844 	tegra_dc_sor_set_lane_count(dev, link_cfg->lane_count);
845 
846 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
847 			      DP_PADCTL_TX_PU_ENABLE |
848 			      DP_PADCTL_TX_PU_VALUE_DEFAULT_MASK,
849 			      DP_PADCTL_TX_PU_ENABLE |
850 			      2 << DP_PADCTL_TX_PU_VALUE_SHIFT);
851 
852 	/* Precharge */
853 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum), 0xf0, 0xf0);
854 	udelay(20);
855 
856 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum), 0xf0, 0x0);
857 }
858 
859 int tegra_dc_sor_set_voltage_swing(struct udevice *dev,
860 				    const struct tegra_dp_link_config *link_cfg)
861 {
862 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
863 	u32 drive_current = 0;
864 	u32 pre_emphasis = 0;
865 
866 	/* Set to a known-good pre-calibrated setting */
867 	switch (link_cfg->link_bw) {
868 	case SOR_LINK_SPEED_G1_62:
869 	case SOR_LINK_SPEED_G2_7:
870 		drive_current = 0x13131313;
871 		pre_emphasis = 0;
872 		break;
873 	case SOR_LINK_SPEED_G5_4:
874 		debug("T124 does not support 5.4G link clock.\n");
875 	default:
876 		debug("Invalid sor link bandwidth: %d\n", link_cfg->link_bw);
877 		return -ENOLINK;
878 	}
879 
880 	tegra_sor_writel(sor, LANE_DRIVE_CURRENT(sor->portnum), drive_current);
881 	tegra_sor_writel(sor, PR(sor->portnum), pre_emphasis);
882 
883 	return 0;
884 }
885 
886 void tegra_dc_sor_power_down_unused_lanes(struct udevice *dev,
887 			const struct tegra_dp_link_config *link_cfg)
888 {
889 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
890 	u32 pad_ctrl = 0;
891 	int err = 0;
892 
893 	switch (link_cfg->lane_count) {
894 	case 4:
895 		pad_ctrl = DP_PADCTL_PD_TXD_0_NO |
896 			DP_PADCTL_PD_TXD_1_NO |
897 			DP_PADCTL_PD_TXD_2_NO |
898 			DP_PADCTL_PD_TXD_3_NO;
899 		break;
900 	case 2:
901 		pad_ctrl = DP_PADCTL_PD_TXD_0_NO |
902 			DP_PADCTL_PD_TXD_1_NO |
903 			DP_PADCTL_PD_TXD_2_YES |
904 			DP_PADCTL_PD_TXD_3_YES;
905 		break;
906 	case 1:
907 		pad_ctrl = DP_PADCTL_PD_TXD_0_NO |
908 			DP_PADCTL_PD_TXD_1_YES |
909 			DP_PADCTL_PD_TXD_2_YES |
910 			DP_PADCTL_PD_TXD_3_YES;
911 		break;
912 	default:
913 		printf("Invalid sor lane count: %u\n", link_cfg->lane_count);
914 		return;
915 	}
916 
917 	pad_ctrl |= DP_PADCTL_PAD_CAL_PD_POWERDOWN;
918 	tegra_sor_writel(sor, DP_PADCTL(sor->portnum), pad_ctrl);
919 
920 	err = tegra_dc_sor_enable_lane_sequencer(sor, 0, 0);
921 	if (err) {
922 		debug("Wait for lane power down failed: %d\n", err);
923 		return;
924 	}
925 }
926 
927 int tegra_sor_precharge_lanes(struct udevice *dev,
928 			      const struct tegra_dp_link_config *cfg)
929 {
930 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
931 	u32 val = 0;
932 
933 	switch (cfg->lane_count) {
934 	case 4:
935 		val |= (DP_PADCTL_PD_TXD_3_NO |
936 			DP_PADCTL_PD_TXD_2_NO);
937 		/* fall through */
938 	case 2:
939 		val |= DP_PADCTL_PD_TXD_1_NO;
940 		/* fall through */
941 	case 1:
942 		val |= DP_PADCTL_PD_TXD_0_NO;
943 		break;
944 	default:
945 		debug("dp: invalid lane number %d\n", cfg->lane_count);
946 		return -EINVAL;
947 	}
948 
949 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
950 			      (0xf << DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT),
951 			      (val << DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT));
952 	udelay(100);
953 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
954 			      (0xf << DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT),
955 			      0);
956 
957 	return 0;
958 }
959 
960 static void tegra_dc_sor_enable_sor(struct dc_ctlr *disp_ctrl, bool enable)
961 {
962 	u32 reg_val = readl(&disp_ctrl->disp.disp_win_opt);
963 
964 	reg_val = enable ? reg_val | SOR_ENABLE : reg_val & ~SOR_ENABLE;
965 	writel(reg_val, &disp_ctrl->disp.disp_win_opt);
966 }
967 
968 int tegra_dc_sor_detach(struct udevice *dc_dev, struct udevice *dev)
969 {
970 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
971 	int dc_reg_ctx[DC_REG_SAVE_SPACE];
972 	struct dc_ctlr *disp_ctrl;
973 	unsigned long dc_int_mask;
974 	int ret;
975 
976 	debug("%s\n", __func__);
977 	/* Use the first display controller */
978 	disp_ctrl = (struct dc_ctlr *)dev_read_addr(dev);
979 
980 	/* Sleep mode */
981 	tegra_sor_writel(sor, SUPER_STATE1, SUPER_STATE1_ASY_HEAD_OP_SLEEP |
982 			 SUPER_STATE1_ASY_ORMODE_SAFE |
983 			 SUPER_STATE1_ATTACHED_YES);
984 	tegra_dc_sor_super_update(sor);
985 
986 	tegra_dc_sor_disable_win_short_raster(disp_ctrl, dc_reg_ctx);
987 
988 	if (tegra_dc_sor_poll_register(sor, TEST,
989 				       TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
990 				       TEST_ACT_HEAD_OPMODE_SLEEP, 100,
991 				       TEGRA_SOR_ATTACH_TIMEOUT_MS)) {
992 		debug("dc timeout waiting for OPMOD = SLEEP\n");
993 		ret = -ETIMEDOUT;
994 		goto err;
995 	}
996 
997 	tegra_sor_writel(sor, SUPER_STATE1, SUPER_STATE1_ASY_HEAD_OP_SLEEP |
998 			 SUPER_STATE1_ASY_ORMODE_SAFE |
999 			 SUPER_STATE1_ATTACHED_NO);
1000 
1001 	/* Mask DC interrupts during the 2 dummy frames required for detach */
1002 	dc_int_mask = readl(&disp_ctrl->cmd.int_mask);
1003 	writel(0, &disp_ctrl->cmd.int_mask);
1004 
1005 	/* Stop DC->SOR path */
1006 	tegra_dc_sor_enable_sor(disp_ctrl, false);
1007 	ret = tegra_dc_sor_general_act(disp_ctrl);
1008 	if (ret)
1009 		goto err;
1010 
1011 	/* Stop DC */
1012 	writel(CTRL_MODE_STOP << CTRL_MODE_SHIFT, &disp_ctrl->cmd.disp_cmd);
1013 	ret = tegra_dc_sor_general_act(disp_ctrl);
1014 	if (ret)
1015 		goto err;
1016 
1017 	tegra_dc_sor_restore_win_and_raster(disp_ctrl, dc_reg_ctx);
1018 
1019 	writel(dc_int_mask, &disp_ctrl->cmd.int_mask);
1020 
1021 	return 0;
1022 err:
1023 	debug("%s: ret=%d\n", __func__, ret);
1024 
1025 	return ret;
1026 }
1027 
1028 static int tegra_sor_set_backlight(struct udevice *dev, int percent)
1029 {
1030 	struct tegra_dc_sor_data *priv = dev_get_priv(dev);
1031 	int ret;
1032 
1033 	ret = panel_enable_backlight(priv->panel);
1034 	if (ret) {
1035 		debug("sor: Cannot enable panel backlight\n");
1036 		return ret;
1037 	}
1038 
1039 	return 0;
1040 }
1041 
1042 static int tegra_sor_ofdata_to_platdata(struct udevice *dev)
1043 {
1044 	struct tegra_dc_sor_data *priv = dev_get_priv(dev);
1045 	int ret;
1046 
1047 	priv->base = (void *)dev_read_addr(dev);
1048 
1049 	priv->pmc_base = (void *)syscon_get_first_range(TEGRA_SYSCON_PMC);
1050 	if (IS_ERR(priv->pmc_base))
1051 		return PTR_ERR(priv->pmc_base);
1052 
1053 	ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "nvidia,panel",
1054 					   &priv->panel);
1055 	if (ret) {
1056 		debug("%s: Cannot find panel for '%s' (ret=%d)\n", __func__,
1057 		      dev->name, ret);
1058 		return ret;
1059 	}
1060 
1061 	return 0;
1062 }
1063 
1064 static const struct video_bridge_ops tegra_sor_ops = {
1065 	.set_backlight	= tegra_sor_set_backlight,
1066 };
1067 
1068 static const struct udevice_id tegra_sor_ids[] = {
1069 	{ .compatible = "nvidia,tegra124-sor" },
1070 	{ }
1071 };
1072 
1073 U_BOOT_DRIVER(sor_tegra) = {
1074 	.name	= "sor_tegra",
1075 	.id	= UCLASS_VIDEO_BRIDGE,
1076 	.of_match = tegra_sor_ids,
1077 	.ofdata_to_platdata = tegra_sor_ofdata_to_platdata,
1078 	.ops	= &tegra_sor_ops,
1079 	.priv_auto_alloc_size = sizeof(struct tegra_dc_sor_data),
1080 };
1081