intel_module.c revision 03b705cf
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
3103b705cfSriastradh#include <xf86.h>
3203b705cfSriastradh#include <xf86Parser.h>
3303b705cfSriastradh#include <xorgVersion.h>
3403b705cfSriastradh
3503b705cfSriastradh#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,99,0,0)
3603b705cfSriastradh#include <xf86Resources.h>
3703b705cfSriastradh#endif
3803b705cfSriastradh
3903b705cfSriastradh#include "intel_driver.h"
4003b705cfSriastradh#include "intel_options.h"
4103b705cfSriastradh#include "legacy/legacy.h"
4203b705cfSriastradh#include "sna/sna_module.h"
4303b705cfSriastradh#include "uxa/uxa_module.h"
4403b705cfSriastradh
4503b705cfSriastradh#include "i915_pciids.h" /* copied from (kernel) include/drm/i915_pciids.h */
4603b705cfSriastradh
4703b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
4803b705cfSriastradh#include <xf86platformBus.h>
4903b705cfSriastradh#endif
5003b705cfSriastradh
5103b705cfSriastradhstatic const struct intel_device_info intel_generic_info = {
5203b705cfSriastradh	.gen = -1,
5303b705cfSriastradh};
5403b705cfSriastradh
5503b705cfSriastradhstatic const struct intel_device_info intel_i81x_info = {
5603b705cfSriastradh	.gen = 010,
5703b705cfSriastradh};
5803b705cfSriastradh
5903b705cfSriastradhstatic const struct intel_device_info intel_i830_info = {
6003b705cfSriastradh	.gen = 020,
6103b705cfSriastradh};
6203b705cfSriastradhstatic const struct intel_device_info intel_i845_info = {
6303b705cfSriastradh	.gen = 020,
6403b705cfSriastradh};
6503b705cfSriastradhstatic const struct intel_device_info intel_i855_info = {
6603b705cfSriastradh	.gen = 021,
6703b705cfSriastradh};
6803b705cfSriastradhstatic const struct intel_device_info intel_i865_info = {
6903b705cfSriastradh	.gen = 022,
7003b705cfSriastradh};
7103b705cfSriastradh
7203b705cfSriastradhstatic const struct intel_device_info intel_i915_info = {
7303b705cfSriastradh	.gen = 030,
7403b705cfSriastradh};
7503b705cfSriastradhstatic const struct intel_device_info intel_i945_info = {
7603b705cfSriastradh	.gen = 031,
7703b705cfSriastradh};
7803b705cfSriastradh
7903b705cfSriastradhstatic const struct intel_device_info intel_g33_info = {
8003b705cfSriastradh	.gen = 033,
8103b705cfSriastradh};
8203b705cfSriastradh
8303b705cfSriastradhstatic const struct intel_device_info intel_i965_info = {
8403b705cfSriastradh	.gen = 040,
8503b705cfSriastradh};
8603b705cfSriastradh
8703b705cfSriastradhstatic const struct intel_device_info intel_g4x_info = {
8803b705cfSriastradh	.gen = 045,
8903b705cfSriastradh};
9003b705cfSriastradh
9103b705cfSriastradhstatic const struct intel_device_info intel_ironlake_info = {
9203b705cfSriastradh	.gen = 050,
9303b705cfSriastradh};
9403b705cfSriastradh
9503b705cfSriastradhstatic const struct intel_device_info intel_sandybridge_info = {
9603b705cfSriastradh	.gen = 060,
9703b705cfSriastradh};
9803b705cfSriastradh
9903b705cfSriastradhstatic const struct intel_device_info intel_ivybridge_info = {
10003b705cfSriastradh	.gen = 070,
10103b705cfSriastradh};
10203b705cfSriastradh
10303b705cfSriastradhstatic const struct intel_device_info intel_valleyview_info = {
10403b705cfSriastradh	.gen = 071,
10503b705cfSriastradh};
10603b705cfSriastradh
10703b705cfSriastradhstatic const struct intel_device_info intel_haswell_info = {
10803b705cfSriastradh	.gen = 075,
10903b705cfSriastradh};
11003b705cfSriastradh
11103b705cfSriastradhstatic const SymTabRec intel_chipsets[] = {
11203b705cfSriastradh	{PCI_CHIP_I810,				"i810"},
11303b705cfSriastradh	{PCI_CHIP_I810_DC100,			"i810-dc100"},
11403b705cfSriastradh	{PCI_CHIP_I810_E,			"i810e"},
11503b705cfSriastradh	{PCI_CHIP_I815,				"i815"},
11603b705cfSriastradh	{PCI_CHIP_I830_M,			"i830M"},
11703b705cfSriastradh	{PCI_CHIP_845_G,			"845G"},
11803b705cfSriastradh	{PCI_CHIP_I854,				"854"},
11903b705cfSriastradh	{PCI_CHIP_I855_GM,			"852GM/855GM"},
12003b705cfSriastradh	{PCI_CHIP_I865_G,			"865G"},
12103b705cfSriastradh	{PCI_CHIP_I915_G,			"915G"},
12203b705cfSriastradh	{PCI_CHIP_E7221_G,			"E7221 (i915)"},
12303b705cfSriastradh	{PCI_CHIP_I915_GM,			"915GM"},
12403b705cfSriastradh	{PCI_CHIP_I945_G,			"945G"},
12503b705cfSriastradh	{PCI_CHIP_I945_GM,			"945GM"},
12603b705cfSriastradh	{PCI_CHIP_I945_GME,			"945GME"},
12703b705cfSriastradh	{PCI_CHIP_PINEVIEW_M,			"Pineview GM"},
12803b705cfSriastradh	{PCI_CHIP_PINEVIEW_G,			"Pineview G"},
12903b705cfSriastradh	{PCI_CHIP_I965_G,			"965G"},
13003b705cfSriastradh	{PCI_CHIP_G35_G,			"G35"},
13103b705cfSriastradh	{PCI_CHIP_I965_Q,			"965Q"},
13203b705cfSriastradh	{PCI_CHIP_I946_GZ,			"946GZ"},
13303b705cfSriastradh	{PCI_CHIP_I965_GM,			"965GM"},
13403b705cfSriastradh	{PCI_CHIP_I965_GME,			"965GME/GLE"},
13503b705cfSriastradh	{PCI_CHIP_G33_G,			"G33"},
13603b705cfSriastradh	{PCI_CHIP_Q35_G,			"Q35"},
13703b705cfSriastradh	{PCI_CHIP_Q33_G,			"Q33"},
13803b705cfSriastradh	{PCI_CHIP_GM45_GM,			"GM45"},
13903b705cfSriastradh	{PCI_CHIP_G45_E_G,			"4 Series"},
14003b705cfSriastradh	{PCI_CHIP_G45_G,			"G45/G43"},
14103b705cfSriastradh	{PCI_CHIP_Q45_G,			"Q45/Q43"},
14203b705cfSriastradh	{PCI_CHIP_G41_G,			"G41"},
14303b705cfSriastradh	{PCI_CHIP_B43_G,			"B43"},
14403b705cfSriastradh	{PCI_CHIP_B43_G1,			"B43"},
14503b705cfSriastradh	{PCI_CHIP_IRONLAKE_D_G,			"HD Graphics"},
14603b705cfSriastradh	{PCI_CHIP_IRONLAKE_M_G,			"HD Graphics"},
14703b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT1,		"HD Graphics 2000" },
14803b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT2,		"HD Graphics 3000" },
14903b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_GT2_PLUS,		"HD Graphics 3000" },
15003b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT1,		"HD Graphics 2000" },
15103b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT2,		"HD Graphics 3000" },
15203b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS,	"HD Graphics 3000" },
15303b705cfSriastradh	{PCI_CHIP_SANDYBRIDGE_S_GT,		"HD Graphics" },
15403b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_M_GT1,		"HD Graphics 2500" },
15503b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_M_GT2,		"HD Graphics 4000" },
15603b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_D_GT1,		"HD Graphics 2500" },
15703b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_D_GT2,		"HD Graphics 4000" },
15803b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_S_GT1,		"HD Graphics" },
15903b705cfSriastradh	{PCI_CHIP_IVYBRIDGE_S_GT2,		"HD Graphics P4000" },
16003b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT1,		"HD Graphics" },
16103b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT2,		"HD Graphics 4600" },
16203b705cfSriastradh	{PCI_CHIP_HASWELL_D_GT3,		"HD Graphics 5000" }, /* ??? */
16303b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT1,		"HD Graphics" },
16403b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT2,		"HD Graphics 4600" },
16503b705cfSriastradh	{PCI_CHIP_HASWELL_M_GT3,		"HD Graphics 5000" }, /* ??? */
16603b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT1,		"HD Graphics" },
16703b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT2,		"HD Graphics P4600/P4700" },
16803b705cfSriastradh	{PCI_CHIP_HASWELL_S_GT3,		"HD Graphics 5000" }, /* ??? */
16903b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT1,		"HD Graphics" }, /* ??? */
17003b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT2,		"HD Graphics" }, /* ??? */
17103b705cfSriastradh	{PCI_CHIP_HASWELL_B_GT3,		"HD Graphics" }, /* ??? */
17203b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT1,		"HD Graphics" },
17303b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT2,		"HD Graphics" }, /* ??? */
17403b705cfSriastradh	{PCI_CHIP_HASWELL_E_GT3,		"HD Graphics" }, /* ??? */
17503b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT1,		"HD Graphics" }, /* ??? */
17603b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT2,		"HD Graphics" }, /* ??? */
17703b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_D_GT3,		"Iris(TM) Graphics 5100" },
17803b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT1,		"HD Graphics" },
17903b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT2,		"HD Graphics 4400" },
18003b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_M_GT3,		"HD Graphics 5000" },
18103b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT1,		"HD Graphics" }, /* ??? */
18203b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT2,		"HD Graphics" }, /* ??? */
18303b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_S_GT3,		"Iris(TM) Graphics 5100" },
18403b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT1,		"HD Graphics" }, /* ??? */
18503b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT2,		"HD Graphics" }, /* ??? */
18603b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_B_GT3,		"Iris(TM) Graphics 5100" },
18703b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT1,		"HD Graphics" },
18803b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT2,		"HD Graphics 4200" },
18903b705cfSriastradh	{PCI_CHIP_HASWELL_ULT_E_GT3,		"Iris(TM) Graphics 5100" },
19003b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT1,		"HD Graphics" }, /* ??? */
19103b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT2,		"HD Graphics 4600" },
19203b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_D_GT3,		"Iris(TM) Pro Graphics 5200" },
19303b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT1,		"HD Graphics" }, /* ??? */
19403b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT2,		"HD Graphics 4600" },
19503b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_M_GT3,		"Iris(TM) Pro Graphics 5200" },
19603b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT1,		"HD Graphics" }, /* ??? */
19703b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT2,		"HD Graphics" }, /* ??? */
19803b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_S_GT3,		"Iris(TM) Pro Graphics 5200" },
19903b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT1,		"HD Graphics" }, /* ??? */
20003b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT2,		"HD Graphics" }, /* ??? */
20103b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_B_GT3,		"Iris(TM) Pro Graphics 5200" },
20203b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT1,		"HD Graphics" }, /* ??? */
20303b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT2,		"HD Graphics" }, /* ??? */
20403b705cfSriastradh	{PCI_CHIP_HASWELL_CRW_E_GT3,		"Iris(TM) Pro Graphics 5200" },
20503b705cfSriastradh	{-1,					NULL}
20603b705cfSriastradh};
20703b705cfSriastradh#define NUM_CHIPSETS (sizeof(intel_chipsets) / sizeof(intel_chipsets[0]))
20803b705cfSriastradh
20903b705cfSriastradhstatic const struct pci_id_match intel_device_match[] = {
21003b705cfSriastradh#if !KMS_ONLY
21103b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810, &intel_i81x_info),
21203b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810_DC100, &intel_i81x_info),
21303b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I810_E, &intel_i81x_info),
21403b705cfSriastradh	INTEL_VGA_DEVICE(PCI_CHIP_I815, &intel_i81x_info),
21503b705cfSriastradh#endif
21603b705cfSriastradh
21703b705cfSriastradh#if !UMS_ONLY
21803b705cfSriastradh	INTEL_I830_IDS(&intel_i830_info),
21903b705cfSriastradh	INTEL_I845G_IDS(&intel_i830_info),
22003b705cfSriastradh	INTEL_I85X_IDS(&intel_i855_info),
22103b705cfSriastradh	INTEL_I865G_IDS(&intel_i865_info),
22203b705cfSriastradh
22303b705cfSriastradh	INTEL_I915G_IDS(&intel_i915_info),
22403b705cfSriastradh	INTEL_I915GM_IDS(&intel_i915_info),
22503b705cfSriastradh	INTEL_I945G_IDS(&intel_i945_info),
22603b705cfSriastradh	INTEL_I945GM_IDS(&intel_i945_info),
22703b705cfSriastradh
22803b705cfSriastradh	INTEL_G33_IDS(&intel_g33_info),
22903b705cfSriastradh	INTEL_PINEVIEW_IDS(&intel_g33_info),
23003b705cfSriastradh
23103b705cfSriastradh	INTEL_I965G_IDS(&intel_i965_info),
23203b705cfSriastradh	INTEL_I965GM_IDS(&intel_i965_info),
23303b705cfSriastradh
23403b705cfSriastradh	INTEL_G45_IDS(&intel_g4x_info),
23503b705cfSriastradh	INTEL_GM45_IDS(&intel_g4x_info),
23603b705cfSriastradh
23703b705cfSriastradh	INTEL_IRONLAKE_D_IDS(&intel_ironlake_info),
23803b705cfSriastradh	INTEL_IRONLAKE_M_IDS(&intel_ironlake_info),
23903b705cfSriastradh
24003b705cfSriastradh	INTEL_SNB_D_IDS(&intel_sandybridge_info),
24103b705cfSriastradh	INTEL_SNB_M_IDS(&intel_sandybridge_info),
24203b705cfSriastradh
24303b705cfSriastradh	INTEL_IVB_D_IDS(&intel_ivybridge_info),
24403b705cfSriastradh	INTEL_IVB_M_IDS(&intel_ivybridge_info),
24503b705cfSriastradh
24603b705cfSriastradh	INTEL_HSW_D_IDS(&intel_haswell_info),
24703b705cfSriastradh	INTEL_HSW_M_IDS(&intel_haswell_info),
24803b705cfSriastradh
24903b705cfSriastradh	INTEL_VLV_D_IDS(&intel_valleyview_info),
25003b705cfSriastradh	INTEL_VLV_M_IDS(&intel_valleyview_info),
25103b705cfSriastradh
25203b705cfSriastradh	INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info),
25303b705cfSriastradh#endif
25403b705cfSriastradh
25503b705cfSriastradh	{ 0, 0, 0 },
25603b705cfSriastradh};
25703b705cfSriastradh
25803b705cfSriastradhvoid
25903b705cfSriastradhintel_detect_chipset(ScrnInfoPtr scrn,
26003b705cfSriastradh		     EntityInfoPtr ent,
26103b705cfSriastradh		     struct pci_device *pci)
26203b705cfSriastradh{
26303b705cfSriastradh	MessageType from = X_PROBED;
26403b705cfSriastradh	const char *name = NULL;
26503b705cfSriastradh	int i;
26603b705cfSriastradh
26703b705cfSriastradh	if (ent->device->chipID >= 0) {
26803b705cfSriastradh		xf86DrvMsg(scrn->scrnIndex, from = X_CONFIG,
26903b705cfSriastradh			   "ChipID override: 0x%04X\n",
27003b705cfSriastradh			   ent->device->chipID);
27103b705cfSriastradh		pci->device_id = ent->device->chipID;
27203b705cfSriastradh	}
27303b705cfSriastradh
27403b705cfSriastradh	for (i = 0; intel_chipsets[i].name != NULL; i++) {
27503b705cfSriastradh		if (pci->device_id == intel_chipsets[i].token) {
27603b705cfSriastradh			name = intel_chipsets[i].name;
27703b705cfSriastradh			break;
27803b705cfSriastradh		}
27903b705cfSriastradh	}
28003b705cfSriastradh	if (name == NULL) {
28103b705cfSriastradh		int gen = 0;
28203b705cfSriastradh
28303b705cfSriastradh		for (i = 0; intel_device_match[i].device_id != 0; i++) {
28403b705cfSriastradh			if (pci->device_id == intel_device_match[i].device_id) {
28503b705cfSriastradh				const struct intel_device_info *info = (void *)intel_device_match[i].match_data;
28603b705cfSriastradh				gen = info->gen >> 3;
28703b705cfSriastradh				break;
28803b705cfSriastradh			}
28903b705cfSriastradh		}
29003b705cfSriastradh
29103b705cfSriastradh		if(gen) {
29203b705cfSriastradh			xf86DrvMsg(scrn->scrnIndex, from,
29303b705cfSriastradh				   "gen%d engineering sample\n", gen);
29403b705cfSriastradh		} else {
29503b705cfSriastradh			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
29603b705cfSriastradh				   "Unknown chipset\n");
29703b705cfSriastradh		}
29803b705cfSriastradh		name = "unknown";
29903b705cfSriastradh	} else {
30003b705cfSriastradh		xf86DrvMsg(scrn->scrnIndex, from,
30103b705cfSriastradh			   "Integrated Graphics Chipset: Intel(R) %s\n",
30203b705cfSriastradh			   name);
30303b705cfSriastradh	}
30403b705cfSriastradh
30503b705cfSriastradh	scrn->chipset = (char *)name;
30603b705cfSriastradh}
30703b705cfSriastradh
30803b705cfSriastradh/*
30903b705cfSriastradh * intel_identify --
31003b705cfSriastradh *
31103b705cfSriastradh * Returns the string name for the driver based on the chipset.
31203b705cfSriastradh *
31303b705cfSriastradh */
31403b705cfSriastradhstatic void intel_identify(int flags)
31503b705cfSriastradh{
31603b705cfSriastradh	const SymTabRec *chipset;
31703b705cfSriastradh	const char *stack[64], **unique;
31803b705cfSriastradh	int i, j, size, len;
31903b705cfSriastradh
32003b705cfSriastradh	unique = stack;
32103b705cfSriastradh	size = sizeof(stack)/sizeof(stack[0]);
32203b705cfSriastradh	i = 0;
32303b705cfSriastradh
32403b705cfSriastradh	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Integrated Graphics Chipsets:\n\t");
32503b705cfSriastradh	len = 8;
32603b705cfSriastradh
32703b705cfSriastradh	for (chipset = intel_chipsets; chipset->name; chipset++) {
32803b705cfSriastradh		for (j = i; --j >= 0;)
32903b705cfSriastradh			if (strcmp(unique[j], chipset->name) == 0)
33003b705cfSriastradh				break;
33103b705cfSriastradh		if (j < 0) {
33203b705cfSriastradh			int name_len = strlen(chipset->name);
33303b705cfSriastradh			if (i != 0) {
33403b705cfSriastradh				xf86ErrorF(",");
33503b705cfSriastradh				len++;
33603b705cfSriastradh				if (len + 2 + name_len < 78) {
33703b705cfSriastradh					xf86ErrorF(" ");
33803b705cfSriastradh					len++;
33903b705cfSriastradh				} else {
34003b705cfSriastradh					xf86ErrorF("\n\t");
34103b705cfSriastradh					len = 8;
34203b705cfSriastradh				}
34303b705cfSriastradh			}
34403b705cfSriastradh			xf86ErrorF("%s", chipset->name);
34503b705cfSriastradh			len += name_len;
34603b705cfSriastradh
34703b705cfSriastradh			if (i == size) {
34803b705cfSriastradh				const char **new_unique;
34903b705cfSriastradh
35003b705cfSriastradh				if (unique == stack)
35103b705cfSriastradh					new_unique = malloc(2*sizeof(*unique)*size);
35203b705cfSriastradh				else
35303b705cfSriastradh					new_unique = realloc(unique, 2*sizeof(*unique)*size);
35403b705cfSriastradh				if (new_unique != NULL) {
35503b705cfSriastradh					if (unique == stack)
35603b705cfSriastradh						memcpy(new_unique, stack,
35703b705cfSriastradh						       sizeof(stack));
35803b705cfSriastradh					unique = new_unique;
35903b705cfSriastradh					size *= 2;
36003b705cfSriastradh				}
36103b705cfSriastradh			}
36203b705cfSriastradh			if (i < size)
36303b705cfSriastradh				unique[i++] = chipset->name;
36403b705cfSriastradh		}
36503b705cfSriastradh	}
36603b705cfSriastradh	xf86ErrorF("\n");
36703b705cfSriastradh	if (unique != stack)
36803b705cfSriastradh		free(unique);
36903b705cfSriastradh}
37003b705cfSriastradh
37103b705cfSriastradhstatic Bool intel_driver_func(ScrnInfoPtr pScrn,
37203b705cfSriastradh			      xorgDriverFuncOp op,
37303b705cfSriastradh			      pointer ptr)
37403b705cfSriastradh{
37503b705cfSriastradh	xorgHWFlags *flag;
37603b705cfSriastradh
37703b705cfSriastradh	switch (op) {
37803b705cfSriastradh	case GET_REQUIRED_HW_INTERFACES:
37903b705cfSriastradh		flag = (CARD32*)ptr;
38003b705cfSriastradh#ifdef KMS_ONLY
38103b705cfSriastradh		(*flag) = 0;
38203b705cfSriastradh#else
38303b705cfSriastradh		(*flag) = HW_IO | HW_MMIO;
38403b705cfSriastradh#endif
38503b705cfSriastradh#ifdef HW_SKIP_CONSOLE
38603b705cfSriastradh		if (hosted())
38703b705cfSriastradh			(*flag) = HW_SKIP_CONSOLE;
38803b705cfSriastradh#endif
38903b705cfSriastradh
39003b705cfSriastradh		return TRUE;
39103b705cfSriastradh	default:
39203b705cfSriastradh		/* Unknown or deprecated function */
39303b705cfSriastradh		return FALSE;
39403b705cfSriastradh	}
39503b705cfSriastradh}
39603b705cfSriastradh
39703b705cfSriastradh#if !UMS_ONLY
39803b705cfSriastradhextern XF86ConfigPtr xf86configptr;
39903b705cfSriastradh
40003b705cfSriastradhstatic XF86ConfDevicePtr
40103b705cfSriastradh_xf86findDriver(const char *ident, XF86ConfDevicePtr p)
40203b705cfSriastradh{
40303b705cfSriastradh	while (p) {
40403b705cfSriastradh		if (p->dev_driver && xf86nameCompare(ident, p->dev_driver) == 0)
40503b705cfSriastradh			return p;
40603b705cfSriastradh
40703b705cfSriastradh		p = p->list.next;
40803b705cfSriastradh	}
40903b705cfSriastradh
41003b705cfSriastradh	return NULL;
41103b705cfSriastradh}
41203b705cfSriastradh
41303b705cfSriastradhstatic enum accel_method { UXA, SNA } get_accel_method(void)
41403b705cfSriastradh{
41503b705cfSriastradh	enum accel_method accel_method = DEFAULT_ACCEL_METHOD;
41603b705cfSriastradh	XF86ConfDevicePtr dev;
41703b705cfSriastradh
41803b705cfSriastradh	if (hosted())
41903b705cfSriastradh		return SNA;
42003b705cfSriastradh
42103b705cfSriastradh	dev = _xf86findDriver("intel", xf86configptr->conf_device_lst);
42203b705cfSriastradh	if (dev && dev->dev_option_lst) {
42303b705cfSriastradh		const char *s;
42403b705cfSriastradh
42503b705cfSriastradh		s = xf86FindOptionValue(dev->dev_option_lst, "AccelMethod");
42603b705cfSriastradh		if (s ) {
42703b705cfSriastradh			if (strcasecmp(s, "sna") == 0)
42803b705cfSriastradh				accel_method = SNA;
42903b705cfSriastradh			else if (strcasecmp(s, "uxa") == 0)
43003b705cfSriastradh				accel_method = UXA;
43103b705cfSriastradh			else if (strcasecmp(s, "glamor") == 0)
43203b705cfSriastradh				accel_method = UXA;
43303b705cfSriastradh		}
43403b705cfSriastradh	}
43503b705cfSriastradh
43603b705cfSriastradh	return accel_method;
43703b705cfSriastradh}
43803b705cfSriastradh#endif
43903b705cfSriastradh
44003b705cfSriastradhstatic Bool
44103b705cfSriastradhintel_scrn_create(DriverPtr		driver,
44203b705cfSriastradh		  int			entity_num,
44303b705cfSriastradh		  intptr_t		match_data,
44403b705cfSriastradh		  unsigned		flags)
44503b705cfSriastradh{
44603b705cfSriastradh	ScrnInfoPtr scrn;
44703b705cfSriastradh
44803b705cfSriastradh	scrn = xf86AllocateScreen(driver, flags);
44903b705cfSriastradh	if (scrn == NULL)
45003b705cfSriastradh		return FALSE;
45103b705cfSriastradh
45203b705cfSriastradh	scrn->driverVersion = INTEL_VERSION;
45303b705cfSriastradh	scrn->driverName = (char *)INTEL_DRIVER_NAME;
45403b705cfSriastradh	scrn->name = (char *)INTEL_NAME;
45503b705cfSriastradh	scrn->driverPrivate = (void *)(match_data | 1);
45603b705cfSriastradh	scrn->Probe = NULL;
45703b705cfSriastradh
45803b705cfSriastradh	if (xf86IsEntitySharable(entity_num))
45903b705cfSriastradh		xf86SetEntityShared(entity_num);
46003b705cfSriastradh	xf86AddEntityToScreen(scrn, entity_num);
46103b705cfSriastradh
46203b705cfSriastradh#if !KMS_ONLY
46303b705cfSriastradh	if ((unsigned)((struct intel_device_info *)match_data)->gen < 020)
46403b705cfSriastradh		return lg_i810_init(scrn);
46503b705cfSriastradh#endif
46603b705cfSriastradh
46703b705cfSriastradh#if !UMS_ONLY
46803b705cfSriastradh	switch (get_accel_method()) {
46903b705cfSriastradh#if USE_SNA
47003b705cfSriastradh	case SNA: return sna_init_scrn(scrn, entity_num);
47103b705cfSriastradh#endif
47203b705cfSriastradh#if USE_UXA
47303b705cfSriastradh	case UXA: return intel_init_scrn(scrn);
47403b705cfSriastradh#endif
47503b705cfSriastradh
47603b705cfSriastradh	default: break;
47703b705cfSriastradh	}
47803b705cfSriastradh#endif
47903b705cfSriastradh
48003b705cfSriastradh	return FALSE;
48103b705cfSriastradh}
48203b705cfSriastradh
48303b705cfSriastradh/*
48403b705cfSriastradh * intel_pci_probe --
48503b705cfSriastradh *
48603b705cfSriastradh * Look through the PCI bus to find cards that are intel boards.
48703b705cfSriastradh * Setup the dispatch table for the rest of the driver functions.
48803b705cfSriastradh *
48903b705cfSriastradh */
49003b705cfSriastradhstatic Bool intel_pci_probe(DriverPtr		driver,
49103b705cfSriastradh			    int			entity_num,
49203b705cfSriastradh			    struct pci_device	*pci,
49303b705cfSriastradh			    intptr_t		match_data)
49403b705cfSriastradh{
49503b705cfSriastradh	if (intel_open_device(entity_num, pci, NULL) == -1) {
49603b705cfSriastradh#if KMS_ONLY
49703b705cfSriastradh		return FALSE;
49803b705cfSriastradh#else
49903b705cfSriastradh		switch (pci->device_id) {
50003b705cfSriastradh		case PCI_CHIP_I810:
50103b705cfSriastradh		case PCI_CHIP_I810_DC100:
50203b705cfSriastradh		case PCI_CHIP_I810_E:
50303b705cfSriastradh		case PCI_CHIP_I815:
50403b705cfSriastradh			if (!hosted())
50503b705cfSriastradh				break;
50603b705cfSriastradh		default:
50703b705cfSriastradh			return FALSE;
50803b705cfSriastradh		}
50903b705cfSriastradh#endif
51003b705cfSriastradh	}
51103b705cfSriastradh
51203b705cfSriastradh	return intel_scrn_create(driver, entity_num, match_data, 0);
51303b705cfSriastradh}
51403b705cfSriastradh
51503b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
51603b705cfSriastradhstatic Bool
51703b705cfSriastradhintel_platform_probe(DriverPtr driver,
51803b705cfSriastradh		     int entity_num, int flags,
51903b705cfSriastradh		     struct xf86_platform_device *dev,
52003b705cfSriastradh		     intptr_t match_data)
52103b705cfSriastradh{
52203b705cfSriastradh	unsigned scrn_flags = 0;
52303b705cfSriastradh
52403b705cfSriastradh	if (!dev->pdev)
52503b705cfSriastradh		return FALSE;
52603b705cfSriastradh
52703b705cfSriastradh	if (intel_open_device(entity_num, dev->pdev,
52803b705cfSriastradh			      xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH)) == -1)
52903b705cfSriastradh		return FALSE;
53003b705cfSriastradh
53103b705cfSriastradh	/* Allow ourselves to act as a slaved output if not primary */
53203b705cfSriastradh	if (flags & PLATFORM_PROBE_GPU_SCREEN) {
53303b705cfSriastradh		flags &= ~PLATFORM_PROBE_GPU_SCREEN;
53403b705cfSriastradh		scrn_flags |= XF86_ALLOCATE_GPU_SCREEN;
53503b705cfSriastradh	}
53603b705cfSriastradh
53703b705cfSriastradh	/* if we get any flags we don't understand fail to probe for now */
53803b705cfSriastradh	if (flags)
53903b705cfSriastradh		return FALSE;
54003b705cfSriastradh
54103b705cfSriastradh	return intel_scrn_create(driver, entity_num, match_data, scrn_flags);
54203b705cfSriastradh}
54303b705cfSriastradh#endif
54403b705cfSriastradh
54503b705cfSriastradh#ifdef XFree86LOADER
54603b705cfSriastradh
54703b705cfSriastradhstatic MODULESETUPPROTO(intel_setup);
54803b705cfSriastradh
54903b705cfSriastradhstatic XF86ModuleVersionInfo intel_version = {
55003b705cfSriastradh	"intel",
55103b705cfSriastradh	MODULEVENDORSTRING,
55203b705cfSriastradh	MODINFOSTRING1,
55303b705cfSriastradh	MODINFOSTRING2,
55403b705cfSriastradh	XORG_VERSION_CURRENT,
55503b705cfSriastradh	INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
55603b705cfSriastradh	ABI_CLASS_VIDEODRV,
55703b705cfSriastradh	ABI_VIDEODRV_VERSION,
55803b705cfSriastradh	MOD_CLASS_VIDEODRV,
55903b705cfSriastradh	{0, 0, 0, 0}
56003b705cfSriastradh};
56103b705cfSriastradh
56203b705cfSriastradhstatic const OptionInfoRec *
56303b705cfSriastradhintel_available_options(int chipid, int busid)
56403b705cfSriastradh{
56503b705cfSriastradh	switch (chipid) {
56603b705cfSriastradh#if !KMS_ONLY
56703b705cfSriastradh	case PCI_CHIP_I810:
56803b705cfSriastradh	case PCI_CHIP_I810_DC100:
56903b705cfSriastradh	case PCI_CHIP_I810_E:
57003b705cfSriastradh	case PCI_CHIP_I815:
57103b705cfSriastradh		return lg_i810_available_options(chipid, busid);
57203b705cfSriastradh#endif
57303b705cfSriastradh
57403b705cfSriastradh	default:
57503b705cfSriastradh		return intel_options;
57603b705cfSriastradh	}
57703b705cfSriastradh}
57803b705cfSriastradh
57903b705cfSriastradhstatic DriverRec intel = {
58003b705cfSriastradh	INTEL_VERSION,
58103b705cfSriastradh	(char *)INTEL_DRIVER_NAME,
58203b705cfSriastradh	intel_identify,
58303b705cfSriastradh	NULL,
58403b705cfSriastradh	intel_available_options,
58503b705cfSriastradh	NULL,
58603b705cfSriastradh	0,
58703b705cfSriastradh	intel_driver_func,
58803b705cfSriastradh	intel_device_match,
58903b705cfSriastradh	intel_pci_probe,
59003b705cfSriastradh#ifdef XSERVER_PLATFORM_BUS
59103b705cfSriastradh	intel_platform_probe
59203b705cfSriastradh#endif
59303b705cfSriastradh};
59403b705cfSriastradh
59503b705cfSriastradhstatic pointer intel_setup(pointer module,
59603b705cfSriastradh			   pointer opts,
59703b705cfSriastradh			   int *errmaj,
59803b705cfSriastradh			   int *errmin)
59903b705cfSriastradh{
60003b705cfSriastradh	static Bool setupDone = 0;
60103b705cfSriastradh
60203b705cfSriastradh	/* This module should be loaded only once, but check to be sure.
60303b705cfSriastradh	*/
60403b705cfSriastradh	if (!setupDone) {
60503b705cfSriastradh		setupDone = 1;
60603b705cfSriastradh		xf86AddDriver(&intel, module, HaveDriverFuncs);
60703b705cfSriastradh
60803b705cfSriastradh		/*
60903b705cfSriastradh		 * The return value must be non-NULL on success even though there
61003b705cfSriastradh		 * is no TearDownProc.
61103b705cfSriastradh		 */
61203b705cfSriastradh		return (pointer) 1;
61303b705cfSriastradh	} else {
61403b705cfSriastradh		if (errmaj)
61503b705cfSriastradh			*errmaj = LDR_ONCEONLY;
61603b705cfSriastradh		return NULL;
61703b705cfSriastradh	}
61803b705cfSriastradh}
61903b705cfSriastradh
62003b705cfSriastradh_X_EXPORT XF86ModuleData intelModuleData = { &intel_version, intel_setup, NULL };
62103b705cfSriastradh#endif
622