blob: fe89d147aa20f17dc575d7f1993c38975bbdbe88 [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);
Patrick Georgi40a3e322015-06-22 19:41:29 +0200582}
583#endif
584
585static void tegra_dc_sor_config_panel(struct tegra_dc_sor_data *sor,
586 int is_lvds)
587{
588 const struct tegra_dc *dc = sor->dc;
589 const struct tegra_dc_dp_data *dp = dc->out;
590 const struct tegra_dc_dp_link_config *link_cfg = &dp->link_cfg;
591 const struct soc_nvidia_tegra210_config *config = dc->config;
592
593 const int head_num = 0;
594 u32 reg_val = NV_SOR_STATE1_ASY_OWNER_HEAD0 << head_num;
595 u32 vsync_end, hsync_end;
596 u32 vblank_end, hblank_end;
597 u32 vblank_start, hblank_start;
598
599 reg_val |= is_lvds ? NV_SOR_STATE1_ASY_PROTOCOL_LVDS_CUSTOM :
600 NV_SOR_STATE1_ASY_PROTOCOL_DP_A;
601 reg_val |= NV_SOR_STATE1_ASY_SUBOWNER_NONE |
602 NV_SOR_STATE1_ASY_CRCMODE_COMPLETE_RASTER;
603
604 reg_val |= NV_SOR_STATE1_ASY_HSYNCPOL_NEGATIVE_TRUE;
605 reg_val |= NV_SOR_STATE1_ASY_VSYNCPOL_NEGATIVE_TRUE;
606 reg_val |= (link_cfg->bits_per_pixel > 18) ?
607 NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_24_444 :
608 NV_SOR_STATE1_ASY_PIXELDEPTH_BPP_18_444;
609
610 tegra_sor_writel(sor, NV_SOR_STATE1, reg_val);
611
612 /* Skipping programming NV_HEAD_STATE0, assuming:
613 interlacing: PROGRESSIVE, dynamic range: VESA, colorspace: RGB */
614
615 tegra_sor_writel(sor, NV_HEAD_STATE1(head_num),
616 vtotal(config) << NV_HEAD_STATE1_VTOTAL_SHIFT |
617 htotal(config) << NV_HEAD_STATE1_HTOTAL_SHIFT);
618
619 vsync_end = config->vsync_width - 1;
620 hsync_end = config->hsync_width - 1;
621 tegra_sor_writel(sor, NV_HEAD_STATE2(head_num),
622 vsync_end << NV_HEAD_STATE2_VSYNC_END_SHIFT |
623 hsync_end << NV_HEAD_STATE2_HSYNC_END_SHIFT);
624
625 vblank_end = vsync_end + config->vback_porch;
626 hblank_end = hsync_end + config->hback_porch;
627 tegra_sor_writel(sor, NV_HEAD_STATE3(head_num),
628 vblank_end << NV_HEAD_STATE3_VBLANK_END_SHIFT |
629 hblank_end << NV_HEAD_STATE3_HBLANK_END_SHIFT);
630
631 vblank_start = vblank_end + config->yres;
632 hblank_start = hblank_end + config->xres;
633 tegra_sor_writel(sor, NV_HEAD_STATE4(head_num),
634 vblank_start << NV_HEAD_STATE4_VBLANK_START_SHIFT |
635 hblank_start << NV_HEAD_STATE4_HBLANK_START_SHIFT);
636
637 /* TODO: adding interlace mode support */
638 tegra_sor_writel(sor, NV_HEAD_STATE5(head_num), 0x1);
639
640 tegra_sor_write_field(sor, NV_SOR_CSTM,
641 NV_SOR_CSTM_ROTCLK_DEFAULT_MASK |
642 NV_SOR_CSTM_LVDS_EN_ENABLE,
643 2 << NV_SOR_CSTM_ROTCLK_SHIFT |
644 is_lvds ? NV_SOR_CSTM_LVDS_EN_ENABLE :
645 NV_SOR_CSTM_LVDS_EN_DISABLE);
646
647 tegra_dc_sor_config_pwm(sor, 1024, 1024);
648}
649
650static void tegra_dc_sor_enable_dc(struct tegra_dc_sor_data *sor)
651{
652 struct tegra_dc *dc = sor->dc;
653 struct display_controller *disp_ctrl = (void *)dc->base;
654
655 u32 reg_val = READL(&disp_ctrl->cmd.state_access);
656
657 WRITEL(reg_val | WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
658 WRITEL(VSYNC_H_POSITION(1), &disp_ctrl->disp.disp_timing_opt);
659
660 /* Enable DC now - otherwise pure text console may not show. */
661 WRITEL(DISP_CTRL_MODE_C_DISPLAY, &disp_ctrl->cmd.disp_cmd);
662 WRITEL(reg_val, &disp_ctrl->cmd.state_access);
663}
664
665void tegra_dc_sor_enable_dp(struct tegra_dc_sor_data *sor)
666{
667 const struct tegra_dc_dp_link_config *link_cfg = sor->link_cfg;
668
669 tegra_sor_write_field(sor, NV_SOR_CLK_CNTRL,
670 NV_SOR_CLK_CNTRL_DP_CLK_SEL_MASK,
671 NV_SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK);
672
673 tegra_sor_write_field(sor, NV_SOR_PLL2,
674 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_MASK,
675 NV_SOR_PLL2_AUX6_BANDGAP_POWERDOWN_DISABLE);
676 udelay(25);
677
678 tegra_sor_write_field(sor, NV_SOR_PLL3,
679 NV_SOR_PLL3_PLLVDD_MODE_MASK,
680 NV_SOR_PLL3_PLLVDD_MODE_V3_3);
681 tegra_sor_writel(sor, NV_SOR_PLL0,
682 0xf << NV_SOR_PLL0_ICHPMP_SHFIT |
683 0x3 << NV_SOR_PLL0_VCOCAP_SHIFT |
684 NV_SOR_PLL0_PLLREG_LEVEL_V45 |
685 NV_SOR_PLL0_RESISTORSEL_EXT |
686 NV_SOR_PLL0_PWR_ON | NV_SOR_PLL0_VCOPD_RESCIND);
687 tegra_sor_write_field(sor, NV_SOR_PLL2,
688 NV_SOR_PLL2_AUX1_SEQ_MASK | NV_SOR_PLL2_AUX9_LVDSEN_OVERRIDE |
689 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
690 NV_SOR_PLL2_AUX1_SEQ_PLLCAPPD_OVERRIDE |
691 NV_SOR_PLL2_AUX9_LVDSEN_OVERRIDE |
692 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE);
693 tegra_sor_writel(sor, NV_SOR_PLL1,
694 NV_SOR_PLL1_TERM_COMPOUT_HIGH | NV_SOR_PLL1_TMDS_TERM_ENABLE);
695
696 if (tegra_dc_sor_poll_register(sor, NV_SOR_PLL2,
697 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_MASK,
698 NV_SOR_PLL2_AUX8_SEQ_PLLCAPPD_ENFORCE_DISABLE,
699 100, TEGRA_SOR_TIMEOUT_MS * 1000)) {
700 printk(BIOS_ERR, "DP failed to lock PLL\n");
701 return;
702 }
703
704 tegra_sor_write_field(sor, NV_SOR_PLL2,
705 NV_SOR_PLL2_AUX2_MASK | NV_SOR_PLL2_AUX7_PORT_POWERDOWN_MASK,
706 NV_SOR_PLL2_AUX2_OVERRIDE_POWERDOWN |
707 NV_SOR_PLL2_AUX7_PORT_POWERDOWN_DISABLE);
708
709 tegra_dc_sor_power_up(sor, 0);
710
711 /* re-enable SOR clock */
712 tegra_sor_enable_edp_clock(sor); /* select pll_dp as clock source */
713
714 /* Power up lanes */
715 tegra_dc_sor_power_dplanes(sor, link_cfg->lane_count, 1);
716
717 tegra_dc_sor_set_dp_mode(sor, link_cfg);
718
719}
720
721void tegra_dc_sor_attach(struct tegra_dc_sor_data *sor)
722{
723 u32 reg_val;
724 struct display_controller *disp_ctrl = (void *)sor->dc->base;
725
726 tegra_dc_sor_enable_dc(sor);
727 tegra_dc_sor_config_panel(sor, 0);
728
729 WRITEL(0x9f00, &disp_ctrl->cmd.state_ctrl);
730 WRITEL(0x9f, &disp_ctrl->cmd.state_ctrl);
731
732 WRITEL(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE |
733 PW3_ENABLE | PW4_ENABLE | PM0_ENABLE | PM1_ENABLE,
734 &disp_ctrl->cmd.disp_pow_ctrl);
735
736 reg_val = tegra_sor_readl(sor, NV_SOR_TEST);
737 if (reg_val & NV_SOR_TEST_ATTACHED_TRUE)
738 return;
739
740 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
741 NV_SOR_SUPER_STATE1_ATTACHED_NO);
742
743 /*
744 * Enable display2sor clock at least 2 cycles before DC start,
745 * to clear sor internal valid signal.
746 */
747
748 /* Stop dc for 3 cycles */
749 WRITEL(0, &disp_ctrl->disp.disp_win_opt);
750 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
751 udelay(FRAME_IN_MS * 1000 * 3);
752
753 /* Attach head */
754 tegra_dc_sor_update(sor);
755 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
756 NV_SOR_SUPER_STATE1_ATTACHED_YES);
757 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
758 NV_SOR_SUPER_STATE1_ATTACHED_YES |
759 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_AWAKE |
760 NV_SOR_SUPER_STATE1_ASY_ORMODE_NORMAL);
761 tegra_dc_sor_super_update(sor);
762
763 /* wait for another 5 cycles */
764 udelay(FRAME_IN_MS * 1000 * 5);
765
766 /* Re-enable dc */
767 WRITEL(READ_MUX_ACTIVE | WRITE_MUX_ACTIVE,
768 &disp_ctrl->cmd.state_access);
769 WRITEL(SOR_ENABLE, &disp_ctrl->disp.disp_win_opt);
770
771 WRITEL(DISP_CTRL_MODE_C_DISPLAY, &disp_ctrl->cmd.disp_cmd);
772 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
773
774 if (tegra_dc_sor_poll_register(sor, NV_SOR_TEST,
775 NV_SOR_TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
776 NV_SOR_TEST_ACT_HEAD_OPMODE_AWAKE,
777 100, TEGRA_SOR_ATTACH_TIMEOUT_MS * 1000))
778 printk(BIOS_ERR, "dc timeout waiting for OPMOD = AWAKE\n");
779 else
780 printk(BIOS_INFO, "%s: sor is attached\n", __func__);
781
782#if DEBUG_SOR
783 dump_sor_reg(sor);
784#endif
785}
786
787void tegra_dc_sor_set_lane_parm(struct tegra_dc_sor_data *sor,
788 const struct tegra_dc_dp_link_config *link_cfg)
789{
790 tegra_sor_writel(sor, NV_SOR_LANE_DRIVE_CURRENT(sor->portnum),
791 link_cfg->drive_current);
792 tegra_sor_writel(sor, NV_SOR_PR(sor->portnum),
793 link_cfg->preemphasis);
794 tegra_sor_writel(sor, NV_SOR_POSTCURSOR(sor->portnum),
795 link_cfg->postcursor);
796 tegra_sor_writel(sor, NV_SOR_LVDS, 0);
797
798 tegra_dc_sor_set_link_bandwidth(sor, link_cfg->link_bw);
799 tegra_dc_sor_set_lane_count(sor, link_cfg->lane_count);
800
801 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
802 NV_SOR_DP_PADCTL_TX_PU_ENABLE |
803 NV_SOR_DP_PADCTL_TX_PU_VALUE_DEFAULT_MASK,
804 NV_SOR_DP_PADCTL_TX_PU_ENABLE |
805 2 << NV_SOR_DP_PADCTL_TX_PU_VALUE_SHIFT);
806
807 /* Precharge */
808 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
809 0xf0, 0xf0);
810 udelay(20);
811
812 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
813 0xf0, 0x0);
814}
815
816void tegra_dc_sor_set_voltage_swing(struct tegra_dc_sor_data *sor)
817{
818 u32 drive_current = 0;
819 u32 pre_emphasis = 0;
820
821 /* Set to a known-good pre-calibrated setting */
822 switch (sor->link_cfg->link_bw) {
823 case SOR_LINK_SPEED_G1_62:
824 case SOR_LINK_SPEED_G2_7:
825 drive_current = 0x13131313;
826 pre_emphasis = 0;
827 break;
828 case SOR_LINK_SPEED_G5_4:
829 printk(BIOS_WARNING, "T1xx does not support 5.4G link"
830 " clock.\n");
831 default:
832 printk(BIOS_WARNING, "Invalid sor link bandwidth: %d\n",
833 sor->link_cfg->link_bw);
834 return;
835 }
836
837 tegra_sor_writel(sor, NV_SOR_LANE_DRIVE_CURRENT(sor->portnum),
838 drive_current);
839 tegra_sor_writel(sor, NV_SOR_PR(sor->portnum), pre_emphasis);
840}
841
842void tegra_dc_sor_power_down_unused_lanes(struct tegra_dc_sor_data *sor)
843{
844 u32 pad_ctrl = 0;
845 int err = 0;
846
847 switch (sor->link_cfg->lane_count) {
848 case 4:
849 pad_ctrl = (NV_SOR_DP_PADCTL_PD_TXD_0_NO |
850 NV_SOR_DP_PADCTL_PD_TXD_1_NO |
851 NV_SOR_DP_PADCTL_PD_TXD_2_NO |
852 NV_SOR_DP_PADCTL_PD_TXD_3_NO);
853 break;
854 case 2:
855 pad_ctrl = (NV_SOR_DP_PADCTL_PD_TXD_0_NO |
856 NV_SOR_DP_PADCTL_PD_TXD_1_NO |
857 NV_SOR_DP_PADCTL_PD_TXD_2_YES |
858 NV_SOR_DP_PADCTL_PD_TXD_3_YES);
859 break;
860 case 1:
861 pad_ctrl = (NV_SOR_DP_PADCTL_PD_TXD_0_NO |
862 NV_SOR_DP_PADCTL_PD_TXD_1_YES |
863 NV_SOR_DP_PADCTL_PD_TXD_2_YES |
864 NV_SOR_DP_PADCTL_PD_TXD_3_YES);
865 break;
866 default:
867 printk(BIOS_ERR, "Invalid sor lane count: %u\n",
868 sor->link_cfg->lane_count);
869 return;
870 }
871
872 pad_ctrl |= NV_SOR_DP_PADCTL_PAD_CAL_PD_POWERDOWN;
873 tegra_sor_writel(sor, NV_SOR_DP_PADCTL(sor->portnum), pad_ctrl);
874
875 err = tegra_dc_sor_enable_lane_sequencer(sor, 0, 0);
876 if (err) {
877 printk(BIOS_ERR,
878 "Wait for lane power down failed: %d\n", err);
879 return;
880 }
881}
882
883void tegra_sor_precharge_lanes(struct tegra_dc_sor_data *sor)
884{
885 const struct tegra_dc_dp_link_config *cfg = sor->link_cfg;
886 u32 val = 0;
887
888 switch (cfg->lane_count) {
889 case 4:
890 val |= (NV_SOR_DP_PADCTL_PD_TXD_3_NO |
891 NV_SOR_DP_PADCTL_PD_TXD_2_NO);
892 /* fall through */
893 case 2:
894 val |= NV_SOR_DP_PADCTL_PD_TXD_1_NO;
895 /* fall through */
896 case 1:
897 val |= NV_SOR_DP_PADCTL_PD_TXD_0_NO;
898 break;
899 default:
900 printk(BIOS_ERR,
901 "dp: invalid lane number %d\n", cfg->lane_count);
902 return;
903 }
904
905 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
906 (0xf << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT),
907 (val << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT));
908 udelay(100);
909 tegra_sor_write_field(sor, NV_SOR_DP_PADCTL(sor->portnum),
910 (0xf << NV_SOR_DP_PADCTL_COMODE_TXD_0_DP_TXD_2_SHIFT), 0);
911}
912
913static u32 tegra_dc_poll_register(void *reg,
914 u32 mask, u32 exp_val, u32 poll_interval_us, u32 timeout_us)
915{
916 u32 temp = timeout_us;
917 u32 reg_val = 0;
918
919 do {
920 udelay(poll_interval_us);
921 reg_val = READL(reg);
922 if (timeout_us > poll_interval_us)
923 timeout_us -= poll_interval_us;
924 else
925 break;
926 } while ((reg_val & mask) != exp_val);
927
928 if ((reg_val & mask) == exp_val)
929 return 0; /* success */
930
931 return temp;
932}
933
934static void tegra_dc_sor_general_act(struct display_controller *disp_ctrl)
935{
936 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
937
938 if (tegra_dc_poll_register(&disp_ctrl->cmd.state_ctrl,
939 GENERAL_ACT_REQ, 0, 100,
940 TEGRA_DC_POLL_TIMEOUT_MS*1000))
941 printk(BIOS_ERR,
942 "dc timeout waiting for DC to stop\n");
943}
944
945static struct tegra_dc_mode min_mode = {
946 .h_ref_to_sync = 0,
947 .v_ref_to_sync = 1,
948 .h_sync_width = 1,
949 .v_sync_width = 1,
950 .h_back_porch = 20,
951 .v_back_porch = 0,
952 .h_active = 16,
953 .v_active = 16,
954 .h_front_porch = 1,
955 .v_front_porch = 2,
956};
957
958/* Disable windows and set minimum raster timings */
959static void
960tegra_dc_sor_disable_win_short_raster(struct display_controller *disp_ctrl,
961 int *dc_reg_ctx)
962{
963 int selected_windows, i;
964
965 selected_windows = READL(&disp_ctrl->cmd.disp_win_header);
966
967 /* Store and clear window options */
968 for (i = 0; i < DC_N_WINDOWS; ++i) {
969 WRITEL(WINDOW_A_SELECT << i, &disp_ctrl->cmd.disp_win_header);
970 dc_reg_ctx[i] = READL(&disp_ctrl->win.win_opt);
971 WRITEL(0, &disp_ctrl->win.win_opt);
972 WRITEL(WIN_A_ACT_REQ << i, &disp_ctrl->cmd.state_ctrl);
973 }
974
975 WRITEL(selected_windows, &disp_ctrl->cmd.disp_win_header);
976
977 /* Store current raster timings and set minimum timings */
978 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.ref_to_sync);
979 WRITEL(min_mode.h_ref_to_sync | (min_mode.v_ref_to_sync << 16),
980 &disp_ctrl->disp.ref_to_sync);
981
982 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.sync_width);
983 WRITEL(min_mode.h_sync_width | (min_mode.v_sync_width << 16),
984 &disp_ctrl->disp.sync_width);
985
986 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.back_porch);
987 WRITEL(min_mode.h_back_porch |
988 min_mode.v_back_porch << 16,
989 &disp_ctrl->disp.back_porch);
990
991 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.front_porch);
992 WRITEL(min_mode.h_front_porch |
993 min_mode.v_front_porch << 16,
994 &disp_ctrl->disp.front_porch);
995
996 dc_reg_ctx[i++] = READL(&disp_ctrl->disp.disp_active);
997 WRITEL(min_mode.h_active | (min_mode.v_active << 16),
998 &disp_ctrl->disp.disp_active);
999
1000 WRITEL(GENERAL_ACT_REQ, &disp_ctrl->cmd.state_ctrl);
1001}
1002
1003/* Restore previous windows status and raster timings */
1004static void
1005tegra_dc_sor_restore_win_and_raster(struct display_controller *disp_ctrl,
1006 int *dc_reg_ctx)
1007{
1008 int selected_windows, i;
1009
1010 selected_windows = READL(&disp_ctrl->cmd.disp_win_header);
1011
1012 for (i = 0; i < DC_N_WINDOWS; ++i) {
1013 WRITEL(WINDOW_A_SELECT << i, &disp_ctrl->cmd.disp_win_header);
1014 WRITEL(dc_reg_ctx[i], &disp_ctrl->win.win_opt);
1015 WRITEL(WIN_A_ACT_REQ << i, &disp_ctrl->cmd.state_ctrl);
1016 }
1017
1018 WRITEL(selected_windows, &disp_ctrl->cmd.disp_win_header);
1019
1020 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.ref_to_sync);
1021 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.sync_width);
1022 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.back_porch);
1023 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.front_porch);
1024 WRITEL(dc_reg_ctx[i++], &disp_ctrl->disp.disp_active);
1025
1026 WRITEL(GENERAL_UPDATE, &disp_ctrl->cmd.state_ctrl);
1027}
1028
1029static void tegra_dc_sor_enable_sor(struct tegra_dc_sor_data *sor, int enable)
1030{
1031 struct display_controller *disp_ctrl = (void *)sor->dc->base;
1032 u32 reg_val = READL(&disp_ctrl->disp.disp_win_opt);
1033
1034 reg_val = enable ? reg_val | SOR_ENABLE : reg_val & ~SOR_ENABLE;
1035 WRITEL(reg_val, &disp_ctrl->disp.disp_win_opt);
1036}
1037
1038void tegra_dc_detach(struct tegra_dc_sor_data *sor)
1039{
1040 struct display_controller *disp_ctrl = (void *)sor->dc->base;
1041 int dc_reg_ctx[DC_N_WINDOWS + 5];
1042 unsigned long dc_int_mask;
1043
1044 /* Sleep mode */
1045 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
1046 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SLEEP |
1047 NV_SOR_SUPER_STATE1_ASY_ORMODE_SAFE |
1048 NV_SOR_SUPER_STATE1_ATTACHED_YES);
1049 tegra_dc_sor_super_update(sor);
1050
1051 tegra_dc_sor_disable_win_short_raster(disp_ctrl, dc_reg_ctx);
1052
1053 if (tegra_dc_sor_poll_register(sor, NV_SOR_TEST,
1054 NV_SOR_TEST_ACT_HEAD_OPMODE_DEFAULT_MASK,
1055 NV_SOR_TEST_ACT_HEAD_OPMODE_SLEEP,
1056 100, TEGRA_SOR_ATTACH_TIMEOUT_MS*1000)) {
1057 printk(BIOS_ERR,
1058 "dc timeout waiting for OPMOD = SLEEP\n");
1059 }
1060
1061 tegra_sor_writel(sor, NV_SOR_SUPER_STATE1,
1062 NV_SOR_SUPER_STATE1_ASY_HEAD_OP_SLEEP |
1063 NV_SOR_SUPER_STATE1_ASY_ORMODE_SAFE |
1064 NV_SOR_SUPER_STATE1_ATTACHED_NO);
1065
1066 /* Mask DC interrupts during the 2 dummy frames required for detach */
1067 dc_int_mask = READL(&disp_ctrl->cmd.int_mask);
1068 WRITEL(0, &disp_ctrl->cmd.int_mask);
1069
1070 /* Stop DC->SOR path */
1071 tegra_dc_sor_enable_sor(sor, 0);
1072 tegra_dc_sor_general_act(disp_ctrl);
1073
1074 /* Stop DC */
1075 WRITEL(DISP_CTRL_MODE_STOP, &disp_ctrl->cmd.disp_cmd);
1076 tegra_dc_sor_general_act(disp_ctrl);
1077
1078 tegra_dc_sor_restore_win_and_raster(disp_ctrl, dc_reg_ctx);
1079
1080 WRITEL(dc_int_mask, &disp_ctrl->cmd.int_mask);
1081}