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