blob: eafd0b8a71d2946961f1580b324c4bf90c54dfb7 [file] [log] [blame]
Thierry Reding6b6b6042013-11-15 16:06:05 +01001/*
2 * Copyright (C) 2013 NVIDIA Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk.h>
Thierry Redinga82752e2014-01-31 10:02:15 +010010#include <linux/debugfs.h>
Thierry Reding6b6b6042013-11-15 16:06:05 +010011#include <linux/io.h>
12#include <linux/platform_device.h>
13#include <linux/reset.h>
Thierry Reding306a7f92014-07-17 13:17:24 +020014
15#include <soc/tegra/powergate.h>
Thierry Reding6b6b6042013-11-15 16:06:05 +010016
17#include <drm/drm_dp_helper.h>
18
19#include "dc.h"
20#include "drm.h"
21#include "sor.h"
22
23struct tegra_sor {
24 struct host1x_client client;
25 struct tegra_output output;
26 struct device *dev;
27
28 void __iomem *regs;
29
30 struct reset_control *rst;
31 struct clk *clk_parent;
32 struct clk *clk_safe;
33 struct clk *clk_dp;
34 struct clk *clk;
35
36 struct tegra_dpaux *dpaux;
37
Thierry Reding86f5c522014-03-26 11:13:16 +010038 struct mutex lock;
Thierry Reding6b6b6042013-11-15 16:06:05 +010039 bool enabled;
Thierry Redinga82752e2014-01-31 10:02:15 +010040
41 struct dentry *debugfs;
Thierry Reding6b6b6042013-11-15 16:06:05 +010042};
43
Thierry Reding34fa1832014-06-05 16:31:10 +020044struct tegra_sor_config {
45 u32 bits_per_pixel;
46
47 u32 active_polarity;
48 u32 active_count;
49 u32 tu_size;
50 u32 active_frac;
51 u32 watermark;
Thierry Reding7890b572014-06-05 16:12:46 +020052
53 u32 hblank_symbols;
54 u32 vblank_symbols;
Thierry Reding34fa1832014-06-05 16:31:10 +020055};
56
Thierry Reding6b6b6042013-11-15 16:06:05 +010057static inline struct tegra_sor *
58host1x_client_to_sor(struct host1x_client *client)
59{
60 return container_of(client, struct tegra_sor, client);
61}
62
63static inline struct tegra_sor *to_sor(struct tegra_output *output)
64{
65 return container_of(output, struct tegra_sor, output);
66}
67
68static inline unsigned long tegra_sor_readl(struct tegra_sor *sor,
69 unsigned long offset)
70{
71 return readl(sor->regs + (offset << 2));
72}
73
74static inline void tegra_sor_writel(struct tegra_sor *sor, unsigned long value,
75 unsigned long offset)
76{
77 writel(value, sor->regs + (offset << 2));
78}
79
80static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
81 struct drm_dp_link *link)
82{
83 unsigned long value;
84 unsigned int i;
85 u8 pattern;
86 int err;
87
88 /* setup lane parameters */
89 value = SOR_LANE_DRIVE_CURRENT_LANE3(0x40) |
90 SOR_LANE_DRIVE_CURRENT_LANE2(0x40) |
91 SOR_LANE_DRIVE_CURRENT_LANE1(0x40) |
92 SOR_LANE_DRIVE_CURRENT_LANE0(0x40);
93 tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT_0);
94
95 value = SOR_LANE_PREEMPHASIS_LANE3(0x0f) |
96 SOR_LANE_PREEMPHASIS_LANE2(0x0f) |
97 SOR_LANE_PREEMPHASIS_LANE1(0x0f) |
98 SOR_LANE_PREEMPHASIS_LANE0(0x0f);
99 tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS_0);
100
101 value = SOR_LANE_POST_CURSOR_LANE3(0x00) |
102 SOR_LANE_POST_CURSOR_LANE2(0x00) |
103 SOR_LANE_POST_CURSOR_LANE1(0x00) |
104 SOR_LANE_POST_CURSOR_LANE0(0x00);
105 tegra_sor_writel(sor, value, SOR_LANE_POST_CURSOR_0);
106
107 /* disable LVDS mode */
108 tegra_sor_writel(sor, 0, SOR_LVDS);
109
110 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
111 value |= SOR_DP_PADCTL_TX_PU_ENABLE;
112 value &= ~SOR_DP_PADCTL_TX_PU_MASK;
113 value |= SOR_DP_PADCTL_TX_PU(2); /* XXX: don't hardcode? */
114 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
115
116 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
117 value |= SOR_DP_PADCTL_CM_TXD_3 | SOR_DP_PADCTL_CM_TXD_2 |
118 SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0;
119 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
120
121 usleep_range(10, 100);
122
123 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
124 value &= ~(SOR_DP_PADCTL_CM_TXD_3 | SOR_DP_PADCTL_CM_TXD_2 |
125 SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0);
126 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
127
128 err = tegra_dpaux_prepare(sor->dpaux, DP_SET_ANSI_8B10B);
129 if (err < 0)
130 return err;
131
132 for (i = 0, value = 0; i < link->num_lanes; i++) {
133 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
134 SOR_DP_TPG_SCRAMBLER_NONE |
135 SOR_DP_TPG_PATTERN_TRAIN1;
136 value = (value << 8) | lane;
137 }
138
139 tegra_sor_writel(sor, value, SOR_DP_TPG);
140
141 pattern = DP_TRAINING_PATTERN_1;
142
143 err = tegra_dpaux_train(sor->dpaux, link, pattern);
144 if (err < 0)
145 return err;
146
147 value = tegra_sor_readl(sor, SOR_DP_SPARE_0);
148 value |= SOR_DP_SPARE_SEQ_ENABLE;
149 value &= ~SOR_DP_SPARE_PANEL_INTERNAL;
150 value |= SOR_DP_SPARE_MACRO_SOR_CLK;
151 tegra_sor_writel(sor, value, SOR_DP_SPARE_0);
152
153 for (i = 0, value = 0; i < link->num_lanes; i++) {
154 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
155 SOR_DP_TPG_SCRAMBLER_NONE |
156 SOR_DP_TPG_PATTERN_TRAIN2;
157 value = (value << 8) | lane;
158 }
159
160 tegra_sor_writel(sor, value, SOR_DP_TPG);
161
162 pattern = DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_2;
163
164 err = tegra_dpaux_train(sor->dpaux, link, pattern);
165 if (err < 0)
166 return err;
167
168 for (i = 0, value = 0; i < link->num_lanes; i++) {
169 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
170 SOR_DP_TPG_SCRAMBLER_GALIOS |
171 SOR_DP_TPG_PATTERN_NONE;
172 value = (value << 8) | lane;
173 }
174
175 tegra_sor_writel(sor, value, SOR_DP_TPG);
176
177 pattern = DP_TRAINING_PATTERN_DISABLE;
178
179 err = tegra_dpaux_train(sor->dpaux, link, pattern);
180 if (err < 0)
181 return err;
182
183 return 0;
184}
185
186static void tegra_sor_super_update(struct tegra_sor *sor)
187{
188 tegra_sor_writel(sor, 0, SOR_SUPER_STATE_0);
189 tegra_sor_writel(sor, 1, SOR_SUPER_STATE_0);
190 tegra_sor_writel(sor, 0, SOR_SUPER_STATE_0);
191}
192
193static void tegra_sor_update(struct tegra_sor *sor)
194{
195 tegra_sor_writel(sor, 0, SOR_STATE_0);
196 tegra_sor_writel(sor, 1, SOR_STATE_0);
197 tegra_sor_writel(sor, 0, SOR_STATE_0);
198}
199
200static int tegra_sor_setup_pwm(struct tegra_sor *sor, unsigned long timeout)
201{
202 unsigned long value;
203
204 value = tegra_sor_readl(sor, SOR_PWM_DIV);
205 value &= ~SOR_PWM_DIV_MASK;
206 value |= 0x400; /* period */
207 tegra_sor_writel(sor, value, SOR_PWM_DIV);
208
209 value = tegra_sor_readl(sor, SOR_PWM_CTL);
210 value &= ~SOR_PWM_CTL_DUTY_CYCLE_MASK;
211 value |= 0x400; /* duty cycle */
212 value &= ~SOR_PWM_CTL_CLK_SEL; /* clock source: PCLK */
213 value |= SOR_PWM_CTL_TRIGGER;
214 tegra_sor_writel(sor, value, SOR_PWM_CTL);
215
216 timeout = jiffies + msecs_to_jiffies(timeout);
217
218 while (time_before(jiffies, timeout)) {
219 value = tegra_sor_readl(sor, SOR_PWM_CTL);
220 if ((value & SOR_PWM_CTL_TRIGGER) == 0)
221 return 0;
222
223 usleep_range(25, 100);
224 }
225
226 return -ETIMEDOUT;
227}
228
229static int tegra_sor_attach(struct tegra_sor *sor)
230{
231 unsigned long value, timeout;
232
233 /* wake up in normal mode */
234 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
235 value |= SOR_SUPER_STATE_HEAD_MODE_AWAKE;
236 value |= SOR_SUPER_STATE_MODE_NORMAL;
237 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
238 tegra_sor_super_update(sor);
239
240 /* attach */
241 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
242 value |= SOR_SUPER_STATE_ATTACHED;
243 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
244 tegra_sor_super_update(sor);
245
246 timeout = jiffies + msecs_to_jiffies(250);
247
248 while (time_before(jiffies, timeout)) {
249 value = tegra_sor_readl(sor, SOR_TEST);
250 if ((value & SOR_TEST_ATTACHED) != 0)
251 return 0;
252
253 usleep_range(25, 100);
254 }
255
256 return -ETIMEDOUT;
257}
258
259static int tegra_sor_wakeup(struct tegra_sor *sor)
260{
261 struct tegra_dc *dc = to_tegra_dc(sor->output.encoder.crtc);
262 unsigned long value, timeout;
263
264 /* enable display controller outputs */
265 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
266 value |= PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
267 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE;
268 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
269
270 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
271 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
272
273 timeout = jiffies + msecs_to_jiffies(250);
274
275 /* wait for head to wake up */
276 while (time_before(jiffies, timeout)) {
277 value = tegra_sor_readl(sor, SOR_TEST);
278 value &= SOR_TEST_HEAD_MODE_MASK;
279
280 if (value == SOR_TEST_HEAD_MODE_AWAKE)
281 return 0;
282
283 usleep_range(25, 100);
284 }
285
286 return -ETIMEDOUT;
287}
288
289static int tegra_sor_power_up(struct tegra_sor *sor, unsigned long timeout)
290{
291 unsigned long value;
292
293 value = tegra_sor_readl(sor, SOR_PWR);
294 value |= SOR_PWR_TRIGGER | SOR_PWR_NORMAL_STATE_PU;
295 tegra_sor_writel(sor, value, SOR_PWR);
296
297 timeout = jiffies + msecs_to_jiffies(timeout);
298
299 while (time_before(jiffies, timeout)) {
300 value = tegra_sor_readl(sor, SOR_PWR);
301 if ((value & SOR_PWR_TRIGGER) == 0)
302 return 0;
303
304 usleep_range(25, 100);
305 }
306
307 return -ETIMEDOUT;
308}
309
Thierry Reding34fa1832014-06-05 16:31:10 +0200310struct tegra_sor_params {
311 /* number of link clocks per line */
312 unsigned int num_clocks;
313 /* ratio between input and output */
314 u64 ratio;
315 /* precision factor */
316 u64 precision;
317
318 unsigned int active_polarity;
319 unsigned int active_count;
320 unsigned int active_frac;
321 unsigned int tu_size;
322 unsigned int error;
323};
324
325static int tegra_sor_compute_params(struct tegra_sor *sor,
326 struct tegra_sor_params *params,
327 unsigned int tu_size)
328{
329 u64 active_sym, active_count, frac, approx;
330 u32 active_polarity, active_frac = 0;
331 const u64 f = params->precision;
332 s64 error;
333
334 active_sym = params->ratio * tu_size;
335 active_count = div_u64(active_sym, f) * f;
336 frac = active_sym - active_count;
337
338 /* fraction < 0.5 */
339 if (frac >= (f / 2)) {
340 active_polarity = 1;
341 frac = f - frac;
342 } else {
343 active_polarity = 0;
344 }
345
346 if (frac != 0) {
347 frac = div_u64(f * f, frac); /* 1/fraction */
348 if (frac <= (15 * f)) {
349 active_frac = div_u64(frac, f);
350
351 /* round up */
352 if (active_polarity)
353 active_frac++;
354 } else {
355 active_frac = active_polarity ? 1 : 15;
356 }
357 }
358
359 if (active_frac == 1)
360 active_polarity = 0;
361
362 if (active_polarity == 1) {
363 if (active_frac) {
364 approx = active_count + (active_frac * (f - 1)) * f;
365 approx = div_u64(approx, active_frac * f);
366 } else {
367 approx = active_count + f;
368 }
369 } else {
370 if (active_frac)
371 approx = active_count + div_u64(f, active_frac);
372 else
373 approx = active_count;
374 }
375
376 error = div_s64(active_sym - approx, tu_size);
377 error *= params->num_clocks;
378
379 if (error <= 0 && abs64(error) < params->error) {
380 params->active_count = div_u64(active_count, f);
381 params->active_polarity = active_polarity;
382 params->active_frac = active_frac;
383 params->error = abs64(error);
384 params->tu_size = tu_size;
385
386 if (error == 0)
387 return true;
388 }
389
390 return false;
391}
392
393static int tegra_sor_calc_config(struct tegra_sor *sor,
394 struct drm_display_mode *mode,
395 struct tegra_sor_config *config,
396 struct drm_dp_link *link)
397{
398 const u64 f = 100000, link_rate = link->rate * 1000;
399 const u64 pclk = mode->clock * 1000;
Thierry Reding7890b572014-06-05 16:12:46 +0200400 u64 input, output, watermark, num;
Thierry Reding34fa1832014-06-05 16:31:10 +0200401 struct tegra_sor_params params;
Thierry Reding34fa1832014-06-05 16:31:10 +0200402 u32 num_syms_per_line;
403 unsigned int i;
404
405 if (!link_rate || !link->num_lanes || !pclk || !config->bits_per_pixel)
406 return -EINVAL;
407
408 output = link_rate * 8 * link->num_lanes;
409 input = pclk * config->bits_per_pixel;
410
411 if (input >= output)
412 return -ERANGE;
413
414 memset(&params, 0, sizeof(params));
415 params.ratio = div64_u64(input * f, output);
416 params.num_clocks = div_u64(link_rate * mode->hdisplay, pclk);
417 params.precision = f;
418 params.error = 64 * f;
419 params.tu_size = 64;
420
421 for (i = params.tu_size; i >= 32; i--)
422 if (tegra_sor_compute_params(sor, &params, i))
423 break;
424
425 if (params.active_frac == 0) {
426 config->active_polarity = 0;
427 config->active_count = params.active_count;
428
429 if (!params.active_polarity)
430 config->active_count--;
431
432 config->tu_size = params.tu_size;
433 config->active_frac = 1;
434 } else {
435 config->active_polarity = params.active_polarity;
436 config->active_count = params.active_count;
437 config->active_frac = params.active_frac;
438 config->tu_size = params.tu_size;
439 }
440
441 dev_dbg(sor->dev,
442 "polarity: %d active count: %d tu size: %d active frac: %d\n",
443 config->active_polarity, config->active_count,
444 config->tu_size, config->active_frac);
445
446 watermark = params.ratio * config->tu_size * (f - params.ratio);
447 watermark = div_u64(watermark, f);
448
449 watermark = div_u64(watermark + params.error, f);
450 config->watermark = watermark + (config->bits_per_pixel / 8) + 2;
451 num_syms_per_line = (mode->hdisplay * config->bits_per_pixel) *
452 (link->num_lanes * 8);
453
454 if (config->watermark > 30) {
455 config->watermark = 30;
456 dev_err(sor->dev,
457 "unable to compute TU size, forcing watermark to %u\n",
458 config->watermark);
459 } else if (config->watermark > num_syms_per_line) {
460 config->watermark = num_syms_per_line;
461 dev_err(sor->dev, "watermark too high, forcing to %u\n",
462 config->watermark);
463 }
464
Thierry Reding7890b572014-06-05 16:12:46 +0200465 /* compute the number of symbols per horizontal blanking interval */
466 num = ((mode->htotal - mode->hdisplay) - 7) * link_rate;
467 config->hblank_symbols = div_u64(num, pclk);
468
469 if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
470 config->hblank_symbols -= 3;
471
472 config->hblank_symbols -= 12 / link->num_lanes;
473
474 /* compute the number of symbols per vertical blanking interval */
475 num = (mode->hdisplay - 25) * link_rate;
476 config->vblank_symbols = div_u64(num, pclk);
477 config->vblank_symbols -= 36 / link->num_lanes + 4;
478
479 dev_dbg(sor->dev, "blank symbols: H:%u V:%u\n", config->hblank_symbols,
480 config->vblank_symbols);
481
Thierry Reding34fa1832014-06-05 16:31:10 +0200482 return 0;
483}
484
Thierry Reding6b6b6042013-11-15 16:06:05 +0100485static int tegra_output_sor_enable(struct tegra_output *output)
486{
487 struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
488 struct drm_display_mode *mode = &dc->base.mode;
489 unsigned int vbe, vse, hbe, hse, vbs, hbs, i;
490 struct tegra_sor *sor = to_sor(output);
Thierry Reding34fa1832014-06-05 16:31:10 +0200491 struct tegra_sor_config config;
492 struct drm_dp_link link;
493 struct drm_dp_aux *aux;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100494 unsigned long value;
Thierry Reding86f5c522014-03-26 11:13:16 +0100495 int err = 0;
496
497 mutex_lock(&sor->lock);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100498
499 if (sor->enabled)
Thierry Reding86f5c522014-03-26 11:13:16 +0100500 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100501
502 err = clk_prepare_enable(sor->clk);
503 if (err < 0)
Thierry Reding86f5c522014-03-26 11:13:16 +0100504 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100505
506 reset_control_deassert(sor->rst);
507
Thierry Reding34fa1832014-06-05 16:31:10 +0200508 /* FIXME: properly convert to struct drm_dp_aux */
509 aux = (struct drm_dp_aux *)sor->dpaux;
510
Thierry Reding6b6b6042013-11-15 16:06:05 +0100511 if (sor->dpaux) {
512 err = tegra_dpaux_enable(sor->dpaux);
513 if (err < 0)
514 dev_err(sor->dev, "failed to enable DP: %d\n", err);
Thierry Reding34fa1832014-06-05 16:31:10 +0200515
516 err = drm_dp_link_probe(aux, &link);
517 if (err < 0) {
518 dev_err(sor->dev, "failed to probe eDP link: %d\n",
519 err);
520 return err;
521 }
Thierry Reding6b6b6042013-11-15 16:06:05 +0100522 }
523
524 err = clk_set_parent(sor->clk, sor->clk_safe);
525 if (err < 0)
526 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
527
Thierry Reding34fa1832014-06-05 16:31:10 +0200528 memset(&config, 0, sizeof(config));
529 config.bits_per_pixel = 24; /* XXX: don't hardcode? */
530
531 err = tegra_sor_calc_config(sor, mode, &config, &link);
532 if (err < 0)
533 dev_err(sor->dev, "failed to compute link configuration: %d\n",
534 err);
535
Thierry Reding6b6b6042013-11-15 16:06:05 +0100536 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
537 value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;
538 value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK;
539 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
540
541 value = tegra_sor_readl(sor, SOR_PLL_2);
542 value &= ~SOR_PLL_2_BANDGAP_POWERDOWN;
543 tegra_sor_writel(sor, value, SOR_PLL_2);
544 usleep_range(20, 100);
545
546 value = tegra_sor_readl(sor, SOR_PLL_3);
547 value |= SOR_PLL_3_PLL_VDD_MODE_V3_3;
548 tegra_sor_writel(sor, value, SOR_PLL_3);
549
550 value = SOR_PLL_0_ICHPMP(0xf) | SOR_PLL_0_VCOCAP_RST |
551 SOR_PLL_0_PLLREG_LEVEL_V45 | SOR_PLL_0_RESISTOR_EXT;
552 tegra_sor_writel(sor, value, SOR_PLL_0);
553
554 value = tegra_sor_readl(sor, SOR_PLL_2);
555 value |= SOR_PLL_2_SEQ_PLLCAPPD;
556 value &= ~SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
557 value |= SOR_PLL_2_LVDS_ENABLE;
558 tegra_sor_writel(sor, value, SOR_PLL_2);
559
560 value = SOR_PLL_1_TERM_COMPOUT | SOR_PLL_1_TMDS_TERM;
561 tegra_sor_writel(sor, value, SOR_PLL_1);
562
563 while (true) {
564 value = tegra_sor_readl(sor, SOR_PLL_2);
565 if ((value & SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE) == 0)
566 break;
567
568 usleep_range(250, 1000);
569 }
570
571 value = tegra_sor_readl(sor, SOR_PLL_2);
572 value &= ~SOR_PLL_2_POWERDOWN_OVERRIDE;
573 value &= ~SOR_PLL_2_PORT_POWERDOWN;
574 tegra_sor_writel(sor, value, SOR_PLL_2);
575
576 /*
577 * power up
578 */
579
580 /* set safe link bandwidth (1.62 Gbps) */
581 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
582 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
583 value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G1_62;
584 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
585
586 /* step 1 */
587 value = tegra_sor_readl(sor, SOR_PLL_2);
588 value |= SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE | SOR_PLL_2_PORT_POWERDOWN |
589 SOR_PLL_2_BANDGAP_POWERDOWN;
590 tegra_sor_writel(sor, value, SOR_PLL_2);
591
592 value = tegra_sor_readl(sor, SOR_PLL_0);
593 value |= SOR_PLL_0_VCOPD | SOR_PLL_0_POWER_OFF;
594 tegra_sor_writel(sor, value, SOR_PLL_0);
595
596 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
597 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
598 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
599
600 /* step 2 */
601 err = tegra_io_rail_power_on(TEGRA_IO_RAIL_LVDS);
602 if (err < 0) {
603 dev_err(sor->dev, "failed to power on I/O rail: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100604 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100605 }
606
607 usleep_range(5, 100);
608
609 /* step 3 */
610 value = tegra_sor_readl(sor, SOR_PLL_2);
611 value &= ~SOR_PLL_2_BANDGAP_POWERDOWN;
612 tegra_sor_writel(sor, value, SOR_PLL_2);
613
614 usleep_range(20, 100);
615
616 /* step 4 */
617 value = tegra_sor_readl(sor, SOR_PLL_0);
618 value &= ~SOR_PLL_0_POWER_OFF;
619 value &= ~SOR_PLL_0_VCOPD;
620 tegra_sor_writel(sor, value, SOR_PLL_0);
621
622 value = tegra_sor_readl(sor, SOR_PLL_2);
623 value &= ~SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
624 tegra_sor_writel(sor, value, SOR_PLL_2);
625
626 usleep_range(200, 1000);
627
628 /* step 5 */
629 value = tegra_sor_readl(sor, SOR_PLL_2);
630 value &= ~SOR_PLL_2_PORT_POWERDOWN;
631 tegra_sor_writel(sor, value, SOR_PLL_2);
632
633 /* switch to DP clock */
634 err = clk_set_parent(sor->clk, sor->clk_dp);
635 if (err < 0)
636 dev_err(sor->dev, "failed to set DP parent clock: %d\n", err);
637
Thierry Reding899451b2014-06-05 16:19:48 +0200638 /* power DP lanes */
Thierry Reding6b6b6042013-11-15 16:06:05 +0100639 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
Thierry Reding899451b2014-06-05 16:19:48 +0200640
641 if (link.num_lanes <= 2)
642 value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2);
643 else
644 value |= SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2;
645
646 if (link.num_lanes <= 1)
647 value &= ~SOR_DP_PADCTL_PD_TXD_1;
648 else
649 value |= SOR_DP_PADCTL_PD_TXD_1;
650
651 if (link.num_lanes == 0)
652 value &= ~SOR_DP_PADCTL_PD_TXD_0;
653 else
654 value |= SOR_DP_PADCTL_PD_TXD_0;
655
Thierry Reding6b6b6042013-11-15 16:06:05 +0100656 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
657
658 value = tegra_sor_readl(sor, SOR_DP_LINKCTL_0);
659 value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
Thierry Reding0c90a182014-06-05 16:29:46 +0200660 value |= SOR_DP_LINKCTL_LANE_COUNT(link.num_lanes);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100661 tegra_sor_writel(sor, value, SOR_DP_LINKCTL_0);
662
663 /* start lane sequencer */
664 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |
665 SOR_LANE_SEQ_CTL_POWER_STATE_UP;
666 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
667
668 while (true) {
669 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
670 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
671 break;
672
673 usleep_range(250, 1000);
674 }
675
Thierry Redinga4263fe2014-06-05 16:16:23 +0200676 /* set link bandwidth */
Thierry Reding6b6b6042013-11-15 16:06:05 +0100677 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
678 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
Thierry Redinga4263fe2014-06-05 16:16:23 +0200679 value |= drm_dp_link_rate_to_bw_code(link.rate) << 2;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100680 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
681
682 /* set linkctl */
683 value = tegra_sor_readl(sor, SOR_DP_LINKCTL_0);
684 value |= SOR_DP_LINKCTL_ENABLE;
685
686 value &= ~SOR_DP_LINKCTL_TU_SIZE_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +0200687 value |= SOR_DP_LINKCTL_TU_SIZE(config.tu_size);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100688
689 value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
690 tegra_sor_writel(sor, value, SOR_DP_LINKCTL_0);
691
692 for (i = 0, value = 0; i < 4; i++) {
693 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
694 SOR_DP_TPG_SCRAMBLER_GALIOS |
695 SOR_DP_TPG_PATTERN_NONE;
696 value = (value << 8) | lane;
697 }
698
699 tegra_sor_writel(sor, value, SOR_DP_TPG);
700
701 value = tegra_sor_readl(sor, SOR_DP_CONFIG_0);
702 value &= ~SOR_DP_CONFIG_WATERMARK_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +0200703 value |= SOR_DP_CONFIG_WATERMARK(config.watermark);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100704
705 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_COUNT_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +0200706 value |= SOR_DP_CONFIG_ACTIVE_SYM_COUNT(config.active_count);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100707
708 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_FRAC_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +0200709 value |= SOR_DP_CONFIG_ACTIVE_SYM_FRAC(config.active_frac);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100710
Thierry Reding34fa1832014-06-05 16:31:10 +0200711 if (config.active_polarity)
712 value |= SOR_DP_CONFIG_ACTIVE_SYM_POLARITY;
713 else
714 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_POLARITY;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100715
716 value |= SOR_DP_CONFIG_ACTIVE_SYM_ENABLE;
Thierry Reding1f64ae72014-06-05 16:20:27 +0200717 value |= SOR_DP_CONFIG_DISPARITY_NEGATIVE;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100718 tegra_sor_writel(sor, value, SOR_DP_CONFIG_0);
719
720 value = tegra_sor_readl(sor, SOR_DP_AUDIO_HBLANK_SYMBOLS);
721 value &= ~SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK;
Thierry Reding7890b572014-06-05 16:12:46 +0200722 value |= config.hblank_symbols & 0xffff;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100723 tegra_sor_writel(sor, value, SOR_DP_AUDIO_HBLANK_SYMBOLS);
724
725 value = tegra_sor_readl(sor, SOR_DP_AUDIO_VBLANK_SYMBOLS);
726 value &= ~SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK;
Thierry Reding7890b572014-06-05 16:12:46 +0200727 value |= config.vblank_symbols & 0xffff;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100728 tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS);
729
730 /* enable pad calibration logic */
731 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
732 value |= SOR_DP_PADCTL_PAD_CAL_PD;
733 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
734
735 if (sor->dpaux) {
Thierry Reding6b6b6042013-11-15 16:06:05 +0100736 u8 rate, lanes;
737
738 err = drm_dp_link_probe(aux, &link);
739 if (err < 0) {
740 dev_err(sor->dev, "failed to probe eDP link: %d\n",
741 err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100742 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100743 }
744
745 err = drm_dp_link_power_up(aux, &link);
746 if (err < 0) {
747 dev_err(sor->dev, "failed to power up eDP link: %d\n",
748 err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100749 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100750 }
751
752 err = drm_dp_link_configure(aux, &link);
753 if (err < 0) {
754 dev_err(sor->dev, "failed to configure eDP link: %d\n",
755 err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100756 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100757 }
758
759 rate = drm_dp_link_rate_to_bw_code(link.rate);
760 lanes = link.num_lanes;
761
762 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
763 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
764 value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate);
765 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
766
767 value = tegra_sor_readl(sor, SOR_DP_LINKCTL_0);
768 value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
769 value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
770
771 if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
772 value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
773
774 tegra_sor_writel(sor, value, SOR_DP_LINKCTL_0);
775
776 /* disable training pattern generator */
777
778 for (i = 0; i < link.num_lanes; i++) {
779 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
780 SOR_DP_TPG_SCRAMBLER_GALIOS |
781 SOR_DP_TPG_PATTERN_NONE;
782 value = (value << 8) | lane;
783 }
784
785 tegra_sor_writel(sor, value, SOR_DP_TPG);
786
787 err = tegra_sor_dp_train_fast(sor, &link);
788 if (err < 0) {
789 dev_err(sor->dev, "DP fast link training failed: %d\n",
790 err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100791 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100792 }
793
794 dev_dbg(sor->dev, "fast link training succeeded\n");
795 }
796
797 err = tegra_sor_power_up(sor, 250);
798 if (err < 0) {
799 dev_err(sor->dev, "failed to power up SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100800 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100801 }
802
803 /* start display controller in continuous mode */
804 value = tegra_dc_readl(dc, DC_CMD_STATE_ACCESS);
805 value |= WRITE_MUX;
806 tegra_dc_writel(dc, value, DC_CMD_STATE_ACCESS);
807
808 tegra_dc_writel(dc, VSYNC_H_POSITION(1), DC_DISP_DISP_TIMING_OPTIONS);
809 tegra_dc_writel(dc, DISP_CTRL_MODE_C_DISPLAY, DC_CMD_DISPLAY_COMMAND);
810
811 value = tegra_dc_readl(dc, DC_CMD_STATE_ACCESS);
812 value &= ~WRITE_MUX;
813 tegra_dc_writel(dc, value, DC_CMD_STATE_ACCESS);
814
815 /*
816 * configure panel (24bpp, vsync-, hsync-, DP-A protocol, complete
817 * raster, associate with display controller)
818 */
Thierry Reding34fa1832014-06-05 16:31:10 +0200819 value = SOR_STATE_ASY_VSYNCPOL |
Thierry Reding6b6b6042013-11-15 16:06:05 +0100820 SOR_STATE_ASY_HSYNCPOL |
821 SOR_STATE_ASY_PROTOCOL_DP_A |
822 SOR_STATE_ASY_CRC_MODE_COMPLETE |
823 SOR_STATE_ASY_OWNER(dc->pipe + 1);
Thierry Reding34fa1832014-06-05 16:31:10 +0200824
825 switch (config.bits_per_pixel) {
826 case 24:
827 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;
828 break;
829
830 case 18:
831 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444;
832 break;
833
834 default:
835 BUG();
836 break;
837 }
838
Thierry Reding6b6b6042013-11-15 16:06:05 +0100839 tegra_sor_writel(sor, value, SOR_STATE_1);
840
841 /*
842 * TODO: The video timing programming below doesn't seem to match the
843 * register definitions.
844 */
845
846 value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff);
847 tegra_sor_writel(sor, value, SOR_HEAD_STATE_1(0));
848
849 vse = mode->vsync_end - mode->vsync_start - 1;
850 hse = mode->hsync_end - mode->hsync_start - 1;
851
852 value = ((vse & 0x7fff) << 16) | (hse & 0x7fff);
853 tegra_sor_writel(sor, value, SOR_HEAD_STATE_2(0));
854
855 vbe = vse + (mode->vsync_start - mode->vdisplay);
856 hbe = hse + (mode->hsync_start - mode->hdisplay);
857
858 value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff);
859 tegra_sor_writel(sor, value, SOR_HEAD_STATE_3(0));
860
861 vbs = vbe + mode->vdisplay;
862 hbs = hbe + mode->hdisplay;
863
864 value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff);
865 tegra_sor_writel(sor, value, SOR_HEAD_STATE_4(0));
866
Thierry Reding6b6b6042013-11-15 16:06:05 +0100867 /* CSTM (LVDS, link A/B, upper) */
Stéphane Marchesin143b1df2014-05-22 20:32:47 -0700868 value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B |
Thierry Reding6b6b6042013-11-15 16:06:05 +0100869 SOR_CSTM_UPPER;
870 tegra_sor_writel(sor, value, SOR_CSTM);
871
872 /* PWM setup */
873 err = tegra_sor_setup_pwm(sor, 250);
874 if (err < 0) {
875 dev_err(sor->dev, "failed to setup PWM: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100876 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100877 }
878
879 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
880 value |= SOR_ENABLE;
881 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
882
883 tegra_sor_update(sor);
884
885 err = tegra_sor_attach(sor);
886 if (err < 0) {
887 dev_err(sor->dev, "failed to attach SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100888 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100889 }
890
891 err = tegra_sor_wakeup(sor);
892 if (err < 0) {
893 dev_err(sor->dev, "failed to enable DC: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100894 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100895 }
896
897 sor->enabled = true;
898
Thierry Reding86f5c522014-03-26 11:13:16 +0100899unlock:
900 mutex_unlock(&sor->lock);
901 return err;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100902}
903
904static int tegra_sor_detach(struct tegra_sor *sor)
905{
906 unsigned long value, timeout;
907
908 /* switch to safe mode */
909 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
910 value &= ~SOR_SUPER_STATE_MODE_NORMAL;
911 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
912 tegra_sor_super_update(sor);
913
914 timeout = jiffies + msecs_to_jiffies(250);
915
916 while (time_before(jiffies, timeout)) {
917 value = tegra_sor_readl(sor, SOR_PWR);
918 if (value & SOR_PWR_MODE_SAFE)
919 break;
920 }
921
922 if ((value & SOR_PWR_MODE_SAFE) == 0)
923 return -ETIMEDOUT;
924
925 /* go to sleep */
926 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
927 value &= ~SOR_SUPER_STATE_HEAD_MODE_MASK;
928 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
929 tegra_sor_super_update(sor);
930
931 /* detach */
932 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
933 value &= ~SOR_SUPER_STATE_ATTACHED;
934 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
935 tegra_sor_super_update(sor);
936
937 timeout = jiffies + msecs_to_jiffies(250);
938
939 while (time_before(jiffies, timeout)) {
940 value = tegra_sor_readl(sor, SOR_TEST);
941 if ((value & SOR_TEST_ATTACHED) == 0)
942 break;
943
944 usleep_range(25, 100);
945 }
946
947 if ((value & SOR_TEST_ATTACHED) != 0)
948 return -ETIMEDOUT;
949
950 return 0;
951}
952
953static int tegra_sor_power_down(struct tegra_sor *sor)
954{
955 unsigned long value, timeout;
956 int err;
957
958 value = tegra_sor_readl(sor, SOR_PWR);
959 value &= ~SOR_PWR_NORMAL_STATE_PU;
960 value |= SOR_PWR_TRIGGER;
961 tegra_sor_writel(sor, value, SOR_PWR);
962
963 timeout = jiffies + msecs_to_jiffies(250);
964
965 while (time_before(jiffies, timeout)) {
966 value = tegra_sor_readl(sor, SOR_PWR);
967 if ((value & SOR_PWR_TRIGGER) == 0)
968 return 0;
969
970 usleep_range(25, 100);
971 }
972
973 if ((value & SOR_PWR_TRIGGER) != 0)
974 return -ETIMEDOUT;
975
976 err = clk_set_parent(sor->clk, sor->clk_safe);
977 if (err < 0)
978 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
979
980 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
981 value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
982 SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2);
983 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
984
985 /* stop lane sequencer */
Stéphane Marchesinca185c62014-05-22 20:32:48 -0700986 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_UP |
Thierry Reding6b6b6042013-11-15 16:06:05 +0100987 SOR_LANE_SEQ_CTL_POWER_STATE_DOWN;
988 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
989
990 timeout = jiffies + msecs_to_jiffies(250);
991
992 while (time_before(jiffies, timeout)) {
993 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
994 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
995 break;
996
997 usleep_range(25, 100);
998 }
999
1000 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)
1001 return -ETIMEDOUT;
1002
1003 value = tegra_sor_readl(sor, SOR_PLL_2);
1004 value |= SOR_PLL_2_PORT_POWERDOWN;
1005 tegra_sor_writel(sor, value, SOR_PLL_2);
1006
1007 usleep_range(20, 100);
1008
1009 value = tegra_sor_readl(sor, SOR_PLL_0);
1010 value |= SOR_PLL_0_POWER_OFF;
1011 value |= SOR_PLL_0_VCOPD;
1012 tegra_sor_writel(sor, value, SOR_PLL_0);
1013
1014 value = tegra_sor_readl(sor, SOR_PLL_2);
1015 value |= SOR_PLL_2_SEQ_PLLCAPPD;
1016 value |= SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
1017 tegra_sor_writel(sor, value, SOR_PLL_2);
1018
1019 usleep_range(20, 100);
1020
1021 return 0;
1022}
1023
1024static int tegra_output_sor_disable(struct tegra_output *output)
1025{
1026 struct tegra_dc *dc = to_tegra_dc(output->encoder.crtc);
1027 struct tegra_sor *sor = to_sor(output);
1028 unsigned long value;
Thierry Reding86f5c522014-03-26 11:13:16 +01001029 int err = 0;
1030
1031 mutex_lock(&sor->lock);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001032
1033 if (!sor->enabled)
Thierry Reding86f5c522014-03-26 11:13:16 +01001034 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001035
1036 err = tegra_sor_detach(sor);
1037 if (err < 0) {
1038 dev_err(sor->dev, "failed to detach SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001039 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001040 }
1041
1042 tegra_sor_writel(sor, 0, SOR_STATE_1);
1043 tegra_sor_update(sor);
1044
1045 /*
1046 * The following accesses registers of the display controller, so make
1047 * sure it's only executed when the output is attached to one.
1048 */
1049 if (dc) {
1050 /*
1051 * XXX: We can't do this here because it causes the SOR to go
1052 * into an erroneous state and the output will look scrambled
1053 * the next time it is enabled. Presumably this is because we
1054 * should be doing this only on the next VBLANK. A possible
1055 * solution would be to queue a "power-off" event to trigger
1056 * this code to be run during the next VBLANK.
1057 */
1058 /*
1059 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_POWER_CONTROL);
1060 value &= ~(PW0_ENABLE | PW1_ENABLE | PW2_ENABLE | PW3_ENABLE |
1061 PW4_ENABLE | PM0_ENABLE | PM1_ENABLE);
1062 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_POWER_CONTROL);
1063 */
1064
1065 value = tegra_dc_readl(dc, DC_CMD_DISPLAY_COMMAND);
1066 value &= ~DISP_CTRL_MODE_MASK;
1067 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_COMMAND);
1068
1069 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
1070 value &= ~SOR_ENABLE;
1071 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
1072
1073 tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
1074 tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
1075 }
1076
1077 err = tegra_sor_power_down(sor);
1078 if (err < 0) {
1079 dev_err(sor->dev, "failed to power down SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001080 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001081 }
1082
1083 if (sor->dpaux) {
1084 err = tegra_dpaux_disable(sor->dpaux);
1085 if (err < 0) {
1086 dev_err(sor->dev, "failed to disable DP: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001087 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001088 }
1089 }
1090
1091 err = tegra_io_rail_power_off(TEGRA_IO_RAIL_LVDS);
1092 if (err < 0) {
1093 dev_err(sor->dev, "failed to power off I/O rail: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001094 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001095 }
1096
1097 reset_control_assert(sor->rst);
1098 clk_disable_unprepare(sor->clk);
1099
1100 sor->enabled = false;
1101
Thierry Reding86f5c522014-03-26 11:13:16 +01001102unlock:
1103 mutex_unlock(&sor->lock);
1104 return err;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001105}
1106
1107static int tegra_output_sor_setup_clock(struct tegra_output *output,
Thierry Reding91eded92014-03-26 13:32:21 +01001108 struct clk *clk, unsigned long pclk,
1109 unsigned int *div)
Thierry Reding6b6b6042013-11-15 16:06:05 +01001110{
1111 struct tegra_sor *sor = to_sor(output);
1112 int err;
1113
Thierry Reding6b6b6042013-11-15 16:06:05 +01001114 err = clk_set_parent(clk, sor->clk_parent);
1115 if (err < 0) {
1116 dev_err(sor->dev, "failed to set parent clock: %d\n", err);
1117 return err;
1118 }
1119
1120 err = clk_set_rate(sor->clk_parent, pclk);
1121 if (err < 0) {
Thierry Reding91eded92014-03-26 13:32:21 +01001122 dev_err(sor->dev, "failed to set clock rate to %lu Hz\n", pclk);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001123 return err;
1124 }
1125
Thierry Reding91eded92014-03-26 13:32:21 +01001126 *div = 0;
1127
Thierry Reding6b6b6042013-11-15 16:06:05 +01001128 return 0;
1129}
1130
1131static int tegra_output_sor_check_mode(struct tegra_output *output,
1132 struct drm_display_mode *mode,
1133 enum drm_mode_status *status)
1134{
1135 /*
1136 * FIXME: For now, always assume that the mode is okay.
1137 */
1138
1139 *status = MODE_OK;
1140
1141 return 0;
1142}
1143
1144static enum drm_connector_status
1145tegra_output_sor_detect(struct tegra_output *output)
1146{
1147 struct tegra_sor *sor = to_sor(output);
1148
1149 if (sor->dpaux)
1150 return tegra_dpaux_detect(sor->dpaux);
1151
1152 return connector_status_unknown;
1153}
1154
1155static const struct tegra_output_ops sor_ops = {
1156 .enable = tegra_output_sor_enable,
1157 .disable = tegra_output_sor_disable,
1158 .setup_clock = tegra_output_sor_setup_clock,
1159 .check_mode = tegra_output_sor_check_mode,
1160 .detect = tegra_output_sor_detect,
1161};
1162
Thierry Redinga82752e2014-01-31 10:02:15 +01001163static int tegra_sor_crc_open(struct inode *inode, struct file *file)
1164{
1165 file->private_data = inode->i_private;
1166
1167 return 0;
1168}
1169
1170static int tegra_sor_crc_release(struct inode *inode, struct file *file)
1171{
1172 return 0;
1173}
1174
1175static int tegra_sor_crc_wait(struct tegra_sor *sor, unsigned long timeout)
1176{
1177 u32 value;
1178
1179 timeout = jiffies + msecs_to_jiffies(timeout);
1180
1181 while (time_before(jiffies, timeout)) {
1182 value = tegra_sor_readl(sor, SOR_CRC_A);
1183 if (value & SOR_CRC_A_VALID)
1184 return 0;
1185
1186 usleep_range(100, 200);
1187 }
1188
1189 return -ETIMEDOUT;
1190}
1191
1192static ssize_t tegra_sor_crc_read(struct file *file, char __user *buffer,
1193 size_t size, loff_t *ppos)
1194{
1195 struct tegra_sor *sor = file->private_data;
Thierry Reding86f5c522014-03-26 11:13:16 +01001196 ssize_t num, err;
Thierry Redinga82752e2014-01-31 10:02:15 +01001197 char buf[10];
Thierry Redinga82752e2014-01-31 10:02:15 +01001198 u32 value;
Thierry Reding86f5c522014-03-26 11:13:16 +01001199
1200 mutex_lock(&sor->lock);
1201
1202 if (!sor->enabled) {
1203 err = -EAGAIN;
1204 goto unlock;
1205 }
Thierry Redinga82752e2014-01-31 10:02:15 +01001206
1207 value = tegra_sor_readl(sor, SOR_STATE_1);
1208 value &= ~SOR_STATE_ASY_CRC_MODE_MASK;
1209 tegra_sor_writel(sor, value, SOR_STATE_1);
1210
1211 value = tegra_sor_readl(sor, SOR_CRC_CNTRL);
1212 value |= SOR_CRC_CNTRL_ENABLE;
1213 tegra_sor_writel(sor, value, SOR_CRC_CNTRL);
1214
1215 value = tegra_sor_readl(sor, SOR_TEST);
1216 value &= ~SOR_TEST_CRC_POST_SERIALIZE;
1217 tegra_sor_writel(sor, value, SOR_TEST);
1218
1219 err = tegra_sor_crc_wait(sor, 100);
1220 if (err < 0)
Thierry Reding86f5c522014-03-26 11:13:16 +01001221 goto unlock;
Thierry Redinga82752e2014-01-31 10:02:15 +01001222
1223 tegra_sor_writel(sor, SOR_CRC_A_RESET, SOR_CRC_A);
1224 value = tegra_sor_readl(sor, SOR_CRC_B);
1225
1226 num = scnprintf(buf, sizeof(buf), "%08x\n", value);
1227
Thierry Reding86f5c522014-03-26 11:13:16 +01001228 err = simple_read_from_buffer(buffer, size, ppos, buf, num);
1229
1230unlock:
1231 mutex_unlock(&sor->lock);
1232 return err;
Thierry Redinga82752e2014-01-31 10:02:15 +01001233}
1234
1235static const struct file_operations tegra_sor_crc_fops = {
1236 .owner = THIS_MODULE,
1237 .open = tegra_sor_crc_open,
1238 .read = tegra_sor_crc_read,
1239 .release = tegra_sor_crc_release,
1240};
1241
Thierry Reding1b0c7b42014-05-28 13:46:12 +02001242static int tegra_sor_debugfs_init(struct tegra_sor *sor,
1243 struct drm_minor *minor)
Thierry Redinga82752e2014-01-31 10:02:15 +01001244{
1245 struct dentry *entry;
1246 int err = 0;
1247
Thierry Reding1b0c7b42014-05-28 13:46:12 +02001248 sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root);
Thierry Redinga82752e2014-01-31 10:02:15 +01001249 if (!sor->debugfs)
1250 return -ENOMEM;
1251
1252 entry = debugfs_create_file("crc", 0644, sor->debugfs, sor,
1253 &tegra_sor_crc_fops);
1254 if (!entry) {
1255 dev_err(sor->dev,
1256 "cannot create /sys/kernel/debug/dri/%s/sor/crc\n",
Thierry Reding1b0c7b42014-05-28 13:46:12 +02001257 minor->debugfs_root->d_name.name);
Thierry Redinga82752e2014-01-31 10:02:15 +01001258 err = -ENOMEM;
1259 goto remove;
1260 }
1261
1262 return err;
1263
1264remove:
1265 debugfs_remove(sor->debugfs);
1266 sor->debugfs = NULL;
1267 return err;
1268}
1269
1270static int tegra_sor_debugfs_exit(struct tegra_sor *sor)
1271{
Thierry Reding95781842014-04-25 16:48:36 +02001272 debugfs_remove_recursive(sor->debugfs);
Thierry Redinga82752e2014-01-31 10:02:15 +01001273 sor->debugfs = NULL;
1274
1275 return 0;
1276}
1277
Thierry Reding6b6b6042013-11-15 16:06:05 +01001278static int tegra_sor_init(struct host1x_client *client)
1279{
Thierry Reding9910f5c2014-05-22 09:57:15 +02001280 struct drm_device *drm = dev_get_drvdata(client->parent);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001281 struct tegra_sor *sor = host1x_client_to_sor(client);
1282 int err;
1283
1284 if (!sor->dpaux)
1285 return -ENODEV;
1286
1287 sor->output.type = TEGRA_OUTPUT_EDP;
1288
1289 sor->output.dev = sor->dev;
1290 sor->output.ops = &sor_ops;
1291
Thierry Reding9910f5c2014-05-22 09:57:15 +02001292 err = tegra_output_init(drm, &sor->output);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001293 if (err < 0) {
1294 dev_err(sor->dev, "output setup failed: %d\n", err);
1295 return err;
1296 }
1297
Thierry Redinga82752e2014-01-31 10:02:15 +01001298 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
Thierry Reding1b0c7b42014-05-28 13:46:12 +02001299 err = tegra_sor_debugfs_init(sor, drm->primary);
Thierry Redinga82752e2014-01-31 10:02:15 +01001300 if (err < 0)
1301 dev_err(sor->dev, "debugfs setup failed: %d\n", err);
1302 }
1303
Thierry Reding6b6b6042013-11-15 16:06:05 +01001304 if (sor->dpaux) {
1305 err = tegra_dpaux_attach(sor->dpaux, &sor->output);
1306 if (err < 0) {
1307 dev_err(sor->dev, "failed to attach DP: %d\n", err);
1308 return err;
1309 }
1310 }
1311
1312 return 0;
1313}
1314
1315static int tegra_sor_exit(struct host1x_client *client)
1316{
1317 struct tegra_sor *sor = host1x_client_to_sor(client);
1318 int err;
1319
1320 err = tegra_output_disable(&sor->output);
1321 if (err < 0) {
1322 dev_err(sor->dev, "output failed to disable: %d\n", err);
1323 return err;
1324 }
1325
1326 if (sor->dpaux) {
1327 err = tegra_dpaux_detach(sor->dpaux);
1328 if (err < 0) {
1329 dev_err(sor->dev, "failed to detach DP: %d\n", err);
1330 return err;
1331 }
1332 }
1333
Thierry Redinga82752e2014-01-31 10:02:15 +01001334 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
1335 err = tegra_sor_debugfs_exit(sor);
1336 if (err < 0)
1337 dev_err(sor->dev, "debugfs cleanup failed: %d\n", err);
1338 }
1339
Thierry Reding6b6b6042013-11-15 16:06:05 +01001340 err = tegra_output_exit(&sor->output);
1341 if (err < 0) {
1342 dev_err(sor->dev, "output cleanup failed: %d\n", err);
1343 return err;
1344 }
1345
1346 return 0;
1347}
1348
1349static const struct host1x_client_ops sor_client_ops = {
1350 .init = tegra_sor_init,
1351 .exit = tegra_sor_exit,
1352};
1353
1354static int tegra_sor_probe(struct platform_device *pdev)
1355{
1356 struct device_node *np;
1357 struct tegra_sor *sor;
1358 struct resource *regs;
1359 int err;
1360
1361 sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL);
1362 if (!sor)
1363 return -ENOMEM;
1364
1365 sor->output.dev = sor->dev = &pdev->dev;
1366
1367 np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0);
1368 if (np) {
1369 sor->dpaux = tegra_dpaux_find_by_of_node(np);
1370 of_node_put(np);
1371
1372 if (!sor->dpaux)
1373 return -EPROBE_DEFER;
1374 }
1375
1376 err = tegra_output_probe(&sor->output);
1377 if (err < 0)
1378 return err;
1379
1380 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1381 sor->regs = devm_ioremap_resource(&pdev->dev, regs);
1382 if (IS_ERR(sor->regs))
1383 return PTR_ERR(sor->regs);
1384
1385 sor->rst = devm_reset_control_get(&pdev->dev, "sor");
1386 if (IS_ERR(sor->rst))
1387 return PTR_ERR(sor->rst);
1388
1389 sor->clk = devm_clk_get(&pdev->dev, NULL);
1390 if (IS_ERR(sor->clk))
1391 return PTR_ERR(sor->clk);
1392
1393 sor->clk_parent = devm_clk_get(&pdev->dev, "parent");
1394 if (IS_ERR(sor->clk_parent))
1395 return PTR_ERR(sor->clk_parent);
1396
1397 err = clk_prepare_enable(sor->clk_parent);
1398 if (err < 0)
1399 return err;
1400
1401 sor->clk_safe = devm_clk_get(&pdev->dev, "safe");
1402 if (IS_ERR(sor->clk_safe))
1403 return PTR_ERR(sor->clk_safe);
1404
1405 err = clk_prepare_enable(sor->clk_safe);
1406 if (err < 0)
1407 return err;
1408
1409 sor->clk_dp = devm_clk_get(&pdev->dev, "dp");
1410 if (IS_ERR(sor->clk_dp))
1411 return PTR_ERR(sor->clk_dp);
1412
1413 err = clk_prepare_enable(sor->clk_dp);
1414 if (err < 0)
1415 return err;
1416
1417 INIT_LIST_HEAD(&sor->client.list);
1418 sor->client.ops = &sor_client_ops;
1419 sor->client.dev = &pdev->dev;
1420
Thierry Reding86f5c522014-03-26 11:13:16 +01001421 mutex_init(&sor->lock);
1422
Thierry Reding6b6b6042013-11-15 16:06:05 +01001423 err = host1x_client_register(&sor->client);
1424 if (err < 0) {
1425 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1426 err);
1427 return err;
1428 }
1429
1430 platform_set_drvdata(pdev, sor);
1431
1432 return 0;
1433}
1434
1435static int tegra_sor_remove(struct platform_device *pdev)
1436{
1437 struct tegra_sor *sor = platform_get_drvdata(pdev);
1438 int err;
1439
1440 err = host1x_client_unregister(&sor->client);
1441 if (err < 0) {
1442 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
1443 err);
1444 return err;
1445 }
1446
1447 clk_disable_unprepare(sor->clk_parent);
1448 clk_disable_unprepare(sor->clk_safe);
1449 clk_disable_unprepare(sor->clk_dp);
1450 clk_disable_unprepare(sor->clk);
1451
1452 return 0;
1453}
1454
1455static const struct of_device_id tegra_sor_of_match[] = {
1456 { .compatible = "nvidia,tegra124-sor", },
1457 { },
1458};
1459
1460struct platform_driver tegra_sor_driver = {
1461 .driver = {
1462 .name = "tegra-sor",
1463 .of_match_table = tegra_sor_of_match,
1464 },
1465 .probe = tegra_sor_probe,
1466 .remove = tegra_sor_remove,
1467};