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