gma500: udelay(20000) it too long again
[pandora-kernel.git] / drivers / staging / gma500 / mdfld_intel_display.c
1 /*
2  * Copyright © 2006-2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *      Eric Anholt <eric@anholt.net>
25  */
26
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"
32
33 #include <linux/pm_runtime.h>
34
35 #ifdef MIN
36 #undef MIN
37 #endif
38
39 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
40
41 /* Hardcoded currently */
42 static int ksel = KSEL_CRYSTAL_19;
43
44 extern void mdfld_save_display(struct drm_device *dev);
45 extern bool gbgfxsuspended;
46
47 struct psb_intel_range_t {
48         int min, max;
49 };
50
51 struct mdfld_limit_t {
52         struct psb_intel_range_t dot, m, p1;
53 };
54
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;
65 };
66
67
68
69 #define COUNT_MAX 0x10000000
70
71 void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
72 {
73         int count, temp;
74         u32 pipeconf_reg = PIPEACONF;
75         
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;
88         }
89
90         /* FIXME JLIU7_PO */
91         psb_intel_wait_for_vblank(dev);
92         return;
93
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;
99         }
100 }
101
102 void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
103 {
104         int count, temp;
105         u32 pipeconf_reg = PIPEACONF;
106         
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;
119         }
120
121         /* FIXME JLIU7_PO */
122         psb_intel_wait_for_vblank(dev);
123         return;
124
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;
130         }
131 }
132
133
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)
138 {
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;
149
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;
164         }
165         
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;
176
177                 if (gma_power_begin(dev, true)) {
178                         REG_WRITE(control, temp);
179                         REG_WRITE(base, 0);
180                         gma_power_end(dev);
181                 }
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;
189                 }
190                 return 0;
191         }
192
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;
197         }
198
199         obj = drm_gem_object_lookup(dev, file_priv, handle);
200         if (!obj)
201                 return -ENOENT;
202
203         if (obj->size < width * height * 4) {
204                 dev_dbg(dev->dev, "buffer is to small\n");
205                 return -ENOMEM;
206         }
207
208         gt = container_of(obj, struct gtt_range, gem);
209
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;
215         }
216
217
218         addr = gt->offset;      /* Or resource.start ??? */
219
220         psb_intel_crtc->cursor_addr = addr;
221
222         temp = 0;
223         /* set the pipe for the cursor */
224         temp |= (pipe << 28);
225         temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
226
227         if (gma_power_begin(dev, true)) {
228                 REG_WRITE(control, temp);
229                 REG_WRITE(base, addr);
230                 gma_power_end(dev);
231         }
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;
239         }
240         return 0;
241 }
242
243 static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
244 {
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;
255
256         switch (pipe) {
257         case 0:
258                 if (dpu_info) {
259                         rect.x = x;
260                         rect.y = y;
261                 
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;
283         }
284                 
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;
292         }
293         if (y < 0) {
294                 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
295                 y = -y;
296         }
297
298         temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
299         temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
300
301         addr = psb_intel_crtc->cursor_addr;
302
303         if (gma_power_begin(dev, true)) {
304                 REG_WRITE(pos, temp);
305                 REG_WRITE(base, addr);
306                 gma_power_end(dev);
307         }
308
309         return 0;
310 }
311
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,
318 };
319
320 static struct drm_device globle_dev;
321
322 void mdfld__intel_plane_set_alpha(int enable)
323 {
324         struct drm_device *dev = &globle_dev;
325         int dspcntr_reg = DSPACNTR;
326         u32 dspcntr;
327
328         dspcntr = REG_READ(dspcntr_reg);
329
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;
336         }
337
338         REG_WRITE(dspcntr_reg, dspcntr);
339 }
340
341 int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb)
342 {
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;
355
356         memcpy(&globle_dev, dev, sizeof(struct drm_device));
357
358         if (!gma_power_begin(dev, true))
359                 return 0;
360
361         /* no fb bound */
362         if (!crtc->fb) {
363                 dev_err(dev->dev, "No FB bound\n");
364                 goto psb_intel_pipe_cleaner;
365         }
366
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;
386         }
387
388         ret = psb_gtt_pin(psbfb->gtt);
389         if (ret < 0)
390                 goto psb_intel_pipe_set_base_exit;
391
392         start = psbfb->gtt->offset;
393         offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
394
395         REG_WRITE(dspstride, crtc->fb->pitch);
396         dspcntr = REG_READ(dspcntr_reg);
397         dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
398
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;
417         }
418         REG_WRITE(dspcntr_reg, dspcntr);
419
420         dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
421                                                 start, offset, x, y);
422
423         REG_WRITE(dsplinoff, offset);
424         REG_READ(dsplinoff);
425         REG_WRITE(dspsurf, start);
426         REG_READ(dspsurf);
427
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);
432
433 psb_intel_pipe_set_base_exit:
434         gma_power_end(dev);
435         return ret;
436 }
437
438 /**
439  * Disable the pipe, plane and pll.
440  *
441  */
442 void mdfld_disable_crtc (struct drm_device *dev, int pipe)
443 {
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;
450
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;
470         }
471
472         if (pipe != 1)
473                 mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
474
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);
483         }
484
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);
488
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);
496
497                 /* Wait for for the pipe disable to take effect. */
498                 mdfldWaitForPipeDisable(dev, pipe);
499         }
500
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);
511
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);
517                         }
518                 }
519         }
520
521 }
522
523 /**
524  * Sets the power management mode of the pipe and plane.
525  *
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.
528  */
529 static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
530 {
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;
547
548         if (!gma_power_begin(dev, true))
549                 return;
550
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);
556             }
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;
562         }
563
564
565 /* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
566 /* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
567
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;
594         }
595
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.
598          */
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);
605
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);
613                         }
614
615                         REG_WRITE(dpll_reg, temp);
616                         REG_READ(dpll_reg);
617                         /* FIXME_MDFLD PO - change 500 to 1 after PO */
618                         udelay(500);
619                         
620                         REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
621                         REG_READ(dpll_reg);
622
623                         /**
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.
627                          */
628                         while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
629                                 udelay(150);
630                                 timeout ++;
631                         }
632                 }
633
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));
641                 }
642
643                 /* Enable the pipe */
644                 temp = REG_READ(pipeconf_reg);
645                 if ((temp & PIPEACONF_ENABLE) == 0) {
646                         REG_WRITE(pipeconf_reg, pipeconf);
647
648                         /* Wait for for the pipe enable to take effect. */
649                         mdfldWaitForPipeEnable(dev, pipe);
650                 }
651
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);
691                         }
692                 }
693
694                 psb_intel_crtc_load_lut(crtc);
695
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 */
699
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);
707
708                 /* Disable the VGA plane that we never use */
709                 REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
710
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);
719                 }
720
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);
724
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);
733
734                         /* Wait for for the pipe disable to take effect. */
735                         mdfldWaitForPipeDisable(dev, pipe);
736                 }
737
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);
754                 }
755 #endif  /* MDFLD_PO_JLIU7 */    
756                         }
757                 }
758                 break;
759         }
760
761         enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
762
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
769
770         gma_power_end(dev);
771 }
772
773
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
782
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
817
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},
823          },
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},
828          },
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},
833          },
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},
838          },
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},
843          },
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},
848          },
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},
853          },
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},
858          },
859 };
860
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 */
881 };
882
883 static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc)
884 {
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;
888
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");
913         }
914
915         return limit;
916 }
917
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)
920 {
921         clock->dot = (refclk * clock->m) / clock->p1;
922 }
923
924 /**
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
927  */
928 static bool
929 mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
930                 struct mdfld_intel_clock_t *best_clock)
931 {
932         struct mdfld_intel_clock_t clock;
933         const struct mdfld_limit_t *limit = mdfld_limit(crtc);
934         int err = target;
935
936         memset(best_clock, 0, sizeof(*best_clock));
937
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;
942
943                         mdfld_clock(refclk, &clock);
944
945                         this_err = abs(clock.dot - target);
946                         if (this_err < err) {
947                                 *best_clock = clock;
948                                 err = this_err;
949                         }
950                 }
951         }
952         return err != target;
953 }
954
955 /**
956  * Return the pipe currently connected to the panel fitter,
957  * or -1 if the panel fitter is not present or not in use
958  */
959 static int mdfld_panel_fitter_pipe(struct drm_device *dev)
960 {
961         u32 pfit_control;
962
963         pfit_control = REG_READ(PFIT_CONTROL);
964
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;
969 }
970
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)
976 {
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;
1009
1010         dev_dbg(dev->dev, "pipe = 0x%x \n", pipe);
1011
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;
1053         }
1054
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);
1077
1078         if (!gma_power_begin(dev, true))
1079                 return 0;
1080
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));
1083
1084         list_for_each_entry(connector, &mode_config->connector_list, head) {
1085                         
1086                 encoder = connector->encoder;
1087                 
1088                 if(!encoder)
1089                         continue;
1090
1091                 if (encoder->crtc != crtc)
1092                         continue;
1093
1094                 psb_intel_output = to_psb_intel_output(connector);
1095                 
1096                 dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type);
1097
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;
1117                 }
1118         }
1119
1120         /* Disable the VGA plane that we never use */
1121         REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
1122
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);
1126
1127         /* pipesrc and dspsize control the size that is scaled from,
1128          * which should always be the user's requested size.
1129          */
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. */
1133
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));
1144         }
1145
1146         REG_WRITE(dsppos_reg, 0);
1147
1148         if (psb_intel_output)
1149                 drm_connector_property_get_value(&psb_intel_output->base,
1150                         dev->mode_config.scaling_mode_property, &scalingType);
1151
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;
1156
1157                 offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
1158                 offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
1159
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));
1185         }
1186
1187         /* Flush the plane changes */
1188         {
1189                 struct drm_crtc_helper_funcs *crtc_funcs =
1190                     crtc->helper_private;
1191                 crtc_funcs->mode_set_base(crtc, x, y, old_fb);
1192         }
1193
1194         /* setup pipeconf */
1195         *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
1196
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; */
1203
1204         if (is_mipi2)
1205         {
1206                 goto mrst_crtc_mode_set_exit;
1207         }
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;
1212
1213         if (is_hdmi) {
1214                 if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
1215                 {
1216                         refclk = 19200;
1217
1218                         if (is_mipi || is_mipi2)
1219                         {
1220                                 clk_n = 1, clk_p2 = 8;
1221                         } else if (is_hdmi) {
1222                                 clk_n = 1, clk_p2 = 10;
1223                         }
1224                 } else if (ksel == KSEL_BYPASS_25) { 
1225                         refclk = 25000;
1226
1227                         if (is_mipi || is_mipi2)
1228                         {
1229                                 clk_n = 1, clk_p2 = 8;
1230                         } else if (is_hdmi) {
1231                                 clk_n = 1, clk_p2 = 10;
1232                         }
1233                 } else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) {
1234                         refclk = 83000;
1235
1236                         if (is_mipi || is_mipi2)
1237                         {
1238                                 clk_n = 4, clk_p2 = 8;
1239                         } else if (is_hdmi) {
1240                                 clk_n = 4, clk_p2 = 10;
1241                         }
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)
1246                         {
1247                                 clk_n = 4, clk_p2 = 8;
1248                         } else if (is_hdmi) {
1249                                 clk_n = 4, clk_p2 = 10;
1250                         }
1251                 }
1252
1253                 if (is_mipi)
1254                         clk_byte = dev_priv->bpp / 8;
1255                 else if (is_mipi2)
1256                         clk_byte = dev_priv->bpp2 / 8;
1257         
1258                 clk_tmp = clk * clk_n * clk_p2 * clk_byte;
1259
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);
1262
1263                 ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
1264
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)];
1270
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);
1274                 }
1275
1276                 dpll = REG_READ(dpll_reg);
1277
1278                 if (dpll & DPLL_VCO_ENABLE) {
1279                         dpll &= ~DPLL_VCO_ENABLE;
1280                         REG_WRITE(dpll_reg, dpll);
1281                         REG_READ(dpll_reg);
1282
1283                         /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
1284                         /* FIXME_MDFLD PO - change 500 to 1 after PO */
1285                         udelay(500);
1286
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);
1293                 }
1294
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);
1301                 }       
1302
1303                 dpll = 0; 
1304
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;    
1310                 }
1311 #endif /* FIXME revisit later */
1312
1313                 if (is_hdmi)
1314                         dpll |= MDFLD_VCO_SEL;  
1315
1316                 fp = (clk_n / 2) << 16;
1317                 fp |= m_conv; 
1318
1319                 /* compute bitmask from p1 value */
1320                 dpll |= (1 << (clock.p1 - 2)) << 17;
1321
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. */
1335
1336                 dpll = 0x00800000;
1337                 fp = 0x000000c1;
1338 }
1339
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);
1344
1345         dpll |= DPLL_VCO_ENABLE;
1346         REG_WRITE(dpll_reg, dpll);
1347         REG_READ(dpll_reg);
1348
1349         /* wait for DSI PLL to lock */
1350         while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
1351                 udelay(150);
1352                 timeout ++;
1353         }
1354
1355         if (is_mipi)
1356                 goto mrst_crtc_mode_set_exit;
1357
1358         dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi);
1359
1360         REG_WRITE(pipeconf_reg, *pipeconf);
1361         REG_READ(pipeconf_reg);
1362
1363         /* Wait for for the pipe enable to take effect. */
1364 //FIXME_JLIU7 HDMI      mrstWaitForPipeEnable(dev);
1365
1366         REG_WRITE(dspcntr_reg, *dspcntr);
1367         psb_intel_wait_for_vblank(dev);
1368
1369 mrst_crtc_mode_set_exit:
1370
1371         gma_power_end(dev);
1372
1373         return 0;
1374 }
1375
1376 static void mdfld_crtc_prepare(struct drm_crtc *crtc)
1377 {
1378         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1379         crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
1380 }
1381
1382 static void mdfld_crtc_commit(struct drm_crtc *crtc)
1383 {
1384         struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1385         crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1386 }
1387
1388 static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc,
1389                                   struct drm_display_mode *mode,
1390                                   struct drm_display_mode *adjusted_mode)
1391 {
1392         return true;
1393 }
1394
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,
1402 };