intel_module.c revision 42542f5f
103b705cfSriastradh/*
203b705cfSriastradh * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
303b705cfSriastradh * All Rights Reserved.
403b705cfSriastradh * Copyright © 2010 Intel Corporation
503b705cfSriastradh *
603b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a
703b705cfSriastradh * copy of this software and associated documentation files (the "Software"),
803b705cfSriastradh * to deal in the Software without restriction, including without limitation
903b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1003b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the
1103b705cfSriastradh * Software is furnished to do so, subject to the following conditions:
1203b705cfSriastradh *
1303b705cfSriastradh * The above copyright notice and this permission notice (including the next
1403b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the
1503b705cfSriastradh * Software.
1603b705cfSriastradh *
1703b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1803b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1903b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2003b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2103b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2203b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2303b705cfSriastradh * SOFTWARE.
2403b705cfSriastradh *
2503b705cfSriastradh */
2603b705cfSriastradh
2703b705cfSriastradh#ifdef HAVE_CONFIG_H
2803b705cfSriastradh#include "config.h"
2903b705cfSriastradh#endif
3003b705cfSriastradh
3142542f5fSchristos#include <xorg-server.h>
3242542f5fSchristos#include <xorgVersion.h>
3342542f5fSchristos
3403b705cfSriastradh#include <xf86.h>
3503b705cfSriastradh#include <xf86Parser.h>
3603b705cfSriastradh
3703b705cfSriastradh#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,99,0,0)
3803b705cfSriastradh#include <xf86Resources.h>
3903b705cfSriastradh#endif
4003b705cfSriastradh
4103b705cfSriastradh#include "intel_driver.h"
4203b705cfSriastradh#include "intel_options.h"
4303b705cfSriastradh#include "legacy/legacy.h"
4403b705cfSriastradh#include "sna/sna_module.h"
4503b705cfSriastradh#include "uxa/uxa_module.h"
4603b705cfSriastradh
4703b705cfSriastradh#include "i915_pciids.h" /* copied from (kernel) include/drm/i915_pciids.h */
4803b705cfSriastradh
4903b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
5003b705cfSriastradh#include <xf86platformBus.h>
5103b705cfSriastradh#endif
5203b705cfSriastradh
5342542f5fSchristos#ifndef XF86_ALLOCATE_GPU_SCREEN
5442542f5fSchristos#define XF86_ALLOCATE_GPU_SCREEN 0
5542542f5fSchristos#endif
5642542f5fSchristos
5703b705cfSriastradhstatic const struct intel_device_info intel_generic_info = {
5803b705cfSriastradh	.gen = -1,
5903b705cfSriastradh};
6003b705cfSriastradh
6103b705cfSriastradhstatic const struct intel_device_info intel_i81x_info = {
6203b705cfSriastradh	.gen = 010,
6303b705cfSriastradh};
6403b705cfSriastradh
6503b705cfSriastradhstatic const struct intel_device_info intel_i830_info = {
6603b705cfSriastradh	.gen = 020,
6703b705cfSriastradh};
6803b705cfSriastradhstatic const struct intel_device_info intel_i845_info = {
6903b705cfSriastradh	.gen = 020,
7003b705cfSriastradh};
7103b705cfSriastradhstatic const struct intel_device_info intel_i855_info = {
7203b705cfSriastradh	.gen = 021,
7303b705cfSriastradh};
7403b705cfSriastradhstatic const struct intel_device_info intel_i865_info = {
7503b705cfSriastradh	.gen = 022,
7603b705cfSriastradh};
7703b705cfSriastradh
7803b705cfSriastradhstatic const struct intel_device_info intel_i915_info = {
7903b705cfSriastradh	.gen = 030,
8003b705cfSriastradh};
8103b705cfSriastradhstatic const struct intel_device_info intel_i945_info = {
8203b705cfSriastradh	.gen = 031,
8303b705cfSriastradh};
8403b705cfSriastradh
8503b705cfSriastradhstatic const struct intel_device_info intel_g33_info = {
8603b705cfSriastradh	.gen = 033,
8703b705cfSriastradh};
8803b705cfSriastradh
8903b705cfSriastradhstatic const struct intel_device_info intel_i965_info = {
9003b705cfSriastradh	.gen = 040,
9103b705cfSriastradh};
9203b705cfSriastradh
9303b705cfSriastradhstatic const struct intel_device_info intel_g4x_info = {
9403b705cfSriastradh	.gen = 045,
9503b705cfSriastradh};
9603b705cfSriastradh
9703b705cfSriastradhstatic const struct intel_device_info intel_ironlake_info = {
9803b705cfSriastradh	.gen = 050,
9903b705cfSriastradh};
10003b705cfSriastradh
10103b705cfSriastradhstatic const struct intel_device_info intel_sandybridge_info = {
10203b705cfSriastradh	.gen = 060,
10303b705cfSriastradh};
10403b705cfSriastradh
10503b705cfSriastradhstatic const struct intel_device_info intel_ivybridge_info = {
10603b705cfSriastradh	.gen = 070,
10703b705cfSriastradh};
10803b705cfSriastradh
10903b705cfSriastradhstatic const struct intel_device_info intel_valleyview_info = {
11003b705cfSriastradh	.gen = 071,
11103b705cfSriastradh};
11203b705cfSriastradh
11303b705cfSriastradhstatic const struct intel_device_info intel_haswell_info = {
11403b705cfSriastradh	.gen = 075,
11503b705cfSriastradh};
11603b705cfSriastradh
11742542f5fSchristosstatic const struct intel_device_info intel_broadwell_info = {
11842542f5fSchristos	.gen = 0100,
11942542f5fSchristos};
12042542f5fSchristos
12142542f5fSchristosstatic const struct intel_device_info intel_cherryview_info = {
12242542f5fSchristos	.gen = 0101,
12342542f5fSchristos};
12442542f5fSchristos
12503b705cfSriastradhstatic const SymTabRec intel_chipsets[] = {
12603b705cfSriastradh	{PCI_CHIP_I810,				"i810"},
12703b705cfSriastradh	{PCI_CHIP_I810_DC100,			"i810-dc100"},
12803b705cfSriastradh	{PCI_CHIP_I810_E,			"i810e"},
12903b705cfSriastradh	{PCI_CHIP_I815,				"i815"},
13003b705cfSriastradh	{PCI_CHIP_I830_M,			"i830M"},
13103b705cfSriastradh	{PCI_CHIP_845_G,			"845G"},
13203b705cfSriastradh	{PCI_CHIP_I854,				"854"},
13303b705cfSriastradh	{PCI_CHIP_I855_GM,			"852GM/855GM"},
13403b705cfSriastradh	{PCI_CHIP_I865_G,			"865G"},
13503b705cfSriastradh	{PCI_CHIP_I915_G,			"915G"},
13603b705cfSriastradh	{PCI_CHIP_E7221_G,			"E7221 (i915)"},
13703b705cfSriastradh	{PCI_CHIP_I915_GM,			"915GM"},
13803b705cfSriastradh	{PCI_CHIP_I945_G,			"945G"},
13903b705cfSriastradh	{PCI_CHIP_I945_GM,			"945GM"},
14003b705cfSriastradh	{PCI_CHIP_I945_GME,			"945GME"},
14103b705cfSriastradh	{PCI_CHIP_PINEVIEW_M,			"Pineview GM"},
14203b705cfSriastradh	{PCI_CHIP_PINEVIEW_G,			"Pineview G"},
14303b705cfSriastradh	{PCI_CHIP_I965_G,			"965G"},
14403b705cfSriastradh	{PCI_CHIP_G35_G,			"G35"},
14503b705cfSriastradh	{PCI_CHIP_I965_Q,			"965Q"},
14603b705cfSriastradh	{PCI_CHIP_I946_GZ,			"946GZ"},
14703b705cfSriastradh	{PCI_CHIP_I965_GM,			"965GM"},
14803b705cfSriastradh	{PCI_CHIP_I965_GME,			"965GME/GLE"},
14903b705cfSriastradh	{PCI_CHIP_G33_G,			"G33"},
15003b705cfSriastradh	{PCI_CHIP_Q35_G,			"Q35"},
15103b705cfSriastradh	{PCI_CHIP_Q33_G,			"Q33"},
15203b705cfSriastradh	{PCI_CHIP_GM45_GM,			"GM45"},
15303b705cfSriastradh	{PCI_CHIP_G45_E_G,			"4 Series"},
15403b705cfSriastradh	{PCI_CHIP_G45_G,			"G45/G43"},
15503b705cfSriastradh	{PCI_CHIP_Q45_G,			"Q45/Q43"},
15603b705cfSriastradh	{PCI_CHIP_G41_G,			"G41"},
15703b705cfSriastradh	{PCI_CHIP_B43_G,			"B43"},
15803b705cfSriastradh	{PCI_CHIP_B43_G1,			"B43"},
15942542f5fSchristos
16042542f5fSchristos	{0, ""},
16142542f5fSchristos
16203b705cfSriastradh	{PCI_CHIP_IRONLAKE_D_G,			"HD Graphics"},
16303b705cfSriastradh	{PCI_CHIP_IRONLAKE_M_G,			"HD Graphics"},
16403b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT1,		"HD Graphics 2000" },
16503b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT2,		"HD Graphics 3000" },
16603b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT2_PLUS,		"HD Graphics 3000" },
16703b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT1,		"HD Graphics 2000" },
16803b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT2,		"HD Graphics 3000" },
16903b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS,	"HD Graphics 3000" },
17003b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_S_GT,		"HD Graphics" },
17103b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_M_GT1,		"HD Graphics 2500" },
17203b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_M_GT2,		"HD Graphics 4000" },
17303b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_D_GT1,		"HD Graphics 2500" },
17403b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_D_GT2,		"HD Graphics 4000" },
17503b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_S_GT1,		"HD Graphics" },
17603b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_S_GT2,		"HD Graphics P4000" },
17703b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT1,		"HD Graphics" },
17803b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT2,		"HD Graphics 4600" },
17903b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT3,		"HD Graphics 5000" }, /* ??? */
18003b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT1,		"HD Graphics" },
18103b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT2,		"HD Graphics 4600" },
18203b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT3,		"HD Graphics 5000" }, /* ??? */
18303b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT1,		"HD Graphics" },
18403b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT2,		"HD Graphics P4600/P4700" },
18503b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT3,		"HD Graphics 5000" }, /* ??? */
18603b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT1,		"HD Graphics" }, /* ??? */
18703b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT2,		"HD Graphics" }, /* ??? */
18803b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT3,		"HD Graphics" }, /* ??? */
18903b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT1,		"HD Graphics" },
19003b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT2,		"HD Graphics" }, /* ??? */
19103b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT3,		"HD Graphics" }, /* ??? */
19203b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT1,		"HD Graphics" }, /* ??? */
19303b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT2,		"HD Graphics" }, /* ??? */
19403b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT3,		"Iris(TM) Graphics 5100" },
19503b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT1,		"HD Graphics" },
19603b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT2,		"HD Graphics 4400" },
19703b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT3,		"HD Graphics 5000" },
19803b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT1,		"HD Graphics" }, /* ??? */
19903b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT2,		"HD Graphics" }, /* ??? */
20003b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT3,		"Iris(TM) Graphics 5100" },
20103b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT1,		"HD Graphics" }, /* ??? */
20203b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT2,		"HD Graphics" }, /* ??? */
20303b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT3,		"Iris(TM) Graphics 5100" },
20403b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT1,		"HD Graphics" },
20503b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT2,		"HD Graphics 4200" },
20603b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT3,		"Iris(TM) Graphics 5100" },
20703b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT1,		"HD Graphics" }, /* ??? */
20803b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT2,		"HD Graphics 4600" },
20903b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT3,		"Iris(TM) Pro Graphics 5200" },
21003b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT1,		"HD Graphics" }, /* ??? */
21103b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT2,		"HD Graphics 4600" },
21203b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT3,		"Iris(TM) Pro Graphics 5200" },
21303b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT1,		"HD Graphics" }, /* ??? */
21403b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT2,		"HD Graphics" }, /* ??? */
21503b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT3,		"Iris(TM) Pro Graphics 5200" },
21603b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT1,		"HD Graphics" }, /* ??? */
21703b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT2,		"HD Graphics" }, /* ??? */
21803b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT3,		"Iris(TM) Pro Graphics 5200" },
21903b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT1,		"HD Graphics" }, /* ??? */
22003b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT2,		"HD Graphics" }, /* ??? */
22103b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT3,		"Iris(TM) Pro Graphics 5200" },
22242542f5fSchristos
22342542f5fSchristos	/* Valleyview (Baytail) */
22442542f5fSchristos	{0x0f30, "HD Graphics"},
22542542f5fSchristos	{0x0f31, "HD Graphics"},
22642542f5fSchristos	{0x0f32, "HD Graphics"},
22742542f5fSchristos	{0x0f33, "HD Graphics"},
22842542f5fSchristos	{0x0155, "HD Graphics"},
22942542f5fSchristos	{0x0157, "HD Graphics"},
23042542f5fSchristos
23142542f5fSchristos	/* Broadwell Marketing names */
23242542f5fSchristos	{0x1602, "HD graphics"},
23342542f5fSchristos	{0x1606, "HD graphics"},
23442542f5fSchristos	{0x160B, "HD graphics"},
23542542f5fSchristos	{0x160A, "HD graphics"},
23642542f5fSchristos	{0x160D, "HD graphics"},
23742542f5fSchristos	{0x160E, "HD graphics"},
23842542f5fSchristos	{0x1612, "HD graphics 5600"},
23942542f5fSchristos	{0x1616, "HD graphics 5500"},
24042542f5fSchristos	{0x161B, "HD graphics"},
24142542f5fSchristos	{0x161A, "HD graphics"},
24242542f5fSchristos	{0x161D, "HD graphics"},
24342542f5fSchristos	{0x161E, "HD graphics 5300"},
24442542f5fSchristos	{0x1622, "Iris Pro graphics 6200"},
24542542f5fSchristos	{0x1626, "HD graphics 6000"},
24642542f5fSchristos	{0x162B, "Iris graphics 6100"},
24742542f5fSchristos	{0x162A, "Iris Pro graphics P6300"},
24842542f5fSchristos	{0x162D, "HD graphics"},
24942542f5fSchristos	{0x162E, "HD graphics"},
25042542f5fSchristos	{0x1632, "HD graphics"},
25142542f5fSchristos	{0x1636, "HD graphics"},
25242542f5fSchristos	{0x163B, "HD graphics"},
25342542f5fSchristos	{0x163A, "HD graphics"},
25442542f5fSchristos	{0x163D, "HD graphics"},
25542542f5fSchristos	{0x163E, "HD graphics"},
25642542f5fSchristos
25742542f5fSchristos	/* When adding new identifiers, also update:
25842542f5fSchristos	 * 1. intel_identify()
25942542f5fSchristos	 * 2. man/intel.man
26042542f5fSchristos	 * 3. README
26142542f5fSchristos	 */
26242542f5fSchristos
26342542f5fSchristos	{-1, NULL} /* Sentinel */
26403b705cfSriastradh};
26503b705cfSriastradh
26603b705cfSriastradhstatic const struct pci_id_match intel_device_match[] = {
26742542f5fSchristos#if UMS
26803b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810, &intel_i81x_info),
26903b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810_DC100, &intel_i81x_info),
27003b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810_E, &intel_i81x_info),
27103b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I815, &intel_i81x_info),
27203b705cfSriastradh#endif
27303b705cfSriastradh
27442542f5fSchristos#if KMS
27503b705cfSriastradh	INTEL_I830_IDS(&intel_i830_info),
27642542f5fSchristos	INTEL_I845G_IDS(&intel_i845_info),
27703b705cfSriastradh	INTEL_I85X_IDS(&intel_i855_info),
27803b705cfSriastradh	INTEL_I865G_IDS(&intel_i865_info),
27903b705cfSriastradh
28003b705cfSriastradh	INTEL_I915G_IDS(&intel_i915_info),
28103b705cfSriastradh	INTEL_I915GM_IDS(&intel_i915_info),
28203b705cfSriastradh	INTEL_I945G_IDS(&intel_i945_info),
28303b705cfSriastradh	INTEL_I945GM_IDS(&intel_i945_info),
28403b705cfSriastradh
28503b705cfSriastradh	INTEL_G33_IDS(&intel_g33_info),
28603b705cfSriastradh	INTEL_PINEVIEW_IDS(&intel_g33_info),
28703b705cfSriastradh
28803b705cfSriastradh	INTEL_I965G_IDS(&intel_i965_info),
28903b705cfSriastradh	INTEL_I965GM_IDS(&intel_i965_info),
29003b705cfSriastradh
29103b705cfSriastradh	INTEL_G45_IDS(&intel_g4x_info),
29203b705cfSriastradh	INTEL_GM45_IDS(&intel_g4x_info),
29303b705cfSriastradh
29403b705cfSriastradh	INTEL_IRONLAKE_D_IDS(&intel_ironlake_info),
29503b705cfSriastradh	INTEL_IRONLAKE_M_IDS(&intel_ironlake_info),
29603b705cfSriastradh
29703b705cfSriastradh	INTEL_SNB_D_IDS(&intel_sandybridge_info),
29803b705cfSriastradh	INTEL_SNB_M_IDS(&intel_sandybridge_info),
29903b705cfSriastradh
30003b705cfSriastradh	INTEL_IVB_D_IDS(&intel_ivybridge_info),
30103b705cfSriastradh	INTEL_IVB_M_IDS(&intel_ivybridge_info),
30203b705cfSriastradh
30303b705cfSriastradh	INTEL_HSW_D_IDS(&intel_haswell_info),
30403b705cfSriastradh	INTEL_HSW_M_IDS(&intel_haswell_info),
30503b705cfSriastradh
30603b705cfSriastradh	INTEL_VLV_D_IDS(&intel_valleyview_info),
30703b705cfSriastradh	INTEL_VLV_M_IDS(&intel_valleyview_info),
30803b705cfSriastradh
30942542f5fSchristos	INTEL_BDW_D_IDS(&intel_broadwell_info),
31042542f5fSchristos	INTEL_BDW_M_IDS(&intel_broadwell_info),
31142542f5fSchristos
31242542f5fSchristos	INTEL_CHV_IDS(&intel_cherryview_info),
31342542f5fSchristos
31403b705cfSriastradh	INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info),
31503b705cfSriastradh#endif
31603b705cfSriastradh
31703b705cfSriastradh	{ 0, 0, 0 },
31803b705cfSriastradh};
31903b705cfSriastradh
32003b705cfSriastradhvoid
32142542f5fSchristosintel_detect_chipset(ScrnInfoPtr scrn, EntityInfoPtr ent)
32203b705cfSriastradh{
32303b705cfSriastradh	MessageType from = X_PROBED;
32403b705cfSriastradh	const char *name = NULL;
32542542f5fSchristos	int devid;
32603b705cfSriastradh	int i;
32703b705cfSriastradh
32803b705cfSriastradh	if (ent->device->chipID >= 0) {
32903b705cfSriastradh		xf86DrvMsg(scrn->scrnIndex, from = X_CONFIG,
33003b705cfSriastradh			   "ChipID override: 0x%04X\n",
33103b705cfSriastradh			   ent->device->chipID);
33242542f5fSchristos		devid = ent->device->chipID;
33342542f5fSchristos	} else {
33442542f5fSchristos		struct pci_device *pci;
33542542f5fSchristos
33642542f5fSchristos		pci = xf86GetPciInfoForEntity(ent->index);
33742542f5fSchristos		if (pci != NULL)
33842542f5fSchristos			devid = pci->device_id;
33942542f5fSchristos		else
34042542f5fSchristos			devid = intel_get_device_id(scrn);
34103b705cfSriastradh	}
34203b705cfSriastradh
34303b705cfSriastradh	for (i = 0; intel_chipsets[i].name != NULL; i++) {
34442542f5fSchristos		if (devid == intel_chipsets[i].token) {
34503b705cfSriastradh			name = intel_chipsets[i].name;
34603b705cfSriastradh			break;
34703b705cfSriastradh		}
34803b705cfSriastradh	}
34903b705cfSriastradh	if (name == NULL) {
35003b705cfSriastradh		int gen = 0;
35103b705cfSriastradh
35203b705cfSriastradh		for (i = 0; intel_device_match[i].device_id != 0; i++) {
35342542f5fSchristos			if (devid == intel_device_match[i].device_id) {
35403b705cfSriastradh				const struct intel_device_info *info = (void *)intel_device_match[i].match_data;
35503b705cfSriastradh				gen = info->gen >> 3;
35603b705cfSriastradh				break;
35703b705cfSriastradh			}
35803b705cfSriastradh		}
35903b705cfSriastradh
36042542f5fSchristos		if (gen) {
36103b705cfSriastradh			xf86DrvMsg(scrn->scrnIndex, from,
36203b705cfSriastradh				   "gen%d engineering sample\n", gen);
36303b705cfSriastradh		} else {
36403b705cfSriastradh			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
36503b705cfSriastradh				   "Unknown chipset\n");
36603b705cfSriastradh		}
36742542f5fSchristos
36803b705cfSriastradh		name = "unknown";
36903b705cfSriastradh	} else {
37003b705cfSriastradh		xf86DrvMsg(scrn->scrnIndex, from,
37103b705cfSriastradh			   "Integrated Graphics Chipset: Intel(R) %s\n",
37203b705cfSriastradh			   name);
37303b705cfSriastradh	}
37403b705cfSriastradh
37503b705cfSriastradh	scrn->chipset = (char *)name;
37603b705cfSriastradh}
37703b705cfSriastradh
37803b705cfSriastradh/*
37903b705cfSriastradh * intel_identify --
38003b705cfSriastradh *
38103b705cfSriastradh * Returns the string name for the driver based on the chipset.
38203b705cfSriastradh *
38303b705cfSriastradh */
38403b705cfSriastradhstatic void intel_identify(int flags)
38503b705cfSriastradh{
38603b705cfSriastradh	const SymTabRec *chipset;
38703b705cfSriastradh	const char *stack[64], **unique;
38803b705cfSriastradh	int i, j, size, len;
38903b705cfSriastradh
39003b705cfSriastradh	unique = stack;
39103b705cfSriastradh	size = sizeof(stack)/sizeof(stack[0]);
39203b705cfSriastradh	i = 0;
39303b705cfSriastradh
39403b705cfSriastradh	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Integrated Graphics Chipsets:\n\t");
39503b705cfSriastradh	len = 8;
39603b705cfSriastradh
39742542f5fSchristos	for (chipset = intel_chipsets; chipset->token; chipset++) {
39803b705cfSriastradh		for (j = i; --j >= 0;)
39903b705cfSriastradh			if (strcmp(unique[j], chipset->name) == 0)
40003b705cfSriastradh				break;
40103b705cfSriastradh		if (j < 0) {
40203b705cfSriastradh			int name_len = strlen(chipset->name);
40303b705cfSriastradh			if (i != 0) {
40403b705cfSriastradh				xf86ErrorF(",");
40503b705cfSriastradh				len++;
40603b705cfSriastradh				if (len + 2 + name_len < 78) {
40703b705cfSriastradh					xf86ErrorF(" ");
40803b705cfSriastradh					len++;
40903b705cfSriastradh				} else {
41003b705cfSriastradh					xf86ErrorF("\n\t");
41103b705cfSriastradh					len = 8;
41203b705cfSriastradh				}
41303b705cfSriastradh			}
41403b705cfSriastradh			xf86ErrorF("%s", chipset->name);
41503b705cfSriastradh			len += name_len;
41603b705cfSriastradh
41703b705cfSriastradh			if (i == size) {
41803b705cfSriastradh				const char **new_unique;
41903b705cfSriastradh
42003b705cfSriastradh				if (unique == stack)
42103b705cfSriastradh					new_unique = malloc(2*sizeof(*unique)*size);
42203b705cfSriastradh				else
42303b705cfSriastradh					new_unique = realloc(unique, 2*sizeof(*unique)*size);
42403b705cfSriastradh				if (new_unique != NULL) {
42503b705cfSriastradh					if (unique == stack)
42603b705cfSriastradh						memcpy(new_unique, stack,
42703b705cfSriastradh						       sizeof(stack));
42803b705cfSriastradh					unique = new_unique;
42903b705cfSriastradh					size *= 2;
43003b705cfSriastradh				}
43103b705cfSriastradh			}
43203b705cfSriastradh			if (i < size)
43303b705cfSriastradh				unique[i++] = chipset->name;
43403b705cfSriastradh		}
43503b705cfSriastradh	}
43603b705cfSriastradh	xf86ErrorF("\n");
43703b705cfSriastradh	if (unique != stack)
43803b705cfSriastradh		free(unique);
43942542f5fSchristos
44042542f5fSchristos	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) HD Graphics: 2000-6000\n");
44142542f5fSchristos	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Graphics: 5100, 6100\n");
44242542f5fSchristos	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Pro Graphics: 5200, 6200, P6300\n");
44303b705cfSriastradh}
44403b705cfSriastradh
44503b705cfSriastradhstatic Bool intel_driver_func(ScrnInfoPtr pScrn,
44603b705cfSriastradh			      xorgDriverFuncOp op,
44703b705cfSriastradh			      pointer ptr)
44803b705cfSriastradh{
44903b705cfSriastradh	xorgHWFlags *flag;
45003b705cfSriastradh
45103b705cfSriastradh	switch (op) {
45203b705cfSriastradh	case GET_REQUIRED_HW_INTERFACES:
45303b705cfSriastradh		flag = (CARD32*)ptr;
45403b705cfSriastradh		(*flag) = 0;
45542542f5fSchristos#if UMS
45603b705cfSriastradh		(*flag) = HW_IO | HW_MMIO;
45703b705cfSriastradh#endif
45803b705cfSriastradh#ifdef HW_SKIP_CONSOLE
45903b705cfSriastradh		if (hosted())
46003b705cfSriastradh			(*flag) = HW_SKIP_CONSOLE;
46103b705cfSriastradh#endif
46203b705cfSriastradh
46303b705cfSriastradh		return TRUE;
46442542f5fSchristos
46542542f5fSchristos#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0)
46642542f5fSchristos	case SUPPORTS_SERVER_FDS:
46742542f5fSchristos		return TRUE;
46842542f5fSchristos#endif
46942542f5fSchristos
47003b705cfSriastradh	default:
47103b705cfSriastradh		/* Unknown or deprecated function */
47203b705cfSriastradh		return FALSE;
47303b705cfSriastradh	}
47403b705cfSriastradh}
47503b705cfSriastradh
47642542f5fSchristos#if KMS
47703b705cfSriastradhextern XF86ConfigPtr xf86configptr;
47803b705cfSriastradh
47903b705cfSriastradhstatic XF86ConfDevicePtr
48003b705cfSriastradh_xf86findDriver(const char *ident, XF86ConfDevicePtr p)
48103b705cfSriastradh{
48203b705cfSriastradh	while (p) {
48303b705cfSriastradh		if (p->dev_driver && xf86nameCompare(ident, p->dev_driver) == 0)
48403b705cfSriastradh			return p;
48503b705cfSriastradh
48603b705cfSriastradh		p = p->list.next;
48703b705cfSriastradh	}
48803b705cfSriastradh
48903b705cfSriastradh	return NULL;
49003b705cfSriastradh}
49103b705cfSriastradh
49242542f5fSchristosstatic enum accel_method { NOACCEL, SNA, UXA, GLAMOR } get_accel_method(void)
49303b705cfSriastradh{
49403b705cfSriastradh	enum accel_method accel_method = DEFAULT_ACCEL_METHOD;
49503b705cfSriastradh	XF86ConfDevicePtr dev;
49603b705cfSriastradh
49703b705cfSriastradh	if (hosted())
49803b705cfSriastradh		return SNA;
49903b705cfSriastradh
50003b705cfSriastradh	dev = _xf86findDriver("intel", xf86configptr->conf_device_lst);
50103b705cfSriastradh	if (dev && dev->dev_option_lst) {
50203b705cfSriastradh		const char *s;
50303b705cfSriastradh
50403b705cfSriastradh		s = xf86FindOptionValue(dev->dev_option_lst, "AccelMethod");
50503b705cfSriastradh		if (s ) {
50642542f5fSchristos			if (strcasecmp(s, "none") == 0)
50742542f5fSchristos				accel_method = NOACCEL;
50842542f5fSchristos			else if (strcasecmp(s, "sna") == 0)
50903b705cfSriastradh				accel_method = SNA;
51003b705cfSriastradh			else if (strcasecmp(s, "uxa") == 0)
51103b705cfSriastradh				accel_method = UXA;
51203b705cfSriastradh			else if (strcasecmp(s, "glamor") == 0)
51342542f5fSchristos				accel_method = GLAMOR;
51403b705cfSriastradh		}
51503b705cfSriastradh	}
51603b705cfSriastradh
51703b705cfSriastradh	return accel_method;
51803b705cfSriastradh}
51903b705cfSriastradh#endif
52003b705cfSriastradh
52103b705cfSriastradhstatic Bool
52203b705cfSriastradhintel_scrn_create(DriverPtr		driver,
52303b705cfSriastradh		  int			entity_num,
52403b705cfSriastradh		  intptr_t		match_data,
52503b705cfSriastradh		  unsigned		flags)
52603b705cfSriastradh{
52703b705cfSriastradh	ScrnInfoPtr scrn;
52803b705cfSriastradh
52942542f5fSchristos	if (match_data == 0) {
53042542f5fSchristos		int devid = intel_entity_get_devid(entity_num), i;
53142542f5fSchristos		if (devid == 0)
53242542f5fSchristos			return FALSE;
53342542f5fSchristos
53442542f5fSchristos		for (i = 0; intel_device_match[i].device_id != 0; i++) {
53542542f5fSchristos			if (devid == intel_device_match[i].device_id) {
53642542f5fSchristos				match_data = (intptr_t)&intel_device_match[i];
53742542f5fSchristos				break;
53842542f5fSchristos			}
53942542f5fSchristos		}
54042542f5fSchristos
54142542f5fSchristos		if (match_data == 0)
54242542f5fSchristos			return FALSE;
54342542f5fSchristos	}
54442542f5fSchristos
54503b705cfSriastradh	scrn = xf86AllocateScreen(driver, flags);
54603b705cfSriastradh	if (scrn == NULL)
54703b705cfSriastradh		return FALSE;
54803b705cfSriastradh
54903b705cfSriastradh	scrn->driverVersion = INTEL_VERSION;
55003b705cfSriastradh	scrn->driverName = (char *)INTEL_DRIVER_NAME;
55103b705cfSriastradh	scrn->name = (char *)INTEL_NAME;
55242542f5fSchristos	scrn->driverPrivate = (void *)(match_data | (flags & XF86_ALLOCATE_GPU_SCREEN) | 2);
55303b705cfSriastradh	scrn->Probe = NULL;
55403b705cfSriastradh
55503b705cfSriastradh	if (xf86IsEntitySharable(entity_num))
55603b705cfSriastradh		xf86SetEntityShared(entity_num);
55703b705cfSriastradh	xf86AddEntityToScreen(scrn, entity_num);
55803b705cfSriastradh
55942542f5fSchristos#if UMS
56003b705cfSriastradh	if ((unsigned)((struct intel_device_info *)match_data)->gen < 020)
56103b705cfSriastradh		return lg_i810_init(scrn);
56203b705cfSriastradh#endif
56303b705cfSriastradh
56442542f5fSchristos#if KMS
56503b705cfSriastradh	switch (get_accel_method()) {
56603b705cfSriastradh#if USE_SNA
56742542f5fSchristos	case NOACCEL:
56842542f5fSchristos	case SNA:
56942542f5fSchristos		return sna_init_scrn(scrn, entity_num);
57003b705cfSriastradh#endif
57103b705cfSriastradh#if USE_UXA
57242542f5fSchristos#if !USE_SNA
57342542f5fSchristos	case NOACCEL:
57442542f5fSchristos#endif
57542542f5fSchristos	case GLAMOR:
57642542f5fSchristos	case UXA:
57742542f5fSchristos		  return intel_init_scrn(scrn);
57803b705cfSriastradh#endif
57903b705cfSriastradh
58003b705cfSriastradh	default: break;
58103b705cfSriastradh	}
58203b705cfSriastradh#endif
58303b705cfSriastradh
58403b705cfSriastradh	return FALSE;
58503b705cfSriastradh}
58603b705cfSriastradh
58703b705cfSriastradh/*
58803b705cfSriastradh * intel_pci_probe --
58903b705cfSriastradh *
59003b705cfSriastradh * Look through the PCI bus to find cards that are intel boards.
59103b705cfSriastradh * Setup the dispatch table for the rest of the driver functions.
59203b705cfSriastradh *
59303b705cfSriastradh */
59403b705cfSriastradhstatic Bool intel_pci_probe(DriverPtr		driver,
59503b705cfSriastradh			    int			entity_num,
59603b705cfSriastradh			    struct pci_device	*pci,
59703b705cfSriastradh			    intptr_t		match_data)
59803b705cfSriastradh{
59903b705cfSriastradh	if (intel_open_device(entity_num, pci, NULL) == -1) {
60042542f5fSchristos#if UMS
60103b705cfSriastradh		switch (pci->device_id) {
60203b705cfSriastradh		case PCI_CHIP_I810:
60303b705cfSriastradh		case PCI_CHIP_I810_DC100:
60403b705cfSriastradh		case PCI_CHIP_I810_E:
60503b705cfSriastradh		case PCI_CHIP_I815:
60603b705cfSriastradh			if (!hosted())
60703b705cfSriastradh				break;
60803b705cfSriastradh		default:
60903b705cfSriastradh			return FALSE;
61003b705cfSriastradh		}
61142542f5fSchristos#else
61242542f5fSchristos		return FALSE;
61303b705cfSriastradh#endif
61403b705cfSriastradh	}
61503b705cfSriastradh
61603b705cfSriastradh	return intel_scrn_create(driver, entity_num, match_data, 0);
61703b705cfSriastradh}
61803b705cfSriastradh
61903b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
62003b705cfSriastradhstatic Bool
62103b705cfSriastradhintel_platform_probe(DriverPtr driver,
62203b705cfSriastradh		     int entity_num, int flags,
62303b705cfSriastradh		     struct xf86_platform_device *dev,
62403b705cfSriastradh		     intptr_t match_data)
62503b705cfSriastradh{
62603b705cfSriastradh	unsigned scrn_flags = 0;
62703b705cfSriastradh
62842542f5fSchristos	if (intel_open_device(entity_num, dev->pdev, dev) == -1)
62903b705cfSriastradh		return FALSE;
63003b705cfSriastradh
63103b705cfSriastradh	/* Allow ourselves to act as a slaved output if not primary */
63203b705cfSriastradh	if (flags & PLATFORM_PROBE_GPU_SCREEN) {
63303b705cfSriastradh		flags &= ~PLATFORM_PROBE_GPU_SCREEN;
63403b705cfSriastradh		scrn_flags |= XF86_ALLOCATE_GPU_SCREEN;
63503b705cfSriastradh	}
63603b705cfSriastradh
63703b705cfSriastradh	/* if we get any flags we don't understand fail to probe for now */
63803b705cfSriastradh	if (flags)
63903b705cfSriastradh		return FALSE;
64003b705cfSriastradh
64103b705cfSriastradh	return intel_scrn_create(driver, entity_num, match_data, scrn_flags);
64203b705cfSriastradh}
64303b705cfSriastradh#endif
64403b705cfSriastradh
64503b705cfSriastradh#ifdef XFree86LOADER
64603b705cfSriastradh
64703b705cfSriastradhstatic MODULESETUPPROTO(intel_setup);
64803b705cfSriastradh
64903b705cfSriastradhstatic XF86ModuleVersionInfo intel_version = {
65003b705cfSriastradh	"intel",
65103b705cfSriastradh	MODULEVENDORSTRING,
65203b705cfSriastradh	MODINFOSTRING1,
65303b705cfSriastradh	MODINFOSTRING2,
65403b705cfSriastradh	XORG_VERSION_CURRENT,
65503b705cfSriastradh	INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
65603b705cfSriastradh	ABI_CLASS_VIDEODRV,
65703b705cfSriastradh	ABI_VIDEODRV_VERSION,
65803b705cfSriastradh	MOD_CLASS_VIDEODRV,
65903b705cfSriastradh	{0, 0, 0, 0}
66003b705cfSriastradh};
66103b705cfSriastradh
66203b705cfSriastradhstatic const OptionInfoRec *
66303b705cfSriastradhintel_available_options(int chipid, int busid)
66403b705cfSriastradh{
66503b705cfSriastradh	switch (chipid) {
66642542f5fSchristos#if UMS
66703b705cfSriastradh	case PCI_CHIP_I810:
66803b705cfSriastradh	case PCI_CHIP_I810_DC100:
66903b705cfSriastradh	case PCI_CHIP_I810_E:
67003b705cfSriastradh	case PCI_CHIP_I815:
67103b705cfSriastradh		return lg_i810_available_options(chipid, busid);
67203b705cfSriastradh#endif
67303b705cfSriastradh
67403b705cfSriastradh	default:
67503b705cfSriastradh		return intel_options;
67603b705cfSriastradh	}
67703b705cfSriastradh}
67803b705cfSriastradh
67903b705cfSriastradhstatic DriverRec intel = {
68003b705cfSriastradh	INTEL_VERSION,
68103b705cfSriastradh	(char *)INTEL_DRIVER_NAME,
68203b705cfSriastradh	intel_identify,
68303b705cfSriastradh	NULL,
68403b705cfSriastradh	intel_available_options,
68503b705cfSriastradh	NULL,
68603b705cfSriastradh	0,
68703b705cfSriastradh	intel_driver_func,
68803b705cfSriastradh	intel_device_match,
68903b705cfSriastradh	intel_pci_probe,
69003b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
69103b705cfSriastradh	intel_platform_probe
69203b705cfSriastradh#endif
69303b705cfSriastradh};
69403b705cfSriastradh
69503b705cfSriastradhstatic pointer intel_setup(pointer module,
69603b705cfSriastradh			   pointer opts,
69703b705cfSriastradh			   int *errmaj,
69803b705cfSriastradh			   int *errmin)
69903b705cfSriastradh{
70003b705cfSriastradh	static Bool setupDone = 0;
70103b705cfSriastradh
70203b705cfSriastradh	/* This module should be loaded only once, but check to be sure.
70303b705cfSriastradh	*/
70403b705cfSriastradh	if (!setupDone) {
70503b705cfSriastradh		setupDone = 1;
70603b705cfSriastradh		xf86AddDriver(&intel, module, HaveDriverFuncs);
70703b705cfSriastradh
70803b705cfSriastradh		/*
70903b705cfSriastradh		 * The return value must be non-NULL on success even though there
71003b705cfSriastradh		 * is no TearDownProc.
71103b705cfSriastradh		 */
71203b705cfSriastradh		return (pointer) 1;
71303b705cfSriastradh	} else {
71403b705cfSriastradh		if (errmaj)
71503b705cfSriastradh			*errmaj = LDR_ONCEONLY;
71603b705cfSriastradh		return NULL;
71703b705cfSriastradh	}
71803b705cfSriastradh}
71903b705cfSriastradh
72003b705cfSriastradh_X_EXPORT XF86ModuleData intelModuleData = { &intel_version, intel_setup, NULL };
72103b705cfSriastradh#endif
722