blob: 59b8aec1aeaed3015f5cde9b34004ebf8c7d12c2 [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 Reding6fad8f62014-11-28 15:41:34 +010011#include <linux/gpio.h>
Thierry Reding6b6b6042013-11-15 16:06:05 +010012#include <linux/io.h>
13#include <linux/platform_device.h>
14#include <linux/reset.h>
Thierry Reding306a7f92014-07-17 13:17:24 +020015
Thierry Reding72323982014-07-11 13:19:06 +020016#include <soc/tegra/pmc.h>
Thierry Reding6b6b6042013-11-15 16:06:05 +010017
Thierry Reding4aa3df72014-11-24 16:27:13 +010018#include <drm/drm_atomic_helper.h>
Thierry Reding6b6b6042013-11-15 16:06:05 +010019#include <drm/drm_dp_helper.h>
Thierry Reding6fad8f62014-11-28 15:41:34 +010020#include <drm/drm_panel.h>
Thierry Reding6b6b6042013-11-15 16:06:05 +010021
22#include "dc.h"
23#include "drm.h"
24#include "sor.h"
25
26struct tegra_sor {
27 struct host1x_client client;
28 struct tegra_output output;
29 struct device *dev;
30
31 void __iomem *regs;
32
33 struct reset_control *rst;
34 struct clk *clk_parent;
35 struct clk *clk_safe;
36 struct clk *clk_dp;
37 struct clk *clk;
38
39 struct tegra_dpaux *dpaux;
40
Thierry Reding86f5c522014-03-26 11:13:16 +010041 struct mutex lock;
Thierry Reding6b6b6042013-11-15 16:06:05 +010042 bool enabled;
Thierry Redinga82752e2014-01-31 10:02:15 +010043
44 struct dentry *debugfs;
Thierry Reding6b6b6042013-11-15 16:06:05 +010045};
46
Thierry Reding34fa1832014-06-05 16:31:10 +020047struct tegra_sor_config {
48 u32 bits_per_pixel;
49
50 u32 active_polarity;
51 u32 active_count;
52 u32 tu_size;
53 u32 active_frac;
54 u32 watermark;
Thierry Reding7890b572014-06-05 16:12:46 +020055
56 u32 hblank_symbols;
57 u32 vblank_symbols;
Thierry Reding34fa1832014-06-05 16:31:10 +020058};
59
Thierry Reding6b6b6042013-11-15 16:06:05 +010060static inline struct tegra_sor *
61host1x_client_to_sor(struct host1x_client *client)
62{
63 return container_of(client, struct tegra_sor, client);
64}
65
66static inline struct tegra_sor *to_sor(struct tegra_output *output)
67{
68 return container_of(output, struct tegra_sor, output);
69}
70
Thierry Reding28fe2072015-01-26 16:02:48 +010071static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned long offset)
Thierry Reding6b6b6042013-11-15 16:06:05 +010072{
73 return readl(sor->regs + (offset << 2));
74}
75
Thierry Reding28fe2072015-01-26 16:02:48 +010076static inline void tegra_sor_writel(struct tegra_sor *sor, u32 value,
Thierry Reding6b6b6042013-11-15 16:06:05 +010077 unsigned long offset)
78{
79 writel(value, sor->regs + (offset << 2));
80}
81
82static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
83 struct drm_dp_link *link)
84{
Thierry Reding6b6b6042013-11-15 16:06:05 +010085 unsigned int i;
86 u8 pattern;
Thierry Reding28fe2072015-01-26 16:02:48 +010087 u32 value;
Thierry Reding6b6b6042013-11-15 16:06:05 +010088 int err;
89
90 /* setup lane parameters */
91 value = SOR_LANE_DRIVE_CURRENT_LANE3(0x40) |
92 SOR_LANE_DRIVE_CURRENT_LANE2(0x40) |
93 SOR_LANE_DRIVE_CURRENT_LANE1(0x40) |
94 SOR_LANE_DRIVE_CURRENT_LANE0(0x40);
95 tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT_0);
96
97 value = SOR_LANE_PREEMPHASIS_LANE3(0x0f) |
98 SOR_LANE_PREEMPHASIS_LANE2(0x0f) |
99 SOR_LANE_PREEMPHASIS_LANE1(0x0f) |
100 SOR_LANE_PREEMPHASIS_LANE0(0x0f);
101 tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS_0);
102
103 value = SOR_LANE_POST_CURSOR_LANE3(0x00) |
104 SOR_LANE_POST_CURSOR_LANE2(0x00) |
105 SOR_LANE_POST_CURSOR_LANE1(0x00) |
106 SOR_LANE_POST_CURSOR_LANE0(0x00);
107 tegra_sor_writel(sor, value, SOR_LANE_POST_CURSOR_0);
108
109 /* disable LVDS mode */
110 tegra_sor_writel(sor, 0, SOR_LVDS);
111
112 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
113 value |= SOR_DP_PADCTL_TX_PU_ENABLE;
114 value &= ~SOR_DP_PADCTL_TX_PU_MASK;
115 value |= SOR_DP_PADCTL_TX_PU(2); /* XXX: don't hardcode? */
116 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
117
118 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
119 value |= SOR_DP_PADCTL_CM_TXD_3 | SOR_DP_PADCTL_CM_TXD_2 |
120 SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0;
121 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
122
123 usleep_range(10, 100);
124
125 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
126 value &= ~(SOR_DP_PADCTL_CM_TXD_3 | SOR_DP_PADCTL_CM_TXD_2 |
127 SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0);
128 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
129
130 err = tegra_dpaux_prepare(sor->dpaux, DP_SET_ANSI_8B10B);
131 if (err < 0)
132 return err;
133
134 for (i = 0, value = 0; i < link->num_lanes; i++) {
135 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
136 SOR_DP_TPG_SCRAMBLER_NONE |
137 SOR_DP_TPG_PATTERN_TRAIN1;
138 value = (value << 8) | lane;
139 }
140
141 tegra_sor_writel(sor, value, SOR_DP_TPG);
142
143 pattern = DP_TRAINING_PATTERN_1;
144
145 err = tegra_dpaux_train(sor->dpaux, link, pattern);
146 if (err < 0)
147 return err;
148
149 value = tegra_sor_readl(sor, SOR_DP_SPARE_0);
150 value |= SOR_DP_SPARE_SEQ_ENABLE;
151 value &= ~SOR_DP_SPARE_PANEL_INTERNAL;
152 value |= SOR_DP_SPARE_MACRO_SOR_CLK;
153 tegra_sor_writel(sor, value, SOR_DP_SPARE_0);
154
155 for (i = 0, value = 0; i < link->num_lanes; i++) {
156 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
157 SOR_DP_TPG_SCRAMBLER_NONE |
158 SOR_DP_TPG_PATTERN_TRAIN2;
159 value = (value << 8) | lane;
160 }
161
162 tegra_sor_writel(sor, value, SOR_DP_TPG);
163
164 pattern = DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_2;
165
166 err = tegra_dpaux_train(sor->dpaux, link, pattern);
167 if (err < 0)
168 return err;
169
170 for (i = 0, value = 0; i < link->num_lanes; i++) {
171 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
172 SOR_DP_TPG_SCRAMBLER_GALIOS |
173 SOR_DP_TPG_PATTERN_NONE;
174 value = (value << 8) | lane;
175 }
176
177 tegra_sor_writel(sor, value, SOR_DP_TPG);
178
179 pattern = DP_TRAINING_PATTERN_DISABLE;
180
181 err = tegra_dpaux_train(sor->dpaux, link, pattern);
182 if (err < 0)
183 return err;
184
185 return 0;
186}
187
188static void tegra_sor_super_update(struct tegra_sor *sor)
189{
190 tegra_sor_writel(sor, 0, SOR_SUPER_STATE_0);
191 tegra_sor_writel(sor, 1, SOR_SUPER_STATE_0);
192 tegra_sor_writel(sor, 0, SOR_SUPER_STATE_0);
193}
194
195static void tegra_sor_update(struct tegra_sor *sor)
196{
197 tegra_sor_writel(sor, 0, SOR_STATE_0);
198 tegra_sor_writel(sor, 1, SOR_STATE_0);
199 tegra_sor_writel(sor, 0, SOR_STATE_0);
200}
201
202static int tegra_sor_setup_pwm(struct tegra_sor *sor, unsigned long timeout)
203{
Thierry Reding28fe2072015-01-26 16:02:48 +0100204 u32 value;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100205
206 value = tegra_sor_readl(sor, SOR_PWM_DIV);
207 value &= ~SOR_PWM_DIV_MASK;
208 value |= 0x400; /* period */
209 tegra_sor_writel(sor, value, SOR_PWM_DIV);
210
211 value = tegra_sor_readl(sor, SOR_PWM_CTL);
212 value &= ~SOR_PWM_CTL_DUTY_CYCLE_MASK;
213 value |= 0x400; /* duty cycle */
214 value &= ~SOR_PWM_CTL_CLK_SEL; /* clock source: PCLK */
215 value |= SOR_PWM_CTL_TRIGGER;
216 tegra_sor_writel(sor, value, SOR_PWM_CTL);
217
218 timeout = jiffies + msecs_to_jiffies(timeout);
219
220 while (time_before(jiffies, timeout)) {
221 value = tegra_sor_readl(sor, SOR_PWM_CTL);
222 if ((value & SOR_PWM_CTL_TRIGGER) == 0)
223 return 0;
224
225 usleep_range(25, 100);
226 }
227
228 return -ETIMEDOUT;
229}
230
231static int tegra_sor_attach(struct tegra_sor *sor)
232{
233 unsigned long value, timeout;
234
235 /* wake up in normal mode */
236 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
237 value |= SOR_SUPER_STATE_HEAD_MODE_AWAKE;
238 value |= SOR_SUPER_STATE_MODE_NORMAL;
239 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
240 tegra_sor_super_update(sor);
241
242 /* attach */
243 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
244 value |= SOR_SUPER_STATE_ATTACHED;
245 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
246 tegra_sor_super_update(sor);
247
248 timeout = jiffies + msecs_to_jiffies(250);
249
250 while (time_before(jiffies, timeout)) {
251 value = tegra_sor_readl(sor, SOR_TEST);
252 if ((value & SOR_TEST_ATTACHED) != 0)
253 return 0;
254
255 usleep_range(25, 100);
256 }
257
258 return -ETIMEDOUT;
259}
260
261static int tegra_sor_wakeup(struct tegra_sor *sor)
262{
Thierry Reding6b6b6042013-11-15 16:06:05 +0100263 unsigned long value, timeout;
264
Thierry Reding6b6b6042013-11-15 16:06:05 +0100265 timeout = jiffies + msecs_to_jiffies(250);
266
267 /* wait for head to wake up */
268 while (time_before(jiffies, timeout)) {
269 value = tegra_sor_readl(sor, SOR_TEST);
270 value &= SOR_TEST_HEAD_MODE_MASK;
271
272 if (value == SOR_TEST_HEAD_MODE_AWAKE)
273 return 0;
274
275 usleep_range(25, 100);
276 }
277
278 return -ETIMEDOUT;
279}
280
281static int tegra_sor_power_up(struct tegra_sor *sor, unsigned long timeout)
282{
Thierry Reding28fe2072015-01-26 16:02:48 +0100283 u32 value;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100284
285 value = tegra_sor_readl(sor, SOR_PWR);
286 value |= SOR_PWR_TRIGGER | SOR_PWR_NORMAL_STATE_PU;
287 tegra_sor_writel(sor, value, SOR_PWR);
288
289 timeout = jiffies + msecs_to_jiffies(timeout);
290
291 while (time_before(jiffies, timeout)) {
292 value = tegra_sor_readl(sor, SOR_PWR);
293 if ((value & SOR_PWR_TRIGGER) == 0)
294 return 0;
295
296 usleep_range(25, 100);
297 }
298
299 return -ETIMEDOUT;
300}
301
Thierry Reding34fa1832014-06-05 16:31:10 +0200302struct tegra_sor_params {
303 /* number of link clocks per line */
304 unsigned int num_clocks;
305 /* ratio between input and output */
306 u64 ratio;
307 /* precision factor */
308 u64 precision;
309
310 unsigned int active_polarity;
311 unsigned int active_count;
312 unsigned int active_frac;
313 unsigned int tu_size;
314 unsigned int error;
315};
316
317static int tegra_sor_compute_params(struct tegra_sor *sor,
318 struct tegra_sor_params *params,
319 unsigned int tu_size)
320{
321 u64 active_sym, active_count, frac, approx;
322 u32 active_polarity, active_frac = 0;
323 const u64 f = params->precision;
324 s64 error;
325
326 active_sym = params->ratio * tu_size;
327 active_count = div_u64(active_sym, f) * f;
328 frac = active_sym - active_count;
329
330 /* fraction < 0.5 */
331 if (frac >= (f / 2)) {
332 active_polarity = 1;
333 frac = f - frac;
334 } else {
335 active_polarity = 0;
336 }
337
338 if (frac != 0) {
339 frac = div_u64(f * f, frac); /* 1/fraction */
340 if (frac <= (15 * f)) {
341 active_frac = div_u64(frac, f);
342
343 /* round up */
344 if (active_polarity)
345 active_frac++;
346 } else {
347 active_frac = active_polarity ? 1 : 15;
348 }
349 }
350
351 if (active_frac == 1)
352 active_polarity = 0;
353
354 if (active_polarity == 1) {
355 if (active_frac) {
356 approx = active_count + (active_frac * (f - 1)) * f;
357 approx = div_u64(approx, active_frac * f);
358 } else {
359 approx = active_count + f;
360 }
361 } else {
362 if (active_frac)
363 approx = active_count + div_u64(f, active_frac);
364 else
365 approx = active_count;
366 }
367
368 error = div_s64(active_sym - approx, tu_size);
369 error *= params->num_clocks;
370
371 if (error <= 0 && abs64(error) < params->error) {
372 params->active_count = div_u64(active_count, f);
373 params->active_polarity = active_polarity;
374 params->active_frac = active_frac;
375 params->error = abs64(error);
376 params->tu_size = tu_size;
377
378 if (error == 0)
379 return true;
380 }
381
382 return false;
383}
384
385static int tegra_sor_calc_config(struct tegra_sor *sor,
386 struct drm_display_mode *mode,
387 struct tegra_sor_config *config,
388 struct drm_dp_link *link)
389{
390 const u64 f = 100000, link_rate = link->rate * 1000;
391 const u64 pclk = mode->clock * 1000;
Thierry Reding7890b572014-06-05 16:12:46 +0200392 u64 input, output, watermark, num;
Thierry Reding34fa1832014-06-05 16:31:10 +0200393 struct tegra_sor_params params;
Thierry Reding34fa1832014-06-05 16:31:10 +0200394 u32 num_syms_per_line;
395 unsigned int i;
396
397 if (!link_rate || !link->num_lanes || !pclk || !config->bits_per_pixel)
398 return -EINVAL;
399
400 output = link_rate * 8 * link->num_lanes;
401 input = pclk * config->bits_per_pixel;
402
403 if (input >= output)
404 return -ERANGE;
405
406 memset(&params, 0, sizeof(params));
407 params.ratio = div64_u64(input * f, output);
408 params.num_clocks = div_u64(link_rate * mode->hdisplay, pclk);
409 params.precision = f;
410 params.error = 64 * f;
411 params.tu_size = 64;
412
413 for (i = params.tu_size; i >= 32; i--)
414 if (tegra_sor_compute_params(sor, &params, i))
415 break;
416
417 if (params.active_frac == 0) {
418 config->active_polarity = 0;
419 config->active_count = params.active_count;
420
421 if (!params.active_polarity)
422 config->active_count--;
423
424 config->tu_size = params.tu_size;
425 config->active_frac = 1;
426 } else {
427 config->active_polarity = params.active_polarity;
428 config->active_count = params.active_count;
429 config->active_frac = params.active_frac;
430 config->tu_size = params.tu_size;
431 }
432
433 dev_dbg(sor->dev,
434 "polarity: %d active count: %d tu size: %d active frac: %d\n",
435 config->active_polarity, config->active_count,
436 config->tu_size, config->active_frac);
437
438 watermark = params.ratio * config->tu_size * (f - params.ratio);
439 watermark = div_u64(watermark, f);
440
441 watermark = div_u64(watermark + params.error, f);
442 config->watermark = watermark + (config->bits_per_pixel / 8) + 2;
443 num_syms_per_line = (mode->hdisplay * config->bits_per_pixel) *
444 (link->num_lanes * 8);
445
446 if (config->watermark > 30) {
447 config->watermark = 30;
448 dev_err(sor->dev,
449 "unable to compute TU size, forcing watermark to %u\n",
450 config->watermark);
451 } else if (config->watermark > num_syms_per_line) {
452 config->watermark = num_syms_per_line;
453 dev_err(sor->dev, "watermark too high, forcing to %u\n",
454 config->watermark);
455 }
456
Thierry Reding7890b572014-06-05 16:12:46 +0200457 /* compute the number of symbols per horizontal blanking interval */
458 num = ((mode->htotal - mode->hdisplay) - 7) * link_rate;
459 config->hblank_symbols = div_u64(num, pclk);
460
461 if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
462 config->hblank_symbols -= 3;
463
464 config->hblank_symbols -= 12 / link->num_lanes;
465
466 /* compute the number of symbols per vertical blanking interval */
467 num = (mode->hdisplay - 25) * link_rate;
468 config->vblank_symbols = div_u64(num, pclk);
469 config->vblank_symbols -= 36 / link->num_lanes + 4;
470
471 dev_dbg(sor->dev, "blank symbols: H:%u V:%u\n", config->hblank_symbols,
472 config->vblank_symbols);
473
Thierry Reding34fa1832014-06-05 16:31:10 +0200474 return 0;
475}
476
Thierry Reding6fad8f62014-11-28 15:41:34 +0100477static int tegra_sor_detach(struct tegra_sor *sor)
Thierry Reding6b6b6042013-11-15 16:06:05 +0100478{
Thierry Reding6fad8f62014-11-28 15:41:34 +0100479 unsigned long value, timeout;
480
481 /* switch to safe mode */
482 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
483 value &= ~SOR_SUPER_STATE_MODE_NORMAL;
484 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
485 tegra_sor_super_update(sor);
486
487 timeout = jiffies + msecs_to_jiffies(250);
488
489 while (time_before(jiffies, timeout)) {
490 value = tegra_sor_readl(sor, SOR_PWR);
491 if (value & SOR_PWR_MODE_SAFE)
492 break;
493 }
494
495 if ((value & SOR_PWR_MODE_SAFE) == 0)
496 return -ETIMEDOUT;
497
498 /* go to sleep */
499 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
500 value &= ~SOR_SUPER_STATE_HEAD_MODE_MASK;
501 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
502 tegra_sor_super_update(sor);
503
504 /* detach */
505 value = tegra_sor_readl(sor, SOR_SUPER_STATE_1);
506 value &= ~SOR_SUPER_STATE_ATTACHED;
507 tegra_sor_writel(sor, value, SOR_SUPER_STATE_1);
508 tegra_sor_super_update(sor);
509
510 timeout = jiffies + msecs_to_jiffies(250);
511
512 while (time_before(jiffies, timeout)) {
513 value = tegra_sor_readl(sor, SOR_TEST);
514 if ((value & SOR_TEST_ATTACHED) == 0)
515 break;
516
517 usleep_range(25, 100);
518 }
519
520 if ((value & SOR_TEST_ATTACHED) != 0)
521 return -ETIMEDOUT;
522
523 return 0;
524}
525
526static int tegra_sor_power_down(struct tegra_sor *sor)
527{
528 unsigned long value, timeout;
529 int err;
530
531 value = tegra_sor_readl(sor, SOR_PWR);
532 value &= ~SOR_PWR_NORMAL_STATE_PU;
533 value |= SOR_PWR_TRIGGER;
534 tegra_sor_writel(sor, value, SOR_PWR);
535
536 timeout = jiffies + msecs_to_jiffies(250);
537
538 while (time_before(jiffies, timeout)) {
539 value = tegra_sor_readl(sor, SOR_PWR);
540 if ((value & SOR_PWR_TRIGGER) == 0)
541 return 0;
542
543 usleep_range(25, 100);
544 }
545
546 if ((value & SOR_PWR_TRIGGER) != 0)
547 return -ETIMEDOUT;
548
549 err = clk_set_parent(sor->clk, sor->clk_safe);
550 if (err < 0)
551 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
552
553 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
554 value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
555 SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2);
556 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
557
558 /* stop lane sequencer */
559 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_UP |
560 SOR_LANE_SEQ_CTL_POWER_STATE_DOWN;
561 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
562
563 timeout = jiffies + msecs_to_jiffies(250);
564
565 while (time_before(jiffies, timeout)) {
566 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
567 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
568 break;
569
570 usleep_range(25, 100);
571 }
572
573 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)
574 return -ETIMEDOUT;
575
576 value = tegra_sor_readl(sor, SOR_PLL_2);
577 value |= SOR_PLL_2_PORT_POWERDOWN;
578 tegra_sor_writel(sor, value, SOR_PLL_2);
579
580 usleep_range(20, 100);
581
582 value = tegra_sor_readl(sor, SOR_PLL_0);
583 value |= SOR_PLL_0_POWER_OFF;
584 value |= SOR_PLL_0_VCOPD;
585 tegra_sor_writel(sor, value, SOR_PLL_0);
586
587 value = tegra_sor_readl(sor, SOR_PLL_2);
588 value |= SOR_PLL_2_SEQ_PLLCAPPD;
589 value |= SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
590 tegra_sor_writel(sor, value, SOR_PLL_2);
591
592 usleep_range(20, 100);
593
594 return 0;
595}
596
597static int tegra_sor_crc_open(struct inode *inode, struct file *file)
598{
599 file->private_data = inode->i_private;
600
601 return 0;
602}
603
604static int tegra_sor_crc_release(struct inode *inode, struct file *file)
605{
606 return 0;
607}
608
609static int tegra_sor_crc_wait(struct tegra_sor *sor, unsigned long timeout)
610{
611 u32 value;
612
613 timeout = jiffies + msecs_to_jiffies(timeout);
614
615 while (time_before(jiffies, timeout)) {
616 value = tegra_sor_readl(sor, SOR_CRC_A);
617 if (value & SOR_CRC_A_VALID)
618 return 0;
619
620 usleep_range(100, 200);
621 }
622
623 return -ETIMEDOUT;
624}
625
626static ssize_t tegra_sor_crc_read(struct file *file, char __user *buffer,
627 size_t size, loff_t *ppos)
628{
629 struct tegra_sor *sor = file->private_data;
630 ssize_t num, err;
631 char buf[10];
632 u32 value;
633
634 mutex_lock(&sor->lock);
635
636 if (!sor->enabled) {
637 err = -EAGAIN;
638 goto unlock;
639 }
640
641 value = tegra_sor_readl(sor, SOR_STATE_1);
642 value &= ~SOR_STATE_ASY_CRC_MODE_MASK;
643 tegra_sor_writel(sor, value, SOR_STATE_1);
644
645 value = tegra_sor_readl(sor, SOR_CRC_CNTRL);
646 value |= SOR_CRC_CNTRL_ENABLE;
647 tegra_sor_writel(sor, value, SOR_CRC_CNTRL);
648
649 value = tegra_sor_readl(sor, SOR_TEST);
650 value &= ~SOR_TEST_CRC_POST_SERIALIZE;
651 tegra_sor_writel(sor, value, SOR_TEST);
652
653 err = tegra_sor_crc_wait(sor, 100);
654 if (err < 0)
655 goto unlock;
656
657 tegra_sor_writel(sor, SOR_CRC_A_RESET, SOR_CRC_A);
658 value = tegra_sor_readl(sor, SOR_CRC_B);
659
660 num = scnprintf(buf, sizeof(buf), "%08x\n", value);
661
662 err = simple_read_from_buffer(buffer, size, ppos, buf, num);
663
664unlock:
665 mutex_unlock(&sor->lock);
666 return err;
667}
668
669static const struct file_operations tegra_sor_crc_fops = {
670 .owner = THIS_MODULE,
671 .open = tegra_sor_crc_open,
672 .read = tegra_sor_crc_read,
673 .release = tegra_sor_crc_release,
674};
675
676static int tegra_sor_debugfs_init(struct tegra_sor *sor,
677 struct drm_minor *minor)
678{
679 struct dentry *entry;
680 int err = 0;
681
682 sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root);
683 if (!sor->debugfs)
684 return -ENOMEM;
685
686 entry = debugfs_create_file("crc", 0644, sor->debugfs, sor,
687 &tegra_sor_crc_fops);
688 if (!entry) {
689 dev_err(sor->dev,
690 "cannot create /sys/kernel/debug/dri/%s/sor/crc\n",
691 minor->debugfs_root->d_name.name);
692 err = -ENOMEM;
693 goto remove;
694 }
695
696 return err;
697
698remove:
699 debugfs_remove(sor->debugfs);
700 sor->debugfs = NULL;
701 return err;
702}
703
Thierry Reding4009c222014-12-19 15:47:30 +0100704static void tegra_sor_debugfs_exit(struct tegra_sor *sor)
Thierry Reding6fad8f62014-11-28 15:41:34 +0100705{
706 debugfs_remove_recursive(sor->debugfs);
707 sor->debugfs = NULL;
Thierry Reding6fad8f62014-11-28 15:41:34 +0100708}
709
710static void tegra_sor_connector_dpms(struct drm_connector *connector, int mode)
711{
712}
713
714static enum drm_connector_status
715tegra_sor_connector_detect(struct drm_connector *connector, bool force)
716{
717 struct tegra_output *output = connector_to_output(connector);
718 struct tegra_sor *sor = to_sor(output);
719
720 if (sor->dpaux)
721 return tegra_dpaux_detect(sor->dpaux);
722
723 return connector_status_unknown;
724}
725
726static const struct drm_connector_funcs tegra_sor_connector_funcs = {
727 .dpms = tegra_sor_connector_dpms,
Thierry Reding9d441892014-11-24 17:02:53 +0100728 .reset = drm_atomic_helper_connector_reset,
Thierry Reding6fad8f62014-11-28 15:41:34 +0100729 .detect = tegra_sor_connector_detect,
730 .fill_modes = drm_helper_probe_single_connector_modes,
731 .destroy = tegra_output_connector_destroy,
Thierry Reding9d441892014-11-24 17:02:53 +0100732 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
Thierry Reding4aa3df72014-11-24 16:27:13 +0100733 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
Thierry Reding6fad8f62014-11-28 15:41:34 +0100734};
735
736static int tegra_sor_connector_get_modes(struct drm_connector *connector)
737{
738 struct tegra_output *output = connector_to_output(connector);
739 struct tegra_sor *sor = to_sor(output);
740 int err;
741
742 if (sor->dpaux)
743 tegra_dpaux_enable(sor->dpaux);
744
745 err = tegra_output_connector_get_modes(connector);
746
747 if (sor->dpaux)
748 tegra_dpaux_disable(sor->dpaux);
749
750 return err;
751}
752
753static enum drm_mode_status
754tegra_sor_connector_mode_valid(struct drm_connector *connector,
755 struct drm_display_mode *mode)
756{
757 return MODE_OK;
758}
759
760static const struct drm_connector_helper_funcs tegra_sor_connector_helper_funcs = {
761 .get_modes = tegra_sor_connector_get_modes,
762 .mode_valid = tegra_sor_connector_mode_valid,
763 .best_encoder = tegra_output_connector_best_encoder,
764};
765
766static const struct drm_encoder_funcs tegra_sor_encoder_funcs = {
767 .destroy = tegra_output_encoder_destroy,
768};
769
770static void tegra_sor_encoder_dpms(struct drm_encoder *encoder, int mode)
771{
772}
773
Thierry Reding6fad8f62014-11-28 15:41:34 +0100774static void tegra_sor_encoder_prepare(struct drm_encoder *encoder)
775{
776}
777
778static void tegra_sor_encoder_commit(struct drm_encoder *encoder)
779{
780}
781
782static void tegra_sor_encoder_mode_set(struct drm_encoder *encoder,
783 struct drm_display_mode *mode,
784 struct drm_display_mode *adjusted)
785{
786 struct tegra_output *output = encoder_to_output(encoder);
787 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100788 unsigned int vbe, vse, hbe, hse, vbs, hbs, i;
789 struct tegra_sor *sor = to_sor(output);
Thierry Reding34fa1832014-06-05 16:31:10 +0200790 struct tegra_sor_config config;
791 struct drm_dp_link link;
792 struct drm_dp_aux *aux;
Thierry Reding86f5c522014-03-26 11:13:16 +0100793 int err = 0;
Thierry Reding28fe2072015-01-26 16:02:48 +0100794 u32 value;
Thierry Reding86f5c522014-03-26 11:13:16 +0100795
796 mutex_lock(&sor->lock);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100797
798 if (sor->enabled)
Thierry Reding86f5c522014-03-26 11:13:16 +0100799 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100800
801 err = clk_prepare_enable(sor->clk);
802 if (err < 0)
Thierry Reding86f5c522014-03-26 11:13:16 +0100803 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100804
805 reset_control_deassert(sor->rst);
806
Thierry Reding6fad8f62014-11-28 15:41:34 +0100807 if (output->panel)
808 drm_panel_prepare(output->panel);
809
Thierry Reding34fa1832014-06-05 16:31:10 +0200810 /* FIXME: properly convert to struct drm_dp_aux */
811 aux = (struct drm_dp_aux *)sor->dpaux;
812
Thierry Reding6b6b6042013-11-15 16:06:05 +0100813 if (sor->dpaux) {
814 err = tegra_dpaux_enable(sor->dpaux);
815 if (err < 0)
816 dev_err(sor->dev, "failed to enable DP: %d\n", err);
Thierry Reding34fa1832014-06-05 16:31:10 +0200817
818 err = drm_dp_link_probe(aux, &link);
819 if (err < 0) {
820 dev_err(sor->dev, "failed to probe eDP link: %d\n",
821 err);
Dan Carpenter2263c462014-06-11 10:06:09 +0300822 goto unlock;
Thierry Reding34fa1832014-06-05 16:31:10 +0200823 }
Thierry Reding6b6b6042013-11-15 16:06:05 +0100824 }
825
826 err = clk_set_parent(sor->clk, sor->clk_safe);
827 if (err < 0)
828 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
829
Thierry Reding34fa1832014-06-05 16:31:10 +0200830 memset(&config, 0, sizeof(config));
Stéphane Marchesin054b1bd2014-06-19 18:18:29 -0700831 config.bits_per_pixel = output->connector.display_info.bpc * 3;
Thierry Reding34fa1832014-06-05 16:31:10 +0200832
833 err = tegra_sor_calc_config(sor, mode, &config, &link);
834 if (err < 0)
835 dev_err(sor->dev, "failed to compute link configuration: %d\n",
836 err);
837
Thierry Reding6b6b6042013-11-15 16:06:05 +0100838 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
839 value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;
840 value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK;
841 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
842
843 value = tegra_sor_readl(sor, SOR_PLL_2);
844 value &= ~SOR_PLL_2_BANDGAP_POWERDOWN;
845 tegra_sor_writel(sor, value, SOR_PLL_2);
846 usleep_range(20, 100);
847
848 value = tegra_sor_readl(sor, SOR_PLL_3);
849 value |= SOR_PLL_3_PLL_VDD_MODE_V3_3;
850 tegra_sor_writel(sor, value, SOR_PLL_3);
851
852 value = SOR_PLL_0_ICHPMP(0xf) | SOR_PLL_0_VCOCAP_RST |
853 SOR_PLL_0_PLLREG_LEVEL_V45 | SOR_PLL_0_RESISTOR_EXT;
854 tegra_sor_writel(sor, value, SOR_PLL_0);
855
856 value = tegra_sor_readl(sor, SOR_PLL_2);
857 value |= SOR_PLL_2_SEQ_PLLCAPPD;
858 value &= ~SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
859 value |= SOR_PLL_2_LVDS_ENABLE;
860 tegra_sor_writel(sor, value, SOR_PLL_2);
861
862 value = SOR_PLL_1_TERM_COMPOUT | SOR_PLL_1_TMDS_TERM;
863 tegra_sor_writel(sor, value, SOR_PLL_1);
864
865 while (true) {
866 value = tegra_sor_readl(sor, SOR_PLL_2);
867 if ((value & SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE) == 0)
868 break;
869
870 usleep_range(250, 1000);
871 }
872
873 value = tegra_sor_readl(sor, SOR_PLL_2);
874 value &= ~SOR_PLL_2_POWERDOWN_OVERRIDE;
875 value &= ~SOR_PLL_2_PORT_POWERDOWN;
876 tegra_sor_writel(sor, value, SOR_PLL_2);
877
878 /*
879 * power up
880 */
881
882 /* set safe link bandwidth (1.62 Gbps) */
883 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
884 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
885 value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G1_62;
886 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
887
888 /* step 1 */
889 value = tegra_sor_readl(sor, SOR_PLL_2);
890 value |= SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE | SOR_PLL_2_PORT_POWERDOWN |
891 SOR_PLL_2_BANDGAP_POWERDOWN;
892 tegra_sor_writel(sor, value, SOR_PLL_2);
893
894 value = tegra_sor_readl(sor, SOR_PLL_0);
895 value |= SOR_PLL_0_VCOPD | SOR_PLL_0_POWER_OFF;
896 tegra_sor_writel(sor, value, SOR_PLL_0);
897
898 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
899 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
900 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
901
902 /* step 2 */
903 err = tegra_io_rail_power_on(TEGRA_IO_RAIL_LVDS);
904 if (err < 0) {
905 dev_err(sor->dev, "failed to power on I/O rail: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +0100906 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100907 }
908
909 usleep_range(5, 100);
910
911 /* step 3 */
912 value = tegra_sor_readl(sor, SOR_PLL_2);
913 value &= ~SOR_PLL_2_BANDGAP_POWERDOWN;
914 tegra_sor_writel(sor, value, SOR_PLL_2);
915
916 usleep_range(20, 100);
917
918 /* step 4 */
919 value = tegra_sor_readl(sor, SOR_PLL_0);
920 value &= ~SOR_PLL_0_POWER_OFF;
921 value &= ~SOR_PLL_0_VCOPD;
922 tegra_sor_writel(sor, value, SOR_PLL_0);
923
924 value = tegra_sor_readl(sor, SOR_PLL_2);
925 value &= ~SOR_PLL_2_SEQ_PLLCAPPD_ENFORCE;
926 tegra_sor_writel(sor, value, SOR_PLL_2);
927
928 usleep_range(200, 1000);
929
930 /* step 5 */
931 value = tegra_sor_readl(sor, SOR_PLL_2);
932 value &= ~SOR_PLL_2_PORT_POWERDOWN;
933 tegra_sor_writel(sor, value, SOR_PLL_2);
934
935 /* switch to DP clock */
936 err = clk_set_parent(sor->clk, sor->clk_dp);
937 if (err < 0)
938 dev_err(sor->dev, "failed to set DP parent clock: %d\n", err);
939
Thierry Reding899451b2014-06-05 16:19:48 +0200940 /* power DP lanes */
Thierry Reding6b6b6042013-11-15 16:06:05 +0100941 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
Thierry Reding899451b2014-06-05 16:19:48 +0200942
943 if (link.num_lanes <= 2)
944 value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2);
945 else
946 value |= SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2;
947
948 if (link.num_lanes <= 1)
949 value &= ~SOR_DP_PADCTL_PD_TXD_1;
950 else
951 value |= SOR_DP_PADCTL_PD_TXD_1;
952
953 if (link.num_lanes == 0)
954 value &= ~SOR_DP_PADCTL_PD_TXD_0;
955 else
956 value |= SOR_DP_PADCTL_PD_TXD_0;
957
Thierry Reding6b6b6042013-11-15 16:06:05 +0100958 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
959
960 value = tegra_sor_readl(sor, SOR_DP_LINKCTL_0);
961 value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
Thierry Reding0c90a182014-06-05 16:29:46 +0200962 value |= SOR_DP_LINKCTL_LANE_COUNT(link.num_lanes);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100963 tegra_sor_writel(sor, value, SOR_DP_LINKCTL_0);
964
965 /* start lane sequencer */
966 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |
967 SOR_LANE_SEQ_CTL_POWER_STATE_UP;
968 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
969
970 while (true) {
971 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
972 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
973 break;
974
975 usleep_range(250, 1000);
976 }
977
Thierry Redinga4263fe2014-06-05 16:16:23 +0200978 /* set link bandwidth */
Thierry Reding6b6b6042013-11-15 16:06:05 +0100979 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
980 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
Thierry Redinga4263fe2014-06-05 16:16:23 +0200981 value |= drm_dp_link_rate_to_bw_code(link.rate) << 2;
Thierry Reding6b6b6042013-11-15 16:06:05 +0100982 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
983
984 /* set linkctl */
985 value = tegra_sor_readl(sor, SOR_DP_LINKCTL_0);
986 value |= SOR_DP_LINKCTL_ENABLE;
987
988 value &= ~SOR_DP_LINKCTL_TU_SIZE_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +0200989 value |= SOR_DP_LINKCTL_TU_SIZE(config.tu_size);
Thierry Reding6b6b6042013-11-15 16:06:05 +0100990
991 value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
992 tegra_sor_writel(sor, value, SOR_DP_LINKCTL_0);
993
994 for (i = 0, value = 0; i < 4; i++) {
995 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
996 SOR_DP_TPG_SCRAMBLER_GALIOS |
997 SOR_DP_TPG_PATTERN_NONE;
998 value = (value << 8) | lane;
999 }
1000
1001 tegra_sor_writel(sor, value, SOR_DP_TPG);
1002
1003 value = tegra_sor_readl(sor, SOR_DP_CONFIG_0);
1004 value &= ~SOR_DP_CONFIG_WATERMARK_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +02001005 value |= SOR_DP_CONFIG_WATERMARK(config.watermark);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001006
1007 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_COUNT_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +02001008 value |= SOR_DP_CONFIG_ACTIVE_SYM_COUNT(config.active_count);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001009
1010 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_FRAC_MASK;
Thierry Reding34fa1832014-06-05 16:31:10 +02001011 value |= SOR_DP_CONFIG_ACTIVE_SYM_FRAC(config.active_frac);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001012
Thierry Reding34fa1832014-06-05 16:31:10 +02001013 if (config.active_polarity)
1014 value |= SOR_DP_CONFIG_ACTIVE_SYM_POLARITY;
1015 else
1016 value &= ~SOR_DP_CONFIG_ACTIVE_SYM_POLARITY;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001017
1018 value |= SOR_DP_CONFIG_ACTIVE_SYM_ENABLE;
Thierry Reding1f64ae72014-06-05 16:20:27 +02001019 value |= SOR_DP_CONFIG_DISPARITY_NEGATIVE;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001020 tegra_sor_writel(sor, value, SOR_DP_CONFIG_0);
1021
1022 value = tegra_sor_readl(sor, SOR_DP_AUDIO_HBLANK_SYMBOLS);
1023 value &= ~SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK;
Thierry Reding7890b572014-06-05 16:12:46 +02001024 value |= config.hblank_symbols & 0xffff;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001025 tegra_sor_writel(sor, value, SOR_DP_AUDIO_HBLANK_SYMBOLS);
1026
1027 value = tegra_sor_readl(sor, SOR_DP_AUDIO_VBLANK_SYMBOLS);
1028 value &= ~SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK;
Thierry Reding7890b572014-06-05 16:12:46 +02001029 value |= config.vblank_symbols & 0xffff;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001030 tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS);
1031
1032 /* enable pad calibration logic */
1033 value = tegra_sor_readl(sor, SOR_DP_PADCTL_0);
1034 value |= SOR_DP_PADCTL_PAD_CAL_PD;
1035 tegra_sor_writel(sor, value, SOR_DP_PADCTL_0);
1036
1037 if (sor->dpaux) {
Thierry Reding6b6b6042013-11-15 16:06:05 +01001038 u8 rate, lanes;
1039
1040 err = drm_dp_link_probe(aux, &link);
1041 if (err < 0) {
1042 dev_err(sor->dev, "failed to probe eDP link: %d\n",
1043 err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001044 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001045 }
1046
1047 err = drm_dp_link_power_up(aux, &link);
1048 if (err < 0) {
1049 dev_err(sor->dev, "failed to power up eDP link: %d\n",
1050 err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001051 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001052 }
1053
1054 err = drm_dp_link_configure(aux, &link);
1055 if (err < 0) {
1056 dev_err(sor->dev, "failed to configure eDP link: %d\n",
1057 err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001058 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001059 }
1060
1061 rate = drm_dp_link_rate_to_bw_code(link.rate);
1062 lanes = link.num_lanes;
1063
1064 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
1065 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
1066 value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate);
1067 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
1068
1069 value = tegra_sor_readl(sor, SOR_DP_LINKCTL_0);
1070 value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
1071 value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
1072
1073 if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
1074 value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
1075
1076 tegra_sor_writel(sor, value, SOR_DP_LINKCTL_0);
1077
1078 /* disable training pattern generator */
1079
1080 for (i = 0; i < link.num_lanes; i++) {
1081 unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
1082 SOR_DP_TPG_SCRAMBLER_GALIOS |
1083 SOR_DP_TPG_PATTERN_NONE;
1084 value = (value << 8) | lane;
1085 }
1086
1087 tegra_sor_writel(sor, value, SOR_DP_TPG);
1088
1089 err = tegra_sor_dp_train_fast(sor, &link);
1090 if (err < 0) {
1091 dev_err(sor->dev, "DP fast link training failed: %d\n",
1092 err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001093 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001094 }
1095
1096 dev_dbg(sor->dev, "fast link training succeeded\n");
1097 }
1098
1099 err = tegra_sor_power_up(sor, 250);
1100 if (err < 0) {
1101 dev_err(sor->dev, "failed to power up SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001102 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001103 }
1104
Thierry Reding6b6b6042013-11-15 16:06:05 +01001105 /*
1106 * configure panel (24bpp, vsync-, hsync-, DP-A protocol, complete
1107 * raster, associate with display controller)
1108 */
Thierry Reding3f4f3b52014-07-07 15:35:06 +02001109 value = SOR_STATE_ASY_PROTOCOL_DP_A |
Thierry Reding6b6b6042013-11-15 16:06:05 +01001110 SOR_STATE_ASY_CRC_MODE_COMPLETE |
1111 SOR_STATE_ASY_OWNER(dc->pipe + 1);
Thierry Reding34fa1832014-06-05 16:31:10 +02001112
Thierry Reding3f4f3b52014-07-07 15:35:06 +02001113 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
1114 value &= ~SOR_STATE_ASY_HSYNCPOL;
1115
1116 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1117 value |= SOR_STATE_ASY_HSYNCPOL;
1118
1119 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
1120 value &= ~SOR_STATE_ASY_VSYNCPOL;
1121
1122 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1123 value |= SOR_STATE_ASY_VSYNCPOL;
1124
Thierry Reding34fa1832014-06-05 16:31:10 +02001125 switch (config.bits_per_pixel) {
1126 case 24:
1127 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;
1128 break;
1129
1130 case 18:
1131 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444;
1132 break;
1133
1134 default:
1135 BUG();
1136 break;
1137 }
1138
Thierry Reding6b6b6042013-11-15 16:06:05 +01001139 tegra_sor_writel(sor, value, SOR_STATE_1);
1140
1141 /*
1142 * TODO: The video timing programming below doesn't seem to match the
1143 * register definitions.
1144 */
1145
1146 value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff);
1147 tegra_sor_writel(sor, value, SOR_HEAD_STATE_1(0));
1148
1149 vse = mode->vsync_end - mode->vsync_start - 1;
1150 hse = mode->hsync_end - mode->hsync_start - 1;
1151
1152 value = ((vse & 0x7fff) << 16) | (hse & 0x7fff);
1153 tegra_sor_writel(sor, value, SOR_HEAD_STATE_2(0));
1154
1155 vbe = vse + (mode->vsync_start - mode->vdisplay);
1156 hbe = hse + (mode->hsync_start - mode->hdisplay);
1157
1158 value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff);
1159 tegra_sor_writel(sor, value, SOR_HEAD_STATE_3(0));
1160
1161 vbs = vbe + mode->vdisplay;
1162 hbs = hbe + mode->hdisplay;
1163
1164 value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff);
1165 tegra_sor_writel(sor, value, SOR_HEAD_STATE_4(0));
1166
Thierry Reding6b6b6042013-11-15 16:06:05 +01001167 /* CSTM (LVDS, link A/B, upper) */
Stéphane Marchesin143b1df2014-05-22 20:32:47 -07001168 value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B |
Thierry Reding6b6b6042013-11-15 16:06:05 +01001169 SOR_CSTM_UPPER;
1170 tegra_sor_writel(sor, value, SOR_CSTM);
1171
1172 /* PWM setup */
1173 err = tegra_sor_setup_pwm(sor, 250);
1174 if (err < 0) {
1175 dev_err(sor->dev, "failed to setup PWM: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001176 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001177 }
1178
Thierry Reding666cb872014-12-08 16:32:47 +01001179 tegra_sor_update(sor);
1180
Thierry Reding6b6b6042013-11-15 16:06:05 +01001181 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
1182 value |= SOR_ENABLE;
1183 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
1184
Thierry Reding666cb872014-12-08 16:32:47 +01001185 tegra_dc_commit(dc);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001186
1187 err = tegra_sor_attach(sor);
1188 if (err < 0) {
1189 dev_err(sor->dev, "failed to attach SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001190 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001191 }
1192
1193 err = tegra_sor_wakeup(sor);
1194 if (err < 0) {
1195 dev_err(sor->dev, "failed to enable DC: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001196 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001197 }
1198
Thierry Reding6fad8f62014-11-28 15:41:34 +01001199 if (output->panel)
1200 drm_panel_enable(output->panel);
1201
Thierry Reding6b6b6042013-11-15 16:06:05 +01001202 sor->enabled = true;
1203
Thierry Reding86f5c522014-03-26 11:13:16 +01001204unlock:
1205 mutex_unlock(&sor->lock);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001206}
1207
Thierry Reding6fad8f62014-11-28 15:41:34 +01001208static void tegra_sor_encoder_disable(struct drm_encoder *encoder)
Thierry Reding6b6b6042013-11-15 16:06:05 +01001209{
Thierry Reding6fad8f62014-11-28 15:41:34 +01001210 struct tegra_output *output = encoder_to_output(encoder);
1211 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001212 struct tegra_sor *sor = to_sor(output);
Thierry Reding6fad8f62014-11-28 15:41:34 +01001213 u32 value;
1214 int err;
Thierry Reding86f5c522014-03-26 11:13:16 +01001215
1216 mutex_lock(&sor->lock);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001217
1218 if (!sor->enabled)
Thierry Reding86f5c522014-03-26 11:13:16 +01001219 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001220
Thierry Reding6fad8f62014-11-28 15:41:34 +01001221 if (output->panel)
1222 drm_panel_disable(output->panel);
1223
Thierry Reding6b6b6042013-11-15 16:06:05 +01001224 err = tegra_sor_detach(sor);
1225 if (err < 0) {
1226 dev_err(sor->dev, "failed to detach SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001227 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001228 }
1229
1230 tegra_sor_writel(sor, 0, SOR_STATE_1);
1231 tegra_sor_update(sor);
1232
1233 /*
1234 * The following accesses registers of the display controller, so make
1235 * sure it's only executed when the output is attached to one.
1236 */
1237 if (dc) {
Thierry Reding6b6b6042013-11-15 16:06:05 +01001238 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
1239 value &= ~SOR_ENABLE;
1240 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
1241
Thierry Reding62b9e062014-11-21 17:33:33 +01001242 tegra_dc_commit(dc);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001243 }
1244
1245 err = tegra_sor_power_down(sor);
1246 if (err < 0) {
1247 dev_err(sor->dev, "failed to power down SOR: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001248 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001249 }
1250
1251 if (sor->dpaux) {
1252 err = tegra_dpaux_disable(sor->dpaux);
1253 if (err < 0) {
1254 dev_err(sor->dev, "failed to disable DP: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001255 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001256 }
1257 }
1258
1259 err = tegra_io_rail_power_off(TEGRA_IO_RAIL_LVDS);
1260 if (err < 0) {
1261 dev_err(sor->dev, "failed to power off I/O rail: %d\n", err);
Thierry Reding86f5c522014-03-26 11:13:16 +01001262 goto unlock;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001263 }
1264
Thierry Reding6fad8f62014-11-28 15:41:34 +01001265 if (output->panel)
1266 drm_panel_unprepare(output->panel);
1267
Thierry Reding6b6b6042013-11-15 16:06:05 +01001268 clk_disable_unprepare(sor->clk);
Thierry Reding6fad8f62014-11-28 15:41:34 +01001269 reset_control_assert(sor->rst);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001270
1271 sor->enabled = false;
1272
Thierry Reding86f5c522014-03-26 11:13:16 +01001273unlock:
1274 mutex_unlock(&sor->lock);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001275}
1276
Thierry Reding82f15112014-12-08 17:26:46 +01001277static int
1278tegra_sor_encoder_atomic_check(struct drm_encoder *encoder,
1279 struct drm_crtc_state *crtc_state,
1280 struct drm_connector_state *conn_state)
1281{
1282 struct tegra_output *output = encoder_to_output(encoder);
1283 struct tegra_dc *dc = to_tegra_dc(conn_state->crtc);
1284 unsigned long pclk = crtc_state->mode.clock * 1000;
1285 struct tegra_sor *sor = to_sor(output);
1286 int err;
1287
1288 err = tegra_dc_state_setup_clock(dc, crtc_state, sor->clk_parent,
1289 pclk, 0);
1290 if (err < 0) {
1291 dev_err(output->dev, "failed to setup CRTC state: %d\n", err);
1292 return err;
1293 }
1294
1295 return 0;
1296}
1297
Thierry Reding6fad8f62014-11-28 15:41:34 +01001298static const struct drm_encoder_helper_funcs tegra_sor_encoder_helper_funcs = {
1299 .dpms = tegra_sor_encoder_dpms,
Thierry Reding6fad8f62014-11-28 15:41:34 +01001300 .prepare = tegra_sor_encoder_prepare,
1301 .commit = tegra_sor_encoder_commit,
1302 .mode_set = tegra_sor_encoder_mode_set,
1303 .disable = tegra_sor_encoder_disable,
Thierry Reding82f15112014-12-08 17:26:46 +01001304 .atomic_check = tegra_sor_encoder_atomic_check,
Thierry Reding6b6b6042013-11-15 16:06:05 +01001305};
1306
1307static int tegra_sor_init(struct host1x_client *client)
1308{
Thierry Reding9910f5c2014-05-22 09:57:15 +02001309 struct drm_device *drm = dev_get_drvdata(client->parent);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001310 struct tegra_sor *sor = host1x_client_to_sor(client);
1311 int err;
1312
1313 if (!sor->dpaux)
1314 return -ENODEV;
1315
Thierry Reding6b6b6042013-11-15 16:06:05 +01001316 sor->output.dev = sor->dev;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001317
Thierry Reding6fad8f62014-11-28 15:41:34 +01001318 drm_connector_init(drm, &sor->output.connector,
1319 &tegra_sor_connector_funcs,
1320 DRM_MODE_CONNECTOR_eDP);
1321 drm_connector_helper_add(&sor->output.connector,
1322 &tegra_sor_connector_helper_funcs);
1323 sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
1324
Thierry Reding6fad8f62014-11-28 15:41:34 +01001325 drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs,
1326 DRM_MODE_ENCODER_TMDS);
1327 drm_encoder_helper_add(&sor->output.encoder,
1328 &tegra_sor_encoder_helper_funcs);
1329
1330 drm_mode_connector_attach_encoder(&sor->output.connector,
1331 &sor->output.encoder);
1332 drm_connector_register(&sor->output.connector);
1333
Thierry Redingea130b22014-12-19 15:51:35 +01001334 err = tegra_output_init(drm, &sor->output);
1335 if (err < 0) {
1336 dev_err(client->dev, "failed to initialize output: %d\n", err);
1337 return err;
1338 }
Thierry Reding6fad8f62014-11-28 15:41:34 +01001339
Thierry Redingea130b22014-12-19 15:51:35 +01001340 sor->output.encoder.possible_crtcs = 0x3;
Thierry Reding6b6b6042013-11-15 16:06:05 +01001341
Thierry Redinga82752e2014-01-31 10:02:15 +01001342 if (IS_ENABLED(CONFIG_DEBUG_FS)) {
Thierry Reding1b0c7b42014-05-28 13:46:12 +02001343 err = tegra_sor_debugfs_init(sor, drm->primary);
Thierry Redinga82752e2014-01-31 10:02:15 +01001344 if (err < 0)
1345 dev_err(sor->dev, "debugfs setup failed: %d\n", err);
1346 }
1347
Thierry Reding6b6b6042013-11-15 16:06:05 +01001348 if (sor->dpaux) {
1349 err = tegra_dpaux_attach(sor->dpaux, &sor->output);
1350 if (err < 0) {
1351 dev_err(sor->dev, "failed to attach DP: %d\n", err);
1352 return err;
1353 }
1354 }
1355
Thierry Reding6fad8f62014-11-28 15:41:34 +01001356 err = clk_prepare_enable(sor->clk);
1357 if (err < 0) {
1358 dev_err(sor->dev, "failed to enable clock: %d\n", err);
1359 return err;
1360 }
1361
1362 err = clk_prepare_enable(sor->clk_safe);
1363 if (err < 0)
1364 return err;
1365
1366 err = clk_prepare_enable(sor->clk_dp);
1367 if (err < 0)
1368 return err;
1369
Thierry Reding6b6b6042013-11-15 16:06:05 +01001370 return 0;
1371}
1372
1373static int tegra_sor_exit(struct host1x_client *client)
1374{
1375 struct tegra_sor *sor = host1x_client_to_sor(client);
1376 int err;
1377
Thierry Reding328ec692014-12-19 15:55:08 +01001378 tegra_output_exit(&sor->output);
1379
Thierry Reding6b6b6042013-11-15 16:06:05 +01001380 if (sor->dpaux) {
1381 err = tegra_dpaux_detach(sor->dpaux);
1382 if (err < 0) {
1383 dev_err(sor->dev, "failed to detach DP: %d\n", err);
1384 return err;
1385 }
1386 }
1387
Thierry Reding6fad8f62014-11-28 15:41:34 +01001388 clk_disable_unprepare(sor->clk_safe);
1389 clk_disable_unprepare(sor->clk_dp);
1390 clk_disable_unprepare(sor->clk);
1391
Thierry Reding4009c222014-12-19 15:47:30 +01001392 if (IS_ENABLED(CONFIG_DEBUG_FS))
1393 tegra_sor_debugfs_exit(sor);
Thierry Redinga82752e2014-01-31 10:02:15 +01001394
Thierry Reding6b6b6042013-11-15 16:06:05 +01001395 return 0;
1396}
1397
1398static const struct host1x_client_ops sor_client_ops = {
1399 .init = tegra_sor_init,
1400 .exit = tegra_sor_exit,
1401};
1402
1403static int tegra_sor_probe(struct platform_device *pdev)
1404{
1405 struct device_node *np;
1406 struct tegra_sor *sor;
1407 struct resource *regs;
1408 int err;
1409
1410 sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL);
1411 if (!sor)
1412 return -ENOMEM;
1413
1414 sor->output.dev = sor->dev = &pdev->dev;
1415
1416 np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0);
1417 if (np) {
1418 sor->dpaux = tegra_dpaux_find_by_of_node(np);
1419 of_node_put(np);
1420
1421 if (!sor->dpaux)
1422 return -EPROBE_DEFER;
1423 }
1424
1425 err = tegra_output_probe(&sor->output);
1426 if (err < 0)
1427 return err;
1428
1429 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1430 sor->regs = devm_ioremap_resource(&pdev->dev, regs);
1431 if (IS_ERR(sor->regs))
1432 return PTR_ERR(sor->regs);
1433
1434 sor->rst = devm_reset_control_get(&pdev->dev, "sor");
1435 if (IS_ERR(sor->rst))
1436 return PTR_ERR(sor->rst);
1437
1438 sor->clk = devm_clk_get(&pdev->dev, NULL);
1439 if (IS_ERR(sor->clk))
1440 return PTR_ERR(sor->clk);
1441
1442 sor->clk_parent = devm_clk_get(&pdev->dev, "parent");
1443 if (IS_ERR(sor->clk_parent))
1444 return PTR_ERR(sor->clk_parent);
1445
Thierry Reding6b6b6042013-11-15 16:06:05 +01001446 sor->clk_safe = devm_clk_get(&pdev->dev, "safe");
1447 if (IS_ERR(sor->clk_safe))
1448 return PTR_ERR(sor->clk_safe);
1449
Thierry Reding6b6b6042013-11-15 16:06:05 +01001450 sor->clk_dp = devm_clk_get(&pdev->dev, "dp");
1451 if (IS_ERR(sor->clk_dp))
1452 return PTR_ERR(sor->clk_dp);
1453
Thierry Reding6b6b6042013-11-15 16:06:05 +01001454 INIT_LIST_HEAD(&sor->client.list);
1455 sor->client.ops = &sor_client_ops;
1456 sor->client.dev = &pdev->dev;
1457
Thierry Reding86f5c522014-03-26 11:13:16 +01001458 mutex_init(&sor->lock);
1459
Thierry Reding6b6b6042013-11-15 16:06:05 +01001460 err = host1x_client_register(&sor->client);
1461 if (err < 0) {
1462 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1463 err);
1464 return err;
1465 }
1466
1467 platform_set_drvdata(pdev, sor);
1468
1469 return 0;
1470}
1471
1472static int tegra_sor_remove(struct platform_device *pdev)
1473{
1474 struct tegra_sor *sor = platform_get_drvdata(pdev);
1475 int err;
1476
1477 err = host1x_client_unregister(&sor->client);
1478 if (err < 0) {
1479 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
1480 err);
1481 return err;
1482 }
1483
Thierry Reding328ec692014-12-19 15:55:08 +01001484 tegra_output_remove(&sor->output);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001485
1486 return 0;
1487}
1488
1489static const struct of_device_id tegra_sor_of_match[] = {
1490 { .compatible = "nvidia,tegra124-sor", },
1491 { },
1492};
Stephen Warrenef707282014-06-18 16:21:55 -06001493MODULE_DEVICE_TABLE(of, tegra_sor_of_match);
Thierry Reding6b6b6042013-11-15 16:06:05 +01001494
1495struct platform_driver tegra_sor_driver = {
1496 .driver = {
1497 .name = "tegra-sor",
1498 .of_match_table = tegra_sor_of_match,
1499 },
1500 .probe = tegra_sor_probe,
1501 .remove = tegra_sor_remove,
1502};