diff mbox series

[libdrm,1/4] intel: add IS_GENX() generic macro

Message ID 20180824235649.19444-2-lucas.demarchi@intel.com (mailing list archive)
State New, archived
Headers show
Series intel: rework how we add PCI IDs | expand

Commit Message

Lucas De Marchi Aug. 24, 2018, 11:56 p.m. UTC
This will allow platforms to reuse kernel IDs instead of manually
keeping them in sync. In most of the cases we only need to extend
IS_9XX().  Current platforms that fit this requirement can be ported
over to use this macro.

The i915_pciids.h header is in sync with kernel tree on
drm-tip 2018y-08m-20d-21h-41m-11s.

Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 intel/i915_pciids.h   | 461 ++++++++++++++++++++++++++++++++++++++++++
 intel/intel_chipset.h |  20 ++
 2 files changed, 481 insertions(+)
 create mode 100644 intel/i915_pciids.h

Comments

Chris Wilson Aug. 25, 2018, 9:35 a.m. UTC | #1
Quoting Lucas De Marchi (2018-08-25 00:56:46)
> diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
> index 4a34b7be..8a0e3e76 100644
> --- a/intel/intel_chipset.h
> +++ b/intel/intel_chipset.h
> @@ -568,6 +568,26 @@
>  
>  #define IS_GEN11(devid)                (IS_ICELAKE_11(devid))
>  
> +/* New platforms use kernel pci ids */
> +#include "i915_pciids.h"
> +
> +struct pci_device_id {

Don't call it pci_device_id, depending on caller that name may already
be taken by libpciaccess.

> +       uint32_t unused0, device;
> +       uint32_t unused1, unused2;
> +       uint32_t unused3, unused4;
These are all uint16_t.

> +       unsigned long unused5;

Simply make the unused disappear from the macro.

> +};
> +
> +#define IS_GENX(x, devid) ({ \
> +       struct pci_device_id __ids[] = { INTEL_ ## x ## _IDS(0) };      \

While that's a neat trick it's instantiating the array for each caller,
and it does appear that we repeat a few of the macros.

The best I can offer to keep the change non-invasive (other than just
switching to a platform bitmask and filling (devid, gen, platform) from
the pci match data on initialisation) is a two pass approach.

static inline int __find_in_pciid(uint16_t devid,
	const struct pci_device_id *ids, size_t count)
{
	size_t i = 0; /* we should rethink this if we think there are more than 4B of them! */
	for (i = 0; i < count; i++) {
		if (ids[i].device == devid)
			return 1;
	}
	return 0;
}


#define __is_genx(x) \
static inline int __is_gen##x(uint16_t devid) \
{ \
	static const struct pci_device_id __ids[] = { INTEL_ ## x ## _IDS(0) }; \
	return __find_in_pciid(devid, __ids, sizeof(__ids)/sizeof(__ids[0]); \
}
__is_genx(3);
__is_genx(4);
__is_genx(5);
__is_genx(6);
__is_genx(7);
__is_genx(8);
__is_genx(9);
__is_genx(10);
__is_genx(11);

#define IS_GENX(x, devid) __is_gen##x(devid)

That should help cut down the object size expansion. But longer term I'd
prefer if we moved to towards finding the match data once. Also we need
to pull into the canonical header the friendly names for mesa.
-Chris
Lucas De Marchi Aug. 27, 2018, 9:19 p.m. UTC | #2
On Sat, Aug 25, 2018 at 10:35:23AM +0100, Chris Wilson wrote:
> Quoting Lucas De Marchi (2018-08-25 00:56:46)
> > diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
> > index 4a34b7be..8a0e3e76 100644
> > --- a/intel/intel_chipset.h
> > +++ b/intel/intel_chipset.h
> > @@ -568,6 +568,26 @@
> >  
> >  #define IS_GEN11(devid)                (IS_ICELAKE_11(devid))
> >  
> > +/* New platforms use kernel pci ids */
> > +#include "i915_pciids.h"
> > +
> > +struct pci_device_id {
> 
> Don't call it pci_device_id, depending on caller that name may already
> be taken by libpciaccess.

ok. I can actually move it inside the function/macro and use an
autogenerated name.

> 
> > +       uint32_t unused0, device;
> > +       uint32_t unused1, unused2;
> > +       uint32_t unused3, unused4;
> These are all uint16_t.

kernel "document" them as uint32_t:

/*
 * A pci_device_id struct {
 *      __u32 vendor, device;
 *      __u32 subvendor, subdevice;
 *      __u32 class, class_mask;
 *      kernel_ulong_t driver_data;
 * };
 * Don't use C99 here because "class" is reserved and we want to
 * give userspace flexibility.


> 
> > +       unsigned long unused5;
> 
> Simply make the unused disappear from the macro.
> 
> > +};
> > +
> > +#define IS_GENX(x, devid) ({ \
> > +       struct pci_device_id __ids[] = { INTEL_ ## x ## _IDS(0) };      \
> 
> While that's a neat trick it's instantiating the array for each caller,
> and it does appear that we repeat a few of the macros.
> 
> The best I can offer to keep the change non-invasive (other than just
> switching to a platform bitmask and filling (devid, gen, platform) from
> the pci match data on initialisation) is a two pass approach.
> 
> static inline int __find_in_pciid(uint16_t devid,
> 	const struct pci_device_id *ids, size_t count)
> {
> 	size_t i = 0; /* we should rethink this if we think there are more than 4B of them! */
> 	for (i = 0; i < count; i++) {
> 		if (ids[i].device == devid)
> 			return 1;
> 	}
> 	return 0;
> }
> 
> 
> #define __is_genx(x) \

here I would name this DEFINE_IS_GENX, since it's a macro to define
the functions, not to be used in other places.

> static inline int __is_gen##x(uint16_t devid) \
> { \
> 	static const struct pci_device_id __ids[] = { INTEL_ ## x ## _IDS(0) }; \
> 	return __find_in_pciid(devid, __ids, sizeof(__ids)/sizeof(__ids[0]); \
> }
> __is_genx(3);
> __is_genx(4);
> __is_genx(5);
> __is_genx(6);
> __is_genx(7);
> __is_genx(8);
> __is_genx(9);
> __is_genx(10);
> __is_genx(11);
> 
> #define IS_GENX(x, devid) __is_gen##x(devid)

i915_pciids.h is not consistent with how the macros are called. See that
in my patch. So here I'd have:

#define DEFINE_IS_GENX(x, pfx) \
static inline int __is_gen##x(uint16_t devid) \
{ \
	static const struct pci_device_id __ids[] = { INTEL_ ## pfx ## _IDS(0) }; \
	return __find_in_pciid(devid, __ids, sizeof(__ids)/sizeof(__ids[0]); \
}

#define IS_GEN10(devid) IS_GENX(10, CNL, devid)

For gen9 is more complicated as it needs several ids.


> 
> That should help cut down the object size expansion. But longer term I'd

I'm not opposed to turning it into inline function, but if the goal is
to reduce the object size expansion, just making the array static const
should suffice... we do call the macros several times, but most of the
size is for constructing the array, not to find the elements.


> prefer if we moved to towards finding the match data once. Also we need
> to pull into the canonical header the friendly names for mesa.

what do you mean by "friendly names for mesa".

The other option that is actually my preferred is to let the kernel tell
user space what it is.  What do you think about having an ioctl that returns
what is the gen + additional interesting info?  Then user space could
base its decisions on features and fallback to gen version when there
isn't a way to discover if a feature/bug is present.  This would allow
to simply remove the pci ids from user space projects which IMO would be
a good thing.

Lucas De Marchi

> -Chris
Chris Wilson Aug. 27, 2018, 9:40 p.m. UTC | #3
Quoting Lucas De Marchi (2018-08-27 22:19:54)
> On Sat, Aug 25, 2018 at 10:35:23AM +0100, Chris Wilson wrote:
> > Quoting Lucas De Marchi (2018-08-25 00:56:46)
> > That should help cut down the object size expansion. But longer term I'd
> 
> I'm not opposed to turning it into inline function, but if the goal is
> to reduce the object size expansion, just making the array static const
> should suffice... we do call the macros several times, but most of the
> size is for constructing the array, not to find the elements.

It'll construct the array on the stack, painfully. I thought you were
trying for a minimal change :)

> > prefer if we moved to towards finding the match data once. Also we need
> > to pull into the canonical header the friendly names for mesa.
> 
> what do you mean by "friendly names for mesa".
> 
> The other option that is actually my preferred is to let the kernel tell
> user space what it is.  What do you think about having an ioctl that returns
> what is the gen + additional interesting info?  Then user space could
> base its decisions on features and fallback to gen version when there
> isn't a way to discover if a feature/bug is present.  This would allow
> to simply remove the pci ids from user space projects which IMO would be
> a good thing.

There simply wasn't enough interest. The key point is selling it to
mesa, see include/pci_ids/i965_pci_ids.h

The challenge with the centralised db of interesting info is that it
will always be out of date for userspace (think userspace having to cope
with a 5 year kernel, and a kernel having to cope with 10 year old
userspace) and never enough so they still have to supplement it without
their own db.

That isn't to say that there isn't a lot of interesting hw properties
that userspace needs to know, but they are also tend to be the ones tied
to fuses and not pciid.

What we do all duplicate are the pci-ids, so pulling those into a
central header containing the commonly used per-id information in a format
that can be embedded into any of the caller's structs is challenge
enough.
-Chris
Lucas De Marchi Aug. 27, 2018, 11:15 p.m. UTC | #4
On Mon, Aug 27, 2018 at 10:40:28PM +0100, Chris Wilson wrote:
> Quoting Lucas De Marchi (2018-08-27 22:19:54)
> > On Sat, Aug 25, 2018 at 10:35:23AM +0100, Chris Wilson wrote:
> > > Quoting Lucas De Marchi (2018-08-25 00:56:46)
> > > That should help cut down the object size expansion. But longer term I'd
> > 
> > I'm not opposed to turning it into inline function, but if the goal is
> > to reduce the object size expansion, just making the array static const
> > should suffice... we do call the macros several times, but most of the
> > size is for constructing the array, not to find the elements.
> 
> It'll construct the array on the stack, painfully. I thought you were
> trying for a minimal change :)

the way I meant it it won't construct in the stack.

> 
> > > prefer if we moved to towards finding the match data once. Also we need
> > > to pull into the canonical header the friendly names for mesa.
> > 
> > what do you mean by "friendly names for mesa".
> > 
> > The other option that is actually my preferred is to let the kernel tell
> > user space what it is.  What do you think about having an ioctl that returns
> > what is the gen + additional interesting info?  Then user space could
> > base its decisions on features and fallback to gen version when there
> > isn't a way to discover if a feature/bug is present.  This would allow
> > to simply remove the pci ids from user space projects which IMO would be
> > a good thing.
> 
> There simply wasn't enough interest. The key point is selling it to
> mesa, see include/pci_ids/i965_pci_ids.h
> 
> The challenge with the centralised db of interesting info is that it
> will always be out of date for userspace (think userspace having to cope
> with a 5 year kernel, and a kernel having to cope with 10 year old
> userspace) and never enough so they still have to supplement it without
> their own db.
> 
> That isn't to say that there isn't a lot of interesting hw properties
> that userspace needs to know, but they are also tend to be the ones tied
> to fuses and not pciid.
> 
> What we do all duplicate are the pci-ids, so pulling those into a
> central header containing the commonly used per-id information in a format
> that can be embedded into any of the caller's structs is challenge
> enough.


I think kernel, igt and libdrm would be happy with either runtime or a
common header. Checking now what mesa does, giving a friendly name and
assigning the properties for each and every device is out of reach, at
least for now.  So  fair enough regarding the runtime option.

However I don't think that means we shouldn't try improve libdrm/igt
just because it won't solve it for mesa (at least with the
"common header approach"). I'll try to spin a new version to handle your
comment.

Lucas De Marchi
Lucas De Marchi Aug. 28, 2018, 1 a.m. UTC | #5
On Sat, Aug 25, 2018 at 10:35:23AM +0100, Chris Wilson wrote:
> Quoting Lucas De Marchi (2018-08-25 00:56:46)
> > diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
> > index 4a34b7be..8a0e3e76 100644
> > --- a/intel/intel_chipset.h
> > +++ b/intel/intel_chipset.h
> > @@ -568,6 +568,26 @@
> >  
> >  #define IS_GEN11(devid)                (IS_ICELAKE_11(devid))
> >  
> > +/* New platforms use kernel pci ids */
> > +#include "i915_pciids.h"
> > +
> > +struct pci_device_id {
> 
> Don't call it pci_device_id, depending on caller that name may already
> be taken by libpciaccess.
> 
> > +       uint32_t unused0, device;
> > +       uint32_t unused1, unused2;
> > +       uint32_t unused3, unused4;
> These are all uint16_t.

more on this:

I can make the first 2 uint16_t, but not the rest due to the way they
are declared in INTEL_VGA_DEVICE: (~0 has int type by default), unused3
and unused4 are clearly not uint16_t

> 
> > +       unsigned long unused5;
> 
> Simply make the unused disappear from the macro.

that would mean defining macro hackery to get hid of them from
INTEL_VGA_DEVICE() by using macro recursion, but not worth IMO. If we
want to go this route, then I think we should at least use X Macro
to define the ids rather than the list we currently have. Something
along the lines (in i915_pciids.h):


#define _INTEL_ICL_IDS \
	X(0x8A50) \
	X(0x8A51) \
	X(0x8A5C) \
	X(0x8A5D) \
	X(0x8A52) \
	X(0x8A5A) \
	X(0x8A5B) \
	X(0x8A71) \
	X(0x8A70)

...

#define X(id, info)	INTEL_VGA_DEVICE(id, info),
#define INTEL_ICL_IDS(info) _INTEL_ICL_IDS
#undef X

Then here we would just define another X to transform the list into an
array:

#include "i915_pciids.h"
...
#define X(id, gen) { id, gen }

struct pci_device {
	uint16_t id;
	uint16_t gen;
} devices = {
_INTEL_ICL_IDS
}


We would be screwed if X is defined to something else, but we could change
the name.

Lucas De Marchi
> 
> > +};
> > +
> > +#define IS_GENX(x, devid) ({ \
> > +       struct pci_device_id __ids[] = { INTEL_ ## x ## _IDS(0) };      \
> 
> While that's a neat trick it's instantiating the array for each caller,
> and it does appear that we repeat a few of the macros.
> 
> The best I can offer to keep the change non-invasive (other than just
> switching to a platform bitmask and filling (devid, gen, platform) from
> the pci match data on initialisation) is a two pass approach.
> 
> static inline int __find_in_pciid(uint16_t devid,
> 	const struct pci_device_id *ids, size_t count)
> {
> 	size_t i = 0; /* we should rethink this if we think there are more than 4B of them! */
> 	for (i = 0; i < count; i++) {
> 		if (ids[i].device == devid)
> 			return 1;
> 	}
> 	return 0;
> }
> 
> 
> #define __is_genx(x) \
> static inline int __is_gen##x(uint16_t devid) \
> { \
> 	static const struct pci_device_id __ids[] = { INTEL_ ## x ## _IDS(0) }; \
> 	return __find_in_pciid(devid, __ids, sizeof(__ids)/sizeof(__ids[0]); \
> }
> __is_genx(3);
> __is_genx(4);
> __is_genx(5);
> __is_genx(6);
> __is_genx(7);
> __is_genx(8);
> __is_genx(9);
> __is_genx(10);
> __is_genx(11);
> 
> #define IS_GENX(x, devid) __is_gen##x(devid)
> 
> That should help cut down the object size expansion. But longer term I'd
> prefer if we moved to towards finding the match data once. Also we need
> to pull into the canonical header the friendly names for mesa.
> -Chris
Chris Wilson Aug. 28, 2018, 8:38 a.m. UTC | #6
Quoting Lucas De Marchi (2018-08-28 02:00:27)
> On Sat, Aug 25, 2018 at 10:35:23AM +0100, Chris Wilson wrote:
> > Quoting Lucas De Marchi (2018-08-25 00:56:46)
> > > diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
> > > index 4a34b7be..8a0e3e76 100644
> > > --- a/intel/intel_chipset.h
> > > +++ b/intel/intel_chipset.h
> > > @@ -568,6 +568,26 @@
> > >  
> > >  #define IS_GEN11(devid)                (IS_ICELAKE_11(devid))
> > >  
> > > +/* New platforms use kernel pci ids */
> > > +#include "i915_pciids.h"
> > > +
> > > +struct pci_device_id {
> > 
> > Don't call it pci_device_id, depending on caller that name may already
> > be taken by libpciaccess.
> > 
> > > +       uint32_t unused0, device;
> > > +       uint32_t unused1, unused2;
> > > +       uint32_t unused3, unused4;
> > These are all uint16_t.
> 
> more on this:
> 
> I can make the first 2 uint16_t, but not the rest due to the way they
> are declared in INTEL_VGA_DEVICE: (~0 has int type by default), unused3
> and unused4 are clearly not uint16_t

I had it in my mind that we did have one extra level of macro in there
that would allow us to drop unused fields. We could redef
INTEL_VGA_DEVICE() and INTEL_QUANTA_VGA_DEVICE() but one extra level of
macro would be easier for future.

And then while you are there, add the missing 'u' to ~0u
-Chris.
Lucas De Marchi Aug. 28, 2018, 4:16 p.m. UTC | #7
On Tue, Aug 28, 2018 at 09:38:59AM +0100, Chris Wilson wrote:
> Quoting Lucas De Marchi (2018-08-28 02:00:27)
> > On Sat, Aug 25, 2018 at 10:35:23AM +0100, Chris Wilson wrote:
> > > Quoting Lucas De Marchi (2018-08-25 00:56:46)
> > > > diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
> > > > index 4a34b7be..8a0e3e76 100644
> > > > --- a/intel/intel_chipset.h
> > > > +++ b/intel/intel_chipset.h
> > > > @@ -568,6 +568,26 @@
> > > >  
> > > >  #define IS_GEN11(devid)                (IS_ICELAKE_11(devid))
> > > >  
> > > > +/* New platforms use kernel pci ids */
> > > > +#include "i915_pciids.h"
> > > > +
> > > > +struct pci_device_id {
> > > 
> > > Don't call it pci_device_id, depending on caller that name may already
> > > be taken by libpciaccess.
> > > 
> > > > +       uint32_t unused0, device;
> > > > +       uint32_t unused1, unused2;
> > > > +       uint32_t unused3, unused4;
> > > These are all uint16_t.
> > 
> > more on this:
> > 
> > I can make the first 2 uint16_t, but not the rest due to the way they
> > are declared in INTEL_VGA_DEVICE: (~0 has int type by default), unused3
> > and unused4 are clearly not uint16_t
> 
> I had it in my mind that we did have one extra level of macro in there
> that would allow us to drop unused fields. We could redef

we don't have right now, that needs to be added. And for any extra level
of macro we need to redef INTEL_VGA_DEVICE nonetheless because it
expands to "{ ... }". I don't know any cpp trick to remove the extra
fields if it keeps the braces. 

> INTEL_VGA_DEVICE() and INTEL_QUANTA_VGA_DEVICE() but one extra level of
> macro would be easier for future.

So... I don't see a way out except to redef it. This works today for
libdrm (on top of my unsent version of this patch):


[ NO CI ] diff --git a/intel/intel_chipset.c b/intel/intel_chipset.c
[ NO CI ] index 79581819..8ea24194 100644
[ NO CI ] --- a/intel/intel_chipset.c
[ NO CI ] +++ b/intel/intel_chipset.c
@@ -27,11 +27,12 @@
 
 #include "i915_pciids.h"
 
+#undef INTEL_VGA_DEVICE
+#define INTEL_VGA_DEVICE(id, gen) { id, gen }
+
 static const struct pci_device {
-	uint16_t unused0, device;
-	uint32_t unused1, unused2;
-	uint32_t unused3, unused4;
-	int gen;
+	uint16_t device;
+	uint16_t gen;
 } pciids[] = {
 	INTEL_ICL_11_IDS(11),
 	INTEL_CNL_IDS(10),

> 
> And then while you are there, add the missing 'u' to ~0u
> -Chris.
diff mbox series

Patch

diff --git a/intel/i915_pciids.h b/intel/i915_pciids.h
new file mode 100644
index 00000000..fd965ffb
--- /dev/null
+++ b/intel/i915_pciids.h
@@ -0,0 +1,461 @@ 
+/*
+ * Copyright 2013 Intel Corporation
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _I915_PCIIDS_H
+#define _I915_PCIIDS_H
+
+/*
+ * A pci_device_id struct {
+ *	__u32 vendor, device;
+ *      __u32 subvendor, subdevice;
+ *	__u32 class, class_mask;
+ *	kernel_ulong_t driver_data;
+ * };
+ * Don't use C99 here because "class" is reserved and we want to
+ * give userspace flexibility.
+ */
+#define INTEL_VGA_DEVICE(id, info) {		\
+	0x8086,	id,				\
+	~0, ~0,					\
+	0x030000, 0xff0000,			\
+	(unsigned long) info }
+
+#define INTEL_QUANTA_VGA_DEVICE(info) {		\
+	0x8086,	0x16a,				\
+	0x152d,	0x8990,				\
+	0x030000, 0xff0000,			\
+	(unsigned long) info }
+
+#define INTEL_I810_IDS(info)					\
+	INTEL_VGA_DEVICE(0x7121, info), /* I810 */		\
+	INTEL_VGA_DEVICE(0x7123, info), /* I810_DC100 */	\
+	INTEL_VGA_DEVICE(0x7125, info)  /* I810_E */
+
+#define INTEL_I815_IDS(info)					\
+	INTEL_VGA_DEVICE(0x1132, info)  /* I815*/
+
+#define INTEL_I830_IDS(info)				\
+	INTEL_VGA_DEVICE(0x3577, info)
+
+#define INTEL_I845G_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2562, info)
+
+#define INTEL_I85X_IDS(info)				\
+	INTEL_VGA_DEVICE(0x3582, info), /* I855_GM */ \
+	INTEL_VGA_DEVICE(0x358e, info)
+
+#define INTEL_I865G_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2572, info) /* I865_G */
+
+#define INTEL_I915G_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2582, info), /* I915_G */ \
+	INTEL_VGA_DEVICE(0x258a, info)  /* E7221_G */
+
+#define INTEL_I915GM_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2592, info) /* I915_GM */
+
+#define INTEL_I945G_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2772, info) /* I945_G */
+
+#define INTEL_I945GM_IDS(info)				\
+	INTEL_VGA_DEVICE(0x27a2, info), /* I945_GM */ \
+	INTEL_VGA_DEVICE(0x27ae, info)  /* I945_GME */
+
+#define INTEL_I965G_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2972, info), /* I946_GZ */	\
+	INTEL_VGA_DEVICE(0x2982, info),	/* G35_G */	\
+	INTEL_VGA_DEVICE(0x2992, info),	/* I965_Q */	\
+	INTEL_VGA_DEVICE(0x29a2, info)	/* I965_G */
+
+#define INTEL_G33_IDS(info)				\
+	INTEL_VGA_DEVICE(0x29b2, info), /* Q35_G */ \
+	INTEL_VGA_DEVICE(0x29c2, info),	/* G33_G */ \
+	INTEL_VGA_DEVICE(0x29d2, info)	/* Q33_G */
+
+#define INTEL_I965GM_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2a02, info),	/* I965_GM */ \
+	INTEL_VGA_DEVICE(0x2a12, info)  /* I965_GME */
+
+#define INTEL_GM45_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2a42, info) /* GM45_G */
+
+#define INTEL_G45_IDS(info)				\
+	INTEL_VGA_DEVICE(0x2e02, info), /* IGD_E_G */ \
+	INTEL_VGA_DEVICE(0x2e12, info), /* Q45_G */ \
+	INTEL_VGA_DEVICE(0x2e22, info), /* G45_G */ \
+	INTEL_VGA_DEVICE(0x2e32, info), /* G41_G */ \
+	INTEL_VGA_DEVICE(0x2e42, info), /* B43_G */ \
+	INTEL_VGA_DEVICE(0x2e92, info)	/* B43_G.1 */
+
+#define INTEL_PINEVIEW_IDS(info)			\
+	INTEL_VGA_DEVICE(0xa001, info),			\
+	INTEL_VGA_DEVICE(0xa011, info)
+
+#define INTEL_IRONLAKE_D_IDS(info) \
+	INTEL_VGA_DEVICE(0x0042, info)
+
+#define INTEL_IRONLAKE_M_IDS(info) \
+	INTEL_VGA_DEVICE(0x0046, info)
+
+#define INTEL_SNB_D_GT1_IDS(info) \
+	INTEL_VGA_DEVICE(0x0102, info), \
+	INTEL_VGA_DEVICE(0x010A, info)
+
+#define INTEL_SNB_D_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x0112, info), \
+	INTEL_VGA_DEVICE(0x0122, info)
+
+#define INTEL_SNB_D_IDS(info) \
+	INTEL_SNB_D_GT1_IDS(info), \
+	INTEL_SNB_D_GT2_IDS(info)
+
+#define INTEL_SNB_M_GT1_IDS(info) \
+	INTEL_VGA_DEVICE(0x0106, info)
+
+#define INTEL_SNB_M_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x0116, info), \
+	INTEL_VGA_DEVICE(0x0126, info)
+
+#define INTEL_SNB_M_IDS(info) \
+	INTEL_SNB_M_GT1_IDS(info), \
+	INTEL_SNB_M_GT2_IDS(info)
+
+#define INTEL_IVB_M_GT1_IDS(info) \
+	INTEL_VGA_DEVICE(0x0156, info) /* GT1 mobile */
+
+#define INTEL_IVB_M_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x0166, info) /* GT2 mobile */
+
+#define INTEL_IVB_M_IDS(info) \
+	INTEL_IVB_M_GT1_IDS(info), \
+	INTEL_IVB_M_GT2_IDS(info)
+
+#define INTEL_IVB_D_GT1_IDS(info) \
+	INTEL_VGA_DEVICE(0x0152, info), /* GT1 desktop */ \
+	INTEL_VGA_DEVICE(0x015a, info)  /* GT1 server */
+
+#define INTEL_IVB_D_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x0162, info), /* GT2 desktop */ \
+	INTEL_VGA_DEVICE(0x016a, info)  /* GT2 server */
+
+#define INTEL_IVB_D_IDS(info) \
+	INTEL_IVB_D_GT1_IDS(info), \
+	INTEL_IVB_D_GT2_IDS(info)
+
+#define INTEL_IVB_Q_IDS(info) \
+	INTEL_QUANTA_VGA_DEVICE(info) /* Quanta transcode */
+
+#define INTEL_HSW_GT1_IDS(info) \
+	INTEL_VGA_DEVICE(0x0402, info), /* GT1 desktop */ \
+	INTEL_VGA_DEVICE(0x040a, info), /* GT1 server */ \
+	INTEL_VGA_DEVICE(0x040B, info), /* GT1 reserved */ \
+	INTEL_VGA_DEVICE(0x040E, info), /* GT1 reserved */ \
+	INTEL_VGA_DEVICE(0x0C02, info), /* SDV GT1 desktop */ \
+	INTEL_VGA_DEVICE(0x0C0A, info), /* SDV GT1 server */ \
+	INTEL_VGA_DEVICE(0x0C0B, info), /* SDV GT1 reserved */ \
+	INTEL_VGA_DEVICE(0x0C0E, info), /* SDV GT1 reserved */ \
+	INTEL_VGA_DEVICE(0x0A02, info), /* ULT GT1 desktop */ \
+	INTEL_VGA_DEVICE(0x0A0A, info), /* ULT GT1 server */ \
+	INTEL_VGA_DEVICE(0x0A0B, info), /* ULT GT1 reserved */ \
+	INTEL_VGA_DEVICE(0x0D02, info), /* CRW GT1 desktop */ \
+	INTEL_VGA_DEVICE(0x0D0A, info), /* CRW GT1 server */ \
+	INTEL_VGA_DEVICE(0x0D0B, info), /* CRW GT1 reserved */ \
+	INTEL_VGA_DEVICE(0x0D0E, info), /* CRW GT1 reserved */ \
+	INTEL_VGA_DEVICE(0x0406, info), /* GT1 mobile */ \
+	INTEL_VGA_DEVICE(0x0C06, info), /* SDV GT1 mobile */ \
+	INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \
+	INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \
+	INTEL_VGA_DEVICE(0x0D06, info)  /* CRW GT1 mobile */
+
+#define INTEL_HSW_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x0412, info), /* GT2 desktop */ \
+	INTEL_VGA_DEVICE(0x041a, info), /* GT2 server */ \
+	INTEL_VGA_DEVICE(0x041B, info), /* GT2 reserved */ \
+	INTEL_VGA_DEVICE(0x041E, info), /* GT2 reserved */ \
+	INTEL_VGA_DEVICE(0x0C12, info), /* SDV GT2 desktop */ \
+	INTEL_VGA_DEVICE(0x0C1A, info), /* SDV GT2 server */ \
+	INTEL_VGA_DEVICE(0x0C1B, info), /* SDV GT2 reserved */ \
+	INTEL_VGA_DEVICE(0x0C1E, info), /* SDV GT2 reserved */ \
+	INTEL_VGA_DEVICE(0x0A12, info), /* ULT GT2 desktop */ \
+	INTEL_VGA_DEVICE(0x0A1A, info), /* ULT GT2 server */ \
+	INTEL_VGA_DEVICE(0x0A1B, info), /* ULT GT2 reserved */ \
+	INTEL_VGA_DEVICE(0x0D12, info), /* CRW GT2 desktop */ \
+	INTEL_VGA_DEVICE(0x0D1A, info), /* CRW GT2 server */ \
+	INTEL_VGA_DEVICE(0x0D1B, info), /* CRW GT2 reserved */ \
+	INTEL_VGA_DEVICE(0x0D1E, info), /* CRW GT2 reserved */ \
+	INTEL_VGA_DEVICE(0x0416, info), /* GT2 mobile */ \
+	INTEL_VGA_DEVICE(0x0426, info), /* GT2 mobile */ \
+	INTEL_VGA_DEVICE(0x0C16, info), /* SDV GT2 mobile */ \
+	INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \
+	INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \
+	INTEL_VGA_DEVICE(0x0D16, info)  /* CRW GT2 mobile */
+
+#define INTEL_HSW_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x0422, info), /* GT3 desktop */ \
+	INTEL_VGA_DEVICE(0x042a, info), /* GT3 server */ \
+	INTEL_VGA_DEVICE(0x042B, info), /* GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x042E, info), /* GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x0C22, info), /* SDV GT3 desktop */ \
+	INTEL_VGA_DEVICE(0x0C2A, info), /* SDV GT3 server */ \
+	INTEL_VGA_DEVICE(0x0C2B, info), /* SDV GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x0C2E, info), /* SDV GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x0A22, info), /* ULT GT3 desktop */ \
+	INTEL_VGA_DEVICE(0x0A2A, info), /* ULT GT3 server */ \
+	INTEL_VGA_DEVICE(0x0A2B, info), /* ULT GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x0D22, info), /* CRW GT3 desktop */ \
+	INTEL_VGA_DEVICE(0x0D2A, info), /* CRW GT3 server */ \
+	INTEL_VGA_DEVICE(0x0D2B, info), /* CRW GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x0D2E, info), /* CRW GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x0C26, info), /* SDV GT3 mobile */ \
+	INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \
+	INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \
+	INTEL_VGA_DEVICE(0x0D26, info)  /* CRW GT3 mobile */
+
+#define INTEL_HSW_IDS(info) \
+	INTEL_HSW_GT1_IDS(info), \
+	INTEL_HSW_GT2_IDS(info), \
+	INTEL_HSW_GT3_IDS(info)
+
+#define INTEL_VLV_IDS(info) \
+	INTEL_VGA_DEVICE(0x0f30, info), \
+	INTEL_VGA_DEVICE(0x0f31, info), \
+	INTEL_VGA_DEVICE(0x0f32, info), \
+	INTEL_VGA_DEVICE(0x0f33, info), \
+	INTEL_VGA_DEVICE(0x0157, info), \
+	INTEL_VGA_DEVICE(0x0155, info)
+
+#define INTEL_BDW_GT1_IDS(info)  \
+	INTEL_VGA_DEVICE(0x1602, info), /* GT1 ULT */ \
+	INTEL_VGA_DEVICE(0x1606, info), /* GT1 ULT */ \
+	INTEL_VGA_DEVICE(0x160B, info), /* GT1 Iris */ \
+	INTEL_VGA_DEVICE(0x160E, info), /* GT1 ULX */ \
+	INTEL_VGA_DEVICE(0x160A, info), /* GT1 Server */ \
+	INTEL_VGA_DEVICE(0x160D, info)  /* GT1 Workstation */
+
+#define INTEL_BDW_GT2_IDS(info)  \
+	INTEL_VGA_DEVICE(0x1612, info), /* GT2 Halo */	\
+	INTEL_VGA_DEVICE(0x1616, info), /* GT2 ULT */ \
+	INTEL_VGA_DEVICE(0x161B, info), /* GT2 ULT */ \
+	INTEL_VGA_DEVICE(0x161E, info), /* GT2 ULX */ \
+	INTEL_VGA_DEVICE(0x161A, info), /* GT2 Server */ \
+	INTEL_VGA_DEVICE(0x161D, info)  /* GT2 Workstation */
+
+#define INTEL_BDW_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x1622, info), /* ULT */ \
+	INTEL_VGA_DEVICE(0x1626, info), /* ULT */ \
+	INTEL_VGA_DEVICE(0x162B, info), /* Iris */ \
+	INTEL_VGA_DEVICE(0x162E, info),  /* ULX */\
+	INTEL_VGA_DEVICE(0x162A, info), /* Server */ \
+	INTEL_VGA_DEVICE(0x162D, info)  /* Workstation */
+
+#define INTEL_BDW_RSVD_IDS(info) \
+	INTEL_VGA_DEVICE(0x1632, info), /* ULT */ \
+	INTEL_VGA_DEVICE(0x1636, info), /* ULT */ \
+	INTEL_VGA_DEVICE(0x163B, info), /* Iris */ \
+	INTEL_VGA_DEVICE(0x163E, info), /* ULX */ \
+	INTEL_VGA_DEVICE(0x163A, info), /* Server */ \
+	INTEL_VGA_DEVICE(0x163D, info)  /* Workstation */
+
+#define INTEL_BDW_IDS(info) \
+	INTEL_BDW_GT1_IDS(info), \
+	INTEL_BDW_GT2_IDS(info), \
+	INTEL_BDW_GT3_IDS(info), \
+	INTEL_BDW_RSVD_IDS(info)
+
+#define INTEL_CHV_IDS(info) \
+	INTEL_VGA_DEVICE(0x22b0, info), \
+	INTEL_VGA_DEVICE(0x22b1, info), \
+	INTEL_VGA_DEVICE(0x22b2, info), \
+	INTEL_VGA_DEVICE(0x22b3, info)
+
+#define INTEL_SKL_GT1_IDS(info)	\
+	INTEL_VGA_DEVICE(0x1906, info), /* ULT GT1 */ \
+	INTEL_VGA_DEVICE(0x190E, info), /* ULX GT1 */ \
+	INTEL_VGA_DEVICE(0x1902, info), /* DT  GT1 */ \
+	INTEL_VGA_DEVICE(0x190B, info), /* Halo GT1 */ \
+	INTEL_VGA_DEVICE(0x190A, info) /* SRV GT1 */
+
+#define INTEL_SKL_GT2_IDS(info)	\
+	INTEL_VGA_DEVICE(0x1916, info), /* ULT GT2 */ \
+	INTEL_VGA_DEVICE(0x1921, info), /* ULT GT2F */ \
+	INTEL_VGA_DEVICE(0x191E, info), /* ULX GT2 */ \
+	INTEL_VGA_DEVICE(0x1912, info), /* DT  GT2 */ \
+	INTEL_VGA_DEVICE(0x191B, info), /* Halo GT2 */ \
+	INTEL_VGA_DEVICE(0x191A, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x191D, info)  /* WKS GT2 */
+
+#define INTEL_SKL_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x1923, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x1926, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x1927, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x192B, info), /* Halo GT3 */ \
+	INTEL_VGA_DEVICE(0x192D, info)  /* SRV GT3 */
+
+#define INTEL_SKL_GT4_IDS(info) \
+	INTEL_VGA_DEVICE(0x1932, info), /* DT GT4 */ \
+	INTEL_VGA_DEVICE(0x193B, info), /* Halo GT4 */ \
+	INTEL_VGA_DEVICE(0x193D, info), /* WKS GT4 */ \
+	INTEL_VGA_DEVICE(0x192A, info), /* SRV GT4 */ \
+	INTEL_VGA_DEVICE(0x193A, info)  /* SRV GT4e */
+
+#define INTEL_SKL_IDS(info)	 \
+	INTEL_SKL_GT1_IDS(info), \
+	INTEL_SKL_GT2_IDS(info), \
+	INTEL_SKL_GT3_IDS(info), \
+	INTEL_SKL_GT4_IDS(info)
+
+#define INTEL_BXT_IDS(info) \
+	INTEL_VGA_DEVICE(0x0A84, info), \
+	INTEL_VGA_DEVICE(0x1A84, info), \
+	INTEL_VGA_DEVICE(0x1A85, info), \
+	INTEL_VGA_DEVICE(0x5A84, info), /* APL HD Graphics 505 */ \
+	INTEL_VGA_DEVICE(0x5A85, info)  /* APL HD Graphics 500 */
+
+#define INTEL_GLK_IDS(info) \
+	INTEL_VGA_DEVICE(0x3184, info), \
+	INTEL_VGA_DEVICE(0x3185, info)
+
+#define INTEL_KBL_GT1_IDS(info)	\
+	INTEL_VGA_DEVICE(0x5913, info), /* ULT GT1.5 */ \
+	INTEL_VGA_DEVICE(0x5915, info), /* ULX GT1.5 */ \
+	INTEL_VGA_DEVICE(0x5906, info), /* ULT GT1 */ \
+	INTEL_VGA_DEVICE(0x590E, info), /* ULX GT1 */ \
+	INTEL_VGA_DEVICE(0x5902, info), /* DT  GT1 */ \
+	INTEL_VGA_DEVICE(0x5908, info), /* Halo GT1 */ \
+	INTEL_VGA_DEVICE(0x590B, info), /* Halo GT1 */ \
+	INTEL_VGA_DEVICE(0x590A, info) /* SRV GT1 */
+
+#define INTEL_KBL_GT2_IDS(info)	\
+	INTEL_VGA_DEVICE(0x5916, info), /* ULT GT2 */ \
+	INTEL_VGA_DEVICE(0x5917, info), /* Mobile GT2 */ \
+	INTEL_VGA_DEVICE(0x5921, info), /* ULT GT2F */ \
+	INTEL_VGA_DEVICE(0x591E, info), /* ULX GT2 */ \
+	INTEL_VGA_DEVICE(0x5912, info), /* DT  GT2 */ \
+	INTEL_VGA_DEVICE(0x591B, info), /* Halo GT2 */ \
+	INTEL_VGA_DEVICE(0x591A, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x591D, info) /* WKS GT2 */
+
+#define INTEL_KBL_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x5923, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x5926, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x5927, info) /* ULT GT3 */
+
+#define INTEL_KBL_GT4_IDS(info) \
+	INTEL_VGA_DEVICE(0x593B, info) /* Halo GT4 */
+
+/* AML/KBL Y GT2 */
+#define INTEL_AML_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x591C, info),  /* ULX GT2 */ \
+	INTEL_VGA_DEVICE(0x87C0, info) /* ULX GT2 */
+
+#define INTEL_KBL_IDS(info) \
+	INTEL_KBL_GT1_IDS(info), \
+	INTEL_KBL_GT2_IDS(info), \
+	INTEL_KBL_GT3_IDS(info), \
+	INTEL_KBL_GT4_IDS(info), \
+	INTEL_AML_GT2_IDS(info)
+
+/* CFL S */
+#define INTEL_CFL_S_GT1_IDS(info) \
+	INTEL_VGA_DEVICE(0x3E90, info), /* SRV GT1 */ \
+	INTEL_VGA_DEVICE(0x3E93, info), /* SRV GT1 */ \
+	INTEL_VGA_DEVICE(0x3E99, info)  /* SRV GT1 */
+
+#define INTEL_CFL_S_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x3E91, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x3E92, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x3E96, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x3E98, info), /* SRV GT2 */ \
+	INTEL_VGA_DEVICE(0x3E9A, info)  /* SRV GT2 */
+
+/* CFL H */
+#define INTEL_CFL_H_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x3E9B, info), /* Halo GT2 */ \
+	INTEL_VGA_DEVICE(0x3E94, info)  /* Halo GT2 */
+
+/* CFL U GT2 */
+#define INTEL_CFL_U_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x3EA9, info)
+
+/* CFL U GT3 */
+#define INTEL_CFL_U_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x3EA5, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x3EA6, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x3EA7, info), /* ULT GT3 */ \
+	INTEL_VGA_DEVICE(0x3EA8, info)  /* ULT GT3 */
+
+/* WHL/CFL U GT1 */
+#define INTEL_WHL_U_GT1_IDS(info) \
+	INTEL_VGA_DEVICE(0x3EA1, info)
+
+/* WHL/CFL U GT2 */
+#define INTEL_WHL_U_GT2_IDS(info) \
+	INTEL_VGA_DEVICE(0x3EA0, info)
+
+/* WHL/CFL U GT3 */
+#define INTEL_WHL_U_GT3_IDS(info) \
+	INTEL_VGA_DEVICE(0x3EA2, info), \
+	INTEL_VGA_DEVICE(0x3EA3, info), \
+	INTEL_VGA_DEVICE(0x3EA4, info)
+
+#define INTEL_CFL_IDS(info)	   \
+	INTEL_CFL_S_GT1_IDS(info), \
+	INTEL_CFL_S_GT2_IDS(info), \
+	INTEL_CFL_H_GT2_IDS(info), \
+	INTEL_CFL_U_GT2_IDS(info), \
+	INTEL_CFL_U_GT3_IDS(info), \
+	INTEL_WHL_U_GT1_IDS(info), \
+	INTEL_WHL_U_GT2_IDS(info), \
+	INTEL_WHL_U_GT3_IDS(info)
+
+/* CNL */
+#define INTEL_CNL_IDS(info) \
+	INTEL_VGA_DEVICE(0x5A51, info), \
+	INTEL_VGA_DEVICE(0x5A59, info), \
+	INTEL_VGA_DEVICE(0x5A41, info), \
+	INTEL_VGA_DEVICE(0x5A49, info), \
+	INTEL_VGA_DEVICE(0x5A52, info), \
+	INTEL_VGA_DEVICE(0x5A5A, info), \
+	INTEL_VGA_DEVICE(0x5A42, info), \
+	INTEL_VGA_DEVICE(0x5A4A, info), \
+	INTEL_VGA_DEVICE(0x5A50, info), \
+	INTEL_VGA_DEVICE(0x5A40, info), \
+	INTEL_VGA_DEVICE(0x5A54, info), \
+	INTEL_VGA_DEVICE(0x5A5C, info), \
+	INTEL_VGA_DEVICE(0x5A44, info), \
+	INTEL_VGA_DEVICE(0x5A4C, info)
+
+/* ICL */
+#define INTEL_ICL_11_IDS(info) \
+	INTEL_VGA_DEVICE(0x8A50, info), \
+	INTEL_VGA_DEVICE(0x8A51, info), \
+	INTEL_VGA_DEVICE(0x8A5C, info), \
+	INTEL_VGA_DEVICE(0x8A5D, info), \
+	INTEL_VGA_DEVICE(0x8A52, info), \
+	INTEL_VGA_DEVICE(0x8A5A, info), \
+	INTEL_VGA_DEVICE(0x8A5B, info), \
+	INTEL_VGA_DEVICE(0x8A71, info), \
+	INTEL_VGA_DEVICE(0x8A70, info)
+
+#endif /* _I915_PCIIDS_H */
diff --git a/intel/intel_chipset.h b/intel/intel_chipset.h
index 4a34b7be..8a0e3e76 100644
--- a/intel/intel_chipset.h
+++ b/intel/intel_chipset.h
@@ -568,6 +568,26 @@ 
 
 #define IS_GEN11(devid)		(IS_ICELAKE_11(devid))
 
+/* New platforms use kernel pci ids */
+#include "i915_pciids.h"
+
+struct pci_device_id {
+	uint32_t unused0, device;
+	uint32_t unused1, unused2;
+	uint32_t unused3, unused4;
+	unsigned long unused5;
+};
+
+#define IS_GENX(x, devid) ({ \
+	struct pci_device_id __ids[] = { INTEL_ ## x ## _IDS(0) };	\
+	unsigned int __i = 0;						\
+	size_t __n = sizeof(__ids) / sizeof(__ids[0]);			\
+	for (__i = 0; __i < __n; __i++)					\
+		if (__ids[__i].device == (uint32_t)devid)		\
+			break;						\
+	__i < __n;})
+
+/* all platforms */
 #define IS_9XX(dev)		(IS_GEN3(dev) || \
 				 IS_GEN4(dev) || \
 				 IS_GEN5(dev) || \