void intel_batch_teardown(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int i; for (i = 0; i < ARRAY_SIZE(intel->last_batch_bo); i++) { if (intel->last_batch_bo[i] != NULL) { dri_bo_unreference(intel->last_batch_bo[i]); intel->last_batch_bo[i] = NULL; } } if (intel->batch_bo != NULL) { dri_bo_unreference(intel->batch_bo); intel->batch_bo = NULL; } if (intel->vertex_bo) { dri_bo_unreference(intel->vertex_bo); intel->vertex_bo = NULL; } while (!list_is_empty(&intel->batch_pixmaps)) list_del(intel->batch_pixmaps.next); }
static void intel_emit_post_sync_nonzero_flush(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); /* keep this entire sequence of 3 PIPE_CONTROL cmds in one batch to * avoid upsetting the gpu. */ BEGIN_BATCH(3*4); OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_CS_STALL | BRW_PIPE_CONTROL_STALL_AT_SCOREBOARD); OUT_BATCH(0); /* address */ OUT_BATCH(0); /* write data */ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_WRITE_QWORD); OUT_RELOC(intel->wa_scratch_bo, I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 0); OUT_BATCH(0); /* write data */ /* now finally the _real flush */ OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2)); OUT_BATCH(BRW_PIPE_CONTROL_WC_FLUSH | BRW_PIPE_CONTROL_TC_FLUSH | BRW_PIPE_CONTROL_NOWRITE); OUT_BATCH(0); /* write address */ OUT_BATCH(0); /* write data */ ADVANCE_BATCH(); }
static Bool i830_dvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); I830OutputPrivatePtr intel_output = output->driver_private; /* If we have timings from the BIOS for the panel, put them in * to the adjusted mode. The CRTC will be set up for this mode, * with the panel scaling set up to source from the H/VDisplay * of the original mode. */ if (intel->lvds_fixed_mode != NULL) { adjusted_mode->HDisplay = intel->lvds_fixed_mode->HDisplay; adjusted_mode->HSyncStart = intel->lvds_fixed_mode->HSyncStart; adjusted_mode->HSyncEnd = intel->lvds_fixed_mode->HSyncEnd; adjusted_mode->HTotal = intel->lvds_fixed_mode->HTotal; adjusted_mode->VDisplay = intel->lvds_fixed_mode->VDisplay; adjusted_mode->VSyncStart = intel->lvds_fixed_mode->VSyncStart; adjusted_mode->VSyncEnd = intel->lvds_fixed_mode->VSyncEnd; adjusted_mode->VTotal = intel->lvds_fixed_mode->VTotal; adjusted_mode->Clock = intel->lvds_fixed_mode->Clock; xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); } if (intel_output->i2c_drv->vid_rec->mode_fixup) return intel_output->i2c_drv->vid_rec->mode_fixup (intel_output->i2c_drv->dev_priv, mode, adjusted_mode); return TRUE; }
/* * Queue a flip back to the normal frame buffer */ static void intel_present_unflip(ScreenPtr screen, uint64_t event_id) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); PixmapPtr pixmap = screen->GetScreenPixmap(screen); struct intel_present_vblank_event *event = NULL; dri_bo *bo; if (!intel_present_check_flip(NULL, screen->root, pixmap, true)) goto fail; bo = intel_get_pixmap_bo(pixmap); if (!bo) goto fail; event = calloc(1, sizeof(struct intel_present_vblank_event)); if (!event) goto fail; event->event_id = event_id; if (!intel_do_pageflip(intel, bo, -1, FALSE, event, intel_present_flip_event, intel_present_flip_abort)) goto fail; return; fail: xf86SetDesiredModes(scrn); present_event_notify(event_id, 0, 0); free(event); }
/* * Test to see if page flipping is possible on the target crtc */ static Bool intel_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, Bool sync_flip) { ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); dri_bo *bo; if (!scrn->vtSema) return FALSE; if (intel->shadow_present) return FALSE; if (!intel->use_pageflipping) return FALSE; if (crtc && !intel_crtc_on(crtc->devPrivate)) return FALSE; /* Check stride, can't change that on flip */ if (pixmap->devKind != intel->front_pitch) return FALSE; /* Make sure there's a bo we can get to */ bo = intel_get_pixmap_bo(pixmap); if (!bo) return FALSE; return TRUE; }
static void drmmode_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) { ScrnInfoPtr scrn = crtc->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_ptr drmmode = drmmode_crtc->drmmode; if (rotate_pixmap) { intel_set_pixmap_bo(rotate_pixmap, NULL); FreeScratchPixmapHeader(rotate_pixmap); } if (data) { /* Be sure to sync acceleration before the memory gets * unbound. */ drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id); drmmode_crtc->rotate_fb_id = 0; dri_bo_unreference(drmmode_crtc->rotate_bo); drmmode_crtc->rotate_bo = NULL; } intel->shadow_present = intel->use_shadow; }
/* * Queue a flip back to the normal frame buffer */ static void intel_present_unflip(ScreenPtr screen, uint64_t event_id) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_present_vblank_event *event; PixmapPtr pixmap = screen->GetScreenPixmap(screen); dri_bo *bo; Bool ret; if (!intel_present_check_flip(NULL, screen->root, pixmap, true)) return; bo = intel_get_pixmap_bo(pixmap); if (!bo) return; event = calloc(1, sizeof(struct intel_present_vblank_event)); if (!event) return; event->event_id = event_id; ret = intel_do_pageflip(intel, bo, -1, FALSE, event, intel_present_flip_event, intel_present_flip_abort); if (!ret) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n"); } }
/** * Sets up hardware state for a series of solid fills. */ static Bool intel_uxa_prepare_solid(PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg) { ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); drm_intel_bo *bo_table[] = { NULL, /* batch_bo */ intel_get_pixmap_bo(pixmap), }; if (!intel_check_pitch_2d(pixmap)) return FALSE; if (!intel_get_aperture_space(scrn, bo_table, ARRAY_SIZE(bo_table))) return FALSE; intel->BR[13] = (I830PatternROP[alu] & 0xff) << 16; switch (pixmap->drawable.bitsPerPixel) { case 8: break; case 16: /* RGB565 */ intel->BR[13] |= (1 << 24); break; case 32: /* RGB8888 */ intel->BR[13] |= ((1 << 24) | (1 << 25)); break; } intel->BR[16] = fg; return TRUE; }
static DisplayModePtr i830_dvo_get_modes(xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); I830OutputPrivatePtr intel_output = output->driver_private; DisplayModePtr modes; /* We should probably have an i2c driver get_modes function for those * devices which will have a fixed set of modes determined by the chip * (TV-out, for example), but for now with just TMDS and LVDS, that's not * the case. */ modes = i830_ddc_get_modes(output); if (modes != NULL) return modes; if (intel_output->i2c_drv->vid_rec->get_modes) { modes = intel_output->i2c_drv->vid_rec->get_modes (intel_output->i2c_drv->dev_priv); if (modes != NULL) return modes; } if (intel->lvds_fixed_mode != NULL) return xf86DuplicateMode(intel->lvds_fixed_mode); return NULL; }
void intel_set_gem_max_sizes(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); size_t agp_size = agp_aperture_size(xf86GetPciInfoForEntity(intel->pEnt->index), INTEL_INFO(intel)->gen); /* The chances of being able to mmap an object larger than * agp_size/2 are slim. Moreover, we may be forced to fallback * using a gtt mapping as both the source and a mask, as well * as a destination and all need to fit into the aperture. */ intel->max_gtt_map_size = agp_size / 4; /* Let objects be tiled up to the size where only 4 would fit in * the aperture, presuming best case alignment. Also if we * cannot mmap it using the GTT we will be stuck. */ intel->max_tiling_size = intel->max_gtt_map_size; /* Large BOs will tend to hit SW fallbacks frequently, and also will * tend to fail to successfully map when doing SW fallbacks because we * overcommit address space for BO access, or worse cause aperture * thrashing. */ intel->max_bo_size = intel->max_gtt_map_size; }
static void intel_batch_do_flush(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_pixmap *priv; list_for_each_entry(priv, &intel->batch_pixmaps, batch) priv->dirty = 0; }
/* * Flush the DRM event queue when full; this * makes space for new requests */ static Bool intel_present_flush_drm_events(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); return intel_mode_read_drm_events(intel) >= 0; }
static dri_bo *bo_alloc(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); int size = 4 * 4096; /* The 865 has issues with larger-than-page-sized batch buffers. */ if (IS_I865G(intel)) size = 4096; return dri_bo_alloc(intel->bufmgr, "batch", size, 4096); }
/* * Flush our batch buffer when requested by the Present extension. */ static void intel_present_flush(WindowPtr window) { ScreenPtr screen = window->drawable.pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); if (intel->flush_rendering) intel->flush_rendering(intel); }
void intel_debug_flush(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); if (intel->debug_flush & DEBUG_FLUSH_CACHES) intel_batch_emit_flush(scrn); if (intel->debug_flush & DEBUG_FLUSH_BATCHES) intel_batch_submit(scrn); }
static void i830_dvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, DisplayModePtr adjusted_mode) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); xf86CrtcPtr crtc = output->crtc; I830CrtcPrivatePtr intel_crtc = crtc->driver_private; I830OutputPrivatePtr intel_output = output->driver_private; struct _I830DVODriver *drv = intel_output->i2c_drv; int pipe = intel_crtc->pipe; uint32_t dvo; unsigned int dvo_reg = drv->dvo_reg, dvo_srcdim_reg; int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; switch (dvo_reg) { case DVOA: default: dvo_srcdim_reg = DVOA_SRCDIM; break; case DVOB: dvo_srcdim_reg = DVOB_SRCDIM; break; case DVOC: dvo_srcdim_reg = DVOC_SRCDIM; break; } intel_output->i2c_drv->vid_rec->mode_set(intel_output->i2c_drv->dev_priv, mode, adjusted_mode); /* Save the data order, since I don't know what it should be set to. */ dvo = INREG(dvo_reg) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG); dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | DVO_BLANK_ACTIVE_HIGH; if (pipe == 1) dvo |= DVO_PIPE_B_SELECT; dvo |= DVO_PIPE_STALL; if (adjusted_mode->Flags & V_PHSYNC) dvo |= DVO_HSYNC_ACTIVE_HIGH; if (adjusted_mode->Flags & V_PVSYNC) dvo |= DVO_VSYNC_ACTIVE_HIGH; OUTREG(dpll_reg, INREG(dpll_reg) | DPLL_DVO_HIGH_SPEED); /*OUTREG(DVOB_SRCDIM, (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ OUTREG(dvo_srcdim_reg, (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT)); /*OUTREG(DVOB, dvo);*/ OUTREG(dvo_reg, dvo); }
static xf86CrtcPtr i830_dvo_get_crtc(xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); I830OutputPrivatePtr intel_output = output->driver_private; struct _I830DVODriver *drv = intel_output->i2c_drv; int pipe = !!(INREG(drv->dvo_reg) & SDVO_PIPE_B_SELECT); return intel_pipe_to_crtc(scrn, pipe); }
static PixmapPtr intel_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); struct intel_uxa_pixmap *priv; PixmapPtr pixmap; dri_bo *bo; if (depth < 8) return NULL; switch (bpp) { case 8: case 16: case 32: break; default: return NULL; } pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); if (!pixmap) return NULL; if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL)) goto free_pixmap; bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, fd, (uint32_t)height * stride); if (bo == NULL) goto free_pixmap; intel_uxa_set_pixmap_bo(pixmap, bo); dri_bo_unreference(bo); priv = intel_uxa_get_pixmap_private(pixmap); if (priv == NULL) goto free_pixmap; priv->pinned |= PIN_DRI3; return pixmap; free_pixmap: fbDestroyPixmap(pixmap); return NULL; }
drm_intel_bo *intel_allocate_framebuffer(ScrnInfoPtr scrn, int width, int height, int cpp, int *out_stride, uint32_t *out_tiling) { intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t tiling; int stride, size; drm_intel_bo *bo; intel_set_gem_max_sizes(scrn); if (intel->tiling & INTEL_TILING_FB) tiling = I915_TILING_X; else tiling = I915_TILING_NONE; retry: size = intel_compute_size(intel, width, height, intel->cpp*8, 0, &tiling, &stride); if (!intel_check_display_stride(scrn, stride, tiling)) { if (tiling != I915_TILING_NONE) { tiling = I915_TILING_NONE; goto retry; } xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Front buffer stride %d kB " "exceeds display limit\n", stride / 1024); return NULL; } bo = drm_intel_bo_alloc(intel->bufmgr, "front buffer", size, 0); if (bo == NULL) return FALSE; if (tiling != I915_TILING_NONE) drm_intel_bo_set_tiling(bo, &tiling, stride); xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocated new frame buffer %dx%d stride %d, %s\n", width, height, stride, tiling == I915_TILING_NONE ? "untiled" : "tiled"); drm_intel_bo_disable_reuse(bo); *out_stride = stride; *out_tiling = tiling; return bo; }
static void i830_dvo_restore(xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); I830OutputPrivatePtr intel_output = output->driver_private; void * dev_priv = intel_output->i2c_drv->dev_priv; (*intel_output->i2c_drv->vid_rec->restore)(dev_priv); OUTREG(DVOA, intel->saveDVOA); OUTREG(DVOB, intel->saveDVOB); OUTREG(DVOC, intel->saveDVOC); }
void intel_batch_init(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); intel->batch_emit_start = 0; intel->batch_emitting = 0; intel->vertex_id = 0; intel->last_batch_bo[0] = bo_alloc(scrn); intel->last_batch_bo[1] = bo_alloc(scrn); intel->batch_bo = bo_alloc(scrn); intel->batch_used = 0; intel->last_3d = LAST_3D_OTHER; }
static Bool intel_present_has_async_flip(ScreenPtr screen) { #ifdef DRM_CAP_ASYNC_PAGE_FLIP ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); int ret; uint64_t value; ret = drmGetCap(intel->drmSubFD, DRM_CAP_ASYNC_PAGE_FLIP, &value); if (ret == 0) return value == 1; #endif return FALSE; }
static int i830_lvds_get_backlight_native(xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t blc_pwm_ctl, reg; if (HAS_PCH_SPLIT(intel)) reg = BLC_PWM_CPU_CTL; else reg = BLC_PWM_CTL; blc_pwm_ctl = INREG(reg); blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; return blc_pwm_ctl; }
/* * Native methods */ static void i830_lvds_set_backlight_native(xf86OutputPtr output, int level) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); uint32_t blc_pwm_ctl, reg; if (HAS_PCH_SPLIT(intel)) reg = BLC_PWM_CPU_CTL; else reg = BLC_PWM_CTL; blc_pwm_ctl = INREG(reg); blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; OUTREG(reg, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); }
static int intel_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); intel_screen_private *intel = intel_get_screen_private(scrn); int fd; fd = intel_get_client_fd(intel->dev); if (fd < 0) return -fd; *out = fd; return Success; }
static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2) { ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); unsigned long pitch; uint32_t cmd; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 > pixmap->drawable.width) x2 = pixmap->drawable.width; if (y2 > pixmap->drawable.height) y2 = pixmap->drawable.height; if (x2 <= x1 || y2 <= y1) return; pitch = intel_pixmap_pitch(pixmap); { BEGIN_BATCH_BLT(6); cmd = XY_COLOR_BLT_CMD; if (pixmap->drawable.bitsPerPixel == 32) cmd |= XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB; if (INTEL_INFO(intel)->gen >= 40 && intel_pixmap_tiled(pixmap)) { assert((pitch % 512) == 0); pitch >>= 2; cmd |= XY_COLOR_BLT_TILED; } OUT_BATCH(cmd); OUT_BATCH(intel->BR[13] | pitch); OUT_BATCH((y1 << 16) | (x1 & 0xffff)); OUT_BATCH((y2 << 16) | (x2 & 0xffff)); OUT_RELOC_PIXMAP_FENCED(pixmap, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); OUT_BATCH(intel->BR[16]); ADVANCE_BATCH(); }
static void i830_dvo_save(xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; intel_screen_private *intel = intel_get_screen_private(scrn); I830OutputPrivatePtr intel_output = output->driver_private; void * dev_priv = intel_output->i2c_drv->dev_priv; /* Each output should probably just save the registers it touches, but for * now, use more overkill. */ intel->saveDVOA = INREG(DVOA); intel->saveDVOB = INREG(DVOB); intel->saveDVOC = INREG(DVOC); (*intel_output->i2c_drv->vid_rec->save)(dev_priv); }
static void intel_next_batch(ScrnInfoPtr scrn, int mode) { intel_screen_private *intel = intel_get_screen_private(scrn); dri_bo *tmp; drm_intel_gem_bo_clear_relocs(intel->batch_bo, 0); tmp = intel->last_batch_bo[mode]; intel->last_batch_bo[mode] = intel->batch_bo; intel->batch_bo = tmp; intel->batch_used = 0; /* We don't know when another client has executed, so we have * to reinitialize our 3D state per batch. */ intel->last_3d = LAST_3D_OTHER; }
Bool i830_check_composite_texture(ScreenPtr screen, PicturePtr picture) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; intel_screen_private *intel = intel_get_screen_private(scrn); if (picture->repeatType > RepeatReflect) { intel_debug_fallback(scrn, "Unsupported picture repeat %d\n", picture->repeatType); return FALSE; } if (picture->filter != PictFilterNearest && picture->filter != PictFilterBilinear) { intel_debug_fallback(scrn, "Unsupported filter 0x%x\n", picture->filter); return FALSE; } if (picture->pDrawable) { int w, h; w = picture->pDrawable->width; h = picture->pDrawable->height; if ((w > 2048) || (h > 2048)) { intel_debug_fallback(scrn, "Picture w/h too large (%dx%d)\n", w, h); return FALSE; } /* XXX we can use the xrgb32 types if there the picture covers the clip */ if (!i8xx_get_card_format(intel, picture)) { intel_debug_fallback(scrn, "Unsupported picture format " "0x%x\n", (int)picture->format); return FALSE; } return TRUE; } return FALSE; }
/** * Attempts to get a fixed panel timing for LVDS (currently only the i830). * * Other chips with DVO LVDS will need to extend this to deal with the LVDS * chip being on DVOB/C and having multiple pipes. */ static DisplayModePtr i830_dvo_get_current_mode (xf86OutputPtr output) { ScrnInfoPtr scrn = output->scrn; I830OutputPrivatePtr intel_output = output->driver_private; intel_screen_private *intel = intel_get_screen_private(scrn); struct _I830DVODriver *drv = intel_output->i2c_drv; unsigned int dvo_reg = drv->dvo_reg; uint32_t dvo = INREG(dvo_reg); DisplayModePtr mode = NULL; /* If the DVO port is active, that'll be the LVDS, so we can pull out * its timings to get how the BIOS set up the panel. */ if (dvo & DVO_ENABLE) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int pipe = (dvo & DVO_PIPE_B_SELECT) ? 1 : 0; int c; for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; I830CrtcPrivatePtr intel_crtc = crtc->driver_private; if (intel_crtc->pipe == pipe) { mode = i830_crtc_mode_get(scrn, crtc); if (mode) { mode->type |= M_T_PREFERRED; if (dvo & DVO_HSYNC_ACTIVE_HIGH) mode->Flags |= V_PHSYNC; if (dvo & DVO_VSYNC_ACTIVE_HIGH) mode->Flags |= V_PVSYNC; } break; } } } return mode; }