blob: cdf2e14aa45daf46f5215732e41ec5c205c4ab3a [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;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700446 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100447 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530448 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
449 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300450 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000451 hdmi_default_entry = 7;
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +0200452 } else if (IS_HASWELL(dev_priv)) {
Art Runyane58623c2013-11-02 21:07:41 -0700453 ddi_translations_fdi = hsw_ddi_translations_fdi;
454 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700455 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100456 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530457 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300458 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000459 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700460 } else {
461 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700462 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700463 ddi_translations_fdi = bdw_ddi_translations_fdi;
464 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100465 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530466 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
467 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300468 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000469 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700470 }
471
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200472 switch (encoder->type) {
473 case INTEL_OUTPUT_EDP:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700474 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530475 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700476 break;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200477 case INTEL_OUTPUT_DISPLAYPORT:
478 case INTEL_OUTPUT_HDMI:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700479 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530480 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700481 break;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200482 case INTEL_OUTPUT_ANALOG:
483 ddi_translations = ddi_translations_fdi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530484 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700485 break;
486 default:
487 BUG();
488 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300489
Ville Syrjälä9712e682015-09-18 20:03:22 +0300490 for (i = 0; i < size; i++) {
491 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
492 ddi_translations[i].trans1 | iboost_bit);
493 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
494 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300495 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100496
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200497 if (encoder->type != INTEL_OUTPUT_HDMI)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100498 return;
499
Damien Lespiauce4dd492014-08-01 11:07:54 +0100500 /* Choose a good default if VBT is badly populated */
501 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
502 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000503 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100504
Paulo Zanoni6acab152013-09-12 17:06:24 -0300505 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300506 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
507 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
508 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
509 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300510}
511
Paulo Zanoni248138b2012-11-29 11:29:31 -0200512static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
513 enum port port)
514{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200515 i915_reg_t reg = DDI_BUF_CTL(port);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200516 int i;
517
Vandana Kannan3449ca82015-03-27 14:19:09 +0200518 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200519 udelay(1);
520 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
521 return;
522 }
523 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
524}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300525
526/* Starting with Haswell, different DDI ports can work in FDI mode for
527 * connection to the PCH-located connectors. For this, it is necessary to train
528 * both the DDI port and PCH receiver for the desired DDI buffer settings.
529 *
530 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
531 * please note that when FDI mode is active on DDI E, it shares 2 lines with
532 * DDI A (which is used for eDP)
533 */
534
535void hsw_fdi_link_train(struct drm_crtc *crtc)
536{
537 struct drm_device *dev = crtc->dev;
538 struct drm_i915_private *dev_priv = dev->dev_private;
539 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200540 struct intel_encoder *encoder;
Paulo Zanoni04945642012-11-01 21:00:59 -0200541 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300542
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +0200543 for_each_encoder_on_crtc(dev, crtc, encoder) {
544 WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG);
545 intel_prepare_ddi_buffer(encoder);
546 }
547
Paulo Zanoni04945642012-11-01 21:00:59 -0200548 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
549 * mode set "sequence for CRT port" document:
550 * - TP1 to TP2 time with the default value
551 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100552 *
553 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200554 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300555 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200556 FDI_RX_PWRDN_LANE0_VAL(2) |
557 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
558
559 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000560 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100561 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200562 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300563 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
564 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200565 udelay(220);
566
567 /* Switch from Rawclk to PCDclk */
568 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300569 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200570
571 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200572 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
573 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200574
575 /* Start the training iterating through available voltages and emphasis,
576 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300577 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300578 /* Configure DP_TP_CTL with auto-training */
579 I915_WRITE(DP_TP_CTL(PORT_E),
580 DP_TP_CTL_FDI_AUTOTRAIN |
581 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
582 DP_TP_CTL_LINK_TRAIN_PAT1 |
583 DP_TP_CTL_ENABLE);
584
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000585 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
586 * DDI E does not support port reversal, the functionality is
587 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
588 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300589 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200590 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200591 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530592 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200593 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300594
595 udelay(600);
596
Paulo Zanoni04945642012-11-01 21:00:59 -0200597 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300598 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300599
Paulo Zanoni04945642012-11-01 21:00:59 -0200600 /* Enable PCH FDI Receiver with auto-training */
601 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300602 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
603 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200604
605 /* Wait for FDI receiver lane calibration */
606 udelay(30);
607
608 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300609 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200610 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300611 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
612 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200613
614 /* Wait for FDI auto training time */
615 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300616
617 temp = I915_READ(DP_TP_STATUS(PORT_E));
618 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200619 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200620 break;
621 }
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300622
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200623 /*
624 * Leave things enabled even if we failed to train FDI.
625 * Results in less fireworks from the state checker.
626 */
627 if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
628 DRM_ERROR("FDI link training failed!\n");
629 break;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300630 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200631
Paulo Zanoni248138b2012-11-29 11:29:31 -0200632 temp = I915_READ(DDI_BUF_CTL(PORT_E));
633 temp &= ~DDI_BUF_CTL_ENABLE;
634 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
635 POSTING_READ(DDI_BUF_CTL(PORT_E));
636
Paulo Zanoni04945642012-11-01 21:00:59 -0200637 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200638 temp = I915_READ(DP_TP_CTL(PORT_E));
639 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
640 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
641 I915_WRITE(DP_TP_CTL(PORT_E), temp);
642 POSTING_READ(DP_TP_CTL(PORT_E));
643
644 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200645
646 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300647 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
648 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200649
650 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300651 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200652 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
653 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300654 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
655 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300656 }
657
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200658 /* Enable normal pixel sending for FDI */
659 I915_WRITE(DP_TP_CTL(PORT_E),
660 DP_TP_CTL_FDI_AUTOTRAIN |
661 DP_TP_CTL_LINK_TRAIN_NORMAL |
662 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
663 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300664}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300665
Dave Airlie44905a272014-05-02 13:36:43 +1000666void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
667{
668 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
669 struct intel_digital_port *intel_dig_port =
670 enc_to_dig_port(&encoder->base);
671
672 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530673 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300674 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000675}
676
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300677static struct intel_encoder *
678intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
679{
680 struct drm_device *dev = crtc->dev;
681 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
682 struct intel_encoder *intel_encoder, *ret = NULL;
683 int num_encoders = 0;
684
685 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
686 ret = intel_encoder;
687 num_encoders++;
688 }
689
690 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300691 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
692 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300693
694 BUG_ON(ret == NULL);
695 return ret;
696}
697
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530698struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200699intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200700{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200701 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
702 struct intel_encoder *ret = NULL;
703 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300704 struct drm_connector *connector;
705 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200706 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200707 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200708
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200709 state = crtc_state->base.state;
710
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300711 for_each_connector_in_state(state, connector, connector_state, i) {
712 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200713 continue;
714
Ander Conselvan de Oliveirada3ced22015-04-21 17:12:59 +0300715 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200716 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200717 }
718
719 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
720 pipe_name(crtc->pipe));
721
722 BUG_ON(ret == NULL);
723 return ret;
724}
725
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100726#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100727#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100728
729#define P_MIN 2
730#define P_MAX 64
731#define P_INC 2
732
733/* Constraints for PLL good behavior */
734#define REF_MIN 48
735#define REF_MAX 400
736#define VCO_MIN 2400
737#define VCO_MAX 4800
738
Damien Lespiau27893392014-09-04 12:27:23 +0100739#define abs_diff(a, b) ({ \
740 typeof(a) __a = (a); \
741 typeof(b) __b = (b); \
742 (void) (&__a == &__b); \
743 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100744
Damien Lespiau63582982015-05-07 18:38:46 +0100745struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100746 unsigned p, n2, r2;
747};
748
Damien Lespiau63582982015-05-07 18:38:46 +0100749static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300750{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100751 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300752
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100753 switch (clock) {
754 case 25175000:
755 case 25200000:
756 case 27000000:
757 case 27027000:
758 case 37762500:
759 case 37800000:
760 case 40500000:
761 case 40541000:
762 case 54000000:
763 case 54054000:
764 case 59341000:
765 case 59400000:
766 case 72000000:
767 case 74176000:
768 case 74250000:
769 case 81000000:
770 case 81081000:
771 case 89012000:
772 case 89100000:
773 case 108000000:
774 case 108108000:
775 case 111264000:
776 case 111375000:
777 case 148352000:
778 case 148500000:
779 case 162000000:
780 case 162162000:
781 case 222525000:
782 case 222750000:
783 case 296703000:
784 case 297000000:
785 budget = 0;
786 break;
787 case 233500000:
788 case 245250000:
789 case 247750000:
790 case 253250000:
791 case 298000000:
792 budget = 1500;
793 break;
794 case 169128000:
795 case 169500000:
796 case 179500000:
797 case 202000000:
798 budget = 2000;
799 break;
800 case 256250000:
801 case 262500000:
802 case 270000000:
803 case 272500000:
804 case 273750000:
805 case 280750000:
806 case 281250000:
807 case 286000000:
808 case 291750000:
809 budget = 4000;
810 break;
811 case 267250000:
812 case 268500000:
813 budget = 5000;
814 break;
815 default:
816 budget = 1000;
817 break;
818 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300819
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100820 return budget;
821}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300822
Damien Lespiau63582982015-05-07 18:38:46 +0100823static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
824 unsigned r2, unsigned n2, unsigned p,
825 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100826{
827 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300828
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100829 /* No best (r,n,p) yet */
830 if (best->p == 0) {
831 best->p = p;
832 best->n2 = n2;
833 best->r2 = r2;
834 return;
835 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300836
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100837 /*
838 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
839 * freq2k.
840 *
841 * delta = 1e6 *
842 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
843 * freq2k;
844 *
845 * and we would like delta <= budget.
846 *
847 * If the discrepancy is above the PPM-based budget, always prefer to
848 * improve upon the previous solution. However, if you're within the
849 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
850 */
851 a = freq2k * budget * p * r2;
852 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100853 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
854 diff_best = abs_diff(freq2k * best->p * best->r2,
855 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100856 c = 1000000 * diff;
857 d = 1000000 * diff_best;
858
859 if (a < c && b < d) {
860 /* If both are above the budget, pick the closer */
861 if (best->p * best->r2 * diff < p * r2 * diff_best) {
862 best->p = p;
863 best->n2 = n2;
864 best->r2 = r2;
865 }
866 } else if (a >= c && b < d) {
867 /* If A is below the threshold but B is above it? Update. */
868 best->p = p;
869 best->n2 = n2;
870 best->r2 = r2;
871 } else if (a >= c && b >= d) {
872 /* Both are below the limit, so pick the higher n2/(r2*r2) */
873 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
874 best->p = p;
875 best->n2 = n2;
876 best->r2 = r2;
877 }
878 }
879 /* Otherwise a < c && b >= d, do nothing */
880}
881
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200882static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
883 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800884{
885 int refclk = LC_FREQ;
886 int n, p, r;
887 u32 wrpll;
888
889 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300890 switch (wrpll & WRPLL_PLL_REF_MASK) {
891 case WRPLL_PLL_SSC:
892 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800893 /*
894 * We could calculate spread here, but our checking
895 * code only cares about 5% accuracy, and spread is a max of
896 * 0.5% downspread.
897 */
898 refclk = 135;
899 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300900 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800901 refclk = LC_FREQ;
902 break;
903 default:
904 WARN(1, "bad wrpll refclk\n");
905 return 0;
906 }
907
908 r = wrpll & WRPLL_DIVIDER_REF_MASK;
909 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
910 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
911
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800912 /* Convert to KHz, p & r have a fixed point portion */
913 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800914}
915
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000916static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
917 uint32_t dpll)
918{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200919 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000920 uint32_t cfgcr1_val, cfgcr2_val;
921 uint32_t p0, p1, p2, dco_freq;
922
Ville Syrjälä923c12412015-09-30 17:06:43 +0300923 cfgcr1_reg = DPLL_CFGCR1(dpll);
924 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000925
926 cfgcr1_val = I915_READ(cfgcr1_reg);
927 cfgcr2_val = I915_READ(cfgcr2_reg);
928
929 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
930 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
931
932 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
933 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
934 else
935 p1 = 1;
936
937
938 switch (p0) {
939 case DPLL_CFGCR2_PDIV_1:
940 p0 = 1;
941 break;
942 case DPLL_CFGCR2_PDIV_2:
943 p0 = 2;
944 break;
945 case DPLL_CFGCR2_PDIV_3:
946 p0 = 3;
947 break;
948 case DPLL_CFGCR2_PDIV_7:
949 p0 = 7;
950 break;
951 }
952
953 switch (p2) {
954 case DPLL_CFGCR2_KDIV_5:
955 p2 = 5;
956 break;
957 case DPLL_CFGCR2_KDIV_2:
958 p2 = 2;
959 break;
960 case DPLL_CFGCR2_KDIV_3:
961 p2 = 3;
962 break;
963 case DPLL_CFGCR2_KDIV_1:
964 p2 = 1;
965 break;
966 }
967
968 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
969
970 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
971 1000) / 0x8000;
972
973 return dco_freq / (p0 * p1 * p2 * 5);
974}
975
Ville Syrjälä398a0172015-06-30 15:33:51 +0300976static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
977{
978 int dotclock;
979
980 if (pipe_config->has_pch_encoder)
981 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
982 &pipe_config->fdi_m_n);
983 else if (pipe_config->has_dp_encoder)
984 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
985 &pipe_config->dp_m_n);
986 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
987 dotclock = pipe_config->port_clock * 2 / 3;
988 else
989 dotclock = pipe_config->port_clock;
990
991 if (pipe_config->pixel_multiplier)
992 dotclock /= pipe_config->pixel_multiplier;
993
994 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
995}
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000996
997static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +0200998 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000999{
1000 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001001 int link_clock = 0;
1002 uint32_t dpll_ctl1, dpll;
1003
Damien Lespiau134ffa42014-11-14 17:24:34 +00001004 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001005
1006 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1007
1008 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1009 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1010 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001011 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1012 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001013
1014 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001015 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001016 link_clock = 81000;
1017 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001018 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301019 link_clock = 108000;
1020 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001021 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001022 link_clock = 135000;
1023 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001024 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301025 link_clock = 162000;
1026 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001027 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301028 link_clock = 216000;
1029 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001030 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001031 link_clock = 270000;
1032 break;
1033 default:
1034 WARN(1, "Unsupported link rate\n");
1035 break;
1036 }
1037 link_clock *= 2;
1038 }
1039
1040 pipe_config->port_clock = link_clock;
1041
Ville Syrjälä398a0172015-06-30 15:33:51 +03001042 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001043}
1044
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001045static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001046 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001047{
1048 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001049 int link_clock = 0;
1050 u32 val, pll;
1051
Daniel Vetter26804af2014-06-25 22:01:55 +03001052 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001053 switch (val & PORT_CLK_SEL_MASK) {
1054 case PORT_CLK_SEL_LCPLL_810:
1055 link_clock = 81000;
1056 break;
1057 case PORT_CLK_SEL_LCPLL_1350:
1058 link_clock = 135000;
1059 break;
1060 case PORT_CLK_SEL_LCPLL_2700:
1061 link_clock = 270000;
1062 break;
1063 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001064 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001065 break;
1066 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001067 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001068 break;
1069 case PORT_CLK_SEL_SPLL:
1070 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1071 if (pll == SPLL_PLL_FREQ_810MHz)
1072 link_clock = 81000;
1073 else if (pll == SPLL_PLL_FREQ_1350MHz)
1074 link_clock = 135000;
1075 else if (pll == SPLL_PLL_FREQ_2700MHz)
1076 link_clock = 270000;
1077 else {
1078 WARN(1, "bad spll freq\n");
1079 return;
1080 }
1081 break;
1082 default:
1083 WARN(1, "bad port clock sel\n");
1084 return;
1085 }
1086
1087 pipe_config->port_clock = link_clock * 2;
1088
Ville Syrjälä398a0172015-06-30 15:33:51 +03001089 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001090}
1091
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301092static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1093 enum intel_dpll_id dpll)
1094{
Imre Deakaa610dc2015-06-22 23:35:52 +03001095 struct intel_shared_dpll *pll;
1096 struct intel_dpll_hw_state *state;
1097 intel_clock_t clock;
1098
1099 /* For DDI ports we always use a shared PLL. */
1100 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1101 return 0;
1102
1103 pll = &dev_priv->shared_dplls[dpll];
1104 state = &pll->config.hw_state;
1105
1106 clock.m1 = 2;
1107 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1108 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1109 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1110 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1111 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1112 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1113
1114 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301115}
1116
1117static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1118 struct intel_crtc_state *pipe_config)
1119{
1120 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1121 enum port port = intel_ddi_get_encoder_port(encoder);
1122 uint32_t dpll = port;
1123
Ville Syrjälä398a0172015-06-30 15:33:51 +03001124 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301125
Ville Syrjälä398a0172015-06-30 15:33:51 +03001126 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301127}
1128
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001129void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001130 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001131{
Damien Lespiau22606a12014-12-12 14:26:57 +00001132 struct drm_device *dev = encoder->base.dev;
1133
1134 if (INTEL_INFO(dev)->gen <= 8)
1135 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001136 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001137 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301138 else if (IS_BROXTON(dev))
1139 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001140}
1141
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001142static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001143hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1144 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001145{
1146 uint64_t freq2k;
1147 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001148 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001149 unsigned budget;
1150
1151 freq2k = clock / 100;
1152
Damien Lespiau63582982015-05-07 18:38:46 +01001153 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001154
1155 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1156 * and directly pass the LC PLL to it. */
1157 if (freq2k == 5400000) {
1158 *n2_out = 2;
1159 *p_out = 1;
1160 *r2_out = 2;
1161 return;
1162 }
1163
1164 /*
1165 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1166 * the WR PLL.
1167 *
1168 * We want R so that REF_MIN <= Ref <= REF_MAX.
1169 * Injecting R2 = 2 * R gives:
1170 * REF_MAX * r2 > LC_FREQ * 2 and
1171 * REF_MIN * r2 < LC_FREQ * 2
1172 *
1173 * Which means the desired boundaries for r2 are:
1174 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1175 *
1176 */
1177 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1178 r2 <= LC_FREQ * 2 / REF_MIN;
1179 r2++) {
1180
1181 /*
1182 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1183 *
1184 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1185 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1186 * VCO_MAX * r2 > n2 * LC_FREQ and
1187 * VCO_MIN * r2 < n2 * LC_FREQ)
1188 *
1189 * Which means the desired boundaries for n2 are:
1190 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1191 */
1192 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1193 n2 <= VCO_MAX * r2 / LC_FREQ;
1194 n2++) {
1195
1196 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001197 hsw_wrpll_update_rnp(freq2k, budget,
1198 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001199 }
1200 }
1201
1202 *n2_out = best.n2;
1203 *p_out = best.p;
1204 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001205}
1206
Damien Lespiau0220ab62014-07-29 18:06:22 +01001207static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001208hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001209 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001210 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001211{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001212 int clock = crtc_state->port_clock;
1213
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001214 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001215 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001216 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001217 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001218
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001219 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001220
Daniel Vetter114fe482014-06-25 22:01:48 +03001221 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001222 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1223 WRPLL_DIVIDER_POST(p);
1224
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001225 memset(&crtc_state->dpll_hw_state, 0,
1226 sizeof(crtc_state->dpll_hw_state));
1227
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001228 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001229
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001230 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001231 if (pll == NULL) {
1232 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1233 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001234 return false;
1235 }
1236
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001237 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001238 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1239 struct drm_atomic_state *state = crtc_state->base.state;
1240 struct intel_shared_dpll_config *spll =
1241 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1242
1243 if (spll->crtc_mask &&
1244 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1245 return false;
1246
1247 crtc_state->shared_dpll = DPLL_ID_SPLL;
1248 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1249 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001250 }
1251
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001252 return true;
1253}
1254
Damien Lespiaudc253812015-06-25 16:15:06 +01001255struct skl_wrpll_context {
1256 uint64_t min_deviation; /* current minimal deviation */
1257 uint64_t central_freq; /* chosen central freq */
1258 uint64_t dco_freq; /* chosen dco freq */
1259 unsigned int p; /* chosen divider */
1260};
1261
1262static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1263{
1264 memset(ctx, 0, sizeof(*ctx));
1265
1266 ctx->min_deviation = U64_MAX;
1267}
1268
1269/* DCO freq must be within +1%/-6% of the DCO central freq */
1270#define SKL_DCO_MAX_PDEVIATION 100
1271#define SKL_DCO_MAX_NDEVIATION 600
1272
1273static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1274 uint64_t central_freq,
1275 uint64_t dco_freq,
1276 unsigned int divider)
1277{
1278 uint64_t deviation;
1279
1280 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1281 central_freq);
1282
1283 /* positive deviation */
1284 if (dco_freq >= central_freq) {
1285 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1286 deviation < ctx->min_deviation) {
1287 ctx->min_deviation = deviation;
1288 ctx->central_freq = central_freq;
1289 ctx->dco_freq = dco_freq;
1290 ctx->p = divider;
1291 }
1292 /* negative deviation */
1293 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
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 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001300}
1301
1302static void skl_wrpll_get_multipliers(unsigned int p,
1303 unsigned int *p0 /* out */,
1304 unsigned int *p1 /* out */,
1305 unsigned int *p2 /* out */)
1306{
1307 /* even dividers */
1308 if (p % 2 == 0) {
1309 unsigned int half = p / 2;
1310
1311 if (half == 1 || half == 2 || half == 3 || half == 5) {
1312 *p0 = 2;
1313 *p1 = 1;
1314 *p2 = half;
1315 } else if (half % 2 == 0) {
1316 *p0 = 2;
1317 *p1 = half / 2;
1318 *p2 = 2;
1319 } else if (half % 3 == 0) {
1320 *p0 = 3;
1321 *p1 = half / 3;
1322 *p2 = 2;
1323 } else if (half % 7 == 0) {
1324 *p0 = 7;
1325 *p1 = half / 7;
1326 *p2 = 2;
1327 }
1328 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1329 *p0 = 3;
1330 *p1 = 1;
1331 *p2 = p / 3;
1332 } else if (p == 5 || p == 7) {
1333 *p0 = p;
1334 *p1 = 1;
1335 *p2 = 1;
1336 } else if (p == 15) {
1337 *p0 = 3;
1338 *p1 = 1;
1339 *p2 = 5;
1340 } else if (p == 21) {
1341 *p0 = 7;
1342 *p1 = 1;
1343 *p2 = 3;
1344 } else if (p == 35) {
1345 *p0 = 7;
1346 *p1 = 1;
1347 *p2 = 5;
1348 }
1349}
1350
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001351struct skl_wrpll_params {
1352 uint32_t dco_fraction;
1353 uint32_t dco_integer;
1354 uint32_t qdiv_ratio;
1355 uint32_t qdiv_mode;
1356 uint32_t kdiv;
1357 uint32_t pdiv;
1358 uint32_t central_freq;
1359};
1360
Damien Lespiau76516fb2015-05-07 18:38:42 +01001361static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1362 uint64_t afe_clock,
1363 uint64_t central_freq,
1364 uint32_t p0, uint32_t p1, uint32_t p2)
1365{
1366 uint64_t dco_freq;
1367
Damien Lespiau76516fb2015-05-07 18:38:42 +01001368 switch (central_freq) {
1369 case 9600000000ULL:
1370 params->central_freq = 0;
1371 break;
1372 case 9000000000ULL:
1373 params->central_freq = 1;
1374 break;
1375 case 8400000000ULL:
1376 params->central_freq = 3;
1377 }
1378
1379 switch (p0) {
1380 case 1:
1381 params->pdiv = 0;
1382 break;
1383 case 2:
1384 params->pdiv = 1;
1385 break;
1386 case 3:
1387 params->pdiv = 2;
1388 break;
1389 case 7:
1390 params->pdiv = 4;
1391 break;
1392 default:
1393 WARN(1, "Incorrect PDiv\n");
1394 }
1395
1396 switch (p2) {
1397 case 5:
1398 params->kdiv = 0;
1399 break;
1400 case 2:
1401 params->kdiv = 1;
1402 break;
1403 case 3:
1404 params->kdiv = 2;
1405 break;
1406 case 1:
1407 params->kdiv = 3;
1408 break;
1409 default:
1410 WARN(1, "Incorrect KDiv\n");
1411 }
1412
1413 params->qdiv_ratio = p1;
1414 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1415
1416 dco_freq = p0 * p1 * p2 * afe_clock;
1417
1418 /*
1419 * Intermediate values are in Hz.
1420 * Divide by MHz to match bsepc
1421 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001422 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001423 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001424 div_u64((div_u64(dco_freq, 24) -
1425 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001426}
1427
Damien Lespiau318bd822015-05-07 18:38:40 +01001428static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001429skl_ddi_calculate_wrpll(int clock /* in Hz */,
1430 struct skl_wrpll_params *wrpll_params)
1431{
1432 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001433 uint64_t dco_central_freq[3] = {8400000000ULL,
1434 9000000000ULL,
1435 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001436 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1437 24, 28, 30, 32, 36, 40, 42, 44,
1438 48, 52, 54, 56, 60, 64, 66, 68,
1439 70, 72, 76, 78, 80, 84, 88, 90,
1440 92, 96, 98 };
1441 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1442 static const struct {
1443 const int *list;
1444 int n_dividers;
1445 } dividers[] = {
1446 { even_dividers, ARRAY_SIZE(even_dividers) },
1447 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1448 };
1449 struct skl_wrpll_context ctx;
1450 unsigned int dco, d, i;
1451 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001452
Damien Lespiaudc253812015-06-25 16:15:06 +01001453 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001454
Damien Lespiaudc253812015-06-25 16:15:06 +01001455 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1456 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1457 for (i = 0; i < dividers[d].n_dividers; i++) {
1458 unsigned int p = dividers[d].list[i];
1459 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001460
Damien Lespiaudc253812015-06-25 16:15:06 +01001461 skl_wrpll_try_divider(&ctx,
1462 dco_central_freq[dco],
1463 dco_freq,
1464 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001465 /*
1466 * Skip the remaining dividers if we're sure to
1467 * have found the definitive divider, we can't
1468 * improve a 0 deviation.
1469 */
1470 if (ctx.min_deviation == 0)
1471 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001472 }
1473 }
Damien Lespiau267db662015-06-25 16:19:24 +01001474
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001475skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001476 /*
1477 * If a solution is found with an even divider, prefer
1478 * this one.
1479 */
1480 if (d == 0 && ctx.p)
1481 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001482 }
1483
Damien Lespiaudc253812015-06-25 16:15:06 +01001484 if (!ctx.p) {
1485 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001486 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001487 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001488
Damien Lespiaudc253812015-06-25 16:15:06 +01001489 /*
1490 * gcc incorrectly analyses that these can be used without being
1491 * initialized. To be fair, it's hard to guess.
1492 */
1493 p0 = p1 = p2 = 0;
1494 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1495 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1496 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001497
Damien Lespiau318bd822015-05-07 18:38:40 +01001498 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001499}
1500
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001501static bool
1502skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001503 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001504 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001505{
1506 struct intel_shared_dpll *pll;
1507 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001508 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001509
1510 /*
1511 * See comment in intel_dpll_hw_state to understand why we always use 0
1512 * as the DPLL id in this function.
1513 */
1514
1515 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1516
1517 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1518 struct skl_wrpll_params wrpll_params = { 0, };
1519
1520 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1521
Damien Lespiau318bd822015-05-07 18:38:40 +01001522 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1523 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001524
1525 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1526 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1527 wrpll_params.dco_integer;
1528
1529 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1530 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1531 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1532 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1533 wrpll_params.central_freq;
Lyude78385cb2016-02-02 10:49:43 -05001534 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1535 intel_encoder->type == INTEL_OUTPUT_DP_MST) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001536 switch (crtc_state->port_clock / 2) {
1537 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001538 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001539 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001540 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001541 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001542 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001543 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001544 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001545 break;
1546 }
1547
1548 cfgcr1 = cfgcr2 = 0;
Lyude5a01d5b2016-02-02 09:35:09 -05001549 } else if (intel_encoder->type == INTEL_OUTPUT_EDP) {
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001550 return true;
Lyude5a01d5b2016-02-02 09:35:09 -05001551 } else
1552 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001553
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001554 memset(&crtc_state->dpll_hw_state, 0,
1555 sizeof(crtc_state->dpll_hw_state));
1556
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001557 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1558 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1559 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001560
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001561 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001562 if (pll == NULL) {
1563 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1564 pipe_name(intel_crtc->pipe));
1565 return false;
1566 }
1567
1568 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001569 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001570
1571 return true;
1572}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001573
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301574/* bxt clock parameters */
1575struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301576 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301577 uint32_t p1;
1578 uint32_t p2;
1579 uint32_t m2_int;
1580 uint32_t m2_frac;
1581 bool m2_frac_en;
1582 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301583};
1584
1585/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301586static const struct bxt_clk_div bxt_dp_clk_val[] = {
1587 {162000, 4, 2, 32, 1677722, 1, 1},
1588 {270000, 4, 1, 27, 0, 0, 1},
1589 {540000, 2, 1, 27, 0, 0, 1},
1590 {216000, 3, 2, 32, 1677722, 1, 1},
1591 {243000, 4, 1, 24, 1258291, 1, 1},
1592 {324000, 4, 1, 32, 1677722, 1, 1},
1593 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301594};
1595
1596static bool
1597bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1598 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001599 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301600{
1601 struct intel_shared_dpll *pll;
1602 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301603 int vco = 0;
1604 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301605 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001606 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301607
1608 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1609 intel_clock_t best_clock;
1610
1611 /* Calculate HDMI div */
1612 /*
1613 * FIXME: tie the following calculation into
1614 * i9xx_crtc_compute_clock
1615 */
1616 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1617 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1618 clock, pipe_name(intel_crtc->pipe));
1619 return false;
1620 }
1621
1622 clk_div.p1 = best_clock.p1;
1623 clk_div.p2 = best_clock.p2;
1624 WARN_ON(best_clock.m1 != 2);
1625 clk_div.n = best_clock.n;
1626 clk_div.m2_int = best_clock.m2 >> 22;
1627 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1628 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1629
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301630 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301631 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1632 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301633 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301634
Sonika Jindal64987fc2015-05-26 17:50:13 +05301635 clk_div = bxt_dp_clk_val[0];
1636 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1637 if (bxt_dp_clk_val[i].clock == clock) {
1638 clk_div = bxt_dp_clk_val[i];
1639 break;
1640 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301641 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301642 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1643 }
1644
Vandana Kannane6292552015-07-01 17:02:57 +05301645 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301646 prop_coef = 4;
1647 int_coef = 9;
1648 gain_ctl = 3;
1649 targ_cnt = 8;
1650 } else if ((vco > 5400000 && vco < 6200000) ||
1651 (vco >= 4800000 && vco < 5400000)) {
1652 prop_coef = 5;
1653 int_coef = 11;
1654 gain_ctl = 3;
1655 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301656 } else if (vco == 5400000) {
1657 prop_coef = 3;
1658 int_coef = 8;
1659 gain_ctl = 1;
1660 targ_cnt = 9;
1661 } else {
1662 DRM_ERROR("Invalid VCO\n");
1663 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301664 }
1665
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001666 memset(&crtc_state->dpll_hw_state, 0,
1667 sizeof(crtc_state->dpll_hw_state));
1668
Vandana Kannane0681e32015-05-13 12:20:35 +05301669 if (clock > 270000)
1670 lanestagger = 0x18;
1671 else if (clock > 135000)
1672 lanestagger = 0x0d;
1673 else if (clock > 67000)
1674 lanestagger = 0x07;
1675 else if (clock > 33000)
1676 lanestagger = 0x04;
1677 else
1678 lanestagger = 0x02;
1679
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301680 crtc_state->dpll_hw_state.ebb0 =
1681 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1682 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1683 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1684 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1685
1686 if (clk_div.m2_frac_en)
1687 crtc_state->dpll_hw_state.pll3 =
1688 PORT_PLL_M2_FRAC_ENABLE;
1689
1690 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301691 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301692 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301693 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301694
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301695 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1696
Imre Deak05712c12015-06-18 17:25:54 +03001697 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1698
Vandana Kannane6292552015-07-01 17:02:57 +05301699 crtc_state->dpll_hw_state.pll10 =
1700 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1701 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301702
Imre Deak05712c12015-06-18 17:25:54 +03001703 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1704
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301705 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301706 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301707
1708 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1709 if (pll == NULL) {
1710 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1711 pipe_name(intel_crtc->pipe));
1712 return false;
1713 }
1714
1715 /* shared DPLL id 0 is DPLL A */
1716 crtc_state->ddi_pll_sel = pll->id;
1717
1718 return true;
1719}
1720
Damien Lespiau0220ab62014-07-29 18:06:22 +01001721/*
1722 * Tries to find a *shared* PLL for the CRTC and store it in
1723 * intel_crtc->ddi_pll_sel.
1724 *
1725 * For private DPLLs, compute_config() should do the selection for us. This
1726 * function should be folded into compute_config() eventually.
1727 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001728bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1729 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001730{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001731 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001732 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001733 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001734
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001735 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001736 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001737 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301738 else if (IS_BROXTON(dev))
1739 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001740 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001741 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001742 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001743 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001744}
1745
Paulo Zanonidae84792012-10-15 15:51:30 -03001746void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1747{
1748 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1749 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1750 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001751 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001752 int type = intel_encoder->type;
1753 uint32_t temp;
1754
Dave Airlie0e32b392014-05-02 14:02:48 +10001755 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001756 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001757 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001758 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001759 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001760 break;
1761 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001762 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001763 break;
1764 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001765 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001766 break;
1767 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001768 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001769 break;
1770 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001771 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001772 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001773 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001774 }
1775}
1776
Dave Airlie0e32b392014-05-02 14:02:48 +10001777void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1778{
1779 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1780 struct drm_device *dev = crtc->dev;
1781 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001782 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001783 uint32_t temp;
1784 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1785 if (state == true)
1786 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1787 else
1788 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1789 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1790}
1791
Damien Lespiau8228c252013-03-07 15:30:27 +00001792void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001793{
1794 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1795 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001796 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001797 struct drm_device *dev = crtc->dev;
1798 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001799 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001800 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001801 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001802 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001803 uint32_t temp;
1804
Paulo Zanoniad80a812012-10-24 16:06:19 -02001805 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1806 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001807 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001808
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001809 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001810 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001811 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001812 break;
1813 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001814 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001815 break;
1816 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001817 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001818 break;
1819 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001820 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001821 break;
1822 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001823 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001824 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001825
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001826 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001827 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001828 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001829 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001830
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001831 if (cpu_transcoder == TRANSCODER_EDP) {
1832 switch (pipe) {
1833 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001834 /* On Haswell, can only use the always-on power well for
1835 * eDP when not using the panel fitter, and when not
1836 * using motion blur mitigation (which we don't
1837 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001838 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001839 (intel_crtc->config->pch_pfit.enabled ||
1840 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001841 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1842 else
1843 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001844 break;
1845 case PIPE_B:
1846 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1847 break;
1848 case PIPE_C:
1849 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1850 break;
1851 default:
1852 BUG();
1853 break;
1854 }
1855 }
1856
Paulo Zanoni7739c332012-10-15 15:51:29 -03001857 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001858 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001859 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001860 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001861 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001862
Paulo Zanoni7739c332012-10-15 15:51:29 -03001863 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001864 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001865 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001866
1867 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1868 type == INTEL_OUTPUT_EDP) {
1869 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1870
Dave Airlie0e32b392014-05-02 14:02:48 +10001871 if (intel_dp->is_mst) {
1872 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1873 } else
1874 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1875
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001876 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001877 } else if (type == INTEL_OUTPUT_DP_MST) {
1878 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1879
1880 if (intel_dp->is_mst) {
1881 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1882 } else
1883 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001884
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001885 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001886 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001887 WARN(1, "Invalid encoder type %d for pipe %c\n",
1888 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001889 }
1890
Paulo Zanoniad80a812012-10-24 16:06:19 -02001891 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001892}
1893
Paulo Zanoniad80a812012-10-24 16:06:19 -02001894void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1895 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001896{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001897 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001898 uint32_t val = I915_READ(reg);
1899
Dave Airlie0e32b392014-05-02 14:02:48 +10001900 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001901 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001902 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001903}
1904
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001905bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1906{
1907 struct drm_device *dev = intel_connector->base.dev;
1908 struct drm_i915_private *dev_priv = dev->dev_private;
1909 struct intel_encoder *intel_encoder = intel_connector->encoder;
1910 int type = intel_connector->base.connector_type;
1911 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1912 enum pipe pipe = 0;
1913 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001914 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001915 uint32_t tmp;
1916
Paulo Zanoni882244a2014-04-01 14:55:12 -03001917 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001918 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001919 return false;
1920
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001921 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1922 return false;
1923
1924 if (port == PORT_A)
1925 cpu_transcoder = TRANSCODER_EDP;
1926 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001927 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001928
1929 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1930
1931 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1932 case TRANS_DDI_MODE_SELECT_HDMI:
1933 case TRANS_DDI_MODE_SELECT_DVI:
1934 return (type == DRM_MODE_CONNECTOR_HDMIA);
1935
1936 case TRANS_DDI_MODE_SELECT_DP_SST:
1937 if (type == DRM_MODE_CONNECTOR_eDP)
1938 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001939 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001940 case TRANS_DDI_MODE_SELECT_DP_MST:
1941 /* if the transcoder is in MST state then
1942 * connector isn't connected */
1943 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001944
1945 case TRANS_DDI_MODE_SELECT_FDI:
1946 return (type == DRM_MODE_CONNECTOR_VGA);
1947
1948 default:
1949 return false;
1950 }
1951}
1952
Daniel Vetter85234cd2012-07-02 13:27:29 +02001953bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1954 enum pipe *pipe)
1955{
1956 struct drm_device *dev = encoder->base.dev;
1957 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001958 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02001959 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02001960 u32 tmp;
1961 int i;
1962
Imre Deak6d129be2014-03-05 16:20:54 +02001963 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001964 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02001965 return false;
1966
Paulo Zanonife43d3f2012-10-15 15:51:39 -03001967 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001968
1969 if (!(tmp & DDI_BUF_CTL_ENABLE))
1970 return false;
1971
Paulo Zanoniad80a812012-10-24 16:06:19 -02001972 if (port == PORT_A) {
1973 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02001974
Paulo Zanoniad80a812012-10-24 16:06:19 -02001975 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
1976 case TRANS_DDI_EDP_INPUT_A_ON:
1977 case TRANS_DDI_EDP_INPUT_A_ONOFF:
1978 *pipe = PIPE_A;
1979 break;
1980 case TRANS_DDI_EDP_INPUT_B_ONOFF:
1981 *pipe = PIPE_B;
1982 break;
1983 case TRANS_DDI_EDP_INPUT_C_ONOFF:
1984 *pipe = PIPE_C;
1985 break;
1986 }
1987
1988 return true;
1989 } else {
1990 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
1991 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
1992
1993 if ((tmp & TRANS_DDI_PORT_MASK)
1994 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10001995 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
1996 return false;
1997
Paulo Zanoniad80a812012-10-24 16:06:19 -02001998 *pipe = i;
1999 return true;
2000 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002001 }
2002 }
2003
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002004 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002005
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002006 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002007}
2008
Paulo Zanonifc914632012-10-05 12:05:54 -03002009void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2010{
2011 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302012 struct drm_device *dev = crtc->dev;
2013 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002014 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2015 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002016 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002017
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002018 if (cpu_transcoder != TRANSCODER_EDP)
2019 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2020 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002021}
2022
2023void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2024{
2025 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002026 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002027
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002028 if (cpu_transcoder != TRANSCODER_EDP)
2029 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2030 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002031}
2032
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002033static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
2034 u32 level, enum port port, int type)
David Weinehallf8896f52015-06-25 11:11:03 +03002035{
David Weinehallf8896f52015-06-25 11:11:03 +03002036 const struct ddi_buf_trans *ddi_translations;
2037 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002038 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002039 int n_entries;
2040 u32 reg;
2041
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002042 /* VBT may override standard boost values */
2043 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2044 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2045
David Weinehallf8896f52015-06-25 11:11:03 +03002046 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002047 if (dp_iboost) {
2048 iboost = dp_iboost;
2049 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002050 ddi_translations = skl_get_buf_trans_dp(dev_priv, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002051 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002052 }
David Weinehallf8896f52015-06-25 11:11:03 +03002053 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002054 if (dp_iboost) {
2055 iboost = dp_iboost;
2056 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002057 ddi_translations = skl_get_buf_trans_edp(dev_priv, &n_entries);
Ville Syrjälä10afa0b2015-12-08 19:59:43 +02002058
2059 if (WARN_ON(port != PORT_A &&
2060 port != PORT_E && n_entries > 9))
2061 n_entries = 9;
2062
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002063 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002064 }
David Weinehallf8896f52015-06-25 11:11:03 +03002065 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002066 if (hdmi_iboost) {
2067 iboost = hdmi_iboost;
2068 } else {
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002069 ddi_translations = skl_get_buf_trans_hdmi(dev_priv, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002070 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002071 }
David Weinehallf8896f52015-06-25 11:11:03 +03002072 } else {
2073 return;
2074 }
2075
2076 /* Make sure that the requested I_boost is valid */
2077 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2078 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2079 return;
2080 }
2081
2082 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2083 reg &= ~BALANCE_LEG_MASK(port);
2084 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2085
2086 if (iboost)
2087 reg |= iboost << BALANCE_LEG_SHIFT(port);
2088 else
2089 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2090
2091 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2092}
2093
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002094static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
2095 u32 level, enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302096{
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302097 const struct bxt_ddi_buf_trans *ddi_translations;
2098 u32 n_entries, i;
2099 uint32_t val;
2100
Sonika Jindald9d70002015-09-24 10:24:56 +05302101 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2102 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2103 ddi_translations = bxt_ddi_translations_edp;
2104 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2105 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302106 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2107 ddi_translations = bxt_ddi_translations_dp;
2108 } else if (type == INTEL_OUTPUT_HDMI) {
2109 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2110 ddi_translations = bxt_ddi_translations_hdmi;
2111 } else {
2112 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2113 type);
2114 return;
2115 }
2116
2117 /* Check if default value has to be used */
2118 if (level >= n_entries ||
2119 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2120 for (i = 0; i < n_entries; i++) {
2121 if (ddi_translations[i].default_index) {
2122 level = i;
2123 break;
2124 }
2125 }
2126 }
2127
2128 /*
2129 * While we write to the group register to program all lanes at once we
2130 * can read only lane registers and we pick lanes 0/1 for that.
2131 */
2132 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2133 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2134 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2135
2136 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2137 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2138 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2139 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2140 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2141
2142 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302143 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302144 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302145 val |= SCALE_DCOMP_METHOD;
2146
2147 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2148 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2149
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302150 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2151
2152 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2153 val &= ~DE_EMPHASIS;
2154 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2155 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2156
2157 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2158 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2159 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2160}
2161
David Weinehallf8896f52015-06-25 11:11:03 +03002162static uint32_t translate_signal_level(int signal_levels)
2163{
2164 uint32_t level;
2165
2166 switch (signal_levels) {
2167 default:
2168 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2169 signal_levels);
2170 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2171 level = 0;
2172 break;
2173 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2174 level = 1;
2175 break;
2176 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2177 level = 2;
2178 break;
2179 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2180 level = 3;
2181 break;
2182
2183 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2184 level = 4;
2185 break;
2186 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2187 level = 5;
2188 break;
2189 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2190 level = 6;
2191 break;
2192
2193 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2194 level = 7;
2195 break;
2196 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2197 level = 8;
2198 break;
2199
2200 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2201 level = 9;
2202 break;
2203 }
2204
2205 return level;
2206}
2207
2208uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2209{
2210 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002211 struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
David Weinehallf8896f52015-06-25 11:11:03 +03002212 struct intel_encoder *encoder = &dport->base;
2213 uint8_t train_set = intel_dp->train_set[0];
2214 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2215 DP_TRAIN_PRE_EMPHASIS_MASK);
2216 enum port port = dport->port;
2217 uint32_t level;
2218
2219 level = translate_signal_level(signal_levels);
2220
Ville Syrjälä78ab0ba2015-12-08 19:59:41 +02002221 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
2222 skl_ddi_set_iboost(dev_priv, level, port, encoder->type);
2223 else if (IS_BROXTON(dev_priv))
2224 bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
David Weinehallf8896f52015-06-25 11:11:03 +03002225
2226 return DDI_BUF_TRANS_SELECT(level);
2227}
2228
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002229void intel_ddi_clk_select(struct intel_encoder *encoder,
2230 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002231{
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002232 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2233 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002234
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002235 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2236 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002237 uint32_t val;
2238
Damien Lespiau5416d872014-11-14 17:24:33 +00002239 /*
2240 * DPLL0 is used for eDP and is the only "private" DPLL (as
2241 * opposed to shared) on SKL
2242 */
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002243 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002244 WARN_ON(dpll != SKL_DPLL0);
2245
2246 val = I915_READ(DPLL_CTRL1);
2247
2248 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2249 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002250 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002251 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002252
2253 I915_WRITE(DPLL_CTRL1, val);
2254 POSTING_READ(DPLL_CTRL1);
2255 }
2256
2257 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002258 val = I915_READ(DPLL_CTRL2);
2259
2260 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2261 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2262 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2263 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2264
2265 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002266
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002267 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2268 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2269 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002270 }
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002271}
2272
2273static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2274{
2275 struct drm_encoder *encoder = &intel_encoder->base;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002276 struct drm_i915_private *dev_priv = to_i915(encoder->dev);
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002277 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2278 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2279 int type = intel_encoder->type;
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002280
2281 intel_prepare_ddi_buffer(intel_encoder);
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002282
2283 if (type == INTEL_OUTPUT_EDP) {
2284 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2285 intel_edp_panel_on(intel_dp);
2286 }
2287
2288 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002289
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002290 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002291 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002292
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002293 intel_dp_set_link_params(intel_dp, crtc->config);
2294
Dave Airlie44905a272014-05-02 13:36:43 +10002295 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002296
2297 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2298 intel_dp_start_link_train(intel_dp);
Ville Syrjälä6a7e4f92015-12-08 19:59:44 +02002299 if (port != PORT_A || INTEL_INFO(dev_priv)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002300 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002301 } else if (type == INTEL_OUTPUT_HDMI) {
2302 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2303
2304 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002305 crtc->config->has_hdmi_sink,
2306 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002307 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002308}
2309
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002310static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002311{
2312 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002313 struct drm_device *dev = encoder->dev;
2314 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002315 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002316 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002317 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002318 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002319
2320 val = I915_READ(DDI_BUF_CTL(port));
2321 if (val & DDI_BUF_CTL_ENABLE) {
2322 val &= ~DDI_BUF_CTL_ENABLE;
2323 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002324 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002325 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002326
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002327 val = I915_READ(DP_TP_CTL(port));
2328 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2329 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2330 I915_WRITE(DP_TP_CTL(port), val);
2331
2332 if (wait)
2333 intel_wait_ddi_buf_idle(dev_priv, port);
2334
Jani Nikula76bb80e2013-11-15 15:29:57 +02002335 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002336 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002337 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002338 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002339 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002340 }
2341
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002342 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002343 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2344 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302345 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002346 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002347}
2348
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002349static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002350{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002351 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002352 struct drm_crtc *crtc = encoder->crtc;
2353 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002354 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002355 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002356 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2357 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002358
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002359 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002360 struct intel_digital_port *intel_dig_port =
2361 enc_to_dig_port(encoder);
2362
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002363 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2364 * are ignored so nothing special needs to be done besides
2365 * enabling the port.
2366 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002367 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07002368 intel_dig_port->saved_port_bits |
2369 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002370 } else if (type == INTEL_OUTPUT_EDP) {
2371 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2372
Vandana Kannan23f08d82014-11-13 14:55:22 +00002373 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002374 intel_dp_stop_link_train(intel_dp);
2375
Daniel Vetter4be73782014-01-17 14:39:48 +01002376 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002377 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302378 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002379 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002380
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002381 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002382 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002383 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002384 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002385}
2386
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002387static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002388{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002389 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002390 struct drm_crtc *crtc = encoder->crtc;
2391 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002392 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002393 struct drm_device *dev = encoder->dev;
2394 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002395
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002396 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002397 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002398 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2399 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002400
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002401 if (type == INTEL_OUTPUT_EDP) {
2402 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2403
Vandana Kannanc3955782015-01-22 15:17:40 +05302404 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002405 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002406 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002407 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002408}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002409
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002410static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002411 struct intel_shared_dpll *pll)
2412{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002413 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002414 POSTING_READ(WRPLL_CTL(pll->id));
2415 udelay(20);
2416}
2417
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002418static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002419 struct intel_shared_dpll *pll)
2420{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002421 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2422 POSTING_READ(SPLL_CTL);
2423 udelay(20);
2424}
2425
2426static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2427 struct intel_shared_dpll *pll)
2428{
Daniel Vetter12030432014-06-25 22:02:00 +03002429 uint32_t val;
2430
2431 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002432 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2433 POSTING_READ(WRPLL_CTL(pll->id));
2434}
2435
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002436static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2437 struct intel_shared_dpll *pll)
2438{
2439 uint32_t val;
2440
2441 val = I915_READ(SPLL_CTL);
2442 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2443 POSTING_READ(SPLL_CTL);
2444}
2445
2446static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2447 struct intel_shared_dpll *pll,
2448 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002449{
2450 uint32_t val;
2451
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002452 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002453 return false;
2454
2455 val = I915_READ(WRPLL_CTL(pll->id));
2456 hw_state->wrpll = val;
2457
2458 return val & WRPLL_PLL_ENABLE;
2459}
2460
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002461static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2462 struct intel_shared_dpll *pll,
2463 struct intel_dpll_hw_state *hw_state)
2464{
2465 uint32_t val;
2466
2467 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2468 return false;
2469
2470 val = I915_READ(SPLL_CTL);
2471 hw_state->spll = val;
2472
2473 return val & SPLL_PLL_ENABLE;
2474}
2475
2476
Damien Lespiauca1381b2014-07-15 15:05:33 +01002477static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002478 "WRPLL 1",
2479 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002480 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002481};
2482
Damien Lespiau143b3072014-07-29 18:06:19 +01002483static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002484{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002485 int i;
2486
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002487 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002488
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002489 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002490 dev_priv->shared_dplls[i].id = i;
2491 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002492 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2493 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002494 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002495 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002496 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002497
2498 /* SPLL is special, but needs to be initialized anyway.. */
2499 dev_priv->shared_dplls[i].id = i;
2500 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2501 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2502 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2503 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2504
Damien Lespiau143b3072014-07-29 18:06:19 +01002505}
2506
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002507static const char * const skl_ddi_pll_names[] = {
2508 "DPLL 1",
2509 "DPLL 2",
2510 "DPLL 3",
2511};
2512
2513struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002514 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002515};
2516
2517/* this array is indexed by the *shared* pll id */
2518static const struct skl_dpll_regs skl_dpll_regs[3] = {
2519 {
2520 /* DPLL 1 */
2521 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002522 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2523 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002524 },
2525 {
2526 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002527 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002528 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2529 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002530 },
2531 {
2532 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002533 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002534 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2535 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002536 },
2537};
2538
2539static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2540 struct intel_shared_dpll *pll)
2541{
2542 uint32_t val;
2543 unsigned int dpll;
2544 const struct skl_dpll_regs *regs = skl_dpll_regs;
2545
2546 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2547 dpll = pll->id + 1;
2548
2549 val = I915_READ(DPLL_CTRL1);
2550
2551 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002552 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002553 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2554
2555 I915_WRITE(DPLL_CTRL1, val);
2556 POSTING_READ(DPLL_CTRL1);
2557
2558 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2559 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2560 POSTING_READ(regs[pll->id].cfgcr1);
2561 POSTING_READ(regs[pll->id].cfgcr2);
2562
2563 /* the enable bit is always bit 31 */
2564 I915_WRITE(regs[pll->id].ctl,
2565 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2566
2567 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2568 DRM_ERROR("DPLL %d not locked\n", dpll);
2569}
2570
2571static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2572 struct intel_shared_dpll *pll)
2573{
2574 const struct skl_dpll_regs *regs = skl_dpll_regs;
2575
2576 /* the enable bit is always bit 31 */
2577 I915_WRITE(regs[pll->id].ctl,
2578 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2579 POSTING_READ(regs[pll->id].ctl);
2580}
2581
2582static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2583 struct intel_shared_dpll *pll,
2584 struct intel_dpll_hw_state *hw_state)
2585{
2586 uint32_t val;
2587 unsigned int dpll;
2588 const struct skl_dpll_regs *regs = skl_dpll_regs;
2589
2590 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2591 return false;
2592
2593 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2594 dpll = pll->id + 1;
2595
2596 val = I915_READ(regs[pll->id].ctl);
2597 if (!(val & LCPLL_PLL_ENABLE))
2598 return false;
2599
2600 val = I915_READ(DPLL_CTRL1);
2601 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2602
2603 /* avoid reading back stale values if HDMI mode is not enabled */
2604 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2605 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2606 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2607 }
2608
2609 return true;
2610}
2611
2612static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2613{
2614 int i;
2615
2616 dev_priv->num_shared_dpll = 3;
2617
2618 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2619 dev_priv->shared_dplls[i].id = i;
2620 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2621 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2622 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2623 dev_priv->shared_dplls[i].get_hw_state =
2624 skl_ddi_pll_get_hw_state;
2625 }
2626}
2627
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302628static void broxton_phy_init(struct drm_i915_private *dev_priv,
2629 enum dpio_phy phy)
2630{
2631 enum port port;
2632 uint32_t val;
2633
2634 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2635 val |= GT_DISPLAY_POWER_ON(phy);
2636 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2637
2638 /* Considering 10ms timeout until BSpec is updated */
2639 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2640 DRM_ERROR("timeout during PHY%d power on\n", phy);
2641
2642 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2643 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2644 int lane;
2645
2646 for (lane = 0; lane < 4; lane++) {
2647 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2648 /*
2649 * Note that on CHV this flag is called UPAR, but has
2650 * the same function.
2651 */
2652 val &= ~LATENCY_OPTIM;
2653 if (lane != 1)
2654 val |= LATENCY_OPTIM;
2655
2656 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2657 }
2658 }
2659
2660 /* Program PLL Rcomp code offset */
2661 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2662 val &= ~IREF0RC_OFFSET_MASK;
2663 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2664 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2665
2666 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2667 val &= ~IREF1RC_OFFSET_MASK;
2668 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2669 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2670
2671 /* Program power gating */
2672 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2673 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2674 SUS_CLK_CONFIG;
2675 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2676
2677 if (phy == DPIO_PHY0) {
2678 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2679 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2680 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2681 }
2682
2683 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2684 val &= ~OCL2_LDOFUSE_PWR_DIS;
2685 /*
2686 * On PHY1 disable power on the second channel, since no port is
2687 * connected there. On PHY0 both channels have a port, so leave it
2688 * enabled.
2689 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2690 * power down the second channel on PHY0 as well.
2691 */
2692 if (phy == DPIO_PHY1)
2693 val |= OCL2_LDOFUSE_PWR_DIS;
2694 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2695
2696 if (phy == DPIO_PHY0) {
2697 uint32_t grc_code;
2698 /*
2699 * PHY0 isn't connected to an RCOMP resistor so copy over
2700 * the corresponding calibrated value from PHY1, and disable
2701 * the automatic calibration on PHY0.
2702 */
2703 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2704 10))
2705 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2706
2707 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2708 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2709 grc_code = val << GRC_CODE_FAST_SHIFT |
2710 val << GRC_CODE_SLOW_SHIFT |
2711 val;
2712 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2713
2714 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2715 val |= GRC_DIS | GRC_RDY_OVRD;
2716 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2717 }
2718
2719 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2720 val |= COMMON_RESET_DIS;
2721 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2722}
2723
2724void broxton_ddi_phy_init(struct drm_device *dev)
2725{
2726 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2727 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2728 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2729}
2730
2731static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2732 enum dpio_phy phy)
2733{
2734 uint32_t val;
2735
2736 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2737 val &= ~COMMON_RESET_DIS;
2738 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2739}
2740
2741void broxton_ddi_phy_uninit(struct drm_device *dev)
2742{
2743 struct drm_i915_private *dev_priv = dev->dev_private;
2744
2745 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2746 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2747
2748 /* FIXME: do this in broxton_phy_uninit per phy */
2749 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2750}
2751
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302752static const char * const bxt_ddi_pll_names[] = {
2753 "PORT PLL A",
2754 "PORT PLL B",
2755 "PORT PLL C",
2756};
2757
2758static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2759 struct intel_shared_dpll *pll)
2760{
2761 uint32_t temp;
2762 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2763
2764 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2765 temp &= ~PORT_PLL_REF_SEL;
2766 /* Non-SSC reference */
2767 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2768
2769 /* Disable 10 bit clock */
2770 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2771 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2772 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2773
2774 /* Write P1 & P2 */
2775 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2776 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2777 temp |= pll->config.hw_state.ebb0;
2778 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2779
2780 /* Write M2 integer */
2781 temp = I915_READ(BXT_PORT_PLL(port, 0));
2782 temp &= ~PORT_PLL_M2_MASK;
2783 temp |= pll->config.hw_state.pll0;
2784 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2785
2786 /* Write N */
2787 temp = I915_READ(BXT_PORT_PLL(port, 1));
2788 temp &= ~PORT_PLL_N_MASK;
2789 temp |= pll->config.hw_state.pll1;
2790 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2791
2792 /* Write M2 fraction */
2793 temp = I915_READ(BXT_PORT_PLL(port, 2));
2794 temp &= ~PORT_PLL_M2_FRAC_MASK;
2795 temp |= pll->config.hw_state.pll2;
2796 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2797
2798 /* Write M2 fraction enable */
2799 temp = I915_READ(BXT_PORT_PLL(port, 3));
2800 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2801 temp |= pll->config.hw_state.pll3;
2802 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2803
2804 /* Write coeff */
2805 temp = I915_READ(BXT_PORT_PLL(port, 6));
2806 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2807 temp &= ~PORT_PLL_INT_COEFF_MASK;
2808 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2809 temp |= pll->config.hw_state.pll6;
2810 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2811
2812 /* Write calibration val */
2813 temp = I915_READ(BXT_PORT_PLL(port, 8));
2814 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2815 temp |= pll->config.hw_state.pll8;
2816 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2817
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302818 temp = I915_READ(BXT_PORT_PLL(port, 9));
2819 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002820 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302821 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2822
2823 temp = I915_READ(BXT_PORT_PLL(port, 10));
2824 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2825 temp &= ~PORT_PLL_DCO_AMP_MASK;
2826 temp |= pll->config.hw_state.pll10;
2827 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302828
2829 /* Recalibrate with new settings */
2830 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2831 temp |= PORT_PLL_RECALIBRATE;
2832 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002833 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2834 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302835 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2836
2837 /* Enable PLL */
2838 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2839 temp |= PORT_PLL_ENABLE;
2840 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2841 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2842
2843 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2844 PORT_PLL_LOCK), 200))
2845 DRM_ERROR("PLL %d not locked\n", port);
2846
2847 /*
2848 * While we write to the group register to program all lanes at once we
2849 * can read only lane registers and we pick lanes 0/1 for that.
2850 */
2851 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2852 temp &= ~LANE_STAGGER_MASK;
2853 temp &= ~LANESTAGGER_STRAP_OVRD;
2854 temp |= pll->config.hw_state.pcsdw12;
2855 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2856}
2857
2858static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2859 struct intel_shared_dpll *pll)
2860{
2861 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2862 uint32_t temp;
2863
2864 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2865 temp &= ~PORT_PLL_ENABLE;
2866 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2867 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2868}
2869
2870static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2871 struct intel_shared_dpll *pll,
2872 struct intel_dpll_hw_state *hw_state)
2873{
2874 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2875 uint32_t val;
2876
2877 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2878 return false;
2879
2880 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2881 if (!(val & PORT_PLL_ENABLE))
2882 return false;
2883
2884 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002885 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2886
Imre Deak05712c12015-06-18 17:25:54 +03002887 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2888 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2889
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302890 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002891 hw_state->pll0 &= PORT_PLL_M2_MASK;
2892
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302893 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002894 hw_state->pll1 &= PORT_PLL_N_MASK;
2895
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302896 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002897 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2898
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302899 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002900 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2901
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302902 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002903 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2904 PORT_PLL_INT_COEFF_MASK |
2905 PORT_PLL_GAIN_CTL_MASK;
2906
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302907 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002908 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2909
Imre Deak05712c12015-06-18 17:25:54 +03002910 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2911 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2912
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302913 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002914 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2915 PORT_PLL_DCO_AMP_MASK;
2916
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302917 /*
2918 * While we write to the group register to program all lanes at once we
2919 * can read only lane registers. We configure all lanes the same way, so
2920 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2921 */
2922 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002923 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302924 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2925 hw_state->pcsdw12,
2926 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002927 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302928
2929 return true;
2930}
2931
2932static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2933{
2934 int i;
2935
2936 dev_priv->num_shared_dpll = 3;
2937
2938 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2939 dev_priv->shared_dplls[i].id = i;
2940 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2941 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2942 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2943 dev_priv->shared_dplls[i].get_hw_state =
2944 bxt_ddi_pll_get_hw_state;
2945 }
2946}
2947
Damien Lespiau143b3072014-07-29 18:06:19 +01002948void intel_ddi_pll_init(struct drm_device *dev)
2949{
2950 struct drm_i915_private *dev_priv = dev->dev_private;
2951 uint32_t val = I915_READ(LCPLL_CTL);
2952
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002953 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002954 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302955 else if (IS_BROXTON(dev))
2956 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002957 else
2958 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002959
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002960 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01002961 int cdclk_freq;
2962
2963 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01002964 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05302965 if (skl_sanitize_cdclk(dev_priv))
2966 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02002967 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
2968 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05302969 } else if (IS_BROXTON(dev)) {
2970 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302971 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002972 } else {
2973 /*
2974 * The LCPLL register should be turned on by the BIOS. For now
2975 * let's just check its state and print errors in case
2976 * something is wrong. Don't even try to turn it on.
2977 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002978
Satheeshakrishna M121643c2014-11-13 14:55:15 +00002979 if (val & LCPLL_CD_SOURCE_FCLK)
2980 DRM_ERROR("CDCLK source is not LCPLL\n");
2981
2982 if (val & LCPLL_PLL_DISABLE)
2983 DRM_ERROR("LCPLL is disabled\n");
2984 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002985}
Paulo Zanonic19b0662012-10-15 15:51:41 -03002986
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002987void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03002988{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03002989 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
2990 struct drm_i915_private *dev_priv =
2991 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02002992 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002993 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05302994 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03002995
2996 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
2997 val = I915_READ(DDI_BUF_CTL(port));
2998 if (val & DDI_BUF_CTL_ENABLE) {
2999 val &= ~DDI_BUF_CTL_ENABLE;
3000 I915_WRITE(DDI_BUF_CTL(port), val);
3001 wait = true;
3002 }
3003
3004 val = I915_READ(DP_TP_CTL(port));
3005 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3006 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3007 I915_WRITE(DP_TP_CTL(port), val);
3008 POSTING_READ(DP_TP_CTL(port));
3009
3010 if (wait)
3011 intel_wait_ddi_buf_idle(dev_priv, port);
3012 }
3013
Dave Airlie0e32b392014-05-02 14:02:48 +10003014 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003015 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003016 if (intel_dp->is_mst)
3017 val |= DP_TP_CTL_MODE_MST;
3018 else {
3019 val |= DP_TP_CTL_MODE_SST;
3020 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3021 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3022 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003023 I915_WRITE(DP_TP_CTL(port), val);
3024 POSTING_READ(DP_TP_CTL(port));
3025
3026 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3027 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3028 POSTING_READ(DDI_BUF_CTL(port));
3029
3030 udelay(600);
3031}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003032
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003033void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3034{
3035 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3036 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3037 uint32_t val;
3038
3039 intel_ddi_post_disable(intel_encoder);
3040
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003041 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003042 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003043 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003044
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003045 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003046 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3047 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003048 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003049
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003050 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003051 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003052 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003053
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003054 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003055 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003056 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003057}
3058
Libin Yang3d52ccf2015-12-02 14:09:44 +08003059bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
3060 struct intel_crtc *intel_crtc)
3061{
3062 u32 temp;
3063
3064 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
3065 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
3066 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
3067 return true;
3068 }
3069 return false;
3070}
3071
Ville Syrjälä6801c182013-09-24 14:24:05 +03003072void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003073 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003074{
3075 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3076 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003077 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003078 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003079 u32 temp, flags = 0;
3080
3081 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3082 if (temp & TRANS_DDI_PHSYNC)
3083 flags |= DRM_MODE_FLAG_PHSYNC;
3084 else
3085 flags |= DRM_MODE_FLAG_NHSYNC;
3086 if (temp & TRANS_DDI_PVSYNC)
3087 flags |= DRM_MODE_FLAG_PVSYNC;
3088 else
3089 flags |= DRM_MODE_FLAG_NVSYNC;
3090
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003091 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003092
3093 switch (temp & TRANS_DDI_BPC_MASK) {
3094 case TRANS_DDI_BPC_6:
3095 pipe_config->pipe_bpp = 18;
3096 break;
3097 case TRANS_DDI_BPC_8:
3098 pipe_config->pipe_bpp = 24;
3099 break;
3100 case TRANS_DDI_BPC_10:
3101 pipe_config->pipe_bpp = 30;
3102 break;
3103 case TRANS_DDI_BPC_12:
3104 pipe_config->pipe_bpp = 36;
3105 break;
3106 default:
3107 break;
3108 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003109
3110 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3111 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003112 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003113 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3114
Ville Syrjäläcda0aaa2015-11-26 18:27:07 +02003115 if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003116 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003117 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003118 case TRANS_DDI_MODE_SELECT_DVI:
3119 case TRANS_DDI_MODE_SELECT_FDI:
3120 break;
3121 case TRANS_DDI_MODE_SELECT_DP_SST:
3122 case TRANS_DDI_MODE_SELECT_DP_MST:
3123 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003124 pipe_config->lane_count =
3125 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003126 intel_dp_get_m_n(intel_crtc, pipe_config);
3127 break;
3128 default:
3129 break;
3130 }
Daniel Vetter10214422013-11-18 07:38:16 +01003131
Libin Yang3d52ccf2015-12-02 14:09:44 +08003132 pipe_config->has_audio =
3133 intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003134
Daniel Vetter10214422013-11-18 07:38:16 +01003135 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3136 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3137 /*
3138 * This is a big fat ugly hack.
3139 *
3140 * Some machines in UEFI boot mode provide us a VBT that has 18
3141 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3142 * unknown we fail to light up. Yet the same BIOS boots up with
3143 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3144 * max, not what it tells us to use.
3145 *
3146 * Note: This will still be broken if the eDP panel is not lit
3147 * up by the BIOS, and thus we can't get the mode at module
3148 * load.
3149 */
3150 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3151 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3152 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3153 }
Jesse Barnes11578552014-01-21 12:42:10 -08003154
Damien Lespiau22606a12014-12-12 14:26:57 +00003155 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003156}
3157
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003158static void intel_ddi_destroy(struct drm_encoder *encoder)
3159{
3160 /* HDMI has nothing special to destroy, so we can go with this. */
3161 intel_dp_encoder_destroy(encoder);
3162}
3163
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003164static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003165 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003166{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003167 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003168 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003169
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003170 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003171
Daniel Vettereccb1402013-05-22 00:50:22 +02003172 if (port == PORT_A)
3173 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3174
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003175 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003176 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003177 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003178 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003179}
3180
3181static const struct drm_encoder_funcs intel_ddi_funcs = {
3182 .destroy = intel_ddi_destroy,
3183};
3184
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003185static struct intel_connector *
3186intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3187{
3188 struct intel_connector *connector;
3189 enum port port = intel_dig_port->port;
3190
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003191 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003192 if (!connector)
3193 return NULL;
3194
3195 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3196 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3197 kfree(connector);
3198 return NULL;
3199 }
3200
3201 return connector;
3202}
3203
3204static struct intel_connector *
3205intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3206{
3207 struct intel_connector *connector;
3208 enum port port = intel_dig_port->port;
3209
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003210 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003211 if (!connector)
3212 return NULL;
3213
3214 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3215 intel_hdmi_init_connector(intel_dig_port, connector);
3216
3217 return connector;
3218}
3219
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003220void intel_ddi_init(struct drm_device *dev, enum port port)
3221{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003222 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003223 struct intel_digital_port *intel_dig_port;
3224 struct intel_encoder *intel_encoder;
3225 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003226 bool init_hdmi, init_dp;
Ville Syrjälä10e7bec2015-12-08 19:59:37 +02003227 int max_lanes;
3228
3229 if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
3230 switch (port) {
3231 case PORT_A:
3232 max_lanes = 4;
3233 break;
3234 case PORT_E:
3235 max_lanes = 0;
3236 break;
3237 default:
3238 max_lanes = 4;
3239 break;
3240 }
3241 } else {
3242 switch (port) {
3243 case PORT_A:
3244 max_lanes = 2;
3245 break;
3246 case PORT_E:
3247 max_lanes = 2;
3248 break;
3249 default:
3250 max_lanes = 4;
3251 break;
3252 }
3253 }
Paulo Zanoni311a2092013-09-12 17:12:18 -03003254
3255 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3256 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3257 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3258 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003259 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003260 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003261 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003262 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003263
Daniel Vetterb14c5672013-09-19 12:18:32 +02003264 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003265 if (!intel_dig_port)
3266 return;
3267
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003268 intel_encoder = &intel_dig_port->base;
3269 encoder = &intel_encoder->base;
3270
3271 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
Ville Syrjälä13a3d912015-12-09 16:20:18 +02003272 DRM_MODE_ENCODER_TMDS, NULL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003273
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003274 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003275 intel_encoder->enable = intel_enable_ddi;
3276 intel_encoder->pre_enable = intel_ddi_pre_enable;
3277 intel_encoder->disable = intel_disable_ddi;
3278 intel_encoder->post_disable = intel_ddi_post_disable;
3279 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003280 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003281
3282 intel_dig_port->port = port;
Takashi Iwai0bdf5a02015-11-30 18:19:39 +01003283 dev_priv->dig_port_map[port] = intel_encoder;
Stéphane Marchesinbcf53de2013-07-12 13:54:41 -07003284 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3285 (DDI_BUF_PORT_REVERSAL |
3286 DDI_A_4_LANES);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003287
Matt Roper6c566dc2015-11-05 14:53:32 -08003288 /*
3289 * Bspec says that DDI_A_4_LANES is the only supported configuration
3290 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3291 * wasn't lit up at boot. Force this bit on in our internal
3292 * configuration so that we use the proper lane count for our
3293 * calculations.
3294 */
3295 if (IS_BROXTON(dev) && port == PORT_A) {
3296 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3297 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3298 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
Matt Ropered8d60f2016-01-28 15:09:37 -08003299 max_lanes = 4;
Matt Roper6c566dc2015-11-05 14:53:32 -08003300 }
3301 }
3302
Matt Ropered8d60f2016-01-28 15:09:37 -08003303 intel_dig_port->max_lanes = max_lanes;
3304
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003305 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003306 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003307 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003308
Chris Wilsonf68d6972014-08-04 07:15:09 +01003309 if (init_dp) {
3310 if (!intel_ddi_init_dp_connector(intel_dig_port))
3311 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003312
Chris Wilsonf68d6972014-08-04 07:15:09 +01003313 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303314 /*
3315 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3316 * interrupts to check the external panel connection.
3317 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003318 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303319 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3320 else
3321 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003322 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003323
Paulo Zanoni311a2092013-09-12 17:12:18 -03003324 /* In theory we don't need the encoder->type check, but leave it just in
3325 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003326 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3327 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3328 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003329 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003330
3331 return;
3332
3333err:
3334 drm_encoder_cleanup(encoder);
3335 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003336}