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