blob: 06d30029da51a7980f7afc8c645160f9823563c4 [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 },
136 { 0x00009010, 0x000000C7, 0x0 },
137 { 0x00002016, 0x0000009B, 0x0 },
138 { 0x00005012, 0x00000088, 0x0 },
139 { 0x00007011, 0x000000C7, 0x0 },
140 { 0x00002016, 0x000000DF, 0x0 },
141 { 0x00005012, 0x000000C7, 0x0 },
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 },
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700149 { 0x80009010, 0x000000C7, 0x1 }, /* Uses I_boost level 0x1 */
150 { 0x0000201B, 0x0000009D, 0x0 },
David Weinehallf8896f52015-06-25 11:11:03 +0300151 { 0x00005012, 0x000000C7, 0x0 },
152 { 0x00007011, 0x000000C7, 0x0 },
153 { 0x00002016, 0x00000088, 0x0 },
154 { 0x00005012, 0x000000C7, 0x0 },
155};
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 },
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700162 { 0x80009010, 0x000000C7, 0x3 }, /* Uses I_boost level 0x3 */
David Weinehallf8896f52015-06-25 11:11:03 +0300163 { 0x00000018, 0x0000009D, 0x0 },
164 { 0x00005012, 0x000000C7, 0x0 },
165 { 0x00007011, 0x000000C7, 0x0 },
166 { 0x00000018, 0x00000088, 0x0 },
167 { 0x00005012, 0x000000C7, 0x0 },
168};
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{
348 return intel_dig_port->hdmi.hdmi_reg;
349}
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 Zanoni0d536cb2012-11-23 16:46:41 -0200553 if (!HAS_DDI(dev))
554 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300555
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300556 for_each_intel_encoder(dev, intel_encoder) {
557 struct intel_digital_port *intel_dig_port;
558 enum port port;
559 bool supports_hdmi;
560
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530561 if (intel_encoder->type == INTEL_OUTPUT_DSI)
562 continue;
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300563
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530564 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300565 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100566 continue;
567
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300568 supports_hdmi = intel_dig_port &&
569 intel_dig_port_supports_hdmi(intel_dig_port);
570
571 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
572 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100573 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300574}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300575
Paulo Zanoni248138b2012-11-29 11:29:31 -0200576static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
577 enum port port)
578{
579 uint32_t reg = DDI_BUF_CTL(port);
580 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 Airlie44905a22014-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 Airlie44905a22014-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 Mbcddf612014-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 Oliveirada3ced22015-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 Oliveirada3ced22015-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 Oliveirada3ced22015-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
Damien Lespiau63582982015-05-07 18:38:46 +0100934static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, int reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800935{
936 int refclk = LC_FREQ;
937 int n, p, r;
938 u32 wrpll;
939
940 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300941 switch (wrpll & WRPLL_PLL_REF_MASK) {
942 case WRPLL_PLL_SSC:
943 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800944 /*
945 * We could calculate spread here, but our checking
946 * code only cares about 5% accuracy, and spread is a max of
947 * 0.5% downspread.
948 */
949 refclk = 135;
950 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300951 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800952 refclk = LC_FREQ;
953 break;
954 default:
955 WARN(1, "bad wrpll refclk\n");
956 return 0;
957 }
958
959 r = wrpll & WRPLL_DIVIDER_REF_MASK;
960 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
961 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
962
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800963 /* Convert to KHz, p & r have a fixed point portion */
964 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800965}
966
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000967static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
968 uint32_t dpll)
969{
970 uint32_t cfgcr1_reg, cfgcr2_reg;
971 uint32_t cfgcr1_val, cfgcr2_val;
972 uint32_t p0, p1, p2, dco_freq;
973
Ville Syrjälä923c12412015-09-30 17:06:43 +0300974 cfgcr1_reg = DPLL_CFGCR1(dpll);
975 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000976
977 cfgcr1_val = I915_READ(cfgcr1_reg);
978 cfgcr2_val = I915_READ(cfgcr2_reg);
979
980 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
981 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
982
983 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
984 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
985 else
986 p1 = 1;
987
988
989 switch (p0) {
990 case DPLL_CFGCR2_PDIV_1:
991 p0 = 1;
992 break;
993 case DPLL_CFGCR2_PDIV_2:
994 p0 = 2;
995 break;
996 case DPLL_CFGCR2_PDIV_3:
997 p0 = 3;
998 break;
999 case DPLL_CFGCR2_PDIV_7:
1000 p0 = 7;
1001 break;
1002 }
1003
1004 switch (p2) {
1005 case DPLL_CFGCR2_KDIV_5:
1006 p2 = 5;
1007 break;
1008 case DPLL_CFGCR2_KDIV_2:
1009 p2 = 2;
1010 break;
1011 case DPLL_CFGCR2_KDIV_3:
1012 p2 = 3;
1013 break;
1014 case DPLL_CFGCR2_KDIV_1:
1015 p2 = 1;
1016 break;
1017 }
1018
1019 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1020
1021 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1022 1000) / 0x8000;
1023
1024 return dco_freq / (p0 * p1 * p2 * 5);
1025}
1026
Ville Syrjälä398a0172015-06-30 15:33:51 +03001027static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1028{
1029 int dotclock;
1030
1031 if (pipe_config->has_pch_encoder)
1032 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1033 &pipe_config->fdi_m_n);
1034 else if (pipe_config->has_dp_encoder)
1035 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1036 &pipe_config->dp_m_n);
1037 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1038 dotclock = pipe_config->port_clock * 2 / 3;
1039 else
1040 dotclock = pipe_config->port_clock;
1041
1042 if (pipe_config->pixel_multiplier)
1043 dotclock /= pipe_config->pixel_multiplier;
1044
1045 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1046}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001047
1048static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001049 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001050{
1051 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001052 int link_clock = 0;
1053 uint32_t dpll_ctl1, dpll;
1054
Damien Lespiau134ffa42014-11-14 17:24:34 +00001055 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001056
1057 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1058
1059 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1060 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1061 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001062 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1063 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001064
1065 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001066 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001067 link_clock = 81000;
1068 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001069 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301070 link_clock = 108000;
1071 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001072 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001073 link_clock = 135000;
1074 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001075 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301076 link_clock = 162000;
1077 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001078 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301079 link_clock = 216000;
1080 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001081 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001082 link_clock = 270000;
1083 break;
1084 default:
1085 WARN(1, "Unsupported link rate\n");
1086 break;
1087 }
1088 link_clock *= 2;
1089 }
1090
1091 pipe_config->port_clock = link_clock;
1092
Ville Syrjälä398a0172015-06-30 15:33:51 +03001093 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001094}
1095
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001096static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001097 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001098{
1099 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001100 int link_clock = 0;
1101 u32 val, pll;
1102
Daniel Vetter26804af2014-06-25 22:01:55 +03001103 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001104 switch (val & PORT_CLK_SEL_MASK) {
1105 case PORT_CLK_SEL_LCPLL_810:
1106 link_clock = 81000;
1107 break;
1108 case PORT_CLK_SEL_LCPLL_1350:
1109 link_clock = 135000;
1110 break;
1111 case PORT_CLK_SEL_LCPLL_2700:
1112 link_clock = 270000;
1113 break;
1114 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001115 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001116 break;
1117 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001118 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001119 break;
1120 case PORT_CLK_SEL_SPLL:
1121 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1122 if (pll == SPLL_PLL_FREQ_810MHz)
1123 link_clock = 81000;
1124 else if (pll == SPLL_PLL_FREQ_1350MHz)
1125 link_clock = 135000;
1126 else if (pll == SPLL_PLL_FREQ_2700MHz)
1127 link_clock = 270000;
1128 else {
1129 WARN(1, "bad spll freq\n");
1130 return;
1131 }
1132 break;
1133 default:
1134 WARN(1, "bad port clock sel\n");
1135 return;
1136 }
1137
1138 pipe_config->port_clock = link_clock * 2;
1139
Ville Syrjälä398a0172015-06-30 15:33:51 +03001140 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001141}
1142
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301143static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1144 enum intel_dpll_id dpll)
1145{
Imre Deakaa610dc2015-06-22 23:35:52 +03001146 struct intel_shared_dpll *pll;
1147 struct intel_dpll_hw_state *state;
1148 intel_clock_t clock;
1149
1150 /* For DDI ports we always use a shared PLL. */
1151 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1152 return 0;
1153
1154 pll = &dev_priv->shared_dplls[dpll];
1155 state = &pll->config.hw_state;
1156
1157 clock.m1 = 2;
1158 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1159 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1160 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1161 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1162 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1163 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1164
1165 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301166}
1167
1168static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1169 struct intel_crtc_state *pipe_config)
1170{
1171 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1172 enum port port = intel_ddi_get_encoder_port(encoder);
1173 uint32_t dpll = port;
1174
Ville Syrjälä398a0172015-06-30 15:33:51 +03001175 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301176
Ville Syrjälä398a0172015-06-30 15:33:51 +03001177 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301178}
1179
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001180void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001181 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001182{
Damien Lespiau22606a12014-12-12 14:26:57 +00001183 struct drm_device *dev = encoder->base.dev;
1184
1185 if (INTEL_INFO(dev)->gen <= 8)
1186 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001187 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001188 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301189 else if (IS_BROXTON(dev))
1190 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001191}
1192
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001193static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001194hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1195 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001196{
1197 uint64_t freq2k;
1198 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001199 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001200 unsigned budget;
1201
1202 freq2k = clock / 100;
1203
Damien Lespiau63582982015-05-07 18:38:46 +01001204 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001205
1206 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1207 * and directly pass the LC PLL to it. */
1208 if (freq2k == 5400000) {
1209 *n2_out = 2;
1210 *p_out = 1;
1211 *r2_out = 2;
1212 return;
1213 }
1214
1215 /*
1216 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1217 * the WR PLL.
1218 *
1219 * We want R so that REF_MIN <= Ref <= REF_MAX.
1220 * Injecting R2 = 2 * R gives:
1221 * REF_MAX * r2 > LC_FREQ * 2 and
1222 * REF_MIN * r2 < LC_FREQ * 2
1223 *
1224 * Which means the desired boundaries for r2 are:
1225 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1226 *
1227 */
1228 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1229 r2 <= LC_FREQ * 2 / REF_MIN;
1230 r2++) {
1231
1232 /*
1233 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1234 *
1235 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1236 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1237 * VCO_MAX * r2 > n2 * LC_FREQ and
1238 * VCO_MIN * r2 < n2 * LC_FREQ)
1239 *
1240 * Which means the desired boundaries for n2 are:
1241 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1242 */
1243 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1244 n2 <= VCO_MAX * r2 / LC_FREQ;
1245 n2++) {
1246
1247 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001248 hsw_wrpll_update_rnp(freq2k, budget,
1249 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001250 }
1251 }
1252
1253 *n2_out = best.n2;
1254 *p_out = best.p;
1255 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001256}
1257
Damien Lespiau0220ab62014-07-29 18:06:22 +01001258static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001259hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001260 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001261 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001262{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001263 int clock = crtc_state->port_clock;
1264
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001265 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001266 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001267 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001268 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001269
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001270 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001271
Daniel Vetter114fe482014-06-25 22:01:48 +03001272 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001273 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1274 WRPLL_DIVIDER_POST(p);
1275
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001276 memset(&crtc_state->dpll_hw_state, 0,
1277 sizeof(crtc_state->dpll_hw_state));
1278
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001279 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001280
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001281 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001282 if (pll == NULL) {
1283 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1284 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001285 return false;
1286 }
1287
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001288 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001289 }
1290
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001291 return true;
1292}
1293
Damien Lespiaudc253812015-06-25 16:15:06 +01001294struct skl_wrpll_context {
1295 uint64_t min_deviation; /* current minimal deviation */
1296 uint64_t central_freq; /* chosen central freq */
1297 uint64_t dco_freq; /* chosen dco freq */
1298 unsigned int p; /* chosen divider */
1299};
1300
1301static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1302{
1303 memset(ctx, 0, sizeof(*ctx));
1304
1305 ctx->min_deviation = U64_MAX;
1306}
1307
1308/* DCO freq must be within +1%/-6% of the DCO central freq */
1309#define SKL_DCO_MAX_PDEVIATION 100
1310#define SKL_DCO_MAX_NDEVIATION 600
1311
1312static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1313 uint64_t central_freq,
1314 uint64_t dco_freq,
1315 unsigned int divider)
1316{
1317 uint64_t deviation;
1318
1319 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1320 central_freq);
1321
1322 /* positive deviation */
1323 if (dco_freq >= central_freq) {
1324 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1325 deviation < ctx->min_deviation) {
1326 ctx->min_deviation = deviation;
1327 ctx->central_freq = central_freq;
1328 ctx->dco_freq = dco_freq;
1329 ctx->p = divider;
1330 }
1331 /* negative deviation */
1332 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1333 deviation < ctx->min_deviation) {
1334 ctx->min_deviation = deviation;
1335 ctx->central_freq = central_freq;
1336 ctx->dco_freq = dco_freq;
1337 ctx->p = divider;
1338 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001339}
1340
1341static void skl_wrpll_get_multipliers(unsigned int p,
1342 unsigned int *p0 /* out */,
1343 unsigned int *p1 /* out */,
1344 unsigned int *p2 /* out */)
1345{
1346 /* even dividers */
1347 if (p % 2 == 0) {
1348 unsigned int half = p / 2;
1349
1350 if (half == 1 || half == 2 || half == 3 || half == 5) {
1351 *p0 = 2;
1352 *p1 = 1;
1353 *p2 = half;
1354 } else if (half % 2 == 0) {
1355 *p0 = 2;
1356 *p1 = half / 2;
1357 *p2 = 2;
1358 } else if (half % 3 == 0) {
1359 *p0 = 3;
1360 *p1 = half / 3;
1361 *p2 = 2;
1362 } else if (half % 7 == 0) {
1363 *p0 = 7;
1364 *p1 = half / 7;
1365 *p2 = 2;
1366 }
1367 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1368 *p0 = 3;
1369 *p1 = 1;
1370 *p2 = p / 3;
1371 } else if (p == 5 || p == 7) {
1372 *p0 = p;
1373 *p1 = 1;
1374 *p2 = 1;
1375 } else if (p == 15) {
1376 *p0 = 3;
1377 *p1 = 1;
1378 *p2 = 5;
1379 } else if (p == 21) {
1380 *p0 = 7;
1381 *p1 = 1;
1382 *p2 = 3;
1383 } else if (p == 35) {
1384 *p0 = 7;
1385 *p1 = 1;
1386 *p2 = 5;
1387 }
1388}
1389
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001390struct skl_wrpll_params {
1391 uint32_t dco_fraction;
1392 uint32_t dco_integer;
1393 uint32_t qdiv_ratio;
1394 uint32_t qdiv_mode;
1395 uint32_t kdiv;
1396 uint32_t pdiv;
1397 uint32_t central_freq;
1398};
1399
Damien Lespiau76516fb2015-05-07 18:38:42 +01001400static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1401 uint64_t afe_clock,
1402 uint64_t central_freq,
1403 uint32_t p0, uint32_t p1, uint32_t p2)
1404{
1405 uint64_t dco_freq;
1406
Damien Lespiau76516fb2015-05-07 18:38:42 +01001407 switch (central_freq) {
1408 case 9600000000ULL:
1409 params->central_freq = 0;
1410 break;
1411 case 9000000000ULL:
1412 params->central_freq = 1;
1413 break;
1414 case 8400000000ULL:
1415 params->central_freq = 3;
1416 }
1417
1418 switch (p0) {
1419 case 1:
1420 params->pdiv = 0;
1421 break;
1422 case 2:
1423 params->pdiv = 1;
1424 break;
1425 case 3:
1426 params->pdiv = 2;
1427 break;
1428 case 7:
1429 params->pdiv = 4;
1430 break;
1431 default:
1432 WARN(1, "Incorrect PDiv\n");
1433 }
1434
1435 switch (p2) {
1436 case 5:
1437 params->kdiv = 0;
1438 break;
1439 case 2:
1440 params->kdiv = 1;
1441 break;
1442 case 3:
1443 params->kdiv = 2;
1444 break;
1445 case 1:
1446 params->kdiv = 3;
1447 break;
1448 default:
1449 WARN(1, "Incorrect KDiv\n");
1450 }
1451
1452 params->qdiv_ratio = p1;
1453 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1454
1455 dco_freq = p0 * p1 * p2 * afe_clock;
1456
1457 /*
1458 * Intermediate values are in Hz.
1459 * Divide by MHz to match bsepc
1460 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001461 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001462 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001463 div_u64((div_u64(dco_freq, 24) -
1464 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001465}
1466
Damien Lespiau318bd822015-05-07 18:38:40 +01001467static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001468skl_ddi_calculate_wrpll(int clock /* in Hz */,
1469 struct skl_wrpll_params *wrpll_params)
1470{
1471 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001472 uint64_t dco_central_freq[3] = {8400000000ULL,
1473 9000000000ULL,
1474 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001475 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1476 24, 28, 30, 32, 36, 40, 42, 44,
1477 48, 52, 54, 56, 60, 64, 66, 68,
1478 70, 72, 76, 78, 80, 84, 88, 90,
1479 92, 96, 98 };
1480 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1481 static const struct {
1482 const int *list;
1483 int n_dividers;
1484 } dividers[] = {
1485 { even_dividers, ARRAY_SIZE(even_dividers) },
1486 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1487 };
1488 struct skl_wrpll_context ctx;
1489 unsigned int dco, d, i;
1490 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001491
Damien Lespiaudc253812015-06-25 16:15:06 +01001492 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001493
Damien Lespiaudc253812015-06-25 16:15:06 +01001494 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1495 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1496 for (i = 0; i < dividers[d].n_dividers; i++) {
1497 unsigned int p = dividers[d].list[i];
1498 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001499
Damien Lespiaudc253812015-06-25 16:15:06 +01001500 skl_wrpll_try_divider(&ctx,
1501 dco_central_freq[dco],
1502 dco_freq,
1503 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001504 /*
1505 * Skip the remaining dividers if we're sure to
1506 * have found the definitive divider, we can't
1507 * improve a 0 deviation.
1508 */
1509 if (ctx.min_deviation == 0)
1510 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001511 }
1512 }
Damien Lespiau267db662015-06-25 16:19:24 +01001513
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001514skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001515 /*
1516 * If a solution is found with an even divider, prefer
1517 * this one.
1518 */
1519 if (d == 0 && ctx.p)
1520 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001521 }
1522
Damien Lespiaudc253812015-06-25 16:15:06 +01001523 if (!ctx.p) {
1524 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001525 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001526 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001527
Damien Lespiaudc253812015-06-25 16:15:06 +01001528 /*
1529 * gcc incorrectly analyses that these can be used without being
1530 * initialized. To be fair, it's hard to guess.
1531 */
1532 p0 = p1 = p2 = 0;
1533 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1534 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1535 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001536
Damien Lespiau318bd822015-05-07 18:38:40 +01001537 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001538}
1539
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001540static bool
1541skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001542 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001543 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001544{
1545 struct intel_shared_dpll *pll;
1546 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001547 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001548
1549 /*
1550 * See comment in intel_dpll_hw_state to understand why we always use 0
1551 * as the DPLL id in this function.
1552 */
1553
1554 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1555
1556 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1557 struct skl_wrpll_params wrpll_params = { 0, };
1558
1559 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1560
Damien Lespiau318bd822015-05-07 18:38:40 +01001561 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1562 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001563
1564 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1565 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1566 wrpll_params.dco_integer;
1567
1568 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1569 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1570 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1571 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1572 wrpll_params.central_freq;
1573 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001574 switch (crtc_state->port_clock / 2) {
1575 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001576 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001577 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001578 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001579 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001580 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001581 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001582 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001583 break;
1584 }
1585
1586 cfgcr1 = cfgcr2 = 0;
1587 } else /* eDP */
1588 return true;
1589
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001590 memset(&crtc_state->dpll_hw_state, 0,
1591 sizeof(crtc_state->dpll_hw_state));
1592
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001593 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1594 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1595 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001596
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001597 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001598 if (pll == NULL) {
1599 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1600 pipe_name(intel_crtc->pipe));
1601 return false;
1602 }
1603
1604 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001605 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001606
1607 return true;
1608}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001609
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301610/* bxt clock parameters */
1611struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301612 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301613 uint32_t p1;
1614 uint32_t p2;
1615 uint32_t m2_int;
1616 uint32_t m2_frac;
1617 bool m2_frac_en;
1618 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301619};
1620
1621/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301622static const struct bxt_clk_div bxt_dp_clk_val[] = {
1623 {162000, 4, 2, 32, 1677722, 1, 1},
1624 {270000, 4, 1, 27, 0, 0, 1},
1625 {540000, 2, 1, 27, 0, 0, 1},
1626 {216000, 3, 2, 32, 1677722, 1, 1},
1627 {243000, 4, 1, 24, 1258291, 1, 1},
1628 {324000, 4, 1, 32, 1677722, 1, 1},
1629 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301630};
1631
1632static bool
1633bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1634 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001635 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301636{
1637 struct intel_shared_dpll *pll;
1638 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301639 int vco = 0;
1640 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301641 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001642 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301643
1644 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1645 intel_clock_t best_clock;
1646
1647 /* Calculate HDMI div */
1648 /*
1649 * FIXME: tie the following calculation into
1650 * i9xx_crtc_compute_clock
1651 */
1652 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1653 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1654 clock, pipe_name(intel_crtc->pipe));
1655 return false;
1656 }
1657
1658 clk_div.p1 = best_clock.p1;
1659 clk_div.p2 = best_clock.p2;
1660 WARN_ON(best_clock.m1 != 2);
1661 clk_div.n = best_clock.n;
1662 clk_div.m2_int = best_clock.m2 >> 22;
1663 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1664 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1665
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301666 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301667 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1668 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301669 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301670
Sonika Jindal64987fc2015-05-26 17:50:13 +05301671 clk_div = bxt_dp_clk_val[0];
1672 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1673 if (bxt_dp_clk_val[i].clock == clock) {
1674 clk_div = bxt_dp_clk_val[i];
1675 break;
1676 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301677 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301678 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1679 }
1680
Vandana Kannane6292552015-07-01 17:02:57 +05301681 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301682 prop_coef = 4;
1683 int_coef = 9;
1684 gain_ctl = 3;
1685 targ_cnt = 8;
1686 } else if ((vco > 5400000 && vco < 6200000) ||
1687 (vco >= 4800000 && vco < 5400000)) {
1688 prop_coef = 5;
1689 int_coef = 11;
1690 gain_ctl = 3;
1691 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301692 } else if (vco == 5400000) {
1693 prop_coef = 3;
1694 int_coef = 8;
1695 gain_ctl = 1;
1696 targ_cnt = 9;
1697 } else {
1698 DRM_ERROR("Invalid VCO\n");
1699 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301700 }
1701
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001702 memset(&crtc_state->dpll_hw_state, 0,
1703 sizeof(crtc_state->dpll_hw_state));
1704
Vandana Kannane0681e32015-05-13 12:20:35 +05301705 if (clock > 270000)
1706 lanestagger = 0x18;
1707 else if (clock > 135000)
1708 lanestagger = 0x0d;
1709 else if (clock > 67000)
1710 lanestagger = 0x07;
1711 else if (clock > 33000)
1712 lanestagger = 0x04;
1713 else
1714 lanestagger = 0x02;
1715
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301716 crtc_state->dpll_hw_state.ebb0 =
1717 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1718 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1719 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1720 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1721
1722 if (clk_div.m2_frac_en)
1723 crtc_state->dpll_hw_state.pll3 =
1724 PORT_PLL_M2_FRAC_ENABLE;
1725
1726 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301727 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301728 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301729 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301730
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301731 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1732
Imre Deak05712c12015-06-18 17:25:54 +03001733 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1734
Vandana Kannane6292552015-07-01 17:02:57 +05301735 crtc_state->dpll_hw_state.pll10 =
1736 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1737 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301738
Imre Deak05712c12015-06-18 17:25:54 +03001739 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1740
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301741 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301742 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301743
1744 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1745 if (pll == NULL) {
1746 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1747 pipe_name(intel_crtc->pipe));
1748 return false;
1749 }
1750
1751 /* shared DPLL id 0 is DPLL A */
1752 crtc_state->ddi_pll_sel = pll->id;
1753
1754 return true;
1755}
1756
Damien Lespiau0220ab62014-07-29 18:06:22 +01001757/*
1758 * Tries to find a *shared* PLL for the CRTC and store it in
1759 * intel_crtc->ddi_pll_sel.
1760 *
1761 * For private DPLLs, compute_config() should do the selection for us. This
1762 * function should be folded into compute_config() eventually.
1763 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001764bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1765 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001766{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001767 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001768 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001769 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001770
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001771 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001772 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001773 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301774 else if (IS_BROXTON(dev))
1775 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001776 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001777 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001778 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001779 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001780}
1781
Paulo Zanonidae84792012-10-15 15:51:30 -03001782void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1783{
1784 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1785 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1786 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001787 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001788 int type = intel_encoder->type;
1789 uint32_t temp;
1790
Dave Airlie0e32b392014-05-02 14:02:48 +10001791 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001792 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001793 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001794 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001795 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001796 break;
1797 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001798 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001799 break;
1800 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001801 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001802 break;
1803 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001804 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001805 break;
1806 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001807 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001808 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001809 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001810 }
1811}
1812
Dave Airlie0e32b392014-05-02 14:02:48 +10001813void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1814{
1815 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1816 struct drm_device *dev = crtc->dev;
1817 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001818 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001819 uint32_t temp;
1820 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1821 if (state == true)
1822 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1823 else
1824 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1825 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1826}
1827
Damien Lespiau8228c252013-03-07 15:30:27 +00001828void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001829{
1830 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1831 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001832 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001833 struct drm_device *dev = crtc->dev;
1834 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001835 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001836 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001837 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001838 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001839 uint32_t temp;
1840
Paulo Zanoniad80a812012-10-24 16:06:19 -02001841 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1842 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001843 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001844
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001845 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001846 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001847 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001848 break;
1849 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001850 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001851 break;
1852 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001853 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001854 break;
1855 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001856 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001857 break;
1858 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001859 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001860 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001861
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001862 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001863 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001864 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001865 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c2012-08-08 14:15:28 -03001866
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001867 if (cpu_transcoder == TRANSCODER_EDP) {
1868 switch (pipe) {
1869 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001870 /* On Haswell, can only use the always-on power well for
1871 * eDP when not using the panel fitter, and when not
1872 * using motion blur mitigation (which we don't
1873 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001874 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001875 (intel_crtc->config->pch_pfit.enabled ||
1876 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001877 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1878 else
1879 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001880 break;
1881 case PIPE_B:
1882 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1883 break;
1884 case PIPE_C:
1885 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1886 break;
1887 default:
1888 BUG();
1889 break;
1890 }
1891 }
1892
Paulo Zanoni7739c332012-10-15 15:51:29 -03001893 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001894 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001895 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001896 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001897 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001898
Paulo Zanoni7739c332012-10-15 15:51:29 -03001899 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001900 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001901 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001902
1903 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1904 type == INTEL_OUTPUT_EDP) {
1905 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1906
Dave Airlie0e32b392014-05-02 14:02:48 +10001907 if (intel_dp->is_mst) {
1908 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1909 } else
1910 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1911
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001912 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001913 } else if (type == INTEL_OUTPUT_DP_MST) {
1914 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1915
1916 if (intel_dp->is_mst) {
1917 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1918 } else
1919 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001920
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001921 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001922 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001923 WARN(1, "Invalid encoder type %d for pipe %c\n",
1924 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001925 }
1926
Paulo Zanoniad80a812012-10-24 16:06:19 -02001927 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001928}
1929
Paulo Zanoniad80a812012-10-24 16:06:19 -02001930void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1931 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001932{
Paulo Zanoniad80a812012-10-24 16:06:19 -02001933 uint32_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001934 uint32_t val = I915_READ(reg);
1935
Dave Airlie0e32b392014-05-02 14:02:48 +10001936 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001937 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001938 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001939}
1940
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001941bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1942{
1943 struct drm_device *dev = intel_connector->base.dev;
1944 struct drm_i915_private *dev_priv = dev->dev_private;
1945 struct intel_encoder *intel_encoder = intel_connector->encoder;
1946 int type = intel_connector->base.connector_type;
1947 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1948 enum pipe pipe = 0;
1949 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001950 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001951 uint32_t tmp;
1952
Paulo Zanoni882244a2014-04-01 14:55:12 -03001953 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001954 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001955 return false;
1956
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001957 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1958 return false;
1959
1960 if (port == PORT_A)
1961 cpu_transcoder = TRANSCODER_EDP;
1962 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001963 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001964
1965 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1966
1967 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1968 case TRANS_DDI_MODE_SELECT_HDMI:
1969 case TRANS_DDI_MODE_SELECT_DVI:
1970 return (type == DRM_MODE_CONNECTOR_HDMIA);
1971
1972 case TRANS_DDI_MODE_SELECT_DP_SST:
1973 if (type == DRM_MODE_CONNECTOR_eDP)
1974 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001975 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001976 case TRANS_DDI_MODE_SELECT_DP_MST:
1977 /* if the transcoder is in MST state then
1978 * connector isn't connected */
1979 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001980
1981 case TRANS_DDI_MODE_SELECT_FDI:
1982 return (type == DRM_MODE_CONNECTOR_VGA);
1983
1984 default:
1985 return false;
1986 }
1987}
1988
Daniel Vetter85234cd2012-07-02 13:27:29 +02001989bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1990 enum pipe *pipe)
1991{
1992 struct drm_device *dev = encoder->base.dev;
1993 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001994 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001995 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001996 u32 tmp;
1997 int i;
1998
Imre Deak6d129be2014-03-05 16:20:54 +02001999 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002000 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002001 return false;
2002
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002003 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002004
2005 if (!(tmp & DDI_BUF_CTL_ENABLE))
2006 return false;
2007
Paulo Zanoniad80a812012-10-24 16:06:19 -02002008 if (port == PORT_A) {
2009 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002010
Paulo Zanoniad80a812012-10-24 16:06:19 -02002011 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2012 case TRANS_DDI_EDP_INPUT_A_ON:
2013 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2014 *pipe = PIPE_A;
2015 break;
2016 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2017 *pipe = PIPE_B;
2018 break;
2019 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2020 *pipe = PIPE_C;
2021 break;
2022 }
2023
2024 return true;
2025 } else {
2026 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2027 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2028
2029 if ((tmp & TRANS_DDI_PORT_MASK)
2030 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002031 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2032 return false;
2033
Paulo Zanoniad80a812012-10-24 16:06:19 -02002034 *pipe = i;
2035 return true;
2036 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002037 }
2038 }
2039
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002040 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002041
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002042 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002043}
2044
Paulo Zanonifc914632012-10-05 12:05:54 -03002045void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2046{
2047 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302048 struct drm_device *dev = crtc->dev;
2049 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002050 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2051 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002052 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002053
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002054 if (cpu_transcoder != TRANSCODER_EDP)
2055 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2056 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002057}
2058
2059void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2060{
2061 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002062 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002063
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002064 if (cpu_transcoder != TRANSCODER_EDP)
2065 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2066 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002067}
2068
David Weinehallf8896f52015-06-25 11:11:03 +03002069static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2070 enum port port, int type)
2071{
2072 struct drm_i915_private *dev_priv = dev->dev_private;
2073 const struct ddi_buf_trans *ddi_translations;
2074 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002075 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002076 int n_entries;
2077 u32 reg;
2078
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002079 /* VBT may override standard boost values */
2080 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2081 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2082
David Weinehallf8896f52015-06-25 11:11:03 +03002083 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002084 if (dp_iboost) {
2085 iboost = dp_iboost;
2086 } else {
2087 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
2088 iboost = ddi_translations[port].i_boost;
2089 }
David Weinehallf8896f52015-06-25 11:11:03 +03002090 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002091 if (dp_iboost) {
2092 iboost = dp_iboost;
2093 } else {
2094 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
2095 iboost = ddi_translations[port].i_boost;
2096 }
David Weinehallf8896f52015-06-25 11:11:03 +03002097 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002098 if (hdmi_iboost) {
2099 iboost = hdmi_iboost;
2100 } else {
2101 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
2102 iboost = ddi_translations[port].i_boost;
2103 }
David Weinehallf8896f52015-06-25 11:11:03 +03002104 } else {
2105 return;
2106 }
2107
2108 /* Make sure that the requested I_boost is valid */
2109 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2110 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2111 return;
2112 }
2113
2114 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2115 reg &= ~BALANCE_LEG_MASK(port);
2116 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2117
2118 if (iboost)
2119 reg |= iboost << BALANCE_LEG_SHIFT(port);
2120 else
2121 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2122
2123 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2124}
2125
2126static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2127 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302128{
2129 struct drm_i915_private *dev_priv = dev->dev_private;
2130 const struct bxt_ddi_buf_trans *ddi_translations;
2131 u32 n_entries, i;
2132 uint32_t val;
2133
Sonika Jindald9d70002015-09-24 10:24:56 +05302134 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2135 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2136 ddi_translations = bxt_ddi_translations_edp;
2137 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2138 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302139 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2140 ddi_translations = bxt_ddi_translations_dp;
2141 } else if (type == INTEL_OUTPUT_HDMI) {
2142 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2143 ddi_translations = bxt_ddi_translations_hdmi;
2144 } else {
2145 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2146 type);
2147 return;
2148 }
2149
2150 /* Check if default value has to be used */
2151 if (level >= n_entries ||
2152 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2153 for (i = 0; i < n_entries; i++) {
2154 if (ddi_translations[i].default_index) {
2155 level = i;
2156 break;
2157 }
2158 }
2159 }
2160
2161 /*
2162 * While we write to the group register to program all lanes at once we
2163 * can read only lane registers and we pick lanes 0/1 for that.
2164 */
2165 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2166 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2167 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2168
2169 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2170 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2171 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2172 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2173 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2174
2175 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302176 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302177 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302178 val |= SCALE_DCOMP_METHOD;
2179
2180 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2181 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2182
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302183 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2184
2185 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2186 val &= ~DE_EMPHASIS;
2187 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2188 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2189
2190 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2191 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2192 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2193}
2194
David Weinehallf8896f52015-06-25 11:11:03 +03002195static uint32_t translate_signal_level(int signal_levels)
2196{
2197 uint32_t level;
2198
2199 switch (signal_levels) {
2200 default:
2201 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2202 signal_levels);
2203 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2204 level = 0;
2205 break;
2206 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2207 level = 1;
2208 break;
2209 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2210 level = 2;
2211 break;
2212 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2213 level = 3;
2214 break;
2215
2216 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2217 level = 4;
2218 break;
2219 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2220 level = 5;
2221 break;
2222 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2223 level = 6;
2224 break;
2225
2226 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2227 level = 7;
2228 break;
2229 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2230 level = 8;
2231 break;
2232
2233 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2234 level = 9;
2235 break;
2236 }
2237
2238 return level;
2239}
2240
2241uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2242{
2243 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2244 struct drm_device *dev = dport->base.base.dev;
2245 struct intel_encoder *encoder = &dport->base;
2246 uint8_t train_set = intel_dp->train_set[0];
2247 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2248 DP_TRAIN_PRE_EMPHASIS_MASK);
2249 enum port port = dport->port;
2250 uint32_t level;
2251
2252 level = translate_signal_level(signal_levels);
2253
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002254 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
David Weinehallf8896f52015-06-25 11:11:03 +03002255 skl_ddi_set_iboost(dev, level, port, encoder->type);
2256 else if (IS_BROXTON(dev))
2257 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2258
2259 return DDI_BUF_TRANS_SELECT(level);
2260}
2261
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002262static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002263{
Paulo Zanonic19b0662012-10-15 15:51:41 -03002264 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002265 struct drm_device *dev = encoder->dev;
2266 struct drm_i915_private *dev_priv = dev->dev_private;
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002267 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002268 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002269 int type = intel_encoder->type;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302270 int hdmi_level;
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002271
2272 if (type == INTEL_OUTPUT_EDP) {
2273 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter4be73782014-01-17 14:39:48 +01002274 intel_edp_panel_on(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002275 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002276
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002277 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002278 uint32_t dpll = crtc->config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002279 uint32_t val;
2280
Damien Lespiau5416d872014-11-14 17:24:33 +00002281 /*
2282 * DPLL0 is used for eDP and is the only "private" DPLL (as
2283 * opposed to shared) on SKL
2284 */
2285 if (type == INTEL_OUTPUT_EDP) {
2286 WARN_ON(dpll != SKL_DPLL0);
2287
2288 val = I915_READ(DPLL_CTRL1);
2289
2290 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2291 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002292 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002293 val |= crtc->config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002294
2295 I915_WRITE(DPLL_CTRL1, val);
2296 POSTING_READ(DPLL_CTRL1);
2297 }
2298
2299 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002300 val = I915_READ(DPLL_CTRL2);
2301
2302 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2303 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2304 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2305 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2306
2307 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002308
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302309 } else if (INTEL_INFO(dev)->gen < 9) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002310 WARN_ON(crtc->config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2311 I915_WRITE(PORT_CLK_SEL(port), crtc->config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002312 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03002313
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002314 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002315 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002316
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002317 intel_dp_set_link_params(intel_dp, crtc->config);
2318
Dave Airlie44905a22014-05-02 13:36:43 +10002319 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002320
2321 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2322 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002323 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002324 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002325 } else if (type == INTEL_OUTPUT_HDMI) {
2326 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2327
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302328 if (IS_BROXTON(dev)) {
2329 hdmi_level = dev_priv->vbt.
2330 ddi_port_info[port].hdmi_level_shift;
2331 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2332 INTEL_OUTPUT_HDMI);
2333 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002334 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002335 crtc->config->has_hdmi_sink,
2336 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002337 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002338}
2339
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002340static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002341{
2342 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002343 struct drm_device *dev = encoder->dev;
2344 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002345 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002346 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002347 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002348 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002349
2350 val = I915_READ(DDI_BUF_CTL(port));
2351 if (val & DDI_BUF_CTL_ENABLE) {
2352 val &= ~DDI_BUF_CTL_ENABLE;
2353 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002354 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002355 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002356
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002357 val = I915_READ(DP_TP_CTL(port));
2358 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2359 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2360 I915_WRITE(DP_TP_CTL(port), val);
2361
2362 if (wait)
2363 intel_wait_ddi_buf_idle(dev_priv, port);
2364
Jani Nikula76bb80e2013-11-15 15:29:57 +02002365 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002366 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002367 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002368 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002369 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002370 }
2371
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002372 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002373 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2374 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302375 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002376 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002377}
2378
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002379static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002380{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002381 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002382 struct drm_crtc *crtc = encoder->crtc;
2383 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002384 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002385 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002386 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2387 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002388
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002389 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002390 struct intel_digital_port *intel_dig_port =
2391 enc_to_dig_port(encoder);
2392
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002393 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2394 * are ignored so nothing special needs to be done besides
2395 * enabling the port.
2396 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002397 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002398 intel_dig_port->saved_port_bits |
2399 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002400 } else if (type == INTEL_OUTPUT_EDP) {
2401 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2402
Vandana Kannan23f08d82014-11-13 14:55:22 +00002403 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002404 intel_dp_stop_link_train(intel_dp);
2405
Daniel Vetter4be73782014-01-17 14:39:48 +01002406 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002407 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302408 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002409 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002410
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002411 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002412 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002413 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002414 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002415}
2416
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002417static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002418{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002419 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002420 struct drm_crtc *crtc = encoder->crtc;
2421 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002422 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002423 struct drm_device *dev = encoder->dev;
2424 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002425
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002426 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002427 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002428 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2429 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002430
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002431 if (type == INTEL_OUTPUT_EDP) {
2432 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2433
Vandana Kannanc3955782015-01-22 15:17:40 +05302434 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002435 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002436 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002437 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002438}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002439
Daniel Vettere0b01be2014-06-25 22:02:01 +03002440static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv,
2441 struct intel_shared_dpll *pll)
2442{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002443 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002444 POSTING_READ(WRPLL_CTL(pll->id));
2445 udelay(20);
2446}
2447
Daniel Vetter12030432014-06-25 22:02:00 +03002448static void hsw_ddi_pll_disable(struct drm_i915_private *dev_priv,
2449 struct intel_shared_dpll *pll)
2450{
2451 uint32_t val;
2452
2453 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002454 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2455 POSTING_READ(WRPLL_CTL(pll->id));
2456}
2457
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002458static bool hsw_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2459 struct intel_shared_dpll *pll,
2460 struct intel_dpll_hw_state *hw_state)
2461{
2462 uint32_t val;
2463
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002464 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002465 return false;
2466
2467 val = I915_READ(WRPLL_CTL(pll->id));
2468 hw_state->wrpll = val;
2469
2470 return val & WRPLL_PLL_ENABLE;
2471}
2472
Damien Lespiauca1381b2014-07-15 15:05:33 +01002473static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002474 "WRPLL 1",
2475 "WRPLL 2",
2476};
2477
Damien Lespiau143b3072014-07-29 18:06:19 +01002478static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002479{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002480 int i;
2481
Daniel Vetter716c2e52014-06-25 22:02:02 +03002482 dev_priv->num_shared_dpll = 2;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002483
Daniel Vetter716c2e52014-06-25 22:02:02 +03002484 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002485 dev_priv->shared_dplls[i].id = i;
2486 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Daniel Vetter12030432014-06-25 22:02:00 +03002487 dev_priv->shared_dplls[i].disable = hsw_ddi_pll_disable;
Daniel Vettere0b01be2014-06-25 22:02:01 +03002488 dev_priv->shared_dplls[i].enable = hsw_ddi_pll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002489 dev_priv->shared_dplls[i].get_hw_state =
2490 hsw_ddi_pll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002491 }
Damien Lespiau143b3072014-07-29 18:06:19 +01002492}
2493
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002494static const char * const skl_ddi_pll_names[] = {
2495 "DPLL 1",
2496 "DPLL 2",
2497 "DPLL 3",
2498};
2499
2500struct skl_dpll_regs {
2501 u32 ctl, cfgcr1, cfgcr2;
2502};
2503
2504/* this array is indexed by the *shared* pll id */
2505static const struct skl_dpll_regs skl_dpll_regs[3] = {
2506 {
2507 /* DPLL 1 */
2508 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002509 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2510 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002511 },
2512 {
2513 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002514 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002515 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2516 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002517 },
2518 {
2519 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002520 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002521 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2522 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002523 },
2524};
2525
2526static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2527 struct intel_shared_dpll *pll)
2528{
2529 uint32_t val;
2530 unsigned int dpll;
2531 const struct skl_dpll_regs *regs = skl_dpll_regs;
2532
2533 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2534 dpll = pll->id + 1;
2535
2536 val = I915_READ(DPLL_CTRL1);
2537
2538 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002539 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002540 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2541
2542 I915_WRITE(DPLL_CTRL1, val);
2543 POSTING_READ(DPLL_CTRL1);
2544
2545 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2546 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2547 POSTING_READ(regs[pll->id].cfgcr1);
2548 POSTING_READ(regs[pll->id].cfgcr2);
2549
2550 /* the enable bit is always bit 31 */
2551 I915_WRITE(regs[pll->id].ctl,
2552 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2553
2554 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2555 DRM_ERROR("DPLL %d not locked\n", dpll);
2556}
2557
2558static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2559 struct intel_shared_dpll *pll)
2560{
2561 const struct skl_dpll_regs *regs = skl_dpll_regs;
2562
2563 /* the enable bit is always bit 31 */
2564 I915_WRITE(regs[pll->id].ctl,
2565 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2566 POSTING_READ(regs[pll->id].ctl);
2567}
2568
2569static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2570 struct intel_shared_dpll *pll,
2571 struct intel_dpll_hw_state *hw_state)
2572{
2573 uint32_t val;
2574 unsigned int dpll;
2575 const struct skl_dpll_regs *regs = skl_dpll_regs;
2576
2577 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2578 return false;
2579
2580 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2581 dpll = pll->id + 1;
2582
2583 val = I915_READ(regs[pll->id].ctl);
2584 if (!(val & LCPLL_PLL_ENABLE))
2585 return false;
2586
2587 val = I915_READ(DPLL_CTRL1);
2588 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2589
2590 /* avoid reading back stale values if HDMI mode is not enabled */
2591 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2592 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2593 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2594 }
2595
2596 return true;
2597}
2598
2599static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2600{
2601 int i;
2602
2603 dev_priv->num_shared_dpll = 3;
2604
2605 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2606 dev_priv->shared_dplls[i].id = i;
2607 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2608 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2609 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2610 dev_priv->shared_dplls[i].get_hw_state =
2611 skl_ddi_pll_get_hw_state;
2612 }
2613}
2614
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302615static void broxton_phy_init(struct drm_i915_private *dev_priv,
2616 enum dpio_phy phy)
2617{
2618 enum port port;
2619 uint32_t val;
2620
2621 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2622 val |= GT_DISPLAY_POWER_ON(phy);
2623 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2624
2625 /* Considering 10ms timeout until BSpec is updated */
2626 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2627 DRM_ERROR("timeout during PHY%d power on\n", phy);
2628
2629 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2630 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2631 int lane;
2632
2633 for (lane = 0; lane < 4; lane++) {
2634 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2635 /*
2636 * Note that on CHV this flag is called UPAR, but has
2637 * the same function.
2638 */
2639 val &= ~LATENCY_OPTIM;
2640 if (lane != 1)
2641 val |= LATENCY_OPTIM;
2642
2643 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2644 }
2645 }
2646
2647 /* Program PLL Rcomp code offset */
2648 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2649 val &= ~IREF0RC_OFFSET_MASK;
2650 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2651 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2652
2653 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2654 val &= ~IREF1RC_OFFSET_MASK;
2655 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2656 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2657
2658 /* Program power gating */
2659 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2660 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2661 SUS_CLK_CONFIG;
2662 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2663
2664 if (phy == DPIO_PHY0) {
2665 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2666 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2667 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2668 }
2669
2670 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2671 val &= ~OCL2_LDOFUSE_PWR_DIS;
2672 /*
2673 * On PHY1 disable power on the second channel, since no port is
2674 * connected there. On PHY0 both channels have a port, so leave it
2675 * enabled.
2676 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2677 * power down the second channel on PHY0 as well.
2678 */
2679 if (phy == DPIO_PHY1)
2680 val |= OCL2_LDOFUSE_PWR_DIS;
2681 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2682
2683 if (phy == DPIO_PHY0) {
2684 uint32_t grc_code;
2685 /*
2686 * PHY0 isn't connected to an RCOMP resistor so copy over
2687 * the corresponding calibrated value from PHY1, and disable
2688 * the automatic calibration on PHY0.
2689 */
2690 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2691 10))
2692 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2693
2694 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2695 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2696 grc_code = val << GRC_CODE_FAST_SHIFT |
2697 val << GRC_CODE_SLOW_SHIFT |
2698 val;
2699 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2700
2701 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2702 val |= GRC_DIS | GRC_RDY_OVRD;
2703 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2704 }
2705
2706 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2707 val |= COMMON_RESET_DIS;
2708 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2709}
2710
2711void broxton_ddi_phy_init(struct drm_device *dev)
2712{
2713 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2714 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2715 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2716}
2717
2718static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2719 enum dpio_phy phy)
2720{
2721 uint32_t val;
2722
2723 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2724 val &= ~COMMON_RESET_DIS;
2725 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2726}
2727
2728void broxton_ddi_phy_uninit(struct drm_device *dev)
2729{
2730 struct drm_i915_private *dev_priv = dev->dev_private;
2731
2732 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2733 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2734
2735 /* FIXME: do this in broxton_phy_uninit per phy */
2736 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2737}
2738
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302739static const char * const bxt_ddi_pll_names[] = {
2740 "PORT PLL A",
2741 "PORT PLL B",
2742 "PORT PLL C",
2743};
2744
2745static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2746 struct intel_shared_dpll *pll)
2747{
2748 uint32_t temp;
2749 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2750
2751 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2752 temp &= ~PORT_PLL_REF_SEL;
2753 /* Non-SSC reference */
2754 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2755
2756 /* Disable 10 bit clock */
2757 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2758 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2759 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2760
2761 /* Write P1 & P2 */
2762 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2763 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2764 temp |= pll->config.hw_state.ebb0;
2765 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2766
2767 /* Write M2 integer */
2768 temp = I915_READ(BXT_PORT_PLL(port, 0));
2769 temp &= ~PORT_PLL_M2_MASK;
2770 temp |= pll->config.hw_state.pll0;
2771 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2772
2773 /* Write N */
2774 temp = I915_READ(BXT_PORT_PLL(port, 1));
2775 temp &= ~PORT_PLL_N_MASK;
2776 temp |= pll->config.hw_state.pll1;
2777 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2778
2779 /* Write M2 fraction */
2780 temp = I915_READ(BXT_PORT_PLL(port, 2));
2781 temp &= ~PORT_PLL_M2_FRAC_MASK;
2782 temp |= pll->config.hw_state.pll2;
2783 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2784
2785 /* Write M2 fraction enable */
2786 temp = I915_READ(BXT_PORT_PLL(port, 3));
2787 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2788 temp |= pll->config.hw_state.pll3;
2789 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2790
2791 /* Write coeff */
2792 temp = I915_READ(BXT_PORT_PLL(port, 6));
2793 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2794 temp &= ~PORT_PLL_INT_COEFF_MASK;
2795 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2796 temp |= pll->config.hw_state.pll6;
2797 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2798
2799 /* Write calibration val */
2800 temp = I915_READ(BXT_PORT_PLL(port, 8));
2801 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2802 temp |= pll->config.hw_state.pll8;
2803 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2804
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302805 temp = I915_READ(BXT_PORT_PLL(port, 9));
2806 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002807 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302808 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2809
2810 temp = I915_READ(BXT_PORT_PLL(port, 10));
2811 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2812 temp &= ~PORT_PLL_DCO_AMP_MASK;
2813 temp |= pll->config.hw_state.pll10;
2814 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302815
2816 /* Recalibrate with new settings */
2817 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2818 temp |= PORT_PLL_RECALIBRATE;
2819 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002820 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2821 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302822 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2823
2824 /* Enable PLL */
2825 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2826 temp |= PORT_PLL_ENABLE;
2827 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2828 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2829
2830 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2831 PORT_PLL_LOCK), 200))
2832 DRM_ERROR("PLL %d not locked\n", port);
2833
2834 /*
2835 * While we write to the group register to program all lanes at once we
2836 * can read only lane registers and we pick lanes 0/1 for that.
2837 */
2838 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2839 temp &= ~LANE_STAGGER_MASK;
2840 temp &= ~LANESTAGGER_STRAP_OVRD;
2841 temp |= pll->config.hw_state.pcsdw12;
2842 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2843}
2844
2845static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2846 struct intel_shared_dpll *pll)
2847{
2848 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2849 uint32_t temp;
2850
2851 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2852 temp &= ~PORT_PLL_ENABLE;
2853 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2854 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2855}
2856
2857static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2858 struct intel_shared_dpll *pll,
2859 struct intel_dpll_hw_state *hw_state)
2860{
2861 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2862 uint32_t val;
2863
2864 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2865 return false;
2866
2867 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2868 if (!(val & PORT_PLL_ENABLE))
2869 return false;
2870
2871 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002872 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2873
Imre Deak05712c12015-06-18 17:25:54 +03002874 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2875 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2876
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302877 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002878 hw_state->pll0 &= PORT_PLL_M2_MASK;
2879
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302880 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002881 hw_state->pll1 &= PORT_PLL_N_MASK;
2882
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302883 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002884 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2885
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302886 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002887 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2888
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302889 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002890 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2891 PORT_PLL_INT_COEFF_MASK |
2892 PORT_PLL_GAIN_CTL_MASK;
2893
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302894 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002895 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2896
Imre Deak05712c12015-06-18 17:25:54 +03002897 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2898 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2899
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302900 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002901 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2902 PORT_PLL_DCO_AMP_MASK;
2903
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302904 /*
2905 * While we write to the group register to program all lanes at once we
2906 * can read only lane registers. We configure all lanes the same way, so
2907 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2908 */
2909 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002910 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302911 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2912 hw_state->pcsdw12,
2913 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002914 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302915
2916 return true;
2917}
2918
2919static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2920{
2921 int i;
2922
2923 dev_priv->num_shared_dpll = 3;
2924
2925 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2926 dev_priv->shared_dplls[i].id = i;
2927 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2928 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2929 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2930 dev_priv->shared_dplls[i].get_hw_state =
2931 bxt_ddi_pll_get_hw_state;
2932 }
2933}
2934
Damien Lespiau143b3072014-07-29 18:06:19 +01002935void intel_ddi_pll_init(struct drm_device *dev)
2936{
2937 struct drm_i915_private *dev_priv = dev->dev_private;
2938 uint32_t val = I915_READ(LCPLL_CTL);
2939
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002940 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002941 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302942 else if (IS_BROXTON(dev))
2943 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002944 else
2945 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002946
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002947 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002948 int cdclk_freq;
2949
2950 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002951 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05302952 if (skl_sanitize_cdclk(dev_priv))
2953 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002954 else
2955 intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS);
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302956 } else if (IS_BROXTON(dev)) {
2957 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302958 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002959 } else {
2960 /*
2961 * The LCPLL register should be turned on by the BIOS. For now
2962 * let's just check its state and print errors in case
2963 * something is wrong. Don't even try to turn it on.
2964 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002965
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002966 if (val & LCPLL_CD_SOURCE_FCLK)
2967 DRM_ERROR("CDCLK source is not LCPLL\n");
2968
2969 if (val & LCPLL_PLL_DISABLE)
2970 DRM_ERROR("LCPLL is disabled\n");
2971 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002972}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002973
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002974void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03002975{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002976 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
2977 struct drm_i915_private *dev_priv =
2978 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02002979 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002980 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302981 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002982
2983 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2984 val = I915_READ(DDI_BUF_CTL(port));
2985 if (val & DDI_BUF_CTL_ENABLE) {
2986 val &= ~DDI_BUF_CTL_ENABLE;
2987 I915_WRITE(DDI_BUF_CTL(port), val);
2988 wait = true;
2989 }
2990
2991 val = I915_READ(DP_TP_CTL(port));
2992 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2993 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2994 I915_WRITE(DP_TP_CTL(port), val);
2995 POSTING_READ(DP_TP_CTL(port));
2996
2997 if (wait)
2998 intel_wait_ddi_buf_idle(dev_priv, port);
2999 }
3000
Dave Airlie0e32b392014-05-02 14:02:48 +10003001 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003002 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003003 if (intel_dp->is_mst)
3004 val |= DP_TP_CTL_MODE_MST;
3005 else {
3006 val |= DP_TP_CTL_MODE_SST;
3007 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3008 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3009 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003010 I915_WRITE(DP_TP_CTL(port), val);
3011 POSTING_READ(DP_TP_CTL(port));
3012
3013 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3014 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3015 POSTING_READ(DDI_BUF_CTL(port));
3016
3017 udelay(600);
3018}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003019
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003020void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3021{
3022 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3023 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3024 uint32_t val;
3025
3026 intel_ddi_post_disable(intel_encoder);
3027
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003028 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003029 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003030 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003031
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003032 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003033 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3034 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003035 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003036
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003037 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003038 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003039 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003040
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003041 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003042 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003043 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003044}
3045
Ville Syrjälä6801c182013-09-24 14:24:05 +03003046void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003047 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003048{
3049 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3050 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003051 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003052 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003053 u32 temp, flags = 0;
3054
3055 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3056 if (temp & TRANS_DDI_PHSYNC)
3057 flags |= DRM_MODE_FLAG_PHSYNC;
3058 else
3059 flags |= DRM_MODE_FLAG_NHSYNC;
3060 if (temp & TRANS_DDI_PVSYNC)
3061 flags |= DRM_MODE_FLAG_PVSYNC;
3062 else
3063 flags |= DRM_MODE_FLAG_NVSYNC;
3064
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003065 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003066
3067 switch (temp & TRANS_DDI_BPC_MASK) {
3068 case TRANS_DDI_BPC_6:
3069 pipe_config->pipe_bpp = 18;
3070 break;
3071 case TRANS_DDI_BPC_8:
3072 pipe_config->pipe_bpp = 24;
3073 break;
3074 case TRANS_DDI_BPC_10:
3075 pipe_config->pipe_bpp = 30;
3076 break;
3077 case TRANS_DDI_BPC_12:
3078 pipe_config->pipe_bpp = 36;
3079 break;
3080 default:
3081 break;
3082 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003083
3084 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3085 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003086 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003087 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3088
3089 if (intel_hdmi->infoframe_enabled(&encoder->base))
3090 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003091 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003092 case TRANS_DDI_MODE_SELECT_DVI:
3093 case TRANS_DDI_MODE_SELECT_FDI:
3094 break;
3095 case TRANS_DDI_MODE_SELECT_DP_SST:
3096 case TRANS_DDI_MODE_SELECT_DP_MST:
3097 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003098 pipe_config->lane_count =
3099 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003100 intel_dp_get_m_n(intel_crtc, pipe_config);
3101 break;
3102 default:
3103 break;
3104 }
Daniel Vetter10214422013-11-18 07:38:16 +01003105
Daniel Vetterf458ebb2014-09-30 10:56:39 +02003106 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Paulo Zanonia60551b2014-05-21 16:23:20 -03003107 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Jani Nikula82910ac2014-10-27 16:26:59 +02003108 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
Paulo Zanonia60551b2014-05-21 16:23:20 -03003109 pipe_config->has_audio = true;
3110 }
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003111
Daniel Vetter10214422013-11-18 07:38:16 +01003112 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3113 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3114 /*
3115 * This is a big fat ugly hack.
3116 *
3117 * Some machines in UEFI boot mode provide us a VBT that has 18
3118 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3119 * unknown we fail to light up. Yet the same BIOS boots up with
3120 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3121 * max, not what it tells us to use.
3122 *
3123 * Note: This will still be broken if the eDP panel is not lit
3124 * up by the BIOS, and thus we can't get the mode at module
3125 * load.
3126 */
3127 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3128 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3129 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3130 }
Jesse Barnes11578552014-01-21 12:42:10 -08003131
Damien Lespiau22606a12014-12-12 14:26:57 +00003132 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003133}
3134
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003135static void intel_ddi_destroy(struct drm_encoder *encoder)
3136{
3137 /* HDMI has nothing special to destroy, so we can go with this. */
3138 intel_dp_encoder_destroy(encoder);
3139}
3140
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003141static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003142 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003143{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003144 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003145 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003146
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003147 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003148
Daniel Vettereccb1402013-05-22 00:50:22 +02003149 if (port == PORT_A)
3150 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3151
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003152 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003153 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003154 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003155 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003156}
3157
3158static const struct drm_encoder_funcs intel_ddi_funcs = {
3159 .destroy = intel_ddi_destroy,
3160};
3161
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003162static struct intel_connector *
3163intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3164{
3165 struct intel_connector *connector;
3166 enum port port = intel_dig_port->port;
3167
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003168 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003169 if (!connector)
3170 return NULL;
3171
3172 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3173 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3174 kfree(connector);
3175 return NULL;
3176 }
3177
3178 return connector;
3179}
3180
3181static struct intel_connector *
3182intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3183{
3184 struct intel_connector *connector;
3185 enum port port = intel_dig_port->port;
3186
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003187 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003188 if (!connector)
3189 return NULL;
3190
3191 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3192 intel_hdmi_init_connector(intel_dig_port, connector);
3193
3194 return connector;
3195}
3196
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003197void intel_ddi_init(struct drm_device *dev, enum port port)
3198{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003199 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003200 struct intel_digital_port *intel_dig_port;
3201 struct intel_encoder *intel_encoder;
3202 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003203 bool init_hdmi, init_dp;
3204
3205 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3206 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3207 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3208 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003209 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003210 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003211 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003212 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003213
Daniel Vetterb14c5672013-09-19 12:18:32 +02003214 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003215 if (!intel_dig_port)
3216 return;
3217
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003218 intel_encoder = &intel_dig_port->base;
3219 encoder = &intel_encoder->base;
3220
3221 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3222 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003223
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003224 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003225 intel_encoder->enable = intel_enable_ddi;
3226 intel_encoder->pre_enable = intel_ddi_pre_enable;
3227 intel_encoder->disable = intel_disable_ddi;
3228 intel_encoder->post_disable = intel_ddi_post_disable;
3229 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003230 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003231
3232 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003233 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3234 (DDI_BUF_PORT_REVERSAL |
3235 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003236
3237 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003238 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003239 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003240
Chris Wilsonf68d6972014-08-04 07:15:09 +01003241 if (init_dp) {
3242 if (!intel_ddi_init_dp_connector(intel_dig_port))
3243 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003244
Chris Wilsonf68d6972014-08-04 07:15:09 +01003245 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303246 /*
3247 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3248 * interrupts to check the external panel connection.
3249 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003250 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303251 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3252 else
3253 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003254 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003255
Paulo Zanoni311a2092013-09-12 17:12:18 -03003256 /* In theory we don't need the encoder->type check, but leave it just in
3257 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003258 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3259 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3260 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003261 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003262
3263 return;
3264
3265err:
3266 drm_encoder_cleanup(encoder);
3267 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003268}