linux/drivers/gpu/drm/mgag200/mgag200_mode.c
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Matt Turner.
   3 * Copyright 2012 Red Hat
   4 *
   5 * This file is subject to the terms and conditions of the GNU General
   6 * Public License version 2. See the file COPYING in the main
   7 * directory of this archive for more details.
   8 *
   9 * Authors: Matthew Garrett
  10 *          Matt Turner
  11 *          Dave Airlie
  12 */
  13
  14#include <linux/delay.h>
  15
  16#include <drm/drmP.h>
  17#include <drm/drm_crtc_helper.h>
  18#include <drm/drm_plane_helper.h>
  19
  20#include "mgag200_drv.h"
  21
  22#define MGAG200_LUT_SIZE 256
  23
  24/*
  25 * This file contains setup code for the CRTC.
  26 */
  27
  28static void mga_crtc_load_lut(struct drm_crtc *crtc)
  29{
  30        struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
  31        struct drm_device *dev = crtc->dev;
  32        struct mga_device *mdev = dev->dev_private;
  33        struct drm_framebuffer *fb = crtc->primary->fb;
  34        int i;
  35
  36        if (!crtc->enabled)
  37                return;
  38
  39        WREG8(DAC_INDEX + MGA1064_INDEX, 0);
  40
  41        if (fb && fb->format->cpp[0] * 8 == 16) {
  42                int inc = (fb->format->depth == 15) ? 8 : 4;
  43                u8 r, b;
  44                for (i = 0; i < MGAG200_LUT_SIZE; i += inc) {
  45                        if (fb->format->depth == 16) {
  46                                if (i > (MGAG200_LUT_SIZE >> 1)) {
  47                                        r = b = 0;
  48                                } else {
  49                                        r = mga_crtc->lut_r[i << 1];
  50                                        b = mga_crtc->lut_b[i << 1];
  51                                }
  52                        } else {
  53                                r = mga_crtc->lut_r[i];
  54                                b = mga_crtc->lut_b[i];
  55                        }
  56                        /* VGA registers */
  57                        WREG8(DAC_INDEX + MGA1064_COL_PAL, r);
  58                        WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
  59                        WREG8(DAC_INDEX + MGA1064_COL_PAL, b);
  60                }
  61                return;
  62        }
  63        for (i = 0; i < MGAG200_LUT_SIZE; i++) {
  64                /* VGA registers */
  65                WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_r[i]);
  66                WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_g[i]);
  67                WREG8(DAC_INDEX + MGA1064_COL_PAL, mga_crtc->lut_b[i]);
  68        }
  69}
  70
  71static inline void mga_wait_vsync(struct mga_device *mdev)
  72{
  73        unsigned long timeout = jiffies + HZ/10;
  74        unsigned int status = 0;
  75
  76        do {
  77                status = RREG32(MGAREG_Status);
  78        } while ((status & 0x08) && time_before(jiffies, timeout));
  79        timeout = jiffies + HZ/10;
  80        status = 0;
  81        do {
  82                status = RREG32(MGAREG_Status);
  83        } while (!(status & 0x08) && time_before(jiffies, timeout));
  84}
  85
  86static inline void mga_wait_busy(struct mga_device *mdev)
  87{
  88        unsigned long timeout = jiffies + HZ;
  89        unsigned int status = 0;
  90        do {
  91                status = RREG8(MGAREG_Status + 2);
  92        } while ((status & 0x01) && time_before(jiffies, timeout));
  93}
  94
  95#define P_ARRAY_SIZE 9
  96
  97static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
  98{
  99        unsigned int vcomax, vcomin, pllreffreq;
 100        unsigned int delta, tmpdelta, permitteddelta;
 101        unsigned int testp, testm, testn;
 102        unsigned int p, m, n;
 103        unsigned int computed;
 104        unsigned int pvalues_e4[P_ARRAY_SIZE] = {16, 14, 12, 10, 8, 6, 4, 2, 1};
 105        unsigned int fvv;
 106        unsigned int i;
 107
 108        if (mdev->unique_rev_id <= 0x03) {
 109
 110                m = n = p = 0;
 111                vcomax = 320000;
 112                vcomin = 160000;
 113                pllreffreq = 25000;
 114
 115                delta = 0xffffffff;
 116                permitteddelta = clock * 5 / 1000;
 117
 118                for (testp = 8; testp > 0; testp /= 2) {
 119                        if (clock * testp > vcomax)
 120                                continue;
 121                        if (clock * testp < vcomin)
 122                                continue;
 123
 124                        for (testn = 17; testn < 256; testn++) {
 125                                for (testm = 1; testm < 32; testm++) {
 126                                        computed = (pllreffreq * testn) /
 127                                                (testm * testp);
 128                                        if (computed > clock)
 129                                                tmpdelta = computed - clock;
 130                                        else
 131                                                tmpdelta = clock - computed;
 132                                        if (tmpdelta < delta) {
 133                                                delta = tmpdelta;
 134                                                m = testm - 1;
 135                                                n = testn - 1;
 136                                                p = testp - 1;
 137                                        }
 138                                }
 139                        }
 140                }
 141        } else {
 142
 143
 144                m = n = p = 0;
 145                vcomax        = 1600000;
 146                vcomin        = 800000;
 147                pllreffreq    = 25000;
 148
 149                if (clock < 25000)
 150                        clock = 25000;
 151
 152                clock = clock * 2;
 153
 154                delta = 0xFFFFFFFF;
 155                /* Permited delta is 0.5% as VESA Specification */
 156                permitteddelta = clock * 5 / 1000;
 157
 158                for (i = 0 ; i < P_ARRAY_SIZE ; i++) {
 159                        testp = pvalues_e4[i];
 160
 161                        if ((clock * testp) > vcomax)
 162                                continue;
 163                        if ((clock * testp) < vcomin)
 164                                continue;
 165
 166                        for (testn = 50; testn <= 256; testn++) {
 167                                for (testm = 1; testm <= 32; testm++) {
 168                                        computed = (pllreffreq * testn) /
 169                                                (testm * testp);
 170                                        if (computed > clock)
 171                                                tmpdelta = computed - clock;
 172                                        else
 173                                                tmpdelta = clock - computed;
 174
 175                                        if (tmpdelta < delta) {
 176                                                delta = tmpdelta;
 177                                                m = testm - 1;
 178                                                n = testn - 1;
 179                                                p = testp - 1;
 180                                        }
 181                                }
 182                        }
 183                }
 184
 185                fvv = pllreffreq * (n + 1) / (m + 1);
 186                fvv = (fvv - 800000) / 50000;
 187
 188                if (fvv > 15)
 189                        fvv = 15;
 190
 191                p |= (fvv << 4);
 192                m |= 0x80;
 193
 194                clock = clock / 2;
 195        }
 196
 197        if (delta > permitteddelta) {
 198                pr_warn("PLL delta too large\n");
 199                return 1;
 200        }
 201
 202        WREG_DAC(MGA1064_PIX_PLLC_M, m);
 203        WREG_DAC(MGA1064_PIX_PLLC_N, n);
 204        WREG_DAC(MGA1064_PIX_PLLC_P, p);
 205
 206        if (mdev->unique_rev_id >= 0x04) {
 207                WREG_DAC(0x1a, 0x09);
 208                msleep(20);
 209                WREG_DAC(0x1a, 0x01);
 210
 211        }
 212
 213        return 0;
 214}
 215
 216static int mga_g200wb_set_plls(struct mga_device *mdev, long clock)
 217{
 218        unsigned int vcomax, vcomin, pllreffreq;
 219        unsigned int delta, tmpdelta;
 220        unsigned int testp, testm, testn, testp2;
 221        unsigned int p, m, n;
 222        unsigned int computed;
 223        int i, j, tmpcount, vcount;
 224        bool pll_locked = false;
 225        u8 tmp;
 226
 227        m = n = p = 0;
 228
 229        delta = 0xffffffff;
 230
 231        if (mdev->type == G200_EW3) {
 232
 233                vcomax = 800000;
 234                vcomin = 400000;
 235                pllreffreq = 25000;
 236
 237                for (testp = 1; testp < 8; testp++) {
 238                        for (testp2 = 1; testp2 < 8; testp2++) {
 239                                if (testp < testp2)
 240                                        continue;
 241                                if ((clock * testp * testp2) > vcomax)
 242                                        continue;
 243                                if ((clock * testp * testp2) < vcomin)
 244                                        continue;
 245                                for (testm = 1; testm < 26; testm++) {
 246                                        for (testn = 32; testn < 2048 ; testn++) {
 247                                                computed = (pllreffreq * testn) /
 248                                                        (testm * testp * testp2);
 249                                                if (computed > clock)
 250                                                        tmpdelta = computed - clock;
 251                                                else
 252                                                        tmpdelta = clock - computed;
 253                                                if (tmpdelta < delta) {
 254                                                        delta = tmpdelta;
 255                                                        m = ((testn & 0x100) >> 1) |
 256                                                                (testm);
 257                                                        n = (testn & 0xFF);
 258                                                        p = ((testn & 0x600) >> 3) |
 259                                                                (testp2 << 3) |
 260                                                                (testp);
 261                                                }
 262                                        }
 263                                }
 264                        }
 265                }
 266        } else {
 267
 268                vcomax = 550000;
 269                vcomin = 150000;
 270                pllreffreq = 48000;
 271
 272                for (testp = 1; testp < 9; testp++) {
 273                        if (clock * testp > vcomax)
 274                                continue;
 275                        if (clock * testp < vcomin)
 276                                continue;
 277
 278                        for (testm = 1; testm < 17; testm++) {
 279                                for (testn = 1; testn < 151; testn++) {
 280                                        computed = (pllreffreq * testn) /
 281                                                (testm * testp);
 282                                        if (computed > clock)
 283                                                tmpdelta = computed - clock;
 284                                        else
 285                                                tmpdelta = clock - computed;
 286                                        if (tmpdelta < delta) {
 287                                                delta = tmpdelta;
 288                                                n = testn - 1;
 289                                                m = (testm - 1) |
 290                                                        ((n >> 1) & 0x80);
 291                                                p = testp - 1;
 292                                        }
 293                                }
 294                        }
 295                }
 296        }
 297
 298        for (i = 0; i <= 32 && pll_locked == false; i++) {
 299                if (i > 0) {
 300                        WREG8(MGAREG_CRTC_INDEX, 0x1e);
 301                        tmp = RREG8(MGAREG_CRTC_DATA);
 302                        if (tmp < 0xff)
 303                                WREG8(MGAREG_CRTC_DATA, tmp+1);
 304                }
 305
 306                /* set pixclkdis to 1 */
 307                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 308                tmp = RREG8(DAC_DATA);
 309                tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 310                WREG8(DAC_DATA, tmp);
 311
 312                WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 313                tmp = RREG8(DAC_DATA);
 314                tmp |= MGA1064_REMHEADCTL_CLKDIS;
 315                WREG8(DAC_DATA, tmp);
 316
 317                /* select PLL Set C */
 318                tmp = RREG8(MGAREG_MEM_MISC_READ);
 319                tmp |= 0x3 << 2;
 320                WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 321
 322                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 323                tmp = RREG8(DAC_DATA);
 324                tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80;
 325                WREG8(DAC_DATA, tmp);
 326
 327                udelay(500);
 328
 329                /* reset the PLL */
 330                WREG8(DAC_INDEX, MGA1064_VREF_CTL);
 331                tmp = RREG8(DAC_DATA);
 332                tmp &= ~0x04;
 333                WREG8(DAC_DATA, tmp);
 334
 335                udelay(50);
 336
 337                /* program pixel pll register */
 338                WREG_DAC(MGA1064_WB_PIX_PLLC_N, n);
 339                WREG_DAC(MGA1064_WB_PIX_PLLC_M, m);
 340                WREG_DAC(MGA1064_WB_PIX_PLLC_P, p);
 341
 342                udelay(50);
 343
 344                /* turn pll on */
 345                WREG8(DAC_INDEX, MGA1064_VREF_CTL);
 346                tmp = RREG8(DAC_DATA);
 347                tmp |= 0x04;
 348                WREG_DAC(MGA1064_VREF_CTL, tmp);
 349
 350                udelay(500);
 351
 352                /* select the pixel pll */
 353                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 354                tmp = RREG8(DAC_DATA);
 355                tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
 356                tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
 357                WREG8(DAC_DATA, tmp);
 358
 359                WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 360                tmp = RREG8(DAC_DATA);
 361                tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK;
 362                tmp |= MGA1064_REMHEADCTL_CLKSL_PLL;
 363                WREG8(DAC_DATA, tmp);
 364
 365                /* reset dotclock rate bit */
 366                WREG8(MGAREG_SEQ_INDEX, 1);
 367                tmp = RREG8(MGAREG_SEQ_DATA);
 368                tmp &= ~0x8;
 369                WREG8(MGAREG_SEQ_DATA, tmp);
 370
 371                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 372                tmp = RREG8(DAC_DATA);
 373                tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 374                WREG8(DAC_DATA, tmp);
 375
 376                vcount = RREG8(MGAREG_VCOUNT);
 377
 378                for (j = 0; j < 30 && pll_locked == false; j++) {
 379                        tmpcount = RREG8(MGAREG_VCOUNT);
 380                        if (tmpcount < vcount)
 381                                vcount = 0;
 382                        if ((tmpcount - vcount) > 2)
 383                                pll_locked = true;
 384                        else
 385                                udelay(5);
 386                }
 387        }
 388        WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 389        tmp = RREG8(DAC_DATA);
 390        tmp &= ~MGA1064_REMHEADCTL_CLKDIS;
 391        WREG_DAC(MGA1064_REMHEADCTL, tmp);
 392        return 0;
 393}
 394
 395static int mga_g200ev_set_plls(struct mga_device *mdev, long clock)
 396{
 397        unsigned int vcomax, vcomin, pllreffreq;
 398        unsigned int delta, tmpdelta;
 399        unsigned int testp, testm, testn;
 400        unsigned int p, m, n;
 401        unsigned int computed;
 402        u8 tmp;
 403
 404        m = n = p = 0;
 405        vcomax = 550000;
 406        vcomin = 150000;
 407        pllreffreq = 50000;
 408
 409        delta = 0xffffffff;
 410
 411        for (testp = 16; testp > 0; testp--) {
 412                if (clock * testp > vcomax)
 413                        continue;
 414                if (clock * testp < vcomin)
 415                        continue;
 416
 417                for (testn = 1; testn < 257; testn++) {
 418                        for (testm = 1; testm < 17; testm++) {
 419                                computed = (pllreffreq * testn) /
 420                                        (testm * testp);
 421                                if (computed > clock)
 422                                        tmpdelta = computed - clock;
 423                                else
 424                                        tmpdelta = clock - computed;
 425                                if (tmpdelta < delta) {
 426                                        delta = tmpdelta;
 427                                        n = testn - 1;
 428                                        m = testm - 1;
 429                                        p = testp - 1;
 430                                }
 431                        }
 432                }
 433        }
 434
 435        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 436        tmp = RREG8(DAC_DATA);
 437        tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 438        WREG8(DAC_DATA, tmp);
 439
 440        tmp = RREG8(MGAREG_MEM_MISC_READ);
 441        tmp |= 0x3 << 2;
 442        WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 443
 444        WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
 445        tmp = RREG8(DAC_DATA);
 446        WREG8(DAC_DATA, tmp & ~0x40);
 447
 448        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 449        tmp = RREG8(DAC_DATA);
 450        tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 451        WREG8(DAC_DATA, tmp);
 452
 453        WREG_DAC(MGA1064_EV_PIX_PLLC_M, m);
 454        WREG_DAC(MGA1064_EV_PIX_PLLC_N, n);
 455        WREG_DAC(MGA1064_EV_PIX_PLLC_P, p);
 456
 457        udelay(50);
 458
 459        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 460        tmp = RREG8(DAC_DATA);
 461        tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 462        WREG8(DAC_DATA, tmp);
 463
 464        udelay(500);
 465
 466        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 467        tmp = RREG8(DAC_DATA);
 468        tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
 469        tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
 470        WREG8(DAC_DATA, tmp);
 471
 472        WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT);
 473        tmp = RREG8(DAC_DATA);
 474        WREG8(DAC_DATA, tmp | 0x40);
 475
 476        tmp = RREG8(MGAREG_MEM_MISC_READ);
 477        tmp |= (0x3 << 2);
 478        WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 479
 480        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 481        tmp = RREG8(DAC_DATA);
 482        tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 483        WREG8(DAC_DATA, tmp);
 484
 485        return 0;
 486}
 487
 488static int mga_g200eh_set_plls(struct mga_device *mdev, long clock)
 489{
 490        unsigned int vcomax, vcomin, pllreffreq;
 491        unsigned int delta, tmpdelta;
 492        unsigned int testp, testm, testn;
 493        unsigned int p, m, n;
 494        unsigned int computed;
 495        int i, j, tmpcount, vcount;
 496        u8 tmp;
 497        bool pll_locked = false;
 498
 499        m = n = p = 0;
 500
 501        if (mdev->type == G200_EH3) {
 502                vcomax = 3000000;
 503                vcomin = 1500000;
 504                pllreffreq = 25000;
 505
 506                delta = 0xffffffff;
 507
 508                testp = 0;
 509
 510                for (testm = 150; testm >= 6; testm--) {
 511                        if (clock * testm > vcomax)
 512                                continue;
 513                        if (clock * testm < vcomin)
 514                                continue;
 515                        for (testn = 120; testn >= 60; testn--) {
 516                                computed = (pllreffreq * testn) / testm;
 517                                if (computed > clock)
 518                                        tmpdelta = computed - clock;
 519                                else
 520                                        tmpdelta = clock - computed;
 521                                if (tmpdelta < delta) {
 522                                        delta = tmpdelta;
 523                                        n = testn;
 524                                        m = testm;
 525                                        p = testp;
 526                                }
 527                                if (delta == 0)
 528                                        break;
 529                        }
 530                        if (delta == 0)
 531                                break;
 532                }
 533        } else {
 534
 535                vcomax = 800000;
 536                vcomin = 400000;
 537                pllreffreq = 33333;
 538
 539                delta = 0xffffffff;
 540
 541                for (testp = 16; testp > 0; testp >>= 1) {
 542                        if (clock * testp > vcomax)
 543                                continue;
 544                        if (clock * testp < vcomin)
 545                                continue;
 546
 547                        for (testm = 1; testm < 33; testm++) {
 548                                for (testn = 17; testn < 257; testn++) {
 549                                        computed = (pllreffreq * testn) /
 550                                                (testm * testp);
 551                                        if (computed > clock)
 552                                                tmpdelta = computed - clock;
 553                                        else
 554                                                tmpdelta = clock - computed;
 555                                        if (tmpdelta < delta) {
 556                                                delta = tmpdelta;
 557                                                n = testn - 1;
 558                                                m = (testm - 1);
 559                                                p = testp - 1;
 560                                        }
 561                                        if ((clock * testp) >= 600000)
 562                                                p |= 0x80;
 563                                }
 564                        }
 565                }
 566        }
 567        for (i = 0; i <= 32 && pll_locked == false; i++) {
 568                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 569                tmp = RREG8(DAC_DATA);
 570                tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 571                WREG8(DAC_DATA, tmp);
 572
 573                tmp = RREG8(MGAREG_MEM_MISC_READ);
 574                tmp |= 0x3 << 2;
 575                WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 576
 577                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 578                tmp = RREG8(DAC_DATA);
 579                tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 580                WREG8(DAC_DATA, tmp);
 581
 582                udelay(500);
 583
 584                WREG_DAC(MGA1064_EH_PIX_PLLC_M, m);
 585                WREG_DAC(MGA1064_EH_PIX_PLLC_N, n);
 586                WREG_DAC(MGA1064_EH_PIX_PLLC_P, p);
 587
 588                udelay(500);
 589
 590                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 591                tmp = RREG8(DAC_DATA);
 592                tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK;
 593                tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL;
 594                WREG8(DAC_DATA, tmp);
 595
 596                WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 597                tmp = RREG8(DAC_DATA);
 598                tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 599                tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 600                WREG8(DAC_DATA, tmp);
 601
 602                vcount = RREG8(MGAREG_VCOUNT);
 603
 604                for (j = 0; j < 30 && pll_locked == false; j++) {
 605                        tmpcount = RREG8(MGAREG_VCOUNT);
 606                        if (tmpcount < vcount)
 607                                vcount = 0;
 608                        if ((tmpcount - vcount) > 2)
 609                                pll_locked = true;
 610                        else
 611                                udelay(5);
 612                }
 613        }
 614
 615        return 0;
 616}
 617
 618static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
 619{
 620        unsigned int vcomax, vcomin, pllreffreq;
 621        unsigned int delta, tmpdelta;
 622        int testr, testn, testm, testo;
 623        unsigned int p, m, n;
 624        unsigned int computed, vco;
 625        int tmp;
 626        const unsigned int m_div_val[] = { 1, 2, 4, 8 };
 627
 628        m = n = p = 0;
 629        vcomax = 1488000;
 630        vcomin = 1056000;
 631        pllreffreq = 48000;
 632
 633        delta = 0xffffffff;
 634
 635        for (testr = 0; testr < 4; testr++) {
 636                if (delta == 0)
 637                        break;
 638                for (testn = 5; testn < 129; testn++) {
 639                        if (delta == 0)
 640                                break;
 641                        for (testm = 3; testm >= 0; testm--) {
 642                                if (delta == 0)
 643                                        break;
 644                                for (testo = 5; testo < 33; testo++) {
 645                                        vco = pllreffreq * (testn + 1) /
 646                                                (testr + 1);
 647                                        if (vco < vcomin)
 648                                                continue;
 649                                        if (vco > vcomax)
 650                                                continue;
 651                                        computed = vco / (m_div_val[testm] * (testo + 1));
 652                                        if (computed > clock)
 653                                                tmpdelta = computed - clock;
 654                                        else
 655                                                tmpdelta = clock - computed;
 656                                        if (tmpdelta < delta) {
 657                                                delta = tmpdelta;
 658                                                m = testm | (testo << 3);
 659                                                n = testn;
 660                                                p = testr | (testr << 3);
 661                                        }
 662                                }
 663                        }
 664                }
 665        }
 666
 667        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 668        tmp = RREG8(DAC_DATA);
 669        tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS;
 670        WREG8(DAC_DATA, tmp);
 671
 672        WREG8(DAC_INDEX, MGA1064_REMHEADCTL);
 673        tmp = RREG8(DAC_DATA);
 674        tmp |= MGA1064_REMHEADCTL_CLKDIS;
 675        WREG8(DAC_DATA, tmp);
 676
 677        tmp = RREG8(MGAREG_MEM_MISC_READ);
 678        tmp |= (0x3<<2) | 0xc0;
 679        WREG8(MGAREG_MEM_MISC_WRITE, tmp);
 680
 681        WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL);
 682        tmp = RREG8(DAC_DATA);
 683        tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS;
 684        tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN;
 685        WREG8(DAC_DATA, tmp);
 686
 687        udelay(500);
 688
 689        WREG_DAC(MGA1064_ER_PIX_PLLC_N, n);
 690        WREG_DAC(MGA1064_ER_PIX_PLLC_M, m);
 691        WREG_DAC(MGA1064_ER_PIX_PLLC_P, p);
 692
 693        udelay(50);
 694
 695        return 0;
 696}
 697
 698static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
 699{
 700        switch(mdev->type) {
 701        case G200_SE_A:
 702        case G200_SE_B:
 703                return mga_g200se_set_plls(mdev, clock);
 704                break;
 705        case G200_WB:
 706        case G200_EW3:
 707                return mga_g200wb_set_plls(mdev, clock);
 708                break;
 709        case G200_EV:
 710                return mga_g200ev_set_plls(mdev, clock);
 711                break;
 712        case G200_EH:
 713        case G200_EH3:
 714                return mga_g200eh_set_plls(mdev, clock);
 715                break;
 716        case G200_ER:
 717                return mga_g200er_set_plls(mdev, clock);
 718                break;
 719        }
 720        return 0;
 721}
 722
 723static void mga_g200wb_prepare(struct drm_crtc *crtc)
 724{
 725        struct mga_device *mdev = crtc->dev->dev_private;
 726        u8 tmp;
 727        int iter_max;
 728
 729        /* 1- The first step is to warn the BMC of an upcoming mode change.
 730         * We are putting the misc<0> to output.*/
 731
 732        WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
 733        tmp = RREG8(DAC_DATA);
 734        tmp |= 0x10;
 735        WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
 736
 737        /* we are putting a 1 on the misc<0> line */
 738        WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
 739        tmp = RREG8(DAC_DATA);
 740        tmp |= 0x10;
 741        WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
 742
 743        /* 2- Second step to mask and further scan request
 744         * This will be done by asserting the remfreqmsk bit (XSPAREREG<7>)
 745         */
 746        WREG8(DAC_INDEX, MGA1064_SPAREREG);
 747        tmp = RREG8(DAC_DATA);
 748        tmp |= 0x80;
 749        WREG_DAC(MGA1064_SPAREREG, tmp);
 750
 751        /* 3a- the third step is to verifu if there is an active scan
 752         * We are searching for a 0 on remhsyncsts <XSPAREREG<0>)
 753         */
 754        iter_max = 300;
 755        while (!(tmp & 0x1) && iter_max) {
 756                WREG8(DAC_INDEX, MGA1064_SPAREREG);
 757                tmp = RREG8(DAC_DATA);
 758                udelay(1000);
 759                iter_max--;
 760        }
 761
 762        /* 3b- this step occurs only if the remove is actually scanning
 763         * we are waiting for the end of the frame which is a 1 on
 764         * remvsyncsts (XSPAREREG<1>)
 765         */
 766        if (iter_max) {
 767                iter_max = 300;
 768                while ((tmp & 0x2) && iter_max) {
 769                        WREG8(DAC_INDEX, MGA1064_SPAREREG);
 770                        tmp = RREG8(DAC_DATA);
 771                        udelay(1000);
 772                        iter_max--;
 773                }
 774        }
 775}
 776
 777static void mga_g200wb_commit(struct drm_crtc *crtc)
 778{
 779        u8 tmp;
 780        struct mga_device *mdev = crtc->dev->dev_private;
 781
 782        /* 1- The first step is to ensure that the vrsten and hrsten are set */
 783        WREG8(MGAREG_CRTCEXT_INDEX, 1);
 784        tmp = RREG8(MGAREG_CRTCEXT_DATA);
 785        WREG8(MGAREG_CRTCEXT_DATA, tmp | 0x88);
 786
 787        /* 2- second step is to assert the rstlvl2 */
 788        WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
 789        tmp = RREG8(DAC_DATA);
 790        tmp |= 0x8;
 791        WREG8(DAC_DATA, tmp);
 792
 793        /* wait 10 us */
 794        udelay(10);
 795
 796        /* 3- deassert rstlvl2 */
 797        tmp &= ~0x08;
 798        WREG8(DAC_INDEX, MGA1064_REMHEADCTL2);
 799        WREG8(DAC_DATA, tmp);
 800
 801        /* 4- remove mask of scan request */
 802        WREG8(DAC_INDEX, MGA1064_SPAREREG);
 803        tmp = RREG8(DAC_DATA);
 804        tmp &= ~0x80;
 805        WREG8(DAC_DATA, tmp);
 806
 807        /* 5- put back a 0 on the misc<0> line */
 808        WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
 809        tmp = RREG8(DAC_DATA);
 810        tmp &= ~0x10;
 811        WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
 812}
 813
 814/*
 815   This is how the framebuffer base address is stored in g200 cards:
 816   * Assume @offset is the gpu_addr variable of the framebuffer object
 817   * Then addr is the number of _pixels_ (not bytes) from the start of
 818     VRAM to the first pixel we want to display. (divided by 2 for 32bit
 819     framebuffers)
 820   * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers
 821   addr<20> -> CRTCEXT0<6>
 822   addr<19-16> -> CRTCEXT0<3-0>
 823   addr<15-8> -> CRTCC<7-0>
 824   addr<7-0> -> CRTCD<7-0>
 825   CRTCEXT0 has to be programmed last to trigger an update and make the
 826   new addr variable take effect.
 827 */
 828static void mga_set_start_address(struct drm_crtc *crtc, unsigned offset)
 829{
 830        struct mga_device *mdev = crtc->dev->dev_private;
 831        u32 addr;
 832        int count;
 833        u8 crtcext0;
 834
 835        while (RREG8(0x1fda) & 0x08);
 836        while (!(RREG8(0x1fda) & 0x08));
 837
 838        count = RREG8(MGAREG_VCOUNT) + 2;
 839        while (RREG8(MGAREG_VCOUNT) < count);
 840
 841        WREG8(MGAREG_CRTCEXT_INDEX, 0);
 842        crtcext0 = RREG8(MGAREG_CRTCEXT_DATA);
 843        crtcext0 &= 0xB0;
 844        addr = offset / 8;
 845        /* Can't store addresses any higher than that...
 846           but we also don't have more than 16MB of memory, so it should be fine. */
 847        WARN_ON(addr > 0x1fffff);
 848        crtcext0 |= (!!(addr & (1<<20)))<<6;
 849        WREG_CRT(0x0d, (u8)(addr & 0xff));
 850        WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff);
 851        WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0);
 852}
 853
 854
 855/* ast is different - we will force move buffers out of VRAM */
 856static int mga_crtc_do_set_base(struct drm_crtc *crtc,
 857                                struct drm_framebuffer *fb,
 858                                int x, int y, int atomic)
 859{
 860        struct mga_device *mdev = crtc->dev->dev_private;
 861        struct drm_gem_object *obj;
 862        struct mga_framebuffer *mga_fb;
 863        struct mgag200_bo *bo;
 864        int ret;
 865        u64 gpu_addr;
 866
 867        /* push the previous fb to system ram */
 868        if (!atomic && fb) {
 869                mga_fb = to_mga_framebuffer(fb);
 870                obj = mga_fb->obj;
 871                bo = gem_to_mga_bo(obj);
 872                ret = mgag200_bo_reserve(bo, false);
 873                if (ret)
 874                        return ret;
 875                mgag200_bo_push_sysram(bo);
 876                mgag200_bo_unreserve(bo);
 877        }
 878
 879        mga_fb = to_mga_framebuffer(crtc->primary->fb);
 880        obj = mga_fb->obj;
 881        bo = gem_to_mga_bo(obj);
 882
 883        ret = mgag200_bo_reserve(bo, false);
 884        if (ret)
 885                return ret;
 886
 887        ret = mgag200_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
 888        if (ret) {
 889                mgag200_bo_unreserve(bo);
 890                return ret;
 891        }
 892
 893        if (&mdev->mfbdev->mfb == mga_fb) {
 894                /* if pushing console in kmap it */
 895                ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
 896                if (ret)
 897                        DRM_ERROR("failed to kmap fbcon\n");
 898
 899        }
 900        mgag200_bo_unreserve(bo);
 901
 902        mga_set_start_address(crtc, (u32)gpu_addr);
 903
 904        return 0;
 905}
 906
 907static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 908                                  struct drm_framebuffer *old_fb)
 909{
 910        return mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
 911}
 912
 913static int mga_crtc_mode_set(struct drm_crtc *crtc,
 914                                struct drm_display_mode *mode,
 915                                struct drm_display_mode *adjusted_mode,
 916                                int x, int y, struct drm_framebuffer *old_fb)
 917{
 918        struct drm_device *dev = crtc->dev;
 919        struct mga_device *mdev = dev->dev_private;
 920        const struct drm_framebuffer *fb = crtc->primary->fb;
 921        int hdisplay, hsyncstart, hsyncend, htotal;
 922        int vdisplay, vsyncstart, vsyncend, vtotal;
 923        int pitch;
 924        int option = 0, option2 = 0;
 925        int i;
 926        unsigned char misc = 0;
 927        unsigned char ext_vga[6];
 928        u8 bppshift;
 929
 930        static unsigned char dacvalue[] = {
 931                /* 0x00: */        0,    0,    0,    0,    0,    0, 0x00,    0,
 932                /* 0x08: */        0,    0,    0,    0,    0,    0,    0,    0,
 933                /* 0x10: */        0,    0,    0,    0,    0,    0,    0,    0,
 934                /* 0x18: */     0x00,    0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
 935                /* 0x20: */     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 936                /* 0x28: */     0x00, 0x00, 0x00, 0x00,    0,    0,    0, 0x40,
 937                /* 0x30: */     0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
 938                /* 0x38: */     0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
 939                /* 0x40: */        0,    0,    0,    0,    0,    0,    0,    0,
 940                /* 0x48: */        0,    0,    0,    0,    0,    0,    0,    0
 941        };
 942
 943        bppshift = mdev->bpp_shifts[fb->format->cpp[0] - 1];
 944
 945        switch (mdev->type) {
 946        case G200_SE_A:
 947        case G200_SE_B:
 948                dacvalue[MGA1064_VREF_CTL] = 0x03;
 949                dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
 950                dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_DAC_EN |
 951                                             MGA1064_MISC_CTL_VGA8 |
 952                                             MGA1064_MISC_CTL_DAC_RAM_CS;
 953                if (mdev->has_sdram)
 954                        option = 0x40049120;
 955                else
 956                        option = 0x4004d120;
 957                option2 = 0x00008000;
 958                break;
 959        case G200_WB:
 960        case G200_EW3:
 961                dacvalue[MGA1064_VREF_CTL] = 0x07;
 962                option = 0x41049120;
 963                option2 = 0x0000b000;
 964                break;
 965        case G200_EV:
 966                dacvalue[MGA1064_PIX_CLK_CTL] = MGA1064_PIX_CLK_CTL_SEL_PLL;
 967                dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
 968                                             MGA1064_MISC_CTL_DAC_RAM_CS;
 969                option = 0x00000120;
 970                option2 = 0x0000b000;
 971                break;
 972        case G200_EH:
 973        case G200_EH3:
 974                dacvalue[MGA1064_MISC_CTL] = MGA1064_MISC_CTL_VGA8 |
 975                                             MGA1064_MISC_CTL_DAC_RAM_CS;
 976                option = 0x00000120;
 977                option2 = 0x0000b000;
 978                break;
 979        case G200_ER:
 980                break;
 981        }
 982
 983        switch (fb->format->cpp[0] * 8) {
 984        case 8:
 985                dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_8bits;
 986                break;
 987        case 16:
 988                if (fb->format->depth == 15)
 989                        dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_15bits;
 990                else
 991                        dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_16bits;
 992                break;
 993        case 24:
 994                dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_24bits;
 995                break;
 996        case 32:
 997                dacvalue[MGA1064_MUL_CTL] = MGA1064_MUL_CTL_32_24bits;
 998                break;
 999        }
1000
1001        if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1002                misc |= 0x40;
1003        if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1004                misc |= 0x80;
1005
1006
1007        for (i = 0; i < sizeof(dacvalue); i++) {
1008                if ((i <= 0x17) ||
1009                    (i == 0x1b) ||
1010                    (i == 0x1c) ||
1011                    ((i >= 0x1f) && (i <= 0x29)) ||
1012                    ((i >= 0x30) && (i <= 0x37)))
1013                        continue;
1014                if (IS_G200_SE(mdev) &&
1015                    ((i == 0x2c) || (i == 0x2d) || (i == 0x2e)))
1016                        continue;
1017                if ((mdev->type == G200_EV ||
1018                    mdev->type == G200_WB ||
1019                    mdev->type == G200_EH ||
1020                    mdev->type == G200_EW3 ||
1021                    mdev->type == G200_EH3) &&
1022                    (i >= 0x44) && (i <= 0x4e))
1023                        continue;
1024
1025                WREG_DAC(i, dacvalue[i]);
1026        }
1027
1028        if (mdev->type == G200_ER)
1029                WREG_DAC(0x90, 0);
1030
1031        if (option)
1032                pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
1033        if (option2)
1034                pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
1035
1036        WREG_SEQ(2, 0xf);
1037        WREG_SEQ(3, 0);
1038        WREG_SEQ(4, 0xe);
1039
1040        pitch = fb->pitches[0] / fb->format->cpp[0];
1041        if (fb->format->cpp[0] * 8 == 24)
1042                pitch = (pitch * 3) >> (4 - bppshift);
1043        else
1044                pitch = pitch >> (4 - bppshift);
1045
1046        hdisplay = mode->hdisplay / 8 - 1;
1047        hsyncstart = mode->hsync_start / 8 - 1;
1048        hsyncend = mode->hsync_end / 8 - 1;
1049        htotal = mode->htotal / 8 - 1;
1050
1051        /* Work around hardware quirk */
1052        if ((htotal & 0x07) == 0x06 || (htotal & 0x07) == 0x04)
1053                htotal++;
1054
1055        vdisplay = mode->vdisplay - 1;
1056        vsyncstart = mode->vsync_start - 1;
1057        vsyncend = mode->vsync_end - 1;
1058        vtotal = mode->vtotal - 2;
1059
1060        WREG_GFX(0, 0);
1061        WREG_GFX(1, 0);
1062        WREG_GFX(2, 0);
1063        WREG_GFX(3, 0);
1064        WREG_GFX(4, 0);
1065        WREG_GFX(5, 0x40);
1066        WREG_GFX(6, 0x5);
1067        WREG_GFX(7, 0xf);
1068        WREG_GFX(8, 0xf);
1069
1070        WREG_CRT(0, htotal - 4);
1071        WREG_CRT(1, hdisplay);
1072        WREG_CRT(2, hdisplay);
1073        WREG_CRT(3, (htotal & 0x1F) | 0x80);
1074        WREG_CRT(4, hsyncstart);
1075        WREG_CRT(5, ((htotal & 0x20) << 2) | (hsyncend & 0x1F));
1076        WREG_CRT(6, vtotal & 0xFF);
1077        WREG_CRT(7, ((vtotal & 0x100) >> 8) |
1078                 ((vdisplay & 0x100) >> 7) |
1079                 ((vsyncstart & 0x100) >> 6) |
1080                 ((vdisplay & 0x100) >> 5) |
1081                 ((vdisplay & 0x100) >> 4) | /* linecomp */
1082                 ((vtotal & 0x200) >> 4)|
1083                 ((vdisplay & 0x200) >> 3) |
1084                 ((vsyncstart & 0x200) >> 2));
1085        WREG_CRT(9, ((vdisplay & 0x200) >> 4) |
1086                 ((vdisplay & 0x200) >> 3));
1087        WREG_CRT(10, 0);
1088        WREG_CRT(11, 0);
1089        WREG_CRT(12, 0);
1090        WREG_CRT(13, 0);
1091        WREG_CRT(14, 0);
1092        WREG_CRT(15, 0);
1093        WREG_CRT(16, vsyncstart & 0xFF);
1094        WREG_CRT(17, (vsyncend & 0x0F) | 0x20);
1095        WREG_CRT(18, vdisplay & 0xFF);
1096        WREG_CRT(19, pitch & 0xFF);
1097        WREG_CRT(20, 0);
1098        WREG_CRT(21, vdisplay & 0xFF);
1099        WREG_CRT(22, (vtotal + 1) & 0xFF);
1100        WREG_CRT(23, 0xc3);
1101        WREG_CRT(24, vdisplay & 0xFF);
1102
1103        ext_vga[0] = 0;
1104        ext_vga[5] = 0;
1105
1106        /* TODO interlace */
1107
1108        ext_vga[0] |= (pitch & 0x300) >> 4;
1109        ext_vga[1] = (((htotal - 4) & 0x100) >> 8) |
1110                ((hdisplay & 0x100) >> 7) |
1111                ((hsyncstart & 0x100) >> 6) |
1112                (htotal & 0x40);
1113        ext_vga[2] = ((vtotal & 0xc00) >> 10) |
1114                ((vdisplay & 0x400) >> 8) |
1115                ((vdisplay & 0xc00) >> 7) |
1116                ((vsyncstart & 0xc00) >> 5) |
1117                ((vdisplay & 0x400) >> 3);
1118        if (fb->format->cpp[0] * 8 == 24)
1119                ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80;
1120        else
1121                ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
1122        ext_vga[4] = 0;
1123        if (mdev->type == G200_WB || mdev->type == G200_EW3)
1124                ext_vga[1] |= 0x88;
1125
1126        /* Set pixel clocks */
1127        misc = 0x2d;
1128        WREG8(MGA_MISC_OUT, misc);
1129
1130        mga_crtc_set_plls(mdev, mode->clock);
1131
1132        for (i = 0; i < 6; i++) {
1133                WREG_ECRT(i, ext_vga[i]);
1134        }
1135
1136        if (mdev->type == G200_ER)
1137                WREG_ECRT(0x24, 0x5);
1138
1139        if (mdev->type == G200_EW3)
1140                WREG_ECRT(0x34, 0x5);
1141
1142        if (mdev->type == G200_EV) {
1143                WREG_ECRT(6, 0);
1144        }
1145
1146        WREG_ECRT(0, ext_vga[0]);
1147        /* Enable mga pixel clock */
1148        misc = 0x2d;
1149
1150        WREG8(MGA_MISC_OUT, misc);
1151
1152        if (adjusted_mode)
1153                memcpy(&mdev->mode, mode, sizeof(struct drm_display_mode));
1154
1155        mga_crtc_do_set_base(crtc, old_fb, x, y, 0);
1156
1157        /* reset tagfifo */
1158        if (mdev->type == G200_ER) {
1159                u32 mem_ctl = RREG32(MGAREG_MEMCTL);
1160                u8 seq1;
1161
1162                /* screen off */
1163                WREG8(MGAREG_SEQ_INDEX, 0x01);
1164                seq1 = RREG8(MGAREG_SEQ_DATA) | 0x20;
1165                WREG8(MGAREG_SEQ_DATA, seq1);
1166
1167                WREG32(MGAREG_MEMCTL, mem_ctl | 0x00200000);
1168                udelay(1000);
1169                WREG32(MGAREG_MEMCTL, mem_ctl & ~0x00200000);
1170
1171                WREG8(MGAREG_SEQ_DATA, seq1 & ~0x20);
1172        }
1173
1174
1175        if (IS_G200_SE(mdev)) {
1176                if  (mdev->unique_rev_id >= 0x04) {
1177                        WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1178                        WREG8(MGAREG_CRTCEXT_DATA, 0);
1179                } else if (mdev->unique_rev_id >= 0x02) {
1180                        u8 hi_pri_lvl;
1181                        u32 bpp;
1182                        u32 mb;
1183
1184                        if (fb->format->cpp[0] * 8 > 16)
1185                                bpp = 32;
1186                        else if (fb->format->cpp[0] * 8 > 8)
1187                                bpp = 16;
1188                        else
1189                                bpp = 8;
1190
1191                        mb = (mode->clock * bpp) / 1000;
1192                        if (mb > 3100)
1193                                hi_pri_lvl = 0;
1194                        else if (mb > 2600)
1195                                hi_pri_lvl = 1;
1196                        else if (mb > 1900)
1197                                hi_pri_lvl = 2;
1198                        else if (mb > 1160)
1199                                hi_pri_lvl = 3;
1200                        else if (mb > 440)
1201                                hi_pri_lvl = 4;
1202                        else
1203                                hi_pri_lvl = 5;
1204
1205                        WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1206                        WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl);
1207                } else {
1208                        WREG8(MGAREG_CRTCEXT_INDEX, 0x06);
1209                        if (mdev->unique_rev_id >= 0x01)
1210                                WREG8(MGAREG_CRTCEXT_DATA, 0x03);
1211                        else
1212                                WREG8(MGAREG_CRTCEXT_DATA, 0x04);
1213                }
1214        }
1215        return 0;
1216}
1217
1218#if 0 /* code from mjg to attempt D3 on crtc dpms off - revisit later */
1219static int mga_suspend(struct drm_crtc *crtc)
1220{
1221        struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1222        struct drm_device *dev = crtc->dev;
1223        struct mga_device *mdev = dev->dev_private;
1224        struct pci_dev *pdev = dev->pdev;
1225        int option;
1226
1227        if (mdev->suspended)
1228                return 0;
1229
1230        WREG_SEQ(1, 0x20);
1231        WREG_ECRT(1, 0x30);
1232        /* Disable the pixel clock */
1233        WREG_DAC(0x1a, 0x05);
1234        /* Power down the DAC */
1235        WREG_DAC(0x1e, 0x18);
1236        /* Power down the pixel PLL */
1237        WREG_DAC(0x1a, 0x0d);
1238
1239        /* Disable PLLs and clocks */
1240        pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1241        option &= ~(0x1F8024);
1242        pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1243        pci_set_power_state(pdev, PCI_D3hot);
1244        pci_disable_device(pdev);
1245
1246        mdev->suspended = true;
1247
1248        return 0;
1249}
1250
1251static int mga_resume(struct drm_crtc *crtc)
1252{
1253        struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1254        struct drm_device *dev = crtc->dev;
1255        struct mga_device *mdev = dev->dev_private;
1256        struct pci_dev *pdev = dev->pdev;
1257        int option;
1258
1259        if (!mdev->suspended)
1260                return 0;
1261
1262        pci_set_power_state(pdev, PCI_D0);
1263        pci_enable_device(pdev);
1264
1265        /* Disable sysclk */
1266        pci_read_config_dword(pdev, PCI_MGA_OPTION, &option);
1267        option &= ~(0x4);
1268        pci_write_config_dword(pdev, PCI_MGA_OPTION, option);
1269
1270        mdev->suspended = false;
1271
1272        return 0;
1273}
1274
1275#endif
1276
1277static void mga_crtc_dpms(struct drm_crtc *crtc, int mode)
1278{
1279        struct drm_device *dev = crtc->dev;
1280        struct mga_device *mdev = dev->dev_private;
1281        u8 seq1 = 0, crtcext1 = 0;
1282
1283        switch (mode) {
1284        case DRM_MODE_DPMS_ON:
1285                seq1 = 0;
1286                crtcext1 = 0;
1287                mga_crtc_load_lut(crtc);
1288                break;
1289        case DRM_MODE_DPMS_STANDBY:
1290                seq1 = 0x20;
1291                crtcext1 = 0x10;
1292                break;
1293        case DRM_MODE_DPMS_SUSPEND:
1294                seq1 = 0x20;
1295                crtcext1 = 0x20;
1296                break;
1297        case DRM_MODE_DPMS_OFF:
1298                seq1 = 0x20;
1299                crtcext1 = 0x30;
1300                break;
1301        }
1302
1303#if 0
1304        if (mode == DRM_MODE_DPMS_OFF) {
1305                mga_suspend(crtc);
1306        }
1307#endif
1308        WREG8(MGAREG_SEQ_INDEX, 0x01);
1309        seq1 |= RREG8(MGAREG_SEQ_DATA) & ~0x20;
1310        mga_wait_vsync(mdev);
1311        mga_wait_busy(mdev);
1312        WREG8(MGAREG_SEQ_DATA, seq1);
1313        msleep(20);
1314        WREG8(MGAREG_CRTCEXT_INDEX, 0x01);
1315        crtcext1 |= RREG8(MGAREG_CRTCEXT_DATA) & ~0x30;
1316        WREG8(MGAREG_CRTCEXT_DATA, crtcext1);
1317
1318#if 0
1319        if (mode == DRM_MODE_DPMS_ON && mdev->suspended == true) {
1320                mga_resume(crtc);
1321                drm_helper_resume_force_mode(dev);
1322        }
1323#endif
1324}
1325
1326/*
1327 * This is called before a mode is programmed. A typical use might be to
1328 * enable DPMS during the programming to avoid seeing intermediate stages,
1329 * but that's not relevant to us
1330 */
1331static void mga_crtc_prepare(struct drm_crtc *crtc)
1332{
1333        struct drm_device *dev = crtc->dev;
1334        struct mga_device *mdev = dev->dev_private;
1335        u8 tmp;
1336
1337        /*      mga_resume(crtc);*/
1338
1339        WREG8(MGAREG_CRTC_INDEX, 0x11);
1340        tmp = RREG8(MGAREG_CRTC_DATA);
1341        WREG_CRT(0x11, tmp | 0x80);
1342
1343        if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1344                WREG_SEQ(0, 1);
1345                msleep(50);
1346                WREG_SEQ(1, 0x20);
1347                msleep(20);
1348        } else {
1349                WREG8(MGAREG_SEQ_INDEX, 0x1);
1350                tmp = RREG8(MGAREG_SEQ_DATA);
1351
1352                /* start sync reset */
1353                WREG_SEQ(0, 1);
1354                WREG_SEQ(1, tmp | 0x20);
1355        }
1356
1357        if (mdev->type == G200_WB || mdev->type == G200_EW3)
1358                mga_g200wb_prepare(crtc);
1359
1360        WREG_CRT(17, 0);
1361}
1362
1363/*
1364 * This is called after a mode is programmed. It should reverse anything done
1365 * by the prepare function
1366 */
1367static void mga_crtc_commit(struct drm_crtc *crtc)
1368{
1369        struct drm_device *dev = crtc->dev;
1370        struct mga_device *mdev = dev->dev_private;
1371        const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1372        u8 tmp;
1373
1374        if (mdev->type == G200_WB || mdev->type == G200_EW3)
1375                mga_g200wb_commit(crtc);
1376
1377        if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {
1378                msleep(50);
1379                WREG_SEQ(1, 0x0);
1380                msleep(20);
1381                WREG_SEQ(0, 0x3);
1382        } else {
1383                WREG8(MGAREG_SEQ_INDEX, 0x1);
1384                tmp = RREG8(MGAREG_SEQ_DATA);
1385
1386                tmp &= ~0x20;
1387                WREG_SEQ(0x1, tmp);
1388                WREG_SEQ(0, 3);
1389        }
1390        crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1391}
1392
1393/*
1394 * The core can pass us a set of gamma values to program. We actually only
1395 * use this for 8-bit mode so can't perform smooth fades on deeper modes,
1396 * but it's a requirement that we provide the function
1397 */
1398static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1399                              u16 *blue, uint32_t size,
1400                              struct drm_modeset_acquire_ctx *ctx)
1401{
1402        struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1403        int i;
1404
1405        for (i = 0; i < size; i++) {
1406                mga_crtc->lut_r[i] = red[i] >> 8;
1407                mga_crtc->lut_g[i] = green[i] >> 8;
1408                mga_crtc->lut_b[i] = blue[i] >> 8;
1409        }
1410        mga_crtc_load_lut(crtc);
1411
1412        return 0;
1413}
1414
1415/* Simple cleanup function */
1416static void mga_crtc_destroy(struct drm_crtc *crtc)
1417{
1418        struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1419
1420        drm_crtc_cleanup(crtc);
1421        kfree(mga_crtc);
1422}
1423
1424static void mga_crtc_disable(struct drm_crtc *crtc)
1425{
1426        int ret;
1427        DRM_DEBUG_KMS("\n");
1428        mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
1429        if (crtc->primary->fb) {
1430                struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->primary->fb);
1431                struct drm_gem_object *obj = mga_fb->obj;
1432                struct mgag200_bo *bo = gem_to_mga_bo(obj);
1433                ret = mgag200_bo_reserve(bo, false);
1434                if (ret)
1435                        return;
1436                mgag200_bo_push_sysram(bo);
1437                mgag200_bo_unreserve(bo);
1438        }
1439        crtc->primary->fb = NULL;
1440}
1441
1442/* These provide the minimum set of functions required to handle a CRTC */
1443static const struct drm_crtc_funcs mga_crtc_funcs = {
1444        .cursor_set = mga_crtc_cursor_set,
1445        .cursor_move = mga_crtc_cursor_move,
1446        .gamma_set = mga_crtc_gamma_set,
1447        .set_config = drm_crtc_helper_set_config,
1448        .destroy = mga_crtc_destroy,
1449};
1450
1451static const struct drm_crtc_helper_funcs mga_helper_funcs = {
1452        .disable = mga_crtc_disable,
1453        .dpms = mga_crtc_dpms,
1454        .mode_set = mga_crtc_mode_set,
1455        .mode_set_base = mga_crtc_mode_set_base,
1456        .prepare = mga_crtc_prepare,
1457        .commit = mga_crtc_commit,
1458        .load_lut = mga_crtc_load_lut,
1459};
1460
1461/* CRTC setup */
1462static void mga_crtc_init(struct mga_device *mdev)
1463{
1464        struct mga_crtc *mga_crtc;
1465        int i;
1466
1467        mga_crtc = kzalloc(sizeof(struct mga_crtc) +
1468                              (MGAG200FB_CONN_LIMIT * sizeof(struct drm_connector *)),
1469                              GFP_KERNEL);
1470
1471        if (mga_crtc == NULL)
1472                return;
1473
1474        drm_crtc_init(mdev->dev, &mga_crtc->base, &mga_crtc_funcs);
1475
1476        drm_mode_crtc_set_gamma_size(&mga_crtc->base, MGAG200_LUT_SIZE);
1477        mdev->mode_info.crtc = mga_crtc;
1478
1479        for (i = 0; i < MGAG200_LUT_SIZE; i++) {
1480                mga_crtc->lut_r[i] = i;
1481                mga_crtc->lut_g[i] = i;
1482                mga_crtc->lut_b[i] = i;
1483        }
1484
1485        drm_crtc_helper_add(&mga_crtc->base, &mga_helper_funcs);
1486}
1487
1488/** Sets the color ramps on behalf of fbcon */
1489void mga_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
1490                              u16 blue, int regno)
1491{
1492        struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1493
1494        mga_crtc->lut_r[regno] = red >> 8;
1495        mga_crtc->lut_g[regno] = green >> 8;
1496        mga_crtc->lut_b[regno] = blue >> 8;
1497}
1498
1499/** Gets the color ramps on behalf of fbcon */
1500void mga_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
1501                              u16 *blue, int regno)
1502{
1503        struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1504
1505        *red = (u16)mga_crtc->lut_r[regno] << 8;
1506        *green = (u16)mga_crtc->lut_g[regno] << 8;
1507        *blue = (u16)mga_crtc->lut_b[regno] << 8;
1508}
1509
1510/*
1511 * The encoder comes after the CRTC in the output pipeline, but before
1512 * the connector. It's responsible for ensuring that the digital
1513 * stream is appropriately converted into the output format. Setup is
1514 * very simple in this case - all we have to do is inform qemu of the
1515 * colour depth in order to ensure that it displays appropriately
1516 */
1517
1518/*
1519 * These functions are analagous to those in the CRTC code, but are intended
1520 * to handle any encoder-specific limitations
1521 */
1522static void mga_encoder_mode_set(struct drm_encoder *encoder,
1523                                struct drm_display_mode *mode,
1524                                struct drm_display_mode *adjusted_mode)
1525{
1526
1527}
1528
1529static void mga_encoder_dpms(struct drm_encoder *encoder, int state)
1530{
1531        return;
1532}
1533
1534static void mga_encoder_prepare(struct drm_encoder *encoder)
1535{
1536}
1537
1538static void mga_encoder_commit(struct drm_encoder *encoder)
1539{
1540}
1541
1542static void mga_encoder_destroy(struct drm_encoder *encoder)
1543{
1544        struct mga_encoder *mga_encoder = to_mga_encoder(encoder);
1545        drm_encoder_cleanup(encoder);
1546        kfree(mga_encoder);
1547}
1548
1549static const struct drm_encoder_helper_funcs mga_encoder_helper_funcs = {
1550        .dpms = mga_encoder_dpms,
1551        .mode_set = mga_encoder_mode_set,
1552        .prepare = mga_encoder_prepare,
1553        .commit = mga_encoder_commit,
1554};
1555
1556static const struct drm_encoder_funcs mga_encoder_encoder_funcs = {
1557        .destroy = mga_encoder_destroy,
1558};
1559
1560static struct drm_encoder *mga_encoder_init(struct drm_device *dev)
1561{
1562        struct drm_encoder *encoder;
1563        struct mga_encoder *mga_encoder;
1564
1565        mga_encoder = kzalloc(sizeof(struct mga_encoder), GFP_KERNEL);
1566        if (!mga_encoder)
1567                return NULL;
1568
1569        encoder = &mga_encoder->base;
1570        encoder->possible_crtcs = 0x1;
1571
1572        drm_encoder_init(dev, encoder, &mga_encoder_encoder_funcs,
1573                         DRM_MODE_ENCODER_DAC, NULL);
1574        drm_encoder_helper_add(encoder, &mga_encoder_helper_funcs);
1575
1576        return encoder;
1577}
1578
1579
1580static int mga_vga_get_modes(struct drm_connector *connector)
1581{
1582        struct mga_connector *mga_connector = to_mga_connector(connector);
1583        struct edid *edid;
1584        int ret = 0;
1585
1586        edid = drm_get_edid(connector, &mga_connector->i2c->adapter);
1587        if (edid) {
1588                drm_mode_connector_update_edid_property(connector, edid);
1589                ret = drm_add_edid_modes(connector, edid);
1590                kfree(edid);
1591        }
1592        return ret;
1593}
1594
1595static uint32_t mga_vga_calculate_mode_bandwidth(struct drm_display_mode *mode,
1596                                                        int bits_per_pixel)
1597{
1598        uint32_t total_area, divisor;
1599        uint64_t active_area, pixels_per_second, bandwidth;
1600        uint64_t bytes_per_pixel = (bits_per_pixel + 7) / 8;
1601
1602        divisor = 1024;
1603
1604        if (!mode->htotal || !mode->vtotal || !mode->clock)
1605                return 0;
1606
1607        active_area = mode->hdisplay * mode->vdisplay;
1608        total_area = mode->htotal * mode->vtotal;
1609
1610        pixels_per_second = active_area * mode->clock * 1000;
1611        do_div(pixels_per_second, total_area);
1612
1613        bandwidth = pixels_per_second * bytes_per_pixel * 100;
1614        do_div(bandwidth, divisor);
1615
1616        return (uint32_t)(bandwidth);
1617}
1618
1619#define MODE_BANDWIDTH  MODE_BAD
1620
1621static int mga_vga_mode_valid(struct drm_connector *connector,
1622                                 struct drm_display_mode *mode)
1623{
1624        struct drm_device *dev = connector->dev;
1625        struct mga_device *mdev = (struct mga_device*)dev->dev_private;
1626        int bpp = 32;
1627
1628        if (IS_G200_SE(mdev)) {
1629                if (mdev->unique_rev_id == 0x01) {
1630                        if (mode->hdisplay > 1600)
1631                                return MODE_VIRTUAL_X;
1632                        if (mode->vdisplay > 1200)
1633                                return MODE_VIRTUAL_Y;
1634                        if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1635                                > (24400 * 1024))
1636                                return MODE_BANDWIDTH;
1637                } else if (mdev->unique_rev_id == 0x02) {
1638                        if (mode->hdisplay > 1920)
1639                                return MODE_VIRTUAL_X;
1640                        if (mode->vdisplay > 1200)
1641                                return MODE_VIRTUAL_Y;
1642                        if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1643                                > (30100 * 1024))
1644                                return MODE_BANDWIDTH;
1645                } else {
1646                        if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1647                                > (55000 * 1024))
1648                                return MODE_BANDWIDTH;
1649                }
1650        } else if (mdev->type == G200_WB) {
1651                if (mode->hdisplay > 1280)
1652                        return MODE_VIRTUAL_X;
1653                if (mode->vdisplay > 1024)
1654                        return MODE_VIRTUAL_Y;
1655                if (mga_vga_calculate_mode_bandwidth(mode,
1656                        bpp > (31877 * 1024)))
1657                        return MODE_BANDWIDTH;
1658        } else if (mdev->type == G200_EV &&
1659                (mga_vga_calculate_mode_bandwidth(mode, bpp)
1660                        > (32700 * 1024))) {
1661                return MODE_BANDWIDTH;
1662        } else if (mdev->type == G200_EH &&
1663                (mga_vga_calculate_mode_bandwidth(mode, bpp)
1664                        > (37500 * 1024))) {
1665                return MODE_BANDWIDTH;
1666        } else if (mdev->type == G200_ER &&
1667                (mga_vga_calculate_mode_bandwidth(mode,
1668                        bpp) > (55000 * 1024))) {
1669                return MODE_BANDWIDTH;
1670        }
1671
1672        if ((mode->hdisplay % 8) != 0 || (mode->hsync_start % 8) != 0 ||
1673            (mode->hsync_end % 8) != 0 || (mode->htotal % 8) != 0) {
1674                return MODE_H_ILLEGAL;
1675        }
1676
1677        if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 ||
1678            mode->crtc_hsync_end > 4096 || mode->crtc_htotal > 4096 ||
1679            mode->crtc_vdisplay > 2048 || mode->crtc_vsync_start > 4096 ||
1680            mode->crtc_vsync_end > 4096 || mode->crtc_vtotal > 4096) {
1681                return MODE_BAD;
1682        }
1683
1684        /* Validate the mode input by the user */
1685        if (connector->cmdline_mode.specified) {
1686                if (connector->cmdline_mode.bpp_specified)
1687                        bpp = connector->cmdline_mode.bpp;
1688        }
1689
1690        if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) {
1691                if (connector->cmdline_mode.specified)
1692                        connector->cmdline_mode.specified = false;
1693                return MODE_BAD;
1694        }
1695
1696        return MODE_OK;
1697}
1698
1699static struct drm_encoder *mga_connector_best_encoder(struct drm_connector
1700                                                  *connector)
1701{
1702        int enc_id = connector->encoder_ids[0];
1703        /* pick the encoder ids */
1704        if (enc_id)
1705                return drm_encoder_find(connector->dev, enc_id);
1706        return NULL;
1707}
1708
1709static void mga_connector_destroy(struct drm_connector *connector)
1710{
1711        struct mga_connector *mga_connector = to_mga_connector(connector);
1712        mgag200_i2c_destroy(mga_connector->i2c);
1713        drm_connector_cleanup(connector);
1714        kfree(connector);
1715}
1716
1717static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = {
1718        .get_modes = mga_vga_get_modes,
1719        .mode_valid = mga_vga_mode_valid,
1720        .best_encoder = mga_connector_best_encoder,
1721};
1722
1723static const struct drm_connector_funcs mga_vga_connector_funcs = {
1724        .dpms = drm_helper_connector_dpms,
1725        .fill_modes = drm_helper_probe_single_connector_modes,
1726        .destroy = mga_connector_destroy,
1727};
1728
1729static struct drm_connector *mga_vga_init(struct drm_device *dev)
1730{
1731        struct drm_connector *connector;
1732        struct mga_connector *mga_connector;
1733
1734        mga_connector = kzalloc(sizeof(struct mga_connector), GFP_KERNEL);
1735        if (!mga_connector)
1736                return NULL;
1737
1738        connector = &mga_connector->base;
1739
1740        drm_connector_init(dev, connector,
1741                           &mga_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA);
1742
1743        drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
1744
1745        drm_connector_register(connector);
1746
1747        mga_connector->i2c = mgag200_i2c_create(dev);
1748        if (!mga_connector->i2c)
1749                DRM_ERROR("failed to add ddc bus\n");
1750
1751        return connector;
1752}
1753
1754
1755int mgag200_modeset_init(struct mga_device *mdev)
1756{
1757        struct drm_encoder *encoder;
1758        struct drm_connector *connector;
1759        int ret;
1760
1761        mdev->mode_info.mode_config_initialized = true;
1762
1763        mdev->dev->mode_config.max_width = MGAG200_MAX_FB_WIDTH;
1764        mdev->dev->mode_config.max_height = MGAG200_MAX_FB_HEIGHT;
1765
1766        mdev->dev->mode_config.fb_base = mdev->mc.vram_base;
1767
1768        mga_crtc_init(mdev);
1769
1770        encoder = mga_encoder_init(mdev->dev);
1771        if (!encoder) {
1772                DRM_ERROR("mga_encoder_init failed\n");
1773                return -1;
1774        }
1775
1776        connector = mga_vga_init(mdev->dev);
1777        if (!connector) {
1778                DRM_ERROR("mga_vga_init failed\n");
1779                return -1;
1780        }
1781
1782        drm_mode_connector_attach_encoder(connector, encoder);
1783
1784        ret = mgag200_fbdev_init(mdev);
1785        if (ret) {
1786                DRM_ERROR("mga_fbdev_init failed\n");
1787                return ret;
1788        }
1789
1790        return 0;
1791}
1792
1793void mgag200_modeset_fini(struct mga_device *mdev)
1794{
1795
1796}
1797