Line data Source code
1 : /*
2 : * Copyright © 2013 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
21 : * DEALINGS IN THE SOFTWARE.
22 : *
23 : * Authors:
24 : * Shobhit Kumar <shobhit.kumar@intel.com>
25 : * Yogesh Mohan Marimuthu <yogesh.mohan.marimuthu@intel.com>
26 : */
27 :
28 : #ifdef __linux__
29 : #include <linux/kernel.h>
30 : #endif
31 : #include "intel_drv.h"
32 : #include "i915_drv.h"
33 : #include "intel_dsi.h"
34 :
35 : #define DSI_HSS_PACKET_SIZE 4
36 : #define DSI_HSE_PACKET_SIZE 4
37 : #define DSI_HSA_PACKET_EXTRA_SIZE 6
38 : #define DSI_HBP_PACKET_EXTRA_SIZE 6
39 : #define DSI_HACTIVE_PACKET_EXTRA_SIZE 6
40 : #define DSI_HFP_PACKET_EXTRA_SIZE 6
41 : #define DSI_EOTP_PACKET_SIZE 4
42 :
43 0 : static int dsi_pixel_format_bpp(int pixel_format)
44 : {
45 : int bpp;
46 :
47 0 : switch (pixel_format) {
48 : default:
49 : case VID_MODE_FORMAT_RGB888:
50 : case VID_MODE_FORMAT_RGB666_LOOSE:
51 : bpp = 24;
52 0 : break;
53 : case VID_MODE_FORMAT_RGB666:
54 : bpp = 18;
55 0 : break;
56 : case VID_MODE_FORMAT_RGB565:
57 : bpp = 16;
58 0 : break;
59 : }
60 :
61 0 : return bpp;
62 : }
63 :
64 : struct dsi_mnp {
65 : u32 dsi_pll_ctrl;
66 : u32 dsi_pll_div;
67 : };
68 :
69 : static const u32 lfsr_converts[] = {
70 : 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 62 - 70 */
71 : 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
72 : 106, 53, 282, 397, 454, 227, 113, 56, 284, 142, /* 81 - 90 */
73 : 71, 35, 273, 136, 324, 418, 465, 488, 500, 506 /* 91 - 100 */
74 : };
75 :
76 : #ifdef DSI_CLK_FROM_RR
77 :
78 : static u32 dsi_rr_formula(const struct drm_display_mode *mode,
79 : int pixel_format, int video_mode_format,
80 : int lane_count, bool eotp)
81 : {
82 : u32 bpp;
83 : u32 hactive, vactive, hfp, hsync, hbp, vfp, vsync, vbp;
84 : u32 hsync_bytes, hbp_bytes, hactive_bytes, hfp_bytes;
85 : u32 bytes_per_line, bytes_per_frame;
86 : u32 num_frames;
87 : u32 bytes_per_x_frames, bytes_per_x_frames_x_lanes;
88 : u32 dsi_bit_clock_hz;
89 : u32 dsi_clk;
90 :
91 : bpp = dsi_pixel_format_bpp(pixel_format);
92 :
93 : hactive = mode->hdisplay;
94 : vactive = mode->vdisplay;
95 : hfp = mode->hsync_start - mode->hdisplay;
96 : hsync = mode->hsync_end - mode->hsync_start;
97 : hbp = mode->htotal - mode->hsync_end;
98 :
99 : vfp = mode->vsync_start - mode->vdisplay;
100 : vsync = mode->vsync_end - mode->vsync_start;
101 : vbp = mode->vtotal - mode->vsync_end;
102 :
103 : hsync_bytes = DIV_ROUND_UP(hsync * bpp, 8);
104 : hbp_bytes = DIV_ROUND_UP(hbp * bpp, 8);
105 : hactive_bytes = DIV_ROUND_UP(hactive * bpp, 8);
106 : hfp_bytes = DIV_ROUND_UP(hfp * bpp, 8);
107 :
108 : bytes_per_line = DSI_HSS_PACKET_SIZE + hsync_bytes +
109 : DSI_HSA_PACKET_EXTRA_SIZE + DSI_HSE_PACKET_SIZE +
110 : hbp_bytes + DSI_HBP_PACKET_EXTRA_SIZE +
111 : hactive_bytes + DSI_HACTIVE_PACKET_EXTRA_SIZE +
112 : hfp_bytes + DSI_HFP_PACKET_EXTRA_SIZE;
113 :
114 : /*
115 : * XXX: Need to accurately calculate LP to HS transition timeout and add
116 : * it to bytes_per_line/bytes_per_frame.
117 : */
118 :
119 : if (eotp && video_mode_format == VIDEO_MODE_BURST)
120 : bytes_per_line += DSI_EOTP_PACKET_SIZE;
121 :
122 : bytes_per_frame = vsync * bytes_per_line + vbp * bytes_per_line +
123 : vactive * bytes_per_line + vfp * bytes_per_line;
124 :
125 : if (eotp &&
126 : (video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE ||
127 : video_mode_format == VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS))
128 : bytes_per_frame += DSI_EOTP_PACKET_SIZE;
129 :
130 : num_frames = drm_mode_vrefresh(mode);
131 : bytes_per_x_frames = num_frames * bytes_per_frame;
132 :
133 : bytes_per_x_frames_x_lanes = bytes_per_x_frames / lane_count;
134 :
135 : /* the dsi clock is divided by 2 in the hardware to get dsi ddr clock */
136 : dsi_bit_clock_hz = bytes_per_x_frames_x_lanes * 8;
137 : dsi_clk = dsi_bit_clock_hz / 1000;
138 :
139 : if (eotp && video_mode_format == VIDEO_MODE_BURST)
140 : dsi_clk *= 2;
141 :
142 : return dsi_clk;
143 : }
144 :
145 : #else
146 :
147 : /* Get DSI clock from pixel clock */
148 0 : static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count)
149 : {
150 : u32 dsi_clk_khz;
151 0 : u32 bpp = dsi_pixel_format_bpp(pixel_format);
152 :
153 : /* DSI data rate = pixel clock * bits per pixel / lane count
154 : pixel clock is converted from KHz to Hz */
155 0 : dsi_clk_khz = DIV_ROUND_CLOSEST(pclk * bpp, lane_count);
156 :
157 0 : return dsi_clk_khz;
158 : }
159 :
160 : #endif
161 :
162 0 : static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
163 : struct dsi_mnp *dsi_mnp, int target_dsi_clk)
164 : {
165 : unsigned int calc_m = 0, calc_p = 0;
166 : unsigned int m_min, m_max, p_min = 2, p_max = 6;
167 : unsigned int m, n, p;
168 : int ref_clk;
169 : int delta = target_dsi_clk;
170 : u32 m_seed;
171 :
172 : /* target_dsi_clk is expected in kHz */
173 0 : if (target_dsi_clk < 300000 || target_dsi_clk > 1150000) {
174 0 : DRM_ERROR("DSI CLK Out of Range\n");
175 0 : return -ECHRNG;
176 : }
177 :
178 0 : if (IS_CHERRYVIEW(dev_priv)) {
179 : ref_clk = 100000;
180 : n = 4;
181 : m_min = 70;
182 : m_max = 96;
183 0 : } else {
184 : ref_clk = 25000;
185 : n = 1;
186 : m_min = 62;
187 : m_max = 92;
188 : }
189 :
190 0 : for (m = m_min; m <= m_max && delta; m++) {
191 0 : for (p = p_min; p <= p_max && delta; p++) {
192 : /*
193 : * Find the optimal m and p divisors with minimal delta
194 : * +/- the required clock
195 : */
196 0 : int calc_dsi_clk = (m * ref_clk) / (p * n);
197 0 : int d = abs(target_dsi_clk - calc_dsi_clk);
198 0 : if (d < delta) {
199 : delta = d;
200 : calc_m = m;
201 : calc_p = p;
202 0 : }
203 : }
204 : }
205 :
206 : /* register has log2(N1), this works fine for powers of two */
207 0 : n = ffs(n) - 1;
208 0 : m_seed = lfsr_converts[calc_m - 62];
209 0 : dsi_mnp->dsi_pll_ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
210 0 : dsi_mnp->dsi_pll_div = n << DSI_PLL_N1_DIV_SHIFT |
211 : m_seed << DSI_PLL_M1_DIV_SHIFT;
212 :
213 0 : return 0;
214 0 : }
215 :
216 : /*
217 : * XXX: The muxing and gating is hard coded for now. Need to add support for
218 : * sharing PLLs with two DSI outputs.
219 : */
220 0 : static void vlv_configure_dsi_pll(struct intel_encoder *encoder)
221 : {
222 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
223 0 : struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
224 : int ret;
225 0 : struct dsi_mnp dsi_mnp;
226 : u32 dsi_clk;
227 :
228 0 : dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
229 0 : intel_dsi->lane_count);
230 :
231 0 : ret = dsi_calc_mnp(dev_priv, &dsi_mnp, dsi_clk);
232 0 : if (ret) {
233 : DRM_DEBUG_KMS("dsi_calc_mnp failed\n");
234 0 : return;
235 : }
236 :
237 0 : if (intel_dsi->ports & (1 << PORT_A))
238 0 : dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI0_DSIPLL;
239 :
240 0 : if (intel_dsi->ports & (1 << PORT_C))
241 0 : dsi_mnp.dsi_pll_ctrl |= DSI_PLL_CLK_GATE_DSI1_DSIPLL;
242 :
243 : DRM_DEBUG_KMS("dsi pll div %08x, ctrl %08x\n",
244 : dsi_mnp.dsi_pll_div, dsi_mnp.dsi_pll_ctrl);
245 :
246 0 : vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, 0);
247 0 : vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_DIVIDER, dsi_mnp.dsi_pll_div);
248 0 : vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, dsi_mnp.dsi_pll_ctrl);
249 0 : }
250 :
251 0 : static void vlv_enable_dsi_pll(struct intel_encoder *encoder)
252 : {
253 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
254 : u32 tmp;
255 :
256 : DRM_DEBUG_KMS("\n");
257 :
258 0 : mutex_lock(&dev_priv->sb_lock);
259 :
260 0 : vlv_configure_dsi_pll(encoder);
261 :
262 : /* wait at least 0.5 us after ungating before enabling VCO */
263 0 : usleep_range(1, 10);
264 :
265 0 : tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
266 0 : tmp |= DSI_PLL_VCO_EN;
267 0 : vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
268 :
269 0 : if (wait_for(vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL) &
270 : DSI_PLL_LOCK, 20)) {
271 :
272 : mutex_unlock(&dev_priv->sb_lock);
273 0 : DRM_ERROR("DSI PLL lock failed\n");
274 0 : return;
275 : }
276 : mutex_unlock(&dev_priv->sb_lock);
277 :
278 : DRM_DEBUG_KMS("DSI PLL locked\n");
279 0 : }
280 :
281 0 : static void vlv_disable_dsi_pll(struct intel_encoder *encoder)
282 : {
283 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
284 : u32 tmp;
285 :
286 : DRM_DEBUG_KMS("\n");
287 :
288 0 : mutex_lock(&dev_priv->sb_lock);
289 :
290 0 : tmp = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
291 0 : tmp &= ~DSI_PLL_VCO_EN;
292 0 : tmp |= DSI_PLL_LDO_GATE;
293 0 : vlv_cck_write(dev_priv, CCK_REG_DSI_PLL_CONTROL, tmp);
294 :
295 0 : mutex_unlock(&dev_priv->sb_lock);
296 0 : }
297 :
298 0 : static void bxt_disable_dsi_pll(struct intel_encoder *encoder)
299 : {
300 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
301 : u32 val;
302 :
303 : DRM_DEBUG_KMS("\n");
304 :
305 0 : val = I915_READ(BXT_DSI_PLL_ENABLE);
306 0 : val &= ~BXT_DSI_PLL_DO_ENABLE;
307 0 : I915_WRITE(BXT_DSI_PLL_ENABLE, val);
308 :
309 : /*
310 : * PLL lock should deassert within 200us.
311 : * Wait up to 1ms before timing out.
312 : */
313 0 : if (wait_for((I915_READ(BXT_DSI_PLL_ENABLE)
314 : & BXT_DSI_PLL_LOCKED) == 0, 1))
315 0 : DRM_ERROR("Timeout waiting for PLL lock deassertion\n");
316 0 : }
317 :
318 0 : static void assert_bpp_mismatch(int pixel_format, int pipe_bpp)
319 : {
320 0 : int bpp = dsi_pixel_format_bpp(pixel_format);
321 :
322 0 : WARN(bpp != pipe_bpp,
323 : "bpp match assertion failure (expected %d, current %d)\n",
324 : bpp, pipe_bpp);
325 0 : }
326 :
327 0 : u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
328 : {
329 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
330 0 : struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
331 : u32 dsi_clock, pclk;
332 : u32 pll_ctl, pll_div;
333 : u32 m = 0, p = 0, n;
334 : int refclk = 25000;
335 : int i;
336 :
337 : DRM_DEBUG_KMS("\n");
338 :
339 0 : mutex_lock(&dev_priv->sb_lock);
340 0 : pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
341 0 : pll_div = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_DIVIDER);
342 0 : mutex_unlock(&dev_priv->sb_lock);
343 :
344 : /* mask out other bits and extract the P1 divisor */
345 0 : pll_ctl &= DSI_PLL_P1_POST_DIV_MASK;
346 0 : pll_ctl = pll_ctl >> (DSI_PLL_P1_POST_DIV_SHIFT - 2);
347 :
348 : /* N1 divisor */
349 0 : n = (pll_div & DSI_PLL_N1_DIV_MASK) >> DSI_PLL_N1_DIV_SHIFT;
350 0 : n = 1 << n; /* register has log2(N1) */
351 :
352 : /* mask out the other bits and extract the M1 divisor */
353 0 : pll_div &= DSI_PLL_M1_DIV_MASK;
354 : pll_div = pll_div >> DSI_PLL_M1_DIV_SHIFT;
355 :
356 0 : while (pll_ctl) {
357 0 : pll_ctl = pll_ctl >> 1;
358 0 : p++;
359 : }
360 0 : p--;
361 :
362 0 : if (!p) {
363 0 : DRM_ERROR("wrong P1 divisor\n");
364 0 : return 0;
365 : }
366 :
367 0 : for (i = 0; i < ARRAY_SIZE(lfsr_converts); i++) {
368 0 : if (lfsr_converts[i] == pll_div)
369 : break;
370 : }
371 :
372 0 : if (i == ARRAY_SIZE(lfsr_converts)) {
373 0 : DRM_ERROR("wrong m_seed programmed\n");
374 0 : return 0;
375 : }
376 :
377 0 : m = i + 62;
378 :
379 0 : dsi_clock = (m * refclk) / (p * n);
380 :
381 : /* pixel_format and pipe_bpp should agree */
382 0 : assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp);
383 :
384 0 : pclk = DIV_ROUND_CLOSEST(dsi_clock * intel_dsi->lane_count, pipe_bpp);
385 :
386 0 : return pclk;
387 0 : }
388 :
389 0 : u32 bxt_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp)
390 : {
391 : u32 pclk;
392 : u32 dsi_clk;
393 : u32 dsi_ratio;
394 0 : struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
395 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
396 :
397 : /* Divide by zero */
398 0 : if (!pipe_bpp) {
399 0 : DRM_ERROR("Invalid BPP(0)\n");
400 0 : return 0;
401 : }
402 :
403 0 : dsi_ratio = I915_READ(BXT_DSI_PLL_CTL) &
404 : BXT_DSI_PLL_RATIO_MASK;
405 :
406 : /* Invalid DSI ratio ? */
407 0 : if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN ||
408 0 : dsi_ratio > BXT_DSI_PLL_RATIO_MAX) {
409 0 : DRM_ERROR("Invalid DSI pll ratio(%u) programmed\n", dsi_ratio);
410 0 : return 0;
411 : }
412 :
413 0 : dsi_clk = (dsi_ratio * BXT_REF_CLOCK_KHZ) / 2;
414 :
415 : /* pixel_format and pipe_bpp should agree */
416 0 : assert_bpp_mismatch(intel_dsi->pixel_format, pipe_bpp);
417 :
418 0 : pclk = DIV_ROUND_CLOSEST(dsi_clk * intel_dsi->lane_count, pipe_bpp);
419 :
420 : DRM_DEBUG_DRIVER("Calculated pclk=%u\n", pclk);
421 0 : return pclk;
422 0 : }
423 :
424 0 : static void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
425 : {
426 : u32 temp;
427 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
428 0 : struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
429 :
430 0 : temp = I915_READ(MIPI_CTRL(port));
431 0 : temp &= ~ESCAPE_CLOCK_DIVIDER_MASK;
432 0 : I915_WRITE(MIPI_CTRL(port), temp |
433 : intel_dsi->escape_clk_div <<
434 : ESCAPE_CLOCK_DIVIDER_SHIFT);
435 0 : }
436 :
437 : /* Program BXT Mipi clocks and dividers */
438 0 : static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port)
439 : {
440 : u32 tmp;
441 : u32 divider;
442 : u32 dsi_rate;
443 : u32 pll_ratio;
444 0 : struct drm_i915_private *dev_priv = dev->dev_private;
445 :
446 : /* Clear old configurations */
447 0 : tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
448 0 : tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
449 0 : tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port));
450 0 : tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port));
451 0 : tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port));
452 :
453 : /* Get the current DSI rate(actual) */
454 0 : pll_ratio = I915_READ(BXT_DSI_PLL_CTL) &
455 : BXT_DSI_PLL_RATIO_MASK;
456 0 : dsi_rate = (BXT_REF_CLOCK_KHZ * pll_ratio) / 2;
457 :
458 : /* Max possible output of clock is 39.5 MHz, program value -1 */
459 0 : divider = (dsi_rate / BXT_MAX_VAR_OUTPUT_KHZ) - 1;
460 0 : tmp |= BXT_MIPI_ESCLK_VAR_DIV(port, divider);
461 :
462 : /*
463 : * Tx escape clock must be as close to 20MHz possible, but should
464 : * not exceed it. Hence select divide by 2
465 : */
466 0 : tmp |= BXT_MIPI_TX_ESCLK_8XDIV_BY2(port);
467 :
468 0 : tmp |= BXT_MIPI_RX_ESCLK_8X_BY3(port);
469 :
470 0 : I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
471 0 : }
472 :
473 0 : static bool bxt_configure_dsi_pll(struct intel_encoder *encoder)
474 : {
475 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
476 0 : struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
477 : u8 dsi_ratio;
478 : u32 dsi_clk;
479 : u32 val;
480 :
481 0 : dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format,
482 0 : intel_dsi->lane_count);
483 :
484 : /*
485 : * From clock diagram, to get PLL ratio divider, divide double of DSI
486 : * link rate (i.e., 2*8x=16x frequency value) by ref clock. Make sure to
487 : * round 'up' the result
488 : */
489 0 : dsi_ratio = DIV_ROUND_UP(dsi_clk * 2, BXT_REF_CLOCK_KHZ);
490 0 : if (dsi_ratio < BXT_DSI_PLL_RATIO_MIN ||
491 0 : dsi_ratio > BXT_DSI_PLL_RATIO_MAX) {
492 0 : DRM_ERROR("Cant get a suitable ratio from DSI PLL ratios\n");
493 0 : return false;
494 : }
495 :
496 : /*
497 : * Program DSI ratio and Select MIPIC and MIPIA PLL output as 8x
498 : * Spec says both have to be programmed, even if one is not getting
499 : * used. Configure MIPI_CLOCK_CTL dividers in modeset
500 : */
501 0 : val = I915_READ(BXT_DSI_PLL_CTL);
502 0 : val &= ~BXT_DSI_PLL_PVD_RATIO_MASK;
503 0 : val &= ~BXT_DSI_FREQ_SEL_MASK;
504 0 : val &= ~BXT_DSI_PLL_RATIO_MASK;
505 0 : val |= (dsi_ratio | BXT_DSIA_16X_BY2 | BXT_DSIC_16X_BY2);
506 :
507 : /* As per recommendation from hardware team,
508 : * Prog PVD ratio =1 if dsi ratio <= 50
509 : */
510 0 : if (dsi_ratio <= 50) {
511 0 : val &= ~BXT_DSI_PLL_PVD_RATIO_MASK;
512 0 : val |= BXT_DSI_PLL_PVD_RATIO_1;
513 0 : }
514 :
515 0 : I915_WRITE(BXT_DSI_PLL_CTL, val);
516 0 : POSTING_READ(BXT_DSI_PLL_CTL);
517 :
518 0 : return true;
519 0 : }
520 :
521 0 : static void bxt_enable_dsi_pll(struct intel_encoder *encoder)
522 : {
523 0 : struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
524 0 : struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
525 : enum port port;
526 : u32 val;
527 :
528 : DRM_DEBUG_KMS("\n");
529 :
530 0 : val = I915_READ(BXT_DSI_PLL_ENABLE);
531 :
532 0 : if (val & BXT_DSI_PLL_DO_ENABLE) {
533 0 : WARN(1, "DSI PLL already enabled. Disabling it.\n");
534 0 : val &= ~BXT_DSI_PLL_DO_ENABLE;
535 0 : I915_WRITE(BXT_DSI_PLL_ENABLE, val);
536 0 : }
537 :
538 : /* Configure PLL vales */
539 0 : if (!bxt_configure_dsi_pll(encoder)) {
540 0 : DRM_ERROR("Configure DSI PLL failed, abort PLL enable\n");
541 0 : return;
542 : }
543 :
544 : /* Program TX, RX, Dphy clocks */
545 0 : for_each_dsi_port(port, intel_dsi->ports)
546 0 : bxt_dsi_program_clocks(encoder->base.dev, port);
547 :
548 : /* Enable DSI PLL */
549 0 : val = I915_READ(BXT_DSI_PLL_ENABLE);
550 0 : val |= BXT_DSI_PLL_DO_ENABLE;
551 0 : I915_WRITE(BXT_DSI_PLL_ENABLE, val);
552 :
553 : /* Timeout and fail if PLL not locked */
554 0 : if (wait_for(I915_READ(BXT_DSI_PLL_ENABLE) & BXT_DSI_PLL_LOCKED, 1)) {
555 0 : DRM_ERROR("Timed out waiting for DSI PLL to lock\n");
556 0 : return;
557 : }
558 :
559 : DRM_DEBUG_KMS("DSI PLL locked\n");
560 0 : }
561 :
562 0 : void intel_enable_dsi_pll(struct intel_encoder *encoder)
563 : {
564 0 : struct drm_device *dev = encoder->base.dev;
565 :
566 0 : if (IS_VALLEYVIEW(dev))
567 0 : vlv_enable_dsi_pll(encoder);
568 0 : else if (IS_BROXTON(dev))
569 0 : bxt_enable_dsi_pll(encoder);
570 0 : }
571 :
572 0 : void intel_disable_dsi_pll(struct intel_encoder *encoder)
573 : {
574 0 : struct drm_device *dev = encoder->base.dev;
575 :
576 0 : if (IS_VALLEYVIEW(dev))
577 0 : vlv_disable_dsi_pll(encoder);
578 0 : else if (IS_BROXTON(dev))
579 0 : bxt_disable_dsi_pll(encoder);
580 0 : }
581 :
582 0 : static void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
583 : {
584 : u32 tmp;
585 0 : struct drm_device *dev = encoder->base.dev;
586 0 : struct drm_i915_private *dev_priv = dev->dev_private;
587 :
588 : /* Clear old configurations */
589 0 : tmp = I915_READ(BXT_MIPI_CLOCK_CTL);
590 0 : tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port));
591 0 : tmp &= ~(BXT_MIPI_RX_ESCLK_FIXDIV_MASK(port));
592 0 : tmp &= ~(BXT_MIPI_ESCLK_VAR_DIV_MASK(port));
593 0 : tmp &= ~(BXT_MIPI_DPHY_DIVIDER_MASK(port));
594 0 : I915_WRITE(BXT_MIPI_CLOCK_CTL, tmp);
595 0 : I915_WRITE(MIPI_EOT_DISABLE(port), CLOCKSTOP);
596 0 : }
597 :
598 0 : void intel_dsi_reset_clocks(struct intel_encoder *encoder, enum port port)
599 : {
600 0 : struct drm_device *dev = encoder->base.dev;
601 :
602 0 : if (IS_BROXTON(dev))
603 0 : bxt_dsi_reset_clocks(encoder, port);
604 0 : else if (IS_VALLEYVIEW(dev))
605 0 : vlv_dsi_reset_clocks(encoder, port);
606 0 : }
|