blob: 3b57bf06abe8598c1c3b6fba0dc8e19b7f192619 [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 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800136 { 0x80009010, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300137 { 0x00002016, 0x0000009B, 0x0 },
138 { 0x00005012, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800139 { 0x80007011, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300140 { 0x00002016, 0x000000DF, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800141 { 0x80005012, 0x000000C0, 0x1 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000142};
143
David Weinehallf8896f52015-06-25 11:11:03 +0300144/* Skylake U */
145static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700146 { 0x0000201B, 0x000000A2, 0x0 },
David Weinehallf8896f52015-06-25 11:11:03 +0300147 { 0x00005012, 0x00000088, 0x0 },
Rodrigo Vivi63ebce12016-01-05 07:58:31 -0800148 { 0x80007011, 0x000000CD, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800149 { 0x80009010, 0x000000C0, 0x1 },
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700150 { 0x0000201B, 0x0000009D, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800151 { 0x80005012, 0x000000C0, 0x1 },
152 { 0x80007011, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300153 { 0x00002016, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800154 { 0x80005012, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300155};
156
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700157/* Skylake Y */
158static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300159 { 0x00000018, 0x000000A2, 0x0 },
160 { 0x00005012, 0x00000088, 0x0 },
Rodrigo Vivi63ebce12016-01-05 07:58:31 -0800161 { 0x80007011, 0x000000CD, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800162 { 0x80009010, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300163 { 0x00000018, 0x0000009D, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800164 { 0x80005012, 0x000000C0, 0x3 },
165 { 0x80007011, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300166 { 0x00000018, 0x00000088, 0x0 },
Rodrigo Vivid7097cf2016-01-05 11:18:55 -0800167 { 0x80005012, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300168};
169
170/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700171 * Skylake H and S
David Weinehallf8896f52015-06-25 11:11:03 +0300172 * eDP 1.4 low vswing translation parameters
173 */
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530174static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300175 { 0x00000018, 0x000000A8, 0x0 },
176 { 0x00004013, 0x000000A9, 0x0 },
177 { 0x00007011, 0x000000A2, 0x0 },
178 { 0x00009010, 0x0000009C, 0x0 },
179 { 0x00000018, 0x000000A9, 0x0 },
180 { 0x00006013, 0x000000A2, 0x0 },
181 { 0x00007011, 0x000000A6, 0x0 },
182 { 0x00000018, 0x000000AB, 0x0 },
183 { 0x00007013, 0x0000009F, 0x0 },
184 { 0x00000018, 0x000000DF, 0x0 },
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530185};
186
David Weinehallf8896f52015-06-25 11:11:03 +0300187/*
188 * Skylake U
189 * eDP 1.4 low vswing translation parameters
190 */
191static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
192 { 0x00000018, 0x000000A8, 0x0 },
193 { 0x00004013, 0x000000A9, 0x0 },
194 { 0x00007011, 0x000000A2, 0x0 },
195 { 0x00009010, 0x0000009C, 0x0 },
196 { 0x00000018, 0x000000A9, 0x0 },
197 { 0x00006013, 0x000000A2, 0x0 },
198 { 0x00007011, 0x000000A6, 0x0 },
199 { 0x00002016, 0x000000AB, 0x0 },
200 { 0x00005013, 0x0000009F, 0x0 },
201 { 0x00000018, 0x000000DF, 0x0 },
202};
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530203
David Weinehallf8896f52015-06-25 11:11:03 +0300204/*
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700205 * Skylake Y
David Weinehallf8896f52015-06-25 11:11:03 +0300206 * eDP 1.4 low vswing translation parameters
207 */
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700208static const struct ddi_buf_trans skl_y_ddi_translations_edp[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300209 { 0x00000018, 0x000000A8, 0x0 },
210 { 0x00004013, 0x000000AB, 0x0 },
211 { 0x00007011, 0x000000A4, 0x0 },
212 { 0x00009010, 0x000000DF, 0x0 },
213 { 0x00000018, 0x000000AA, 0x0 },
214 { 0x00006013, 0x000000A4, 0x0 },
215 { 0x00007011, 0x0000009D, 0x0 },
216 { 0x00000018, 0x000000A0, 0x0 },
217 { 0x00006012, 0x000000DF, 0x0 },
218 { 0x00000018, 0x0000008A, 0x0 },
219};
220
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700221/* Skylake U, H and S */
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000222static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300223 { 0x00000018, 0x000000AC, 0x0 },
224 { 0x00005012, 0x0000009D, 0x0 },
225 { 0x00007011, 0x00000088, 0x0 },
226 { 0x00000018, 0x000000A1, 0x0 },
227 { 0x00000018, 0x00000098, 0x0 },
228 { 0x00004013, 0x00000088, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800229 { 0x80006012, 0x000000CD, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300230 { 0x00000018, 0x000000DF, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800231 { 0x80003015, 0x000000CD, 0x1 }, /* Default */
232 { 0x80003015, 0x000000C0, 0x1 },
233 { 0x80000018, 0x000000C0, 0x1 },
David Weinehallf8896f52015-06-25 11:11:03 +0300234};
235
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700236/* Skylake Y */
237static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = {
David Weinehallf8896f52015-06-25 11:11:03 +0300238 { 0x00000018, 0x000000A1, 0x0 },
239 { 0x00005012, 0x000000DF, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800240 { 0x80007011, 0x000000CB, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300241 { 0x00000018, 0x000000A4, 0x0 },
242 { 0x00000018, 0x0000009D, 0x0 },
243 { 0x00004013, 0x00000080, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800244 { 0x80006013, 0x000000C0, 0x3 },
David Weinehallf8896f52015-06-25 11:11:03 +0300245 { 0x00000018, 0x0000008A, 0x0 },
Rodrigo Vivi2e784162016-01-05 11:11:27 -0800246 { 0x80003015, 0x000000C0, 0x3 }, /* Default */
247 { 0x80003015, 0x000000C0, 0x3 },
248 { 0x80000018, 0x000000C0, 0x3 },
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000249};
250
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530251struct bxt_ddi_buf_trans {
252 u32 margin; /* swing value */
253 u32 scale; /* scale value */
254 u32 enable; /* scale enable */
255 u32 deemphasis;
256 bool default_index; /* true if the entry represents default value */
257};
258
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530259static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
260 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300261 { 52, 0x9A, 0, 128, true }, /* 0: 400 0 */
262 { 78, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
263 { 104, 0x9A, 0, 64, false }, /* 2: 400 6 */
264 { 154, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
265 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
266 { 116, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
267 { 154, 0x9A, 0, 64, false }, /* 6: 600 6 */
268 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
269 { 154, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
David Weinehallf8896f52015-06-25 11:11:03 +0300270 { 154, 0x9A, 1, 128, false }, /* 9: 1200 0 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530271};
272
Sonika Jindald9d70002015-09-24 10:24:56 +0530273static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = {
274 /* Idx NT mV diff db */
275 { 26, 0, 0, 128, false }, /* 0: 200 0 */
276 { 38, 0, 0, 112, false }, /* 1: 200 1.5 */
277 { 48, 0, 0, 96, false }, /* 2: 200 4 */
278 { 54, 0, 0, 69, false }, /* 3: 200 6 */
279 { 32, 0, 0, 128, false }, /* 4: 250 0 */
280 { 48, 0, 0, 104, false }, /* 5: 250 1.5 */
281 { 54, 0, 0, 85, false }, /* 6: 250 4 */
282 { 43, 0, 0, 128, false }, /* 7: 300 0 */
283 { 54, 0, 0, 101, false }, /* 8: 300 1.5 */
284 { 48, 0, 0, 128, false }, /* 9: 300 0 */
285};
286
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530287/* BSpec has 2 recommended values - entries 0 and 8.
288 * Using the entry with higher vswing.
289 */
290static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
291 /* Idx NT mV diff db */
Imre Deakfe4c63c2015-06-04 18:01:35 +0300292 { 52, 0x9A, 0, 128, false }, /* 0: 400 0 */
293 { 52, 0x9A, 0, 85, false }, /* 1: 400 3.5 */
294 { 52, 0x9A, 0, 64, false }, /* 2: 400 6 */
295 { 42, 0x9A, 0, 43, false }, /* 3: 400 9.5 */
296 { 77, 0x9A, 0, 128, false }, /* 4: 600 0 */
297 { 77, 0x9A, 0, 85, false }, /* 5: 600 3.5 */
298 { 77, 0x9A, 0, 64, false }, /* 6: 600 6 */
299 { 102, 0x9A, 0, 128, false }, /* 7: 800 0 */
300 { 102, 0x9A, 0, 85, false }, /* 8: 800 3.5 */
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530301 { 154, 0x9A, 1, 128, true }, /* 9: 1200 0 */
302};
303
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200304static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
305 u32 level, enum port port, int type);
David Weinehallf8896f52015-06-25 11:11:03 +0300306
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
Ville Syrjäläacee2992015-12-08 19:59:39 +0200345static const struct ddi_buf_trans *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200346skl_get_buf_trans_dp(struct drm_i915_private *dev_priv, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300347{
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200348 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700349 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200350 return skl_y_ddi_translations_dp;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200351 } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300352 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200353 return skl_u_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300354 } else {
David Weinehallf8896f52015-06-25 11:11:03 +0300355 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200356 return skl_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300357 }
David Weinehallf8896f52015-06-25 11:11:03 +0300358}
359
360static const struct ddi_buf_trans *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200361skl_get_buf_trans_edp(struct drm_i915_private *dev_priv, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300362{
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200363 if (dev_priv->edp_low_vswing) {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200364 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200365 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
366 return skl_y_ddi_translations_edp;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200367 } else if (IS_SKL_ULT(dev_priv) || IS_KBL_ULT(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200368 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
369 return skl_u_ddi_translations_edp;
370 } else {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200371 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
372 return skl_ddi_translations_edp;
Ville Syrjäläacee2992015-12-08 19:59:39 +0200373 }
David Weinehallf8896f52015-06-25 11:11:03 +0300374 }
Ville Syrjäläcd1101c2015-12-08 19:59:40 +0200375
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200376 return skl_get_buf_trans_dp(dev_priv, n_entries);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200377}
David Weinehallf8896f52015-06-25 11:11:03 +0300378
Ville Syrjäläacee2992015-12-08 19:59:39 +0200379static const struct ddi_buf_trans *
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200380skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
Ville Syrjäläacee2992015-12-08 19:59:39 +0200381{
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200382 if (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200383 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
384 return skl_y_ddi_translations_hdmi;
385 } else {
386 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
387 return skl_ddi_translations_hdmi;
388 }
David Weinehallf8896f52015-06-25 11:11:03 +0300389}
390
Art Runyane58623c2013-11-02 21:07:41 -0700391/*
392 * Starting with Haswell, DDI port buffers must be programmed with correct
393 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300394 * but the HDMI/DVI fields are shared among those. So we program the DDI
395 * in either FDI or DP modes only, as HDMI connections will work with both
396 * of those
397 */
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200398void intel_prepare_ddi_buffer(struct intel_encoder *encoder)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300399{
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200400 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300401 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000402 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530403 size;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200404 int hdmi_level;
405 enum port port;
Jani Nikula10122052014-08-27 16:27:30 +0300406 const struct ddi_buf_trans *ddi_translations_fdi;
407 const struct ddi_buf_trans *ddi_translations_dp;
408 const struct ddi_buf_trans *ddi_translations_edp;
409 const struct ddi_buf_trans *ddi_translations_hdmi;
410 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700411
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200412 port = intel_ddi_get_encoder_port(encoder);
413 hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
414
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200415 if (IS_BROXTON(dev_priv)) {
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200416 if (encoder->type != INTEL_OUTPUT_HDMI)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530417 return;
418
419 /* Vswing programming for HDMI */
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200420 bxt_ddi_vswing_sequence(dev_priv, hdmi_level, port,
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530421 INTEL_OUTPUT_HDMI);
422 return;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200423 }
424
425 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300426 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300427 ddi_translations_dp =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200428 skl_get_buf_trans_dp(dev_priv, &n_dp_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300429 ddi_translations_edp =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200430 skl_get_buf_trans_edp(dev_priv, &n_edp_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300431 ddi_translations_hdmi =
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200432 skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries);
David Weinehallf8896f52015-06-25 11:11:03 +0300433 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300434 /* If we're boosting the current, set bit 31 of trans1 */
435 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
436 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
437 iboost_bit = 1<<31;
Ville Syrjälä10afa0b2015-12-08 19:59:43 +0200438
Ville Syrjäläceccad52016-01-12 17:28:16 +0200439 if (WARN_ON(encoder->type == INTEL_OUTPUT_EDP &&
440 port != PORT_A && port != PORT_E &&
441 n_edp_entries > 9))
Ville Syrjälä10afa0b2015-12-08 19:59:43 +0200442 n_edp_entries = 9;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200443 } else if (IS_BROADWELL(dev_priv)) {
Art Runyane58623c2013-11-02 21:07:41 -0700444 ddi_translations_fdi = bdw_ddi_translations_fdi;
445 ddi_translations_dp = bdw_ddi_translations_dp;
Mika Kahola992e7a42016-04-20 15:39:02 +0300446
447 if (dev_priv->edp_low_vswing) {
448 ddi_translations_edp = bdw_ddi_translations_edp;
449 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
450 } else {
451 ddi_translations_edp = bdw_ddi_translations_dp;
452 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
453 }
454
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100455 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Mika Kahola992e7a42016-04-20 15:39:02 +0300456
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530457 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300458 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000459 hdmi_default_entry = 7;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200460 } else if (IS_HASWELL(dev_priv)) {
Art Runyane58623c2013-11-02 21:07:41 -0700461 ddi_translations_fdi = hsw_ddi_translations_fdi;
462 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700463 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100464 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530465 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300466 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000467 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700468 } else {
469 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700470 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700471 ddi_translations_fdi = bdw_ddi_translations_fdi;
472 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100473 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530474 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
475 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300476 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000477 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700478 }
479
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200480 switch (encoder->type) {
481 case INTEL_OUTPUT_EDP:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700482 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530483 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700484 break;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200485 case INTEL_OUTPUT_DISPLAYPORT:
486 case INTEL_OUTPUT_HDMI:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700487 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530488 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700489 break;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200490 case INTEL_OUTPUT_ANALOG:
491 ddi_translations = ddi_translations_fdi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530492 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700493 break;
494 default:
495 BUG();
496 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300497
Ville Syrjälä9712e682015-09-18 20:03:22 +0300498 for (i = 0; i < size; i++) {
499 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
500 ddi_translations[i].trans1 | iboost_bit);
501 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
502 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300503 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100504
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200505 if (encoder->type != INTEL_OUTPUT_HDMI)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100506 return;
507
Damien Lespiauce4dd492014-08-01 11:07:54 +0100508 /* Choose a good default if VBT is badly populated */
509 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
510 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000511 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100512
Paulo Zanoni6acab152013-09-12 17:06:24 -0300513 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300514 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
515 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
516 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
517 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300518}
519
Paulo Zanoni248138b2012-11-29 11:29:31 -0200520static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
521 enum port port)
522{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200523 i915_reg_t reg = DDI_BUF_CTL(port);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200524 int i;
525
Vandana Kannan3449ca82015-03-27 14:19:09 +0200526 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200527 udelay(1);
528 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
529 return;
530 }
531 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
532}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300533
534/* Starting with Haswell, different DDI ports can work in FDI mode for
535 * connection to the PCH-located connectors. For this, it is necessary to train
536 * both the DDI port and PCH receiver for the desired DDI buffer settings.
537 *
538 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
539 * please note that when FDI mode is active on DDI E, it shares 2 lines with
540 * DDI A (which is used for eDP)
541 */
542
543void hsw_fdi_link_train(struct drm_crtc *crtc)
544{
545 struct drm_device *dev = crtc->dev;
546 struct drm_i915_private *dev_priv = dev->dev_private;
547 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200548 struct intel_encoder *encoder;
Paulo Zanoni04945642012-11-01 21:00:59 -0200549 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300550
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200551 for_each_encoder_on_crtc(dev, crtc, encoder) {
552 WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
553 intel_prepare_ddi_buffer(encoder);
554 }
555
Paulo Zanoni04945642012-11-01 21:00:59 -0200556 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
557 * mode set "sequence for CRT port" document:
558 * - TP1 to TP2 time with the default value
559 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100560 *
561 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200562 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300563 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200564 FDI_RX_PWRDN_LANE0_VAL(2) |
565 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
566
567 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000568 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100569 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200570 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300571 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
572 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200573 udelay(220);
574
575 /* Switch from Rawclk to PCDclk */
576 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300577 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200578
579 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200580 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
581 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200582
583 /* Start the training iterating through available voltages and emphasis,
584 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300585 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300586 /* Configure DP_TP_CTL with auto-training */
587 I915_WRITE(DP_TP_CTL(PORT_E),
588 DP_TP_CTL_FDI_AUTOTRAIN |
589 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
590 DP_TP_CTL_LINK_TRAIN_PAT1 |
591 DP_TP_CTL_ENABLE);
592
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000593 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
594 * DDI E does not support port reversal, the functionality is
595 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
596 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300597 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200598 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200599 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530600 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200601 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300602
603 udelay(600);
604
Paulo Zanoni04945642012-11-01 21:00:59 -0200605 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300606 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300607
Paulo Zanoni04945642012-11-01 21:00:59 -0200608 /* Enable PCH FDI Receiver with auto-training */
609 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300610 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
611 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200612
613 /* Wait for FDI receiver lane calibration */
614 udelay(30);
615
616 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300617 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200618 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300619 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
620 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200621
622 /* Wait for FDI auto training time */
623 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300624
625 temp = I915_READ(DP_TP_STATUS(PORT_E));
626 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200627 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200628 break;
629 }
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300630
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200631 /*
632 * Leave things enabled even if we failed to train FDI.
633 * Results in less fireworks from the state checker.
634 */
635 if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
636 DRM_ERROR("FDI link training failed!\n");
637 break;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300638 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200639
Paulo Zanoni248138b2012-11-29 11:29:31 -0200640 temp = I915_READ(DDI_BUF_CTL(PORT_E));
641 temp &= ~DDI_BUF_CTL_ENABLE;
642 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
643 POSTING_READ(DDI_BUF_CTL(PORT_E));
644
Paulo Zanoni04945642012-11-01 21:00:59 -0200645 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200646 temp = I915_READ(DP_TP_CTL(PORT_E));
647 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
648 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
649 I915_WRITE(DP_TP_CTL(PORT_E), temp);
650 POSTING_READ(DP_TP_CTL(PORT_E));
651
652 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200653
654 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300655 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
656 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200657
658 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300659 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200660 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
661 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300662 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
663 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300664 }
665
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200666 /* Enable normal pixel sending for FDI */
667 I915_WRITE(DP_TP_CTL(PORT_E),
668 DP_TP_CTL_FDI_AUTOTRAIN |
669 DP_TP_CTL_LINK_TRAIN_NORMAL |
670 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
671 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300672}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300673
Dave Airlie44905a22014-05-02 13:36:43 +1000674void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
675{
676 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
677 struct intel_digital_port *intel_dig_port =
678 enc_to_dig_port(&encoder->base);
679
680 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530681 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300682 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a22014-05-02 13:36:43 +1000683}
684
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300685static struct intel_encoder *
686intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
687{
688 struct drm_device *dev = crtc->dev;
689 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
690 struct intel_encoder *intel_encoder, *ret = NULL;
691 int num_encoders = 0;
692
693 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
694 ret = intel_encoder;
695 num_encoders++;
696 }
697
698 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300699 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
700 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300701
702 BUG_ON(ret == NULL);
703 return ret;
704}
705
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530706struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200707intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200708{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200709 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
710 struct intel_encoder *ret = NULL;
711 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300712 struct drm_connector *connector;
713 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200714 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200715 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200716
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200717 state = crtc_state->base.state;
718
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300719 for_each_connector_in_state(state, connector, connector_state, i) {
720 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200721 continue;
722
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300723 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200724 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200725 }
726
727 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
728 pipe_name(crtc->pipe));
729
730 BUG_ON(ret == NULL);
731 return ret;
732}
733
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100734#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100735#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100736
737#define P_MIN 2
738#define P_MAX 64
739#define P_INC 2
740
741/* Constraints for PLL good behavior */
742#define REF_MIN 48
743#define REF_MAX 400
744#define VCO_MIN 2400
745#define VCO_MAX 4800
746
Damien Lespiau27893392014-09-04 12:27:23 +0100747#define abs_diff(a, b) ({ \
748 typeof(a) __a = (a); \
749 typeof(b) __b = (b); \
750 (void) (&__a == &__b); \
751 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100752
Damien Lespiau63582982015-05-07 18:38:46 +0100753struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100754 unsigned p, n2, r2;
755};
756
Damien Lespiau63582982015-05-07 18:38:46 +0100757static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300758{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100759 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300760
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100761 switch (clock) {
762 case 25175000:
763 case 25200000:
764 case 27000000:
765 case 27027000:
766 case 37762500:
767 case 37800000:
768 case 40500000:
769 case 40541000:
770 case 54000000:
771 case 54054000:
772 case 59341000:
773 case 59400000:
774 case 72000000:
775 case 74176000:
776 case 74250000:
777 case 81000000:
778 case 81081000:
779 case 89012000:
780 case 89100000:
781 case 108000000:
782 case 108108000:
783 case 111264000:
784 case 111375000:
785 case 148352000:
786 case 148500000:
787 case 162000000:
788 case 162162000:
789 case 222525000:
790 case 222750000:
791 case 296703000:
792 case 297000000:
793 budget = 0;
794 break;
795 case 233500000:
796 case 245250000:
797 case 247750000:
798 case 253250000:
799 case 298000000:
800 budget = 1500;
801 break;
802 case 169128000:
803 case 169500000:
804 case 179500000:
805 case 202000000:
806 budget = 2000;
807 break;
808 case 256250000:
809 case 262500000:
810 case 270000000:
811 case 272500000:
812 case 273750000:
813 case 280750000:
814 case 281250000:
815 case 286000000:
816 case 291750000:
817 budget = 4000;
818 break;
819 case 267250000:
820 case 268500000:
821 budget = 5000;
822 break;
823 default:
824 budget = 1000;
825 break;
826 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300827
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100828 return budget;
829}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300830
Damien Lespiau63582982015-05-07 18:38:46 +0100831static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
832 unsigned r2, unsigned n2, unsigned p,
833 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100834{
835 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300836
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100837 /* No best (r,n,p) yet */
838 if (best->p == 0) {
839 best->p = p;
840 best->n2 = n2;
841 best->r2 = r2;
842 return;
843 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300844
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100845 /*
846 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
847 * freq2k.
848 *
849 * delta = 1e6 *
850 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
851 * freq2k;
852 *
853 * and we would like delta <= budget.
854 *
855 * If the discrepancy is above the PPM-based budget, always prefer to
856 * improve upon the previous solution. However, if you're within the
857 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
858 */
859 a = freq2k * budget * p * r2;
860 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100861 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
862 diff_best = abs_diff(freq2k * best->p * best->r2,
863 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100864 c = 1000000 * diff;
865 d = 1000000 * diff_best;
866
867 if (a < c && b < d) {
868 /* If both are above the budget, pick the closer */
869 if (best->p * best->r2 * diff < p * r2 * diff_best) {
870 best->p = p;
871 best->n2 = n2;
872 best->r2 = r2;
873 }
874 } else if (a >= c && b < d) {
875 /* If A is below the threshold but B is above it? Update. */
876 best->p = p;
877 best->n2 = n2;
878 best->r2 = r2;
879 } else if (a >= c && b >= d) {
880 /* Both are below the limit, so pick the higher n2/(r2*r2) */
881 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
882 best->p = p;
883 best->n2 = n2;
884 best->r2 = r2;
885 }
886 }
887 /* Otherwise a < c && b >= d, do nothing */
888}
889
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200890static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
891 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800892{
893 int refclk = LC_FREQ;
894 int n, p, r;
895 u32 wrpll;
896
897 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300898 switch (wrpll & WRPLL_PLL_REF_MASK) {
899 case WRPLL_PLL_SSC:
900 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800901 /*
902 * We could calculate spread here, but our checking
903 * code only cares about 5% accuracy, and spread is a max of
904 * 0.5% downspread.
905 */
906 refclk = 135;
907 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300908 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800909 refclk = LC_FREQ;
910 break;
911 default:
912 WARN(1, "bad wrpll refclk\n");
913 return 0;
914 }
915
916 r = wrpll & WRPLL_DIVIDER_REF_MASK;
917 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
918 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
919
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800920 /* Convert to KHz, p & r have a fixed point portion */
921 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800922}
923
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000924static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
925 uint32_t dpll)
926{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200927 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000928 uint32_t cfgcr1_val, cfgcr2_val;
929 uint32_t p0, p1, p2, dco_freq;
930
Ville Syrjälä923c12412015-09-30 17:06:43 +0300931 cfgcr1_reg = DPLL_CFGCR1(dpll);
932 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000933
934 cfgcr1_val = I915_READ(cfgcr1_reg);
935 cfgcr2_val = I915_READ(cfgcr2_reg);
936
937 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
938 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
939
940 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
941 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
942 else
943 p1 = 1;
944
945
946 switch (p0) {
947 case DPLL_CFGCR2_PDIV_1:
948 p0 = 1;
949 break;
950 case DPLL_CFGCR2_PDIV_2:
951 p0 = 2;
952 break;
953 case DPLL_CFGCR2_PDIV_3:
954 p0 = 3;
955 break;
956 case DPLL_CFGCR2_PDIV_7:
957 p0 = 7;
958 break;
959 }
960
961 switch (p2) {
962 case DPLL_CFGCR2_KDIV_5:
963 p2 = 5;
964 break;
965 case DPLL_CFGCR2_KDIV_2:
966 p2 = 2;
967 break;
968 case DPLL_CFGCR2_KDIV_3:
969 p2 = 3;
970 break;
971 case DPLL_CFGCR2_KDIV_1:
972 p2 = 1;
973 break;
974 }
975
976 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
977
978 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
979 1000) / 0x8000;
980
981 return dco_freq / (p0 * p1 * p2 * 5);
982}
983
Ville Syrjälä398a0172015-06-30 15:33:51 +0300984static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
985{
986 int dotclock;
987
988 if (pipe_config->has_pch_encoder)
989 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
990 &pipe_config->fdi_m_n);
991 else if (pipe_config->has_dp_encoder)
992 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
993 &pipe_config->dp_m_n);
994 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
995 dotclock = pipe_config->port_clock * 2 / 3;
996 else
997 dotclock = pipe_config->port_clock;
998
999 if (pipe_config->pixel_multiplier)
1000 dotclock /= pipe_config->pixel_multiplier;
1001
1002 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1003}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001004
1005static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001006 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001007{
1008 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001009 int link_clock = 0;
1010 uint32_t dpll_ctl1, dpll;
1011
Damien Lespiau134ffa42014-11-14 17:24:34 +00001012 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001013
1014 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1015
1016 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1017 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1018 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001019 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1020 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001021
1022 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001023 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001024 link_clock = 81000;
1025 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001026 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301027 link_clock = 108000;
1028 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001029 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001030 link_clock = 135000;
1031 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001032 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301033 link_clock = 162000;
1034 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001035 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301036 link_clock = 216000;
1037 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001038 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001039 link_clock = 270000;
1040 break;
1041 default:
1042 WARN(1, "Unsupported link rate\n");
1043 break;
1044 }
1045 link_clock *= 2;
1046 }
1047
1048 pipe_config->port_clock = link_clock;
1049
Ville Syrjälä398a0172015-06-30 15:33:51 +03001050 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001051}
1052
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001053static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001054 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001055{
1056 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001057 int link_clock = 0;
1058 u32 val, pll;
1059
Daniel Vetter26804af2014-06-25 22:01:55 +03001060 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001061 switch (val & PORT_CLK_SEL_MASK) {
1062 case PORT_CLK_SEL_LCPLL_810:
1063 link_clock = 81000;
1064 break;
1065 case PORT_CLK_SEL_LCPLL_1350:
1066 link_clock = 135000;
1067 break;
1068 case PORT_CLK_SEL_LCPLL_2700:
1069 link_clock = 270000;
1070 break;
1071 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001072 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001073 break;
1074 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001075 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001076 break;
1077 case PORT_CLK_SEL_SPLL:
1078 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1079 if (pll == SPLL_PLL_FREQ_810MHz)
1080 link_clock = 81000;
1081 else if (pll == SPLL_PLL_FREQ_1350MHz)
1082 link_clock = 135000;
1083 else if (pll == SPLL_PLL_FREQ_2700MHz)
1084 link_clock = 270000;
1085 else {
1086 WARN(1, "bad spll freq\n");
1087 return;
1088 }
1089 break;
1090 default:
1091 WARN(1, "bad port clock sel\n");
1092 return;
1093 }
1094
1095 pipe_config->port_clock = link_clock * 2;
1096
Ville Syrjälä398a0172015-06-30 15:33:51 +03001097 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001098}
1099
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301100static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1101 enum intel_dpll_id dpll)
1102{
Imre Deakaa610dc2015-06-22 23:35:52 +03001103 struct intel_shared_dpll *pll;
1104 struct intel_dpll_hw_state *state;
1105 intel_clock_t clock;
1106
1107 /* For DDI ports we always use a shared PLL. */
1108 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1109 return 0;
1110
1111 pll = &dev_priv->shared_dplls[dpll];
1112 state = &pll->config.hw_state;
1113
1114 clock.m1 = 2;
1115 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1116 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1117 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1118 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1119 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1120 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1121
1122 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301123}
1124
1125static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1126 struct intel_crtc_state *pipe_config)
1127{
1128 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1129 enum port port = intel_ddi_get_encoder_port(encoder);
1130 uint32_t dpll = port;
1131
Ville Syrjälä398a0172015-06-30 15:33:51 +03001132 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301133
Ville Syrjälä398a0172015-06-30 15:33:51 +03001134 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301135}
1136
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001137void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001138 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001139{
Damien Lespiau22606a12014-12-12 14:26:57 +00001140 struct drm_device *dev = encoder->base.dev;
1141
1142 if (INTEL_INFO(dev)->gen <= 8)
1143 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001144 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001145 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301146 else if (IS_BROXTON(dev))
1147 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001148}
1149
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001150static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001151hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1152 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001153{
1154 uint64_t freq2k;
1155 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001156 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001157 unsigned budget;
1158
1159 freq2k = clock / 100;
1160
Damien Lespiau63582982015-05-07 18:38:46 +01001161 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001162
1163 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1164 * and directly pass the LC PLL to it. */
1165 if (freq2k == 5400000) {
1166 *n2_out = 2;
1167 *p_out = 1;
1168 *r2_out = 2;
1169 return;
1170 }
1171
1172 /*
1173 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1174 * the WR PLL.
1175 *
1176 * We want R so that REF_MIN <= Ref <= REF_MAX.
1177 * Injecting R2 = 2 * R gives:
1178 * REF_MAX * r2 > LC_FREQ * 2 and
1179 * REF_MIN * r2 < LC_FREQ * 2
1180 *
1181 * Which means the desired boundaries for r2 are:
1182 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1183 *
1184 */
1185 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1186 r2 <= LC_FREQ * 2 / REF_MIN;
1187 r2++) {
1188
1189 /*
1190 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1191 *
1192 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1193 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1194 * VCO_MAX * r2 > n2 * LC_FREQ and
1195 * VCO_MIN * r2 < n2 * LC_FREQ)
1196 *
1197 * Which means the desired boundaries for n2 are:
1198 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1199 */
1200 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1201 n2 <= VCO_MAX * r2 / LC_FREQ;
1202 n2++) {
1203
1204 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001205 hsw_wrpll_update_rnp(freq2k, budget,
1206 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001207 }
1208 }
1209
1210 *n2_out = best.n2;
1211 *p_out = best.p;
1212 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001213}
1214
Damien Lespiau0220ab62014-07-29 18:06:22 +01001215static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001216hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001217 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001218 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001219{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001220 int clock = crtc_state->port_clock;
1221
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001222 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001223 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001224 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001225 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001226
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001227 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001228
Daniel Vetter114fe482014-06-25 22:01:48 +03001229 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001230 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1231 WRPLL_DIVIDER_POST(p);
1232
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001233 memset(&crtc_state->dpll_hw_state, 0,
1234 sizeof(crtc_state->dpll_hw_state));
1235
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001236 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001237
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001238 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001239 if (pll == NULL) {
1240 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1241 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001242 return false;
1243 }
1244
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001245 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001246 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1247 struct drm_atomic_state *state = crtc_state->base.state;
1248 struct intel_shared_dpll_config *spll =
1249 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1250
1251 if (spll->crtc_mask &&
1252 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1253 return false;
1254
1255 crtc_state->shared_dpll = DPLL_ID_SPLL;
1256 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1257 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001258 }
1259
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001260 return true;
1261}
1262
Damien Lespiaudc253812015-06-25 16:15:06 +01001263struct skl_wrpll_context {
1264 uint64_t min_deviation; /* current minimal deviation */
1265 uint64_t central_freq; /* chosen central freq */
1266 uint64_t dco_freq; /* chosen dco freq */
1267 unsigned int p; /* chosen divider */
1268};
1269
1270static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1271{
1272 memset(ctx, 0, sizeof(*ctx));
1273
1274 ctx->min_deviation = U64_MAX;
1275}
1276
1277/* DCO freq must be within +1%/-6% of the DCO central freq */
1278#define SKL_DCO_MAX_PDEVIATION 100
1279#define SKL_DCO_MAX_NDEVIATION 600
1280
1281static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1282 uint64_t central_freq,
1283 uint64_t dco_freq,
1284 unsigned int divider)
1285{
1286 uint64_t deviation;
1287
1288 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1289 central_freq);
1290
1291 /* positive deviation */
1292 if (dco_freq >= central_freq) {
1293 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1294 deviation < ctx->min_deviation) {
1295 ctx->min_deviation = deviation;
1296 ctx->central_freq = central_freq;
1297 ctx->dco_freq = dco_freq;
1298 ctx->p = divider;
1299 }
1300 /* negative deviation */
1301 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1302 deviation < ctx->min_deviation) {
1303 ctx->min_deviation = deviation;
1304 ctx->central_freq = central_freq;
1305 ctx->dco_freq = dco_freq;
1306 ctx->p = divider;
1307 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001308}
1309
1310static void skl_wrpll_get_multipliers(unsigned int p,
1311 unsigned int *p0 /* out */,
1312 unsigned int *p1 /* out */,
1313 unsigned int *p2 /* out */)
1314{
1315 /* even dividers */
1316 if (p % 2 == 0) {
1317 unsigned int half = p / 2;
1318
1319 if (half == 1 || half == 2 || half == 3 || half == 5) {
1320 *p0 = 2;
1321 *p1 = 1;
1322 *p2 = half;
1323 } else if (half % 2 == 0) {
1324 *p0 = 2;
1325 *p1 = half / 2;
1326 *p2 = 2;
1327 } else if (half % 3 == 0) {
1328 *p0 = 3;
1329 *p1 = half / 3;
1330 *p2 = 2;
1331 } else if (half % 7 == 0) {
1332 *p0 = 7;
1333 *p1 = half / 7;
1334 *p2 = 2;
1335 }
1336 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1337 *p0 = 3;
1338 *p1 = 1;
1339 *p2 = p / 3;
1340 } else if (p == 5 || p == 7) {
1341 *p0 = p;
1342 *p1 = 1;
1343 *p2 = 1;
1344 } else if (p == 15) {
1345 *p0 = 3;
1346 *p1 = 1;
1347 *p2 = 5;
1348 } else if (p == 21) {
1349 *p0 = 7;
1350 *p1 = 1;
1351 *p2 = 3;
1352 } else if (p == 35) {
1353 *p0 = 7;
1354 *p1 = 1;
1355 *p2 = 5;
1356 }
1357}
1358
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001359struct skl_wrpll_params {
1360 uint32_t dco_fraction;
1361 uint32_t dco_integer;
1362 uint32_t qdiv_ratio;
1363 uint32_t qdiv_mode;
1364 uint32_t kdiv;
1365 uint32_t pdiv;
1366 uint32_t central_freq;
1367};
1368
Damien Lespiau76516fb2015-05-07 18:38:42 +01001369static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1370 uint64_t afe_clock,
1371 uint64_t central_freq,
1372 uint32_t p0, uint32_t p1, uint32_t p2)
1373{
1374 uint64_t dco_freq;
1375
Damien Lespiau76516fb2015-05-07 18:38:42 +01001376 switch (central_freq) {
1377 case 9600000000ULL:
1378 params->central_freq = 0;
1379 break;
1380 case 9000000000ULL:
1381 params->central_freq = 1;
1382 break;
1383 case 8400000000ULL:
1384 params->central_freq = 3;
1385 }
1386
1387 switch (p0) {
1388 case 1:
1389 params->pdiv = 0;
1390 break;
1391 case 2:
1392 params->pdiv = 1;
1393 break;
1394 case 3:
1395 params->pdiv = 2;
1396 break;
1397 case 7:
1398 params->pdiv = 4;
1399 break;
1400 default:
1401 WARN(1, "Incorrect PDiv\n");
1402 }
1403
1404 switch (p2) {
1405 case 5:
1406 params->kdiv = 0;
1407 break;
1408 case 2:
1409 params->kdiv = 1;
1410 break;
1411 case 3:
1412 params->kdiv = 2;
1413 break;
1414 case 1:
1415 params->kdiv = 3;
1416 break;
1417 default:
1418 WARN(1, "Incorrect KDiv\n");
1419 }
1420
1421 params->qdiv_ratio = p1;
1422 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1423
1424 dco_freq = p0 * p1 * p2 * afe_clock;
1425
1426 /*
1427 * Intermediate values are in Hz.
1428 * Divide by MHz to match bsepc
1429 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001430 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001431 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001432 div_u64((div_u64(dco_freq, 24) -
1433 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001434}
1435
Damien Lespiau318bd822015-05-07 18:38:40 +01001436static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001437skl_ddi_calculate_wrpll(int clock /* in Hz */,
1438 struct skl_wrpll_params *wrpll_params)
1439{
1440 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001441 uint64_t dco_central_freq[3] = {8400000000ULL,
1442 9000000000ULL,
1443 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001444 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1445 24, 28, 30, 32, 36, 40, 42, 44,
1446 48, 52, 54, 56, 60, 64, 66, 68,
1447 70, 72, 76, 78, 80, 84, 88, 90,
1448 92, 96, 98 };
1449 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1450 static const struct {
1451 const int *list;
1452 int n_dividers;
1453 } dividers[] = {
1454 { even_dividers, ARRAY_SIZE(even_dividers) },
1455 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1456 };
1457 struct skl_wrpll_context ctx;
1458 unsigned int dco, d, i;
1459 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001460
Damien Lespiaudc253812015-06-25 16:15:06 +01001461 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001462
Damien Lespiaudc253812015-06-25 16:15:06 +01001463 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1464 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1465 for (i = 0; i < dividers[d].n_dividers; i++) {
1466 unsigned int p = dividers[d].list[i];
1467 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001468
Damien Lespiaudc253812015-06-25 16:15:06 +01001469 skl_wrpll_try_divider(&ctx,
1470 dco_central_freq[dco],
1471 dco_freq,
1472 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001473 /*
1474 * Skip the remaining dividers if we're sure to
1475 * have found the definitive divider, we can't
1476 * improve a 0 deviation.
1477 */
1478 if (ctx.min_deviation == 0)
1479 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001480 }
1481 }
Damien Lespiau267db662015-06-25 16:19:24 +01001482
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001483skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001484 /*
1485 * If a solution is found with an even divider, prefer
1486 * this one.
1487 */
1488 if (d == 0 && ctx.p)
1489 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001490 }
1491
Damien Lespiaudc253812015-06-25 16:15:06 +01001492 if (!ctx.p) {
1493 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001494 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001495 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001496
Damien Lespiaudc253812015-06-25 16:15:06 +01001497 /*
1498 * gcc incorrectly analyses that these can be used without being
1499 * initialized. To be fair, it's hard to guess.
1500 */
1501 p0 = p1 = p2 = 0;
1502 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1503 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1504 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001505
Damien Lespiau318bd822015-05-07 18:38:40 +01001506 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001507}
1508
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001509static bool
1510skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001511 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001512 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001513{
1514 struct intel_shared_dpll *pll;
1515 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001516 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001517
1518 /*
1519 * See comment in intel_dpll_hw_state to understand why we always use 0
1520 * as the DPLL id in this function.
1521 */
1522
1523 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1524
1525 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1526 struct skl_wrpll_params wrpll_params = { 0, };
1527
1528 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1529
Damien Lespiau318bd822015-05-07 18:38:40 +01001530 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1531 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001532
1533 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1534 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1535 wrpll_params.dco_integer;
1536
1537 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1538 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1539 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1540 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1541 wrpll_params.central_freq;
Lyude78385cb2016-02-02 10:49:43 -05001542 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1543 intel_encoder->type == INTEL_OUTPUT_DP_MST) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001544 switch (crtc_state->port_clock / 2) {
1545 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001546 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001547 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001548 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001549 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001550 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001551 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001552 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001553 break;
1554 }
1555
1556 cfgcr1 = cfgcr2 = 0;
Lyude5a01d5b2016-02-02 09:35:09 -05001557 } else if (intel_encoder->type == INTEL_OUTPUT_EDP) {
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001558 return true;
Lyude5a01d5b2016-02-02 09:35:09 -05001559 } else
1560 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001561
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001562 memset(&crtc_state->dpll_hw_state, 0,
1563 sizeof(crtc_state->dpll_hw_state));
1564
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001565 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1566 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1567 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001568
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001569 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001570 if (pll == NULL) {
1571 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1572 pipe_name(intel_crtc->pipe));
1573 return false;
1574 }
1575
1576 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001577 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001578
1579 return true;
1580}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001581
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301582/* bxt clock parameters */
1583struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301584 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301585 uint32_t p1;
1586 uint32_t p2;
1587 uint32_t m2_int;
1588 uint32_t m2_frac;
1589 bool m2_frac_en;
1590 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301591};
1592
1593/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301594static const struct bxt_clk_div bxt_dp_clk_val[] = {
1595 {162000, 4, 2, 32, 1677722, 1, 1},
1596 {270000, 4, 1, 27, 0, 0, 1},
1597 {540000, 2, 1, 27, 0, 0, 1},
1598 {216000, 3, 2, 32, 1677722, 1, 1},
1599 {243000, 4, 1, 24, 1258291, 1, 1},
1600 {324000, 4, 1, 32, 1677722, 1, 1},
1601 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301602};
1603
1604static bool
1605bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1606 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001607 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301608{
1609 struct intel_shared_dpll *pll;
1610 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301611 int vco = 0;
1612 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301613 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001614 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301615
1616 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1617 intel_clock_t best_clock;
1618
1619 /* Calculate HDMI div */
1620 /*
1621 * FIXME: tie the following calculation into
1622 * i9xx_crtc_compute_clock
1623 */
1624 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1625 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1626 clock, pipe_name(intel_crtc->pipe));
1627 return false;
1628 }
1629
1630 clk_div.p1 = best_clock.p1;
1631 clk_div.p2 = best_clock.p2;
1632 WARN_ON(best_clock.m1 != 2);
1633 clk_div.n = best_clock.n;
1634 clk_div.m2_int = best_clock.m2 >> 22;
1635 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1636 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1637
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301638 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301639 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1640 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301641 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301642
Sonika Jindal64987fc2015-05-26 17:50:13 +05301643 clk_div = bxt_dp_clk_val[0];
1644 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1645 if (bxt_dp_clk_val[i].clock == clock) {
1646 clk_div = bxt_dp_clk_val[i];
1647 break;
1648 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301649 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301650 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1651 }
1652
Vandana Kannane6292552015-07-01 17:02:57 +05301653 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301654 prop_coef = 4;
1655 int_coef = 9;
1656 gain_ctl = 3;
1657 targ_cnt = 8;
1658 } else if ((vco > 5400000 && vco < 6200000) ||
1659 (vco >= 4800000 && vco < 5400000)) {
1660 prop_coef = 5;
1661 int_coef = 11;
1662 gain_ctl = 3;
1663 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301664 } else if (vco == 5400000) {
1665 prop_coef = 3;
1666 int_coef = 8;
1667 gain_ctl = 1;
1668 targ_cnt = 9;
1669 } else {
1670 DRM_ERROR("Invalid VCO\n");
1671 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301672 }
1673
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001674 memset(&crtc_state->dpll_hw_state, 0,
1675 sizeof(crtc_state->dpll_hw_state));
1676
Vandana Kannane0681e32015-05-13 12:20:35 +05301677 if (clock > 270000)
1678 lanestagger = 0x18;
1679 else if (clock > 135000)
1680 lanestagger = 0x0d;
1681 else if (clock > 67000)
1682 lanestagger = 0x07;
1683 else if (clock > 33000)
1684 lanestagger = 0x04;
1685 else
1686 lanestagger = 0x02;
1687
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301688 crtc_state->dpll_hw_state.ebb0 =
1689 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1690 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1691 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1692 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1693
1694 if (clk_div.m2_frac_en)
1695 crtc_state->dpll_hw_state.pll3 =
1696 PORT_PLL_M2_FRAC_ENABLE;
1697
1698 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301699 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301700 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301701 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301702
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301703 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1704
Imre Deak05712c12015-06-18 17:25:54 +03001705 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1706
Vandana Kannane6292552015-07-01 17:02:57 +05301707 crtc_state->dpll_hw_state.pll10 =
1708 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1709 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301710
Imre Deak05712c12015-06-18 17:25:54 +03001711 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1712
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301713 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301714 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301715
1716 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1717 if (pll == NULL) {
1718 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1719 pipe_name(intel_crtc->pipe));
1720 return false;
1721 }
1722
1723 /* shared DPLL id 0 is DPLL A */
1724 crtc_state->ddi_pll_sel = pll->id;
1725
1726 return true;
1727}
1728
Damien Lespiau0220ab62014-07-29 18:06:22 +01001729/*
1730 * Tries to find a *shared* PLL for the CRTC and store it in
1731 * intel_crtc->ddi_pll_sel.
1732 *
1733 * For private DPLLs, compute_config() should do the selection for us. This
1734 * function should be folded into compute_config() eventually.
1735 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001736bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1737 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001738{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001739 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001740 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001741 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001742
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001743 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001744 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001745 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301746 else if (IS_BROXTON(dev))
1747 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001748 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001749 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001750 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001751 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001752}
1753
Paulo Zanonidae84792012-10-15 15:51:30 -03001754void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1755{
1756 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1757 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1758 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001759 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001760 int type = intel_encoder->type;
1761 uint32_t temp;
1762
Dave Airlie0e32b392014-05-02 14:02:48 +10001763 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001764 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001765 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001766 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001767 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001768 break;
1769 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001770 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001771 break;
1772 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001773 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001774 break;
1775 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001776 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001777 break;
1778 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001779 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001780 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001781 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001782 }
1783}
1784
Dave Airlie0e32b392014-05-02 14:02:48 +10001785void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1786{
1787 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1788 struct drm_device *dev = crtc->dev;
1789 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001790 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001791 uint32_t temp;
1792 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1793 if (state == true)
1794 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1795 else
1796 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1797 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1798}
1799
Damien Lespiau8228c252013-03-07 15:30:27 +00001800void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001801{
1802 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1803 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001804 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001805 struct drm_device *dev = crtc->dev;
1806 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001807 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001808 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001809 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001810 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001811 uint32_t temp;
1812
Paulo Zanoniad80a812012-10-24 16:06:19 -02001813 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1814 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001815 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001816
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001817 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001818 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001819 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001820 break;
1821 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001822 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001823 break;
1824 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001825 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001826 break;
1827 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001828 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001829 break;
1830 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001831 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001832 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001833
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001834 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001835 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001836 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001837 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c2012-08-08 14:15:28 -03001838
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001839 if (cpu_transcoder == TRANSCODER_EDP) {
1840 switch (pipe) {
1841 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001842 /* On Haswell, can only use the always-on power well for
1843 * eDP when not using the panel fitter, and when not
1844 * using motion blur mitigation (which we don't
1845 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001846 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001847 (intel_crtc->config->pch_pfit.enabled ||
1848 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001849 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1850 else
1851 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001852 break;
1853 case PIPE_B:
1854 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1855 break;
1856 case PIPE_C:
1857 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1858 break;
1859 default:
1860 BUG();
1861 break;
1862 }
1863 }
1864
Paulo Zanoni7739c332012-10-15 15:51:29 -03001865 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001866 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001867 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001868 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001869 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001870
Paulo Zanoni7739c332012-10-15 15:51:29 -03001871 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001872 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001873 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001874
1875 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1876 type == INTEL_OUTPUT_EDP) {
1877 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1878
Dave Airlie0e32b392014-05-02 14:02:48 +10001879 if (intel_dp->is_mst) {
1880 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1881 } else
1882 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1883
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001884 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001885 } else if (type == INTEL_OUTPUT_DP_MST) {
1886 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1887
1888 if (intel_dp->is_mst) {
1889 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1890 } else
1891 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001892
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001893 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001894 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001895 WARN(1, "Invalid encoder type %d for pipe %c\n",
1896 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001897 }
1898
Paulo Zanoniad80a812012-10-24 16:06:19 -02001899 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001900}
1901
Paulo Zanoniad80a812012-10-24 16:06:19 -02001902void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1903 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001904{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001905 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001906 uint32_t val = I915_READ(reg);
1907
Dave Airlie0e32b392014-05-02 14:02:48 +10001908 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001909 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001910 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001911}
1912
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001913bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1914{
1915 struct drm_device *dev = intel_connector->base.dev;
1916 struct drm_i915_private *dev_priv = dev->dev_private;
1917 struct intel_encoder *intel_encoder = intel_connector->encoder;
1918 int type = intel_connector->base.connector_type;
1919 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1920 enum pipe pipe = 0;
1921 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001922 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001923 uint32_t tmp;
Imre Deake27daab2016-02-12 18:55:16 +02001924 bool ret;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001925
Paulo Zanoni882244a2014-04-01 14:55:12 -03001926 power_domain = intel_display_port_power_domain(intel_encoder);
Imre Deake27daab2016-02-12 18:55:16 +02001927 if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001928 return false;
1929
Imre Deake27daab2016-02-12 18:55:16 +02001930 if (!intel_encoder->get_hw_state(intel_encoder, &pipe)) {
1931 ret = false;
1932 goto out;
1933 }
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001934
1935 if (port == PORT_A)
1936 cpu_transcoder = TRANSCODER_EDP;
1937 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001938 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001939
1940 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1941
1942 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1943 case TRANS_DDI_MODE_SELECT_HDMI:
1944 case TRANS_DDI_MODE_SELECT_DVI:
Imre Deake27daab2016-02-12 18:55:16 +02001945 ret = type == DRM_MODE_CONNECTOR_HDMIA;
1946 break;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001947
1948 case TRANS_DDI_MODE_SELECT_DP_SST:
Imre Deake27daab2016-02-12 18:55:16 +02001949 ret = type == DRM_MODE_CONNECTOR_eDP ||
1950 type == DRM_MODE_CONNECTOR_DisplayPort;
1951 break;
1952
Dave Airlie0e32b392014-05-02 14:02:48 +10001953 case TRANS_DDI_MODE_SELECT_DP_MST:
1954 /* if the transcoder is in MST state then
1955 * connector isn't connected */
Imre Deake27daab2016-02-12 18:55:16 +02001956 ret = false;
1957 break;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001958
1959 case TRANS_DDI_MODE_SELECT_FDI:
Imre Deake27daab2016-02-12 18:55:16 +02001960 ret = type == DRM_MODE_CONNECTOR_VGA;
1961 break;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001962
1963 default:
Imre Deake27daab2016-02-12 18:55:16 +02001964 ret = false;
1965 break;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001966 }
Imre Deake27daab2016-02-12 18:55:16 +02001967
1968out:
1969 intel_display_power_put(dev_priv, power_domain);
1970
1971 return ret;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001972}
1973
Daniel Vetter85234cd2012-07-02 13:27:29 +02001974bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1975 enum pipe *pipe)
1976{
1977 struct drm_device *dev = encoder->base.dev;
1978 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001979 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001980 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001981 u32 tmp;
1982 int i;
Imre Deake27daab2016-02-12 18:55:16 +02001983 bool ret;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001984
Imre Deak6d129be2014-03-05 16:20:54 +02001985 power_domain = intel_display_port_power_domain(encoder);
Imre Deake27daab2016-02-12 18:55:16 +02001986 if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001987 return false;
1988
Imre Deake27daab2016-02-12 18:55:16 +02001989 ret = false;
1990
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001991 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001992
1993 if (!(tmp & DDI_BUF_CTL_ENABLE))
Imre Deake27daab2016-02-12 18:55:16 +02001994 goto out;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001995
Paulo Zanoniad80a812012-10-24 16:06:19 -02001996 if (port == PORT_A) {
1997 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001998
Paulo Zanoniad80a812012-10-24 16:06:19 -02001999 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2000 case TRANS_DDI_EDP_INPUT_A_ON:
2001 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2002 *pipe = PIPE_A;
2003 break;
2004 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2005 *pipe = PIPE_B;
2006 break;
2007 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2008 *pipe = PIPE_C;
2009 break;
2010 }
2011
Imre Deake27daab2016-02-12 18:55:16 +02002012 ret = true;
Paulo Zanoniad80a812012-10-24 16:06:19 -02002013
Imre Deake27daab2016-02-12 18:55:16 +02002014 goto out;
2015 }
Dave Airlie0e32b392014-05-02 14:02:48 +10002016
Imre Deake27daab2016-02-12 18:55:16 +02002017 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2018 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2019
2020 if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(port)) {
2021 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) ==
2022 TRANS_DDI_MODE_SELECT_DP_MST)
2023 goto out;
2024
2025 *pipe = i;
2026 ret = true;
2027
2028 goto out;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002029 }
2030 }
2031
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002032 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002033
Imre Deake27daab2016-02-12 18:55:16 +02002034out:
2035 intel_display_power_put(dev_priv, power_domain);
2036
2037 return ret;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002038}
2039
Paulo Zanonifc914632012-10-05 12:05:54 -03002040void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2041{
2042 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302043 struct drm_device *dev = crtc->dev;
2044 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002045 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2046 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002047 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002048
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002049 if (cpu_transcoder != TRANSCODER_EDP)
2050 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2051 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002052}
2053
2054void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2055{
2056 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002057 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002058
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002059 if (cpu_transcoder != TRANSCODER_EDP)
2060 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2061 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002062}
2063
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002064static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
2065 u32 level, enum port port, int type)
David Weinehallf8896f52015-06-25 11:11:03 +03002066{
David Weinehallf8896f52015-06-25 11:11:03 +03002067 const struct ddi_buf_trans *ddi_translations;
2068 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002069 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002070 int n_entries;
2071 u32 reg;
2072
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002073 /* VBT may override standard boost values */
2074 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2075 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2076
David Weinehallf8896f52015-06-25 11:11:03 +03002077 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002078 if (dp_iboost) {
2079 iboost = dp_iboost;
2080 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002081 ddi_translations = skl_get_buf_trans_dp(dev_priv, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002082 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002083 }
David Weinehallf8896f52015-06-25 11:11:03 +03002084 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002085 if (dp_iboost) {
2086 iboost = dp_iboost;
2087 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002088 ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
Ville Syrjälä10afa0b2015-12-08 19:59:43 +02002089
2090 if (WARN_ON(port != PORT_A &&
2091 port != PORT_E && n_entries > 9))
2092 n_entries = 9;
2093
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002094 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002095 }
David Weinehallf8896f52015-06-25 11:11:03 +03002096 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002097 if (hdmi_iboost) {
2098 iboost = hdmi_iboost;
2099 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002100 ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002101 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002102 }
David Weinehallf8896f52015-06-25 11:11:03 +03002103 } else {
2104 return;
2105 }
2106
2107 /* Make sure that the requested I_boost is valid */
2108 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2109 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2110 return;
2111 }
2112
2113 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2114 reg &= ~BALANCE_LEG_MASK(port);
2115 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2116
2117 if (iboost)
2118 reg |= iboost << BALANCE_LEG_SHIFT(port);
2119 else
2120 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2121
2122 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2123}
2124
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002125static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
2126 u32 level, enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302127{
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302128 const struct bxt_ddi_buf_trans *ddi_translations;
2129 u32 n_entries, i;
2130 uint32_t val;
2131
Sonika Jindald9d70002015-09-24 10:24:56 +05302132 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2133 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2134 ddi_translations = bxt_ddi_translations_edp;
2135 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2136 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302137 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2138 ddi_translations = bxt_ddi_translations_dp;
2139 } else if (type == INTEL_OUTPUT_HDMI) {
2140 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2141 ddi_translations = bxt_ddi_translations_hdmi;
2142 } else {
2143 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2144 type);
2145 return;
2146 }
2147
2148 /* Check if default value has to be used */
2149 if (level >= n_entries ||
2150 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2151 for (i = 0; i < n_entries; i++) {
2152 if (ddi_translations[i].default_index) {
2153 level = i;
2154 break;
2155 }
2156 }
2157 }
2158
2159 /*
2160 * While we write to the group register to program all lanes at once we
2161 * can read only lane registers and we pick lanes 0/1 for that.
2162 */
2163 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2164 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2165 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2166
2167 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2168 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2169 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2170 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2171 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2172
2173 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302174 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302175 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302176 val |= SCALE_DCOMP_METHOD;
2177
2178 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2179 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2180
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302181 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2182
2183 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2184 val &= ~DE_EMPHASIS;
2185 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2186 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2187
2188 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2189 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2190 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2191}
2192
David Weinehallf8896f52015-06-25 11:11:03 +03002193static uint32_t translate_signal_level(int signal_levels)
2194{
2195 uint32_t level;
2196
2197 switch (signal_levels) {
2198 default:
2199 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2200 signal_levels);
2201 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2202 level = 0;
2203 break;
2204 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2205 level = 1;
2206 break;
2207 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2208 level = 2;
2209 break;
2210 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2211 level = 3;
2212 break;
2213
2214 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2215 level = 4;
2216 break;
2217 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2218 level = 5;
2219 break;
2220 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2221 level = 6;
2222 break;
2223
2224 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2225 level = 7;
2226 break;
2227 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2228 level = 8;
2229 break;
2230
2231 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2232 level = 9;
2233 break;
2234 }
2235
2236 return level;
2237}
2238
2239uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2240{
2241 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002242 struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
David Weinehallf8896f52015-06-25 11:11:03 +03002243 struct intel_encoder *encoder = &dport->base;
2244 uint8_t train_set = intel_dp->train_set[0];
2245 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2246 DP_TRAIN_PRE_EMPHASIS_MASK);
2247 enum port port = dport->port;
2248 uint32_t level;
2249
2250 level = translate_signal_level(signal_levels);
2251
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002252 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
2253 skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
2254 else if (IS_BROXTON(dev_priv))
2255 bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
David Weinehallf8896f52015-06-25 11:11:03 +03002256
2257 return DDI_BUF_TRANS_SELECT(level);
2258}
2259
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002260void intel_ddi_clk_select(struct intel_encoder *encoder,
2261 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002262{
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002263 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2264 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002265
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002266 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2267 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002268 uint32_t val;
2269
Damien Lespiau5416d872014-11-14 17:24:33 +00002270 /*
2271 * DPLL0 is used for eDP and is the only "private" DPLL (as
2272 * opposed to shared) on SKL
2273 */
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002274 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002275 WARN_ON(dpll != SKL_DPLL0);
2276
2277 val = I915_READ(DPLL_CTRL1);
2278
2279 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2280 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002281 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002282 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002283
2284 I915_WRITE(DPLL_CTRL1, val);
2285 POSTING_READ(DPLL_CTRL1);
2286 }
2287
2288 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002289 val = I915_READ(DPLL_CTRL2);
2290
2291 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2292 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2293 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2294 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2295
2296 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002297
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002298 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2299 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2300 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002301 }
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002302}
2303
2304static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2305{
2306 struct drm_encoder *encoder = &intel_encoder->base;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002307 struct drm_i915_private *dev_priv = to_i915(encoder->dev);
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002308 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2309 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2310 int type = intel_encoder->type;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002311
2312 intel_prepare_ddi_buffer(intel_encoder);
Ville Syrjäläe404ba82015-08-17 18:46:20 +03002313
2314 if (type == INTEL_OUTPUT_EDP) {
2315 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2316 intel_edp_panel_on(intel_dp);
2317 }
2318
2319 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002320
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002321 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002322 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002323
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002324 intel_dp_set_link_params(intel_dp, crtc->config);
2325
Dave Airlie44905a22014-05-02 13:36:43 +10002326 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002327
2328 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2329 intel_dp_start_link_train(intel_dp);
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002330 if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002331 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002332 } else if (type == INTEL_OUTPUT_HDMI) {
2333 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2334
2335 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002336 crtc->config->has_hdmi_sink,
2337 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002338 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002339}
2340
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002341static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002342{
2343 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002344 struct drm_device *dev = encoder->dev;
2345 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002346 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002347 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002348 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002349 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002350
2351 val = I915_READ(DDI_BUF_CTL(port));
2352 if (val & DDI_BUF_CTL_ENABLE) {
2353 val &= ~DDI_BUF_CTL_ENABLE;
2354 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002355 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002356 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002357
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002358 val = I915_READ(DP_TP_CTL(port));
2359 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2360 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2361 I915_WRITE(DP_TP_CTL(port), val);
2362
2363 if (wait)
2364 intel_wait_ddi_buf_idle(dev_priv, port);
2365
Jani Nikula76bb80e2013-11-15 15:29:57 +02002366 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002367 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002368 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002369 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002370 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002371 }
2372
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002373 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002374 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2375 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302376 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002377 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002378}
2379
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002380static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002381{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002382 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002383 struct drm_crtc *crtc = encoder->crtc;
2384 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002385 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002386 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002387 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2388 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002389
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002390 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002391 struct intel_digital_port *intel_dig_port =
2392 enc_to_dig_port(encoder);
2393
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002394 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2395 * are ignored so nothing special needs to be done besides
2396 * enabling the port.
2397 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002398 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002399 intel_dig_port->saved_port_bits |
2400 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002401 } else if (type == INTEL_OUTPUT_EDP) {
2402 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2403
Vandana Kannan23f08d82014-11-13 14:55:22 +00002404 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002405 intel_dp_stop_link_train(intel_dp);
2406
Daniel Vetter4be73782014-01-17 14:39:48 +01002407 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002408 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302409 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002410 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002411
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002412 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002413 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002414 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002415 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002416}
2417
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002418static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002419{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002420 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002421 struct drm_crtc *crtc = encoder->crtc;
2422 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002423 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002424 struct drm_device *dev = encoder->dev;
2425 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002426
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002427 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002428 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002429 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2430 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002431
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002432 if (type == INTEL_OUTPUT_EDP) {
2433 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2434
Vandana Kannanc3955782015-01-22 15:17:40 +05302435 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002436 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002437 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002438 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002439}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002440
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002441static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002442 struct intel_shared_dpll *pll)
2443{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002444 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002445 POSTING_READ(WRPLL_CTL(pll->id));
2446 udelay(20);
2447}
2448
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002449static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002450 struct intel_shared_dpll *pll)
2451{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002452 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2453 POSTING_READ(SPLL_CTL);
2454 udelay(20);
2455}
2456
2457static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2458 struct intel_shared_dpll *pll)
2459{
Daniel Vetter12030432014-06-25 22:02:00 +03002460 uint32_t val;
2461
2462 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002463 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2464 POSTING_READ(WRPLL_CTL(pll->id));
2465}
2466
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002467static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2468 struct intel_shared_dpll *pll)
2469{
2470 uint32_t val;
2471
2472 val = I915_READ(SPLL_CTL);
2473 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2474 POSTING_READ(SPLL_CTL);
2475}
2476
2477static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2478 struct intel_shared_dpll *pll,
2479 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002480{
2481 uint32_t val;
2482
Imre Deake27daab2016-02-12 18:55:16 +02002483 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002484 return false;
2485
2486 val = I915_READ(WRPLL_CTL(pll->id));
2487 hw_state->wrpll = val;
2488
Imre Deake27daab2016-02-12 18:55:16 +02002489 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
2490
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002491 return val & WRPLL_PLL_ENABLE;
2492}
2493
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002494static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2495 struct intel_shared_dpll *pll,
2496 struct intel_dpll_hw_state *hw_state)
2497{
2498 uint32_t val;
2499
Imre Deake27daab2016-02-12 18:55:16 +02002500 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002501 return false;
2502
2503 val = I915_READ(SPLL_CTL);
2504 hw_state->spll = val;
2505
Imre Deake27daab2016-02-12 18:55:16 +02002506 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
2507
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002508 return val & SPLL_PLL_ENABLE;
2509}
2510
2511
Damien Lespiauca1381b2014-07-15 15:05:33 +01002512static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002513 "WRPLL 1",
2514 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002515 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002516};
2517
Damien Lespiau143b3072014-07-29 18:06:19 +01002518static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002519{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002520 int i;
2521
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002522 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002523
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002524 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002525 dev_priv->shared_dplls[i].id = i;
2526 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002527 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2528 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002529 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002530 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002531 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002532
2533 /* SPLL is special, but needs to be initialized anyway.. */
2534 dev_priv->shared_dplls[i].id = i;
2535 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2536 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2537 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2538 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2539
Damien Lespiau143b3072014-07-29 18:06:19 +01002540}
2541
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002542static const char * const skl_ddi_pll_names[] = {
2543 "DPLL 1",
2544 "DPLL 2",
2545 "DPLL 3",
2546};
2547
2548struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002549 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002550};
2551
2552/* this array is indexed by the *shared* pll id */
2553static const struct skl_dpll_regs skl_dpll_regs[3] = {
2554 {
2555 /* DPLL 1 */
2556 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002557 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2558 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002559 },
2560 {
2561 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002562 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002563 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2564 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002565 },
2566 {
2567 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002568 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002569 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2570 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002571 },
2572};
2573
2574static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2575 struct intel_shared_dpll *pll)
2576{
2577 uint32_t val;
2578 unsigned int dpll;
2579 const struct skl_dpll_regs *regs = skl_dpll_regs;
2580
2581 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2582 dpll = pll->id + 1;
2583
2584 val = I915_READ(DPLL_CTRL1);
2585
2586 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002587 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002588 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2589
2590 I915_WRITE(DPLL_CTRL1, val);
2591 POSTING_READ(DPLL_CTRL1);
2592
2593 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2594 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2595 POSTING_READ(regs[pll->id].cfgcr1);
2596 POSTING_READ(regs[pll->id].cfgcr2);
2597
2598 /* the enable bit is always bit 31 */
2599 I915_WRITE(regs[pll->id].ctl,
2600 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2601
2602 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2603 DRM_ERROR("DPLL %d not locked\n", dpll);
2604}
2605
2606static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2607 struct intel_shared_dpll *pll)
2608{
2609 const struct skl_dpll_regs *regs = skl_dpll_regs;
2610
2611 /* the enable bit is always bit 31 */
2612 I915_WRITE(regs[pll->id].ctl,
2613 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2614 POSTING_READ(regs[pll->id].ctl);
2615}
2616
2617static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2618 struct intel_shared_dpll *pll,
2619 struct intel_dpll_hw_state *hw_state)
2620{
2621 uint32_t val;
2622 unsigned int dpll;
2623 const struct skl_dpll_regs *regs = skl_dpll_regs;
Imre Deake27daab2016-02-12 18:55:16 +02002624 bool ret;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002625
Imre Deake27daab2016-02-12 18:55:16 +02002626 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002627 return false;
2628
Imre Deake27daab2016-02-12 18:55:16 +02002629 ret = false;
2630
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002631 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2632 dpll = pll->id + 1;
2633
2634 val = I915_READ(regs[pll->id].ctl);
2635 if (!(val & LCPLL_PLL_ENABLE))
Imre Deake27daab2016-02-12 18:55:16 +02002636 goto out;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002637
2638 val = I915_READ(DPLL_CTRL1);
2639 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2640
2641 /* avoid reading back stale values if HDMI mode is not enabled */
2642 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2643 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2644 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2645 }
Imre Deake27daab2016-02-12 18:55:16 +02002646 ret = true;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002647
Imre Deake27daab2016-02-12 18:55:16 +02002648out:
2649 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
2650
2651 return ret;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002652}
2653
2654static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2655{
2656 int i;
2657
2658 dev_priv->num_shared_dpll = 3;
2659
2660 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2661 dev_priv->shared_dplls[i].id = i;
2662 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2663 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2664 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2665 dev_priv->shared_dplls[i].get_hw_state =
2666 skl_ddi_pll_get_hw_state;
2667 }
2668}
2669
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302670static void broxton_phy_init(struct drm_i915_private *dev_priv,
2671 enum dpio_phy phy)
2672{
2673 enum port port;
2674 uint32_t val;
2675
2676 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2677 val |= GT_DISPLAY_POWER_ON(phy);
2678 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2679
2680 /* Considering 10ms timeout until BSpec is updated */
2681 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2682 DRM_ERROR("timeout during PHY%d power on\n", phy);
2683
2684 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2685 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2686 int lane;
2687
2688 for (lane = 0; lane < 4; lane++) {
2689 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2690 /*
2691 * Note that on CHV this flag is called UPAR, but has
2692 * the same function.
2693 */
2694 val &= ~LATENCY_OPTIM;
2695 if (lane != 1)
2696 val |= LATENCY_OPTIM;
2697
2698 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2699 }
2700 }
2701
2702 /* Program PLL Rcomp code offset */
2703 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2704 val &= ~IREF0RC_OFFSET_MASK;
2705 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2706 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2707
2708 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2709 val &= ~IREF1RC_OFFSET_MASK;
2710 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2711 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2712
2713 /* Program power gating */
2714 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2715 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2716 SUS_CLK_CONFIG;
2717 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2718
2719 if (phy == DPIO_PHY0) {
2720 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2721 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2722 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2723 }
2724
2725 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2726 val &= ~OCL2_LDOFUSE_PWR_DIS;
2727 /*
2728 * On PHY1 disable power on the second channel, since no port is
2729 * connected there. On PHY0 both channels have a port, so leave it
2730 * enabled.
2731 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2732 * power down the second channel on PHY0 as well.
2733 */
2734 if (phy == DPIO_PHY1)
2735 val |= OCL2_LDOFUSE_PWR_DIS;
2736 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2737
2738 if (phy == DPIO_PHY0) {
2739 uint32_t grc_code;
2740 /*
2741 * PHY0 isn't connected to an RCOMP resistor so copy over
2742 * the corresponding calibrated value from PHY1, and disable
2743 * the automatic calibration on PHY0.
2744 */
2745 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2746 10))
2747 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2748
2749 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2750 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2751 grc_code = val << GRC_CODE_FAST_SHIFT |
2752 val << GRC_CODE_SLOW_SHIFT |
2753 val;
2754 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2755
2756 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2757 val |= GRC_DIS | GRC_RDY_OVRD;
2758 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2759 }
2760
2761 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2762 val |= COMMON_RESET_DIS;
2763 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2764}
2765
2766void broxton_ddi_phy_init(struct drm_device *dev)
2767{
2768 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2769 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2770 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2771}
2772
2773static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2774 enum dpio_phy phy)
2775{
2776 uint32_t val;
2777
2778 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2779 val &= ~COMMON_RESET_DIS;
2780 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2781}
2782
2783void broxton_ddi_phy_uninit(struct drm_device *dev)
2784{
2785 struct drm_i915_private *dev_priv = dev->dev_private;
2786
2787 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2788 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2789
2790 /* FIXME: do this in broxton_phy_uninit per phy */
2791 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2792}
2793
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302794static const char * const bxt_ddi_pll_names[] = {
2795 "PORT PLL A",
2796 "PORT PLL B",
2797 "PORT PLL C",
2798};
2799
2800static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2801 struct intel_shared_dpll *pll)
2802{
2803 uint32_t temp;
2804 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2805
2806 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2807 temp &= ~PORT_PLL_REF_SEL;
2808 /* Non-SSC reference */
2809 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2810
2811 /* Disable 10 bit clock */
2812 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2813 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2814 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2815
2816 /* Write P1 & P2 */
2817 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2818 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2819 temp |= pll->config.hw_state.ebb0;
2820 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2821
2822 /* Write M2 integer */
2823 temp = I915_READ(BXT_PORT_PLL(port, 0));
2824 temp &= ~PORT_PLL_M2_MASK;
2825 temp |= pll->config.hw_state.pll0;
2826 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2827
2828 /* Write N */
2829 temp = I915_READ(BXT_PORT_PLL(port, 1));
2830 temp &= ~PORT_PLL_N_MASK;
2831 temp |= pll->config.hw_state.pll1;
2832 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2833
2834 /* Write M2 fraction */
2835 temp = I915_READ(BXT_PORT_PLL(port, 2));
2836 temp &= ~PORT_PLL_M2_FRAC_MASK;
2837 temp |= pll->config.hw_state.pll2;
2838 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2839
2840 /* Write M2 fraction enable */
2841 temp = I915_READ(BXT_PORT_PLL(port, 3));
2842 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2843 temp |= pll->config.hw_state.pll3;
2844 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2845
2846 /* Write coeff */
2847 temp = I915_READ(BXT_PORT_PLL(port, 6));
2848 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2849 temp &= ~PORT_PLL_INT_COEFF_MASK;
2850 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2851 temp |= pll->config.hw_state.pll6;
2852 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2853
2854 /* Write calibration val */
2855 temp = I915_READ(BXT_PORT_PLL(port, 8));
2856 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2857 temp |= pll->config.hw_state.pll8;
2858 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2859
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302860 temp = I915_READ(BXT_PORT_PLL(port, 9));
2861 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002862 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302863 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2864
2865 temp = I915_READ(BXT_PORT_PLL(port, 10));
2866 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2867 temp &= ~PORT_PLL_DCO_AMP_MASK;
2868 temp |= pll->config.hw_state.pll10;
2869 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302870
2871 /* Recalibrate with new settings */
2872 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2873 temp |= PORT_PLL_RECALIBRATE;
2874 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002875 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2876 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302877 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2878
2879 /* Enable PLL */
2880 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2881 temp |= PORT_PLL_ENABLE;
2882 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2883 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2884
2885 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2886 PORT_PLL_LOCK), 200))
2887 DRM_ERROR("PLL %d not locked\n", port);
2888
2889 /*
2890 * While we write to the group register to program all lanes at once we
2891 * can read only lane registers and we pick lanes 0/1 for that.
2892 */
2893 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2894 temp &= ~LANE_STAGGER_MASK;
2895 temp &= ~LANESTAGGER_STRAP_OVRD;
2896 temp |= pll->config.hw_state.pcsdw12;
2897 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2898}
2899
2900static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2901 struct intel_shared_dpll *pll)
2902{
2903 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2904 uint32_t temp;
2905
2906 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2907 temp &= ~PORT_PLL_ENABLE;
2908 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2909 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2910}
2911
2912static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2913 struct intel_shared_dpll *pll,
2914 struct intel_dpll_hw_state *hw_state)
2915{
2916 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2917 uint32_t val;
Imre Deake27daab2016-02-12 18:55:16 +02002918 bool ret;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302919
Imre Deake27daab2016-02-12 18:55:16 +02002920 if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS))
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302921 return false;
2922
Imre Deake27daab2016-02-12 18:55:16 +02002923 ret = false;
2924
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302925 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2926 if (!(val & PORT_PLL_ENABLE))
Imre Deake27daab2016-02-12 18:55:16 +02002927 goto out;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302928
2929 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002930 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2931
Imre Deak05712c12015-06-18 17:25:54 +03002932 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2933 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2934
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302935 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002936 hw_state->pll0 &= PORT_PLL_M2_MASK;
2937
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302938 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002939 hw_state->pll1 &= PORT_PLL_N_MASK;
2940
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302941 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002942 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2943
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302944 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002945 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2946
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302947 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002948 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2949 PORT_PLL_INT_COEFF_MASK |
2950 PORT_PLL_GAIN_CTL_MASK;
2951
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302952 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002953 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2954
Imre Deak05712c12015-06-18 17:25:54 +03002955 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2956 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2957
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302958 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002959 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2960 PORT_PLL_DCO_AMP_MASK;
2961
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302962 /*
2963 * While we write to the group register to program all lanes at once we
2964 * can read only lane registers. We configure all lanes the same way, so
2965 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2966 */
2967 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002968 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302969 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2970 hw_state->pcsdw12,
2971 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002972 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302973
Imre Deake27daab2016-02-12 18:55:16 +02002974 ret = true;
2975
2976out:
2977 intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS);
2978
2979 return ret;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302980}
2981
2982static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2983{
2984 int i;
2985
2986 dev_priv->num_shared_dpll = 3;
2987
2988 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2989 dev_priv->shared_dplls[i].id = i;
2990 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2991 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2992 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2993 dev_priv->shared_dplls[i].get_hw_state =
2994 bxt_ddi_pll_get_hw_state;
2995 }
2996}
2997
Damien Lespiau143b3072014-07-29 18:06:19 +01002998void intel_ddi_pll_init(struct drm_device *dev)
2999{
3000 struct drm_i915_private *dev_priv = dev->dev_private;
3001 uint32_t val = I915_READ(LCPLL_CTL);
3002
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07003003 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003004 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05303005 else if (IS_BROXTON(dev))
3006 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003007 else
3008 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003009
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07003010 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01003011 int cdclk_freq;
3012
3013 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01003014 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05303015 if (skl_sanitize_cdclk(dev_priv))
3016 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02003017 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
3018 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05303019 } else if (IS_BROXTON(dev)) {
3020 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05303021 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003022 } else {
3023 /*
3024 * The LCPLL register should be turned on by the BIOS. For now
3025 * let's just check its state and print errors in case
3026 * something is wrong. Don't even try to turn it on.
3027 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003028
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003029 if (val & LCPLL_CD_SOURCE_FCLK)
3030 DRM_ERROR("CDCLK source is not LCPLL\n");
3031
3032 if (val & LCPLL_PLL_DISABLE)
3033 DRM_ERROR("LCPLL is disabled\n");
3034 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003035}
Paulo Zanonic19b0662012-10-15 15:51:41 -03003036
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003037void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03003038{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003039 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3040 struct drm_i915_private *dev_priv =
3041 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02003042 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003043 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05303044 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003045
3046 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
3047 val = I915_READ(DDI_BUF_CTL(port));
3048 if (val & DDI_BUF_CTL_ENABLE) {
3049 val &= ~DDI_BUF_CTL_ENABLE;
3050 I915_WRITE(DDI_BUF_CTL(port), val);
3051 wait = true;
3052 }
3053
3054 val = I915_READ(DP_TP_CTL(port));
3055 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3056 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3057 I915_WRITE(DP_TP_CTL(port), val);
3058 POSTING_READ(DP_TP_CTL(port));
3059
3060 if (wait)
3061 intel_wait_ddi_buf_idle(dev_priv, port);
3062 }
3063
Dave Airlie0e32b392014-05-02 14:02:48 +10003064 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003065 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003066 if (intel_dp->is_mst)
3067 val |= DP_TP_CTL_MODE_MST;
3068 else {
3069 val |= DP_TP_CTL_MODE_SST;
3070 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3071 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3072 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003073 I915_WRITE(DP_TP_CTL(port), val);
3074 POSTING_READ(DP_TP_CTL(port));
3075
3076 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3077 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3078 POSTING_READ(DDI_BUF_CTL(port));
3079
3080 udelay(600);
3081}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003082
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003083void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3084{
3085 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3086 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3087 uint32_t val;
3088
3089 intel_ddi_post_disable(intel_encoder);
3090
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003091 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003092 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003093 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003094
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003095 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003096 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3097 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003098 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003099
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003100 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003101 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003102 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003103
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003104 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003105 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003106 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003107}
3108
Libin Yang3d52ccf2015-12-02 14:09:44 +08003109bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
3110 struct intel_crtc *intel_crtc)
3111{
3112 u32 temp;
3113
Imre Deake27daab2016-02-12 18:55:16 +02003114 if (intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
Libin Yang3d52ccf2015-12-02 14:09:44 +08003115 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
Imre Deake27daab2016-02-12 18:55:16 +02003116
3117 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
3118
Libin Yang3d52ccf2015-12-02 14:09:44 +08003119 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
3120 return true;
3121 }
Imre Deake27daab2016-02-12 18:55:16 +02003122
Libin Yang3d52ccf2015-12-02 14:09:44 +08003123 return false;
3124}
3125
Ville Syrjälä6801c182013-09-24 14:24:05 +03003126void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003127 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003128{
3129 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3130 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003131 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003132 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003133 u32 temp, flags = 0;
3134
3135 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3136 if (temp & TRANS_DDI_PHSYNC)
3137 flags |= DRM_MODE_FLAG_PHSYNC;
3138 else
3139 flags |= DRM_MODE_FLAG_NHSYNC;
3140 if (temp & TRANS_DDI_PVSYNC)
3141 flags |= DRM_MODE_FLAG_PVSYNC;
3142 else
3143 flags |= DRM_MODE_FLAG_NVSYNC;
3144
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003145 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003146
3147 switch (temp & TRANS_DDI_BPC_MASK) {
3148 case TRANS_DDI_BPC_6:
3149 pipe_config->pipe_bpp = 18;
3150 break;
3151 case TRANS_DDI_BPC_8:
3152 pipe_config->pipe_bpp = 24;
3153 break;
3154 case TRANS_DDI_BPC_10:
3155 pipe_config->pipe_bpp = 30;
3156 break;
3157 case TRANS_DDI_BPC_12:
3158 pipe_config->pipe_bpp = 36;
3159 break;
3160 default:
3161 break;
3162 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003163
3164 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3165 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003166 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003167 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3168
Ville Syrjäläcda0aaa2015-11-26 18:27:07 +02003169 if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003170 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003171 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003172 case TRANS_DDI_MODE_SELECT_DVI:
3173 case TRANS_DDI_MODE_SELECT_FDI:
3174 break;
3175 case TRANS_DDI_MODE_SELECT_DP_SST:
3176 case TRANS_DDI_MODE_SELECT_DP_MST:
3177 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003178 pipe_config->lane_count =
3179 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003180 intel_dp_get_m_n(intel_crtc, pipe_config);
3181 break;
3182 default:
3183 break;
3184 }
Daniel Vetter10214422013-11-18 07:38:16 +01003185
Libin Yang3d52ccf2015-12-02 14:09:44 +08003186 pipe_config->has_audio =
3187 intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003188
Daniel Vetter10214422013-11-18 07:38:16 +01003189 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3190 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3191 /*
3192 * This is a big fat ugly hack.
3193 *
3194 * Some machines in UEFI boot mode provide us a VBT that has 18
3195 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3196 * unknown we fail to light up. Yet the same BIOS boots up with
3197 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3198 * max, not what it tells us to use.
3199 *
3200 * Note: This will still be broken if the eDP panel is not lit
3201 * up by the BIOS, and thus we can't get the mode at module
3202 * load.
3203 */
3204 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3205 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3206 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3207 }
Jesse Barnes11578552014-01-21 12:42:10 -08003208
Damien Lespiau22606a12014-12-12 14:26:57 +00003209 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003210}
3211
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003212static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003213 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003214{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003215 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003216 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003217
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003218 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003219
Daniel Vettereccb1402013-05-22 00:50:22 +02003220 if (port == PORT_A)
3221 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3222
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003223 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003224 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003225 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003226 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003227}
3228
3229static const struct drm_encoder_funcs intel_ddi_funcs = {
Imre Deak5eaa60c2016-04-18 10:04:21 +03003230 .reset = intel_dp_encoder_reset,
3231 .destroy = intel_dp_encoder_destroy,
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003232};
3233
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003234static struct intel_connector *
3235intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3236{
3237 struct intel_connector *connector;
3238 enum port port = intel_dig_port->port;
3239
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003240 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003241 if (!connector)
3242 return NULL;
3243
3244 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3245 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3246 kfree(connector);
3247 return NULL;
3248 }
3249
3250 return connector;
3251}
3252
3253static struct intel_connector *
3254intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3255{
3256 struct intel_connector *connector;
3257 enum port port = intel_dig_port->port;
3258
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003259 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003260 if (!connector)
3261 return NULL;
3262
3263 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3264 intel_hdmi_init_connector(intel_dig_port, connector);
3265
3266 return connector;
3267}
3268
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003269void intel_ddi_init(struct drm_device *dev, enum port port)
3270{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003271 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003272 struct intel_digital_port *intel_dig_port;
3273 struct intel_encoder *intel_encoder;
3274 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003275 bool init_hdmi, init_dp;
Ville Syrjälä10e7bec2015-12-08 19:59:37 +02003276 int max_lanes;
3277
3278 if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
3279 switch (port) {
3280 case PORT_A:
3281 max_lanes = 4;
3282 break;
3283 case PORT_E:
3284 max_lanes = 0;
3285 break;
3286 default:
3287 max_lanes = 4;
3288 break;
3289 }
3290 } else {
3291 switch (port) {
3292 case PORT_A:
3293 max_lanes = 2;
3294 break;
3295 case PORT_E:
3296 max_lanes = 2;
3297 break;
3298 default:
3299 max_lanes = 4;
3300 break;
3301 }
3302 }
Paulo Zanoni311a2092013-09-12 17:12:18 -03003303
3304 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3305 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3306 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3307 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003308 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003309 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003310 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003311 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003312
Daniel Vetterb14c5672013-09-19 12:18:32 +02003313 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003314 if (!intel_dig_port)
3315 return;
3316
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003317 intel_encoder = &intel_dig_port->base;
3318 encoder = &intel_encoder->base;
3319
3320 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
Ville Syrjälä13a3d912015-12-09 16:20:18 +02003321 DRM_MODE_ENCODER_TMDS, NULL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003322
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003323 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003324 intel_encoder->enable = intel_enable_ddi;
3325 intel_encoder->pre_enable = intel_ddi_pre_enable;
3326 intel_encoder->disable = intel_disable_ddi;
3327 intel_encoder->post_disable = intel_ddi_post_disable;
3328 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003329 intel_encoder->get_config = intel_ddi_get_config;
Imre Deak5eaa60c2016-04-18 10:04:21 +03003330 intel_encoder->suspend = intel_dp_encoder_suspend;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003331
3332 intel_dig_port->port = port;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003333 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3334 (DDI_BUF_PORT_REVERSAL |
3335 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003336
Matt Roper6c566dc2015-11-05 14:53:32 -08003337 /*
3338 * Bspec says that DDI_A_4_LANES is the only supported configuration
3339 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3340 * wasn't lit up at boot. Force this bit on in our internal
3341 * configuration so that we use the proper lane count for our
3342 * calculations.
3343 */
3344 if (IS_BROXTON(dev) && port == PORT_A) {
3345 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3346 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3347 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
Matt Ropered8d60f2016-01-28 15:09:37 -08003348 max_lanes = 4;
Matt Roper6c566dc2015-11-05 14:53:32 -08003349 }
3350 }
3351
Matt Ropered8d60f2016-01-28 15:09:37 -08003352 intel_dig_port->max_lanes = max_lanes;
3353
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003354 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003355 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003356 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003357
Chris Wilsonf68d6972014-08-04 07:15:09 +01003358 if (init_dp) {
3359 if (!intel_ddi_init_dp_connector(intel_dig_port))
3360 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003361
Chris Wilsonf68d6972014-08-04 07:15:09 +01003362 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303363 /*
3364 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3365 * interrupts to check the external panel connection.
3366 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003367 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303368 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3369 else
3370 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003371 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003372
Paulo Zanoni311a2092013-09-12 17:12:18 -03003373 /* In theory we don't need the encoder->type check, but leave it just in
3374 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003375 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3376 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3377 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003378 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003379
3380 return;
3381
3382err:
3383 drm_encoder_cleanup(encoder);
3384 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003385}