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