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