blob: 7961fcc2addab8a8e68015fb4c7dc3b6dbe69a58 [file] [log] [blame]
Eugeni Dodonov45244b82012-05-09 15:37:20 -03001/*
2 * Copyright © 2012 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eugeni Dodonov <eugeni.dodonov@intel.com>
25 *
26 */
27
28#include "i915_drv.h"
29#include "intel_drv.h"
30
Jani Nikula10122052014-08-27 16:27:30 +030031struct ddi_buf_trans {
32 u32 trans1; /* balance leg enable, de-emph level */
33 u32 trans2; /* vref sel, vswing */
David Weinehallf8896f52015-06-25 11:11:03 +030034 u8 i_boost; /* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
Jani Nikula10122052014-08-27 16:27:30 +030035};
36
Eugeni Dodonov45244b82012-05-09 15:37:20 -030037/* HDMI/DVI modes ignore everything but the last 2 items. So we share
38 * them for both DP and FDI transports, allowing those ports to
39 * automatically adapt to HDMI connections as well
40 */
Jani Nikula10122052014-08-27 16:27:30 +030041static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030042 { 0x00FFFFFF, 0x0006000E, 0x0 },
43 { 0x00D75FFF, 0x0005000A, 0x0 },
44 { 0x00C30FFF, 0x00040006, 0x0 },
45 { 0x80AAAFFF, 0x000B0000, 0x0 },
46 { 0x00FFFFFF, 0x0005000A, 0x0 },
47 { 0x00D75FFF, 0x000C0004, 0x0 },
48 { 0x80C30FFF, 0x000B0000, 0x0 },
49 { 0x00FFFFFF, 0x00040006, 0x0 },
50 { 0x80D75FFF, 0x000B0000, 0x0 },
Eugeni Dodonov45244b82012-05-09 15:37:20 -030051};
52
Jani Nikula10122052014-08-27 16:27:30 +030053static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030054 { 0x00FFFFFF, 0x0007000E, 0x0 },
55 { 0x00D75FFF, 0x000F000A, 0x0 },
56 { 0x00C30FFF, 0x00060006, 0x0 },
57 { 0x00AAAFFF, 0x001E0000, 0x0 },
58 { 0x00FFFFFF, 0x000F000A, 0x0 },
59 { 0x00D75FFF, 0x00160004, 0x0 },
60 { 0x00C30FFF, 0x001E0000, 0x0 },
61 { 0x00FFFFFF, 0x00060006, 0x0 },
62 { 0x00D75FFF, 0x001E0000, 0x0 },
Paulo Zanoni6acab152013-09-12 17:06:24 -030063};
64
Jani Nikula10122052014-08-27 16:27:30 +030065static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
66 /* Idx NT mV d T mV d db */
David Weinehallf8896f52015-06-25 11:11:03 +030067 { 0x00FFFFFF, 0x0006000E, 0x0 },/* 0: 400 400 0 */
68 { 0x00E79FFF, 0x000E000C, 0x0 },/* 1: 400 500 2 */
69 { 0x00D75FFF, 0x0005000A, 0x0 },/* 2: 400 600 3.5 */
70 { 0x00FFFFFF, 0x0005000A, 0x0 },/* 3: 600 600 0 */
71 { 0x00E79FFF, 0x001D0007, 0x0 },/* 4: 600 750 2 */
72 { 0x00D75FFF, 0x000C0004, 0x0 },/* 5: 600 900 3.5 */
73 { 0x00FFFFFF, 0x00040006, 0x0 },/* 6: 800 800 0 */
74 { 0x80E79FFF, 0x00030002, 0x0 },/* 7: 800 1000 2 */
75 { 0x00FFFFFF, 0x00140005, 0x0 },/* 8: 850 850 0 */
76 { 0x00FFFFFF, 0x000C0004, 0x0 },/* 9: 900 900 0 */
77 { 0x00FFFFFF, 0x001C0003, 0x0 },/* 10: 950 950 0 */
78 { 0x80FFFFFF, 0x00030002, 0x0 },/* 11: 1000 1000 0 */
Eugeni Dodonov45244b82012-05-09 15:37:20 -030079};
80
Jani Nikula10122052014-08-27 16:27:30 +030081static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030082 { 0x00FFFFFF, 0x00000012, 0x0 },
83 { 0x00EBAFFF, 0x00020011, 0x0 },
84 { 0x00C71FFF, 0x0006000F, 0x0 },
85 { 0x00AAAFFF, 0x000E000A, 0x0 },
86 { 0x00FFFFFF, 0x00020011, 0x0 },
87 { 0x00DB6FFF, 0x0005000F, 0x0 },
88 { 0x00BEEFFF, 0x000A000C, 0x0 },
89 { 0x00FFFFFF, 0x0005000F, 0x0 },
90 { 0x00DB6FFF, 0x000A000C, 0x0 },
Paulo Zanoni300644c2013-11-02 21:07:42 -070091};
92
Jani Nikula10122052014-08-27 16:27:30 +030093static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +030094 { 0x00FFFFFF, 0x0007000E, 0x0 },
95 { 0x00D75FFF, 0x000E000A, 0x0 },
96 { 0x00BEFFFF, 0x00140006, 0x0 },
97 { 0x80B2CFFF, 0x001B0002, 0x0 },
98 { 0x00FFFFFF, 0x000E000A, 0x0 },
99 { 0x00DB6FFF, 0x00160005, 0x0 },
100 { 0x80C71FFF, 0x001A0002, 0x0 },
101 { 0x00F7DFFF, 0x00180004, 0x0 },
102 { 0x80D75FFF, 0x001B0002, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700103};
104
Jani Nikula10122052014-08-27 16:27:30 +0300105static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300106 { 0x00FFFFFF, 0x0001000E, 0x0 },
107 { 0x00D75FFF, 0x0004000A, 0x0 },
108 { 0x00C30FFF, 0x00070006, 0x0 },
109 { 0x00AAAFFF, 0x000C0000, 0x0 },
110 { 0x00FFFFFF, 0x0004000A, 0x0 },
111 { 0x00D75FFF, 0x00090004, 0x0 },
112 { 0x00C30FFF, 0x000C0000, 0x0 },
113 { 0x00FFFFFF, 0x00070006, 0x0 },
114 { 0x00D75FFF, 0x000C0000, 0x0 },
Art Runyane58623c2013-11-02 21:07:41 -0700115};
116
Jani Nikula10122052014-08-27 16:27:30 +0300117static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
118 /* Idx NT mV d T mV df db */
David Weinehallf8896f52015-06-25 11:11:03 +0300119 { 0x00FFFFFF, 0x0007000E, 0x0 },/* 0: 400 400 0 */
120 { 0x00D75FFF, 0x000E000A, 0x0 },/* 1: 400 600 3.5 */
121 { 0x00BEFFFF, 0x00140006, 0x0 },/* 2: 400 800 6 */
122 { 0x00FFFFFF, 0x0009000D, 0x0 },/* 3: 450 450 0 */
123 { 0x00FFFFFF, 0x000E000A, 0x0 },/* 4: 600 600 0 */
124 { 0x00D7FFFF, 0x00140006, 0x0 },/* 5: 600 800 2.5 */
125 { 0x80CB2FFF, 0x001B0002, 0x0 },/* 6: 600 1000 4.5 */
126 { 0x00FFFFFF, 0x00140006, 0x0 },/* 7: 800 800 0 */
127 { 0x80E79FFF, 0x001B0002, 0x0 },/* 8: 800 1000 2 */
128 { 0x80FFFFFF, 0x001B0002, 0x0 },/* 9: 1000 1000 0 */
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100129};
130
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700131/* Skylake H and S */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000132static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300133 { 0x00002016, 0x000000A0, 0x0 },
134 { 0x00005012, 0x0000009B, 0x0 },
135 { 0x00007011, 0x00000088, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800136 { 0x80009010, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */
David Weinehallf8896f52015-06-25 11:11:03 +0300137 { 0x00002016, 0x0000009B, 0x0 },
138 { 0x00005012, 0x00000088, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800139 { 0x80007011, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */
David Weinehallf8896f52015-06-25 11:11:03 +0300140 { 0x00002016, 0x000000DF, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800141 { 0x80005012, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000142};
143
David Weinehallf8896f52015-06-25 11:11:03 +0300144/* Skylake U */
145static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700146 { 0x0000201B, 0x000000A2, 0x0 },
David Weinehallf8896f52015-06-25 11:11:03 +0300147 { 0x00005012, 0x00000088, 0x0 },
148 { 0x00007011, 0x00000087, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800149 { 0x80009010, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700150 { 0x0000201B, 0x0000009D, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800151 { 0x80005012, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */
152 { 0x80007011, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */
David Weinehallf8896f52015-06-25 11:11:03 +0300153 { 0x00002016, 0x00000088, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800154 { 0x80005012, 0x000000C0, 0x1 }, /* Uses I_boost level 0x1 */
David Weinehallf8896f52015-06-25 11:11:03 +0300155};
156
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700157/* Skylake Y */
158static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300159 { 0x00000018, 0x000000A2, 0x0 },
160 { 0x00005012, 0x00000088, 0x0 },
161 { 0x00007011, 0x00000087, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800162 { 0x80009010, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */
David Weinehallf8896f52015-06-25 11:11:03 +0300163 { 0x00000018, 0x0000009D, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800164 { 0x80005012, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */
165 { 0x80007011, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */
David Weinehallf8896f52015-06-25 11:11:03 +0300166 { 0x00000018, 0x00000088, 0x0 },
jim.bride@linux.intel.comd1c0a002015-11-06 15:30:54 -0800167 { 0x80005012, 0x000000C0, 0x3 }, /* Uses I_boost level 0x3 */
David Weinehallf8896f52015-06-25 11:11:03 +0300168};
169
170/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700171 * Skylake H and S
David Weinehallf8896f52015-06-25 11:11:03 +0300172 * eDP 1.4 low vswing translation parameters
173 */
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530174static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300175 { 0x00000018, 0x000000A8, 0x0 },
176 { 0x00004013, 0x000000A9, 0x0 },
177 { 0x00007011, 0x000000A2, 0x0 },
178 { 0x00009010, 0x0000009C, 0x0 },
179 { 0x00000018, 0x000000A9, 0x0 },
180 { 0x00006013, 0x000000A2, 0x0 },
181 { 0x00007011, 0x000000A6, 0x0 },
182 { 0x00000018, 0x000000AB, 0x0 },
183 { 0x00007013, 0x0000009F, 0x0 },
184 { 0x00000018, 0x000000DF, 0x0 },
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530185};
186
David Weinehallf8896f52015-06-25 11:11:03 +0300187/*
188 * Skylake U
189 * eDP 1.4 low vswing translation parameters
190 */
191static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
192 { 0x00000018, 0x000000A8, 0x0 },
193 { 0x00004013, 0x000000A9, 0x0 },
194 { 0x00007011, 0x000000A2, 0x0 },
195 { 0x00009010, 0x0000009C, 0x0 },
196 { 0x00000018, 0x000000A9, 0x0 },
197 { 0x00006013, 0x000000A2, 0x0 },
198 { 0x00007011, 0x000000A6, 0x0 },
199 { 0x00002016, 0x000000AB, 0x0 },
200 { 0x00005013, 0x0000009F, 0x0 },
201 { 0x00000018, 0x000000DF, 0x0 },
202};
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530203
David Weinehallf8896f52015-06-25 11:11:03 +0300204/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700205 * Skylake Y
David Weinehallf8896f52015-06-25 11:11:03 +0300206 * eDP 1.4 low vswing translation parameters
207 */
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700208static const struct ddi_buf_trans skl_y_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300209 { 0x00000018, 0x000000A8, 0x0 },
210 { 0x00004013, 0x000000AB, 0x0 },
211 { 0x00007011, 0x000000A4, 0x0 },
212 { 0x00009010, 0x000000DF, 0x0 },
213 { 0x00000018, 0x000000AA, 0x0 },
214 { 0x00006013, 0x000000A4, 0x0 },
215 { 0x00007011, 0x0000009D, 0x0 },
216 { 0x00000018, 0x000000A0, 0x0 },
217 { 0x00006012, 0x000000DF, 0x0 },
218 { 0x00000018, 0x0000008A, 0x0 },
219};
220
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700221/* Skylake U, H and S */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000222static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300223 { 0x00000018, 0x000000AC, 0x0 },
224 { 0x00005012, 0x0000009D, 0x0 },
225 { 0x00007011, 0x00000088, 0x0 },
226 { 0x00000018, 0x000000A1, 0x0 },
227 { 0x00000018, 0x00000098, 0x0 },
228 { 0x00004013, 0x00000088, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800229 { 0x80006012, 0x000000CD, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300230 { 0x00000018, 0x000000DF, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800231 { 0x80003015, 0x000000CD, 0x1 }, /* Default */
232 { 0x80003015, 0x000000C0, 0x1 },
233 { 0x80000018, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300234};
235
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700236/* Skylake Y */
237static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300238 { 0x00000018, 0x000000A1, 0x0 },
239 { 0x00005012, 0x000000DF, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800240 { 0x80007011, 0x000000CB, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300241 { 0x00000018, 0x000000A4, 0x0 },
242 { 0x00000018, 0x0000009D, 0x0 },
243 { 0x00004013, 0x00000080, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800244 { 0x80006013, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300245 { 0x00000018, 0x0000008A, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800246 { 0x80003015, 0x000000C0, 0x3 }, /* Default */
247 { 0x80003015, 0x000000C0, 0x3 },
248 { 0x80000018, 0x000000C0, 0x3 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000249};
250
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530251struct bxt_ddi_buf_trans {
252 u32 margin; /* swing value */
253 u32 scale; /* scale value */
254 u32 enable; /* scale enable */
255 u32 deemphasis;
256 bool default_index; /* true if the entry represents default value */
257};
258
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530259static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
260 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300261 { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */
262 { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
263 { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */
264 { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
265 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
266 { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
267 { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */
268 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
269 { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
David Weinehallf8896f52015-06-25 11:11:03 +0300270 { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530271};
272
Sonika Jindald9d70002015-09-24 10:24:56 +0530273static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = {
274 /* Idx NT mV diff db */
275 { 26, 0, 0, 128, false }, /* 0: 200 0 */
276 { 38, 0, 0, 112, false }, /* 1: 200 1.5 */
277 { 48, 0, 0, 96, false }, /* 2: 200 4 */
278 { 54, 0, 0, 69, false }, /* 3: 200 6 */
279 { 32, 0, 0, 128, false }, /* 4: 250 0 */
280 { 48, 0, 0, 104, false }, /* 5: 250 1.5 */
281 { 54, 0, 0, 85, false }, /* 6: 250 4 */
282 { 43, 0, 0, 128, false }, /* 7: 300 0 */
283 { 54, 0, 0, 101, false }, /* 8: 300 1.5 */
284 { 48, 0, 0, 128, false }, /* 9: 300 0 */
285};
286
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530287/* BSpec has 2 recommended values - entries 0 and 8.
288 * Using the entry with higher vswing.
289 */
290static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
291 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300292 { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */
293 { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
294 { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */
295 { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
296 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
297 { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
298 { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */
299 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
300 { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530301 { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */
302};
303
David Weinehallf8896f52015-06-25 11:11:03 +0300304static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
305 enum port port, int type);
306
Imre Deaka1e6ad62015-04-17 19:31:21 +0300307static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
308 struct intel_digital_port **dig_port,
309 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300310{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300311 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300312
Jani Nikula8cd21b72015-09-29 10:24:26 +0300313 switch (intel_encoder->type) {
314 case INTEL_OUTPUT_DP_MST:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300315 *dig_port = enc_to_mst(encoder)->primary;
316 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300317 break;
318 case INTEL_OUTPUT_DISPLAYPORT:
319 case INTEL_OUTPUT_EDP:
320 case INTEL_OUTPUT_HDMI:
321 case INTEL_OUTPUT_UNKNOWN:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300322 *dig_port = enc_to_dig_port(encoder);
323 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300324 break;
325 case INTEL_OUTPUT_ANALOG:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300326 *dig_port = NULL;
327 *port = PORT_E;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300328 break;
329 default:
330 WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
331 break;
Paulo Zanonifc914632012-10-05 12:05:54 -0300332 }
333}
334
Imre Deaka1e6ad62015-04-17 19:31:21 +0300335enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
336{
337 struct intel_digital_port *dig_port;
338 enum port port;
339
340 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
341
342 return port;
343}
344
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100345static bool
346intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
347{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200348 return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100349}
350
David Weinehallf8896f52015-06-25 11:11:03 +0300351static const struct ddi_buf_trans *skl_get_buf_trans_dp(struct drm_device *dev,
352 int *n_entries)
353{
David Weinehallf8896f52015-06-25 11:11:03 +0300354 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300355
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800356 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700357 ddi_translations = skl_y_ddi_translations_dp;
358 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800359 } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300360 ddi_translations = skl_u_ddi_translations_dp;
361 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
362 } else {
363 ddi_translations = skl_ddi_translations_dp;
364 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
365 }
366
367 return ddi_translations;
368}
369
370static const struct ddi_buf_trans *skl_get_buf_trans_edp(struct drm_device *dev,
371 int *n_entries)
372{
373 struct drm_i915_private *dev_priv = dev->dev_private;
374 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300375
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800376 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300377 if (dev_priv->edp_low_vswing) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700378 ddi_translations = skl_y_ddi_translations_edp;
379 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
David Weinehallf8896f52015-06-25 11:11:03 +0300380 } else {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700381 ddi_translations = skl_y_ddi_translations_dp;
382 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
David Weinehallf8896f52015-06-25 11:11:03 +0300383 }
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800384 } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300385 if (dev_priv->edp_low_vswing) {
386 ddi_translations = skl_u_ddi_translations_edp;
387 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
388 } else {
389 ddi_translations = skl_u_ddi_translations_dp;
390 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
391 }
392 } else {
393 if (dev_priv->edp_low_vswing) {
394 ddi_translations = skl_ddi_translations_edp;
395 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
396 } else {
397 ddi_translations = skl_ddi_translations_dp;
398 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
399 }
400 }
401
402 return ddi_translations;
403}
404
405static const struct ddi_buf_trans *
406skl_get_buf_trans_hdmi(struct drm_device *dev,
407 int *n_entries)
408{
David Weinehallf8896f52015-06-25 11:11:03 +0300409 const struct ddi_buf_trans *ddi_translations;
David Weinehallf8896f52015-06-25 11:11:03 +0300410
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800411 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700412 ddi_translations = skl_y_ddi_translations_hdmi;
413 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
David Weinehallf8896f52015-06-25 11:11:03 +0300414 } else {
415 ddi_translations = skl_ddi_translations_hdmi;
416 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
417 }
418
419 return ddi_translations;
420}
421
Art Runyane58623c2013-11-02 21:07:41 -0700422/*
423 * Starting with Haswell, DDI port buffers must be programmed with correct
424 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300425 * but the HDMI/DVI fields are shared among those. So we program the DDI
426 * in either FDI or DP modes only, as HDMI connections will work with both
427 * of those
428 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300429static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
430 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300431{
432 struct drm_i915_private *dev_priv = dev->dev_private;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300433 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000434 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530435 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300436 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300437 const struct ddi_buf_trans *ddi_translations_fdi;
438 const struct ddi_buf_trans *ddi_translations_dp;
439 const struct ddi_buf_trans *ddi_translations_edp;
440 const struct ddi_buf_trans *ddi_translations_hdmi;
441 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700442
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530443 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300444 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530445 return;
446
447 /* Vswing programming for HDMI */
448 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
449 INTEL_OUTPUT_HDMI);
450 return;
Rodrigo Vivief11bdb2015-10-28 04:16:45 -0700451 } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300452 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300453 ddi_translations_dp =
454 skl_get_buf_trans_dp(dev, &n_dp_entries);
455 ddi_translations_edp =
456 skl_get_buf_trans_edp(dev, &n_edp_entries);
457 ddi_translations_hdmi =
458 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
459 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300460 /* If we're boosting the current, set bit 31 of trans1 */
461 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
462 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
463 iboost_bit = 1<<31;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000464 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700465 ddi_translations_fdi = bdw_ddi_translations_fdi;
466 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700467 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100468 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530469 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
470 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300471 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000472 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700473 } else if (IS_HASWELL(dev)) {
474 ddi_translations_fdi = hsw_ddi_translations_fdi;
475 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700476 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100477 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530478 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300479 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000480 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700481 } else {
482 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700483 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700484 ddi_translations_fdi = bdw_ddi_translations_fdi;
485 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100486 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530487 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
488 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300489 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000490 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700491 }
492
Paulo Zanoni300644c2013-11-02 21:07:42 -0700493 switch (port) {
494 case PORT_A:
495 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530496 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700497 break;
498 case PORT_B:
499 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700500 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530501 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700502 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700503 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530504 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700505 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530506 size = n_edp_entries;
507 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700508 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530509 size = n_dp_entries;
510 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700511 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700512 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000513 if (ddi_translations_fdi)
514 ddi_translations = ddi_translations_fdi;
515 else
516 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530517 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700518 break;
519 default:
520 BUG();
521 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300522
Ville Syrjälä9712e682015-09-18 20:03:22 +0300523 for (i = 0; i < size; i++) {
524 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
525 ddi_translations[i].trans1 | iboost_bit);
526 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
527 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300528 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100529
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300530 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100531 return;
532
Damien Lespiauce4dd492014-08-01 11:07:54 +0100533 /* Choose a good default if VBT is badly populated */
534 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
535 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000536 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100537
Paulo Zanoni6acab152013-09-12 17:06:24 -0300538 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300539 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
540 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
541 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
542 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300543}
544
545/* Program DDI buffers translations for DP. By default, program ports A-D in DP
546 * mode and port E for FDI.
547 */
548void intel_prepare_ddi(struct drm_device *dev)
549{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300550 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100551 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300552
Paulo Zanoni0d536cb2012-11-23 16:46:41 -0200553 if (!HAS_DDI(dev))
554 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300555
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300556 for_each_intel_encoder(dev, intel_encoder) {
557 struct intel_digital_port *intel_dig_port;
558 enum port port;
559 bool supports_hdmi;
560
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530561 if (intel_encoder->type == INTEL_OUTPUT_DSI)
562 continue;
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300563
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530564 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300565 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100566 continue;
567
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300568 supports_hdmi = intel_dig_port &&
569 intel_dig_port_supports_hdmi(intel_dig_port);
570
571 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
572 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100573 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300574}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300575
Paulo Zanoni248138b2012-11-29 11:29:31 -0200576static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
577 enum port port)
578{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200579 i915_reg_t reg = DDI_BUF_CTL(port);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200580 int i;
581
Vandana Kannan3449ca82015-03-27 14:19:09 +0200582 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200583 udelay(1);
584 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
585 return;
586 }
587 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
588}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300589
590/* Starting with Haswell, different DDI ports can work in FDI mode for
591 * connection to the PCH-located connectors. For this, it is necessary to train
592 * both the DDI port and PCH receiver for the desired DDI buffer settings.
593 *
594 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
595 * please note that when FDI mode is active on DDI E, it shares 2 lines with
596 * DDI A (which is used for eDP)
597 */
598
599void hsw_fdi_link_train(struct drm_crtc *crtc)
600{
601 struct drm_device *dev = crtc->dev;
602 struct drm_i915_private *dev_priv = dev->dev_private;
603 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200604 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300605
Paulo Zanoni04945642012-11-01 21:00:59 -0200606 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
607 * mode set "sequence for CRT port" document:
608 * - TP1 to TP2 time with the default value
609 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100610 *
611 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200612 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300613 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200614 FDI_RX_PWRDN_LANE0_VAL(2) |
615 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
616
617 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000618 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100619 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200620 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300621 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
622 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200623 udelay(220);
624
625 /* Switch from Rawclk to PCDclk */
626 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300627 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200628
629 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200630 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
631 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200632
633 /* Start the training iterating through available voltages and emphasis,
634 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300635 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300636 /* Configure DP_TP_CTL with auto-training */
637 I915_WRITE(DP_TP_CTL(PORT_E),
638 DP_TP_CTL_FDI_AUTOTRAIN |
639 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
640 DP_TP_CTL_LINK_TRAIN_PAT1 |
641 DP_TP_CTL_ENABLE);
642
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000643 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
644 * DDI E does not support port reversal, the functionality is
645 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
646 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300647 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200648 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200649 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530650 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200651 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300652
653 udelay(600);
654
Paulo Zanoni04945642012-11-01 21:00:59 -0200655 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300656 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300657
Paulo Zanoni04945642012-11-01 21:00:59 -0200658 /* Enable PCH FDI Receiver with auto-training */
659 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300660 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
661 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200662
663 /* Wait for FDI receiver lane calibration */
664 udelay(30);
665
666 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300667 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200668 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300669 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
670 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200671
672 /* Wait for FDI auto training time */
673 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300674
675 temp = I915_READ(DP_TP_STATUS(PORT_E));
676 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200677 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200678 break;
679 }
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300680
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200681 /*
682 * Leave things enabled even if we failed to train FDI.
683 * Results in less fireworks from the state checker.
684 */
685 if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
686 DRM_ERROR("FDI link training failed!\n");
687 break;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300688 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200689
Paulo Zanoni248138b2012-11-29 11:29:31 -0200690 temp = I915_READ(DDI_BUF_CTL(PORT_E));
691 temp &= ~DDI_BUF_CTL_ENABLE;
692 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
693 POSTING_READ(DDI_BUF_CTL(PORT_E));
694
Paulo Zanoni04945642012-11-01 21:00:59 -0200695 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200696 temp = I915_READ(DP_TP_CTL(PORT_E));
697 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
698 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
699 I915_WRITE(DP_TP_CTL(PORT_E), temp);
700 POSTING_READ(DP_TP_CTL(PORT_E));
701
702 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200703
704 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300705 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
706 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200707
708 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300709 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200710 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
711 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300712 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
713 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300714 }
715
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200716 /* Enable normal pixel sending for FDI */
717 I915_WRITE(DP_TP_CTL(PORT_E),
718 DP_TP_CTL_FDI_AUTOTRAIN |
719 DP_TP_CTL_LINK_TRAIN_NORMAL |
720 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
721 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300722}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300723
Dave Airlie44905a272014-05-02 13:36:43 +1000724void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
725{
726 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
727 struct intel_digital_port *intel_dig_port =
728 enc_to_dig_port(&encoder->base);
729
730 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530731 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300732 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000733}
734
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300735static struct intel_encoder *
736intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
737{
738 struct drm_device *dev = crtc->dev;
739 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
740 struct intel_encoder *intel_encoder, *ret = NULL;
741 int num_encoders = 0;
742
743 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
744 ret = intel_encoder;
745 num_encoders++;
746 }
747
748 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300749 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
750 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300751
752 BUG_ON(ret == NULL);
753 return ret;
754}
755
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530756struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200757intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200758{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200759 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
760 struct intel_encoder *ret = NULL;
761 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300762 struct drm_connector *connector;
763 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200764 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200765 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200766
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200767 state = crtc_state->base.state;
768
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300769 for_each_connector_in_state(state, connector, connector_state, i) {
770 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200771 continue;
772
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300773 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200774 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200775 }
776
777 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
778 pipe_name(crtc->pipe));
779
780 BUG_ON(ret == NULL);
781 return ret;
782}
783
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100784#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100785#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100786
787#define P_MIN 2
788#define P_MAX 64
789#define P_INC 2
790
791/* Constraints for PLL good behavior */
792#define REF_MIN 48
793#define REF_MAX 400
794#define VCO_MIN 2400
795#define VCO_MAX 4800
796
Damien Lespiau27893392014-09-04 12:27:23 +0100797#define abs_diff(a, b) ({ \
798 typeof(a) __a = (a); \
799 typeof(b) __b = (b); \
800 (void) (&__a == &__b); \
801 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100802
Damien Lespiau63582982015-05-07 18:38:46 +0100803struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100804 unsigned p, n2, r2;
805};
806
Damien Lespiau63582982015-05-07 18:38:46 +0100807static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300808{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100809 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300810
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100811 switch (clock) {
812 case 25175000:
813 case 25200000:
814 case 27000000:
815 case 27027000:
816 case 37762500:
817 case 37800000:
818 case 40500000:
819 case 40541000:
820 case 54000000:
821 case 54054000:
822 case 59341000:
823 case 59400000:
824 case 72000000:
825 case 74176000:
826 case 74250000:
827 case 81000000:
828 case 81081000:
829 case 89012000:
830 case 89100000:
831 case 108000000:
832 case 108108000:
833 case 111264000:
834 case 111375000:
835 case 148352000:
836 case 148500000:
837 case 162000000:
838 case 162162000:
839 case 222525000:
840 case 222750000:
841 case 296703000:
842 case 297000000:
843 budget = 0;
844 break;
845 case 233500000:
846 case 245250000:
847 case 247750000:
848 case 253250000:
849 case 298000000:
850 budget = 1500;
851 break;
852 case 169128000:
853 case 169500000:
854 case 179500000:
855 case 202000000:
856 budget = 2000;
857 break;
858 case 256250000:
859 case 262500000:
860 case 270000000:
861 case 272500000:
862 case 273750000:
863 case 280750000:
864 case 281250000:
865 case 286000000:
866 case 291750000:
867 budget = 4000;
868 break;
869 case 267250000:
870 case 268500000:
871 budget = 5000;
872 break;
873 default:
874 budget = 1000;
875 break;
876 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300877
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100878 return budget;
879}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300880
Damien Lespiau63582982015-05-07 18:38:46 +0100881static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
882 unsigned r2, unsigned n2, unsigned p,
883 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100884{
885 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300886
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100887 /* No best (r,n,p) yet */
888 if (best->p == 0) {
889 best->p = p;
890 best->n2 = n2;
891 best->r2 = r2;
892 return;
893 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300894
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100895 /*
896 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
897 * freq2k.
898 *
899 * delta = 1e6 *
900 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
901 * freq2k;
902 *
903 * and we would like delta <= budget.
904 *
905 * If the discrepancy is above the PPM-based budget, always prefer to
906 * improve upon the previous solution. However, if you're within the
907 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
908 */
909 a = freq2k * budget * p * r2;
910 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100911 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
912 diff_best = abs_diff(freq2k * best->p * best->r2,
913 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100914 c = 1000000 * diff;
915 d = 1000000 * diff_best;
916
917 if (a < c && b < d) {
918 /* If both are above the budget, pick the closer */
919 if (best->p * best->r2 * diff < p * r2 * diff_best) {
920 best->p = p;
921 best->n2 = n2;
922 best->r2 = r2;
923 }
924 } else if (a >= c && b < d) {
925 /* If A is below the threshold but B is above it? Update. */
926 best->p = p;
927 best->n2 = n2;
928 best->r2 = r2;
929 } else if (a >= c && b >= d) {
930 /* Both are below the limit, so pick the higher n2/(r2*r2) */
931 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
932 best->p = p;
933 best->n2 = n2;
934 best->r2 = r2;
935 }
936 }
937 /* Otherwise a < c && b >= d, do nothing */
938}
939
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200940static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
941 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800942{
943 int refclk = LC_FREQ;
944 int n, p, r;
945 u32 wrpll;
946
947 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300948 switch (wrpll & WRPLL_PLL_REF_MASK) {
949 case WRPLL_PLL_SSC:
950 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800951 /*
952 * We could calculate spread here, but our checking
953 * code only cares about 5% accuracy, and spread is a max of
954 * 0.5% downspread.
955 */
956 refclk = 135;
957 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300958 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800959 refclk = LC_FREQ;
960 break;
961 default:
962 WARN(1, "bad wrpll refclk\n");
963 return 0;
964 }
965
966 r = wrpll & WRPLL_DIVIDER_REF_MASK;
967 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
968 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
969
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800970 /* Convert to KHz, p & r have a fixed point portion */
971 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800972}
973
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000974static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
975 uint32_t dpll)
976{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200977 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000978 uint32_t cfgcr1_val, cfgcr2_val;
979 uint32_t p0, p1, p2, dco_freq;
980
Ville Syrjälä923c12412015-09-30 17:06:43 +0300981 cfgcr1_reg = DPLL_CFGCR1(dpll);
982 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000983
984 cfgcr1_val = I915_READ(cfgcr1_reg);
985 cfgcr2_val = I915_READ(cfgcr2_reg);
986
987 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
988 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
989
990 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
991 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
992 else
993 p1 = 1;
994
995
996 switch (p0) {
997 case DPLL_CFGCR2_PDIV_1:
998 p0 = 1;
999 break;
1000 case DPLL_CFGCR2_PDIV_2:
1001 p0 = 2;
1002 break;
1003 case DPLL_CFGCR2_PDIV_3:
1004 p0 = 3;
1005 break;
1006 case DPLL_CFGCR2_PDIV_7:
1007 p0 = 7;
1008 break;
1009 }
1010
1011 switch (p2) {
1012 case DPLL_CFGCR2_KDIV_5:
1013 p2 = 5;
1014 break;
1015 case DPLL_CFGCR2_KDIV_2:
1016 p2 = 2;
1017 break;
1018 case DPLL_CFGCR2_KDIV_3:
1019 p2 = 3;
1020 break;
1021 case DPLL_CFGCR2_KDIV_1:
1022 p2 = 1;
1023 break;
1024 }
1025
1026 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1027
1028 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1029 1000) / 0x8000;
1030
1031 return dco_freq / (p0 * p1 * p2 * 5);
1032}
1033
Ville Syrjälä398a0172015-06-30 15:33:51 +03001034static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1035{
1036 int dotclock;
1037
1038 if (pipe_config->has_pch_encoder)
1039 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1040 &pipe_config->fdi_m_n);
1041 else if (pipe_config->has_dp_encoder)
1042 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1043 &pipe_config->dp_m_n);
1044 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1045 dotclock = pipe_config->port_clock * 2 / 3;
1046 else
1047 dotclock = pipe_config->port_clock;
1048
1049 if (pipe_config->pixel_multiplier)
1050 dotclock /= pipe_config->pixel_multiplier;
1051
1052 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1053}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001054
1055static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001056 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001057{
1058 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001059 int link_clock = 0;
1060 uint32_t dpll_ctl1, dpll;
1061
Damien Lespiau134ffa42014-11-14 17:24:34 +00001062 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001063
1064 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1065
1066 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1067 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1068 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001069 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1070 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001071
1072 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001073 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001074 link_clock = 81000;
1075 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001076 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301077 link_clock = 108000;
1078 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001079 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001080 link_clock = 135000;
1081 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001082 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301083 link_clock = 162000;
1084 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001085 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301086 link_clock = 216000;
1087 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001088 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001089 link_clock = 270000;
1090 break;
1091 default:
1092 WARN(1, "Unsupported link rate\n");
1093 break;
1094 }
1095 link_clock *= 2;
1096 }
1097
1098 pipe_config->port_clock = link_clock;
1099
Ville Syrjälä398a0172015-06-30 15:33:51 +03001100 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001101}
1102
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001103static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001104 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001105{
1106 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001107 int link_clock = 0;
1108 u32 val, pll;
1109
Daniel Vetter26804af2014-06-25 22:01:55 +03001110 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001111 switch (val & PORT_CLK_SEL_MASK) {
1112 case PORT_CLK_SEL_LCPLL_810:
1113 link_clock = 81000;
1114 break;
1115 case PORT_CLK_SEL_LCPLL_1350:
1116 link_clock = 135000;
1117 break;
1118 case PORT_CLK_SEL_LCPLL_2700:
1119 link_clock = 270000;
1120 break;
1121 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001122 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001123 break;
1124 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001125 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001126 break;
1127 case PORT_CLK_SEL_SPLL:
1128 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1129 if (pll == SPLL_PLL_FREQ_810MHz)
1130 link_clock = 81000;
1131 else if (pll == SPLL_PLL_FREQ_1350MHz)
1132 link_clock = 135000;
1133 else if (pll == SPLL_PLL_FREQ_2700MHz)
1134 link_clock = 270000;
1135 else {
1136 WARN(1, "bad spll freq\n");
1137 return;
1138 }
1139 break;
1140 default:
1141 WARN(1, "bad port clock sel\n");
1142 return;
1143 }
1144
1145 pipe_config->port_clock = link_clock * 2;
1146
Ville Syrjälä398a0172015-06-30 15:33:51 +03001147 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001148}
1149
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301150static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1151 enum intel_dpll_id dpll)
1152{
Imre Deakaa610dc2015-06-22 23:35:52 +03001153 struct intel_shared_dpll *pll;
1154 struct intel_dpll_hw_state *state;
1155 intel_clock_t clock;
1156
1157 /* For DDI ports we always use a shared PLL. */
1158 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1159 return 0;
1160
1161 pll = &dev_priv->shared_dplls[dpll];
1162 state = &pll->config.hw_state;
1163
1164 clock.m1 = 2;
1165 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1166 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1167 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1168 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1169 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1170 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1171
1172 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301173}
1174
1175static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1176 struct intel_crtc_state *pipe_config)
1177{
1178 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1179 enum port port = intel_ddi_get_encoder_port(encoder);
1180 uint32_t dpll = port;
1181
Ville Syrjälä398a0172015-06-30 15:33:51 +03001182 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301183
Ville Syrjälä398a0172015-06-30 15:33:51 +03001184 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301185}
1186
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001187void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001188 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001189{
Damien Lespiau22606a12014-12-12 14:26:57 +00001190 struct drm_device *dev = encoder->base.dev;
1191
1192 if (INTEL_INFO(dev)->gen <= 8)
1193 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001194 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001195 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301196 else if (IS_BROXTON(dev))
1197 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001198}
1199
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001200static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001201hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1202 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001203{
1204 uint64_t freq2k;
1205 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001206 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001207 unsigned budget;
1208
1209 freq2k = clock / 100;
1210
Damien Lespiau63582982015-05-07 18:38:46 +01001211 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001212
1213 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1214 * and directly pass the LC PLL to it. */
1215 if (freq2k == 5400000) {
1216 *n2_out = 2;
1217 *p_out = 1;
1218 *r2_out = 2;
1219 return;
1220 }
1221
1222 /*
1223 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1224 * the WR PLL.
1225 *
1226 * We want R so that REF_MIN <= Ref <= REF_MAX.
1227 * Injecting R2 = 2 * R gives:
1228 * REF_MAX * r2 > LC_FREQ * 2 and
1229 * REF_MIN * r2 < LC_FREQ * 2
1230 *
1231 * Which means the desired boundaries for r2 are:
1232 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1233 *
1234 */
1235 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1236 r2 <= LC_FREQ * 2 / REF_MIN;
1237 r2++) {
1238
1239 /*
1240 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1241 *
1242 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1243 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1244 * VCO_MAX * r2 > n2 * LC_FREQ and
1245 * VCO_MIN * r2 < n2 * LC_FREQ)
1246 *
1247 * Which means the desired boundaries for n2 are:
1248 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1249 */
1250 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1251 n2 <= VCO_MAX * r2 / LC_FREQ;
1252 n2++) {
1253
1254 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001255 hsw_wrpll_update_rnp(freq2k, budget,
1256 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001257 }
1258 }
1259
1260 *n2_out = best.n2;
1261 *p_out = best.p;
1262 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001263}
1264
Damien Lespiau0220ab62014-07-29 18:06:22 +01001265static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001266hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001267 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001268 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001269{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001270 int clock = crtc_state->port_clock;
1271
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001272 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001273 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001274 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001275 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001276
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001277 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001278
Daniel Vetter114fe482014-06-25 22:01:48 +03001279 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001280 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1281 WRPLL_DIVIDER_POST(p);
1282
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001283 memset(&crtc_state->dpll_hw_state, 0,
1284 sizeof(crtc_state->dpll_hw_state));
1285
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001286 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001287
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001288 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001289 if (pll == NULL) {
1290 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1291 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001292 return false;
1293 }
1294
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001295 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001296 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1297 struct drm_atomic_state *state = crtc_state->base.state;
1298 struct intel_shared_dpll_config *spll =
1299 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1300
1301 if (spll->crtc_mask &&
1302 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1303 return false;
1304
1305 crtc_state->shared_dpll = DPLL_ID_SPLL;
1306 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1307 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001308 }
1309
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001310 return true;
1311}
1312
Damien Lespiaudc253812015-06-25 16:15:06 +01001313struct skl_wrpll_context {
1314 uint64_t min_deviation; /* current minimal deviation */
1315 uint64_t central_freq; /* chosen central freq */
1316 uint64_t dco_freq; /* chosen dco freq */
1317 unsigned int p; /* chosen divider */
1318};
1319
1320static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1321{
1322 memset(ctx, 0, sizeof(*ctx));
1323
1324 ctx->min_deviation = U64_MAX;
1325}
1326
1327/* DCO freq must be within +1%/-6% of the DCO central freq */
1328#define SKL_DCO_MAX_PDEVIATION 100
1329#define SKL_DCO_MAX_NDEVIATION 600
1330
1331static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1332 uint64_t central_freq,
1333 uint64_t dco_freq,
1334 unsigned int divider)
1335{
1336 uint64_t deviation;
1337
1338 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1339 central_freq);
1340
1341 /* positive deviation */
1342 if (dco_freq >= central_freq) {
1343 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1344 deviation < ctx->min_deviation) {
1345 ctx->min_deviation = deviation;
1346 ctx->central_freq = central_freq;
1347 ctx->dco_freq = dco_freq;
1348 ctx->p = divider;
1349 }
1350 /* negative deviation */
1351 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1352 deviation < ctx->min_deviation) {
1353 ctx->min_deviation = deviation;
1354 ctx->central_freq = central_freq;
1355 ctx->dco_freq = dco_freq;
1356 ctx->p = divider;
1357 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001358}
1359
1360static void skl_wrpll_get_multipliers(unsigned int p,
1361 unsigned int *p0 /* out */,
1362 unsigned int *p1 /* out */,
1363 unsigned int *p2 /* out */)
1364{
1365 /* even dividers */
1366 if (p % 2 == 0) {
1367 unsigned int half = p / 2;
1368
1369 if (half == 1 || half == 2 || half == 3 || half == 5) {
1370 *p0 = 2;
1371 *p1 = 1;
1372 *p2 = half;
1373 } else if (half % 2 == 0) {
1374 *p0 = 2;
1375 *p1 = half / 2;
1376 *p2 = 2;
1377 } else if (half % 3 == 0) {
1378 *p0 = 3;
1379 *p1 = half / 3;
1380 *p2 = 2;
1381 } else if (half % 7 == 0) {
1382 *p0 = 7;
1383 *p1 = half / 7;
1384 *p2 = 2;
1385 }
1386 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1387 *p0 = 3;
1388 *p1 = 1;
1389 *p2 = p / 3;
1390 } else if (p == 5 || p == 7) {
1391 *p0 = p;
1392 *p1 = 1;
1393 *p2 = 1;
1394 } else if (p == 15) {
1395 *p0 = 3;
1396 *p1 = 1;
1397 *p2 = 5;
1398 } else if (p == 21) {
1399 *p0 = 7;
1400 *p1 = 1;
1401 *p2 = 3;
1402 } else if (p == 35) {
1403 *p0 = 7;
1404 *p1 = 1;
1405 *p2 = 5;
1406 }
1407}
1408
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001409struct skl_wrpll_params {
1410 uint32_t dco_fraction;
1411 uint32_t dco_integer;
1412 uint32_t qdiv_ratio;
1413 uint32_t qdiv_mode;
1414 uint32_t kdiv;
1415 uint32_t pdiv;
1416 uint32_t central_freq;
1417};
1418
Damien Lespiau76516fb2015-05-07 18:38:42 +01001419static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1420 uint64_t afe_clock,
1421 uint64_t central_freq,
1422 uint32_t p0, uint32_t p1, uint32_t p2)
1423{
1424 uint64_t dco_freq;
1425
Damien Lespiau76516fb2015-05-07 18:38:42 +01001426 switch (central_freq) {
1427 case 9600000000ULL:
1428 params->central_freq = 0;
1429 break;
1430 case 9000000000ULL:
1431 params->central_freq = 1;
1432 break;
1433 case 8400000000ULL:
1434 params->central_freq = 3;
1435 }
1436
1437 switch (p0) {
1438 case 1:
1439 params->pdiv = 0;
1440 break;
1441 case 2:
1442 params->pdiv = 1;
1443 break;
1444 case 3:
1445 params->pdiv = 2;
1446 break;
1447 case 7:
1448 params->pdiv = 4;
1449 break;
1450 default:
1451 WARN(1, "Incorrect PDiv\n");
1452 }
1453
1454 switch (p2) {
1455 case 5:
1456 params->kdiv = 0;
1457 break;
1458 case 2:
1459 params->kdiv = 1;
1460 break;
1461 case 3:
1462 params->kdiv = 2;
1463 break;
1464 case 1:
1465 params->kdiv = 3;
1466 break;
1467 default:
1468 WARN(1, "Incorrect KDiv\n");
1469 }
1470
1471 params->qdiv_ratio = p1;
1472 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1473
1474 dco_freq = p0 * p1 * p2 * afe_clock;
1475
1476 /*
1477 * Intermediate values are in Hz.
1478 * Divide by MHz to match bsepc
1479 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001480 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001481 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001482 div_u64((div_u64(dco_freq, 24) -
1483 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001484}
1485
Damien Lespiau318bd822015-05-07 18:38:40 +01001486static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001487skl_ddi_calculate_wrpll(int clock /* in Hz */,
1488 struct skl_wrpll_params *wrpll_params)
1489{
1490 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001491 uint64_t dco_central_freq[3] = {8400000000ULL,
1492 9000000000ULL,
1493 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001494 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1495 24, 28, 30, 32, 36, 40, 42, 44,
1496 48, 52, 54, 56, 60, 64, 66, 68,
1497 70, 72, 76, 78, 80, 84, 88, 90,
1498 92, 96, 98 };
1499 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1500 static const struct {
1501 const int *list;
1502 int n_dividers;
1503 } dividers[] = {
1504 { even_dividers, ARRAY_SIZE(even_dividers) },
1505 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1506 };
1507 struct skl_wrpll_context ctx;
1508 unsigned int dco, d, i;
1509 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001510
Damien Lespiaudc253812015-06-25 16:15:06 +01001511 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001512
Damien Lespiaudc253812015-06-25 16:15:06 +01001513 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1514 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1515 for (i = 0; i < dividers[d].n_dividers; i++) {
1516 unsigned int p = dividers[d].list[i];
1517 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001518
Damien Lespiaudc253812015-06-25 16:15:06 +01001519 skl_wrpll_try_divider(&ctx,
1520 dco_central_freq[dco],
1521 dco_freq,
1522 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001523 /*
1524 * Skip the remaining dividers if we're sure to
1525 * have found the definitive divider, we can't
1526 * improve a 0 deviation.
1527 */
1528 if (ctx.min_deviation == 0)
1529 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001530 }
1531 }
Damien Lespiau267db662015-06-25 16:19:24 +01001532
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001533skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001534 /*
1535 * If a solution is found with an even divider, prefer
1536 * this one.
1537 */
1538 if (d == 0 && ctx.p)
1539 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001540 }
1541
Damien Lespiaudc253812015-06-25 16:15:06 +01001542 if (!ctx.p) {
1543 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001544 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001545 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001546
Damien Lespiaudc253812015-06-25 16:15:06 +01001547 /*
1548 * gcc incorrectly analyses that these can be used without being
1549 * initialized. To be fair, it's hard to guess.
1550 */
1551 p0 = p1 = p2 = 0;
1552 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1553 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1554 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001555
Damien Lespiau318bd822015-05-07 18:38:40 +01001556 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001557}
1558
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001559static bool
1560skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001561 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001562 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001563{
1564 struct intel_shared_dpll *pll;
1565 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001566 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001567
1568 /*
1569 * See comment in intel_dpll_hw_state to understand why we always use 0
1570 * as the DPLL id in this function.
1571 */
1572
1573 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1574
1575 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1576 struct skl_wrpll_params wrpll_params = { 0, };
1577
1578 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1579
Damien Lespiau318bd822015-05-07 18:38:40 +01001580 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1581 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001582
1583 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1584 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1585 wrpll_params.dco_integer;
1586
1587 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1588 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1589 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1590 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1591 wrpll_params.central_freq;
1592 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001593 switch (crtc_state->port_clock / 2) {
1594 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001595 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001596 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001597 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001598 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001599 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001600 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001601 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001602 break;
1603 }
1604
1605 cfgcr1 = cfgcr2 = 0;
1606 } else /* eDP */
1607 return true;
1608
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001609 memset(&crtc_state->dpll_hw_state, 0,
1610 sizeof(crtc_state->dpll_hw_state));
1611
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001612 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1613 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1614 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001615
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001616 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001617 if (pll == NULL) {
1618 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1619 pipe_name(intel_crtc->pipe));
1620 return false;
1621 }
1622
1623 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001624 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001625
1626 return true;
1627}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001628
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301629/* bxt clock parameters */
1630struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301631 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301632 uint32_t p1;
1633 uint32_t p2;
1634 uint32_t m2_int;
1635 uint32_t m2_frac;
1636 bool m2_frac_en;
1637 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301638};
1639
1640/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301641static const struct bxt_clk_div bxt_dp_clk_val[] = {
1642 {162000, 4, 2, 32, 1677722, 1, 1},
1643 {270000, 4, 1, 27, 0, 0, 1},
1644 {540000, 2, 1, 27, 0, 0, 1},
1645 {216000, 3, 2, 32, 1677722, 1, 1},
1646 {243000, 4, 1, 24, 1258291, 1, 1},
1647 {324000, 4, 1, 32, 1677722, 1, 1},
1648 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301649};
1650
1651static bool
1652bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1653 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001654 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301655{
1656 struct intel_shared_dpll *pll;
1657 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301658 int vco = 0;
1659 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301660 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001661 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301662
1663 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1664 intel_clock_t best_clock;
1665
1666 /* Calculate HDMI div */
1667 /*
1668 * FIXME: tie the following calculation into
1669 * i9xx_crtc_compute_clock
1670 */
1671 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1672 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1673 clock, pipe_name(intel_crtc->pipe));
1674 return false;
1675 }
1676
1677 clk_div.p1 = best_clock.p1;
1678 clk_div.p2 = best_clock.p2;
1679 WARN_ON(best_clock.m1 != 2);
1680 clk_div.n = best_clock.n;
1681 clk_div.m2_int = best_clock.m2 >> 22;
1682 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1683 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1684
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301685 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301686 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1687 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301688 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301689
Sonika Jindal64987fc2015-05-26 17:50:13 +05301690 clk_div = bxt_dp_clk_val[0];
1691 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1692 if (bxt_dp_clk_val[i].clock == clock) {
1693 clk_div = bxt_dp_clk_val[i];
1694 break;
1695 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301696 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301697 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1698 }
1699
Vandana Kannane6292552015-07-01 17:02:57 +05301700 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301701 prop_coef = 4;
1702 int_coef = 9;
1703 gain_ctl = 3;
1704 targ_cnt = 8;
1705 } else if ((vco > 5400000 && vco < 6200000) ||
1706 (vco >= 4800000 && vco < 5400000)) {
1707 prop_coef = 5;
1708 int_coef = 11;
1709 gain_ctl = 3;
1710 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301711 } else if (vco == 5400000) {
1712 prop_coef = 3;
1713 int_coef = 8;
1714 gain_ctl = 1;
1715 targ_cnt = 9;
1716 } else {
1717 DRM_ERROR("Invalid VCO\n");
1718 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301719 }
1720
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001721 memset(&crtc_state->dpll_hw_state, 0,
1722 sizeof(crtc_state->dpll_hw_state));
1723
Vandana Kannane0681e32015-05-13 12:20:35 +05301724 if (clock > 270000)
1725 lanestagger = 0x18;
1726 else if (clock > 135000)
1727 lanestagger = 0x0d;
1728 else if (clock > 67000)
1729 lanestagger = 0x07;
1730 else if (clock > 33000)
1731 lanestagger = 0x04;
1732 else
1733 lanestagger = 0x02;
1734
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301735 crtc_state->dpll_hw_state.ebb0 =
1736 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1737 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1738 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1739 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1740
1741 if (clk_div.m2_frac_en)
1742 crtc_state->dpll_hw_state.pll3 =
1743 PORT_PLL_M2_FRAC_ENABLE;
1744
1745 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301746 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301747 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301748 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301749
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301750 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1751
Imre Deak05712c12015-06-18 17:25:54 +03001752 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1753
Vandana Kannane6292552015-07-01 17:02:57 +05301754 crtc_state->dpll_hw_state.pll10 =
1755 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1756 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301757
Imre Deak05712c12015-06-18 17:25:54 +03001758 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1759
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301760 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301761 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301762
1763 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1764 if (pll == NULL) {
1765 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1766 pipe_name(intel_crtc->pipe));
1767 return false;
1768 }
1769
1770 /* shared DPLL id 0 is DPLL A */
1771 crtc_state->ddi_pll_sel = pll->id;
1772
1773 return true;
1774}
1775
Damien Lespiau0220ab62014-07-29 18:06:22 +01001776/*
1777 * Tries to find a *shared* PLL for the CRTC and store it in
1778 * intel_crtc->ddi_pll_sel.
1779 *
1780 * For private DPLLs, compute_config() should do the selection for us. This
1781 * function should be folded into compute_config() eventually.
1782 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001783bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1784 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001785{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001786 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001787 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001788 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001789
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001790 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001791 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001792 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301793 else if (IS_BROXTON(dev))
1794 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001795 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001796 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001797 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001798 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001799}
1800
Paulo Zanonidae84792012-10-15 15:51:30 -03001801void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1802{
1803 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1804 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1805 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001806 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001807 int type = intel_encoder->type;
1808 uint32_t temp;
1809
Dave Airlie0e32b392014-05-02 14:02:48 +10001810 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001811 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001812 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001813 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001814 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001815 break;
1816 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001817 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001818 break;
1819 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001820 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001821 break;
1822 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001823 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001824 break;
1825 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001826 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001827 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001828 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001829 }
1830}
1831
Dave Airlie0e32b392014-05-02 14:02:48 +10001832void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1833{
1834 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1835 struct drm_device *dev = crtc->dev;
1836 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001837 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001838 uint32_t temp;
1839 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1840 if (state == true)
1841 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1842 else
1843 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1844 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1845}
1846
Damien Lespiau8228c252013-03-07 15:30:27 +00001847void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001848{
1849 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1850 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001851 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001852 struct drm_device *dev = crtc->dev;
1853 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001854 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001855 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001856 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001857 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001858 uint32_t temp;
1859
Paulo Zanoniad80a812012-10-24 16:06:19 -02001860 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1861 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001862 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001863
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001864 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001865 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001866 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001867 break;
1868 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001869 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001870 break;
1871 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001872 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001873 break;
1874 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001875 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001876 break;
1877 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001878 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001879 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001880
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001881 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001882 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001883 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001884 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001885
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001886 if (cpu_transcoder == TRANSCODER_EDP) {
1887 switch (pipe) {
1888 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001889 /* On Haswell, can only use the always-on power well for
1890 * eDP when not using the panel fitter, and when not
1891 * using motion blur mitigation (which we don't
1892 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001893 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001894 (intel_crtc->config->pch_pfit.enabled ||
1895 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001896 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1897 else
1898 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001899 break;
1900 case PIPE_B:
1901 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1902 break;
1903 case PIPE_C:
1904 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1905 break;
1906 default:
1907 BUG();
1908 break;
1909 }
1910 }
1911
Paulo Zanoni7739c332012-10-15 15:51:29 -03001912 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001913 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001914 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001915 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001916 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001917
Paulo Zanoni7739c332012-10-15 15:51:29 -03001918 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001919 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001920 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001921
1922 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1923 type == INTEL_OUTPUT_EDP) {
1924 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1925
Dave Airlie0e32b392014-05-02 14:02:48 +10001926 if (intel_dp->is_mst) {
1927 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1928 } else
1929 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1930
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001931 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001932 } else if (type == INTEL_OUTPUT_DP_MST) {
1933 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1934
1935 if (intel_dp->is_mst) {
1936 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1937 } else
1938 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001939
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001940 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001941 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001942 WARN(1, "Invalid encoder type %d for pipe %c\n",
1943 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001944 }
1945
Paulo Zanoniad80a812012-10-24 16:06:19 -02001946 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001947}
1948
Paulo Zanoniad80a812012-10-24 16:06:19 -02001949void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1950 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001951{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001952 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001953 uint32_t val = I915_READ(reg);
1954
Dave Airlie0e32b392014-05-02 14:02:48 +10001955 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001956 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001957 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001958}
1959
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001960bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1961{
1962 struct drm_device *dev = intel_connector->base.dev;
1963 struct drm_i915_private *dev_priv = dev->dev_private;
1964 struct intel_encoder *intel_encoder = intel_connector->encoder;
1965 int type = intel_connector->base.connector_type;
1966 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1967 enum pipe pipe = 0;
1968 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001969 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001970 uint32_t tmp;
1971
Paulo Zanoni882244a2014-04-01 14:55:12 -03001972 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001973 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001974 return false;
1975
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001976 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1977 return false;
1978
1979 if (port == PORT_A)
1980 cpu_transcoder = TRANSCODER_EDP;
1981 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001982 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001983
1984 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1985
1986 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1987 case TRANS_DDI_MODE_SELECT_HDMI:
1988 case TRANS_DDI_MODE_SELECT_DVI:
1989 return (type == DRM_MODE_CONNECTOR_HDMIA);
1990
1991 case TRANS_DDI_MODE_SELECT_DP_SST:
1992 if (type == DRM_MODE_CONNECTOR_eDP)
1993 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001994 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001995 case TRANS_DDI_MODE_SELECT_DP_MST:
1996 /* if the transcoder is in MST state then
1997 * connector isn't connected */
1998 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001999
2000 case TRANS_DDI_MODE_SELECT_FDI:
2001 return (type == DRM_MODE_CONNECTOR_VGA);
2002
2003 default:
2004 return false;
2005 }
2006}
2007
Daniel Vetter85234cd2012-07-02 13:27:29 +02002008bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
2009 enum pipe *pipe)
2010{
2011 struct drm_device *dev = encoder->base.dev;
2012 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002013 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002014 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002015 u32 tmp;
2016 int i;
2017
Imre Deak6d129be2014-03-05 16:20:54 +02002018 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002019 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002020 return false;
2021
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002022 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002023
2024 if (!(tmp & DDI_BUF_CTL_ENABLE))
2025 return false;
2026
Paulo Zanoniad80a812012-10-24 16:06:19 -02002027 if (port == PORT_A) {
2028 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002029
Paulo Zanoniad80a812012-10-24 16:06:19 -02002030 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2031 case TRANS_DDI_EDP_INPUT_A_ON:
2032 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2033 *pipe = PIPE_A;
2034 break;
2035 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2036 *pipe = PIPE_B;
2037 break;
2038 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2039 *pipe = PIPE_C;
2040 break;
2041 }
2042
2043 return true;
2044 } else {
2045 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2046 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2047
2048 if ((tmp & TRANS_DDI_PORT_MASK)
2049 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002050 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2051 return false;
2052
Paulo Zanoniad80a812012-10-24 16:06:19 -02002053 *pipe = i;
2054 return true;
2055 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002056 }
2057 }
2058
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002059 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002060
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002061 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002062}
2063
Paulo Zanonifc914632012-10-05 12:05:54 -03002064void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2065{
2066 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302067 struct drm_device *dev = crtc->dev;
2068 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002069 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2070 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002071 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002072
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002073 if (cpu_transcoder != TRANSCODER_EDP)
2074 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2075 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002076}
2077
2078void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2079{
2080 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002081 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002082
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002083 if (cpu_transcoder != TRANSCODER_EDP)
2084 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2085 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002086}
2087
David Weinehallf8896f52015-06-25 11:11:03 +03002088static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2089 enum port port, int type)
2090{
2091 struct drm_i915_private *dev_priv = dev->dev_private;
2092 const struct ddi_buf_trans *ddi_translations;
2093 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002094 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002095 int n_entries;
2096 u32 reg;
2097
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002098 /* VBT may override standard boost values */
2099 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2100 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2101
David Weinehallf8896f52015-06-25 11:11:03 +03002102 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002103 if (dp_iboost) {
2104 iboost = dp_iboost;
2105 } else {
2106 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002107 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002108 }
David Weinehallf8896f52015-06-25 11:11:03 +03002109 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002110 if (dp_iboost) {
2111 iboost = dp_iboost;
2112 } else {
2113 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002114 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002115 }
David Weinehallf8896f52015-06-25 11:11:03 +03002116 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002117 if (hdmi_iboost) {
2118 iboost = hdmi_iboost;
2119 } else {
2120 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002121 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002122 }
David Weinehallf8896f52015-06-25 11:11:03 +03002123 } else {
2124 return;
2125 }
2126
2127 /* Make sure that the requested I_boost is valid */
2128 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2129 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2130 return;
2131 }
2132
2133 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2134 reg &= ~BALANCE_LEG_MASK(port);
2135 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2136
2137 if (iboost)
2138 reg |= iboost << BALANCE_LEG_SHIFT(port);
2139 else
2140 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2141
2142 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2143}
2144
2145static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2146 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302147{
2148 struct drm_i915_private *dev_priv = dev->dev_private;
2149 const struct bxt_ddi_buf_trans *ddi_translations;
2150 u32 n_entries, i;
2151 uint32_t val;
2152
Sonika Jindald9d70002015-09-24 10:24:56 +05302153 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2154 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2155 ddi_translations = bxt_ddi_translations_edp;
2156 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2157 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302158 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2159 ddi_translations = bxt_ddi_translations_dp;
2160 } else if (type == INTEL_OUTPUT_HDMI) {
2161 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2162 ddi_translations = bxt_ddi_translations_hdmi;
2163 } else {
2164 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2165 type);
2166 return;
2167 }
2168
2169 /* Check if default value has to be used */
2170 if (level >= n_entries ||
2171 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2172 for (i = 0; i < n_entries; i++) {
2173 if (ddi_translations[i].default_index) {
2174 level = i;
2175 break;
2176 }
2177 }
2178 }
2179
2180 /*
2181 * While we write to the group register to program all lanes at once we
2182 * can read only lane registers and we pick lanes 0/1 for that.
2183 */
2184 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2185 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2186 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2187
2188 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2189 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2190 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2191 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2192 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2193
2194 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302195 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302196 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302197 val |= SCALE_DCOMP_METHOD;
2198
2199 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2200 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2201
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302202 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2203
2204 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2205 val &= ~DE_EMPHASIS;
2206 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2207 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2208
2209 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2210 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2211 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2212}
2213
David Weinehallf8896f52015-06-25 11:11:03 +03002214static uint32_t translate_signal_level(int signal_levels)
2215{
2216 uint32_t level;
2217
2218 switch (signal_levels) {
2219 default:
2220 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2221 signal_levels);
2222 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2223 level = 0;
2224 break;
2225 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2226 level = 1;
2227 break;
2228 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2229 level = 2;
2230 break;
2231 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2232 level = 3;
2233 break;
2234
2235 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2236 level = 4;
2237 break;
2238 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2239 level = 5;
2240 break;
2241 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2242 level = 6;
2243 break;
2244
2245 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2246 level = 7;
2247 break;
2248 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2249 level = 8;
2250 break;
2251
2252 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2253 level = 9;
2254 break;
2255 }
2256
2257 return level;
2258}
2259
2260uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2261{
2262 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2263 struct drm_device *dev = dport->base.base.dev;
2264 struct intel_encoder *encoder = &dport->base;
2265 uint8_t train_set = intel_dp->train_set[0];
2266 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2267 DP_TRAIN_PRE_EMPHASIS_MASK);
2268 enum port port = dport->port;
2269 uint32_t level;
2270
2271 level = translate_signal_level(signal_levels);
2272
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002273 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
David Weinehallf8896f52015-06-25 11:11:03 +03002274 skl_ddi_set_iboost(dev, level, port, encoder->type);
2275 else if (IS_BROXTON(dev))
2276 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2277
2278 return DDI_BUF_TRANS_SELECT(level);
2279}
2280
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002281void intel_ddi_clk_select(struct intel_encoder *encoder,
2282 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002283{
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002284 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2285 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002286
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002287 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2288 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002289 uint32_t val;
2290
Damien Lespiau5416d872014-11-14 17:24:33 +00002291 /*
2292 * DPLL0 is used for eDP and is the only "private" DPLL (as
2293 * opposed to shared) on SKL
2294 */
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002295 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002296 WARN_ON(dpll != SKL_DPLL0);
2297
2298 val = I915_READ(DPLL_CTRL1);
2299
2300 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2301 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002302 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002303 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002304
2305 I915_WRITE(DPLL_CTRL1, val);
2306 POSTING_READ(DPLL_CTRL1);
2307 }
2308
2309 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002310 val = I915_READ(DPLL_CTRL2);
2311
2312 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2313 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2314 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2315 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2316
2317 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002318
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002319 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2320 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2321 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002322 }
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002323}
2324
2325static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2326{
2327 struct drm_encoder *encoder = &intel_encoder->base;
2328 struct drm_device *dev = encoder->dev;
2329 struct drm_i915_private *dev_priv = dev->dev_private;
2330 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2331 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2332 int type = intel_encoder->type;
2333 int hdmi_level;
2334
2335 if (type == INTEL_OUTPUT_EDP) {
2336 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2337 intel_edp_panel_on(intel_dp);
2338 }
2339
2340 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002341
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002342 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002343 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002344
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002345 intel_dp_set_link_params(intel_dp, crtc->config);
2346
Dave Airlie44905a272014-05-02 13:36:43 +10002347 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002348
2349 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2350 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002351 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002352 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002353 } else if (type == INTEL_OUTPUT_HDMI) {
2354 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2355
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302356 if (IS_BROXTON(dev)) {
2357 hdmi_level = dev_priv->vbt.
2358 ddi_port_info[port].hdmi_level_shift;
2359 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2360 INTEL_OUTPUT_HDMI);
2361 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002362 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002363 crtc->config->has_hdmi_sink,
2364 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002365 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002366}
2367
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002368static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002369{
2370 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002371 struct drm_device *dev = encoder->dev;
2372 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002373 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002374 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002375 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002376 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002377
2378 val = I915_READ(DDI_BUF_CTL(port));
2379 if (val & DDI_BUF_CTL_ENABLE) {
2380 val &= ~DDI_BUF_CTL_ENABLE;
2381 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002382 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002383 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002384
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002385 val = I915_READ(DP_TP_CTL(port));
2386 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2387 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2388 I915_WRITE(DP_TP_CTL(port), val);
2389
2390 if (wait)
2391 intel_wait_ddi_buf_idle(dev_priv, port);
2392
Jani Nikula76bb80e2013-11-15 15:29:57 +02002393 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002394 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002395 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002396 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002397 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002398 }
2399
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002400 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002401 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2402 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302403 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002404 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002405}
2406
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002407static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002408{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002409 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002410 struct drm_crtc *crtc = encoder->crtc;
2411 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002412 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002413 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002414 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2415 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002416
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002417 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002418 struct intel_digital_port *intel_dig_port =
2419 enc_to_dig_port(encoder);
2420
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002421 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2422 * are ignored so nothing special needs to be done besides
2423 * enabling the port.
2424 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002425 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002426 intel_dig_port->saved_port_bits |
2427 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002428 } else if (type == INTEL_OUTPUT_EDP) {
2429 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2430
Vandana Kannan23f08d82014-11-13 14:55:22 +00002431 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002432 intel_dp_stop_link_train(intel_dp);
2433
Daniel Vetter4be73782014-01-17 14:39:48 +01002434 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002435 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302436 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002437 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002438
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002439 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002440 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002441 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002442 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002443}
2444
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002445static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002446{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002447 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002448 struct drm_crtc *crtc = encoder->crtc;
2449 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002450 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002451 struct drm_device *dev = encoder->dev;
2452 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002453
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002454 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002455 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002456 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2457 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002458
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002459 if (type == INTEL_OUTPUT_EDP) {
2460 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2461
Vandana Kannanc3955782015-01-22 15:17:40 +05302462 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002463 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002464 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002465 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002466}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002467
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002468static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002469 struct intel_shared_dpll *pll)
2470{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002471 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002472 POSTING_READ(WRPLL_CTL(pll->id));
2473 udelay(20);
2474}
2475
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002476static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002477 struct intel_shared_dpll *pll)
2478{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002479 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2480 POSTING_READ(SPLL_CTL);
2481 udelay(20);
2482}
2483
2484static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2485 struct intel_shared_dpll *pll)
2486{
Daniel Vetter12030432014-06-25 22:02:00 +03002487 uint32_t val;
2488
2489 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002490 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2491 POSTING_READ(WRPLL_CTL(pll->id));
2492}
2493
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002494static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2495 struct intel_shared_dpll *pll)
2496{
2497 uint32_t val;
2498
2499 val = I915_READ(SPLL_CTL);
2500 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2501 POSTING_READ(SPLL_CTL);
2502}
2503
2504static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2505 struct intel_shared_dpll *pll,
2506 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002507{
2508 uint32_t val;
2509
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002510 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002511 return false;
2512
2513 val = I915_READ(WRPLL_CTL(pll->id));
2514 hw_state->wrpll = val;
2515
2516 return val & WRPLL_PLL_ENABLE;
2517}
2518
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002519static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2520 struct intel_shared_dpll *pll,
2521 struct intel_dpll_hw_state *hw_state)
2522{
2523 uint32_t val;
2524
2525 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2526 return false;
2527
2528 val = I915_READ(SPLL_CTL);
2529 hw_state->spll = val;
2530
2531 return val & SPLL_PLL_ENABLE;
2532}
2533
2534
Damien Lespiauca1381b2014-07-15 15:05:33 +01002535static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002536 "WRPLL 1",
2537 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002538 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002539};
2540
Damien Lespiau143b3072014-07-29 18:06:19 +01002541static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002542{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002543 int i;
2544
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002545 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002546
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002547 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002548 dev_priv->shared_dplls[i].id = i;
2549 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002550 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2551 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002552 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002553 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002554 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002555
2556 /* SPLL is special, but needs to be initialized anyway.. */
2557 dev_priv->shared_dplls[i].id = i;
2558 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2559 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2560 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2561 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2562
Damien Lespiau143b3072014-07-29 18:06:19 +01002563}
2564
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002565static const char * const skl_ddi_pll_names[] = {
2566 "DPLL 1",
2567 "DPLL 2",
2568 "DPLL 3",
2569};
2570
2571struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002572 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002573};
2574
2575/* this array is indexed by the *shared* pll id */
2576static const struct skl_dpll_regs skl_dpll_regs[3] = {
2577 {
2578 /* DPLL 1 */
2579 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002580 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2581 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002582 },
2583 {
2584 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002585 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002586 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2587 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002588 },
2589 {
2590 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002591 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002592 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2593 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002594 },
2595};
2596
2597static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2598 struct intel_shared_dpll *pll)
2599{
2600 uint32_t val;
2601 unsigned int dpll;
2602 const struct skl_dpll_regs *regs = skl_dpll_regs;
2603
2604 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2605 dpll = pll->id + 1;
2606
2607 val = I915_READ(DPLL_CTRL1);
2608
2609 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002610 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002611 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2612
2613 I915_WRITE(DPLL_CTRL1, val);
2614 POSTING_READ(DPLL_CTRL1);
2615
2616 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2617 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2618 POSTING_READ(regs[pll->id].cfgcr1);
2619 POSTING_READ(regs[pll->id].cfgcr2);
2620
2621 /* the enable bit is always bit 31 */
2622 I915_WRITE(regs[pll->id].ctl,
2623 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2624
2625 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2626 DRM_ERROR("DPLL %d not locked\n", dpll);
2627}
2628
2629static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2630 struct intel_shared_dpll *pll)
2631{
2632 const struct skl_dpll_regs *regs = skl_dpll_regs;
2633
2634 /* the enable bit is always bit 31 */
2635 I915_WRITE(regs[pll->id].ctl,
2636 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2637 POSTING_READ(regs[pll->id].ctl);
2638}
2639
2640static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2641 struct intel_shared_dpll *pll,
2642 struct intel_dpll_hw_state *hw_state)
2643{
2644 uint32_t val;
2645 unsigned int dpll;
2646 const struct skl_dpll_regs *regs = skl_dpll_regs;
2647
2648 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2649 return false;
2650
2651 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2652 dpll = pll->id + 1;
2653
2654 val = I915_READ(regs[pll->id].ctl);
2655 if (!(val & LCPLL_PLL_ENABLE))
2656 return false;
2657
2658 val = I915_READ(DPLL_CTRL1);
2659 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2660
2661 /* avoid reading back stale values if HDMI mode is not enabled */
2662 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2663 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2664 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2665 }
2666
2667 return true;
2668}
2669
2670static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2671{
2672 int i;
2673
2674 dev_priv->num_shared_dpll = 3;
2675
2676 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2677 dev_priv->shared_dplls[i].id = i;
2678 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2679 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2680 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2681 dev_priv->shared_dplls[i].get_hw_state =
2682 skl_ddi_pll_get_hw_state;
2683 }
2684}
2685
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302686static void broxton_phy_init(struct drm_i915_private *dev_priv,
2687 enum dpio_phy phy)
2688{
2689 enum port port;
2690 uint32_t val;
2691
2692 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2693 val |= GT_DISPLAY_POWER_ON(phy);
2694 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2695
2696 /* Considering 10ms timeout until BSpec is updated */
2697 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2698 DRM_ERROR("timeout during PHY%d power on\n", phy);
2699
2700 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2701 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2702 int lane;
2703
2704 for (lane = 0; lane < 4; lane++) {
2705 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2706 /*
2707 * Note that on CHV this flag is called UPAR, but has
2708 * the same function.
2709 */
2710 val &= ~LATENCY_OPTIM;
2711 if (lane != 1)
2712 val |= LATENCY_OPTIM;
2713
2714 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2715 }
2716 }
2717
2718 /* Program PLL Rcomp code offset */
2719 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2720 val &= ~IREF0RC_OFFSET_MASK;
2721 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2722 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2723
2724 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2725 val &= ~IREF1RC_OFFSET_MASK;
2726 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2727 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2728
2729 /* Program power gating */
2730 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2731 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2732 SUS_CLK_CONFIG;
2733 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2734
2735 if (phy == DPIO_PHY0) {
2736 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2737 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2738 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2739 }
2740
2741 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2742 val &= ~OCL2_LDOFUSE_PWR_DIS;
2743 /*
2744 * On PHY1 disable power on the second channel, since no port is
2745 * connected there. On PHY0 both channels have a port, so leave it
2746 * enabled.
2747 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2748 * power down the second channel on PHY0 as well.
2749 */
2750 if (phy == DPIO_PHY1)
2751 val |= OCL2_LDOFUSE_PWR_DIS;
2752 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2753
2754 if (phy == DPIO_PHY0) {
2755 uint32_t grc_code;
2756 /*
2757 * PHY0 isn't connected to an RCOMP resistor so copy over
2758 * the corresponding calibrated value from PHY1, and disable
2759 * the automatic calibration on PHY0.
2760 */
2761 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2762 10))
2763 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2764
2765 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2766 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2767 grc_code = val << GRC_CODE_FAST_SHIFT |
2768 val << GRC_CODE_SLOW_SHIFT |
2769 val;
2770 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2771
2772 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2773 val |= GRC_DIS | GRC_RDY_OVRD;
2774 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2775 }
2776
2777 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2778 val |= COMMON_RESET_DIS;
2779 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2780}
2781
2782void broxton_ddi_phy_init(struct drm_device *dev)
2783{
2784 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2785 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2786 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2787}
2788
2789static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2790 enum dpio_phy phy)
2791{
2792 uint32_t val;
2793
2794 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2795 val &= ~COMMON_RESET_DIS;
2796 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2797}
2798
2799void broxton_ddi_phy_uninit(struct drm_device *dev)
2800{
2801 struct drm_i915_private *dev_priv = dev->dev_private;
2802
2803 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2804 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2805
2806 /* FIXME: do this in broxton_phy_uninit per phy */
2807 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2808}
2809
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302810static const char * const bxt_ddi_pll_names[] = {
2811 "PORT PLL A",
2812 "PORT PLL B",
2813 "PORT PLL C",
2814};
2815
2816static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2817 struct intel_shared_dpll *pll)
2818{
2819 uint32_t temp;
2820 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2821
2822 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2823 temp &= ~PORT_PLL_REF_SEL;
2824 /* Non-SSC reference */
2825 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2826
2827 /* Disable 10 bit clock */
2828 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2829 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2830 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2831
2832 /* Write P1 & P2 */
2833 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2834 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2835 temp |= pll->config.hw_state.ebb0;
2836 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2837
2838 /* Write M2 integer */
2839 temp = I915_READ(BXT_PORT_PLL(port, 0));
2840 temp &= ~PORT_PLL_M2_MASK;
2841 temp |= pll->config.hw_state.pll0;
2842 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2843
2844 /* Write N */
2845 temp = I915_READ(BXT_PORT_PLL(port, 1));
2846 temp &= ~PORT_PLL_N_MASK;
2847 temp |= pll->config.hw_state.pll1;
2848 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2849
2850 /* Write M2 fraction */
2851 temp = I915_READ(BXT_PORT_PLL(port, 2));
2852 temp &= ~PORT_PLL_M2_FRAC_MASK;
2853 temp |= pll->config.hw_state.pll2;
2854 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2855
2856 /* Write M2 fraction enable */
2857 temp = I915_READ(BXT_PORT_PLL(port, 3));
2858 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2859 temp |= pll->config.hw_state.pll3;
2860 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2861
2862 /* Write coeff */
2863 temp = I915_READ(BXT_PORT_PLL(port, 6));
2864 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2865 temp &= ~PORT_PLL_INT_COEFF_MASK;
2866 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2867 temp |= pll->config.hw_state.pll6;
2868 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2869
2870 /* Write calibration val */
2871 temp = I915_READ(BXT_PORT_PLL(port, 8));
2872 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2873 temp |= pll->config.hw_state.pll8;
2874 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2875
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302876 temp = I915_READ(BXT_PORT_PLL(port, 9));
2877 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002878 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302879 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2880
2881 temp = I915_READ(BXT_PORT_PLL(port, 10));
2882 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2883 temp &= ~PORT_PLL_DCO_AMP_MASK;
2884 temp |= pll->config.hw_state.pll10;
2885 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302886
2887 /* Recalibrate with new settings */
2888 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2889 temp |= PORT_PLL_RECALIBRATE;
2890 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002891 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2892 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302893 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2894
2895 /* Enable PLL */
2896 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2897 temp |= PORT_PLL_ENABLE;
2898 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2899 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2900
2901 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2902 PORT_PLL_LOCK), 200))
2903 DRM_ERROR("PLL %d not locked\n", port);
2904
2905 /*
2906 * While we write to the group register to program all lanes at once we
2907 * can read only lane registers and we pick lanes 0/1 for that.
2908 */
2909 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2910 temp &= ~LANE_STAGGER_MASK;
2911 temp &= ~LANESTAGGER_STRAP_OVRD;
2912 temp |= pll->config.hw_state.pcsdw12;
2913 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2914}
2915
2916static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2917 struct intel_shared_dpll *pll)
2918{
2919 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2920 uint32_t temp;
2921
2922 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2923 temp &= ~PORT_PLL_ENABLE;
2924 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2925 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2926}
2927
2928static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2929 struct intel_shared_dpll *pll,
2930 struct intel_dpll_hw_state *hw_state)
2931{
2932 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2933 uint32_t val;
2934
2935 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2936 return false;
2937
2938 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2939 if (!(val & PORT_PLL_ENABLE))
2940 return false;
2941
2942 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002943 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2944
Imre Deak05712c12015-06-18 17:25:54 +03002945 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2946 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2947
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302948 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002949 hw_state->pll0 &= PORT_PLL_M2_MASK;
2950
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302951 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002952 hw_state->pll1 &= PORT_PLL_N_MASK;
2953
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302954 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002955 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2956
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302957 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002958 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2959
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302960 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002961 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2962 PORT_PLL_INT_COEFF_MASK |
2963 PORT_PLL_GAIN_CTL_MASK;
2964
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302965 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002966 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2967
Imre Deak05712c12015-06-18 17:25:54 +03002968 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2969 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2970
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302971 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002972 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2973 PORT_PLL_DCO_AMP_MASK;
2974
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302975 /*
2976 * While we write to the group register to program all lanes at once we
2977 * can read only lane registers. We configure all lanes the same way, so
2978 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2979 */
2980 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002981 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302982 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2983 hw_state->pcsdw12,
2984 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002985 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302986
2987 return true;
2988}
2989
2990static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2991{
2992 int i;
2993
2994 dev_priv->num_shared_dpll = 3;
2995
2996 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2997 dev_priv->shared_dplls[i].id = i;
2998 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2999 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
3000 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
3001 dev_priv->shared_dplls[i].get_hw_state =
3002 bxt_ddi_pll_get_hw_state;
3003 }
3004}
3005
Damien Lespiau143b3072014-07-29 18:06:19 +01003006void intel_ddi_pll_init(struct drm_device *dev)
3007{
3008 struct drm_i915_private *dev_priv = dev->dev_private;
3009 uint32_t val = I915_READ(LCPLL_CTL);
3010
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07003011 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003012 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05303013 else if (IS_BROXTON(dev))
3014 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003015 else
3016 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003017
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07003018 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01003019 int cdclk_freq;
3020
3021 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01003022 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05303023 if (skl_sanitize_cdclk(dev_priv))
3024 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02003025 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
3026 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05303027 } else if (IS_BROXTON(dev)) {
3028 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05303029 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003030 } else {
3031 /*
3032 * The LCPLL register should be turned on by the BIOS. For now
3033 * let's just check its state and print errors in case
3034 * something is wrong. Don't even try to turn it on.
3035 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003036
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003037 if (val & LCPLL_CD_SOURCE_FCLK)
3038 DRM_ERROR("CDCLK source is not LCPLL\n");
3039
3040 if (val & LCPLL_PLL_DISABLE)
3041 DRM_ERROR("LCPLL is disabled\n");
3042 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003043}
Paulo Zanonic19b0662012-10-15 15:51:41 -03003044
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003045void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03003046{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003047 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3048 struct drm_i915_private *dev_priv =
3049 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02003050 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003051 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05303052 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003053
3054 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
3055 val = I915_READ(DDI_BUF_CTL(port));
3056 if (val & DDI_BUF_CTL_ENABLE) {
3057 val &= ~DDI_BUF_CTL_ENABLE;
3058 I915_WRITE(DDI_BUF_CTL(port), val);
3059 wait = true;
3060 }
3061
3062 val = I915_READ(DP_TP_CTL(port));
3063 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3064 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3065 I915_WRITE(DP_TP_CTL(port), val);
3066 POSTING_READ(DP_TP_CTL(port));
3067
3068 if (wait)
3069 intel_wait_ddi_buf_idle(dev_priv, port);
3070 }
3071
Dave Airlie0e32b392014-05-02 14:02:48 +10003072 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003073 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003074 if (intel_dp->is_mst)
3075 val |= DP_TP_CTL_MODE_MST;
3076 else {
3077 val |= DP_TP_CTL_MODE_SST;
3078 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3079 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3080 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003081 I915_WRITE(DP_TP_CTL(port), val);
3082 POSTING_READ(DP_TP_CTL(port));
3083
3084 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3085 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3086 POSTING_READ(DDI_BUF_CTL(port));
3087
3088 udelay(600);
3089}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003090
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003091void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3092{
3093 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3094 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3095 uint32_t val;
3096
3097 intel_ddi_post_disable(intel_encoder);
3098
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003099 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003100 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003101 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003102
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003103 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003104 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3105 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003106 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003107
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003108 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003109 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003110 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003111
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003112 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003113 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003114 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003115}
3116
Libin Yang3d52ccf2015-12-02 14:09:44 +08003117bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
3118 struct intel_crtc *intel_crtc)
3119{
3120 u32 temp;
3121
3122 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
3123 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
3124 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
3125 return true;
3126 }
3127 return false;
3128}
3129
Ville Syrjälä6801c182013-09-24 14:24:05 +03003130void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003131 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003132{
3133 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3134 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003135 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003136 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003137 u32 temp, flags = 0;
3138
3139 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3140 if (temp & TRANS_DDI_PHSYNC)
3141 flags |= DRM_MODE_FLAG_PHSYNC;
3142 else
3143 flags |= DRM_MODE_FLAG_NHSYNC;
3144 if (temp & TRANS_DDI_PVSYNC)
3145 flags |= DRM_MODE_FLAG_PVSYNC;
3146 else
3147 flags |= DRM_MODE_FLAG_NVSYNC;
3148
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003149 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003150
3151 switch (temp & TRANS_DDI_BPC_MASK) {
3152 case TRANS_DDI_BPC_6:
3153 pipe_config->pipe_bpp = 18;
3154 break;
3155 case TRANS_DDI_BPC_8:
3156 pipe_config->pipe_bpp = 24;
3157 break;
3158 case TRANS_DDI_BPC_10:
3159 pipe_config->pipe_bpp = 30;
3160 break;
3161 case TRANS_DDI_BPC_12:
3162 pipe_config->pipe_bpp = 36;
3163 break;
3164 default:
3165 break;
3166 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003167
3168 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3169 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003170 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003171 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3172
Ville Syrjäläcda0aaa2015-11-26 18:27:07 +02003173 if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003174 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003175 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003176 case TRANS_DDI_MODE_SELECT_DVI:
3177 case TRANS_DDI_MODE_SELECT_FDI:
3178 break;
3179 case TRANS_DDI_MODE_SELECT_DP_SST:
3180 case TRANS_DDI_MODE_SELECT_DP_MST:
3181 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003182 pipe_config->lane_count =
3183 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003184 intel_dp_get_m_n(intel_crtc, pipe_config);
3185 break;
3186 default:
3187 break;
3188 }
Daniel Vetter10214422013-11-18 07:38:16 +01003189
Libin Yang3d52ccf2015-12-02 14:09:44 +08003190 pipe_config->has_audio =
3191 intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003192
Daniel Vetter10214422013-11-18 07:38:16 +01003193 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3194 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3195 /*
3196 * This is a big fat ugly hack.
3197 *
3198 * Some machines in UEFI boot mode provide us a VBT that has 18
3199 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3200 * unknown we fail to light up. Yet the same BIOS boots up with
3201 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3202 * max, not what it tells us to use.
3203 *
3204 * Note: This will still be broken if the eDP panel is not lit
3205 * up by the BIOS, and thus we can't get the mode at module
3206 * load.
3207 */
3208 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3209 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3210 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3211 }
Jesse Barnes11578552014-01-21 12:42:10 -08003212
Damien Lespiau22606a12014-12-12 14:26:57 +00003213 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003214}
3215
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003216static void intel_ddi_destroy(struct drm_encoder *encoder)
3217{
3218 /* HDMI has nothing special to destroy, so we can go with this. */
3219 intel_dp_encoder_destroy(encoder);
3220}
3221
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003222static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003223 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003224{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003225 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003226 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003227
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003228 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003229
Daniel Vettereccb1402013-05-22 00:50:22 +02003230 if (port == PORT_A)
3231 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3232
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003233 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003234 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003235 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003236 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003237}
3238
3239static const struct drm_encoder_funcs intel_ddi_funcs = {
3240 .destroy = intel_ddi_destroy,
3241};
3242
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003243static struct intel_connector *
3244intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3245{
3246 struct intel_connector *connector;
3247 enum port port = intel_dig_port->port;
3248
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003249 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003250 if (!connector)
3251 return NULL;
3252
3253 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3254 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3255 kfree(connector);
3256 return NULL;
3257 }
3258
3259 return connector;
3260}
3261
3262static struct intel_connector *
3263intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3264{
3265 struct intel_connector *connector;
3266 enum port port = intel_dig_port->port;
3267
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003268 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003269 if (!connector)
3270 return NULL;
3271
3272 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3273 intel_hdmi_init_connector(intel_dig_port, connector);
3274
3275 return connector;
3276}
3277
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003278void intel_ddi_init(struct drm_device *dev, enum port port)
3279{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003280 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003281 struct intel_digital_port *intel_dig_port;
3282 struct intel_encoder *intel_encoder;
3283 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003284 bool init_hdmi, init_dp;
3285
3286 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3287 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3288 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3289 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003290 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003291 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003292 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003293 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003294
Daniel Vetterb14c5672013-09-19 12:18:32 +02003295 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003296 if (!intel_dig_port)
3297 return;
3298
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003299 intel_encoder = &intel_dig_port->base;
3300 encoder = &intel_encoder->base;
3301
3302 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3303 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003304
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003305 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003306 intel_encoder->enable = intel_enable_ddi;
3307 intel_encoder->pre_enable = intel_ddi_pre_enable;
3308 intel_encoder->disable = intel_disable_ddi;
3309 intel_encoder->post_disable = intel_ddi_post_disable;
3310 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003311 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003312
3313 intel_dig_port->port = port;
Takashi Iwai0bdf5a02015-11-30 18:19:39 +01003314 dev_priv->dig_port_map[port] = intel_encoder;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003315 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3316 (DDI_BUF_PORT_REVERSAL |
3317 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003318
Matt Roper6c566dc2015-11-05 14:53:32 -08003319 /*
3320 * Bspec says that DDI_A_4_LANES is the only supported configuration
3321 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3322 * wasn't lit up at boot. Force this bit on in our internal
3323 * configuration so that we use the proper lane count for our
3324 * calculations.
3325 */
3326 if (IS_BROXTON(dev) && port == PORT_A) {
3327 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3328 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3329 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
3330 }
3331 }
3332
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003333 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003334 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003335 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003336
Chris Wilsonf68d6972014-08-04 07:15:09 +01003337 if (init_dp) {
3338 if (!intel_ddi_init_dp_connector(intel_dig_port))
3339 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003340
Chris Wilsonf68d6972014-08-04 07:15:09 +01003341 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303342 /*
3343 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3344 * interrupts to check the external panel connection.
3345 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003346 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303347 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3348 else
3349 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003350 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003351
Paulo Zanoni311a2092013-09-12 17:12:18 -03003352 /* In theory we don't need the encoder->type check, but leave it just in
3353 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003354 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3355 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3356 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003357 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003358
3359 return;
3360
3361err:
3362 drm_encoder_cleanup(encoder);
3363 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003364}