2 * This file is part of the coreboot project.
4 * drivers/video/tegra/dc/sor.c
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
18 #include <console/console.h>
21 #include <soc/addressmap.h>
22 #include <device/device.h>
23 #include <boot/tables.h>
24 #include <soc/nvidia/tegra/dc.h>
25 #include <soc/nvidia/tegra/types.h>
27 #include <soc/nvidia/tegra/displayport.h>
28 #include <soc/clk_rst.h>
29 #include <soc/clock.h>
31 #include <soc/display.h>
35 #define APBDEV_PMC_DPD_SAMPLE (0x20)
36 #define APBDEV_PMC_DPD_SAMPLE_ON_DISABLE (0)
37 #define APBDEV_PMC_DPD_SAMPLE_ON_ENABLE (1)
38 #define APBDEV_PMC_SEL_DPD_TIM (0x1c8)
39 #define APBDEV_PMC_SEL_DPD_TIM_SEL_DPD_TIM_DEFAULT (0x7f)
40 #define APBDEV_PMC_IO_DPD2_REQ (0x1c0)
41 #define APBDEV_PMC_IO_DPD2_REQ_LVDS_SHIFT (25)
42 #define APBDEV_PMC_IO_DPD2_REQ_LVDS_OFF (0 << 25)
43 #define APBDEV_PMC_IO_DPD2_REQ_LVDS_ON (1 << 25)
44 #define APBDEV_PMC_IO_DPD2_REQ_CODE_SHIFT (30)
45 #define APBDEV_PMC_IO_DPD2_REQ_CODE_DEFAULT_MASK (0x3 << 30)
46 #define APBDEV_PMC_IO_DPD2_REQ_CODE_IDLE (0 << 30)
47 #define APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_OFF (1 << 30)
48 #define APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_ON (2 << 30)
49 #define APBDEV_PMC_IO_DPD2_STATUS (0x1c4)
50 #define APBDEV_PMC_IO_DPD2_STATUS_LVDS_SHIFT (25)
51 #define APBDEV_PMC_IO_DPD2_STATUS_LVDS_OFF (0 << 25)
52 #define APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON (1 << 25)
54 #define DC_N_WINDOWS 5
56 static inline u32
tegra_sor_readl(struct tegra_dc_sor_data
*sor
, u32 reg
)
58 void *addr
= sor
->base
+ (u32
) (reg
<< 2);
59 u32 reg_val
= READL(addr
);
63 static inline void tegra_sor_writel(struct tegra_dc_sor_data
*sor
,
66 void *addr
= sor
->base
+ (u32
) (reg
<< 2);
70 static inline void tegra_sor_write_field(struct tegra_dc_sor_data
*sor
,
71 u32 reg
, u32 mask
, u32 val
)
73 u32 reg_val
= tegra_sor_readl(sor
, reg
);
76 tegra_sor_writel(sor
, reg
, reg_val
);
79 void tegra_dp_disable_tx_pu(struct tegra_dc_sor_data
*sor
)
81 tegra_sor_write_field(sor
,
82 NV_SOR_DP_PADCTL(sor
->portnum
),
83 NV_SOR_DP_PADCTL_TX_PU_MASK
,
84 NV_SOR_DP_PADCTL_TX_PU_DISABLE
);
87 void tegra_dp_set_pe_vs_pc(struct tegra_dc_sor_data
*sor
, u32 mask
,
88 u32 pe_reg
, u32 vs_reg
, u32 pc_reg
, u8 pc_supported
)
90 tegra_sor_write_field(sor
, NV_SOR_PR(sor
->portnum
),
92 tegra_sor_write_field(sor
, NV_SOR_DC(sor
->portnum
),
95 tegra_sor_write_field(
96 sor
, NV_SOR_POSTCURSOR(sor
->portnum
),
101 static u32
tegra_dc_sor_poll_register(struct tegra_dc_sor_data
*sor
,
102 u32 reg
, u32 mask
, u32 exp_val
, u32 poll_interval_us
, u32 timeout_us
)
104 u32 temp
= timeout_us
;
108 udelay(poll_interval_us
);
109 reg_val
= tegra_sor_readl(sor
, reg
);
110 if (timeout_us
> poll_interval_us
)
111 timeout_us
-= poll_interval_us
;
114 } while ((reg_val
& mask
) != exp_val
);
116 if ((reg_val
& mask
) == exp_val
)
117 return 0; /* success */
119 "sor_poll_register 0x%x: timeout, "
120 "(reg_val)0x%08x & (mask)0x%08x != (exp_val)0x%08x\n",
121 reg
, reg_val
, mask
, exp_val
);
126 int tegra_dc_sor_set_power_state(struct tegra_dc_sor_data
*sor
, int pu_pd
)
131 orig_val
= tegra_sor_readl(sor
, NV_SOR_PWR
);
133 reg_val
= pu_pd
? NV_SOR_PWR_NORMAL_STATE_PU
:
134 NV_SOR_PWR_NORMAL_STATE_PD
; /* normal state only */
136 if (reg_val
== orig_val
)
137 return 0; /* No update needed */
139 reg_val
|= NV_SOR_PWR_SETTING_NEW_TRIGGER
;
140 tegra_sor_writel(sor
, NV_SOR_PWR
, reg_val
);
142 /* Poll to confirm it is done */
143 if (tegra_dc_sor_poll_register(sor
, NV_SOR_PWR
,
144 NV_SOR_PWR_SETTING_NEW_DEFAULT_MASK
,
145 NV_SOR_PWR_SETTING_NEW_DONE
,
146 100, TEGRA_SOR_TIMEOUT_MS
* 1000)) {
148 "dc timeout waiting for SOR_PWR = NEW_DONE\n");
154 void tegra_dc_sor_set_dp_linkctl(struct tegra_dc_sor_data
*sor
, int ena
,
155 u8 training_pattern
, const struct tegra_dc_dp_link_config
*link_cfg
)
159 reg_val
= tegra_sor_readl(sor
, NV_SOR_DP_LINKCTL(sor
->portnum
));
162 reg_val
|= NV_SOR_DP_LINKCTL_ENABLE_YES
;
164 reg_val
&= NV_SOR_DP_LINKCTL_ENABLE_NO
;
166 reg_val
&= ~NV_SOR_DP_LINKCTL_TUSIZE_MASK
;
167 reg_val
|= (link_cfg
->tu_size
<< NV_SOR_DP_LINKCTL_TUSIZE_SHIFT
);
169 if (link_cfg
->enhanced_framing
)
170 reg_val
|= NV_SOR_DP_LINKCTL_ENHANCEDFRAME_ENABLE
;
172 tegra_sor_writel(sor
, NV_SOR_DP_LINKCTL(sor
->portnum
), reg_val
);
174 switch (training_pattern
) {
175 case training_pattern_1
:
176 tegra_sor_writel(sor
, NV_SOR_DP_TPG
, 0x41414141);
178 case training_pattern_2
:
179 case training_pattern_3
:
180 reg_val
= (link_cfg
->link_bw
== SOR_LINK_SPEED_G5_4
) ?
181 0x43434343 : 0x42424242;
182 tegra_sor_writel(sor
, NV_SOR_DP_TPG
, reg_val
);
185 tegra_sor_writel(sor
, NV_SOR_DP_TPG
, 0x50505050);
190 static int tegra_dc_sor_enable_lane_sequencer(struct tegra_dc_sor_data
*sor
,
195 /* SOR lane sequencer */
197 reg_val
= NV_SOR_LANE_SEQ_CTL_SETTING_NEW_TRIGGER
|
198 NV_SOR_LANE_SEQ_CTL_SEQUENCE_DOWN
|
199 NV_SOR_LANE_SEQ_CTL_NEW_POWER_STATE_PU
;
201 reg_val
= NV_SOR_LANE_SEQ_CTL_SETTING_NEW_TRIGGER
|
202 NV_SOR_LANE_SEQ_CTL_SEQUENCE_UP
|
203 NV_SOR_LANE_SEQ_CTL_NEW_POWER_STATE_PD
;
206 reg_val
|= 15 << NV_SOR_LANE_SEQ_CTL_DELAY_SHIFT
;
208 reg_val
|= 1 << NV_SOR_LANE_SEQ_CTL_DELAY_SHIFT
;
210 tegra_sor_writel(sor
, NV_SOR_LANE_SEQ_CTL
, reg_val
);
212 if (tegra_dc_sor_poll_register(sor
, NV_SOR_LANE_SEQ_CTL
,
213 NV_SOR_LANE_SEQ_CTL_SETTING_MASK
,
214 NV_SOR_LANE_SEQ_CTL_SETTING_NEW_DONE
,
215 100, TEGRA_SOR_TIMEOUT_MS
*1000)) {
217 "dp: timeout while waiting for SOR lane sequencer "
218 "to power down langes\n");
224 static int tegra_dc_sor_power_dplanes(struct tegra_dc_sor_data
*sor
,
225 u32 lane_count
, int pu
)
229 reg_val
= tegra_sor_readl(sor
, NV_SOR_DP_PADCTL(sor
->portnum
));
232 switch (lane_count
) {
234 reg_val
|= (NV_SOR_DP_PADCTL_PD_TXD_3_NO
|
235 NV_SOR_DP_PADCTL_PD_TXD_2_NO
);
238 reg_val
|= NV_SOR_DP_PADCTL_PD_TXD_1_NO
;
240 reg_val
|= NV_SOR_DP_PADCTL_PD_TXD_0_NO
;
244 "dp: invalid lane number %d\n", lane_count
);
248 tegra_sor_writel(sor
, NV_SOR_DP_PADCTL(sor
->portnum
), reg_val
);
249 tegra_dc_sor_set_lane_count(sor
, lane_count
);
251 return tegra_dc_sor_enable_lane_sequencer(sor
, pu
, 0);
254 void tegra_dc_sor_set_panel_power(struct tegra_dc_sor_data
*sor
,
259 reg_val
= tegra_sor_readl(sor
, NV_SOR_DP_PADCTL(sor
->portnum
));
262 reg_val
&= ~NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN
;
264 reg_val
|= NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN
;
266 tegra_sor_writel(sor
, NV_SOR_DP_PADCTL(sor
->portnum
), reg_val
);
269 static void tegra_dc_sor_config_pwm(struct tegra_dc_sor_data
*sor
, u32 pwm_div
,
272 tegra_sor_writel(sor
, NV_SOR_PWM_DIV
, pwm_div
);
273 tegra_sor_writel(sor
, NV_SOR_PWM_CTL
,
274 (pwm_dutycycle
& NV_SOR_PWM_CTL_DUTY_CYCLE_MASK
) |
275 NV_SOR_PWM_CTL_SETTING_NEW_TRIGGER
);
277 if (tegra_dc_sor_poll_register(sor
, NV_SOR_PWM_CTL
,
278 NV_SOR_PWM_CTL_SETTING_NEW_SHIFT
,
279 NV_SOR_PWM_CTL_SETTING_NEW_DONE
,
280 100, TEGRA_SOR_TIMEOUT_MS
* 1000)) {
282 "dp: timeout while waiting for SOR PWM setting\n");
286 static void tegra_dc_sor_set_dp_mode(struct tegra_dc_sor_data
*sor
,
287 const struct tegra_dc_dp_link_config
*link_cfg
)
291 tegra_dc_sor_set_link_bandwidth(sor
, link_cfg
->link_bw
);
293 tegra_dc_sor_set_dp_linkctl(sor
, 1, training_pattern_none
, link_cfg
);
294 reg_val
= tegra_sor_readl(sor
, NV_SOR_DP_CONFIG(sor
->portnum
));
295 reg_val
&= ~NV_SOR_DP_CONFIG_WATERMARK_MASK
;
296 reg_val
|= link_cfg
->watermark
;
297 reg_val
&= ~NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_MASK
;
298 reg_val
|= (link_cfg
->active_count
<<
299 NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_SHIFT
);
300 reg_val
&= ~NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_MASK
;
301 reg_val
|= (link_cfg
->active_frac
<<
302 NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_SHIFT
);
303 if (link_cfg
->activepolarity
)
304 reg_val
|= NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE
;
306 reg_val
&= ~NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE
;
307 reg_val
|= (NV_SOR_DP_CONFIG_ACTIVESYM_CNTL_ENABLE
|
308 NV_SOR_DP_CONFIG_RD_RESET_VAL_NEGATIVE
);
310 tegra_sor_writel(sor
, NV_SOR_DP_CONFIG(sor
->portnum
), reg_val
);
312 /* program h/vblank sym */
313 tegra_sor_write_field(sor
, NV_SOR_DP_AUDIO_HBLANK_SYMBOLS
,
314 NV_SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK
, link_cfg
->hblank_sym
);
316 tegra_sor_write_field(sor
, NV_SOR_DP_AUDIO_VBLANK_SYMBOLS
,
317 NV_SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK
, link_cfg
->vblank_sym
);
320 static inline void tegra_dc_sor_super_update(struct tegra_dc_sor_data
*sor
)
322 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE0
, 0);
323 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE0
, 1);
324 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE0
, 0);
327 static inline void tegra_dc_sor_update(struct tegra_dc_sor_data
*sor
)
329 tegra_sor_writel(sor
, NV_SOR_STATE0
, 0);
330 tegra_sor_writel(sor
, NV_SOR_STATE0
, 1);
331 tegra_sor_writel(sor
, NV_SOR_STATE0
, 0);
334 static void tegra_dc_sor_io_set_dpd(struct tegra_dc_sor_data
*sor
, int up
)
337 void *pmc_base
= sor
->pmc_base
;
340 WRITEL(APBDEV_PMC_DPD_SAMPLE_ON_ENABLE
,
341 pmc_base
+ APBDEV_PMC_DPD_SAMPLE
);
342 WRITEL(10, pmc_base
+ APBDEV_PMC_SEL_DPD_TIM
);
345 reg_val
= READL(pmc_base
+ APBDEV_PMC_IO_DPD2_REQ
);
346 reg_val
&= ~(APBDEV_PMC_IO_DPD2_REQ_LVDS_ON
||
347 APBDEV_PMC_IO_DPD2_REQ_CODE_DEFAULT_MASK
);
349 reg_val
= up
? APBDEV_PMC_IO_DPD2_REQ_LVDS_ON
|
350 APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_OFF
:
351 APBDEV_PMC_IO_DPD2_REQ_LVDS_OFF
|
352 APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_ON
;
354 WRITEL(reg_val
, pmc_base
+ APBDEV_PMC_IO_DPD2_REQ
);
360 reg_val
= READL(pmc_base
+ APBDEV_PMC_IO_DPD2_STATUS
);
365 } while ((reg_val
& APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON
) != 0);
367 if ((reg_val
& APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON
) != 0)
369 "PMC_IO_DPD2 polling failed (0x%x)\n", reg_val
);
372 WRITEL(APBDEV_PMC_DPD_SAMPLE_ON_DISABLE
,
373 pmc_base
+ APBDEV_PMC_DPD_SAMPLE
);
376 void tegra_dc_sor_set_internal_panel(struct tegra_dc_sor_data
*sor
, int is_int
)
380 reg_val
= tegra_sor_readl(sor
, NV_SOR_DP_SPARE(sor
->portnum
));
382 reg_val
|= NV_SOR_DP_SPARE_PANEL_INTERNAL
;
384 reg_val
&= ~NV_SOR_DP_SPARE_PANEL_INTERNAL
;
386 reg_val
|= NV_SOR_DP_SPARE_SOR_CLK_SEL_MACRO_SORCLK
|
387 NV_SOR_DP_SPARE_SEQ_ENABLE_YES
;
388 tegra_sor_writel(sor
, NV_SOR_DP_SPARE(sor
->portnum
), reg_val
);
391 void tegra_dc_sor_read_link_config(struct tegra_dc_sor_data
*sor
, u8
*link_bw
,
396 reg_val
= tegra_sor_readl(sor
, NV_SOR_CLK_CNTRL
);
397 *link_bw
= (reg_val
& NV_SOR_CLK_CNTRL_DP_LINK_SPEED_MASK
)
398 >> NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT
;
399 reg_val
= tegra_sor_readl(sor
,
400 NV_SOR_DP_LINKCTL(sor
->portnum
));
402 switch (reg_val
& NV_SOR_DP_LINKCTL_LANECOUNT_MASK
) {
403 case NV_SOR_DP_LINKCTL_LANECOUNT_ZERO
:
406 case NV_SOR_DP_LINKCTL_LANECOUNT_ONE
:
409 case NV_SOR_DP_LINKCTL_LANECOUNT_TWO
:
412 case NV_SOR_DP_LINKCTL_LANECOUNT_FOUR
:
416 printk(BIOS_ERR
, "Unknown lane count\n");
420 void tegra_dc_sor_set_link_bandwidth(struct tegra_dc_sor_data
*sor
, u8 link_bw
)
422 tegra_sor_write_field(sor
, NV_SOR_CLK_CNTRL
,
423 NV_SOR_CLK_CNTRL_DP_LINK_SPEED_MASK
,
424 link_bw
<< NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT
);
427 void tegra_dc_sor_set_lane_count(struct tegra_dc_sor_data
*sor
, u8 lane_count
)
431 reg_val
= tegra_sor_readl(sor
, NV_SOR_DP_LINKCTL(sor
->portnum
));
432 reg_val
&= ~NV_SOR_DP_LINKCTL_LANECOUNT_MASK
;
433 switch (lane_count
) {
437 reg_val
|= NV_SOR_DP_LINKCTL_LANECOUNT_ONE
;
440 reg_val
|= NV_SOR_DP_LINKCTL_LANECOUNT_TWO
;
443 reg_val
|= NV_SOR_DP_LINKCTL_LANECOUNT_FOUR
;
446 /* 0 should be handled earlier. */
447 printk(BIOS_ERR
, "dp: Invalid lane count %d\n",
451 tegra_sor_writel(sor
, NV_SOR_DP_LINKCTL(sor
->portnum
), reg_val
);
454 static void tegra_sor_enable_edp_clock(struct tegra_dc_sor_data
*sor
)
459 /* The SOR power sequencer does not work for t1xx so SW has to
460 go through the power sequence manually */
461 /* Power up steps from spec: */
462 /* STEP PDPORT PDPLL PDBG PLLVCOD PLLCAPD E_DPD PDCAL */
463 /* 1 1 1 1 1 1 1 1 */
464 /* 2 1 1 1 1 1 0 1 */
465 /* 3 1 1 0 1 1 0 1 */
466 /* 4 1 0 0 0 0 0 1 */
467 /* 5 0 0 0 0 0 0 1 */
468 static void tegra_dc_sor_power_up(struct tegra_dc_sor_data
*sor
,
471 if (sor
->power_is_up
)
475 tegra_dc_sor_set_link_bandwidth(sor
,
476 is_lvds
? NV_SOR_CLK_CNTRL_DP_LINK_SPEED_LVDS
:
477 NV_SOR_CLK_CNTRL_DP_LINK_SPEED_G1_62
);
480 tegra_sor_write_field(sor
, NV_SOR_PLL2
,
481 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK
| /* PDPORT */
482 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK
| /* PDBG */
483 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK
, /* PLLCAPD */
484 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_ENABLE
|
485 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_ENABLE
|
486 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_ENABLE
);
487 tegra_sor_write_field(sor
, NV_SOR_PLL0
,
488 NV_SOR_PLL0_PWR_MASK
| /* PDPLL */
489 NV_SOR_PLL0_VCOPD_MASK
, /* PLLVCOPD */
490 NV_SOR_PLL0_PWR_OFF
|
491 NV_SOR_PLL0_VCOPD_ASSERT
);
492 tegra_sor_write_field(sor
, NV_SOR_DP_PADCTL(sor
->portnum
),
493 NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN
, /* PDCAL */
494 NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERUP
);
497 tegra_dc_sor_io_set_dpd(sor
, 1);
501 tegra_sor_write_field(sor
, NV_SOR_PLL2
,
502 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK
,
503 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE
);
507 tegra_sor_write_field(sor
, NV_SOR_PLL0
,
508 NV_SOR_PLL0_PWR_MASK
| /* PDPLL */
509 NV_SOR_PLL0_VCOPD_MASK
, /* PLLVCOPD */
510 NV_SOR_PLL0_PWR_ON
| NV_SOR_PLL0_VCOPD_RESCIND
);
511 tegra_sor_write_field(sor
, NV_SOR_PLL2
,
512 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK
, /* PLLCAPD */
513 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE
);
517 tegra_sor_write_field(sor
, NV_SOR_PLL2
,
518 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK
, /* PDPORT */
519 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_DISABLE
);
521 sor
->power_is_up
= 1;
525 static void dump_sor_reg(struct tegra_dc_sor_data
*sor
)
527 #define DUMP_REG(a) printk(BIOS_INFO, "%-32s %03x %08x\n", \
528 #a, a, tegra_sor_readl(sor, a));
530 DUMP_REG(NV_SOR_SUPER_STATE0
);
531 DUMP_REG(NV_SOR_SUPER_STATE1
);
532 DUMP_REG(NV_SOR_STATE0
);
533 DUMP_REG(NV_SOR_STATE1
);
534 DUMP_REG(NV_HEAD_STATE0(0));
535 DUMP_REG(NV_HEAD_STATE0(1));
536 DUMP_REG(NV_HEAD_STATE1(0));
537 DUMP_REG(NV_HEAD_STATE1(1));
538 DUMP_REG(NV_HEAD_STATE2(0));
539 DUMP_REG(NV_HEAD_STATE2(1));
540 DUMP_REG(NV_HEAD_STATE3(0));
541 DUMP_REG(NV_HEAD_STATE3(1));
542 DUMP_REG(NV_HEAD_STATE4(0));
543 DUMP_REG(NV_HEAD_STATE4(1));
544 DUMP_REG(NV_HEAD_STATE5(0));
545 DUMP_REG(NV_HEAD_STATE5(1));
546 DUMP_REG(NV_SOR_CRC_CNTRL
);
547 DUMP_REG(NV_SOR_CLK_CNTRL
);
548 DUMP_REG(NV_SOR_CAP
);
549 DUMP_REG(NV_SOR_PWR
);
550 DUMP_REG(NV_SOR_TEST
);
551 DUMP_REG(NV_SOR_PLL0
);
552 DUMP_REG(NV_SOR_PLL1
);
553 DUMP_REG(NV_SOR_PLL2
);
554 DUMP_REG(NV_SOR_PLL3
);
555 DUMP_REG(NV_SOR_CSTM
);
556 DUMP_REG(NV_SOR_LVDS
);
557 DUMP_REG(NV_SOR_CRCA
);
558 DUMP_REG(NV_SOR_CRCB
);
559 DUMP_REG(NV_SOR_SEQ_CTL
);
560 DUMP_REG(NV_SOR_LANE_SEQ_CTL
);
561 DUMP_REG(NV_SOR_SEQ_INST(0));
562 DUMP_REG(NV_SOR_SEQ_INST(1));
563 DUMP_REG(NV_SOR_SEQ_INST(2));
564 DUMP_REG(NV_SOR_SEQ_INST(3));
565 DUMP_REG(NV_SOR_SEQ_INST(4));
566 DUMP_REG(NV_SOR_SEQ_INST(5));
567 DUMP_REG(NV_SOR_SEQ_INST(6));
568 DUMP_REG(NV_SOR_SEQ_INST(7));
569 DUMP_REG(NV_SOR_SEQ_INST(8));
570 DUMP_REG(NV_SOR_PWM_DIV
);
571 DUMP_REG(NV_SOR_PWM_CTL
);
572 DUMP_REG(NV_SOR_MSCHECK
);
573 DUMP_REG(NV_SOR_XBAR_CTRL
);
574 DUMP_REG(NV_SOR_DP_LINKCTL(0));
575 DUMP_REG(NV_SOR_DP_LINKCTL(1));
576 DUMP_REG(NV_SOR_DC(0));
577 DUMP_REG(NV_SOR_DC(1));
578 DUMP_REG(NV_SOR_LANE_DRIVE_CURRENT(0));
579 DUMP_REG(NV_SOR_PR(0));
580 DUMP_REG(NV_SOR_LANE4_PREEMPHASIS(0));
581 DUMP_REG(NV_SOR_POSTCURSOR(0));
582 DUMP_REG(NV_SOR_DP_CONFIG(0));
583 DUMP_REG(NV_SOR_DP_CONFIG(1));
584 DUMP_REG(NV_SOR_DP_MN(0));
585 DUMP_REG(NV_SOR_DP_MN(1));
586 DUMP_REG(NV_SOR_DP_PADCTL(0));
587 DUMP_REG(NV_SOR_DP_PADCTL(1));
588 DUMP_REG(NV_SOR_DP_DEBUG(0));
589 DUMP_REG(NV_SOR_DP_DEBUG(1));
590 DUMP_REG(NV_SOR_DP_SPARE(0));
591 DUMP_REG(NV_SOR_DP_SPARE(1));
592 DUMP_REG(NV_SOR_DP_TPG
);
598 static void tegra_dc_sor_config_panel(struct tegra_dc_sor_data
*sor
,
601 const struct tegra_dc
*dc
= sor
->dc
;
602 const struct tegra_dc_dp_data
*dp
= dc
->out
;
603 const struct tegra_dc_dp_link_config
*link_cfg
= &dp
->link_cfg
;
604 const struct soc_nvidia_tegra210_config
*config
= dc
->config
;
606 const int head_num
= 0;
607 u32 reg_val
= NV_SOR_STATE1_ASY_OWNER_HEAD0
<< head_num
;
608 u32 vsync_end
, hsync_end
;
609 u32 vblank_end
, hblank_end
;
610 u32 vblank_start
, hblank_start
;
612 reg_val
|= is_lvds
? NV_SOR_STATE1_ASY_PROTOCOL_LVDS_CUSTOM
:
613 NV_SOR_STATE1_ASY_PROTOCOL_DP_A
;
614 reg_val
|= NV_SOR_STATE1_ASY_SUBOWNER_NONE
|
615 NV_SOR_STATE1_ASY_CRCMODE_COMPLETE_RASTER
;
617 reg_val
|= NV_SOR_STATE1_ASY_HSYNCPOL_NEGATIVE_TRUE
;
618 reg_val
|= NV_SOR_STATE1_ASY_VSYNCPOL_NEGATIVE_TRUE
;
619 reg_val
|= (link_cfg
->bits_per_pixel
> 18) ?
620 NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_24_444
:
621 NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_18_444
;
623 tegra_sor_writel(sor
, NV_SOR_STATE1
, reg_val
);
625 /* Skipping programming NV_HEAD_STATE0, assuming:
626 interlacing: PROGRESSIVE, dynamic range: VESA, colorspace: RGB */
628 tegra_sor_writel(sor
, NV_HEAD_STATE1(head_num
),
629 vtotal(config
) << NV_HEAD_STATE1_VTOTAL_SHIFT
|
630 htotal(config
) << NV_HEAD_STATE1_HTOTAL_SHIFT
);
632 vsync_end
= config
->vsync_width
- 1;
633 hsync_end
= config
->hsync_width
- 1;
634 tegra_sor_writel(sor
, NV_HEAD_STATE2(head_num
),
635 vsync_end
<< NV_HEAD_STATE2_VSYNC_END_SHIFT
|
636 hsync_end
<< NV_HEAD_STATE2_HSYNC_END_SHIFT
);
638 vblank_end
= vsync_end
+ config
->vback_porch
;
639 hblank_end
= hsync_end
+ config
->hback_porch
;
640 tegra_sor_writel(sor
, NV_HEAD_STATE3(head_num
),
641 vblank_end
<< NV_HEAD_STATE3_VBLANK_END_SHIFT
|
642 hblank_end
<< NV_HEAD_STATE3_HBLANK_END_SHIFT
);
644 vblank_start
= vblank_end
+ config
->yres
;
645 hblank_start
= hblank_end
+ config
->xres
;
646 tegra_sor_writel(sor
, NV_HEAD_STATE4(head_num
),
647 vblank_start
<< NV_HEAD_STATE4_VBLANK_START_SHIFT
|
648 hblank_start
<< NV_HEAD_STATE4_HBLANK_START_SHIFT
);
650 /* TODO: adding interlace mode support */
651 tegra_sor_writel(sor
, NV_HEAD_STATE5(head_num
), 0x1);
653 tegra_sor_write_field(sor
, NV_SOR_CSTM
,
654 NV_SOR_CSTM_ROTCLK_DEFAULT_MASK
|
655 NV_SOR_CSTM_LVDS_EN_ENABLE
,
656 2 << NV_SOR_CSTM_ROTCLK_SHIFT
|
657 is_lvds
? NV_SOR_CSTM_LVDS_EN_ENABLE
:
658 NV_SOR_CSTM_LVDS_EN_DISABLE
);
660 tegra_dc_sor_config_pwm(sor
, 1024, 1024);
663 static void tegra_dc_sor_enable_dc(struct tegra_dc_sor_data
*sor
)
665 struct tegra_dc
*dc
= sor
->dc
;
666 struct display_controller
*disp_ctrl
= (void *)dc
->base
;
668 u32 reg_val
= READL(&disp_ctrl
->cmd
.state_access
);
670 WRITEL(reg_val
| WRITE_MUX_ACTIVE
, &disp_ctrl
->cmd
.state_access
);
671 WRITEL(VSYNC_H_POSITION(1), &disp_ctrl
->disp
.disp_timing_opt
);
673 /* Enable DC now - otherwise pure text console may not show. */
674 WRITEL(DISP_CTRL_MODE_C_DISPLAY
, &disp_ctrl
->cmd
.disp_cmd
);
675 WRITEL(reg_val
, &disp_ctrl
->cmd
.state_access
);
678 void tegra_dc_sor_enable_dp(struct tegra_dc_sor_data
*sor
)
680 const struct tegra_dc_dp_link_config
*link_cfg
= sor
->link_cfg
;
682 tegra_sor_write_field(sor
, NV_SOR_CLK_CNTRL
,
683 NV_SOR_CLK_CNTRL_DP_CLK_SEL_MASK
,
684 NV_SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK
);
686 tegra_sor_write_field(sor
, NV_SOR_PLL2
,
687 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK
,
688 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE
);
691 tegra_sor_write_field(sor
, NV_SOR_PLL3
,
692 NV_SOR_PLL3_PLLVDD_MODE_MASK
,
693 NV_SOR_PLL3_PLLVDD_MODE_V3_3
);
694 tegra_sor_writel(sor
, NV_SOR_PLL0
,
695 0xf << NV_SOR_PLL0_ICHPMP_SHFIT
|
696 0x3 << NV_SOR_PLL0_VCOCAP_SHIFT
|
697 NV_SOR_PLL0_PLLREG_LEVEL_V45
|
698 NV_SOR_PLL0_RESISTORSEL_EXT
|
699 NV_SOR_PLL0_PWR_ON
| NV_SOR_PLL0_VCOPD_RESCIND
);
700 tegra_sor_write_field(sor
, NV_SOR_PLL2
,
701 NV_SOR_PLL2_AUX1_SEQ_MASK
| NV_SOR_PLL2_AUX9_LVDSEN_OVERRIDE
|
702 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK
,
703 NV_SOR_PLL2_AUX1_SEQ_PLLCAPPD_OVERRIDE
|
704 NV_SOR_PLL2_AUX9_LVDSEN_OVERRIDE
|
705 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE
);
706 tegra_sor_writel(sor
, NV_SOR_PLL1
,
707 NV_SOR_PLL1_TERM_COMPOUT_HIGH
| NV_SOR_PLL1_TMDS_TERM_ENABLE
);
709 if (tegra_dc_sor_poll_register(sor
, NV_SOR_PLL2
,
710 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK
,
711 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE
,
712 100, TEGRA_SOR_TIMEOUT_MS
* 1000)) {
713 printk(BIOS_ERR
, "DP failed to lock PLL\n");
717 tegra_sor_write_field(sor
, NV_SOR_PLL2
,
718 NV_SOR_PLL2_AUX2_MASK
| NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK
,
719 NV_SOR_PLL2_AUX2_OVERRIDE_POWERDOWN
|
720 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_DISABLE
);
722 tegra_dc_sor_power_up(sor
, 0);
724 /* re-enable SOR clock */
725 tegra_sor_enable_edp_clock(sor
); /* select pll_dp as clock source */
728 tegra_dc_sor_power_dplanes(sor
, link_cfg
->lane_count
, 1);
730 tegra_dc_sor_set_dp_mode(sor
, link_cfg
);
734 void tegra_dc_sor_attach(struct tegra_dc_sor_data
*sor
)
737 struct display_controller
*disp_ctrl
= (void *)sor
->dc
->base
;
739 tegra_dc_sor_enable_dc(sor
);
740 tegra_dc_sor_config_panel(sor
, 0);
742 WRITEL(0x9f00, &disp_ctrl
->cmd
.state_ctrl
);
743 WRITEL(0x9f, &disp_ctrl
->cmd
.state_ctrl
);
745 WRITEL(PW0_ENABLE
| PW1_ENABLE
| PW2_ENABLE
|
746 PW3_ENABLE
| PW4_ENABLE
| PM0_ENABLE
| PM1_ENABLE
,
747 &disp_ctrl
->cmd
.disp_pow_ctrl
);
749 reg_val
= tegra_sor_readl(sor
, NV_SOR_TEST
);
750 if (reg_val
& NV_SOR_TEST_ATTACHED_TRUE
)
753 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE1
,
754 NV_SOR_SUPER_STATE1_ATTACHED_NO
);
757 * Enable display2sor clock at least 2 cycles before DC start,
758 * to clear sor internal valid signal.
761 /* Stop dc for 3 cycles */
762 WRITEL(0, &disp_ctrl
->disp
.disp_win_opt
);
763 WRITEL(GENERAL_ACT_REQ
, &disp_ctrl
->cmd
.state_ctrl
);
764 udelay(FRAME_IN_MS
* 1000 * 3);
767 tegra_dc_sor_update(sor
);
768 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE1
,
769 NV_SOR_SUPER_STATE1_ATTACHED_YES
);
770 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE1
,
771 NV_SOR_SUPER_STATE1_ATTACHED_YES
|
772 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_AWAKE
|
773 NV_SOR_SUPER_STATE1_ASY_ORMODE_NORMAL
);
774 tegra_dc_sor_super_update(sor
);
776 /* wait for another 5 cycles */
777 udelay(FRAME_IN_MS
* 1000 * 5);
780 WRITEL(READ_MUX_ACTIVE
| WRITE_MUX_ACTIVE
,
781 &disp_ctrl
->cmd
.state_access
);
782 WRITEL(SOR_ENABLE
, &disp_ctrl
->disp
.disp_win_opt
);
784 WRITEL(DISP_CTRL_MODE_C_DISPLAY
, &disp_ctrl
->cmd
.disp_cmd
);
785 WRITEL(GENERAL_ACT_REQ
, &disp_ctrl
->cmd
.state_ctrl
);
787 if (tegra_dc_sor_poll_register(sor
, NV_SOR_TEST
,
788 NV_SOR_TEST_ACT_HEAD_OPMODE_DEFAULT_MASK
,
789 NV_SOR_TEST_ACT_HEAD_OPMODE_AWAKE
,
790 100, TEGRA_SOR_ATTACH_TIMEOUT_MS
* 1000))
791 printk(BIOS_ERR
, "dc timeout waiting for OPMOD = AWAKE\n");
793 printk(BIOS_INFO
, "%s: sor is attached\n", __func__
);
800 void tegra_dc_sor_set_lane_parm(struct tegra_dc_sor_data
*sor
,
801 const struct tegra_dc_dp_link_config
*link_cfg
)
803 tegra_sor_writel(sor
, NV_SOR_LANE_DRIVE_CURRENT(sor
->portnum
),
804 link_cfg
->drive_current
);
805 tegra_sor_writel(sor
, NV_SOR_PR(sor
->portnum
),
806 link_cfg
->preemphasis
);
807 tegra_sor_writel(sor
, NV_SOR_POSTCURSOR(sor
->portnum
),
808 link_cfg
->postcursor
);
809 tegra_sor_writel(sor
, NV_SOR_LVDS
, 0);
811 tegra_dc_sor_set_link_bandwidth(sor
, link_cfg
->link_bw
);
812 tegra_dc_sor_set_lane_count(sor
, link_cfg
->lane_count
);
814 tegra_sor_write_field(sor
, NV_SOR_DP_PADCTL(sor
->portnum
),
815 NV_SOR_DP_PADCTL_TX_PU_ENABLE
|
816 NV_SOR_DP_PADCTL_TX_PU_VALUE_DEFAULT_MASK
,
817 NV_SOR_DP_PADCTL_TX_PU_ENABLE
|
818 2 << NV_SOR_DP_PADCTL_TX_PU_VALUE_SHIFT
);
821 tegra_sor_write_field(sor
, NV_SOR_DP_PADCTL(sor
->portnum
),
825 tegra_sor_write_field(sor
, NV_SOR_DP_PADCTL(sor
->portnum
),
829 void tegra_dc_sor_set_voltage_swing(struct tegra_dc_sor_data
*sor
)
831 u32 drive_current
= 0;
832 u32 pre_emphasis
= 0;
834 /* Set to a known-good pre-calibrated setting */
835 switch (sor
->link_cfg
->link_bw
) {
836 case SOR_LINK_SPEED_G1_62
:
837 case SOR_LINK_SPEED_G2_7
:
838 drive_current
= 0x13131313;
841 case SOR_LINK_SPEED_G5_4
:
842 printk(BIOS_WARNING
, "T1xx does not support 5.4G link"
845 printk(BIOS_WARNING
, "Invalid sor link bandwidth: %d\n",
846 sor
->link_cfg
->link_bw
);
850 tegra_sor_writel(sor
, NV_SOR_LANE_DRIVE_CURRENT(sor
->portnum
),
852 tegra_sor_writel(sor
, NV_SOR_PR(sor
->portnum
), pre_emphasis
);
855 void tegra_dc_sor_power_down_unused_lanes(struct tegra_dc_sor_data
*sor
)
860 switch (sor
->link_cfg
->lane_count
) {
862 pad_ctrl
= (NV_SOR_DP_PADCTL_PD_TXD_0_NO
|
863 NV_SOR_DP_PADCTL_PD_TXD_1_NO
|
864 NV_SOR_DP_PADCTL_PD_TXD_2_NO
|
865 NV_SOR_DP_PADCTL_PD_TXD_3_NO
);
868 pad_ctrl
= (NV_SOR_DP_PADCTL_PD_TXD_0_NO
|
869 NV_SOR_DP_PADCTL_PD_TXD_1_NO
|
870 NV_SOR_DP_PADCTL_PD_TXD_2_YES
|
871 NV_SOR_DP_PADCTL_PD_TXD_3_YES
);
874 pad_ctrl
= (NV_SOR_DP_PADCTL_PD_TXD_0_NO
|
875 NV_SOR_DP_PADCTL_PD_TXD_1_YES
|
876 NV_SOR_DP_PADCTL_PD_TXD_2_YES
|
877 NV_SOR_DP_PADCTL_PD_TXD_3_YES
);
880 printk(BIOS_ERR
, "Invalid sor lane count: %u\n",
881 sor
->link_cfg
->lane_count
);
885 pad_ctrl
|= NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN
;
886 tegra_sor_writel(sor
, NV_SOR_DP_PADCTL(sor
->portnum
), pad_ctrl
);
888 err
= tegra_dc_sor_enable_lane_sequencer(sor
, 0, 0);
891 "Wait for lane power down failed: %d\n", err
);
896 void tegra_sor_precharge_lanes(struct tegra_dc_sor_data
*sor
)
898 const struct tegra_dc_dp_link_config
*cfg
= sor
->link_cfg
;
901 switch (cfg
->lane_count
) {
903 val
|= (NV_SOR_DP_PADCTL_PD_TXD_3_NO
|
904 NV_SOR_DP_PADCTL_PD_TXD_2_NO
);
907 val
|= NV_SOR_DP_PADCTL_PD_TXD_1_NO
;
910 val
|= NV_SOR_DP_PADCTL_PD_TXD_0_NO
;
914 "dp: invalid lane number %d\n", cfg
->lane_count
);
918 tegra_sor_write_field(sor
, NV_SOR_DP_PADCTL(sor
->portnum
),
919 (0xf << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT
),
920 (val
<< NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT
));
922 tegra_sor_write_field(sor
, NV_SOR_DP_PADCTL(sor
->portnum
),
923 (0xf << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT
), 0);
926 static u32
tegra_dc_poll_register(void *reg
,
927 u32 mask
, u32 exp_val
, u32 poll_interval_us
, u32 timeout_us
)
929 u32 temp
= timeout_us
;
933 udelay(poll_interval_us
);
934 reg_val
= READL(reg
);
935 if (timeout_us
> poll_interval_us
)
936 timeout_us
-= poll_interval_us
;
939 } while ((reg_val
& mask
) != exp_val
);
941 if ((reg_val
& mask
) == exp_val
)
942 return 0; /* success */
947 static void tegra_dc_sor_general_act(struct display_controller
*disp_ctrl
)
949 WRITEL(GENERAL_ACT_REQ
, &disp_ctrl
->cmd
.state_ctrl
);
951 if (tegra_dc_poll_register(&disp_ctrl
->cmd
.state_ctrl
,
952 GENERAL_ACT_REQ
, 0, 100,
953 TEGRA_DC_POLL_TIMEOUT_MS
*1000))
955 "dc timeout waiting for DC to stop\n");
958 static struct tegra_dc_mode min_mode
= {
971 /* Disable windows and set minimum raster timings */
973 tegra_dc_sor_disable_win_short_raster(struct display_controller
*disp_ctrl
,
976 int selected_windows
, i
;
978 selected_windows
= READL(&disp_ctrl
->cmd
.disp_win_header
);
980 /* Store and clear window options */
981 for (i
= 0; i
< DC_N_WINDOWS
; ++i
) {
982 WRITEL(WINDOW_A_SELECT
<< i
, &disp_ctrl
->cmd
.disp_win_header
);
983 dc_reg_ctx
[i
] = READL(&disp_ctrl
->win
.win_opt
);
984 WRITEL(0, &disp_ctrl
->win
.win_opt
);
985 WRITEL(WIN_A_ACT_REQ
<< i
, &disp_ctrl
->cmd
.state_ctrl
);
988 WRITEL(selected_windows
, &disp_ctrl
->cmd
.disp_win_header
);
990 /* Store current raster timings and set minimum timings */
991 dc_reg_ctx
[i
++] = READL(&disp_ctrl
->disp
.ref_to_sync
);
992 WRITEL(min_mode
.h_ref_to_sync
| (min_mode
.v_ref_to_sync
<< 16),
993 &disp_ctrl
->disp
.ref_to_sync
);
995 dc_reg_ctx
[i
++] = READL(&disp_ctrl
->disp
.sync_width
);
996 WRITEL(min_mode
.h_sync_width
| (min_mode
.v_sync_width
<< 16),
997 &disp_ctrl
->disp
.sync_width
);
999 dc_reg_ctx
[i
++] = READL(&disp_ctrl
->disp
.back_porch
);
1000 WRITEL(min_mode
.h_back_porch
|
1001 min_mode
.v_back_porch
<< 16,
1002 &disp_ctrl
->disp
.back_porch
);
1004 dc_reg_ctx
[i
++] = READL(&disp_ctrl
->disp
.front_porch
);
1005 WRITEL(min_mode
.h_front_porch
|
1006 min_mode
.v_front_porch
<< 16,
1007 &disp_ctrl
->disp
.front_porch
);
1009 dc_reg_ctx
[i
++] = READL(&disp_ctrl
->disp
.disp_active
);
1010 WRITEL(min_mode
.h_active
| (min_mode
.v_active
<< 16),
1011 &disp_ctrl
->disp
.disp_active
);
1013 WRITEL(GENERAL_ACT_REQ
, &disp_ctrl
->cmd
.state_ctrl
);
1016 /* Restore previous windows status and raster timings */
1018 tegra_dc_sor_restore_win_and_raster(struct display_controller
*disp_ctrl
,
1021 int selected_windows
, i
;
1023 selected_windows
= READL(&disp_ctrl
->cmd
.disp_win_header
);
1025 for (i
= 0; i
< DC_N_WINDOWS
; ++i
) {
1026 WRITEL(WINDOW_A_SELECT
<< i
, &disp_ctrl
->cmd
.disp_win_header
);
1027 WRITEL(dc_reg_ctx
[i
], &disp_ctrl
->win
.win_opt
);
1028 WRITEL(WIN_A_ACT_REQ
<< i
, &disp_ctrl
->cmd
.state_ctrl
);
1031 WRITEL(selected_windows
, &disp_ctrl
->cmd
.disp_win_header
);
1033 WRITEL(dc_reg_ctx
[i
++], &disp_ctrl
->disp
.ref_to_sync
);
1034 WRITEL(dc_reg_ctx
[i
++], &disp_ctrl
->disp
.sync_width
);
1035 WRITEL(dc_reg_ctx
[i
++], &disp_ctrl
->disp
.back_porch
);
1036 WRITEL(dc_reg_ctx
[i
++], &disp_ctrl
->disp
.front_porch
);
1037 WRITEL(dc_reg_ctx
[i
++], &disp_ctrl
->disp
.disp_active
);
1039 WRITEL(GENERAL_UPDATE
, &disp_ctrl
->cmd
.state_ctrl
);
1042 static void tegra_dc_sor_enable_sor(struct tegra_dc_sor_data
*sor
, int enable
)
1044 struct display_controller
*disp_ctrl
= (void *)sor
->dc
->base
;
1045 u32 reg_val
= READL(&disp_ctrl
->disp
.disp_win_opt
);
1047 reg_val
= enable
? reg_val
| SOR_ENABLE
: reg_val
& ~SOR_ENABLE
;
1048 WRITEL(reg_val
, &disp_ctrl
->disp
.disp_win_opt
);
1051 void tegra_dc_detach(struct tegra_dc_sor_data
*sor
)
1053 struct display_controller
*disp_ctrl
= (void *)sor
->dc
->base
;
1054 int dc_reg_ctx
[DC_N_WINDOWS
+ 5];
1055 unsigned long dc_int_mask
;
1058 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE1
,
1059 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SLEEP
|
1060 NV_SOR_SUPER_STATE1_ASY_ORMODE_SAFE
|
1061 NV_SOR_SUPER_STATE1_ATTACHED_YES
);
1062 tegra_dc_sor_super_update(sor
);
1064 tegra_dc_sor_disable_win_short_raster(disp_ctrl
, dc_reg_ctx
);
1066 if (tegra_dc_sor_poll_register(sor
, NV_SOR_TEST
,
1067 NV_SOR_TEST_ACT_HEAD_OPMODE_DEFAULT_MASK
,
1068 NV_SOR_TEST_ACT_HEAD_OPMODE_SLEEP
,
1069 100, TEGRA_SOR_ATTACH_TIMEOUT_MS
*1000)) {
1071 "dc timeout waiting for OPMOD = SLEEP\n");
1074 tegra_sor_writel(sor
, NV_SOR_SUPER_STATE1
,
1075 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SLEEP
|
1076 NV_SOR_SUPER_STATE1_ASY_ORMODE_SAFE
|
1077 NV_SOR_SUPER_STATE1_ATTACHED_NO
);
1079 /* Mask DC interrupts during the 2 dummy frames required for detach */
1080 dc_int_mask
= READL(&disp_ctrl
->cmd
.int_mask
);
1081 WRITEL(0, &disp_ctrl
->cmd
.int_mask
);
1083 /* Stop DC->SOR path */
1084 tegra_dc_sor_enable_sor(sor
, 0);
1085 tegra_dc_sor_general_act(disp_ctrl
);
1088 WRITEL(DISP_CTRL_MODE_STOP
, &disp_ctrl
->cmd
.disp_cmd
);
1089 tegra_dc_sor_general_act(disp_ctrl
);
1091 tegra_dc_sor_restore_win_and_raster(disp_ctrl
, dc_reg_ctx
);
1093 WRITEL(dc_int_mask
, &disp_ctrl
->cmd
.int_mask
);