• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
tegra_sor_readl(struct tegra_dc_sor_data * sor,u32 reg)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 
tegra_sor_writel(struct tegra_dc_sor_data * sor,u32 reg,u32 val)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 
tegra_sor_write_field(struct tegra_dc_sor_data * sor,u32 reg,u32 mask,u32 val)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 
tegra_dp_disable_tx_pu(struct udevice * dev)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 
tegra_dp_set_pe_vs_pc(struct udevice * dev,u32 mask,u32 pe_reg,u32 vs_reg,u32 pc_reg,u8 pc_supported)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 
tegra_dc_sor_poll_register(struct tegra_dc_sor_data * sor,u32 reg,u32 mask,u32 exp_val,int poll_interval_us,int timeout_ms)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 
tegra_dc_sor_set_power_state(struct udevice * dev,int pu_pd)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 
tegra_dc_sor_set_dp_linkctl(struct udevice * dev,int ena,u8 training_pattern,const struct tegra_dp_link_config * link_cfg)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 
tegra_dc_sor_enable_lane_sequencer(struct tegra_dc_sor_data * sor,int pu,int is_lvds)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 
tegra_dc_sor_power_dplanes(struct udevice * dev,u32 lane_count,int pu)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 
tegra_dc_sor_set_panel_power(struct udevice * dev,int power_up)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 
tegra_dc_sor_config_pwm(struct tegra_dc_sor_data * sor,u32 pwm_div,u32 pwm_dutycycle)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 
tegra_dc_sor_set_dp_mode(struct udevice * dev,const struct tegra_dp_link_config * link_cfg)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 
tegra_dc_sor_super_update(struct tegra_dc_sor_data * sor)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 
tegra_dc_sor_update(struct tegra_dc_sor_data * sor)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 
tegra_dc_sor_io_set_dpd(struct tegra_dc_sor_data * sor,int up)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 
tegra_dc_sor_set_internal_panel(struct udevice * dev,int is_int)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 
tegra_dc_sor_read_link_config(struct udevice * dev,u8 * link_bw,u8 * lane_count)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 
tegra_dc_sor_set_link_bandwidth(struct udevice * dev,u8 link_bw)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 
tegra_dc_sor_set_lane_count(struct udevice * dev,u8 lane_count)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  */
tegra_dc_sor_power_up(struct udevice * dev,int is_lvds)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
dump_sor_reg(struct tegra_dc_sor_data * sor)534 static void dump_sor_reg(struct tegra_dc_sor_data *sor)
535 {
536 #define DUMP_REG(a) printk(BIOS_INFO, "%-32s  %03x  %08x\n",		\
537 		#a, a, tegra_sor_readl(sor, a));
538 
539 	DUMP_REG(SUPER_STATE0);
540 	DUMP_REG(SUPER_STATE1);
541 	DUMP_REG(STATE0);
542 	DUMP_REG(STATE1);
543 	DUMP_REG(NV_HEAD_STATE0(0));
544 	DUMP_REG(NV_HEAD_STATE0(1));
545 	DUMP_REG(NV_HEAD_STATE1(0));
546 	DUMP_REG(NV_HEAD_STATE1(1));
547 	DUMP_REG(NV_HEAD_STATE2(0));
548 	DUMP_REG(NV_HEAD_STATE2(1));
549 	DUMP_REG(NV_HEAD_STATE3(0));
550 	DUMP_REG(NV_HEAD_STATE3(1));
551 	DUMP_REG(NV_HEAD_STATE4(0));
552 	DUMP_REG(NV_HEAD_STATE4(1));
553 	DUMP_REG(NV_HEAD_STATE5(0));
554 	DUMP_REG(NV_HEAD_STATE5(1));
555 	DUMP_REG(CRC_CNTRL);
556 	DUMP_REG(CLK_CNTRL);
557 	DUMP_REG(CAP);
558 	DUMP_REG(PWR);
559 	DUMP_REG(TEST);
560 	DUMP_REG(PLL0);
561 	DUMP_REG(PLL1);
562 	DUMP_REG(PLL2);
563 	DUMP_REG(PLL3);
564 	DUMP_REG(CSTM);
565 	DUMP_REG(LVDS);
566 	DUMP_REG(CRCA);
567 	DUMP_REG(CRCB);
568 	DUMP_REG(SEQ_CTL);
569 	DUMP_REG(LANE_SEQ_CTL);
570 	DUMP_REG(SEQ_INST(0));
571 	DUMP_REG(SEQ_INST(1));
572 	DUMP_REG(SEQ_INST(2));
573 	DUMP_REG(SEQ_INST(3));
574 	DUMP_REG(SEQ_INST(4));
575 	DUMP_REG(SEQ_INST(5));
576 	DUMP_REG(SEQ_INST(6));
577 	DUMP_REG(SEQ_INST(7));
578 	DUMP_REG(SEQ_INST(8));
579 	DUMP_REG(PWM_DIV);
580 	DUMP_REG(PWM_CTL);
581 	DUMP_REG(MSCHECK);
582 	DUMP_REG(XBAR_CTRL);
583 	DUMP_REG(DP_LINKCTL(0));
584 	DUMP_REG(DP_LINKCTL(1));
585 	DUMP_REG(DC(0));
586 	DUMP_REG(DC(1));
587 	DUMP_REG(LANE_DRIVE_CURRENT(0));
588 	DUMP_REG(PR(0));
589 	DUMP_REG(LANE4_PREEMPHASIS(0));
590 	DUMP_REG(POSTCURSOR(0));
591 	DUMP_REG(DP_CONFIG(0));
592 	DUMP_REG(DP_CONFIG(1));
593 	DUMP_REG(DP_MN(0));
594 	DUMP_REG(DP_MN(1));
595 	DUMP_REG(DP_PADCTL(0));
596 	DUMP_REG(DP_PADCTL(1));
597 	DUMP_REG(DP_DEBUG(0));
598 	DUMP_REG(DP_DEBUG(1));
599 	DUMP_REG(DP_SPARE(0));
600 	DUMP_REG(DP_SPARE(1));
601 	DUMP_REG(DP_TPG);
602 
603 	return;
604 }
605 #endif
606 
tegra_dc_sor_config_panel(struct tegra_dc_sor_data * sor,int is_lvds,const struct tegra_dp_link_config * link_cfg,const struct display_timing * timing)607 static void tegra_dc_sor_config_panel(struct tegra_dc_sor_data *sor,
608 			int is_lvds,
609 			const struct tegra_dp_link_config *link_cfg,
610 			const struct display_timing *timing)
611 {
612 	const int	head_num = 0;
613 	u32		reg_val	 = STATE1_ASY_OWNER_HEAD0 << head_num;
614 	u32		vtotal, htotal;
615 	u32		vsync_end, hsync_end;
616 	u32		vblank_end, hblank_end;
617 	u32		vblank_start, hblank_start;
618 
619 	reg_val |= is_lvds ? STATE1_ASY_PROTOCOL_LVDS_CUSTOM :
620 		STATE1_ASY_PROTOCOL_DP_A;
621 	reg_val |= STATE1_ASY_SUBOWNER_NONE |
622 		STATE1_ASY_CRCMODE_COMPLETE_RASTER;
623 
624 	reg_val |= STATE1_ASY_HSYNCPOL_NEGATIVE_TRUE;
625 	reg_val |= STATE1_ASY_VSYNCPOL_NEGATIVE_TRUE;
626 	reg_val |= (link_cfg->bits_per_pixel > 18) ?
627 		STATE1_ASY_PIXELDEPTH_BPP_24_444 :
628 		STATE1_ASY_PIXELDEPTH_BPP_18_444;
629 
630 	tegra_sor_writel(sor, STATE1, reg_val);
631 
632 	/*
633 	 * Skipping programming NV_HEAD_STATE0, assuming:
634 	 * interlacing: PROGRESSIVE, dynamic range: VESA, colorspace: RGB
635 	 */
636 	vtotal = timing->vsync_len.typ + timing->vback_porch.typ +
637 		timing->vactive.typ + timing->vfront_porch.typ;
638 	htotal = timing->hsync_len.typ + timing->hback_porch.typ +
639 		timing->hactive.typ + timing->hfront_porch.typ;
640 
641 	tegra_sor_writel(sor, NV_HEAD_STATE1(head_num),
642 			 vtotal << NV_HEAD_STATE1_VTOTAL_SHIFT |
643 			 htotal << NV_HEAD_STATE1_HTOTAL_SHIFT);
644 
645 	vsync_end = timing->vsync_len.typ - 1;
646 	hsync_end = timing->hsync_len.typ - 1;
647 	tegra_sor_writel(sor, NV_HEAD_STATE2(head_num),
648 			 vsync_end << NV_HEAD_STATE2_VSYNC_END_SHIFT |
649 			 hsync_end << NV_HEAD_STATE2_HSYNC_END_SHIFT);
650 
651 	vblank_end = vsync_end + timing->vback_porch.typ;
652 	hblank_end = hsync_end + timing->hback_porch.typ;
653 	tegra_sor_writel(sor, NV_HEAD_STATE3(head_num),
654 			 vblank_end << NV_HEAD_STATE3_VBLANK_END_SHIFT |
655 			 hblank_end << NV_HEAD_STATE3_HBLANK_END_SHIFT);
656 
657 	vblank_start = vblank_end + timing->vactive.typ;
658 	hblank_start = hblank_end + timing->hactive.typ;
659 	tegra_sor_writel(sor, NV_HEAD_STATE4(head_num),
660 			 vblank_start << NV_HEAD_STATE4_VBLANK_START_SHIFT |
661 			 hblank_start << NV_HEAD_STATE4_HBLANK_START_SHIFT);
662 
663 	/* TODO: adding interlace mode support */
664 	tegra_sor_writel(sor, NV_HEAD_STATE5(head_num), 0x1);
665 
666 	tegra_sor_write_field(sor, CSTM,
667 			      CSTM_ROTCLK_DEFAULT_MASK |
668 			      CSTM_LVDS_EN_ENABLE,
669 			      2 << CSTM_ROTCLK_SHIFT |
670 			      is_lvds ? CSTM_LVDS_EN_ENABLE :
671 			      CSTM_LVDS_EN_DISABLE);
672 
673 	 tegra_dc_sor_config_pwm(sor, 1024, 1024);
674 }
675 
tegra_dc_sor_enable_dc(struct dc_ctlr * disp_ctrl)676 static void tegra_dc_sor_enable_dc(struct dc_ctlr *disp_ctrl)
677 {
678 	u32 reg_val = readl(&disp_ctrl->cmd.state_access);
679 
680 	writel(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
681 	writel(VSYNC_H_POSITION(1), &disp_ctrl->disp.disp_timing_opt);
682 
683 	/* Enable DC now - otherwise pure text console may not show. */
684 	writel(CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT,
685 	       &disp_ctrl->cmd.disp_cmd);
686 	writel(reg_val, &disp_ctrl->cmd.state_access);
687 }
688 
tegra_dc_sor_enable_dp(struct udevice * dev,const struct tegra_dp_link_config * link_cfg)689 int tegra_dc_sor_enable_dp(struct udevice *dev,
690 			   const struct tegra_dp_link_config *link_cfg)
691 {
692 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
693 	int ret;
694 
695 	tegra_sor_write_field(sor, CLK_CNTRL,
696 			      CLK_CNTRL_DP_CLK_SEL_MASK,
697 			      CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK);
698 
699 	tegra_sor_write_field(sor, PLL2,
700 			      PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
701 			      PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
702 	udelay(25);
703 
704 	tegra_sor_write_field(sor, PLL3,
705 			      PLL3_PLLVDD_MODE_MASK,
706 			      PLL3_PLLVDD_MODE_V3_3);
707 	tegra_sor_writel(sor, PLL0,
708 			 0xf << PLL0_ICHPMP_SHFIT |
709 			 0x3 << PLL0_VCOCAP_SHIFT |
710 			 PLL0_PLLREG_LEVEL_V45 |
711 			 PLL0_RESISTORSEL_EXT |
712 			 PLL0_PWR_ON | PLL0_VCOPD_RESCIND);
713 	tegra_sor_write_field(sor, PLL2,
714 			      PLL2_AUX1_SEQ_MASK |
715 			      PLL2_AUX9_LVDSEN_OVERRIDE |
716 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
717 			      PLL2_AUX1_SEQ_PLLCAPPD_OVERRIDE |
718 			      PLL2_AUX9_LVDSEN_OVERRIDE |
719 			      PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
720 	tegra_sor_writel(sor, PLL1, PLL1_TERM_COMPOUT_HIGH |
721 			 PLL1_TMDS_TERM_ENABLE);
722 
723 	if (tegra_dc_sor_poll_register(sor, PLL2,
724 				       PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
725 				       PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE,
726 				       100, TEGRA_SOR_TIMEOUT_MS)) {
727 		printf("DP failed to lock PLL\n");
728 		return -EIO;
729 	}
730 
731 	tegra_sor_write_field(sor, PLL2, PLL2_AUX2_MASK |
732 			      PLL2_AUX7_PORT_POWERDOWN_MASK,
733 			      PLL2_AUX2_OVERRIDE_POWERDOWN |
734 			      PLL2_AUX7_PORT_POWERDOWN_DISABLE);
735 
736 	ret = tegra_dc_sor_power_up(dev, 0);
737 	if (ret) {
738 		debug("DP failed to power up\n");
739 		return ret;
740 	}
741 
742 	/* re-enable SOR clock */
743 	clock_sor_enable_edp_clock();
744 
745 	/* Power up lanes */
746 	tegra_dc_sor_power_dplanes(dev, link_cfg->lane_count, 1);
747 
748 	tegra_dc_sor_set_dp_mode(dev, link_cfg);
749 	debug("%s ret\n", __func__);
750 
751 	return 0;
752 }
753 
tegra_dc_sor_attach(struct udevice * dc_dev,struct udevice * dev,const struct tegra_dp_link_config * link_cfg,const struct display_timing * timing)754 int tegra_dc_sor_attach(struct udevice *dc_dev, struct udevice *dev,
755 			const struct tegra_dp_link_config *link_cfg,
756 			const struct display_timing *timing)
757 {
758 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
759 	struct dc_ctlr *disp_ctrl;
760 	u32 reg_val;
761 
762 	/* Use the first display controller */
763 	debug("%s\n", __func__);
764 	disp_ctrl = (struct dc_ctlr *)dev_read_addr(dc_dev);
765 
766 	tegra_dc_sor_enable_dc(disp_ctrl);
767 	tegra_dc_sor_config_panel(sor, 0, link_cfg, timing);
768 
769 	writel(0x9f00, &disp_ctrl->cmd.state_ctrl);
770 	writel(0x9f, &disp_ctrl->cmd.state_ctrl);
771 
772 	writel(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
773 	       PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
774 	       &disp_ctrl->cmd.disp_pow_ctrl);
775 
776 	reg_val = tegra_sor_readl(sor, TEST);
777 	if (reg_val & TEST_ATTACHED_TRUE)
778 		return -EEXIST;
779 
780 	tegra_sor_writel(sor, SUPER_STATE1,
781 			 SUPER_STATE1_ATTACHED_NO);
782 
783 	/*
784 	 * Enable display2sor clock at least 2 cycles before DC start,
785 	 * to clear sor internal valid signal.
786 	 */
787 	writel(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
788 	writel(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
789 	writel(0, &disp_ctrl->disp.disp_win_opt);
790 	writel(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
791 
792 	/* Attach head */
793 	tegra_dc_sor_update(sor);
794 	tegra_sor_writel(sor, SUPER_STATE1,
795 			 SUPER_STATE1_ATTACHED_YES);
796 	tegra_sor_writel(sor, SUPER_STATE1,
797 			 SUPER_STATE1_ATTACHED_YES |
798 			 SUPER_STATE1_ASY_HEAD_OP_AWAKE |
799 			 SUPER_STATE1_ASY_ORMODE_NORMAL);
800 	tegra_dc_sor_super_update(sor);
801 
802 	/* Enable dc */
803 	reg_val = readl(&disp_ctrl->cmd.state_access);
804 	writel(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
805 	writel(CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT,
806 	       &disp_ctrl->cmd.disp_cmd);
807 	writel(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
808 	writel(reg_val, &disp_ctrl->cmd.state_access);
809 
810 	if (tegra_dc_sor_poll_register(sor, TEST,
811 				       TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
812 				       TEST_ACT_HEAD_OPMODE_AWAKE,
813 				       100,
814 				       TEGRA_SOR_ATTACH_TIMEOUT_MS)) {
815 		printf("dc timeout waiting for OPMOD = AWAKE\n");
816 		return -ETIMEDOUT;
817 	} else {
818 		debug("%s: sor is attached\n", __func__);
819 	}
820 
821 #if DEBUG_SOR
822 	dump_sor_reg(sor);
823 #endif
824 	debug("%s: ret=%d\n", __func__, 0);
825 
826 	return 0;
827 }
828 
tegra_dc_sor_set_lane_parm(struct udevice * dev,const struct tegra_dp_link_config * link_cfg)829 void tegra_dc_sor_set_lane_parm(struct udevice *dev,
830 		const struct tegra_dp_link_config *link_cfg)
831 {
832 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
833 
834 	tegra_sor_writel(sor, LANE_DRIVE_CURRENT(sor->portnum),
835 			 link_cfg->drive_current);
836 	tegra_sor_writel(sor, PR(sor->portnum),
837 			 link_cfg->preemphasis);
838 	tegra_sor_writel(sor, POSTCURSOR(sor->portnum),
839 			 link_cfg->postcursor);
840 	tegra_sor_writel(sor, LVDS, 0);
841 
842 	tegra_dc_sor_set_link_bandwidth(dev, link_cfg->link_bw);
843 	tegra_dc_sor_set_lane_count(dev, link_cfg->lane_count);
844 
845 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
846 			      DP_PADCTL_TX_PU_ENABLE |
847 			      DP_PADCTL_TX_PU_VALUE_DEFAULT_MASK,
848 			      DP_PADCTL_TX_PU_ENABLE |
849 			      2 << DP_PADCTL_TX_PU_VALUE_SHIFT);
850 
851 	/* Precharge */
852 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum), 0xf0, 0xf0);
853 	udelay(20);
854 
855 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum), 0xf0, 0x0);
856 }
857 
tegra_dc_sor_set_voltage_swing(struct udevice * dev,const struct tegra_dp_link_config * link_cfg)858 int tegra_dc_sor_set_voltage_swing(struct udevice *dev,
859 				    const struct tegra_dp_link_config *link_cfg)
860 {
861 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
862 	u32 drive_current = 0;
863 	u32 pre_emphasis = 0;
864 
865 	/* Set to a known-good pre-calibrated setting */
866 	switch (link_cfg->link_bw) {
867 	case SOR_LINK_SPEED_G1_62:
868 	case SOR_LINK_SPEED_G2_7:
869 		drive_current = 0x13131313;
870 		pre_emphasis = 0;
871 		break;
872 	case SOR_LINK_SPEED_G5_4:
873 		debug("T124 does not support 5.4G link clock.\n");
874 	default:
875 		debug("Invalid sor link bandwidth: %d\n", link_cfg->link_bw);
876 		return -ENOLINK;
877 	}
878 
879 	tegra_sor_writel(sor, LANE_DRIVE_CURRENT(sor->portnum), drive_current);
880 	tegra_sor_writel(sor, PR(sor->portnum), pre_emphasis);
881 
882 	return 0;
883 }
884 
tegra_dc_sor_power_down_unused_lanes(struct udevice * dev,const struct tegra_dp_link_config * link_cfg)885 void tegra_dc_sor_power_down_unused_lanes(struct udevice *dev,
886 			const struct tegra_dp_link_config *link_cfg)
887 {
888 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
889 	u32 pad_ctrl = 0;
890 	int err = 0;
891 
892 	switch (link_cfg->lane_count) {
893 	case 4:
894 		pad_ctrl = DP_PADCTL_PD_TXD_0_NO |
895 			DP_PADCTL_PD_TXD_1_NO |
896 			DP_PADCTL_PD_TXD_2_NO |
897 			DP_PADCTL_PD_TXD_3_NO;
898 		break;
899 	case 2:
900 		pad_ctrl = DP_PADCTL_PD_TXD_0_NO |
901 			DP_PADCTL_PD_TXD_1_NO |
902 			DP_PADCTL_PD_TXD_2_YES |
903 			DP_PADCTL_PD_TXD_3_YES;
904 		break;
905 	case 1:
906 		pad_ctrl = DP_PADCTL_PD_TXD_0_NO |
907 			DP_PADCTL_PD_TXD_1_YES |
908 			DP_PADCTL_PD_TXD_2_YES |
909 			DP_PADCTL_PD_TXD_3_YES;
910 		break;
911 	default:
912 		printf("Invalid sor lane count: %u\n", link_cfg->lane_count);
913 		return;
914 	}
915 
916 	pad_ctrl |= DP_PADCTL_PAD_CAL_PD_POWERDOWN;
917 	tegra_sor_writel(sor, DP_PADCTL(sor->portnum), pad_ctrl);
918 
919 	err = tegra_dc_sor_enable_lane_sequencer(sor, 0, 0);
920 	if (err) {
921 		debug("Wait for lane power down failed: %d\n", err);
922 		return;
923 	}
924 }
925 
tegra_sor_precharge_lanes(struct udevice * dev,const struct tegra_dp_link_config * cfg)926 int tegra_sor_precharge_lanes(struct udevice *dev,
927 			      const struct tegra_dp_link_config *cfg)
928 {
929 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
930 	u32 val = 0;
931 
932 	switch (cfg->lane_count) {
933 	case 4:
934 		val |= (DP_PADCTL_PD_TXD_3_NO |
935 			DP_PADCTL_PD_TXD_2_NO);
936 		/* fall through */
937 	case 2:
938 		val |= DP_PADCTL_PD_TXD_1_NO;
939 		/* fall through */
940 	case 1:
941 		val |= DP_PADCTL_PD_TXD_0_NO;
942 		break;
943 	default:
944 		debug("dp: invalid lane number %d\n", cfg->lane_count);
945 		return -EINVAL;
946 	}
947 
948 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
949 			      (0xf << DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT),
950 			      (val << DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT));
951 	udelay(100);
952 	tegra_sor_write_field(sor, DP_PADCTL(sor->portnum),
953 			      (0xf << DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT),
954 			      0);
955 
956 	return 0;
957 }
958 
tegra_dc_sor_enable_sor(struct dc_ctlr * disp_ctrl,bool enable)959 static void tegra_dc_sor_enable_sor(struct dc_ctlr *disp_ctrl, bool enable)
960 {
961 	u32 reg_val = readl(&disp_ctrl->disp.disp_win_opt);
962 
963 	reg_val = enable ? reg_val | SOR_ENABLE : reg_val & ~SOR_ENABLE;
964 	writel(reg_val, &disp_ctrl->disp.disp_win_opt);
965 }
966 
tegra_dc_sor_detach(struct udevice * dc_dev,struct udevice * dev)967 int tegra_dc_sor_detach(struct udevice *dc_dev, struct udevice *dev)
968 {
969 	struct tegra_dc_sor_data *sor = dev_get_priv(dev);
970 	int dc_reg_ctx[DC_REG_SAVE_SPACE];
971 	struct dc_ctlr *disp_ctrl;
972 	unsigned long dc_int_mask;
973 	int ret;
974 
975 	debug("%s\n", __func__);
976 	/* Use the first display controller */
977 	disp_ctrl = (struct dc_ctlr *)dev_read_addr(dev);
978 
979 	/* Sleep mode */
980 	tegra_sor_writel(sor, SUPER_STATE1, SUPER_STATE1_ASY_HEAD_OP_SLEEP |
981 			 SUPER_STATE1_ASY_ORMODE_SAFE |
982 			 SUPER_STATE1_ATTACHED_YES);
983 	tegra_dc_sor_super_update(sor);
984 
985 	tegra_dc_sor_disable_win_short_raster(disp_ctrl, dc_reg_ctx);
986 
987 	if (tegra_dc_sor_poll_register(sor, TEST,
988 				       TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
989 				       TEST_ACT_HEAD_OPMODE_SLEEP, 100,
990 				       TEGRA_SOR_ATTACH_TIMEOUT_MS)) {
991 		debug("dc timeout waiting for OPMOD = SLEEP\n");
992 		ret = -ETIMEDOUT;
993 		goto err;
994 	}
995 
996 	tegra_sor_writel(sor, SUPER_STATE1, SUPER_STATE1_ASY_HEAD_OP_SLEEP |
997 			 SUPER_STATE1_ASY_ORMODE_SAFE |
998 			 SUPER_STATE1_ATTACHED_NO);
999 
1000 	/* Mask DC interrupts during the 2 dummy frames required for detach */
1001 	dc_int_mask = readl(&disp_ctrl->cmd.int_mask);
1002 	writel(0, &disp_ctrl->cmd.int_mask);
1003 
1004 	/* Stop DC->SOR path */
1005 	tegra_dc_sor_enable_sor(disp_ctrl, false);
1006 	ret = tegra_dc_sor_general_act(disp_ctrl);
1007 	if (ret)
1008 		goto err;
1009 
1010 	/* Stop DC */
1011 	writel(CTRL_MODE_STOP << CTRL_MODE_SHIFT, &disp_ctrl->cmd.disp_cmd);
1012 	ret = tegra_dc_sor_general_act(disp_ctrl);
1013 	if (ret)
1014 		goto err;
1015 
1016 	tegra_dc_sor_restore_win_and_raster(disp_ctrl, dc_reg_ctx);
1017 
1018 	writel(dc_int_mask, &disp_ctrl->cmd.int_mask);
1019 
1020 	return 0;
1021 err:
1022 	debug("%s: ret=%d\n", __func__, ret);
1023 
1024 	return ret;
1025 }
1026 
tegra_sor_set_backlight(struct udevice * dev,int percent)1027 static int tegra_sor_set_backlight(struct udevice *dev, int percent)
1028 {
1029 	struct tegra_dc_sor_data *priv = dev_get_priv(dev);
1030 	int ret;
1031 
1032 	ret = panel_enable_backlight(priv->panel);
1033 	if (ret) {
1034 		debug("sor: Cannot enable panel backlight\n");
1035 		return ret;
1036 	}
1037 
1038 	return 0;
1039 }
1040 
tegra_sor_ofdata_to_platdata(struct udevice * dev)1041 static int tegra_sor_ofdata_to_platdata(struct udevice *dev)
1042 {
1043 	struct tegra_dc_sor_data *priv = dev_get_priv(dev);
1044 	int ret;
1045 
1046 	priv->base = (void *)dev_read_addr(dev);
1047 
1048 	priv->pmc_base = (void *)syscon_get_first_range(TEGRA_SYSCON_PMC);
1049 	if (IS_ERR(priv->pmc_base))
1050 		return PTR_ERR(priv->pmc_base);
1051 
1052 	ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "nvidia,panel",
1053 					   &priv->panel);
1054 	if (ret) {
1055 		debug("%s: Cannot find panel for '%s' (ret=%d)\n", __func__,
1056 		      dev->name, ret);
1057 		return ret;
1058 	}
1059 
1060 	return 0;
1061 }
1062 
1063 static const struct video_bridge_ops tegra_sor_ops = {
1064 	.set_backlight	= tegra_sor_set_backlight,
1065 };
1066 
1067 static const struct udevice_id tegra_sor_ids[] = {
1068 	{ .compatible = "nvidia,tegra124-sor" },
1069 	{ }
1070 };
1071 
1072 U_BOOT_DRIVER(sor_tegra) = {
1073 	.name	= "sor_tegra",
1074 	.id	= UCLASS_VIDEO_BRIDGE,
1075 	.of_match = tegra_sor_ids,
1076 	.ofdata_to_platdata = tegra_sor_ofdata_to_platdata,
1077 	.ops	= &tegra_sor_ops,
1078 	.priv_auto_alloc_size = sizeof(struct tegra_dc_sor_data),
1079 };
1080