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