intel_module.c revision 13496ba1
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
12513496ba1Ssnjstatic const struct intel_device_info intel_skylake_info = {
12613496ba1Ssnj	.gen = 0110,
12713496ba1Ssnj};
12813496ba1Ssnj
12913496ba1Ssnj
13003b705cfSriastradhstatic const SymTabRec intel_chipsets[] = {
13103b705cfSriastradh	{PCI_CHIP_I810,				"i810"},
13203b705cfSriastradh	{PCI_CHIP_I810_DC100,			"i810-dc100"},
13303b705cfSriastradh	{PCI_CHIP_I810_E,			"i810e"},
13403b705cfSriastradh	{PCI_CHIP_I815,				"i815"},
13503b705cfSriastradh	{PCI_CHIP_I830_M,			"i830M"},
13603b705cfSriastradh	{PCI_CHIP_845_G,			"845G"},
13703b705cfSriastradh	{PCI_CHIP_I854,				"854"},
13803b705cfSriastradh	{PCI_CHIP_I855_GM,			"852GM/855GM"},
13903b705cfSriastradh	{PCI_CHIP_I865_G,			"865G"},
14003b705cfSriastradh	{PCI_CHIP_I915_G,			"915G"},
14103b705cfSriastradh	{PCI_CHIP_E7221_G,			"E7221 (i915)"},
14203b705cfSriastradh	{PCI_CHIP_I915_GM,			"915GM"},
14303b705cfSriastradh	{PCI_CHIP_I945_G,			"945G"},
14403b705cfSriastradh	{PCI_CHIP_I945_GM,			"945GM"},
14503b705cfSriastradh	{PCI_CHIP_I945_GME,			"945GME"},
14603b705cfSriastradh	{PCI_CHIP_PINEVIEW_M,			"Pineview GM"},
14703b705cfSriastradh	{PCI_CHIP_PINEVIEW_G,			"Pineview G"},
14803b705cfSriastradh	{PCI_CHIP_I965_G,			"965G"},
14903b705cfSriastradh	{PCI_CHIP_G35_G,			"G35"},
15003b705cfSriastradh	{PCI_CHIP_I965_Q,			"965Q"},
15103b705cfSriastradh	{PCI_CHIP_I946_GZ,			"946GZ"},
15203b705cfSriastradh	{PCI_CHIP_I965_GM,			"965GM"},
15303b705cfSriastradh	{PCI_CHIP_I965_GME,			"965GME/GLE"},
15403b705cfSriastradh	{PCI_CHIP_G33_G,			"G33"},
15503b705cfSriastradh	{PCI_CHIP_Q35_G,			"Q35"},
15603b705cfSriastradh	{PCI_CHIP_Q33_G,			"Q33"},
15703b705cfSriastradh	{PCI_CHIP_GM45_GM,			"GM45"},
15803b705cfSriastradh	{PCI_CHIP_G45_E_G,			"4 Series"},
15903b705cfSriastradh	{PCI_CHIP_G45_G,			"G45/G43"},
16003b705cfSriastradh	{PCI_CHIP_Q45_G,			"Q45/Q43"},
16103b705cfSriastradh	{PCI_CHIP_G41_G,			"G41"},
16203b705cfSriastradh	{PCI_CHIP_B43_G,			"B43"},
16303b705cfSriastradh	{PCI_CHIP_B43_G1,			"B43"},
16442542f5fSchristos
16542542f5fSchristos	{0, ""},
16642542f5fSchristos
16703b705cfSriastradh	{PCI_CHIP_IRONLAKE_D_G,			"HD Graphics"},
16803b705cfSriastradh	{PCI_CHIP_IRONLAKE_M_G,			"HD Graphics"},
16903b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT1,		"HD Graphics 2000" },
17003b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT2,		"HD Graphics 3000" },
17103b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT2_PLUS,		"HD Graphics 3000" },
17203b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT1,		"HD Graphics 2000" },
17303b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT2,		"HD Graphics 3000" },
17403b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS,	"HD Graphics 3000" },
17503b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_S_GT,		"HD Graphics" },
17603b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_M_GT1,		"HD Graphics 2500" },
17703b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_M_GT2,		"HD Graphics 4000" },
17803b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_D_GT1,		"HD Graphics 2500" },
17903b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_D_GT2,		"HD Graphics 4000" },
18003b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_S_GT1,		"HD Graphics" },
18103b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_S_GT2,		"HD Graphics P4000" },
18203b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT1,		"HD Graphics" },
18303b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT2,		"HD Graphics 4600" },
18403b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT3,		"HD Graphics 5000" }, /* ??? */
18503b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT1,		"HD Graphics" },
18603b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT2,		"HD Graphics 4600" },
18703b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT3,		"HD Graphics 5000" }, /* ??? */
18803b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT1,		"HD Graphics" },
18903b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT2,		"HD Graphics P4600/P4700" },
19003b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT3,		"HD Graphics 5000" }, /* ??? */
19103b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT1,		"HD Graphics" }, /* ??? */
19203b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT2,		"HD Graphics" }, /* ??? */
19303b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT3,		"HD Graphics" }, /* ??? */
19403b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT1,		"HD Graphics" },
19503b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT2,		"HD Graphics" }, /* ??? */
19603b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT3,		"HD Graphics" }, /* ??? */
19703b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT1,		"HD Graphics" }, /* ??? */
19803b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT2,		"HD Graphics" }, /* ??? */
19903b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT3,		"Iris(TM) Graphics 5100" },
20003b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT1,		"HD Graphics" },
20103b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT2,		"HD Graphics 4400" },
20203b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT3,		"HD Graphics 5000" },
20303b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT1,		"HD Graphics" }, /* ??? */
20403b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT2,		"HD Graphics" }, /* ??? */
20503b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT3,		"Iris(TM) Graphics 5100" },
20603b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT1,		"HD Graphics" }, /* ??? */
20703b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT2,		"HD Graphics" }, /* ??? */
20803b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT3,		"Iris(TM) Graphics 5100" },
20903b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT1,		"HD Graphics" },
21003b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT2,		"HD Graphics 4200" },
21103b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT3,		"Iris(TM) Graphics 5100" },
21203b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT1,		"HD Graphics" }, /* ??? */
21303b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT2,		"HD Graphics 4600" },
21403b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT3,		"Iris(TM) Pro Graphics 5200" },
21503b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT1,		"HD Graphics" }, /* ??? */
21603b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT2,		"HD Graphics 4600" },
21703b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT3,		"Iris(TM) Pro Graphics 5200" },
21803b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT1,		"HD Graphics" }, /* ??? */
21903b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT2,		"HD Graphics" }, /* ??? */
22003b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT3,		"Iris(TM) Pro Graphics 5200" },
22103b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT1,		"HD Graphics" }, /* ??? */
22203b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT2,		"HD Graphics" }, /* ??? */
22303b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT3,		"Iris(TM) Pro Graphics 5200" },
22403b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT1,		"HD Graphics" }, /* ??? */
22503b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT2,		"HD Graphics" }, /* ??? */
22603b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT3,		"Iris(TM) Pro Graphics 5200" },
22742542f5fSchristos
22842542f5fSchristos	/* Valleyview (Baytail) */
22942542f5fSchristos	{0x0f30, "HD Graphics"},
23042542f5fSchristos	{0x0f31, "HD Graphics"},
23142542f5fSchristos	{0x0f32, "HD Graphics"},
23242542f5fSchristos	{0x0f33, "HD Graphics"},
23342542f5fSchristos	{0x0155, "HD Graphics"},
23442542f5fSchristos	{0x0157, "HD Graphics"},
23542542f5fSchristos
23642542f5fSchristos	/* Broadwell Marketing names */
23742542f5fSchristos	{0x1602, "HD graphics"},
23842542f5fSchristos	{0x1606, "HD graphics"},
23942542f5fSchristos	{0x160B, "HD graphics"},
24042542f5fSchristos	{0x160A, "HD graphics"},
24142542f5fSchristos	{0x160D, "HD graphics"},
24242542f5fSchristos	{0x160E, "HD graphics"},
24342542f5fSchristos	{0x1612, "HD graphics 5600"},
24442542f5fSchristos	{0x1616, "HD graphics 5500"},
24542542f5fSchristos	{0x161B, "HD graphics"},
24642542f5fSchristos	{0x161A, "HD graphics"},
24742542f5fSchristos	{0x161D, "HD graphics"},
24842542f5fSchristos	{0x161E, "HD graphics 5300"},
24942542f5fSchristos	{0x1622, "Iris Pro graphics 6200"},
25042542f5fSchristos	{0x1626, "HD graphics 6000"},
25142542f5fSchristos	{0x162B, "Iris graphics 6100"},
25242542f5fSchristos	{0x162A, "Iris Pro graphics P6300"},
25342542f5fSchristos	{0x162D, "HD graphics"},
25442542f5fSchristos	{0x162E, "HD graphics"},
25542542f5fSchristos	{0x1632, "HD graphics"},
25642542f5fSchristos	{0x1636, "HD graphics"},
25742542f5fSchristos	{0x163B, "HD graphics"},
25842542f5fSchristos	{0x163A, "HD graphics"},
25942542f5fSchristos	{0x163D, "HD graphics"},
26042542f5fSchristos	{0x163E, "HD graphics"},
26142542f5fSchristos
26242542f5fSchristos	/* When adding new identifiers, also update:
26342542f5fSchristos	 * 1. intel_identify()
26442542f5fSchristos	 * 2. man/intel.man
26542542f5fSchristos	 * 3. README
26642542f5fSchristos	 */
26742542f5fSchristos
26842542f5fSchristos	{-1, NULL} /* Sentinel */
26903b705cfSriastradh};
27003b705cfSriastradh
27103b705cfSriastradhstatic const struct pci_id_match intel_device_match[] = {
27242542f5fSchristos#if UMS
27303b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810, &intel_i81x_info),
27403b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810_DC100, &intel_i81x_info),
27503b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810_E, &intel_i81x_info),
27603b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I815, &intel_i81x_info),
27703b705cfSriastradh#endif
27803b705cfSriastradh
27942542f5fSchristos#if KMS
28003b705cfSriastradh	INTEL_I830_IDS(&intel_i830_info),
28142542f5fSchristos	INTEL_I845G_IDS(&intel_i845_info),
28203b705cfSriastradh	INTEL_I85X_IDS(&intel_i855_info),
28303b705cfSriastradh	INTEL_I865G_IDS(&intel_i865_info),
28403b705cfSriastradh
28503b705cfSriastradh	INTEL_I915G_IDS(&intel_i915_info),
28603b705cfSriastradh	INTEL_I915GM_IDS(&intel_i915_info),
28703b705cfSriastradh	INTEL_I945G_IDS(&intel_i945_info),
28803b705cfSriastradh	INTEL_I945GM_IDS(&intel_i945_info),
28903b705cfSriastradh
29003b705cfSriastradh	INTEL_G33_IDS(&intel_g33_info),
29103b705cfSriastradh	INTEL_PINEVIEW_IDS(&intel_g33_info),
29203b705cfSriastradh
29303b705cfSriastradh	INTEL_I965G_IDS(&intel_i965_info),
29403b705cfSriastradh	INTEL_I965GM_IDS(&intel_i965_info),
29503b705cfSriastradh
29603b705cfSriastradh	INTEL_G45_IDS(&intel_g4x_info),
29703b705cfSriastradh	INTEL_GM45_IDS(&intel_g4x_info),
29803b705cfSriastradh
29903b705cfSriastradh	INTEL_IRONLAKE_D_IDS(&intel_ironlake_info),
30003b705cfSriastradh	INTEL_IRONLAKE_M_IDS(&intel_ironlake_info),
30103b705cfSriastradh
30203b705cfSriastradh	INTEL_SNB_D_IDS(&intel_sandybridge_info),
30303b705cfSriastradh	INTEL_SNB_M_IDS(&intel_sandybridge_info),
30403b705cfSriastradh
30503b705cfSriastradh	INTEL_IVB_D_IDS(&intel_ivybridge_info),
30603b705cfSriastradh	INTEL_IVB_M_IDS(&intel_ivybridge_info),
30703b705cfSriastradh
30803b705cfSriastradh	INTEL_HSW_D_IDS(&intel_haswell_info),
30903b705cfSriastradh	INTEL_HSW_M_IDS(&intel_haswell_info),
31003b705cfSriastradh
31103b705cfSriastradh	INTEL_VLV_D_IDS(&intel_valleyview_info),
31203b705cfSriastradh	INTEL_VLV_M_IDS(&intel_valleyview_info),
31303b705cfSriastradh
31442542f5fSchristos	INTEL_BDW_D_IDS(&intel_broadwell_info),
31542542f5fSchristos	INTEL_BDW_M_IDS(&intel_broadwell_info),
31642542f5fSchristos
31742542f5fSchristos	INTEL_CHV_IDS(&intel_cherryview_info),
31842542f5fSchristos
31913496ba1Ssnj	INTEL_SKL_IDS(&intel_skylake_info),
32013496ba1Ssnj
32103b705cfSriastradh	INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info),
32203b705cfSriastradh#endif
32303b705cfSriastradh
32403b705cfSriastradh	{ 0, 0, 0 },
32503b705cfSriastradh};
32603b705cfSriastradh
32703b705cfSriastradhvoid
32813496ba1Ssnjintel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev)
32903b705cfSriastradh{
33042542f5fSchristos	int devid;
33113496ba1Ssnj	const char *name = NULL;
33203b705cfSriastradh	int i;
33303b705cfSriastradh
33413496ba1Ssnj	if (dev == NULL) {
33513496ba1Ssnj		EntityInfoPtr ent;
33642542f5fSchristos		struct pci_device *pci;
33742542f5fSchristos
33813496ba1Ssnj		ent = xf86GetEntityInfo(scrn->entityList[0]);
33913496ba1Ssnj		if (ent->device->chipID >= 0) {
34013496ba1Ssnj			xf86DrvMsg(scrn->scrnIndex, X_CONFIG,
34113496ba1Ssnj				   "ChipID override: 0x%04X\n",
34213496ba1Ssnj				   ent->device->chipID);
34313496ba1Ssnj			devid = ent->device->chipID;
34413496ba1Ssnj		} else {
34513496ba1Ssnj			pci = xf86GetPciInfoForEntity(ent->index);
34613496ba1Ssnj			if (pci)
34713496ba1Ssnj				devid = pci->device_id;
34813496ba1Ssnj			else
34913496ba1Ssnj				devid = ~0;
35013496ba1Ssnj		}
35113496ba1Ssnj	} else
35213496ba1Ssnj		devid = intel_get_device_id(dev);
35303b705cfSriastradh
35403b705cfSriastradh	for (i = 0; intel_chipsets[i].name != NULL; i++) {
35542542f5fSchristos		if (devid == intel_chipsets[i].token) {
35603b705cfSriastradh			name = intel_chipsets[i].name;
35703b705cfSriastradh			break;
35803b705cfSriastradh		}
35903b705cfSriastradh	}
36003b705cfSriastradh	if (name == NULL) {
36103b705cfSriastradh		int gen = 0;
36203b705cfSriastradh
36303b705cfSriastradh		for (i = 0; intel_device_match[i].device_id != 0; i++) {
36442542f5fSchristos			if (devid == intel_device_match[i].device_id) {
36503b705cfSriastradh				const struct intel_device_info *info = (void *)intel_device_match[i].match_data;
36603b705cfSriastradh				gen = info->gen >> 3;
36703b705cfSriastradh				break;
36803b705cfSriastradh			}
36903b705cfSriastradh		}
37003b705cfSriastradh
37142542f5fSchristos		if (gen) {
37213496ba1Ssnj			xf86DrvMsg(scrn->scrnIndex, X_PROBED,
37303b705cfSriastradh				   "gen%d engineering sample\n", gen);
37403b705cfSriastradh		} else {
37503b705cfSriastradh			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
37603b705cfSriastradh				   "Unknown chipset\n");
37703b705cfSriastradh		}
37842542f5fSchristos
37903b705cfSriastradh		name = "unknown";
38003b705cfSriastradh	} else {
38113496ba1Ssnj		xf86DrvMsg(scrn->scrnIndex, X_PROBED,
38203b705cfSriastradh			   "Integrated Graphics Chipset: Intel(R) %s\n",
38303b705cfSriastradh			   name);
38403b705cfSriastradh	}
38503b705cfSriastradh
38603b705cfSriastradh	scrn->chipset = (char *)name;
38703b705cfSriastradh}
38803b705cfSriastradh
38903b705cfSriastradh/*
39003b705cfSriastradh * intel_identify --
39103b705cfSriastradh *
39203b705cfSriastradh * Returns the string name for the driver based on the chipset.
39303b705cfSriastradh *
39403b705cfSriastradh */
39503b705cfSriastradhstatic void intel_identify(int flags)
39603b705cfSriastradh{
39703b705cfSriastradh	const SymTabRec *chipset;
39803b705cfSriastradh	const char *stack[64], **unique;
39903b705cfSriastradh	int i, j, size, len;
40003b705cfSriastradh
40103b705cfSriastradh	unique = stack;
40203b705cfSriastradh	size = sizeof(stack)/sizeof(stack[0]);
40303b705cfSriastradh	i = 0;
40403b705cfSriastradh
40503b705cfSriastradh	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Integrated Graphics Chipsets:\n\t");
40603b705cfSriastradh	len = 8;
40703b705cfSriastradh
40842542f5fSchristos	for (chipset = intel_chipsets; chipset->token; chipset++) {
40903b705cfSriastradh		for (j = i; --j >= 0;)
41003b705cfSriastradh			if (strcmp(unique[j], chipset->name) == 0)
41103b705cfSriastradh				break;
41203b705cfSriastradh		if (j < 0) {
41303b705cfSriastradh			int name_len = strlen(chipset->name);
41403b705cfSriastradh			if (i != 0) {
41503b705cfSriastradh				xf86ErrorF(",");
41603b705cfSriastradh				len++;
41703b705cfSriastradh				if (len + 2 + name_len < 78) {
41803b705cfSriastradh					xf86ErrorF(" ");
41903b705cfSriastradh					len++;
42003b705cfSriastradh				} else {
42103b705cfSriastradh					xf86ErrorF("\n\t");
42203b705cfSriastradh					len = 8;
42303b705cfSriastradh				}
42403b705cfSriastradh			}
42503b705cfSriastradh			xf86ErrorF("%s", chipset->name);
42603b705cfSriastradh			len += name_len;
42703b705cfSriastradh
42803b705cfSriastradh			if (i == size) {
42903b705cfSriastradh				const char **new_unique;
43003b705cfSriastradh
43103b705cfSriastradh				if (unique == stack)
43203b705cfSriastradh					new_unique = malloc(2*sizeof(*unique)*size);
43303b705cfSriastradh				else
43403b705cfSriastradh					new_unique = realloc(unique, 2*sizeof(*unique)*size);
43503b705cfSriastradh				if (new_unique != NULL) {
43603b705cfSriastradh					if (unique == stack)
43703b705cfSriastradh						memcpy(new_unique, stack,
43803b705cfSriastradh						       sizeof(stack));
43903b705cfSriastradh					unique = new_unique;
44003b705cfSriastradh					size *= 2;
44103b705cfSriastradh				}
44203b705cfSriastradh			}
44303b705cfSriastradh			if (i < size)
44403b705cfSriastradh				unique[i++] = chipset->name;
44503b705cfSriastradh		}
44603b705cfSriastradh	}
44703b705cfSriastradh	xf86ErrorF("\n");
44803b705cfSriastradh	if (unique != stack)
44903b705cfSriastradh		free(unique);
45042542f5fSchristos
45142542f5fSchristos	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) HD Graphics: 2000-6000\n");
45242542f5fSchristos	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Graphics: 5100, 6100\n");
45342542f5fSchristos	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Pro Graphics: 5200, 6200, P6300\n");
45403b705cfSriastradh}
45503b705cfSriastradh
45603b705cfSriastradhstatic Bool intel_driver_func(ScrnInfoPtr pScrn,
45703b705cfSriastradh			      xorgDriverFuncOp op,
45803b705cfSriastradh			      pointer ptr)
45903b705cfSriastradh{
46003b705cfSriastradh	xorgHWFlags *flag;
46103b705cfSriastradh
46203b705cfSriastradh	switch (op) {
46303b705cfSriastradh	case GET_REQUIRED_HW_INTERFACES:
46403b705cfSriastradh		flag = (CARD32*)ptr;
46503b705cfSriastradh		(*flag) = 0;
46642542f5fSchristos#if UMS
46703b705cfSriastradh		(*flag) = HW_IO | HW_MMIO;
46803b705cfSriastradh#endif
46903b705cfSriastradh#ifdef HW_SKIP_CONSOLE
47003b705cfSriastradh		if (hosted())
47103b705cfSriastradh			(*flag) = HW_SKIP_CONSOLE;
47203b705cfSriastradh#endif
47303b705cfSriastradh
47403b705cfSriastradh		return TRUE;
47542542f5fSchristos
47642542f5fSchristos#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0)
47742542f5fSchristos	case SUPPORTS_SERVER_FDS:
47842542f5fSchristos		return TRUE;
47942542f5fSchristos#endif
48042542f5fSchristos
48103b705cfSriastradh	default:
48203b705cfSriastradh		/* Unknown or deprecated function */
48303b705cfSriastradh		return FALSE;
48403b705cfSriastradh	}
48503b705cfSriastradh}
48603b705cfSriastradh
48742542f5fSchristos#if KMS
48803b705cfSriastradhextern XF86ConfigPtr xf86configptr;
48903b705cfSriastradh
49003b705cfSriastradhstatic XF86ConfDevicePtr
49103b705cfSriastradh_xf86findDriver(const char *ident, XF86ConfDevicePtr p)
49203b705cfSriastradh{
49303b705cfSriastradh	while (p) {
49403b705cfSriastradh		if (p->dev_driver && xf86nameCompare(ident, p->dev_driver) == 0)
49503b705cfSriastradh			return p;
49603b705cfSriastradh
49703b705cfSriastradh		p = p->list.next;
49803b705cfSriastradh	}
49903b705cfSriastradh
50003b705cfSriastradh	return NULL;
50103b705cfSriastradh}
50203b705cfSriastradh
50313496ba1Ssnjstatic enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
50403b705cfSriastradh{
50503b705cfSriastradh	enum accel_method accel_method = DEFAULT_ACCEL_METHOD;
50603b705cfSriastradh	XF86ConfDevicePtr dev;
50703b705cfSriastradh
50803b705cfSriastradh	if (hosted())
50903b705cfSriastradh		return SNA;
51003b705cfSriastradh
51103b705cfSriastradh	dev = _xf86findDriver("intel", xf86configptr->conf_device_lst);
51203b705cfSriastradh	if (dev && dev->dev_option_lst) {
51303b705cfSriastradh		const char *s;
51403b705cfSriastradh
51503b705cfSriastradh		s = xf86FindOptionValue(dev->dev_option_lst, "AccelMethod");
51603b705cfSriastradh		if (s ) {
51742542f5fSchristos			if (strcasecmp(s, "none") == 0)
51842542f5fSchristos				accel_method = NOACCEL;
51942542f5fSchristos			else if (strcasecmp(s, "sna") == 0)
52003b705cfSriastradh				accel_method = SNA;
52103b705cfSriastradh			else if (strcasecmp(s, "uxa") == 0)
52203b705cfSriastradh				accel_method = UXA;
52303b705cfSriastradh		}
52403b705cfSriastradh	}
52503b705cfSriastradh
52603b705cfSriastradh	return accel_method;
52703b705cfSriastradh}
52803b705cfSriastradh#endif
52903b705cfSriastradh
53003b705cfSriastradhstatic Bool
53103b705cfSriastradhintel_scrn_create(DriverPtr		driver,
53203b705cfSriastradh		  int			entity_num,
53303b705cfSriastradh		  intptr_t		match_data,
53403b705cfSriastradh		  unsigned		flags)
53503b705cfSriastradh{
53603b705cfSriastradh	ScrnInfoPtr scrn;
53703b705cfSriastradh
53842542f5fSchristos	if (match_data == 0) {
53942542f5fSchristos		int devid = intel_entity_get_devid(entity_num), i;
54042542f5fSchristos		if (devid == 0)
54142542f5fSchristos			return FALSE;
54242542f5fSchristos
54342542f5fSchristos		for (i = 0; intel_device_match[i].device_id != 0; i++) {
54442542f5fSchristos			if (devid == intel_device_match[i].device_id) {
54542542f5fSchristos				match_data = (intptr_t)&intel_device_match[i];
54642542f5fSchristos				break;
54742542f5fSchristos			}
54842542f5fSchristos		}
54942542f5fSchristos
55042542f5fSchristos		if (match_data == 0)
55142542f5fSchristos			return FALSE;
55242542f5fSchristos	}
55342542f5fSchristos
55403b705cfSriastradh	scrn = xf86AllocateScreen(driver, flags);
55503b705cfSriastradh	if (scrn == NULL)
55603b705cfSriastradh		return FALSE;
55703b705cfSriastradh
55803b705cfSriastradh	scrn->driverVersion = INTEL_VERSION;
55903b705cfSriastradh	scrn->driverName = (char *)INTEL_DRIVER_NAME;
56003b705cfSriastradh	scrn->name = (char *)INTEL_NAME;
56142542f5fSchristos	scrn->driverPrivate = (void *)(match_data | (flags & XF86_ALLOCATE_GPU_SCREEN) | 2);
56203b705cfSriastradh	scrn->Probe = NULL;
56303b705cfSriastradh
56403b705cfSriastradh	if (xf86IsEntitySharable(entity_num))
56503b705cfSriastradh		xf86SetEntityShared(entity_num);
56603b705cfSriastradh	xf86AddEntityToScreen(scrn, entity_num);
56703b705cfSriastradh
56842542f5fSchristos#if UMS
56903b705cfSriastradh	if ((unsigned)((struct intel_device_info *)match_data)->gen < 020)
57003b705cfSriastradh		return lg_i810_init(scrn);
57103b705cfSriastradh#endif
57203b705cfSriastradh
57342542f5fSchristos#if KMS
57403b705cfSriastradh	switch (get_accel_method()) {
57503b705cfSriastradh#if USE_SNA
57642542f5fSchristos	case NOACCEL:
57742542f5fSchristos	case SNA:
57842542f5fSchristos		return sna_init_scrn(scrn, entity_num);
57903b705cfSriastradh#endif
58003b705cfSriastradh#if USE_UXA
58142542f5fSchristos#if !USE_SNA
58242542f5fSchristos	case NOACCEL:
58342542f5fSchristos#endif
58442542f5fSchristos	case UXA:
58542542f5fSchristos		  return intel_init_scrn(scrn);
58603b705cfSriastradh#endif
58703b705cfSriastradh
58803b705cfSriastradh	default: break;
58903b705cfSriastradh	}
59003b705cfSriastradh#endif
59103b705cfSriastradh
59203b705cfSriastradh	return FALSE;
59303b705cfSriastradh}
59403b705cfSriastradh
59503b705cfSriastradh/*
59603b705cfSriastradh * intel_pci_probe --
59703b705cfSriastradh *
59803b705cfSriastradh * Look through the PCI bus to find cards that are intel boards.
59903b705cfSriastradh * Setup the dispatch table for the rest of the driver functions.
60003b705cfSriastradh *
60103b705cfSriastradh */
60203b705cfSriastradhstatic Bool intel_pci_probe(DriverPtr		driver,
60303b705cfSriastradh			    int			entity_num,
60403b705cfSriastradh			    struct pci_device	*pci,
60503b705cfSriastradh			    intptr_t		match_data)
60603b705cfSriastradh{
60703b705cfSriastradh	if (intel_open_device(entity_num, pci, NULL) == -1) {
60842542f5fSchristos#if UMS
60903b705cfSriastradh		switch (pci->device_id) {
61003b705cfSriastradh		case PCI_CHIP_I810:
61103b705cfSriastradh		case PCI_CHIP_I810_DC100:
61203b705cfSriastradh		case PCI_CHIP_I810_E:
61303b705cfSriastradh		case PCI_CHIP_I815:
61403b705cfSriastradh			if (!hosted())
61503b705cfSriastradh				break;
61603b705cfSriastradh		default:
61703b705cfSriastradh			return FALSE;
61803b705cfSriastradh		}
61942542f5fSchristos#else
62042542f5fSchristos		return FALSE;
62103b705cfSriastradh#endif
62203b705cfSriastradh	}
62303b705cfSriastradh
62403b705cfSriastradh	return intel_scrn_create(driver, entity_num, match_data, 0);
62503b705cfSriastradh}
62603b705cfSriastradh
62703b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
62803b705cfSriastradhstatic Bool
62903b705cfSriastradhintel_platform_probe(DriverPtr driver,
63003b705cfSriastradh		     int entity_num, int flags,
63103b705cfSriastradh		     struct xf86_platform_device *dev,
63203b705cfSriastradh		     intptr_t match_data)
63303b705cfSriastradh{
63403b705cfSriastradh	unsigned scrn_flags = 0;
63503b705cfSriastradh
63642542f5fSchristos	if (intel_open_device(entity_num, dev->pdev, dev) == -1)
63703b705cfSriastradh		return FALSE;
63803b705cfSriastradh
63903b705cfSriastradh	/* Allow ourselves to act as a slaved output if not primary */
64003b705cfSriastradh	if (flags & PLATFORM_PROBE_GPU_SCREEN) {
64103b705cfSriastradh		flags &= ~PLATFORM_PROBE_GPU_SCREEN;
64203b705cfSriastradh		scrn_flags |= XF86_ALLOCATE_GPU_SCREEN;
64303b705cfSriastradh	}
64403b705cfSriastradh
64503b705cfSriastradh	/* if we get any flags we don't understand fail to probe for now */
64603b705cfSriastradh	if (flags)
64703b705cfSriastradh		return FALSE;
64803b705cfSriastradh
64903b705cfSriastradh	return intel_scrn_create(driver, entity_num, match_data, scrn_flags);
65003b705cfSriastradh}
65103b705cfSriastradh#endif
65203b705cfSriastradh
65303b705cfSriastradh#ifdef XFree86LOADER
65403b705cfSriastradh
65503b705cfSriastradhstatic MODULESETUPPROTO(intel_setup);
65603b705cfSriastradh
65703b705cfSriastradhstatic XF86ModuleVersionInfo intel_version = {
65803b705cfSriastradh	"intel",
65903b705cfSriastradh	MODULEVENDORSTRING,
66003b705cfSriastradh	MODINFOSTRING1,
66103b705cfSriastradh	MODINFOSTRING2,
66203b705cfSriastradh	XORG_VERSION_CURRENT,
66303b705cfSriastradh	INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
66403b705cfSriastradh	ABI_CLASS_VIDEODRV,
66503b705cfSriastradh	ABI_VIDEODRV_VERSION,
66603b705cfSriastradh	MOD_CLASS_VIDEODRV,
66703b705cfSriastradh	{0, 0, 0, 0}
66803b705cfSriastradh};
66903b705cfSriastradh
67003b705cfSriastradhstatic const OptionInfoRec *
67103b705cfSriastradhintel_available_options(int chipid, int busid)
67203b705cfSriastradh{
67303b705cfSriastradh	switch (chipid) {
67442542f5fSchristos#if UMS
67503b705cfSriastradh	case PCI_CHIP_I810:
67603b705cfSriastradh	case PCI_CHIP_I810_DC100:
67703b705cfSriastradh	case PCI_CHIP_I810_E:
67803b705cfSriastradh	case PCI_CHIP_I815:
67903b705cfSriastradh		return lg_i810_available_options(chipid, busid);
68003b705cfSriastradh#endif
68103b705cfSriastradh
68203b705cfSriastradh	default:
68303b705cfSriastradh		return intel_options;
68403b705cfSriastradh	}
68503b705cfSriastradh}
68603b705cfSriastradh
68703b705cfSriastradhstatic DriverRec intel = {
68803b705cfSriastradh	INTEL_VERSION,
68903b705cfSriastradh	(char *)INTEL_DRIVER_NAME,
69003b705cfSriastradh	intel_identify,
69103b705cfSriastradh	NULL,
69203b705cfSriastradh	intel_available_options,
69303b705cfSriastradh	NULL,
69403b705cfSriastradh	0,
69503b705cfSriastradh	intel_driver_func,
69603b705cfSriastradh	intel_device_match,
69703b705cfSriastradh	intel_pci_probe,
69803b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
69903b705cfSriastradh	intel_platform_probe
70003b705cfSriastradh#endif
70103b705cfSriastradh};
70203b705cfSriastradh
70303b705cfSriastradhstatic pointer intel_setup(pointer module,
70403b705cfSriastradh			   pointer opts,
70503b705cfSriastradh			   int *errmaj,
70603b705cfSriastradh			   int *errmin)
70703b705cfSriastradh{
70803b705cfSriastradh	static Bool setupDone = 0;
70903b705cfSriastradh
71003b705cfSriastradh	/* This module should be loaded only once, but check to be sure.
71103b705cfSriastradh	*/
71203b705cfSriastradh	if (!setupDone) {
71303b705cfSriastradh		setupDone = 1;
71403b705cfSriastradh		xf86AddDriver(&intel, module, HaveDriverFuncs);
71503b705cfSriastradh
71603b705cfSriastradh		/*
71703b705cfSriastradh		 * The return value must be non-NULL on success even though there
71803b705cfSriastradh		 * is no TearDownProc.
71903b705cfSriastradh		 */
72003b705cfSriastradh		return (pointer) 1;
72103b705cfSriastradh	} else {
72203b705cfSriastradh		if (errmaj)
72303b705cfSriastradh			*errmaj = LDR_ONCEONLY;
72403b705cfSriastradh		return NULL;
72503b705cfSriastradh	}
72603b705cfSriastradh}
72703b705cfSriastradh
72803b705cfSriastradh_X_EXPORT XF86ModuleData intelModuleData = { &intel_version, intel_setup, NULL };
72903b705cfSriastradh#endif
730