Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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