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