aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dpio_phy.c
diff options
context:
space:
mode:
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2016-10-06 12:22:17 -0400
committerAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>2016-10-28 05:24:01 -0400
commit47a6bc61b86657646aea38e837a7f25c68cec7f8 (patch)
tree43bb3b2206c21059ac45d01ba850983cd1b3a5b5 /drivers/gpu/drm/i915/intel_dpio_phy.c
parentb284eedaf74bdbd262f71a7937ca78f45354173f (diff)
drm/i915: Move broxton phy code to intel_dpio_phy.c
The phy in broxton is also a dpio phy, similar to cherryview but with programming through MMIO. So move the code together with the other similar phys. Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/d611de6d256593cf904172db7ff27f164480c228.1475770848.git-series.ander.conselvan.de.oliveira@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dpio_phy.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dpio_phy.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/intel_dpio_phy.c b/drivers/gpu/drm/i915/intel_dpio_phy.c
index 047f48748944..edf0cfd860c4 100644
--- a/drivers/gpu/drm/i915/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/intel_dpio_phy.c
@@ -23,6 +23,333 @@
23 23
24#include "intel_drv.h" 24#include "intel_drv.h"
25 25
26bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
27 enum dpio_phy phy)
28{
29 enum port port;
30
31 if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy)))
32 return false;
33
34 if ((I915_READ(BXT_PORT_CL1CM_DW0(phy)) &
35 (PHY_POWER_GOOD | PHY_RESERVED)) != PHY_POWER_GOOD) {
36 DRM_DEBUG_DRIVER("DDI PHY %d powered, but power hasn't settled\n",
37 phy);
38
39 return false;
40 }
41
42 if (phy == DPIO_PHY1 &&
43 !(I915_READ(BXT_PORT_REF_DW3(DPIO_PHY1)) & GRC_DONE)) {
44 DRM_DEBUG_DRIVER("DDI PHY 1 powered, but GRC isn't done\n");
45
46 return false;
47 }
48
49 if (!(I915_READ(BXT_PHY_CTL_FAMILY(phy)) & COMMON_RESET_DIS)) {
50 DRM_DEBUG_DRIVER("DDI PHY %d powered, but still in reset\n",
51 phy);
52
53 return false;
54 }
55
56 for_each_port_masked(port,
57 phy == DPIO_PHY0 ? BIT(PORT_B) | BIT(PORT_C) :
58 BIT(PORT_A)) {
59 u32 tmp = I915_READ(BXT_PHY_CTL(port));
60
61 if (tmp & BXT_PHY_CMNLANE_POWERDOWN_ACK) {
62 DRM_DEBUG_DRIVER("DDI PHY %d powered, but common lane "
63 "for port %c powered down "
64 "(PHY_CTL %08x)\n",
65 phy, port_name(port), tmp);
66
67 return false;
68 }
69 }
70
71 return true;
72}
73
74static u32 bxt_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy)
75{
76 u32 val = I915_READ(BXT_PORT_REF_DW6(phy));
77
78 return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
79}
80
81static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv,
82 enum dpio_phy phy)
83{
84 if (intel_wait_for_register(dev_priv,
85 BXT_PORT_REF_DW3(phy),
86 GRC_DONE, GRC_DONE,
87 10))
88 DRM_ERROR("timeout waiting for PHY%d GRC\n", phy);
89}
90
91void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy)
92{
93 u32 val;
94
95 if (bxt_ddi_phy_is_enabled(dev_priv, phy)) {
96 /* Still read out the GRC value for state verification */
97 if (phy == DPIO_PHY0)
98 dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, phy);
99
100 if (bxt_ddi_phy_verify_state(dev_priv, phy)) {
101 DRM_DEBUG_DRIVER("DDI PHY %d already enabled, "
102 "won't reprogram it\n", phy);
103
104 return;
105 }
106
107 DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, "
108 "force reprogramming it\n", phy);
109 }
110
111 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
112 val |= GT_DISPLAY_POWER_ON(phy);
113 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
114
115 /*
116 * The PHY registers start out inaccessible and respond to reads with
117 * all 1s. Eventually they become accessible as they power up, then
118 * the reserved bit will give the default 0. Poll on the reserved bit
119 * becoming 0 to find when the PHY is accessible.
120 * HW team confirmed that the time to reach phypowergood status is
121 * anywhere between 50 us and 100us.
122 */
123 if (wait_for_us(((I915_READ(BXT_PORT_CL1CM_DW0(phy)) &
124 (PHY_RESERVED | PHY_POWER_GOOD)) == PHY_POWER_GOOD), 100)) {
125 DRM_ERROR("timeout during PHY%d power on\n", phy);
126 }
127
128 /* Program PLL Rcomp code offset */
129 val = I915_READ(BXT_PORT_CL1CM_DW9(phy));
130 val &= ~IREF0RC_OFFSET_MASK;
131 val |= 0xE4 << IREF0RC_OFFSET_SHIFT;
132 I915_WRITE(BXT_PORT_CL1CM_DW9(phy), val);
133
134 val = I915_READ(BXT_PORT_CL1CM_DW10(phy));
135 val &= ~IREF1RC_OFFSET_MASK;
136 val |= 0xE4 << IREF1RC_OFFSET_SHIFT;
137 I915_WRITE(BXT_PORT_CL1CM_DW10(phy), val);
138
139 /* Program power gating */
140 val = I915_READ(BXT_PORT_CL1CM_DW28(phy));
141 val |= OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN |
142 SUS_CLK_CONFIG;
143 I915_WRITE(BXT_PORT_CL1CM_DW28(phy), val);
144
145 if (phy == DPIO_PHY0) {
146 val = I915_READ(BXT_PORT_CL2CM_DW6_BC);
147 val |= DW6_OLDO_DYN_PWR_DOWN_EN;
148 I915_WRITE(BXT_PORT_CL2CM_DW6_BC, val);
149 }
150
151 val = I915_READ(BXT_PORT_CL1CM_DW30(phy));
152 val &= ~OCL2_LDOFUSE_PWR_DIS;
153 /*
154 * On PHY1 disable power on the second channel, since no port is
155 * connected there. On PHY0 both channels have a port, so leave it
156 * enabled.
157 * TODO: port C is only connected on BXT-P, so on BXT0/1 we should
158 * power down the second channel on PHY0 as well.
159 *
160 * FIXME: Clarify programming of the following, the register is
161 * read-only with bit 6 fixed at 0 at least in stepping A.
162 */
163 if (phy == DPIO_PHY1)
164 val |= OCL2_LDOFUSE_PWR_DIS;
165 I915_WRITE(BXT_PORT_CL1CM_DW30(phy), val);
166
167 if (phy == DPIO_PHY0) {
168 uint32_t grc_code;
169 /*
170 * PHY0 isn't connected to an RCOMP resistor so copy over
171 * the corresponding calibrated value from PHY1, and disable
172 * the automatic calibration on PHY0.
173 */
174 val = dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, DPIO_PHY1);
175 grc_code = val << GRC_CODE_FAST_SHIFT |
176 val << GRC_CODE_SLOW_SHIFT |
177 val;
178 I915_WRITE(BXT_PORT_REF_DW6(DPIO_PHY0), grc_code);
179
180 val = I915_READ(BXT_PORT_REF_DW8(DPIO_PHY0));
181 val |= GRC_DIS | GRC_RDY_OVRD;
182 I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val);
183 }
184
185 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
186 val |= COMMON_RESET_DIS;
187 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
188
189 if (phy == DPIO_PHY1)
190 bxt_phy_wait_grc_done(dev_priv, DPIO_PHY1);
191}
192
193void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy)
194{
195 uint32_t val;
196
197 val = I915_READ(BXT_PHY_CTL_FAMILY(phy));
198 val &= ~COMMON_RESET_DIS;
199 I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val);
200
201 val = I915_READ(BXT_P_CR_GT_DISP_PWRON);
202 val &= ~GT_DISPLAY_POWER_ON(phy);
203 I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val);
204}
205
206static bool __printf(6, 7)
207__phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy,
208 i915_reg_t reg, u32 mask, u32 expected,
209 const char *reg_fmt, ...)
210{
211 struct va_format vaf;
212 va_list args;
213 u32 val;
214
215 val = I915_READ(reg);
216 if ((val & mask) == expected)
217 return true;
218
219 va_start(args, reg_fmt);
220 vaf.fmt = reg_fmt;
221 vaf.va = &args;
222
223 DRM_DEBUG_DRIVER("DDI PHY %d reg %pV [%08x] state mismatch: "
224 "current %08x, expected %08x (mask %08x)\n",
225 phy, &vaf, reg.reg, val, (val & ~mask) | expected,
226 mask);
227
228 va_end(args);
229
230 return false;
231}
232
233bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv,
234 enum dpio_phy phy)
235{
236 uint32_t mask;
237 bool ok;
238
239#define _CHK(reg, mask, exp, fmt, ...) \
240 __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \
241 ## __VA_ARGS__)
242
243 if (!bxt_ddi_phy_is_enabled(dev_priv, phy))
244 return false;
245
246 ok = true;
247
248 /* PLL Rcomp code offset */
249 ok &= _CHK(BXT_PORT_CL1CM_DW9(phy),
250 IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT,
251 "BXT_PORT_CL1CM_DW9(%d)", phy);
252 ok &= _CHK(BXT_PORT_CL1CM_DW10(phy),
253 IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT,
254 "BXT_PORT_CL1CM_DW10(%d)", phy);
255
256 /* Power gating */
257 mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG;
258 ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask,
259 "BXT_PORT_CL1CM_DW28(%d)", phy);
260
261 if (phy == DPIO_PHY0)
262 ok &= _CHK(BXT_PORT_CL2CM_DW6_BC,
263 DW6_OLDO_DYN_PWR_DOWN_EN, DW6_OLDO_DYN_PWR_DOWN_EN,
264 "BXT_PORT_CL2CM_DW6_BC");
265
266 /*
267 * TODO: Verify BXT_PORT_CL1CM_DW30 bit OCL2_LDOFUSE_PWR_DIS,
268 * at least on stepping A this bit is read-only and fixed at 0.
269 */
270
271 if (phy == DPIO_PHY0) {
272 u32 grc_code = dev_priv->bxt_phy_grc;
273
274 grc_code = grc_code << GRC_CODE_FAST_SHIFT |
275 grc_code << GRC_CODE_SLOW_SHIFT |
276 grc_code;
277 mask = GRC_CODE_FAST_MASK | GRC_CODE_SLOW_MASK |
278 GRC_CODE_NOM_MASK;
279 ok &= _CHK(BXT_PORT_REF_DW6(DPIO_PHY0), mask, grc_code,
280 "BXT_PORT_REF_DW6(%d)", DPIO_PHY0);
281
282 mask = GRC_DIS | GRC_RDY_OVRD;
283 ok &= _CHK(BXT_PORT_REF_DW8(DPIO_PHY0), mask, mask,
284 "BXT_PORT_REF_DW8(%d)", DPIO_PHY0);
285 }
286
287 return ok;
288#undef _CHK
289}
290
291uint8_t
292bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder,
293 uint8_t lane_count)
294{
295 switch (lane_count) {
296 case 1:
297 return 0;
298 case 2:
299 return BIT(2) | BIT(0);
300 case 4:
301 return BIT(3) | BIT(2) | BIT(0);
302 default:
303 MISSING_CASE(lane_count);
304
305 return 0;
306 }
307}
308
309void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder *encoder,
310 uint8_t lane_lat_optim_mask)
311{
312 struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
313 struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
314 enum port port = dport->port;
315 int lane;
316
317 for (lane = 0; lane < 4; lane++) {
318 u32 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
319
320 /*
321 * Note that on CHV this flag is called UPAR, but has
322 * the same function.
323 */
324 val &= ~LATENCY_OPTIM;
325 if (lane_lat_optim_mask & BIT(lane))
326 val |= LATENCY_OPTIM;
327
328 I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val);
329 }
330}
331
332uint8_t
333bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder)
334{
335 struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
336 struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev);
337 enum port port = dport->port;
338 int lane;
339 uint8_t mask;
340
341 mask = 0;
342 for (lane = 0; lane < 4; lane++) {
343 u32 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane));
344
345 if (val & LATENCY_OPTIM)
346 mask |= BIT(lane);
347 }
348
349 return mask;
350}
351
352
26void chv_set_phy_signal_level(struct intel_encoder *encoder, 353void chv_set_phy_signal_level(struct intel_encoder *encoder,
27 u32 deemph_reg_value, u32 margin_reg_value, 354 u32 deemph_reg_value, u32 margin_reg_value,
28 bool uniq_trans_scale) 355 bool uniq_trans_scale)