intelfbhw.c revision 3f7a26b4b9768fe31597d1af35106aa512dc3742
1/* 2 * intelfb 3 * 4 * Linux framebuffer driver for Intel(R) 865G integrated graphics chips. 5 * 6 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> 7 * 2004 Sylvain Meyer 8 * 9 * This driver consists of two parts. The first part (intelfbdrv.c) provides 10 * the basic fbdev interfaces, is derived in part from the radeonfb and 11 * vesafb drivers, and is covered by the GPL. The second part (intelfbhw.c) 12 * provides the code to program the hardware. Most of it is derived from 13 * the i810/i830 XFree86 driver. The HW-specific code is covered here 14 * under a dual license (GPL and MIT/XFree86 license). 15 * 16 * Author: David Dawes 17 * 18 */ 19 20/* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */ 21 22#include <linux/module.h> 23#include <linux/kernel.h> 24#include <linux/errno.h> 25#include <linux/string.h> 26#include <linux/mm.h> 27#include <linux/slab.h> 28#include <linux/delay.h> 29#include <linux/fb.h> 30#include <linux/ioport.h> 31#include <linux/init.h> 32#include <linux/pci.h> 33#include <linux/vmalloc.h> 34#include <linux/pagemap.h> 35#include <linux/interrupt.h> 36 37#include <asm/io.h> 38 39#include "intelfb.h" 40#include "intelfbhw.h" 41 42struct pll_min_max { 43 int min_m, max_m, min_m1, max_m1; 44 int min_m2, max_m2, min_n, max_n; 45 int min_p, max_p, min_p1, max_p1; 46 int min_vco, max_vco, p_transition_clk, ref_clk; 47 int p_inc_lo, p_inc_hi; 48}; 49 50#define PLLS_I8xx 0 51#define PLLS_I9xx 1 52#define PLLS_MAX 2 53 54static struct pll_min_max plls[PLLS_MAX] = { 55 { 108, 140, 18, 26, 56 6, 16, 3, 16, 57 4, 128, 0, 31, 58 930000, 1400000, 165000, 48000, 59 4, 2 }, /* I8xx */ 60 61 { 75, 120, 10, 20, 62 5, 9, 4, 7, 63 5, 80, 1, 8, 64 1400000, 2800000, 200000, 96000, 65 10, 5 } /* I9xx */ 66}; 67 68int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo) 69{ 70 u32 tmp; 71 if (!pdev || !dinfo) 72 return 1; 73 74 switch (pdev->device) { 75 case PCI_DEVICE_ID_INTEL_830M: 76 dinfo->name = "Intel(R) 830M"; 77 dinfo->chipset = INTEL_830M; 78 dinfo->mobile = 1; 79 dinfo->pll_index = PLLS_I8xx; 80 return 0; 81 case PCI_DEVICE_ID_INTEL_845G: 82 dinfo->name = "Intel(R) 845G"; 83 dinfo->chipset = INTEL_845G; 84 dinfo->mobile = 0; 85 dinfo->pll_index = PLLS_I8xx; 86 return 0; 87 case PCI_DEVICE_ID_INTEL_85XGM: 88 tmp = 0; 89 dinfo->mobile = 1; 90 dinfo->pll_index = PLLS_I8xx; 91 pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp); 92 switch ((tmp >> INTEL_85X_VARIANT_SHIFT) & 93 INTEL_85X_VARIANT_MASK) { 94 case INTEL_VAR_855GME: 95 dinfo->name = "Intel(R) 855GME"; 96 dinfo->chipset = INTEL_855GME; 97 return 0; 98 case INTEL_VAR_855GM: 99 dinfo->name = "Intel(R) 855GM"; 100 dinfo->chipset = INTEL_855GM; 101 return 0; 102 case INTEL_VAR_852GME: 103 dinfo->name = "Intel(R) 852GME"; 104 dinfo->chipset = INTEL_852GME; 105 return 0; 106 case INTEL_VAR_852GM: 107 dinfo->name = "Intel(R) 852GM"; 108 dinfo->chipset = INTEL_852GM; 109 return 0; 110 default: 111 dinfo->name = "Intel(R) 852GM/855GM"; 112 dinfo->chipset = INTEL_85XGM; 113 return 0; 114 } 115 break; 116 case PCI_DEVICE_ID_INTEL_865G: 117 dinfo->name = "Intel(R) 865G"; 118 dinfo->chipset = INTEL_865G; 119 dinfo->mobile = 0; 120 dinfo->pll_index = PLLS_I8xx; 121 return 0; 122 case PCI_DEVICE_ID_INTEL_915G: 123 dinfo->name = "Intel(R) 915G"; 124 dinfo->chipset = INTEL_915G; 125 dinfo->mobile = 0; 126 dinfo->pll_index = PLLS_I9xx; 127 return 0; 128 case PCI_DEVICE_ID_INTEL_915GM: 129 dinfo->name = "Intel(R) 915GM"; 130 dinfo->chipset = INTEL_915GM; 131 dinfo->mobile = 1; 132 dinfo->pll_index = PLLS_I9xx; 133 return 0; 134 case PCI_DEVICE_ID_INTEL_945G: 135 dinfo->name = "Intel(R) 945G"; 136 dinfo->chipset = INTEL_945G; 137 dinfo->mobile = 0; 138 dinfo->pll_index = PLLS_I9xx; 139 return 0; 140 case PCI_DEVICE_ID_INTEL_945GM: 141 dinfo->name = "Intel(R) 945GM"; 142 dinfo->chipset = INTEL_945GM; 143 dinfo->mobile = 1; 144 dinfo->pll_index = PLLS_I9xx; 145 return 0; 146 case PCI_DEVICE_ID_INTEL_945GME: 147 dinfo->name = "Intel(R) 945GME"; 148 dinfo->chipset = INTEL_945GME; 149 dinfo->mobile = 1; 150 dinfo->pll_index = PLLS_I9xx; 151 return 0; 152 case PCI_DEVICE_ID_INTEL_965G: 153 dinfo->name = "Intel(R) 965G"; 154 dinfo->chipset = INTEL_965G; 155 dinfo->mobile = 0; 156 dinfo->pll_index = PLLS_I9xx; 157 return 0; 158 case PCI_DEVICE_ID_INTEL_965GM: 159 dinfo->name = "Intel(R) 965GM"; 160 dinfo->chipset = INTEL_965GM; 161 dinfo->mobile = 1; 162 dinfo->pll_index = PLLS_I9xx; 163 return 0; 164 default: 165 return 1; 166 } 167} 168 169int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, 170 int *stolen_size) 171{ 172 struct pci_dev *bridge_dev; 173 u16 tmp; 174 int stolen_overhead; 175 176 if (!pdev || !aperture_size || !stolen_size) 177 return 1; 178 179 /* Find the bridge device. It is always 0:0.0 */ 180 if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) { 181 ERR_MSG("cannot find bridge device\n"); 182 return 1; 183 } 184 185 /* Get the fb aperture size and "stolen" memory amount. */ 186 tmp = 0; 187 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); 188 pci_dev_put(bridge_dev); 189 190 switch (pdev->device) { 191 case PCI_DEVICE_ID_INTEL_915G: 192 case PCI_DEVICE_ID_INTEL_915GM: 193 case PCI_DEVICE_ID_INTEL_945G: 194 case PCI_DEVICE_ID_INTEL_945GM: 195 case PCI_DEVICE_ID_INTEL_945GME: 196 case PCI_DEVICE_ID_INTEL_965G: 197 case PCI_DEVICE_ID_INTEL_965GM: 198 /* 915, 945 and 965 chipsets support a 256MB aperture. 199 Aperture size is determined by inspected the 200 base address of the aperture. */ 201 if (pci_resource_start(pdev, 2) & 0x08000000) 202 *aperture_size = MB(128); 203 else 204 *aperture_size = MB(256); 205 break; 206 default: 207 if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) 208 *aperture_size = MB(64); 209 else 210 *aperture_size = MB(128); 211 break; 212 } 213 214 /* Stolen memory size is reduced by the GTT and the popup. 215 GTT is 1K per MB of aperture size, and popup is 4K. */ 216 stolen_overhead = (*aperture_size / MB(1)) + 4; 217 switch(pdev->device) { 218 case PCI_DEVICE_ID_INTEL_830M: 219 case PCI_DEVICE_ID_INTEL_845G: 220 switch (tmp & INTEL_830_GMCH_GMS_MASK) { 221 case INTEL_830_GMCH_GMS_STOLEN_512: 222 *stolen_size = KB(512) - KB(stolen_overhead); 223 return 0; 224 case INTEL_830_GMCH_GMS_STOLEN_1024: 225 *stolen_size = MB(1) - KB(stolen_overhead); 226 return 0; 227 case INTEL_830_GMCH_GMS_STOLEN_8192: 228 *stolen_size = MB(8) - KB(stolen_overhead); 229 return 0; 230 case INTEL_830_GMCH_GMS_LOCAL: 231 ERR_MSG("only local memory found\n"); 232 return 1; 233 case INTEL_830_GMCH_GMS_DISABLED: 234 ERR_MSG("video memory is disabled\n"); 235 return 1; 236 default: 237 ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n", 238 tmp & INTEL_830_GMCH_GMS_MASK); 239 return 1; 240 } 241 break; 242 default: 243 switch (tmp & INTEL_855_GMCH_GMS_MASK) { 244 case INTEL_855_GMCH_GMS_STOLEN_1M: 245 *stolen_size = MB(1) - KB(stolen_overhead); 246 return 0; 247 case INTEL_855_GMCH_GMS_STOLEN_4M: 248 *stolen_size = MB(4) - KB(stolen_overhead); 249 return 0; 250 case INTEL_855_GMCH_GMS_STOLEN_8M: 251 *stolen_size = MB(8) - KB(stolen_overhead); 252 return 0; 253 case INTEL_855_GMCH_GMS_STOLEN_16M: 254 *stolen_size = MB(16) - KB(stolen_overhead); 255 return 0; 256 case INTEL_855_GMCH_GMS_STOLEN_32M: 257 *stolen_size = MB(32) - KB(stolen_overhead); 258 return 0; 259 case INTEL_915G_GMCH_GMS_STOLEN_48M: 260 *stolen_size = MB(48) - KB(stolen_overhead); 261 return 0; 262 case INTEL_915G_GMCH_GMS_STOLEN_64M: 263 *stolen_size = MB(64) - KB(stolen_overhead); 264 return 0; 265 case INTEL_855_GMCH_GMS_DISABLED: 266 ERR_MSG("video memory is disabled\n"); 267 return 0; 268 default: 269 ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n", 270 tmp & INTEL_855_GMCH_GMS_MASK); 271 return 1; 272 } 273 } 274} 275 276int intelfbhw_check_non_crt(struct intelfb_info *dinfo) 277{ 278 int dvo = 0; 279 280 if (INREG(LVDS) & PORT_ENABLE) 281 dvo |= LVDS_PORT; 282 if (INREG(DVOA) & PORT_ENABLE) 283 dvo |= DVOA_PORT; 284 if (INREG(DVOB) & PORT_ENABLE) 285 dvo |= DVOB_PORT; 286 if (INREG(DVOC) & PORT_ENABLE) 287 dvo |= DVOC_PORT; 288 289 return dvo; 290} 291 292const char * intelfbhw_dvo_to_string(int dvo) 293{ 294 if (dvo & DVOA_PORT) 295 return "DVO port A"; 296 else if (dvo & DVOB_PORT) 297 return "DVO port B"; 298 else if (dvo & DVOC_PORT) 299 return "DVO port C"; 300 else if (dvo & LVDS_PORT) 301 return "LVDS port"; 302 else 303 return NULL; 304} 305 306 307int intelfbhw_validate_mode(struct intelfb_info *dinfo, 308 struct fb_var_screeninfo *var) 309{ 310 int bytes_per_pixel; 311 int tmp; 312 313#if VERBOSE > 0 314 DBG_MSG("intelfbhw_validate_mode\n"); 315#endif 316 317 bytes_per_pixel = var->bits_per_pixel / 8; 318 if (bytes_per_pixel == 3) 319 bytes_per_pixel = 4; 320 321 /* Check if enough video memory. */ 322 tmp = var->yres_virtual * var->xres_virtual * bytes_per_pixel; 323 if (tmp > dinfo->fb.size) { 324 WRN_MSG("Not enough video ram for mode " 325 "(%d KByte vs %d KByte).\n", 326 BtoKB(tmp), BtoKB(dinfo->fb.size)); 327 return 1; 328 } 329 330 /* Check if x/y limits are OK. */ 331 if (var->xres - 1 > HACTIVE_MASK) { 332 WRN_MSG("X resolution too large (%d vs %d).\n", 333 var->xres, HACTIVE_MASK + 1); 334 return 1; 335 } 336 if (var->yres - 1 > VACTIVE_MASK) { 337 WRN_MSG("Y resolution too large (%d vs %d).\n", 338 var->yres, VACTIVE_MASK + 1); 339 return 1; 340 } 341 if (var->xres < 4) { 342 WRN_MSG("X resolution too small (%d vs 4).\n", var->xres); 343 return 1; 344 } 345 if (var->yres < 4) { 346 WRN_MSG("Y resolution too small (%d vs 4).\n", var->yres); 347 return 1; 348 } 349 350 /* Check for doublescan modes. */ 351 if (var->vmode & FB_VMODE_DOUBLE) { 352 WRN_MSG("Mode is double-scan.\n"); 353 return 1; 354 } 355 356 if ((var->vmode & FB_VMODE_INTERLACED) && (var->yres & 1)) { 357 WRN_MSG("Odd number of lines in interlaced mode\n"); 358 return 1; 359 } 360 361 /* Check if clock is OK. */ 362 tmp = 1000000000 / var->pixclock; 363 if (tmp < MIN_CLOCK) { 364 WRN_MSG("Pixel clock is too low (%d MHz vs %d MHz).\n", 365 (tmp + 500) / 1000, MIN_CLOCK / 1000); 366 return 1; 367 } 368 if (tmp > MAX_CLOCK) { 369 WRN_MSG("Pixel clock is too high (%d MHz vs %d MHz).\n", 370 (tmp + 500) / 1000, MAX_CLOCK / 1000); 371 return 1; 372 } 373 374 return 0; 375} 376 377int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 378{ 379 struct intelfb_info *dinfo = GET_DINFO(info); 380 u32 offset, xoffset, yoffset; 381 382#if VERBOSE > 0 383 DBG_MSG("intelfbhw_pan_display\n"); 384#endif 385 386 xoffset = ROUND_DOWN_TO(var->xoffset, 8); 387 yoffset = var->yoffset; 388 389 if ((xoffset + var->xres > var->xres_virtual) || 390 (yoffset + var->yres > var->yres_virtual)) 391 return -EINVAL; 392 393 offset = (yoffset * dinfo->pitch) + 394 (xoffset * var->bits_per_pixel) / 8; 395 396 offset += dinfo->fb.offset << 12; 397 398 dinfo->vsync.pan_offset = offset; 399 if ((var->activate & FB_ACTIVATE_VBL) && 400 !intelfbhw_enable_irq(dinfo)) 401 dinfo->vsync.pan_display = 1; 402 else { 403 dinfo->vsync.pan_display = 0; 404 OUTREG(DSPABASE, offset); 405 } 406 407 return 0; 408} 409 410/* Blank the screen. */ 411void intelfbhw_do_blank(int blank, struct fb_info *info) 412{ 413 struct intelfb_info *dinfo = GET_DINFO(info); 414 u32 tmp; 415 416#if VERBOSE > 0 417 DBG_MSG("intelfbhw_do_blank: blank is %d\n", blank); 418#endif 419 420 /* Turn plane A on or off */ 421 tmp = INREG(DSPACNTR); 422 if (blank) 423 tmp &= ~DISPPLANE_PLANE_ENABLE; 424 else 425 tmp |= DISPPLANE_PLANE_ENABLE; 426 OUTREG(DSPACNTR, tmp); 427 /* Flush */ 428 tmp = INREG(DSPABASE); 429 OUTREG(DSPABASE, tmp); 430 431 /* Turn off/on the HW cursor */ 432#if VERBOSE > 0 433 DBG_MSG("cursor_on is %d\n", dinfo->cursor_on); 434#endif 435 if (dinfo->cursor_on) { 436 if (blank) 437 intelfbhw_cursor_hide(dinfo); 438 else 439 intelfbhw_cursor_show(dinfo); 440 dinfo->cursor_on = 1; 441 } 442 dinfo->cursor_blanked = blank; 443 444 /* Set DPMS level */ 445 tmp = INREG(ADPA) & ~ADPA_DPMS_CONTROL_MASK; 446 switch (blank) { 447 case FB_BLANK_UNBLANK: 448 case FB_BLANK_NORMAL: 449 tmp |= ADPA_DPMS_D0; 450 break; 451 case FB_BLANK_VSYNC_SUSPEND: 452 tmp |= ADPA_DPMS_D1; 453 break; 454 case FB_BLANK_HSYNC_SUSPEND: 455 tmp |= ADPA_DPMS_D2; 456 break; 457 case FB_BLANK_POWERDOWN: 458 tmp |= ADPA_DPMS_D3; 459 break; 460 } 461 OUTREG(ADPA, tmp); 462 463 return; 464} 465 466 467void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, 468 unsigned red, unsigned green, unsigned blue, 469 unsigned transp) 470{ 471 u32 palette_reg = (dinfo->pipe == PIPE_A) ? 472 PALETTE_A : PALETTE_B; 473 474#if VERBOSE > 0 475 DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n", 476 regno, red, green, blue); 477#endif 478 479 OUTREG(palette_reg + (regno << 2), 480 (red << PALETTE_8_RED_SHIFT) | 481 (green << PALETTE_8_GREEN_SHIFT) | 482 (blue << PALETTE_8_BLUE_SHIFT)); 483} 484 485 486int intelfbhw_read_hw_state(struct intelfb_info *dinfo, 487 struct intelfb_hwstate *hw, int flag) 488{ 489 int i; 490 491#if VERBOSE > 0 492 DBG_MSG("intelfbhw_read_hw_state\n"); 493#endif 494 495 if (!hw || !dinfo) 496 return -1; 497 498 /* Read in as much of the HW state as possible. */ 499 hw->vga0_divisor = INREG(VGA0_DIVISOR); 500 hw->vga1_divisor = INREG(VGA1_DIVISOR); 501 hw->vga_pd = INREG(VGAPD); 502 hw->dpll_a = INREG(DPLL_A); 503 hw->dpll_b = INREG(DPLL_B); 504 hw->fpa0 = INREG(FPA0); 505 hw->fpa1 = INREG(FPA1); 506 hw->fpb0 = INREG(FPB0); 507 hw->fpb1 = INREG(FPB1); 508 509 if (flag == 1) 510 return flag; 511 512#if 0 513 /* This seems to be a problem with the 852GM/855GM */ 514 for (i = 0; i < PALETTE_8_ENTRIES; i++) { 515 hw->palette_a[i] = INREG(PALETTE_A + (i << 2)); 516 hw->palette_b[i] = INREG(PALETTE_B + (i << 2)); 517 } 518#endif 519 520 if (flag == 2) 521 return flag; 522 523 hw->htotal_a = INREG(HTOTAL_A); 524 hw->hblank_a = INREG(HBLANK_A); 525 hw->hsync_a = INREG(HSYNC_A); 526 hw->vtotal_a = INREG(VTOTAL_A); 527 hw->vblank_a = INREG(VBLANK_A); 528 hw->vsync_a = INREG(VSYNC_A); 529 hw->src_size_a = INREG(SRC_SIZE_A); 530 hw->bclrpat_a = INREG(BCLRPAT_A); 531 hw->htotal_b = INREG(HTOTAL_B); 532 hw->hblank_b = INREG(HBLANK_B); 533 hw->hsync_b = INREG(HSYNC_B); 534 hw->vtotal_b = INREG(VTOTAL_B); 535 hw->vblank_b = INREG(VBLANK_B); 536 hw->vsync_b = INREG(VSYNC_B); 537 hw->src_size_b = INREG(SRC_SIZE_B); 538 hw->bclrpat_b = INREG(BCLRPAT_B); 539 540 if (flag == 3) 541 return flag; 542 543 hw->adpa = INREG(ADPA); 544 hw->dvoa = INREG(DVOA); 545 hw->dvob = INREG(DVOB); 546 hw->dvoc = INREG(DVOC); 547 hw->dvoa_srcdim = INREG(DVOA_SRCDIM); 548 hw->dvob_srcdim = INREG(DVOB_SRCDIM); 549 hw->dvoc_srcdim = INREG(DVOC_SRCDIM); 550 hw->lvds = INREG(LVDS); 551 552 if (flag == 4) 553 return flag; 554 555 hw->pipe_a_conf = INREG(PIPEACONF); 556 hw->pipe_b_conf = INREG(PIPEBCONF); 557 hw->disp_arb = INREG(DISPARB); 558 559 if (flag == 5) 560 return flag; 561 562 hw->cursor_a_control = INREG(CURSOR_A_CONTROL); 563 hw->cursor_b_control = INREG(CURSOR_B_CONTROL); 564 hw->cursor_a_base = INREG(CURSOR_A_BASEADDR); 565 hw->cursor_b_base = INREG(CURSOR_B_BASEADDR); 566 567 if (flag == 6) 568 return flag; 569 570 for (i = 0; i < 4; i++) { 571 hw->cursor_a_palette[i] = INREG(CURSOR_A_PALETTE0 + (i << 2)); 572 hw->cursor_b_palette[i] = INREG(CURSOR_B_PALETTE0 + (i << 2)); 573 } 574 575 if (flag == 7) 576 return flag; 577 578 hw->cursor_size = INREG(CURSOR_SIZE); 579 580 if (flag == 8) 581 return flag; 582 583 hw->disp_a_ctrl = INREG(DSPACNTR); 584 hw->disp_b_ctrl = INREG(DSPBCNTR); 585 hw->disp_a_base = INREG(DSPABASE); 586 hw->disp_b_base = INREG(DSPBBASE); 587 hw->disp_a_stride = INREG(DSPASTRIDE); 588 hw->disp_b_stride = INREG(DSPBSTRIDE); 589 590 if (flag == 9) 591 return flag; 592 593 hw->vgacntrl = INREG(VGACNTRL); 594 595 if (flag == 10) 596 return flag; 597 598 hw->add_id = INREG(ADD_ID); 599 600 if (flag == 11) 601 return flag; 602 603 for (i = 0; i < 7; i++) { 604 hw->swf0x[i] = INREG(SWF00 + (i << 2)); 605 hw->swf1x[i] = INREG(SWF10 + (i << 2)); 606 if (i < 3) 607 hw->swf3x[i] = INREG(SWF30 + (i << 2)); 608 } 609 610 for (i = 0; i < 8; i++) 611 hw->fence[i] = INREG(FENCE + (i << 2)); 612 613 hw->instpm = INREG(INSTPM); 614 hw->mem_mode = INREG(MEM_MODE); 615 hw->fw_blc_0 = INREG(FW_BLC_0); 616 hw->fw_blc_1 = INREG(FW_BLC_1); 617 618 hw->hwstam = INREG16(HWSTAM); 619 hw->ier = INREG16(IER); 620 hw->iir = INREG16(IIR); 621 hw->imr = INREG16(IMR); 622 623 return 0; 624} 625 626 627static int calc_vclock3(int index, int m, int n, int p) 628{ 629 if (p == 0 || n == 0) 630 return 0; 631 return plls[index].ref_clk * m / n / p; 632} 633 634static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, 635 int lvds) 636{ 637 struct pll_min_max *pll = &plls[index]; 638 u32 m, vco, p; 639 640 m = (5 * (m1 + 2)) + (m2 + 2); 641 n += 2; 642 vco = pll->ref_clk * m / n; 643 644 if (index == PLLS_I8xx) 645 p = ((p1 + 2) * (1 << (p2 + 1))); 646 else 647 p = ((p1) * (p2 ? 5 : 10)); 648 return vco / p; 649} 650 651#if REGDUMP 652static void intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, 653 int *o_p1, int *o_p2) 654{ 655 int p1, p2; 656 657 if (IS_I9XX(dinfo)) { 658 if (dpll & DPLL_P1_FORCE_DIV2) 659 p1 = 1; 660 else 661 p1 = (dpll >> DPLL_P1_SHIFT) & 0xff; 662 663 p1 = ffs(p1); 664 665 p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; 666 } else { 667 if (dpll & DPLL_P1_FORCE_DIV2) 668 p1 = 0; 669 else 670 p1 = (dpll >> DPLL_P1_SHIFT) & DPLL_P1_MASK; 671 p2 = (dpll >> DPLL_P2_SHIFT) & DPLL_P2_MASK; 672 } 673 674 *o_p1 = p1; 675 *o_p2 = p2; 676} 677#endif 678 679 680void intelfbhw_print_hw_state(struct intelfb_info *dinfo, 681 struct intelfb_hwstate *hw) 682{ 683#if REGDUMP 684 int i, m1, m2, n, p1, p2; 685 int index = dinfo->pll_index; 686 DBG_MSG("intelfbhw_print_hw_state\n"); 687 688 if (!hw) 689 return; 690 /* Read in as much of the HW state as possible. */ 691 printk("hw state dump start\n"); 692 printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor); 693 printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor); 694 printk(" VGAPD: 0x%08x\n", hw->vga_pd); 695 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 696 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 697 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 698 699 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); 700 701 printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 702 m1, m2, n, p1, p2); 703 printk(" VGA0: clock is %d\n", 704 calc_vclock(index, m1, m2, n, p1, p2, 0)); 705 706 n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 707 m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 708 m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 709 710 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); 711 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 712 m1, m2, n, p1, p2); 713 printk(" VGA1: clock is %d\n", 714 calc_vclock(index, m1, m2, n, p1, p2, 0)); 715 716 printk(" DPLL_A: 0x%08x\n", hw->dpll_a); 717 printk(" DPLL_B: 0x%08x\n", hw->dpll_b); 718 printk(" FPA0: 0x%08x\n", hw->fpa0); 719 printk(" FPA1: 0x%08x\n", hw->fpa1); 720 printk(" FPB0: 0x%08x\n", hw->fpb0); 721 printk(" FPB1: 0x%08x\n", hw->fpb1); 722 723 n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 724 m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 725 m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 726 727 intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2); 728 729 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 730 m1, m2, n, p1, p2); 731 printk(" PLLA0: clock is %d\n", 732 calc_vclock(index, m1, m2, n, p1, p2, 0)); 733 734 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 735 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 736 m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 737 738 intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2); 739 740 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 741 m1, m2, n, p1, p2); 742 printk(" PLLA1: clock is %d\n", 743 calc_vclock(index, m1, m2, n, p1, p2, 0)); 744 745#if 0 746 printk(" PALETTE_A:\n"); 747 for (i = 0; i < PALETTE_8_ENTRIES) 748 printk(" %3d: 0x%08x\n", i, hw->palette_a[i]); 749 printk(" PALETTE_B:\n"); 750 for (i = 0; i < PALETTE_8_ENTRIES) 751 printk(" %3d: 0x%08x\n", i, hw->palette_b[i]); 752#endif 753 754 printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a); 755 printk(" HBLANK_A: 0x%08x\n", hw->hblank_a); 756 printk(" HSYNC_A: 0x%08x\n", hw->hsync_a); 757 printk(" VTOTAL_A: 0x%08x\n", hw->vtotal_a); 758 printk(" VBLANK_A: 0x%08x\n", hw->vblank_a); 759 printk(" VSYNC_A: 0x%08x\n", hw->vsync_a); 760 printk(" SRC_SIZE_A: 0x%08x\n", hw->src_size_a); 761 printk(" BCLRPAT_A: 0x%08x\n", hw->bclrpat_a); 762 printk(" HTOTAL_B: 0x%08x\n", hw->htotal_b); 763 printk(" HBLANK_B: 0x%08x\n", hw->hblank_b); 764 printk(" HSYNC_B: 0x%08x\n", hw->hsync_b); 765 printk(" VTOTAL_B: 0x%08x\n", hw->vtotal_b); 766 printk(" VBLANK_B: 0x%08x\n", hw->vblank_b); 767 printk(" VSYNC_B: 0x%08x\n", hw->vsync_b); 768 printk(" SRC_SIZE_B: 0x%08x\n", hw->src_size_b); 769 printk(" BCLRPAT_B: 0x%08x\n", hw->bclrpat_b); 770 771 printk(" ADPA: 0x%08x\n", hw->adpa); 772 printk(" DVOA: 0x%08x\n", hw->dvoa); 773 printk(" DVOB: 0x%08x\n", hw->dvob); 774 printk(" DVOC: 0x%08x\n", hw->dvoc); 775 printk(" DVOA_SRCDIM: 0x%08x\n", hw->dvoa_srcdim); 776 printk(" DVOB_SRCDIM: 0x%08x\n", hw->dvob_srcdim); 777 printk(" DVOC_SRCDIM: 0x%08x\n", hw->dvoc_srcdim); 778 printk(" LVDS: 0x%08x\n", hw->lvds); 779 780 printk(" PIPEACONF: 0x%08x\n", hw->pipe_a_conf); 781 printk(" PIPEBCONF: 0x%08x\n", hw->pipe_b_conf); 782 printk(" DISPARB: 0x%08x\n", hw->disp_arb); 783 784 printk(" CURSOR_A_CONTROL: 0x%08x\n", hw->cursor_a_control); 785 printk(" CURSOR_B_CONTROL: 0x%08x\n", hw->cursor_b_control); 786 printk(" CURSOR_A_BASEADDR: 0x%08x\n", hw->cursor_a_base); 787 printk(" CURSOR_B_BASEADDR: 0x%08x\n", hw->cursor_b_base); 788 789 printk(" CURSOR_A_PALETTE: "); 790 for (i = 0; i < 4; i++) { 791 printk("0x%08x", hw->cursor_a_palette[i]); 792 if (i < 3) 793 printk(", "); 794 } 795 printk("\n"); 796 printk(" CURSOR_B_PALETTE: "); 797 for (i = 0; i < 4; i++) { 798 printk("0x%08x", hw->cursor_b_palette[i]); 799 if (i < 3) 800 printk(", "); 801 } 802 printk("\n"); 803 804 printk(" CURSOR_SIZE: 0x%08x\n", hw->cursor_size); 805 806 printk(" DSPACNTR: 0x%08x\n", hw->disp_a_ctrl); 807 printk(" DSPBCNTR: 0x%08x\n", hw->disp_b_ctrl); 808 printk(" DSPABASE: 0x%08x\n", hw->disp_a_base); 809 printk(" DSPBBASE: 0x%08x\n", hw->disp_b_base); 810 printk(" DSPASTRIDE: 0x%08x\n", hw->disp_a_stride); 811 printk(" DSPBSTRIDE: 0x%08x\n", hw->disp_b_stride); 812 813 printk(" VGACNTRL: 0x%08x\n", hw->vgacntrl); 814 printk(" ADD_ID: 0x%08x\n", hw->add_id); 815 816 for (i = 0; i < 7; i++) { 817 printk(" SWF0%d 0x%08x\n", i, 818 hw->swf0x[i]); 819 } 820 for (i = 0; i < 7; i++) { 821 printk(" SWF1%d 0x%08x\n", i, 822 hw->swf1x[i]); 823 } 824 for (i = 0; i < 3; i++) { 825 printk(" SWF3%d 0x%08x\n", i, 826 hw->swf3x[i]); 827 } 828 for (i = 0; i < 8; i++) 829 printk(" FENCE%d 0x%08x\n", i, 830 hw->fence[i]); 831 832 printk(" INSTPM 0x%08x\n", hw->instpm); 833 printk(" MEM_MODE 0x%08x\n", hw->mem_mode); 834 printk(" FW_BLC_0 0x%08x\n", hw->fw_blc_0); 835 printk(" FW_BLC_1 0x%08x\n", hw->fw_blc_1); 836 837 printk(" HWSTAM 0x%04x\n", hw->hwstam); 838 printk(" IER 0x%04x\n", hw->ier); 839 printk(" IIR 0x%04x\n", hw->iir); 840 printk(" IMR 0x%04x\n", hw->imr); 841 printk("hw state dump end\n"); 842#endif 843} 844 845 846 847/* Split the M parameter into M1 and M2. */ 848static int splitm(int index, unsigned int m, unsigned int *retm1, 849 unsigned int *retm2) 850{ 851 int m1, m2; 852 int testm; 853 struct pll_min_max *pll = &plls[index]; 854 855 /* no point optimising too much - brute force m */ 856 for (m1 = pll->min_m1; m1 < pll->max_m1 + 1; m1++) { 857 for (m2 = pll->min_m2; m2 < pll->max_m2 + 1; m2++) { 858 testm = (5 * (m1 + 2)) + (m2 + 2); 859 if (testm == m) { 860 *retm1 = (unsigned int)m1; 861 *retm2 = (unsigned int)m2; 862 return 0; 863 } 864 } 865 } 866 return 1; 867} 868 869/* Split the P parameter into P1 and P2. */ 870static int splitp(int index, unsigned int p, unsigned int *retp1, 871 unsigned int *retp2) 872{ 873 int p1, p2; 874 struct pll_min_max *pll = &plls[index]; 875 876 if (index == PLLS_I9xx) { 877 p2 = (p % 10) ? 1 : 0; 878 879 p1 = p / (p2 ? 5 : 10); 880 881 *retp1 = (unsigned int)p1; 882 *retp2 = (unsigned int)p2; 883 return 0; 884 } 885 886 if (p % 4 == 0) 887 p2 = 1; 888 else 889 p2 = 0; 890 p1 = (p / (1 << (p2 + 1))) - 2; 891 if (p % 4 == 0 && p1 < pll->min_p1) { 892 p2 = 0; 893 p1 = (p / (1 << (p2 + 1))) - 2; 894 } 895 if (p1 < pll->min_p1 || p1 > pll->max_p1 || 896 (p1 + 2) * (1 << (p2 + 1)) != p) { 897 return 1; 898 } else { 899 *retp1 = (unsigned int)p1; 900 *retp2 = (unsigned int)p2; 901 return 0; 902 } 903} 904 905static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, 906 u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock) 907{ 908 u32 m1, m2, n, p1, p2, n1, testm; 909 u32 f_vco, p, p_best = 0, m, f_out = 0; 910 u32 err_max, err_target, err_best = 10000000; 911 u32 n_best = 0, m_best = 0, f_best, f_err; 912 u32 p_min, p_max, p_inc, div_max; 913 struct pll_min_max *pll = &plls[index]; 914 915 /* Accept 0.5% difference, but aim for 0.1% */ 916 err_max = 5 * clock / 1000; 917 err_target = clock / 1000; 918 919 DBG_MSG("Clock is %d\n", clock); 920 921 div_max = pll->max_vco / clock; 922 923 p_inc = (clock <= pll->p_transition_clk) ? pll->p_inc_lo : pll->p_inc_hi; 924 p_min = p_inc; 925 p_max = ROUND_DOWN_TO(div_max, p_inc); 926 if (p_min < pll->min_p) 927 p_min = pll->min_p; 928 if (p_max > pll->max_p) 929 p_max = pll->max_p; 930 931 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); 932 933 p = p_min; 934 do { 935 if (splitp(index, p, &p1, &p2)) { 936 WRN_MSG("cannot split p = %d\n", p); 937 p += p_inc; 938 continue; 939 } 940 n = pll->min_n; 941 f_vco = clock * p; 942 943 do { 944 m = ROUND_UP_TO(f_vco * n, pll->ref_clk) / pll->ref_clk; 945 if (m < pll->min_m) 946 m = pll->min_m + 1; 947 if (m > pll->max_m) 948 m = pll->max_m - 1; 949 for (testm = m - 1; testm <= m; testm++) { 950 f_out = calc_vclock3(index, testm, n, p); 951 if (splitm(index, testm, &m1, &m2)) { 952 WRN_MSG("cannot split m = %d\n", 953 testm); 954 continue; 955 } 956 if (clock > f_out) 957 f_err = clock - f_out; 958 else/* slightly bias the error for bigger clocks */ 959 f_err = f_out - clock + 1; 960 961 if (f_err < err_best) { 962 m_best = testm; 963 n_best = n; 964 p_best = p; 965 f_best = f_out; 966 err_best = f_err; 967 } 968 } 969 n++; 970 } while ((n <= pll->max_n) && (f_out >= clock)); 971 p += p_inc; 972 } while ((p <= p_max)); 973 974 if (!m_best) { 975 WRN_MSG("cannot find parameters for clock %d\n", clock); 976 return 1; 977 } 978 m = m_best; 979 n = n_best; 980 p = p_best; 981 splitm(index, m, &m1, &m2); 982 splitp(index, p, &p1, &p2); 983 n1 = n - 2; 984 985 DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), " 986 "f: %d (%d), VCO: %d\n", 987 m, m1, m2, n, n1, p, p1, p2, 988 calc_vclock3(index, m, n, p), 989 calc_vclock(index, m1, m2, n1, p1, p2, 0), 990 calc_vclock3(index, m, n, p) * p); 991 *retm1 = m1; 992 *retm2 = m2; 993 *retn = n1; 994 *retp1 = p1; 995 *retp2 = p2; 996 *retclock = calc_vclock(index, m1, m2, n1, p1, p2, 0); 997 998 return 0; 999} 1000 1001static __inline__ int check_overflow(u32 value, u32 limit, 1002 const char *description) 1003{ 1004 if (value > limit) { 1005 WRN_MSG("%s value %d exceeds limit %d\n", 1006 description, value, limit); 1007 return 1; 1008 } 1009 return 0; 1010} 1011 1012/* It is assumed that hw is filled in with the initial state information. */ 1013int intelfbhw_mode_to_hw(struct intelfb_info *dinfo, 1014 struct intelfb_hwstate *hw, 1015 struct fb_var_screeninfo *var) 1016{ 1017 int pipe = PIPE_A; 1018 u32 *dpll, *fp0, *fp1; 1019 u32 m1, m2, n, p1, p2, clock_target, clock; 1020 u32 hsync_start, hsync_end, hblank_start, hblank_end, htotal, hactive; 1021 u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive; 1022 u32 vsync_pol, hsync_pol; 1023 u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf; 1024 u32 stride_alignment; 1025 1026 DBG_MSG("intelfbhw_mode_to_hw\n"); 1027 1028 /* Disable VGA */ 1029 hw->vgacntrl |= VGA_DISABLE; 1030 1031 /* Check whether pipe A or pipe B is enabled. */ 1032 if (hw->pipe_a_conf & PIPECONF_ENABLE) 1033 pipe = PIPE_A; 1034 else if (hw->pipe_b_conf & PIPECONF_ENABLE) 1035 pipe = PIPE_B; 1036 1037 /* Set which pipe's registers will be set. */ 1038 if (pipe == PIPE_B) { 1039 dpll = &hw->dpll_b; 1040 fp0 = &hw->fpb0; 1041 fp1 = &hw->fpb1; 1042 hs = &hw->hsync_b; 1043 hb = &hw->hblank_b; 1044 ht = &hw->htotal_b; 1045 vs = &hw->vsync_b; 1046 vb = &hw->vblank_b; 1047 vt = &hw->vtotal_b; 1048 ss = &hw->src_size_b; 1049 pipe_conf = &hw->pipe_b_conf; 1050 } else { 1051 dpll = &hw->dpll_a; 1052 fp0 = &hw->fpa0; 1053 fp1 = &hw->fpa1; 1054 hs = &hw->hsync_a; 1055 hb = &hw->hblank_a; 1056 ht = &hw->htotal_a; 1057 vs = &hw->vsync_a; 1058 vb = &hw->vblank_a; 1059 vt = &hw->vtotal_a; 1060 ss = &hw->src_size_a; 1061 pipe_conf = &hw->pipe_a_conf; 1062 } 1063 1064 /* Use ADPA register for sync control. */ 1065 hw->adpa &= ~ADPA_USE_VGA_HVPOLARITY; 1066 1067 /* sync polarity */ 1068 hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 1069 ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW; 1070 vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 1071 ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW; 1072 hw->adpa &= ~((ADPA_SYNC_ACTIVE_MASK << ADPA_VSYNC_ACTIVE_SHIFT) | 1073 (ADPA_SYNC_ACTIVE_MASK << ADPA_HSYNC_ACTIVE_SHIFT)); 1074 hw->adpa |= (hsync_pol << ADPA_HSYNC_ACTIVE_SHIFT) | 1075 (vsync_pol << ADPA_VSYNC_ACTIVE_SHIFT); 1076 1077 /* Connect correct pipe to the analog port DAC */ 1078 hw->adpa &= ~(PIPE_MASK << ADPA_PIPE_SELECT_SHIFT); 1079 hw->adpa |= (pipe << ADPA_PIPE_SELECT_SHIFT); 1080 1081 /* Set DPMS state to D0 (on) */ 1082 hw->adpa &= ~ADPA_DPMS_CONTROL_MASK; 1083 hw->adpa |= ADPA_DPMS_D0; 1084 1085 hw->adpa |= ADPA_DAC_ENABLE; 1086 1087 *dpll |= (DPLL_VCO_ENABLE | DPLL_VGA_MODE_DISABLE); 1088 *dpll &= ~(DPLL_RATE_SELECT_MASK | DPLL_REFERENCE_SELECT_MASK); 1089 *dpll |= (DPLL_REFERENCE_DEFAULT | DPLL_RATE_SELECT_FP0); 1090 1091 /* Desired clock in kHz */ 1092 clock_target = 1000000000 / var->pixclock; 1093 1094 if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2, 1095 &n, &p1, &p2, &clock)) { 1096 WRN_MSG("calc_pll_params failed\n"); 1097 return 1; 1098 } 1099 1100 /* Check for overflow. */ 1101 if (check_overflow(p1, DPLL_P1_MASK, "PLL P1 parameter")) 1102 return 1; 1103 if (check_overflow(p2, DPLL_P2_MASK, "PLL P2 parameter")) 1104 return 1; 1105 if (check_overflow(m1, FP_DIVISOR_MASK, "PLL M1 parameter")) 1106 return 1; 1107 if (check_overflow(m2, FP_DIVISOR_MASK, "PLL M2 parameter")) 1108 return 1; 1109 if (check_overflow(n, FP_DIVISOR_MASK, "PLL N parameter")) 1110 return 1; 1111 1112 *dpll &= ~DPLL_P1_FORCE_DIV2; 1113 *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | 1114 (DPLL_P1_MASK << DPLL_P1_SHIFT)); 1115 1116 if (IS_I9XX(dinfo)) { 1117 *dpll |= (p2 << DPLL_I9XX_P2_SHIFT); 1118 *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT; 1119 } else 1120 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); 1121 1122 *fp0 = (n << FP_N_DIVISOR_SHIFT) | 1123 (m1 << FP_M1_DIVISOR_SHIFT) | 1124 (m2 << FP_M2_DIVISOR_SHIFT); 1125 *fp1 = *fp0; 1126 1127 hw->dvob &= ~PORT_ENABLE; 1128 hw->dvoc &= ~PORT_ENABLE; 1129 1130 /* Use display plane A. */ 1131 hw->disp_a_ctrl |= DISPPLANE_PLANE_ENABLE; 1132 hw->disp_a_ctrl &= ~DISPPLANE_GAMMA_ENABLE; 1133 hw->disp_a_ctrl &= ~DISPPLANE_PIXFORMAT_MASK; 1134 switch (intelfb_var_to_depth(var)) { 1135 case 8: 1136 hw->disp_a_ctrl |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE; 1137 break; 1138 case 15: 1139 hw->disp_a_ctrl |= DISPPLANE_15_16BPP; 1140 break; 1141 case 16: 1142 hw->disp_a_ctrl |= DISPPLANE_16BPP; 1143 break; 1144 case 24: 1145 hw->disp_a_ctrl |= DISPPLANE_32BPP_NO_ALPHA; 1146 break; 1147 } 1148 hw->disp_a_ctrl &= ~(PIPE_MASK << DISPPLANE_SEL_PIPE_SHIFT); 1149 hw->disp_a_ctrl |= (pipe << DISPPLANE_SEL_PIPE_SHIFT); 1150 1151 /* Set CRTC registers. */ 1152 hactive = var->xres; 1153 hsync_start = hactive + var->right_margin; 1154 hsync_end = hsync_start + var->hsync_len; 1155 htotal = hsync_end + var->left_margin; 1156 hblank_start = hactive; 1157 hblank_end = htotal; 1158 1159 DBG_MSG("H: act %d, ss %d, se %d, tot %d bs %d, be %d\n", 1160 hactive, hsync_start, hsync_end, htotal, hblank_start, 1161 hblank_end); 1162 1163 vactive = var->yres; 1164 if (var->vmode & FB_VMODE_INTERLACED) 1165 vactive--; /* the chip adds 2 halflines automatically */ 1166 vsync_start = vactive + var->lower_margin; 1167 vsync_end = vsync_start + var->vsync_len; 1168 vtotal = vsync_end + var->upper_margin; 1169 vblank_start = vactive; 1170 vblank_end = vtotal; 1171 vblank_end = vsync_end + 1; 1172 1173 DBG_MSG("V: act %d, ss %d, se %d, tot %d bs %d, be %d\n", 1174 vactive, vsync_start, vsync_end, vtotal, vblank_start, 1175 vblank_end); 1176 1177 /* Adjust for register values, and check for overflow. */ 1178 hactive--; 1179 if (check_overflow(hactive, HACTIVE_MASK, "CRTC hactive")) 1180 return 1; 1181 hsync_start--; 1182 if (check_overflow(hsync_start, HSYNCSTART_MASK, "CRTC hsync_start")) 1183 return 1; 1184 hsync_end--; 1185 if (check_overflow(hsync_end, HSYNCEND_MASK, "CRTC hsync_end")) 1186 return 1; 1187 htotal--; 1188 if (check_overflow(htotal, HTOTAL_MASK, "CRTC htotal")) 1189 return 1; 1190 hblank_start--; 1191 if (check_overflow(hblank_start, HBLANKSTART_MASK, "CRTC hblank_start")) 1192 return 1; 1193 hblank_end--; 1194 if (check_overflow(hblank_end, HBLANKEND_MASK, "CRTC hblank_end")) 1195 return 1; 1196 1197 vactive--; 1198 if (check_overflow(vactive, VACTIVE_MASK, "CRTC vactive")) 1199 return 1; 1200 vsync_start--; 1201 if (check_overflow(vsync_start, VSYNCSTART_MASK, "CRTC vsync_start")) 1202 return 1; 1203 vsync_end--; 1204 if (check_overflow(vsync_end, VSYNCEND_MASK, "CRTC vsync_end")) 1205 return 1; 1206 vtotal--; 1207 if (check_overflow(vtotal, VTOTAL_MASK, "CRTC vtotal")) 1208 return 1; 1209 vblank_start--; 1210 if (check_overflow(vblank_start, VBLANKSTART_MASK, "CRTC vblank_start")) 1211 return 1; 1212 vblank_end--; 1213 if (check_overflow(vblank_end, VBLANKEND_MASK, "CRTC vblank_end")) 1214 return 1; 1215 1216 *ht = (htotal << HTOTAL_SHIFT) | (hactive << HACTIVE_SHIFT); 1217 *hb = (hblank_start << HBLANKSTART_SHIFT) | 1218 (hblank_end << HSYNCEND_SHIFT); 1219 *hs = (hsync_start << HSYNCSTART_SHIFT) | (hsync_end << HSYNCEND_SHIFT); 1220 1221 *vt = (vtotal << VTOTAL_SHIFT) | (vactive << VACTIVE_SHIFT); 1222 *vb = (vblank_start << VBLANKSTART_SHIFT) | 1223 (vblank_end << VSYNCEND_SHIFT); 1224 *vs = (vsync_start << VSYNCSTART_SHIFT) | (vsync_end << VSYNCEND_SHIFT); 1225 *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) | 1226 (vactive << SRC_SIZE_VERT_SHIFT); 1227 1228 hw->disp_a_stride = dinfo->pitch; 1229 DBG_MSG("pitch is %d\n", hw->disp_a_stride); 1230 1231 hw->disp_a_base = hw->disp_a_stride * var->yoffset + 1232 var->xoffset * var->bits_per_pixel / 8; 1233 1234 hw->disp_a_base += dinfo->fb.offset << 12; 1235 1236 /* Check stride alignment. */ 1237 stride_alignment = IS_I9XX(dinfo) ? STRIDE_ALIGNMENT_I9XX : 1238 STRIDE_ALIGNMENT; 1239 if (hw->disp_a_stride % stride_alignment != 0) { 1240 WRN_MSG("display stride %d has bad alignment %d\n", 1241 hw->disp_a_stride, stride_alignment); 1242 return 1; 1243 } 1244 1245 /* Set the palette to 8-bit mode. */ 1246 *pipe_conf &= ~PIPECONF_GAMMA; 1247 1248 if (var->vmode & FB_VMODE_INTERLACED) 1249 *pipe_conf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; 1250 else 1251 *pipe_conf &= ~PIPECONF_INTERLACE_MASK; 1252 1253 return 0; 1254} 1255 1256/* Program a (non-VGA) video mode. */ 1257int intelfbhw_program_mode(struct intelfb_info *dinfo, 1258 const struct intelfb_hwstate *hw, int blank) 1259{ 1260 int pipe = PIPE_A; 1261 u32 tmp; 1262 const u32 *dpll, *fp0, *fp1, *pipe_conf; 1263 const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss; 1264 u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg, pipe_stat_reg; 1265 u32 hsync_reg, htotal_reg, hblank_reg; 1266 u32 vsync_reg, vtotal_reg, vblank_reg; 1267 u32 src_size_reg; 1268 u32 count, tmp_val[3]; 1269 1270 /* Assume single pipe, display plane A, analog CRT. */ 1271 1272#if VERBOSE > 0 1273 DBG_MSG("intelfbhw_program_mode\n"); 1274#endif 1275 1276 /* Disable VGA */ 1277 tmp = INREG(VGACNTRL); 1278 tmp |= VGA_DISABLE; 1279 OUTREG(VGACNTRL, tmp); 1280 1281 /* Check whether pipe A or pipe B is enabled. */ 1282 if (hw->pipe_a_conf & PIPECONF_ENABLE) 1283 pipe = PIPE_A; 1284 else if (hw->pipe_b_conf & PIPECONF_ENABLE) 1285 pipe = PIPE_B; 1286 1287 dinfo->pipe = pipe; 1288 1289 if (pipe == PIPE_B) { 1290 dpll = &hw->dpll_b; 1291 fp0 = &hw->fpb0; 1292 fp1 = &hw->fpb1; 1293 pipe_conf = &hw->pipe_b_conf; 1294 hs = &hw->hsync_b; 1295 hb = &hw->hblank_b; 1296 ht = &hw->htotal_b; 1297 vs = &hw->vsync_b; 1298 vb = &hw->vblank_b; 1299 vt = &hw->vtotal_b; 1300 ss = &hw->src_size_b; 1301 dpll_reg = DPLL_B; 1302 fp0_reg = FPB0; 1303 fp1_reg = FPB1; 1304 pipe_conf_reg = PIPEBCONF; 1305 pipe_stat_reg = PIPEBSTAT; 1306 hsync_reg = HSYNC_B; 1307 htotal_reg = HTOTAL_B; 1308 hblank_reg = HBLANK_B; 1309 vsync_reg = VSYNC_B; 1310 vtotal_reg = VTOTAL_B; 1311 vblank_reg = VBLANK_B; 1312 src_size_reg = SRC_SIZE_B; 1313 } else { 1314 dpll = &hw->dpll_a; 1315 fp0 = &hw->fpa0; 1316 fp1 = &hw->fpa1; 1317 pipe_conf = &hw->pipe_a_conf; 1318 hs = &hw->hsync_a; 1319 hb = &hw->hblank_a; 1320 ht = &hw->htotal_a; 1321 vs = &hw->vsync_a; 1322 vb = &hw->vblank_a; 1323 vt = &hw->vtotal_a; 1324 ss = &hw->src_size_a; 1325 dpll_reg = DPLL_A; 1326 fp0_reg = FPA0; 1327 fp1_reg = FPA1; 1328 pipe_conf_reg = PIPEACONF; 1329 pipe_stat_reg = PIPEASTAT; 1330 hsync_reg = HSYNC_A; 1331 htotal_reg = HTOTAL_A; 1332 hblank_reg = HBLANK_A; 1333 vsync_reg = VSYNC_A; 1334 vtotal_reg = VTOTAL_A; 1335 vblank_reg = VBLANK_A; 1336 src_size_reg = SRC_SIZE_A; 1337 } 1338 1339 /* turn off pipe */ 1340 tmp = INREG(pipe_conf_reg); 1341 tmp &= ~PIPECONF_ENABLE; 1342 OUTREG(pipe_conf_reg, tmp); 1343 1344 count = 0; 1345 do { 1346 tmp_val[count % 3] = INREG(PIPEA_DSL); 1347 if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1] == tmp_val[2])) 1348 break; 1349 count++; 1350 udelay(1); 1351 if (count % 200 == 0) { 1352 tmp = INREG(pipe_conf_reg); 1353 tmp &= ~PIPECONF_ENABLE; 1354 OUTREG(pipe_conf_reg, tmp); 1355 } 1356 } while (count < 2000); 1357 1358 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); 1359 1360 /* Disable planes A and B. */ 1361 tmp = INREG(DSPACNTR); 1362 tmp &= ~DISPPLANE_PLANE_ENABLE; 1363 OUTREG(DSPACNTR, tmp); 1364 tmp = INREG(DSPBCNTR); 1365 tmp &= ~DISPPLANE_PLANE_ENABLE; 1366 OUTREG(DSPBCNTR, tmp); 1367 1368 /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ 1369 mdelay(20); 1370 1371 OUTREG(DVOB, INREG(DVOB) & ~PORT_ENABLE); 1372 OUTREG(DVOC, INREG(DVOC) & ~PORT_ENABLE); 1373 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); 1374 1375 /* Disable Sync */ 1376 tmp = INREG(ADPA); 1377 tmp &= ~ADPA_DPMS_CONTROL_MASK; 1378 tmp |= ADPA_DPMS_D3; 1379 OUTREG(ADPA, tmp); 1380 1381 /* do some funky magic - xyzzy */ 1382 OUTREG(0x61204, 0xabcd0000); 1383 1384 /* turn off PLL */ 1385 tmp = INREG(dpll_reg); 1386 tmp &= ~DPLL_VCO_ENABLE; 1387 OUTREG(dpll_reg, tmp); 1388 1389 /* Set PLL parameters */ 1390 OUTREG(fp0_reg, *fp0); 1391 OUTREG(fp1_reg, *fp1); 1392 1393 /* Enable PLL */ 1394 OUTREG(dpll_reg, *dpll); 1395 1396 /* Set DVOs B/C */ 1397 OUTREG(DVOB, hw->dvob); 1398 OUTREG(DVOC, hw->dvoc); 1399 1400 /* undo funky magic */ 1401 OUTREG(0x61204, 0x00000000); 1402 1403 /* Set ADPA */ 1404 OUTREG(ADPA, INREG(ADPA) | ADPA_DAC_ENABLE); 1405 OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3); 1406 1407 /* Set pipe parameters */ 1408 OUTREG(hsync_reg, *hs); 1409 OUTREG(hblank_reg, *hb); 1410 OUTREG(htotal_reg, *ht); 1411 OUTREG(vsync_reg, *vs); 1412 OUTREG(vblank_reg, *vb); 1413 OUTREG(vtotal_reg, *vt); 1414 OUTREG(src_size_reg, *ss); 1415 1416 switch (dinfo->info->var.vmode & (FB_VMODE_INTERLACED | 1417 FB_VMODE_ODD_FLD_FIRST)) { 1418 case FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST: 1419 OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_ODD_EN); 1420 break; 1421 case FB_VMODE_INTERLACED: /* even lines first */ 1422 OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_EVEN_EN); 1423 break; 1424 default: /* non-interlaced */ 1425 OUTREG(pipe_stat_reg, 0xFFFF); /* clear all status bits only */ 1426 } 1427 /* Enable pipe */ 1428 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); 1429 1430 /* Enable sync */ 1431 tmp = INREG(ADPA); 1432 tmp &= ~ADPA_DPMS_CONTROL_MASK; 1433 tmp |= ADPA_DPMS_D0; 1434 OUTREG(ADPA, tmp); 1435 1436 /* setup display plane */ 1437 if (dinfo->pdev->device == PCI_DEVICE_ID_INTEL_830M) { 1438 /* 1439 * i830M errata: the display plane must be enabled 1440 * to allow writes to the other bits in the plane 1441 * control register. 1442 */ 1443 tmp = INREG(DSPACNTR); 1444 if ((tmp & DISPPLANE_PLANE_ENABLE) != DISPPLANE_PLANE_ENABLE) { 1445 tmp |= DISPPLANE_PLANE_ENABLE; 1446 OUTREG(DSPACNTR, tmp); 1447 OUTREG(DSPACNTR, 1448 hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); 1449 mdelay(1); 1450 } 1451 } 1452 1453 OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); 1454 OUTREG(DSPASTRIDE, hw->disp_a_stride); 1455 OUTREG(DSPABASE, hw->disp_a_base); 1456 1457 /* Enable plane */ 1458 if (!blank) { 1459 tmp = INREG(DSPACNTR); 1460 tmp |= DISPPLANE_PLANE_ENABLE; 1461 OUTREG(DSPACNTR, tmp); 1462 OUTREG(DSPABASE, hw->disp_a_base); 1463 } 1464 1465 return 0; 1466} 1467 1468/* forward declarations */ 1469static void refresh_ring(struct intelfb_info *dinfo); 1470static void reset_state(struct intelfb_info *dinfo); 1471static void do_flush(struct intelfb_info *dinfo); 1472 1473static u32 get_ring_space(struct intelfb_info *dinfo) 1474{ 1475 u32 ring_space; 1476 1477 if (dinfo->ring_tail >= dinfo->ring_head) 1478 ring_space = dinfo->ring.size - 1479 (dinfo->ring_tail - dinfo->ring_head); 1480 else 1481 ring_space = dinfo->ring_head - dinfo->ring_tail; 1482 1483 if (ring_space > RING_MIN_FREE) 1484 ring_space -= RING_MIN_FREE; 1485 else 1486 ring_space = 0; 1487 1488 return ring_space; 1489} 1490 1491static int wait_ring(struct intelfb_info *dinfo, int n) 1492{ 1493 int i = 0; 1494 unsigned long end; 1495 u32 last_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1496 1497#if VERBOSE > 0 1498 DBG_MSG("wait_ring: %d\n", n); 1499#endif 1500 1501 end = jiffies + (HZ * 3); 1502 while (dinfo->ring_space < n) { 1503 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1504 dinfo->ring_space = get_ring_space(dinfo); 1505 1506 if (dinfo->ring_head != last_head) { 1507 end = jiffies + (HZ * 3); 1508 last_head = dinfo->ring_head; 1509 } 1510 i++; 1511 if (time_before(end, jiffies)) { 1512 if (!i) { 1513 /* Try again */ 1514 reset_state(dinfo); 1515 refresh_ring(dinfo); 1516 do_flush(dinfo); 1517 end = jiffies + (HZ * 3); 1518 i = 1; 1519 } else { 1520 WRN_MSG("ring buffer : space: %d wanted %d\n", 1521 dinfo->ring_space, n); 1522 WRN_MSG("lockup - turning off hardware " 1523 "acceleration\n"); 1524 dinfo->ring_lockup = 1; 1525 break; 1526 } 1527 } 1528 udelay(1); 1529 } 1530 return i; 1531} 1532 1533static void do_flush(struct intelfb_info *dinfo) 1534{ 1535 START_RING(2); 1536 OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); 1537 OUT_RING(MI_NOOP); 1538 ADVANCE_RING(); 1539} 1540 1541void intelfbhw_do_sync(struct intelfb_info *dinfo) 1542{ 1543#if VERBOSE > 0 1544 DBG_MSG("intelfbhw_do_sync\n"); 1545#endif 1546 1547 if (!dinfo->accel) 1548 return; 1549 1550 /* 1551 * Send a flush, then wait until the ring is empty. This is what 1552 * the XFree86 driver does, and actually it doesn't seem a lot worse 1553 * than the recommended method (both have problems). 1554 */ 1555 do_flush(dinfo); 1556 wait_ring(dinfo, dinfo->ring.size - RING_MIN_FREE); 1557 dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE; 1558} 1559 1560static void refresh_ring(struct intelfb_info *dinfo) 1561{ 1562#if VERBOSE > 0 1563 DBG_MSG("refresh_ring\n"); 1564#endif 1565 1566 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1567 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; 1568 dinfo->ring_space = get_ring_space(dinfo); 1569} 1570 1571static void reset_state(struct intelfb_info *dinfo) 1572{ 1573 int i; 1574 u32 tmp; 1575 1576#if VERBOSE > 0 1577 DBG_MSG("reset_state\n"); 1578#endif 1579 1580 for (i = 0; i < FENCE_NUM; i++) 1581 OUTREG(FENCE + (i << 2), 0); 1582 1583 /* Flush the ring buffer if it's enabled. */ 1584 tmp = INREG(PRI_RING_LENGTH); 1585 if (tmp & RING_ENABLE) { 1586#if VERBOSE > 0 1587 DBG_MSG("reset_state: ring was enabled\n"); 1588#endif 1589 refresh_ring(dinfo); 1590 intelfbhw_do_sync(dinfo); 1591 DO_RING_IDLE(); 1592 } 1593 1594 OUTREG(PRI_RING_LENGTH, 0); 1595 OUTREG(PRI_RING_HEAD, 0); 1596 OUTREG(PRI_RING_TAIL, 0); 1597 OUTREG(PRI_RING_START, 0); 1598} 1599 1600/* Stop the 2D engine, and turn off the ring buffer. */ 1601void intelfbhw_2d_stop(struct intelfb_info *dinfo) 1602{ 1603#if VERBOSE > 0 1604 DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", 1605 dinfo->accel, dinfo->ring_active); 1606#endif 1607 1608 if (!dinfo->accel) 1609 return; 1610 1611 dinfo->ring_active = 0; 1612 reset_state(dinfo); 1613} 1614 1615/* 1616 * Enable the ring buffer, and initialise the 2D engine. 1617 * It is assumed that the graphics engine has been stopped by previously 1618 * calling intelfb_2d_stop(). 1619 */ 1620void intelfbhw_2d_start(struct intelfb_info *dinfo) 1621{ 1622#if VERBOSE > 0 1623 DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n", 1624 dinfo->accel, dinfo->ring_active); 1625#endif 1626 1627 if (!dinfo->accel) 1628 return; 1629 1630 /* Initialise the primary ring buffer. */ 1631 OUTREG(PRI_RING_LENGTH, 0); 1632 OUTREG(PRI_RING_TAIL, 0); 1633 OUTREG(PRI_RING_HEAD, 0); 1634 1635 OUTREG(PRI_RING_START, dinfo->ring.physical & RING_START_MASK); 1636 OUTREG(PRI_RING_LENGTH, 1637 ((dinfo->ring.size - GTT_PAGE_SIZE) & RING_LENGTH_MASK) | 1638 RING_NO_REPORT | RING_ENABLE); 1639 refresh_ring(dinfo); 1640 dinfo->ring_active = 1; 1641} 1642 1643/* 2D fillrect (solid fill or invert) */ 1644void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, 1645 u32 h, u32 color, u32 pitch, u32 bpp, u32 rop) 1646{ 1647 u32 br00, br09, br13, br14, br16; 1648 1649#if VERBOSE > 0 1650 DBG_MSG("intelfbhw_do_fillrect: (%d,%d) %dx%d, c 0x%06x, p %d bpp %d, " 1651 "rop 0x%02x\n", x, y, w, h, color, pitch, bpp, rop); 1652#endif 1653 1654 br00 = COLOR_BLT_CMD; 1655 br09 = dinfo->fb_start + (y * pitch + x * (bpp / 8)); 1656 br13 = (rop << ROP_SHIFT) | pitch; 1657 br14 = (h << HEIGHT_SHIFT) | ((w * (bpp / 8)) << WIDTH_SHIFT); 1658 br16 = color; 1659 1660 switch (bpp) { 1661 case 8: 1662 br13 |= COLOR_DEPTH_8; 1663 break; 1664 case 16: 1665 br13 |= COLOR_DEPTH_16; 1666 break; 1667 case 32: 1668 br13 |= COLOR_DEPTH_32; 1669 br00 |= WRITE_ALPHA | WRITE_RGB; 1670 break; 1671 } 1672 1673 START_RING(6); 1674 OUT_RING(br00); 1675 OUT_RING(br13); 1676 OUT_RING(br14); 1677 OUT_RING(br09); 1678 OUT_RING(br16); 1679 OUT_RING(MI_NOOP); 1680 ADVANCE_RING(); 1681 1682#if VERBOSE > 0 1683 DBG_MSG("ring = 0x%08x, 0x%08x (%d)\n", dinfo->ring_head, 1684 dinfo->ring_tail, dinfo->ring_space); 1685#endif 1686} 1687 1688void 1689intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury, 1690 u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch, u32 bpp) 1691{ 1692 u32 br00, br09, br11, br12, br13, br22, br23, br26; 1693 1694#if VERBOSE > 0 1695 DBG_MSG("intelfbhw_do_bitblt: (%d,%d)->(%d,%d) %dx%d, p %d bpp %d\n", 1696 curx, cury, dstx, dsty, w, h, pitch, bpp); 1697#endif 1698 1699 br00 = XY_SRC_COPY_BLT_CMD; 1700 br09 = dinfo->fb_start; 1701 br11 = (pitch << PITCH_SHIFT); 1702 br12 = dinfo->fb_start; 1703 br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT); 1704 br22 = (dstx << WIDTH_SHIFT) | (dsty << HEIGHT_SHIFT); 1705 br23 = ((dstx + w) << WIDTH_SHIFT) | 1706 ((dsty + h) << HEIGHT_SHIFT); 1707 br26 = (curx << WIDTH_SHIFT) | (cury << HEIGHT_SHIFT); 1708 1709 switch (bpp) { 1710 case 8: 1711 br13 |= COLOR_DEPTH_8; 1712 break; 1713 case 16: 1714 br13 |= COLOR_DEPTH_16; 1715 break; 1716 case 32: 1717 br13 |= COLOR_DEPTH_32; 1718 br00 |= WRITE_ALPHA | WRITE_RGB; 1719 break; 1720 } 1721 1722 START_RING(8); 1723 OUT_RING(br00); 1724 OUT_RING(br13); 1725 OUT_RING(br22); 1726 OUT_RING(br23); 1727 OUT_RING(br09); 1728 OUT_RING(br26); 1729 OUT_RING(br11); 1730 OUT_RING(br12); 1731 ADVANCE_RING(); 1732} 1733 1734int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w, 1735 u32 h, const u8* cdat, u32 x, u32 y, u32 pitch, 1736 u32 bpp) 1737{ 1738 int nbytes, ndwords, pad, tmp; 1739 u32 br00, br09, br13, br18, br19, br22, br23; 1740 int dat, ix, iy, iw; 1741 int i, j; 1742 1743#if VERBOSE > 0 1744 DBG_MSG("intelfbhw_do_drawglyph: (%d,%d) %dx%d\n", x, y, w, h); 1745#endif 1746 1747 /* size in bytes of a padded scanline */ 1748 nbytes = ROUND_UP_TO(w, 16) / 8; 1749 1750 /* Total bytes of padded scanline data to write out. */ 1751 nbytes = nbytes * h; 1752 1753 /* 1754 * Check if the glyph data exceeds the immediate mode limit. 1755 * It would take a large font (1K pixels) to hit this limit. 1756 */ 1757 if (nbytes > MAX_MONO_IMM_SIZE) 1758 return 0; 1759 1760 /* Src data is packaged a dword (32-bit) at a time. */ 1761 ndwords = ROUND_UP_TO(nbytes, 4) / 4; 1762 1763 /* 1764 * Ring has to be padded to a quad word. But because the command starts 1765 with 7 bytes, pad only if there is an even number of ndwords 1766 */ 1767 pad = !(ndwords % 2); 1768 1769 tmp = (XY_MONO_SRC_IMM_BLT_CMD & DW_LENGTH_MASK) + ndwords; 1770 br00 = (XY_MONO_SRC_IMM_BLT_CMD & ~DW_LENGTH_MASK) | tmp; 1771 br09 = dinfo->fb_start; 1772 br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT); 1773 br18 = bg; 1774 br19 = fg; 1775 br22 = (x << WIDTH_SHIFT) | (y << HEIGHT_SHIFT); 1776 br23 = ((x + w) << WIDTH_SHIFT) | ((y + h) << HEIGHT_SHIFT); 1777 1778 switch (bpp) { 1779 case 8: 1780 br13 |= COLOR_DEPTH_8; 1781 break; 1782 case 16: 1783 br13 |= COLOR_DEPTH_16; 1784 break; 1785 case 32: 1786 br13 |= COLOR_DEPTH_32; 1787 br00 |= WRITE_ALPHA | WRITE_RGB; 1788 break; 1789 } 1790 1791 START_RING(8 + ndwords); 1792 OUT_RING(br00); 1793 OUT_RING(br13); 1794 OUT_RING(br22); 1795 OUT_RING(br23); 1796 OUT_RING(br09); 1797 OUT_RING(br18); 1798 OUT_RING(br19); 1799 ix = iy = 0; 1800 iw = ROUND_UP_TO(w, 8) / 8; 1801 while (ndwords--) { 1802 dat = 0; 1803 for (j = 0; j < 2; ++j) { 1804 for (i = 0; i < 2; ++i) { 1805 if (ix != iw || i == 0) 1806 dat |= cdat[iy*iw + ix++] << (i+j*2)*8; 1807 } 1808 if (ix == iw && iy != (h-1)) { 1809 ix = 0; 1810 ++iy; 1811 } 1812 } 1813 OUT_RING(dat); 1814 } 1815 if (pad) 1816 OUT_RING(MI_NOOP); 1817 ADVANCE_RING(); 1818 1819 return 1; 1820} 1821 1822/* HW cursor functions. */ 1823void intelfbhw_cursor_init(struct intelfb_info *dinfo) 1824{ 1825 u32 tmp; 1826 1827#if VERBOSE > 0 1828 DBG_MSG("intelfbhw_cursor_init\n"); 1829#endif 1830 1831 if (dinfo->mobile || IS_I9XX(dinfo)) { 1832 if (!dinfo->cursor.physical) 1833 return; 1834 tmp = INREG(CURSOR_A_CONTROL); 1835 tmp &= ~(CURSOR_MODE_MASK | CURSOR_MOBILE_GAMMA_ENABLE | 1836 CURSOR_MEM_TYPE_LOCAL | 1837 (1 << CURSOR_PIPE_SELECT_SHIFT)); 1838 tmp |= CURSOR_MODE_DISABLE; 1839 OUTREG(CURSOR_A_CONTROL, tmp); 1840 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1841 } else { 1842 tmp = INREG(CURSOR_CONTROL); 1843 tmp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE | 1844 CURSOR_ENABLE | CURSOR_STRIDE_MASK); 1845 tmp = CURSOR_FORMAT_3C; 1846 OUTREG(CURSOR_CONTROL, tmp); 1847 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.offset << 12); 1848 tmp = (64 << CURSOR_SIZE_H_SHIFT) | 1849 (64 << CURSOR_SIZE_V_SHIFT); 1850 OUTREG(CURSOR_SIZE, tmp); 1851 } 1852} 1853 1854void intelfbhw_cursor_hide(struct intelfb_info *dinfo) 1855{ 1856 u32 tmp; 1857 1858#if VERBOSE > 0 1859 DBG_MSG("intelfbhw_cursor_hide\n"); 1860#endif 1861 1862 dinfo->cursor_on = 0; 1863 if (dinfo->mobile || IS_I9XX(dinfo)) { 1864 if (!dinfo->cursor.physical) 1865 return; 1866 tmp = INREG(CURSOR_A_CONTROL); 1867 tmp &= ~CURSOR_MODE_MASK; 1868 tmp |= CURSOR_MODE_DISABLE; 1869 OUTREG(CURSOR_A_CONTROL, tmp); 1870 /* Flush changes */ 1871 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1872 } else { 1873 tmp = INREG(CURSOR_CONTROL); 1874 tmp &= ~CURSOR_ENABLE; 1875 OUTREG(CURSOR_CONTROL, tmp); 1876 } 1877} 1878 1879void intelfbhw_cursor_show(struct intelfb_info *dinfo) 1880{ 1881 u32 tmp; 1882 1883#if VERBOSE > 0 1884 DBG_MSG("intelfbhw_cursor_show\n"); 1885#endif 1886 1887 dinfo->cursor_on = 1; 1888 1889 if (dinfo->cursor_blanked) 1890 return; 1891 1892 if (dinfo->mobile || IS_I9XX(dinfo)) { 1893 if (!dinfo->cursor.physical) 1894 return; 1895 tmp = INREG(CURSOR_A_CONTROL); 1896 tmp &= ~CURSOR_MODE_MASK; 1897 tmp |= CURSOR_MODE_64_4C_AX; 1898 OUTREG(CURSOR_A_CONTROL, tmp); 1899 /* Flush changes */ 1900 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1901 } else { 1902 tmp = INREG(CURSOR_CONTROL); 1903 tmp |= CURSOR_ENABLE; 1904 OUTREG(CURSOR_CONTROL, tmp); 1905 } 1906} 1907 1908void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y) 1909{ 1910 u32 tmp; 1911 1912#if VERBOSE > 0 1913 DBG_MSG("intelfbhw_cursor_setpos: (%d, %d)\n", x, y); 1914#endif 1915 1916 /* 1917 * Sets the position. The coordinates are assumed to already 1918 * have any offset adjusted. Assume that the cursor is never 1919 * completely off-screen, and that x, y are always >= 0. 1920 */ 1921 1922 tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | 1923 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); 1924 OUTREG(CURSOR_A_POSITION, tmp); 1925 1926 if (IS_I9XX(dinfo)) 1927 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1928} 1929 1930void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg) 1931{ 1932#if VERBOSE > 0 1933 DBG_MSG("intelfbhw_cursor_setcolor\n"); 1934#endif 1935 1936 OUTREG(CURSOR_A_PALETTE0, bg & CURSOR_PALETTE_MASK); 1937 OUTREG(CURSOR_A_PALETTE1, fg & CURSOR_PALETTE_MASK); 1938 OUTREG(CURSOR_A_PALETTE2, fg & CURSOR_PALETTE_MASK); 1939 OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK); 1940} 1941 1942void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height, 1943 u8 *data) 1944{ 1945 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1946 int i, j, w = width / 8; 1947 int mod = width % 8, t_mask, d_mask; 1948 1949#if VERBOSE > 0 1950 DBG_MSG("intelfbhw_cursor_load\n"); 1951#endif 1952 1953 if (!dinfo->cursor.virtual) 1954 return; 1955 1956 t_mask = 0xff >> mod; 1957 d_mask = ~(0xff >> mod); 1958 for (i = height; i--; ) { 1959 for (j = 0; j < w; j++) { 1960 writeb(0x00, addr + j); 1961 writeb(*(data++), addr + j+8); 1962 } 1963 if (mod) { 1964 writeb(t_mask, addr + j); 1965 writeb(*(data++) & d_mask, addr + j+8); 1966 } 1967 addr += 16; 1968 } 1969} 1970 1971void intelfbhw_cursor_reset(struct intelfb_info *dinfo) 1972{ 1973 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1974 int i, j; 1975 1976#if VERBOSE > 0 1977 DBG_MSG("intelfbhw_cursor_reset\n"); 1978#endif 1979 1980 if (!dinfo->cursor.virtual) 1981 return; 1982 1983 for (i = 64; i--; ) { 1984 for (j = 0; j < 8; j++) { 1985 writeb(0xff, addr + j+0); 1986 writeb(0x00, addr + j+8); 1987 } 1988 addr += 16; 1989 } 1990} 1991 1992static irqreturn_t intelfbhw_irq(int irq, void *dev_id) 1993{ 1994 u16 tmp; 1995 struct intelfb_info *dinfo = dev_id; 1996 1997 spin_lock(&dinfo->int_lock); 1998 1999 tmp = INREG16(IIR); 2000 if (dinfo->info->var.vmode & FB_VMODE_INTERLACED) 2001 tmp &= PIPE_A_EVENT_INTERRUPT; 2002 else 2003 tmp &= VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */ 2004 2005 if (tmp == 0) { 2006 spin_unlock(&dinfo->int_lock); 2007 return IRQ_RETVAL(0); /* not us */ 2008 } 2009 2010 /* clear status bits 0-15 ASAP and don't touch bits 16-31 */ 2011 OUTREG(PIPEASTAT, INREG(PIPEASTAT)); 2012 2013 OUTREG16(IIR, tmp); 2014 if (dinfo->vsync.pan_display) { 2015 dinfo->vsync.pan_display = 0; 2016 OUTREG(DSPABASE, dinfo->vsync.pan_offset); 2017 } 2018 2019 dinfo->vsync.count++; 2020 wake_up_interruptible(&dinfo->vsync.wait); 2021 2022 spin_unlock(&dinfo->int_lock); 2023 2024 return IRQ_RETVAL(1); 2025} 2026 2027int intelfbhw_enable_irq(struct intelfb_info *dinfo) 2028{ 2029 u16 tmp; 2030 if (!test_and_set_bit(0, &dinfo->irq_flags)) { 2031 if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED, 2032 "intelfb", dinfo)) { 2033 clear_bit(0, &dinfo->irq_flags); 2034 return -EINVAL; 2035 } 2036 2037 spin_lock_irq(&dinfo->int_lock); 2038 OUTREG16(HWSTAM, 0xfffe); /* i830 DRM uses ffff */ 2039 OUTREG16(IMR, 0); 2040 } else 2041 spin_lock_irq(&dinfo->int_lock); 2042 2043 if (dinfo->info->var.vmode & FB_VMODE_INTERLACED) 2044 tmp = PIPE_A_EVENT_INTERRUPT; 2045 else 2046 tmp = VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */ 2047 if (tmp != INREG16(IER)) { 2048 DBG_MSG("changing IER to 0x%X\n", tmp); 2049 OUTREG16(IER, tmp); 2050 } 2051 2052 spin_unlock_irq(&dinfo->int_lock); 2053 return 0; 2054} 2055 2056void intelfbhw_disable_irq(struct intelfb_info *dinfo) 2057{ 2058 if (test_and_clear_bit(0, &dinfo->irq_flags)) { 2059 if (dinfo->vsync.pan_display) { 2060 dinfo->vsync.pan_display = 0; 2061 OUTREG(DSPABASE, dinfo->vsync.pan_offset); 2062 } 2063 spin_lock_irq(&dinfo->int_lock); 2064 OUTREG16(HWSTAM, 0xffff); 2065 OUTREG16(IMR, 0xffff); 2066 OUTREG16(IER, 0x0); 2067 2068 OUTREG16(IIR, INREG16(IIR)); /* clear IRQ requests */ 2069 spin_unlock_irq(&dinfo->int_lock); 2070 2071 free_irq(dinfo->pdev->irq, dinfo); 2072 } 2073} 2074 2075int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) 2076{ 2077 struct intelfb_vsync *vsync; 2078 unsigned int count; 2079 int ret; 2080 2081 switch (pipe) { 2082 case 0: 2083 vsync = &dinfo->vsync; 2084 break; 2085 default: 2086 return -ENODEV; 2087 } 2088 2089 ret = intelfbhw_enable_irq(dinfo); 2090 if (ret) 2091 return ret; 2092 2093 count = vsync->count; 2094 ret = wait_event_interruptible_timeout(vsync->wait, 2095 count != vsync->count, HZ / 10); 2096 if (ret < 0) 2097 return ret; 2098 if (ret == 0) { 2099 DBG_MSG("wait_for_vsync timed out!\n"); 2100 return -ETIMEDOUT; 2101 } 2102 2103 return 0; 2104} 2105