aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-07-30 04:34:24 -0400
committerThierry Reding <treding@nvidia.com>2015-08-13 07:49:37 -0400
commit459cc2c6800b545a482e428a631d99bca8da7790 (patch)
treed7b372fdf731bee5ec6dcf820f4eafcd804e9f58
parent3309ac836229d8bc3db7618e04a51334bef13b0a (diff)
drm/tegra: sor: Add HDMI support
The SOR1 introduced on Tegra210 supports HDMI 2.0 and DisplayPort. Add HDMI support and name the debugfs node after the type of SOR. The SOR introduced with Tegra124 is known simply as "sor", whereas the additional SOR found on Tegra210 is known as "sor1". Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt1
-rw-r--r--drivers/gpu/drm/tegra/dc.h4
-rw-r--r--drivers/gpu/drm/tegra/drm.c1
-rw-r--r--drivers/gpu/drm/tegra/sor.c994
-rw-r--r--drivers/gpu/drm/tegra/sor.h86
5 files changed, 1052 insertions, 34 deletions
diff --git a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
index 626115911282..e685610d38e2 100644
--- a/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
@@ -201,6 +201,7 @@ of the following host1x client modules:
201 - "nvidia,tegra124-sor": for Tegra124 and Tegra132 201 - "nvidia,tegra124-sor": for Tegra124 and Tegra132
202 - "nvidia,tegra132-sor": for Tegra132 202 - "nvidia,tegra132-sor": for Tegra132
203 - "nvidia,tegra210-sor": for Tegra210 203 - "nvidia,tegra210-sor": for Tegra210
204 - "nvidia,tegra210-sor1": for Tegra210
204 - reg: Physical base address and length of the controller's registers. 205 - reg: Physical base address and length of the controller's registers.
205 - interrupts: The interrupt outputs from the controller. 206 - interrupts: The interrupt outputs from the controller.
206 - clocks: Must contain an entry for each entry in clock-names. 207 - clocks: Must contain an entry for each entry in clock-names.
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 203056a378f0..4a268635749b 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -128,6 +128,8 @@
128#define DC_DISP_DISP_WIN_OPTIONS 0x402 128#define DC_DISP_DISP_WIN_OPTIONS 0x402
129#define HDMI_ENABLE (1 << 30) 129#define HDMI_ENABLE (1 << 30)
130#define DSI_ENABLE (1 << 29) 130#define DSI_ENABLE (1 << 29)
131#define SOR1_TIMING_CYA (1 << 27)
132#define SOR1_ENABLE (1 << 26)
131#define SOR_ENABLE (1 << 25) 133#define SOR_ENABLE (1 << 25)
132#define CURSOR_ENABLE (1 << 16) 134#define CURSOR_ENABLE (1 << 16)
133 135
@@ -247,9 +249,11 @@
247#define BASE_COLOR_SIZE565 (6 << 0) 249#define BASE_COLOR_SIZE565 (6 << 0)
248#define BASE_COLOR_SIZE332 (7 << 0) 250#define BASE_COLOR_SIZE332 (7 << 0)
249#define BASE_COLOR_SIZE888 (8 << 0) 251#define BASE_COLOR_SIZE888 (8 << 0)
252#define DITHER_CONTROL_MASK (3 << 8)
250#define DITHER_CONTROL_DISABLE (0 << 8) 253#define DITHER_CONTROL_DISABLE (0 << 8)
251#define DITHER_CONTROL_ORDERED (2 << 8) 254#define DITHER_CONTROL_ORDERED (2 << 8)
252#define DITHER_CONTROL_ERRDIFF (3 << 8) 255#define DITHER_CONTROL_ERRDIFF (3 << 8)
256#define BASE_COLOR_SIZE_MASK (0xf << 0)
253#define BASE_COLOR_SIZE_666 (0 << 0) 257#define BASE_COLOR_SIZE_666 (0 << 0)
254#define BASE_COLOR_SIZE_111 (1 << 0) 258#define BASE_COLOR_SIZE_111 (1 << 0)
255#define BASE_COLOR_SIZE_222 (2 << 0) 259#define BASE_COLOR_SIZE_222 (2 << 0)
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index dfbbd88b040f..6d88cf1fcd1c 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1061,6 +1061,7 @@ static const struct of_device_id host1x_drm_subdevs[] = {
1061 { .compatible = "nvidia,tegra210-dc", }, 1061 { .compatible = "nvidia,tegra210-dc", },
1062 { .compatible = "nvidia,tegra210-dsi", }, 1062 { .compatible = "nvidia,tegra210-dsi", },
1063 { .compatible = "nvidia,tegra210-sor", }, 1063 { .compatible = "nvidia,tegra210-sor", },
1064 { .compatible = "nvidia,tegra210-sor1", },
1064 { /* sentinel */ } 1065 { /* sentinel */ }
1065}; 1066};
1066 1067
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 8495478d1e15..da1715ebdd71 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -10,7 +10,9 @@
10#include <linux/debugfs.h> 10#include <linux/debugfs.h>
11#include <linux/gpio.h> 11#include <linux/gpio.h>
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/of_device.h>
13#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/regulator/consumer.h>
14#include <linux/reset.h> 16#include <linux/reset.h>
15 17
16#include <soc/tegra/pmc.h> 18#include <soc/tegra/pmc.h>
@@ -23,11 +25,146 @@
23#include "drm.h" 25#include "drm.h"
24#include "sor.h" 26#include "sor.h"
25 27
28#define SOR_REKEY 0x38
29
30struct tegra_sor_hdmi_settings {
31 unsigned long frequency;
32
33 u8 vcocap;
34 u8 ichpmp;
35 u8 loadadj;
36 u8 termadj;
37 u8 tx_pu;
38 u8 bg_vref;
39
40 u8 drive_current[4];
41 u8 preemphasis[4];
42};
43
44#if 1
45static const struct tegra_sor_hdmi_settings tegra210_sor_hdmi_defaults[] = {
46 {
47 .frequency = 54000000,
48 .vcocap = 0x0,
49 .ichpmp = 0x1,
50 .loadadj = 0x3,
51 .termadj = 0x9,
52 .tx_pu = 0x10,
53 .bg_vref = 0x8,
54 .drive_current = { 0x33, 0x3a, 0x3a, 0x3a },
55 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
56 }, {
57 .frequency = 75000000,
58 .vcocap = 0x3,
59 .ichpmp = 0x1,
60 .loadadj = 0x3,
61 .termadj = 0x9,
62 .tx_pu = 0x40,
63 .bg_vref = 0x8,
64 .drive_current = { 0x33, 0x3a, 0x3a, 0x3a },
65 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
66 }, {
67 .frequency = 150000000,
68 .vcocap = 0x3,
69 .ichpmp = 0x1,
70 .loadadj = 0x3,
71 .termadj = 0x9,
72 .tx_pu = 0x66,
73 .bg_vref = 0x8,
74 .drive_current = { 0x33, 0x3a, 0x3a, 0x3a },
75 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
76 }, {
77 .frequency = 300000000,
78 .vcocap = 0x3,
79 .ichpmp = 0x1,
80 .loadadj = 0x3,
81 .termadj = 0x9,
82 .tx_pu = 0x66,
83 .bg_vref = 0xa,
84 .drive_current = { 0x33, 0x3f, 0x3f, 0x3f },
85 .preemphasis = { 0x00, 0x17, 0x17, 0x17 },
86 }, {
87 .frequency = 600000000,
88 .vcocap = 0x3,
89 .ichpmp = 0x1,
90 .loadadj = 0x3,
91 .termadj = 0x9,
92 .tx_pu = 0x66,
93 .bg_vref = 0x8,
94 .drive_current = { 0x33, 0x3f, 0x3f, 0x3f },
95 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
96 },
97};
98#else
99static const struct tegra_sor_hdmi_settings tegra210_sor_hdmi_defaults[] = {
100 {
101 .frequency = 75000000,
102 .vcocap = 0x3,
103 .ichpmp = 0x1,
104 .loadadj = 0x3,
105 .termadj = 0x9,
106 .tx_pu = 0x40,
107 .bg_vref = 0x8,
108 .drive_current = { 0x29, 0x29, 0x29, 0x29 },
109 .preemphasis = { 0x00, 0x00, 0x00, 0x00 },
110 }, {
111 .frequency = 150000000,
112 .vcocap = 0x3,
113 .ichpmp = 0x1,
114 .loadadj = 0x3,
115 .termadj = 0x9,
116 .tx_pu = 0x66,
117 .bg_vref = 0x8,
118 .drive_current = { 0x30, 0x37, 0x37, 0x37 },
119 .preemphasis = { 0x01, 0x02, 0x02, 0x02 },
120 }, {
121 .frequency = 300000000,
122 .vcocap = 0x3,
123 .ichpmp = 0x6,
124 .loadadj = 0x3,
125 .termadj = 0x9,
126 .tx_pu = 0x66,
127 .bg_vref = 0xf,
128 .drive_current = { 0x30, 0x37, 0x37, 0x37 },
129 .preemphasis = { 0x10, 0x3e, 0x3e, 0x3e },
130 }, {
131 .frequency = 600000000,
132 .vcocap = 0x3,
133 .ichpmp = 0xa,
134 .loadadj = 0x3,
135 .termadj = 0xb,
136 .tx_pu = 0x66,
137 .bg_vref = 0xe,
138 .drive_current = { 0x35, 0x3e, 0x3e, 0x3e },
139 .preemphasis = { 0x02, 0x3f, 0x3f, 0x3f },
140 },
141};
142#endif
143
144struct tegra_sor_soc {
145 bool supports_edp;
146 bool supports_lvds;
147 bool supports_hdmi;
148 bool supports_dp;
149
150 const struct tegra_sor_hdmi_settings *settings;
151 unsigned int num_settings;
152};
153
154struct tegra_sor;
155
156struct tegra_sor_ops {
157 const char *name;
158 int (*probe)(struct tegra_sor *sor);
159 int (*remove)(struct tegra_sor *sor);
160};
161
26struct tegra_sor { 162struct tegra_sor {
27 struct host1x_client client; 163 struct host1x_client client;
28 struct tegra_output output; 164 struct tegra_output output;
29 struct device *dev; 165 struct device *dev;
30 166
167 const struct tegra_sor_soc *soc;
31 void __iomem *regs; 168 void __iomem *regs;
32 169
33 struct reset_control *rst; 170 struct reset_control *rst;
@@ -41,6 +178,16 @@ struct tegra_sor {
41 struct drm_info_list *debugfs_files; 178 struct drm_info_list *debugfs_files;
42 struct drm_minor *minor; 179 struct drm_minor *minor;
43 struct dentry *debugfs; 180 struct dentry *debugfs;
181
182 const struct tegra_sor_ops *ops;
183
184 /* for HDMI 2.0 */
185 struct tegra_sor_hdmi_settings *settings;
186 unsigned int num_settings;
187
188 struct regulator *avdd_io_supply;
189 struct regulator *vdd_pll_supply;
190 struct regulator *hdmi_supply;
44}; 191};
45 192
46struct tegra_sor_config { 193struct tegra_sor_config {
@@ -184,6 +331,47 @@ static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
184 return 0; 331 return 0;
185} 332}
186 333
334static void tegra_sor_dp_term_calibrate(struct tegra_sor *sor)
335{
336 u32 mask = 0x08, adj = 0, value;
337
338 /* enable pad calibration logic */
339 value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
340 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
341 tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
342
343 value = tegra_sor_readl(sor, SOR_PLL1);
344 value |= SOR_PLL1_TMDS_TERM;
345 tegra_sor_writel(sor, value, SOR_PLL1);
346
347 while (mask) {
348 adj |= mask;
349
350 value = tegra_sor_readl(sor, SOR_PLL1);
351 value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;
352 value |= SOR_PLL1_TMDS_TERMADJ(adj);
353 tegra_sor_writel(sor, value, SOR_PLL1);
354
355 usleep_range(100, 200);
356
357 value = tegra_sor_readl(sor, SOR_PLL1);
358 if (value & SOR_PLL1_TERM_COMPOUT)
359 adj &= ~mask;
360
361 mask >>= 1;
362 }
363
364 value = tegra_sor_readl(sor, SOR_PLL1);
365 value &= ~SOR_PLL1_TMDS_TERMADJ_MASK;
366 value |= SOR_PLL1_TMDS_TERMADJ(adj);
367 tegra_sor_writel(sor, value, SOR_PLL1);
368
369 /* disable pad calibration logic */
370 value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
371 value |= SOR_DP_PADCTL_PAD_CAL_PD;
372 tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
373}
374
187static void tegra_sor_super_update(struct tegra_sor *sor) 375static void tegra_sor_super_update(struct tegra_sor *sor)
188{ 376{
189 tegra_sor_writel(sor, 0, SOR_SUPER_STATE0); 377 tegra_sor_writel(sor, 0, SOR_SUPER_STATE0);
@@ -800,10 +988,11 @@ static const struct drm_info_list debugfs_files[] = {
800static int tegra_sor_debugfs_init(struct tegra_sor *sor, 988static int tegra_sor_debugfs_init(struct tegra_sor *sor,
801 struct drm_minor *minor) 989 struct drm_minor *minor)
802{ 990{
991 const char *name = sor->soc->supports_dp ? "sor1" : "sor";
803 unsigned int i; 992 unsigned int i;
804 int err; 993 int err;
805 994
806 sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root); 995 sor->debugfs = debugfs_create_dir(name, minor->debugfs_root);
807 if (!sor->debugfs) 996 if (!sor->debugfs)
808 return -ENOMEM; 997 return -ENOMEM;
809 998
@@ -858,7 +1047,7 @@ tegra_sor_connector_detect(struct drm_connector *connector, bool force)
858 if (sor->dpaux) 1047 if (sor->dpaux)
859 return tegra_dpaux_detect(sor->dpaux); 1048 return tegra_dpaux_detect(sor->dpaux);
860 1049
861 return connector_status_unknown; 1050 return tegra_output_connector_detect(connector, force);
862} 1051}
863 1052
864static const struct drm_connector_funcs tegra_sor_connector_funcs = { 1053static const struct drm_connector_funcs tegra_sor_connector_funcs = {
@@ -956,6 +1145,48 @@ static void tegra_sor_edp_disable(struct drm_encoder *encoder)
956 clk_disable_unprepare(sor->clk); 1145 clk_disable_unprepare(sor->clk);
957} 1146}
958 1147
1148#if 0
1149static int calc_h_ref_to_sync(const struct drm_display_mode *mode,
1150 unsigned int *value)
1151{
1152 unsigned int hfp, hsw, hbp, a = 0, b;
1153
1154 hfp = mode->hsync_start - mode->hdisplay;
1155 hsw = mode->hsync_end - mode->hsync_start;
1156 hbp = mode->htotal - mode->hsync_end;
1157
1158 pr_info("hfp: %u, hsw: %u, hbp: %u\n", hfp, hsw, hbp);
1159
1160 b = hfp - 1;
1161
1162 pr_info("a: %u, b: %u\n", a, b);
1163 pr_info("a + hsw + hbp = %u\n", a + hsw + hbp);
1164
1165 if (a + hsw + hbp <= 11) {
1166 a = 1 + 11 - hsw - hbp;
1167 pr_info("a: %u\n", a);
1168 }
1169
1170 if (a > b)
1171 return -EINVAL;
1172
1173 if (hsw < 1)
1174 return -EINVAL;
1175
1176 if (mode->hdisplay < 16)
1177 return -EINVAL;
1178
1179 if (value) {
1180 if (b > a && a % 2)
1181 *value = a + 1;
1182 else
1183 *value = a;
1184 }
1185
1186 return 0;
1187}
1188#endif
1189
959static void tegra_sor_edp_enable(struct drm_encoder *encoder) 1190static void tegra_sor_edp_enable(struct drm_encoder *encoder)
960{ 1191{
961 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 1192 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
@@ -1377,34 +1608,578 @@ tegra_sor_encoder_atomic_check(struct drm_encoder *encoder,
1377 return 0; 1608 return 0;
1378} 1609}
1379 1610
1380static const struct drm_encoder_helper_funcs tegra_sor_edp_helper_funcs = { 1611static const struct drm_encoder_helper_funcs tegra_sor_edp_helpers = {
1381 .disable = tegra_sor_edp_disable, 1612 .disable = tegra_sor_edp_disable,
1382 .enable = tegra_sor_edp_enable, 1613 .enable = tegra_sor_edp_enable,
1383 .atomic_check = tegra_sor_encoder_atomic_check, 1614 .atomic_check = tegra_sor_encoder_atomic_check,
1384}; 1615};
1385 1616
1617static inline u32 tegra_sor_hdmi_subpack(const u8 *ptr, size_t size)
1618{
1619 u32 value = 0;
1620 size_t i;
1621
1622 for (i = size; i > 0; i--)
1623 value = (value << 8) | ptr[i - 1];
1624
1625 return value;
1626}
1627
1628static void tegra_sor_hdmi_write_infopack(struct tegra_sor *sor,
1629 const void *data, size_t size)
1630{
1631 const u8 *ptr = data;
1632 unsigned long offset;
1633 size_t i, j;
1634 u32 value;
1635
1636 switch (ptr[0]) {
1637 case HDMI_INFOFRAME_TYPE_AVI:
1638 offset = SOR_HDMI_AVI_INFOFRAME_HEADER;
1639 break;
1640
1641 case HDMI_INFOFRAME_TYPE_AUDIO:
1642 offset = SOR_HDMI_AUDIO_INFOFRAME_HEADER;
1643 break;
1644
1645 case HDMI_INFOFRAME_TYPE_VENDOR:
1646 offset = SOR_HDMI_VSI_INFOFRAME_HEADER;
1647 break;
1648
1649 default:
1650 dev_err(sor->dev, "unsupported infoframe type: %02x\n",
1651 ptr[0]);
1652 return;
1653 }
1654
1655 value = INFOFRAME_HEADER_TYPE(ptr[0]) |
1656 INFOFRAME_HEADER_VERSION(ptr[1]) |
1657 INFOFRAME_HEADER_LEN(ptr[2]);
1658 tegra_sor_writel(sor, value, offset);
1659 offset++;
1660
1661 /*
1662 * Each subpack contains 7 bytes, divided into:
1663 * - subpack_low: bytes 0 - 3
1664 * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00)
1665 */
1666 for (i = 3, j = 0; i < size; i += 7, j += 8) {
1667 size_t rem = size - i, num = min_t(size_t, rem, 4);
1668
1669 value = tegra_sor_hdmi_subpack(&ptr[i], num);
1670 tegra_sor_writel(sor, value, offset++);
1671
1672 num = min_t(size_t, rem - num, 3);
1673
1674 value = tegra_sor_hdmi_subpack(&ptr[i + 4], num);
1675 tegra_sor_writel(sor, value, offset++);
1676 }
1677}
1678
1679static int
1680tegra_sor_hdmi_setup_avi_infoframe(struct tegra_sor *sor,
1681 const struct drm_display_mode *mode)
1682{
1683 u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
1684 struct hdmi_avi_infoframe frame;
1685 u32 value;
1686 int err;
1687
1688 /* disable AVI infoframe */
1689 value = tegra_sor_readl(sor, SOR_HDMI_AVI_INFOFRAME_CTRL);
1690 value &= ~INFOFRAME_CTRL_SINGLE;
1691 value &= ~INFOFRAME_CTRL_OTHER;
1692 value &= ~INFOFRAME_CTRL_ENABLE;
1693 tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);
1694
1695 err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
1696 if (err < 0) {
1697 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
1698 return err;
1699 }
1700
1701 err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer));
1702 if (err < 0) {
1703 dev_err(sor->dev, "failed to pack AVI infoframe: %d\n", err);
1704 return err;
1705 }
1706
1707 tegra_sor_hdmi_write_infopack(sor, buffer, err);
1708
1709 /* enable AVI infoframe */
1710 value = tegra_sor_readl(sor, SOR_HDMI_AVI_INFOFRAME_CTRL);
1711 value |= INFOFRAME_CTRL_CHECKSUM_ENABLE;
1712 value |= INFOFRAME_CTRL_ENABLE;
1713 tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL);
1714
1715 return 0;
1716}
1717
1718static void tegra_sor_hdmi_disable_audio_infoframe(struct tegra_sor *sor)
1719{
1720 u32 value;
1721
1722 value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
1723 value &= ~INFOFRAME_CTRL_ENABLE;
1724 tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL);
1725}
1726
1727static struct tegra_sor_hdmi_settings *
1728tegra_sor_hdmi_find_settings(struct tegra_sor *sor, unsigned long frequency)
1729{
1730 unsigned int i;
1731
1732 for (i = 0; i < sor->num_settings; i++)
1733 if (frequency <= sor->settings[i].frequency)
1734 return &sor->settings[i];
1735
1736 return NULL;
1737}
1738
1739static void tegra_sor_hdmi_disable(struct drm_encoder *encoder)
1740{
1741 struct tegra_output *output = encoder_to_output(encoder);
1742 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
1743 struct tegra_sor *sor = to_sor(output);
1744 u32 value;
1745 int err;
1746
1747 err = tegra_sor_detach(sor);
1748 if (err < 0)
1749 dev_err(sor->dev, "failed to detach SOR: %d\n", err);
1750
1751 tegra_sor_writel(sor, 0, SOR_STATE1);
1752 tegra_sor_update(sor);
1753
1754 /* disable display to SOR clock */
1755 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
1756 value &= ~SOR1_TIMING_CYA;
1757 value &= ~SOR1_ENABLE;
1758 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
1759
1760 tegra_dc_commit(dc);
1761
1762 err = tegra_sor_power_down(sor);
1763 if (err < 0)
1764 dev_err(sor->dev, "failed to power down SOR: %d\n", err);
1765
1766 err = tegra_io_rail_power_off(TEGRA_IO_RAIL_HDMI);
1767 if (err < 0)
1768 dev_err(sor->dev, "failed to power off HDMI rail: %d\n", err);
1769
1770 reset_control_assert(sor->rst);
1771 usleep_range(1000, 2000);
1772 clk_disable_unprepare(sor->clk);
1773}
1774
1775static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
1776{
1777 struct tegra_output *output = encoder_to_output(encoder);
1778 unsigned int h_ref_to_sync = 1, pulse_start, max_ac;
1779 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
1780 unsigned int vbe, vse, hbe, hse, vbs, hbs, div;
1781 struct tegra_sor_hdmi_settings *settings;
1782 struct tegra_sor *sor = to_sor(output);
1783 struct drm_display_mode *mode;
1784 struct drm_display_info *info;
1785 u32 value;
1786 int err;
1787
1788 mode = &encoder->crtc->state->adjusted_mode;
1789 info = &output->connector.display_info;
1790
1791 err = clk_prepare_enable(sor->clk);
1792 if (err < 0)
1793 dev_err(sor->dev, "failed to enable clock: %d\n", err);
1794
1795 usleep_range(1000, 2000);
1796
1797 reset_control_deassert(sor->rst);
1798
1799 err = clk_set_parent(sor->clk, sor->clk_safe);
1800 if (err < 0)
1801 dev_err(sor->dev, "failed to set safe parent clock: %d\n", err);
1802
1803 div = clk_get_rate(sor->clk) / 1000000 * 4;
1804
1805 err = tegra_io_rail_power_on(TEGRA_IO_RAIL_HDMI);
1806 if (err < 0)
1807 dev_err(sor->dev, "failed to power on HDMI rail: %d\n", err);
1808
1809 usleep_range(20, 100);
1810
1811 value = tegra_sor_readl(sor, SOR_PLL2);
1812 value &= ~SOR_PLL2_BANDGAP_POWERDOWN;
1813 tegra_sor_writel(sor, value, SOR_PLL2);
1814
1815 usleep_range(20, 100);
1816
1817 value = tegra_sor_readl(sor, SOR_PLL3);
1818 value &= ~SOR_PLL3_PLL_VDD_MODE_3V3;
1819 tegra_sor_writel(sor, value, SOR_PLL3);
1820
1821 value = tegra_sor_readl(sor, SOR_PLL0);
1822 value &= ~SOR_PLL0_VCOPD;
1823 value &= ~SOR_PLL0_PWR;
1824 tegra_sor_writel(sor, value, SOR_PLL0);
1825
1826 value = tegra_sor_readl(sor, SOR_PLL2);
1827 value &= ~SOR_PLL2_SEQ_PLLCAPPD_ENFORCE;
1828 tegra_sor_writel(sor, value, SOR_PLL2);
1829
1830 usleep_range(200, 400);
1831
1832 value = tegra_sor_readl(sor, SOR_PLL2);
1833 value &= ~SOR_PLL2_POWERDOWN_OVERRIDE;
1834 value &= ~SOR_PLL2_PORT_POWERDOWN;
1835 tegra_sor_writel(sor, value, SOR_PLL2);
1836
1837 usleep_range(20, 100);
1838
1839 value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
1840 value |= SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 |
1841 SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2;
1842 tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
1843
1844 while (true) {
1845 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
1846 if ((value & SOR_LANE_SEQ_CTL_STATE_BUSY) == 0)
1847 break;
1848
1849 usleep_range(250, 1000);
1850 }
1851
1852 value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN |
1853 SOR_LANE_SEQ_CTL_POWER_STATE_UP | SOR_LANE_SEQ_CTL_DELAY(5);
1854 tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL);
1855
1856 while (true) {
1857 value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL);
1858 if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0)
1859 break;
1860
1861 usleep_range(250, 1000);
1862 }
1863
1864 value = tegra_sor_readl(sor, SOR_CLK_CNTRL);
1865 value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK;
1866 value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK;
1867
1868 if (mode->clock < 340000)
1869 value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G2_70;
1870 else
1871 value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G5_40;
1872
1873 value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_PCLK;
1874 tegra_sor_writel(sor, value, SOR_CLK_CNTRL);
1875
1876 value = tegra_sor_readl(sor, SOR_DP_SPARE0);
1877 value |= SOR_DP_SPARE_DISP_VIDEO_PREAMBLE;
1878 value &= ~SOR_DP_SPARE_PANEL_INTERNAL;
1879 value |= SOR_DP_SPARE_SEQ_ENABLE;
1880 tegra_sor_writel(sor, value, SOR_DP_SPARE0);
1881
1882 value = SOR_SEQ_CTL_PU_PC(0) | SOR_SEQ_CTL_PU_PC_ALT(0) |
1883 SOR_SEQ_CTL_PD_PC(8) | SOR_SEQ_CTL_PD_PC_ALT(8);
1884 tegra_sor_writel(sor, value, SOR_SEQ_CTL);
1885
1886 value = SOR_SEQ_INST_DRIVE_PWM_OUT_LO | SOR_SEQ_INST_HALT |
1887 SOR_SEQ_INST_WAIT_VSYNC | SOR_SEQ_INST_WAIT(1);
1888 tegra_sor_writel(sor, value, SOR_SEQ_INST(0));
1889 tegra_sor_writel(sor, value, SOR_SEQ_INST(8));
1890
1891 /* program the reference clock */
1892 value = SOR_REFCLK_DIV_INT(div) | SOR_REFCLK_DIV_FRAC(div);
1893 tegra_sor_writel(sor, value, SOR_REFCLK);
1894
1895 /* XXX don't hardcode */
1896 value = SOR_XBAR_CTRL_LINK1_XSEL(4, 4) |
1897 SOR_XBAR_CTRL_LINK1_XSEL(3, 3) |
1898 SOR_XBAR_CTRL_LINK1_XSEL(2, 2) |
1899 SOR_XBAR_CTRL_LINK1_XSEL(1, 1) |
1900 SOR_XBAR_CTRL_LINK1_XSEL(0, 0) |
1901 SOR_XBAR_CTRL_LINK0_XSEL(4, 4) |
1902 SOR_XBAR_CTRL_LINK0_XSEL(3, 3) |
1903 SOR_XBAR_CTRL_LINK0_XSEL(2, 0) |
1904 SOR_XBAR_CTRL_LINK0_XSEL(1, 1) |
1905 SOR_XBAR_CTRL_LINK0_XSEL(0, 2);
1906 tegra_sor_writel(sor, value, SOR_XBAR_CTRL);
1907
1908 tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL);
1909
1910 err = clk_set_parent(sor->clk, sor->clk_parent);
1911 if (err < 0)
1912 dev_err(sor->dev, "failed to set parent clock: %d\n", err);
1913
1914 value = SOR_INPUT_CONTROL_HDMI_SRC_SELECT(dc->pipe);
1915
1916 /* XXX is this the proper check? */
1917 if (mode->clock < 75000)
1918 value |= SOR_INPUT_CONTROL_ARM_VIDEO_RANGE_LIMITED;
1919
1920 tegra_sor_writel(sor, value, SOR_INPUT_CONTROL);
1921
1922 max_ac = ((mode->htotal - mode->hdisplay) - SOR_REKEY - 18) / 32;
1923
1924 value = SOR_HDMI_CTRL_ENABLE | SOR_HDMI_CTRL_MAX_AC_PACKET(max_ac) |
1925 SOR_HDMI_CTRL_AUDIO_LAYOUT | SOR_HDMI_CTRL_REKEY(SOR_REKEY);
1926 tegra_sor_writel(sor, value, SOR_HDMI_CTRL);
1927
1928 /* H_PULSE2 setup */
1929 pulse_start = h_ref_to_sync + (mode->hsync_end - mode->hsync_start) +
1930 (mode->htotal - mode->hsync_end) - 10;
1931
1932 value = PULSE_LAST_END_A | PULSE_QUAL_VACTIVE |
1933 PULSE_POLARITY_HIGH | PULSE_MODE_NORMAL;
1934 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_CONTROL);
1935
1936 value = PULSE_END(pulse_start + 8) | PULSE_START(pulse_start);
1937 tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_POSITION_A);
1938
1939 value = tegra_dc_readl(dc, DC_DISP_DISP_SIGNAL_OPTIONS0);
1940 value |= H_PULSE2_ENABLE;
1941 tegra_dc_writel(dc, value, DC_DISP_DISP_SIGNAL_OPTIONS0);
1942
1943 /* infoframe setup */
1944 err = tegra_sor_hdmi_setup_avi_infoframe(sor, mode);
1945 if (err < 0)
1946 dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err);
1947
1948 /* XXX HDMI audio support not implemented yet */
1949 tegra_sor_hdmi_disable_audio_infoframe(sor);
1950
1951 /* use single TMDS protocol */
1952 value = tegra_sor_readl(sor, SOR_STATE1);
1953 value &= ~SOR_STATE_ASY_PROTOCOL_MASK;
1954 value |= SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A;
1955 tegra_sor_writel(sor, value, SOR_STATE1);
1956
1957 /* power up pad calibration */
1958 value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
1959 value &= ~SOR_DP_PADCTL_PAD_CAL_PD;
1960 tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
1961
1962 /* production settings */
1963 settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000);
1964 if (IS_ERR(settings)) {
1965 dev_err(sor->dev, "no settings for pixel clock %d Hz: %ld\n",
1966 mode->clock * 1000, PTR_ERR(settings));
1967 return;
1968 }
1969
1970 value = tegra_sor_readl(sor, SOR_PLL0);
1971 value &= ~SOR_PLL0_ICHPMP_MASK;
1972 value &= ~SOR_PLL0_VCOCAP_MASK;
1973 value |= SOR_PLL0_ICHPMP(settings->ichpmp);
1974 value |= SOR_PLL0_VCOCAP(settings->vcocap);
1975 tegra_sor_writel(sor, value, SOR_PLL0);
1976
1977 tegra_sor_dp_term_calibrate(sor);
1978
1979 value = tegra_sor_readl(sor, SOR_PLL1);
1980 value &= ~SOR_PLL1_LOADADJ_MASK;
1981 value |= SOR_PLL1_LOADADJ(settings->loadadj);
1982 tegra_sor_writel(sor, value, SOR_PLL1);
1983
1984 value = tegra_sor_readl(sor, SOR_PLL3);
1985 value &= ~SOR_PLL3_BG_VREF_LEVEL_MASK;
1986 value |= SOR_PLL3_BG_VREF_LEVEL(settings->bg_vref);
1987 tegra_sor_writel(sor, value, SOR_PLL3);
1988
1989 value = settings->drive_current[0] << 24 |
1990 settings->drive_current[1] << 16 |
1991 settings->drive_current[2] << 8 |
1992 settings->drive_current[3] << 0;
1993 tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT0);
1994
1995 value = settings->preemphasis[0] << 24 |
1996 settings->preemphasis[1] << 16 |
1997 settings->preemphasis[2] << 8 |
1998 settings->preemphasis[3] << 0;
1999 tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS0);
2000
2001 value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
2002 value &= ~SOR_DP_PADCTL_TX_PU_MASK;
2003 value |= SOR_DP_PADCTL_TX_PU_ENABLE;
2004 value |= SOR_DP_PADCTL_TX_PU(settings->tx_pu);
2005 tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
2006
2007 /* power down pad calibration */
2008 value = tegra_sor_readl(sor, SOR_DP_PADCTL0);
2009 value |= SOR_DP_PADCTL_PAD_CAL_PD;
2010 tegra_sor_writel(sor, value, SOR_DP_PADCTL0);
2011
2012 /* miscellaneous display controller settings */
2013 value = VSYNC_H_POSITION(1);
2014 tegra_dc_writel(dc, value, DC_DISP_DISP_TIMING_OPTIONS);
2015
2016 value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL);
2017 value &= ~DITHER_CONTROL_MASK;
2018 value &= ~BASE_COLOR_SIZE_MASK;
2019
2020 switch (info->bpc) {
2021 case 6:
2022 value |= BASE_COLOR_SIZE_666;
2023 break;
2024
2025 case 8:
2026 value |= BASE_COLOR_SIZE_888;
2027 break;
2028
2029 default:
2030 WARN(1, "%u bits-per-color not supported\n", info->bpc);
2031 break;
2032 }
2033
2034 tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL);
2035
2036 err = tegra_sor_power_up(sor, 250);
2037 if (err < 0)
2038 dev_err(sor->dev, "failed to power up SOR: %d\n", err);
2039
2040 /* configure mode */
2041 value = tegra_sor_readl(sor, SOR_STATE1);
2042 value &= ~SOR_STATE_ASY_PIXELDEPTH_MASK;
2043 value &= ~SOR_STATE_ASY_CRC_MODE_MASK;
2044 value &= ~SOR_STATE_ASY_OWNER_MASK;
2045
2046 value |= SOR_STATE_ASY_CRC_MODE_COMPLETE |
2047 SOR_STATE_ASY_OWNER(dc->pipe + 1);
2048
2049 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
2050 value &= ~SOR_STATE_ASY_HSYNCPOL;
2051
2052 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
2053 value |= SOR_STATE_ASY_HSYNCPOL;
2054
2055 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
2056 value &= ~SOR_STATE_ASY_VSYNCPOL;
2057
2058 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
2059 value |= SOR_STATE_ASY_VSYNCPOL;
2060
2061 switch (info->bpc) {
2062 case 8:
2063 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;
2064 break;
2065
2066 case 6:
2067 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444;
2068 break;
2069
2070 default:
2071 BUG();
2072 break;
2073 }
2074
2075 tegra_sor_writel(sor, value, SOR_STATE1);
2076
2077 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe));
2078 value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK;
2079 value &= ~SOR_HEAD_STATE_DYNRANGE_MASK;
2080 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe));
2081
2082 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe));
2083 value &= ~SOR_HEAD_STATE_COLORSPACE_MASK;
2084 value |= SOR_HEAD_STATE_COLORSPACE_RGB;
2085 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe));
2086
2087 /*
2088 * TODO: The video timing programming below doesn't seem to match the
2089 * register definitions.
2090 */
2091
2092 value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff);
2093 tegra_sor_writel(sor, value, SOR_HEAD_STATE1(dc->pipe));
2094
2095 /* sync end = sync width - 1 */
2096 vse = mode->vsync_end - mode->vsync_start - 1;
2097 hse = mode->hsync_end - mode->hsync_start - 1;
2098
2099 value = ((vse & 0x7fff) << 16) | (hse & 0x7fff);
2100 tegra_sor_writel(sor, value, SOR_HEAD_STATE2(dc->pipe));
2101
2102 /* blank end = sync end + back porch */
2103 vbe = vse + (mode->vtotal - mode->vsync_end);
2104 hbe = hse + (mode->htotal - mode->hsync_end);
2105
2106 value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff);
2107 tegra_sor_writel(sor, value, SOR_HEAD_STATE3(dc->pipe));
2108
2109 /* blank start = blank end + active */
2110 vbs = vbe + mode->vdisplay;
2111 hbs = hbe + mode->hdisplay;
2112
2113 value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff);
2114 tegra_sor_writel(sor, value, SOR_HEAD_STATE4(dc->pipe));
2115
2116 tegra_sor_writel(sor, 0x1, SOR_HEAD_STATE5(dc->pipe));
2117
2118 tegra_sor_update(sor);
2119
2120 err = tegra_sor_attach(sor);
2121 if (err < 0)
2122 dev_err(sor->dev, "failed to attach SOR: %d\n", err);
2123
2124 /* enable display to SOR clock and generate HDMI preamble */
2125 value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
2126 value |= SOR1_ENABLE | SOR1_TIMING_CYA;
2127 tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
2128
2129 tegra_dc_commit(dc);
2130
2131 err = tegra_sor_wakeup(sor);
2132 if (err < 0)
2133 dev_err(sor->dev, "failed to wakeup SOR: %d\n", err);
2134}
2135
2136static const struct drm_encoder_helper_funcs tegra_sor_hdmi_helpers = {
2137 .disable = tegra_sor_hdmi_disable,
2138 .enable = tegra_sor_hdmi_enable,
2139 .atomic_check = tegra_sor_encoder_atomic_check,
2140};
2141
1386static int tegra_sor_init(struct host1x_client *client) 2142static int tegra_sor_init(struct host1x_client *client)
1387{ 2143{
1388 struct drm_device *drm = dev_get_drvdata(client->parent); 2144 struct drm_device *drm = dev_get_drvdata(client->parent);
2145 const struct drm_encoder_helper_funcs *helpers = NULL;
1389 struct tegra_sor *sor = host1x_client_to_sor(client); 2146 struct tegra_sor *sor = host1x_client_to_sor(client);
2147 int connector = DRM_MODE_CONNECTOR_Unknown;
2148 int encoder = DRM_MODE_ENCODER_NONE;
1390 int err; 2149 int err;
1391 2150
1392 if (!sor->dpaux) 2151 if (!sor->dpaux) {
1393 return -ENODEV; 2152 if (sor->soc->supports_hdmi) {
2153 connector = DRM_MODE_CONNECTOR_HDMIA;
2154 encoder = DRM_MODE_ENCODER_TMDS;
2155 helpers = &tegra_sor_hdmi_helpers;
2156 } else if (sor->soc->supports_lvds) {
2157 connector = DRM_MODE_CONNECTOR_LVDS;
2158 encoder = DRM_MODE_ENCODER_LVDS;
2159 }
2160 } else {
2161 if (sor->soc->supports_edp) {
2162 connector = DRM_MODE_CONNECTOR_eDP;
2163 encoder = DRM_MODE_ENCODER_TMDS;
2164 helpers = &tegra_sor_edp_helpers;
2165 } else if (sor->soc->supports_dp) {
2166 connector = DRM_MODE_CONNECTOR_DisplayPort;
2167 encoder = DRM_MODE_ENCODER_TMDS;
2168 }
2169 }
1394 2170
1395 sor->output.dev = sor->dev; 2171 sor->output.dev = sor->dev;
1396 2172
1397 drm_connector_init(drm, &sor->output.connector, 2173 drm_connector_init(drm, &sor->output.connector,
1398 &tegra_sor_connector_funcs, 2174 &tegra_sor_connector_funcs,
1399 DRM_MODE_CONNECTOR_eDP); 2175 connector);
1400 drm_connector_helper_add(&sor->output.connector, 2176 drm_connector_helper_add(&sor->output.connector,
1401 &tegra_sor_connector_helper_funcs); 2177 &tegra_sor_connector_helper_funcs);
1402 sor->output.connector.dpms = DRM_MODE_DPMS_OFF; 2178 sor->output.connector.dpms = DRM_MODE_DPMS_OFF;
1403 2179
1404 drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs, 2180 drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs,
1405 DRM_MODE_ENCODER_TMDS); 2181 encoder);
1406 drm_encoder_helper_add(&sor->output.encoder, 2182 drm_encoder_helper_add(&sor->output.encoder, helpers);
1407 &tegra_sor_edp_helper_funcs);
1408 2183
1409 drm_mode_connector_attach_encoder(&sor->output.connector, 2184 drm_mode_connector_attach_encoder(&sor->output.connector,
1410 &sor->output.encoder); 2185 &sor->output.encoder);
@@ -1497,18 +2272,130 @@ static const struct host1x_client_ops sor_client_ops = {
1497 .exit = tegra_sor_exit, 2272 .exit = tegra_sor_exit,
1498}; 2273};
1499 2274
2275static const struct tegra_sor_ops tegra_sor_edp_ops = {
2276 .name = "eDP",
2277};
2278
2279static int tegra_sor_hdmi_probe(struct tegra_sor *sor)
2280{
2281 int err;
2282
2283 sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io");
2284 if (IS_ERR(sor->avdd_io_supply)) {
2285 dev_err(sor->dev, "cannot get AVDD I/O supply: %ld\n",
2286 PTR_ERR(sor->avdd_io_supply));
2287 return PTR_ERR(sor->avdd_io_supply);
2288 }
2289
2290 err = regulator_enable(sor->avdd_io_supply);
2291 if (err < 0) {
2292 dev_err(sor->dev, "failed to enable AVDD I/O supply: %d\n",
2293 err);
2294 return err;
2295 }
2296
2297 sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-pll");
2298 if (IS_ERR(sor->vdd_pll_supply)) {
2299 dev_err(sor->dev, "cannot get VDD PLL supply: %ld\n",
2300 PTR_ERR(sor->vdd_pll_supply));
2301 return PTR_ERR(sor->vdd_pll_supply);
2302 }
2303
2304 err = regulator_enable(sor->vdd_pll_supply);
2305 if (err < 0) {
2306 dev_err(sor->dev, "failed to enable VDD PLL supply: %d\n",
2307 err);
2308 return err;
2309 }
2310
2311 sor->hdmi_supply = devm_regulator_get(sor->dev, "hdmi");
2312 if (IS_ERR(sor->hdmi_supply)) {
2313 dev_err(sor->dev, "cannot get HDMI supply: %ld\n",
2314 PTR_ERR(sor->hdmi_supply));
2315 return PTR_ERR(sor->hdmi_supply);
2316 }
2317
2318 err = regulator_enable(sor->hdmi_supply);
2319 if (err < 0) {
2320 dev_err(sor->dev, "failed to enable HDMI supply: %d\n", err);
2321 return err;
2322 }
2323
2324 return 0;
2325}
2326
2327static int tegra_sor_hdmi_remove(struct tegra_sor *sor)
2328{
2329 regulator_disable(sor->hdmi_supply);
2330 regulator_disable(sor->vdd_pll_supply);
2331 regulator_disable(sor->avdd_io_supply);
2332
2333 return 0;
2334}
2335
2336static const struct tegra_sor_ops tegra_sor_hdmi_ops = {
2337 .name = "HDMI",
2338 .probe = tegra_sor_hdmi_probe,
2339 .remove = tegra_sor_hdmi_remove,
2340};
2341
2342static const struct tegra_sor_soc tegra124_sor = {
2343 .supports_edp = true,
2344 .supports_lvds = true,
2345 .supports_hdmi = false,
2346 .supports_dp = false,
2347};
2348
2349static const struct tegra_sor_soc tegra210_sor = {
2350 .supports_edp = true,
2351 .supports_lvds = false,
2352 .supports_hdmi = false,
2353 .supports_dp = false,
2354};
2355
2356static const struct tegra_sor_soc tegra210_sor1 = {
2357 .supports_edp = false,
2358 .supports_lvds = false,
2359 .supports_hdmi = true,
2360 .supports_dp = true,
2361
2362 .num_settings = ARRAY_SIZE(tegra210_sor_hdmi_defaults),
2363 .settings = tegra210_sor_hdmi_defaults,
2364};
2365
2366static const struct of_device_id tegra_sor_of_match[] = {
2367 { .compatible = "nvidia,tegra210-sor1", .data = &tegra210_sor1 },
2368 { .compatible = "nvidia,tegra210-sor", .data = &tegra210_sor },
2369 { .compatible = "nvidia,tegra124-sor", .data = &tegra124_sor },
2370 { },
2371};
2372MODULE_DEVICE_TABLE(of, tegra_sor_of_match);
2373
1500static int tegra_sor_probe(struct platform_device *pdev) 2374static int tegra_sor_probe(struct platform_device *pdev)
1501{ 2375{
2376 const struct of_device_id *match;
1502 struct device_node *np; 2377 struct device_node *np;
1503 struct tegra_sor *sor; 2378 struct tegra_sor *sor;
1504 struct resource *regs; 2379 struct resource *regs;
1505 int err; 2380 int err;
1506 2381
2382 match = of_match_device(tegra_sor_of_match, &pdev->dev);
2383
1507 sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL); 2384 sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL);
1508 if (!sor) 2385 if (!sor)
1509 return -ENOMEM; 2386 return -ENOMEM;
1510 2387
1511 sor->output.dev = sor->dev = &pdev->dev; 2388 sor->output.dev = sor->dev = &pdev->dev;
2389 sor->soc = match->data;
2390
2391 sor->settings = devm_kmemdup(&pdev->dev, sor->soc->settings,
2392 sor->soc->num_settings *
2393 sizeof(*sor->settings),
2394 GFP_KERNEL);
2395 if (!sor->settings)
2396 return -ENOMEM;
2397
2398 sor->num_settings = sor->soc->num_settings;
1512 2399
1513 np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0); 2400 np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0);
1514 if (np) { 2401 if (np) {
@@ -1519,50 +2406,83 @@ static int tegra_sor_probe(struct platform_device *pdev)
1519 return -EPROBE_DEFER; 2406 return -EPROBE_DEFER;
1520 } 2407 }
1521 2408
2409 if (!sor->dpaux) {
2410 if (sor->soc->supports_hdmi) {
2411 sor->ops = &tegra_sor_hdmi_ops;
2412 } else if (sor->soc->supports_lvds) {
2413 dev_err(&pdev->dev, "LVDS not supported yet\n");
2414 return -ENODEV;
2415 } else {
2416 dev_err(&pdev->dev, "unknown (non-DP) support\n");
2417 return -ENODEV;
2418 }
2419 } else {
2420 if (sor->soc->supports_edp) {
2421 sor->ops = &tegra_sor_edp_ops;
2422 } else if (sor->soc->supports_dp) {
2423 dev_err(&pdev->dev, "DisplayPort not supported yet\n");
2424 return -ENODEV;
2425 } else {
2426 dev_err(&pdev->dev, "unknown (DP) support\n");
2427 return -ENODEV;
2428 }
2429 }
2430
1522 err = tegra_output_probe(&sor->output); 2431 err = tegra_output_probe(&sor->output);
1523 if (err < 0) { 2432 if (err < 0) {
1524 dev_err(&pdev->dev, "failed to probe output: %d\n", err); 2433 dev_err(&pdev->dev, "failed to probe output: %d\n", err);
1525 return err; 2434 return err;
1526 } 2435 }
1527 2436
2437 if (sor->ops && sor->ops->probe) {
2438 err = sor->ops->probe(sor);
2439 if (err < 0) {
2440 dev_err(&pdev->dev, "failed to probe %s: %d\n",
2441 sor->ops->name, err);
2442 goto output;
2443 }
2444 }
2445
1528 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2446 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1529 sor->regs = devm_ioremap_resource(&pdev->dev, regs); 2447 sor->regs = devm_ioremap_resource(&pdev->dev, regs);
1530 if (IS_ERR(sor->regs)) 2448 if (IS_ERR(sor->regs)) {
1531 return PTR_ERR(sor->regs); 2449 err = PTR_ERR(sor->regs);
2450 goto remove;
2451 }
1532 2452
1533 sor->rst = devm_reset_control_get(&pdev->dev, "sor"); 2453 sor->rst = devm_reset_control_get(&pdev->dev, "sor");
1534 if (IS_ERR(sor->rst)) { 2454 if (IS_ERR(sor->rst)) {
1535 dev_err(&pdev->dev, "failed to get reset control: %ld\n", 2455 err = PTR_ERR(sor->rst);
1536 PTR_ERR(sor->rst)); 2456 dev_err(&pdev->dev, "failed to get reset control: %d\n", err);
1537 return PTR_ERR(sor->rst); 2457 goto remove;
1538 } 2458 }
1539 2459
1540 sor->clk = devm_clk_get(&pdev->dev, NULL); 2460 sor->clk = devm_clk_get(&pdev->dev, NULL);
1541 if (IS_ERR(sor->clk)) { 2461 if (IS_ERR(sor->clk)) {
1542 dev_err(&pdev->dev, "failed to get module clock: %ld\n", 2462 err = PTR_ERR(sor->clk);
1543 PTR_ERR(sor->clk)); 2463 dev_err(&pdev->dev, "failed to get module clock: %d\n", err);
1544 return PTR_ERR(sor->clk); 2464 goto remove;
1545 } 2465 }
1546 2466
1547 sor->clk_parent = devm_clk_get(&pdev->dev, "parent"); 2467 sor->clk_parent = devm_clk_get(&pdev->dev, "parent");
1548 if (IS_ERR(sor->clk_parent)) { 2468 if (IS_ERR(sor->clk_parent)) {
1549 dev_err(&pdev->dev, "failed to get parent clock: %ld\n", 2469 err = PTR_ERR(sor->clk_parent);
1550 PTR_ERR(sor->clk_parent)); 2470 dev_err(&pdev->dev, "failed to get parent clock: %d\n", err);
1551 return PTR_ERR(sor->clk_parent); 2471 goto remove;
1552 } 2472 }
1553 2473
1554 sor->clk_safe = devm_clk_get(&pdev->dev, "safe"); 2474 sor->clk_safe = devm_clk_get(&pdev->dev, "safe");
1555 if (IS_ERR(sor->clk_safe)) { 2475 if (IS_ERR(sor->clk_safe)) {
1556 dev_err(&pdev->dev, "failed to get safe clock: %ld\n", 2476 err = PTR_ERR(sor->clk_safe);
1557 PTR_ERR(sor->clk_safe)); 2477 dev_err(&pdev->dev, "failed to get safe clock: %d\n", err);
1558 return PTR_ERR(sor->clk_safe); 2478 goto remove;
1559 } 2479 }
1560 2480
1561 sor->clk_dp = devm_clk_get(&pdev->dev, "dp"); 2481 sor->clk_dp = devm_clk_get(&pdev->dev, "dp");
1562 if (IS_ERR(sor->clk_dp)) { 2482 if (IS_ERR(sor->clk_dp)) {
1563 dev_err(&pdev->dev, "failed to get DP clock: %ld\n", 2483 err = PTR_ERR(sor->clk_dp);
1564 PTR_ERR(sor->clk_dp)); 2484 dev_err(&pdev->dev, "failed to get DP clock: %d\n", err);
1565 return PTR_ERR(sor->clk_dp); 2485 goto remove;
1566 } 2486 }
1567 2487
1568 INIT_LIST_HEAD(&sor->client.list); 2488 INIT_LIST_HEAD(&sor->client.list);
@@ -1573,12 +2493,19 @@ static int tegra_sor_probe(struct platform_device *pdev)
1573 if (err < 0) { 2493 if (err < 0) {
1574 dev_err(&pdev->dev, "failed to register host1x client: %d\n", 2494 dev_err(&pdev->dev, "failed to register host1x client: %d\n",
1575 err); 2495 err);
1576 return err; 2496 goto remove;
1577 } 2497 }
1578 2498
1579 platform_set_drvdata(pdev, sor); 2499 platform_set_drvdata(pdev, sor);
1580 2500
1581 return 0; 2501 return 0;
2502
2503remove:
2504 if (sor->ops && sor->ops->remove)
2505 sor->ops->remove(sor);
2506output:
2507 tegra_output_remove(&sor->output);
2508 return err;
1582} 2509}
1583 2510
1584static int tegra_sor_remove(struct platform_device *pdev) 2511static int tegra_sor_remove(struct platform_device *pdev)
@@ -1593,18 +2520,17 @@ static int tegra_sor_remove(struct platform_device *pdev)
1593 return err; 2520 return err;
1594 } 2521 }
1595 2522
2523 if (sor->ops && sor->ops->remove) {
2524 err = sor->ops->remove(sor);
2525 if (err < 0)
2526 dev_err(&pdev->dev, "failed to remove SOR: %d\n", err);
2527 }
2528
1596 tegra_output_remove(&sor->output); 2529 tegra_output_remove(&sor->output);
1597 2530
1598 return 0; 2531 return 0;
1599} 2532}
1600 2533
1601static const struct of_device_id tegra_sor_of_match[] = {
1602 { .compatible = "nvidia,tegra124-sor", },
1603 { .compatible = "nvidia,tegra210-sor", },
1604 { },
1605};
1606MODULE_DEVICE_TABLE(of, tegra_sor_of_match);
1607
1608struct platform_driver tegra_sor_driver = { 2534struct platform_driver tegra_sor_driver = {
1609 .driver = { 2535 .driver = {
1610 .name = "tegra-sor", 2536 .name = "tegra-sor",
diff --git a/drivers/gpu/drm/tegra/sor.h b/drivers/gpu/drm/tegra/sor.h
index 561b03ba969d..2d31d027e3f6 100644
--- a/drivers/gpu/drm/tegra/sor.h
+++ b/drivers/gpu/drm/tegra/sor.h
@@ -43,6 +43,12 @@
43#define SOR_STATE_ASY_OWNER(x) (((x) & 0xf) << 0) 43#define SOR_STATE_ASY_OWNER(x) (((x) & 0xf) << 0)
44 44
45#define SOR_HEAD_STATE0(x) (0x05 + (x)) 45#define SOR_HEAD_STATE0(x) (0x05 + (x))
46#define SOR_HEAD_STATE_RANGECOMPRESS_MASK (0x1 << 3)
47#define SOR_HEAD_STATE_DYNRANGE_MASK (0x1 << 2)
48#define SOR_HEAD_STATE_DYNRANGE_VESA (0 << 2)
49#define SOR_HEAD_STATE_DYNRANGE_CEA (1 << 2)
50#define SOR_HEAD_STATE_COLORSPACE_MASK (0x3 << 0)
51#define SOR_HEAD_STATE_COLORSPACE_RGB (0 << 0)
46#define SOR_HEAD_STATE1(x) (0x07 + (x)) 52#define SOR_HEAD_STATE1(x) (0x07 + (x))
47#define SOR_HEAD_STATE2(x) (0x09 + (x)) 53#define SOR_HEAD_STATE2(x) (0x09 + (x))
48#define SOR_HEAD_STATE3(x) (0x0b + (x)) 54#define SOR_HEAD_STATE3(x) (0x0b + (x))
@@ -96,7 +102,11 @@
96 102
97#define SOR_PLL1 0x18 103#define SOR_PLL1 0x18
98/* XXX: read-only bit? */ 104/* XXX: read-only bit? */
105#define SOR_PLL1_LOADADJ_MASK (0xf << 20)
106#define SOR_PLL1_LOADADJ(x) (((x) & 0xf) << 20)
99#define SOR_PLL1_TERM_COMPOUT (1 << 15) 107#define SOR_PLL1_TERM_COMPOUT (1 << 15)
108#define SOR_PLL1_TMDS_TERMADJ_MASK (0xf << 9)
109#define SOR_PLL1_TMDS_TERMADJ(x) (((x) & 0xf) << 9)
100#define SOR_PLL1_TMDS_TERM (1 << 8) 110#define SOR_PLL1_TMDS_TERM (1 << 8)
101 111
102#define SOR_PLL2 0x19 112#define SOR_PLL2 0x19
@@ -106,12 +116,17 @@
106#define SOR_PLL2_BANDGAP_POWERDOWN (1 << 22) 116#define SOR_PLL2_BANDGAP_POWERDOWN (1 << 22)
107#define SOR_PLL2_POWERDOWN_OVERRIDE (1 << 18) 117#define SOR_PLL2_POWERDOWN_OVERRIDE (1 << 18)
108#define SOR_PLL2_SEQ_PLLCAPPD (1 << 17) 118#define SOR_PLL2_SEQ_PLLCAPPD (1 << 17)
119#define SOR_PLL2_SEQ_PLL_PULLDOWN (1 << 16)
109 120
110#define SOR_PLL3 0x1a 121#define SOR_PLL3 0x1a
122#define SOR_PLL3_BG_VREF_LEVEL_MASK (0xf << 24)
123#define SOR_PLL3_BG_VREF_LEVEL(x) (((x) & 0xf) << 24)
111#define SOR_PLL3_PLL_VDD_MODE_1V8 (0 << 13) 124#define SOR_PLL3_PLL_VDD_MODE_1V8 (0 << 13)
112#define SOR_PLL3_PLL_VDD_MODE_3V3 (1 << 13) 125#define SOR_PLL3_PLL_VDD_MODE_3V3 (1 << 13)
113 126
114#define SOR_CSTM 0x1b 127#define SOR_CSTM 0x1b
128#define SOR_CSTM_ROTCLK_MASK (0xf << 24)
129#define SOR_CSTM_ROTCLK(x) (((x) & 0xf) << 24)
115#define SOR_CSTM_LVDS (1 << 16) 130#define SOR_CSTM_LVDS (1 << 16)
116#define SOR_CSTM_LINK_ACT_B (1 << 15) 131#define SOR_CSTM_LINK_ACT_B (1 << 15)
117#define SOR_CSTM_LINK_ACT_A (1 << 14) 132#define SOR_CSTM_LINK_ACT_A (1 << 14)
@@ -124,15 +139,45 @@
124#define SOR_CRCB 0x1e 139#define SOR_CRCB 0x1e
125#define SOR_BLANK 0x1f 140#define SOR_BLANK 0x1f
126#define SOR_SEQ_CTL 0x20 141#define SOR_SEQ_CTL 0x20
142#define SOR_SEQ_CTL_PD_PC_ALT(x) (((x) & 0xf) << 12)
143#define SOR_SEQ_CTL_PD_PC(x) (((x) & 0xf) << 8)
144#define SOR_SEQ_CTL_PU_PC_ALT(x) (((x) & 0xf) << 4)
145#define SOR_SEQ_CTL_PU_PC(x) (((x) & 0xf) << 0)
127 146
128#define SOR_LANE_SEQ_CTL 0x21 147#define SOR_LANE_SEQ_CTL 0x21
129#define SOR_LANE_SEQ_CTL_TRIGGER (1 << 31) 148#define SOR_LANE_SEQ_CTL_TRIGGER (1 << 31)
149#define SOR_LANE_SEQ_CTL_STATE_BUSY (1 << 28)
130#define SOR_LANE_SEQ_CTL_SEQUENCE_UP (0 << 20) 150#define SOR_LANE_SEQ_CTL_SEQUENCE_UP (0 << 20)
131#define SOR_LANE_SEQ_CTL_SEQUENCE_DOWN (1 << 20) 151#define SOR_LANE_SEQ_CTL_SEQUENCE_DOWN (1 << 20)
132#define SOR_LANE_SEQ_CTL_POWER_STATE_UP (0 << 16) 152#define SOR_LANE_SEQ_CTL_POWER_STATE_UP (0 << 16)
133#define SOR_LANE_SEQ_CTL_POWER_STATE_DOWN (1 << 16) 153#define SOR_LANE_SEQ_CTL_POWER_STATE_DOWN (1 << 16)
154#define SOR_LANE_SEQ_CTL_DELAY(x) (((x) & 0xf) << 12)
134 155
135#define SOR_SEQ_INST(x) (0x22 + (x)) 156#define SOR_SEQ_INST(x) (0x22 + (x))
157#define SOR_SEQ_INST_PLL_PULLDOWN (1 << 31)
158#define SOR_SEQ_INST_POWERDOWN_MACRO (1 << 30)
159#define SOR_SEQ_INST_ASSERT_PLL_RESET (1 << 29)
160#define SOR_SEQ_INST_BLANK_V (1 << 28)
161#define SOR_SEQ_INST_BLANK_H (1 << 27)
162#define SOR_SEQ_INST_BLANK_DE (1 << 26)
163#define SOR_SEQ_INST_BLACK_DATA (1 << 25)
164#define SOR_SEQ_INST_TRISTATE_IOS (1 << 24)
165#define SOR_SEQ_INST_DRIVE_PWM_OUT_LO (1 << 23)
166#define SOR_SEQ_INST_PIN_B_LOW (0 << 22)
167#define SOR_SEQ_INST_PIN_B_HIGH (1 << 22)
168#define SOR_SEQ_INST_PIN_A_LOW (0 << 21)
169#define SOR_SEQ_INST_PIN_A_HIGH (1 << 21)
170#define SOR_SEQ_INST_SEQUENCE_UP (0 << 19)
171#define SOR_SEQ_INST_SEQUENCE_DOWN (1 << 19)
172#define SOR_SEQ_INST_LANE_SEQ_STOP (0 << 18)
173#define SOR_SEQ_INST_LANE_SEQ_RUN (1 << 18)
174#define SOR_SEQ_INST_PORT_POWERDOWN (1 << 17)
175#define SOR_SEQ_INST_PLL_POWERDOWN (1 << 16)
176#define SOR_SEQ_INST_HALT (1 << 15)
177#define SOR_SEQ_INST_WAIT_US (0 << 12)
178#define SOR_SEQ_INST_WAIT_MS (1 << 12)
179#define SOR_SEQ_INST_WAIT_VSYNC (2 << 12)
180#define SOR_SEQ_INST_WAIT(x) (((x) & 0x3ff) << 0)
136 181
137#define SOR_PWM_DIV 0x32 182#define SOR_PWM_DIV 0x32
138#define SOR_PWM_DIV_MASK 0xffffff 183#define SOR_PWM_DIV_MASK 0xffffff
@@ -165,6 +210,10 @@
165#define SOR_TRIG 0x48 210#define SOR_TRIG 0x48
166#define SOR_MSCHECK 0x49 211#define SOR_MSCHECK 0x49
167#define SOR_XBAR_CTRL 0x4a 212#define SOR_XBAR_CTRL 0x4a
213#define SOR_XBAR_CTRL_LINK1_XSEL(channel, value) ((((value) & 0x7) << ((channel) * 3)) << 17)
214#define SOR_XBAR_CTRL_LINK0_XSEL(channel, value) ((((value) & 0x7) << ((channel) * 3)) << 2)
215#define SOR_XBAR_CTRL_LINK_SWAP (1 << 1)
216#define SOR_XBAR_CTRL_BYPASS (1 << 0)
168#define SOR_XBAR_POL 0x4b 217#define SOR_XBAR_POL 0x4b
169 218
170#define SOR_DP_LINKCTL0 0x4c 219#define SOR_DP_LINKCTL0 0x4c
@@ -237,6 +286,7 @@
237#define SOR_DP_DEBUG1 0x5f 286#define SOR_DP_DEBUG1 0x5f
238 287
239#define SOR_DP_SPARE0 0x60 288#define SOR_DP_SPARE0 0x60
289#define SOR_DP_SPARE_DISP_VIDEO_PREAMBLE (1 << 3)
240#define SOR_DP_SPARE_MACRO_SOR_CLK (1 << 2) 290#define SOR_DP_SPARE_MACRO_SOR_CLK (1 << 2)
241#define SOR_DP_SPARE_PANEL_INTERNAL (1 << 1) 291#define SOR_DP_SPARE_PANEL_INTERNAL (1 << 1)
242#define SOR_DP_SPARE_SEQ_ENABLE (1 << 0) 292#define SOR_DP_SPARE_SEQ_ENABLE (1 << 0)
@@ -281,4 +331,40 @@
281#define SOR_DP_LQ_CSTM1 0x70 331#define SOR_DP_LQ_CSTM1 0x70
282#define SOR_DP_LQ_CSTM2 0x71 332#define SOR_DP_LQ_CSTM2 0x71
283 333
334#define SOR_HDMI_AUDIO_INFOFRAME_CTRL 0x9a
335#define SOR_HDMI_AUDIO_INFOFRAME_STATUS 0x9b
336#define SOR_HDMI_AUDIO_INFOFRAME_HEADER 0x9c
337
338#define SOR_HDMI_AVI_INFOFRAME_CTRL 0x9f
339#define INFOFRAME_CTRL_CHECKSUM_ENABLE (1 << 9)
340#define INFOFRAME_CTRL_SINGLE (1 << 8)
341#define INFOFRAME_CTRL_OTHER (1 << 4)
342#define INFOFRAME_CTRL_ENABLE (1 << 0)
343
344#define SOR_HDMI_AVI_INFOFRAME_STATUS 0xa0
345#define INFOFRAME_STATUS_DONE (1 << 0)
346
347#define SOR_HDMI_AVI_INFOFRAME_HEADER 0xa1
348#define INFOFRAME_HEADER_LEN(x) (((x) & 0xff) << 16)
349#define INFOFRAME_HEADER_VERSION(x) (((x) & 0xff) << 8)
350#define INFOFRAME_HEADER_TYPE(x) (((x) & 0xff) << 0)
351
352#define SOR_HDMI_CTRL 0xc0
353#define SOR_HDMI_CTRL_ENABLE (1 << 30)
354#define SOR_HDMI_CTRL_MAX_AC_PACKET(x) (((x) & 0x1f) << 16)
355#define SOR_HDMI_CTRL_AUDIO_LAYOUT (1 << 10)
356#define SOR_HDMI_CTRL_REKEY(x) (((x) & 0x7f) << 0)
357
358#define SOR_REFCLK 0xe6
359#define SOR_REFCLK_DIV_INT(x) ((((x) >> 2) & 0xff) << 8)
360#define SOR_REFCLK_DIV_FRAC(x) (((x) & 0x3) << 6)
361
362#define SOR_INPUT_CONTROL 0xe8
363#define SOR_INPUT_CONTROL_ARM_VIDEO_RANGE_LIMITED (1 << 1)
364#define SOR_INPUT_CONTROL_HDMI_SRC_SELECT(x) (((x) & 0x1) << 0)
365
366#define SOR_HDMI_VSI_INFOFRAME_CTRL 0x123
367#define SOR_HDMI_VSI_INFOFRAME_STATUS 0x124
368#define SOR_HDMI_VSI_INFOFRAME_HEADER 0x125
369
284#endif 370#endif