1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3428d7b3dSmrg * All Rights Reserved.
4428d7b3dSmrg * Copyright © 2010 Intel Corporation
5428d7b3dSmrg *
6428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
7428d7b3dSmrg * copy of this software and associated documentation files (the "Software"),
8428d7b3dSmrg * to deal in the Software without restriction, including without limitation
9428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the
11428d7b3dSmrg * Software is furnished to do so, subject to the following conditions:
12428d7b3dSmrg *
13428d7b3dSmrg * The above copyright notice and this permission notice (including the next
14428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the
15428d7b3dSmrg * Software.
16428d7b3dSmrg *
17428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23428d7b3dSmrg * SOFTWARE.
24428d7b3dSmrg *
25428d7b3dSmrg */
26428d7b3dSmrg
27428d7b3dSmrg#ifdef HAVE_CONFIG_H
28428d7b3dSmrg#include "config.h"
29428d7b3dSmrg#endif
30428d7b3dSmrg
31428d7b3dSmrg#include <xorg-server.h>
32428d7b3dSmrg#include <xorgVersion.h>
33428d7b3dSmrg
34428d7b3dSmrg#include <xf86.h>
35428d7b3dSmrg#include <xf86Parser.h>
36428d7b3dSmrg
37428d7b3dSmrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,99,0,0)
38428d7b3dSmrg#include <xf86Resources.h>
39428d7b3dSmrg#endif
40428d7b3dSmrg
41428d7b3dSmrg#include "intel_driver.h"
42428d7b3dSmrg#include "intel_options.h"
43428d7b3dSmrg#include "legacy/legacy.h"
44428d7b3dSmrg#include "sna/sna_module.h"
45428d7b3dSmrg#include "uxa/uxa_module.h"
46428d7b3dSmrg
47428d7b3dSmrg#include "i915_pciids.h" /* copied from (kernel) include/drm/i915_pciids.h */
48428d7b3dSmrg
49428d7b3dSmrg#ifdef XSERVER_PLATFORM_BUS
50428d7b3dSmrg#include <xf86platformBus.h>
51428d7b3dSmrg#endif
52428d7b3dSmrg
53428d7b3dSmrg#ifndef XF86_ALLOCATE_GPU_SCREEN
54428d7b3dSmrg#define XF86_ALLOCATE_GPU_SCREEN 0
55428d7b3dSmrg#endif
56428d7b3dSmrg
57428d7b3dSmrgstatic const struct intel_device_info intel_generic_info = {
58428d7b3dSmrg	.gen = -1,
59428d7b3dSmrg};
60428d7b3dSmrg
61428d7b3dSmrgstatic const struct intel_device_info intel_i81x_info = {
62428d7b3dSmrg	.gen = 010,
63428d7b3dSmrg};
64428d7b3dSmrg
65428d7b3dSmrgstatic const struct intel_device_info intel_i830_info = {
66428d7b3dSmrg	.gen = 020,
67428d7b3dSmrg};
68428d7b3dSmrgstatic const struct intel_device_info intel_i845_info = {
69428d7b3dSmrg	.gen = 020,
70428d7b3dSmrg};
71428d7b3dSmrgstatic const struct intel_device_info intel_i855_info = {
72428d7b3dSmrg	.gen = 021,
73428d7b3dSmrg};
74428d7b3dSmrgstatic const struct intel_device_info intel_i865_info = {
75428d7b3dSmrg	.gen = 022,
76428d7b3dSmrg};
77428d7b3dSmrg
78428d7b3dSmrgstatic const struct intel_device_info intel_i915_info = {
79428d7b3dSmrg	.gen = 030,
80428d7b3dSmrg};
81428d7b3dSmrgstatic const struct intel_device_info intel_i945_info = {
82428d7b3dSmrg	.gen = 031,
83428d7b3dSmrg};
84428d7b3dSmrg
85428d7b3dSmrgstatic const struct intel_device_info intel_g33_info = {
86428d7b3dSmrg	.gen = 033,
87428d7b3dSmrg};
88428d7b3dSmrg
89428d7b3dSmrgstatic const struct intel_device_info intel_i965_info = {
90428d7b3dSmrg	.gen = 040,
91428d7b3dSmrg};
92428d7b3dSmrg
93428d7b3dSmrgstatic const struct intel_device_info intel_g4x_info = {
94428d7b3dSmrg	.gen = 045,
95428d7b3dSmrg};
96428d7b3dSmrg
97428d7b3dSmrgstatic const struct intel_device_info intel_ironlake_info = {
98428d7b3dSmrg	.gen = 050,
99428d7b3dSmrg};
100428d7b3dSmrg
101428d7b3dSmrgstatic const struct intel_device_info intel_sandybridge_info = {
102428d7b3dSmrg	.gen = 060,
103428d7b3dSmrg};
104428d7b3dSmrg
105428d7b3dSmrgstatic const struct intel_device_info intel_ivybridge_info = {
106428d7b3dSmrg	.gen = 070,
107428d7b3dSmrg};
108428d7b3dSmrg
109428d7b3dSmrgstatic const struct intel_device_info intel_valleyview_info = {
110428d7b3dSmrg	.gen = 071,
111428d7b3dSmrg};
112428d7b3dSmrg
113428d7b3dSmrgstatic const struct intel_device_info intel_haswell_info = {
114428d7b3dSmrg	.gen = 075,
115428d7b3dSmrg};
116428d7b3dSmrg
117428d7b3dSmrgstatic const struct intel_device_info intel_broadwell_info = {
118428d7b3dSmrg	.gen = 0100,
119428d7b3dSmrg};
120428d7b3dSmrg
121428d7b3dSmrgstatic const struct intel_device_info intel_cherryview_info = {
122428d7b3dSmrg	.gen = 0101,
123428d7b3dSmrg};
124428d7b3dSmrg
125428d7b3dSmrgstatic const struct intel_device_info intel_skylake_info = {
126428d7b3dSmrg	.gen = 0110,
127428d7b3dSmrg};
128428d7b3dSmrg
129428d7b3dSmrg
130428d7b3dSmrgstatic const SymTabRec intel_chipsets[] = {
131428d7b3dSmrg	{PCI_CHIP_I810,				"i810"},
132428d7b3dSmrg	{PCI_CHIP_I810_DC100,			"i810-dc100"},
133428d7b3dSmrg	{PCI_CHIP_I810_E,			"i810e"},
134428d7b3dSmrg	{PCI_CHIP_I815,				"i815"},
135428d7b3dSmrg	{PCI_CHIP_I830_M,			"i830M"},
136428d7b3dSmrg	{PCI_CHIP_845_G,			"845G"},
137428d7b3dSmrg	{PCI_CHIP_I854,				"854"},
138428d7b3dSmrg	{PCI_CHIP_I855_GM,			"852GM/855GM"},
139428d7b3dSmrg	{PCI_CHIP_I865_G,			"865G"},
140428d7b3dSmrg	{PCI_CHIP_I915_G,			"915G"},
141428d7b3dSmrg	{PCI_CHIP_E7221_G,			"E7221 (i915)"},
142428d7b3dSmrg	{PCI_CHIP_I915_GM,			"915GM"},
143428d7b3dSmrg	{PCI_CHIP_I945_G,			"945G"},
144428d7b3dSmrg	{PCI_CHIP_I945_GM,			"945GM"},
145428d7b3dSmrg	{PCI_CHIP_I945_GME,			"945GME"},
146428d7b3dSmrg	{PCI_CHIP_PINEVIEW_M,			"Pineview GM"},
147428d7b3dSmrg	{PCI_CHIP_PINEVIEW_G,			"Pineview G"},
148428d7b3dSmrg	{PCI_CHIP_I965_G,			"965G"},
149428d7b3dSmrg	{PCI_CHIP_G35_G,			"G35"},
150428d7b3dSmrg	{PCI_CHIP_I965_Q,			"965Q"},
151428d7b3dSmrg	{PCI_CHIP_I946_GZ,			"946GZ"},
152428d7b3dSmrg	{PCI_CHIP_I965_GM,			"965GM"},
153428d7b3dSmrg	{PCI_CHIP_I965_GME,			"965GME/GLE"},
154428d7b3dSmrg	{PCI_CHIP_G33_G,			"G33"},
155428d7b3dSmrg	{PCI_CHIP_Q35_G,			"Q35"},
156428d7b3dSmrg	{PCI_CHIP_Q33_G,			"Q33"},
157428d7b3dSmrg	{PCI_CHIP_GM45_GM,			"GM45"},
158428d7b3dSmrg	{PCI_CHIP_G45_E_G,			"4 Series"},
159428d7b3dSmrg	{PCI_CHIP_G45_G,			"G45/G43"},
160428d7b3dSmrg	{PCI_CHIP_Q45_G,			"Q45/Q43"},
161428d7b3dSmrg	{PCI_CHIP_G41_G,			"G41"},
162428d7b3dSmrg	{PCI_CHIP_B43_G,			"B43"},
163428d7b3dSmrg	{PCI_CHIP_B43_G1,			"B43"},
164428d7b3dSmrg
165428d7b3dSmrg	{0, ""},
166428d7b3dSmrg
167428d7b3dSmrg	{PCI_CHIP_IRONLAKE_D_G,			"HD Graphics"},
168428d7b3dSmrg	{PCI_CHIP_IRONLAKE_M_G,			"HD Graphics"},
169428d7b3dSmrg	{PCI_CHIP_SANDYBRIDGE_GT1,		"HD Graphics 2000" },
170428d7b3dSmrg	{PCI_CHIP_SANDYBRIDGE_GT2,		"HD Graphics 3000" },
171428d7b3dSmrg	{PCI_CHIP_SANDYBRIDGE_GT2_PLUS,		"HD Graphics 3000" },
172428d7b3dSmrg	{PCI_CHIP_SANDYBRIDGE_M_GT1,		"HD Graphics 2000" },
173428d7b3dSmrg	{PCI_CHIP_SANDYBRIDGE_M_GT2,		"HD Graphics 3000" },
174428d7b3dSmrg	{PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS,	"HD Graphics 3000" },
175428d7b3dSmrg	{PCI_CHIP_SANDYBRIDGE_S_GT,		"HD Graphics" },
176428d7b3dSmrg	{PCI_CHIP_IVYBRIDGE_M_GT1,		"HD Graphics 2500" },
177428d7b3dSmrg	{PCI_CHIP_IVYBRIDGE_M_GT2,		"HD Graphics 4000" },
178428d7b3dSmrg	{PCI_CHIP_IVYBRIDGE_D_GT1,		"HD Graphics 2500" },
179428d7b3dSmrg	{PCI_CHIP_IVYBRIDGE_D_GT2,		"HD Graphics 4000" },
180428d7b3dSmrg	{PCI_CHIP_IVYBRIDGE_S_GT1,		"HD Graphics" },
181428d7b3dSmrg	{PCI_CHIP_IVYBRIDGE_S_GT2,		"HD Graphics P4000" },
182428d7b3dSmrg	{PCI_CHIP_HASWELL_D_GT1,		"HD Graphics" },
183428d7b3dSmrg	{PCI_CHIP_HASWELL_D_GT2,		"HD Graphics 4600" },
184428d7b3dSmrg	{PCI_CHIP_HASWELL_D_GT3,		"HD Graphics 5000" }, /* ??? */
185428d7b3dSmrg	{PCI_CHIP_HASWELL_M_GT1,		"HD Graphics" },
186428d7b3dSmrg	{PCI_CHIP_HASWELL_M_GT2,		"HD Graphics 4600" },
187428d7b3dSmrg	{PCI_CHIP_HASWELL_M_GT3,		"HD Graphics 5000" }, /* ??? */
188428d7b3dSmrg	{PCI_CHIP_HASWELL_S_GT1,		"HD Graphics" },
189428d7b3dSmrg	{PCI_CHIP_HASWELL_S_GT2,		"HD Graphics P4600/P4700" },
190428d7b3dSmrg	{PCI_CHIP_HASWELL_S_GT3,		"HD Graphics 5000" }, /* ??? */
191428d7b3dSmrg	{PCI_CHIP_HASWELL_B_GT1,		"HD Graphics" }, /* ??? */
192428d7b3dSmrg	{PCI_CHIP_HASWELL_B_GT2,		"HD Graphics" }, /* ??? */
193428d7b3dSmrg	{PCI_CHIP_HASWELL_B_GT3,		"HD Graphics" }, /* ??? */
194428d7b3dSmrg	{PCI_CHIP_HASWELL_E_GT1,		"HD Graphics" },
195428d7b3dSmrg	{PCI_CHIP_HASWELL_E_GT2,		"HD Graphics" }, /* ??? */
196428d7b3dSmrg	{PCI_CHIP_HASWELL_E_GT3,		"HD Graphics" }, /* ??? */
197428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_D_GT1,		"HD Graphics" }, /* ??? */
198428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_D_GT2,		"HD Graphics" }, /* ??? */
199428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_D_GT3,		"Iris(TM) Graphics 5100" },
200428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_M_GT1,		"HD Graphics" },
201428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_M_GT2,		"HD Graphics 4400" },
202428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_M_GT3,		"HD Graphics 5000" },
203428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_S_GT1,		"HD Graphics" }, /* ??? */
204428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_S_GT2,		"HD Graphics" }, /* ??? */
205428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_S_GT3,		"Iris(TM) Graphics 5100" },
206428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_B_GT1,		"HD Graphics" }, /* ??? */
207428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_B_GT2,		"HD Graphics" }, /* ??? */
208428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_B_GT3,		"Iris(TM) Graphics 5100" },
209428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_E_GT1,		"HD Graphics" },
210428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_E_GT2,		"HD Graphics 4200" },
211428d7b3dSmrg	{PCI_CHIP_HASWELL_ULT_E_GT3,		"Iris(TM) Graphics 5100" },
212428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_D_GT1,		"HD Graphics" }, /* ??? */
213428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_D_GT2,		"HD Graphics 4600" },
214428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_D_GT3,		"Iris(TM) Pro Graphics 5200" },
215428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_M_GT1,		"HD Graphics" }, /* ??? */
216428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_M_GT2,		"HD Graphics 4600" },
217428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_M_GT3,		"Iris(TM) Pro Graphics 5200" },
218428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_S_GT1,		"HD Graphics" }, /* ??? */
219428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_S_GT2,		"HD Graphics" }, /* ??? */
220428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_S_GT3,		"Iris(TM) Pro Graphics 5200" },
221428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_B_GT1,		"HD Graphics" }, /* ??? */
222428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_B_GT2,		"HD Graphics" }, /* ??? */
223428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_B_GT3,		"Iris(TM) Pro Graphics 5200" },
224428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_E_GT1,		"HD Graphics" }, /* ??? */
225428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_E_GT2,		"HD Graphics" }, /* ??? */
226428d7b3dSmrg	{PCI_CHIP_HASWELL_CRW_E_GT3,		"Iris(TM) Pro Graphics 5200" },
227428d7b3dSmrg
228428d7b3dSmrg	/* Valleyview (Baytail) */
229428d7b3dSmrg	{0x0f30, "HD Graphics"},
230428d7b3dSmrg	{0x0f31, "HD Graphics"},
231428d7b3dSmrg	{0x0f32, "HD Graphics"},
232428d7b3dSmrg	{0x0f33, "HD Graphics"},
233428d7b3dSmrg	{0x0155, "HD Graphics"},
234428d7b3dSmrg	{0x0157, "HD Graphics"},
235428d7b3dSmrg
236428d7b3dSmrg	/* Broadwell Marketing names */
237428d7b3dSmrg	{0x1602, "HD graphics"},
238428d7b3dSmrg	{0x1606, "HD graphics"},
239428d7b3dSmrg	{0x160B, "HD graphics"},
240428d7b3dSmrg	{0x160A, "HD graphics"},
241428d7b3dSmrg	{0x160D, "HD graphics"},
242428d7b3dSmrg	{0x160E, "HD graphics"},
243428d7b3dSmrg	{0x1612, "HD graphics 5600"},
244428d7b3dSmrg	{0x1616, "HD graphics 5500"},
245428d7b3dSmrg	{0x161B, "HD graphics"},
246428d7b3dSmrg	{0x161A, "HD graphics"},
247428d7b3dSmrg	{0x161D, "HD graphics"},
248428d7b3dSmrg	{0x161E, "HD graphics 5300"},
249428d7b3dSmrg	{0x1622, "Iris Pro graphics 6200"},
250428d7b3dSmrg	{0x1626, "HD graphics 6000"},
251428d7b3dSmrg	{0x162B, "Iris graphics 6100"},
252428d7b3dSmrg	{0x162A, "Iris Pro graphics P6300"},
253428d7b3dSmrg	{0x162D, "HD graphics"},
254428d7b3dSmrg	{0x162E, "HD graphics"},
255428d7b3dSmrg	{0x1632, "HD graphics"},
256428d7b3dSmrg	{0x1636, "HD graphics"},
257428d7b3dSmrg	{0x163B, "HD graphics"},
258428d7b3dSmrg	{0x163A, "HD graphics"},
259428d7b3dSmrg	{0x163D, "HD graphics"},
260428d7b3dSmrg	{0x163E, "HD graphics"},
261428d7b3dSmrg
262428d7b3dSmrg	/* When adding new identifiers, also update:
263428d7b3dSmrg	 * 1. intel_identify()
264428d7b3dSmrg	 * 2. man/intel.man
265428d7b3dSmrg	 * 3. README
266428d7b3dSmrg	 */
267428d7b3dSmrg
268428d7b3dSmrg	{-1, NULL} /* Sentinel */
269428d7b3dSmrg};
270428d7b3dSmrg
271428d7b3dSmrgstatic const struct pci_id_match intel_device_match[] = {
272428d7b3dSmrg#if UMS
273428d7b3dSmrg	INTEL_VGA_DEVICE(PCI_CHIP_I810, &intel_i81x_info),
274428d7b3dSmrg	INTEL_VGA_DEVICE(PCI_CHIP_I810_DC100, &intel_i81x_info),
275428d7b3dSmrg	INTEL_VGA_DEVICE(PCI_CHIP_I810_E, &intel_i81x_info),
276428d7b3dSmrg	INTEL_VGA_DEVICE(PCI_CHIP_I815, &intel_i81x_info),
277428d7b3dSmrg#endif
278428d7b3dSmrg
279428d7b3dSmrg#if KMS
280428d7b3dSmrg	INTEL_I830_IDS(&intel_i830_info),
281428d7b3dSmrg	INTEL_I845G_IDS(&intel_i845_info),
282428d7b3dSmrg	INTEL_I85X_IDS(&intel_i855_info),
283428d7b3dSmrg	INTEL_I865G_IDS(&intel_i865_info),
284428d7b3dSmrg
285428d7b3dSmrg	INTEL_I915G_IDS(&intel_i915_info),
286428d7b3dSmrg	INTEL_I915GM_IDS(&intel_i915_info),
287428d7b3dSmrg	INTEL_I945G_IDS(&intel_i945_info),
288428d7b3dSmrg	INTEL_I945GM_IDS(&intel_i945_info),
289428d7b3dSmrg
290428d7b3dSmrg	INTEL_G33_IDS(&intel_g33_info),
291428d7b3dSmrg	INTEL_PINEVIEW_IDS(&intel_g33_info),
292428d7b3dSmrg
293428d7b3dSmrg	INTEL_I965G_IDS(&intel_i965_info),
294428d7b3dSmrg	INTEL_I965GM_IDS(&intel_i965_info),
295428d7b3dSmrg
296428d7b3dSmrg	INTEL_G45_IDS(&intel_g4x_info),
297428d7b3dSmrg	INTEL_GM45_IDS(&intel_g4x_info),
298428d7b3dSmrg
299428d7b3dSmrg	INTEL_IRONLAKE_D_IDS(&intel_ironlake_info),
300428d7b3dSmrg	INTEL_IRONLAKE_M_IDS(&intel_ironlake_info),
301428d7b3dSmrg
302428d7b3dSmrg	INTEL_SNB_D_IDS(&intel_sandybridge_info),
303428d7b3dSmrg	INTEL_SNB_M_IDS(&intel_sandybridge_info),
304428d7b3dSmrg
305428d7b3dSmrg	INTEL_IVB_D_IDS(&intel_ivybridge_info),
306428d7b3dSmrg	INTEL_IVB_M_IDS(&intel_ivybridge_info),
307428d7b3dSmrg
308428d7b3dSmrg	INTEL_HSW_D_IDS(&intel_haswell_info),
309428d7b3dSmrg	INTEL_HSW_M_IDS(&intel_haswell_info),
310428d7b3dSmrg
311428d7b3dSmrg	INTEL_VLV_D_IDS(&intel_valleyview_info),
312428d7b3dSmrg	INTEL_VLV_M_IDS(&intel_valleyview_info),
313428d7b3dSmrg
314428d7b3dSmrg	INTEL_BDW_D_IDS(&intel_broadwell_info),
315428d7b3dSmrg	INTEL_BDW_M_IDS(&intel_broadwell_info),
316428d7b3dSmrg
317428d7b3dSmrg	INTEL_CHV_IDS(&intel_cherryview_info),
318428d7b3dSmrg
319428d7b3dSmrg	INTEL_SKL_IDS(&intel_skylake_info),
320428d7b3dSmrg
321428d7b3dSmrg	INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info),
322428d7b3dSmrg#endif
323428d7b3dSmrg
324428d7b3dSmrg	{ 0, 0, 0 },
325428d7b3dSmrg};
326428d7b3dSmrg
327428d7b3dSmrgvoid
328428d7b3dSmrgintel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev)
329428d7b3dSmrg{
330428d7b3dSmrg	int devid;
331428d7b3dSmrg	const char *name = NULL;
332428d7b3dSmrg	int i;
333428d7b3dSmrg
334428d7b3dSmrg	if (dev == NULL) {
335428d7b3dSmrg		EntityInfoPtr ent;
336428d7b3dSmrg		struct pci_device *pci;
337428d7b3dSmrg
338428d7b3dSmrg		ent = xf86GetEntityInfo(scrn->entityList[0]);
339428d7b3dSmrg		if (ent->device->chipID >= 0) {
340428d7b3dSmrg			xf86DrvMsg(scrn->scrnIndex, X_CONFIG,
341428d7b3dSmrg				   "ChipID override: 0x%04X\n",
342428d7b3dSmrg				   ent->device->chipID);
343428d7b3dSmrg			devid = ent->device->chipID;
344428d7b3dSmrg		} else {
345428d7b3dSmrg			pci = xf86GetPciInfoForEntity(ent->index);
346428d7b3dSmrg			if (pci)
347428d7b3dSmrg				devid = pci->device_id;
348428d7b3dSmrg			else
349428d7b3dSmrg				devid = ~0;
350428d7b3dSmrg		}
351428d7b3dSmrg	} else
352428d7b3dSmrg		devid = intel_get_device_id(dev);
353428d7b3dSmrg
354428d7b3dSmrg	for (i = 0; intel_chipsets[i].name != NULL; i++) {
355428d7b3dSmrg		if (devid == intel_chipsets[i].token) {
356428d7b3dSmrg			name = intel_chipsets[i].name;
357428d7b3dSmrg			break;
358428d7b3dSmrg		}
359428d7b3dSmrg	}
360428d7b3dSmrg	if (name == NULL) {
361428d7b3dSmrg		int gen = 0;
362428d7b3dSmrg
363428d7b3dSmrg		for (i = 0; intel_device_match[i].device_id != 0; i++) {
364428d7b3dSmrg			if (devid == intel_device_match[i].device_id) {
365428d7b3dSmrg				const struct intel_device_info *info = (void *)intel_device_match[i].match_data;
366428d7b3dSmrg				gen = info->gen >> 3;
367428d7b3dSmrg				break;
368428d7b3dSmrg			}
369428d7b3dSmrg		}
370428d7b3dSmrg
371428d7b3dSmrg		if (gen) {
372428d7b3dSmrg			xf86DrvMsg(scrn->scrnIndex, X_PROBED,
373428d7b3dSmrg				   "gen%d engineering sample\n", gen);
374428d7b3dSmrg		} else {
375428d7b3dSmrg			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
376428d7b3dSmrg				   "Unknown chipset\n");
377428d7b3dSmrg		}
378428d7b3dSmrg
379428d7b3dSmrg		name = "unknown";
380428d7b3dSmrg	} else {
381428d7b3dSmrg		xf86DrvMsg(scrn->scrnIndex, X_PROBED,
382428d7b3dSmrg			   "Integrated Graphics Chipset: Intel(R) %s\n",
383428d7b3dSmrg			   name);
384428d7b3dSmrg	}
385428d7b3dSmrg
386428d7b3dSmrg	scrn->chipset = (char *)name;
387428d7b3dSmrg}
388428d7b3dSmrg
389428d7b3dSmrg/*
390428d7b3dSmrg * intel_identify --
391428d7b3dSmrg *
392428d7b3dSmrg * Returns the string name for the driver based on the chipset.
393428d7b3dSmrg *
394428d7b3dSmrg */
395428d7b3dSmrgstatic void intel_identify(int flags)
396428d7b3dSmrg{
397428d7b3dSmrg	const SymTabRec *chipset;
398428d7b3dSmrg	const char *stack[64], **unique;
399428d7b3dSmrg	int i, j, size, len;
400428d7b3dSmrg
401428d7b3dSmrg	unique = stack;
402428d7b3dSmrg	size = sizeof(stack)/sizeof(stack[0]);
403428d7b3dSmrg	i = 0;
404428d7b3dSmrg
405428d7b3dSmrg	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Integrated Graphics Chipsets:\n\t");
406428d7b3dSmrg	len = 8;
407428d7b3dSmrg
408428d7b3dSmrg	for (chipset = intel_chipsets; chipset->token; chipset++) {
409428d7b3dSmrg		for (j = i; --j >= 0;)
410428d7b3dSmrg			if (strcmp(unique[j], chipset->name) == 0)
411428d7b3dSmrg				break;
412428d7b3dSmrg		if (j < 0) {
413428d7b3dSmrg			int name_len = strlen(chipset->name);
414428d7b3dSmrg			if (i != 0) {
415428d7b3dSmrg				xf86ErrorF(",");
416428d7b3dSmrg				len++;
417428d7b3dSmrg				if (len + 2 + name_len < 78) {
418428d7b3dSmrg					xf86ErrorF(" ");
419428d7b3dSmrg					len++;
420428d7b3dSmrg				} else {
421428d7b3dSmrg					xf86ErrorF("\n\t");
422428d7b3dSmrg					len = 8;
423428d7b3dSmrg				}
424428d7b3dSmrg			}
425428d7b3dSmrg			xf86ErrorF("%s", chipset->name);
426428d7b3dSmrg			len += name_len;
427428d7b3dSmrg
428428d7b3dSmrg			if (i == size) {
429428d7b3dSmrg				const char **new_unique;
430428d7b3dSmrg
431428d7b3dSmrg				if (unique == stack)
432428d7b3dSmrg					new_unique = malloc(2*sizeof(*unique)*size);
433428d7b3dSmrg				else
434428d7b3dSmrg					new_unique = realloc(unique, 2*sizeof(*unique)*size);
435428d7b3dSmrg				if (new_unique != NULL) {
436428d7b3dSmrg					if (unique == stack)
437428d7b3dSmrg						memcpy(new_unique, stack,
438428d7b3dSmrg						       sizeof(stack));
439428d7b3dSmrg					unique = new_unique;
440428d7b3dSmrg					size *= 2;
441428d7b3dSmrg				}
442428d7b3dSmrg			}
443428d7b3dSmrg			if (i < size)
444428d7b3dSmrg				unique[i++] = chipset->name;
445428d7b3dSmrg		}
446428d7b3dSmrg	}
447428d7b3dSmrg	xf86ErrorF("\n");
448428d7b3dSmrg	if (unique != stack)
449428d7b3dSmrg		free(unique);
450428d7b3dSmrg
451428d7b3dSmrg	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) HD Graphics: 2000-6000\n");
452428d7b3dSmrg	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Graphics: 5100, 6100\n");
453428d7b3dSmrg	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Pro Graphics: 5200, 6200, P6300\n");
454428d7b3dSmrg}
455428d7b3dSmrg
456428d7b3dSmrgstatic Bool intel_driver_func(ScrnInfoPtr pScrn,
457428d7b3dSmrg			      xorgDriverFuncOp op,
458428d7b3dSmrg			      pointer ptr)
459428d7b3dSmrg{
460428d7b3dSmrg	xorgHWFlags *flag;
461428d7b3dSmrg
462428d7b3dSmrg	switch (op) {
463428d7b3dSmrg	case GET_REQUIRED_HW_INTERFACES:
464428d7b3dSmrg		flag = (CARD32*)ptr;
465428d7b3dSmrg		(*flag) = 0;
466428d7b3dSmrg#if UMS
467428d7b3dSmrg		(*flag) = HW_IO | HW_MMIO;
468428d7b3dSmrg#endif
469428d7b3dSmrg#ifdef HW_SKIP_CONSOLE
470428d7b3dSmrg		if (hosted())
471428d7b3dSmrg			(*flag) = HW_SKIP_CONSOLE;
472428d7b3dSmrg#endif
473428d7b3dSmrg
474428d7b3dSmrg		return TRUE;
475428d7b3dSmrg
476428d7b3dSmrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0)
477428d7b3dSmrg	case SUPPORTS_SERVER_FDS:
478428d7b3dSmrg		return TRUE;
479428d7b3dSmrg#endif
480428d7b3dSmrg
481428d7b3dSmrg	default:
482428d7b3dSmrg		/* Unknown or deprecated function */
483428d7b3dSmrg		return FALSE;
484428d7b3dSmrg	}
485428d7b3dSmrg}
486428d7b3dSmrg
487428d7b3dSmrg#if KMS
488428d7b3dSmrgextern XF86ConfigPtr xf86configptr;
489428d7b3dSmrg
490428d7b3dSmrgstatic XF86ConfDevicePtr
491428d7b3dSmrg_xf86findDriver(const char *ident, XF86ConfDevicePtr p)
492428d7b3dSmrg{
493428d7b3dSmrg	while (p) {
494428d7b3dSmrg		if (p->dev_driver && xf86nameCompare(ident, p->dev_driver) == 0)
495428d7b3dSmrg			return p;
496428d7b3dSmrg
497428d7b3dSmrg		p = p->list.next;
498428d7b3dSmrg	}
499428d7b3dSmrg
500428d7b3dSmrg	return NULL;
501428d7b3dSmrg}
502428d7b3dSmrg
503428d7b3dSmrgstatic enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
504428d7b3dSmrg{
505428d7b3dSmrg	enum accel_method accel_method = DEFAULT_ACCEL_METHOD;
506428d7b3dSmrg	XF86ConfDevicePtr dev;
507428d7b3dSmrg
508428d7b3dSmrg	if (hosted())
509428d7b3dSmrg		return SNA;
510428d7b3dSmrg
511428d7b3dSmrg	dev = _xf86findDriver("intel", xf86configptr->conf_device_lst);
512428d7b3dSmrg	if (dev && dev->dev_option_lst) {
513428d7b3dSmrg		const char *s;
514428d7b3dSmrg
515428d7b3dSmrg		s = xf86FindOptionValue(dev->dev_option_lst, "AccelMethod");
516428d7b3dSmrg		if (s ) {
517428d7b3dSmrg			if (strcasecmp(s, "none") == 0)
518428d7b3dSmrg				accel_method = NOACCEL;
519428d7b3dSmrg			else if (strcasecmp(s, "sna") == 0)
520428d7b3dSmrg				accel_method = SNA;
521428d7b3dSmrg			else if (strcasecmp(s, "uxa") == 0)
522428d7b3dSmrg				accel_method = UXA;
523428d7b3dSmrg		}
524428d7b3dSmrg	}
525428d7b3dSmrg
526428d7b3dSmrg	return accel_method;
527428d7b3dSmrg}
528428d7b3dSmrg#endif
529428d7b3dSmrg
530428d7b3dSmrgstatic Bool
531428d7b3dSmrgintel_scrn_create(DriverPtr		driver,
532428d7b3dSmrg		  int			entity_num,
533428d7b3dSmrg		  intptr_t		match_data,
534428d7b3dSmrg		  unsigned		flags)
535428d7b3dSmrg{
536428d7b3dSmrg	ScrnInfoPtr scrn;
537428d7b3dSmrg
538428d7b3dSmrg	if (match_data == 0) {
539428d7b3dSmrg		int devid = intel_entity_get_devid(entity_num), i;
540428d7b3dSmrg		if (devid == 0)
541428d7b3dSmrg			return FALSE;
542428d7b3dSmrg
543428d7b3dSmrg		for (i = 0; intel_device_match[i].device_id != 0; i++) {
544428d7b3dSmrg			if (devid == intel_device_match[i].device_id) {
545428d7b3dSmrg				match_data = (intptr_t)&intel_device_match[i];
546428d7b3dSmrg				break;
547428d7b3dSmrg			}
548428d7b3dSmrg		}
549428d7b3dSmrg
550428d7b3dSmrg		if (match_data == 0)
551428d7b3dSmrg			return FALSE;
552428d7b3dSmrg	}
553428d7b3dSmrg
554428d7b3dSmrg	scrn = xf86AllocateScreen(driver, flags);
555428d7b3dSmrg	if (scrn == NULL)
556428d7b3dSmrg		return FALSE;
557428d7b3dSmrg
558428d7b3dSmrg	scrn->driverVersion = INTEL_VERSION;
559428d7b3dSmrg	scrn->driverName = (char *)INTEL_DRIVER_NAME;
560428d7b3dSmrg	scrn->name = (char *)INTEL_NAME;
561428d7b3dSmrg	scrn->driverPrivate = (void *)(match_data | (flags & XF86_ALLOCATE_GPU_SCREEN) | 2);
562428d7b3dSmrg	scrn->Probe = NULL;
563428d7b3dSmrg
564428d7b3dSmrg	if (xf86IsEntitySharable(entity_num))
565428d7b3dSmrg		xf86SetEntityShared(entity_num);
566428d7b3dSmrg	xf86AddEntityToScreen(scrn, entity_num);
567428d7b3dSmrg
568428d7b3dSmrg#if UMS
569428d7b3dSmrg	if ((unsigned)((struct intel_device_info *)match_data)->gen < 020)
570428d7b3dSmrg		return lg_i810_init(scrn);
571428d7b3dSmrg#endif
572428d7b3dSmrg
573428d7b3dSmrg#if KMS
574428d7b3dSmrg	switch (get_accel_method()) {
575428d7b3dSmrg#if USE_SNA
576428d7b3dSmrg	case NOACCEL:
577428d7b3dSmrg	case SNA:
578428d7b3dSmrg		return sna_init_scrn(scrn, entity_num);
579428d7b3dSmrg#endif
580428d7b3dSmrg#if USE_UXA
581428d7b3dSmrg#if !USE_SNA
582428d7b3dSmrg	case NOACCEL:
583428d7b3dSmrg#endif
584428d7b3dSmrg	case UXA:
585428d7b3dSmrg		  return intel_init_scrn(scrn);
586428d7b3dSmrg#endif
587428d7b3dSmrg
588428d7b3dSmrg	default: break;
589428d7b3dSmrg	}
590428d7b3dSmrg#endif
591428d7b3dSmrg
592428d7b3dSmrg	return FALSE;
593428d7b3dSmrg}
594428d7b3dSmrg
595428d7b3dSmrg/*
596428d7b3dSmrg * intel_pci_probe --
597428d7b3dSmrg *
598428d7b3dSmrg * Look through the PCI bus to find cards that are intel boards.
599428d7b3dSmrg * Setup the dispatch table for the rest of the driver functions.
600428d7b3dSmrg *
601428d7b3dSmrg */
602428d7b3dSmrgstatic Bool intel_pci_probe(DriverPtr		driver,
603428d7b3dSmrg			    int			entity_num,
604428d7b3dSmrg			    struct pci_device	*pci,
605428d7b3dSmrg			    intptr_t		match_data)
606428d7b3dSmrg{
607428d7b3dSmrg	if (intel_open_device(entity_num, pci, NULL) == -1) {
608428d7b3dSmrg#if UMS
609428d7b3dSmrg		switch (pci->device_id) {
610428d7b3dSmrg		case PCI_CHIP_I810:
611428d7b3dSmrg		case PCI_CHIP_I810_DC100:
612428d7b3dSmrg		case PCI_CHIP_I810_E:
613428d7b3dSmrg		case PCI_CHIP_I815:
614428d7b3dSmrg			if (!hosted())
615428d7b3dSmrg				break;
616428d7b3dSmrg		default:
617428d7b3dSmrg			return FALSE;
618428d7b3dSmrg		}
619428d7b3dSmrg#else
620428d7b3dSmrg		return FALSE;
621428d7b3dSmrg#endif
622428d7b3dSmrg	}
623428d7b3dSmrg
624428d7b3dSmrg	return intel_scrn_create(driver, entity_num, match_data, 0);
625428d7b3dSmrg}
626428d7b3dSmrg
627428d7b3dSmrg#ifdef XSERVER_PLATFORM_BUS
628428d7b3dSmrgstatic Bool
629428d7b3dSmrgintel_platform_probe(DriverPtr driver,
630428d7b3dSmrg		     int entity_num, int flags,
631428d7b3dSmrg		     struct xf86_platform_device *dev,
632428d7b3dSmrg		     intptr_t match_data)
633428d7b3dSmrg{
634428d7b3dSmrg	unsigned scrn_flags = 0;
635428d7b3dSmrg
636428d7b3dSmrg	if (intel_open_device(entity_num, dev->pdev, dev) == -1)
637428d7b3dSmrg		return FALSE;
638428d7b3dSmrg
639428d7b3dSmrg	/* Allow ourselves to act as a slaved output if not primary */
640428d7b3dSmrg	if (flags & PLATFORM_PROBE_GPU_SCREEN) {
641428d7b3dSmrg		flags &= ~PLATFORM_PROBE_GPU_SCREEN;
642428d7b3dSmrg		scrn_flags |= XF86_ALLOCATE_GPU_SCREEN;
643428d7b3dSmrg	}
644428d7b3dSmrg
645428d7b3dSmrg	/* if we get any flags we don't understand fail to probe for now */
646428d7b3dSmrg	if (flags)
647428d7b3dSmrg		return FALSE;
648428d7b3dSmrg
649428d7b3dSmrg	return intel_scrn_create(driver, entity_num, match_data, scrn_flags);
650428d7b3dSmrg}
651428d7b3dSmrg#endif
652428d7b3dSmrg
653428d7b3dSmrg#ifdef XFree86LOADER
654428d7b3dSmrg
655428d7b3dSmrgstatic MODULESETUPPROTO(intel_setup);
656428d7b3dSmrg
657428d7b3dSmrgstatic XF86ModuleVersionInfo intel_version = {
658428d7b3dSmrg	"intel",
659428d7b3dSmrg	MODULEVENDORSTRING,
660428d7b3dSmrg	MODINFOSTRING1,
661428d7b3dSmrg	MODINFOSTRING2,
662428d7b3dSmrg	XORG_VERSION_CURRENT,
663428d7b3dSmrg	INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
664428d7b3dSmrg	ABI_CLASS_VIDEODRV,
665428d7b3dSmrg	ABI_VIDEODRV_VERSION,
666428d7b3dSmrg	MOD_CLASS_VIDEODRV,
667428d7b3dSmrg	{0, 0, 0, 0}
668428d7b3dSmrg};
669428d7b3dSmrg
670428d7b3dSmrgstatic const OptionInfoRec *
671428d7b3dSmrgintel_available_options(int chipid, int busid)
672428d7b3dSmrg{
673428d7b3dSmrg	switch (chipid) {
674428d7b3dSmrg#if UMS
675428d7b3dSmrg	case PCI_CHIP_I810:
676428d7b3dSmrg	case PCI_CHIP_I810_DC100:
677428d7b3dSmrg	case PCI_CHIP_I810_E:
678428d7b3dSmrg	case PCI_CHIP_I815:
679428d7b3dSmrg		return lg_i810_available_options(chipid, busid);
680428d7b3dSmrg#endif
681428d7b3dSmrg
682428d7b3dSmrg	default:
683428d7b3dSmrg		return intel_options;
684428d7b3dSmrg	}
685428d7b3dSmrg}
686428d7b3dSmrg
687428d7b3dSmrgstatic DriverRec intel = {
688428d7b3dSmrg	INTEL_VERSION,
689428d7b3dSmrg	(char *)INTEL_DRIVER_NAME,
690428d7b3dSmrg	intel_identify,
691428d7b3dSmrg	NULL,
692428d7b3dSmrg	intel_available_options,
693428d7b3dSmrg	NULL,
694428d7b3dSmrg	0,
695428d7b3dSmrg	intel_driver_func,
696428d7b3dSmrg	intel_device_match,
697428d7b3dSmrg	intel_pci_probe,
698428d7b3dSmrg#ifdef XSERVER_PLATFORM_BUS
699428d7b3dSmrg	intel_platform_probe
700428d7b3dSmrg#endif
701428d7b3dSmrg};
702428d7b3dSmrg
703428d7b3dSmrgstatic pointer intel_setup(pointer module,
704428d7b3dSmrg			   pointer opts,
705428d7b3dSmrg			   int *errmaj,
706428d7b3dSmrg			   int *errmin)
707428d7b3dSmrg{
708428d7b3dSmrg	static Bool setupDone = 0;
709428d7b3dSmrg
710428d7b3dSmrg	/* This module should be loaded only once, but check to be sure.
711428d7b3dSmrg	*/
712428d7b3dSmrg	if (!setupDone) {
713428d7b3dSmrg		setupDone = 1;
714428d7b3dSmrg		xf86AddDriver(&intel, module, HaveDriverFuncs);
715428d7b3dSmrg
716428d7b3dSmrg		/*
717428d7b3dSmrg		 * The return value must be non-NULL on success even though there
718428d7b3dSmrg		 * is no TearDownProc.
719428d7b3dSmrg		 */
720428d7b3dSmrg		return (pointer) 1;
721428d7b3dSmrg	} else {
722428d7b3dSmrg		if (errmaj)
723428d7b3dSmrg			*errmaj = LDR_ONCEONLY;
724428d7b3dSmrg		return NULL;
725428d7b3dSmrg	}
726428d7b3dSmrg}
727428d7b3dSmrg
728428d7b3dSmrg_X_EXPORT XF86ModuleData intelModuleData = { &intel_version, intel_setup, NULL };
729428d7b3dSmrg#endif
730