blob: 9b50d93996bc9ca62379c8b47d39d80ecc5eee42 [file] [log] [blame]
Angel Ponsa2ee7612020-04-04 18:51:15 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Angel Ponsa2ee7612020-04-04 18:51:15 +02002
Patrick Georgi40a3e322015-06-22 19:41:29 +02003/*
4 * drivers/video/tegra/dc/sor.c
Patrick Georgi40a3e322015-06-22 19:41:29 +02005 */
6
7#include <console/console.h>
Patrick Georgi40a3e322015-06-22 19:41:29 +02008#include <stdint.h>
Patrick Georgi40a3e322015-06-22 19:41:29 +02009#include <delay.h>
10#include <soc/addressmap.h>
11#include <device/device.h>
Patrick Georgi40a3e322015-06-22 19:41:29 +020012#include <boot/tables.h>
Patrick Georgi40a3e322015-06-22 19:41:29 +020013#include <soc/nvidia/tegra/dc.h>
14#include <soc/nvidia/tegra/types.h>
15#include <soc/sor.h>
16#include <soc/nvidia/tegra/displayport.h>
17#include <soc/clk_rst.h>
18#include <soc/clock.h>
19#include "chip.h"
20#include <soc/display.h>
21
22#define DEBUG_SOR 0
23
24#define APBDEV_PMC_DPD_SAMPLE (0x20)
25#define APBDEV_PMC_DPD_SAMPLE_ON_DISABLE (0)
26#define APBDEV_PMC_DPD_SAMPLE_ON_ENABLE (1)
27#define APBDEV_PMC_SEL_DPD_TIM (0x1c8)
28#define APBDEV_PMC_SEL_DPD_TIM_SEL_DPD_TIM_DEFAULT (0x7f)
29#define APBDEV_PMC_IO_DPD2_REQ (0x1c0)
30#define APBDEV_PMC_IO_DPD2_REQ_LVDS_SHIFT (25)
31#define APBDEV_PMC_IO_DPD2_REQ_LVDS_OFF (0 << 25)
32#define APBDEV_PMC_IO_DPD2_REQ_LVDS_ON (1 << 25)
33#define APBDEV_PMC_IO_DPD2_REQ_CODE_SHIFT (30)
34#define APBDEV_PMC_IO_DPD2_REQ_CODE_DEFAULT_MASK (0x3 << 30)
35#define APBDEV_PMC_IO_DPD2_REQ_CODE_IDLE (0 << 30)
36#define APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_OFF (1 << 30)
37#define APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_ON (2 << 30)
38#define APBDEV_PMC_IO_DPD2_STATUS (0x1c4)
39#define APBDEV_PMC_IO_DPD2_STATUS_LVDS_SHIFT (25)
40#define APBDEV_PMC_IO_DPD2_STATUS_LVDS_OFF (0 << 25)
41#define APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON (1 << 25)
42
43#define DC_N_WINDOWS 5
44
45static inline u32 tegra_sor_readl(struct tegra_dc_sor_data *sor, u32 reg)
46{
47 void *addr = sor->base + (u32) (reg << 2);
48 u32 reg_val = READL(addr);
49 return reg_val;
50}
51
52static inline void tegra_sor_writel(struct tegra_dc_sor_data *sor,
53 u32 reg, u32 val)
54{
55 void *addr = sor->base + (u32) (reg << 2);
56 WRITEL(val, addr);
57}
58
59static 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
68void tegra_dp_disable_tx_pu(struct tegra_dc_sor_data *sor)
69{
70 tegra_sor_write_field(sor,
71 NV_SOR_DP_PADCTL(sor->portnum),
72 NV_SOR_DP_PADCTL_TX_PU_MASK,
73 NV_SOR_DP_PADCTL_TX_PU_DISABLE);
74}
75
76void tegra_dp_set_pe_vs_pc(struct tegra_dc_sor_data *sor, u32 mask,
77 u32 pe_reg, u32 vs_reg, u32 pc_reg, u8 pc_supported)
78{
79 tegra_sor_write_field(sor, NV_SOR_PR(sor->portnum),
80 mask, pe_reg);
81 tegra_sor_write_field(sor, NV_SOR_DC(sor->portnum),
82 mask, vs_reg);
83 if (pc_supported) {
84 tegra_sor_write_field(
85 sor, NV_SOR_POSTCURSOR(sor->portnum),
86 mask, pc_reg);
87 }
88}
89
90static u32 tegra_dc_sor_poll_register(struct tegra_dc_sor_data *sor,
91 u32 reg, u32 mask, u32 exp_val, u32 poll_interval_us, u32 timeout_us)
92{
93 u32 temp = timeout_us;
94 u32 reg_val = 0;
95
96 do {
97 udelay(poll_interval_us);
98 reg_val = tegra_sor_readl(sor, reg);
99 if (timeout_us > poll_interval_us)
100 timeout_us -= poll_interval_us;
101 else
102 break;
103 } while ((reg_val & mask) != exp_val);
104
105 if ((reg_val & mask) == exp_val)
106 return 0; /* success */
107 printk(BIOS_ERR,
108 "sor_poll_register 0x%x: timeout, "
109 "(reg_val)0x%08x & (mask)0x%08x != (exp_val)0x%08x\n",
110 reg, reg_val, mask, exp_val);
111
112 return temp;
113}
114
115int tegra_dc_sor_set_power_state(struct tegra_dc_sor_data *sor, int pu_pd)
116{
117 u32 reg_val;
118 u32 orig_val;
119
120 orig_val = tegra_sor_readl(sor, NV_SOR_PWR);
121
122 reg_val = pu_pd ? NV_SOR_PWR_NORMAL_STATE_PU :
123 NV_SOR_PWR_NORMAL_STATE_PD; /* normal state only */
124
125 if (reg_val == orig_val)
126 return 0; /* No update needed */
127
128 reg_val |= NV_SOR_PWR_SETTING_NEW_TRIGGER;
129 tegra_sor_writel(sor, NV_SOR_PWR, reg_val);
130
131 /* Poll to confirm it is done */
132 if (tegra_dc_sor_poll_register(sor, NV_SOR_PWR,
133 NV_SOR_PWR_SETTING_NEW_DEFAULT_MASK,
134 NV_SOR_PWR_SETTING_NEW_DONE,
135 100, TEGRA_SOR_TIMEOUT_MS * 1000)) {
136 printk(BIOS_ERR,
137 "dc timeout waiting for SOR_PWR = NEW_DONE\n");
138 return -EFAULT;
139 }
140 return 0;
141}
142
143void tegra_dc_sor_set_dp_linkctl(struct tegra_dc_sor_data *sor, int ena,
144 u8 training_pattern, const struct tegra_dc_dp_link_config *link_cfg)
145{
146 u32 reg_val;
147
148 reg_val = tegra_sor_readl(sor, NV_SOR_DP_LINKCTL(sor->portnum));
149
150 if (ena)
151 reg_val |= NV_SOR_DP_LINKCTL_ENABLE_YES;
152 else
153 reg_val &= NV_SOR_DP_LINKCTL_ENABLE_NO;
154
155 reg_val &= ~NV_SOR_DP_LINKCTL_TUSIZE_MASK;
156 reg_val |= (link_cfg->tu_size << NV_SOR_DP_LINKCTL_TUSIZE_SHIFT);
157
158 if (link_cfg->enhanced_framing)
159 reg_val |= NV_SOR_DP_LINKCTL_ENHANCEDFRAME_ENABLE;
160
161 tegra_sor_writel(sor, NV_SOR_DP_LINKCTL(sor->portnum), reg_val);
162
163 switch (training_pattern) {
164 case training_pattern_1:
165 tegra_sor_writel(sor, NV_SOR_DP_TPG, 0x41414141);
166 break;
167 case training_pattern_2:
168 case training_pattern_3:
169 reg_val = (link_cfg->link_bw == SOR_LINK_SPEED_G5_4) ?
170 0x43434343 : 0x42424242;
171 tegra_sor_writel(sor, NV_SOR_DP_TPG, reg_val);
172 break;
173 default:
174 tegra_sor_writel(sor, NV_SOR_DP_TPG, 0x50505050);
175 break;
176 }
177}
178
179static int tegra_dc_sor_enable_lane_sequencer(struct tegra_dc_sor_data *sor,
180 int pu, int is_lvds)
181{
182 u32 reg_val;
183
184 /* SOR lane sequencer */
185 if (pu)
186 reg_val = NV_SOR_LANE_SEQ_CTL_SETTING_NEW_TRIGGER |
187 NV_SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |
188 NV_SOR_LANE_SEQ_CTL_NEW_POWER_STATE_PU;
189 else
190 reg_val = NV_SOR_LANE_SEQ_CTL_SETTING_NEW_TRIGGER |
191 NV_SOR_LANE_SEQ_CTL_SEQUENCE_UP |
192 NV_SOR_LANE_SEQ_CTL_NEW_POWER_STATE_PD;
193
194 if (is_lvds)
195 reg_val |= 15 << NV_SOR_LANE_SEQ_CTL_DELAY_SHIFT;
196 else
197 reg_val |= 1 << NV_SOR_LANE_SEQ_CTL_DELAY_SHIFT;
198
199 tegra_sor_writel(sor, NV_SOR_LANE_SEQ_CTL, reg_val);
200
201 if (tegra_dc_sor_poll_register(sor, NV_SOR_LANE_SEQ_CTL,
202 NV_SOR_LANE_SEQ_CTL_SETTING_MASK,
203 NV_SOR_LANE_SEQ_CTL_SETTING_NEW_DONE,
204 100, TEGRA_SOR_TIMEOUT_MS*1000)) {
205 printk(BIOS_ERR,
206 "dp: timeout while waiting for SOR lane sequencer "
207 "to power down langes\n");
208 return -1;
209 }
210 return 0;
211}
212
213static int tegra_dc_sor_power_dplanes(struct tegra_dc_sor_data *sor,
214 u32 lane_count, int pu)
215{
216 u32 reg_val;
217
218 reg_val = tegra_sor_readl(sor, NV_SOR_DP_PADCTL(sor->portnum));
219
220 if (pu) {
221 switch (lane_count) {
222 case 4:
223 reg_val |= (NV_SOR_DP_PADCTL_PD_TXD_3_NO |
224 NV_SOR_DP_PADCTL_PD_TXD_2_NO);
225 /* fall through */
226 case 2:
227 reg_val |= NV_SOR_DP_PADCTL_PD_TXD_1_NO;
228 case 1:
229 reg_val |= NV_SOR_DP_PADCTL_PD_TXD_0_NO;
230 break;
231 default:
232 printk(BIOS_ERR,
233 "dp: invalid lane number %d\n", lane_count);
234 return -1;
235 }
236
237 tegra_sor_writel(sor, NV_SOR_DP_PADCTL(sor->portnum), reg_val);
238 tegra_dc_sor_set_lane_count(sor, lane_count);
239 }
240 return tegra_dc_sor_enable_lane_sequencer(sor, pu, 0);
241}
242
243void tegra_dc_sor_set_panel_power(struct tegra_dc_sor_data *sor,
244 int power_up)
245{
246 u32 reg_val;
247
248 reg_val = tegra_sor_readl(sor, NV_SOR_DP_PADCTL(sor->portnum));
249
250 if (power_up)
251 reg_val &= ~NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN;
252 else
253 reg_val |= NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN;
254
255 tegra_sor_writel(sor, NV_SOR_DP_PADCTL(sor->portnum), reg_val);
256}
257
258static void tegra_dc_sor_config_pwm(struct tegra_dc_sor_data *sor, u32 pwm_div,
259 u32 pwm_dutycycle)
260{
261 tegra_sor_writel(sor, NV_SOR_PWM_DIV, pwm_div);
262 tegra_sor_writel(sor, NV_SOR_PWM_CTL,
263 (pwm_dutycycle & NV_SOR_PWM_CTL_DUTY_CYCLE_MASK) |
264 NV_SOR_PWM_CTL_SETTING_NEW_TRIGGER);
265
266 if (tegra_dc_sor_poll_register(sor, NV_SOR_PWM_CTL,
267 NV_SOR_PWM_CTL_SETTING_NEW_SHIFT,
268 NV_SOR_PWM_CTL_SETTING_NEW_DONE,
269 100, TEGRA_SOR_TIMEOUT_MS * 1000)) {
270 printk(BIOS_ERR,
271 "dp: timeout while waiting for SOR PWM setting\n");
272 }
273}
274
275static void tegra_dc_sor_set_dp_mode(struct tegra_dc_sor_data *sor,
276 const struct tegra_dc_dp_link_config *link_cfg)
277{
278 u32 reg_val;
279
280 tegra_dc_sor_set_link_bandwidth(sor, link_cfg->link_bw);
281
282 tegra_dc_sor_set_dp_linkctl(sor, 1, training_pattern_none, link_cfg);
283 reg_val = tegra_sor_readl(sor, NV_SOR_DP_CONFIG(sor->portnum));
284 reg_val &= ~NV_SOR_DP_CONFIG_WATERMARK_MASK;
285 reg_val |= link_cfg->watermark;
286 reg_val &= ~NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_MASK;
287 reg_val |= (link_cfg->active_count <<
288 NV_SOR_DP_CONFIG_ACTIVESYM_COUNT_SHIFT);
289 reg_val &= ~NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_MASK;
290 reg_val |= (link_cfg->active_frac <<
291 NV_SOR_DP_CONFIG_ACTIVESYM_FRAC_SHIFT);
292 if (link_cfg->activepolarity)
293 reg_val |= NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE;
294 else
295 reg_val &= ~NV_SOR_DP_CONFIG_ACTIVESYM_POLARITY_POSITIVE;
296 reg_val |= (NV_SOR_DP_CONFIG_ACTIVESYM_CNTL_ENABLE |
297 NV_SOR_DP_CONFIG_RD_RESET_VAL_NEGATIVE);
298
299 tegra_sor_writel(sor, NV_SOR_DP_CONFIG(sor->portnum), reg_val);
300
301 /* program h/vblank sym */
302 tegra_sor_write_field(sor, NV_SOR_DP_AUDIO_HBLANK_SYMBOLS,
303 NV_SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK, link_cfg->hblank_sym);
304
305 tegra_sor_write_field(sor, NV_SOR_DP_AUDIO_VBLANK_SYMBOLS,
306 NV_SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK, link_cfg->vblank_sym);
307}
308
309static inline void tegra_dc_sor_super_update(struct tegra_dc_sor_data *sor)
310{
311 tegra_sor_writel(sor, NV_SOR_SUPER_STATE0, 0);
312 tegra_sor_writel(sor, NV_SOR_SUPER_STATE0, 1);
313 tegra_sor_writel(sor, NV_SOR_SUPER_STATE0, 0);
314}
315
316static inline void tegra_dc_sor_update(struct tegra_dc_sor_data *sor)
317{
318 tegra_sor_writel(sor, NV_SOR_STATE0, 0);
319 tegra_sor_writel(sor, NV_SOR_STATE0, 1);
320 tegra_sor_writel(sor, NV_SOR_STATE0, 0);
321}
322
323static void tegra_dc_sor_io_set_dpd(struct tegra_dc_sor_data *sor, int up)
324{
325 u32 reg_val;
326 void *pmc_base = sor->pmc_base;
327
328 if (up) {
329 WRITEL(APBDEV_PMC_DPD_SAMPLE_ON_ENABLE,
330 pmc_base + APBDEV_PMC_DPD_SAMPLE);
331 WRITEL(10, pmc_base + APBDEV_PMC_SEL_DPD_TIM);
332 }
333
334 reg_val = READL(pmc_base + APBDEV_PMC_IO_DPD2_REQ);
335 reg_val &= ~(APBDEV_PMC_IO_DPD2_REQ_LVDS_ON ||
336 APBDEV_PMC_IO_DPD2_REQ_CODE_DEFAULT_MASK);
337
338 reg_val = up ? APBDEV_PMC_IO_DPD2_REQ_LVDS_ON |
339 APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_OFF :
340 APBDEV_PMC_IO_DPD2_REQ_LVDS_OFF |
341 APBDEV_PMC_IO_DPD2_REQ_CODE_DPD_ON;
342
343 WRITEL(reg_val, pmc_base + APBDEV_PMC_IO_DPD2_REQ);
344
345 /* Polling */
346 u32 temp = 10*1000;
347 do {
348 udelay(20);
349 reg_val = READL(pmc_base + APBDEV_PMC_IO_DPD2_STATUS);
350 if (temp > 20)
351 temp -= 20;
352 else
353 break;
354 } while ((reg_val & APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON) != 0);
355
356 if ((reg_val & APBDEV_PMC_IO_DPD2_STATUS_LVDS_ON) != 0)
357 printk(BIOS_ERR,
358 "PMC_IO_DPD2 polling failed (0x%x)\n", reg_val);
359
360 if (up)
361 WRITEL(APBDEV_PMC_DPD_SAMPLE_ON_DISABLE,
362 pmc_base + APBDEV_PMC_DPD_SAMPLE);
363}
364
365void tegra_dc_sor_set_internal_panel(struct tegra_dc_sor_data *sor, int is_int)
366{
367 u32 reg_val;
368
369 reg_val = tegra_sor_readl(sor, NV_SOR_DP_SPARE(sor->portnum));
370 if (is_int)
371 reg_val |= NV_SOR_DP_SPARE_PANEL_INTERNAL;
372 else
373 reg_val &= ~NV_SOR_DP_SPARE_PANEL_INTERNAL;
374
375 reg_val |= NV_SOR_DP_SPARE_SOR_CLK_SEL_MACRO_SORCLK |
376 NV_SOR_DP_SPARE_SEQ_ENABLE_YES;
377 tegra_sor_writel(sor, NV_SOR_DP_SPARE(sor->portnum), reg_val);
378}
379
380void tegra_dc_sor_read_link_config(struct tegra_dc_sor_data *sor, u8 *link_bw,
381 u8 *lane_count)
382{
383 u32 reg_val;
384
385 reg_val = tegra_sor_readl(sor, NV_SOR_CLK_CNTRL);
386 *link_bw = (reg_val & NV_SOR_CLK_CNTRL_DP_LINK_SPEED_MASK)
387 >> NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT;
388 reg_val = tegra_sor_readl(sor,
389 NV_SOR_DP_LINKCTL(sor->portnum));
390
391 switch (reg_val & NV_SOR_DP_LINKCTL_LANECOUNT_MASK) {
392 case NV_SOR_DP_LINKCTL_LANECOUNT_ZERO:
393 *lane_count = 0;
394 break;
395 case NV_SOR_DP_LINKCTL_LANECOUNT_ONE:
396 *lane_count = 1;
397 break;
398 case NV_SOR_DP_LINKCTL_LANECOUNT_TWO:
399 *lane_count = 2;
400 break;
401 case NV_SOR_DP_LINKCTL_LANECOUNT_FOUR:
402 *lane_count = 4;
403 break;
404 default:
405 printk(BIOS_ERR, "Unknown lane count\n");
406 }
407}
408
409void tegra_dc_sor_set_link_bandwidth(struct tegra_dc_sor_data *sor, u8 link_bw)
410{
411 tegra_sor_write_field(sor, NV_SOR_CLK_CNTRL,
412 NV_SOR_CLK_CNTRL_DP_LINK_SPEED_MASK,
413 link_bw << NV_SOR_CLK_CNTRL_DP_LINK_SPEED_SHIFT);
414}
415
416void tegra_dc_sor_set_lane_count(struct tegra_dc_sor_data *sor, u8 lane_count)
417{
418 u32 reg_val;
419
420 reg_val = tegra_sor_readl(sor, NV_SOR_DP_LINKCTL(sor->portnum));
421 reg_val &= ~NV_SOR_DP_LINKCTL_LANECOUNT_MASK;
422 switch (lane_count) {
423 case 0:
424 break;
425 case 1:
426 reg_val |= NV_SOR_DP_LINKCTL_LANECOUNT_ONE;
427 break;
428 case 2:
429 reg_val |= NV_SOR_DP_LINKCTL_LANECOUNT_TWO;
430 break;
431 case 4:
432 reg_val |= NV_SOR_DP_LINKCTL_LANECOUNT_FOUR;
433 break;
434 default:
435 /* 0 should be handled earlier. */
436 printk(BIOS_ERR, "dp: Invalid lane count %d\n",
437 lane_count);
438 return;
439 }
440 tegra_sor_writel(sor, NV_SOR_DP_LINKCTL(sor->portnum), reg_val);
441}
442
443static void tegra_sor_enable_edp_clock(struct tegra_dc_sor_data *sor)
444{
445 sor_clock_start();
446}
447
448/* The SOR power sequencer does not work for t1xx so SW has to
449 go through the power sequence manually */
450/* Power up steps from spec: */
451/* STEP PDPORT PDPLL PDBG PLLVCOD PLLCAPD E_DPD PDCAL */
452/* 1 1 1 1 1 1 1 1 */
453/* 2 1 1 1 1 1 0 1 */
454/* 3 1 1 0 1 1 0 1 */
455/* 4 1 0 0 0 0 0 1 */
456/* 5 0 0 0 0 0 0 1 */
457static void tegra_dc_sor_power_up(struct tegra_dc_sor_data *sor,
458 int is_lvds)
459{
460 if (sor->power_is_up)
461 return;
462
463 /* Set link bw */
464 tegra_dc_sor_set_link_bandwidth(sor,
465 is_lvds ? NV_SOR_CLK_CNTRL_DP_LINK_SPEED_LVDS :
466 NV_SOR_CLK_CNTRL_DP_LINK_SPEED_G1_62);
467
468 /* step 1 */
469 tegra_sor_write_field(sor, NV_SOR_PLL2,
470 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK | /* PDPORT */
471 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK | /* PDBG */
472 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK, /* PLLCAPD */
473 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_ENABLE |
474 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_ENABLE |
475 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_ENABLE);
476 tegra_sor_write_field(sor, NV_SOR_PLL0,
477 NV_SOR_PLL0_PWR_MASK | /* PDPLL */
478 NV_SOR_PLL0_VCOPD_MASK, /* PLLVCOPD */
479 NV_SOR_PLL0_PWR_OFF |
480 NV_SOR_PLL0_VCOPD_ASSERT);
481 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
482 NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN, /* PDCAL */
483 NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERUP);
484
485 /* step 2 */
486 tegra_dc_sor_io_set_dpd(sor, 1);
487 udelay(15);
488
489 /* step 3 */
490 tegra_sor_write_field(sor, NV_SOR_PLL2,
491 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
492 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
493 udelay(25);
494
495 /* step 4 */
496 tegra_sor_write_field(sor, NV_SOR_PLL0,
497 NV_SOR_PLL0_PWR_MASK | /* PDPLL */
498 NV_SOR_PLL0_VCOPD_MASK, /* PLLVCOPD */
499 NV_SOR_PLL0_PWR_ON | NV_SOR_PLL0_VCOPD_RESCIND);
500 tegra_sor_write_field(sor, NV_SOR_PLL2,
501 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK, /* PLLCAPD */
502 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
503 udelay(225);
504
505 /* step 5 */
506 tegra_sor_write_field(sor, NV_SOR_PLL2,
507 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK, /* PDPORT */
508 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_DISABLE);
509
510 sor->power_is_up = 1;
511}
512
513#if DEBUG_SOR
514static void dump_sor_reg(struct tegra_dc_sor_data *sor)
515{
516#define DUMP_REG(a) printk(BIOS_INFO, "%-32s %03x %08x\n", \
517 #a, a, tegra_sor_readl(sor, a));
518
519 DUMP_REG(NV_SOR_SUPER_STATE0);
520 DUMP_REG(NV_SOR_SUPER_STATE1);
521 DUMP_REG(NV_SOR_STATE0);
522 DUMP_REG(NV_SOR_STATE1);
523 DUMP_REG(NV_HEAD_STATE0(0));
524 DUMP_REG(NV_HEAD_STATE0(1));
525 DUMP_REG(NV_HEAD_STATE1(0));
526 DUMP_REG(NV_HEAD_STATE1(1));
527 DUMP_REG(NV_HEAD_STATE2(0));
528 DUMP_REG(NV_HEAD_STATE2(1));
529 DUMP_REG(NV_HEAD_STATE3(0));
530 DUMP_REG(NV_HEAD_STATE3(1));
531 DUMP_REG(NV_HEAD_STATE4(0));
532 DUMP_REG(NV_HEAD_STATE4(1));
533 DUMP_REG(NV_HEAD_STATE5(0));
534 DUMP_REG(NV_HEAD_STATE5(1));
535 DUMP_REG(NV_SOR_CRC_CNTRL);
536 DUMP_REG(NV_SOR_CLK_CNTRL);
537 DUMP_REG(NV_SOR_CAP);
538 DUMP_REG(NV_SOR_PWR);
539 DUMP_REG(NV_SOR_TEST);
540 DUMP_REG(NV_SOR_PLL0);
541 DUMP_REG(NV_SOR_PLL1);
542 DUMP_REG(NV_SOR_PLL2);
543 DUMP_REG(NV_SOR_PLL3);
544 DUMP_REG(NV_SOR_CSTM);
545 DUMP_REG(NV_SOR_LVDS);
546 DUMP_REG(NV_SOR_CRCA);
547 DUMP_REG(NV_SOR_CRCB);
548 DUMP_REG(NV_SOR_SEQ_CTL);
549 DUMP_REG(NV_SOR_LANE_SEQ_CTL);
550 DUMP_REG(NV_SOR_SEQ_INST(0));
551 DUMP_REG(NV_SOR_SEQ_INST(1));
552 DUMP_REG(NV_SOR_SEQ_INST(2));
553 DUMP_REG(NV_SOR_SEQ_INST(3));
554 DUMP_REG(NV_SOR_SEQ_INST(4));
555 DUMP_REG(NV_SOR_SEQ_INST(5));
556 DUMP_REG(NV_SOR_SEQ_INST(6));
557 DUMP_REG(NV_SOR_SEQ_INST(7));
558 DUMP_REG(NV_SOR_SEQ_INST(8));
559 DUMP_REG(NV_SOR_PWM_DIV);
560 DUMP_REG(NV_SOR_PWM_CTL);
561 DUMP_REG(NV_SOR_MSCHECK);
562 DUMP_REG(NV_SOR_XBAR_CTRL);
563 DUMP_REG(NV_SOR_DP_LINKCTL(0));
564 DUMP_REG(NV_SOR_DP_LINKCTL(1));
565 DUMP_REG(NV_SOR_DC(0));
566 DUMP_REG(NV_SOR_DC(1));
567 DUMP_REG(NV_SOR_LANE_DRIVE_CURRENT(0));
568 DUMP_REG(NV_SOR_PR(0));
569 DUMP_REG(NV_SOR_LANE4_PREEMPHASIS(0));
570 DUMP_REG(NV_SOR_POSTCURSOR(0));
571 DUMP_REG(NV_SOR_DP_CONFIG(0));
572 DUMP_REG(NV_SOR_DP_CONFIG(1));
573 DUMP_REG(NV_SOR_DP_MN(0));
574 DUMP_REG(NV_SOR_DP_MN(1));
575 DUMP_REG(NV_SOR_DP_PADCTL(0));
576 DUMP_REG(NV_SOR_DP_PADCTL(1));
577 DUMP_REG(NV_SOR_DP_DEBUG(0));
578 DUMP_REG(NV_SOR_DP_DEBUG(1));
579 DUMP_REG(NV_SOR_DP_SPARE(0));
580 DUMP_REG(NV_SOR_DP_SPARE(1));
581 DUMP_REG(NV_SOR_DP_TPG);
582
583 return;
584}
585#endif
586
587static void tegra_dc_sor_config_panel(struct tegra_dc_sor_data *sor,
588 int is_lvds)
589{
590 const struct tegra_dc *dc = sor->dc;
591 const struct tegra_dc_dp_data *dp = dc->out;
592 const struct tegra_dc_dp_link_config *link_cfg = &dp->link_cfg;
593 const struct soc_nvidia_tegra210_config *config = dc->config;
594
595 const int head_num = 0;
596 u32 reg_val = NV_SOR_STATE1_ASY_OWNER_HEAD0 << head_num;
597 u32 vsync_end, hsync_end;
598 u32 vblank_end, hblank_end;
599 u32 vblank_start, hblank_start;
600
601 reg_val |= is_lvds ? NV_SOR_STATE1_ASY_PROTOCOL_LVDS_CUSTOM :
602 NV_SOR_STATE1_ASY_PROTOCOL_DP_A;
603 reg_val |= NV_SOR_STATE1_ASY_SUBOWNER_NONE |
604 NV_SOR_STATE1_ASY_CRCMODE_COMPLETE_RASTER;
605
606 reg_val |= NV_SOR_STATE1_ASY_HSYNCPOL_NEGATIVE_TRUE;
607 reg_val |= NV_SOR_STATE1_ASY_VSYNCPOL_NEGATIVE_TRUE;
608 reg_val |= (link_cfg->bits_per_pixel > 18) ?
609 NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_24_444 :
610 NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_18_444;
611
612 tegra_sor_writel(sor, NV_SOR_STATE1, reg_val);
613
614 /* Skipping programming NV_HEAD_STATE0, assuming:
615 interlacing: PROGRESSIVE, dynamic range: VESA, colorspace: RGB */
616
617 tegra_sor_writel(sor, NV_HEAD_STATE1(head_num),
618 vtotal(config) << NV_HEAD_STATE1_VTOTAL_SHIFT |
619 htotal(config) << NV_HEAD_STATE1_HTOTAL_SHIFT);
620
621 vsync_end = config->vsync_width - 1;
622 hsync_end = config->hsync_width - 1;
623 tegra_sor_writel(sor, NV_HEAD_STATE2(head_num),
624 vsync_end << NV_HEAD_STATE2_VSYNC_END_SHIFT |
625 hsync_end << NV_HEAD_STATE2_HSYNC_END_SHIFT);
626
627 vblank_end = vsync_end + config->vback_porch;
628 hblank_end = hsync_end + config->hback_porch;
629 tegra_sor_writel(sor, NV_HEAD_STATE3(head_num),
630 vblank_end << NV_HEAD_STATE3_VBLANK_END_SHIFT |
631 hblank_end << NV_HEAD_STATE3_HBLANK_END_SHIFT);
632
633 vblank_start = vblank_end + config->yres;
634 hblank_start = hblank_end + config->xres;
635 tegra_sor_writel(sor, NV_HEAD_STATE4(head_num),
636 vblank_start << NV_HEAD_STATE4_VBLANK_START_SHIFT |
637 hblank_start << NV_HEAD_STATE4_HBLANK_START_SHIFT);
638
639 /* TODO: adding interlace mode support */
640 tegra_sor_writel(sor, NV_HEAD_STATE5(head_num), 0x1);
641
642 tegra_sor_write_field(sor, NV_SOR_CSTM,
643 NV_SOR_CSTM_ROTCLK_DEFAULT_MASK |
644 NV_SOR_CSTM_LVDS_EN_ENABLE,
645 2 << NV_SOR_CSTM_ROTCLK_SHIFT |
646 is_lvds ? NV_SOR_CSTM_LVDS_EN_ENABLE :
647 NV_SOR_CSTM_LVDS_EN_DISABLE);
648
649 tegra_dc_sor_config_pwm(sor, 1024, 1024);
650}
651
652static void tegra_dc_sor_enable_dc(struct tegra_dc_sor_data *sor)
653{
654 struct tegra_dc *dc = sor->dc;
655 struct display_controller *disp_ctrl = (void *)dc->base;
656
657 u32 reg_val = READL(&disp_ctrl->cmd.state_access);
658
659 WRITEL(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
660 WRITEL(VSYNC_H_POSITION(1), &disp_ctrl->disp.disp_timing_opt);
661
662 /* Enable DC now - otherwise pure text console may not show. */
663 WRITEL(DISP_CTRL_MODE_C_DISPLAY, &disp_ctrl->cmd.disp_cmd);
664 WRITEL(reg_val, &disp_ctrl->cmd.state_access);
665}
666
667void tegra_dc_sor_enable_dp(struct tegra_dc_sor_data *sor)
668{
669 const struct tegra_dc_dp_link_config *link_cfg = sor->link_cfg;
670
671 tegra_sor_write_field(sor, NV_SOR_CLK_CNTRL,
672 NV_SOR_CLK_CNTRL_DP_CLK_SEL_MASK,
673 NV_SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK);
674
675 tegra_sor_write_field(sor, NV_SOR_PLL2,
676 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
677 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
678 udelay(25);
679
680 tegra_sor_write_field(sor, NV_SOR_PLL3,
681 NV_SOR_PLL3_PLLVDD_MODE_MASK,
682 NV_SOR_PLL3_PLLVDD_MODE_V3_3);
683 tegra_sor_writel(sor, NV_SOR_PLL0,
684 0xf << NV_SOR_PLL0_ICHPMP_SHFIT |
685 0x3 << NV_SOR_PLL0_VCOCAP_SHIFT |
686 NV_SOR_PLL0_PLLREG_LEVEL_V45 |
687 NV_SOR_PLL0_RESISTORSEL_EXT |
688 NV_SOR_PLL0_PWR_ON | NV_SOR_PLL0_VCOPD_RESCIND);
689 tegra_sor_write_field(sor, NV_SOR_PLL2,
690 NV_SOR_PLL2_AUX1_SEQ_MASK | NV_SOR_PLL2_AUX9_LVDSEN_OVERRIDE |
691 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
692 NV_SOR_PLL2_AUX1_SEQ_PLLCAPPD_OVERRIDE |
693 NV_SOR_PLL2_AUX9_LVDSEN_OVERRIDE |
694 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
695 tegra_sor_writel(sor, NV_SOR_PLL1,
696 NV_SOR_PLL1_TERM_COMPOUT_HIGH | NV_SOR_PLL1_TMDS_TERM_ENABLE);
697
698 if (tegra_dc_sor_poll_register(sor, NV_SOR_PLL2,
699 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
700 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE,
701 100, TEGRA_SOR_TIMEOUT_MS * 1000)) {
702 printk(BIOS_ERR, "DP failed to lock PLL\n");
703 return;
704 }
705
706 tegra_sor_write_field(sor, NV_SOR_PLL2,
707 NV_SOR_PLL2_AUX2_MASK | NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK,
708 NV_SOR_PLL2_AUX2_OVERRIDE_POWERDOWN |
709 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_DISABLE);
710
711 tegra_dc_sor_power_up(sor, 0);
712
713 /* re-enable SOR clock */
714 tegra_sor_enable_edp_clock(sor); /* select pll_dp as clock source */
715
716 /* Power up lanes */
717 tegra_dc_sor_power_dplanes(sor, link_cfg->lane_count, 1);
718
719 tegra_dc_sor_set_dp_mode(sor, link_cfg);
720
721}
722
723void tegra_dc_sor_attach(struct tegra_dc_sor_data *sor)
724{
725 u32 reg_val;
726 struct display_controller *disp_ctrl = (void *)sor->dc->base;
727
728 tegra_dc_sor_enable_dc(sor);
729 tegra_dc_sor_config_panel(sor, 0);
730
731 WRITEL(0x9f00, &disp_ctrl->cmd.state_ctrl);
732 WRITEL(0x9f, &disp_ctrl->cmd.state_ctrl);
733
734 WRITEL(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE |
735 PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
736 &disp_ctrl->cmd.disp_pow_ctrl);
737
738 reg_val = tegra_sor_readl(sor, NV_SOR_TEST);
739 if (reg_val & NV_SOR_TEST_ATTACHED_TRUE)
740 return;
741
742 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
743 NV_SOR_SUPER_STATE1_ATTACHED_NO);
744
745 /*
746 * Enable display2sor clock at least 2 cycles before DC start,
747 * to clear sor internal valid signal.
748 */
749
750 /* Stop dc for 3 cycles */
751 WRITEL(0, &disp_ctrl->disp.disp_win_opt);
752 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
753 udelay(FRAME_IN_MS * 1000 * 3);
754
755 /* Attach head */
756 tegra_dc_sor_update(sor);
757 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
758 NV_SOR_SUPER_STATE1_ATTACHED_YES);
759 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
760 NV_SOR_SUPER_STATE1_ATTACHED_YES |
761 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_AWAKE |
762 NV_SOR_SUPER_STATE1_ASY_ORMODE_NORMAL);
763 tegra_dc_sor_super_update(sor);
764
765 /* wait for another 5 cycles */
766 udelay(FRAME_IN_MS * 1000 * 5);
767
768 /* Re-enable dc */
769 WRITEL(READ_MUX_ACTIVE | WRITE_MUX_ACTIVE,
770 &disp_ctrl->cmd.state_access);
771 WRITEL(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
772
773 WRITEL(DISP_CTRL_MODE_C_DISPLAY, &disp_ctrl->cmd.disp_cmd);
774 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
775
776 if (tegra_dc_sor_poll_register(sor, NV_SOR_TEST,
777 NV_SOR_TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
778 NV_SOR_TEST_ACT_HEAD_OPMODE_AWAKE,
779 100, TEGRA_SOR_ATTACH_TIMEOUT_MS * 1000))
780 printk(BIOS_ERR, "dc timeout waiting for OPMOD = AWAKE\n");
781 else
782 printk(BIOS_INFO, "%s: sor is attached\n", __func__);
783
784#if DEBUG_SOR
785 dump_sor_reg(sor);
786#endif
787}
788
789void tegra_dc_sor_set_lane_parm(struct tegra_dc_sor_data *sor,
790 const struct tegra_dc_dp_link_config *link_cfg)
791{
792 tegra_sor_writel(sor, NV_SOR_LANE_DRIVE_CURRENT(sor->portnum),
793 link_cfg->drive_current);
794 tegra_sor_writel(sor, NV_SOR_PR(sor->portnum),
795 link_cfg->preemphasis);
796 tegra_sor_writel(sor, NV_SOR_POSTCURSOR(sor->portnum),
797 link_cfg->postcursor);
798 tegra_sor_writel(sor, NV_SOR_LVDS, 0);
799
800 tegra_dc_sor_set_link_bandwidth(sor, link_cfg->link_bw);
801 tegra_dc_sor_set_lane_count(sor, link_cfg->lane_count);
802
803 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
804 NV_SOR_DP_PADCTL_TX_PU_ENABLE |
805 NV_SOR_DP_PADCTL_TX_PU_VALUE_DEFAULT_MASK,
806 NV_SOR_DP_PADCTL_TX_PU_ENABLE |
807 2 << NV_SOR_DP_PADCTL_TX_PU_VALUE_SHIFT);
808
809 /* Precharge */
810 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
811 0xf0, 0xf0);
812 udelay(20);
813
814 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
815 0xf0, 0x0);
816}
817
818void tegra_dc_sor_set_voltage_swing(struct tegra_dc_sor_data *sor)
819{
820 u32 drive_current = 0;
821 u32 pre_emphasis = 0;
822
823 /* Set to a known-good pre-calibrated setting */
824 switch (sor->link_cfg->link_bw) {
825 case SOR_LINK_SPEED_G1_62:
826 case SOR_LINK_SPEED_G2_7:
827 drive_current = 0x13131313;
828 pre_emphasis = 0;
829 break;
830 case SOR_LINK_SPEED_G5_4:
831 printk(BIOS_WARNING, "T1xx does not support 5.4G link"
832 " clock.\n");
833 default:
834 printk(BIOS_WARNING, "Invalid sor link bandwidth: %d\n",
835 sor->link_cfg->link_bw);
836 return;
837 }
838
839 tegra_sor_writel(sor, NV_SOR_LANE_DRIVE_CURRENT(sor->portnum),
840 drive_current);
841 tegra_sor_writel(sor, NV_SOR_PR(sor->portnum), pre_emphasis);
842}
843
844void tegra_dc_sor_power_down_unused_lanes(struct tegra_dc_sor_data *sor)
845{
846 u32 pad_ctrl = 0;
847 int err = 0;
848
849 switch (sor->link_cfg->lane_count) {
850 case 4:
851 pad_ctrl = (NV_SOR_DP_PADCTL_PD_TXD_0_NO |
852 NV_SOR_DP_PADCTL_PD_TXD_1_NO |
853 NV_SOR_DP_PADCTL_PD_TXD_2_NO |
854 NV_SOR_DP_PADCTL_PD_TXD_3_NO);
855 break;
856 case 2:
857 pad_ctrl = (NV_SOR_DP_PADCTL_PD_TXD_0_NO |
858 NV_SOR_DP_PADCTL_PD_TXD_1_NO |
859 NV_SOR_DP_PADCTL_PD_TXD_2_YES |
860 NV_SOR_DP_PADCTL_PD_TXD_3_YES);
861 break;
862 case 1:
863 pad_ctrl = (NV_SOR_DP_PADCTL_PD_TXD_0_NO |
864 NV_SOR_DP_PADCTL_PD_TXD_1_YES |
865 NV_SOR_DP_PADCTL_PD_TXD_2_YES |
866 NV_SOR_DP_PADCTL_PD_TXD_3_YES);
867 break;
868 default:
869 printk(BIOS_ERR, "Invalid sor lane count: %u\n",
870 sor->link_cfg->lane_count);
871 return;
872 }
873
874 pad_ctrl |= NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN;
875 tegra_sor_writel(sor, NV_SOR_DP_PADCTL(sor->portnum), pad_ctrl);
876
877 err = tegra_dc_sor_enable_lane_sequencer(sor, 0, 0);
878 if (err) {
879 printk(BIOS_ERR,
880 "Wait for lane power down failed: %d\n", err);
881 return;
882 }
883}
884
885void tegra_sor_precharge_lanes(struct tegra_dc_sor_data *sor)
886{
887 const struct tegra_dc_dp_link_config *cfg = sor->link_cfg;
888 u32 val = 0;
889
890 switch (cfg->lane_count) {
891 case 4:
892 val |= (NV_SOR_DP_PADCTL_PD_TXD_3_NO |
893 NV_SOR_DP_PADCTL_PD_TXD_2_NO);
894 /* fall through */
895 case 2:
896 val |= NV_SOR_DP_PADCTL_PD_TXD_1_NO;
897 /* fall through */
898 case 1:
899 val |= NV_SOR_DP_PADCTL_PD_TXD_0_NO;
900 break;
901 default:
902 printk(BIOS_ERR,
903 "dp: invalid lane number %d\n", cfg->lane_count);
904 return;
905 }
906
907 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
908 (0xf << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT),
909 (val << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT));
910 udelay(100);
911 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
912 (0xf << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT), 0);
913}
914
915static u32 tegra_dc_poll_register(void *reg,
916 u32 mask, u32 exp_val, u32 poll_interval_us, u32 timeout_us)
917{
918 u32 temp = timeout_us;
919 u32 reg_val = 0;
920
921 do {
922 udelay(poll_interval_us);
923 reg_val = READL(reg);
924 if (timeout_us > poll_interval_us)
925 timeout_us -= poll_interval_us;
926 else
927 break;
928 } while ((reg_val & mask) != exp_val);
929
930 if ((reg_val & mask) == exp_val)
931 return 0; /* success */
932
933 return temp;
934}
935
936static void tegra_dc_sor_general_act(struct display_controller *disp_ctrl)
937{
938 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
939
940 if (tegra_dc_poll_register(&disp_ctrl->cmd.state_ctrl,
941 GENERAL_ACT_REQ, 0, 100,
942 TEGRA_DC_POLL_TIMEOUT_MS*1000))
943 printk(BIOS_ERR,
944 "dc timeout waiting for DC to stop\n");
945}
946
947static struct tegra_dc_mode min_mode = {
948 .h_ref_to_sync = 0,
949 .v_ref_to_sync = 1,
950 .h_sync_width = 1,
951 .v_sync_width = 1,
952 .h_back_porch = 20,
953 .v_back_porch = 0,
954 .h_active = 16,
955 .v_active = 16,
956 .h_front_porch = 1,
957 .v_front_porch = 2,
958};
959
960/* Disable windows and set minimum raster timings */
961static void
962tegra_dc_sor_disable_win_short_raster(struct display_controller *disp_ctrl,
963 int *dc_reg_ctx)
964{
965 int selected_windows, i;
966
967 selected_windows = READL(&disp_ctrl->cmd.disp_win_header);
968
969 /* Store and clear window options */
970 for (i = 0; i < DC_N_WINDOWS; ++i) {
971 WRITEL(WINDOW_A_SELECT << i, &disp_ctrl->cmd.disp_win_header);
972 dc_reg_ctx[i] = READL(&disp_ctrl->win.win_opt);
973 WRITEL(0, &disp_ctrl->win.win_opt);
974 WRITEL(WIN_A_ACT_REQ << i, &disp_ctrl->cmd.state_ctrl);
975 }
976
977 WRITEL(selected_windows, &disp_ctrl->cmd.disp_win_header);
978
979 /* Store current raster timings and set minimum timings */
980 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.ref_to_sync);
981 WRITEL(min_mode.h_ref_to_sync | (min_mode.v_ref_to_sync << 16),
982 &disp_ctrl->disp.ref_to_sync);
983
984 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.sync_width);
985 WRITEL(min_mode.h_sync_width | (min_mode.v_sync_width << 16),
986 &disp_ctrl->disp.sync_width);
987
988 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.back_porch);
989 WRITEL(min_mode.h_back_porch |
990 min_mode.v_back_porch << 16,
991 &disp_ctrl->disp.back_porch);
992
993 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.front_porch);
994 WRITEL(min_mode.h_front_porch |
995 min_mode.v_front_porch << 16,
996 &disp_ctrl->disp.front_porch);
997
998 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.disp_active);
999 WRITEL(min_mode.h_active | (min_mode.v_active << 16),
1000 &disp_ctrl->disp.disp_active);
1001
1002 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
1003}
1004
1005/* Restore previous windows status and raster timings */
1006static void
1007tegra_dc_sor_restore_win_and_raster(struct display_controller *disp_ctrl,
1008 int *dc_reg_ctx)
1009{
1010 int selected_windows, i;
1011
1012 selected_windows = READL(&disp_ctrl->cmd.disp_win_header);
1013
1014 for (i = 0; i < DC_N_WINDOWS; ++i) {
1015 WRITEL(WINDOW_A_SELECT << i, &disp_ctrl->cmd.disp_win_header);
1016 WRITEL(dc_reg_ctx[i], &disp_ctrl->win.win_opt);
1017 WRITEL(WIN_A_ACT_REQ << i, &disp_ctrl->cmd.state_ctrl);
1018 }
1019
1020 WRITEL(selected_windows, &disp_ctrl->cmd.disp_win_header);
1021
1022 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.ref_to_sync);
1023 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.sync_width);
1024 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.back_porch);
1025 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.front_porch);
1026 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.disp_active);
1027
1028 WRITEL(GENERAL_UPDATE, &disp_ctrl->cmd.state_ctrl);
1029}
1030
1031static void tegra_dc_sor_enable_sor(struct tegra_dc_sor_data *sor, int enable)
1032{
1033 struct display_controller *disp_ctrl = (void *)sor->dc->base;
1034 u32 reg_val = READL(&disp_ctrl->disp.disp_win_opt);
1035
1036 reg_val = enable ? reg_val | SOR_ENABLE : reg_val & ~SOR_ENABLE;
1037 WRITEL(reg_val, &disp_ctrl->disp.disp_win_opt);
1038}
1039
1040void tegra_dc_detach(struct tegra_dc_sor_data *sor)
1041{
1042 struct display_controller *disp_ctrl = (void *)sor->dc->base;
1043 int dc_reg_ctx[DC_N_WINDOWS + 5];
1044 unsigned long dc_int_mask;
1045
1046 /* Sleep mode */
1047 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
1048 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SLEEP |
1049 NV_SOR_SUPER_STATE1_ASY_ORMODE_SAFE |
1050 NV_SOR_SUPER_STATE1_ATTACHED_YES);
1051 tegra_dc_sor_super_update(sor);
1052
1053 tegra_dc_sor_disable_win_short_raster(disp_ctrl, dc_reg_ctx);
1054
1055 if (tegra_dc_sor_poll_register(sor, NV_SOR_TEST,
1056 NV_SOR_TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
1057 NV_SOR_TEST_ACT_HEAD_OPMODE_SLEEP,
1058 100, TEGRA_SOR_ATTACH_TIMEOUT_MS*1000)) {
1059 printk(BIOS_ERR,
1060 "dc timeout waiting for OPMOD = SLEEP\n");
1061 }
1062
1063 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
1064 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SLEEP |
1065 NV_SOR_SUPER_STATE1_ASY_ORMODE_SAFE |
1066 NV_SOR_SUPER_STATE1_ATTACHED_NO);
1067
1068 /* Mask DC interrupts during the 2 dummy frames required for detach */
1069 dc_int_mask = READL(&disp_ctrl->cmd.int_mask);
1070 WRITEL(0, &disp_ctrl->cmd.int_mask);
1071
1072 /* Stop DC->SOR path */
1073 tegra_dc_sor_enable_sor(sor, 0);
1074 tegra_dc_sor_general_act(disp_ctrl);
1075
1076 /* Stop DC */
1077 WRITEL(DISP_CTRL_MODE_STOP, &disp_ctrl->cmd.disp_cmd);
1078 tegra_dc_sor_general_act(disp_ctrl);
1079
1080 tegra_dc_sor_restore_win_and_raster(disp_ctrl, dc_reg_ctx);
1081
1082 WRITEL(dc_int_mask, &disp_ctrl->cmd.int_mask);
1083}