blob: 55e5af5cbd3d536cfd2f3863c81752f8c83e098b [file] [log] [blame]
Kirill A. Shutemov026abc32012-03-08 16:02:20 +00001/*
2 * Copyright © 2006-2007 Intel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Authors:
18 * Eric Anholt <eric@anholt.net>
19 */
20
21#include <linux/i2c.h>
22#include <linux/pm_runtime.h>
23
24#include <drm/drmP.h>
25#include "psb_intel_reg.h"
26#include "psb_intel_display.h"
27#include "framebuffer.h"
28#include "mdfld_output.h"
29#include "mdfld_dsi_output.h"
30
31/* Hardcoded currently */
32static int ksel = KSEL_CRYSTAL_19;
33
34struct psb_intel_range_t {
35 int min, max;
36};
37
38struct mrst_limit_t {
39 struct psb_intel_range_t dot, m, p1;
40};
41
42struct mrst_clock_t {
43 /* derived values */
44 int dot;
45 int m;
46 int p1;
47};
48
49#define COUNT_MAX 0x10000000
50
51void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
52{
53 int count, temp;
54 u32 pipeconf_reg = PIPEACONF;
55
56 switch (pipe) {
57 case 0:
58 break;
59 case 1:
60 pipeconf_reg = PIPEBCONF;
61 break;
62 case 2:
63 pipeconf_reg = PIPECCONF;
64 break;
65 default:
66 DRM_ERROR("Illegal Pipe Number.\n");
67 return;
68 }
69
70 /* FIXME JLIU7_PO */
71 psb_intel_wait_for_vblank(dev);
72 return;
73
74 /* Wait for for the pipe disable to take effect. */
75 for (count = 0; count < COUNT_MAX; count++) {
76 temp = REG_READ(pipeconf_reg);
77 if ((temp & PIPEACONF_PIPE_STATE) == 0)
78 break;
79 }
80}
81
82void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
83{
84 int count, temp;
85 u32 pipeconf_reg = PIPEACONF;
86
87 switch (pipe) {
88 case 0:
89 break;
90 case 1:
91 pipeconf_reg = PIPEBCONF;
92 break;
93 case 2:
94 pipeconf_reg = PIPECCONF;
95 break;
96 default:
97 DRM_ERROR("Illegal Pipe Number.\n");
98 return;
99 }
100
101 /* FIXME JLIU7_PO */
102 psb_intel_wait_for_vblank(dev);
103 return;
104
105 /* Wait for for the pipe enable to take effect. */
106 for (count = 0; count < COUNT_MAX; count++) {
107 temp = REG_READ(pipeconf_reg);
108 if ((temp & PIPEACONF_PIPE_STATE) == 1)
109 break;
110 }
111}
112
113static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
114{
115 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
116 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
117}
118
119static void psb_intel_crtc_commit(struct drm_crtc *crtc)
120{
121 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
122 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
123}
124
125static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
126 struct drm_display_mode *mode,
127 struct drm_display_mode *adjusted_mode)
128{
129 return true;
130}
131
132/**
133 * Return the pipe currently connected to the panel fitter,
134 * or -1 if the panel fitter is not present or not in use
135 */
136static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
137{
138 u32 pfit_control;
139
140 pfit_control = REG_READ(PFIT_CONTROL);
141
142 /* See if the panel fitter is in use */
143 if ((pfit_control & PFIT_ENABLE) == 0)
144 return -1;
145
146 /* 965 can place panel fitter on either pipe */
147 return (pfit_control >> 29) & 0x3;
148}
149
150static struct drm_device globle_dev;
151
152void mdfld__intel_plane_set_alpha(int enable)
153{
154 struct drm_device *dev = &globle_dev;
155 int dspcntr_reg = DSPACNTR;
156 u32 dspcntr;
157
158 dspcntr = REG_READ(dspcntr_reg);
159
160 if (enable) {
161 dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
162 dspcntr |= DISPPLANE_32BPP;
163 } else {
164 dspcntr &= ~DISPPLANE_32BPP;
165 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
166 }
167
168 REG_WRITE(dspcntr_reg, dspcntr);
169}
170
171static int check_fb(struct drm_framebuffer *fb)
172{
173 if (!fb)
174 return 0;
175
176 switch (fb->bits_per_pixel) {
177 case 8:
178 case 16:
179 case 24:
180 case 32:
181 return 0;
182 default:
183 DRM_ERROR("Unknown color depth\n");
184 return -EINVAL;
185 }
186}
187
188static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
189 struct drm_framebuffer *old_fb)
190{
191 struct drm_device *dev = crtc->dev;
192 /* struct drm_i915_master_private *master_priv; */
193 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
194 struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
195 int pipe = psb_intel_crtc->pipe;
196 unsigned long start, offset;
197 int dsplinoff = DSPALINOFF;
198 int dspsurf = DSPASURF;
199 int dspstride = DSPASTRIDE;
200 int dspcntr_reg = DSPACNTR;
201 u32 dspcntr;
202 int ret;
203
204 memcpy(&globle_dev, dev, sizeof(struct drm_device));
205
206 dev_dbg(dev->dev, "pipe = 0x%x.\n", pipe);
207
208 /* no fb bound */
209 if (!crtc->fb) {
210 dev_dbg(dev->dev, "No FB bound\n");
211 return 0;
212 }
213
214 ret = check_fb(crtc->fb);
215 if (ret)
216 return ret;
217
218 switch (pipe) {
219 case 0:
220 dsplinoff = DSPALINOFF;
221 break;
222 case 1:
223 dsplinoff = DSPBLINOFF;
224 dspsurf = DSPBSURF;
225 dspstride = DSPBSTRIDE;
226 dspcntr_reg = DSPBCNTR;
227 break;
228 case 2:
229 dsplinoff = DSPCLINOFF;
230 dspsurf = DSPCSURF;
231 dspstride = DSPCSTRIDE;
232 dspcntr_reg = DSPCCNTR;
233 break;
234 default:
235 DRM_ERROR("Illegal Pipe Number.\n");
236 return -EINVAL;
237 }
238
239 if (!gma_power_begin(dev, true))
240 return 0;
241
242 start = psbfb->gtt->offset;
243 offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8);
244
245 REG_WRITE(dspstride, crtc->fb->pitches[0]);
246 dspcntr = REG_READ(dspcntr_reg);
247 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
248
249 switch (crtc->fb->bits_per_pixel) {
250 case 8:
251 dspcntr |= DISPPLANE_8BPP;
252 break;
253 case 16:
254 if (crtc->fb->depth == 15)
255 dspcntr |= DISPPLANE_15_16BPP;
256 else
257 dspcntr |= DISPPLANE_16BPP;
258 break;
259 case 24:
260 case 32:
261 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
262 break;
263 }
264 REG_WRITE(dspcntr_reg, dspcntr);
265
266 dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
267 start, offset, x, y);
268 REG_WRITE(dsplinoff, offset);
269 REG_READ(dsplinoff);
270 REG_WRITE(dspsurf, start);
271 REG_READ(dspsurf);
272
273 gma_power_end(dev);
274
275 return 0;
276}
277
278/*
279 * Disable the pipe, plane and pll.
280 *
281 */
282void mdfld_disable_crtc(struct drm_device *dev, int pipe)
283{
284 int dpll_reg = MRST_DPLL_A;
285 int dspcntr_reg = DSPACNTR;
286 int dspbase_reg = MRST_DSPABASE;
287 int pipeconf_reg = PIPEACONF;
288 u32 temp;
289
290 dev_dbg(dev->dev, "pipe = %d\n", pipe);
291
292
293 switch (pipe) {
294 case 0:
295 break;
296 case 1:
297 dpll_reg = MDFLD_DPLL_B;
298 dspcntr_reg = DSPBCNTR;
299 dspbase_reg = DSPBSURF;
300 pipeconf_reg = PIPEBCONF;
301 break;
302 case 2:
303 dpll_reg = MRST_DPLL_A;
304 dspcntr_reg = DSPCCNTR;
305 dspbase_reg = MDFLD_DSPCBASE;
306 pipeconf_reg = PIPECCONF;
307 break;
308 default:
309 DRM_ERROR("Illegal Pipe Number.\n");
310 return;
311 }
312
313 if (pipe != 1)
314 mdfld_dsi_gen_fifo_ready(dev, MIPI_GEN_FIFO_STAT_REG(pipe),
315 HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
316
317 /* Disable display plane */
318 temp = REG_READ(dspcntr_reg);
319 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
320 REG_WRITE(dspcntr_reg,
321 temp & ~DISPLAY_PLANE_ENABLE);
322 /* Flush the plane changes */
323 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
324 REG_READ(dspbase_reg);
325 }
326
327 /* FIXME_JLIU7 MDFLD_PO revisit */
328
329 /* Next, disable display pipes */
330 temp = REG_READ(pipeconf_reg);
331 if ((temp & PIPEACONF_ENABLE) != 0) {
332 temp &= ~PIPEACONF_ENABLE;
333 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
334 REG_WRITE(pipeconf_reg, temp);
335 REG_READ(pipeconf_reg);
336
337 /* Wait for for the pipe disable to take effect. */
338 mdfldWaitForPipeDisable(dev, pipe);
339 }
340
341 temp = REG_READ(dpll_reg);
342 if (temp & DPLL_VCO_ENABLE) {
343 if ((pipe != 1 &&
344 !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF))
345 & PIPEACONF_ENABLE)) || pipe == 1) {
346 temp &= ~(DPLL_VCO_ENABLE);
347 REG_WRITE(dpll_reg, temp);
348 REG_READ(dpll_reg);
349 /* Wait for the clocks to turn off. */
350 /* FIXME_MDFLD PO may need more delay */
351 udelay(500);
352
353 if (!(temp & MDFLD_PWR_GATE_EN)) {
354 /* gating power of DPLL */
355 REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
356 /* FIXME_MDFLD PO - change 500 to 1 after PO */
357 udelay(5000);
358 }
359 }
360 }
361
362}
363
364/**
365 * Sets the power management mode of the pipe and plane.
366 *
367 * This code should probably grow support for turning the cursor off and back
368 * on appropriately at the same time as we're turning the pipe off/on.
369 */
370static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
371{
372 struct drm_device *dev = crtc->dev;
373 struct drm_psb_private *dev_priv = dev->dev_private;
374 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
375 int pipe = psb_intel_crtc->pipe;
376 int dpll_reg = MRST_DPLL_A;
377 int dspcntr_reg = DSPACNTR;
378 int dspbase_reg = MRST_DSPABASE;
379 int pipeconf_reg = PIPEACONF;
380 u32 pipestat_reg = PIPEASTAT;
381 u32 pipeconf = dev_priv->pipeconf[pipe];
382 u32 temp;
383 bool enabled;
384 int timeout = 0;
385
386 dev_dbg(dev->dev, "mode = %d, pipe = %d\n", mode, pipe);
387
388/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
389/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
390
391 switch (pipe) {
392 case 0:
393 break;
394 case 1:
395 dpll_reg = DPLL_B;
396 dspcntr_reg = DSPBCNTR;
397 dspbase_reg = MRST_DSPBBASE;
398 pipeconf_reg = PIPEBCONF;
399 dpll_reg = MDFLD_DPLL_B;
400 break;
401 case 2:
402 dpll_reg = MRST_DPLL_A;
403 dspcntr_reg = DSPCCNTR;
404 dspbase_reg = MDFLD_DSPCBASE;
405 pipeconf_reg = PIPECCONF;
406 pipestat_reg = PIPECSTAT;
407 break;
408 default:
409 DRM_ERROR("Illegal Pipe Number.\n");
410 return;
411 }
412
413 if (!gma_power_begin(dev, true))
414 return;
415
416 /* XXX: When our outputs are all unaware of DPMS modes other than off
417 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
418 */
419 switch (mode) {
420 case DRM_MODE_DPMS_ON:
421 case DRM_MODE_DPMS_STANDBY:
422 case DRM_MODE_DPMS_SUSPEND:
423 /* Enable the DPLL */
424 temp = REG_READ(dpll_reg);
425
426 if ((temp & DPLL_VCO_ENABLE) == 0) {
427 /* When ungating power of DPLL, needs to wait 0.5us
428 before enable the VCO */
429 if (temp & MDFLD_PWR_GATE_EN) {
430 temp &= ~MDFLD_PWR_GATE_EN;
431 REG_WRITE(dpll_reg, temp);
432 /* FIXME_MDFLD PO - change 500 to 1 after PO */
433 udelay(500);
434 }
435
436 REG_WRITE(dpll_reg, temp);
437 REG_READ(dpll_reg);
438 /* FIXME_MDFLD PO - change 500 to 1 after PO */
439 udelay(500);
440
441 REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
442 REG_READ(dpll_reg);
443
444 /**
445 * wait for DSI PLL to lock
446 * NOTE: only need to poll status of pipe 0 and pipe 1,
447 * since both MIPI pipes share the same PLL.
448 */
449 while ((pipe != 2) && (timeout < 20000) &&
450 !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
451 udelay(150);
452 timeout++;
453 }
454 }
455
456 /* Enable the plane */
457 temp = REG_READ(dspcntr_reg);
458 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
459 REG_WRITE(dspcntr_reg,
460 temp | DISPLAY_PLANE_ENABLE);
461 /* Flush the plane changes */
462 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
463 }
464
465 /* Enable the pipe */
466 temp = REG_READ(pipeconf_reg);
467 if ((temp & PIPEACONF_ENABLE) == 0) {
468 REG_WRITE(pipeconf_reg, pipeconf);
469
470 /* Wait for for the pipe enable to take effect. */
471 mdfldWaitForPipeEnable(dev, pipe);
472 }
473
474 /*workaround for sighting 3741701 Random X blank display*/
475 /*perform w/a in video mode only on pipe A or C*/
476 if (pipe == 0 || pipe == 2) {
477 REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
478 msleep(100);
479 if (PIPE_VBLANK_STATUS & REG_READ(pipestat_reg))
480 dev_dbg(dev->dev, "OK");
481 else {
482 dev_dbg(dev->dev, "STUCK!!!!");
483 /*shutdown controller*/
484 temp = REG_READ(dspcntr_reg);
485 REG_WRITE(dspcntr_reg,
486 temp & ~DISPLAY_PLANE_ENABLE);
487 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
488 /*mdfld_dsi_dpi_shut_down(dev, pipe);*/
489 REG_WRITE(0xb048, 1);
490 msleep(100);
491 temp = REG_READ(pipeconf_reg);
492 temp &= ~PIPEACONF_ENABLE;
493 REG_WRITE(pipeconf_reg, temp);
494 msleep(100); /*wait for pipe disable*/
495 REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0);
496 msleep(100);
497 REG_WRITE(0xb004, REG_READ(0xb004));
498 /* try to bring the controller back up again*/
499 REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 1);
500 temp = REG_READ(dspcntr_reg);
501 REG_WRITE(dspcntr_reg,
502 temp | DISPLAY_PLANE_ENABLE);
503 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
504 /*mdfld_dsi_dpi_turn_on(dev, pipe);*/
505 REG_WRITE(0xb048, 2);
506 msleep(100);
507 temp = REG_READ(pipeconf_reg);
508 temp |= PIPEACONF_ENABLE;
509 REG_WRITE(pipeconf_reg, temp);
510 }
511 }
512
513 psb_intel_crtc_load_lut(crtc);
514
515 /* Give the overlay scaler a chance to enable
516 if it's on this pipe */
517 /* psb_intel_crtc_dpms_video(crtc, true); TODO */
518
519 break;
520 case DRM_MODE_DPMS_OFF:
521 /* Give the overlay scaler a chance to disable
522 * if it's on this pipe */
523 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
524 if (pipe != 1)
525 mdfld_dsi_gen_fifo_ready(dev,
526 MIPI_GEN_FIFO_STAT_REG(pipe),
527 HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
528
529 /* Disable the VGA plane that we never use */
530 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
531
532 /* Disable display plane */
533 temp = REG_READ(dspcntr_reg);
534 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
535 REG_WRITE(dspcntr_reg,
536 temp & ~DISPLAY_PLANE_ENABLE);
537 /* Flush the plane changes */
538 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
539 REG_READ(dspbase_reg);
540 }
541
542 /* Next, disable display pipes */
543 temp = REG_READ(pipeconf_reg);
544 if ((temp & PIPEACONF_ENABLE) != 0) {
545 temp &= ~PIPEACONF_ENABLE;
546 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
547 REG_WRITE(pipeconf_reg, temp);
548 REG_READ(pipeconf_reg);
549
550 /* Wait for for the pipe disable to take effect. */
551 mdfldWaitForPipeDisable(dev, pipe);
552 }
553
554 temp = REG_READ(dpll_reg);
555 if (temp & DPLL_VCO_ENABLE) {
556 if ((pipe != 1 && !((REG_READ(PIPEACONF)
557 | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
558 || pipe == 1) {
559 temp &= ~(DPLL_VCO_ENABLE);
560 REG_WRITE(dpll_reg, temp);
561 REG_READ(dpll_reg);
562 /* Wait for the clocks to turn off. */
563 /* FIXME_MDFLD PO may need more delay */
564 udelay(500);
565 }
566 }
567 break;
568 }
569 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
570 gma_power_end(dev);
571}
572
573
574#define MDFLD_LIMT_DPLL_19 0
575#define MDFLD_LIMT_DPLL_25 1
576#define MDFLD_LIMT_DPLL_83 2
577#define MDFLD_LIMT_DPLL_100 3
578#define MDFLD_LIMT_DSIPLL_19 4
579#define MDFLD_LIMT_DSIPLL_25 5
580#define MDFLD_LIMT_DSIPLL_83 6
581#define MDFLD_LIMT_DSIPLL_100 7
582
583#define MDFLD_DOT_MIN 19750
584#define MDFLD_DOT_MAX 120000
585#define MDFLD_DPLL_M_MIN_19 113
586#define MDFLD_DPLL_M_MAX_19 155
587#define MDFLD_DPLL_P1_MIN_19 2
588#define MDFLD_DPLL_P1_MAX_19 10
589#define MDFLD_DPLL_M_MIN_25 101
590#define MDFLD_DPLL_M_MAX_25 130
591#define MDFLD_DPLL_P1_MIN_25 2
592#define MDFLD_DPLL_P1_MAX_25 10
593#define MDFLD_DPLL_M_MIN_83 64
594#define MDFLD_DPLL_M_MAX_83 64
595#define MDFLD_DPLL_P1_MIN_83 2
596#define MDFLD_DPLL_P1_MAX_83 2
597#define MDFLD_DPLL_M_MIN_100 64
598#define MDFLD_DPLL_M_MAX_100 64
599#define MDFLD_DPLL_P1_MIN_100 2
600#define MDFLD_DPLL_P1_MAX_100 2
601#define MDFLD_DSIPLL_M_MIN_19 131
602#define MDFLD_DSIPLL_M_MAX_19 175
603#define MDFLD_DSIPLL_P1_MIN_19 3
604#define MDFLD_DSIPLL_P1_MAX_19 8
605#define MDFLD_DSIPLL_M_MIN_25 97
606#define MDFLD_DSIPLL_M_MAX_25 140
607#define MDFLD_DSIPLL_P1_MIN_25 3
608#define MDFLD_DSIPLL_P1_MAX_25 9
609#define MDFLD_DSIPLL_M_MIN_83 33
610#define MDFLD_DSIPLL_M_MAX_83 92
611#define MDFLD_DSIPLL_P1_MIN_83 2
612#define MDFLD_DSIPLL_P1_MAX_83 3
613#define MDFLD_DSIPLL_M_MIN_100 97
614#define MDFLD_DSIPLL_M_MAX_100 140
615#define MDFLD_DSIPLL_P1_MIN_100 3
616#define MDFLD_DSIPLL_P1_MAX_100 9
617
618static const struct mrst_limit_t mdfld_limits[] = {
619 { /* MDFLD_LIMT_DPLL_19 */
620 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
621 .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
622 .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
623 },
624 { /* MDFLD_LIMT_DPLL_25 */
625 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
626 .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
627 .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
628 },
629 { /* MDFLD_LIMT_DPLL_83 */
630 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
631 .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
632 .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
633 },
634 { /* MDFLD_LIMT_DPLL_100 */
635 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
636 .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
637 .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
638 },
639 { /* MDFLD_LIMT_DSIPLL_19 */
640 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
641 .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
642 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
643 },
644 { /* MDFLD_LIMT_DSIPLL_25 */
645 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
646 .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
647 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
648 },
649 { /* MDFLD_LIMT_DSIPLL_83 */
650 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
651 .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
652 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
653 },
654 { /* MDFLD_LIMT_DSIPLL_100 */
655 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
656 .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
657 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
658 },
659};
660
661#define MDFLD_M_MIN 21
662#define MDFLD_M_MAX 180
663static const u32 mdfld_m_converts[] = {
664/* M configuration table from 9-bit LFSR table */
665 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
666 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */
667 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
668 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
669 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
670 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
671 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
672 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
673 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
674 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
675 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
676 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
677 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
678 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
679 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
680 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
681};
682
683static const struct mrst_limit_t *mdfld_limit(struct drm_crtc *crtc)
684{
685 const struct mrst_limit_t *limit = NULL;
686 struct drm_device *dev = crtc->dev;
687 struct drm_psb_private *dev_priv = dev->dev_private;
688
689 if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
690 || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
691 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
692 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
693 else if (ksel == KSEL_BYPASS_25)
694 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
695 else if ((ksel == KSEL_BYPASS_83_100) &&
696 (dev_priv->core_freq == 166))
697 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
698 else if ((ksel == KSEL_BYPASS_83_100) &&
699 (dev_priv->core_freq == 100 ||
700 dev_priv->core_freq == 200))
701 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
702 } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
703 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
704 limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
705 else if (ksel == KSEL_BYPASS_25)
706 limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
707 else if ((ksel == KSEL_BYPASS_83_100) &&
708 (dev_priv->core_freq == 166))
709 limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
710 else if ((ksel == KSEL_BYPASS_83_100) &&
711 (dev_priv->core_freq == 100 ||
712 dev_priv->core_freq == 200))
713 limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
714 } else {
715 limit = NULL;
716 dev_dbg(dev->dev, "mdfld_limit Wrong display type.\n");
717 }
718
719 return limit;
720}
721
722/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
723static void mdfld_clock(int refclk, struct mrst_clock_t *clock)
724{
725 clock->dot = (refclk * clock->m) / clock->p1;
726}
727
728/**
729 * Returns a set of divisors for the desired target clock with the given refclk,
730 * or FALSE. Divisor values are the actual divisors for
731 */
732static bool
733mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
734 struct mrst_clock_t *best_clock)
735{
736 struct mrst_clock_t clock;
737 const struct mrst_limit_t *limit = mdfld_limit(crtc);
738 int err = target;
739
740 memset(best_clock, 0, sizeof(*best_clock));
741
742 for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
743 for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
744 clock.p1++) {
745 int this_err;
746
747 mdfld_clock(refclk, &clock);
748
749 this_err = abs(clock.dot - target);
750 if (this_err < err) {
751 *best_clock = clock;
752 err = this_err;
753 }
754 }
755 }
756 return err != target;
757}
758
759static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
760 struct drm_display_mode *mode,
761 struct drm_display_mode *adjusted_mode,
762 int x, int y,
763 struct drm_framebuffer *old_fb)
764{
765 struct drm_device *dev = crtc->dev;
766 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
767 struct drm_psb_private *dev_priv = dev->dev_private;
768 int pipe = psb_intel_crtc->pipe;
769 int fp_reg = MRST_FPA0;
770 int dpll_reg = MRST_DPLL_A;
771 int dspcntr_reg = DSPACNTR;
772 int pipeconf_reg = PIPEACONF;
773 int htot_reg = HTOTAL_A;
774 int hblank_reg = HBLANK_A;
775 int hsync_reg = HSYNC_A;
776 int vtot_reg = VTOTAL_A;
777 int vblank_reg = VBLANK_A;
778 int vsync_reg = VSYNC_A;
779 int dspsize_reg = DSPASIZE;
780 int dsppos_reg = DSPAPOS;
781 int pipesrc_reg = PIPEASRC;
782 u32 *pipeconf = &dev_priv->pipeconf[pipe];
783 u32 *dspcntr = &dev_priv->dspcntr[pipe];
784 int refclk = 0;
785 int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0,
786 clk_tmp = 0;
787 struct mrst_clock_t clock;
788 bool ok;
789 u32 dpll = 0, fp = 0;
790 bool is_crt = false, is_lvds = false, is_tv = false;
791 bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
792 struct drm_mode_config *mode_config = &dev->mode_config;
793 struct psb_intel_encoder *psb_intel_encoder = NULL;
794 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
795 struct drm_encoder *encoder;
796 struct drm_connector *connector;
797 int timeout = 0;
798 int ret;
799
800 dev_dbg(dev->dev, "pipe = 0x%x\n", pipe);
801
802#if 0
803 if (pipe == 1) {
804 if (!gma_power_begin(dev, true))
805 return 0;
806 android_hdmi_crtc_mode_set(crtc, mode, adjusted_mode,
807 x, y, old_fb);
808 goto mrst_crtc_mode_set_exit;
809 }
810#endif
811
812 switch (pipe) {
813 case 0:
814 break;
815 case 1:
816 fp_reg = FPB0;
817 dpll_reg = DPLL_B;
818 dspcntr_reg = DSPBCNTR;
819 pipeconf_reg = PIPEBCONF;
820 htot_reg = HTOTAL_B;
821 hblank_reg = HBLANK_B;
822 hsync_reg = HSYNC_B;
823 vtot_reg = VTOTAL_B;
824 vblank_reg = VBLANK_B;
825 vsync_reg = VSYNC_B;
826 dspsize_reg = DSPBSIZE;
827 dsppos_reg = DSPBPOS;
828 pipesrc_reg = PIPEBSRC;
829 fp_reg = MDFLD_DPLL_DIV0;
830 dpll_reg = MDFLD_DPLL_B;
831 break;
832 case 2:
833 dpll_reg = MRST_DPLL_A;
834 dspcntr_reg = DSPCCNTR;
835 pipeconf_reg = PIPECCONF;
836 htot_reg = HTOTAL_C;
837 hblank_reg = HBLANK_C;
838 hsync_reg = HSYNC_C;
839 vtot_reg = VTOTAL_C;
840 vblank_reg = VBLANK_C;
841 vsync_reg = VSYNC_C;
842 dspsize_reg = DSPCSIZE;
843 dsppos_reg = DSPCPOS;
844 pipesrc_reg = PIPECSRC;
845 break;
846 default:
847 DRM_ERROR("Illegal Pipe Number.\n");
848 return 0;
849 }
850
851 ret = check_fb(crtc->fb);
852 if (ret)
853 return ret;
854
855 dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
856 adjusted_mode->hdisplay);
857 dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
858 adjusted_mode->vdisplay);
859 dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
860 adjusted_mode->hsync_start);
861 dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
862 adjusted_mode->hsync_end);
863 dev_dbg(dev->dev, "adjusted_htotal = %d\n",
864 adjusted_mode->htotal);
865 dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
866 adjusted_mode->vsync_start);
867 dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
868 adjusted_mode->vsync_end);
869 dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
870 adjusted_mode->vtotal);
871 dev_dbg(dev->dev, "adjusted_clock = %d\n",
872 adjusted_mode->clock);
873 dev_dbg(dev->dev, "hdisplay = %d\n",
874 mode->hdisplay);
875 dev_dbg(dev->dev, "vdisplay = %d\n",
876 mode->vdisplay);
877
878 if (!gma_power_begin(dev, true))
879 return 0;
880
881 memcpy(&psb_intel_crtc->saved_mode, mode,
882 sizeof(struct drm_display_mode));
883 memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode,
884 sizeof(struct drm_display_mode));
885
886 list_for_each_entry(connector, &mode_config->connector_list, head) {
887 if (!connector)
888 continue;
889
890 encoder = connector->encoder;
891
892 if (!encoder)
893 continue;
894
895 if (encoder->crtc != crtc)
896 continue;
897
898 psb_intel_encoder = psb_intel_attached_encoder(connector);
899
900 switch (psb_intel_encoder->type) {
901 case INTEL_OUTPUT_LVDS:
902 is_lvds = true;
903 break;
904 case INTEL_OUTPUT_TVOUT:
905 is_tv = true;
906 break;
907 case INTEL_OUTPUT_ANALOG:
908 is_crt = true;
909 break;
910 case INTEL_OUTPUT_MIPI:
911 is_mipi = true;
912 break;
913 case INTEL_OUTPUT_MIPI2:
914 is_mipi2 = true;
915 break;
916 case INTEL_OUTPUT_HDMI:
917 is_hdmi = true;
918 break;
919 }
920 }
921
922 /* Disable the VGA plane that we never use */
923 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
924
925 /* Disable the panel fitter if it was on our pipe */
926 if (psb_intel_panel_fitter_pipe(dev) == pipe)
927 REG_WRITE(PFIT_CONTROL, 0);
928
929 /* pipesrc and dspsize control the size that is scaled from,
930 * which should always be the user's requested size.
931 */
932 if (pipe == 1) {
933 /* FIXME: To make HDMI display with 864x480 (TPO), 480x864
934 * (PYR) or 480x854 (TMD), set the sprite width/height and
935 * souce image size registers with the adjusted mode for
936 * pipe B.
937 */
938
939 /*
940 * The defined sprite rectangle must always be completely
941 * contained within the displayable area of the screen image
942 * (frame buffer).
943 */
944 REG_WRITE(dspsize_reg, ((min(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
945 | (min(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
946 /* Set the CRTC with encoder mode. */
947 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
948 | (mode->crtc_vdisplay - 1));
949 } else {
950 REG_WRITE(dspsize_reg,
951 ((mode->crtc_vdisplay - 1) << 16) |
952 (mode->crtc_hdisplay - 1));
953 REG_WRITE(pipesrc_reg,
954 ((mode->crtc_hdisplay - 1) << 16) |
955 (mode->crtc_vdisplay - 1));
956 }
957
958 REG_WRITE(dsppos_reg, 0);
959
960 if (psb_intel_encoder)
961 drm_connector_property_get_value(connector,
962 dev->mode_config.scaling_mode_property, &scalingType);
963
964 if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
965 /* Medfield doesn't have register support for centering so we
966 * need to mess with the h/vblank and h/vsync start and ends
967 * to get centering
968 */
969 int offsetX = 0, offsetY = 0;
970
971 offsetX = (adjusted_mode->crtc_hdisplay -
972 mode->crtc_hdisplay) / 2;
973 offsetY = (adjusted_mode->crtc_vdisplay -
974 mode->crtc_vdisplay) / 2;
975
976 REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
977 ((adjusted_mode->crtc_htotal - 1) << 16));
978 REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
979 ((adjusted_mode->crtc_vtotal - 1) << 16));
980 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start -
981 offsetX - 1) |
982 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
983 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start -
984 offsetX - 1) |
985 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
986 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start -
987 offsetY - 1) |
988 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
989 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start -
990 offsetY - 1) |
991 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
992 } else {
993 REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
994 ((adjusted_mode->crtc_htotal - 1) << 16));
995 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
996 ((adjusted_mode->crtc_vtotal - 1) << 16));
997 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
998 ((adjusted_mode->crtc_hblank_end - 1) << 16));
999 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
1000 ((adjusted_mode->crtc_hsync_end - 1) << 16));
1001 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
1002 ((adjusted_mode->crtc_vblank_end - 1) << 16));
1003 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
1004 ((adjusted_mode->crtc_vsync_end - 1) << 16));
1005 }
1006
1007 /* Flush the plane changes */
1008 {
1009 struct drm_crtc_helper_funcs *crtc_funcs =
1010 crtc->helper_private;
1011 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
1012 }
1013
1014 /* setup pipeconf */
1015 *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
1016
1017 /* Set up the display plane register */
1018 *dspcntr = REG_READ(dspcntr_reg);
1019 *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
1020 *dspcntr |= DISPLAY_PLANE_ENABLE;
1021
1022 if (is_mipi2)
1023 goto mrst_crtc_mode_set_exit;
1024 clk = adjusted_mode->clock;
1025
1026 if (is_hdmi) {
1027 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19)) {
1028 refclk = 19200;
1029
1030 if (is_mipi || is_mipi2)
1031 clk_n = 1, clk_p2 = 8;
1032 else if (is_hdmi)
1033 clk_n = 1, clk_p2 = 10;
1034 } else if (ksel == KSEL_BYPASS_25) {
1035 refclk = 25000;
1036
1037 if (is_mipi || is_mipi2)
1038 clk_n = 1, clk_p2 = 8;
1039 else if (is_hdmi)
1040 clk_n = 1, clk_p2 = 10;
1041 } else if ((ksel == KSEL_BYPASS_83_100) &&
1042 dev_priv->core_freq == 166) {
1043 refclk = 83000;
1044
1045 if (is_mipi || is_mipi2)
1046 clk_n = 4, clk_p2 = 8;
1047 else if (is_hdmi)
1048 clk_n = 4, clk_p2 = 10;
1049 } else if ((ksel == KSEL_BYPASS_83_100) &&
1050 (dev_priv->core_freq == 100 ||
1051 dev_priv->core_freq == 200)) {
1052 refclk = 100000;
1053 if (is_mipi || is_mipi2)
1054 clk_n = 4, clk_p2 = 8;
1055 else if (is_hdmi)
1056 clk_n = 4, clk_p2 = 10;
1057 }
1058
1059 if (is_mipi)
1060 clk_byte = dev_priv->bpp / 8;
1061 else if (is_mipi2)
1062 clk_byte = dev_priv->bpp2 / 8;
1063
1064 clk_tmp = clk * clk_n * clk_p2 * clk_byte;
1065
1066 dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d.\n",
1067 clk, clk_n, clk_p2);
1068 dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d.\n",
1069 adjusted_mode->clock, clk_tmp);
1070
1071 ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
1072
1073 if (!ok) {
1074 DRM_ERROR
1075 ("mdfldFindBestPLL fail in mdfld_crtc_mode_set.\n");
1076 } else {
1077 m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
1078
1079 dev_dbg(dev->dev, "dot clock = %d,"
1080 "m = %d, p1 = %d, m_conv = %d.\n",
1081 clock.dot, clock.m,
1082 clock.p1, m_conv);
1083 }
1084
1085 dpll = REG_READ(dpll_reg);
1086
1087 if (dpll & DPLL_VCO_ENABLE) {
1088 dpll &= ~DPLL_VCO_ENABLE;
1089 REG_WRITE(dpll_reg, dpll);
1090 REG_READ(dpll_reg);
1091
1092 /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
1093 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1094 udelay(500);
1095
1096 /* reset M1, N1 & P1 */
1097 REG_WRITE(fp_reg, 0);
1098 dpll &= ~MDFLD_P1_MASK;
1099 REG_WRITE(dpll_reg, dpll);
1100 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1101 udelay(500);
1102 }
1103
1104 /* When ungating power of DPLL, needs to wait 0.5us before
1105 * enable the VCO */
1106 if (dpll & MDFLD_PWR_GATE_EN) {
1107 dpll &= ~MDFLD_PWR_GATE_EN;
1108 REG_WRITE(dpll_reg, dpll);
1109 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1110 udelay(500);
1111 }
1112 dpll = 0;
1113
1114#if 0 /* FIXME revisit later */
1115 if (ksel == KSEL_CRYSTAL_19 || ksel == KSEL_BYPASS_19 ||
1116 ksel == KSEL_BYPASS_25)
1117 dpll &= ~MDFLD_INPUT_REF_SEL;
1118 else if (ksel == KSEL_BYPASS_83_100)
1119 dpll |= MDFLD_INPUT_REF_SEL;
1120#endif /* FIXME revisit later */
1121
1122 if (is_hdmi)
1123 dpll |= MDFLD_VCO_SEL;
1124
1125 fp = (clk_n / 2) << 16;
1126 fp |= m_conv;
1127
1128 /* compute bitmask from p1 value */
1129 dpll |= (1 << (clock.p1 - 2)) << 17;
1130
1131#if 0 /* 1080p30 & 720p */
1132 dpll = 0x00050000;
1133 fp = 0x000001be;
1134#endif
1135#if 0 /* 480p */
1136 dpll = 0x02010000;
1137 fp = 0x000000d2;
1138#endif
1139 } else {
1140#if 0 /*DBI_TPO_480x864*/
1141 dpll = 0x00020000;
1142 fp = 0x00000156;
1143#endif /* DBI_TPO_480x864 */ /* get from spec. */
1144
1145 dpll = 0x00800000;
1146 fp = 0x000000c1;
1147 }
1148
1149 REG_WRITE(fp_reg, fp);
1150 REG_WRITE(dpll_reg, dpll);
1151 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1152 udelay(500);
1153
1154 dpll |= DPLL_VCO_ENABLE;
1155 REG_WRITE(dpll_reg, dpll);
1156 REG_READ(dpll_reg);
1157
1158 /* wait for DSI PLL to lock */
1159 while (timeout < 20000 &&
1160 !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
1161 udelay(150);
1162 timeout++;
1163 }
1164
1165 if (is_mipi)
1166 goto mrst_crtc_mode_set_exit;
1167
1168 dev_dbg(dev->dev, "is_mipi = 0x%x\n", is_mipi);
1169
1170 REG_WRITE(pipeconf_reg, *pipeconf);
1171 REG_READ(pipeconf_reg);
1172
1173 /* Wait for for the pipe enable to take effect. */
1174 REG_WRITE(dspcntr_reg, *dspcntr);
1175 psb_intel_wait_for_vblank(dev);
1176
1177mrst_crtc_mode_set_exit:
1178
1179 gma_power_end(dev);
1180
1181 return 0;
1182}
1183
1184const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
1185 .dpms = mdfld_crtc_dpms,
1186 .mode_fixup = psb_intel_crtc_mode_fixup,
1187 .mode_set = mdfld_crtc_mode_set,
1188 .mode_set_base = mdfld__intel_pipe_set_base,
1189 .prepare = psb_intel_crtc_prepare,
1190 .commit = psb_intel_crtc_commit,
1191};
1192