intel_driver.c revision 13496ba1
103b705cfSriastradh/************************************************************************** 203b705cfSriastradh 303b705cfSriastradhCopyright 2001 VA Linux Systems Inc., Fremont, California. 403b705cfSriastradhCopyright © 2002 by David Dawes 503b705cfSriastradh 603b705cfSriastradhAll Rights Reserved. 703b705cfSriastradh 803b705cfSriastradhPermission is hereby granted, free of charge, to any person obtaining a 903b705cfSriastradhcopy of this software and associated documentation files (the "Software"), 1003b705cfSriastradhto deal in the Software without restriction, including without limitation 1103b705cfSriastradhon the rights to use, copy, modify, merge, publish, distribute, sub 1203b705cfSriastradhlicense, and/or sell copies of the Software, and to permit persons to whom 1303b705cfSriastradhthe Software is furnished to do so, subject to the following conditions: 1403b705cfSriastradh 1503b705cfSriastradhThe above copyright notice and this permission notice (including the next 1603b705cfSriastradhparagraph) shall be included in all copies or substantial portions of the 1703b705cfSriastradhSoftware. 1803b705cfSriastradh 1903b705cfSriastradhTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 2003b705cfSriastradhIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 2103b705cfSriastradhFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 2203b705cfSriastradhTHE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 2303b705cfSriastradhDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 2403b705cfSriastradhOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 2503b705cfSriastradhUSE OR OTHER DEALINGS IN THE SOFTWARE. 2603b705cfSriastradh 2703b705cfSriastradh**************************************************************************/ 2803b705cfSriastradh 2903b705cfSriastradh/* 3003b705cfSriastradh * Authors: Jeff Hartmann <jhartmann@valinux.com> 3103b705cfSriastradh * Abraham van der Merwe <abraham@2d3d.co.za> 3203b705cfSriastradh * David Dawes <dawes@xfree86.org> 3303b705cfSriastradh * Alan Hourihane <alanh@tungstengraphics.com> 3403b705cfSriastradh */ 3503b705cfSriastradh 3603b705cfSriastradh#ifdef HAVE_CONFIG_H 3703b705cfSriastradh#include "config.h" 3803b705cfSriastradh#endif 3903b705cfSriastradh 4003b705cfSriastradh#include <assert.h> 4103b705cfSriastradh#include <string.h> 4203b705cfSriastradh#include <stdio.h> 4303b705cfSriastradh#include <unistd.h> 4403b705cfSriastradh#include <stdlib.h> 4503b705cfSriastradh#include <stdio.h> 4603b705cfSriastradh#include <errno.h> 4703b705cfSriastradh 4842542f5fSchristos#include "xorg-server.h" 4903b705cfSriastradh#include "xf86.h" 5003b705cfSriastradh#include "xf86_OSproc.h" 5103b705cfSriastradh#include "xf86cmap.h" 5203b705cfSriastradh#include "xf86drm.h" 5303b705cfSriastradh#include "compiler.h" 5403b705cfSriastradh#include "mipointer.h" 5503b705cfSriastradh#include "micmap.h" 5603b705cfSriastradh#include <X11/extensions/randr.h> 5703b705cfSriastradh#include "fb.h" 5803b705cfSriastradh#include "miscstruct.h" 5903b705cfSriastradh#include "dixstruct.h" 6003b705cfSriastradh#include "xf86xv.h" 6103b705cfSriastradh#include "shadow.h" 6203b705cfSriastradh#include "intel.h" 6303b705cfSriastradh#include "intel_video.h" 6403b705cfSriastradh#include "uxa_module.h" 6503b705cfSriastradh 6603b705cfSriastradh#ifdef INTEL_XVMC 6703b705cfSriastradh#define _INTEL_XVMC_SERVER_ 6803b705cfSriastradh#include "intel_xvmc.h" 6903b705cfSriastradh#endif 7003b705cfSriastradh 7113496ba1Ssnj#if USE_UXA 7213496ba1Ssnj#include "intel_uxa.h" 7313496ba1Ssnj#endif 7403b705cfSriastradh 7503b705cfSriastradh#include "intel_options.h" 7613496ba1Ssnj#include "i915_drm.h" 7703b705cfSriastradh 7803b705cfSriastradhstatic void i830AdjustFrame(ADJUST_FRAME_ARGS_DECL); 7903b705cfSriastradhstatic Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL); 8003b705cfSriastradhstatic Bool I830EnterVT(VT_FUNC_ARGS_DECL); 8103b705cfSriastradh 8203b705cfSriastradh/* temporary */ 8303b705cfSriastradhextern void xf86SetCursor(ScreenPtr screen, CursorPtr pCurs, int x, int y); 8403b705cfSriastradh 8503b705cfSriastradh/* Export I830 options to i830 driver where necessary */ 8603b705cfSriastradhstatic void 8703b705cfSriastradhI830LoadPalette(ScrnInfoPtr scrn, int numColors, int *indices, 8803b705cfSriastradh LOCO * colors, VisualPtr pVisual) 8903b705cfSriastradh{ 9003b705cfSriastradh xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 9103b705cfSriastradh int i, j, index; 9203b705cfSriastradh int p; 9303b705cfSriastradh uint16_t lut_r[256], lut_g[256], lut_b[256]; 9403b705cfSriastradh 9503b705cfSriastradh for (p = 0; p < xf86_config->num_crtc; p++) { 9603b705cfSriastradh xf86CrtcPtr crtc = xf86_config->crtc[p]; 9703b705cfSriastradh 9803b705cfSriastradh switch (scrn->depth) { 9903b705cfSriastradh case 15: 10003b705cfSriastradh for (i = 0; i < numColors; i++) { 10103b705cfSriastradh index = indices[i]; 10203b705cfSriastradh for (j = 0; j < 8; j++) { 10303b705cfSriastradh lut_r[index * 8 + j] = 10403b705cfSriastradh colors[index].red << 8; 10503b705cfSriastradh lut_g[index * 8 + j] = 10603b705cfSriastradh colors[index].green << 8; 10703b705cfSriastradh lut_b[index * 8 + j] = 10803b705cfSriastradh colors[index].blue << 8; 10903b705cfSriastradh } 11003b705cfSriastradh } 11103b705cfSriastradh break; 11203b705cfSriastradh case 16: 11303b705cfSriastradh for (i = 0; i < numColors; i++) { 11403b705cfSriastradh index = indices[i]; 11503b705cfSriastradh 11603b705cfSriastradh if (index <= 31) { 11703b705cfSriastradh for (j = 0; j < 8; j++) { 11803b705cfSriastradh lut_r[index * 8 + j] = 11903b705cfSriastradh colors[index].red << 8; 12003b705cfSriastradh lut_b[index * 8 + j] = 12103b705cfSriastradh colors[index].blue << 8; 12203b705cfSriastradh } 12303b705cfSriastradh } 12403b705cfSriastradh 12503b705cfSriastradh for (j = 0; j < 4; j++) { 12603b705cfSriastradh lut_g[index * 4 + j] = 12703b705cfSriastradh colors[index].green << 8; 12803b705cfSriastradh } 12903b705cfSriastradh } 13003b705cfSriastradh break; 13103b705cfSriastradh default: 13203b705cfSriastradh for (i = 0; i < numColors; i++) { 13303b705cfSriastradh index = indices[i]; 13403b705cfSriastradh lut_r[index] = colors[index].red << 8; 13503b705cfSriastradh lut_g[index] = colors[index].green << 8; 13603b705cfSriastradh lut_b[index] = colors[index].blue << 8; 13703b705cfSriastradh } 13803b705cfSriastradh break; 13903b705cfSriastradh } 14003b705cfSriastradh 14103b705cfSriastradh /* Make the change through RandR */ 14203b705cfSriastradh#ifdef RANDR_12_INTERFACE 14303b705cfSriastradh RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 14403b705cfSriastradh#else 14503b705cfSriastradh crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); 14603b705cfSriastradh#endif 14703b705cfSriastradh } 14803b705cfSriastradh} 14903b705cfSriastradh 15003b705cfSriastradh/** 15103b705cfSriastradh * Adjust the screen pixmap for the current location of the front buffer. 15203b705cfSriastradh * This is done at EnterVT when buffers are bound as long as the resources 15303b705cfSriastradh * have already been created, but the first EnterVT happens before 15403b705cfSriastradh * CreateScreenResources. 15503b705cfSriastradh */ 15603b705cfSriastradhstatic Bool i830CreateScreenResources(ScreenPtr screen) 15703b705cfSriastradh{ 15803b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 15903b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 16003b705cfSriastradh 16103b705cfSriastradh screen->CreateScreenResources = intel->CreateScreenResources; 16203b705cfSriastradh if (!(*screen->CreateScreenResources) (screen)) 16303b705cfSriastradh return FALSE; 16403b705cfSriastradh 16503b705cfSriastradh if (!intel_uxa_create_screen_resources(screen)) 16603b705cfSriastradh return FALSE; 16703b705cfSriastradh 16803b705cfSriastradh intel_copy_fb(scrn); 16903b705cfSriastradh return TRUE; 17003b705cfSriastradh} 17103b705cfSriastradh 17213496ba1Ssnjvoid 17313496ba1Ssnjintel_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo) 17413496ba1Ssnj{ 17513496ba1Ssnj intel_uxa_set_pixmap_bo(pixmap, bo); 17613496ba1Ssnj} 17713496ba1Ssnj 17813496ba1Ssnjdri_bo * 17913496ba1Ssnjintel_get_pixmap_bo(PixmapPtr pixmap) 18013496ba1Ssnj{ 18113496ba1Ssnj return intel_uxa_get_pixmap_bo(pixmap); 18213496ba1Ssnj} 18313496ba1Ssnj 18413496ba1Ssnjvoid 18513496ba1Ssnjintel_flush(intel_screen_private *intel) 18613496ba1Ssnj{ 18713496ba1Ssnj intel_batch_submit(intel->scrn); 18813496ba1Ssnj} 18913496ba1Ssnj 19003b705cfSriastradhstatic void PreInitCleanup(ScrnInfoPtr scrn) 19103b705cfSriastradh{ 19203b705cfSriastradh if (!scrn || !scrn->driverPrivate) 19303b705cfSriastradh return; 19403b705cfSriastradh 19503b705cfSriastradh free(scrn->driverPrivate); 19603b705cfSriastradh scrn->driverPrivate = NULL; 19703b705cfSriastradh} 19803b705cfSriastradh 19903b705cfSriastradhstatic void intel_check_chipset_option(ScrnInfoPtr scrn) 20003b705cfSriastradh{ 20103b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 20213496ba1Ssnj intel_detect_chipset(scrn, intel->dev); 20303b705cfSriastradh} 20403b705cfSriastradh 20503b705cfSriastradhstatic Bool I830GetEarlyOptions(ScrnInfoPtr scrn) 20603b705cfSriastradh{ 20703b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 20803b705cfSriastradh 20903b705cfSriastradh /* Process the options */ 21003b705cfSriastradh intel->Options = intel_options_get(scrn); 21103b705cfSriastradh if (!intel->Options) 21203b705cfSriastradh return FALSE; 21303b705cfSriastradh 21413496ba1Ssnj#if USE_UXA 21503b705cfSriastradh intel->fallback_debug = xf86ReturnOptValBool(intel->Options, 21603b705cfSriastradh OPTION_FALLBACKDEBUG, 21703b705cfSriastradh FALSE); 21803b705cfSriastradh 21903b705cfSriastradh intel->debug_flush = 0; 22003b705cfSriastradh 22103b705cfSriastradh if (xf86ReturnOptValBool(intel->Options, 22203b705cfSriastradh OPTION_DEBUG_FLUSH_BATCHES, 22303b705cfSriastradh FALSE)) 22403b705cfSriastradh intel->debug_flush |= DEBUG_FLUSH_BATCHES; 22503b705cfSriastradh 22603b705cfSriastradh if (xf86ReturnOptValBool(intel->Options, 22703b705cfSriastradh OPTION_DEBUG_FLUSH_CACHES, 22803b705cfSriastradh FALSE)) 22903b705cfSriastradh intel->debug_flush |= DEBUG_FLUSH_CACHES; 23003b705cfSriastradh 23103b705cfSriastradh if (xf86ReturnOptValBool(intel->Options, 23203b705cfSriastradh OPTION_DEBUG_WAIT, 23303b705cfSriastradh FALSE)) 23403b705cfSriastradh intel->debug_flush |= DEBUG_FLUSH_WAIT; 23503b705cfSriastradh 23613496ba1Ssnj#endif 23703b705cfSriastradh return TRUE; 23803b705cfSriastradh} 23903b705cfSriastradh 24003b705cfSriastradhstatic Bool intel_option_cast_string_to_bool(intel_screen_private *intel, 24103b705cfSriastradh int id, Bool val) 24203b705cfSriastradh{ 24342542f5fSchristos#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0) 24403b705cfSriastradh xf86getBoolValue(&val, xf86GetOptValString(intel->Options, id)); 24503b705cfSriastradh return val; 24642542f5fSchristos#else 24742542f5fSchristos return val; 24842542f5fSchristos#endif 24903b705cfSriastradh} 25003b705cfSriastradh 25103b705cfSriastradhstatic void intel_check_dri_option(ScrnInfoPtr scrn) 25203b705cfSriastradh{ 25303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 25403b705cfSriastradh 25542542f5fSchristos intel->dri2 = intel->dri3 = DRI_NONE; 25603b705cfSriastradh if (!intel_option_cast_string_to_bool(intel, OPTION_DRI, TRUE)) 25742542f5fSchristos intel->dri2 = intel->dri3 = DRI_DISABLED; 25803b705cfSriastradh 25903b705cfSriastradh if (scrn->depth != 16 && scrn->depth != 24 && scrn->depth != 30) { 26003b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, 26103b705cfSriastradh "DRI is disabled because it " 26203b705cfSriastradh "runs only at depths 16, 24, and 30.\n"); 26342542f5fSchristos intel->dri2 = intel->dri3 = DRI_DISABLED; 26403b705cfSriastradh } 26503b705cfSriastradh} 26603b705cfSriastradh 26703b705cfSriastradhstatic Bool intel_open_drm_master(ScrnInfoPtr scrn) 26803b705cfSriastradh{ 26903b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 27013496ba1Ssnj intel->dev = intel_get_device(scrn, &intel->drmSubFD); 27113496ba1Ssnj return intel->dev != NULL; 27203b705cfSriastradh} 27303b705cfSriastradh 27403b705cfSriastradhstatic int intel_init_bufmgr(intel_screen_private *intel) 27503b705cfSriastradh{ 27603b705cfSriastradh int batch_size; 27703b705cfSriastradh 27803b705cfSriastradh batch_size = 4096 * 4; 27903b705cfSriastradh if (IS_I865G(intel)) 28003b705cfSriastradh /* The 865 has issues with larger-than-page-sized batch buffers. */ 28103b705cfSriastradh batch_size = 4096; 28203b705cfSriastradh 28303b705cfSriastradh intel->bufmgr = drm_intel_bufmgr_gem_init(intel->drmSubFD, batch_size); 28403b705cfSriastradh if (!intel->bufmgr) 28503b705cfSriastradh return FALSE; 28603b705cfSriastradh 28703b705cfSriastradh if (xf86ReturnOptValBool(intel->Options, OPTION_BUFFER_CACHE, TRUE)) 28803b705cfSriastradh drm_intel_bufmgr_gem_enable_reuse(intel->bufmgr); 28903b705cfSriastradh drm_intel_bufmgr_gem_set_vma_cache_size(intel->bufmgr, 512); 29003b705cfSriastradh drm_intel_bufmgr_gem_enable_fenced_relocs(intel->bufmgr); 29103b705cfSriastradh 29203b705cfSriastradh list_init(&intel->batch_pixmaps); 29303b705cfSriastradh 29403b705cfSriastradh if ((INTEL_INFO(intel)->gen == 060)) { 29503b705cfSriastradh intel->wa_scratch_bo = 29603b705cfSriastradh drm_intel_bo_alloc(intel->bufmgr, "wa scratch", 29703b705cfSriastradh 4096, 4096); 29803b705cfSriastradh } 29903b705cfSriastradh 30003b705cfSriastradh return TRUE; 30103b705cfSriastradh} 30203b705cfSriastradh 30303b705cfSriastradhstatic void intel_bufmgr_fini(intel_screen_private *intel) 30403b705cfSriastradh{ 30503b705cfSriastradh if (intel->bufmgr == NULL) 30603b705cfSriastradh return; 30703b705cfSriastradh 30803b705cfSriastradh drm_intel_bo_unreference(intel->wa_scratch_bo); 30903b705cfSriastradh drm_intel_bufmgr_destroy(intel->bufmgr); 31003b705cfSriastradh} 31103b705cfSriastradh 31203b705cfSriastradhstatic void I830XvInit(ScrnInfoPtr scrn) 31303b705cfSriastradh{ 31403b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 31503b705cfSriastradh MessageType from = X_PROBED; 31603b705cfSriastradh 31703b705cfSriastradh intel->XvPreferOverlay = 31803b705cfSriastradh xf86ReturnOptValBool(intel->Options, OPTION_PREFER_OVERLAY, FALSE); 31903b705cfSriastradh 32003b705cfSriastradh if (xf86GetOptValInteger(intel->Options, OPTION_VIDEO_KEY, 32103b705cfSriastradh &(intel->colorKey))) { 32203b705cfSriastradh from = X_CONFIG; 32303b705cfSriastradh } else if (xf86GetOptValInteger(intel->Options, OPTION_COLOR_KEY, 32403b705cfSriastradh &(intel->colorKey))) { 32503b705cfSriastradh from = X_CONFIG; 32603b705cfSriastradh } else { 32703b705cfSriastradh intel->colorKey = 32803b705cfSriastradh (1 << scrn->offset.red) | (1 << scrn->offset.green) | 32903b705cfSriastradh (((scrn->mask.blue >> scrn->offset.blue) - 1) << 33003b705cfSriastradh scrn->offset.blue); 33103b705cfSriastradh from = X_DEFAULT; 33203b705cfSriastradh } 33303b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, from, "video overlay key set to 0x%x\n", 33403b705cfSriastradh intel->colorKey); 33503b705cfSriastradh} 33603b705cfSriastradh 33703b705cfSriastradhstatic Bool drm_has_boolean_param(struct intel_screen_private *intel, 33803b705cfSriastradh int param) 33903b705cfSriastradh{ 34003b705cfSriastradh drm_i915_getparam_t gp; 34103b705cfSriastradh int value; 34203b705cfSriastradh 34303b705cfSriastradh gp.value = &value; 34403b705cfSriastradh gp.param = param; 34503b705cfSriastradh if (drmIoctl(intel->drmSubFD, DRM_IOCTL_I915_GETPARAM, &gp)) 34603b705cfSriastradh return FALSE; 34703b705cfSriastradh 34803b705cfSriastradh return value; 34903b705cfSriastradh} 35003b705cfSriastradh 35103b705cfSriastradhstatic Bool has_kernel_flush(struct intel_screen_private *intel) 35203b705cfSriastradh{ 35303b705cfSriastradh /* The BLT ring was introduced at the same time as the 35403b705cfSriastradh * automatic flush for the busy-ioctl. 35503b705cfSriastradh */ 35603b705cfSriastradh return drm_has_boolean_param(intel, I915_PARAM_HAS_BLT); 35703b705cfSriastradh} 35803b705cfSriastradh 35903b705cfSriastradhstatic Bool has_relaxed_fencing(struct intel_screen_private *intel) 36003b705cfSriastradh{ 36103b705cfSriastradh return drm_has_boolean_param(intel, I915_PARAM_HAS_RELAXED_FENCING); 36203b705cfSriastradh} 36303b705cfSriastradh 36403b705cfSriastradhstatic Bool has_prime_vmap_flush(struct intel_screen_private *intel) 36503b705cfSriastradh{ 36603b705cfSriastradh return drm_has_boolean_param(intel, I915_PARAM_HAS_PRIME_VMAP_FLUSH); 36703b705cfSriastradh} 36803b705cfSriastradh 36903b705cfSriastradhstatic Bool can_accelerate_blt(struct intel_screen_private *intel) 37003b705cfSriastradh{ 37103b705cfSriastradh if (INTEL_INFO(intel)->gen == -1) 37203b705cfSriastradh return FALSE; 37303b705cfSriastradh 37403b705cfSriastradh if (xf86ReturnOptValBool(intel->Options, OPTION_ACCEL_DISABLE, FALSE) || 37503b705cfSriastradh !intel_option_cast_string_to_bool(intel, OPTION_ACCEL_METHOD, TRUE)) { 37603b705cfSriastradh xf86DrvMsg(intel->scrn->scrnIndex, X_CONFIG, 37703b705cfSriastradh "Disabling hardware acceleration.\n"); 37803b705cfSriastradh return FALSE; 37903b705cfSriastradh } 38003b705cfSriastradh 38103b705cfSriastradh if (INTEL_INFO(intel)->gen == 060) { 38213496ba1Ssnj struct pci_device *const device = xf86GetPciInfoForEntity(intel->pEnt->index); 38303b705cfSriastradh 38403b705cfSriastradh /* Sandybridge rev07 locks up easily, even with the 38503b705cfSriastradh * BLT ring workaround in place. 38603b705cfSriastradh * Thus use shadowfb by default. 38703b705cfSriastradh */ 38803b705cfSriastradh if (device->revision < 8) { 38903b705cfSriastradh xf86DrvMsg(intel->scrn->scrnIndex, X_WARNING, 39003b705cfSriastradh "Disabling hardware acceleration on this pre-production hardware.\n"); 39103b705cfSriastradh 39203b705cfSriastradh return FALSE; 39303b705cfSriastradh } 39403b705cfSriastradh } 39503b705cfSriastradh 39603b705cfSriastradh if (INTEL_INFO(intel)->gen >= 060) { 39703b705cfSriastradh drm_i915_getparam_t gp; 39803b705cfSriastradh int value; 39903b705cfSriastradh 40003b705cfSriastradh /* On Sandybridge we need the BLT in order to do anything since 40103b705cfSriastradh * it so frequently used in the acceleration code paths. 40203b705cfSriastradh */ 40303b705cfSriastradh gp.value = &value; 40403b705cfSriastradh gp.param = I915_PARAM_HAS_BLT; 40503b705cfSriastradh if (drmIoctl(intel->drmSubFD, DRM_IOCTL_I915_GETPARAM, &gp)) 40603b705cfSriastradh return FALSE; 40703b705cfSriastradh } 40803b705cfSriastradh 40903b705cfSriastradh return TRUE; 41003b705cfSriastradh} 41103b705cfSriastradh 41203b705cfSriastradhstatic void intel_setup_capabilities(ScrnInfoPtr scrn) 41303b705cfSriastradh{ 41403b705cfSriastradh#ifdef INTEL_PIXMAP_SHARING 41503b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 41603b705cfSriastradh uint64_t value; 41703b705cfSriastradh int ret; 41803b705cfSriastradh 41903b705cfSriastradh scrn->capabilities = 0; 42003b705cfSriastradh 42103b705cfSriastradh ret = drmGetCap(intel->drmSubFD, DRM_CAP_PRIME, &value); 42203b705cfSriastradh if (ret == 0) { 42303b705cfSriastradh if (value & DRM_PRIME_CAP_EXPORT) 42403b705cfSriastradh scrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload; 42503b705cfSriastradh if (value & DRM_PRIME_CAP_IMPORT) 42603b705cfSriastradh scrn->capabilities |= RR_Capability_SinkOutput; 42703b705cfSriastradh } 42803b705cfSriastradh#endif 42903b705cfSriastradh} 43003b705cfSriastradh 43103b705cfSriastradh/** 43203b705cfSriastradh * This is called before ScreenInit to do any require probing of screen 43303b705cfSriastradh * configuration. 43403b705cfSriastradh * 43503b705cfSriastradh * This code generally covers probing, module loading, option handling 43603b705cfSriastradh * card mapping, and RandR setup. 43703b705cfSriastradh * 43803b705cfSriastradh * Since xf86InitialConfiguration ends up requiring that we set video modes 43903b705cfSriastradh * in order to detect configuration, we end up having to do a lot of driver 44003b705cfSriastradh * setup (talking to the DRM, mapping the device, etc.) in this function. 44103b705cfSriastradh * As a result, we want to set up that server initialization once rather 44203b705cfSriastradh * that doing it per generation. 44303b705cfSriastradh */ 44403b705cfSriastradhstatic Bool I830PreInit(ScrnInfoPtr scrn, int flags) 44503b705cfSriastradh{ 44603b705cfSriastradh intel_screen_private *intel; 44703b705cfSriastradh rgb defaultWeight = { 0, 0, 0 }; 44803b705cfSriastradh EntityInfoPtr pEnt; 44903b705cfSriastradh int flags24; 45003b705cfSriastradh Gamma zeros = { 0.0, 0.0, 0.0 }; 45103b705cfSriastradh 45203b705cfSriastradh if (scrn->numEntities != 1) 45303b705cfSriastradh return FALSE; 45403b705cfSriastradh 45503b705cfSriastradh pEnt = xf86GetEntityInfo(scrn->entityList[0]); 45603b705cfSriastradh if (pEnt == NULL) 45703b705cfSriastradh return FALSE; 45803b705cfSriastradh 45903b705cfSriastradh if (pEnt->location.type != BUS_PCI 46003b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS 46103b705cfSriastradh && pEnt->location.type != BUS_PLATFORM 46203b705cfSriastradh#endif 46303b705cfSriastradh ) 46403b705cfSriastradh return FALSE; 46503b705cfSriastradh 46603b705cfSriastradh if (flags & PROBE_DETECT) 46703b705cfSriastradh return TRUE; 46803b705cfSriastradh 46942542f5fSchristos if (((uintptr_t)scrn->driverPrivate) & 3) { 47003b705cfSriastradh intel = xnfcalloc(sizeof(*intel), 1); 47103b705cfSriastradh if (intel == NULL) 47203b705cfSriastradh return FALSE; 47303b705cfSriastradh 47442542f5fSchristos intel->info = (void *)((uintptr_t)scrn->driverPrivate & ~3); 47503b705cfSriastradh scrn->driverPrivate = intel; 47603b705cfSriastradh } 47703b705cfSriastradh intel = intel_get_screen_private(scrn); 47803b705cfSriastradh intel->scrn = scrn; 47903b705cfSriastradh intel->pEnt = pEnt; 48003b705cfSriastradh 48103b705cfSriastradh scrn->displayWidth = 640; /* default it */ 48203b705cfSriastradh 48303b705cfSriastradh if (!intel_open_drm_master(scrn)) { 48403b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 48503b705cfSriastradh "Failed to become DRM master.\n"); 48603b705cfSriastradh return FALSE; 48703b705cfSriastradh } 48803b705cfSriastradh 48903b705cfSriastradh scrn->monitor = scrn->confScreen->monitor; 49003b705cfSriastradh scrn->progClock = TRUE; 49103b705cfSriastradh scrn->rgbBits = 8; 49203b705cfSriastradh 49303b705cfSriastradh flags24 = Support32bppFb | PreferConvert24to32 | SupportConvert24to32; 49403b705cfSriastradh 49503b705cfSriastradh if (!xf86SetDepthBpp(scrn, 0, 0, 0, flags24)) 49603b705cfSriastradh return FALSE; 49703b705cfSriastradh 49803b705cfSriastradh switch (scrn->depth) { 49903b705cfSriastradh case 15: 50003b705cfSriastradh case 16: 50103b705cfSriastradh case 24: 50203b705cfSriastradh case 30: 50303b705cfSriastradh break; 50403b705cfSriastradh case 8: 50503b705cfSriastradh default: 50603b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 50703b705cfSriastradh "Given depth (%d) is not supported by intel driver\n", 50803b705cfSriastradh scrn->depth); 50903b705cfSriastradh return FALSE; 51003b705cfSriastradh } 51103b705cfSriastradh xf86PrintDepthBpp(scrn); 51203b705cfSriastradh 51303b705cfSriastradh if (!xf86SetWeight(scrn, defaultWeight, defaultWeight)) 51403b705cfSriastradh return FALSE; 51503b705cfSriastradh if (!xf86SetDefaultVisual(scrn, -1)) 51603b705cfSriastradh return FALSE; 51703b705cfSriastradh 51803b705cfSriastradh intel->cpp = scrn->bitsPerPixel / 8; 51903b705cfSriastradh 52003b705cfSriastradh if (!I830GetEarlyOptions(scrn)) 52103b705cfSriastradh return FALSE; 52203b705cfSriastradh 52303b705cfSriastradh intel_setup_capabilities(scrn); 52403b705cfSriastradh intel_check_chipset_option(scrn); 52503b705cfSriastradh intel_check_dri_option(scrn); 52603b705cfSriastradh 52703b705cfSriastradh if (!intel_init_bufmgr(intel)) { 52803b705cfSriastradh PreInitCleanup(scrn); 52903b705cfSriastradh return FALSE; 53003b705cfSriastradh } 53103b705cfSriastradh 53203b705cfSriastradh intel->force_fallback = 53303b705cfSriastradh drmCommandNone(intel->drmSubFD, DRM_I915_GEM_THROTTLE) != 0; 53403b705cfSriastradh 53503b705cfSriastradh /* Enable tiling by default */ 53603b705cfSriastradh intel->tiling = INTEL_TILING_ALL; 53703b705cfSriastradh 53803b705cfSriastradh /* Allow user override if they set a value */ 53903b705cfSriastradh if (!xf86ReturnOptValBool(intel->Options, OPTION_TILING_2D, TRUE)) 54003b705cfSriastradh intel->tiling &= ~INTEL_TILING_2D; 54103b705cfSriastradh if (xf86ReturnOptValBool(intel->Options, OPTION_TILING_FB, FALSE)) 54203b705cfSriastradh intel->tiling &= ~INTEL_TILING_FB; 54303b705cfSriastradh if (!can_accelerate_blt(intel)) { 54403b705cfSriastradh intel->force_fallback = TRUE; 54503b705cfSriastradh intel->tiling &= ~INTEL_TILING_FB; 54603b705cfSriastradh } 54703b705cfSriastradh 54803b705cfSriastradh intel->has_kernel_flush = has_kernel_flush(intel); 54903b705cfSriastradh 55003b705cfSriastradh intel->has_prime_vmap_flush = has_prime_vmap_flush(intel); 55103b705cfSriastradh 55203b705cfSriastradh intel->has_relaxed_fencing = INTEL_INFO(intel)->gen >= 033; 55303b705cfSriastradh /* And override the user if there is no kernel support */ 55403b705cfSriastradh if (intel->has_relaxed_fencing) 55503b705cfSriastradh intel->has_relaxed_fencing = has_relaxed_fencing(intel); 55603b705cfSriastradh 55703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, 55803b705cfSriastradh "Relaxed fencing %s\n", 55903b705cfSriastradh intel->has_relaxed_fencing ? "enabled" : "disabled"); 56003b705cfSriastradh 56103b705cfSriastradh /* SwapBuffers delays to avoid tearing */ 56203b705cfSriastradh intel->swapbuffers_wait = xf86ReturnOptValBool(intel->Options, 56303b705cfSriastradh OPTION_SWAPBUFFERS_WAIT, 56403b705cfSriastradh TRUE); 56503b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Wait on SwapBuffers? %s\n", 56603b705cfSriastradh intel->swapbuffers_wait ? "enabled" : "disabled"); 56703b705cfSriastradh 56803b705cfSriastradh intel->use_triple_buffer = 56903b705cfSriastradh xf86ReturnOptValBool(intel->Options, 57003b705cfSriastradh OPTION_TRIPLE_BUFFER, 57103b705cfSriastradh TRUE); 57203b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Triple buffering? %s\n", 57303b705cfSriastradh intel->use_triple_buffer ? "enabled" : "disabled"); 57403b705cfSriastradh 57503b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Framebuffer %s\n", 57603b705cfSriastradh intel->tiling & INTEL_TILING_FB ? "tiled" : "linear"); 57703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "Pixmaps %s\n", 57803b705cfSriastradh intel->tiling & INTEL_TILING_2D ? "tiled" : "linear"); 57903b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "3D buffers %s\n", 58003b705cfSriastradh intel->tiling & INTEL_TILING_3D ? "tiled" : "linear"); 58103b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_CONFIG, "SwapBuffers wait %sabled\n", 58203b705cfSriastradh intel->swapbuffers_wait ? "en" : "dis"); 58303b705cfSriastradh 58403b705cfSriastradh I830XvInit(scrn); 58503b705cfSriastradh 58603b705cfSriastradh if (!intel_mode_pre_init(scrn, intel->drmSubFD, intel->cpp)) { 58703b705cfSriastradh PreInitCleanup(scrn); 58803b705cfSriastradh return FALSE; 58903b705cfSriastradh } 59003b705cfSriastradh 59103b705cfSriastradh if (!xf86SetGamma(scrn, zeros)) { 59203b705cfSriastradh PreInitCleanup(scrn); 59303b705cfSriastradh return FALSE; 59403b705cfSriastradh } 59503b705cfSriastradh 59603b705cfSriastradh if (scrn->modes == NULL) { 59703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, "No modes.\n"); 59803b705cfSriastradh PreInitCleanup(scrn); 59903b705cfSriastradh return FALSE; 60003b705cfSriastradh } 60103b705cfSriastradh scrn->currentMode = scrn->modes; 60203b705cfSriastradh 60303b705cfSriastradh /* Set display resolution */ 60403b705cfSriastradh xf86SetDpi(scrn, 0, 0); 60503b705cfSriastradh 60603b705cfSriastradh /* Load the required sub modules */ 60703b705cfSriastradh if (!xf86LoadSubModule(scrn, "fb")) { 60803b705cfSriastradh PreInitCleanup(scrn); 60903b705cfSriastradh return FALSE; 61003b705cfSriastradh } 61103b705cfSriastradh 61242542f5fSchristos /* Load the dri modules if requested. */ 61342542f5fSchristos#if HAVE_DRI2 61442542f5fSchristos if (intel->dri2 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri2")) 61542542f5fSchristos intel->dri2 = DRI_DISABLED; 61642542f5fSchristos#endif 61742542f5fSchristos#if HAVE_DRI3 61842542f5fSchristos if (intel->dri3 != DRI_DISABLED && !xf86LoadSubModule(scrn, "dri3")) 61942542f5fSchristos intel->dri3 = DRI_DISABLED; 62042542f5fSchristos#endif 62103b705cfSriastradh 62203b705cfSriastradh return TRUE; 62303b705cfSriastradh} 62403b705cfSriastradh 62503b705cfSriastradh#ifdef INTEL_PIXMAP_SHARING 62603b705cfSriastradhstatic void 62703b705cfSriastradhredisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty) 62803b705cfSriastradh{ 62903b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 63003b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 63103b705cfSriastradh RegionRec pixregion; 63203b705cfSriastradh int was_blocked; 63303b705cfSriastradh 63403b705cfSriastradh PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap); 63503b705cfSriastradh RegionTranslate(&pixregion, dirty->x, dirty->y); 63603b705cfSriastradh RegionIntersect(&pixregion, &pixregion, DamageRegion(dirty->damage)); 63703b705cfSriastradh RegionTranslate(&pixregion, -dirty->x, -dirty->y); 63803b705cfSriastradh was_blocked = RegionNil(&pixregion); 63903b705cfSriastradh DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion); 64003b705cfSriastradh RegionUninit(&pixregion); 64103b705cfSriastradh if (was_blocked) 64203b705cfSriastradh return; 64303b705cfSriastradh 64403b705cfSriastradh PixmapRegionInit(&pixregion, dirty->slave_dst->master_pixmap); 64503b705cfSriastradh PixmapSyncDirtyHelper(dirty, &pixregion); 64603b705cfSriastradh RegionUninit(&pixregion); 64703b705cfSriastradh 64813496ba1Ssnj intel_flush(intel); 64903b705cfSriastradh if (!intel->has_prime_vmap_flush) { 65013496ba1Ssnj drm_intel_bo *bo = intel_uxa_get_pixmap_bo(dirty->slave_dst->master_pixmap); 65103b705cfSriastradh was_blocked = xf86BlockSIGIO(); 65203b705cfSriastradh drm_intel_bo_map(bo, FALSE); 65303b705cfSriastradh drm_intel_bo_unmap(bo); 65403b705cfSriastradh xf86UnblockSIGIO(was_blocked); 65503b705cfSriastradh } 65603b705cfSriastradh 65703b705cfSriastradh DamageRegionProcessPending(&dirty->slave_dst->drawable); 65803b705cfSriastradh return; 65903b705cfSriastradh} 66003b705cfSriastradh 66103b705cfSriastradhstatic void 66203b705cfSriastradhintel_dirty_update(ScreenPtr screen) 66303b705cfSriastradh{ 66403b705cfSriastradh RegionPtr region; 66503b705cfSriastradh PixmapDirtyUpdatePtr ent; 66603b705cfSriastradh 66703b705cfSriastradh if (xorg_list_is_empty(&screen->pixmap_dirty_list)) 66803b705cfSriastradh return; 66903b705cfSriastradh 67003b705cfSriastradh xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) { 67103b705cfSriastradh region = DamageRegion(ent->damage); 67203b705cfSriastradh if (RegionNotEmpty(region)) { 67303b705cfSriastradh redisplay_dirty(screen, ent); 67403b705cfSriastradh DamageEmpty(ent->damage); 67503b705cfSriastradh } 67603b705cfSriastradh } 67703b705cfSriastradh} 67803b705cfSriastradh#endif 67903b705cfSriastradh 68003b705cfSriastradhstatic void 68103b705cfSriastradhI830BlockHandler(BLOCKHANDLER_ARGS_DECL) 68203b705cfSriastradh{ 68303b705cfSriastradh SCREEN_PTR(arg); 68403b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 68503b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 68603b705cfSriastradh 68703b705cfSriastradh screen->BlockHandler = intel->BlockHandler; 68803b705cfSriastradh 68903b705cfSriastradh (*screen->BlockHandler) (BLOCKHANDLER_ARGS); 69003b705cfSriastradh 69103b705cfSriastradh intel->BlockHandler = screen->BlockHandler; 69203b705cfSriastradh screen->BlockHandler = I830BlockHandler; 69303b705cfSriastradh 69403b705cfSriastradh intel_uxa_block_handler(intel); 69503b705cfSriastradh intel_video_block_handler(intel); 69603b705cfSriastradh#ifdef INTEL_PIXMAP_SHARING 69703b705cfSriastradh intel_dirty_update(screen); 69803b705cfSriastradh#endif 69903b705cfSriastradh} 70003b705cfSriastradh 70103b705cfSriastradhstatic Bool 70203b705cfSriastradhintel_init_initial_framebuffer(ScrnInfoPtr scrn) 70303b705cfSriastradh{ 70403b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 70503b705cfSriastradh int width = scrn->virtualX; 70603b705cfSriastradh int height = scrn->virtualY; 70742542f5fSchristos int pitch; 70803b705cfSriastradh uint32_t tiling; 70903b705cfSriastradh 71003b705cfSriastradh intel->front_buffer = intel_allocate_framebuffer(scrn, 71103b705cfSriastradh width, height, 71203b705cfSriastradh intel->cpp, 71342542f5fSchristos &pitch, &tiling); 71403b705cfSriastradh 71503b705cfSriastradh if (!intel->front_buffer) { 71603b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 71703b705cfSriastradh "Couldn't allocate initial framebuffer.\n"); 71803b705cfSriastradh return FALSE; 71903b705cfSriastradh } 72003b705cfSriastradh 72103b705cfSriastradh intel->front_pitch = pitch; 72203b705cfSriastradh intel->front_tiling = tiling; 72303b705cfSriastradh scrn->displayWidth = pitch / intel->cpp; 72403b705cfSriastradh 72503b705cfSriastradh return TRUE; 72603b705cfSriastradh} 72703b705cfSriastradh 72803b705cfSriastradhstatic void 72903b705cfSriastradhintel_flush_callback(CallbackListPtr *list, 73003b705cfSriastradh pointer user_data, pointer call_data) 73103b705cfSriastradh{ 73203b705cfSriastradh ScrnInfoPtr scrn = user_data; 73313496ba1Ssnj if (scrn->vtSema) 73413496ba1Ssnj intel_flush(intel_get_screen_private(scrn)); 73503b705cfSriastradh} 73603b705cfSriastradh 73703b705cfSriastradh#if HAVE_UDEV 73803b705cfSriastradhstatic void 73903b705cfSriastradhI830HandleUEvents(int fd, void *closure) 74003b705cfSriastradh{ 74103b705cfSriastradh ScrnInfoPtr scrn = closure; 74203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 74303b705cfSriastradh struct udev_device *dev; 74403b705cfSriastradh const char *hotplug; 74503b705cfSriastradh struct stat s; 74603b705cfSriastradh dev_t udev_devnum; 74703b705cfSriastradh 74803b705cfSriastradh dev = udev_monitor_receive_device(intel->uevent_monitor); 74903b705cfSriastradh if (!dev) 75003b705cfSriastradh return; 75103b705cfSriastradh 75203b705cfSriastradh udev_devnum = udev_device_get_devnum(dev); 75303b705cfSriastradh if (fstat(intel->drmSubFD, &s)) { 75403b705cfSriastradh udev_device_unref(dev); 75503b705cfSriastradh return; 75603b705cfSriastradh } 75703b705cfSriastradh /* 75803b705cfSriastradh * Check to make sure this event is directed at our 75903b705cfSriastradh * device (by comparing dev_t values), then make 76003b705cfSriastradh * sure it's a hotplug event (HOTPLUG=1) 76103b705cfSriastradh */ 76203b705cfSriastradh 76303b705cfSriastradh hotplug = udev_device_get_property_value(dev, "HOTPLUG"); 76403b705cfSriastradh 76503b705cfSriastradh if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 && 76603b705cfSriastradh hotplug && atoi(hotplug) == 1) 76742542f5fSchristos { 76842542f5fSchristos intel_mode_hotplug(intel); 76942542f5fSchristos } 77003b705cfSriastradh 77103b705cfSriastradh udev_device_unref(dev); 77203b705cfSriastradh} 77303b705cfSriastradh 77403b705cfSriastradhstatic void 77503b705cfSriastradhI830UeventInit(ScrnInfoPtr scrn) 77603b705cfSriastradh{ 77703b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 77803b705cfSriastradh struct udev *u; 77903b705cfSriastradh struct udev_monitor *mon; 78003b705cfSriastradh Bool hotplug; 78103b705cfSriastradh MessageType from = X_CONFIG; 78203b705cfSriastradh 78303b705cfSriastradh if (!xf86GetOptValBool(intel->Options, OPTION_HOTPLUG, &hotplug)) { 78403b705cfSriastradh from = X_DEFAULT; 78503b705cfSriastradh hotplug = TRUE; 78603b705cfSriastradh } 78703b705cfSriastradh 78803b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, from, "hotplug detection: \"%s\"\n", 78903b705cfSriastradh hotplug ? "enabled" : "disabled"); 79003b705cfSriastradh if (!hotplug) 79103b705cfSriastradh return; 79203b705cfSriastradh 79303b705cfSriastradh u = udev_new(); 79403b705cfSriastradh if (!u) 79503b705cfSriastradh return; 79603b705cfSriastradh 79703b705cfSriastradh mon = udev_monitor_new_from_netlink(u, "udev"); 79803b705cfSriastradh 79903b705cfSriastradh if (!mon) { 80003b705cfSriastradh udev_unref(u); 80103b705cfSriastradh return; 80203b705cfSriastradh } 80303b705cfSriastradh 80403b705cfSriastradh if (udev_monitor_filter_add_match_subsystem_devtype(mon, 80503b705cfSriastradh "drm", 80603b705cfSriastradh "drm_minor") < 0 || 80703b705cfSriastradh udev_monitor_enable_receiving(mon) < 0) 80803b705cfSriastradh { 80903b705cfSriastradh udev_monitor_unref(mon); 81003b705cfSriastradh udev_unref(u); 81103b705cfSriastradh return; 81203b705cfSriastradh } 81303b705cfSriastradh 81442542f5fSchristos intel->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), 81542542f5fSchristos I830HandleUEvents, scrn); 81603b705cfSriastradh if (!intel->uevent_handler) { 81703b705cfSriastradh udev_monitor_unref(mon); 81803b705cfSriastradh udev_unref(u); 81903b705cfSriastradh return; 82003b705cfSriastradh } 82103b705cfSriastradh 82203b705cfSriastradh intel->uevent_monitor = mon; 82303b705cfSriastradh} 82403b705cfSriastradh 82503b705cfSriastradhstatic void 82603b705cfSriastradhI830UeventFini(ScrnInfoPtr scrn) 82703b705cfSriastradh{ 82803b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 82903b705cfSriastradh 83003b705cfSriastradh if (intel->uevent_handler) { 83103b705cfSriastradh struct udev *u = udev_monitor_get_udev(intel->uevent_monitor); 83203b705cfSriastradh 83303b705cfSriastradh xf86RemoveGeneralHandler(intel->uevent_handler); 83403b705cfSriastradh 83503b705cfSriastradh udev_monitor_unref(intel->uevent_monitor); 83603b705cfSriastradh udev_unref(u); 83703b705cfSriastradh intel->uevent_handler = NULL; 83803b705cfSriastradh intel->uevent_monitor = NULL; 83903b705cfSriastradh } 84003b705cfSriastradh} 84103b705cfSriastradh#endif /* HAVE_UDEV */ 84203b705cfSriastradh 84303b705cfSriastradhstatic Bool 84403b705cfSriastradhI830ScreenInit(SCREEN_INIT_ARGS_DECL) 84503b705cfSriastradh{ 84603b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 84703b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 84803b705cfSriastradh VisualPtr visual; 84903b705cfSriastradh#ifdef INTEL_XVMC 85003b705cfSriastradh MessageType from; 85103b705cfSriastradh#endif 85213496ba1Ssnj struct pci_device *const device = xf86GetPciInfoForEntity(intel->pEnt->index); 85303b705cfSriastradh int fb_bar = IS_GEN2(intel) ? 0 : 2; 85403b705cfSriastradh 85503b705cfSriastradh scrn->videoRam = device->regions[fb_bar].size / 1024; 85603b705cfSriastradh 85703b705cfSriastradh intel->last_3d = LAST_3D_OTHER; 85803b705cfSriastradh intel->overlayOn = FALSE; 85903b705cfSriastradh 86003b705cfSriastradh /* 86103b705cfSriastradh * Set this so that the overlay allocation is factored in when 86203b705cfSriastradh * appropriate. 86303b705cfSriastradh */ 86403b705cfSriastradh intel->XvEnabled = TRUE; 86503b705cfSriastradh 86603b705cfSriastradh if (!intel_init_initial_framebuffer(scrn)) 86703b705cfSriastradh return FALSE; 86803b705cfSriastradh 86903b705cfSriastradh miClearVisualTypes(); 87003b705cfSriastradh if (!miSetVisualTypes(scrn->depth, 87103b705cfSriastradh miGetDefaultVisualMask(scrn->depth), 87203b705cfSriastradh scrn->rgbBits, scrn->defaultVisual)) 87303b705cfSriastradh return FALSE; 87403b705cfSriastradh if (!miSetPixmapDepths()) 87503b705cfSriastradh return FALSE; 87603b705cfSriastradh 87742542f5fSchristos /* Must be first, before anything else installs screen callbacks. */ 87803b705cfSriastradh if (!fbScreenInit(screen, NULL, 87903b705cfSriastradh scrn->virtualX, scrn->virtualY, 88003b705cfSriastradh scrn->xDpi, scrn->yDpi, 88103b705cfSriastradh scrn->displayWidth, scrn->bitsPerPixel)) 88203b705cfSriastradh return FALSE; 88303b705cfSriastradh 88403b705cfSriastradh if (scrn->bitsPerPixel > 8) { 88503b705cfSriastradh /* Fixup RGB ordering */ 88603b705cfSriastradh visual = screen->visuals + screen->numVisuals; 88703b705cfSriastradh while (--visual >= screen->visuals) { 88803b705cfSriastradh if ((visual->class | DynamicClass) == DirectColor) { 88903b705cfSriastradh visual->offsetRed = scrn->offset.red; 89003b705cfSriastradh visual->offsetGreen = scrn->offset.green; 89103b705cfSriastradh visual->offsetBlue = scrn->offset.blue; 89203b705cfSriastradh visual->redMask = scrn->mask.red; 89303b705cfSriastradh visual->greenMask = scrn->mask.green; 89403b705cfSriastradh visual->blueMask = scrn->mask.blue; 89503b705cfSriastradh } 89603b705cfSriastradh } 89703b705cfSriastradh } 89803b705cfSriastradh 89903b705cfSriastradh fbPictureInit(screen, NULL, 0); 90003b705cfSriastradh 90103b705cfSriastradh xf86SetBlackWhitePixels(screen); 90203b705cfSriastradh 90303b705cfSriastradh if (!intel_uxa_init(screen)) { 90403b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 90503b705cfSriastradh "Hardware acceleration initialization failed\n"); 90603b705cfSriastradh return FALSE; 90703b705cfSriastradh } 90803b705cfSriastradh 90942542f5fSchristos#if HAVE_DRI2 91042542f5fSchristos if (intel->dri2 == DRI_NONE && I830DRI2ScreenInit(screen)) 91142542f5fSchristos intel->dri2 = DRI_ACTIVE; 91242542f5fSchristos#endif 91342542f5fSchristos 91442542f5fSchristos#if HAVE_DRI3 91542542f5fSchristos if (!intel_sync_init(screen)) 91642542f5fSchristos intel->dri3 = DRI_DISABLED; 91742542f5fSchristos if (intel->dri3 == DRI_NONE && intel_dri3_screen_init(screen)) 91842542f5fSchristos intel->dri3 = DRI_ACTIVE; 91942542f5fSchristos#endif 92042542f5fSchristos 92142542f5fSchristos if (xf86ReturnOptValBool(intel->Options, OPTION_PRESENT, TRUE)) 92242542f5fSchristos intel_present_screen_init(screen); 92342542f5fSchristos 92403b705cfSriastradh xf86SetBackingStore(screen); 92503b705cfSriastradh xf86SetSilkenMouse(screen); 92603b705cfSriastradh miDCInitialize(screen, xf86GetPointerScreenFuncs()); 92703b705cfSriastradh 92803b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, "Initializing HW Cursor\n"); 92903b705cfSriastradh if (!xf86_cursors_init(screen, 64, 64, 93003b705cfSriastradh (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 93103b705cfSriastradh HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 93203b705cfSriastradh HARDWARE_CURSOR_INVERT_MASK | 93303b705cfSriastradh HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 93403b705cfSriastradh HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 93503b705cfSriastradh HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 93603b705cfSriastradh HARDWARE_CURSOR_UPDATE_UNHIDDEN | 93703b705cfSriastradh HARDWARE_CURSOR_ARGB))) { 93803b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_ERROR, 93903b705cfSriastradh "Hardware cursor initialization failed\n"); 94003b705cfSriastradh } 94103b705cfSriastradh 94203b705cfSriastradh intel->BlockHandler = screen->BlockHandler; 94303b705cfSriastradh screen->BlockHandler = I830BlockHandler; 94403b705cfSriastradh 94503b705cfSriastradh#ifdef INTEL_PIXMAP_SHARING 94603b705cfSriastradh screen->StartPixmapTracking = PixmapStartDirtyTracking; 94703b705cfSriastradh screen->StopPixmapTracking = PixmapStopDirtyTracking; 94803b705cfSriastradh#endif 94903b705cfSriastradh 95003b705cfSriastradh if (!AddCallback(&FlushCallback, intel_flush_callback, scrn)) 95103b705cfSriastradh return FALSE; 95203b705cfSriastradh 95303b705cfSriastradh screen->SaveScreen = xf86SaveScreen; 95403b705cfSriastradh intel->CloseScreen = screen->CloseScreen; 95503b705cfSriastradh screen->CloseScreen = I830CloseScreen; 95603b705cfSriastradh intel->CreateScreenResources = screen->CreateScreenResources; 95703b705cfSriastradh screen->CreateScreenResources = i830CreateScreenResources; 95803b705cfSriastradh 95903b705cfSriastradh if (!xf86CrtcScreenInit(screen)) 96003b705cfSriastradh return FALSE; 96103b705cfSriastradh 96203b705cfSriastradh if (!miCreateDefColormap(screen)) 96303b705cfSriastradh return FALSE; 96403b705cfSriastradh 96503b705cfSriastradh if (!xf86HandleColormaps(screen, 256, 8, I830LoadPalette, NULL, 96603b705cfSriastradh CMAP_RELOAD_ON_MODE_SWITCH | 96703b705cfSriastradh CMAP_PALETTED_TRUECOLOR)) { 96803b705cfSriastradh return FALSE; 96903b705cfSriastradh } 97003b705cfSriastradh 97103b705cfSriastradh xf86DPMSInit(screen, xf86DPMSSet, 0); 97203b705cfSriastradh 97303b705cfSriastradh#ifdef INTEL_XVMC 97403b705cfSriastradh if (INTEL_INFO(intel)->gen >= 040) 97503b705cfSriastradh intel->XvMCEnabled = TRUE; 97642542f5fSchristos from = (intel->dri2 == DRI_ACTIVE && 97703b705cfSriastradh xf86GetOptValBool(intel->Options, OPTION_XVMC, 97803b705cfSriastradh &intel->XvMCEnabled) ? X_CONFIG : X_DEFAULT); 97903b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, from, "Intel XvMC decoder %sabled\n", 98003b705cfSriastradh intel->XvMCEnabled ? "en" : "dis"); 98103b705cfSriastradh#endif 98203b705cfSriastradh /* Init video */ 98303b705cfSriastradh if (intel->XvEnabled) 98413496ba1Ssnj intel_video_init(screen); 98503b705cfSriastradh 98642542f5fSchristos#if HAVE_DRI2 98742542f5fSchristos switch (intel->dri2) { 98842542f5fSchristos case DRI_ACTIVE: 98942542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_INFO, 99042542f5fSchristos "DRI2: Enabled\n"); 99142542f5fSchristos break; 99242542f5fSchristos case DRI_DISABLED: 99342542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_INFO, 99442542f5fSchristos "DRI2: Disabled\n"); 99542542f5fSchristos break; 99642542f5fSchristos case DRI_NONE: 99742542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_INFO, 99842542f5fSchristos "DRI2: Failed\n"); 99942542f5fSchristos break; 100042542f5fSchristos } 100142542f5fSchristos#else 100242542f5fSchristos xf86DrvMsg(scrn->scrnIndex, X_INFO, 100342542f5fSchristos "DRI2: Not available\n"); 100442542f5fSchristos#endif 100542542f5fSchristos 100642542f5fSchristos#if HAVE_DRI3 100742542f5fSchristos switch (intel->dri3) { 100842542f5fSchristos case DRI_ACTIVE: 100903b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 101042542f5fSchristos "DRI3: Enabled\n"); 101103b705cfSriastradh break; 101203b705cfSriastradh case DRI_DISABLED: 101303b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 101442542f5fSchristos "DRI3: Disabled\n"); 101503b705cfSriastradh break; 101603b705cfSriastradh case DRI_NONE: 101703b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 101842542f5fSchristos "DRI3: Failed\n"); 101903b705cfSriastradh break; 102003b705cfSriastradh } 102103b705cfSriastradh#else 102203b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_INFO, 102342542f5fSchristos "DRI3: Not available\n"); 102403b705cfSriastradh#endif 102503b705cfSriastradh 102603b705cfSriastradh if (serverGeneration == 1) 102703b705cfSriastradh xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options); 102803b705cfSriastradh 102903b705cfSriastradh intel_mode_init(intel); 103003b705cfSriastradh 103103b705cfSriastradh intel->suspended = FALSE; 103203b705cfSriastradh 103303b705cfSriastradh#if HAVE_UDEV 103403b705cfSriastradh I830UeventInit(scrn); 103503b705cfSriastradh#endif 103603b705cfSriastradh 103703b705cfSriastradh /* Must force it before EnterVT, so we are in control of VT and 103803b705cfSriastradh * later memory should be bound when allocating, e.g rotate_mem */ 103903b705cfSriastradh scrn->vtSema = TRUE; 104003b705cfSriastradh 104103b705cfSriastradh return I830EnterVT(VT_FUNC_ARGS(0)); 104203b705cfSriastradh} 104303b705cfSriastradh 104403b705cfSriastradhstatic void i830AdjustFrame(ADJUST_FRAME_ARGS_DECL) 104503b705cfSriastradh{ 104603b705cfSriastradh} 104703b705cfSriastradh 104803b705cfSriastradhstatic void I830FreeScreen(FREE_SCREEN_ARGS_DECL) 104903b705cfSriastradh{ 105003b705cfSriastradh SCRN_INFO_PTR(arg); 105103b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 105203b705cfSriastradh 105342542f5fSchristos if (intel && !((uintptr_t)intel & 3)) { 105403b705cfSriastradh intel_mode_fini(intel); 105503b705cfSriastradh intel_bufmgr_fini(intel); 105613496ba1Ssnj intel_put_device(intel->dev); 105703b705cfSriastradh 105803b705cfSriastradh free(intel); 105903b705cfSriastradh scrn->driverPrivate = NULL; 106003b705cfSriastradh } 106103b705cfSriastradh} 106203b705cfSriastradh 106303b705cfSriastradhstatic void I830LeaveVT(VT_FUNC_ARGS_DECL) 106403b705cfSriastradh{ 106503b705cfSriastradh SCRN_INFO_PTR(arg); 106613496ba1Ssnj intel_screen_private *intel = intel_get_screen_private(scrn); 106703b705cfSriastradh 106803b705cfSriastradh xf86RotateFreeShadow(scrn); 106903b705cfSriastradh 107003b705cfSriastradh xf86_hide_cursors(scrn); 107103b705cfSriastradh 107213496ba1Ssnj if (intel_put_master(intel->dev)) 107303b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_WARNING, 107403b705cfSriastradh "drmDropMaster failed: %s\n", strerror(errno)); 107503b705cfSriastradh} 107603b705cfSriastradh 107703b705cfSriastradh/* 107803b705cfSriastradh * This gets called when gaining control of the VT, and from ScreenInit(). 107903b705cfSriastradh */ 108003b705cfSriastradhstatic Bool I830EnterVT(VT_FUNC_ARGS_DECL) 108103b705cfSriastradh{ 108203b705cfSriastradh SCRN_INFO_PTR(arg); 108313496ba1Ssnj intel_screen_private *intel = intel_get_screen_private(scrn); 108403b705cfSriastradh 108513496ba1Ssnj if (intel_get_master(intel->dev)) { 108603b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_WARNING, 108703b705cfSriastradh "drmSetMaster failed: %s\n", 108803b705cfSriastradh strerror(errno)); 108942542f5fSchristos return FALSE; 109003b705cfSriastradh } 109103b705cfSriastradh 109203b705cfSriastradh if (!xf86SetDesiredModes(scrn)) 109303b705cfSriastradh return FALSE; 109403b705cfSriastradh 109503b705cfSriastradh intel_mode_disable_unused_functions(scrn); 109603b705cfSriastradh return TRUE; 109703b705cfSriastradh} 109803b705cfSriastradh 109903b705cfSriastradhstatic Bool I830SwitchMode(SWITCH_MODE_ARGS_DECL) 110003b705cfSriastradh{ 110103b705cfSriastradh SCRN_INFO_PTR(arg); 110203b705cfSriastradh 110303b705cfSriastradh return xf86SetSingleMode(scrn, mode, RR_Rotate_0); 110403b705cfSriastradh} 110503b705cfSriastradh 110603b705cfSriastradhstatic Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL) 110703b705cfSriastradh{ 110803b705cfSriastradh ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 110903b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 111003b705cfSriastradh 111103b705cfSriastradh#if HAVE_UDEV 111203b705cfSriastradh I830UeventFini(scrn); 111303b705cfSriastradh#endif 111403b705cfSriastradh 111503b705cfSriastradh intel_mode_close(intel); 111603b705cfSriastradh 111703b705cfSriastradh DeleteCallback(&FlushCallback, intel_flush_callback, scrn); 111803b705cfSriastradh 111903b705cfSriastradh TimerFree(intel->cache_expire); 112003b705cfSriastradh intel->cache_expire = NULL; 112103b705cfSriastradh 112203b705cfSriastradh if (intel->uxa_driver) { 112303b705cfSriastradh uxa_driver_fini(screen); 112403b705cfSriastradh free(intel->uxa_driver); 112503b705cfSriastradh intel->uxa_driver = NULL; 112603b705cfSriastradh } 112703b705cfSriastradh 112803b705cfSriastradh if (intel->back_buffer) { 112903b705cfSriastradh drm_intel_bo_unreference(intel->back_buffer); 113003b705cfSriastradh intel->back_buffer = NULL; 113103b705cfSriastradh } 113203b705cfSriastradh 113303b705cfSriastradh if (intel->front_buffer) { 113403b705cfSriastradh intel_mode_remove_fb(intel); 113503b705cfSriastradh drm_intel_bo_unreference(intel->front_buffer); 113603b705cfSriastradh intel->front_buffer = NULL; 113703b705cfSriastradh } 113803b705cfSriastradh 113903b705cfSriastradh if (scrn->vtSema == TRUE) { 114003b705cfSriastradh I830LeaveVT(VT_FUNC_ARGS(0)); 114103b705cfSriastradh } 114203b705cfSriastradh 114303b705cfSriastradh intel_batch_teardown(scrn); 114403b705cfSriastradh 114542542f5fSchristos if (INTEL_INFO(intel)->gen >= 040 && INTEL_INFO(intel)->gen < 0100) 114603b705cfSriastradh gen4_render_state_cleanup(scrn); 114703b705cfSriastradh 114803b705cfSriastradh xf86_cursors_fini(screen); 114903b705cfSriastradh 115003b705cfSriastradh i965_free_video(scrn); 115103b705cfSriastradh 115203b705cfSriastradh screen->CloseScreen = intel->CloseScreen; 115303b705cfSriastradh (*screen->CloseScreen) (CLOSE_SCREEN_ARGS); 115403b705cfSriastradh 115542542f5fSchristos if (intel->dri2 == DRI_ACTIVE) { 115603b705cfSriastradh I830DRI2CloseScreen(screen); 115742542f5fSchristos intel->dri2 = DRI_NONE; 115803b705cfSriastradh } 115903b705cfSriastradh 116042542f5fSchristos if (intel->dri3 == DRI_ACTIVE) { 116142542f5fSchristos /* nothing to do here? */ 116242542f5fSchristos intel->dri3 = DRI_NONE; 116342542f5fSchristos } 116442542f5fSchristos 116542542f5fSchristos intel_sync_close(screen); 116642542f5fSchristos 116703b705cfSriastradh xf86GARTCloseScreen(scrn->scrnIndex); 116803b705cfSriastradh 116903b705cfSriastradh scrn->vtSema = FALSE; 117003b705cfSriastradh return TRUE; 117103b705cfSriastradh} 117203b705cfSriastradh 117303b705cfSriastradhstatic ModeStatus 117403b705cfSriastradhI830ValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) 117503b705cfSriastradh{ 117603b705cfSriastradh SCRN_INFO_PTR(arg); 117703b705cfSriastradh if (mode->Flags & V_INTERLACE) { 117803b705cfSriastradh if (verbose) { 117903b705cfSriastradh xf86DrvMsg(scrn->scrnIndex, X_PROBED, 118003b705cfSriastradh "Removing interlaced mode \"%s\"\n", 118103b705cfSriastradh mode->name); 118203b705cfSriastradh } 118303b705cfSriastradh return MODE_BAD; 118403b705cfSriastradh } 118503b705cfSriastradh return MODE_OK; 118603b705cfSriastradh} 118703b705cfSriastradh 118803b705cfSriastradh#ifndef SUSPEND_SLEEP 118903b705cfSriastradh#define SUSPEND_SLEEP 0 119003b705cfSriastradh#endif 119103b705cfSriastradh#ifndef RESUME_SLEEP 119203b705cfSriastradh#define RESUME_SLEEP 0 119303b705cfSriastradh#endif 119403b705cfSriastradh 119503b705cfSriastradh/* 119603b705cfSriastradh * This function is only required if we need to do anything differently from 119703b705cfSriastradh * DoApmEvent() in common/xf86PM.c, including if we want to see events other 119803b705cfSriastradh * than suspend/resume. 119903b705cfSriastradh */ 120003b705cfSriastradhstatic Bool I830PMEvent(SCRN_ARG_TYPE arg, pmEvent event, Bool undo) 120103b705cfSriastradh{ 120203b705cfSriastradh SCRN_INFO_PTR(arg); 120303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 120403b705cfSriastradh 120503b705cfSriastradh switch (event) { 120603b705cfSriastradh case XF86_APM_SYS_SUSPEND: 120703b705cfSriastradh case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend? */ 120803b705cfSriastradh case XF86_APM_USER_SUSPEND: 120903b705cfSriastradh case XF86_APM_SYS_STANDBY: 121003b705cfSriastradh case XF86_APM_USER_STANDBY: 121103b705cfSriastradh if (!undo && !intel->suspended) { 121203b705cfSriastradh scrn->LeaveVT(VT_FUNC_ARGS(0)); 121303b705cfSriastradh intel->suspended = TRUE; 121403b705cfSriastradh sleep(SUSPEND_SLEEP); 121503b705cfSriastradh } else if (undo && intel->suspended) { 121603b705cfSriastradh sleep(RESUME_SLEEP); 121703b705cfSriastradh scrn->EnterVT(VT_FUNC_ARGS(0)); 121803b705cfSriastradh intel->suspended = FALSE; 121903b705cfSriastradh } 122003b705cfSriastradh break; 122103b705cfSriastradh case XF86_APM_STANDBY_RESUME: 122203b705cfSriastradh case XF86_APM_NORMAL_RESUME: 122303b705cfSriastradh case XF86_APM_CRITICAL_RESUME: 122403b705cfSriastradh if (intel->suspended) { 122503b705cfSriastradh sleep(RESUME_SLEEP); 122603b705cfSriastradh scrn->EnterVT(VT_FUNC_ARGS(0)); 122703b705cfSriastradh intel->suspended = FALSE; 122803b705cfSriastradh /* 122903b705cfSriastradh * Turn the screen saver off when resuming. This seems to be 123003b705cfSriastradh * needed to stop xscreensaver kicking in (when used). 123103b705cfSriastradh * 123203b705cfSriastradh * XXX DoApmEvent() should probably call this just like 123303b705cfSriastradh * xf86VTSwitch() does. Maybe do it here only in 4.2 123403b705cfSriastradh * compatibility mode. 123503b705cfSriastradh */ 123603b705cfSriastradh SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 123703b705cfSriastradh } 123803b705cfSriastradh break; 123903b705cfSriastradh /* This is currently used for ACPI */ 124003b705cfSriastradh case XF86_APM_CAPABILITY_CHANGED: 124103b705cfSriastradh ErrorF("I830PMEvent: Capability change\n"); 124203b705cfSriastradh 124303b705cfSriastradh SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); 124403b705cfSriastradh 124503b705cfSriastradh break; 124603b705cfSriastradh default: 124703b705cfSriastradh ErrorF("I830PMEvent: received APM event %d\n", event); 124803b705cfSriastradh } 124903b705cfSriastradh return TRUE; 125003b705cfSriastradh} 125103b705cfSriastradh 125203b705cfSriastradhBool intel_init_scrn(ScrnInfoPtr scrn) 125303b705cfSriastradh{ 125403b705cfSriastradh scrn->PreInit = I830PreInit; 125503b705cfSriastradh scrn->ScreenInit = I830ScreenInit; 125603b705cfSriastradh scrn->SwitchMode = I830SwitchMode; 125703b705cfSriastradh scrn->AdjustFrame = i830AdjustFrame; 125803b705cfSriastradh scrn->EnterVT = I830EnterVT; 125903b705cfSriastradh scrn->LeaveVT = I830LeaveVT; 126003b705cfSriastradh scrn->FreeScreen = I830FreeScreen; 126103b705cfSriastradh scrn->ValidMode = I830ValidMode; 126203b705cfSriastradh scrn->PMEvent = I830PMEvent; 126303b705cfSriastradh return TRUE; 126403b705cfSriastradh} 1265