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