hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/gpu/drm/tegra/sor.c
....@@ -1,16 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * 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.
74 */
85
96 #include <linux/clk.h>
107 #include <linux/clk-provider.h>
118 #include <linux/debugfs.h>
12
-#include <linux/gpio.h>
139 #include <linux/io.h>
10
+#include <linux/module.h>
1411 #include <linux/of_device.h>
1512 #include <linux/platform_device.h>
1613 #include <linux/pm_runtime.h>
....@@ -20,22 +17,19 @@
2017 #include <soc/tegra/pmc.h>
2118
2219 #include <drm/drm_atomic_helper.h>
20
+#include <drm/drm_debugfs.h>
2321 #include <drm/drm_dp_helper.h>
22
+#include <drm/drm_file.h>
2423 #include <drm/drm_panel.h>
2524 #include <drm/drm_scdc_helper.h>
25
+#include <drm/drm_simple_kms_helper.h>
2626
2727 #include "dc.h"
28
+#include "dp.h"
2829 #include "drm.h"
30
+#include "hda.h"
2931 #include "sor.h"
3032 #include "trace.h"
31
-
32
-/*
33
- * XXX Remove this after the commit adding it to soc/tegra/pmc.h has been
34
- * merged. Having this around after the commit is merged should be safe since
35
- * the preprocessor will effectively replace all occurrences and therefore no
36
- * duplicate will be defined.
37
- */
38
-#define TEGRA_IO_PAD_HDMI_DP0 26
3933
4034 #define SOR_REKEY 0x38
4135
....@@ -282,6 +276,85 @@
282276 }
283277 };
284278
279
+static const struct tegra_sor_hdmi_settings tegra194_sor_hdmi_defaults[] = {
280
+ {
281
+ .frequency = 54000000,
282
+ .vcocap = 0,
283
+ .filter = 5,
284
+ .ichpmp = 5,
285
+ .loadadj = 3,
286
+ .tmds_termadj = 0xf,
287
+ .tx_pu_value = 0,
288
+ .bg_temp_coef = 3,
289
+ .bg_vref_level = 8,
290
+ .avdd10_level = 4,
291
+ .avdd14_level = 4,
292
+ .sparepll = 0x54,
293
+ .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },
294
+ .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
295
+ }, {
296
+ .frequency = 75000000,
297
+ .vcocap = 1,
298
+ .filter = 5,
299
+ .ichpmp = 5,
300
+ .loadadj = 3,
301
+ .tmds_termadj = 0xf,
302
+ .tx_pu_value = 0,
303
+ .bg_temp_coef = 3,
304
+ .bg_vref_level = 8,
305
+ .avdd10_level = 4,
306
+ .avdd14_level = 4,
307
+ .sparepll = 0x44,
308
+ .drive_current = { 0x3a, 0x3a, 0x3a, 0x33 },
309
+ .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
310
+ }, {
311
+ .frequency = 150000000,
312
+ .vcocap = 3,
313
+ .filter = 5,
314
+ .ichpmp = 5,
315
+ .loadadj = 3,
316
+ .tmds_termadj = 15,
317
+ .tx_pu_value = 0x66 /* 0 */,
318
+ .bg_temp_coef = 3,
319
+ .bg_vref_level = 8,
320
+ .avdd10_level = 4,
321
+ .avdd14_level = 4,
322
+ .sparepll = 0x00, /* 0x34 */
323
+ .drive_current = { 0x3a, 0x3a, 0x3a, 0x37 },
324
+ .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
325
+ }, {
326
+ .frequency = 300000000,
327
+ .vcocap = 3,
328
+ .filter = 5,
329
+ .ichpmp = 5,
330
+ .loadadj = 3,
331
+ .tmds_termadj = 15,
332
+ .tx_pu_value = 64,
333
+ .bg_temp_coef = 3,
334
+ .bg_vref_level = 8,
335
+ .avdd10_level = 4,
336
+ .avdd14_level = 4,
337
+ .sparepll = 0x34,
338
+ .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },
339
+ .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
340
+ }, {
341
+ .frequency = 600000000,
342
+ .vcocap = 3,
343
+ .filter = 5,
344
+ .ichpmp = 5,
345
+ .loadadj = 3,
346
+ .tmds_termadj = 12,
347
+ .tx_pu_value = 96,
348
+ .bg_temp_coef = 3,
349
+ .bg_vref_level = 8,
350
+ .avdd10_level = 4,
351
+ .avdd14_level = 4,
352
+ .sparepll = 0x34,
353
+ .drive_current = { 0x3d, 0x3d, 0x3d, 0x33 },
354
+ .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
355
+ }
356
+};
357
+
285358 struct tegra_sor_regs {
286359 unsigned int head_state0;
287360 unsigned int head_state1;
....@@ -298,10 +371,11 @@
298371 };
299372
300373 struct tegra_sor_soc {
301
- bool supports_edp;
302374 bool supports_lvds;
303375 bool supports_hdmi;
304376 bool supports_dp;
377
+ bool supports_audio;
378
+ bool supports_hdcp;
305379
306380 const struct tegra_sor_regs *regs;
307381 bool has_nvdisplay;
....@@ -310,6 +384,12 @@
310384 unsigned int num_settings;
311385
312386 const u8 *xbar_cfg;
387
+ const u8 *lane_map;
388
+
389
+ const u8 (*voltage_swing)[4][4];
390
+ const u8 (*pre_emphasis)[4][4];
391
+ const u8 (*post_cursor)[4][4];
392
+ const u8 (*tx_pu)[4][4];
313393 };
314394
315395 struct tegra_sor;
....@@ -317,7 +397,8 @@
317397 struct tegra_sor_ops {
318398 const char *name;
319399 int (*probe)(struct tegra_sor *sor);
320
- int (*remove)(struct tegra_sor *sor);
400
+ void (*audio_enable)(struct tegra_sor *sor);
401
+ void (*audio_disable)(struct tegra_sor *sor);
321402 };
322403
323404 struct tegra_sor {
....@@ -328,6 +409,7 @@
328409 const struct tegra_sor_soc *soc;
329410 void __iomem *regs;
330411 unsigned int index;
412
+ unsigned int irq;
331413
332414 struct reset_control *rst;
333415 struct clk *clk_parent;
....@@ -337,6 +419,9 @@
337419 struct clk *clk_dp;
338420 struct clk *clk;
339421
422
+ u8 xbar_cfg[5];
423
+
424
+ struct drm_dp_link link;
340425 struct drm_dp_aux *aux;
341426
342427 struct drm_info_list *debugfs_files;
....@@ -354,6 +439,8 @@
354439
355440 struct delayed_work scdc;
356441 bool scdc_enabled;
442
+
443
+ struct tegra_hda_format format;
357444 };
358445
359446 struct tegra_sor_state {
....@@ -437,9 +524,18 @@
437524 return container_of(hw, struct tegra_clk_sor_pad, hw);
438525 }
439526
440
-static const char * const tegra_clk_sor_pad_parents[] = {
441
- "pll_d2_out0", "pll_dp"
527
+static const char * const tegra_clk_sor_pad_parents[2][2] = {
528
+ { "pll_d_out0", "pll_dp" },
529
+ { "pll_d2_out0", "pll_dp" },
442530 };
531
+
532
+/*
533
+ * Implementing ->set_parent() here isn't really required because the parent
534
+ * will be explicitly selected in the driver code via the DP_CLK_SEL mux in
535
+ * the SOR_CLK_CNTRL register. This is primarily for compatibility with the
536
+ * Tegra186 and later SoC generations where the BPMP implements this clock
537
+ * and doesn't expose the mux via the common clock framework.
538
+ */
443539
444540 static int tegra_clk_sor_pad_set_parent(struct clk_hw *hw, u8 index)
445541 {
....@@ -509,8 +605,8 @@
509605
510606 init.name = name;
511607 init.flags = 0;
512
- init.parent_names = tegra_clk_sor_pad_parents;
513
- init.num_parents = ARRAY_SIZE(tegra_clk_sor_pad_parents);
608
+ init.parent_names = tegra_clk_sor_pad_parents[sor->index];
609
+ init.num_parents = ARRAY_SIZE(tegra_clk_sor_pad_parents[sor->index]);
514610 init.ops = &tegra_clk_sor_pad_ops;
515611
516612 pad->hw.init = &init;
....@@ -520,111 +616,339 @@
520616 return clk;
521617 }
522618
523
-static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
524
- struct drm_dp_link *link)
619
+static void tegra_sor_filter_rates(struct tegra_sor *sor)
525620 {
621
+ struct drm_dp_link *link = &sor->link;
526622 unsigned int i;
527
- u8 pattern;
623
+
624
+ /* Tegra only supports RBR, HBR and HBR2 */
625
+ for (i = 0; i < link->num_rates; i++) {
626
+ switch (link->rates[i]) {
627
+ case 1620000:
628
+ case 2700000:
629
+ case 5400000:
630
+ break;
631
+
632
+ default:
633
+ DRM_DEBUG_KMS("link rate %lu kHz not supported\n",
634
+ link->rates[i]);
635
+ link->rates[i] = 0;
636
+ break;
637
+ }
638
+ }
639
+
640
+ drm_dp_link_update_rates(link);
641
+}
642
+
643
+static int tegra_sor_power_up_lanes(struct tegra_sor *sor, unsigned int lanes)
644
+{
645
+ unsigned long timeout;
528646 u32 value;
529
- int err;
530647
531
- /* setup lane parameters */
532
- value = SOR_LANE_DRIVE_CURRENT_LANE3(0x40) |
533
- SOR_LANE_DRIVE_CURRENT_LANE2(0x40) |
534
- SOR_LANE_DRIVE_CURRENT_LANE1(0x40) |
535
- SOR_LANE_DRIVE_CURRENT_LANE0(0x40);
536
- tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT0);
537
-
538
- value = SOR_LANE_PREEMPHASIS_LANE3(0x0f) |
539
- SOR_LANE_PREEMPHASIS_LANE2(0x0f) |
540
- SOR_LANE_PREEMPHASIS_LANE1(0x0f) |
541
- SOR_LANE_PREEMPHASIS_LANE0(0x0f);
542
- tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS0);
543
-
544
- value = SOR_LANE_POSTCURSOR_LANE3(0x00) |
545
- SOR_LANE_POSTCURSOR_LANE2(0x00) |
546
- SOR_LANE_POSTCURSOR_LANE1(0x00) |
547
- SOR_LANE_POSTCURSOR_LANE0(0x00);
548
- tegra_sor_writel(sor, value, SOR_LANE_POSTCURSOR0);
549
-
550
- /* disable LVDS mode */
551
- tegra_sor_writel(sor, 0, SOR_LVDS);
552
-
648
+ /*
649
+ * Clear or set the PD_TXD bit corresponding to each lane, depending
650
+ * on whether it is used or not.
651
+ */
553652 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
554
- value |= SOR_DP_PADCTL_TX_PU_ENABLE;
555
- value &= ~SOR_DP_PADCTL_TX_PU_MASK;
556
- value |= SOR_DP_PADCTL_TX_PU(2); /* XXX: don't hardcode? */
653
+
654
+ if (lanes <= 2)
655
+ value &= ~(SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[3]) |
656
+ SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[2]));
657
+ else
658
+ value |= SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[3]) |
659
+ SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[2]);
660
+
661
+ if (lanes <= 1)
662
+ value &= ~SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[1]);
663
+ else
664
+ value |= SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[1]);
665
+
666
+ if (lanes == 0)
667
+ value &= ~SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[0]);
668
+ else
669
+ value |= SOR_DP_PADCTL_PD_TXD(sor->soc->lane_map[0]);
670
+
557671 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
558672
673
+ /* start lane sequencer */
674
+ value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |
675
+ SOR_LANE_SEQ_CTL_POWER_STATE_UP;
676
+ tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
677
+
678
+ timeout = jiffies + msecs_to_jiffies(250);
679
+
680
+ while (time_before(jiffies, timeout)) {
681
+ value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
682
+ if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
683
+ break;
684
+
685
+ usleep_range(250, 1000);
686
+ }
687
+
688
+ if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)
689
+ return -ETIMEDOUT;
690
+
691
+ return 0;
692
+}
693
+
694
+static int tegra_sor_power_down_lanes(struct tegra_sor *sor)
695
+{
696
+ unsigned long timeout;
697
+ u32 value;
698
+
699
+ /* power down all lanes */
559700 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
560
- value |= SOR_DP_PADCTL_CM_TXD_3 | SOR_DP_PADCTL_CM_TXD_2 |
561
- SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0;
701
+ value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
702
+ SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2);
562703 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
563704
564
- usleep_range(10, 100);
705
+ /* start lane sequencer */
706
+ value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_UP |
707
+ SOR_LANE_SEQ_CTL_POWER_STATE_DOWN;
708
+ tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
709
+
710
+ timeout = jiffies + msecs_to_jiffies(250);
711
+
712
+ while (time_before(jiffies, timeout)) {
713
+ value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
714
+ if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
715
+ break;
716
+
717
+ usleep_range(25, 100);
718
+ }
719
+
720
+ if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)
721
+ return -ETIMEDOUT;
722
+
723
+ return 0;
724
+}
725
+
726
+static void tegra_sor_dp_precharge(struct tegra_sor *sor, unsigned int lanes)
727
+{
728
+ u32 value;
729
+
730
+ /* pre-charge all used lanes */
731
+ value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
732
+
733
+ if (lanes <= 2)
734
+ value &= ~(SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[3]) |
735
+ SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[2]));
736
+ else
737
+ value |= SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[3]) |
738
+ SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[2]);
739
+
740
+ if (lanes <= 1)
741
+ value &= ~SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[1]);
742
+ else
743
+ value |= SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[1]);
744
+
745
+ if (lanes == 0)
746
+ value &= ~SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[0]);
747
+ else
748
+ value |= SOR_DP_PADCTL_CM_TXD(sor->soc->lane_map[0]);
749
+
750
+ tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
751
+
752
+ usleep_range(15, 100);
565753
566754 value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
567755 value &= ~(SOR_DP_PADCTL_CM_TXD_3 | SOR_DP_PADCTL_CM_TXD_2 |
568756 SOR_DP_PADCTL_CM_TXD_1 | SOR_DP_PADCTL_CM_TXD_0);
569757 tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
758
+}
570759
571
- err = drm_dp_aux_prepare(sor->aux, DP_SET_ANSI_8B10B);
572
- if (err < 0)
573
- return err;
760
+static void tegra_sor_dp_term_calibrate(struct tegra_sor *sor)
761
+{
762
+ u32 mask = 0x08, adj = 0, value;
574763
575
- for (i = 0, value = 0; i < link->num_lanes; i++) {
576
- unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
577
- SOR_DP_TPG_SCRAMBLER_NONE |
578
- SOR_DP_TPG_PATTERN_TRAIN1;
579
- value = (value << 8) | lane;
764
+ /* enable pad calibration logic */
765
+ value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
766
+ value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
767
+ tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
768
+
769
+ value = tegra_sor_readl(sor, sor->soc->regs->pll1);
770
+ value |= SOR_PLL1_TMDS_TERM;
771
+ tegra_sor_writel(sor, value, sor->soc->regs->pll1);
772
+
773
+ while (mask) {
774
+ adj |= mask;
775
+
776
+ value = tegra_sor_readl(sor, sor->soc->regs->pll1);
777
+ value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;
778
+ value |= SOR_PLL1_TMDS_TERMADJ(adj);
779
+ tegra_sor_writel(sor, value, sor->soc->regs->pll1);
780
+
781
+ usleep_range(100, 200);
782
+
783
+ value = tegra_sor_readl(sor, sor->soc->regs->pll1);
784
+ if (value & SOR_PLL1_TERM_COMPOUT)
785
+ adj &= ~mask;
786
+
787
+ mask >>= 1;
580788 }
581789
582
- tegra_sor_writel(sor, value, SOR_DP_TPG);
790
+ value = tegra_sor_readl(sor, sor->soc->regs->pll1);
791
+ value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;
792
+ value |= SOR_PLL1_TMDS_TERMADJ(adj);
793
+ tegra_sor_writel(sor, value, sor->soc->regs->pll1);
583794
584
- pattern = DP_TRAINING_PATTERN_1;
795
+ /* disable pad calibration logic */
796
+ value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
797
+ value |= SOR_DP_PADCTL_PAD_CAL_PD;
798
+ tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
799
+}
585800
586
- err = drm_dp_aux_train(sor->aux, link, pattern);
587
- if (err < 0)
588
- return err;
801
+static int tegra_sor_dp_link_apply_training(struct drm_dp_link *link)
802
+{
803
+ struct tegra_sor *sor = container_of(link, struct tegra_sor, link);
804
+ u32 voltage_swing = 0, pre_emphasis = 0, post_cursor = 0;
805
+ const struct tegra_sor_soc *soc = sor->soc;
806
+ u32 pattern = 0, tx_pu = 0, value;
807
+ unsigned int i;
589808
590
- value = tegra_sor_readl(sor, SOR_DP_SPARE0);
591
- value |= SOR_DP_SPARE_SEQ_ENABLE;
592
- value &= ~SOR_DP_SPARE_PANEL_INTERNAL;
593
- value |= SOR_DP_SPARE_MACRO_SOR_CLK;
594
- tegra_sor_writel(sor, value, SOR_DP_SPARE0);
809
+ for (value = 0, i = 0; i < link->lanes; i++) {
810
+ u8 vs = link->train.request.voltage_swing[i];
811
+ u8 pe = link->train.request.pre_emphasis[i];
812
+ u8 pc = link->train.request.post_cursor[i];
813
+ u8 shift = sor->soc->lane_map[i] << 3;
595814
596
- for (i = 0, value = 0; i < link->num_lanes; i++) {
597
- unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
598
- SOR_DP_TPG_SCRAMBLER_NONE |
599
- SOR_DP_TPG_PATTERN_TRAIN2;
600
- value = (value << 8) | lane;
815
+ voltage_swing |= soc->voltage_swing[pc][vs][pe] << shift;
816
+ pre_emphasis |= soc->pre_emphasis[pc][vs][pe] << shift;
817
+ post_cursor |= soc->post_cursor[pc][vs][pe] << shift;
818
+
819
+ if (sor->soc->tx_pu[pc][vs][pe] > tx_pu)
820
+ tx_pu = sor->soc->tx_pu[pc][vs][pe];
821
+
822
+ switch (link->train.pattern) {
823
+ case DP_TRAINING_PATTERN_DISABLE:
824
+ value = SOR_DP_TPG_SCRAMBLER_GALIOS |
825
+ SOR_DP_TPG_PATTERN_NONE;
826
+ break;
827
+
828
+ case DP_TRAINING_PATTERN_1:
829
+ value = SOR_DP_TPG_SCRAMBLER_NONE |
830
+ SOR_DP_TPG_PATTERN_TRAIN1;
831
+ break;
832
+
833
+ case DP_TRAINING_PATTERN_2:
834
+ value = SOR_DP_TPG_SCRAMBLER_NONE |
835
+ SOR_DP_TPG_PATTERN_TRAIN2;
836
+ break;
837
+
838
+ case DP_TRAINING_PATTERN_3:
839
+ value = SOR_DP_TPG_SCRAMBLER_NONE |
840
+ SOR_DP_TPG_PATTERN_TRAIN3;
841
+ break;
842
+
843
+ default:
844
+ return -EINVAL;
845
+ }
846
+
847
+ if (link->caps.channel_coding)
848
+ value |= SOR_DP_TPG_CHANNEL_CODING;
849
+
850
+ pattern = pattern << 8 | value;
601851 }
602852
603
- tegra_sor_writel(sor, value, SOR_DP_TPG);
853
+ tegra_sor_writel(sor, voltage_swing, SOR_LANE_DRIVE_CURRENT0);
854
+ tegra_sor_writel(sor, pre_emphasis, SOR_LANE_PREEMPHASIS0);
604855
605
- pattern = DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_2;
856
+ if (link->caps.tps3_supported)
857
+ tegra_sor_writel(sor, post_cursor, SOR_LANE_POSTCURSOR0);
606858
607
- err = drm_dp_aux_train(sor->aux, link, pattern);
608
- if (err < 0)
609
- return err;
859
+ tegra_sor_writel(sor, pattern, SOR_DP_TPG);
610860
611
- for (i = 0, value = 0; i < link->num_lanes; i++) {
612
- unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
613
- SOR_DP_TPG_SCRAMBLER_GALIOS |
614
- SOR_DP_TPG_PATTERN_NONE;
615
- value = (value << 8) | lane;
616
- }
861
+ value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
862
+ value &= ~SOR_DP_PADCTL_TX_PU_MASK;
863
+ value |= SOR_DP_PADCTL_TX_PU_ENABLE;
864
+ value |= SOR_DP_PADCTL_TX_PU(tx_pu);
865
+ tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
617866
618
- tegra_sor_writel(sor, value, SOR_DP_TPG);
619
-
620
- pattern = DP_TRAINING_PATTERN_DISABLE;
621
-
622
- err = drm_dp_aux_train(sor->aux, link, pattern);
623
- if (err < 0)
624
- return err;
867
+ usleep_range(20, 100);
625868
626869 return 0;
627870 }
871
+
872
+static int tegra_sor_dp_link_configure(struct drm_dp_link *link)
873
+{
874
+ struct tegra_sor *sor = container_of(link, struct tegra_sor, link);
875
+ unsigned int rate, lanes;
876
+ u32 value;
877
+ int err;
878
+
879
+ rate = drm_dp_link_rate_to_bw_code(link->rate);
880
+ lanes = link->lanes;
881
+
882
+ /* configure link speed and lane count */
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(rate);
886
+ tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
887
+
888
+ value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
889
+ value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
890
+ value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
891
+
892
+ if (link->caps.enhanced_framing)
893
+ value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
894
+
895
+ tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
896
+
897
+ usleep_range(400, 1000);
898
+
899
+ /* configure load pulse position adjustment */
900
+ value = tegra_sor_readl(sor, sor->soc->regs->pll1);
901
+ value &= ~SOR_PLL1_LOADADJ_MASK;
902
+
903
+ switch (rate) {
904
+ case DP_LINK_BW_1_62:
905
+ value |= SOR_PLL1_LOADADJ(0x3);
906
+ break;
907
+
908
+ case DP_LINK_BW_2_7:
909
+ value |= SOR_PLL1_LOADADJ(0x4);
910
+ break;
911
+
912
+ case DP_LINK_BW_5_4:
913
+ value |= SOR_PLL1_LOADADJ(0x6);
914
+ break;
915
+ }
916
+
917
+ tegra_sor_writel(sor, value, sor->soc->regs->pll1);
918
+
919
+ /* use alternate scrambler reset for eDP */
920
+ value = tegra_sor_readl(sor, SOR_DP_SPARE0);
921
+
922
+ if (link->edp == 0)
923
+ value &= ~SOR_DP_SPARE_PANEL_INTERNAL;
924
+ else
925
+ value |= SOR_DP_SPARE_PANEL_INTERNAL;
926
+
927
+ tegra_sor_writel(sor, value, SOR_DP_SPARE0);
928
+
929
+ err = tegra_sor_power_down_lanes(sor);
930
+ if (err < 0) {
931
+ dev_err(sor->dev, "failed to power down lanes: %d\n", err);
932
+ return err;
933
+ }
934
+
935
+ /* power up and pre-charge lanes */
936
+ err = tegra_sor_power_up_lanes(sor, lanes);
937
+ if (err < 0) {
938
+ dev_err(sor->dev, "failed to power up %u lane%s: %d\n",
939
+ lanes, (lanes != 1) ? "s" : "", err);
940
+ return err;
941
+ }
942
+
943
+ tegra_sor_dp_precharge(sor, lanes);
944
+
945
+ return 0;
946
+}
947
+
948
+static const struct drm_dp_link_ops tegra_sor_dp_link_ops = {
949
+ .apply_training = tegra_sor_dp_link_apply_training,
950
+ .configure = tegra_sor_dp_link_configure,
951
+};
628952
629953 static void tegra_sor_super_update(struct tegra_sor *sor)
630954 {
....@@ -829,17 +1153,17 @@
8291153 struct drm_dp_link *link)
8301154 {
8311155 const u64 f = 100000, link_rate = link->rate * 1000;
832
- const u64 pclk = mode->clock * 1000;
1156
+ const u64 pclk = (u64)mode->clock * 1000;
8331157 u64 input, output, watermark, num;
8341158 struct tegra_sor_params params;
8351159 u32 num_syms_per_line;
8361160 unsigned int i;
8371161
838
- if (!link_rate || !link->num_lanes || !pclk || !config->bits_per_pixel)
1162
+ if (!link_rate || !link->lanes || !pclk || !config->bits_per_pixel)
8391163 return -EINVAL;
8401164
841
- output = link_rate * 8 * link->num_lanes;
8421165 input = pclk * config->bits_per_pixel;
1166
+ output = link_rate * 8 * link->lanes;
8431167
8441168 if (input >= output)
8451169 return -ERANGE;
....@@ -882,7 +1206,7 @@
8821206 watermark = div_u64(watermark + params.error, f);
8831207 config->watermark = watermark + (config->bits_per_pixel / 8) + 2;
8841208 num_syms_per_line = (mode->hdisplay * config->bits_per_pixel) *
885
- (link->num_lanes * 8);
1209
+ (link->lanes * 8);
8861210
8871211 if (config->watermark > 30) {
8881212 config->watermark = 30;
....@@ -899,15 +1223,15 @@
8991223 num = ((mode->htotal - mode->hdisplay) - 7) * link_rate;
9001224 config->hblank_symbols = div_u64(num, pclk);
9011225
902
- if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
1226
+ if (link->caps.enhanced_framing)
9031227 config->hblank_symbols -= 3;
9041228
905
- config->hblank_symbols -= 12 / link->num_lanes;
1229
+ config->hblank_symbols -= 12 / link->lanes;
9061230
9071231 /* compute the number of symbols per vertical blanking interval */
9081232 num = (mode->hdisplay - 25) * link_rate;
9091233 config->vblank_symbols = div_u64(num, pclk);
910
- config->vblank_symbols -= 36 / link->num_lanes + 4;
1234
+ config->vblank_symbols -= 36 / link->lanes + 4;
9111235
9121236 dev_dbg(sor->dev, "blank symbols: H:%u V:%u\n", config->hblank_symbols,
9131237 config->vblank_symbols);
....@@ -1122,29 +1446,6 @@
11221446 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
11231447 return err;
11241448 }
1125
-
1126
- value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
1127
- value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
1128
- SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2);
1129
- tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
1130
-
1131
- /* stop lane sequencer */
1132
- value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_UP |
1133
- SOR_LANE_SEQ_CTL_POWER_STATE_DOWN;
1134
- tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
1135
-
1136
- timeout = jiffies + msecs_to_jiffies(250);
1137
-
1138
- while (time_before(jiffies, timeout)) {
1139
- value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
1140
- if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
1141
- break;
1142
-
1143
- usleep_range(25, 100);
1144
- }
1145
-
1146
- if ((value & SOR_LANE_SEQ_CTL_TRIGGER) != 0)
1147
- return -ETIMEDOUT;
11481449
11491450 value = tegra_sor_readl(sor, sor->soc->regs->pll2);
11501451 value |= SOR_PLL2_PORT_POWERDOWN;
....@@ -1385,7 +1686,6 @@
13851686 struct drm_minor *minor = connector->dev->primary;
13861687 struct dentry *root = connector->debugfs_entry;
13871688 struct tegra_sor *sor = to_sor(output);
1388
- int err;
13891689
13901690 sor->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
13911691 GFP_KERNEL);
....@@ -1395,17 +1695,9 @@
13951695 for (i = 0; i < count; i++)
13961696 sor->debugfs_files[i].data = sor;
13971697
1398
- err = drm_debugfs_create_files(sor->debugfs_files, count, root, minor);
1399
- if (err < 0)
1400
- goto free;
1698
+ drm_debugfs_create_files(sor->debugfs_files, count, root, minor);
14011699
14021700 return 0;
1403
-
1404
-free:
1405
- kfree(sor->debugfs_files);
1406
- sor->debugfs_files = NULL;
1407
-
1408
- return err;
14091701 }
14101702
14111703 static void tegra_sor_early_unregister(struct drm_connector *connector)
....@@ -1503,407 +1795,6 @@
15031795 .mode_valid = tegra_sor_connector_mode_valid,
15041796 };
15051797
1506
-static const struct drm_encoder_funcs tegra_sor_encoder_funcs = {
1507
- .destroy = tegra_output_encoder_destroy,
1508
-};
1509
-
1510
-static void tegra_sor_edp_disable(struct drm_encoder *encoder)
1511
-{
1512
- struct tegra_output *output = encoder_to_output(encoder);
1513
- struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
1514
- struct tegra_sor *sor = to_sor(output);
1515
- u32 value;
1516
- int err;
1517
-
1518
- if (output->panel)
1519
- drm_panel_disable(output->panel);
1520
-
1521
- err = tegra_sor_detach(sor);
1522
- if (err < 0)
1523
- dev_err(sor->dev, "failed to detach SOR: %d\n", err);
1524
-
1525
- tegra_sor_writel(sor, 0, SOR_STATE1);
1526
- tegra_sor_update(sor);
1527
-
1528
- /*
1529
- * The following accesses registers of the display controller, so make
1530
- * sure it's only executed when the output is attached to one.
1531
- */
1532
- if (dc) {
1533
- value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
1534
- value &= ~SOR_ENABLE(0);
1535
- tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
1536
-
1537
- tegra_dc_commit(dc);
1538
- }
1539
-
1540
- err = tegra_sor_power_down(sor);
1541
- if (err < 0)
1542
- dev_err(sor->dev, "failed to power down SOR: %d\n", err);
1543
-
1544
- if (sor->aux) {
1545
- err = drm_dp_aux_disable(sor->aux);
1546
- if (err < 0)
1547
- dev_err(sor->dev, "failed to disable DP: %d\n", err);
1548
- }
1549
-
1550
- err = tegra_io_pad_power_disable(sor->pad);
1551
- if (err < 0)
1552
- dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
1553
-
1554
- if (output->panel)
1555
- drm_panel_unprepare(output->panel);
1556
-
1557
- pm_runtime_put(sor->dev);
1558
-}
1559
-
1560
-#if 0
1561
-static int calc_h_ref_to_sync(const struct drm_display_mode *mode,
1562
- unsigned int *value)
1563
-{
1564
- unsigned int hfp, hsw, hbp, a = 0, b;
1565
-
1566
- hfp = mode->hsync_start - mode->hdisplay;
1567
- hsw = mode->hsync_end - mode->hsync_start;
1568
- hbp = mode->htotal - mode->hsync_end;
1569
-
1570
- pr_info("hfp: %u, hsw: %u, hbp: %u\n", hfp, hsw, hbp);
1571
-
1572
- b = hfp - 1;
1573
-
1574
- pr_info("a: %u, b: %u\n", a, b);
1575
- pr_info("a + hsw + hbp = %u\n", a + hsw + hbp);
1576
-
1577
- if (a + hsw + hbp <= 11) {
1578
- a = 1 + 11 - hsw - hbp;
1579
- pr_info("a: %u\n", a);
1580
- }
1581
-
1582
- if (a > b)
1583
- return -EINVAL;
1584
-
1585
- if (hsw < 1)
1586
- return -EINVAL;
1587
-
1588
- if (mode->hdisplay < 16)
1589
- return -EINVAL;
1590
-
1591
- if (value) {
1592
- if (b > a && a % 2)
1593
- *value = a + 1;
1594
- else
1595
- *value = a;
1596
- }
1597
-
1598
- return 0;
1599
-}
1600
-#endif
1601
-
1602
-static void tegra_sor_edp_enable(struct drm_encoder *encoder)
1603
-{
1604
- struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
1605
- struct tegra_output *output = encoder_to_output(encoder);
1606
- struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
1607
- struct tegra_sor *sor = to_sor(output);
1608
- struct tegra_sor_config config;
1609
- struct tegra_sor_state *state;
1610
- struct drm_dp_link link;
1611
- u8 rate, lanes;
1612
- unsigned int i;
1613
- int err = 0;
1614
- u32 value;
1615
-
1616
- state = to_sor_state(output->connector.state);
1617
-
1618
- pm_runtime_get_sync(sor->dev);
1619
-
1620
- if (output->panel)
1621
- drm_panel_prepare(output->panel);
1622
-
1623
- err = drm_dp_aux_enable(sor->aux);
1624
- if (err < 0)
1625
- dev_err(sor->dev, "failed to enable DP: %d\n", err);
1626
-
1627
- err = drm_dp_link_probe(sor->aux, &link);
1628
- if (err < 0) {
1629
- dev_err(sor->dev, "failed to probe eDP link: %d\n", err);
1630
- return;
1631
- }
1632
-
1633
- /* switch to safe parent clock */
1634
- err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
1635
- if (err < 0)
1636
- dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
1637
-
1638
- memset(&config, 0, sizeof(config));
1639
- config.bits_per_pixel = state->bpc * 3;
1640
-
1641
- err = tegra_sor_compute_config(sor, mode, &config, &link);
1642
- if (err < 0)
1643
- dev_err(sor->dev, "failed to compute configuration: %d\n", err);
1644
-
1645
- value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
1646
- value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;
1647
- value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK;
1648
- tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
1649
-
1650
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1651
- value &= ~SOR_PLL2_BANDGAP_POWERDOWN;
1652
- tegra_sor_writel(sor, value, sor->soc->regs->pll2);
1653
- usleep_range(20, 100);
1654
-
1655
- value = tegra_sor_readl(sor, sor->soc->regs->pll3);
1656
- value |= SOR_PLL3_PLL_VDD_MODE_3V3;
1657
- tegra_sor_writel(sor, value, sor->soc->regs->pll3);
1658
-
1659
- value = SOR_PLL0_ICHPMP(0xf) | SOR_PLL0_VCOCAP_RST |
1660
- SOR_PLL0_PLLREG_LEVEL_V45 | SOR_PLL0_RESISTOR_EXT;
1661
- tegra_sor_writel(sor, value, sor->soc->regs->pll0);
1662
-
1663
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1664
- value |= SOR_PLL2_SEQ_PLLCAPPD;
1665
- value &= ~SOR_PLL2_SEQ_PLLCAPPD_ENFORCE;
1666
- value |= SOR_PLL2_LVDS_ENABLE;
1667
- tegra_sor_writel(sor, value, sor->soc->regs->pll2);
1668
-
1669
- value = SOR_PLL1_TERM_COMPOUT | SOR_PLL1_TMDS_TERM;
1670
- tegra_sor_writel(sor, value, sor->soc->regs->pll1);
1671
-
1672
- while (true) {
1673
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1674
- if ((value & SOR_PLL2_SEQ_PLLCAPPD_ENFORCE) == 0)
1675
- break;
1676
-
1677
- usleep_range(250, 1000);
1678
- }
1679
-
1680
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1681
- value &= ~SOR_PLL2_POWERDOWN_OVERRIDE;
1682
- value &= ~SOR_PLL2_PORT_POWERDOWN;
1683
- tegra_sor_writel(sor, value, sor->soc->regs->pll2);
1684
-
1685
- /*
1686
- * power up
1687
- */
1688
-
1689
- /* set safe link bandwidth (1.62 Gbps) */
1690
- value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
1691
- value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
1692
- value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G1_62;
1693
- tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
1694
-
1695
- /* step 1 */
1696
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1697
- value |= SOR_PLL2_SEQ_PLLCAPPD_ENFORCE | SOR_PLL2_PORT_POWERDOWN |
1698
- SOR_PLL2_BANDGAP_POWERDOWN;
1699
- tegra_sor_writel(sor, value, sor->soc->regs->pll2);
1700
-
1701
- value = tegra_sor_readl(sor, sor->soc->regs->pll0);
1702
- value |= SOR_PLL0_VCOPD | SOR_PLL0_PWR;
1703
- tegra_sor_writel(sor, value, sor->soc->regs->pll0);
1704
-
1705
- value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
1706
- value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
1707
- tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
1708
-
1709
- /* step 2 */
1710
- err = tegra_io_pad_power_enable(sor->pad);
1711
- if (err < 0)
1712
- dev_err(sor->dev, "failed to power on I/O pad: %d\n", err);
1713
-
1714
- usleep_range(5, 100);
1715
-
1716
- /* step 3 */
1717
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1718
- value &= ~SOR_PLL2_BANDGAP_POWERDOWN;
1719
- tegra_sor_writel(sor, value, sor->soc->regs->pll2);
1720
-
1721
- usleep_range(20, 100);
1722
-
1723
- /* step 4 */
1724
- value = tegra_sor_readl(sor, sor->soc->regs->pll0);
1725
- value &= ~SOR_PLL0_VCOPD;
1726
- value &= ~SOR_PLL0_PWR;
1727
- tegra_sor_writel(sor, value, sor->soc->regs->pll0);
1728
-
1729
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1730
- value &= ~SOR_PLL2_SEQ_PLLCAPPD_ENFORCE;
1731
- tegra_sor_writel(sor, value, sor->soc->regs->pll2);
1732
-
1733
- usleep_range(200, 1000);
1734
-
1735
- /* step 5 */
1736
- value = tegra_sor_readl(sor, sor->soc->regs->pll2);
1737
- value &= ~SOR_PLL2_PORT_POWERDOWN;
1738
- tegra_sor_writel(sor, value, sor->soc->regs->pll2);
1739
-
1740
- /* XXX not in TRM */
1741
- for (value = 0, i = 0; i < 5; i++)
1742
- value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->soc->xbar_cfg[i]) |
1743
- SOR_XBAR_CTRL_LINK1_XSEL(i, i);
1744
-
1745
- tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);
1746
- tegra_sor_writel(sor, value, SOR_XBAR_CTRL);
1747
-
1748
- /* switch to DP parent clock */
1749
- err = tegra_sor_set_parent_clock(sor, sor->clk_dp);
1750
- if (err < 0)
1751
- dev_err(sor->dev, "failed to set parent clock: %d\n", err);
1752
-
1753
- /* power DP lanes */
1754
- value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
1755
-
1756
- if (link.num_lanes <= 2)
1757
- value &= ~(SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2);
1758
- else
1759
- value |= SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_2;
1760
-
1761
- if (link.num_lanes <= 1)
1762
- value &= ~SOR_DP_PADCTL_PD_TXD_1;
1763
- else
1764
- value |= SOR_DP_PADCTL_PD_TXD_1;
1765
-
1766
- if (link.num_lanes == 0)
1767
- value &= ~SOR_DP_PADCTL_PD_TXD_0;
1768
- else
1769
- value |= SOR_DP_PADCTL_PD_TXD_0;
1770
-
1771
- tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
1772
-
1773
- value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
1774
- value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
1775
- value |= SOR_DP_LINKCTL_LANE_COUNT(link.num_lanes);
1776
- tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
1777
-
1778
- /* start lane sequencer */
1779
- value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |
1780
- SOR_LANE_SEQ_CTL_POWER_STATE_UP;
1781
- tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
1782
-
1783
- while (true) {
1784
- value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
1785
- if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
1786
- break;
1787
-
1788
- usleep_range(250, 1000);
1789
- }
1790
-
1791
- /* set link bandwidth */
1792
- value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
1793
- value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
1794
- value |= drm_dp_link_rate_to_bw_code(link.rate) << 2;
1795
- tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
1796
-
1797
- tegra_sor_apply_config(sor, &config);
1798
-
1799
- /* enable link */
1800
- value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
1801
- value |= SOR_DP_LINKCTL_ENABLE;
1802
- value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
1803
- tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
1804
-
1805
- for (i = 0, value = 0; i < 4; i++) {
1806
- unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
1807
- SOR_DP_TPG_SCRAMBLER_GALIOS |
1808
- SOR_DP_TPG_PATTERN_NONE;
1809
- value = (value << 8) | lane;
1810
- }
1811
-
1812
- tegra_sor_writel(sor, value, SOR_DP_TPG);
1813
-
1814
- /* enable pad calibration logic */
1815
- value = tegra_sor_readl(sor, sor->soc->regs->dp_padctl0);
1816
- value |= SOR_DP_PADCTL_PAD_CAL_PD;
1817
- tegra_sor_writel(sor, value, sor->soc->regs->dp_padctl0);
1818
-
1819
- err = drm_dp_link_probe(sor->aux, &link);
1820
- if (err < 0)
1821
- dev_err(sor->dev, "failed to probe eDP link: %d\n", err);
1822
-
1823
- err = drm_dp_link_power_up(sor->aux, &link);
1824
- if (err < 0)
1825
- dev_err(sor->dev, "failed to power up eDP link: %d\n", err);
1826
-
1827
- err = drm_dp_link_configure(sor->aux, &link);
1828
- if (err < 0)
1829
- dev_err(sor->dev, "failed to configure eDP link: %d\n", err);
1830
-
1831
- rate = drm_dp_link_rate_to_bw_code(link.rate);
1832
- lanes = link.num_lanes;
1833
-
1834
- value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
1835
- value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
1836
- value |= SOR_CLK_CNTRL_DP_LINK_SPEED(rate);
1837
- tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
1838
-
1839
- value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
1840
- value &= ~SOR_DP_LINKCTL_LANE_COUNT_MASK;
1841
- value |= SOR_DP_LINKCTL_LANE_COUNT(lanes);
1842
-
1843
- if (link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
1844
- value |= SOR_DP_LINKCTL_ENHANCED_FRAME;
1845
-
1846
- tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
1847
-
1848
- /* disable training pattern generator */
1849
-
1850
- for (i = 0; i < link.num_lanes; i++) {
1851
- unsigned long lane = SOR_DP_TPG_CHANNEL_CODING |
1852
- SOR_DP_TPG_SCRAMBLER_GALIOS |
1853
- SOR_DP_TPG_PATTERN_NONE;
1854
- value = (value << 8) | lane;
1855
- }
1856
-
1857
- tegra_sor_writel(sor, value, SOR_DP_TPG);
1858
-
1859
- err = tegra_sor_dp_train_fast(sor, &link);
1860
- if (err < 0)
1861
- dev_err(sor->dev, "DP fast link training failed: %d\n", err);
1862
-
1863
- dev_dbg(sor->dev, "fast link training succeeded\n");
1864
-
1865
- err = tegra_sor_power_up(sor, 250);
1866
- if (err < 0)
1867
- dev_err(sor->dev, "failed to power up SOR: %d\n", err);
1868
-
1869
- /* CSTM (LVDS, link A/B, upper) */
1870
- value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B |
1871
- SOR_CSTM_UPPER;
1872
- tegra_sor_writel(sor, value, SOR_CSTM);
1873
-
1874
- /* use DP-A protocol */
1875
- value = tegra_sor_readl(sor, SOR_STATE1);
1876
- value &= ~SOR_STATE_ASY_PROTOCOL_MASK;
1877
- value |= SOR_STATE_ASY_PROTOCOL_DP_A;
1878
- tegra_sor_writel(sor, value, SOR_STATE1);
1879
-
1880
- tegra_sor_mode_set(sor, mode, state);
1881
-
1882
- /* PWM setup */
1883
- err = tegra_sor_setup_pwm(sor, 250);
1884
- if (err < 0)
1885
- dev_err(sor->dev, "failed to setup PWM: %d\n", err);
1886
-
1887
- tegra_sor_update(sor);
1888
-
1889
- value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
1890
- value |= SOR_ENABLE(0);
1891
- tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
1892
-
1893
- tegra_dc_commit(dc);
1894
-
1895
- err = tegra_sor_attach(sor);
1896
- if (err < 0)
1897
- dev_err(sor->dev, "failed to attach SOR: %d\n", err);
1898
-
1899
- err = tegra_sor_wakeup(sor);
1900
- if (err < 0)
1901
- dev_err(sor->dev, "failed to enable DC: %d\n", err);
1902
-
1903
- if (output->panel)
1904
- drm_panel_enable(output->panel);
1905
-}
1906
-
19071798 static int
19081799 tegra_sor_encoder_atomic_check(struct drm_encoder *encoder,
19091800 struct drm_crtc_state *crtc_state,
....@@ -1952,12 +1843,6 @@
19521843
19531844 return 0;
19541845 }
1955
-
1956
-static const struct drm_encoder_helper_funcs tegra_sor_edp_helpers = {
1957
- .disable = tegra_sor_edp_disable,
1958
- .enable = tegra_sor_edp_enable,
1959
- .atomic_check = tegra_sor_encoder_atomic_check,
1960
-};
19611846
19621847 static inline u32 tegra_sor_hdmi_subpack(const u8 *ptr, size_t size)
19631848 {
....@@ -2037,7 +1922,8 @@
20371922 value &= ~INFOFRAME_CTRL_ENABLE;
20381923 tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);
20391924
2040
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
1925
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
1926
+ &sor->output.connector, mode);
20411927 if (err < 0) {
20421928 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
20431929 return err;
....@@ -2060,6 +1946,162 @@
20601946 return 0;
20611947 }
20621948
1949
+static void tegra_sor_write_eld(struct tegra_sor *sor)
1950
+{
1951
+ size_t length = drm_eld_size(sor->output.connector.eld), i;
1952
+
1953
+ for (i = 0; i < length; i++)
1954
+ tegra_sor_writel(sor, i << 8 | sor->output.connector.eld[i],
1955
+ SOR_AUDIO_HDA_ELD_BUFWR);
1956
+
1957
+ /*
1958
+ * The HDA codec will always report an ELD buffer size of 96 bytes and
1959
+ * the HDA codec driver will check that each byte read from the buffer
1960
+ * is valid. Therefore every byte must be written, even if no 96 bytes
1961
+ * were parsed from EDID.
1962
+ */
1963
+ for (i = length; i < 96; i++)
1964
+ tegra_sor_writel(sor, i << 8 | 0, SOR_AUDIO_HDA_ELD_BUFWR);
1965
+}
1966
+
1967
+static void tegra_sor_audio_prepare(struct tegra_sor *sor)
1968
+{
1969
+ u32 value;
1970
+
1971
+ /*
1972
+ * Enable and unmask the HDA codec SCRATCH0 register interrupt. This
1973
+ * is used for interoperability between the HDA codec driver and the
1974
+ * HDMI/DP driver.
1975
+ */
1976
+ value = SOR_INT_CODEC_SCRATCH1 | SOR_INT_CODEC_SCRATCH0;
1977
+ tegra_sor_writel(sor, value, SOR_INT_ENABLE);
1978
+ tegra_sor_writel(sor, value, SOR_INT_MASK);
1979
+
1980
+ tegra_sor_write_eld(sor);
1981
+
1982
+ value = SOR_AUDIO_HDA_PRESENSE_ELDV | SOR_AUDIO_HDA_PRESENSE_PD;
1983
+ tegra_sor_writel(sor, value, SOR_AUDIO_HDA_PRESENSE);
1984
+}
1985
+
1986
+static void tegra_sor_audio_unprepare(struct tegra_sor *sor)
1987
+{
1988
+ tegra_sor_writel(sor, 0, SOR_AUDIO_HDA_PRESENSE);
1989
+ tegra_sor_writel(sor, 0, SOR_INT_MASK);
1990
+ tegra_sor_writel(sor, 0, SOR_INT_ENABLE);
1991
+}
1992
+
1993
+static void tegra_sor_audio_enable(struct tegra_sor *sor)
1994
+{
1995
+ u32 value;
1996
+
1997
+ value = tegra_sor_readl(sor, SOR_AUDIO_CNTRL);
1998
+
1999
+ /* select HDA audio input */
2000
+ value &= ~SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_MASK);
2001
+ value |= SOR_AUDIO_CNTRL_SOURCE_SELECT(SOURCE_SELECT_HDA);
2002
+
2003
+ /* inject null samples */
2004
+ if (sor->format.channels != 2)
2005
+ value &= ~SOR_AUDIO_CNTRL_INJECT_NULLSMPL;
2006
+ else
2007
+ value |= SOR_AUDIO_CNTRL_INJECT_NULLSMPL;
2008
+
2009
+ value |= SOR_AUDIO_CNTRL_AFIFO_FLUSH;
2010
+
2011
+ tegra_sor_writel(sor, value, SOR_AUDIO_CNTRL);
2012
+
2013
+ /* enable advertising HBR capability */
2014
+ tegra_sor_writel(sor, SOR_AUDIO_SPARE_HBR_ENABLE, SOR_AUDIO_SPARE);
2015
+}
2016
+
2017
+static int tegra_sor_hdmi_enable_audio_infoframe(struct tegra_sor *sor)
2018
+{
2019
+ u8 buffer[HDMI_INFOFRAME_SIZE(AUDIO)];
2020
+ struct hdmi_audio_infoframe frame;
2021
+ u32 value;
2022
+ int err;
2023
+
2024
+ err = hdmi_audio_infoframe_init(&frame);
2025
+ if (err < 0) {
2026
+ dev_err(sor->dev, "failed to setup audio infoframe: %d\n", err);
2027
+ return err;
2028
+ }
2029
+
2030
+ frame.channels = sor->format.channels;
2031
+
2032
+ err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
2033
+ if (err < 0) {
2034
+ dev_err(sor->dev, "failed to pack audio infoframe: %d\n", err);
2035
+ return err;
2036
+ }
2037
+
2038
+ tegra_sor_hdmi_write_infopack(sor, buffer, err);
2039
+
2040
+ value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
2041
+ value |= INFOFRAME_CTRL_CHECKSUM_ENABLE;
2042
+ value |= INFOFRAME_CTRL_ENABLE;
2043
+ tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
2044
+
2045
+ return 0;
2046
+}
2047
+
2048
+static void tegra_sor_hdmi_audio_enable(struct tegra_sor *sor)
2049
+{
2050
+ u32 value;
2051
+
2052
+ tegra_sor_audio_enable(sor);
2053
+
2054
+ tegra_sor_writel(sor, 0, SOR_HDMI_ACR_CTRL);
2055
+
2056
+ value = SOR_HDMI_SPARE_ACR_PRIORITY_HIGH |
2057
+ SOR_HDMI_SPARE_CTS_RESET(1) |
2058
+ SOR_HDMI_SPARE_HW_CTS_ENABLE;
2059
+ tegra_sor_writel(sor, value, SOR_HDMI_SPARE);
2060
+
2061
+ /* enable HW CTS */
2062
+ value = SOR_HDMI_ACR_SUBPACK_LOW_SB1(0);
2063
+ tegra_sor_writel(sor, value, SOR_HDMI_ACR_0441_SUBPACK_LOW);
2064
+
2065
+ /* allow packet to be sent */
2066
+ value = SOR_HDMI_ACR_SUBPACK_HIGH_ENABLE;
2067
+ tegra_sor_writel(sor, value, SOR_HDMI_ACR_0441_SUBPACK_HIGH);
2068
+
2069
+ /* reset N counter and enable lookup */
2070
+ value = SOR_HDMI_AUDIO_N_RESET | SOR_HDMI_AUDIO_N_LOOKUP;
2071
+ tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N);
2072
+
2073
+ value = (24000 * 4096) / (128 * sor->format.sample_rate / 1000);
2074
+ tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0320);
2075
+ tegra_sor_writel(sor, 4096, SOR_AUDIO_NVAL_0320);
2076
+
2077
+ tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_0441);
2078
+ tegra_sor_writel(sor, 4704, SOR_AUDIO_NVAL_0441);
2079
+
2080
+ tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_0882);
2081
+ tegra_sor_writel(sor, 9408, SOR_AUDIO_NVAL_0882);
2082
+
2083
+ tegra_sor_writel(sor, 20000, SOR_AUDIO_AVAL_1764);
2084
+ tegra_sor_writel(sor, 18816, SOR_AUDIO_NVAL_1764);
2085
+
2086
+ value = (24000 * 6144) / (128 * sor->format.sample_rate / 1000);
2087
+ tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0480);
2088
+ tegra_sor_writel(sor, 6144, SOR_AUDIO_NVAL_0480);
2089
+
2090
+ value = (24000 * 12288) / (128 * sor->format.sample_rate / 1000);
2091
+ tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_0960);
2092
+ tegra_sor_writel(sor, 12288, SOR_AUDIO_NVAL_0960);
2093
+
2094
+ value = (24000 * 24576) / (128 * sor->format.sample_rate / 1000);
2095
+ tegra_sor_writel(sor, value, SOR_AUDIO_AVAL_1920);
2096
+ tegra_sor_writel(sor, 24576, SOR_AUDIO_NVAL_1920);
2097
+
2098
+ value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_N);
2099
+ value &= ~SOR_HDMI_AUDIO_N_RESET;
2100
+ tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_N);
2101
+
2102
+ tegra_sor_hdmi_enable_audio_infoframe(sor);
2103
+}
2104
+
20632105 static void tegra_sor_hdmi_disable_audio_infoframe(struct tegra_sor *sor)
20642106 {
20652107 u32 value;
....@@ -2067,6 +2109,11 @@
20672109 value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
20682110 value &= ~INFOFRAME_CTRL_ENABLE;
20692111 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
2112
+}
2113
+
2114
+static void tegra_sor_hdmi_audio_disable(struct tegra_sor *sor)
2115
+{
2116
+ tegra_sor_hdmi_disable_audio_infoframe(sor);
20702117 }
20712118
20722119 static struct tegra_sor_hdmi_settings *
....@@ -2164,6 +2211,7 @@
21642211 u32 value;
21652212 int err;
21662213
2214
+ tegra_sor_audio_unprepare(sor);
21672215 tegra_sor_hdmi_scdc_stop(sor);
21682216
21692217 err = tegra_sor_detach(sor);
....@@ -2177,9 +2225,9 @@
21772225 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
21782226
21792227 if (!sor->soc->has_nvdisplay)
2180
- value &= ~(SOR1_TIMING_CYA | SOR_ENABLE(1));
2181
- else
2182
- value &= ~SOR_ENABLE(sor->index);
2228
+ value &= ~SOR1_TIMING_CYA;
2229
+
2230
+ value &= ~SOR_ENABLE(sor->index);
21832231
21842232 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
21852233
....@@ -2193,7 +2241,7 @@
21932241 if (err < 0)
21942242 dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
21952243
2196
- pm_runtime_put(sor->dev);
2244
+ host1x_client_suspend(&sor->client);
21972245 }
21982246
21992247 static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
....@@ -2214,7 +2262,11 @@
22142262 mode = &encoder->crtc->state->adjusted_mode;
22152263 pclk = mode->clock * 1000;
22162264
2217
- pm_runtime_get_sync(sor->dev);
2265
+ err = host1x_client_resume(&sor->client);
2266
+ if (err < 0) {
2267
+ dev_err(sor->dev, "failed to resume: %d\n", err);
2268
+ return;
2269
+ }
22182270
22192271 /* switch to safe parent clock */
22202272 err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
....@@ -2331,22 +2383,40 @@
23312383
23322384 /* XXX not in TRM */
23332385 for (value = 0, i = 0; i < 5; i++)
2334
- value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->soc->xbar_cfg[i]) |
2386
+ value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->xbar_cfg[i]) |
23352387 SOR_XBAR_CTRL_LINK1_XSEL(i, i);
23362388
23372389 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);
23382390 tegra_sor_writel(sor, value, SOR_XBAR_CTRL);
23392391
2340
- /* switch to parent clock */
2341
- err = clk_set_parent(sor->clk, sor->clk_parent);
2392
+ /*
2393
+ * Switch the pad clock to the DP clock. Note that we cannot actually
2394
+ * do this because Tegra186 and later don't support clk_set_parent()
2395
+ * on the sorX_pad_clkout clocks. We already do the equivalent above
2396
+ * using the DP_CLK_SEL mux of the SOR_CLK_CNTRL register.
2397
+ */
2398
+#if 0
2399
+ err = clk_set_parent(sor->clk_pad, sor->clk_dp);
23422400 if (err < 0) {
2343
- dev_err(sor->dev, "failed to set parent clock: %d\n", err);
2401
+ dev_err(sor->dev, "failed to select pad parent clock: %d\n",
2402
+ err);
2403
+ return;
2404
+ }
2405
+#endif
2406
+
2407
+ /* switch the SOR clock to the pad clock */
2408
+ err = tegra_sor_set_parent_clock(sor, sor->clk_pad);
2409
+ if (err < 0) {
2410
+ dev_err(sor->dev, "failed to select SOR parent clock: %d\n",
2411
+ err);
23442412 return;
23452413 }
23462414
2347
- err = tegra_sor_set_parent_clock(sor, sor->clk_pad);
2415
+ /* switch the output clock to the parent pixel clock */
2416
+ err = clk_set_parent(sor->clk, sor->clk_parent);
23482417 if (err < 0) {
2349
- dev_err(sor->dev, "failed to set pad clock: %d\n", err);
2418
+ dev_err(sor->dev, "failed to select output parent clock: %d\n",
2419
+ err);
23502420 return;
23512421 }
23522422
....@@ -2552,9 +2622,9 @@
25522622 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
25532623
25542624 if (!sor->soc->has_nvdisplay)
2555
- value |= SOR_ENABLE(1) | SOR1_TIMING_CYA;
2556
- else
2557
- value |= SOR_ENABLE(sor->index);
2625
+ value |= SOR1_TIMING_CYA;
2626
+
2627
+ value |= SOR_ENABLE(sor->index);
25582628
25592629 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
25602630
....@@ -2572,6 +2642,7 @@
25722642 dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);
25732643
25742644 tegra_sor_hdmi_scdc_start(sor);
2645
+ tegra_sor_audio_prepare(sor);
25752646 }
25762647
25772648 static const struct drm_encoder_helper_funcs tegra_sor_hdmi_helpers = {
....@@ -2580,9 +2651,402 @@
25802651 .atomic_check = tegra_sor_encoder_atomic_check,
25812652 };
25822653
2654
+static void tegra_sor_dp_disable(struct drm_encoder *encoder)
2655
+{
2656
+ struct tegra_output *output = encoder_to_output(encoder);
2657
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
2658
+ struct tegra_sor *sor = to_sor(output);
2659
+ u32 value;
2660
+ int err;
2661
+
2662
+ if (output->panel)
2663
+ drm_panel_disable(output->panel);
2664
+
2665
+ /*
2666
+ * Do not attempt to power down a DP link if we're not connected since
2667
+ * the AUX transactions would just be timing out.
2668
+ */
2669
+ if (output->connector.status != connector_status_disconnected) {
2670
+ err = drm_dp_link_power_down(sor->aux, &sor->link);
2671
+ if (err < 0)
2672
+ dev_err(sor->dev, "failed to power down link: %d\n",
2673
+ err);
2674
+ }
2675
+
2676
+ err = tegra_sor_detach(sor);
2677
+ if (err < 0)
2678
+ dev_err(sor->dev, "failed to detach SOR: %d\n", err);
2679
+
2680
+ tegra_sor_writel(sor, 0, SOR_STATE1);
2681
+ tegra_sor_update(sor);
2682
+
2683
+ value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
2684
+ value &= ~SOR_ENABLE(sor->index);
2685
+ tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
2686
+ tegra_dc_commit(dc);
2687
+
2688
+ value = tegra_sor_readl(sor, SOR_STATE1);
2689
+ value &= ~SOR_STATE_ASY_PROTOCOL_MASK;
2690
+ value &= ~SOR_STATE_ASY_SUBOWNER_MASK;
2691
+ value &= ~SOR_STATE_ASY_OWNER_MASK;
2692
+ tegra_sor_writel(sor, value, SOR_STATE1);
2693
+ tegra_sor_update(sor);
2694
+
2695
+ /* switch to safe parent clock */
2696
+ err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
2697
+ if (err < 0)
2698
+ dev_err(sor->dev, "failed to set safe clock: %d\n", err);
2699
+
2700
+ err = tegra_sor_power_down(sor);
2701
+ if (err < 0)
2702
+ dev_err(sor->dev, "failed to power down SOR: %d\n", err);
2703
+
2704
+ err = tegra_io_pad_power_disable(sor->pad);
2705
+ if (err < 0)
2706
+ dev_err(sor->dev, "failed to power off I/O pad: %d\n", err);
2707
+
2708
+ err = drm_dp_aux_disable(sor->aux);
2709
+ if (err < 0)
2710
+ dev_err(sor->dev, "failed disable DPAUX: %d\n", err);
2711
+
2712
+ if (output->panel)
2713
+ drm_panel_unprepare(output->panel);
2714
+
2715
+ host1x_client_suspend(&sor->client);
2716
+}
2717
+
2718
+static void tegra_sor_dp_enable(struct drm_encoder *encoder)
2719
+{
2720
+ struct tegra_output *output = encoder_to_output(encoder);
2721
+ struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
2722
+ struct tegra_sor *sor = to_sor(output);
2723
+ struct tegra_sor_config config;
2724
+ struct tegra_sor_state *state;
2725
+ struct drm_display_mode *mode;
2726
+ struct drm_display_info *info;
2727
+ unsigned int i;
2728
+ u32 value;
2729
+ int err;
2730
+
2731
+ state = to_sor_state(output->connector.state);
2732
+ mode = &encoder->crtc->state->adjusted_mode;
2733
+ info = &output->connector.display_info;
2734
+
2735
+ err = host1x_client_resume(&sor->client);
2736
+ if (err < 0) {
2737
+ dev_err(sor->dev, "failed to resume: %d\n", err);
2738
+ return;
2739
+ }
2740
+
2741
+ /* switch to safe parent clock */
2742
+ err = tegra_sor_set_parent_clock(sor, sor->clk_safe);
2743
+ if (err < 0)
2744
+ dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
2745
+
2746
+ err = tegra_io_pad_power_enable(sor->pad);
2747
+ if (err < 0)
2748
+ dev_err(sor->dev, "failed to power on LVDS rail: %d\n", err);
2749
+
2750
+ usleep_range(20, 100);
2751
+
2752
+ err = drm_dp_aux_enable(sor->aux);
2753
+ if (err < 0)
2754
+ dev_err(sor->dev, "failed to enable DPAUX: %d\n", err);
2755
+
2756
+ err = drm_dp_link_probe(sor->aux, &sor->link);
2757
+ if (err < 0)
2758
+ dev_err(sor->dev, "failed to probe DP link: %d\n", err);
2759
+
2760
+ tegra_sor_filter_rates(sor);
2761
+
2762
+ err = drm_dp_link_choose(&sor->link, mode, info);
2763
+ if (err < 0)
2764
+ dev_err(sor->dev, "failed to choose link: %d\n", err);
2765
+
2766
+ if (output->panel)
2767
+ drm_panel_prepare(output->panel);
2768
+
2769
+ value = tegra_sor_readl(sor, sor->soc->regs->pll2);
2770
+ value &= ~SOR_PLL2_BANDGAP_POWERDOWN;
2771
+ tegra_sor_writel(sor, value, sor->soc->regs->pll2);
2772
+
2773
+ usleep_range(20, 40);
2774
+
2775
+ value = tegra_sor_readl(sor, sor->soc->regs->pll3);
2776
+ value |= SOR_PLL3_PLL_VDD_MODE_3V3;
2777
+ tegra_sor_writel(sor, value, sor->soc->regs->pll3);
2778
+
2779
+ value = tegra_sor_readl(sor, sor->soc->regs->pll0);
2780
+ value &= ~(SOR_PLL0_VCOPD | SOR_PLL0_PWR);
2781
+ tegra_sor_writel(sor, value, sor->soc->regs->pll0);
2782
+
2783
+ value = tegra_sor_readl(sor, sor->soc->regs->pll2);
2784
+ value &= ~SOR_PLL2_SEQ_PLLCAPPD_ENFORCE;
2785
+ value |= SOR_PLL2_SEQ_PLLCAPPD;
2786
+ tegra_sor_writel(sor, value, sor->soc->regs->pll2);
2787
+
2788
+ usleep_range(200, 400);
2789
+
2790
+ value = tegra_sor_readl(sor, sor->soc->regs->pll2);
2791
+ value &= ~SOR_PLL2_POWERDOWN_OVERRIDE;
2792
+ value &= ~SOR_PLL2_PORT_POWERDOWN;
2793
+ tegra_sor_writel(sor, value, sor->soc->regs->pll2);
2794
+
2795
+ value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
2796
+ value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;
2797
+
2798
+ if (output->panel)
2799
+ value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_DPCLK;
2800
+ else
2801
+ value |= SOR_CLK_CNTRL_DP_CLK_SEL_DIFF_DPCLK;
2802
+
2803
+ tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
2804
+
2805
+ usleep_range(200, 400);
2806
+
2807
+ value = tegra_sor_readl(sor, SOR_DP_SPARE0);
2808
+ /* XXX not in TRM */
2809
+ if (output->panel)
2810
+ value |= SOR_DP_SPARE_PANEL_INTERNAL;
2811
+ else
2812
+ value &= ~SOR_DP_SPARE_PANEL_INTERNAL;
2813
+
2814
+ value |= SOR_DP_SPARE_SEQ_ENABLE;
2815
+ tegra_sor_writel(sor, value, SOR_DP_SPARE0);
2816
+
2817
+ /* XXX not in TRM */
2818
+ tegra_sor_writel(sor, 0, SOR_LVDS);
2819
+
2820
+ value = tegra_sor_readl(sor, sor->soc->regs->pll0);
2821
+ value &= ~SOR_PLL0_ICHPMP_MASK;
2822
+ value &= ~SOR_PLL0_VCOCAP_MASK;
2823
+ value |= SOR_PLL0_ICHPMP(0x1);
2824
+ value |= SOR_PLL0_VCOCAP(0x3);
2825
+ value |= SOR_PLL0_RESISTOR_EXT;
2826
+ tegra_sor_writel(sor, value, sor->soc->regs->pll0);
2827
+
2828
+ /* XXX not in TRM */
2829
+ for (value = 0, i = 0; i < 5; i++)
2830
+ value |= SOR_XBAR_CTRL_LINK0_XSEL(i, sor->soc->xbar_cfg[i]) |
2831
+ SOR_XBAR_CTRL_LINK1_XSEL(i, i);
2832
+
2833
+ tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);
2834
+ tegra_sor_writel(sor, value, SOR_XBAR_CTRL);
2835
+
2836
+ /*
2837
+ * Switch the pad clock to the DP clock. Note that we cannot actually
2838
+ * do this because Tegra186 and later don't support clk_set_parent()
2839
+ * on the sorX_pad_clkout clocks. We already do the equivalent above
2840
+ * using the DP_CLK_SEL mux of the SOR_CLK_CNTRL register.
2841
+ */
2842
+#if 0
2843
+ err = clk_set_parent(sor->clk_pad, sor->clk_parent);
2844
+ if (err < 0) {
2845
+ dev_err(sor->dev, "failed to select pad parent clock: %d\n",
2846
+ err);
2847
+ return;
2848
+ }
2849
+#endif
2850
+
2851
+ /* switch the SOR clock to the pad clock */
2852
+ err = tegra_sor_set_parent_clock(sor, sor->clk_pad);
2853
+ if (err < 0) {
2854
+ dev_err(sor->dev, "failed to select SOR parent clock: %d\n",
2855
+ err);
2856
+ return;
2857
+ }
2858
+
2859
+ /* switch the output clock to the parent pixel clock */
2860
+ err = clk_set_parent(sor->clk, sor->clk_parent);
2861
+ if (err < 0) {
2862
+ dev_err(sor->dev, "failed to select output parent clock: %d\n",
2863
+ err);
2864
+ return;
2865
+ }
2866
+
2867
+ /* use DP-A protocol */
2868
+ value = tegra_sor_readl(sor, SOR_STATE1);
2869
+ value &= ~SOR_STATE_ASY_PROTOCOL_MASK;
2870
+ value |= SOR_STATE_ASY_PROTOCOL_DP_A;
2871
+ tegra_sor_writel(sor, value, SOR_STATE1);
2872
+
2873
+ /* enable port */
2874
+ value = tegra_sor_readl(sor, SOR_DP_LINKCTL0);
2875
+ value |= SOR_DP_LINKCTL_ENABLE;
2876
+ tegra_sor_writel(sor, value, SOR_DP_LINKCTL0);
2877
+
2878
+ tegra_sor_dp_term_calibrate(sor);
2879
+
2880
+ err = drm_dp_link_train(&sor->link);
2881
+ if (err < 0)
2882
+ dev_err(sor->dev, "link training failed: %d\n", err);
2883
+ else
2884
+ dev_dbg(sor->dev, "link training succeeded\n");
2885
+
2886
+ err = drm_dp_link_power_up(sor->aux, &sor->link);
2887
+ if (err < 0)
2888
+ dev_err(sor->dev, "failed to power up DP link: %d\n", err);
2889
+
2890
+ /* compute configuration */
2891
+ memset(&config, 0, sizeof(config));
2892
+ config.bits_per_pixel = state->bpc * 3;
2893
+
2894
+ err = tegra_sor_compute_config(sor, mode, &config, &sor->link);
2895
+ if (err < 0)
2896
+ dev_err(sor->dev, "failed to compute configuration: %d\n", err);
2897
+
2898
+ tegra_sor_apply_config(sor, &config);
2899
+ tegra_sor_mode_set(sor, mode, state);
2900
+
2901
+ if (output->panel) {
2902
+ /* CSTM (LVDS, link A/B, upper) */
2903
+ value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B |
2904
+ SOR_CSTM_UPPER;
2905
+ tegra_sor_writel(sor, value, SOR_CSTM);
2906
+
2907
+ /* PWM setup */
2908
+ err = tegra_sor_setup_pwm(sor, 250);
2909
+ if (err < 0)
2910
+ dev_err(sor->dev, "failed to setup PWM: %d\n", err);
2911
+ }
2912
+
2913
+ tegra_sor_update(sor);
2914
+
2915
+ err = tegra_sor_power_up(sor, 250);
2916
+ if (err < 0)
2917
+ dev_err(sor->dev, "failed to power up SOR: %d\n", err);
2918
+
2919
+ /* attach and wake up */
2920
+ err = tegra_sor_attach(sor);
2921
+ if (err < 0)
2922
+ dev_err(sor->dev, "failed to attach SOR: %d\n", err);
2923
+
2924
+ value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
2925
+ value |= SOR_ENABLE(sor->index);
2926
+ tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
2927
+
2928
+ tegra_dc_commit(dc);
2929
+
2930
+ err = tegra_sor_wakeup(sor);
2931
+ if (err < 0)
2932
+ dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);
2933
+
2934
+ if (output->panel)
2935
+ drm_panel_enable(output->panel);
2936
+}
2937
+
2938
+static const struct drm_encoder_helper_funcs tegra_sor_dp_helpers = {
2939
+ .disable = tegra_sor_dp_disable,
2940
+ .enable = tegra_sor_dp_enable,
2941
+ .atomic_check = tegra_sor_encoder_atomic_check,
2942
+};
2943
+
2944
+static void tegra_sor_disable_regulator(void *data)
2945
+{
2946
+ struct regulator *reg = data;
2947
+
2948
+ regulator_disable(reg);
2949
+}
2950
+
2951
+static int tegra_sor_enable_regulator(struct tegra_sor *sor, struct regulator *reg)
2952
+{
2953
+ int err;
2954
+
2955
+ err = regulator_enable(reg);
2956
+ if (err)
2957
+ return err;
2958
+
2959
+ return devm_add_action_or_reset(sor->dev, tegra_sor_disable_regulator, reg);
2960
+}
2961
+
2962
+static int tegra_sor_hdmi_probe(struct tegra_sor *sor)
2963
+{
2964
+ int err;
2965
+
2966
+ sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io-hdmi-dp");
2967
+ if (IS_ERR(sor->avdd_io_supply)) {
2968
+ dev_err(sor->dev, "cannot get AVDD I/O supply: %ld\n",
2969
+ PTR_ERR(sor->avdd_io_supply));
2970
+ return PTR_ERR(sor->avdd_io_supply);
2971
+ }
2972
+
2973
+ err = tegra_sor_enable_regulator(sor, sor->avdd_io_supply);
2974
+ if (err < 0) {
2975
+ dev_err(sor->dev, "failed to enable AVDD I/O supply: %d\n",
2976
+ err);
2977
+ return err;
2978
+ }
2979
+
2980
+ sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-hdmi-dp-pll");
2981
+ if (IS_ERR(sor->vdd_pll_supply)) {
2982
+ dev_err(sor->dev, "cannot get VDD PLL supply: %ld\n",
2983
+ PTR_ERR(sor->vdd_pll_supply));
2984
+ return PTR_ERR(sor->vdd_pll_supply);
2985
+ }
2986
+
2987
+ err = tegra_sor_enable_regulator(sor, sor->vdd_pll_supply);
2988
+ if (err < 0) {
2989
+ dev_err(sor->dev, "failed to enable VDD PLL supply: %d\n",
2990
+ err);
2991
+ return err;
2992
+ }
2993
+
2994
+ sor->hdmi_supply = devm_regulator_get(sor->dev, "hdmi");
2995
+ if (IS_ERR(sor->hdmi_supply)) {
2996
+ dev_err(sor->dev, "cannot get HDMI supply: %ld\n",
2997
+ PTR_ERR(sor->hdmi_supply));
2998
+ return PTR_ERR(sor->hdmi_supply);
2999
+ }
3000
+
3001
+ err = tegra_sor_enable_regulator(sor, sor->hdmi_supply);
3002
+ if (err < 0) {
3003
+ dev_err(sor->dev, "failed to enable HDMI supply: %d\n", err);
3004
+ return err;
3005
+ }
3006
+
3007
+ INIT_DELAYED_WORK(&sor->scdc, tegra_sor_hdmi_scdc_work);
3008
+
3009
+ return 0;
3010
+}
3011
+
3012
+static const struct tegra_sor_ops tegra_sor_hdmi_ops = {
3013
+ .name = "HDMI",
3014
+ .probe = tegra_sor_hdmi_probe,
3015
+ .audio_enable = tegra_sor_hdmi_audio_enable,
3016
+ .audio_disable = tegra_sor_hdmi_audio_disable,
3017
+};
3018
+
3019
+static int tegra_sor_dp_probe(struct tegra_sor *sor)
3020
+{
3021
+ int err;
3022
+
3023
+ sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io-hdmi-dp");
3024
+ if (IS_ERR(sor->avdd_io_supply))
3025
+ return PTR_ERR(sor->avdd_io_supply);
3026
+
3027
+ err = tegra_sor_enable_regulator(sor, sor->avdd_io_supply);
3028
+ if (err < 0)
3029
+ return err;
3030
+
3031
+ sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-hdmi-dp-pll");
3032
+ if (IS_ERR(sor->vdd_pll_supply))
3033
+ return PTR_ERR(sor->vdd_pll_supply);
3034
+
3035
+ err = tegra_sor_enable_regulator(sor, sor->vdd_pll_supply);
3036
+ if (err < 0)
3037
+ return err;
3038
+
3039
+ return 0;
3040
+}
3041
+
3042
+static const struct tegra_sor_ops tegra_sor_dp_ops = {
3043
+ .name = "DP",
3044
+ .probe = tegra_sor_dp_probe,
3045
+};
3046
+
25833047 static int tegra_sor_init(struct host1x_client *client)
25843048 {
2585
- struct drm_device *drm = dev_get_drvdata(client->parent);
3049
+ struct drm_device *drm = dev_get_drvdata(client->host);
25863050 const struct drm_encoder_helper_funcs *helpers = NULL;
25873051 struct tegra_sor *sor = host1x_client_to_sor(client);
25883052 int connector = DRM_MODE_CONNECTOR_Unknown;
....@@ -2590,7 +3054,7 @@
25903054 int err;
25913055
25923056 if (!sor->aux) {
2593
- if (sor->soc->supports_hdmi) {
3057
+ if (sor->ops == &tegra_sor_hdmi_ops) {
25943058 connector = DRM_MODE_CONNECTOR_HDMIA;
25953059 encoder = DRM_MODE_ENCODER_TMDS;
25963060 helpers = &tegra_sor_hdmi_helpers;
....@@ -2599,27 +3063,31 @@
25993063 encoder = DRM_MODE_ENCODER_LVDS;
26003064 }
26013065 } else {
2602
- if (sor->soc->supports_edp) {
3066
+ if (sor->output.panel) {
26033067 connector = DRM_MODE_CONNECTOR_eDP;
26043068 encoder = DRM_MODE_ENCODER_TMDS;
2605
- helpers = &tegra_sor_edp_helpers;
2606
- } else if (sor->soc->supports_dp) {
3069
+ helpers = &tegra_sor_dp_helpers;
3070
+ } else {
26073071 connector = DRM_MODE_CONNECTOR_DisplayPort;
26083072 encoder = DRM_MODE_ENCODER_TMDS;
3073
+ helpers = &tegra_sor_dp_helpers;
26093074 }
3075
+
3076
+ sor->link.ops = &tegra_sor_dp_link_ops;
3077
+ sor->link.aux = sor->aux;
26103078 }
26113079
26123080 sor->output.dev = sor->dev;
26133081
2614
- drm_connector_init(drm, &sor->output.connector,
2615
- &tegra_sor_connector_funcs,
2616
- connector);
3082
+ drm_connector_init_with_ddc(drm, &sor->output.connector,
3083
+ &tegra_sor_connector_funcs,
3084
+ connector,
3085
+ sor->output.ddc);
26173086 drm_connector_helper_add(&sor->output.connector,
26183087 &tegra_sor_connector_helper_funcs);
26193088 sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
26203089
2621
- drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs,
2622
- encoder, NULL);
3090
+ drm_simple_encoder_init(drm, &sor->output.encoder, encoder);
26233091 drm_encoder_helper_add(&sor->output.encoder, helpers);
26243092
26253093 drm_connector_attach_encoder(&sor->output.connector,
....@@ -2647,18 +3115,31 @@
26473115 * kernel is possible.
26483116 */
26493117 if (sor->rst) {
3118
+ err = pm_runtime_resume_and_get(sor->dev);
3119
+ if (err < 0) {
3120
+ dev_err(sor->dev, "failed to get runtime PM: %d\n", err);
3121
+ return err;
3122
+ }
3123
+
3124
+ err = reset_control_acquire(sor->rst);
3125
+ if (err < 0) {
3126
+ dev_err(sor->dev, "failed to acquire SOR reset: %d\n",
3127
+ err);
3128
+ goto rpm_put;
3129
+ }
3130
+
26503131 err = reset_control_assert(sor->rst);
26513132 if (err < 0) {
26523133 dev_err(sor->dev, "failed to assert SOR reset: %d\n",
26533134 err);
2654
- return err;
3135
+ goto rpm_put;
26553136 }
26563137 }
26573138
26583139 err = clk_prepare_enable(sor->clk);
26593140 if (err < 0) {
26603141 dev_err(sor->dev, "failed to enable clock: %d\n", err);
2661
- return err;
3142
+ goto rpm_put;
26623143 }
26633144
26643145 usleep_range(1000, 3000);
....@@ -2669,8 +3150,11 @@
26693150 dev_err(sor->dev, "failed to deassert SOR reset: %d\n",
26703151 err);
26713152 clk_disable_unprepare(sor->clk);
2672
- return err;
3153
+ goto rpm_put;
26733154 }
3155
+
3156
+ reset_control_release(sor->rst);
3157
+ pm_runtime_put(sor->dev);
26743158 }
26753159
26763160 err = clk_prepare_enable(sor->clk_safe);
....@@ -2687,6 +3171,12 @@
26873171 }
26883172
26893173 return 0;
3174
+
3175
+rpm_put:
3176
+ if (sor->rst)
3177
+ pm_runtime_put(sor->dev);
3178
+
3179
+ return err;
26903180 }
26913181
26923182 static int tegra_sor_exit(struct host1x_client *client)
....@@ -2711,78 +3201,80 @@
27113201 return 0;
27123202 }
27133203
3204
+static int tegra_sor_runtime_suspend(struct host1x_client *client)
3205
+{
3206
+ struct tegra_sor *sor = host1x_client_to_sor(client);
3207
+ struct device *dev = client->dev;
3208
+ int err;
3209
+
3210
+ if (sor->rst) {
3211
+ err = reset_control_assert(sor->rst);
3212
+ if (err < 0) {
3213
+ dev_err(dev, "failed to assert reset: %d\n", err);
3214
+ return err;
3215
+ }
3216
+
3217
+ reset_control_release(sor->rst);
3218
+ }
3219
+
3220
+ usleep_range(1000, 2000);
3221
+
3222
+ clk_disable_unprepare(sor->clk);
3223
+ pm_runtime_put_sync(dev);
3224
+
3225
+ return 0;
3226
+}
3227
+
3228
+static int tegra_sor_runtime_resume(struct host1x_client *client)
3229
+{
3230
+ struct tegra_sor *sor = host1x_client_to_sor(client);
3231
+ struct device *dev = client->dev;
3232
+ int err;
3233
+
3234
+ err = pm_runtime_resume_and_get(dev);
3235
+ if (err < 0) {
3236
+ dev_err(dev, "failed to get runtime PM: %d\n", err);
3237
+ return err;
3238
+ }
3239
+
3240
+ err = clk_prepare_enable(sor->clk);
3241
+ if (err < 0) {
3242
+ dev_err(dev, "failed to enable clock: %d\n", err);
3243
+ goto put_rpm;
3244
+ }
3245
+
3246
+ usleep_range(1000, 2000);
3247
+
3248
+ if (sor->rst) {
3249
+ err = reset_control_acquire(sor->rst);
3250
+ if (err < 0) {
3251
+ dev_err(dev, "failed to acquire reset: %d\n", err);
3252
+ goto disable_clk;
3253
+ }
3254
+
3255
+ err = reset_control_deassert(sor->rst);
3256
+ if (err < 0) {
3257
+ dev_err(dev, "failed to deassert reset: %d\n", err);
3258
+ goto release_reset;
3259
+ }
3260
+ }
3261
+
3262
+ return 0;
3263
+
3264
+release_reset:
3265
+ reset_control_release(sor->rst);
3266
+disable_clk:
3267
+ clk_disable_unprepare(sor->clk);
3268
+put_rpm:
3269
+ pm_runtime_put_sync(dev);
3270
+ return err;
3271
+}
3272
+
27143273 static const struct host1x_client_ops sor_client_ops = {
27153274 .init = tegra_sor_init,
27163275 .exit = tegra_sor_exit,
2717
-};
2718
-
2719
-static const struct tegra_sor_ops tegra_sor_edp_ops = {
2720
- .name = "eDP",
2721
-};
2722
-
2723
-static int tegra_sor_hdmi_probe(struct tegra_sor *sor)
2724
-{
2725
- int err;
2726
-
2727
- sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io");
2728
- if (IS_ERR(sor->avdd_io_supply)) {
2729
- dev_err(sor->dev, "cannot get AVDD I/O supply: %ld\n",
2730
- PTR_ERR(sor->avdd_io_supply));
2731
- return PTR_ERR(sor->avdd_io_supply);
2732
- }
2733
-
2734
- err = regulator_enable(sor->avdd_io_supply);
2735
- if (err < 0) {
2736
- dev_err(sor->dev, "failed to enable AVDD I/O supply: %d\n",
2737
- err);
2738
- return err;
2739
- }
2740
-
2741
- sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-pll");
2742
- if (IS_ERR(sor->vdd_pll_supply)) {
2743
- dev_err(sor->dev, "cannot get VDD PLL supply: %ld\n",
2744
- PTR_ERR(sor->vdd_pll_supply));
2745
- return PTR_ERR(sor->vdd_pll_supply);
2746
- }
2747
-
2748
- err = regulator_enable(sor->vdd_pll_supply);
2749
- if (err < 0) {
2750
- dev_err(sor->dev, "failed to enable VDD PLL supply: %d\n",
2751
- err);
2752
- return err;
2753
- }
2754
-
2755
- sor->hdmi_supply = devm_regulator_get(sor->dev, "hdmi");
2756
- if (IS_ERR(sor->hdmi_supply)) {
2757
- dev_err(sor->dev, "cannot get HDMI supply: %ld\n",
2758
- PTR_ERR(sor->hdmi_supply));
2759
- return PTR_ERR(sor->hdmi_supply);
2760
- }
2761
-
2762
- err = regulator_enable(sor->hdmi_supply);
2763
- if (err < 0) {
2764
- dev_err(sor->dev, "failed to enable HDMI supply: %d\n", err);
2765
- return err;
2766
- }
2767
-
2768
- INIT_DELAYED_WORK(&sor->scdc, tegra_sor_hdmi_scdc_work);
2769
-
2770
- return 0;
2771
-}
2772
-
2773
-static int tegra_sor_hdmi_remove(struct tegra_sor *sor)
2774
-{
2775
- regulator_disable(sor->hdmi_supply);
2776
- regulator_disable(sor->vdd_pll_supply);
2777
- regulator_disable(sor->avdd_io_supply);
2778
-
2779
- return 0;
2780
-}
2781
-
2782
-static const struct tegra_sor_ops tegra_sor_hdmi_ops = {
2783
- .name = "HDMI",
2784
- .probe = tegra_sor_hdmi_probe,
2785
- .remove = tegra_sor_hdmi_remove,
3276
+ .suspend = tegra_sor_runtime_suspend,
3277
+ .resume = tegra_sor_runtime_resume,
27863278 };
27873279
27883280 static const u8 tegra124_sor_xbar_cfg[5] = {
....@@ -2804,14 +3296,161 @@
28043296 .dp_padctl2 = 0x73,
28053297 };
28063298
3299
+/* Tegra124 and Tegra132 have lanes 0 and 2 swapped. */
3300
+static const u8 tegra124_sor_lane_map[4] = {
3301
+ 2, 1, 0, 3,
3302
+};
3303
+
3304
+static const u8 tegra124_sor_voltage_swing[4][4][4] = {
3305
+ {
3306
+ { 0x13, 0x19, 0x1e, 0x28 },
3307
+ { 0x1e, 0x25, 0x2d, },
3308
+ { 0x28, 0x32, },
3309
+ { 0x3c, },
3310
+ }, {
3311
+ { 0x12, 0x17, 0x1b, 0x25 },
3312
+ { 0x1c, 0x23, 0x2a, },
3313
+ { 0x25, 0x2f, },
3314
+ { 0x39, }
3315
+ }, {
3316
+ { 0x12, 0x16, 0x1a, 0x22 },
3317
+ { 0x1b, 0x20, 0x27, },
3318
+ { 0x24, 0x2d, },
3319
+ { 0x36, },
3320
+ }, {
3321
+ { 0x11, 0x14, 0x17, 0x1f },
3322
+ { 0x19, 0x1e, 0x24, },
3323
+ { 0x22, 0x2a, },
3324
+ { 0x32, },
3325
+ },
3326
+};
3327
+
3328
+static const u8 tegra124_sor_pre_emphasis[4][4][4] = {
3329
+ {
3330
+ { 0x00, 0x09, 0x13, 0x25 },
3331
+ { 0x00, 0x0f, 0x1e, },
3332
+ { 0x00, 0x14, },
3333
+ { 0x00, },
3334
+ }, {
3335
+ { 0x00, 0x0a, 0x14, 0x28 },
3336
+ { 0x00, 0x0f, 0x1e, },
3337
+ { 0x00, 0x14, },
3338
+ { 0x00 },
3339
+ }, {
3340
+ { 0x00, 0x0a, 0x14, 0x28 },
3341
+ { 0x00, 0x0f, 0x1e, },
3342
+ { 0x00, 0x14, },
3343
+ { 0x00, },
3344
+ }, {
3345
+ { 0x00, 0x0a, 0x14, 0x28 },
3346
+ { 0x00, 0x0f, 0x1e, },
3347
+ { 0x00, 0x14, },
3348
+ { 0x00, },
3349
+ },
3350
+};
3351
+
3352
+static const u8 tegra124_sor_post_cursor[4][4][4] = {
3353
+ {
3354
+ { 0x00, 0x00, 0x00, 0x00 },
3355
+ { 0x00, 0x00, 0x00, },
3356
+ { 0x00, 0x00, },
3357
+ { 0x00, },
3358
+ }, {
3359
+ { 0x02, 0x02, 0x04, 0x05 },
3360
+ { 0x02, 0x04, 0x05, },
3361
+ { 0x04, 0x05, },
3362
+ { 0x05, },
3363
+ }, {
3364
+ { 0x04, 0x05, 0x08, 0x0b },
3365
+ { 0x05, 0x09, 0x0b, },
3366
+ { 0x08, 0x0a, },
3367
+ { 0x0b, },
3368
+ }, {
3369
+ { 0x05, 0x09, 0x0b, 0x12 },
3370
+ { 0x09, 0x0d, 0x12, },
3371
+ { 0x0b, 0x0f, },
3372
+ { 0x12, },
3373
+ },
3374
+};
3375
+
3376
+static const u8 tegra124_sor_tx_pu[4][4][4] = {
3377
+ {
3378
+ { 0x20, 0x30, 0x40, 0x60 },
3379
+ { 0x30, 0x40, 0x60, },
3380
+ { 0x40, 0x60, },
3381
+ { 0x60, },
3382
+ }, {
3383
+ { 0x20, 0x20, 0x30, 0x50 },
3384
+ { 0x30, 0x40, 0x50, },
3385
+ { 0x40, 0x50, },
3386
+ { 0x60, },
3387
+ }, {
3388
+ { 0x20, 0x20, 0x30, 0x40, },
3389
+ { 0x30, 0x30, 0x40, },
3390
+ { 0x40, 0x50, },
3391
+ { 0x60, },
3392
+ }, {
3393
+ { 0x20, 0x20, 0x20, 0x40, },
3394
+ { 0x30, 0x30, 0x40, },
3395
+ { 0x40, 0x40, },
3396
+ { 0x60, },
3397
+ },
3398
+};
3399
+
28073400 static const struct tegra_sor_soc tegra124_sor = {
2808
- .supports_edp = true,
28093401 .supports_lvds = true,
28103402 .supports_hdmi = false,
2811
- .supports_dp = false,
3403
+ .supports_dp = true,
3404
+ .supports_audio = false,
3405
+ .supports_hdcp = false,
28123406 .regs = &tegra124_sor_regs,
28133407 .has_nvdisplay = false,
28143408 .xbar_cfg = tegra124_sor_xbar_cfg,
3409
+ .lane_map = tegra124_sor_lane_map,
3410
+ .voltage_swing = tegra124_sor_voltage_swing,
3411
+ .pre_emphasis = tegra124_sor_pre_emphasis,
3412
+ .post_cursor = tegra124_sor_post_cursor,
3413
+ .tx_pu = tegra124_sor_tx_pu,
3414
+};
3415
+
3416
+static const u8 tegra132_sor_pre_emphasis[4][4][4] = {
3417
+ {
3418
+ { 0x00, 0x08, 0x12, 0x24 },
3419
+ { 0x01, 0x0e, 0x1d, },
3420
+ { 0x01, 0x13, },
3421
+ { 0x00, },
3422
+ }, {
3423
+ { 0x00, 0x08, 0x12, 0x24 },
3424
+ { 0x00, 0x0e, 0x1d, },
3425
+ { 0x00, 0x13, },
3426
+ { 0x00 },
3427
+ }, {
3428
+ { 0x00, 0x08, 0x12, 0x24 },
3429
+ { 0x00, 0x0e, 0x1d, },
3430
+ { 0x00, 0x13, },
3431
+ { 0x00, },
3432
+ }, {
3433
+ { 0x00, 0x08, 0x12, 0x24 },
3434
+ { 0x00, 0x0e, 0x1d, },
3435
+ { 0x00, 0x13, },
3436
+ { 0x00, },
3437
+ },
3438
+};
3439
+
3440
+static const struct tegra_sor_soc tegra132_sor = {
3441
+ .supports_lvds = true,
3442
+ .supports_hdmi = false,
3443
+ .supports_dp = true,
3444
+ .supports_audio = false,
3445
+ .supports_hdcp = false,
3446
+ .regs = &tegra124_sor_regs,
3447
+ .has_nvdisplay = false,
3448
+ .xbar_cfg = tegra124_sor_xbar_cfg,
3449
+ .lane_map = tegra124_sor_lane_map,
3450
+ .voltage_swing = tegra124_sor_voltage_swing,
3451
+ .pre_emphasis = tegra132_sor_pre_emphasis,
3452
+ .post_cursor = tegra124_sor_post_cursor,
3453
+ .tx_pu = tegra124_sor_tx_pu,
28153454 };
28163455
28173456 static const struct tegra_sor_regs tegra210_sor_regs = {
....@@ -2829,33 +3468,50 @@
28293468 .dp_padctl2 = 0x73,
28303469 };
28313470
2832
-static const struct tegra_sor_soc tegra210_sor = {
2833
- .supports_edp = true,
2834
- .supports_lvds = false,
2835
- .supports_hdmi = false,
2836
- .supports_dp = false,
2837
- .regs = &tegra210_sor_regs,
2838
- .has_nvdisplay = false,
2839
- .xbar_cfg = tegra124_sor_xbar_cfg,
2840
-};
2841
-
28423471 static const u8 tegra210_sor_xbar_cfg[5] = {
28433472 2, 1, 0, 3, 4
28443473 };
28453474
3475
+static const u8 tegra210_sor_lane_map[4] = {
3476
+ 0, 1, 2, 3,
3477
+};
3478
+
3479
+static const struct tegra_sor_soc tegra210_sor = {
3480
+ .supports_lvds = false,
3481
+ .supports_hdmi = false,
3482
+ .supports_dp = true,
3483
+ .supports_audio = false,
3484
+ .supports_hdcp = false,
3485
+
3486
+ .regs = &tegra210_sor_regs,
3487
+ .has_nvdisplay = false,
3488
+
3489
+ .xbar_cfg = tegra210_sor_xbar_cfg,
3490
+ .lane_map = tegra210_sor_lane_map,
3491
+ .voltage_swing = tegra124_sor_voltage_swing,
3492
+ .pre_emphasis = tegra124_sor_pre_emphasis,
3493
+ .post_cursor = tegra124_sor_post_cursor,
3494
+ .tx_pu = tegra124_sor_tx_pu,
3495
+};
3496
+
28463497 static const struct tegra_sor_soc tegra210_sor1 = {
2847
- .supports_edp = false,
28483498 .supports_lvds = false,
28493499 .supports_hdmi = true,
28503500 .supports_dp = true,
3501
+ .supports_audio = true,
3502
+ .supports_hdcp = true,
28513503
28523504 .regs = &tegra210_sor_regs,
28533505 .has_nvdisplay = false,
28543506
28553507 .num_settings = ARRAY_SIZE(tegra210_sor_hdmi_defaults),
28563508 .settings = tegra210_sor_hdmi_defaults,
2857
-
28583509 .xbar_cfg = tegra210_sor_xbar_cfg,
3510
+ .lane_map = tegra210_sor_lane_map,
3511
+ .voltage_swing = tegra124_sor_voltage_swing,
3512
+ .pre_emphasis = tegra124_sor_pre_emphasis,
3513
+ .post_cursor = tegra124_sor_post_cursor,
3514
+ .tx_pu = tegra124_sor_tx_pu,
28593515 };
28603516
28613517 static const struct tegra_sor_regs tegra186_sor_regs = {
....@@ -2873,38 +3529,116 @@
28733529 .dp_padctl2 = 0x16a,
28743530 };
28753531
2876
-static const struct tegra_sor_soc tegra186_sor = {
2877
- .supports_edp = false,
2878
- .supports_lvds = false,
2879
- .supports_hdmi = false,
2880
- .supports_dp = true,
2881
-
2882
- .regs = &tegra186_sor_regs,
2883
- .has_nvdisplay = true,
2884
-
2885
- .xbar_cfg = tegra124_sor_xbar_cfg,
3532
+static const u8 tegra186_sor_voltage_swing[4][4][4] = {
3533
+ {
3534
+ { 0x13, 0x19, 0x1e, 0x28 },
3535
+ { 0x1e, 0x25, 0x2d, },
3536
+ { 0x28, 0x32, },
3537
+ { 0x39, },
3538
+ }, {
3539
+ { 0x12, 0x16, 0x1b, 0x25 },
3540
+ { 0x1c, 0x23, 0x2a, },
3541
+ { 0x25, 0x2f, },
3542
+ { 0x37, }
3543
+ }, {
3544
+ { 0x12, 0x16, 0x1a, 0x22 },
3545
+ { 0x1b, 0x20, 0x27, },
3546
+ { 0x24, 0x2d, },
3547
+ { 0x35, },
3548
+ }, {
3549
+ { 0x11, 0x14, 0x17, 0x1f },
3550
+ { 0x19, 0x1e, 0x24, },
3551
+ { 0x22, 0x2a, },
3552
+ { 0x32, },
3553
+ },
28863554 };
28873555
2888
-static const struct tegra_sor_soc tegra186_sor1 = {
2889
- .supports_edp = false,
3556
+static const u8 tegra186_sor_pre_emphasis[4][4][4] = {
3557
+ {
3558
+ { 0x00, 0x08, 0x12, 0x24 },
3559
+ { 0x01, 0x0e, 0x1d, },
3560
+ { 0x01, 0x13, },
3561
+ { 0x00, },
3562
+ }, {
3563
+ { 0x00, 0x08, 0x12, 0x24 },
3564
+ { 0x00, 0x0e, 0x1d, },
3565
+ { 0x00, 0x13, },
3566
+ { 0x00 },
3567
+ }, {
3568
+ { 0x00, 0x08, 0x14, 0x24 },
3569
+ { 0x00, 0x0e, 0x1d, },
3570
+ { 0x00, 0x13, },
3571
+ { 0x00, },
3572
+ }, {
3573
+ { 0x00, 0x08, 0x12, 0x24 },
3574
+ { 0x00, 0x0e, 0x1d, },
3575
+ { 0x00, 0x13, },
3576
+ { 0x00, },
3577
+ },
3578
+};
3579
+
3580
+static const struct tegra_sor_soc tegra186_sor = {
28903581 .supports_lvds = false,
28913582 .supports_hdmi = true,
28923583 .supports_dp = true,
3584
+ .supports_audio = true,
3585
+ .supports_hdcp = true,
28933586
28943587 .regs = &tegra186_sor_regs,
28953588 .has_nvdisplay = true,
28963589
28973590 .num_settings = ARRAY_SIZE(tegra186_sor_hdmi_defaults),
28983591 .settings = tegra186_sor_hdmi_defaults,
2899
-
29003592 .xbar_cfg = tegra124_sor_xbar_cfg,
3593
+ .lane_map = tegra124_sor_lane_map,
3594
+ .voltage_swing = tegra186_sor_voltage_swing,
3595
+ .pre_emphasis = tegra186_sor_pre_emphasis,
3596
+ .post_cursor = tegra124_sor_post_cursor,
3597
+ .tx_pu = tegra124_sor_tx_pu,
3598
+};
3599
+
3600
+static const struct tegra_sor_regs tegra194_sor_regs = {
3601
+ .head_state0 = 0x151,
3602
+ .head_state1 = 0x155,
3603
+ .head_state2 = 0x159,
3604
+ .head_state3 = 0x15d,
3605
+ .head_state4 = 0x161,
3606
+ .head_state5 = 0x165,
3607
+ .pll0 = 0x169,
3608
+ .pll1 = 0x16a,
3609
+ .pll2 = 0x16b,
3610
+ .pll3 = 0x16c,
3611
+ .dp_padctl0 = 0x16e,
3612
+ .dp_padctl2 = 0x16f,
3613
+};
3614
+
3615
+static const struct tegra_sor_soc tegra194_sor = {
3616
+ .supports_lvds = false,
3617
+ .supports_hdmi = true,
3618
+ .supports_dp = true,
3619
+ .supports_audio = true,
3620
+ .supports_hdcp = true,
3621
+
3622
+ .regs = &tegra194_sor_regs,
3623
+ .has_nvdisplay = true,
3624
+
3625
+ .num_settings = ARRAY_SIZE(tegra194_sor_hdmi_defaults),
3626
+ .settings = tegra194_sor_hdmi_defaults,
3627
+
3628
+ .xbar_cfg = tegra210_sor_xbar_cfg,
3629
+ .lane_map = tegra124_sor_lane_map,
3630
+ .voltage_swing = tegra186_sor_voltage_swing,
3631
+ .pre_emphasis = tegra186_sor_pre_emphasis,
3632
+ .post_cursor = tegra124_sor_post_cursor,
3633
+ .tx_pu = tegra124_sor_tx_pu,
29013634 };
29023635
29033636 static const struct of_device_id tegra_sor_of_match[] = {
2904
- { .compatible = "nvidia,tegra186-sor1", .data = &tegra186_sor1 },
3637
+ { .compatible = "nvidia,tegra194-sor", .data = &tegra194_sor },
29053638 { .compatible = "nvidia,tegra186-sor", .data = &tegra186_sor },
29063639 { .compatible = "nvidia,tegra210-sor1", .data = &tegra210_sor1 },
29073640 { .compatible = "nvidia,tegra210-sor", .data = &tegra210_sor },
3641
+ { .compatible = "nvidia,tegra132-sor", .data = &tegra132_sor },
29083642 { .compatible = "nvidia,tegra124-sor", .data = &tegra124_sor },
29093643 { },
29103644 };
....@@ -2913,6 +3647,8 @@
29133647 static int tegra_sor_parse_dt(struct tegra_sor *sor)
29143648 {
29153649 struct device_node *np = sor->dev->of_node;
3650
+ u32 xbar_cfg[5];
3651
+ unsigned int i;
29163652 u32 value;
29173653 int err;
29183654
....@@ -2929,13 +3665,53 @@
29293665 */
29303666 sor->pad = TEGRA_IO_PAD_HDMI_DP0 + sor->index;
29313667 } else {
2932
- if (sor->soc->supports_edp)
3668
+ if (!sor->soc->supports_audio)
29333669 sor->index = 0;
29343670 else
29353671 sor->index = 1;
29363672 }
29373673
3674
+ err = of_property_read_u32_array(np, "nvidia,xbar-cfg", xbar_cfg, 5);
3675
+ if (err < 0) {
3676
+ /* fall back to default per-SoC XBAR configuration */
3677
+ for (i = 0; i < 5; i++)
3678
+ sor->xbar_cfg[i] = sor->soc->xbar_cfg[i];
3679
+ } else {
3680
+ /* copy cells to SOR XBAR configuration */
3681
+ for (i = 0; i < 5; i++)
3682
+ sor->xbar_cfg[i] = xbar_cfg[i];
3683
+ }
3684
+
29383685 return 0;
3686
+}
3687
+
3688
+static irqreturn_t tegra_sor_irq(int irq, void *data)
3689
+{
3690
+ struct tegra_sor *sor = data;
3691
+ u32 value;
3692
+
3693
+ value = tegra_sor_readl(sor, SOR_INT_STATUS);
3694
+ tegra_sor_writel(sor, value, SOR_INT_STATUS);
3695
+
3696
+ if (value & SOR_INT_CODEC_SCRATCH0) {
3697
+ value = tegra_sor_readl(sor, SOR_AUDIO_HDA_CODEC_SCRATCH0);
3698
+
3699
+ if (value & SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID) {
3700
+ unsigned int format;
3701
+
3702
+ format = value & SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK;
3703
+
3704
+ tegra_hda_parse_format(format, &sor->format);
3705
+
3706
+ if (sor->ops->audio_enable)
3707
+ sor->ops->audio_enable(sor);
3708
+ } else {
3709
+ if (sor->ops->audio_disable)
3710
+ sor->ops->audio_disable(sor);
3711
+ }
3712
+ }
3713
+
3714
+ return IRQ_HANDLED;
29393715 }
29403716
29413717 static int tegra_sor_probe(struct platform_device *pdev)
....@@ -2968,6 +3744,13 @@
29683744
29693745 if (!sor->aux)
29703746 return -EPROBE_DEFER;
3747
+
3748
+ if (get_device(&sor->aux->ddc.dev)) {
3749
+ if (try_module_get(sor->aux->ddc.owner))
3750
+ sor->output.ddc = &sor->aux->ddc;
3751
+ else
3752
+ put_device(&sor->aux->ddc.dev);
3753
+ }
29713754 }
29723755
29733756 if (!sor->aux) {
....@@ -2982,16 +3765,15 @@
29823765 return -ENODEV;
29833766 }
29843767 } else {
2985
- if (sor->soc->supports_edp) {
2986
- sor->ops = &tegra_sor_edp_ops;
2987
- sor->pad = TEGRA_IO_PAD_LVDS;
2988
- } else if (sor->soc->supports_dp) {
2989
- dev_err(&pdev->dev, "DisplayPort not supported yet\n");
2990
- return -ENODEV;
2991
- } else {
2992
- dev_err(&pdev->dev, "unknown (DP) support\n");
2993
- return -ENODEV;
2994
- }
3768
+ np = of_parse_phandle(pdev->dev.of_node, "nvidia,panel", 0);
3769
+ /*
3770
+ * No need to keep this around since we only use it as a check
3771
+ * to see if a panel is connected (eDP) or not (DP).
3772
+ */
3773
+ of_node_put(np);
3774
+
3775
+ sor->ops = &tegra_sor_dp_ops;
3776
+ sor->pad = TEGRA_IO_PAD_LVDS;
29953777 }
29963778
29973779 err = tegra_sor_parse_dt(sor);
....@@ -2999,17 +3781,16 @@
29993781 return err;
30003782
30013783 err = tegra_output_probe(&sor->output);
3002
- if (err < 0) {
3003
- dev_err(&pdev->dev, "failed to probe output: %d\n", err);
3004
- return err;
3005
- }
3784
+ if (err < 0)
3785
+ return dev_err_probe(&pdev->dev, err,
3786
+ "failed to probe output\n");
30063787
30073788 if (sor->ops && sor->ops->probe) {
30083789 err = sor->ops->probe(sor);
30093790 if (err < 0) {
30103791 dev_err(&pdev->dev, "failed to probe %s: %d\n",
30113792 sor->ops->name, err);
3012
- goto output;
3793
+ goto remove;
30133794 }
30143795 }
30153796
....@@ -3020,14 +3801,38 @@
30203801 goto remove;
30213802 }
30223803
3023
- if (!pdev->dev.pm_domain) {
3024
- sor->rst = devm_reset_control_get(&pdev->dev, "sor");
3025
- if (IS_ERR(sor->rst)) {
3026
- err = PTR_ERR(sor->rst);
3804
+ err = platform_get_irq(pdev, 0);
3805
+ if (err < 0) {
3806
+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", err);
3807
+ goto remove;
3808
+ }
3809
+
3810
+ sor->irq = err;
3811
+
3812
+ err = devm_request_irq(sor->dev, sor->irq, tegra_sor_irq, 0,
3813
+ dev_name(sor->dev), sor);
3814
+ if (err < 0) {
3815
+ dev_err(&pdev->dev, "failed to request IRQ: %d\n", err);
3816
+ goto remove;
3817
+ }
3818
+
3819
+ sor->rst = devm_reset_control_get_exclusive_released(&pdev->dev, "sor");
3820
+ if (IS_ERR(sor->rst)) {
3821
+ err = PTR_ERR(sor->rst);
3822
+
3823
+ if (err != -EBUSY || WARN_ON(!pdev->dev.pm_domain)) {
30273824 dev_err(&pdev->dev, "failed to get reset control: %d\n",
30283825 err);
30293826 goto remove;
30303827 }
3828
+
3829
+ /*
3830
+ * At this point, the reset control is most likely being used
3831
+ * by the generic power domain implementation. With any luck
3832
+ * the power domain will have taken care of resetting the SOR
3833
+ * and we don't have to do anything.
3834
+ */
3835
+ sor->rst = NULL;
30313836 }
30323837
30333838 sor->clk = devm_clk_get(&pdev->dev, NULL);
....@@ -3117,47 +3922,54 @@
31173922 platform_set_drvdata(pdev, sor);
31183923 pm_runtime_enable(&pdev->dev);
31193924
3925
+ host1x_client_init(&sor->client);
3926
+ sor->client.ops = &sor_client_ops;
3927
+ sor->client.dev = &pdev->dev;
3928
+
31203929 /*
31213930 * On Tegra210 and earlier, provide our own implementation for the
31223931 * pad output clock.
31233932 */
31243933 if (!sor->clk_pad) {
3125
- err = pm_runtime_get_sync(&pdev->dev);
3126
- if (err < 0) {
3127
- dev_err(&pdev->dev, "failed to get runtime PM: %d\n",
3128
- err);
3129
- goto remove;
3934
+ char *name;
3935
+
3936
+ name = devm_kasprintf(sor->dev, GFP_KERNEL, "sor%u_pad_clkout",
3937
+ sor->index);
3938
+ if (!name) {
3939
+ err = -ENOMEM;
3940
+ goto uninit;
31303941 }
31313942
3132
- sor->clk_pad = tegra_clk_sor_pad_register(sor,
3133
- "sor1_pad_clkout");
3134
- pm_runtime_put(&pdev->dev);
3943
+ err = host1x_client_resume(&sor->client);
3944
+ if (err < 0) {
3945
+ dev_err(sor->dev, "failed to resume: %d\n", err);
3946
+ goto uninit;
3947
+ }
3948
+
3949
+ sor->clk_pad = tegra_clk_sor_pad_register(sor, name);
3950
+ host1x_client_suspend(&sor->client);
31353951 }
31363952
31373953 if (IS_ERR(sor->clk_pad)) {
31383954 err = PTR_ERR(sor->clk_pad);
3139
- dev_err(&pdev->dev, "failed to register SOR pad clock: %d\n",
3955
+ dev_err(sor->dev, "failed to register SOR pad clock: %d\n",
31403956 err);
3141
- goto remove;
3957
+ goto uninit;
31423958 }
31433959
3144
- INIT_LIST_HEAD(&sor->client.list);
3145
- sor->client.ops = &sor_client_ops;
3146
- sor->client.dev = &pdev->dev;
3147
-
3148
- err = host1x_client_register(&sor->client);
3960
+ err = __host1x_client_register(&sor->client);
31493961 if (err < 0) {
31503962 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
31513963 err);
3152
- goto remove;
3964
+ goto uninit;
31533965 }
31543966
31553967 return 0;
31563968
3969
+uninit:
3970
+ host1x_client_exit(&sor->client);
3971
+ pm_runtime_disable(&pdev->dev);
31573972 remove:
3158
- if (sor->ops && sor->ops->remove)
3159
- sor->ops->remove(sor);
3160
-output:
31613973 tegra_output_remove(&sor->output);
31623974 return err;
31633975 }
....@@ -3167,8 +3979,6 @@
31673979 struct tegra_sor *sor = platform_get_drvdata(pdev);
31683980 int err;
31693981
3170
- pm_runtime_disable(&pdev->dev);
3171
-
31723982 err = host1x_client_unregister(&sor->client);
31733983 if (err < 0) {
31743984 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
....@@ -3176,66 +3986,61 @@
31763986 return err;
31773987 }
31783988
3179
- if (sor->ops && sor->ops->remove) {
3180
- err = sor->ops->remove(sor);
3181
- if (err < 0)
3182
- dev_err(&pdev->dev, "failed to remove SOR: %d\n", err);
3183
- }
3989
+ pm_runtime_disable(&pdev->dev);
31843990
31853991 tegra_output_remove(&sor->output);
31863992
31873993 return 0;
31883994 }
31893995
3190
-#ifdef CONFIG_PM
3191
-static int tegra_sor_suspend(struct device *dev)
3996
+static int __maybe_unused tegra_sor_suspend(struct device *dev)
31923997 {
31933998 struct tegra_sor *sor = dev_get_drvdata(dev);
31943999 int err;
31954000
3196
- if (sor->rst) {
3197
- err = reset_control_assert(sor->rst);
3198
- if (err < 0) {
3199
- dev_err(dev, "failed to assert reset: %d\n", err);
3200
- return err;
3201
- }
3202
- }
3203
-
3204
- usleep_range(1000, 2000);
3205
-
3206
- clk_disable_unprepare(sor->clk);
3207
-
3208
- return 0;
3209
-}
3210
-
3211
-static int tegra_sor_resume(struct device *dev)
3212
-{
3213
- struct tegra_sor *sor = dev_get_drvdata(dev);
3214
- int err;
3215
-
3216
- err = clk_prepare_enable(sor->clk);
4001
+ err = tegra_output_suspend(&sor->output);
32174002 if (err < 0) {
3218
- dev_err(dev, "failed to enable clock: %d\n", err);
4003
+ dev_err(dev, "failed to suspend output: %d\n", err);
32194004 return err;
32204005 }
32214006
3222
- usleep_range(1000, 2000);
3223
-
3224
- if (sor->rst) {
3225
- err = reset_control_deassert(sor->rst);
4007
+ if (sor->hdmi_supply) {
4008
+ err = regulator_disable(sor->hdmi_supply);
32264009 if (err < 0) {
3227
- dev_err(dev, "failed to deassert reset: %d\n", err);
3228
- clk_disable_unprepare(sor->clk);
4010
+ tegra_output_resume(&sor->output);
32294011 return err;
32304012 }
32314013 }
32324014
32334015 return 0;
32344016 }
3235
-#endif
4017
+
4018
+static int __maybe_unused tegra_sor_resume(struct device *dev)
4019
+{
4020
+ struct tegra_sor *sor = dev_get_drvdata(dev);
4021
+ int err;
4022
+
4023
+ if (sor->hdmi_supply) {
4024
+ err = regulator_enable(sor->hdmi_supply);
4025
+ if (err < 0)
4026
+ return err;
4027
+ }
4028
+
4029
+ err = tegra_output_resume(&sor->output);
4030
+ if (err < 0) {
4031
+ dev_err(dev, "failed to resume output: %d\n", err);
4032
+
4033
+ if (sor->hdmi_supply)
4034
+ regulator_disable(sor->hdmi_supply);
4035
+
4036
+ return err;
4037
+ }
4038
+
4039
+ return 0;
4040
+}
32364041
32374042 static const struct dev_pm_ops tegra_sor_pm_ops = {
3238
- SET_RUNTIME_PM_OPS(tegra_sor_suspend, tegra_sor_resume, NULL)
4043
+ SET_SYSTEM_SLEEP_PM_OPS(tegra_sor_suspend, tegra_sor_resume)
32394044 };
32404045
32414046 struct platform_driver tegra_sor_driver = {