1/*
2 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 * Copyright © 2010 Intel Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 */
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <xorg-server.h>
32#include <xorgVersion.h>
33
34#include <xf86.h>
35#include <xf86Parser.h>
36
37#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,6,99,0,0)
38#include <xf86Resources.h>
39#endif
40
41#include "intel_driver.h"
42#include "intel_options.h"
43#include "legacy/legacy.h"
44#include "sna/sna_module.h"
45#include "uxa/uxa_module.h"
46
47#include "i915_pciids.h" /* copied from (kernel) include/drm/i915_pciids.h */
48
49#ifdef XSERVER_PLATFORM_BUS
50#include <xf86platformBus.h>
51#endif
52
53#ifndef XF86_ALLOCATE_GPU_SCREEN
54#define XF86_ALLOCATE_GPU_SCREEN 0
55#endif
56
57static const struct intel_device_info intel_generic_info = {
58	.gen = -1,
59};
60
61static const struct intel_device_info intel_i81x_info = {
62	.gen = 010,
63};
64
65static const struct intel_device_info intel_i830_info = {
66	.gen = 020,
67};
68static const struct intel_device_info intel_i845_info = {
69	.gen = 020,
70};
71static const struct intel_device_info intel_i855_info = {
72	.gen = 021,
73};
74static const struct intel_device_info intel_i865_info = {
75	.gen = 022,
76};
77
78static const struct intel_device_info intel_i915_info = {
79	.gen = 030,
80};
81static const struct intel_device_info intel_i945_info = {
82	.gen = 031,
83};
84
85static const struct intel_device_info intel_g33_info = {
86	.gen = 033,
87};
88
89static const struct intel_device_info intel_i965_info = {
90	.gen = 040,
91};
92
93static const struct intel_device_info intel_g4x_info = {
94	.gen = 045,
95};
96
97static const struct intel_device_info intel_ironlake_info = {
98	.gen = 050,
99};
100
101static const struct intel_device_info intel_sandybridge_info = {
102	.gen = 060,
103};
104
105static const struct intel_device_info intel_ivybridge_info = {
106	.gen = 070,
107};
108
109static const struct intel_device_info intel_valleyview_info = {
110	.gen = 071,
111};
112
113static const struct intel_device_info intel_haswell_info = {
114	.gen = 075,
115};
116
117static const struct intel_device_info intel_broadwell_info = {
118	.gen = 0100,
119};
120
121static const struct intel_device_info intel_cherryview_info = {
122	.gen = 0101,
123};
124
125static const struct intel_device_info intel_skylake_info = {
126	.gen = 0110,
127};
128
129static const struct intel_device_info intel_broxton_info = {
130	.gen = 0111,
131};
132
133static const struct intel_device_info intel_kabylake_info = {
134	.gen = 0112,
135};
136
137static const struct intel_device_info intel_geminilake_info = {
138	.gen = 0113,
139};
140
141static const struct intel_device_info intel_coffeelake_info = {
142	.gen = 0114,
143};
144
145static const SymTabRec intel_chipsets[] = {
146	{PCI_CHIP_I810,				"i810"},
147	{PCI_CHIP_I810_DC100,			"i810-dc100"},
148	{PCI_CHIP_I810_E,			"i810e"},
149	{PCI_CHIP_I815,				"i815"},
150	{PCI_CHIP_I830_M,			"i830M"},
151	{PCI_CHIP_845_G,			"845G"},
152	{PCI_CHIP_I854,				"854"},
153	{PCI_CHIP_I855_GM,			"852GM/855GM"},
154	{PCI_CHIP_I865_G,			"865G"},
155	{PCI_CHIP_I915_G,			"915G"},
156	{PCI_CHIP_E7221_G,			"E7221 (i915)"},
157	{PCI_CHIP_I915_GM,			"915GM"},
158	{PCI_CHIP_I945_G,			"945G"},
159	{PCI_CHIP_I945_GM,			"945GM"},
160	{PCI_CHIP_I945_GME,			"945GME"},
161	{PCI_CHIP_PINEVIEW_M,			"Pineview GM"},
162	{PCI_CHIP_PINEVIEW_G,			"Pineview G"},
163	{PCI_CHIP_I965_G,			"965G"},
164	{PCI_CHIP_G35_G,			"G35"},
165	{PCI_CHIP_I965_Q,			"965Q"},
166	{PCI_CHIP_I946_GZ,			"946GZ"},
167	{PCI_CHIP_I965_GM,			"965GM"},
168	{PCI_CHIP_I965_GME,			"965GME/GLE"},
169	{PCI_CHIP_G33_G,			"G33"},
170	{PCI_CHIP_Q35_G,			"Q35"},
171	{PCI_CHIP_Q33_G,			"Q33"},
172	{PCI_CHIP_GM45_GM,			"GM45"},
173	{PCI_CHIP_G45_E_G,			"4 Series"},
174	{PCI_CHIP_G45_G,			"G45/G43"},
175	{PCI_CHIP_Q45_G,			"Q45/Q43"},
176	{PCI_CHIP_G41_G,			"G41"},
177	{PCI_CHIP_B43_G,			"B43"},
178	{PCI_CHIP_B43_G1,			"B43"},
179
180	{0, ""},
181
182	{PCI_CHIP_IRONLAKE_D_G,			"HD Graphics"},
183	{PCI_CHIP_IRONLAKE_M_G,			"HD Graphics"},
184	{PCI_CHIP_SANDYBRIDGE_GT1,		"HD Graphics 2000" },
185	{PCI_CHIP_SANDYBRIDGE_GT2,		"HD Graphics 3000" },
186	{PCI_CHIP_SANDYBRIDGE_GT2_PLUS,		"HD Graphics 3000" },
187	{PCI_CHIP_SANDYBRIDGE_M_GT1,		"HD Graphics 2000" },
188	{PCI_CHIP_SANDYBRIDGE_M_GT2,		"HD Graphics 3000" },
189	{PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS,	"HD Graphics 3000" },
190	{PCI_CHIP_SANDYBRIDGE_S_GT,		"HD Graphics" },
191	{PCI_CHIP_IVYBRIDGE_M_GT1,		"HD Graphics 2500" },
192	{PCI_CHIP_IVYBRIDGE_M_GT2,		"HD Graphics 4000" },
193	{PCI_CHIP_IVYBRIDGE_D_GT1,		"HD Graphics 2500" },
194	{PCI_CHIP_IVYBRIDGE_D_GT2,		"HD Graphics 4000" },
195	{PCI_CHIP_IVYBRIDGE_S_GT1,		"HD Graphics" },
196	{PCI_CHIP_IVYBRIDGE_S_GT2,		"HD Graphics P4000" },
197	{PCI_CHIP_HASWELL_D_GT1,		"HD Graphics" },
198	{PCI_CHIP_HASWELL_D_GT2,		"HD Graphics 4600" },
199	{PCI_CHIP_HASWELL_D_GT3,		"HD Graphics 5000" }, /* ??? */
200	{PCI_CHIP_HASWELL_M_GT1,		"HD Graphics" },
201	{PCI_CHIP_HASWELL_M_GT2,		"HD Graphics 4600" },
202	{PCI_CHIP_HASWELL_M_GT3,		"HD Graphics 5000" }, /* ??? */
203	{PCI_CHIP_HASWELL_S_GT1,		"HD Graphics" },
204	{PCI_CHIP_HASWELL_S_GT2,		"HD Graphics P4600/P4700" },
205	{PCI_CHIP_HASWELL_S_GT3,		"HD Graphics 5000" }, /* ??? */
206	{PCI_CHIP_HASWELL_B_GT1,		"HD Graphics" }, /* ??? */
207	{PCI_CHIP_HASWELL_B_GT2,		"HD Graphics" }, /* ??? */
208	{PCI_CHIP_HASWELL_B_GT3,		"HD Graphics" }, /* ??? */
209	{PCI_CHIP_HASWELL_E_GT1,		"HD Graphics" },
210	{PCI_CHIP_HASWELL_E_GT2,		"HD Graphics" }, /* ??? */
211	{PCI_CHIP_HASWELL_E_GT3,		"HD Graphics" }, /* ??? */
212	{PCI_CHIP_HASWELL_ULT_D_GT1,		"HD Graphics" }, /* ??? */
213	{PCI_CHIP_HASWELL_ULT_D_GT2,		"HD Graphics" }, /* ??? */
214	{PCI_CHIP_HASWELL_ULT_D_GT3,		"Iris(TM) Graphics 5100" },
215	{PCI_CHIP_HASWELL_ULT_M_GT1,		"HD Graphics" },
216	{PCI_CHIP_HASWELL_ULT_M_GT2,		"HD Graphics 4400" },
217	{PCI_CHIP_HASWELL_ULT_M_GT3,		"HD Graphics 5000" },
218	{PCI_CHIP_HASWELL_ULT_S_GT1,		"HD Graphics" }, /* ??? */
219	{PCI_CHIP_HASWELL_ULT_S_GT2,		"HD Graphics" }, /* ??? */
220	{PCI_CHIP_HASWELL_ULT_S_GT3,		"Iris(TM) Graphics 5100" },
221	{PCI_CHIP_HASWELL_ULT_B_GT1,		"HD Graphics" }, /* ??? */
222	{PCI_CHIP_HASWELL_ULT_B_GT2,		"HD Graphics" }, /* ??? */
223	{PCI_CHIP_HASWELL_ULT_B_GT3,		"Iris(TM) Graphics 5100" },
224	{PCI_CHIP_HASWELL_ULT_E_GT1,		"HD Graphics" },
225	{PCI_CHIP_HASWELL_ULT_E_GT2,		"HD Graphics 4200" },
226	{PCI_CHIP_HASWELL_ULT_E_GT3,		"Iris(TM) Graphics 5100" },
227	{PCI_CHIP_HASWELL_CRW_D_GT1,		"HD Graphics" }, /* ??? */
228	{PCI_CHIP_HASWELL_CRW_D_GT2,		"HD Graphics 4600" },
229	{PCI_CHIP_HASWELL_CRW_D_GT3,		"Iris(TM) Pro Graphics 5200" },
230	{PCI_CHIP_HASWELL_CRW_M_GT1,		"HD Graphics" }, /* ??? */
231	{PCI_CHIP_HASWELL_CRW_M_GT2,		"HD Graphics 4600" },
232	{PCI_CHIP_HASWELL_CRW_M_GT3,		"Iris(TM) Pro Graphics 5200" },
233	{PCI_CHIP_HASWELL_CRW_S_GT1,		"HD Graphics" }, /* ??? */
234	{PCI_CHIP_HASWELL_CRW_S_GT2,		"HD Graphics" }, /* ??? */
235	{PCI_CHIP_HASWELL_CRW_S_GT3,		"Iris(TM) Pro Graphics 5200" },
236	{PCI_CHIP_HASWELL_CRW_B_GT1,		"HD Graphics" }, /* ??? */
237	{PCI_CHIP_HASWELL_CRW_B_GT2,		"HD Graphics" }, /* ??? */
238	{PCI_CHIP_HASWELL_CRW_B_GT3,		"Iris(TM) Pro Graphics 5200" },
239	{PCI_CHIP_HASWELL_CRW_E_GT1,		"HD Graphics" }, /* ??? */
240	{PCI_CHIP_HASWELL_CRW_E_GT2,		"HD Graphics" }, /* ??? */
241	{PCI_CHIP_HASWELL_CRW_E_GT3,		"Iris(TM) Pro Graphics 5200" },
242
243	/* Valleyview (Baytail) */
244	{0x0f30, "HD Graphics"},
245	{0x0f31, "HD Graphics"},
246	{0x0f32, "HD Graphics"},
247	{0x0f33, "HD Graphics"},
248	{0x0155, "HD Graphics"},
249	{0x0157, "HD Graphics"},
250
251	/* Broadwell Marketing names */
252	{0x1602, "HD Graphics"},
253	{0x1606, "HD Graphics"},
254	{0x160B, "HD Graphics"},
255	{0x160A, "HD Graphics"},
256	{0x160D, "HD Graphics"},
257	{0x160E, "HD Graphics"},
258	{0x1612, "HD Graphics 5600"},
259	{0x1616, "HD Graphics 5500"},
260	{0x161B, "HD Graphics"},
261	{0x161A, "HD Graphics"},
262	{0x161D, "HD Graphics"},
263	{0x161E, "HD Graphics 5300"},
264	{0x1622, "Iris Pro Graphics 6200"},
265	{0x1626, "HD Graphics 6000"},
266	{0x162B, "Iris Graphics 6100"},
267	{0x162A, "Iris Pro Graphics P6300"},
268	{0x162D, "HD Graphics"},
269	{0x162E, "HD Graphics"},
270	{0x1632, "HD Graphics"},
271	{0x1636, "HD Graphics"},
272	{0x163B, "HD Graphics"},
273	{0x163A, "HD Graphics"},
274	{0x163D, "HD Graphics"},
275	{0x163E, "HD Graphics"},
276
277	/* Cherryview (Cherrytrail/Braswell) */
278	{0x22b0, "HD Graphics"},
279	{0x22b1, "HD Graphics"},
280	{0x22b2, "HD Graphics"},
281	{0x22b3, "HD Graphics"},
282
283	/* Skylake */
284	{0x1902, "HD Graphics 510"},
285	{0x1906, "HD Graphics 510"},
286	{0x190B, "HD Graphics 510"},
287	{0x1912, "HD Graphics 530"},
288	{0x1916, "HD Graphics 520"},
289	{0x191B, "HD Graphics 530"},
290	{0x191D, "HD Graphics P530"},
291	{0x191E, "HD Graphics 515"},
292	{0x1921, "HD Graphics 520"},
293	{0x1926, "Iris Graphics 540"},
294	{0x1927, "Iris Graphics 550"},
295	{0x192B, "Iris Graphics 555"},
296	{0x192D, "Iris Graphics P555"},
297	{0x1932, "Iris Pro Graphics 580"},
298	{0x193A, "Iris Pro Graphics P580"},
299	{0x193B, "Iris Pro Graphics 580"},
300	{0x193D, "Iris Pro Graphics P580"},
301
302	/* Broxton (Apollolake) */
303	{0x5A84, "HD Graphics 505"},
304	{0x5A85, "HD Graphics 500"},
305
306	/* Kabylake */
307	{0x5916, "HD Graphics 620"},
308	{0x591E, "HD Graphics 615"},
309
310	/*Coffeelake*/
311	{0x3E90, "HD Graphics"},
312	{0x3E93, "HD Graphics"},
313	{0x3E99, "HD Graphics"},
314	{0x3E91, "HD Graphics"},
315	{0x3E92, "HD Graphics"},
316	{0x3E96, "HD Graphics"},
317	{0x3E9A, "HD Graphics"},
318	{0x3E9B, "HD Graphics"},
319	{0x3E94, "HD Graphics"},
320	{0x3EA1, "HD Graphics"},
321	{0x3EA4, "HD Graphics"},
322	{0x3EA0, "HD Graphics"},
323	{0x3EA3, "HD Graphics"},
324	{0x3EA9, "HD Graphics"},
325	{0x3EA2, "HD Graphics"},
326	{0x3EA5, "HD Graphics"},
327	{0x3EA6, "HD Graphics"},
328	{0x3EA7, "HD Graphics"},
329	{0x3EA8, "HD Graphics"},
330
331	/* When adding new identifiers, also update:
332	 * 1. intel_identify()
333	 * 2. man/intel.man
334	 * 3. README
335	 */
336
337	{-1, NULL} /* Sentinel */
338};
339
340static const struct pci_id_match intel_device_match[] = {
341#if UMS
342	INTEL_VGA_DEVICE(PCI_CHIP_I810, &intel_i81x_info),
343	INTEL_VGA_DEVICE(PCI_CHIP_I810_DC100, &intel_i81x_info),
344	INTEL_VGA_DEVICE(PCI_CHIP_I810_E, &intel_i81x_info),
345	INTEL_VGA_DEVICE(PCI_CHIP_I815, &intel_i81x_info),
346#endif
347
348#if KMS
349	INTEL_I830_IDS(&intel_i830_info),
350	INTEL_I845G_IDS(&intel_i845_info),
351	INTEL_I85X_IDS(&intel_i855_info),
352	INTEL_I865G_IDS(&intel_i865_info),
353
354	INTEL_I915G_IDS(&intel_i915_info),
355	INTEL_I915GM_IDS(&intel_i915_info),
356	INTEL_I945G_IDS(&intel_i945_info),
357	INTEL_I945GM_IDS(&intel_i945_info),
358
359	INTEL_G33_IDS(&intel_g33_info),
360	INTEL_PINEVIEW_IDS(&intel_g33_info),
361
362	INTEL_I965G_IDS(&intel_i965_info),
363	INTEL_I965GM_IDS(&intel_i965_info),
364
365	INTEL_G45_IDS(&intel_g4x_info),
366	INTEL_GM45_IDS(&intel_g4x_info),
367
368	INTEL_IRONLAKE_D_IDS(&intel_ironlake_info),
369	INTEL_IRONLAKE_M_IDS(&intel_ironlake_info),
370
371	INTEL_SNB_D_IDS(&intel_sandybridge_info),
372	INTEL_SNB_M_IDS(&intel_sandybridge_info),
373
374	INTEL_IVB_D_IDS(&intel_ivybridge_info),
375	INTEL_IVB_M_IDS(&intel_ivybridge_info),
376
377	INTEL_HSW_IDS(&intel_haswell_info),
378	INTEL_VLV_IDS(&intel_valleyview_info),
379	INTEL_BDW_IDS(&intel_broadwell_info),
380	INTEL_CHV_IDS(&intel_cherryview_info),
381	INTEL_SKL_IDS(&intel_skylake_info),
382	INTEL_BXT_IDS(&intel_broxton_info),
383	INTEL_KBL_IDS(&intel_kabylake_info),
384	INTEL_GLK_IDS(&intel_geminilake_info),
385
386	INTEL_CFL_IDS(&intel_coffeelake_info),
387
388	INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info),
389#endif
390
391	{ 0, 0, 0 },
392};
393
394void
395intel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev)
396{
397	int devid;
398	const char *name = NULL;
399	int i;
400
401	if (dev == NULL) {
402		EntityInfoPtr ent;
403		struct pci_device *pci;
404
405		ent = xf86GetEntityInfo(scrn->entityList[0]);
406		if (ent->device->chipID >= 0) {
407			xf86DrvMsg(scrn->scrnIndex, X_CONFIG,
408				   "ChipID override: 0x%04X\n",
409				   ent->device->chipID);
410			devid = ent->device->chipID;
411		} else {
412			pci = xf86GetPciInfoForEntity(ent->index);
413			if (pci)
414				devid = pci->device_id;
415			else
416				devid = ~0;
417		}
418	} else
419		devid = intel_get_device_id(dev);
420
421	for (i = 0; intel_chipsets[i].name != NULL; i++) {
422		if (devid == intel_chipsets[i].token) {
423			name = intel_chipsets[i].name;
424			break;
425		}
426	}
427	if (name == NULL) {
428		int gen = 0;
429
430		for (i = 0; intel_device_match[i].device_id != 0; i++) {
431			if (devid == intel_device_match[i].device_id) {
432				const struct intel_device_info *info = (void *)intel_device_match[i].match_data;
433				gen = info->gen >> 3;
434				break;
435			}
436		}
437
438		if (gen) {
439			xf86DrvMsg(scrn->scrnIndex, X_PROBED,
440				   "gen%d engineering sample\n", gen);
441		} else {
442			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
443				   "Unknown chipset\n");
444		}
445
446		name = "unknown";
447	} else {
448		xf86DrvMsg(scrn->scrnIndex, X_PROBED,
449			   "Integrated Graphics Chipset: Intel(R) %s\n",
450			   name);
451	}
452
453	scrn->chipset = (char *)name;
454}
455
456/*
457 * intel_identify --
458 *
459 * Returns the string name for the driver based on the chipset.
460 *
461 */
462static void intel_identify(int flags)
463{
464	const SymTabRec *chipset;
465	const char *stack[64], **unique;
466	int i, j, size, len;
467
468	unique = stack;
469	size = sizeof(stack)/sizeof(stack[0]);
470	i = 0;
471
472	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Integrated Graphics Chipsets:\n\t");
473	len = 8;
474
475	for (chipset = intel_chipsets; chipset->token; chipset++) {
476		for (j = i; --j >= 0;)
477			if (strcmp(unique[j], chipset->name) == 0)
478				break;
479		if (j < 0) {
480			int name_len = strlen(chipset->name);
481			if (i != 0) {
482				xf86ErrorF(",");
483				len++;
484				if (len + 2 + name_len < 78) {
485					xf86ErrorF(" ");
486					len++;
487				} else {
488					xf86ErrorF("\n\t");
489					len = 8;
490				}
491			}
492			xf86ErrorF("%s", chipset->name);
493			len += name_len;
494
495			if (i == size) {
496				const char **new_unique;
497
498				if (unique == stack)
499					new_unique = malloc(2*sizeof(*unique)*size);
500				else
501					new_unique = realloc(unique, 2*sizeof(*unique)*size);
502				if (new_unique != NULL) {
503					if (unique == stack)
504						memcpy(new_unique, stack,
505						       sizeof(stack));
506					unique = new_unique;
507					size *= 2;
508				}
509			}
510			if (i < size)
511				unique[i++] = chipset->name;
512		}
513	}
514	xf86ErrorF("\n");
515	if (unique != stack)
516		free(unique);
517
518	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) HD Graphics\n");
519	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Graphics\n");
520	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Pro Graphics\n");
521}
522
523static Bool intel_driver_func(ScrnInfoPtr pScrn,
524			      xorgDriverFuncOp op,
525			      pointer ptr)
526{
527	xorgHWFlags *flag;
528
529	switch (op) {
530	case GET_REQUIRED_HW_INTERFACES:
531		flag = (CARD32*)ptr;
532		(*flag) = 0;
533#if UMS
534		(*flag) = HW_IO | HW_MMIO;
535#endif
536#ifdef HW_SKIP_CONSOLE
537		if (hosted())
538			(*flag) = HW_SKIP_CONSOLE;
539#endif
540
541		return TRUE;
542
543#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0)
544	case SUPPORTS_SERVER_FDS:
545		return TRUE;
546#endif
547
548	default:
549		/* Unknown or deprecated function */
550		return FALSE;
551	}
552}
553
554#if KMS
555extern XF86ConfigPtr xf86configptr;
556
557static XF86ConfDevicePtr
558_xf86findDriver(const char *ident, XF86ConfDevicePtr p)
559{
560	while (p) {
561		if (p->dev_driver && xf86nameCompare(ident, p->dev_driver) == 0)
562			return p;
563
564		p = p->list.next;
565	}
566
567	return NULL;
568}
569
570static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(enum accel_method accel_method)
571{
572	XF86ConfDevicePtr dev;
573
574	if (hosted())
575		return SNA;
576
577	if (xf86configptr == NULL) /* X -configure */
578		return SNA;
579
580	dev = _xf86findDriver("intel", xf86configptr->conf_device_lst);
581	if (dev && dev->dev_option_lst) {
582		const char *s;
583
584		s = xf86FindOptionValue(dev->dev_option_lst, "AccelMethod");
585		if (s ) {
586			if (strcasecmp(s, "none") == 0)
587				accel_method = NOACCEL;
588			else if (strcasecmp(s, "sna") == 0)
589				accel_method = SNA;
590			else if (strcasecmp(s, "uxa") == 0)
591				accel_method = UXA;
592		}
593	}
594
595	return accel_method;
596}
597#endif
598
599static Bool
600intel_scrn_create(DriverPtr		driver,
601		  int			entity_num,
602		  intptr_t		match_data,
603		  unsigned		flags)
604{
605	ScrnInfoPtr scrn;
606
607	if (match_data == 0) {
608		int devid = intel_entity_get_devid(entity_num), i;
609		if (devid == 0)
610			return FALSE;
611
612		for (i = 0; intel_device_match[i].device_id != 0; i++) {
613			if (devid == intel_device_match[i].device_id) {
614				match_data = (intptr_t)&intel_device_match[i];
615				break;
616			}
617		}
618
619		if (match_data == 0)
620			return FALSE;
621	}
622
623	scrn = xf86AllocateScreen(driver, flags);
624	if (scrn == NULL)
625		return FALSE;
626
627	scrn->driverVersion = INTEL_VERSION;
628	scrn->driverName = (char *)INTEL_DRIVER_NAME;
629	scrn->name = (char *)INTEL_NAME;
630	scrn->driverPrivate = (void *)(match_data | (flags & XF86_ALLOCATE_GPU_SCREEN) | 2);
631	scrn->Probe = NULL;
632
633	if (xf86IsEntitySharable(entity_num))
634		xf86SetEntityShared(entity_num);
635	xf86AddEntityToScreen(scrn, entity_num);
636
637#if UMS
638	if ((unsigned)((struct intel_device_info *)match_data)->gen < 020)
639		return lg_i810_init(scrn);
640#endif
641
642#if KMS
643	enum accel_method default_accel_method = DEFAULT_ACCEL_METHOD;
644	/*
645	 * XXX
646	 * Use UXA by default for Gen3/4/5 chipsets (except 915) to avoid
647	 * screen corruption etc.  (PR/54995, PR/55198)
648	 */
649	if ((unsigned)((struct intel_device_info *)match_data)->gen > 030 &&
650	    (unsigned)((struct intel_device_info *)match_data)->gen < 060)
651		default_accel_method = UXA;
652
653	switch (get_accel_method(default_accel_method)) {
654#if USE_SNA
655	case NOACCEL:
656	case SNA:
657		return sna_init_scrn(scrn, entity_num);
658#endif
659#if USE_UXA
660#if !USE_SNA
661	case NOACCEL:
662#endif
663	case UXA:
664		return intel_init_scrn(scrn);
665#endif
666
667	default:
668#if USE_SNA
669		return sna_init_scrn(scrn, entity_num);
670#elif USE_UXA
671		return intel_init_scrn(scrn);
672#else
673		break;
674#endif
675	}
676#endif
677
678	return FALSE;
679}
680
681/*
682 * intel_pci_probe --
683 *
684 * Look through the PCI bus to find cards that are intel boards.
685 * Setup the dispatch table for the rest of the driver functions.
686 *
687 */
688static Bool intel_pci_probe(DriverPtr		driver,
689			    int			entity_num,
690			    struct pci_device	*pci,
691			    intptr_t		match_data)
692{
693	Bool ret;
694
695	if (intel_open_device(entity_num, pci, NULL) == -1) {
696#if UMS
697		switch (pci->device_id) {
698		case PCI_CHIP_I810:
699		case PCI_CHIP_I810_DC100:
700		case PCI_CHIP_I810_E:
701		case PCI_CHIP_I815:
702			if (!hosted())
703				break;
704		default:
705			return FALSE;
706		}
707#else
708		return FALSE;
709#endif
710	}
711
712	ret = intel_scrn_create(driver, entity_num, match_data, 0);
713	if (!ret)
714		intel_close_device(entity_num);
715
716	return ret;
717}
718
719#ifdef XSERVER_PLATFORM_BUS
720static Bool
721intel_platform_probe(DriverPtr driver,
722		     int entity_num, int flags,
723		     struct xf86_platform_device *dev,
724		     intptr_t match_data)
725{
726	unsigned scrn_flags = 0;
727
728	if (intel_open_device(entity_num, dev->pdev, dev) == -1)
729		return FALSE;
730
731	/* Allow ourselves to act as a slaved output if not primary */
732	if (flags & PLATFORM_PROBE_GPU_SCREEN) {
733		flags &= ~PLATFORM_PROBE_GPU_SCREEN;
734		scrn_flags |= XF86_ALLOCATE_GPU_SCREEN;
735	}
736
737	/* if we get any flags we don't understand fail to probe for now */
738	if (flags)
739		goto err;
740
741	if (!intel_scrn_create(driver, entity_num, match_data, scrn_flags))
742		goto err;
743
744	return TRUE;
745
746err:
747	intel_close_device(entity_num);
748	return FALSE;
749}
750#endif
751
752#ifdef XFree86LOADER
753
754static MODULESETUPPROTO(intel_setup);
755
756static XF86ModuleVersionInfo intel_version = {
757	"intel",
758	MODULEVENDORSTRING,
759	MODINFOSTRING1,
760	MODINFOSTRING2,
761	XORG_VERSION_CURRENT,
762	INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
763	ABI_CLASS_VIDEODRV,
764	ABI_VIDEODRV_VERSION,
765	MOD_CLASS_VIDEODRV,
766	{0, 0, 0, 0}
767};
768
769static const OptionInfoRec *
770intel_available_options(int chipid, int busid)
771{
772	switch (chipid) {
773#if UMS
774	case PCI_CHIP_I810:
775	case PCI_CHIP_I810_DC100:
776	case PCI_CHIP_I810_E:
777	case PCI_CHIP_I815:
778		return lg_i810_available_options(chipid, busid);
779#endif
780
781	default:
782		return intel_options;
783	}
784}
785
786static DriverRec intel = {
787	INTEL_VERSION,
788	(char *)INTEL_DRIVER_NAME,
789	intel_identify,
790	NULL,
791	intel_available_options,
792	NULL,
793	0,
794	intel_driver_func,
795	intel_device_match,
796	intel_pci_probe,
797#ifdef XSERVER_PLATFORM_BUS
798	intel_platform_probe
799#endif
800};
801
802static pointer intel_setup(pointer module,
803			   pointer opts,
804			   int *errmaj,
805			   int *errmin)
806{
807	static Bool setupDone = 0;
808
809	/* This module should be loaded only once, but check to be sure.
810	*/
811	if (!setupDone) {
812		setupDone = 1;
813		xf86AddDriver(&intel, module, HaveDriverFuncs);
814
815		/*
816		 * The return value must be non-NULL on success even though there
817		 * is no TearDownProc.
818		 */
819		return (pointer) 1;
820	} else {
821		if (errmaj)
822			*errmaj = LDR_ONCEONLY;
823		return NULL;
824	}
825}
826
827_X_EXPORT XF86ModuleData intelModuleData = { &intel_version, intel_setup, NULL };
828#endif
829