root/drivers/gpu/drm/gma500/mdfld_intel_display.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mdfldWaitForPipeDisable
  2. mdfldWaitForPipeEnable
  3. psb_intel_panel_fitter_pipe
  4. mdfld__intel_plane_set_alpha
  5. check_fb
  6. mdfld__intel_pipe_set_base
  7. mdfld_disable_crtc
  8. mdfld_crtc_dpms
  9. mdfld_limit
  10. mdfld_clock
  11. mdfldFindBestPLL
  12. mdfld_crtc_mode_set

   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 };

/* [<][>][^][v][top][bottom][index][help] */