linux/drivers/gpu/drm/gma500/mdfld_intel_display.c
<<
>>
Prefs
   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 */
  23static int ksel = KSEL_CRYSTAL_19;
  24
  25struct psb_intel_range_t {
  26        int min, max;
  27};
  28
  29struct mrst_limit_t {
  30        struct psb_intel_range_t dot, m, p1;
  31};
  32
  33struct mrst_clock_t {
  34        /* derived values */
  35        int dot;
  36        int m;
  37        int p1;
  38};
  39
  40#define COUNT_MAX 0x10000000
  41
  42void 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
  70void 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 */
 102static 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
 116static struct drm_device globle_dev;
 117
 118void 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
 137static 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
 154static 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 */
 229void 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 */
 295static 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
 515static 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
 560static 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
 580static 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. */
 620static 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 */
 629static bool
 630mdfldFindBestPLL(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
 656static 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
1007mrst_crtc_mode_set_exit:
1008
1009        gma_power_end(dev);
1010
1011        return 0;
1012}
1013
1014const 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};
1021