blob: b8b4a3103cf102c0055d49b59a9cb78f3abcddc0 [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
David Weinehallf8896f52015-06-25 11:11:03 +0300304static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
305 enum port port, int type);
306
Imre Deaka1e6ad62015-04-17 19:31:21 +0300307static void ddi_get_encoder_port(struct intel_encoder *intel_encoder,
308 struct intel_digital_port **dig_port,
309 enum port *port)
Paulo Zanonifc914632012-10-05 12:05:54 -0300310{
Paulo Zanoni0bdee302012-10-15 15:51:38 -0300311 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonifc914632012-10-05 12:05:54 -0300312
Jani Nikula8cd21b72015-09-29 10:24:26 +0300313 switch (intel_encoder->type) {
314 case INTEL_OUTPUT_DP_MST:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300315 *dig_port = enc_to_mst(encoder)->primary;
316 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300317 break;
318 case INTEL_OUTPUT_DISPLAYPORT:
319 case INTEL_OUTPUT_EDP:
320 case INTEL_OUTPUT_HDMI:
321 case INTEL_OUTPUT_UNKNOWN:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300322 *dig_port = enc_to_dig_port(encoder);
323 *port = (*dig_port)->port;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300324 break;
325 case INTEL_OUTPUT_ANALOG:
Imre Deaka1e6ad62015-04-17 19:31:21 +0300326 *dig_port = NULL;
327 *port = PORT_E;
Jani Nikula8cd21b72015-09-29 10:24:26 +0300328 break;
329 default:
330 WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type);
331 break;
Paulo Zanonifc914632012-10-05 12:05:54 -0300332 }
333}
334
Imre Deaka1e6ad62015-04-17 19:31:21 +0300335enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
336{
337 struct intel_digital_port *dig_port;
338 enum port port;
339
340 ddi_get_encoder_port(intel_encoder, &dig_port, &port);
341
342 return port;
343}
344
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100345static bool
346intel_dig_port_supports_hdmi(const struct intel_digital_port *intel_dig_port)
347{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200348 return i915_mmio_reg_valid(intel_dig_port->hdmi.hdmi_reg);
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100349}
350
Ville Syrjäläacee2992015-12-08 19:59:39 +0200351static const struct ddi_buf_trans *
352skl_get_buf_trans_dp(struct drm_device *dev, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300353{
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800354 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
Rodrigo Vivi5f8b2532015-08-24 16:48:44 -0700355 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200356 return skl_y_ddi_translations_dp;
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800357 } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) {
David Weinehallf8896f52015-06-25 11:11:03 +0300358 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200359 return skl_u_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300360 } else {
David Weinehallf8896f52015-06-25 11:11:03 +0300361 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
Ville Syrjäläacee2992015-12-08 19:59:39 +0200362 return skl_ddi_translations_dp;
David Weinehallf8896f52015-06-25 11:11:03 +0300363 }
David Weinehallf8896f52015-06-25 11:11:03 +0300364}
365
366static const struct ddi_buf_trans *
Ville Syrjäläacee2992015-12-08 19:59:39 +0200367skl_get_buf_trans_edp(struct drm_device *dev, int *n_entries)
David Weinehallf8896f52015-06-25 11:11:03 +0300368{
Ville Syrjäläacee2992015-12-08 19:59:39 +0200369 struct drm_i915_private *dev_priv = dev->dev_private;
David Weinehallf8896f52015-06-25 11:11:03 +0300370
Rodrigo Vivia5b79912015-12-08 16:58:37 -0800371 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200372 if (dev_priv->edp_low_vswing) {
373 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
374 return skl_y_ddi_translations_edp;
375 } else {
376 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
377 return skl_y_ddi_translations_dp;
378 }
379 } else if (IS_SKL_ULT(dev) || IS_KBL_ULT(dev)) {
380 if (dev_priv->edp_low_vswing) {
381 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
382 return skl_u_ddi_translations_edp;
383 } else {
384 *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
385 return skl_u_ddi_translations_dp;
386 }
David Weinehallf8896f52015-06-25 11:11:03 +0300387 } else {
Ville Syrjäläacee2992015-12-08 19:59:39 +0200388 if (dev_priv->edp_low_vswing) {
389 *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
390 return skl_ddi_translations_edp;
391 } else {
392 *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
393 return skl_ddi_translations_dp;
394 }
David Weinehallf8896f52015-06-25 11:11:03 +0300395 }
Ville Syrjäläacee2992015-12-08 19:59:39 +0200396}
David Weinehallf8896f52015-06-25 11:11:03 +0300397
Ville Syrjäläacee2992015-12-08 19:59:39 +0200398static const struct ddi_buf_trans *
399skl_get_buf_trans_hdmi(struct drm_device *dev, int *n_entries)
400{
401 if (IS_SKL_ULX(dev) || IS_KBL_ULX(dev)) {
402 *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
403 return skl_y_ddi_translations_hdmi;
404 } else {
405 *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
406 return skl_ddi_translations_hdmi;
407 }
David Weinehallf8896f52015-06-25 11:11:03 +0300408}
409
Art Runyane58623c2013-11-02 21:07:41 -0700410/*
411 * Starting with Haswell, DDI port buffers must be programmed with correct
412 * values in advance. The buffer values are different for FDI and DP modes,
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300413 * but the HDMI/DVI fields are shared among those. So we program the DDI
414 * in either FDI or DP modes only, as HDMI connections will work with both
415 * of those
416 */
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300417static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
418 bool supports_hdmi)
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300419{
420 struct drm_i915_private *dev_priv = dev->dev_private;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300421 u32 iboost_bit = 0;
Damien Lespiau7ff44672015-03-02 16:19:36 +0000422 int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530423 size;
Paulo Zanoni6acab152013-09-12 17:06:24 -0300424 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
Jani Nikula10122052014-08-27 16:27:30 +0300425 const struct ddi_buf_trans *ddi_translations_fdi;
426 const struct ddi_buf_trans *ddi_translations_dp;
427 const struct ddi_buf_trans *ddi_translations_edp;
428 const struct ddi_buf_trans *ddi_translations_hdmi;
429 const struct ddi_buf_trans *ddi_translations;
Art Runyane58623c2013-11-02 21:07:41 -0700430
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530431 if (IS_BROXTON(dev)) {
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300432 if (!supports_hdmi)
Vandana Kannan96fb9f92014-11-18 15:45:27 +0530433 return;
434
435 /* Vswing programming for HDMI */
436 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
437 INTEL_OUTPUT_HDMI);
438 return;
Rodrigo Vivief11bdb2015-10-28 04:16:45 -0700439 } else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Paulo Zanonic30400f2015-07-03 12:31:30 -0300440 ddi_translations_fdi = NULL;
David Weinehallf8896f52015-06-25 11:11:03 +0300441 ddi_translations_dp =
442 skl_get_buf_trans_dp(dev, &n_dp_entries);
443 ddi_translations_edp =
444 skl_get_buf_trans_edp(dev, &n_edp_entries);
445 ddi_translations_hdmi =
446 skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
447 hdmi_default_entry = 8;
Antti Koskipaa75067dd2015-07-10 14:10:55 +0300448 /* If we're boosting the current, set bit 31 of trans1 */
449 if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
450 dev_priv->vbt.ddi_port_info[port].dp_boost_level)
451 iboost_bit = 1<<31;
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000452 } else if (IS_BROADWELL(dev)) {
Art Runyane58623c2013-11-02 21:07:41 -0700453 ddi_translations_fdi = bdw_ddi_translations_fdi;
454 ddi_translations_dp = bdw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700455 ddi_translations_edp = bdw_ddi_translations_edp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100456 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530457 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
458 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300459 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000460 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700461 } else if (IS_HASWELL(dev)) {
462 ddi_translations_fdi = hsw_ddi_translations_fdi;
463 ddi_translations_dp = hsw_ddi_translations_dp;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700464 ddi_translations_edp = hsw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100465 ddi_translations_hdmi = hsw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530466 n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300467 n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000468 hdmi_default_entry = 6;
Art Runyane58623c2013-11-02 21:07:41 -0700469 } else {
470 WARN(1, "ddi translation table missing\n");
Paulo Zanoni300644c2013-11-02 21:07:42 -0700471 ddi_translations_edp = bdw_ddi_translations_dp;
Art Runyane58623c2013-11-02 21:07:41 -0700472 ddi_translations_fdi = bdw_ddi_translations_fdi;
473 ddi_translations_dp = bdw_ddi_translations_dp;
Damien Lespiaua26aa8b2014-08-01 11:07:55 +0100474 ddi_translations_hdmi = bdw_ddi_translations_hdmi;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530475 n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
476 n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
Jani Nikula10122052014-08-27 16:27:30 +0300477 n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
Damien Lespiau7ff44672015-03-02 16:19:36 +0000478 hdmi_default_entry = 7;
Art Runyane58623c2013-11-02 21:07:41 -0700479 }
480
Paulo Zanoni300644c2013-11-02 21:07:42 -0700481 switch (port) {
482 case PORT_A:
483 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530484 size = n_edp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700485 break;
486 case PORT_B:
487 case PORT_C:
Paulo Zanoni300644c2013-11-02 21:07:42 -0700488 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530489 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700490 break;
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700491 case PORT_D:
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530492 if (intel_dp_is_edp(dev, PORT_D)) {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700493 ddi_translations = ddi_translations_edp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530494 size = n_edp_entries;
495 } else {
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700496 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530497 size = n_dp_entries;
498 }
Paulo Zanoni77d8d002013-11-02 21:07:45 -0700499 break;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700500 case PORT_E:
Damien Lespiau7f88e3a2013-12-03 13:56:25 +0000501 if (ddi_translations_fdi)
502 ddi_translations = ddi_translations_fdi;
503 else
504 ddi_translations = ddi_translations_dp;
Sonika Jindal7ad14a22015-02-25 10:29:12 +0530505 size = n_dp_entries;
Paulo Zanoni300644c2013-11-02 21:07:42 -0700506 break;
507 default:
508 BUG();
509 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300510
Ville Syrjälä9712e682015-09-18 20:03:22 +0300511 for (i = 0; i < size; i++) {
512 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
513 ddi_translations[i].trans1 | iboost_bit);
514 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
515 ddi_translations[i].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300516 }
Damien Lespiauce4dd492014-08-01 11:07:54 +0100517
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300518 if (!supports_hdmi)
Damien Lespiauce3b7e92014-08-04 15:04:43 +0100519 return;
520
Damien Lespiauce4dd492014-08-01 11:07:54 +0100521 /* Choose a good default if VBT is badly populated */
522 if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN ||
523 hdmi_level >= n_hdmi_entries)
Damien Lespiau7ff44672015-03-02 16:19:36 +0000524 hdmi_level = hdmi_default_entry;
Damien Lespiauce4dd492014-08-01 11:07:54 +0100525
Paulo Zanoni6acab152013-09-12 17:06:24 -0300526 /* Entry 9 is for HDMI: */
Ville Syrjälä9712e682015-09-18 20:03:22 +0300527 I915_WRITE(DDI_BUF_TRANS_LO(port, i),
528 ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
529 I915_WRITE(DDI_BUF_TRANS_HI(port, i),
530 ddi_translations_hdmi[hdmi_level].trans2);
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300531}
532
533/* Program DDI buffers translations for DP. By default, program ports A-D in DP
534 * mode and port E for FDI.
535 */
536void intel_prepare_ddi(struct drm_device *dev)
537{
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300538 struct intel_encoder *intel_encoder;
Damien Lespiaub4037452014-08-04 22:01:33 +0100539 bool visited[I915_MAX_PORTS] = { 0, };
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300540
Paulo Zanoni0d536cb42012-11-23 16:46:41 -0200541 if (!HAS_DDI(dev))
542 return;
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300543
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300544 for_each_intel_encoder(dev, intel_encoder) {
545 struct intel_digital_port *intel_dig_port;
546 enum port port;
547 bool supports_hdmi;
548
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530549 if (intel_encoder->type == INTEL_OUTPUT_DSI)
550 continue;
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300551
Shashank Sharma7d4aefd2015-10-01 22:23:49 +0530552 ddi_get_encoder_port(intel_encoder, &intel_dig_port, &port);
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300553 if (visited[port])
Damien Lespiaub4037452014-08-04 22:01:33 +0100554 continue;
555
Imre Deakfaa0cdb2015-04-17 19:31:22 +0300556 supports_hdmi = intel_dig_port &&
557 intel_dig_port_supports_hdmi(intel_dig_port);
558
559 intel_prepare_ddi_buffers(dev, port, supports_hdmi);
560 visited[port] = true;
Damien Lespiaub4037452014-08-04 22:01:33 +0100561 }
Eugeni Dodonov45244b82012-05-09 15:37:20 -0300562}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300563
Paulo Zanoni248138b2012-11-29 11:29:31 -0200564static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
565 enum port port)
566{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200567 i915_reg_t reg = DDI_BUF_CTL(port);
Paulo Zanoni248138b2012-11-29 11:29:31 -0200568 int i;
569
Vandana Kannan3449ca82015-03-27 14:19:09 +0200570 for (i = 0; i < 16; i++) {
Paulo Zanoni248138b2012-11-29 11:29:31 -0200571 udelay(1);
572 if (I915_READ(reg) & DDI_BUF_IS_IDLE)
573 return;
574 }
575 DRM_ERROR("Timeout waiting for DDI BUF %c idle bit\n", port_name(port));
576}
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300577
578/* Starting with Haswell, different DDI ports can work in FDI mode for
579 * connection to the PCH-located connectors. For this, it is necessary to train
580 * both the DDI port and PCH receiver for the desired DDI buffer settings.
581 *
582 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
583 * please note that when FDI mode is active on DDI E, it shares 2 lines with
584 * DDI A (which is used for eDP)
585 */
586
587void hsw_fdi_link_train(struct drm_crtc *crtc)
588{
589 struct drm_device *dev = crtc->dev;
590 struct drm_i915_private *dev_priv = dev->dev_private;
591 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni04945642012-11-01 21:00:59 -0200592 u32 temp, i, rx_ctl_val;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300593
Paulo Zanoni04945642012-11-01 21:00:59 -0200594 /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
595 * mode set "sequence for CRT port" document:
596 * - TP1 to TP2 time with the default value
597 * - FDI delay to 90h
Damien Lespiau8693a822013-05-03 18:48:11 +0100598 *
599 * WaFDIAutoLinkSetTimingOverrride:hsw
Paulo Zanoni04945642012-11-01 21:00:59 -0200600 */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300601 I915_WRITE(FDI_RX_MISC(PIPE_A), FDI_RX_PWRDN_LANE1_VAL(2) |
Paulo Zanoni04945642012-11-01 21:00:59 -0200602 FDI_RX_PWRDN_LANE0_VAL(2) |
603 FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
604
605 /* Enable the PCH Receiver FDI PLL */
Damien Lespiau3e683202012-12-11 18:48:29 +0000606 rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
Daniel Vetter33d29b12013-02-13 18:04:45 +0100607 FDI_RX_PLL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200608 FDI_DP_PORT_WIDTH(intel_crtc->config->fdi_lanes);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300609 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
610 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200611 udelay(220);
612
613 /* Switch from Rawclk to PCDclk */
614 rx_ctl_val |= FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300615 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
Paulo Zanoni04945642012-11-01 21:00:59 -0200616
617 /* Configure Port Clock Select */
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200618 I915_WRITE(PORT_CLK_SEL(PORT_E), intel_crtc->config->ddi_pll_sel);
619 WARN_ON(intel_crtc->config->ddi_pll_sel != PORT_CLK_SEL_SPLL);
Paulo Zanoni04945642012-11-01 21:00:59 -0200620
621 /* Start the training iterating through available voltages and emphasis,
622 * testing each value twice. */
Jani Nikula10122052014-08-27 16:27:30 +0300623 for (i = 0; i < ARRAY_SIZE(hsw_ddi_translations_fdi) * 2; i++) {
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300624 /* Configure DP_TP_CTL with auto-training */
625 I915_WRITE(DP_TP_CTL(PORT_E),
626 DP_TP_CTL_FDI_AUTOTRAIN |
627 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
628 DP_TP_CTL_LINK_TRAIN_PAT1 |
629 DP_TP_CTL_ENABLE);
630
Damien Lespiau876a8cd2012-12-11 18:48:30 +0000631 /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
632 * DDI E does not support port reversal, the functionality is
633 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
634 * port reversal bit */
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300635 I915_WRITE(DDI_BUF_CTL(PORT_E),
Paulo Zanoni04945642012-11-01 21:00:59 -0200636 DDI_BUF_CTL_ENABLE |
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +0200637 ((intel_crtc->config->fdi_lanes - 1) << 1) |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530638 DDI_BUF_TRANS_SELECT(i / 2));
Paulo Zanoni04945642012-11-01 21:00:59 -0200639 POSTING_READ(DDI_BUF_CTL(PORT_E));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300640
641 udelay(600);
642
Paulo Zanoni04945642012-11-01 21:00:59 -0200643 /* Program PCH FDI Receiver TU */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300644 I915_WRITE(FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
Eugeni Dodonov4acf5182012-07-04 20:15:16 -0300645
Paulo Zanoni04945642012-11-01 21:00:59 -0200646 /* Enable PCH FDI Receiver with auto-training */
647 rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300648 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
649 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200650
651 /* Wait for FDI receiver lane calibration */
652 udelay(30);
653
654 /* Unset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300655 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200656 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300657 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
658 POSTING_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200659
660 /* Wait for FDI auto training time */
661 udelay(5);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300662
663 temp = I915_READ(DP_TP_STATUS(PORT_E));
664 if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
Paulo Zanoni04945642012-11-01 21:00:59 -0200665 DRM_DEBUG_KMS("FDI link training done on step %d\n", i);
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200666 break;
667 }
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300668
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200669 /*
670 * Leave things enabled even if we failed to train FDI.
671 * Results in less fireworks from the state checker.
672 */
673 if (i == ARRAY_SIZE(hsw_ddi_translations_fdi) * 2 - 1) {
674 DRM_ERROR("FDI link training failed!\n");
675 break;
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300676 }
Paulo Zanoni04945642012-11-01 21:00:59 -0200677
Paulo Zanoni248138b2012-11-29 11:29:31 -0200678 temp = I915_READ(DDI_BUF_CTL(PORT_E));
679 temp &= ~DDI_BUF_CTL_ENABLE;
680 I915_WRITE(DDI_BUF_CTL(PORT_E), temp);
681 POSTING_READ(DDI_BUF_CTL(PORT_E));
682
Paulo Zanoni04945642012-11-01 21:00:59 -0200683 /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
Paulo Zanoni248138b2012-11-29 11:29:31 -0200684 temp = I915_READ(DP_TP_CTL(PORT_E));
685 temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
686 temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
687 I915_WRITE(DP_TP_CTL(PORT_E), temp);
688 POSTING_READ(DP_TP_CTL(PORT_E));
689
690 intel_wait_ddi_buf_idle(dev_priv, PORT_E);
Paulo Zanoni04945642012-11-01 21:00:59 -0200691
692 rx_ctl_val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300693 I915_WRITE(FDI_RX_CTL(PIPE_A), rx_ctl_val);
694 POSTING_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200695
696 /* Reset FDI_RX_MISC pwrdn lanes */
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300697 temp = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni04945642012-11-01 21:00:59 -0200698 temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
699 temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +0300700 I915_WRITE(FDI_RX_MISC(PIPE_A), temp);
701 POSTING_READ(FDI_RX_MISC(PIPE_A));
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300702 }
703
Ville Syrjäläa308ccb2015-12-04 22:22:50 +0200704 /* Enable normal pixel sending for FDI */
705 I915_WRITE(DP_TP_CTL(PORT_E),
706 DP_TP_CTL_FDI_AUTOTRAIN |
707 DP_TP_CTL_LINK_TRAIN_NORMAL |
708 DP_TP_CTL_ENHANCED_FRAME_ENABLE |
709 DP_TP_CTL_ENABLE);
Eugeni Dodonovc82e4d22012-05-09 15:37:21 -0300710}
Eugeni Dodonov0e72a5b2012-05-09 15:37:27 -0300711
Dave Airlie44905a272014-05-02 13:36:43 +1000712void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
713{
714 struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
715 struct intel_digital_port *intel_dig_port =
716 enc_to_dig_port(&encoder->base);
717
718 intel_dp->DP = intel_dig_port->saved_port_bits |
Sonika Jindalc5fe6a02014-08-11 08:57:36 +0530719 DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
Ville Syrjälä901c2da2015-08-17 18:05:12 +0300720 intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
Dave Airlie44905a272014-05-02 13:36:43 +1000721}
722
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300723static struct intel_encoder *
724intel_ddi_get_crtc_encoder(struct drm_crtc *crtc)
725{
726 struct drm_device *dev = crtc->dev;
727 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
728 struct intel_encoder *intel_encoder, *ret = NULL;
729 int num_encoders = 0;
730
731 for_each_encoder_on_crtc(dev, crtc, intel_encoder) {
732 ret = intel_encoder;
733 num_encoders++;
734 }
735
736 if (num_encoders != 1)
Ville Syrjälä84f44ce2013-04-17 17:48:49 +0300737 WARN(1, "%d encoders on crtc for pipe %c\n", num_encoders,
738 pipe_name(intel_crtc->pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -0300739
740 BUG_ON(ret == NULL);
741 return ret;
742}
743
Satheeshakrishna Mbcddf612014-08-22 09:49:10 +0530744struct intel_encoder *
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200745intel_ddi_get_crtc_new_encoder(struct intel_crtc_state *crtc_state)
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200746{
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200747 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
748 struct intel_encoder *ret = NULL;
749 struct drm_atomic_state *state;
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300750 struct drm_connector *connector;
751 struct drm_connector_state *connector_state;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200752 int num_encoders = 0;
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200753 int i;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200754
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200755 state = crtc_state->base.state;
756
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300757 for_each_connector_in_state(state, connector, connector_state, i) {
758 if (connector_state->crtc != crtc_state->base.crtc)
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200759 continue;
760
Ander Conselvan de Oliveirada3ced2982015-04-21 17:12:59 +0300761 ret = to_intel_encoder(connector_state->best_encoder);
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +0200762 num_encoders++;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +0200763 }
764
765 WARN(num_encoders != 1, "%d encoders on crtc for pipe %c\n", num_encoders,
766 pipe_name(crtc->pipe));
767
768 BUG_ON(ret == NULL);
769 return ret;
770}
771
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100772#define LC_FREQ 2700
Damien Lespiau27893392014-09-04 12:27:23 +0100773#define LC_FREQ_2K U64_C(LC_FREQ * 2000)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100774
775#define P_MIN 2
776#define P_MAX 64
777#define P_INC 2
778
779/* Constraints for PLL good behavior */
780#define REF_MIN 48
781#define REF_MAX 400
782#define VCO_MIN 2400
783#define VCO_MAX 4800
784
Damien Lespiau27893392014-09-04 12:27:23 +0100785#define abs_diff(a, b) ({ \
786 typeof(a) __a = (a); \
787 typeof(b) __b = (b); \
788 (void) (&__a == &__b); \
789 __a > __b ? (__a - __b) : (__b - __a); })
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100790
Damien Lespiau63582982015-05-07 18:38:46 +0100791struct hsw_wrpll_rnp {
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100792 unsigned p, n2, r2;
793};
794
Damien Lespiau63582982015-05-07 18:38:46 +0100795static unsigned hsw_wrpll_get_budget_for_freq(int clock)
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300796{
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100797 unsigned budget;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300798
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100799 switch (clock) {
800 case 25175000:
801 case 25200000:
802 case 27000000:
803 case 27027000:
804 case 37762500:
805 case 37800000:
806 case 40500000:
807 case 40541000:
808 case 54000000:
809 case 54054000:
810 case 59341000:
811 case 59400000:
812 case 72000000:
813 case 74176000:
814 case 74250000:
815 case 81000000:
816 case 81081000:
817 case 89012000:
818 case 89100000:
819 case 108000000:
820 case 108108000:
821 case 111264000:
822 case 111375000:
823 case 148352000:
824 case 148500000:
825 case 162000000:
826 case 162162000:
827 case 222525000:
828 case 222750000:
829 case 296703000:
830 case 297000000:
831 budget = 0;
832 break;
833 case 233500000:
834 case 245250000:
835 case 247750000:
836 case 253250000:
837 case 298000000:
838 budget = 1500;
839 break;
840 case 169128000:
841 case 169500000:
842 case 179500000:
843 case 202000000:
844 budget = 2000;
845 break;
846 case 256250000:
847 case 262500000:
848 case 270000000:
849 case 272500000:
850 case 273750000:
851 case 280750000:
852 case 281250000:
853 case 286000000:
854 case 291750000:
855 budget = 4000;
856 break;
857 case 267250000:
858 case 268500000:
859 budget = 5000;
860 break;
861 default:
862 budget = 1000;
863 break;
864 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300865
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100866 return budget;
867}
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300868
Damien Lespiau63582982015-05-07 18:38:46 +0100869static void hsw_wrpll_update_rnp(uint64_t freq2k, unsigned budget,
870 unsigned r2, unsigned n2, unsigned p,
871 struct hsw_wrpll_rnp *best)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100872{
873 uint64_t a, b, c, d, diff, diff_best;
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300874
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100875 /* No best (r,n,p) yet */
876 if (best->p == 0) {
877 best->p = p;
878 best->n2 = n2;
879 best->r2 = r2;
880 return;
881 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -0300882
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100883 /*
884 * Output clock is (LC_FREQ_2K / 2000) * N / (P * R), which compares to
885 * freq2k.
886 *
887 * delta = 1e6 *
888 * abs(freq2k - (LC_FREQ_2K * n2/(p * r2))) /
889 * freq2k;
890 *
891 * and we would like delta <= budget.
892 *
893 * If the discrepancy is above the PPM-based budget, always prefer to
894 * improve upon the previous solution. However, if you're within the
895 * budget, try to maximize Ref * VCO, that is N / (P * R^2).
896 */
897 a = freq2k * budget * p * r2;
898 b = freq2k * budget * best->p * best->r2;
Damien Lespiau27893392014-09-04 12:27:23 +0100899 diff = abs_diff(freq2k * p * r2, LC_FREQ_2K * n2);
900 diff_best = abs_diff(freq2k * best->p * best->r2,
901 LC_FREQ_2K * best->n2);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +0100902 c = 1000000 * diff;
903 d = 1000000 * diff_best;
904
905 if (a < c && b < d) {
906 /* If both are above the budget, pick the closer */
907 if (best->p * best->r2 * diff < p * r2 * diff_best) {
908 best->p = p;
909 best->n2 = n2;
910 best->r2 = r2;
911 }
912 } else if (a >= c && b < d) {
913 /* If A is below the threshold but B is above it? Update. */
914 best->p = p;
915 best->n2 = n2;
916 best->r2 = r2;
917 } else if (a >= c && b >= d) {
918 /* Both are below the limit, so pick the higher n2/(r2*r2) */
919 if (n2 * best->r2 * best->r2 > best->n2 * r2 * r2) {
920 best->p = p;
921 best->n2 = n2;
922 best->r2 = r2;
923 }
924 }
925 /* Otherwise a < c && b >= d, do nothing */
926}
927
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200928static int hsw_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv,
929 i915_reg_t reg)
Jesse Barnes11578552014-01-21 12:42:10 -0800930{
931 int refclk = LC_FREQ;
932 int n, p, r;
933 u32 wrpll;
934
935 wrpll = I915_READ(reg);
Daniel Vetter114fe482014-06-25 22:01:48 +0300936 switch (wrpll & WRPLL_PLL_REF_MASK) {
937 case WRPLL_PLL_SSC:
938 case WRPLL_PLL_NON_SSC:
Jesse Barnes11578552014-01-21 12:42:10 -0800939 /*
940 * We could calculate spread here, but our checking
941 * code only cares about 5% accuracy, and spread is a max of
942 * 0.5% downspread.
943 */
944 refclk = 135;
945 break;
Daniel Vetter114fe482014-06-25 22:01:48 +0300946 case WRPLL_PLL_LCPLL:
Jesse Barnes11578552014-01-21 12:42:10 -0800947 refclk = LC_FREQ;
948 break;
949 default:
950 WARN(1, "bad wrpll refclk\n");
951 return 0;
952 }
953
954 r = wrpll & WRPLL_DIVIDER_REF_MASK;
955 p = (wrpll & WRPLL_DIVIDER_POST_MASK) >> WRPLL_DIVIDER_POST_SHIFT;
956 n = (wrpll & WRPLL_DIVIDER_FB_MASK) >> WRPLL_DIVIDER_FB_SHIFT;
957
Jesse Barnes20f0ec12014-01-22 12:58:04 -0800958 /* Convert to KHz, p & r have a fixed point portion */
959 return (refclk * n * 100) / (p * r);
Jesse Barnes11578552014-01-21 12:42:10 -0800960}
961
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000962static int skl_calc_wrpll_link(struct drm_i915_private *dev_priv,
963 uint32_t dpll)
964{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +0200965 i915_reg_t cfgcr1_reg, cfgcr2_reg;
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000966 uint32_t cfgcr1_val, cfgcr2_val;
967 uint32_t p0, p1, p2, dco_freq;
968
Ville Syrjälä923c12412015-09-30 17:06:43 +0300969 cfgcr1_reg = DPLL_CFGCR1(dpll);
970 cfgcr2_reg = DPLL_CFGCR2(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +0000971
972 cfgcr1_val = I915_READ(cfgcr1_reg);
973 cfgcr2_val = I915_READ(cfgcr2_reg);
974
975 p0 = cfgcr2_val & DPLL_CFGCR2_PDIV_MASK;
976 p2 = cfgcr2_val & DPLL_CFGCR2_KDIV_MASK;
977
978 if (cfgcr2_val & DPLL_CFGCR2_QDIV_MODE(1))
979 p1 = (cfgcr2_val & DPLL_CFGCR2_QDIV_RATIO_MASK) >> 8;
980 else
981 p1 = 1;
982
983
984 switch (p0) {
985 case DPLL_CFGCR2_PDIV_1:
986 p0 = 1;
987 break;
988 case DPLL_CFGCR2_PDIV_2:
989 p0 = 2;
990 break;
991 case DPLL_CFGCR2_PDIV_3:
992 p0 = 3;
993 break;
994 case DPLL_CFGCR2_PDIV_7:
995 p0 = 7;
996 break;
997 }
998
999 switch (p2) {
1000 case DPLL_CFGCR2_KDIV_5:
1001 p2 = 5;
1002 break;
1003 case DPLL_CFGCR2_KDIV_2:
1004 p2 = 2;
1005 break;
1006 case DPLL_CFGCR2_KDIV_3:
1007 p2 = 3;
1008 break;
1009 case DPLL_CFGCR2_KDIV_1:
1010 p2 = 1;
1011 break;
1012 }
1013
1014 dco_freq = (cfgcr1_val & DPLL_CFGCR1_DCO_INTEGER_MASK) * 24 * 1000;
1015
1016 dco_freq += (((cfgcr1_val & DPLL_CFGCR1_DCO_FRACTION_MASK) >> 9) * 24 *
1017 1000) / 0x8000;
1018
1019 return dco_freq / (p0 * p1 * p2 * 5);
1020}
1021
Ville Syrjälä398a0172015-06-30 15:33:51 +03001022static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
1023{
1024 int dotclock;
1025
1026 if (pipe_config->has_pch_encoder)
1027 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1028 &pipe_config->fdi_m_n);
1029 else if (pipe_config->has_dp_encoder)
1030 dotclock = intel_dotclock_calculate(pipe_config->port_clock,
1031 &pipe_config->dp_m_n);
1032 else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36)
1033 dotclock = pipe_config->port_clock * 2 / 3;
1034 else
1035 dotclock = pipe_config->port_clock;
1036
1037 if (pipe_config->pixel_multiplier)
1038 dotclock /= pipe_config->pixel_multiplier;
1039
1040 pipe_config->base.adjusted_mode.crtc_clock = dotclock;
1041}
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001042
1043static void skl_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001044 struct intel_crtc_state *pipe_config)
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001045{
1046 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001047 int link_clock = 0;
1048 uint32_t dpll_ctl1, dpll;
1049
Damien Lespiau134ffa42014-11-14 17:24:34 +00001050 dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001051
1052 dpll_ctl1 = I915_READ(DPLL_CTRL1);
1053
1054 if (dpll_ctl1 & DPLL_CTRL1_HDMI_MODE(dpll)) {
1055 link_clock = skl_calc_wrpll_link(dev_priv, dpll);
1056 } else {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001057 link_clock = dpll_ctl1 & DPLL_CTRL1_LINK_RATE_MASK(dpll);
1058 link_clock >>= DPLL_CTRL1_LINK_RATE_SHIFT(dpll);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001059
1060 switch (link_clock) {
Damien Lespiau71cd8422015-04-30 16:39:17 +01001061 case DPLL_CTRL1_LINK_RATE_810:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001062 link_clock = 81000;
1063 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001064 case DPLL_CTRL1_LINK_RATE_1080:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301065 link_clock = 108000;
1066 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001067 case DPLL_CTRL1_LINK_RATE_1350:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001068 link_clock = 135000;
1069 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001070 case DPLL_CTRL1_LINK_RATE_1620:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301071 link_clock = 162000;
1072 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001073 case DPLL_CTRL1_LINK_RATE_2160:
Sonika Jindala8f3ef62015-03-05 10:02:30 +05301074 link_clock = 216000;
1075 break;
Damien Lespiau71cd8422015-04-30 16:39:17 +01001076 case DPLL_CTRL1_LINK_RATE_2700:
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001077 link_clock = 270000;
1078 break;
1079 default:
1080 WARN(1, "Unsupported link rate\n");
1081 break;
1082 }
1083 link_clock *= 2;
1084 }
1085
1086 pipe_config->port_clock = link_clock;
1087
Ville Syrjälä398a0172015-06-30 15:33:51 +03001088 ddi_dotclock_get(pipe_config);
Satheeshakrishna M540e7322014-11-13 14:55:16 +00001089}
1090
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001091static void hsw_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001092 struct intel_crtc_state *pipe_config)
Jesse Barnes11578552014-01-21 12:42:10 -08001093{
1094 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
Jesse Barnes11578552014-01-21 12:42:10 -08001095 int link_clock = 0;
1096 u32 val, pll;
1097
Daniel Vetter26804af2014-06-25 22:01:55 +03001098 val = pipe_config->ddi_pll_sel;
Jesse Barnes11578552014-01-21 12:42:10 -08001099 switch (val & PORT_CLK_SEL_MASK) {
1100 case PORT_CLK_SEL_LCPLL_810:
1101 link_clock = 81000;
1102 break;
1103 case PORT_CLK_SEL_LCPLL_1350:
1104 link_clock = 135000;
1105 break;
1106 case PORT_CLK_SEL_LCPLL_2700:
1107 link_clock = 270000;
1108 break;
1109 case PORT_CLK_SEL_WRPLL1:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001110 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(0));
Jesse Barnes11578552014-01-21 12:42:10 -08001111 break;
1112 case PORT_CLK_SEL_WRPLL2:
Ville Syrjälä01403de2015-09-18 20:03:33 +03001113 link_clock = hsw_ddi_calc_wrpll_link(dev_priv, WRPLL_CTL(1));
Jesse Barnes11578552014-01-21 12:42:10 -08001114 break;
1115 case PORT_CLK_SEL_SPLL:
1116 pll = I915_READ(SPLL_CTL) & SPLL_PLL_FREQ_MASK;
1117 if (pll == SPLL_PLL_FREQ_810MHz)
1118 link_clock = 81000;
1119 else if (pll == SPLL_PLL_FREQ_1350MHz)
1120 link_clock = 135000;
1121 else if (pll == SPLL_PLL_FREQ_2700MHz)
1122 link_clock = 270000;
1123 else {
1124 WARN(1, "bad spll freq\n");
1125 return;
1126 }
1127 break;
1128 default:
1129 WARN(1, "bad port clock sel\n");
1130 return;
1131 }
1132
1133 pipe_config->port_clock = link_clock * 2;
1134
Ville Syrjälä398a0172015-06-30 15:33:51 +03001135 ddi_dotclock_get(pipe_config);
Jesse Barnes11578552014-01-21 12:42:10 -08001136}
1137
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301138static int bxt_calc_pll_link(struct drm_i915_private *dev_priv,
1139 enum intel_dpll_id dpll)
1140{
Imre Deakaa610dc2015-06-22 23:35:52 +03001141 struct intel_shared_dpll *pll;
1142 struct intel_dpll_hw_state *state;
1143 intel_clock_t clock;
1144
1145 /* For DDI ports we always use a shared PLL. */
1146 if (WARN_ON(dpll == DPLL_ID_PRIVATE))
1147 return 0;
1148
1149 pll = &dev_priv->shared_dplls[dpll];
1150 state = &pll->config.hw_state;
1151
1152 clock.m1 = 2;
1153 clock.m2 = (state->pll0 & PORT_PLL_M2_MASK) << 22;
1154 if (state->pll3 & PORT_PLL_M2_FRAC_ENABLE)
1155 clock.m2 |= state->pll2 & PORT_PLL_M2_FRAC_MASK;
1156 clock.n = (state->pll1 & PORT_PLL_N_MASK) >> PORT_PLL_N_SHIFT;
1157 clock.p1 = (state->ebb0 & PORT_PLL_P1_MASK) >> PORT_PLL_P1_SHIFT;
1158 clock.p2 = (state->ebb0 & PORT_PLL_P2_MASK) >> PORT_PLL_P2_SHIFT;
1159
1160 return chv_calc_dpll_params(100000, &clock);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301161}
1162
1163static void bxt_ddi_clock_get(struct intel_encoder *encoder,
1164 struct intel_crtc_state *pipe_config)
1165{
1166 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
1167 enum port port = intel_ddi_get_encoder_port(encoder);
1168 uint32_t dpll = port;
1169
Ville Syrjälä398a0172015-06-30 15:33:51 +03001170 pipe_config->port_clock = bxt_calc_pll_link(dev_priv, dpll);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301171
Ville Syrjälä398a0172015-06-30 15:33:51 +03001172 ddi_dotclock_get(pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301173}
1174
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001175void intel_ddi_clock_get(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02001176 struct intel_crtc_state *pipe_config)
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001177{
Damien Lespiau22606a12014-12-12 14:26:57 +00001178 struct drm_device *dev = encoder->base.dev;
1179
1180 if (INTEL_INFO(dev)->gen <= 8)
1181 hsw_ddi_clock_get(encoder, pipe_config);
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001182 else if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Damien Lespiau22606a12014-12-12 14:26:57 +00001183 skl_ddi_clock_get(encoder, pipe_config);
Satheeshakrishna M977bb382014-08-22 09:49:12 +05301184 else if (IS_BROXTON(dev))
1185 bxt_ddi_clock_get(encoder, pipe_config);
Daniel Vetter3d51278a2014-07-29 20:57:08 +02001186}
1187
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001188static void
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001189hsw_ddi_calculate_wrpll(int clock /* in Hz */,
1190 unsigned *r2_out, unsigned *n2_out, unsigned *p_out)
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001191{
1192 uint64_t freq2k;
1193 unsigned p, n2, r2;
Damien Lespiau63582982015-05-07 18:38:46 +01001194 struct hsw_wrpll_rnp best = { 0, 0, 0 };
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001195 unsigned budget;
1196
1197 freq2k = clock / 100;
1198
Damien Lespiau63582982015-05-07 18:38:46 +01001199 budget = hsw_wrpll_get_budget_for_freq(clock);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001200
1201 /* Special case handling for 540 pixel clock: bypass WR PLL entirely
1202 * and directly pass the LC PLL to it. */
1203 if (freq2k == 5400000) {
1204 *n2_out = 2;
1205 *p_out = 1;
1206 *r2_out = 2;
1207 return;
1208 }
1209
1210 /*
1211 * Ref = LC_FREQ / R, where Ref is the actual reference input seen by
1212 * the WR PLL.
1213 *
1214 * We want R so that REF_MIN <= Ref <= REF_MAX.
1215 * Injecting R2 = 2 * R gives:
1216 * REF_MAX * r2 > LC_FREQ * 2 and
1217 * REF_MIN * r2 < LC_FREQ * 2
1218 *
1219 * Which means the desired boundaries for r2 are:
1220 * LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
1221 *
1222 */
1223 for (r2 = LC_FREQ * 2 / REF_MAX + 1;
1224 r2 <= LC_FREQ * 2 / REF_MIN;
1225 r2++) {
1226
1227 /*
1228 * VCO = N * Ref, that is: VCO = N * LC_FREQ / R
1229 *
1230 * Once again we want VCO_MIN <= VCO <= VCO_MAX.
1231 * Injecting R2 = 2 * R and N2 = 2 * N, we get:
1232 * VCO_MAX * r2 > n2 * LC_FREQ and
1233 * VCO_MIN * r2 < n2 * LC_FREQ)
1234 *
1235 * Which means the desired boundaries for n2 are:
1236 * VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
1237 */
1238 for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
1239 n2 <= VCO_MAX * r2 / LC_FREQ;
1240 n2++) {
1241
1242 for (p = P_MIN; p <= P_MAX; p += P_INC)
Damien Lespiau63582982015-05-07 18:38:46 +01001243 hsw_wrpll_update_rnp(freq2k, budget,
1244 r2, n2, p, &best);
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001245 }
1246 }
1247
1248 *n2_out = best.n2;
1249 *p_out = best.p;
1250 *r2_out = best.r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001251}
1252
Damien Lespiau0220ab62014-07-29 18:06:22 +01001253static bool
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001254hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001255 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001256 struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001257{
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001258 int clock = crtc_state->port_clock;
1259
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001260 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
Daniel Vettere0b01be2014-06-25 22:02:01 +03001261 struct intel_shared_dpll *pll;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001262 uint32_t val;
Damien Lespiau1c0b85c2013-05-10 14:01:51 +01001263 unsigned p, n2, r2;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001264
Damien Lespiaud664c0c2014-07-29 18:06:23 +01001265 hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001266
Daniel Vetter114fe482014-06-25 22:01:48 +03001267 val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL |
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001268 WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
1269 WRPLL_DIVIDER_POST(p);
1270
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001271 memset(&crtc_state->dpll_hw_state, 0,
1272 sizeof(crtc_state->dpll_hw_state));
1273
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001274 crtc_state->dpll_hw_state.wrpll = val;
Daniel Vetter716c2e52014-06-25 22:02:02 +03001275
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001276 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Daniel Vetter716c2e52014-06-25 22:02:02 +03001277 if (pll == NULL) {
1278 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1279 pipe_name(intel_crtc->pipe));
Paulo Zanoni06940012013-10-30 18:27:43 -02001280 return false;
1281 }
1282
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001283 crtc_state->ddi_pll_sel = PORT_CLK_SEL_WRPLL(pll->id);
Maarten Lankhorst00490c22015-11-16 14:42:12 +01001284 } else if (crtc_state->ddi_pll_sel == PORT_CLK_SEL_SPLL) {
1285 struct drm_atomic_state *state = crtc_state->base.state;
1286 struct intel_shared_dpll_config *spll =
1287 &intel_atomic_get_shared_dpll_state(state)[DPLL_ID_SPLL];
1288
1289 if (spll->crtc_mask &&
1290 WARN_ON(spll->hw_state.spll != crtc_state->dpll_hw_state.spll))
1291 return false;
1292
1293 crtc_state->shared_dpll = DPLL_ID_SPLL;
1294 spll->hw_state.spll = crtc_state->dpll_hw_state.spll;
1295 spll->crtc_mask |= 1 << intel_crtc->pipe;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001296 }
1297
Paulo Zanoni6441ab52012-10-05 12:05:58 -03001298 return true;
1299}
1300
Damien Lespiaudc253812015-06-25 16:15:06 +01001301struct skl_wrpll_context {
1302 uint64_t min_deviation; /* current minimal deviation */
1303 uint64_t central_freq; /* chosen central freq */
1304 uint64_t dco_freq; /* chosen dco freq */
1305 unsigned int p; /* chosen divider */
1306};
1307
1308static void skl_wrpll_context_init(struct skl_wrpll_context *ctx)
1309{
1310 memset(ctx, 0, sizeof(*ctx));
1311
1312 ctx->min_deviation = U64_MAX;
1313}
1314
1315/* DCO freq must be within +1%/-6% of the DCO central freq */
1316#define SKL_DCO_MAX_PDEVIATION 100
1317#define SKL_DCO_MAX_NDEVIATION 600
1318
1319static void skl_wrpll_try_divider(struct skl_wrpll_context *ctx,
1320 uint64_t central_freq,
1321 uint64_t dco_freq,
1322 unsigned int divider)
1323{
1324 uint64_t deviation;
1325
1326 deviation = div64_u64(10000 * abs_diff(dco_freq, central_freq),
1327 central_freq);
1328
1329 /* positive deviation */
1330 if (dco_freq >= central_freq) {
1331 if (deviation < SKL_DCO_MAX_PDEVIATION &&
1332 deviation < ctx->min_deviation) {
1333 ctx->min_deviation = deviation;
1334 ctx->central_freq = central_freq;
1335 ctx->dco_freq = dco_freq;
1336 ctx->p = divider;
1337 }
1338 /* negative deviation */
1339 } else if (deviation < SKL_DCO_MAX_NDEVIATION &&
1340 deviation < ctx->min_deviation) {
1341 ctx->min_deviation = deviation;
1342 ctx->central_freq = central_freq;
1343 ctx->dco_freq = dco_freq;
1344 ctx->p = divider;
1345 }
Damien Lespiaudc253812015-06-25 16:15:06 +01001346}
1347
1348static void skl_wrpll_get_multipliers(unsigned int p,
1349 unsigned int *p0 /* out */,
1350 unsigned int *p1 /* out */,
1351 unsigned int *p2 /* out */)
1352{
1353 /* even dividers */
1354 if (p % 2 == 0) {
1355 unsigned int half = p / 2;
1356
1357 if (half == 1 || half == 2 || half == 3 || half == 5) {
1358 *p0 = 2;
1359 *p1 = 1;
1360 *p2 = half;
1361 } else if (half % 2 == 0) {
1362 *p0 = 2;
1363 *p1 = half / 2;
1364 *p2 = 2;
1365 } else if (half % 3 == 0) {
1366 *p0 = 3;
1367 *p1 = half / 3;
1368 *p2 = 2;
1369 } else if (half % 7 == 0) {
1370 *p0 = 7;
1371 *p1 = half / 7;
1372 *p2 = 2;
1373 }
1374 } else if (p == 3 || p == 9) { /* 3, 5, 7, 9, 15, 21, 35 */
1375 *p0 = 3;
1376 *p1 = 1;
1377 *p2 = p / 3;
1378 } else if (p == 5 || p == 7) {
1379 *p0 = p;
1380 *p1 = 1;
1381 *p2 = 1;
1382 } else if (p == 15) {
1383 *p0 = 3;
1384 *p1 = 1;
1385 *p2 = 5;
1386 } else if (p == 21) {
1387 *p0 = 7;
1388 *p1 = 1;
1389 *p2 = 3;
1390 } else if (p == 35) {
1391 *p0 = 7;
1392 *p1 = 1;
1393 *p2 = 5;
1394 }
1395}
1396
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001397struct skl_wrpll_params {
1398 uint32_t dco_fraction;
1399 uint32_t dco_integer;
1400 uint32_t qdiv_ratio;
1401 uint32_t qdiv_mode;
1402 uint32_t kdiv;
1403 uint32_t pdiv;
1404 uint32_t central_freq;
1405};
1406
Damien Lespiau76516fb2015-05-07 18:38:42 +01001407static void skl_wrpll_params_populate(struct skl_wrpll_params *params,
1408 uint64_t afe_clock,
1409 uint64_t central_freq,
1410 uint32_t p0, uint32_t p1, uint32_t p2)
1411{
1412 uint64_t dco_freq;
1413
Damien Lespiau76516fb2015-05-07 18:38:42 +01001414 switch (central_freq) {
1415 case 9600000000ULL:
1416 params->central_freq = 0;
1417 break;
1418 case 9000000000ULL:
1419 params->central_freq = 1;
1420 break;
1421 case 8400000000ULL:
1422 params->central_freq = 3;
1423 }
1424
1425 switch (p0) {
1426 case 1:
1427 params->pdiv = 0;
1428 break;
1429 case 2:
1430 params->pdiv = 1;
1431 break;
1432 case 3:
1433 params->pdiv = 2;
1434 break;
1435 case 7:
1436 params->pdiv = 4;
1437 break;
1438 default:
1439 WARN(1, "Incorrect PDiv\n");
1440 }
1441
1442 switch (p2) {
1443 case 5:
1444 params->kdiv = 0;
1445 break;
1446 case 2:
1447 params->kdiv = 1;
1448 break;
1449 case 3:
1450 params->kdiv = 2;
1451 break;
1452 case 1:
1453 params->kdiv = 3;
1454 break;
1455 default:
1456 WARN(1, "Incorrect KDiv\n");
1457 }
1458
1459 params->qdiv_ratio = p1;
1460 params->qdiv_mode = (params->qdiv_ratio == 1) ? 0 : 1;
1461
1462 dco_freq = p0 * p1 * p2 * afe_clock;
1463
1464 /*
1465 * Intermediate values are in Hz.
1466 * Divide by MHz to match bsepc
1467 */
Damien Lespiau30a78622015-05-07 18:38:43 +01001468 params->dco_integer = div_u64(dco_freq, 24 * MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001469 params->dco_fraction =
Damien Lespiau30a78622015-05-07 18:38:43 +01001470 div_u64((div_u64(dco_freq, 24) -
1471 params->dco_integer * MHz(1)) * 0x8000, MHz(1));
Damien Lespiau76516fb2015-05-07 18:38:42 +01001472}
1473
Damien Lespiau318bd822015-05-07 18:38:40 +01001474static bool
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001475skl_ddi_calculate_wrpll(int clock /* in Hz */,
1476 struct skl_wrpll_params *wrpll_params)
1477{
1478 uint64_t afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
Damien Lespiau21318cc2014-11-14 14:20:27 +00001479 uint64_t dco_central_freq[3] = {8400000000ULL,
1480 9000000000ULL,
1481 9600000000ULL};
Damien Lespiaudc253812015-06-25 16:15:06 +01001482 static const int even_dividers[] = { 4, 6, 8, 10, 12, 14, 16, 18, 20,
1483 24, 28, 30, 32, 36, 40, 42, 44,
1484 48, 52, 54, 56, 60, 64, 66, 68,
1485 70, 72, 76, 78, 80, 84, 88, 90,
1486 92, 96, 98 };
1487 static const int odd_dividers[] = { 3, 5, 7, 9, 15, 21, 35 };
1488 static const struct {
1489 const int *list;
1490 int n_dividers;
1491 } dividers[] = {
1492 { even_dividers, ARRAY_SIZE(even_dividers) },
1493 { odd_dividers, ARRAY_SIZE(odd_dividers) },
1494 };
1495 struct skl_wrpll_context ctx;
1496 unsigned int dco, d, i;
1497 unsigned int p0, p1, p2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001498
Damien Lespiaudc253812015-06-25 16:15:06 +01001499 skl_wrpll_context_init(&ctx);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001500
Damien Lespiaudc253812015-06-25 16:15:06 +01001501 for (d = 0; d < ARRAY_SIZE(dividers); d++) {
1502 for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
1503 for (i = 0; i < dividers[d].n_dividers; i++) {
1504 unsigned int p = dividers[d].list[i];
1505 uint64_t dco_freq = p * afe_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001506
Damien Lespiaudc253812015-06-25 16:15:06 +01001507 skl_wrpll_try_divider(&ctx,
1508 dco_central_freq[dco],
1509 dco_freq,
1510 p);
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001511 /*
1512 * Skip the remaining dividers if we're sure to
1513 * have found the definitive divider, we can't
1514 * improve a 0 deviation.
1515 */
1516 if (ctx.min_deviation == 0)
1517 goto skip_remaining_dividers;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001518 }
1519 }
Damien Lespiau267db662015-06-25 16:19:24 +01001520
Damien Lespiaue7ad9872015-06-26 18:34:29 +01001521skip_remaining_dividers:
Damien Lespiau267db662015-06-25 16:19:24 +01001522 /*
1523 * If a solution is found with an even divider, prefer
1524 * this one.
1525 */
1526 if (d == 0 && ctx.p)
1527 break;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001528 }
1529
Damien Lespiaudc253812015-06-25 16:15:06 +01001530 if (!ctx.p) {
1531 DRM_DEBUG_DRIVER("No valid divider found for %dHz\n", clock);
Damien Lespiau318bd822015-05-07 18:38:40 +01001532 return false;
Damien Lespiaudc253812015-06-25 16:15:06 +01001533 }
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001534
Damien Lespiaudc253812015-06-25 16:15:06 +01001535 /*
1536 * gcc incorrectly analyses that these can be used without being
1537 * initialized. To be fair, it's hard to guess.
1538 */
1539 p0 = p1 = p2 = 0;
1540 skl_wrpll_get_multipliers(ctx.p, &p0, &p1, &p2);
1541 skl_wrpll_params_populate(wrpll_params, afe_clock, ctx.central_freq,
1542 p0, p1, p2);
Damien Lespiau9c236752015-05-07 18:38:41 +01001543
Damien Lespiau318bd822015-05-07 18:38:40 +01001544 return true;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001545}
1546
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001547static bool
1548skl_ddi_pll_select(struct intel_crtc *intel_crtc,
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001549 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001550 struct intel_encoder *intel_encoder)
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001551{
1552 struct intel_shared_dpll *pll;
1553 uint32_t ctrl1, cfgcr1, cfgcr2;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001554 int clock = crtc_state->port_clock;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001555
1556 /*
1557 * See comment in intel_dpll_hw_state to understand why we always use 0
1558 * as the DPLL id in this function.
1559 */
1560
1561 ctrl1 = DPLL_CTRL1_OVERRIDE(0);
1562
1563 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1564 struct skl_wrpll_params wrpll_params = { 0, };
1565
1566 ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
1567
Damien Lespiau318bd822015-05-07 18:38:40 +01001568 if (!skl_ddi_calculate_wrpll(clock * 1000, &wrpll_params))
1569 return false;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001570
1571 cfgcr1 = DPLL_CFGCR1_FREQ_ENABLE |
1572 DPLL_CFGCR1_DCO_FRACTION(wrpll_params.dco_fraction) |
1573 wrpll_params.dco_integer;
1574
1575 cfgcr2 = DPLL_CFGCR2_QDIV_RATIO(wrpll_params.qdiv_ratio) |
1576 DPLL_CFGCR2_QDIV_MODE(wrpll_params.qdiv_mode) |
1577 DPLL_CFGCR2_KDIV(wrpll_params.kdiv) |
1578 DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
1579 wrpll_params.central_freq;
1580 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001581 switch (crtc_state->port_clock / 2) {
1582 case 81000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001583 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001584 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001585 case 135000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001586 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001587 break;
Ville Syrjälä840b32b2015-08-11 20:21:46 +03001588 case 270000:
Damien Lespiau71cd8422015-04-30 16:39:17 +01001589 ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001590 break;
1591 }
1592
1593 cfgcr1 = cfgcr2 = 0;
1594 } else /* eDP */
1595 return true;
1596
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001597 memset(&crtc_state->dpll_hw_state, 0,
1598 sizeof(crtc_state->dpll_hw_state));
1599
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001600 crtc_state->dpll_hw_state.ctrl1 = ctrl1;
1601 crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
1602 crtc_state->dpll_hw_state.cfgcr2 = cfgcr2;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001603
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001604 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001605 if (pll == NULL) {
1606 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1607 pipe_name(intel_crtc->pipe));
1608 return false;
1609 }
1610
1611 /* shared DPLL id 0 is DPLL 1 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001612 crtc_state->ddi_pll_sel = pll->id + 1;
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001613
1614 return true;
1615}
Damien Lespiau0220ab62014-07-29 18:06:22 +01001616
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301617/* bxt clock parameters */
1618struct bxt_clk_div {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301619 int clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301620 uint32_t p1;
1621 uint32_t p2;
1622 uint32_t m2_int;
1623 uint32_t m2_frac;
1624 bool m2_frac_en;
1625 uint32_t n;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301626};
1627
1628/* pre-calculated values for DP linkrates */
Sonika Jindal64987fc2015-05-26 17:50:13 +05301629static const struct bxt_clk_div bxt_dp_clk_val[] = {
1630 {162000, 4, 2, 32, 1677722, 1, 1},
1631 {270000, 4, 1, 27, 0, 0, 1},
1632 {540000, 2, 1, 27, 0, 0, 1},
1633 {216000, 3, 2, 32, 1677722, 1, 1},
1634 {243000, 4, 1, 24, 1258291, 1, 1},
1635 {324000, 4, 1, 32, 1677722, 1, 1},
1636 {432000, 3, 1, 32, 1677722, 1, 1}
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301637};
1638
1639static bool
1640bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
1641 struct intel_crtc_state *crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001642 struct intel_encoder *intel_encoder)
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301643{
1644 struct intel_shared_dpll *pll;
1645 struct bxt_clk_div clk_div = {0};
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301646 int vco = 0;
1647 uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
Vandana Kannane6292552015-07-01 17:02:57 +05301648 uint32_t lanestagger;
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001649 int clock = crtc_state->port_clock;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301650
1651 if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
1652 intel_clock_t best_clock;
1653
1654 /* Calculate HDMI div */
1655 /*
1656 * FIXME: tie the following calculation into
1657 * i9xx_crtc_compute_clock
1658 */
1659 if (!bxt_find_best_dpll(crtc_state, clock, &best_clock)) {
1660 DRM_DEBUG_DRIVER("no PLL dividers found for clock %d pipe %c\n",
1661 clock, pipe_name(intel_crtc->pipe));
1662 return false;
1663 }
1664
1665 clk_div.p1 = best_clock.p1;
1666 clk_div.p2 = best_clock.p2;
1667 WARN_ON(best_clock.m1 != 2);
1668 clk_div.n = best_clock.n;
1669 clk_div.m2_int = best_clock.m2 >> 22;
1670 clk_div.m2_frac = best_clock.m2 & ((1 << 22) - 1);
1671 clk_div.m2_frac_en = clk_div.m2_frac != 0;
1672
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301673 vco = best_clock.vco;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301674 } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT ||
1675 intel_encoder->type == INTEL_OUTPUT_EDP) {
Sonika Jindal64987fc2015-05-26 17:50:13 +05301676 int i;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301677
Sonika Jindal64987fc2015-05-26 17:50:13 +05301678 clk_div = bxt_dp_clk_val[0];
1679 for (i = 0; i < ARRAY_SIZE(bxt_dp_clk_val); ++i) {
1680 if (bxt_dp_clk_val[i].clock == clock) {
1681 clk_div = bxt_dp_clk_val[i];
1682 break;
1683 }
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301684 }
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301685 vco = clock * 10 / 2 * clk_div.p1 * clk_div.p2;
1686 }
1687
Vandana Kannane6292552015-07-01 17:02:57 +05301688 if (vco >= 6200000 && vco <= 6700000) {
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301689 prop_coef = 4;
1690 int_coef = 9;
1691 gain_ctl = 3;
1692 targ_cnt = 8;
1693 } else if ((vco > 5400000 && vco < 6200000) ||
1694 (vco >= 4800000 && vco < 5400000)) {
1695 prop_coef = 5;
1696 int_coef = 11;
1697 gain_ctl = 3;
1698 targ_cnt = 9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301699 } else if (vco == 5400000) {
1700 prop_coef = 3;
1701 int_coef = 8;
1702 gain_ctl = 1;
1703 targ_cnt = 9;
1704 } else {
1705 DRM_ERROR("Invalid VCO\n");
1706 return false;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301707 }
1708
Ander Conselvan de Oliveiradd3cd742015-05-15 13:34:29 +03001709 memset(&crtc_state->dpll_hw_state, 0,
1710 sizeof(crtc_state->dpll_hw_state));
1711
Vandana Kannane0681e32015-05-13 12:20:35 +05301712 if (clock > 270000)
1713 lanestagger = 0x18;
1714 else if (clock > 135000)
1715 lanestagger = 0x0d;
1716 else if (clock > 67000)
1717 lanestagger = 0x07;
1718 else if (clock > 33000)
1719 lanestagger = 0x04;
1720 else
1721 lanestagger = 0x02;
1722
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301723 crtc_state->dpll_hw_state.ebb0 =
1724 PORT_PLL_P1(clk_div.p1) | PORT_PLL_P2(clk_div.p2);
1725 crtc_state->dpll_hw_state.pll0 = clk_div.m2_int;
1726 crtc_state->dpll_hw_state.pll1 = PORT_PLL_N(clk_div.n);
1727 crtc_state->dpll_hw_state.pll2 = clk_div.m2_frac;
1728
1729 if (clk_div.m2_frac_en)
1730 crtc_state->dpll_hw_state.pll3 =
1731 PORT_PLL_M2_FRAC_ENABLE;
1732
1733 crtc_state->dpll_hw_state.pll6 =
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301734 prop_coef | PORT_PLL_INT_COEFF(int_coef);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301735 crtc_state->dpll_hw_state.pll6 |=
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301736 PORT_PLL_GAIN_CTL(gain_ctl);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301737
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05301738 crtc_state->dpll_hw_state.pll8 = targ_cnt;
1739
Imre Deak05712c12015-06-18 17:25:54 +03001740 crtc_state->dpll_hw_state.pll9 = 5 << PORT_PLL_LOCK_THRESHOLD_SHIFT;
1741
Vandana Kannane6292552015-07-01 17:02:57 +05301742 crtc_state->dpll_hw_state.pll10 =
1743 PORT_PLL_DCO_AMP(PORT_PLL_DCO_AMP_DEFAULT)
1744 | PORT_PLL_DCO_AMP_OVR_EN_H;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301745
Imre Deak05712c12015-06-18 17:25:54 +03001746 crtc_state->dpll_hw_state.ebb4 = PORT_PLL_10BIT_CLK_ENABLE;
1747
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301748 crtc_state->dpll_hw_state.pcsdw12 =
Vandana Kannane0681e32015-05-13 12:20:35 +05301749 LANESTAGGER_STRAP_OVRD | lanestagger;
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301750
1751 pll = intel_get_shared_dpll(intel_crtc, crtc_state);
1752 if (pll == NULL) {
1753 DRM_DEBUG_DRIVER("failed to find PLL for pipe %c\n",
1754 pipe_name(intel_crtc->pipe));
1755 return false;
1756 }
1757
1758 /* shared DPLL id 0 is DPLL A */
1759 crtc_state->ddi_pll_sel = pll->id;
1760
1761 return true;
1762}
1763
Damien Lespiau0220ab62014-07-29 18:06:22 +01001764/*
1765 * Tries to find a *shared* PLL for the CRTC and store it in
1766 * intel_crtc->ddi_pll_sel.
1767 *
1768 * For private DPLLs, compute_config() should do the selection for us. This
1769 * function should be folded into compute_config() eventually.
1770 */
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001771bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
1772 struct intel_crtc_state *crtc_state)
Damien Lespiau0220ab62014-07-29 18:06:22 +01001773{
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001774 struct drm_device *dev = intel_crtc->base.dev;
Ander Conselvan de Oliveirad0737e12014-10-29 11:32:30 +02001775 struct intel_encoder *intel_encoder =
Ander Conselvan de Oliveira3165c072015-03-20 16:18:12 +02001776 intel_ddi_get_crtc_new_encoder(crtc_state);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001777
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07001778 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001779 return skl_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001780 intel_encoder);
Satheeshakrishna Md683f3b2014-08-22 09:49:08 +05301781 else if (IS_BROXTON(dev))
1782 return bxt_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001783 intel_encoder);
Satheeshakrishna M82d35432014-11-13 14:55:20 +00001784 else
Ander Conselvan de Oliveira190f68c2015-01-15 14:55:23 +02001785 return hsw_ddi_pll_select(intel_crtc, crtc_state,
Ville Syrjälä96f3f1f2015-07-06 15:10:02 +03001786 intel_encoder);
Damien Lespiau0220ab62014-07-29 18:06:22 +01001787}
1788
Paulo Zanonidae84792012-10-15 15:51:30 -03001789void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
1790{
1791 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
1792 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1793 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001794 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonidae84792012-10-15 15:51:30 -03001795 int type = intel_encoder->type;
1796 uint32_t temp;
1797
Dave Airlie0e32b392014-05-02 14:02:48 +10001798 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) {
Paulo Zanonic9809792012-10-23 18:30:00 -02001799 temp = TRANS_MSA_SYNC_CLK;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001800 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidae84792012-10-15 15:51:30 -03001801 case 18:
Paulo Zanonic9809792012-10-23 18:30:00 -02001802 temp |= TRANS_MSA_6_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001803 break;
1804 case 24:
Paulo Zanonic9809792012-10-23 18:30:00 -02001805 temp |= TRANS_MSA_8_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001806 break;
1807 case 30:
Paulo Zanonic9809792012-10-23 18:30:00 -02001808 temp |= TRANS_MSA_10_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001809 break;
1810 case 36:
Paulo Zanonic9809792012-10-23 18:30:00 -02001811 temp |= TRANS_MSA_12_BPC;
Paulo Zanonidae84792012-10-15 15:51:30 -03001812 break;
1813 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001814 BUG();
Paulo Zanonidae84792012-10-15 15:51:30 -03001815 }
Paulo Zanonic9809792012-10-23 18:30:00 -02001816 I915_WRITE(TRANS_MSA_MISC(cpu_transcoder), temp);
Paulo Zanonidae84792012-10-15 15:51:30 -03001817 }
1818}
1819
Dave Airlie0e32b392014-05-02 14:02:48 +10001820void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state)
1821{
1822 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1823 struct drm_device *dev = crtc->dev;
1824 struct drm_i915_private *dev_priv = dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001825 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Dave Airlie0e32b392014-05-02 14:02:48 +10001826 uint32_t temp;
1827 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1828 if (state == true)
1829 temp |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1830 else
1831 temp &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
1832 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
1833}
1834
Damien Lespiau8228c252013-03-07 15:30:27 +00001835void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001836{
1837 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1838 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001839 struct drm_encoder *encoder = &intel_encoder->base;
Paulo Zanonic7670b12013-11-02 21:07:37 -07001840 struct drm_device *dev = crtc->dev;
1841 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001842 enum pipe pipe = intel_crtc->pipe;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001843 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001844 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni7739c332012-10-15 15:51:29 -03001845 int type = intel_encoder->type;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001846 uint32_t temp;
1847
Paulo Zanoniad80a812012-10-24 16:06:19 -02001848 /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */
1849 temp = TRANS_DDI_FUNC_ENABLE;
Paulo Zanoni174edf12012-10-26 19:05:50 -02001850 temp |= TRANS_DDI_SELECT_PORT(port);
Paulo Zanonidfcef252012-08-08 14:15:29 -03001851
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001852 switch (intel_crtc->config->pipe_bpp) {
Paulo Zanonidfcef252012-08-08 14:15:29 -03001853 case 18:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001854 temp |= TRANS_DDI_BPC_6;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001855 break;
1856 case 24:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001857 temp |= TRANS_DDI_BPC_8;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001858 break;
1859 case 30:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001860 temp |= TRANS_DDI_BPC_10;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001861 break;
1862 case 36:
Paulo Zanoniad80a812012-10-24 16:06:19 -02001863 temp |= TRANS_DDI_BPC_12;
Paulo Zanonidfcef252012-08-08 14:15:29 -03001864 break;
1865 default:
Daniel Vetter4e53c2e2013-03-27 00:44:58 +01001866 BUG();
Paulo Zanonidfcef252012-08-08 14:15:29 -03001867 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001868
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001869 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001870 temp |= TRANS_DDI_PVSYNC;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001871 if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001872 temp |= TRANS_DDI_PHSYNC;
Paulo Zanonif63eb7c42012-08-08 14:15:28 -03001873
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001874 if (cpu_transcoder == TRANSCODER_EDP) {
1875 switch (pipe) {
1876 case PIPE_A:
Paulo Zanonic7670b12013-11-02 21:07:37 -07001877 /* On Haswell, can only use the always-on power well for
1878 * eDP when not using the panel fitter, and when not
1879 * using motion blur mitigation (which we don't
1880 * support). */
Daniel Vetterfabf6e52014-05-29 14:10:22 +02001881 if (IS_HASWELL(dev) &&
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001882 (intel_crtc->config->pch_pfit.enabled ||
1883 intel_crtc->config->pch_pfit.force_thru))
Daniel Vetterd6dd9eb2013-01-29 16:35:20 -02001884 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
1885 else
1886 temp |= TRANS_DDI_EDP_INPUT_A_ON;
Paulo Zanonie6f0bfc2012-10-23 18:30:04 -02001887 break;
1888 case PIPE_B:
1889 temp |= TRANS_DDI_EDP_INPUT_B_ONOFF;
1890 break;
1891 case PIPE_C:
1892 temp |= TRANS_DDI_EDP_INPUT_C_ONOFF;
1893 break;
1894 default:
1895 BUG();
1896 break;
1897 }
1898 }
1899
Paulo Zanoni7739c332012-10-15 15:51:29 -03001900 if (type == INTEL_OUTPUT_HDMI) {
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001901 if (intel_crtc->config->has_hdmi_sink)
Paulo Zanoniad80a812012-10-24 16:06:19 -02001902 temp |= TRANS_DDI_MODE_SELECT_HDMI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001903 else
Paulo Zanoniad80a812012-10-24 16:06:19 -02001904 temp |= TRANS_DDI_MODE_SELECT_DVI;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001905
Paulo Zanoni7739c332012-10-15 15:51:29 -03001906 } else if (type == INTEL_OUTPUT_ANALOG) {
Paulo Zanoniad80a812012-10-24 16:06:19 -02001907 temp |= TRANS_DDI_MODE_SELECT_FDI;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02001908 temp |= (intel_crtc->config->fdi_lanes - 1) << 1;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001909
1910 } else if (type == INTEL_OUTPUT_DISPLAYPORT ||
1911 type == INTEL_OUTPUT_EDP) {
1912 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1913
Dave Airlie0e32b392014-05-02 14:02:48 +10001914 if (intel_dp->is_mst) {
1915 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1916 } else
1917 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
1918
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001919 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Dave Airlie0e32b392014-05-02 14:02:48 +10001920 } else if (type == INTEL_OUTPUT_DP_MST) {
1921 struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
1922
1923 if (intel_dp->is_mst) {
1924 temp |= TRANS_DDI_MODE_SELECT_DP_MST;
1925 } else
1926 temp |= TRANS_DDI_MODE_SELECT_DP_SST;
Paulo Zanoni7739c332012-10-15 15:51:29 -03001927
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03001928 temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001929 } else {
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03001930 WARN(1, "Invalid encoder type %d for pipe %c\n",
1931 intel_encoder->type, pipe_name(pipe));
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001932 }
1933
Paulo Zanoniad80a812012-10-24 16:06:19 -02001934 I915_WRITE(TRANS_DDI_FUNC_CTL(cpu_transcoder), temp);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001935}
1936
Paulo Zanoniad80a812012-10-24 16:06:19 -02001937void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv,
1938 enum transcoder cpu_transcoder)
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001939{
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02001940 i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001941 uint32_t val = I915_READ(reg);
1942
Dave Airlie0e32b392014-05-02 14:02:48 +10001943 val &= ~(TRANS_DDI_FUNC_ENABLE | TRANS_DDI_PORT_MASK | TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
Paulo Zanoniad80a812012-10-24 16:06:19 -02001944 val |= TRANS_DDI_PORT_NONE;
Paulo Zanoni8d9ddbc2012-10-05 12:05:53 -03001945 I915_WRITE(reg, val);
Eugeni Dodonov72662e12012-05-09 15:37:31 -03001946}
1947
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001948bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
1949{
1950 struct drm_device *dev = intel_connector->base.dev;
1951 struct drm_i915_private *dev_priv = dev->dev_private;
1952 struct intel_encoder *intel_encoder = intel_connector->encoder;
1953 int type = intel_connector->base.connector_type;
1954 enum port port = intel_ddi_get_encoder_port(intel_encoder);
1955 enum pipe pipe = 0;
1956 enum transcoder cpu_transcoder;
Paulo Zanoni882244a2014-04-01 14:55:12 -03001957 enum intel_display_power_domain power_domain;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001958 uint32_t tmp;
1959
Paulo Zanoni882244a2014-04-01 14:55:12 -03001960 power_domain = intel_display_port_power_domain(intel_encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02001961 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Paulo Zanoni882244a2014-04-01 14:55:12 -03001962 return false;
1963
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001964 if (!intel_encoder->get_hw_state(intel_encoder, &pipe))
1965 return false;
1966
1967 if (port == PORT_A)
1968 cpu_transcoder = TRANSCODER_EDP;
1969 else
Daniel Vetter1a240d42012-11-29 22:18:51 +01001970 cpu_transcoder = (enum transcoder) pipe;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001971
1972 tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
1973
1974 switch (tmp & TRANS_DDI_MODE_SELECT_MASK) {
1975 case TRANS_DDI_MODE_SELECT_HDMI:
1976 case TRANS_DDI_MODE_SELECT_DVI:
1977 return (type == DRM_MODE_CONNECTOR_HDMIA);
1978
1979 case TRANS_DDI_MODE_SELECT_DP_SST:
1980 if (type == DRM_MODE_CONNECTOR_eDP)
1981 return true;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001982 return (type == DRM_MODE_CONNECTOR_DisplayPort);
Dave Airlie0e32b392014-05-02 14:02:48 +10001983 case TRANS_DDI_MODE_SELECT_DP_MST:
1984 /* if the transcoder is in MST state then
1985 * connector isn't connected */
1986 return false;
Paulo Zanonibcbc8892012-10-26 19:05:51 -02001987
1988 case TRANS_DDI_MODE_SELECT_FDI:
1989 return (type == DRM_MODE_CONNECTOR_VGA);
1990
1991 default:
1992 return false;
1993 }
1994}
1995
Daniel Vetter85234cd2012-07-02 13:27:29 +02001996bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
1997 enum pipe *pipe)
1998{
1999 struct drm_device *dev = encoder->base.dev;
2000 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002001 enum port port = intel_ddi_get_encoder_port(encoder);
Imre Deak6d129be2014-03-05 16:20:54 +02002002 enum intel_display_power_domain power_domain;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002003 u32 tmp;
2004 int i;
2005
Imre Deak6d129be2014-03-05 16:20:54 +02002006 power_domain = intel_display_port_power_domain(encoder);
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002007 if (!intel_display_power_is_enabled(dev_priv, power_domain))
Imre Deak6d129be2014-03-05 16:20:54 +02002008 return false;
2009
Paulo Zanonife43d3f2012-10-15 15:51:39 -03002010 tmp = I915_READ(DDI_BUF_CTL(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002011
2012 if (!(tmp & DDI_BUF_CTL_ENABLE))
2013 return false;
2014
Paulo Zanoniad80a812012-10-24 16:06:19 -02002015 if (port == PORT_A) {
2016 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002017
Paulo Zanoniad80a812012-10-24 16:06:19 -02002018 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
2019 case TRANS_DDI_EDP_INPUT_A_ON:
2020 case TRANS_DDI_EDP_INPUT_A_ONOFF:
2021 *pipe = PIPE_A;
2022 break;
2023 case TRANS_DDI_EDP_INPUT_B_ONOFF:
2024 *pipe = PIPE_B;
2025 break;
2026 case TRANS_DDI_EDP_INPUT_C_ONOFF:
2027 *pipe = PIPE_C;
2028 break;
2029 }
2030
2031 return true;
2032 } else {
2033 for (i = TRANSCODER_A; i <= TRANSCODER_C; i++) {
2034 tmp = I915_READ(TRANS_DDI_FUNC_CTL(i));
2035
2036 if ((tmp & TRANS_DDI_PORT_MASK)
2037 == TRANS_DDI_SELECT_PORT(port)) {
Dave Airlie0e32b392014-05-02 14:02:48 +10002038 if ((tmp & TRANS_DDI_MODE_SELECT_MASK) == TRANS_DDI_MODE_SELECT_DP_MST)
2039 return false;
2040
Paulo Zanoniad80a812012-10-24 16:06:19 -02002041 *pipe = i;
2042 return true;
2043 }
Daniel Vetter85234cd2012-07-02 13:27:29 +02002044 }
2045 }
2046
Ville Syrjälä84f44ce2013-04-17 17:48:49 +03002047 DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
Daniel Vetter85234cd2012-07-02 13:27:29 +02002048
Jesse Barnes22f9fe52013-04-02 10:03:55 -07002049 return false;
Daniel Vetter85234cd2012-07-02 13:27:29 +02002050}
2051
Paulo Zanonifc914632012-10-05 12:05:54 -03002052void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc)
2053{
2054 struct drm_crtc *crtc = &intel_crtc->base;
Shashank Sharma7d4aefd2015-10-01 22:23:49 +05302055 struct drm_device *dev = crtc->dev;
2056 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonifc914632012-10-05 12:05:54 -03002057 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
2058 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002059 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002060
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002061 if (cpu_transcoder != TRANSCODER_EDP)
2062 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2063 TRANS_CLK_SEL_PORT(port));
Paulo Zanonifc914632012-10-05 12:05:54 -03002064}
2065
2066void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
2067{
2068 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002069 enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder;
Paulo Zanonifc914632012-10-05 12:05:54 -03002070
Paulo Zanonibb523fc2012-10-23 18:29:56 -02002071 if (cpu_transcoder != TRANSCODER_EDP)
2072 I915_WRITE(TRANS_CLK_SEL(cpu_transcoder),
2073 TRANS_CLK_SEL_DISABLED);
Paulo Zanonifc914632012-10-05 12:05:54 -03002074}
2075
David Weinehallf8896f52015-06-25 11:11:03 +03002076static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
2077 enum port port, int type)
2078{
2079 struct drm_i915_private *dev_priv = dev->dev_private;
2080 const struct ddi_buf_trans *ddi_translations;
2081 uint8_t iboost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002082 uint8_t dp_iboost, hdmi_iboost;
David Weinehallf8896f52015-06-25 11:11:03 +03002083 int n_entries;
2084 u32 reg;
2085
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002086 /* VBT may override standard boost values */
2087 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
2088 hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
2089
David Weinehallf8896f52015-06-25 11:11:03 +03002090 if (type == INTEL_OUTPUT_DISPLAYPORT) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002091 if (dp_iboost) {
2092 iboost = dp_iboost;
2093 } else {
2094 ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002095 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002096 }
David Weinehallf8896f52015-06-25 11:11:03 +03002097 } else if (type == INTEL_OUTPUT_EDP) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002098 if (dp_iboost) {
2099 iboost = dp_iboost;
2100 } else {
2101 ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002102 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002103 }
David Weinehallf8896f52015-06-25 11:11:03 +03002104 } else if (type == INTEL_OUTPUT_HDMI) {
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002105 if (hdmi_iboost) {
2106 iboost = hdmi_iboost;
2107 } else {
2108 ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
Ander Conselvan de Oliveirae4d4c052015-11-11 15:15:54 +02002109 iboost = ddi_translations[level].i_boost;
Antti Koskipaa75067dd2015-07-10 14:10:55 +03002110 }
David Weinehallf8896f52015-06-25 11:11:03 +03002111 } else {
2112 return;
2113 }
2114
2115 /* Make sure that the requested I_boost is valid */
2116 if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) {
2117 DRM_ERROR("Invalid I_boost value %u\n", iboost);
2118 return;
2119 }
2120
2121 reg = I915_READ(DISPIO_CR_TX_BMU_CR0);
2122 reg &= ~BALANCE_LEG_MASK(port);
2123 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
2124
2125 if (iboost)
2126 reg |= iboost << BALANCE_LEG_SHIFT(port);
2127 else
2128 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
2129
2130 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg);
2131}
2132
2133static void bxt_ddi_vswing_sequence(struct drm_device *dev, u32 level,
2134 enum port port, int type)
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302135{
2136 struct drm_i915_private *dev_priv = dev->dev_private;
2137 const struct bxt_ddi_buf_trans *ddi_translations;
2138 u32 n_entries, i;
2139 uint32_t val;
2140
Sonika Jindald9d70002015-09-24 10:24:56 +05302141 if (type == INTEL_OUTPUT_EDP && dev_priv->edp_low_vswing) {
2142 n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
2143 ddi_translations = bxt_ddi_translations_edp;
2144 } else if (type == INTEL_OUTPUT_DISPLAYPORT
2145 || type == INTEL_OUTPUT_EDP) {
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302146 n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
2147 ddi_translations = bxt_ddi_translations_dp;
2148 } else if (type == INTEL_OUTPUT_HDMI) {
2149 n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
2150 ddi_translations = bxt_ddi_translations_hdmi;
2151 } else {
2152 DRM_DEBUG_KMS("Vswing programming not done for encoder %d\n",
2153 type);
2154 return;
2155 }
2156
2157 /* Check if default value has to be used */
2158 if (level >= n_entries ||
2159 (type == INTEL_OUTPUT_HDMI && level == HDMI_LEVEL_SHIFT_UNKNOWN)) {
2160 for (i = 0; i < n_entries; i++) {
2161 if (ddi_translations[i].default_index) {
2162 level = i;
2163 break;
2164 }
2165 }
2166 }
2167
2168 /*
2169 * While we write to the group register to program all lanes at once we
2170 * can read only lane registers and we pick lanes 0/1 for that.
2171 */
2172 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2173 val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
2174 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2175
2176 val = I915_READ(BXT_PORT_TX_DW2_LN0(port));
2177 val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
2178 val |= ddi_translations[level].margin << MARGIN_000_SHIFT |
2179 ddi_translations[level].scale << UNIQ_TRANS_SCALE_SHIFT;
2180 I915_WRITE(BXT_PORT_TX_DW2_GRP(port), val);
2181
2182 val = I915_READ(BXT_PORT_TX_DW3_LN0(port));
Sonika Jindal9c58a042015-09-24 10:22:54 +05302183 val &= ~SCALE_DCOMP_METHOD;
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302184 if (ddi_translations[level].enable)
Sonika Jindal9c58a042015-09-24 10:22:54 +05302185 val |= SCALE_DCOMP_METHOD;
2186
2187 if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
2188 DRM_ERROR("Disabled scaling while ouniqetrangenmethod was set");
2189
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302190 I915_WRITE(BXT_PORT_TX_DW3_GRP(port), val);
2191
2192 val = I915_READ(BXT_PORT_TX_DW4_LN0(port));
2193 val &= ~DE_EMPHASIS;
2194 val |= ddi_translations[level].deemphasis << DEEMPH_SHIFT;
2195 I915_WRITE(BXT_PORT_TX_DW4_GRP(port), val);
2196
2197 val = I915_READ(BXT_PORT_PCS_DW10_LN01(port));
2198 val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
2199 I915_WRITE(BXT_PORT_PCS_DW10_GRP(port), val);
2200}
2201
David Weinehallf8896f52015-06-25 11:11:03 +03002202static uint32_t translate_signal_level(int signal_levels)
2203{
2204 uint32_t level;
2205
2206 switch (signal_levels) {
2207 default:
2208 DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level: 0x%x\n",
2209 signal_levels);
2210 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2211 level = 0;
2212 break;
2213 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2214 level = 1;
2215 break;
2216 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2217 level = 2;
2218 break;
2219 case DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | DP_TRAIN_PRE_EMPH_LEVEL_3:
2220 level = 3;
2221 break;
2222
2223 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2224 level = 4;
2225 break;
2226 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2227 level = 5;
2228 break;
2229 case DP_TRAIN_VOLTAGE_SWING_LEVEL_1 | DP_TRAIN_PRE_EMPH_LEVEL_2:
2230 level = 6;
2231 break;
2232
2233 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2234 level = 7;
2235 break;
2236 case DP_TRAIN_VOLTAGE_SWING_LEVEL_2 | DP_TRAIN_PRE_EMPH_LEVEL_1:
2237 level = 8;
2238 break;
2239
2240 case DP_TRAIN_VOLTAGE_SWING_LEVEL_3 | DP_TRAIN_PRE_EMPH_LEVEL_0:
2241 level = 9;
2242 break;
2243 }
2244
2245 return level;
2246}
2247
2248uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
2249{
2250 struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
2251 struct drm_device *dev = dport->base.base.dev;
2252 struct intel_encoder *encoder = &dport->base;
2253 uint8_t train_set = intel_dp->train_set[0];
2254 int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
2255 DP_TRAIN_PRE_EMPHASIS_MASK);
2256 enum port port = dport->port;
2257 uint32_t level;
2258
2259 level = translate_signal_level(signal_levels);
2260
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002261 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
David Weinehallf8896f52015-06-25 11:11:03 +03002262 skl_ddi_set_iboost(dev, level, port, encoder->type);
2263 else if (IS_BROXTON(dev))
2264 bxt_ddi_vswing_sequence(dev, level, port, encoder->type);
2265
2266 return DDI_BUF_TRANS_SELECT(level);
2267}
2268
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002269void intel_ddi_clk_select(struct intel_encoder *encoder,
2270 const struct intel_crtc_state *pipe_config)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002271{
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002272 struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
2273 enum port port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002274
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002275 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) {
2276 uint32_t dpll = pipe_config->ddi_pll_sel;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002277 uint32_t val;
2278
Damien Lespiau5416d872014-11-14 17:24:33 +00002279 /*
2280 * DPLL0 is used for eDP and is the only "private" DPLL (as
2281 * opposed to shared) on SKL
2282 */
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002283 if (encoder->type == INTEL_OUTPUT_EDP) {
Damien Lespiau5416d872014-11-14 17:24:33 +00002284 WARN_ON(dpll != SKL_DPLL0);
2285
2286 val = I915_READ(DPLL_CTRL1);
2287
2288 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) |
2289 DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002290 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002291 val |= pipe_config->dpll_hw_state.ctrl1 << (dpll * 6);
Damien Lespiau5416d872014-11-14 17:24:33 +00002292
2293 I915_WRITE(DPLL_CTRL1, val);
2294 POSTING_READ(DPLL_CTRL1);
2295 }
2296
2297 /* DDI -> PLL mapping */
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002298 val = I915_READ(DPLL_CTRL2);
2299
2300 val &= ~(DPLL_CTRL2_DDI_CLK_OFF(port) |
2301 DPLL_CTRL2_DDI_CLK_SEL_MASK(port));
2302 val |= (DPLL_CTRL2_DDI_CLK_SEL(dpll, port) |
2303 DPLL_CTRL2_DDI_SEL_OVERRIDE(port));
2304
2305 I915_WRITE(DPLL_CTRL2, val);
Damien Lespiau5416d872014-11-14 17:24:33 +00002306
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002307 } else if (INTEL_INFO(dev_priv)->gen < 9) {
2308 WARN_ON(pipe_config->ddi_pll_sel == PORT_CLK_SEL_NONE);
2309 I915_WRITE(PORT_CLK_SEL(port), pipe_config->ddi_pll_sel);
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002310 }
Ville Syrjäläe404ba8d2015-08-17 18:46:20 +03002311}
2312
2313static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
2314{
2315 struct drm_encoder *encoder = &intel_encoder->base;
2316 struct drm_device *dev = encoder->dev;
2317 struct drm_i915_private *dev_priv = dev->dev_private;
2318 struct intel_crtc *crtc = to_intel_crtc(encoder->crtc);
2319 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2320 int type = intel_encoder->type;
2321 int hdmi_level;
2322
2323 if (type == INTEL_OUTPUT_EDP) {
2324 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2325 intel_edp_panel_on(intel_dp);
2326 }
2327
2328 intel_ddi_clk_select(intel_encoder, crtc->config);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002329
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002330 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanonic19b0662012-10-15 15:51:41 -03002331 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002332
Ville Syrjälä901c2da2015-08-17 18:05:12 +03002333 intel_dp_set_link_params(intel_dp, crtc->config);
2334
Dave Airlie44905a272014-05-02 13:36:43 +10002335 intel_ddi_init_dp_buf_reg(intel_encoder);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002336
2337 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
2338 intel_dp_start_link_train(intel_dp);
Vandana Kannan23f08d82014-11-13 14:55:22 +00002339 if (port != PORT_A || INTEL_INFO(dev)->gen >= 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002340 intel_dp_stop_link_train(intel_dp);
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002341 } else if (type == INTEL_OUTPUT_HDMI) {
2342 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2343
Vandana Kannan96fb9f92014-11-18 15:45:27 +05302344 if (IS_BROXTON(dev)) {
2345 hdmi_level = dev_priv->vbt.
2346 ddi_port_info[port].hdmi_level_shift;
2347 bxt_ddi_vswing_sequence(dev, hdmi_level, port,
2348 INTEL_OUTPUT_HDMI);
2349 }
Daniel Vetter30cf6db2014-04-24 23:54:58 +02002350 intel_hdmi->set_infoframes(encoder,
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002351 crtc->config->has_hdmi_sink,
2352 &crtc->config->base.adjusted_mode);
Paulo Zanonic19b0662012-10-15 15:51:41 -03002353 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002354}
2355
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002356static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002357{
2358 struct drm_encoder *encoder = &intel_encoder->base;
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002359 struct drm_device *dev = encoder->dev;
2360 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002361 enum port port = intel_ddi_get_encoder_port(intel_encoder);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002362 int type = intel_encoder->type;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002363 uint32_t val;
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002364 bool wait = false;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002365
2366 val = I915_READ(DDI_BUF_CTL(port));
2367 if (val & DDI_BUF_CTL_ENABLE) {
2368 val &= ~DDI_BUF_CTL_ENABLE;
2369 I915_WRITE(DDI_BUF_CTL(port), val);
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002370 wait = true;
Paulo Zanoni2886e932012-10-05 12:06:00 -03002371 }
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002372
Paulo Zanonia836bdf2012-10-15 15:51:32 -03002373 val = I915_READ(DP_TP_CTL(port));
2374 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
2375 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
2376 I915_WRITE(DP_TP_CTL(port), val);
2377
2378 if (wait)
2379 intel_wait_ddi_buf_idle(dev_priv, port);
2380
Jani Nikula76bb80e2013-11-15 15:29:57 +02002381 if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) {
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002382 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
Jani Nikula76bb80e2013-11-15 15:29:57 +02002383 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
Jani Nikula24f3e092014-03-17 16:43:36 +02002384 intel_edp_panel_vdd_on(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002385 intel_edp_panel_off(intel_dp);
Paulo Zanoni82a4d9c2012-10-23 18:30:07 -02002386 }
2387
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002388 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002389 I915_WRITE(DPLL_CTRL2, (I915_READ(DPLL_CTRL2) |
2390 DPLL_CTRL2_DDI_CLK_OFF(port)));
Satheeshakrishna M1ab23382014-08-22 09:49:06 +05302391 else if (INTEL_INFO(dev)->gen < 9)
Satheeshakrishna Mefa80ad2014-11-13 14:55:19 +00002392 I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
Paulo Zanoni6441ab52012-10-05 12:05:58 -03002393}
2394
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002395static void intel_enable_ddi(struct intel_encoder *intel_encoder)
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002396{
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002397 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002398 struct drm_crtc *crtc = encoder->crtc;
2399 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002400 struct drm_device *dev = encoder->dev;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002401 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002402 enum port port = intel_ddi_get_encoder_port(intel_encoder);
2403 int type = intel_encoder->type;
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002404
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002405 if (type == INTEL_OUTPUT_HDMI) {
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002406 struct intel_digital_port *intel_dig_port =
2407 enc_to_dig_port(encoder);
2408
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002409 /* In HDMI/DVI mode, the port width, and swing/emphasis values
2410 * are ignored so nothing special needs to be done besides
2411 * enabling the port.
2412 */
Damien Lespiau876a8cd2012-12-11 18:48:30 +00002413 I915_WRITE(DDI_BUF_CTL(port),
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07002414 intel_dig_port->saved_port_bits |
2415 DDI_BUF_CTL_ENABLE);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002416 } else if (type == INTEL_OUTPUT_EDP) {
2417 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2418
Vandana Kannan23f08d82014-11-13 14:55:22 +00002419 if (port == PORT_A && INTEL_INFO(dev)->gen < 9)
Imre Deak3ab9c632013-05-03 12:57:41 +03002420 intel_dp_stop_link_train(intel_dp);
2421
Daniel Vetter4be73782014-01-17 14:39:48 +01002422 intel_edp_backlight_on(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002423 intel_psr_enable(intel_dp);
Vandana Kannanc3955782015-01-22 15:17:40 +05302424 intel_edp_drrs_enable(intel_dp);
Paulo Zanoni6547fef2012-10-15 15:51:40 -03002425 }
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002426
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002427 if (intel_crtc->config->has_audio) {
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002428 intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002429 intel_audio_codec_enable(intel_encoder);
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002430 }
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002431}
2432
Paulo Zanoni00c09d72012-10-26 19:05:52 -02002433static void intel_disable_ddi(struct intel_encoder *intel_encoder)
Daniel Vetter5ab432e2012-06-30 08:59:56 +02002434{
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002435 struct drm_encoder *encoder = &intel_encoder->base;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002436 struct drm_crtc *crtc = encoder->crtc;
2437 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002438 int type = intel_encoder->type;
Wang Xingchao7b9f35a2013-01-22 23:25:25 +08002439 struct drm_device *dev = encoder->dev;
2440 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002441
Ander Conselvan de Oliveira6e3c9712015-01-15 14:55:25 +02002442 if (intel_crtc->config->has_audio) {
Jani Nikula69bfe1a2014-10-27 16:26:50 +02002443 intel_audio_codec_disable(intel_encoder);
Paulo Zanonid45a0bf2014-05-21 17:29:31 -03002444 intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
2445 }
Paulo Zanoni2831d8422013-03-06 20:03:09 -03002446
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002447 if (type == INTEL_OUTPUT_EDP) {
2448 struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
2449
Vandana Kannanc3955782015-01-22 15:17:40 +05302450 intel_edp_drrs_disable(intel_dp);
Rodrigo Vivi0bc12bc2014-11-14 08:52:28 -08002451 intel_psr_disable(intel_dp);
Daniel Vetter4be73782014-01-17 14:39:48 +01002452 intel_edp_backlight_off(intel_dp);
Paulo Zanonid6c50ff2012-10-23 18:30:06 -02002453 }
Eugeni Dodonov72662e12012-05-09 15:37:31 -03002454}
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002455
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002456static void hsw_ddi_wrpll_enable(struct drm_i915_private *dev_priv,
Daniel Vettere0b01be2014-06-25 22:02:01 +03002457 struct intel_shared_dpll *pll)
2458{
Ander Conselvan de Oliveira3e369b72014-10-29 11:32:32 +02002459 I915_WRITE(WRPLL_CTL(pll->id), pll->config.hw_state.wrpll);
Daniel Vettere0b01be2014-06-25 22:02:01 +03002460 POSTING_READ(WRPLL_CTL(pll->id));
2461 udelay(20);
2462}
2463
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002464static void hsw_ddi_spll_enable(struct drm_i915_private *dev_priv,
Daniel Vetter12030432014-06-25 22:02:00 +03002465 struct intel_shared_dpll *pll)
2466{
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002467 I915_WRITE(SPLL_CTL, pll->config.hw_state.spll);
2468 POSTING_READ(SPLL_CTL);
2469 udelay(20);
2470}
2471
2472static void hsw_ddi_wrpll_disable(struct drm_i915_private *dev_priv,
2473 struct intel_shared_dpll *pll)
2474{
Daniel Vetter12030432014-06-25 22:02:00 +03002475 uint32_t val;
2476
2477 val = I915_READ(WRPLL_CTL(pll->id));
Daniel Vetter12030432014-06-25 22:02:00 +03002478 I915_WRITE(WRPLL_CTL(pll->id), val & ~WRPLL_PLL_ENABLE);
2479 POSTING_READ(WRPLL_CTL(pll->id));
2480}
2481
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002482static void hsw_ddi_spll_disable(struct drm_i915_private *dev_priv,
2483 struct intel_shared_dpll *pll)
2484{
2485 uint32_t val;
2486
2487 val = I915_READ(SPLL_CTL);
2488 I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE);
2489 POSTING_READ(SPLL_CTL);
2490}
2491
2492static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv,
2493 struct intel_shared_dpll *pll,
2494 struct intel_dpll_hw_state *hw_state)
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002495{
2496 uint32_t val;
2497
Daniel Vetterf458ebb2014-09-30 10:56:39 +02002498 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002499 return false;
2500
2501 val = I915_READ(WRPLL_CTL(pll->id));
2502 hw_state->wrpll = val;
2503
2504 return val & WRPLL_PLL_ENABLE;
2505}
2506
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002507static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv,
2508 struct intel_shared_dpll *pll,
2509 struct intel_dpll_hw_state *hw_state)
2510{
2511 uint32_t val;
2512
2513 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2514 return false;
2515
2516 val = I915_READ(SPLL_CTL);
2517 hw_state->spll = val;
2518
2519 return val & SPLL_PLL_ENABLE;
2520}
2521
2522
Damien Lespiauca1381b2014-07-15 15:05:33 +01002523static const char * const hsw_ddi_pll_names[] = {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002524 "WRPLL 1",
2525 "WRPLL 2",
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002526 "SPLL"
Daniel Vetter9cd86932014-06-25 22:01:57 +03002527};
2528
Damien Lespiau143b3072014-07-29 18:06:19 +01002529static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv)
Paulo Zanoni79f689a2012-10-05 12:05:52 -03002530{
Daniel Vetter9cd86932014-06-25 22:01:57 +03002531 int i;
2532
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002533 dev_priv->num_shared_dpll = 3;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002534
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002535 for (i = 0; i < 2; i++) {
Daniel Vetter9cd86932014-06-25 22:01:57 +03002536 dev_priv->shared_dplls[i].id = i;
2537 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002538 dev_priv->shared_dplls[i].disable = hsw_ddi_wrpll_disable;
2539 dev_priv->shared_dplls[i].enable = hsw_ddi_wrpll_enable;
Daniel Vetterd452c5b2014-07-04 11:27:39 -03002540 dev_priv->shared_dplls[i].get_hw_state =
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002541 hsw_ddi_wrpll_get_hw_state;
Daniel Vetter9cd86932014-06-25 22:01:57 +03002542 }
Maarten Lankhorst00490c22015-11-16 14:42:12 +01002543
2544 /* SPLL is special, but needs to be initialized anyway.. */
2545 dev_priv->shared_dplls[i].id = i;
2546 dev_priv->shared_dplls[i].name = hsw_ddi_pll_names[i];
2547 dev_priv->shared_dplls[i].disable = hsw_ddi_spll_disable;
2548 dev_priv->shared_dplls[i].enable = hsw_ddi_spll_enable;
2549 dev_priv->shared_dplls[i].get_hw_state = hsw_ddi_spll_get_hw_state;
2550
Damien Lespiau143b3072014-07-29 18:06:19 +01002551}
2552
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002553static const char * const skl_ddi_pll_names[] = {
2554 "DPLL 1",
2555 "DPLL 2",
2556 "DPLL 3",
2557};
2558
2559struct skl_dpll_regs {
Ville Syrjäläf0f59a02015-11-18 15:33:26 +02002560 i915_reg_t ctl, cfgcr1, cfgcr2;
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002561};
2562
2563/* this array is indexed by the *shared* pll id */
2564static const struct skl_dpll_regs skl_dpll_regs[3] = {
2565 {
2566 /* DPLL 1 */
2567 .ctl = LCPLL2_CTL,
Ville Syrjälä923c12412015-09-30 17:06:43 +03002568 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL1),
2569 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL1),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002570 },
2571 {
2572 /* DPLL 2 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002573 .ctl = WRPLL_CTL(0),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002574 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL2),
2575 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL2),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002576 },
2577 {
2578 /* DPLL 3 */
Ville Syrjälä01403de2015-09-18 20:03:33 +03002579 .ctl = WRPLL_CTL(1),
Ville Syrjälä923c12412015-09-30 17:06:43 +03002580 .cfgcr1 = DPLL_CFGCR1(SKL_DPLL3),
2581 .cfgcr2 = DPLL_CFGCR2(SKL_DPLL3),
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002582 },
2583};
2584
2585static void skl_ddi_pll_enable(struct drm_i915_private *dev_priv,
2586 struct intel_shared_dpll *pll)
2587{
2588 uint32_t val;
2589 unsigned int dpll;
2590 const struct skl_dpll_regs *regs = skl_dpll_regs;
2591
2592 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2593 dpll = pll->id + 1;
2594
2595 val = I915_READ(DPLL_CTRL1);
2596
2597 val &= ~(DPLL_CTRL1_HDMI_MODE(dpll) | DPLL_CTRL1_SSC(dpll) |
Damien Lespiau71cd8422015-04-30 16:39:17 +01002598 DPLL_CTRL1_LINK_RATE_MASK(dpll));
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00002599 val |= pll->config.hw_state.ctrl1 << (dpll * 6);
2600
2601 I915_WRITE(DPLL_CTRL1, val);
2602 POSTING_READ(DPLL_CTRL1);
2603
2604 I915_WRITE(regs[pll->id].cfgcr1, pll->config.hw_state.cfgcr1);
2605 I915_WRITE(regs[pll->id].cfgcr2, pll->config.hw_state.cfgcr2);
2606 POSTING_READ(regs[pll->id].cfgcr1);
2607 POSTING_READ(regs[pll->id].cfgcr2);
2608
2609 /* the enable bit is always bit 31 */
2610 I915_WRITE(regs[pll->id].ctl,
2611 I915_READ(regs[pll->id].ctl) | LCPLL_PLL_ENABLE);
2612
2613 if (wait_for(I915_READ(DPLL_STATUS) & DPLL_LOCK(dpll), 5))
2614 DRM_ERROR("DPLL %d not locked\n", dpll);
2615}
2616
2617static void skl_ddi_pll_disable(struct drm_i915_private *dev_priv,
2618 struct intel_shared_dpll *pll)
2619{
2620 const struct skl_dpll_regs *regs = skl_dpll_regs;
2621
2622 /* the enable bit is always bit 31 */
2623 I915_WRITE(regs[pll->id].ctl,
2624 I915_READ(regs[pll->id].ctl) & ~LCPLL_PLL_ENABLE);
2625 POSTING_READ(regs[pll->id].ctl);
2626}
2627
2628static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2629 struct intel_shared_dpll *pll,
2630 struct intel_dpll_hw_state *hw_state)
2631{
2632 uint32_t val;
2633 unsigned int dpll;
2634 const struct skl_dpll_regs *regs = skl_dpll_regs;
2635
2636 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2637 return false;
2638
2639 /* DPLL0 is not part of the shared DPLLs, so pll->id is 0 for DPLL1 */
2640 dpll = pll->id + 1;
2641
2642 val = I915_READ(regs[pll->id].ctl);
2643 if (!(val & LCPLL_PLL_ENABLE))
2644 return false;
2645
2646 val = I915_READ(DPLL_CTRL1);
2647 hw_state->ctrl1 = (val >> (dpll * 6)) & 0x3f;
2648
2649 /* avoid reading back stale values if HDMI mode is not enabled */
2650 if (val & DPLL_CTRL1_HDMI_MODE(dpll)) {
2651 hw_state->cfgcr1 = I915_READ(regs[pll->id].cfgcr1);
2652 hw_state->cfgcr2 = I915_READ(regs[pll->id].cfgcr2);
2653 }
2654
2655 return true;
2656}
2657
2658static void skl_shared_dplls_init(struct drm_i915_private *dev_priv)
2659{
2660 int i;
2661
2662 dev_priv->num_shared_dpll = 3;
2663
2664 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2665 dev_priv->shared_dplls[i].id = i;
2666 dev_priv->shared_dplls[i].name = skl_ddi_pll_names[i];
2667 dev_priv->shared_dplls[i].disable = skl_ddi_pll_disable;
2668 dev_priv->shared_dplls[i].enable = skl_ddi_pll_enable;
2669 dev_priv->shared_dplls[i].get_hw_state =
2670 skl_ddi_pll_get_hw_state;
2671 }
2672}
2673
Vandana Kannan5c6706e2014-11-24 13:37:39 +05302674static void broxton_phy_init(struct drm_i915_private *dev_priv,
2675 enum dpio_phy phy)
2676{
2677 enum port port;
2678 uint32_t val;
2679
2680 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
2681 val |= GT_DISPLAY_POWER_ON(phy);
2682 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
2683
2684 /* Considering 10ms timeout until BSpec is updated */
2685 if (wait_for(I915_READ(BXT_PORT_CL1CM_DW0(phy)) & PHY_POWER_GOOD, 10))
2686 DRM_ERROR("timeout during PHY%d power on\n", phy);
2687
2688 for (port = (phy == DPIO_PHY0 ? PORT_B : PORT_A);
2689 port <= (phy == DPIO_PHY0 ? PORT_C : PORT_A); port++) {
2690 int lane;
2691
2692 for (lane = 0; lane < 4; lane++) {
2693 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
2694 /*
2695 * Note that on CHV this flag is called UPAR, but has
2696 * the same function.
2697 */
2698 val &= ~LATENCY_OPTIM;
2699 if (lane != 1)
2700 val |= LATENCY_OPTIM;
2701
2702 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
2703 }
2704 }
2705
2706 /* Program PLL Rcomp code offset */
2707 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
2708 val &= ~IREF0RC_OFFSET_MASK;
2709 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
2710 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
2711
2712 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
2713 val &= ~IREF1RC_OFFSET_MASK;
2714 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
2715 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
2716
2717 /* Program power gating */
2718 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
2719 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
2720 SUS_CLK_CONFIG;
2721 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
2722
2723 if (phy == DPIO_PHY0) {
2724 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
2725 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
2726 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
2727 }
2728
2729 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
2730 val &= ~OCL2_LDOFUSE_PWR_DIS;
2731 /*
2732 * On PHY1 disable power on the second channel, since no port is
2733 * connected there. On PHY0 both channels have a port, so leave it
2734 * enabled.
2735 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
2736 * power down the second channel on PHY0 as well.
2737 */
2738 if (phy == DPIO_PHY1)
2739 val |= OCL2_LDOFUSE_PWR_DIS;
2740 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
2741
2742 if (phy == DPIO_PHY0) {
2743 uint32_t grc_code;
2744 /*
2745 * PHY0 isn't connected to an RCOMP resistor so copy over
2746 * the corresponding calibrated value from PHY1, and disable
2747 * the automatic calibration on PHY0.
2748 */
2749 if (wait_for(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE,
2750 10))
2751 DRM_ERROR("timeout waiting for PHY1 GRC\n");
2752
2753 val = I915_READ(BXT_PORT_REF_DW6(DPIO_PHY1));
2754 val = (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
2755 grc_code = val << GRC_CODE_FAST_SHIFT |
2756 val << GRC_CODE_SLOW_SHIFT |
2757 val;
2758 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
2759
2760 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
2761 val |= GRC_DIS | GRC_RDY_OVRD;
2762 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
2763 }
2764
2765 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2766 val |= COMMON_RESET_DIS;
2767 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2768}
2769
2770void broxton_ddi_phy_init(struct drm_device *dev)
2771{
2772 /* Enable PHY1 first since it provides Rcomp for PHY0 */
2773 broxton_phy_init(dev->dev_private, DPIO_PHY1);
2774 broxton_phy_init(dev->dev_private, DPIO_PHY0);
2775}
2776
2777static void broxton_phy_uninit(struct drm_i915_private *dev_priv,
2778 enum dpio_phy phy)
2779{
2780 uint32_t val;
2781
2782 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
2783 val &= ~COMMON_RESET_DIS;
2784 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
2785}
2786
2787void broxton_ddi_phy_uninit(struct drm_device *dev)
2788{
2789 struct drm_i915_private *dev_priv = dev->dev_private;
2790
2791 broxton_phy_uninit(dev_priv, DPIO_PHY1);
2792 broxton_phy_uninit(dev_priv, DPIO_PHY0);
2793
2794 /* FIXME: do this in broxton_phy_uninit per phy */
2795 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, 0);
2796}
2797
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302798static const char * const bxt_ddi_pll_names[] = {
2799 "PORT PLL A",
2800 "PORT PLL B",
2801 "PORT PLL C",
2802};
2803
2804static void bxt_ddi_pll_enable(struct drm_i915_private *dev_priv,
2805 struct intel_shared_dpll *pll)
2806{
2807 uint32_t temp;
2808 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2809
2810 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2811 temp &= ~PORT_PLL_REF_SEL;
2812 /* Non-SSC reference */
2813 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2814
2815 /* Disable 10 bit clock */
2816 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2817 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2818 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2819
2820 /* Write P1 & P2 */
2821 temp = I915_READ(BXT_PORT_PLL_EBB_0(port));
2822 temp &= ~(PORT_PLL_P1_MASK | PORT_PLL_P2_MASK);
2823 temp |= pll->config.hw_state.ebb0;
2824 I915_WRITE(BXT_PORT_PLL_EBB_0(port), temp);
2825
2826 /* Write M2 integer */
2827 temp = I915_READ(BXT_PORT_PLL(port, 0));
2828 temp &= ~PORT_PLL_M2_MASK;
2829 temp |= pll->config.hw_state.pll0;
2830 I915_WRITE(BXT_PORT_PLL(port, 0), temp);
2831
2832 /* Write N */
2833 temp = I915_READ(BXT_PORT_PLL(port, 1));
2834 temp &= ~PORT_PLL_N_MASK;
2835 temp |= pll->config.hw_state.pll1;
2836 I915_WRITE(BXT_PORT_PLL(port, 1), temp);
2837
2838 /* Write M2 fraction */
2839 temp = I915_READ(BXT_PORT_PLL(port, 2));
2840 temp &= ~PORT_PLL_M2_FRAC_MASK;
2841 temp |= pll->config.hw_state.pll2;
2842 I915_WRITE(BXT_PORT_PLL(port, 2), temp);
2843
2844 /* Write M2 fraction enable */
2845 temp = I915_READ(BXT_PORT_PLL(port, 3));
2846 temp &= ~PORT_PLL_M2_FRAC_ENABLE;
2847 temp |= pll->config.hw_state.pll3;
2848 I915_WRITE(BXT_PORT_PLL(port, 3), temp);
2849
2850 /* Write coeff */
2851 temp = I915_READ(BXT_PORT_PLL(port, 6));
2852 temp &= ~PORT_PLL_PROP_COEFF_MASK;
2853 temp &= ~PORT_PLL_INT_COEFF_MASK;
2854 temp &= ~PORT_PLL_GAIN_CTL_MASK;
2855 temp |= pll->config.hw_state.pll6;
2856 I915_WRITE(BXT_PORT_PLL(port, 6), temp);
2857
2858 /* Write calibration val */
2859 temp = I915_READ(BXT_PORT_PLL(port, 8));
2860 temp &= ~PORT_PLL_TARGET_CNT_MASK;
2861 temp |= pll->config.hw_state.pll8;
2862 I915_WRITE(BXT_PORT_PLL(port, 8), temp);
2863
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302864 temp = I915_READ(BXT_PORT_PLL(port, 9));
2865 temp &= ~PORT_PLL_LOCK_THRESHOLD_MASK;
Imre Deak05712c12015-06-18 17:25:54 +03002866 temp |= pll->config.hw_state.pll9;
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302867 I915_WRITE(BXT_PORT_PLL(port, 9), temp);
2868
2869 temp = I915_READ(BXT_PORT_PLL(port, 10));
2870 temp &= ~PORT_PLL_DCO_AMP_OVR_EN_H;
2871 temp &= ~PORT_PLL_DCO_AMP_MASK;
2872 temp |= pll->config.hw_state.pll10;
2873 I915_WRITE(BXT_PORT_PLL(port, 10), temp);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302874
2875 /* Recalibrate with new settings */
2876 temp = I915_READ(BXT_PORT_PLL_EBB_4(port));
2877 temp |= PORT_PLL_RECALIBRATE;
2878 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
Imre Deak05712c12015-06-18 17:25:54 +03002879 temp &= ~PORT_PLL_10BIT_CLK_ENABLE;
2880 temp |= pll->config.hw_state.ebb4;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302881 I915_WRITE(BXT_PORT_PLL_EBB_4(port), temp);
2882
2883 /* Enable PLL */
2884 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2885 temp |= PORT_PLL_ENABLE;
2886 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2887 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2888
2889 if (wait_for_atomic_us((I915_READ(BXT_PORT_PLL_ENABLE(port)) &
2890 PORT_PLL_LOCK), 200))
2891 DRM_ERROR("PLL %d not locked\n", port);
2892
2893 /*
2894 * While we write to the group register to program all lanes at once we
2895 * can read only lane registers and we pick lanes 0/1 for that.
2896 */
2897 temp = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
2898 temp &= ~LANE_STAGGER_MASK;
2899 temp &= ~LANESTAGGER_STRAP_OVRD;
2900 temp |= pll->config.hw_state.pcsdw12;
2901 I915_WRITE(BXT_PORT_PCS_DW12_GRP(port), temp);
2902}
2903
2904static void bxt_ddi_pll_disable(struct drm_i915_private *dev_priv,
2905 struct intel_shared_dpll *pll)
2906{
2907 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2908 uint32_t temp;
2909
2910 temp = I915_READ(BXT_PORT_PLL_ENABLE(port));
2911 temp &= ~PORT_PLL_ENABLE;
2912 I915_WRITE(BXT_PORT_PLL_ENABLE(port), temp);
2913 POSTING_READ(BXT_PORT_PLL_ENABLE(port));
2914}
2915
2916static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
2917 struct intel_shared_dpll *pll,
2918 struct intel_dpll_hw_state *hw_state)
2919{
2920 enum port port = (enum port)pll->id; /* 1:1 port->PLL mapping */
2921 uint32_t val;
2922
2923 if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_PLLS))
2924 return false;
2925
2926 val = I915_READ(BXT_PORT_PLL_ENABLE(port));
2927 if (!(val & PORT_PLL_ENABLE))
2928 return false;
2929
2930 hw_state->ebb0 = I915_READ(BXT_PORT_PLL_EBB_0(port));
Imre Deak793dfa52015-06-18 17:25:53 +03002931 hw_state->ebb0 &= PORT_PLL_P1_MASK | PORT_PLL_P2_MASK;
2932
Imre Deak05712c12015-06-18 17:25:54 +03002933 hw_state->ebb4 = I915_READ(BXT_PORT_PLL_EBB_4(port));
2934 hw_state->ebb4 &= PORT_PLL_10BIT_CLK_ENABLE;
2935
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302936 hw_state->pll0 = I915_READ(BXT_PORT_PLL(port, 0));
Imre Deak793dfa52015-06-18 17:25:53 +03002937 hw_state->pll0 &= PORT_PLL_M2_MASK;
2938
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302939 hw_state->pll1 = I915_READ(BXT_PORT_PLL(port, 1));
Imre Deak793dfa52015-06-18 17:25:53 +03002940 hw_state->pll1 &= PORT_PLL_N_MASK;
2941
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302942 hw_state->pll2 = I915_READ(BXT_PORT_PLL(port, 2));
Imre Deak793dfa52015-06-18 17:25:53 +03002943 hw_state->pll2 &= PORT_PLL_M2_FRAC_MASK;
2944
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302945 hw_state->pll3 = I915_READ(BXT_PORT_PLL(port, 3));
Imre Deak793dfa52015-06-18 17:25:53 +03002946 hw_state->pll3 &= PORT_PLL_M2_FRAC_ENABLE;
2947
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302948 hw_state->pll6 = I915_READ(BXT_PORT_PLL(port, 6));
Imre Deak793dfa52015-06-18 17:25:53 +03002949 hw_state->pll6 &= PORT_PLL_PROP_COEFF_MASK |
2950 PORT_PLL_INT_COEFF_MASK |
2951 PORT_PLL_GAIN_CTL_MASK;
2952
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302953 hw_state->pll8 = I915_READ(BXT_PORT_PLL(port, 8));
Imre Deak793dfa52015-06-18 17:25:53 +03002954 hw_state->pll8 &= PORT_PLL_TARGET_CNT_MASK;
2955
Imre Deak05712c12015-06-18 17:25:54 +03002956 hw_state->pll9 = I915_READ(BXT_PORT_PLL(port, 9));
2957 hw_state->pll9 &= PORT_PLL_LOCK_THRESHOLD_MASK;
2958
Vandana Kannanb6dc71f2015-05-13 12:18:52 +05302959 hw_state->pll10 = I915_READ(BXT_PORT_PLL(port, 10));
Imre Deak793dfa52015-06-18 17:25:53 +03002960 hw_state->pll10 &= PORT_PLL_DCO_AMP_OVR_EN_H |
2961 PORT_PLL_DCO_AMP_MASK;
2962
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302963 /*
2964 * While we write to the group register to program all lanes at once we
2965 * can read only lane registers. We configure all lanes the same way, so
2966 * here just read out lanes 0/1 and output a note if lanes 2/3 differ.
2967 */
2968 hw_state->pcsdw12 = I915_READ(BXT_PORT_PCS_DW12_LN01(port));
Damien Lespiaub5dada82015-09-17 14:20:32 +01002969 if (I915_READ(BXT_PORT_PCS_DW12_LN23(port)) != hw_state->pcsdw12)
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302970 DRM_DEBUG_DRIVER("lane stagger config different for lane 01 (%08x) and 23 (%08x)\n",
2971 hw_state->pcsdw12,
2972 I915_READ(BXT_PORT_PCS_DW12_LN23(port)));
Imre Deak793dfa52015-06-18 17:25:53 +03002973 hw_state->pcsdw12 &= LANE_STAGGER_MASK | LANESTAGGER_STRAP_OVRD;
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05302974
2975 return true;
2976}
2977
2978static void bxt_shared_dplls_init(struct drm_i915_private *dev_priv)
2979{
2980 int i;
2981
2982 dev_priv->num_shared_dpll = 3;
2983
2984 for (i = 0; i < dev_priv->num_shared_dpll; i++) {
2985 dev_priv->shared_dplls[i].id = i;
2986 dev_priv->shared_dplls[i].name = bxt_ddi_pll_names[i];
2987 dev_priv->shared_dplls[i].disable = bxt_ddi_pll_disable;
2988 dev_priv->shared_dplls[i].enable = bxt_ddi_pll_enable;
2989 dev_priv->shared_dplls[i].get_hw_state =
2990 bxt_ddi_pll_get_hw_state;
2991 }
2992}
2993
Damien Lespiau143b3072014-07-29 18:06:19 +01002994void intel_ddi_pll_init(struct drm_device *dev)
2995{
2996 struct drm_i915_private *dev_priv = dev->dev_private;
2997 uint32_t val = I915_READ(LCPLL_CTL);
2998
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07002999 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev))
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003000 skl_shared_dplls_init(dev_priv);
Satheeshakrishna Mdfb82402014-08-22 09:49:09 +05303001 else if (IS_BROXTON(dev))
3002 bxt_shared_dplls_init(dev_priv);
Satheeshakrishna Md1a2dc72014-11-13 14:55:18 +00003003 else
3004 hsw_shared_dplls_init(dev_priv);
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003005
Rodrigo Vivief11bdb2015-10-28 04:16:45 -07003006 if (IS_SKYLAKE(dev) || IS_KABYLAKE(dev)) {
Damien Lespiaud9062ae2015-06-04 18:21:32 +01003007 int cdclk_freq;
3008
3009 cdclk_freq = dev_priv->display.get_display_clock_speed(dev);
Damien Lespiau5d96d8a2015-05-21 16:37:48 +01003010 dev_priv->skl_boot_cdclk = cdclk_freq;
Shobhit Kumarc73666f2015-10-20 18:13:12 +05303011 if (skl_sanitize_cdclk(dev_priv))
3012 DRM_DEBUG_KMS("Sanitized cdclk programmed by pre-os\n");
Damien Lespiau2f693e22015-11-04 19:24:12 +02003013 if (!(I915_READ(LCPLL1_CTL) & LCPLL_PLL_ENABLE))
3014 DRM_ERROR("LCPLL1 is disabled\n");
Vandana Kannanf8437dd12014-11-24 13:37:39 +05303015 } else if (IS_BROXTON(dev)) {
3016 broxton_init_cdclk(dev);
Vandana Kannan5c6706e2014-11-24 13:37:39 +05303017 broxton_ddi_phy_init(dev);
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003018 } else {
3019 /*
3020 * The LCPLL register should be turned on by the BIOS. For now
3021 * let's just check its state and print errors in case
3022 * something is wrong. Don't even try to turn it on.
3023 */
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003024
Satheeshakrishna M121643c2014-11-13 14:55:15 +00003025 if (val & LCPLL_CD_SOURCE_FCLK)
3026 DRM_ERROR("CDCLK source is not LCPLL\n");
3027
3028 if (val & LCPLL_PLL_DISABLE)
3029 DRM_ERROR("LCPLL is disabled\n");
3030 }
Paulo Zanoni79f689a2012-10-05 12:05:52 -03003031}
Paulo Zanonic19b0662012-10-15 15:51:41 -03003032
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003033void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
Paulo Zanonic19b0662012-10-15 15:51:41 -03003034{
Ander Conselvan de Oliveiraad642172015-10-23 13:01:49 +03003035 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
3036 struct drm_i915_private *dev_priv =
3037 to_i915(intel_dig_port->base.base.dev);
Paulo Zanoni174edf12012-10-26 19:05:50 -02003038 enum port port = intel_dig_port->port;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003039 uint32_t val;
Syam Sidhardhanf3e227d2013-02-25 04:05:38 +05303040 bool wait = false;
Paulo Zanonic19b0662012-10-15 15:51:41 -03003041
3042 if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) {
3043 val = I915_READ(DDI_BUF_CTL(port));
3044 if (val & DDI_BUF_CTL_ENABLE) {
3045 val &= ~DDI_BUF_CTL_ENABLE;
3046 I915_WRITE(DDI_BUF_CTL(port), val);
3047 wait = true;
3048 }
3049
3050 val = I915_READ(DP_TP_CTL(port));
3051 val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
3052 val |= DP_TP_CTL_LINK_TRAIN_PAT1;
3053 I915_WRITE(DP_TP_CTL(port), val);
3054 POSTING_READ(DP_TP_CTL(port));
3055
3056 if (wait)
3057 intel_wait_ddi_buf_idle(dev_priv, port);
3058 }
3059
Dave Airlie0e32b392014-05-02 14:02:48 +10003060 val = DP_TP_CTL_ENABLE |
Paulo Zanonic19b0662012-10-15 15:51:41 -03003061 DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
Dave Airlie0e32b392014-05-02 14:02:48 +10003062 if (intel_dp->is_mst)
3063 val |= DP_TP_CTL_MODE_MST;
3064 else {
3065 val |= DP_TP_CTL_MODE_SST;
3066 if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
3067 val |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
3068 }
Paulo Zanonic19b0662012-10-15 15:51:41 -03003069 I915_WRITE(DP_TP_CTL(port), val);
3070 POSTING_READ(DP_TP_CTL(port));
3071
3072 intel_dp->DP |= DDI_BUF_CTL_ENABLE;
3073 I915_WRITE(DDI_BUF_CTL(port), intel_dp->DP);
3074 POSTING_READ(DDI_BUF_CTL(port));
3075
3076 udelay(600);
3077}
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003078
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003079void intel_ddi_fdi_disable(struct drm_crtc *crtc)
3080{
3081 struct drm_i915_private *dev_priv = crtc->dev->dev_private;
3082 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
3083 uint32_t val;
3084
3085 intel_ddi_post_disable(intel_encoder);
3086
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003087 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003088 val &= ~FDI_RX_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003089 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003090
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003091 val = I915_READ(FDI_RX_MISC(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003092 val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
3093 val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003094 I915_WRITE(FDI_RX_MISC(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003095
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003096 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003097 val &= ~FDI_PCDCLK;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003098 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003099
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003100 val = I915_READ(FDI_RX_CTL(PIPE_A));
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003101 val &= ~FDI_RX_PLL_ENABLE;
Ville Syrjäläeede3b52015-09-18 20:03:30 +03003102 I915_WRITE(FDI_RX_CTL(PIPE_A), val);
Paulo Zanoni1ad960f2012-11-01 21:05:05 -02003103}
3104
Libin Yang3d52ccf2015-12-02 14:09:44 +08003105bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
3106 struct intel_crtc *intel_crtc)
3107{
3108 u32 temp;
3109
3110 if (intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO)) {
3111 temp = I915_READ(HSW_AUD_PIN_ELD_CP_VLD);
3112 if (temp & AUDIO_OUTPUT_ENABLE(intel_crtc->pipe))
3113 return true;
3114 }
3115 return false;
3116}
3117
Ville Syrjälä6801c182013-09-24 14:24:05 +03003118void intel_ddi_get_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003119 struct intel_crtc_state *pipe_config)
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003120{
3121 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
3122 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
Ander Conselvan de Oliveira0cb09a92015-01-30 12:17:23 +02003123 enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003124 struct intel_hdmi *intel_hdmi;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003125 u32 temp, flags = 0;
3126
3127 temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
3128 if (temp & TRANS_DDI_PHSYNC)
3129 flags |= DRM_MODE_FLAG_PHSYNC;
3130 else
3131 flags |= DRM_MODE_FLAG_NHSYNC;
3132 if (temp & TRANS_DDI_PVSYNC)
3133 flags |= DRM_MODE_FLAG_PVSYNC;
3134 else
3135 flags |= DRM_MODE_FLAG_NVSYNC;
3136
Ander Conselvan de Oliveira2d112de2015-01-15 14:55:22 +02003137 pipe_config->base.adjusted_mode.flags |= flags;
Ville Syrjälä42571ae2013-09-06 23:29:00 +03003138
3139 switch (temp & TRANS_DDI_BPC_MASK) {
3140 case TRANS_DDI_BPC_6:
3141 pipe_config->pipe_bpp = 18;
3142 break;
3143 case TRANS_DDI_BPC_8:
3144 pipe_config->pipe_bpp = 24;
3145 break;
3146 case TRANS_DDI_BPC_10:
3147 pipe_config->pipe_bpp = 30;
3148 break;
3149 case TRANS_DDI_BPC_12:
3150 pipe_config->pipe_bpp = 36;
3151 break;
3152 default:
3153 break;
3154 }
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003155
3156 switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
3157 case TRANS_DDI_MODE_SELECT_HDMI:
Daniel Vetter6897b4b2014-04-24 23:54:47 +02003158 pipe_config->has_hdmi_sink = true;
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003159 intel_hdmi = enc_to_intel_hdmi(&encoder->base);
3160
Ville Syrjäläcda0aaa2015-11-26 18:27:07 +02003161 if (intel_hdmi->infoframe_enabled(&encoder->base, pipe_config))
Daniel Vetterbbd440f2014-11-20 22:33:59 +01003162 pipe_config->has_infoframe = true;
Jesse Barnescbc572a2014-11-17 13:08:47 -08003163 break;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003164 case TRANS_DDI_MODE_SELECT_DVI:
3165 case TRANS_DDI_MODE_SELECT_FDI:
3166 break;
3167 case TRANS_DDI_MODE_SELECT_DP_SST:
3168 case TRANS_DDI_MODE_SELECT_DP_MST:
3169 pipe_config->has_dp_encoder = true;
Ville Syrjälä90a6b7b2015-07-06 16:39:15 +03003170 pipe_config->lane_count =
3171 ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
Ville Syrjäläeb14cb72013-09-10 17:02:54 +03003172 intel_dp_get_m_n(intel_crtc, pipe_config);
3173 break;
3174 default:
3175 break;
3176 }
Daniel Vetter10214422013-11-18 07:38:16 +01003177
Libin Yang3d52ccf2015-12-02 14:09:44 +08003178 pipe_config->has_audio =
3179 intel_ddi_is_audio_enabled(dev_priv, intel_crtc);
Daniel Vetter9ed109a2014-04-24 23:54:52 +02003180
Daniel Vetter10214422013-11-18 07:38:16 +01003181 if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp_bpp &&
3182 pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
3183 /*
3184 * This is a big fat ugly hack.
3185 *
3186 * Some machines in UEFI boot mode provide us a VBT that has 18
3187 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
3188 * unknown we fail to light up. Yet the same BIOS boots up with
3189 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
3190 * max, not what it tells us to use.
3191 *
3192 * Note: This will still be broken if the eDP panel is not lit
3193 * up by the BIOS, and thus we can't get the mode at module
3194 * load.
3195 */
3196 DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
3197 pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
3198 dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
3199 }
Jesse Barnes11578552014-01-21 12:42:10 -08003200
Damien Lespiau22606a12014-12-12 14:26:57 +00003201 intel_ddi_clock_get(encoder, pipe_config);
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003202}
3203
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003204static void intel_ddi_destroy(struct drm_encoder *encoder)
3205{
3206 /* HDMI has nothing special to destroy, so we can go with this. */
3207 intel_dp_encoder_destroy(encoder);
3208}
3209
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003210static bool intel_ddi_compute_config(struct intel_encoder *encoder,
Ander Conselvan de Oliveira5cec2582015-01-15 14:55:21 +02003211 struct intel_crtc_state *pipe_config)
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003212{
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003213 int type = encoder->type;
Daniel Vettereccb1402013-05-22 00:50:22 +02003214 int port = intel_ddi_get_encoder_port(encoder);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003215
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003216 WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n");
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003217
Daniel Vettereccb1402013-05-22 00:50:22 +02003218 if (port == PORT_A)
3219 pipe_config->cpu_transcoder = TRANSCODER_EDP;
3220
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003221 if (type == INTEL_OUTPUT_HDMI)
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003222 return intel_hdmi_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003223 else
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003224 return intel_dp_compute_config(encoder, pipe_config);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003225}
3226
3227static const struct drm_encoder_funcs intel_ddi_funcs = {
3228 .destroy = intel_ddi_destroy,
3229};
3230
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003231static struct intel_connector *
3232intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
3233{
3234 struct intel_connector *connector;
3235 enum port port = intel_dig_port->port;
3236
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003237 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003238 if (!connector)
3239 return NULL;
3240
3241 intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
3242 if (!intel_dp_init_connector(intel_dig_port, connector)) {
3243 kfree(connector);
3244 return NULL;
3245 }
3246
3247 return connector;
3248}
3249
3250static struct intel_connector *
3251intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port)
3252{
3253 struct intel_connector *connector;
3254 enum port port = intel_dig_port->port;
3255
Ander Conselvan de Oliveira9bdbd0b2015-04-10 10:59:10 +03003256 connector = intel_connector_alloc();
Paulo Zanoni4a28ae52013-10-09 13:52:36 -03003257 if (!connector)
3258 return NULL;
3259
3260 intel_dig_port->hdmi.hdmi_reg = DDI_BUF_CTL(port);
3261 intel_hdmi_init_connector(intel_dig_port, connector);
3262
3263 return connector;
3264}
3265
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003266void intel_ddi_init(struct drm_device *dev, enum port port)
3267{
Damien Lespiau876a8cd2012-12-11 18:48:30 +00003268 struct drm_i915_private *dev_priv = dev->dev_private;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003269 struct intel_digital_port *intel_dig_port;
3270 struct intel_encoder *intel_encoder;
3271 struct drm_encoder *encoder;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003272 bool init_hdmi, init_dp;
Ville Syrjälä10e7bec2015-12-08 19:59:37 +02003273 int max_lanes;
3274
3275 if (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) {
3276 switch (port) {
3277 case PORT_A:
3278 max_lanes = 4;
3279 break;
3280 case PORT_E:
3281 max_lanes = 0;
3282 break;
3283 default:
3284 max_lanes = 4;
3285 break;
3286 }
3287 } else {
3288 switch (port) {
3289 case PORT_A:
3290 max_lanes = 2;
3291 break;
3292 case PORT_E:
3293 max_lanes = 2;
3294 break;
3295 default:
3296 max_lanes = 4;
3297 break;
3298 }
3299 }
Paulo Zanoni311a2092013-09-12 17:12:18 -03003300
3301 init_hdmi = (dev_priv->vbt.ddi_port_info[port].supports_dvi ||
3302 dev_priv->vbt.ddi_port_info[port].supports_hdmi);
3303 init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
3304 if (!init_dp && !init_hdmi) {
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003305 DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
Paulo Zanoni311a2092013-09-12 17:12:18 -03003306 port_name(port));
Rodrigo Vivi500ea702015-08-07 17:01:16 -07003307 return;
Paulo Zanoni311a2092013-09-12 17:12:18 -03003308 }
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003309
Daniel Vetterb14c5672013-09-19 12:18:32 +02003310 intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003311 if (!intel_dig_port)
3312 return;
3313
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003314 intel_encoder = &intel_dig_port->base;
3315 encoder = &intel_encoder->base;
3316
3317 drm_encoder_init(dev, encoder, &intel_ddi_funcs,
3318 DRM_MODE_ENCODER_TMDS);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003319
Daniel Vetter5bfe2ac2013-03-27 00:44:55 +01003320 intel_encoder->compute_config = intel_ddi_compute_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003321 intel_encoder->enable = intel_enable_ddi;
3322 intel_encoder->pre_enable = intel_ddi_pre_enable;
3323 intel_encoder->disable = intel_disable_ddi;
3324 intel_encoder->post_disable = intel_ddi_post_disable;
3325 intel_encoder->get_hw_state = intel_ddi_get_hw_state;
Jesse Barnes045ac3b2013-05-14 17:08:26 -07003326 intel_encoder->get_config = intel_ddi_get_config;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003327
3328 intel_dig_port->port = port;
Takashi Iwai0bdf5a02015-11-30 18:19:39 +01003329 dev_priv->dig_port_map[port] = intel_encoder;
Stéphane Marchesinbcf53de42013-07-12 13:54:41 -07003330 intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) &
3331 (DDI_BUF_PORT_REVERSAL |
3332 DDI_A_4_LANES);
Ville Syrjäläccb1a832015-12-08 19:59:38 +02003333 intel_dig_port->max_lanes = max_lanes;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003334
Matt Roper6c566dc2015-11-05 14:53:32 -08003335 /*
3336 * Bspec says that DDI_A_4_LANES is the only supported configuration
3337 * for Broxton. Yet some BIOS fail to set this bit on port A if eDP
3338 * wasn't lit up at boot. Force this bit on in our internal
3339 * configuration so that we use the proper lane count for our
3340 * calculations.
3341 */
3342 if (IS_BROXTON(dev) && port == PORT_A) {
3343 if (!(intel_dig_port->saved_port_bits & DDI_A_4_LANES)) {
3344 DRM_DEBUG_KMS("BXT BIOS forgot to set DDI_A_4_LANES for port A; fixing\n");
3345 intel_dig_port->saved_port_bits |= DDI_A_4_LANES;
3346 }
3347 }
3348
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003349 intel_encoder->type = INTEL_OUTPUT_UNKNOWN;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003350 intel_encoder->crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);
Ville Syrjäläbc079e82014-03-03 16:15:28 +02003351 intel_encoder->cloneable = 0;
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003352
Chris Wilsonf68d6972014-08-04 07:15:09 +01003353 if (init_dp) {
3354 if (!intel_ddi_init_dp_connector(intel_dig_port))
3355 goto err;
Dave Airlie13cf5502014-06-18 11:29:35 +10003356
Chris Wilsonf68d6972014-08-04 07:15:09 +01003357 intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303358 /*
3359 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
3360 * interrupts to check the external panel connection.
3361 */
Jani Nikulae87a0052015-10-20 15:22:02 +03003362 if (IS_BXT_REVID(dev, 0, BXT_REVID_A1) && port == PORT_B)
Sonika Jindalcf1d5882015-08-10 10:35:36 +05303363 dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
3364 else
3365 dev_priv->hotplug.irq_port[port] = intel_dig_port;
Chris Wilsonf68d6972014-08-04 07:15:09 +01003366 }
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003367
Paulo Zanoni311a2092013-09-12 17:12:18 -03003368 /* In theory we don't need the encoder->type check, but leave it just in
3369 * case we have some really bad VBTs... */
Chris Wilsonf68d6972014-08-04 07:15:09 +01003370 if (intel_encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
3371 if (!intel_ddi_init_hdmi_connector(intel_dig_port))
3372 goto err;
Daniel Vetter21a8e6a2013-04-10 23:28:35 +02003373 }
Chris Wilsonf68d6972014-08-04 07:15:09 +01003374
3375 return;
3376
3377err:
3378 drm_encoder_cleanup(encoder);
3379 kfree(intel_dig_port);
Paulo Zanoni00c09d72012-10-26 19:05:52 -02003380}