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
129
130static const SymTabRec intel_chipsets[] = {
131	{PCI_CHIP_I810,				"i810"},
132	{PCI_CHIP_I810_DC100,			"i810-dc100"},
133	{PCI_CHIP_I810_E,			"i810e"},
134	{PCI_CHIP_I815,				"i815"},
135	{PCI_CHIP_I830_M,			"i830M"},
136	{PCI_CHIP_845_G,			"845G"},
137	{PCI_CHIP_I854,				"854"},
138	{PCI_CHIP_I855_GM,			"852GM/855GM"},
139	{PCI_CHIP_I865_G,			"865G"},
140	{PCI_CHIP_I915_G,			"915G"},
141	{PCI_CHIP_E7221_G,			"E7221 (i915)"},
142	{PCI_CHIP_I915_GM,			"915GM"},
143	{PCI_CHIP_I945_G,			"945G"},
144	{PCI_CHIP_I945_GM,			"945GM"},
145	{PCI_CHIP_I945_GME,			"945GME"},
146	{PCI_CHIP_PINEVIEW_M,			"Pineview GM"},
147	{PCI_CHIP_PINEVIEW_G,			"Pineview G"},
148	{PCI_CHIP_I965_G,			"965G"},
149	{PCI_CHIP_G35_G,			"G35"},
150	{PCI_CHIP_I965_Q,			"965Q"},
151	{PCI_CHIP_I946_GZ,			"946GZ"},
152	{PCI_CHIP_I965_GM,			"965GM"},
153	{PCI_CHIP_I965_GME,			"965GME/GLE"},
154	{PCI_CHIP_G33_G,			"G33"},
155	{PCI_CHIP_Q35_G,			"Q35"},
156	{PCI_CHIP_Q33_G,			"Q33"},
157	{PCI_CHIP_GM45_GM,			"GM45"},
158	{PCI_CHIP_G45_E_G,			"4 Series"},
159	{PCI_CHIP_G45_G,			"G45/G43"},
160	{PCI_CHIP_Q45_G,			"Q45/Q43"},
161	{PCI_CHIP_G41_G,			"G41"},
162	{PCI_CHIP_B43_G,			"B43"},
163	{PCI_CHIP_B43_G1,			"B43"},
164
165	{0, ""},
166
167	{PCI_CHIP_IRONLAKE_D_G,			"HD Graphics"},
168	{PCI_CHIP_IRONLAKE_M_G,			"HD Graphics"},
169	{PCI_CHIP_SANDYBRIDGE_GT1,		"HD Graphics 2000" },
170	{PCI_CHIP_SANDYBRIDGE_GT2,		"HD Graphics 3000" },
171	{PCI_CHIP_SANDYBRIDGE_GT2_PLUS,		"HD Graphics 3000" },
172	{PCI_CHIP_SANDYBRIDGE_M_GT1,		"HD Graphics 2000" },
173	{PCI_CHIP_SANDYBRIDGE_M_GT2,		"HD Graphics 3000" },
174	{PCI_CHIP_SANDYBRIDGE_M_GT2_PLUS,	"HD Graphics 3000" },
175	{PCI_CHIP_SANDYBRIDGE_S_GT,		"HD Graphics" },
176	{PCI_CHIP_IVYBRIDGE_M_GT1,		"HD Graphics 2500" },
177	{PCI_CHIP_IVYBRIDGE_M_GT2,		"HD Graphics 4000" },
178	{PCI_CHIP_IVYBRIDGE_D_GT1,		"HD Graphics 2500" },
179	{PCI_CHIP_IVYBRIDGE_D_GT2,		"HD Graphics 4000" },
180	{PCI_CHIP_IVYBRIDGE_S_GT1,		"HD Graphics" },
181	{PCI_CHIP_IVYBRIDGE_S_GT2,		"HD Graphics P4000" },
182	{PCI_CHIP_HASWELL_D_GT1,		"HD Graphics" },
183	{PCI_CHIP_HASWELL_D_GT2,		"HD Graphics 4600" },
184	{PCI_CHIP_HASWELL_D_GT3,		"HD Graphics 5000" }, /* ??? */
185	{PCI_CHIP_HASWELL_M_GT1,		"HD Graphics" },
186	{PCI_CHIP_HASWELL_M_GT2,		"HD Graphics 4600" },
187	{PCI_CHIP_HASWELL_M_GT3,		"HD Graphics 5000" }, /* ??? */
188	{PCI_CHIP_HASWELL_S_GT1,		"HD Graphics" },
189	{PCI_CHIP_HASWELL_S_GT2,		"HD Graphics P4600/P4700" },
190	{PCI_CHIP_HASWELL_S_GT3,		"HD Graphics 5000" }, /* ??? */
191	{PCI_CHIP_HASWELL_B_GT1,		"HD Graphics" }, /* ??? */
192	{PCI_CHIP_HASWELL_B_GT2,		"HD Graphics" }, /* ??? */
193	{PCI_CHIP_HASWELL_B_GT3,		"HD Graphics" }, /* ??? */
194	{PCI_CHIP_HASWELL_E_GT1,		"HD Graphics" },
195	{PCI_CHIP_HASWELL_E_GT2,		"HD Graphics" }, /* ??? */
196	{PCI_CHIP_HASWELL_E_GT3,		"HD Graphics" }, /* ??? */
197	{PCI_CHIP_HASWELL_ULT_D_GT1,		"HD Graphics" }, /* ??? */
198	{PCI_CHIP_HASWELL_ULT_D_GT2,		"HD Graphics" }, /* ??? */
199	{PCI_CHIP_HASWELL_ULT_D_GT3,		"Iris(TM) Graphics 5100" },
200	{PCI_CHIP_HASWELL_ULT_M_GT1,		"HD Graphics" },
201	{PCI_CHIP_HASWELL_ULT_M_GT2,		"HD Graphics 4400" },
202	{PCI_CHIP_HASWELL_ULT_M_GT3,		"HD Graphics 5000" },
203	{PCI_CHIP_HASWELL_ULT_S_GT1,		"HD Graphics" }, /* ??? */
204	{PCI_CHIP_HASWELL_ULT_S_GT2,		"HD Graphics" }, /* ??? */
205	{PCI_CHIP_HASWELL_ULT_S_GT3,		"Iris(TM) Graphics 5100" },
206	{PCI_CHIP_HASWELL_ULT_B_GT1,		"HD Graphics" }, /* ??? */
207	{PCI_CHIP_HASWELL_ULT_B_GT2,		"HD Graphics" }, /* ??? */
208	{PCI_CHIP_HASWELL_ULT_B_GT3,		"Iris(TM) Graphics 5100" },
209	{PCI_CHIP_HASWELL_ULT_E_GT1,		"HD Graphics" },
210	{PCI_CHIP_HASWELL_ULT_E_GT2,		"HD Graphics 4200" },
211	{PCI_CHIP_HASWELL_ULT_E_GT3,		"Iris(TM) Graphics 5100" },
212	{PCI_CHIP_HASWELL_CRW_D_GT1,		"HD Graphics" }, /* ??? */
213	{PCI_CHIP_HASWELL_CRW_D_GT2,		"HD Graphics 4600" },
214	{PCI_CHIP_HASWELL_CRW_D_GT3,		"Iris(TM) Pro Graphics 5200" },
215	{PCI_CHIP_HASWELL_CRW_M_GT1,		"HD Graphics" }, /* ??? */
216	{PCI_CHIP_HASWELL_CRW_M_GT2,		"HD Graphics 4600" },
217	{PCI_CHIP_HASWELL_CRW_M_GT3,		"Iris(TM) Pro Graphics 5200" },
218	{PCI_CHIP_HASWELL_CRW_S_GT1,		"HD Graphics" }, /* ??? */
219	{PCI_CHIP_HASWELL_CRW_S_GT2,		"HD Graphics" }, /* ??? */
220	{PCI_CHIP_HASWELL_CRW_S_GT3,		"Iris(TM) Pro Graphics 5200" },
221	{PCI_CHIP_HASWELL_CRW_B_GT1,		"HD Graphics" }, /* ??? */
222	{PCI_CHIP_HASWELL_CRW_B_GT2,		"HD Graphics" }, /* ??? */
223	{PCI_CHIP_HASWELL_CRW_B_GT3,		"Iris(TM) Pro Graphics 5200" },
224	{PCI_CHIP_HASWELL_CRW_E_GT1,		"HD Graphics" }, /* ??? */
225	{PCI_CHIP_HASWELL_CRW_E_GT2,		"HD Graphics" }, /* ??? */
226	{PCI_CHIP_HASWELL_CRW_E_GT3,		"Iris(TM) Pro Graphics 5200" },
227
228	/* Valleyview (Baytail) */
229	{0x0f30, "HD Graphics"},
230	{0x0f31, "HD Graphics"},
231	{0x0f32, "HD Graphics"},
232	{0x0f33, "HD Graphics"},
233	{0x0155, "HD Graphics"},
234	{0x0157, "HD Graphics"},
235
236	/* Broadwell Marketing names */
237	{0x1602, "HD graphics"},
238	{0x1606, "HD graphics"},
239	{0x160B, "HD graphics"},
240	{0x160A, "HD graphics"},
241	{0x160D, "HD graphics"},
242	{0x160E, "HD graphics"},
243	{0x1612, "HD graphics 5600"},
244	{0x1616, "HD graphics 5500"},
245	{0x161B, "HD graphics"},
246	{0x161A, "HD graphics"},
247	{0x161D, "HD graphics"},
248	{0x161E, "HD graphics 5300"},
249	{0x1622, "Iris Pro graphics 6200"},
250	{0x1626, "HD graphics 6000"},
251	{0x162B, "Iris graphics 6100"},
252	{0x162A, "Iris Pro graphics P6300"},
253	{0x162D, "HD graphics"},
254	{0x162E, "HD graphics"},
255	{0x1632, "HD graphics"},
256	{0x1636, "HD graphics"},
257	{0x163B, "HD graphics"},
258	{0x163A, "HD graphics"},
259	{0x163D, "HD graphics"},
260	{0x163E, "HD graphics"},
261
262	/* When adding new identifiers, also update:
263	 * 1. intel_identify()
264	 * 2. man/intel.man
265	 * 3. README
266	 */
267
268	{-1, NULL} /* Sentinel */
269};
270
271static const struct pci_id_match intel_device_match[] = {
272#if UMS
273	INTEL_VGA_DEVICE(PCI_CHIP_I810, &intel_i81x_info),
274	INTEL_VGA_DEVICE(PCI_CHIP_I810_DC100, &intel_i81x_info),
275	INTEL_VGA_DEVICE(PCI_CHIP_I810_E, &intel_i81x_info),
276	INTEL_VGA_DEVICE(PCI_CHIP_I815, &intel_i81x_info),
277#endif
278
279#if KMS
280	INTEL_I830_IDS(&intel_i830_info),
281	INTEL_I845G_IDS(&intel_i845_info),
282	INTEL_I85X_IDS(&intel_i855_info),
283	INTEL_I865G_IDS(&intel_i865_info),
284
285	INTEL_I915G_IDS(&intel_i915_info),
286	INTEL_I915GM_IDS(&intel_i915_info),
287	INTEL_I945G_IDS(&intel_i945_info),
288	INTEL_I945GM_IDS(&intel_i945_info),
289
290	INTEL_G33_IDS(&intel_g33_info),
291	INTEL_PINEVIEW_IDS(&intel_g33_info),
292
293	INTEL_I965G_IDS(&intel_i965_info),
294	INTEL_I965GM_IDS(&intel_i965_info),
295
296	INTEL_G45_IDS(&intel_g4x_info),
297	INTEL_GM45_IDS(&intel_g4x_info),
298
299	INTEL_IRONLAKE_D_IDS(&intel_ironlake_info),
300	INTEL_IRONLAKE_M_IDS(&intel_ironlake_info),
301
302	INTEL_SNB_D_IDS(&intel_sandybridge_info),
303	INTEL_SNB_M_IDS(&intel_sandybridge_info),
304
305	INTEL_IVB_D_IDS(&intel_ivybridge_info),
306	INTEL_IVB_M_IDS(&intel_ivybridge_info),
307
308	INTEL_HSW_D_IDS(&intel_haswell_info),
309	INTEL_HSW_M_IDS(&intel_haswell_info),
310
311	INTEL_VLV_D_IDS(&intel_valleyview_info),
312	INTEL_VLV_M_IDS(&intel_valleyview_info),
313
314	INTEL_BDW_D_IDS(&intel_broadwell_info),
315	INTEL_BDW_M_IDS(&intel_broadwell_info),
316
317	INTEL_CHV_IDS(&intel_cherryview_info),
318
319	INTEL_SKL_IDS(&intel_skylake_info),
320
321	INTEL_VGA_DEVICE(PCI_MATCH_ANY, &intel_generic_info),
322#endif
323
324	{ 0, 0, 0 },
325};
326
327void
328intel_detect_chipset(ScrnInfoPtr scrn, struct intel_device *dev)
329{
330	int devid;
331	const char *name = NULL;
332	int i;
333
334	if (dev == NULL) {
335		EntityInfoPtr ent;
336		struct pci_device *pci;
337
338		ent = xf86GetEntityInfo(scrn->entityList[0]);
339		if (ent->device->chipID >= 0) {
340			xf86DrvMsg(scrn->scrnIndex, X_CONFIG,
341				   "ChipID override: 0x%04X\n",
342				   ent->device->chipID);
343			devid = ent->device->chipID;
344		} else {
345			pci = xf86GetPciInfoForEntity(ent->index);
346			if (pci)
347				devid = pci->device_id;
348			else
349				devid = ~0;
350		}
351	} else
352		devid = intel_get_device_id(dev);
353
354	for (i = 0; intel_chipsets[i].name != NULL; i++) {
355		if (devid == intel_chipsets[i].token) {
356			name = intel_chipsets[i].name;
357			break;
358		}
359	}
360	if (name == NULL) {
361		int gen = 0;
362
363		for (i = 0; intel_device_match[i].device_id != 0; i++) {
364			if (devid == intel_device_match[i].device_id) {
365				const struct intel_device_info *info = (void *)intel_device_match[i].match_data;
366				gen = info->gen >> 3;
367				break;
368			}
369		}
370
371		if (gen) {
372			xf86DrvMsg(scrn->scrnIndex, X_PROBED,
373				   "gen%d engineering sample\n", gen);
374		} else {
375			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
376				   "Unknown chipset\n");
377		}
378
379		name = "unknown";
380	} else {
381		xf86DrvMsg(scrn->scrnIndex, X_PROBED,
382			   "Integrated Graphics Chipset: Intel(R) %s\n",
383			   name);
384	}
385
386	scrn->chipset = (char *)name;
387}
388
389/*
390 * intel_identify --
391 *
392 * Returns the string name for the driver based on the chipset.
393 *
394 */
395static void intel_identify(int flags)
396{
397	const SymTabRec *chipset;
398	const char *stack[64], **unique;
399	int i, j, size, len;
400
401	unique = stack;
402	size = sizeof(stack)/sizeof(stack[0]);
403	i = 0;
404
405	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Integrated Graphics Chipsets:\n\t");
406	len = 8;
407
408	for (chipset = intel_chipsets; chipset->token; chipset++) {
409		for (j = i; --j >= 0;)
410			if (strcmp(unique[j], chipset->name) == 0)
411				break;
412		if (j < 0) {
413			int name_len = strlen(chipset->name);
414			if (i != 0) {
415				xf86ErrorF(",");
416				len++;
417				if (len + 2 + name_len < 78) {
418					xf86ErrorF(" ");
419					len++;
420				} else {
421					xf86ErrorF("\n\t");
422					len = 8;
423				}
424			}
425			xf86ErrorF("%s", chipset->name);
426			len += name_len;
427
428			if (i == size) {
429				const char **new_unique;
430
431				if (unique == stack)
432					new_unique = malloc(2*sizeof(*unique)*size);
433				else
434					new_unique = realloc(unique, 2*sizeof(*unique)*size);
435				if (new_unique != NULL) {
436					if (unique == stack)
437						memcpy(new_unique, stack,
438						       sizeof(stack));
439					unique = new_unique;
440					size *= 2;
441				}
442			}
443			if (i < size)
444				unique[i++] = chipset->name;
445		}
446	}
447	xf86ErrorF("\n");
448	if (unique != stack)
449		free(unique);
450
451	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) HD Graphics: 2000-6000\n");
452	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Graphics: 5100, 6100\n");
453	xf86Msg(X_INFO, INTEL_NAME ": Driver for Intel(R) Iris(TM) Pro Graphics: 5200, 6200, P6300\n");
454}
455
456static Bool intel_driver_func(ScrnInfoPtr pScrn,
457			      xorgDriverFuncOp op,
458			      pointer ptr)
459{
460	xorgHWFlags *flag;
461
462	switch (op) {
463	case GET_REQUIRED_HW_INTERFACES:
464		flag = (CARD32*)ptr;
465		(*flag) = 0;
466#if UMS
467		(*flag) = HW_IO | HW_MMIO;
468#endif
469#ifdef HW_SKIP_CONSOLE
470		if (hosted())
471			(*flag) = HW_SKIP_CONSOLE;
472#endif
473
474		return TRUE;
475
476#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0)
477	case SUPPORTS_SERVER_FDS:
478		return TRUE;
479#endif
480
481	default:
482		/* Unknown or deprecated function */
483		return FALSE;
484	}
485}
486
487#if KMS
488extern XF86ConfigPtr xf86configptr;
489
490static XF86ConfDevicePtr
491_xf86findDriver(const char *ident, XF86ConfDevicePtr p)
492{
493	while (p) {
494		if (p->dev_driver && xf86nameCompare(ident, p->dev_driver) == 0)
495			return p;
496
497		p = p->list.next;
498	}
499
500	return NULL;
501}
502
503static enum accel_method { NOACCEL, SNA, UXA } get_accel_method(void)
504{
505	enum accel_method accel_method = DEFAULT_ACCEL_METHOD;
506	XF86ConfDevicePtr dev;
507
508	if (hosted())
509		return SNA;
510
511	dev = _xf86findDriver("intel", xf86configptr->conf_device_lst);
512	if (dev && dev->dev_option_lst) {
513		const char *s;
514
515		s = xf86FindOptionValue(dev->dev_option_lst, "AccelMethod");
516		if (s ) {
517			if (strcasecmp(s, "none") == 0)
518				accel_method = NOACCEL;
519			else if (strcasecmp(s, "sna") == 0)
520				accel_method = SNA;
521			else if (strcasecmp(s, "uxa") == 0)
522				accel_method = UXA;
523		}
524	}
525
526	return accel_method;
527}
528#endif
529
530static Bool
531intel_scrn_create(DriverPtr		driver,
532		  int			entity_num,
533		  intptr_t		match_data,
534		  unsigned		flags)
535{
536	ScrnInfoPtr scrn;
537
538	if (match_data == 0) {
539		int devid = intel_entity_get_devid(entity_num), i;
540		if (devid == 0)
541			return FALSE;
542
543		for (i = 0; intel_device_match[i].device_id != 0; i++) {
544			if (devid == intel_device_match[i].device_id) {
545				match_data = (intptr_t)&intel_device_match[i];
546				break;
547			}
548		}
549
550		if (match_data == 0)
551			return FALSE;
552	}
553
554	scrn = xf86AllocateScreen(driver, flags);
555	if (scrn == NULL)
556		return FALSE;
557
558	scrn->driverVersion = INTEL_VERSION;
559	scrn->driverName = (char *)INTEL_DRIVER_NAME;
560	scrn->name = (char *)INTEL_NAME;
561	scrn->driverPrivate = (void *)(match_data | (flags & XF86_ALLOCATE_GPU_SCREEN) | 2);
562	scrn->Probe = NULL;
563
564	if (xf86IsEntitySharable(entity_num))
565		xf86SetEntityShared(entity_num);
566	xf86AddEntityToScreen(scrn, entity_num);
567
568#if UMS
569	if ((unsigned)((struct intel_device_info *)match_data)->gen < 020)
570		return lg_i810_init(scrn);
571#endif
572
573#if KMS
574	switch (get_accel_method()) {
575#if USE_SNA
576	case NOACCEL:
577	case SNA:
578		return sna_init_scrn(scrn, entity_num);
579#endif
580#if USE_UXA
581#if !USE_SNA
582	case NOACCEL:
583#endif
584	case UXA:
585		  return intel_init_scrn(scrn);
586#endif
587
588	default: break;
589	}
590#endif
591
592	return FALSE;
593}
594
595/*
596 * intel_pci_probe --
597 *
598 * Look through the PCI bus to find cards that are intel boards.
599 * Setup the dispatch table for the rest of the driver functions.
600 *
601 */
602static Bool intel_pci_probe(DriverPtr		driver,
603			    int			entity_num,
604			    struct pci_device	*pci,
605			    intptr_t		match_data)
606{
607	if (intel_open_device(entity_num, pci, NULL) == -1) {
608#if UMS
609		switch (pci->device_id) {
610		case PCI_CHIP_I810:
611		case PCI_CHIP_I810_DC100:
612		case PCI_CHIP_I810_E:
613		case PCI_CHIP_I815:
614			if (!hosted())
615				break;
616		default:
617			return FALSE;
618		}
619#else
620		return FALSE;
621#endif
622	}
623
624	return intel_scrn_create(driver, entity_num, match_data, 0);
625}
626
627#ifdef XSERVER_PLATFORM_BUS
628static Bool
629intel_platform_probe(DriverPtr driver,
630		     int entity_num, int flags,
631		     struct xf86_platform_device *dev,
632		     intptr_t match_data)
633{
634	unsigned scrn_flags = 0;
635
636	if (intel_open_device(entity_num, dev->pdev, dev) == -1)
637		return FALSE;
638
639	/* Allow ourselves to act as a slaved output if not primary */
640	if (flags & PLATFORM_PROBE_GPU_SCREEN) {
641		flags &= ~PLATFORM_PROBE_GPU_SCREEN;
642		scrn_flags |= XF86_ALLOCATE_GPU_SCREEN;
643	}
644
645	/* if we get any flags we don't understand fail to probe for now */
646	if (flags)
647		return FALSE;
648
649	return intel_scrn_create(driver, entity_num, match_data, scrn_flags);
650}
651#endif
652
653#ifdef XFree86LOADER
654
655static MODULESETUPPROTO(intel_setup);
656
657static XF86ModuleVersionInfo intel_version = {
658	"intel",
659	MODULEVENDORSTRING,
660	MODINFOSTRING1,
661	MODINFOSTRING2,
662	XORG_VERSION_CURRENT,
663	INTEL_VERSION_MAJOR, INTEL_VERSION_MINOR, INTEL_VERSION_PATCH,
664	ABI_CLASS_VIDEODRV,
665	ABI_VIDEODRV_VERSION,
666	MOD_CLASS_VIDEODRV,
667	{0, 0, 0, 0}
668};
669
670static const OptionInfoRec *
671intel_available_options(int chipid, int busid)
672{
673	switch (chipid) {
674#if UMS
675	case PCI_CHIP_I810:
676	case PCI_CHIP_I810_DC100:
677	case PCI_CHIP_I810_E:
678	case PCI_CHIP_I815:
679		return lg_i810_available_options(chipid, busid);
680#endif
681
682	default:
683		return intel_options;
684	}
685}
686
687static DriverRec intel = {
688	INTEL_VERSION,
689	(char *)INTEL_DRIVER_NAME,
690	intel_identify,
691	NULL,
692	intel_available_options,
693	NULL,
694	0,
695	intel_driver_func,
696	intel_device_match,
697	intel_pci_probe,
698#ifdef XSERVER_PLATFORM_BUS
699	intel_platform_probe
700#endif
701};
702
703static pointer intel_setup(pointer module,
704			   pointer opts,
705			   int *errmaj,
706			   int *errmin)
707{
708	static Bool setupDone = 0;
709
710	/* This module should be loaded only once, but check to be sure.
711	*/
712	if (!setupDone) {
713		setupDone = 1;
714		xf86AddDriver(&intel, module, HaveDriverFuncs);
715
716		/*
717		 * The return value must be non-NULL on success even though there
718		 * is no TearDownProc.
719		 */
720		return (pointer) 1;
721	} else {
722		if (errmaj)
723			*errmaj = LDR_ONCEONLY;
724		return NULL;
725	}
726}
727
728_X_EXPORT XF86ModuleData intelModuleData = { &intel_version, intel_setup, NULL };
729#endif
730