blob: 37efcd16ec81b1292299348129ed5f3ce18cbb45 [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 },
229 { 0x00006012, 0x00000087, 0x0 },
230 { 0x00000018, 0x000000DF, 0x0 },
231 { 0x00003015, 0x00000087, 0x0 }, /* Default */
232 { 0x00003015, 0x000000C7, 0x0 },
233 { 0x00000018, 0x000000C7, 0x0 },
234};
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 },
240 { 0x00007011, 0x00000084, 0x0 },
241 { 0x00000018, 0x000000A4, 0x0 },
242 { 0x00000018, 0x0000009D, 0x0 },
243 { 0x00004013, 0x00000080, 0x0 },
244 { 0x00006013, 0x000000C7, 0x0 },
245 { 0x00000018, 0x0000008A, 0x0 },
246 { 0x00003015, 0x000000C7, 0x0 }, /* Default */
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700247 { 0x80003015, 0x000000C7, 0x7 }, /* Uses I_boost level 0x7 */
David Weinehallf8896f52015-06-25 11:11:03 +0300248 { 0x00000018, 0x000000C7, 0x0 },
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 Vivi5f8b2532015-08-24 16:48:44 -0700356 if (IS_SKL_ULX(dev)) {
357 ddi_translations = skl_y_ddi_translations_dp;
358 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
David Weinehallf8896f52015-06-25 11:11:03 +0300359 } else if (IS_SKL_ULT(dev)) {
360 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 Vivi5f8b2532015-08-24 16:48:44 -0700376 if (IS_SKL_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 }
384 } else if (IS_SKL_ULT(dev)) {
385 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 Vivi5f8b2532015-08-24 16:48:44 -0700411 if (IS_SKL_ULX(dev)) {
412 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 Zanoni0d536cb42012-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);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300678
679 /* Enable normal pixel sending for FDI */
680 I915_WRITE(DP_TP_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200681 DP_TP_CTL_FDI_AUTOTRAIN |
682 DP_TP_CTL_LINK_TRAIN_NORMAL |
683 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
684 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300685
Paulo Zanoni04945642012-11-01 21:00:59 -0200686 return;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300687 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200688
Paulo Zanoni248138b2012-11-29 11:29:31 -0200689 temp = I915_READ(DDI_BUF_CTL(PORT_E));
690 temp &= ~DDI_BUF_CTL_ENABLE;
691 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
692 POSTING_READ(DDI_BUF_CTL(PORT_E));
693
Paulo Zanoni04945642012-11-01 21:00:59 -0200694 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200695 temp = I915_READ(DP_TP_CTL(PORT_E));
696 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
697 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
698 I915_WRITE(DP_TP_CTL(PORT_E), temp);
699 POSTING_READ(DP_TP_CTL(PORT_E));
700
701 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200702
703 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300704 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
705 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200706
707 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300708 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200709 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
710 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300711 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
712 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300713 }
714
Paulo Zanoni04945642012-11-01 21:00:59 -0200715 DRM_ERROR("FDI link training failed!\n");
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300716}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300717
Dave Airlie44905a272014-05-02 13:36:43 +1000718void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
719{
720 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
721 struct intel_digital_port *intel_dig_port =
722 enc_to_dig_port(&encoder->base);
723
724 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530725 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300726 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000727}
728
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300729static struct intel_encoder *
730intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
731{
732 struct drm_device *dev = crtc->dev;
733 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
734 struct intel_encoder *intel_encoder, *ret = NULL;
735 int num_encoders = 0;
736
737 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
738 ret = intel_encoder;
739 num_encoders++;
740 }
741
742 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300743 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
744 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300745
746 BUG_ON(ret == NULL);
747 return ret;
748}
749
Satheeshakrishna Mbcddf6102014-08-22 09:49:10 +0530750struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200751intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200752{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200753 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
754 struct intel_encoder *ret = NULL;
755 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300756 struct drm_connector *connector;
757 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200758 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200759 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200760
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200761 state = crtc_state->base.state;
762
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300763 for_each_connector_in_state(state, connector, connector_state, i) {
764 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200765 continue;
766
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300767 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200768 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200769 }
770
771 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
772 pipe_name(crtc->pipe));
773
774 BUG_ON(ret == NULL);
775 return ret;
776}
777
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100778#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100779#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100780
781#define P_MIN 2
782#define P_MAX 64
783#define P_INC 2
784
785/* Constraints for PLL good behavior */
786#define REF_MIN 48
787#define REF_MAX 400
788#define VCO_MIN 2400
789#define VCO_MAX 4800
790
Damien Lespiau27893392014-09-04 12:27:23 +0100791#define abs_diff(a, b) ({ \
792 typeof(a) __a = (a); \
793 typeof(b) __b = (b); \
794 (void) (&__a == &__b); \
795 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100796
Damien Lespiau63582982015-05-07 18:38:46 +0100797struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100798 unsigned p, n2, r2;
799};
800
Damien Lespiau63582982015-05-07 18:38:46 +0100801static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300802{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100803 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300804
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100805 switch (clock) {
806 case 25175000:
807 case 25200000:
808 case 27000000:
809 case 27027000:
810 case 37762500:
811 case 37800000:
812 case 40500000:
813 case 40541000:
814 case 54000000:
815 case 54054000:
816 case 59341000:
817 case 59400000:
818 case 72000000:
819 case 74176000:
820 case 74250000:
821 case 81000000:
822 case 81081000:
823 case 89012000:
824 case 89100000:
825 case 108000000:
826 case 108108000:
827 case 111264000:
828 case 111375000:
829 case 148352000:
830 case 148500000:
831 case 162000000:
832 case 162162000:
833 case 222525000:
834 case 222750000:
835 case 296703000:
836 case 297000000:
837 budget = 0;
838 break;
839 case 233500000:
840 case 245250000:
841 case 247750000:
842 case 253250000:
843 case 298000000:
844 budget = 1500;
845 break;
846 case 169128000:
847 case 169500000:
848 case 179500000:
849 case 202000000:
850 budget = 2000;
851 break;
852 case 256250000:
853 case 262500000:
854 case 270000000:
855 case 272500000:
856 case 273750000:
857 case 280750000:
858 case 281250000:
859 case 286000000:
860 case 291750000:
861 budget = 4000;
862 break;
863 case 267250000:
864 case 268500000:
865 budget = 5000;
866 break;
867 default:
868 budget = 1000;
869 break;
870 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300871
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100872 return budget;
873}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300874
Damien Lespiau63582982015-05-07 18:38:46 +0100875static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
876 unsigned r2, unsigned n2, unsigned p,
877 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100878{
879 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300880
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100881 /* No best (r,n,p) yet */
882 if (best->p == 0) {
883 best->p = p;
884 best->n2 = n2;
885 best->r2 = r2;
886 return;
887 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300888
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100889 /*
890 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
891 * freq2k.
892 *
893 * delta = 1e6 *
894 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
895 * freq2k;
896 *
897 * and we would like delta <= budget.
898 *
899 * If the discrepancy is above the PPM-based budget, always prefer to
900 * improve upon the previous solution. However, if you're within the
901 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
902 */
903 a = freq2k * budget * p * r2;
904 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100905 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
906 diff_best = abs_diff(freq2k * best->p * best->r2,
907 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100908 c = 1000000 * diff;
909 d = 1000000 * diff_best;
910
911 if (a < c && b < d) {
912 /* If both are above the budget, pick the closer */
913 if (best->p * best->r2 * diff < p * r2 * diff_best) {
914 best->p = p;
915 best->n2 = n2;
916 best->r2 = r2;
917 }
918 } else if (a >= c && b < d) {
919 /* If A is below the threshold but B is above it? Update. */
920 best->p = p;
921 best->n2 = n2;
922 best->r2 = r2;
923 } else if (a >= c && b >= d) {
924 /* Both are below the limit, so pick the higher n2/(r2*r2) */
925 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
926 best->p = p;
927 best->n2 = n2;
928 best->r2 = r2;
929 }
930 }
931 /* Otherwise a < c && b >= d, do nothing */
932}
933
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200934static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
935 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800936{
937 int refclk = LC_FREQ;
938 int n, p, r;
939 u32 wrpll;
940
941 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300942 switch (wrpll & WRPLL_PLL_REF_MASK) {
943 case WRPLL_PLL_SSC:
944 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800945 /*
946 * We could calculate spread here, but our checking
947 * code only cares about 5% accuracy, and spread is a max of
948 * 0.5% downspread.
949 */
950 refclk = 135;
951 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300952 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800953 refclk = LC_FREQ;
954 break;
955 default:
956 WARN(1, "bad wrpll refclk\n");
957 return 0;
958 }
959
960 r = wrpll & WRPLL_DIVIDER_REF_MASK;
961 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
962 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
963
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800964 /* Convert to KHz, p & r have a fixed point portion */
965 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800966}
967
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000968static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
969 uint32_t dpll)
970{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200971 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000972 uint32_t cfgcr1_val, cfgcr2_val;
973 uint32_t p0, p1, p2, dco_freq;
974
Ville Syrjälä923c12412015-09-30 17:06:43 +0300975 cfgcr1_reg = DPLL_CFGCR1(dpll);
976 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000977
978 cfgcr1_val = I915_READ(cfgcr1_reg);
979 cfgcr2_val = I915_READ(cfgcr2_reg);
980
981 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
982 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
983
984 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
985 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
986 else
987 p1 = 1;
988
989
990 switch (p0) {
991 case DPLL_CFGCR2_PDIV_1:
992 p0 = 1;
993 break;
994 case DPLL_CFGCR2_PDIV_2:
995 p0 = 2;
996 break;
997 case DPLL_CFGCR2_PDIV_3:
998 p0 = 3;
999 break;
1000 case DPLL_CFGCR2_PDIV_7:
1001 p0 = 7;
1002 break;
1003 }
1004
1005 switch (p2) {
1006 case DPLL_CFGCR2_KDIV_5:
1007 p2 = 5;
1008 break;
1009 case DPLL_CFGCR2_KDIV_2:
1010 p2 = 2;
1011 break;
1012 case DPLL_CFGCR2_KDIV_3:
1013 p2 = 3;
1014 break;
1015 case DPLL_CFGCR2_KDIV_1:
1016 p2 = 1;
1017 break;
1018 }
1019
1020 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1021
1022 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1023 1000) / 0x8000;
1024
1025 return dco_freq / (p0 * p1 * p2 * 5);
1026}
1027
Ville Syrjälä398a0172015-06-30 15:33:51 +03001028static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1029{
1030 int dotclock;
1031
1032 if (pipe_config->has_pch_encoder)
1033 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1034 &pipe_config->fdi_m_n);
1035 else if (pipe_config->has_dp_encoder)
1036 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1037 &pipe_config->dp_m_n);
1038 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1039 dotclock = pipe_config->port_clock * 2 / 3;
1040 else
1041 dotclock = pipe_config->port_clock;
1042
1043 if (pipe_config->pixel_multiplier)
1044 dotclock /= pipe_config->pixel_multiplier;
1045
1046 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1047}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001048
1049static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001050 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001051{
1052 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001053 int link_clock = 0;
1054 uint32_t dpll_ctl1, dpll;
1055
Damien Lespiau134ffa42014-11-14 17:24:34 +00001056 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001057
1058 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1059
1060 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1061 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1062 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001063 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1064 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001065
1066 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001067 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001068 link_clock = 81000;
1069 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001070 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301071 link_clock = 108000;
1072 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001073 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001074 link_clock = 135000;
1075 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001076 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301077 link_clock = 162000;
1078 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001079 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301080 link_clock = 216000;
1081 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001082 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001083 link_clock = 270000;
1084 break;
1085 default:
1086 WARN(1, "Unsupported link rate\n");
1087 break;
1088 }
1089 link_clock *= 2;
1090 }
1091
1092 pipe_config->port_clock = link_clock;
1093
Ville Syrjälä398a0172015-06-30 15:33:51 +03001094 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001095}
1096
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001097static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001098 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001099{
1100 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001101 int link_clock = 0;
1102 u32 val, pll;
1103
Daniel Vetter26804af2014-06-25 22:01:55 +03001104 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001105 switch (val & PORT_CLK_SEL_MASK) {
1106 case PORT_CLK_SEL_LCPLL_810:
1107 link_clock = 81000;
1108 break;
1109 case PORT_CLK_SEL_LCPLL_1350:
1110 link_clock = 135000;
1111 break;
1112 case PORT_CLK_SEL_LCPLL_2700:
1113 link_clock = 270000;
1114 break;
1115 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001116 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001117 break;
1118 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001119 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001120 break;
1121 case PORT_CLK_SEL_SPLL:
1122 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1123 if (pll == SPLL_PLL_FREQ_810MHz)
1124 link_clock = 81000;
1125 else if (pll == SPLL_PLL_FREQ_1350MHz)
1126 link_clock = 135000;
1127 else if (pll == SPLL_PLL_FREQ_2700MHz)
1128 link_clock = 270000;
1129 else {
1130 WARN(1, "bad spll freq\n");
1131 return;
1132 }
1133 break;
1134 default:
1135 WARN(1, "bad port clock sel\n");
1136 return;
1137 }
1138
1139 pipe_config->port_clock = link_clock * 2;
1140
Ville Syrjälä398a0172015-06-30 15:33:51 +03001141 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001142}
1143
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301144static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1145 enum intel_dpll_id dpll)
1146{
Imre Deakaa610dc2015-06-22 23:35:52 +03001147 struct intel_shared_dpll *pll;
1148 struct intel_dpll_hw_state *state;
1149 intel_clock_t clock;
1150
1151 /* For DDI ports we always use a shared PLL. */
1152 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1153 return 0;
1154
1155 pll = &dev_priv->shared_dplls[dpll];
1156 state = &pll->config.hw_state;
1157
1158 clock.m1 = 2;
1159 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1160 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1161 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1162 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1163 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1164 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1165
1166 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301167}
1168
1169static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1170 struct intel_crtc_state *pipe_config)
1171{
1172 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1173 enum port port = intel_ddi_get_encoder_port(encoder);
1174 uint32_t dpll = port;
1175
Ville Syrjälä398a0172015-06-30 15:33:51 +03001176 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301177
Ville Syrjälä398a0172015-06-30 15:33:51 +03001178 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301179}
1180
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001181void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001182 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001183{
Damien Lespiau22606a12014-12-12 14:26:57 +00001184 struct drm_device *dev = encoder->base.dev;
1185
1186 if (INTEL_INFO(dev)->gen <= 8)
1187 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001188 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001189 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301190 else if (IS_BROXTON(dev))
1191 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001192}
1193
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001194static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001195hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1196 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001197{
1198 uint64_t freq2k;
1199 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001200 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001201 unsigned budget;
1202
1203 freq2k = clock / 100;
1204
Damien Lespiau63582982015-05-07 18:38:46 +01001205 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001206
1207 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1208 * and directly pass the LC PLL to it. */
1209 if (freq2k == 5400000) {
1210 *n2_out = 2;
1211 *p_out = 1;
1212 *r2_out = 2;
1213 return;
1214 }
1215
1216 /*
1217 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1218 * the WR PLL.
1219 *
1220 * We want R so that REF_MIN <= Ref <= REF_MAX.
1221 * Injecting R2 = 2 * R gives:
1222 * REF_MAX * r2 > LC_FREQ * 2 and
1223 * REF_MIN * r2 < LC_FREQ * 2
1224 *
1225 * Which means the desired boundaries for r2 are:
1226 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1227 *
1228 */
1229 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1230 r2 <= LC_FREQ * 2 / REF_MIN;
1231 r2++) {
1232
1233 /*
1234 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1235 *
1236 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1237 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1238 * VCO_MAX * r2 > n2 * LC_FREQ and
1239 * VCO_MIN * r2 < n2 * LC_FREQ)
1240 *
1241 * Which means the desired boundaries for n2 are:
1242 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1243 */
1244 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1245 n2 <= VCO_MAX * r2 / LC_FREQ;
1246 n2++) {
1247
1248 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001249 hsw_wrpll_update_rnp(freq2k, budget,
1250 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001251 }
1252 }
1253
1254 *n2_out = best.n2;
1255 *p_out = best.p;
1256 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001257}
1258
Damien Lespiau0220ab62014-07-29 18:06:22 +01001259static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001260hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001261 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001262 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001263{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001264 int clock = crtc_state->port_clock;
1265
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001266 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001267 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001268 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001269 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001270
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001271 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001272
Daniel Vetter114fe482014-06-25 22:01:48 +03001273 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001274 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1275 WRPLL_DIVIDER_POST(p);
1276
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001277 memset(&crtc_state->dpll_hw_state, 0,
1278 sizeof(crtc_state->dpll_hw_state));
1279
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001280 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001281
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001282 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001283 if (pll == NULL) {
1284 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1285 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001286 return false;
1287 }
1288
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001289 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001290 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1291 struct drm_atomic_state *state = crtc_state->base.state;
1292 struct intel_shared_dpll_config *spll =
1293 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1294
1295 if (spll->crtc_mask &&
1296 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1297 return false;
1298
1299 crtc_state->shared_dpll = DPLL_ID_SPLL;
1300 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1301 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001302 }
1303
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001304 return true;
1305}
1306
Damien Lespiaudc253812015-06-25 16:15:06 +01001307struct skl_wrpll_context {
1308 uint64_t min_deviation; /* current minimal deviation */
1309 uint64_t central_freq; /* chosen central freq */
1310 uint64_t dco_freq; /* chosen dco freq */
1311 unsigned int p; /* chosen divider */
1312};
1313
1314static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1315{
1316 memset(ctx, 0, sizeof(*ctx));
1317
1318 ctx->min_deviation = U64_MAX;
1319}
1320
1321/* DCO freq must be within +1%/-6% of the DCO central freq */
1322#define SKL_DCO_MAX_PDEVIATION 100
1323#define SKL_DCO_MAX_NDEVIATION 600
1324
1325static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1326 uint64_t central_freq,
1327 uint64_t dco_freq,
1328 unsigned int divider)
1329{
1330 uint64_t deviation;
1331
1332 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1333 central_freq);
1334
1335 /* positive deviation */
1336 if (dco_freq >= central_freq) {
1337 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1338 deviation < ctx->min_deviation) {
1339 ctx->min_deviation = deviation;
1340 ctx->central_freq = central_freq;
1341 ctx->dco_freq = dco_freq;
1342 ctx->p = divider;
1343 }
1344 /* negative deviation */
1345 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1346 deviation < ctx->min_deviation) {
1347 ctx->min_deviation = deviation;
1348 ctx->central_freq = central_freq;
1349 ctx->dco_freq = dco_freq;
1350 ctx->p = divider;
1351 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001352}
1353
1354static void skl_wrpll_get_multipliers(unsigned int p,
1355 unsigned int *p0 /* out */,
1356 unsigned int *p1 /* out */,
1357 unsigned int *p2 /* out */)
1358{
1359 /* even dividers */
1360 if (p % 2 == 0) {
1361 unsigned int half = p / 2;
1362
1363 if (half == 1 || half == 2 || half == 3 || half == 5) {
1364 *p0 = 2;
1365 *p1 = 1;
1366 *p2 = half;
1367 } else if (half % 2 == 0) {
1368 *p0 = 2;
1369 *p1 = half / 2;
1370 *p2 = 2;
1371 } else if (half % 3 == 0) {
1372 *p0 = 3;
1373 *p1 = half / 3;
1374 *p2 = 2;
1375 } else if (half % 7 == 0) {
1376 *p0 = 7;
1377 *p1 = half / 7;
1378 *p2 = 2;
1379 }
1380 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1381 *p0 = 3;
1382 *p1 = 1;
1383 *p2 = p / 3;
1384 } else if (p == 5 || p == 7) {
1385 *p0 = p;
1386 *p1 = 1;
1387 *p2 = 1;
1388 } else if (p == 15) {
1389 *p0 = 3;
1390 *p1 = 1;
1391 *p2 = 5;
1392 } else if (p == 21) {
1393 *p0 = 7;
1394 *p1 = 1;
1395 *p2 = 3;
1396 } else if (p == 35) {
1397 *p0 = 7;
1398 *p1 = 1;
1399 *p2 = 5;
1400 }
1401}
1402
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001403struct skl_wrpll_params {
1404 uint32_t dco_fraction;
1405 uint32_t dco_integer;
1406 uint32_t qdiv_ratio;
1407 uint32_t qdiv_mode;
1408 uint32_t kdiv;
1409 uint32_t pdiv;
1410 uint32_t central_freq;
1411};
1412
Damien Lespiau76516fb2015-05-07 18:38:42 +01001413static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1414 uint64_t afe_clock,
1415 uint64_t central_freq,
1416 uint32_t p0, uint32_t p1, uint32_t p2)
1417{
1418 uint64_t dco_freq;
1419
Damien Lespiau76516fb2015-05-07 18:38:42 +01001420 switch (central_freq) {
1421 case 9600000000ULL:
1422 params->central_freq = 0;
1423 break;
1424 case 9000000000ULL:
1425 params->central_freq = 1;
1426 break;
1427 case 8400000000ULL:
1428 params->central_freq = 3;
1429 }
1430
1431 switch (p0) {
1432 case 1:
1433 params->pdiv = 0;
1434 break;
1435 case 2:
1436 params->pdiv = 1;
1437 break;
1438 case 3:
1439 params->pdiv = 2;
1440 break;
1441 case 7:
1442 params->pdiv = 4;
1443 break;
1444 default:
1445 WARN(1, "Incorrect PDiv\n");
1446 }
1447
1448 switch (p2) {
1449 case 5:
1450 params->kdiv = 0;
1451 break;
1452 case 2:
1453 params->kdiv = 1;
1454 break;
1455 case 3:
1456 params->kdiv = 2;
1457 break;
1458 case 1:
1459 params->kdiv = 3;
1460 break;
1461 default:
1462 WARN(1, "Incorrect KDiv\n");
1463 }
1464
1465 params->qdiv_ratio = p1;
1466 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1467
1468 dco_freq = p0 * p1 * p2 * afe_clock;
1469
1470 /*
1471 * Intermediate values are in Hz.
1472 * Divide by MHz to match bsepc
1473 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001474 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001475 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001476 div_u64((div_u64(dco_freq, 24) -
1477 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001478}
1479
Damien Lespiau318bd822015-05-07 18:38:40 +01001480static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001481skl_ddi_calculate_wrpll(int clock /* in Hz */,
1482 struct skl_wrpll_params *wrpll_params)
1483{
1484 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001485 uint64_t dco_central_freq[3] = {8400000000ULL,
1486 9000000000ULL,
1487 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001488 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1489 24, 28, 30, 32, 36, 40, 42, 44,
1490 48, 52, 54, 56, 60, 64, 66, 68,
1491 70, 72, 76, 78, 80, 84, 88, 90,
1492 92, 96, 98 };
1493 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1494 static const struct {
1495 const int *list;
1496 int n_dividers;
1497 } dividers[] = {
1498 { even_dividers, ARRAY_SIZE(even_dividers) },
1499 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1500 };
1501 struct skl_wrpll_context ctx;
1502 unsigned int dco, d, i;
1503 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001504
Damien Lespiaudc253812015-06-25 16:15:06 +01001505 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001506
Damien Lespiaudc253812015-06-25 16:15:06 +01001507 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1508 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1509 for (i = 0; i < dividers[d].n_dividers; i++) {
1510 unsigned int p = dividers[d].list[i];
1511 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001512
Damien Lespiaudc253812015-06-25 16:15:06 +01001513 skl_wrpll_try_divider(&ctx,
1514 dco_central_freq[dco],
1515 dco_freq,
1516 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001517 /*
1518 * Skip the remaining dividers if we're sure to
1519 * have found the definitive divider, we can't
1520 * improve a 0 deviation.
1521 */
1522 if (ctx.min_deviation == 0)
1523 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001524 }
1525 }
Damien Lespiau267db662015-06-25 16:19:24 +01001526
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001527skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001528 /*
1529 * If a solution is found with an even divider, prefer
1530 * this one.
1531 */
1532 if (d == 0 && ctx.p)
1533 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001534 }
1535
Damien Lespiaudc253812015-06-25 16:15:06 +01001536 if (!ctx.p) {
1537 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001538 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001539 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001540
Damien Lespiaudc253812015-06-25 16:15:06 +01001541 /*
1542 * gcc incorrectly analyses that these can be used without being
1543 * initialized. To be fair, it's hard to guess.
1544 */
1545 p0 = p1 = p2 = 0;
1546 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1547 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1548 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001549
Damien Lespiau318bd822015-05-07 18:38:40 +01001550 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001551}
1552
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001553static bool
1554skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001555 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001556 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001557{
1558 struct intel_shared_dpll *pll;
1559 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001560 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001561
1562 /*
1563 * See comment in intel_dpll_hw_state to understand why we always use 0
1564 * as the DPLL id in this function.
1565 */
1566
1567 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1568
1569 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1570 struct skl_wrpll_params wrpll_params = { 0, };
1571
1572 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1573
Damien Lespiau318bd822015-05-07 18:38:40 +01001574 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1575 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001576
1577 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1578 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1579 wrpll_params.dco_integer;
1580
1581 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1582 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1583 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1584 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1585 wrpll_params.central_freq;
1586 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001587 switch (crtc_state->port_clock / 2) {
1588 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001589 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001590 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001591 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001592 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001593 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001594 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001595 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001596 break;
1597 }
1598
1599 cfgcr1 = cfgcr2 = 0;
1600 } else /* eDP */
1601 return true;
1602
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001603 memset(&crtc_state->dpll_hw_state, 0,
1604 sizeof(crtc_state->dpll_hw_state));
1605
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001606 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1607 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1608 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001609
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001610 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001611 if (pll == NULL) {
1612 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1613 pipe_name(intel_crtc->pipe));
1614 return false;
1615 }
1616
1617 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001618 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001619
1620 return true;
1621}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001622
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301623/* bxt clock parameters */
1624struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301625 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301626 uint32_t p1;
1627 uint32_t p2;
1628 uint32_t m2_int;
1629 uint32_t m2_frac;
1630 bool m2_frac_en;
1631 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301632};
1633
1634/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301635static const struct bxt_clk_div bxt_dp_clk_val[] = {
1636 {162000, 4, 2, 32, 1677722, 1, 1},
1637 {270000, 4, 1, 27, 0, 0, 1},
1638 {540000, 2, 1, 27, 0, 0, 1},
1639 {216000, 3, 2, 32, 1677722, 1, 1},
1640 {243000, 4, 1, 24, 1258291, 1, 1},
1641 {324000, 4, 1, 32, 1677722, 1, 1},
1642 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301643};
1644
1645static bool
1646bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1647 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001648 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301649{
1650 struct intel_shared_dpll *pll;
1651 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301652 int vco = 0;
1653 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301654 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001655 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301656
1657 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1658 intel_clock_t best_clock;
1659
1660 /* Calculate HDMI div */
1661 /*
1662 * FIXME: tie the following calculation into
1663 * i9xx_crtc_compute_clock
1664 */
1665 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1666 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1667 clock, pipe_name(intel_crtc->pipe));
1668 return false;
1669 }
1670
1671 clk_div.p1 = best_clock.p1;
1672 clk_div.p2 = best_clock.p2;
1673 WARN_ON(best_clock.m1 != 2);
1674 clk_div.n = best_clock.n;
1675 clk_div.m2_int = best_clock.m2 >> 22;
1676 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1677 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1678
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301679 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301680 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1681 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301682 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301683
Sonika Jindal64987fc2015-05-26 17:50:13 +05301684 clk_div = bxt_dp_clk_val[0];
1685 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1686 if (bxt_dp_clk_val[i].clock == clock) {
1687 clk_div = bxt_dp_clk_val[i];
1688 break;
1689 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301690 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301691 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1692 }
1693
Vandana Kannane6292552015-07-01 17:02:57 +05301694 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301695 prop_coef = 4;
1696 int_coef = 9;
1697 gain_ctl = 3;
1698 targ_cnt = 8;
1699 } else if ((vco > 5400000 && vco < 6200000) ||
1700 (vco >= 4800000 && vco < 5400000)) {
1701 prop_coef = 5;
1702 int_coef = 11;
1703 gain_ctl = 3;
1704 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301705 } else if (vco == 5400000) {
1706 prop_coef = 3;
1707 int_coef = 8;
1708 gain_ctl = 1;
1709 targ_cnt = 9;
1710 } else {
1711 DRM_ERROR("Invalid VCO\n");
1712 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301713 }
1714
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001715 memset(&crtc_state->dpll_hw_state, 0,
1716 sizeof(crtc_state->dpll_hw_state));
1717
Vandana Kannane0681e32015-05-13 12:20:35 +05301718 if (clock > 270000)
1719 lanestagger = 0x18;
1720 else if (clock > 135000)
1721 lanestagger = 0x0d;
1722 else if (clock > 67000)
1723 lanestagger = 0x07;
1724 else if (clock > 33000)
1725 lanestagger = 0x04;
1726 else
1727 lanestagger = 0x02;
1728
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301729 crtc_state->dpll_hw_state.ebb0 =
1730 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1731 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1732 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1733 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1734
1735 if (clk_div.m2_frac_en)
1736 crtc_state->dpll_hw_state.pll3 =
1737 PORT_PLL_M2_FRAC_ENABLE;
1738
1739 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301740 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301741 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301742 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301743
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301744 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1745
Imre Deak05712c12015-06-18 17:25:54 +03001746 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1747
Vandana Kannane6292552015-07-01 17:02:57 +05301748 crtc_state->dpll_hw_state.pll10 =
1749 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1750 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301751
Imre Deak05712c12015-06-18 17:25:54 +03001752 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1753
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301754 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301755 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301756
1757 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1758 if (pll == NULL) {
1759 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1760 pipe_name(intel_crtc->pipe));
1761 return false;
1762 }
1763
1764 /* shared DPLL id 0 is DPLL A */
1765 crtc_state->ddi_pll_sel = pll->id;
1766
1767 return true;
1768}
1769
Damien Lespiau0220ab62014-07-29 18:06:22 +01001770/*
1771 * Tries to find a *shared* PLL for the CRTC and store it in
1772 * intel_crtc->ddi_pll_sel.
1773 *
1774 * For private DPLLs, compute_config() should do the selection for us. This
1775 * function should be folded into compute_config() eventually.
1776 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001777bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1778 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001779{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001780 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001781 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001782 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001783
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001784 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001785 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001786 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301787 else if (IS_BROXTON(dev))
1788 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001789 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001790 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001791 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001792 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001793}
1794
Paulo Zanonidae84792012-10-15 15:51:30 -03001795void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1796{
1797 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1798 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1799 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001800 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001801 int type = intel_encoder->type;
1802 uint32_t temp;
1803
Dave Airlie0e32b392014-05-02 14:02:48 +10001804 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001805 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001806 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001807 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001808 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001809 break;
1810 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001811 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001812 break;
1813 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001814 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001815 break;
1816 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001817 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001818 break;
1819 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001820 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001821 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001822 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001823 }
1824}
1825
Dave Airlie0e32b392014-05-02 14:02:48 +10001826void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1827{
1828 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1829 struct drm_device *dev = crtc->dev;
1830 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001831 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001832 uint32_t temp;
1833 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1834 if (state == true)
1835 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1836 else
1837 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1838 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1839}
1840
Damien Lespiau8228c252013-03-07 15:30:27 +00001841void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001842{
1843 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1844 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001845 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001846 struct drm_device *dev = crtc->dev;
1847 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001848 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001849 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001850 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001851 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001852 uint32_t temp;
1853
Paulo Zanoniad80a812012-10-24 16:06:19 -02001854 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1855 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001856 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001857
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001858 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001859 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001860 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001861 break;
1862 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001863 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001864 break;
1865 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001866 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001867 break;
1868 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001869 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001870 break;
1871 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001872 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001873 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001874
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001875 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001876 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001877 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001878 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001879
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001880 if (cpu_transcoder == TRANSCODER_EDP) {
1881 switch (pipe) {
1882 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001883 /* On Haswell, can only use the always-on power well for
1884 * eDP when not using the panel fitter, and when not
1885 * using motion blur mitigation (which we don't
1886 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001887 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001888 (intel_crtc->config->pch_pfit.enabled ||
1889 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001890 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1891 else
1892 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001893 break;
1894 case PIPE_B:
1895 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1896 break;
1897 case PIPE_C:
1898 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1899 break;
1900 default:
1901 BUG();
1902 break;
1903 }
1904 }
1905
Paulo Zanoni7739c332012-10-15 15:51:29 -03001906 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001907 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001908 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001909 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001910 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001911
Paulo Zanoni7739c332012-10-15 15:51:29 -03001912 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001913 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001914 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001915
1916 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1917 type == INTEL_OUTPUT_EDP) {
1918 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1919
Dave Airlie0e32b392014-05-02 14:02:48 +10001920 if (intel_dp->is_mst) {
1921 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1922 } else
1923 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1924
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001925 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001926 } else if (type == INTEL_OUTPUT_DP_MST) {
1927 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1928
1929 if (intel_dp->is_mst) {
1930 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1931 } else
1932 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001933
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001934 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001935 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001936 WARN(1, "Invalid encoder type %d for pipe %c\n",
1937 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001938 }
1939
Paulo Zanoniad80a812012-10-24 16:06:19 -02001940 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001941}
1942
Paulo Zanoniad80a812012-10-24 16:06:19 -02001943void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1944 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001945{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001946 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001947 uint32_t val = I915_READ(reg);
1948
Dave Airlie0e32b392014-05-02 14:02:48 +10001949 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001950 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001951 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001952}
1953
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001954bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1955{
1956 struct drm_device *dev = intel_connector->base.dev;
1957 struct drm_i915_private *dev_priv = dev->dev_private;
1958 struct intel_encoder *intel_encoder = intel_connector->encoder;
1959 int type = intel_connector->base.connector_type;
1960 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1961 enum pipe pipe = 0;
1962 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001963 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001964 uint32_t tmp;
1965
Paulo Zanoni882244a2014-04-01 14:55:12 -03001966 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001967 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001968 return false;
1969
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001970 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1971 return false;
1972
1973 if (port == PORT_A)
1974 cpu_transcoder = TRANSCODER_EDP;
1975 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001976 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001977
1978 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1979
1980 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1981 case TRANS_DDI_MODE_SELECT_HDMI:
1982 case TRANS_DDI_MODE_SELECT_DVI:
1983 return (type == DRM_MODE_CONNECTOR_HDMIA);
1984
1985 case TRANS_DDI_MODE_SELECT_DP_SST:
1986 if (type == DRM_MODE_CONNECTOR_eDP)
1987 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001988 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001989 case TRANS_DDI_MODE_SELECT_DP_MST:
1990 /* if the transcoder is in MST state then
1991 * connector isn't connected */
1992 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001993
1994 case TRANS_DDI_MODE_SELECT_FDI:
1995 return (type == DRM_MODE_CONNECTOR_VGA);
1996
1997 default:
1998 return false;
1999 }
2000}
2001
Daniel Vetter85234cd2012-07-02 13:27:29 +02002002bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
2003 enum pipe *pipe)
2004{
2005 struct drm_device *dev = encoder->base.dev;
2006 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002007 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002008 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002009 u32 tmp;
2010 int i;
2011
Imre Deak6d129be2014-03-05 16:20:54 +02002012 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002013 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002014 return false;
2015
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002016 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002017
2018 if (!(tmp & DDI_BUF_CTL_ENABLE))
2019 return false;
2020
Paulo Zanoniad80a812012-10-24 16:06:19 -02002021 if (port == PORT_A) {
2022 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002023
Paulo Zanoniad80a812012-10-24 16:06:19 -02002024 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2025 case TRANS_DDI_EDP_INPUT_A_ON:
2026 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2027 *pipe = PIPE_A;
2028 break;
2029 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2030 *pipe = PIPE_B;
2031 break;
2032 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2033 *pipe = PIPE_C;
2034 break;
2035 }
2036
2037 return true;
2038 } else {
2039 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2040 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2041
2042 if ((tmp & TRANS_DDI_PORT_MASK)
2043 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002044 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2045 return false;
2046
Paulo Zanoniad80a812012-10-24 16:06:19 -02002047 *pipe = i;
2048 return true;
2049 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002050 }
2051 }
2052
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002053 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002054
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002055 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002056}
2057
Paulo Zanonifc914632012-10-05 12:05:54 -03002058void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2059{
2060 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302061 struct drm_device *dev = crtc->dev;
2062 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002063 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2064 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002065 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002066
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002067 if (cpu_transcoder != TRANSCODER_EDP)
2068 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2069 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002070}
2071
2072void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2073{
2074 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002075 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002076
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002077 if (cpu_transcoder != TRANSCODER_EDP)
2078 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2079 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002080}
2081
David Weinehallf8896f52015-06-25 11:11:03 +03002082static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2083 enum port port, int type)
2084{
2085 struct drm_i915_private *dev_priv = dev->dev_private;
2086 const struct ddi_buf_trans *ddi_translations;
2087 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002088 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002089 int n_entries;
2090 u32 reg;
2091
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002092 /* VBT may override standard boost values */
2093 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2094 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2095
David Weinehallf8896f52015-06-25 11:11:03 +03002096 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002097 if (dp_iboost) {
2098 iboost = dp_iboost;
2099 } else {
2100 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002101 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002102 }
David Weinehallf8896f52015-06-25 11:11:03 +03002103 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002104 if (dp_iboost) {
2105 iboost = dp_iboost;
2106 } else {
2107 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002108 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002109 }
David Weinehallf8896f52015-06-25 11:11:03 +03002110 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002111 if (hdmi_iboost) {
2112 iboost = hdmi_iboost;
2113 } else {
2114 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002115 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002116 }
David Weinehallf8896f52015-06-25 11:11:03 +03002117 } else {
2118 return;
2119 }
2120
2121 /* Make sure that the requested I_boost is valid */
2122 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2123 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2124 return;
2125 }
2126
2127 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2128 reg &= ~BALANCE_LEG_MASK(port);
2129 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2130
2131 if (iboost)
2132 reg |= iboost << BALANCE_LEG_SHIFT(port);
2133 else
2134 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2135
2136 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2137}
2138
2139static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2140 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302141{
2142 struct drm_i915_private *dev_priv = dev->dev_private;
2143 const struct bxt_ddi_buf_trans *ddi_translations;
2144 u32 n_entries, i;
2145 uint32_t val;
2146
Sonika Jindald9d70002015-09-24 10:24:56 +05302147 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2148 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2149 ddi_translations = bxt_ddi_translations_edp;
2150 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2151 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302152 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2153 ddi_translations = bxt_ddi_translations_dp;
2154 } else if (type == INTEL_OUTPUT_HDMI) {
2155 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2156 ddi_translations = bxt_ddi_translations_hdmi;
2157 } else {
2158 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2159 type);
2160 return;
2161 }
2162
2163 /* Check if default value has to be used */
2164 if (level >= n_entries ||
2165 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2166 for (i = 0; i < n_entries; i++) {
2167 if (ddi_translations[i].default_index) {
2168 level = i;
2169 break;
2170 }
2171 }
2172 }
2173
2174 /*
2175 * While we write to the group register to program all lanes at once we
2176 * can read only lane registers and we pick lanes 0/1 for that.
2177 */
2178 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2179 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2180 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2181
2182 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2183 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2184 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2185 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2186 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2187
2188 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302189 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302190 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302191 val |= SCALE_DCOMP_METHOD;
2192
2193 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2194 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2195
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302196 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2197
2198 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2199 val &= ~DE_EMPHASIS;
2200 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2201 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2202
2203 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2204 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2205 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2206}
2207
David Weinehallf8896f52015-06-25 11:11:03 +03002208static uint32_t translate_signal_level(int signal_levels)
2209{
2210 uint32_t level;
2211
2212 switch (signal_levels) {
2213 default:
2214 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2215 signal_levels);
2216 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2217 level = 0;
2218 break;
2219 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2220 level = 1;
2221 break;
2222 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2223 level = 2;
2224 break;
2225 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2226 level = 3;
2227 break;
2228
2229 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2230 level = 4;
2231 break;
2232 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2233 level = 5;
2234 break;
2235 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2236 level = 6;
2237 break;
2238
2239 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2240 level = 7;
2241 break;
2242 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2243 level = 8;
2244 break;
2245
2246 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2247 level = 9;
2248 break;
2249 }
2250
2251 return level;
2252}
2253
2254uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2255{
2256 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2257 struct drm_device *dev = dport->base.base.dev;
2258 struct intel_encoder *encoder = &dport->base;
2259 uint8_t train_set = intel_dp->train_set[0];
2260 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2261 DP_TRAIN_PRE_EMPHASIS_MASK);
2262 enum port port = dport->port;
2263 uint32_t level;
2264
2265 level = translate_signal_level(signal_levels);
2266
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002267 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
David Weinehallf8896f52015-06-25 11:11:03 +03002268 skl_ddi_set_iboost(dev, level, port, encoder->type);
2269 else if (IS_BROXTON(dev))
2270 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2271
2272 return DDI_BUF_TRANS_SELECT(level);
2273}
2274
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002275void intel_ddi_clk_select(struct intel_encoder *encoder,
2276 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002277{
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002278 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2279 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002280
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002281 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2282 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002283 uint32_t val;
2284
Damien Lespiau5416d872014-11-14 17:24:33 +00002285 /*
2286 * DPLL0 is used for eDP and is the only "private" DPLL (as
2287 * opposed to shared) on SKL
2288 */
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002289 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002290 WARN_ON(dpll != SKL_DPLL0);
2291
2292 val = I915_READ(DPLL_CTRL1);
2293
2294 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2295 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002296 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002297 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002298
2299 I915_WRITE(DPLL_CTRL1, val);
2300 POSTING_READ(DPLL_CTRL1);
2301 }
2302
2303 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002304 val = I915_READ(DPLL_CTRL2);
2305
2306 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2307 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2308 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2309 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2310
2311 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002312
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002313 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2314 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2315 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002316 }
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002317}
2318
2319static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2320{
2321 struct drm_encoder *encoder = &intel_encoder->base;
2322 struct drm_device *dev = encoder->dev;
2323 struct drm_i915_private *dev_priv = dev->dev_private;
2324 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2325 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2326 int type = intel_encoder->type;
2327 int hdmi_level;
2328
2329 if (type == INTEL_OUTPUT_EDP) {
2330 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2331 intel_edp_panel_on(intel_dp);
2332 }
2333
2334 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002335
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002336 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002337 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002338
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002339 intel_dp_set_link_params(intel_dp, crtc->config);
2340
Dave Airlie44905a272014-05-02 13:36:43 +10002341 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002342
2343 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2344 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002345 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002346 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002347 } else if (type == INTEL_OUTPUT_HDMI) {
2348 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2349
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302350 if (IS_BROXTON(dev)) {
2351 hdmi_level = dev_priv->vbt.
2352 ddi_port_info[port].hdmi_level_shift;
2353 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2354 INTEL_OUTPUT_HDMI);
2355 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002356 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002357 crtc->config->has_hdmi_sink,
2358 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002359 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002360}
2361
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002362static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002363{
2364 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002365 struct drm_device *dev = encoder->dev;
2366 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002367 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002368 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002369 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002370 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002371
2372 val = I915_READ(DDI_BUF_CTL(port));
2373 if (val & DDI_BUF_CTL_ENABLE) {
2374 val &= ~DDI_BUF_CTL_ENABLE;
2375 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002376 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002377 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002378
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002379 val = I915_READ(DP_TP_CTL(port));
2380 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2381 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2382 I915_WRITE(DP_TP_CTL(port), val);
2383
2384 if (wait)
2385 intel_wait_ddi_buf_idle(dev_priv, port);
2386
Jani Nikula76bb80e2013-11-15 15:29:57 +02002387 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002388 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002389 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002390 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002391 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002392 }
2393
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002394 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002395 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2396 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302397 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002398 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002399}
2400
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002401static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002402{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002403 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002404 struct drm_crtc *crtc = encoder->crtc;
2405 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002406 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002407 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002408 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2409 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002410
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002411 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002412 struct intel_digital_port *intel_dig_port =
2413 enc_to_dig_port(encoder);
2414
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002415 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2416 * are ignored so nothing special needs to be done besides
2417 * enabling the port.
2418 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002419 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002420 intel_dig_port->saved_port_bits |
2421 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002422 } else if (type == INTEL_OUTPUT_EDP) {
2423 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2424
Vandana Kannan23f08d82014-11-13 14:55:22 +00002425 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002426 intel_dp_stop_link_train(intel_dp);
2427
Daniel Vetter4be73782014-01-17 14:39:48 +01002428 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002429 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302430 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002431 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002432
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002433 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002434 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002435 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002436 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002437}
2438
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002439static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002440{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002441 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002442 struct drm_crtc *crtc = encoder->crtc;
2443 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002444 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002445 struct drm_device *dev = encoder->dev;
2446 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002447
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002448 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002449 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002450 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2451 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002452
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002453 if (type == INTEL_OUTPUT_EDP) {
2454 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2455
Vandana Kannanc3955782015-01-22 15:17:40 +05302456 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002457 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002458 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002459 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002460}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002461
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002462static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002463 struct intel_shared_dpll *pll)
2464{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002465 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002466 POSTING_READ(WRPLL_CTL(pll->id));
2467 udelay(20);
2468}
2469
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002470static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002471 struct intel_shared_dpll *pll)
2472{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002473 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2474 POSTING_READ(SPLL_CTL);
2475 udelay(20);
2476}
2477
2478static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2479 struct intel_shared_dpll *pll)
2480{
Daniel Vetter12030432014-06-25 22:02:00 +03002481 uint32_t val;
2482
2483 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002484 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2485 POSTING_READ(WRPLL_CTL(pll->id));
2486}
2487
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002488static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2489 struct intel_shared_dpll *pll)
2490{
2491 uint32_t val;
2492
2493 val = I915_READ(SPLL_CTL);
2494 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2495 POSTING_READ(SPLL_CTL);
2496}
2497
2498static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2499 struct intel_shared_dpll *pll,
2500 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002501{
2502 uint32_t val;
2503
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002504 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002505 return false;
2506
2507 val = I915_READ(WRPLL_CTL(pll->id));
2508 hw_state->wrpll = val;
2509
2510 return val & WRPLL_PLL_ENABLE;
2511}
2512
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002513static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2514 struct intel_shared_dpll *pll,
2515 struct intel_dpll_hw_state *hw_state)
2516{
2517 uint32_t val;
2518
2519 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2520 return false;
2521
2522 val = I915_READ(SPLL_CTL);
2523 hw_state->spll = val;
2524
2525 return val & SPLL_PLL_ENABLE;
2526}
2527
2528
Damien Lespiauca1381b2014-07-15 15:05:33 +01002529static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002530 "WRPLL 1",
2531 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002532 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002533};
2534
Damien Lespiau143b3072014-07-29 18:06:19 +01002535static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002536{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002537 int i;
2538
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002539 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002540
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002541 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002542 dev_priv->shared_dplls[i].id = i;
2543 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002544 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2545 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002546 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002547 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002548 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002549
2550 /* SPLL is special, but needs to be initialized anyway.. */
2551 dev_priv->shared_dplls[i].id = i;
2552 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2553 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2554 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2555 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2556
Damien Lespiau143b3072014-07-29 18:06:19 +01002557}
2558
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002559static const char * const skl_ddi_pll_names[] = {
2560 "DPLL 1",
2561 "DPLL 2",
2562 "DPLL 3",
2563};
2564
2565struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002566 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002567};
2568
2569/* this array is indexed by the *shared* pll id */
2570static const struct skl_dpll_regs skl_dpll_regs[3] = {
2571 {
2572 /* DPLL 1 */
2573 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002574 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2575 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002576 },
2577 {
2578 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002579 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002580 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2581 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002582 },
2583 {
2584 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002585 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002586 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2587 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002588 },
2589};
2590
2591static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2592 struct intel_shared_dpll *pll)
2593{
2594 uint32_t val;
2595 unsigned int dpll;
2596 const struct skl_dpll_regs *regs = skl_dpll_regs;
2597
2598 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2599 dpll = pll->id + 1;
2600
2601 val = I915_READ(DPLL_CTRL1);
2602
2603 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002604 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002605 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2606
2607 I915_WRITE(DPLL_CTRL1, val);
2608 POSTING_READ(DPLL_CTRL1);
2609
2610 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2611 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2612 POSTING_READ(regs[pll->id].cfgcr1);
2613 POSTING_READ(regs[pll->id].cfgcr2);
2614
2615 /* the enable bit is always bit 31 */
2616 I915_WRITE(regs[pll->id].ctl,
2617 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2618
2619 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2620 DRM_ERROR("DPLL %d not locked\n", dpll);
2621}
2622
2623static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2624 struct intel_shared_dpll *pll)
2625{
2626 const struct skl_dpll_regs *regs = skl_dpll_regs;
2627
2628 /* the enable bit is always bit 31 */
2629 I915_WRITE(regs[pll->id].ctl,
2630 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2631 POSTING_READ(regs[pll->id].ctl);
2632}
2633
2634static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2635 struct intel_shared_dpll *pll,
2636 struct intel_dpll_hw_state *hw_state)
2637{
2638 uint32_t val;
2639 unsigned int dpll;
2640 const struct skl_dpll_regs *regs = skl_dpll_regs;
2641
2642 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2643 return false;
2644
2645 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2646 dpll = pll->id + 1;
2647
2648 val = I915_READ(regs[pll->id].ctl);
2649 if (!(val & LCPLL_PLL_ENABLE))
2650 return false;
2651
2652 val = I915_READ(DPLL_CTRL1);
2653 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2654
2655 /* avoid reading back stale values if HDMI mode is not enabled */
2656 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2657 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2658 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2659 }
2660
2661 return true;
2662}
2663
2664static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2665{
2666 int i;
2667
2668 dev_priv->num_shared_dpll = 3;
2669
2670 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2671 dev_priv->shared_dplls[i].id = i;
2672 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2673 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2674 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2675 dev_priv->shared_dplls[i].get_hw_state =
2676 skl_ddi_pll_get_hw_state;
2677 }
2678}
2679
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302680static void broxton_phy_init(struct drm_i915_private *dev_priv,
2681 enum dpio_phy phy)
2682{
2683 enum port port;
2684 uint32_t val;
2685
2686 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2687 val |= GT_DISPLAY_POWER_ON(phy);
2688 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2689
2690 /* Considering 10ms timeout until BSpec is updated */
2691 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2692 DRM_ERROR("timeout during PHY%d power on\n", phy);
2693
2694 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2695 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2696 int lane;
2697
2698 for (lane = 0; lane < 4; lane++) {
2699 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2700 /*
2701 * Note that on CHV this flag is called UPAR, but has
2702 * the same function.
2703 */
2704 val &= ~LATENCY_OPTIM;
2705 if (lane != 1)
2706 val |= LATENCY_OPTIM;
2707
2708 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2709 }
2710 }
2711
2712 /* Program PLL Rcomp code offset */
2713 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2714 val &= ~IREF0RC_OFFSET_MASK;
2715 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2716 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2717
2718 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2719 val &= ~IREF1RC_OFFSET_MASK;
2720 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2721 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2722
2723 /* Program power gating */
2724 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2725 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2726 SUS_CLK_CONFIG;
2727 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2728
2729 if (phy == DPIO_PHY0) {
2730 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2731 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2732 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2733 }
2734
2735 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2736 val &= ~OCL2_LDOFUSE_PWR_DIS;
2737 /*
2738 * On PHY1 disable power on the second channel, since no port is
2739 * connected there. On PHY0 both channels have a port, so leave it
2740 * enabled.
2741 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2742 * power down the second channel on PHY0 as well.
2743 */
2744 if (phy == DPIO_PHY1)
2745 val |= OCL2_LDOFUSE_PWR_DIS;
2746 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2747
2748 if (phy == DPIO_PHY0) {
2749 uint32_t grc_code;
2750 /*
2751 * PHY0 isn't connected to an RCOMP resistor so copy over
2752 * the corresponding calibrated value from PHY1, and disable
2753 * the automatic calibration on PHY0.
2754 */
2755 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2756 10))
2757 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2758
2759 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2760 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2761 grc_code = val << GRC_CODE_FAST_SHIFT |
2762 val << GRC_CODE_SLOW_SHIFT |
2763 val;
2764 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2765
2766 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2767 val |= GRC_DIS | GRC_RDY_OVRD;
2768 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2769 }
2770
2771 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2772 val |= COMMON_RESET_DIS;
2773 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2774}
2775
2776void broxton_ddi_phy_init(struct drm_device *dev)
2777{
2778 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2779 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2780 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2781}
2782
2783static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2784 enum dpio_phy phy)
2785{
2786 uint32_t val;
2787
2788 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2789 val &= ~COMMON_RESET_DIS;
2790 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2791}
2792
2793void broxton_ddi_phy_uninit(struct drm_device *dev)
2794{
2795 struct drm_i915_private *dev_priv = dev->dev_private;
2796
2797 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2798 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2799
2800 /* FIXME: do this in broxton_phy_uninit per phy */
2801 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2802}
2803
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302804static const char * const bxt_ddi_pll_names[] = {
2805 "PORT PLL A",
2806 "PORT PLL B",
2807 "PORT PLL C",
2808};
2809
2810static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2811 struct intel_shared_dpll *pll)
2812{
2813 uint32_t temp;
2814 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2815
2816 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2817 temp &= ~PORT_PLL_REF_SEL;
2818 /* Non-SSC reference */
2819 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2820
2821 /* Disable 10 bit clock */
2822 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2823 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2824 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2825
2826 /* Write P1 & P2 */
2827 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2828 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2829 temp |= pll->config.hw_state.ebb0;
2830 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2831
2832 /* Write M2 integer */
2833 temp = I915_READ(BXT_PORT_PLL(port, 0));
2834 temp &= ~PORT_PLL_M2_MASK;
2835 temp |= pll->config.hw_state.pll0;
2836 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2837
2838 /* Write N */
2839 temp = I915_READ(BXT_PORT_PLL(port, 1));
2840 temp &= ~PORT_PLL_N_MASK;
2841 temp |= pll->config.hw_state.pll1;
2842 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2843
2844 /* Write M2 fraction */
2845 temp = I915_READ(BXT_PORT_PLL(port, 2));
2846 temp &= ~PORT_PLL_M2_FRAC_MASK;
2847 temp |= pll->config.hw_state.pll2;
2848 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2849
2850 /* Write M2 fraction enable */
2851 temp = I915_READ(BXT_PORT_PLL(port, 3));
2852 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2853 temp |= pll->config.hw_state.pll3;
2854 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2855
2856 /* Write coeff */
2857 temp = I915_READ(BXT_PORT_PLL(port, 6));
2858 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2859 temp &= ~PORT_PLL_INT_COEFF_MASK;
2860 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2861 temp |= pll->config.hw_state.pll6;
2862 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2863
2864 /* Write calibration val */
2865 temp = I915_READ(BXT_PORT_PLL(port, 8));
2866 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2867 temp |= pll->config.hw_state.pll8;
2868 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2869
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302870 temp = I915_READ(BXT_PORT_PLL(port, 9));
2871 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002872 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302873 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2874
2875 temp = I915_READ(BXT_PORT_PLL(port, 10));
2876 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2877 temp &= ~PORT_PLL_DCO_AMP_MASK;
2878 temp |= pll->config.hw_state.pll10;
2879 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302880
2881 /* Recalibrate with new settings */
2882 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2883 temp |= PORT_PLL_RECALIBRATE;
2884 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002885 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2886 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302887 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2888
2889 /* Enable PLL */
2890 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2891 temp |= PORT_PLL_ENABLE;
2892 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2893 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2894
2895 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2896 PORT_PLL_LOCK), 200))
2897 DRM_ERROR("PLL %d not locked\n", port);
2898
2899 /*
2900 * While we write to the group register to program all lanes at once we
2901 * can read only lane registers and we pick lanes 0/1 for that.
2902 */
2903 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2904 temp &= ~LANE_STAGGER_MASK;
2905 temp &= ~LANESTAGGER_STRAP_OVRD;
2906 temp |= pll->config.hw_state.pcsdw12;
2907 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2908}
2909
2910static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2911 struct intel_shared_dpll *pll)
2912{
2913 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2914 uint32_t temp;
2915
2916 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2917 temp &= ~PORT_PLL_ENABLE;
2918 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2919 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2920}
2921
2922static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2923 struct intel_shared_dpll *pll,
2924 struct intel_dpll_hw_state *hw_state)
2925{
2926 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2927 uint32_t val;
2928
2929 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2930 return false;
2931
2932 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2933 if (!(val & PORT_PLL_ENABLE))
2934 return false;
2935
2936 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002937 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2938
Imre Deak05712c12015-06-18 17:25:54 +03002939 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2940 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2941
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302942 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002943 hw_state->pll0 &= PORT_PLL_M2_MASK;
2944
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302945 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002946 hw_state->pll1 &= PORT_PLL_N_MASK;
2947
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302948 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002949 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2950
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302951 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002952 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2953
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302954 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002955 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2956 PORT_PLL_INT_COEFF_MASK |
2957 PORT_PLL_GAIN_CTL_MASK;
2958
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302959 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002960 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2961
Imre Deak05712c12015-06-18 17:25:54 +03002962 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2963 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2964
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302965 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002966 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2967 PORT_PLL_DCO_AMP_MASK;
2968
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302969 /*
2970 * While we write to the group register to program all lanes at once we
2971 * can read only lane registers. We configure all lanes the same way, so
2972 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2973 */
2974 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002975 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302976 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2977 hw_state->pcsdw12,
2978 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002979 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302980
2981 return true;
2982}
2983
2984static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2985{
2986 int i;
2987
2988 dev_priv->num_shared_dpll = 3;
2989
2990 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2991 dev_priv->shared_dplls[i].id = i;
2992 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2993 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2994 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2995 dev_priv->shared_dplls[i].get_hw_state =
2996 bxt_ddi_pll_get_hw_state;
2997 }
2998}
2999
Damien Lespiau143b3072014-07-29 18:06:19 +01003000void intel_ddi_pll_init(struct drm_device *dev)
3001{
3002 struct drm_i915_private *dev_priv = dev->dev_private;
3003 uint32_t val = I915_READ(LCPLL_CTL);
3004
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07003005 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003006 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05303007 else if (IS_BROXTON(dev))
3008 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003009 else
3010 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003011
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07003012 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01003013 int cdclk_freq;
3014
3015 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01003016 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05303017 if (skl_sanitize_cdclk(dev_priv))
3018 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02003019 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
3020 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05303021 } else if (IS_BROXTON(dev)) {
3022 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05303023 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003024 } else {
3025 /*
3026 * The LCPLL register should be turned on by the BIOS. For now
3027 * let's just check its state and print errors in case
3028 * something is wrong. Don't even try to turn it on.
3029 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003030
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003031 if (val & LCPLL_CD_SOURCE_FCLK)
3032 DRM_ERROR("CDCLK source is not LCPLL\n");
3033
3034 if (val & LCPLL_PLL_DISABLE)
3035 DRM_ERROR("LCPLL is disabled\n");
3036 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003037}
Paulo Zanonic19b0662012-10-15 15:51:41 -03003038
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003039void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03003040{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003041 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3042 struct drm_i915_private *dev_priv =
3043 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02003044 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003045 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05303046 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003047
3048 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
3049 val = I915_READ(DDI_BUF_CTL(port));
3050 if (val & DDI_BUF_CTL_ENABLE) {
3051 val &= ~DDI_BUF_CTL_ENABLE;
3052 I915_WRITE(DDI_BUF_CTL(port), val);
3053 wait = true;
3054 }
3055
3056 val = I915_READ(DP_TP_CTL(port));
3057 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3058 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3059 I915_WRITE(DP_TP_CTL(port), val);
3060 POSTING_READ(DP_TP_CTL(port));
3061
3062 if (wait)
3063 intel_wait_ddi_buf_idle(dev_priv, port);
3064 }
3065
Dave Airlie0e32b392014-05-02 14:02:48 +10003066 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003067 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003068 if (intel_dp->is_mst)
3069 val |= DP_TP_CTL_MODE_MST;
3070 else {
3071 val |= DP_TP_CTL_MODE_SST;
3072 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3073 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3074 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003075 I915_WRITE(DP_TP_CTL(port), val);
3076 POSTING_READ(DP_TP_CTL(port));
3077
3078 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3079 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3080 POSTING_READ(DDI_BUF_CTL(port));
3081
3082 udelay(600);
3083}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003084
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003085void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3086{
3087 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3088 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3089 uint32_t val;
3090
3091 intel_ddi_post_disable(intel_encoder);
3092
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003093 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003094 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003095 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003096
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003097 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003098 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3099 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003100 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003101
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003102 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003103 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003104 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003105
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003106 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003107 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003108 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003109}
3110
Ville Syrjälä6801c182013-09-24 14:24:05 +03003111void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003112 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003113{
3114 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3115 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003116 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003117 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003118 u32 temp, flags = 0;
3119
3120 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3121 if (temp & TRANS_DDI_PHSYNC)
3122 flags |= DRM_MODE_FLAG_PHSYNC;
3123 else
3124 flags |= DRM_MODE_FLAG_NHSYNC;
3125 if (temp & TRANS_DDI_PVSYNC)
3126 flags |= DRM_MODE_FLAG_PVSYNC;
3127 else
3128 flags |= DRM_MODE_FLAG_NVSYNC;
3129
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003130 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003131
3132 switch (temp & TRANS_DDI_BPC_MASK) {
3133 case TRANS_DDI_BPC_6:
3134 pipe_config->pipe_bpp = 18;
3135 break;
3136 case TRANS_DDI_BPC_8:
3137 pipe_config->pipe_bpp = 24;
3138 break;
3139 case TRANS_DDI_BPC_10:
3140 pipe_config->pipe_bpp = 30;
3141 break;
3142 case TRANS_DDI_BPC_12:
3143 pipe_config->pipe_bpp = 36;
3144 break;
3145 default:
3146 break;
3147 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003148
3149 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3150 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b52014-04-24 23:54:47 +02003151 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003152 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3153
3154 if (intel_hdmi->infoframe_enabled(&encoder->base))
3155 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003156 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003157 case TRANS_DDI_MODE_SELECT_DVI:
3158 case TRANS_DDI_MODE_SELECT_FDI:
3159 break;
3160 case TRANS_DDI_MODE_SELECT_DP_SST:
3161 case TRANS_DDI_MODE_SELECT_DP_MST:
3162 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003163 pipe_config->lane_count =
3164 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003165 intel_dp_get_m_n(intel_crtc, pipe_config);
3166 break;
3167 default:
3168 break;
3169 }
Daniel Vetter10214422013-11-18 07:38:16 +01003170
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003171 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003172 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003173 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003174 pipe_config->has_audio = true;
3175 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003176
Daniel Vetter10214422013-11-18 07:38:16 +01003177 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3178 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3179 /*
3180 * This is a big fat ugly hack.
3181 *
3182 * Some machines in UEFI boot mode provide us a VBT that has 18
3183 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3184 * unknown we fail to light up. Yet the same BIOS boots up with
3185 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3186 * max, not what it tells us to use.
3187 *
3188 * Note: This will still be broken if the eDP panel is not lit
3189 * up by the BIOS, and thus we can't get the mode at module
3190 * load.
3191 */
3192 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3193 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3194 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3195 }
Jesse Barnes11578552014-01-21 12:42:10 -08003196
Damien Lespiau22606a12014-12-12 14:26:57 +00003197 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003198}
3199
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003200static void intel_ddi_destroy(struct drm_encoder *encoder)
3201{
3202 /* HDMI has nothing special to destroy, so we can go with this. */
3203 intel_dp_encoder_destroy(encoder);
3204}
3205
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003206static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003207 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003208{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003209 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003210 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003211
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003212 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003213
Daniel Vettereccb1402013-05-22 00:50:22 +02003214 if (port == PORT_A)
3215 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3216
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003217 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003218 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003219 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003220 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003221}
3222
3223static const struct drm_encoder_funcs intel_ddi_funcs = {
3224 .destroy = intel_ddi_destroy,
3225};
3226
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003227static struct intel_connector *
3228intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3229{
3230 struct intel_connector *connector;
3231 enum port port = intel_dig_port->port;
3232
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003233 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003234 if (!connector)
3235 return NULL;
3236
3237 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3238 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3239 kfree(connector);
3240 return NULL;
3241 }
3242
3243 return connector;
3244}
3245
3246static struct intel_connector *
3247intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3248{
3249 struct intel_connector *connector;
3250 enum port port = intel_dig_port->port;
3251
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003252 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003253 if (!connector)
3254 return NULL;
3255
3256 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3257 intel_hdmi_init_connector(intel_dig_port, connector);
3258
3259 return connector;
3260}
3261
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003262void intel_ddi_init(struct drm_device *dev, enum port port)
3263{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003264 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003265 struct intel_digital_port *intel_dig_port;
3266 struct intel_encoder *intel_encoder;
3267 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003268 bool init_hdmi, init_dp;
3269
3270 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3271 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3272 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3273 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003274 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003275 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003276 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003277 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003278
Daniel Vetterb14c5672013-09-19 12:18:32 +02003279 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003280 if (!intel_dig_port)
3281 return;
3282
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003283 intel_encoder = &intel_dig_port->base;
3284 encoder = &intel_encoder->base;
3285
3286 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
Ville Syrjälä13a3d912015-12-09 16:20:18 +02003287 DRM_MODE_ENCODER_TMDS, NULL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003288
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003289 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003290 intel_encoder->enable = intel_enable_ddi;
3291 intel_encoder->pre_enable = intel_ddi_pre_enable;
3292 intel_encoder->disable = intel_disable_ddi;
3293 intel_encoder->post_disable = intel_ddi_post_disable;
3294 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003295 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003296
3297 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003298 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3299 (DDI_BUF_PORT_REVERSAL |
3300 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003301
Matt Roper6c566dc2015-11-05 14:53:32 -08003302 /*
3303 * Bspec says that DDI_A_4_LANES is the only supported configuration
3304 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3305 * wasn't lit up at boot. Force this bit on in our internal
3306 * configuration so that we use the proper lane count for our
3307 * calculations.
3308 */
3309 if (IS_BROXTON(dev) && port == PORT_A) {
3310 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3311 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3312 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
3313 }
3314 }
3315
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003316 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003317 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003318 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003319
Chris Wilsonf68d6972014-08-04 07:15:09 +01003320 if (init_dp) {
3321 if (!intel_ddi_init_dp_connector(intel_dig_port))
3322 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003323
Chris Wilsonf68d6972014-08-04 07:15:09 +01003324 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303325 /*
3326 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3327 * interrupts to check the external panel connection.
3328 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003329 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303330 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3331 else
3332 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003333 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003334
Paulo Zanoni311a2092013-09-12 17:12:18 -03003335 /* In theory we don't need the encoder->type check, but leave it just in
3336 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003337 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3338 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3339 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003340 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003341
3342 return;
3343
3344err:
3345 drm_encoder_cleanup(encoder);
3346 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003347}