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