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