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