gma500: Clean up the DPU config and make it runtime
[linux-2.6/x86.git] / drivers / staging / gma500 / mdfld_intel_display.c
blobaa2ff559383d1b17dacdf298038526185dacb087
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 "framebuffer.h"
28 #include "psb_intel_display.h"
29 #include "mdfld_dsi_dbi.h"
30 #include "mdfld_dsi_dpi.h"
31 #include "mdfld_dsi_dbi_dpu.h"
33 #include <linux/pm_runtime.h>
35 #ifdef MIN
36 #undef MIN
37 #endif
39 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
41 /* Hardcoded currently */
42 static int ksel = KSEL_CRYSTAL_19;
44 extern void mdfld_save_display(struct drm_device *dev);
45 extern bool gbgfxsuspended;
47 struct psb_intel_range_t {
48 int min, max;
51 struct mdfld_limit_t {
52 struct psb_intel_range_t dot, m, p1;
55 struct mdfld_intel_clock_t {
56 /* given values */
57 int n;
58 int m1, m2;
59 int p1, p2;
60 /* derived values */
61 int dot;
62 int vco;
63 int m;
64 int p;
69 #define COUNT_MAX 0x10000000
71 void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
73 int count, temp;
74 u32 pipeconf_reg = PIPEACONF;
76 switch (pipe) {
77 case 0:
78 break;
79 case 1:
80 pipeconf_reg = PIPEBCONF;
81 break;
82 case 2:
83 pipeconf_reg = PIPECCONF;
84 break;
85 default:
86 DRM_ERROR("Illegal Pipe Number. \n");
87 return;
90 /* FIXME JLIU7_PO */
91 psb_intel_wait_for_vblank(dev);
92 return;
94 /* Wait for for the pipe disable to take effect. */
95 for (count = 0; count < COUNT_MAX; count++) {
96 temp = REG_READ(pipeconf_reg);
97 if ((temp & PIPEACONF_PIPE_STATE) == 0)
98 break;
102 void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
104 int count, temp;
105 u32 pipeconf_reg = PIPEACONF;
107 switch (pipe) {
108 case 0:
109 break;
110 case 1:
111 pipeconf_reg = PIPEBCONF;
112 break;
113 case 2:
114 pipeconf_reg = PIPECCONF;
115 break;
116 default:
117 dev_err(dev->dev, "Illegal Pipe Number.\n");
118 return;
121 /* FIXME JLIU7_PO */
122 psb_intel_wait_for_vblank(dev);
123 return;
125 /* Wait for for the pipe enable to take effect. */
126 for (count = 0; count < COUNT_MAX; count++) {
127 temp = REG_READ(pipeconf_reg);
128 if ((temp & PIPEACONF_PIPE_STATE) == 1)
129 break;
134 static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
135 struct drm_file *file_priv,
136 uint32_t handle,
137 uint32_t width, uint32_t height)
139 struct drm_device *dev = crtc->dev;
140 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
141 int pipe = psb_intel_crtc->pipe;
142 uint32_t control = CURACNTR;
143 uint32_t base = CURABASE;
144 uint32_t temp;
145 size_t addr = 0;
146 struct gtt_range *gt;
147 struct drm_gem_object *obj;
148 int ret;
150 switch (pipe) {
151 case 0:
152 break;
153 case 1:
154 control = CURBCNTR;
155 base = CURBBASE;
156 break;
157 case 2:
158 control = CURCCNTR;
159 base = CURCBASE;
160 break;
161 default:
162 dev_err(dev->dev, "Illegal Pipe Number. \n");
163 return -EINVAL;
166 #if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
167 if (pipe != 0)
168 return 0;
169 #endif
170 /* if we want to turn of the cursor ignore width and height */
171 if (!handle) {
172 dev_dbg(dev->dev, "cursor off\n");
173 /* turn off the cursor */
174 temp = 0;
175 temp |= CURSOR_MODE_DISABLE;
177 if (gma_power_begin(dev, true)) {
178 REG_WRITE(control, temp);
179 REG_WRITE(base, 0);
180 gma_power_end(dev);
182 /* Unpin the old GEM object */
183 if (psb_intel_crtc->cursor_obj) {
184 gt = container_of(psb_intel_crtc->cursor_obj,
185 struct gtt_range, gem);
186 psb_gtt_unpin(gt);
187 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
188 psb_intel_crtc->cursor_obj = NULL;
190 return 0;
193 /* Currently we only support 64x64 cursors */
194 if (width != 64 || height != 64) {
195 DRM_ERROR("we currently only support 64x64 cursors\n");
196 return -EINVAL;
199 obj = drm_gem_object_lookup(dev, file_priv, handle);
200 if (!obj)
201 return -ENOENT;
203 if (obj->size < width * height * 4) {
204 dev_dbg(dev->dev, "buffer is to small\n");
205 return -ENOMEM;
208 gt = container_of(obj, struct gtt_range, gem);
210 /* Pin the memory into the GTT */
211 ret = psb_gtt_pin(gt);
212 if (ret) {
213 dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
214 return ret;
218 addr = gt->offset; /* Or resource.start ??? */
220 psb_intel_crtc->cursor_addr = addr;
222 temp = 0;
223 /* set the pipe for the cursor */
224 temp |= (pipe << 28);
225 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
227 if (gma_power_begin(dev, true)) {
228 REG_WRITE(control, temp);
229 REG_WRITE(base, addr);
230 gma_power_end(dev);
232 /* unpin the old GEM object */
233 if (psb_intel_crtc->cursor_obj) {
234 gt = container_of(psb_intel_crtc->cursor_obj,
235 struct gtt_range, gem);
236 psb_gtt_unpin(gt);
237 drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
238 psb_intel_crtc->cursor_obj = obj;
240 return 0;
243 static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
245 struct drm_device *dev = crtc->dev;
246 struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
247 struct mdfld_dbi_dpu_info *dpu_info = dev_priv->dbi_dpu_info;
248 struct psb_drm_dpu_rect rect;
249 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
250 int pipe = psb_intel_crtc->pipe;
251 uint32_t pos = CURAPOS;
252 uint32_t base = CURABASE;
253 uint32_t temp = 0;
254 uint32_t addr;
256 switch (pipe) {
257 case 0:
258 if (dpu_info) {
259 rect.x = x;
260 rect.y = y;
262 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect);
263 mdfld_dpu_exit_dsr(dev);
264 } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
265 mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_0);
266 break;
267 case 1:
268 pos = CURBPOS;
269 base = CURBBASE;
270 break;
271 case 2:
272 if (dpu_info) {
273 mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
274 mdfld_dpu_exit_dsr(dev);
275 } else if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
276 mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_CURSOR_2);
277 pos = CURCPOS;
278 base = CURCBASE;
279 break;
280 default:
281 DRM_ERROR("Illegal Pipe Number. \n");
282 return -EINVAL;
285 #if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
286 if (pipe != 0)
287 return 0;
288 #endif
289 if (x < 0) {
290 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
291 x = -x;
293 if (y < 0) {
294 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
295 y = -y;
298 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
299 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
301 addr = psb_intel_crtc->cursor_addr;
303 if (gma_power_begin(dev, true)) {
304 REG_WRITE(pos, temp);
305 REG_WRITE(base, addr);
306 gma_power_end(dev);
309 return 0;
312 const struct drm_crtc_funcs mdfld_intel_crtc_funcs = {
313 .cursor_set = mdfld_intel_crtc_cursor_set,
314 .cursor_move = mdfld_intel_crtc_cursor_move,
315 .gamma_set = psb_intel_crtc_gamma_set,
316 .set_config = drm_crtc_helper_set_config,
317 .destroy = psb_intel_crtc_destroy,
320 static struct drm_device globle_dev;
322 void mdfld__intel_plane_set_alpha(int enable)
324 struct drm_device *dev = &globle_dev;
325 int dspcntr_reg = DSPACNTR;
326 u32 dspcntr;
328 dspcntr = REG_READ(dspcntr_reg);
330 if (enable) {
331 dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
332 dspcntr |= DISPPLANE_32BPP;
333 } else {
334 dspcntr &= ~DISPPLANE_32BPP;
335 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
338 REG_WRITE(dspcntr_reg, dspcntr);
341 int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb)
343 struct drm_device *dev = crtc->dev;
344 /* struct drm_i915_master_private *master_priv; */
345 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
346 struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
347 int pipe = psb_intel_crtc->pipe;
348 unsigned long start, offset;
349 int dsplinoff = DSPALINOFF;
350 int dspsurf = DSPASURF;
351 int dspstride = DSPASTRIDE;
352 int dspcntr_reg = DSPACNTR;
353 u32 dspcntr;
354 int ret = 0;
356 memcpy(&globle_dev, dev, sizeof(struct drm_device));
358 if (!gma_power_begin(dev, true))
359 return 0;
361 /* no fb bound */
362 if (!crtc->fb) {
363 dev_err(dev->dev, "No FB bound\n");
364 goto psb_intel_pipe_cleaner;
367 switch (pipe) {
368 case 0:
369 dsplinoff = DSPALINOFF;
370 break;
371 case 1:
372 dsplinoff = DSPBLINOFF;
373 dspsurf = DSPBSURF;
374 dspstride = DSPBSTRIDE;
375 dspcntr_reg = DSPBCNTR;
376 break;
377 case 2:
378 dsplinoff = DSPCLINOFF;
379 dspsurf = DSPCSURF;
380 dspstride = DSPCSTRIDE;
381 dspcntr_reg = DSPCCNTR;
382 break;
383 default:
384 dev_err(dev->dev, "Illegal Pipe Number.\n");
385 return -EINVAL;
388 ret = psb_gtt_pin(psbfb->gtt);
389 if (ret < 0)
390 goto psb_intel_pipe_set_base_exit;
392 start = psbfb->gtt->offset;
393 offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
395 REG_WRITE(dspstride, crtc->fb->pitch);
396 dspcntr = REG_READ(dspcntr_reg);
397 dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
399 switch (crtc->fb->bits_per_pixel) {
400 case 8:
401 dspcntr |= DISPPLANE_8BPP;
402 break;
403 case 16:
404 if (crtc->fb->depth == 15)
405 dspcntr |= DISPPLANE_15_16BPP;
406 else
407 dspcntr |= DISPPLANE_16BPP;
408 break;
409 case 24:
410 case 32:
411 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
412 break;
413 default:
414 dev_err(dev->dev, "Unknown color depth\n");
415 ret = -EINVAL;
416 goto psb_intel_pipe_set_base_exit;
418 REG_WRITE(dspcntr_reg, dspcntr);
420 dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
421 start, offset, x, y);
423 REG_WRITE(dsplinoff, offset);
424 REG_READ(dsplinoff);
425 REG_WRITE(dspsurf, start);
426 REG_READ(dspsurf);
428 psb_intel_pipe_cleaner:
429 /* If there was a previous display we can now unpin it */
430 if (old_fb)
431 psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
433 psb_intel_pipe_set_base_exit:
434 gma_power_end(dev);
435 return ret;
439 * Disable the pipe, plane and pll.
442 void mdfld_disable_crtc (struct drm_device *dev, int pipe)
444 int dpll_reg = MRST_DPLL_A;
445 int dspcntr_reg = DSPACNTR;
446 int dspbase_reg = MRST_DSPABASE;
447 int pipeconf_reg = PIPEACONF;
448 u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
449 u32 temp;
451 switch (pipe) {
452 case 0:
453 break;
454 case 1:
455 dpll_reg = MDFLD_DPLL_B;
456 dspcntr_reg = DSPBCNTR;
457 dspbase_reg = DSPBSURF;
458 pipeconf_reg = PIPEBCONF;
459 break;
460 case 2:
461 dpll_reg = MRST_DPLL_A;
462 dspcntr_reg = DSPCCNTR;
463 dspbase_reg = MDFLD_DSPCBASE;
464 pipeconf_reg = PIPECCONF;
465 gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
466 break;
467 default:
468 dev_err(dev->dev, "Illegal Pipe Number. \n");
469 return;
472 if (pipe != 1)
473 mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
475 /* Disable display plane */
476 temp = REG_READ(dspcntr_reg);
477 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
478 REG_WRITE(dspcntr_reg,
479 temp & ~DISPLAY_PLANE_ENABLE);
480 /* Flush the plane changes */
481 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
482 REG_READ(dspbase_reg);
485 /* FIXME_JLIU7 MDFLD_PO revisit */
486 /* Wait for vblank for the disable to take effect */
487 // MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
489 /* Next, disable display pipes */
490 temp = REG_READ(pipeconf_reg);
491 if ((temp & PIPEACONF_ENABLE) != 0) {
492 temp &= ~PIPEACONF_ENABLE;
493 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
494 REG_WRITE(pipeconf_reg, temp);
495 REG_READ(pipeconf_reg);
497 /* Wait for for the pipe disable to take effect. */
498 mdfldWaitForPipeDisable(dev, pipe);
501 temp = REG_READ(dpll_reg);
502 if (temp & DPLL_VCO_ENABLE) {
503 if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
504 || (pipe == 1)){
505 temp &= ~(DPLL_VCO_ENABLE);
506 REG_WRITE(dpll_reg, temp);
507 REG_READ(dpll_reg);
508 /* Wait for the clocks to turn off. */
509 /* FIXME_MDFLD PO may need more delay */
510 udelay(500);
512 if (!(temp & MDFLD_PWR_GATE_EN)) {
513 /* gating power of DPLL */
514 REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
515 /* FIXME_MDFLD PO - change 500 to 1 after PO */
516 udelay(5000);
524 * Sets the power management mode of the pipe and plane.
526 * This code should probably grow support for turning the cursor off and back
527 * on appropriately at the same time as we're turning the pipe off/on.
529 static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
531 struct drm_device *dev = crtc->dev;
532 struct drm_psb_private *dev_priv = dev->dev_private;
533 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
534 int pipe = psb_intel_crtc->pipe;
535 int dpll_reg = MRST_DPLL_A;
536 int dspcntr_reg = DSPACNTR;
537 int dspbase_reg = MRST_DSPABASE;
538 int pipeconf_reg = PIPEACONF;
539 u32 pipestat_reg = PIPEASTAT;
540 u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
541 u32 pipeconf = dev_priv->pipeconf;
542 u32 dspcntr = dev_priv->dspcntr;
543 u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG;
544 u32 temp;
545 bool enabled;
546 int timeout = 0;
548 if (!gma_power_begin(dev, true))
549 return;
551 /* Ignore if system is already in DSR and in suspended state. */
552 if(/*gbgfxsuspended */0 && dev_priv->dispstatus == false && mode == 3){
553 if(dev_priv->rpm_enabled && pipe == 1){
554 // dev_priv->is_mipi_on = false;
555 pm_request_idle(&dev->pdev->dev);
557 return;
558 }else if(mode == 0) {
559 //do not need to set gbdispstatus=true in crtc.
560 //this will be set in encoder such as mdfld_dsi_dbi_dpms
561 //gbdispstatus = true;
565 /* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
566 /* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
568 switch (pipe) {
569 case 0:
570 break;
571 case 1:
572 dpll_reg = DPLL_B;
573 dspcntr_reg = DSPBCNTR;
574 dspbase_reg = MRST_DSPBBASE;
575 pipeconf_reg = PIPEBCONF;
576 pipeconf = dev_priv->pipeconf1;
577 dspcntr = dev_priv->dspcntr1;
578 dpll_reg = MDFLD_DPLL_B;
579 break;
580 case 2:
581 dpll_reg = MRST_DPLL_A;
582 dspcntr_reg = DSPCCNTR;
583 dspbase_reg = MDFLD_DSPCBASE;
584 pipeconf_reg = PIPECCONF;
585 pipestat_reg = PIPECSTAT;
586 pipeconf = dev_priv->pipeconf2;
587 dspcntr = dev_priv->dspcntr2;
588 gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
589 mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET;
590 break;
591 default:
592 dev_err(dev->dev, "Illegal Pipe Number.\n");
593 return;
596 /* XXX: When our outputs are all unaware of DPMS modes other than off
597 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
599 switch (mode) {
600 case DRM_MODE_DPMS_ON:
601 case DRM_MODE_DPMS_STANDBY:
602 case DRM_MODE_DPMS_SUSPEND:
603 /* Enable the DPLL */
604 temp = REG_READ(dpll_reg);
606 if ((temp & DPLL_VCO_ENABLE) == 0) {
607 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
608 if (temp & MDFLD_PWR_GATE_EN) {
609 temp &= ~MDFLD_PWR_GATE_EN;
610 REG_WRITE(dpll_reg, temp);
611 /* FIXME_MDFLD PO - change 500 to 1 after PO */
612 udelay(500);
615 REG_WRITE(dpll_reg, temp);
616 REG_READ(dpll_reg);
617 /* FIXME_MDFLD PO - change 500 to 1 after PO */
618 udelay(500);
620 REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
621 REG_READ(dpll_reg);
624 * wait for DSI PLL to lock
625 * NOTE: only need to poll status of pipe 0 and pipe 1,
626 * since both MIPI pipes share the same PLL.
628 while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
629 udelay(150);
630 timeout ++;
634 /* Enable the plane */
635 temp = REG_READ(dspcntr_reg);
636 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
637 REG_WRITE(dspcntr_reg,
638 temp | DISPLAY_PLANE_ENABLE);
639 /* Flush the plane changes */
640 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
643 /* Enable the pipe */
644 temp = REG_READ(pipeconf_reg);
645 if ((temp & PIPEACONF_ENABLE) == 0) {
646 REG_WRITE(pipeconf_reg, pipeconf);
648 /* Wait for for the pipe enable to take effect. */
649 mdfldWaitForPipeEnable(dev, pipe);
652 /*workaround for sighting 3741701 Random X blank display*/
653 /*perform w/a in video mode only on pipe A or C*/
654 if ((pipe == 0 || pipe == 2) &&
655 (mdfld_panel_dpi(dev) == true)) {
656 REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
657 msleep(100);
658 if(PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) {
659 printk(KERN_ALERT "OK");
660 } else {
661 printk(KERN_ALERT "STUCK!!!!");
662 /*shutdown controller*/
663 temp = REG_READ(dspcntr_reg);
664 REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
665 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
666 /*mdfld_dsi_dpi_shut_down(dev, pipe);*/
667 REG_WRITE(0xb048, 1);
668 msleep(100);
669 temp = REG_READ(pipeconf_reg);
670 temp &= ~PIPEACONF_ENABLE;
671 REG_WRITE(pipeconf_reg, temp);
672 msleep(100); /*wait for pipe disable*/
673 /*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
674 printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/
675 REG_WRITE(mipi_enable_reg, 0);
676 msleep(100);
677 printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
678 printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));
679 REG_WRITE(0xb004, REG_READ(0xb004));
680 /* try to bring the controller back up again*/
681 REG_WRITE(mipi_enable_reg, 1);
682 temp = REG_READ(dspcntr_reg);
683 REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
684 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
685 /*mdfld_dsi_dpi_turn_on(dev, pipe);*/
686 REG_WRITE(0xb048, 2);
687 msleep(100);
688 temp = REG_READ(pipeconf_reg);
689 temp |= PIPEACONF_ENABLE;
690 REG_WRITE(pipeconf_reg, temp);
694 psb_intel_crtc_load_lut(crtc);
696 /* Give the overlay scaler a chance to enable
697 if it's on this pipe */
698 /* psb_intel_crtc_dpms_video(crtc, true); TODO */
700 break;
701 case DRM_MODE_DPMS_OFF:
702 /* Give the overlay scaler a chance to disable
703 * if it's on this pipe */
704 /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
705 if (pipe != 1)
706 mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
708 /* Disable the VGA plane that we never use */
709 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
711 /* Disable display plane */
712 temp = REG_READ(dspcntr_reg);
713 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
714 REG_WRITE(dspcntr_reg,
715 temp & ~DISPLAY_PLANE_ENABLE);
716 /* Flush the plane changes */
717 REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
718 REG_READ(dspbase_reg);
721 /* FIXME_JLIU7 MDFLD_PO revisit */
722 /* Wait for vblank for the disable to take effect */
723 // MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
725 /* Next, disable display pipes */
726 temp = REG_READ(pipeconf_reg);
727 if ((temp & PIPEACONF_ENABLE) != 0) {
728 temp &= ~PIPEACONF_ENABLE;
729 temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
730 REG_WRITE(pipeconf_reg, temp);
731 // REG_WRITE(pipeconf_reg, 0);
732 REG_READ(pipeconf_reg);
734 /* Wait for for the pipe disable to take effect. */
735 mdfldWaitForPipeDisable(dev, pipe);
738 temp = REG_READ(dpll_reg);
739 if (temp & DPLL_VCO_ENABLE) {
740 if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
741 || (pipe == 1)){
742 temp &= ~(DPLL_VCO_ENABLE);
743 REG_WRITE(dpll_reg, temp);
744 REG_READ(dpll_reg);
745 /* Wait for the clocks to turn off. */
746 /* FIXME_MDFLD PO may need more delay */
747 udelay(500);
748 #if 0 /* MDFLD_PO_JLIU7 */
749 if (!(temp & MDFLD_PWR_GATE_EN)) {
750 /* gating power of DPLL */
751 REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
752 /* FIXME_MDFLD PO - change 500 to 1 after PO */
753 udelay(5000);
755 #endif /* MDFLD_PO_JLIU7 */
758 break;
761 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
763 #if 0 /* JB: Add vblank support later */
764 if (enabled)
765 dev_priv->vblank_pipe |= (1 << pipe);
766 else
767 dev_priv->vblank_pipe &= ~(1 << pipe);
768 #endif
770 gma_power_end(dev);
774 #define MDFLD_LIMT_DPLL_19 0
775 #define MDFLD_LIMT_DPLL_25 1
776 #define MDFLD_LIMT_DPLL_83 2
777 #define MDFLD_LIMT_DPLL_100 3
778 #define MDFLD_LIMT_DSIPLL_19 4
779 #define MDFLD_LIMT_DSIPLL_25 5
780 #define MDFLD_LIMT_DSIPLL_83 6
781 #define MDFLD_LIMT_DSIPLL_100 7
783 #define MDFLD_DOT_MIN 19750 /* FIXME_MDFLD JLIU7 need to find out min & max for MDFLD */
784 #define MDFLD_DOT_MAX 120000
785 #define MDFLD_DPLL_M_MIN_19 113
786 #define MDFLD_DPLL_M_MAX_19 155
787 #define MDFLD_DPLL_P1_MIN_19 2
788 #define MDFLD_DPLL_P1_MAX_19 10
789 #define MDFLD_DPLL_M_MIN_25 101
790 #define MDFLD_DPLL_M_MAX_25 130
791 #define MDFLD_DPLL_P1_MIN_25 2
792 #define MDFLD_DPLL_P1_MAX_25 10
793 #define MDFLD_DPLL_M_MIN_83 64
794 #define MDFLD_DPLL_M_MAX_83 64
795 #define MDFLD_DPLL_P1_MIN_83 2
796 #define MDFLD_DPLL_P1_MAX_83 2
797 #define MDFLD_DPLL_M_MIN_100 64
798 #define MDFLD_DPLL_M_MAX_100 64
799 #define MDFLD_DPLL_P1_MIN_100 2
800 #define MDFLD_DPLL_P1_MAX_100 2
801 #define MDFLD_DSIPLL_M_MIN_19 131
802 #define MDFLD_DSIPLL_M_MAX_19 175
803 #define MDFLD_DSIPLL_P1_MIN_19 3
804 #define MDFLD_DSIPLL_P1_MAX_19 8
805 #define MDFLD_DSIPLL_M_MIN_25 97
806 #define MDFLD_DSIPLL_M_MAX_25 140
807 #define MDFLD_DSIPLL_P1_MIN_25 3
808 #define MDFLD_DSIPLL_P1_MAX_25 9
809 #define MDFLD_DSIPLL_M_MIN_83 33
810 #define MDFLD_DSIPLL_M_MAX_83 92
811 #define MDFLD_DSIPLL_P1_MIN_83 2
812 #define MDFLD_DSIPLL_P1_MAX_83 3
813 #define MDFLD_DSIPLL_M_MIN_100 97
814 #define MDFLD_DSIPLL_M_MAX_100 140
815 #define MDFLD_DSIPLL_P1_MIN_100 3
816 #define MDFLD_DSIPLL_P1_MAX_100 9
818 static const struct mdfld_limit_t mdfld_limits[] = {
819 { /* MDFLD_LIMT_DPLL_19 */
820 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
821 .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
822 .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
824 { /* MDFLD_LIMT_DPLL_25 */
825 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
826 .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
827 .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
829 { /* MDFLD_LIMT_DPLL_83 */
830 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
831 .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
832 .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
834 { /* MDFLD_LIMT_DPLL_100 */
835 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
836 .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
837 .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
839 { /* MDFLD_LIMT_DSIPLL_19 */
840 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
841 .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
842 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
844 { /* MDFLD_LIMT_DSIPLL_25 */
845 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
846 .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
847 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
849 { /* MDFLD_LIMT_DSIPLL_83 */
850 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
851 .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
852 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
854 { /* MDFLD_LIMT_DSIPLL_100 */
855 .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
856 .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
857 .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
861 #define MDFLD_M_MIN 21
862 #define MDFLD_M_MAX 180
863 static const u32 mdfld_m_converts[] = {
864 /* M configuration table from 9-bit LFSR table */
865 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
866 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */
867 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
868 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
869 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
870 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
871 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
872 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
873 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
874 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
875 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
876 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
877 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
878 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
879 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
880 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
883 static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc)
885 const struct mdfld_limit_t *limit = NULL;
886 struct drm_device *dev = crtc->dev;
887 struct drm_psb_private *dev_priv = dev->dev_private;
889 if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
890 || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
891 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
892 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
893 else if (ksel == KSEL_BYPASS_25)
894 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
895 else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
896 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
897 else if ((ksel == KSEL_BYPASS_83_100) &&
898 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
899 limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
900 } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
901 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
902 limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
903 else if (ksel == KSEL_BYPASS_25)
904 limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
905 else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
906 limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
907 else if ((ksel == KSEL_BYPASS_83_100) &&
908 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
909 limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
910 } else {
911 limit = NULL;
912 dev_err(dev->dev, "mdfld_limit Wrong display type.\n");
915 return limit;
918 /** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
919 static void mdfld_clock(int refclk, struct mdfld_intel_clock_t *clock)
921 clock->dot = (refclk * clock->m) / clock->p1;
925 * Returns a set of divisors for the desired target clock with the given refclk,
926 * or FALSE. Divisor values are the actual divisors for
928 static bool
929 mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
930 struct mdfld_intel_clock_t *best_clock)
932 struct mdfld_intel_clock_t clock;
933 const struct mdfld_limit_t *limit = mdfld_limit(crtc);
934 int err = target;
936 memset(best_clock, 0, sizeof(*best_clock));
938 for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
939 for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
940 clock.p1++) {
941 int this_err;
943 mdfld_clock(refclk, &clock);
945 this_err = abs(clock.dot - target);
946 if (this_err < err) {
947 *best_clock = clock;
948 err = this_err;
952 return err != target;
956 * Return the pipe currently connected to the panel fitter,
957 * or -1 if the panel fitter is not present or not in use
959 static int mdfld_panel_fitter_pipe(struct drm_device *dev)
961 u32 pfit_control;
963 pfit_control = REG_READ(PFIT_CONTROL);
965 /* See if the panel fitter is in use */
966 if ((pfit_control & PFIT_ENABLE) == 0)
967 return -1;
968 return (pfit_control >> 29) & 3;
971 static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
972 struct drm_display_mode *mode,
973 struct drm_display_mode *adjusted_mode,
974 int x, int y,
975 struct drm_framebuffer *old_fb)
977 struct drm_device *dev = crtc->dev;
978 struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
979 struct drm_psb_private *dev_priv = dev->dev_private;
980 int pipe = psb_intel_crtc->pipe;
981 int fp_reg = MRST_FPA0;
982 int dpll_reg = MRST_DPLL_A;
983 int dspcntr_reg = DSPACNTR;
984 int pipeconf_reg = PIPEACONF;
985 int htot_reg = HTOTAL_A;
986 int hblank_reg = HBLANK_A;
987 int hsync_reg = HSYNC_A;
988 int vtot_reg = VTOTAL_A;
989 int vblank_reg = VBLANK_A;
990 int vsync_reg = VSYNC_A;
991 int dspsize_reg = DSPASIZE;
992 int dsppos_reg = DSPAPOS;
993 int pipesrc_reg = PIPEASRC;
994 u32 *pipeconf = &dev_priv->pipeconf;
995 u32 *dspcntr = &dev_priv->dspcntr;
996 int refclk = 0;
997 int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0;
998 struct mdfld_intel_clock_t clock;
999 bool ok;
1000 u32 dpll = 0, fp = 0;
1001 bool is_crt = false, is_lvds = false, is_tv = false;
1002 bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
1003 struct drm_mode_config *mode_config = &dev->mode_config;
1004 struct psb_intel_output *psb_intel_output = NULL;
1005 uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
1006 struct drm_encoder *encoder;
1007 struct drm_connector *connector;
1008 int timeout = 0;
1010 dev_dbg(dev->dev, "pipe = 0x%x \n", pipe);
1012 switch (pipe) {
1013 case 0:
1014 break;
1015 case 1:
1016 fp_reg = FPB0;
1017 dpll_reg = DPLL_B;
1018 dspcntr_reg = DSPBCNTR;
1019 pipeconf_reg = PIPEBCONF;
1020 htot_reg = HTOTAL_B;
1021 hblank_reg = HBLANK_B;
1022 hsync_reg = HSYNC_B;
1023 vtot_reg = VTOTAL_B;
1024 vblank_reg = VBLANK_B;
1025 vsync_reg = VSYNC_B;
1026 dspsize_reg = DSPBSIZE;
1027 dsppos_reg = DSPBPOS;
1028 pipesrc_reg = PIPEBSRC;
1029 pipeconf = &dev_priv->pipeconf1;
1030 dspcntr = &dev_priv->dspcntr1;
1031 fp_reg = MDFLD_DPLL_DIV0;
1032 dpll_reg = MDFLD_DPLL_B;
1033 break;
1034 case 2:
1035 dpll_reg = MRST_DPLL_A;
1036 dspcntr_reg = DSPCCNTR;
1037 pipeconf_reg = PIPECCONF;
1038 htot_reg = HTOTAL_C;
1039 hblank_reg = HBLANK_C;
1040 hsync_reg = HSYNC_C;
1041 vtot_reg = VTOTAL_C;
1042 vblank_reg = VBLANK_C;
1043 vsync_reg = VSYNC_C;
1044 dspsize_reg = DSPCSIZE;
1045 dsppos_reg = DSPCPOS;
1046 pipesrc_reg = PIPECSRC;
1047 pipeconf = &dev_priv->pipeconf2;
1048 dspcntr = &dev_priv->dspcntr2;
1049 break;
1050 default:
1051 DRM_ERROR("Illegal Pipe Number. \n");
1052 return 0;
1055 dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
1056 adjusted_mode->hdisplay);
1057 dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
1058 adjusted_mode->vdisplay);
1059 dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
1060 adjusted_mode->hsync_start);
1061 dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
1062 adjusted_mode->hsync_end);
1063 dev_dbg(dev->dev, "adjusted_htotal = %d\n",
1064 adjusted_mode->htotal);
1065 dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
1066 adjusted_mode->vsync_start);
1067 dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
1068 adjusted_mode->vsync_end);
1069 dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
1070 adjusted_mode->vtotal);
1071 dev_dbg(dev->dev, "adjusted_clock = %d\n",
1072 adjusted_mode->clock);
1073 dev_dbg(dev->dev, "hdisplay = %d\n",
1074 mode->hdisplay);
1075 dev_dbg(dev->dev, "vdisplay = %d\n",
1076 mode->vdisplay);
1078 if (!gma_power_begin(dev, true))
1079 return 0;
1081 memcpy(&psb_intel_crtc->saved_mode, mode, sizeof(struct drm_display_mode));
1082 memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, sizeof(struct drm_display_mode));
1084 list_for_each_entry(connector, &mode_config->connector_list, head) {
1086 encoder = connector->encoder;
1088 if(!encoder)
1089 continue;
1091 if (encoder->crtc != crtc)
1092 continue;
1094 psb_intel_output = to_psb_intel_output(connector);
1096 dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type);
1098 switch (psb_intel_output->type) {
1099 case INTEL_OUTPUT_LVDS:
1100 is_lvds = true;
1101 break;
1102 case INTEL_OUTPUT_TVOUT:
1103 is_tv = true;
1104 break;
1105 case INTEL_OUTPUT_ANALOG:
1106 is_crt = true;
1107 break;
1108 case INTEL_OUTPUT_MIPI:
1109 is_mipi = true;
1110 break;
1111 case INTEL_OUTPUT_MIPI2:
1112 is_mipi2 = true;
1113 break;
1114 case INTEL_OUTPUT_HDMI:
1115 is_hdmi = true;
1116 break;
1120 /* Disable the VGA plane that we never use */
1121 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
1123 /* Disable the panel fitter if it was on our pipe */
1124 if (mdfld_panel_fitter_pipe(dev) == pipe)
1125 REG_WRITE(PFIT_CONTROL, 0);
1127 /* pipesrc and dspsize control the size that is scaled from,
1128 * which should always be the user's requested size.
1130 if (pipe == 1) {
1131 /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
1132 * width/height and souce image size registers with the adjusted mode for pipe B. */
1134 /* The defined sprite rectangle must always be completely contained within the displayable
1135 * area of the screen image (frame buffer). */
1136 REG_WRITE(dspsize_reg, ((MIN(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
1137 | (MIN(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
1138 /* Set the CRTC with encoder mode. */
1139 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
1140 | (mode->crtc_vdisplay - 1));
1141 } else {
1142 REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1));
1143 REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
1146 REG_WRITE(dsppos_reg, 0);
1148 if (psb_intel_output)
1149 drm_connector_property_get_value(&psb_intel_output->base,
1150 dev->mode_config.scaling_mode_property, &scalingType);
1152 if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
1153 /*Moorestown doesn't have register support for centering so we need to
1154 mess with the h/vblank and h/vsync start and ends to get centering*/
1155 int offsetX = 0, offsetY = 0;
1157 offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
1158 offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
1160 REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
1161 ((adjusted_mode->crtc_htotal - 1) << 16));
1162 REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
1163 ((adjusted_mode->crtc_vtotal - 1) << 16));
1164 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) |
1165 ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
1166 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) |
1167 ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
1168 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) |
1169 ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
1170 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) |
1171 ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
1172 } else {
1173 REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
1174 ((adjusted_mode->crtc_htotal - 1) << 16));
1175 REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
1176 ((adjusted_mode->crtc_vtotal - 1) << 16));
1177 REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
1178 ((adjusted_mode->crtc_hblank_end - 1) << 16));
1179 REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
1180 ((adjusted_mode->crtc_hsync_end - 1) << 16));
1181 REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
1182 ((adjusted_mode->crtc_vblank_end - 1) << 16));
1183 REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
1184 ((adjusted_mode->crtc_vsync_end - 1) << 16));
1187 /* Flush the plane changes */
1189 struct drm_crtc_helper_funcs *crtc_funcs =
1190 crtc->helper_private;
1191 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
1194 /* setup pipeconf */
1195 *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
1197 /* Set up the display plane register */
1198 *dspcntr = REG_READ(dspcntr_reg);
1199 *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
1200 *dspcntr |= DISPLAY_PLANE_ENABLE;
1201 /* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_BOTTOM; */
1202 /* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_GAMMA_ENABLE; */
1204 if (is_mipi2)
1206 goto mrst_crtc_mode_set_exit;
1208 /* FIXME JLIU7 Add MDFLD HDMI supports */
1209 /* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */
1210 /* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */
1211 clk = adjusted_mode->clock;
1213 if (is_hdmi) {
1214 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
1216 refclk = 19200;
1218 if (is_mipi || is_mipi2)
1220 clk_n = 1, clk_p2 = 8;
1221 } else if (is_hdmi) {
1222 clk_n = 1, clk_p2 = 10;
1224 } else if (ksel == KSEL_BYPASS_25) {
1225 refclk = 25000;
1227 if (is_mipi || is_mipi2)
1229 clk_n = 1, clk_p2 = 8;
1230 } else if (is_hdmi) {
1231 clk_n = 1, clk_p2 = 10;
1233 } else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) {
1234 refclk = 83000;
1236 if (is_mipi || is_mipi2)
1238 clk_n = 4, clk_p2 = 8;
1239 } else if (is_hdmi) {
1240 clk_n = 4, clk_p2 = 10;
1242 } else if ((ksel == KSEL_BYPASS_83_100) &&
1243 (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) {
1244 refclk = 100000;
1245 if (is_mipi || is_mipi2)
1247 clk_n = 4, clk_p2 = 8;
1248 } else if (is_hdmi) {
1249 clk_n = 4, clk_p2 = 10;
1253 if (is_mipi)
1254 clk_byte = dev_priv->bpp / 8;
1255 else if (is_mipi2)
1256 clk_byte = dev_priv->bpp2 / 8;
1258 clk_tmp = clk * clk_n * clk_p2 * clk_byte;
1260 dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n, clk_p2);
1261 dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode->clock, clk_tmp);
1263 ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
1265 if (!ok) {
1266 dev_err(dev->dev,
1267 "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n");
1268 } else {
1269 m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
1271 dev_dbg(dev->dev, "dot clock = %d,"
1272 "m = %d, p1 = %d, m_conv = %d. \n", clock.dot, clock.m,
1273 clock.p1, m_conv);
1276 dpll = REG_READ(dpll_reg);
1278 if (dpll & DPLL_VCO_ENABLE) {
1279 dpll &= ~DPLL_VCO_ENABLE;
1280 REG_WRITE(dpll_reg, dpll);
1281 REG_READ(dpll_reg);
1283 /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
1284 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1285 udelay(500);
1287 /* reset M1, N1 & P1 */
1288 REG_WRITE(fp_reg, 0);
1289 dpll &= ~MDFLD_P1_MASK;
1290 REG_WRITE(dpll_reg, dpll);
1291 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1292 udelay(500);
1295 /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
1296 if (dpll & MDFLD_PWR_GATE_EN) {
1297 dpll &= ~MDFLD_PWR_GATE_EN;
1298 REG_WRITE(dpll_reg, dpll);
1299 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1300 udelay(500);
1303 dpll = 0;
1305 #if 0 /* FIXME revisit later */
1306 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19) || (ksel == KSEL_BYPASS_25)) {
1307 dpll &= ~MDFLD_INPUT_REF_SEL;
1308 } else if (ksel == KSEL_BYPASS_83_100) {
1309 dpll |= MDFLD_INPUT_REF_SEL;
1311 #endif /* FIXME revisit later */
1313 if (is_hdmi)
1314 dpll |= MDFLD_VCO_SEL;
1316 fp = (clk_n / 2) << 16;
1317 fp |= m_conv;
1319 /* compute bitmask from p1 value */
1320 dpll |= (1 << (clock.p1 - 2)) << 17;
1322 #if 0 /* 1080p30 & 720p */
1323 dpll = 0x00050000;
1324 fp = 0x000001be;
1325 #endif
1326 #if 0 /* 480p */
1327 dpll = 0x02010000;
1328 fp = 0x000000d2;
1329 #endif
1330 } else {
1331 #if 0 /*DBI_TPO_480x864*/
1332 dpll = 0x00020000;
1333 fp = 0x00000156;
1334 #endif /* DBI_TPO_480x864 */ /* get from spec. */
1336 dpll = 0x00800000;
1337 fp = 0x000000c1;
1340 REG_WRITE(fp_reg, fp);
1341 REG_WRITE(dpll_reg, dpll);
1342 /* FIXME_MDFLD PO - change 500 to 1 after PO */
1343 udelay(500);
1345 dpll |= DPLL_VCO_ENABLE;
1346 REG_WRITE(dpll_reg, dpll);
1347 REG_READ(dpll_reg);
1349 /* wait for DSI PLL to lock */
1350 while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
1351 udelay(150);
1352 timeout ++;
1355 if (is_mipi)
1356 goto mrst_crtc_mode_set_exit;
1358 dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi);
1360 REG_WRITE(pipeconf_reg, *pipeconf);
1361 REG_READ(pipeconf_reg);
1363 /* Wait for for the pipe enable to take effect. */
1364 //FIXME_JLIU7 HDMI mrstWaitForPipeEnable(dev);
1366 REG_WRITE(dspcntr_reg, *dspcntr);
1367 psb_intel_wait_for_vblank(dev);
1369 mrst_crtc_mode_set_exit:
1371 gma_power_end(dev);
1373 return 0;
1376 static void mdfld_crtc_prepare(struct drm_crtc *crtc)
1378 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1379 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
1382 static void mdfld_crtc_commit(struct drm_crtc *crtc)
1384 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1385 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1388 static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc,
1389 struct drm_display_mode *mode,
1390 struct drm_display_mode *adjusted_mode)
1392 return true;
1395 const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
1396 .dpms = mdfld_crtc_dpms,
1397 .mode_fixup = mdfld_crtc_mode_fixup,
1398 .mode_set = mdfld_crtc_mode_set,
1399 .mode_set_base = mdfld__intel_pipe_set_base,
1400 .prepare = mdfld_crtc_prepare,
1401 .commit = mdfld_crtc_commit,