gma500: enable Medfield CRTC support
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / gma500 / mdfld_intel_display.c
blob0b619b68642fae67eb9896fd09b0d9e68a9f5a51
1 /*
2 * Copyright © 2006-2011 Intel Corporation
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:
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.
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.
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
27 #include "psb_fb.h"
28 #include "psb_intel_display.h"
29 #include "mdfld_dsi_dbi.h"
30 #include "mdfld_dsi_dpi.h"
31 //#include "mdfld_dsi_output.h"
32 #ifdef CONFIG_MDFLD_DSI_DPU
33 #include "mdfld_dsi_dbi_dpu.h"
34 #endif
36 #include <linux/pm_runtime.h>
38 #ifdef MIN
39 #undef MIN
40 #endif
42 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
44 /* Hardcoded currently */
45 static int ksel = KSEL_CRYSTAL_19;
47 extern void mdfld_save_display(struct drm_device *dev);
48 extern bool gbgfxsuspended;
50 struct psb_intel_range_t {
51 int min, max;
54 struct mdfld_limit_t {
55 struct psb_intel_range_t dot, m, p1;
58 struct mdfld_intel_clock_t {
59 /* given values */
60 int n;
61 int m1, m2;
62 int p1, p2;
63 /* derived values */
64 int dot;
65 int vco;
66 int m;
67 int p;
72 #define COUNT_MAX 0x10000000
74 void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
76 int count, temp;
77 u32 pipeconf_reg = PIPEACONF;
79 switch (pipe) {
80 case 0:
81 break;
82 case 1:
83 pipeconf_reg = PIPEBCONF;
84 break;
85 case 2:
86 pipeconf_reg = PIPECCONF;
87 break;
88 default:
89 DRM_ERROR("Illegal Pipe Number. \n");
90 return;
93 /* FIXME JLIU7_PO */
94 psb_intel_wait_for_vblank(dev);
95 return;
97 /* Wait for for the pipe disable to take effect. */
98 for (count = 0; count < COUNT_MAX; count++) {
99 temp = REG_READ(pipeconf_reg);
100 if ((temp & PIPEACONF_PIPE_STATE) == 0)
101 break;
105 void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
107 int count, temp;
108 u32 pipeconf_reg = PIPEACONF;
110 switch (pipe) {
111 case 0:
112 break;
113 case 1:
114 pipeconf_reg = PIPEBCONF;
115 break;
116 case 2:
117 pipeconf_reg = PIPECCONF;
118 break;
119 default:
120 dev_err(dev->dev, "Illegal Pipe Number.\n");
121 return;
124 /* FIXME JLIU7_PO */
125 psb_intel_wait_for_vblank(dev);
126 return;
128 /* Wait for for the pipe enable to take effect. */
129 for (count = 0; count < COUNT_MAX; count++) {
130 temp = REG_READ(pipeconf_reg);
131 if ((temp & PIPEACONF_PIPE_STATE) == 1)
132 break;
137 static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
138 struct drm_file *file_priv,
139 uint32_t handle,
140 uint32_t width, uint32_t height)
142 struct drm_device *dev = crtc->dev;
143 struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
144 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
145 int pipe = psb_intel_crtc->pipe;
146 uint32_t control = CURACNTR;
147 uint32_t base = CURABASE;
148 uint32_t temp;
149 size_t addr = 0;
150 struct gtt_range *gt;
151 struct drm_gem_object *obj;
152 int ret;
154 switch (pipe) {
155 case 0:
156 break;
157 case 1:
158 control = CURBCNTR;
159 base = CURBBASE;
160 break;
161 case 2:
162 control = CURCCNTR;
163 base = CURCBASE;
164 break;
165 default:
166 dev_err(dev->dev, "Illegal Pipe Number. \n");
167 return -EINVAL;
170 #if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
171 if (pipe != 0)
172 return 0;
173 #endif
174 /* if we want to turn of the cursor ignore width and height */
175 if (!handle) {
176 dev_dbg(dev->dev, "cursor off\n");
177 /* turn off the cursor */
178 temp = 0;
179 temp |= CURSOR_MODE_DISABLE;
181 if (gma_power_begin(dev, true)) {
182 REG_WRITE(control, temp);
183 REG_WRITE(base, 0);
184 gma_power_end(dev);
186 /* Unpin the old GEM object */
187 if (psb_intel_crtc->cursor_obj) {
188 gt = container_of(psb_intel_crtc->cursor_obj,
189 struct gtt_range, gem);
190 psb_gtt_unpin(gt);
191 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
192 psb_intel_crtc->cursor_obj = NULL;
194 return 0;
197 /* Currently we only support 64x64 cursors */
198 if (width != 64 || height != 64) {
199 DRM_ERROR("we currently only support 64x64 cursors\n");
200 return -EINVAL;
203 obj = drm_gem_object_lookup(dev, file_priv, handle);
204 if (!obj)
205 return -ENOENT;
207 if (obj->size < width * height * 4) {
208 dev_dbg(dev->dev, "buffer is to small\n");
209 return -ENOMEM;
212 gt = container_of(obj, struct gtt_range, gem);
214 /* Pin the memory into the GTT */
215 ret = psb_gtt_pin(gt);
216 if (ret) {
217 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
218 return ret;
222 addr = gt->offset; /* Or resource.start ??? */
224 psb_intel_crtc->cursor_addr = addr;
226 temp = 0;
227 /* set the pipe for the cursor */
228 temp |= (pipe << 28);
229 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
231 if (gma_power_begin(dev, true)) {
232 REG_WRITE(control, temp);
233 REG_WRITE(base, addr);
234 gma_power_end(dev);
236 #if 0
237 /* FIXME: COnvert to GEM */
238 /* unpin the old bo */
239 if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
240 mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
241 psb_intel_crtc->cursor_bo = bo;
243 #endif
244 return 0;
247 static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
249 struct drm_device *dev = crtc->dev;
250 #ifndef CONFIG_MDFLD_DSI_DPU
251 struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
252 #else
253 struct psb_drm_dpu_rect rect;
254 #endif
255 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
256 int pipe = psb_intel_crtc->pipe;
257 uint32_t pos = CURAPOS;
258 uint32_t base = CURABASE;
259 uint32_t temp = 0;
260 uint32_t addr;
262 switch (pipe) {
263 case 0:
264 #ifndef CONFIG_MDFLD_DSI_DPU
265 if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
266 mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_0, 0, 0);
267 #else /*CONFIG_MDFLD_DSI_DPU*/
268 rect.x = x;
269 rect.y = y;
271 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect);
272 mdfld_dpu_exit_dsr(dev);
273 #endif
274 break;
275 case 1:
276 pos = CURBPOS;
277 base = CURBBASE;
278 break;
279 case 2:
280 #ifndef CONFIG_MDFLD_DSI_DPU
281 if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
282 mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_2, 0, 0);
283 #else /*CONFIG_MDFLD_DSI_DPU*/
284 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
285 mdfld_dpu_exit_dsr(dev);
286 #endif
287 pos = CURCPOS;
288 base = CURCBASE;
289 break;
290 default:
291 DRM_ERROR("Illegal Pipe Number. \n");
292 return -EINVAL;
295 #if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
296 if (pipe != 0)
297 return 0;
298 #endif
299 if (x < 0) {
300 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
301 x = -x;
303 if (y < 0) {
304 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
305 y = -y;
308 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
309 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
311 addr = psb_intel_crtc->cursor_addr;
313 if (gma_power_begin(dev, true)) {
314 REG_WRITE(pos, temp);
315 REG_WRITE(base, addr);
316 gma_power_end(dev);
319 return 0;
322 const struct drm_crtc_funcs mdfld_intel_crtc_funcs = {
323 .cursor_set = mdfld_intel_crtc_cursor_set,
324 .cursor_move = mdfld_intel_crtc_cursor_move,
325 .gamma_set = psb_intel_crtc_gamma_set,
326 .set_config = drm_crtc_helper_set_config,
327 .destroy = psb_intel_crtc_destroy,
330 static struct drm_device globle_dev;
332 void mdfld__intel_plane_set_alpha(int enable)
334 struct drm_device *dev = &globle_dev;
335 int dspcntr_reg = DSPACNTR;
336 u32 dspcntr;
338 dspcntr = REG_READ(dspcntr_reg);
340 if (enable) {
341 dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
342 dspcntr |= DISPPLANE_32BPP;
343 } else {
344 dspcntr &= ~DISPPLANE_32BPP;
345 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
348 REG_WRITE(dspcntr_reg, dspcntr);
351 int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb)
353 struct drm_device *dev = crtc->dev;
354 /* struct drm_i915_master_private *master_priv; */
355 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
356 struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
357 struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
358 int pipe = psb_intel_crtc->pipe;
359 unsigned long start, offset;
360 int dsplinoff = DSPALINOFF;
361 int dspsurf = DSPASURF;
362 int dspstride = DSPASTRIDE;
363 int dspcntr_reg = DSPACNTR;
364 u32 dspcntr;
365 int ret = 0;
367 memcpy(&globle_dev, dev, sizeof(struct drm_device));
369 if (!gma_power_begin(dev, true))
370 return 0;
372 /* no fb bound */
373 if (!crtc->fb) {
374 dev_err(dev->dev, "No FB bound\n");
375 goto psb_intel_pipe_cleaner;
378 switch (pipe) {
379 case 0:
380 dsplinoff = DSPALINOFF;
381 break;
382 case 1:
383 dsplinoff = DSPBLINOFF;
384 dspsurf = DSPBSURF;
385 dspstride = DSPBSTRIDE;
386 dspcntr_reg = DSPBCNTR;
387 break;
388 case 2:
389 dsplinoff = DSPCLINOFF;
390 dspsurf = DSPCSURF;
391 dspstride = DSPCSTRIDE;
392 dspcntr_reg = DSPCCNTR;
393 break;
394 default:
395 dev_err(dev->dev, "Illegal Pipe Number.\n");
396 return -EINVAL;
399 ret = psb_gtt_pin(psbfb->gtt);
400 if (ret < 0)
401 goto psb_intel_pipe_set_base_exit;
403 start = psbfb->gtt->offset;
404 offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
406 REG_WRITE(dspstride, crtc->fb->pitch);
407 dspcntr = REG_READ(dspcntr_reg);
408 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
410 switch (crtc->fb->bits_per_pixel) {
411 case 8:
412 dspcntr |= DISPPLANE_8BPP;
413 break;
414 case 16:
415 if (crtc->fb->depth == 15)
416 dspcntr |= DISPPLANE_15_16BPP;
417 else
418 dspcntr |= DISPPLANE_16BPP;
419 break;
420 case 24:
421 case 32:
422 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
423 break;
424 default:
425 dev_err(dev->dev, "Unknown color depth\n");
426 ret = -EINVAL;
427 goto psb_intel_pipe_set_base_exit;
429 REG_WRITE(dspcntr_reg, dspcntr);
431 dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
432 start, offset, x, y);
434 REG_WRITE(dsplinoff, offset);
435 REG_READ(dsplinoff);
436 REG_WRITE(dspsurf, start);
437 REG_READ(dspsurf);
439 psb_intel_pipe_cleaner:
440 /* If there was a previous display we can now unpin it */
441 if (old_fb)
442 psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
444 psb_intel_pipe_set_base_exit:
445 gma_power_end(dev);
446 return ret;
450 * Disable the pipe, plane and pll.
453 void mdfld_disable_crtc (struct drm_device *dev, int pipe)
455 int dpll_reg = MRST_DPLL_A;
456 int dspcntr_reg = DSPACNTR;
457 int dspbase_reg = MRST_DSPABASE;
458 int pipeconf_reg = PIPEACONF;
459 u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
460 u32 temp;
462 switch (pipe) {
463 case 0:
464 break;
465 case 1:
466 dpll_reg = MDFLD_DPLL_B;
467 dspcntr_reg = DSPBCNTR;
468 dspbase_reg = DSPBSURF;
469 pipeconf_reg = PIPEBCONF;
470 break;
471 case 2:
472 dpll_reg = MRST_DPLL_A;
473 dspcntr_reg = DSPCCNTR;
474 dspbase_reg = MDFLD_DSPCBASE;
475 pipeconf_reg = PIPECCONF;
476 gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
477 break;
478 default:
479 dev_err(dev->dev, "Illegal Pipe Number. \n");
480 return;
483 if (pipe != 1)
484 mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
486 /* Disable display plane */
487 temp = REG_READ(dspcntr_reg);
488 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
489 REG_WRITE(dspcntr_reg,
490 temp & ~DISPLAY_PLANE_ENABLE);
491 /* Flush the plane changes */
492 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
493 REG_READ(dspbase_reg);
496 /* FIXME_JLIU7 MDFLD_PO revisit */
497 /* Wait for vblank for the disable to take effect */
498 // MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
500 /* Next, disable display pipes */
501 temp = REG_READ(pipeconf_reg);
502 if ((temp & PIPEACONF_ENABLE) != 0) {
503 temp &= ~PIPEACONF_ENABLE;
504 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
505 REG_WRITE(pipeconf_reg, temp);
506 REG_READ(pipeconf_reg);
508 /* Wait for for the pipe disable to take effect. */
509 mdfldWaitForPipeDisable(dev, pipe);
512 temp = REG_READ(dpll_reg);
513 if (temp & DPLL_VCO_ENABLE) {
514 if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
515 || (pipe == 1)){
516 temp &= ~(DPLL_VCO_ENABLE);
517 REG_WRITE(dpll_reg, temp);
518 REG_READ(dpll_reg);
519 /* Wait for the clocks to turn off. */
520 /* FIXME_MDFLD PO may need more delay */
521 udelay(500);
523 if (!(temp & MDFLD_PWR_GATE_EN)) {
524 /* gating power of DPLL */
525 REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
526 /* FIXME_MDFLD PO - change 500 to 1 after PO */
527 udelay(5000);
535 * Sets the power management mode of the pipe and plane.
537 * This code should probably grow support for turning the cursor off and back
538 * on appropriately at the same time as we're turning the pipe off/on.
540 static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
542 struct drm_device *dev = crtc->dev;
543 struct drm_psb_private *dev_priv = dev->dev_private;
544 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
545 int pipe = psb_intel_crtc->pipe;
546 int dpll_reg = MRST_DPLL_A;
547 int dspcntr_reg = DSPACNTR;
548 int dspbase_reg = MRST_DSPABASE;
549 int pipeconf_reg = PIPEACONF;
550 u32 pipestat_reg = PIPEASTAT;
551 u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
552 u32 pipeconf = dev_priv->pipeconf;
553 u32 dspcntr = dev_priv->dspcntr;
554 u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG;
555 u32 temp;
556 bool enabled;
557 int timeout = 0;
559 if (!gma_power_begin(dev, true))
560 return;
562 /* Ignore if system is already in DSR and in suspended state. */
563 if(/*gbgfxsuspended */0 && dev_priv->dispstatus == false && mode == 3){
564 if(dev_priv->rpm_enabled && pipe == 1){
565 // dev_priv->is_mipi_on = false;
566 pm_request_idle(&dev->pdev->dev);
568 return;
569 }else if(mode == 0) {
570 //do not need to set gbdispstatus=true in crtc.
571 //this will be set in encoder such as mdfld_dsi_dbi_dpms
572 //gbdispstatus = true;
576 /* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
577 /* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
579 switch (pipe) {
580 case 0:
581 break;
582 case 1:
583 dpll_reg = DPLL_B;
584 dspcntr_reg = DSPBCNTR;
585 dspbase_reg = MRST_DSPBBASE;
586 pipeconf_reg = PIPEBCONF;
587 pipeconf = dev_priv->pipeconf1;
588 dspcntr = dev_priv->dspcntr1;
589 dpll_reg = MDFLD_DPLL_B;
590 break;
591 case 2:
592 dpll_reg = MRST_DPLL_A;
593 dspcntr_reg = DSPCCNTR;
594 dspbase_reg = MDFLD_DSPCBASE;
595 pipeconf_reg = PIPECCONF;
596 pipestat_reg = PIPECSTAT;
597 pipeconf = dev_priv->pipeconf2;
598 dspcntr = dev_priv->dspcntr2;
599 gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
600 mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET;
601 break;
602 default:
603 dev_err(dev->dev, "Illegal Pipe Number.\n");
604 return;
607 /* XXX: When our outputs are all unaware of DPMS modes other than off
608 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
610 switch (mode) {
611 case DRM_MODE_DPMS_ON:
612 case DRM_MODE_DPMS_STANDBY:
613 case DRM_MODE_DPMS_SUSPEND:
614 /* Enable the DPLL */
615 temp = REG_READ(dpll_reg);
617 if ((temp & DPLL_VCO_ENABLE) == 0) {
618 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
619 if (temp & MDFLD_PWR_GATE_EN) {
620 temp &= ~MDFLD_PWR_GATE_EN;
621 REG_WRITE(dpll_reg, temp);
622 /* FIXME_MDFLD PO - change 500 to 1 after PO */
623 udelay(500);
626 REG_WRITE(dpll_reg, temp);
627 REG_READ(dpll_reg);
628 /* FIXME_MDFLD PO - change 500 to 1 after PO */
629 udelay(500);
631 REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
632 REG_READ(dpll_reg);
635 * wait for DSI PLL to lock
636 * NOTE: only need to poll status of pipe 0 and pipe 1,
637 * since both MIPI pipes share the same PLL.
639 while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
640 udelay(150);
641 timeout ++;
645 /* Enable the plane */
646 temp = REG_READ(dspcntr_reg);
647 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
648 REG_WRITE(dspcntr_reg,
649 temp | DISPLAY_PLANE_ENABLE);
650 /* Flush the plane changes */
651 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
654 /* Enable the pipe */
655 temp = REG_READ(pipeconf_reg);
656 if ((temp & PIPEACONF_ENABLE) == 0) {
657 REG_WRITE(pipeconf_reg, pipeconf);
659 /* Wait for for the pipe enable to take effect. */
660 mdfldWaitForPipeEnable(dev, pipe);
663 /*workaround for sighting 3741701 Random X blank display*/
664 /*perform w/a in video mode only on pipe A or C*/
665 if ((pipe == 0 || pipe == 2) &&
666 (mdfld_panel_dpi(dev) == true)) {
667 REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
668 msleep(100);
669 if(PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) {
670 printk(KERN_ALERT "OK");
671 } else {
672 printk(KERN_ALERT "STUCK!!!!");
673 /*shutdown controller*/
674 temp = REG_READ(dspcntr_reg);
675 REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
676 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
677 /*mdfld_dsi_dpi_shut_down(dev, pipe);*/
678 REG_WRITE(0xb048, 1);
679 msleep(100);
680 temp = REG_READ(pipeconf_reg);
681 temp &= ~PIPEACONF_ENABLE;
682 REG_WRITE(pipeconf_reg, temp);
683 msleep(100); /*wait for pipe disable*/
684 /*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
685 printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/
686 REG_WRITE(mipi_enable_reg, 0);
687 msleep(100);
688 printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
689 printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));
690 REG_WRITE(0xb004, REG_READ(0xb004));
691 /* try to bring the controller back up again*/
692 REG_WRITE(mipi_enable_reg, 1);
693 temp = REG_READ(dspcntr_reg);
694 REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
695 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
696 /*mdfld_dsi_dpi_turn_on(dev, pipe);*/
697 REG_WRITE(0xb048, 2);
698 msleep(100);
699 temp = REG_READ(pipeconf_reg);
700 temp |= PIPEACONF_ENABLE;
701 REG_WRITE(pipeconf_reg, temp);
705 psb_intel_crtc_load_lut(crtc);
707 /* Give the overlay scaler a chance to enable
708 if it's on this pipe */
709 /* psb_intel_crtc_dpms_video(crtc, true); TODO */
711 break;
712 case DRM_MODE_DPMS_OFF:
713 /* Give the overlay scaler a chance to disable
714 * if it's on this pipe */
715 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
716 if (pipe != 1)
717 mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
719 /* Disable the VGA plane that we never use */
720 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
722 /* Disable display plane */
723 temp = REG_READ(dspcntr_reg);
724 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
725 REG_WRITE(dspcntr_reg,
726 temp & ~DISPLAY_PLANE_ENABLE);
727 /* Flush the plane changes */
728 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
729 REG_READ(dspbase_reg);
732 /* FIXME_JLIU7 MDFLD_PO revisit */
733 /* Wait for vblank for the disable to take effect */
734 // MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
736 /* Next, disable display pipes */
737 temp = REG_READ(pipeconf_reg);
738 if ((temp & PIPEACONF_ENABLE) != 0) {
739 temp &= ~PIPEACONF_ENABLE;
740 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
741 REG_WRITE(pipeconf_reg, temp);
742 // REG_WRITE(pipeconf_reg, 0);
743 REG_READ(pipeconf_reg);
745 /* Wait for for the pipe disable to take effect. */
746 mdfldWaitForPipeDisable(dev, pipe);
749 temp = REG_READ(dpll_reg);
750 if (temp & DPLL_VCO_ENABLE) {
751 if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
752 || (pipe == 1)){
753 temp &= ~(DPLL_VCO_ENABLE);
754 REG_WRITE(dpll_reg, temp);
755 REG_READ(dpll_reg);
756 /* Wait for the clocks to turn off. */
757 /* FIXME_MDFLD PO may need more delay */
758 udelay(500);
759 #if 0 /* MDFLD_PO_JLIU7 */
760 if (!(temp & MDFLD_PWR_GATE_EN)) {
761 /* gating power of DPLL */
762 REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
763 /* FIXME_MDFLD PO - change 500 to 1 after PO */
764 udelay(5000);
766 #endif /* MDFLD_PO_JLIU7 */
769 break;
772 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
774 #if 0 /* JB: Add vblank support later */
775 if (enabled)
776 dev_priv->vblank_pipe |= (1 << pipe);
777 else
778 dev_priv->vblank_pipe &= ~(1 << pipe);
779 #endif
781 gma_power_end(dev);
785 #define MDFLD_LIMT_DPLL_19 0
786 #define MDFLD_LIMT_DPLL_25 1
787 #define MDFLD_LIMT_DPLL_83 2
788 #define MDFLD_LIMT_DPLL_100 3
789 #define MDFLD_LIMT_DSIPLL_19 4
790 #define MDFLD_LIMT_DSIPLL_25 5
791 #define MDFLD_LIMT_DSIPLL_83 6
792 #define MDFLD_LIMT_DSIPLL_100 7
794 #define MDFLD_DOT_MIN 19750 /* FIXME_MDFLD JLIU7 need to find out min & max for MDFLD */
795 #define MDFLD_DOT_MAX 120000
796 #define MDFLD_DPLL_M_MIN_19 113
797 #define MDFLD_DPLL_M_MAX_19 155
798 #define MDFLD_DPLL_P1_MIN_19 2
799 #define MDFLD_DPLL_P1_MAX_19 10
800 #define MDFLD_DPLL_M_MIN_25 101
801 #define MDFLD_DPLL_M_MAX_25 130
802 #define MDFLD_DPLL_P1_MIN_25 2
803 #define MDFLD_DPLL_P1_MAX_25 10
804 #define MDFLD_DPLL_M_MIN_83 64
805 #define MDFLD_DPLL_M_MAX_83 64
806 #define MDFLD_DPLL_P1_MIN_83 2
807 #define MDFLD_DPLL_P1_MAX_83 2
808 #define MDFLD_DPLL_M_MIN_100 64
809 #define MDFLD_DPLL_M_MAX_100 64
810 #define MDFLD_DPLL_P1_MIN_100 2
811 #define MDFLD_DPLL_P1_MAX_100 2
812 #define MDFLD_DSIPLL_M_MIN_19 131
813 #define MDFLD_DSIPLL_M_MAX_19 175
814 #define MDFLD_DSIPLL_P1_MIN_19 3
815 #define MDFLD_DSIPLL_P1_MAX_19 8
816 #define MDFLD_DSIPLL_M_MIN_25 97
817 #define MDFLD_DSIPLL_M_MAX_25 140
818 #define MDFLD_DSIPLL_P1_MIN_25 3
819 #define MDFLD_DSIPLL_P1_MAX_25 9
820 #define MDFLD_DSIPLL_M_MIN_83 33
821 #define MDFLD_DSIPLL_M_MAX_83 92
822 #define MDFLD_DSIPLL_P1_MIN_83 2
823 #define MDFLD_DSIPLL_P1_MAX_83 3
824 #define MDFLD_DSIPLL_M_MIN_100 97
825 #define MDFLD_DSIPLL_M_MAX_100 140
826 #define MDFLD_DSIPLL_P1_MIN_100 3
827 #define MDFLD_DSIPLL_P1_MAX_100 9
829 static const struct mdfld_limit_t mdfld_limits[] = {
830 { /* MDFLD_LIMT_DPLL_19 */
831 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
832 .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
833 .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
835 { /* MDFLD_LIMT_DPLL_25 */
836 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
837 .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
838 .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
840 { /* MDFLD_LIMT_DPLL_83 */
841 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
842 .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
843 .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
845 { /* MDFLD_LIMT_DPLL_100 */
846 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
847 .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
848 .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
850 { /* MDFLD_LIMT_DSIPLL_19 */
851 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
852 .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
853 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
855 { /* MDFLD_LIMT_DSIPLL_25 */
856 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
857 .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
858 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
860 { /* MDFLD_LIMT_DSIPLL_83 */
861 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
862 .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
863 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
865 { /* MDFLD_LIMT_DSIPLL_100 */
866 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
867 .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
868 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
872 #define MDFLD_M_MIN 21
873 #define MDFLD_M_MAX 180
874 static const u32 mdfld_m_converts[] = {
875 /* M configuration table from 9-bit LFSR table */
876 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
877 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */
878 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
879 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
880 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
881 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
882 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
883 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
884 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
885 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
886 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
887 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
888 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
889 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
890 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
891 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
894 static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc)
896 const struct mdfld_limit_t *limit = NULL;
897 struct drm_device *dev = crtc->dev;
898 struct drm_psb_private *dev_priv = dev->dev_private;
900 if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
901 || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
902 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
903 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
904 else if (ksel == KSEL_BYPASS_25)
905 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
906 else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
907 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
908 else if ((ksel == KSEL_BYPASS_83_100) &&
909 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
910 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
911 } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
912 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
913 limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
914 else if (ksel == KSEL_BYPASS_25)
915 limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
916 else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
917 limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
918 else if ((ksel == KSEL_BYPASS_83_100) &&
919 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
920 limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
921 } else {
922 limit = NULL;
923 dev_err(dev->dev, "mdfld_limit Wrong display type.\n");
926 return limit;
929 /** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
930 static void mdfld_clock(int refclk, struct mdfld_intel_clock_t *clock)
932 clock->dot = (refclk * clock->m) / clock->p1;
936 * Returns a set of divisors for the desired target clock with the given refclk,
937 * or FALSE. Divisor values are the actual divisors for
939 static bool
940 mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
941 struct mdfld_intel_clock_t *best_clock)
943 struct mdfld_intel_clock_t clock;
944 const struct mdfld_limit_t *limit = mdfld_limit(crtc);
945 int err = target;
947 memset(best_clock, 0, sizeof(*best_clock));
949 for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
950 for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
951 clock.p1++) {
952 int this_err;
954 mdfld_clock(refclk, &clock);
956 this_err = abs(clock.dot - target);
957 if (this_err < err) {
958 *best_clock = clock;
959 err = this_err;
963 return err != target;
967 * Return the pipe currently connected to the panel fitter,
968 * or -1 if the panel fitter is not present or not in use
970 static int mdfld_panel_fitter_pipe(struct drm_device *dev)
972 u32 pfit_control;
974 pfit_control = REG_READ(PFIT_CONTROL);
976 /* See if the panel fitter is in use */
977 if ((pfit_control & PFIT_ENABLE) == 0)
978 return -1;
979 return (pfit_control >> 29) & 3;
982 static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
983 struct drm_display_mode *mode,
984 struct drm_display_mode *adjusted_mode,
985 int x, int y,
986 struct drm_framebuffer *old_fb)
988 struct drm_device *dev = crtc->dev;
989 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
990 struct drm_psb_private *dev_priv = dev->dev_private;
991 int pipe = psb_intel_crtc->pipe;
992 int fp_reg = MRST_FPA0;
993 int dpll_reg = MRST_DPLL_A;
994 int dspcntr_reg = DSPACNTR;
995 int pipeconf_reg = PIPEACONF;
996 int htot_reg = HTOTAL_A;
997 int hblank_reg = HBLANK_A;
998 int hsync_reg = HSYNC_A;
999 int vtot_reg = VTOTAL_A;
1000 int vblank_reg = VBLANK_A;
1001 int vsync_reg = VSYNC_A;
1002 int dspsize_reg = DSPASIZE;
1003 int dsppos_reg = DSPAPOS;
1004 int pipesrc_reg = PIPEASRC;
1005 u32 *pipeconf = &dev_priv->pipeconf;
1006 u32 *dspcntr = &dev_priv->dspcntr;
1007 int refclk = 0;
1008 int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0;
1009 struct mdfld_intel_clock_t clock;
1010 bool ok;
1011 u32 dpll = 0, fp = 0;
1012 bool is_crt = false, is_lvds = false, is_tv = false;
1013 bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
1014 struct drm_mode_config *mode_config = &dev->mode_config;
1015 struct psb_intel_output *psb_intel_output = NULL;
1016 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
1017 struct drm_encoder *encoder;
1018 struct drm_connector *connector;
1019 int timeout = 0;
1021 dev_dbg(dev->dev, "pipe = 0x%x \n", pipe);
1023 switch (pipe) {
1024 case 0:
1025 break;
1026 case 1:
1027 fp_reg = FPB0;
1028 dpll_reg = DPLL_B;
1029 dspcntr_reg = DSPBCNTR;
1030 pipeconf_reg = PIPEBCONF;
1031 htot_reg = HTOTAL_B;
1032 hblank_reg = HBLANK_B;
1033 hsync_reg = HSYNC_B;
1034 vtot_reg = VTOTAL_B;
1035 vblank_reg = VBLANK_B;
1036 vsync_reg = VSYNC_B;
1037 dspsize_reg = DSPBSIZE;
1038 dsppos_reg = DSPBPOS;
1039 pipesrc_reg = PIPEBSRC;
1040 pipeconf = &dev_priv->pipeconf1;
1041 dspcntr = &dev_priv->dspcntr1;
1042 fp_reg = MDFLD_DPLL_DIV0;
1043 dpll_reg = MDFLD_DPLL_B;
1044 break;
1045 case 2:
1046 dpll_reg = MRST_DPLL_A;
1047 dspcntr_reg = DSPCCNTR;
1048 pipeconf_reg = PIPECCONF;
1049 htot_reg = HTOTAL_C;
1050 hblank_reg = HBLANK_C;
1051 hsync_reg = HSYNC_C;
1052 vtot_reg = VTOTAL_C;
1053 vblank_reg = VBLANK_C;
1054 vsync_reg = VSYNC_C;
1055 dspsize_reg = DSPCSIZE;
1056 dsppos_reg = DSPCPOS;
1057 pipesrc_reg = PIPECSRC;
1058 pipeconf = &dev_priv->pipeconf2;
1059 dspcntr = &dev_priv->dspcntr2;
1060 break;
1061 default:
1062 DRM_ERROR("Illegal Pipe Number. \n");
1063 return 0;
1066 dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
1067 adjusted_mode->hdisplay);
1068 dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
1069 adjusted_mode->vdisplay);
1070 dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
1071 adjusted_mode->hsync_start);
1072 dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
1073 adjusted_mode->hsync_end);
1074 dev_dbg(dev->dev, "adjusted_htotal = %d\n",
1075 adjusted_mode->htotal);
1076 dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
1077 adjusted_mode->vsync_start);
1078 dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
1079 adjusted_mode->vsync_end);
1080 dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
1081 adjusted_mode->vtotal);
1082 dev_dbg(dev->dev, "adjusted_clock = %d\n",
1083 adjusted_mode->clock);
1084 dev_dbg(dev->dev, "hdisplay = %d\n",
1085 mode->hdisplay);
1086 dev_dbg(dev->dev, "vdisplay = %d\n",
1087 mode->vdisplay);
1089 if (!gma_power_begin(dev, true))
1090 return 0;
1092 memcpy(&psb_intel_crtc->saved_mode, mode, sizeof(struct drm_display_mode));
1093 memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, sizeof(struct drm_display_mode));
1095 list_for_each_entry(connector, &mode_config->connector_list, head) {
1096 if(!connector)
1097 continue;
1099 encoder = connector->encoder;
1101 if(!encoder)
1102 continue;
1104 if (encoder->crtc != crtc)
1105 continue;
1107 psb_intel_output = to_psb_intel_output(connector);
1109 dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type);
1111 switch (psb_intel_output->type) {
1112 case INTEL_OUTPUT_LVDS:
1113 is_lvds = true;
1114 break;
1115 case INTEL_OUTPUT_TVOUT:
1116 is_tv = true;
1117 break;
1118 case INTEL_OUTPUT_ANALOG:
1119 is_crt = true;
1120 break;
1121 case INTEL_OUTPUT_MIPI:
1122 is_mipi = true;
1123 break;
1124 case INTEL_OUTPUT_MIPI2:
1125 is_mipi2 = true;
1126 break;
1127 case INTEL_OUTPUT_HDMI:
1128 is_hdmi = true;
1129 break;
1133 /* Disable the VGA plane that we never use */
1134 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
1136 /* Disable the panel fitter if it was on our pipe */
1137 if (mdfld_panel_fitter_pipe(dev) == pipe)
1138 REG_WRITE(PFIT_CONTROL, 0);
1140 /* pipesrc and dspsize control the size that is scaled from,
1141 * which should always be the user's requested size.
1143 if (pipe == 1) {
1144 /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
1145 * width/height and souce image size registers with the adjusted mode for pipe B. */
1147 /* The defined sprite rectangle must always be completely contained within the displayable
1148 * area of the screen image (frame buffer). */
1149 REG_WRITE(dspsize_reg, ((MIN(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
1150 | (MIN(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
1151 /* Set the CRTC with encoder mode. */
1152 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
1153 | (mode->crtc_vdisplay - 1));
1154 } else {
1155 REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1));
1156 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
1159 REG_WRITE(dsppos_reg, 0);
1161 if (psb_intel_output)
1162 drm_connector_property_get_value(&psb_intel_output->base,
1163 dev->mode_config.scaling_mode_property, &scalingType);
1165 if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
1166 /*Moorestown doesn't have register support for centering so we need to
1167 mess with the h/vblank and h/vsync start and ends to get centering*/
1168 int offsetX = 0, offsetY = 0;
1170 offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
1171 offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
1173 REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
1174 ((adjusted_mode->crtc_htotal - 1) << 16));
1175 REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
1176 ((adjusted_mode->crtc_vtotal - 1) << 16));
1177 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) |
1178 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
1179 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) |
1180 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
1181 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) |
1182 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
1183 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) |
1184 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
1185 } else {
1186 REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
1187 ((adjusted_mode->crtc_htotal - 1) << 16));
1188 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
1189 ((adjusted_mode->crtc_vtotal - 1) << 16));
1190 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
1191 ((adjusted_mode->crtc_hblank_end - 1) << 16));
1192 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
1193 ((adjusted_mode->crtc_hsync_end - 1) << 16));
1194 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
1195 ((adjusted_mode->crtc_vblank_end - 1) << 16));
1196 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
1197 ((adjusted_mode->crtc_vsync_end - 1) << 16));
1200 /* Flush the plane changes */
1202 struct drm_crtc_helper_funcs *crtc_funcs =
1203 crtc->helper_private;
1204 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
1207 /* setup pipeconf */
1208 *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
1210 /* Set up the display plane register */
1211 *dspcntr = REG_READ(dspcntr_reg);
1212 *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
1213 *dspcntr |= DISPLAY_PLANE_ENABLE;
1214 /* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_BOTTOM; */
1215 /* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_GAMMA_ENABLE; */
1217 if (is_mipi2)
1219 goto mrst_crtc_mode_set_exit;
1221 /* FIXME JLIU7 Add MDFLD HDMI supports */
1222 /* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */
1223 /* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */
1224 clk = adjusted_mode->clock;
1226 if (is_hdmi) {
1227 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
1229 refclk = 19200;
1231 if (is_mipi || is_mipi2)
1233 clk_n = 1, clk_p2 = 8;
1234 } else if (is_hdmi) {
1235 clk_n = 1, clk_p2 = 10;
1237 } else if (ksel == KSEL_BYPASS_25) {
1238 refclk = 25000;
1240 if (is_mipi || is_mipi2)
1242 clk_n = 1, clk_p2 = 8;
1243 } else if (is_hdmi) {
1244 clk_n = 1, clk_p2 = 10;
1246 } else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) {
1247 refclk = 83000;
1249 if (is_mipi || is_mipi2)
1251 clk_n = 4, clk_p2 = 8;
1252 } else if (is_hdmi) {
1253 clk_n = 4, clk_p2 = 10;
1255 } else if ((ksel == KSEL_BYPASS_83_100) &&
1256 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) {
1257 refclk = 100000;
1258 if (is_mipi || is_mipi2)
1260 clk_n = 4, clk_p2 = 8;
1261 } else if (is_hdmi) {
1262 clk_n = 4, clk_p2 = 10;
1266 if (is_mipi)
1267 clk_byte = dev_priv->bpp / 8;
1268 else if (is_mipi2)
1269 clk_byte = dev_priv->bpp2 / 8;
1271 clk_tmp = clk * clk_n * clk_p2 * clk_byte;
1273 dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n, clk_p2);
1274 dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode->clock, clk_tmp);
1276 ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
1278 if (!ok) {
1279 dev_err(dev->dev,
1280 "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n");
1281 } else {
1282 m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
1284 dev_dbg(dev->dev, "dot clock = %d,"
1285 "m = %d, p1 = %d, m_conv = %d. \n", clock.dot, clock.m,
1286 clock.p1, m_conv);
1289 dpll = REG_READ(dpll_reg);
1291 if (dpll & DPLL_VCO_ENABLE) {
1292 dpll &= ~DPLL_VCO_ENABLE;
1293 REG_WRITE(dpll_reg, dpll);
1294 REG_READ(dpll_reg);
1296 /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
1297 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1298 udelay(500);
1300 /* reset M1, N1 & P1 */
1301 REG_WRITE(fp_reg, 0);
1302 dpll &= ~MDFLD_P1_MASK;
1303 REG_WRITE(dpll_reg, dpll);
1304 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1305 udelay(500);
1308 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
1309 if (dpll & MDFLD_PWR_GATE_EN) {
1310 dpll &= ~MDFLD_PWR_GATE_EN;
1311 REG_WRITE(dpll_reg, dpll);
1312 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1313 udelay(500);
1316 dpll = 0;
1318 #if 0 /* FIXME revisit later */
1319 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19) || (ksel == KSEL_BYPASS_25)) {
1320 dpll &= ~MDFLD_INPUT_REF_SEL;
1321 } else if (ksel == KSEL_BYPASS_83_100) {
1322 dpll |= MDFLD_INPUT_REF_SEL;
1324 #endif /* FIXME revisit later */
1326 if (is_hdmi)
1327 dpll |= MDFLD_VCO_SEL;
1329 fp = (clk_n / 2) << 16;
1330 fp |= m_conv;
1332 /* compute bitmask from p1 value */
1333 dpll |= (1 << (clock.p1 - 2)) << 17;
1335 #if 0 /* 1080p30 & 720p */
1336 dpll = 0x00050000;
1337 fp = 0x000001be;
1338 #endif
1339 #if 0 /* 480p */
1340 dpll = 0x02010000;
1341 fp = 0x000000d2;
1342 #endif
1343 } else {
1344 #if 0 /*DBI_TPO_480x864*/
1345 dpll = 0x00020000;
1346 fp = 0x00000156;
1347 #endif /* DBI_TPO_480x864 */ /* get from spec. */
1349 dpll = 0x00800000;
1350 fp = 0x000000c1;
1353 REG_WRITE(fp_reg, fp);
1354 REG_WRITE(dpll_reg, dpll);
1355 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1356 udelay(500);
1358 dpll |= DPLL_VCO_ENABLE;
1359 REG_WRITE(dpll_reg, dpll);
1360 REG_READ(dpll_reg);
1362 /* wait for DSI PLL to lock */
1363 while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
1364 udelay(150);
1365 timeout ++;
1368 if (is_mipi)
1369 goto mrst_crtc_mode_set_exit;
1371 dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi);
1373 REG_WRITE(pipeconf_reg, *pipeconf);
1374 REG_READ(pipeconf_reg);
1376 /* Wait for for the pipe enable to take effect. */
1377 //FIXME_JLIU7 HDMI mrstWaitForPipeEnable(dev);
1379 REG_WRITE(dspcntr_reg, *dspcntr);
1380 psb_intel_wait_for_vblank(dev);
1382 mrst_crtc_mode_set_exit:
1384 gma_power_end(dev);
1386 return 0;
1389 static void mdfld_crtc_prepare(struct drm_crtc *crtc)
1391 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1392 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
1395 static void mdfld_crtc_commit(struct drm_crtc *crtc)
1397 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1398 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1401 static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc,
1402 struct drm_display_mode *mode,
1403 struct drm_display_mode *adjusted_mode)
1405 return true;
1408 const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
1409 .dpms = mdfld_crtc_dpms,
1410 .mode_fixup = mdfld_crtc_mode_fixup,
1411 .mode_set = mdfld_crtc_mode_set,
1412 .mode_set_base = mdfld__intel_pipe_set_base,
1413 .prepare = mdfld_crtc_prepare,
1414 .commit = mdfld_crtc_commit,