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