[1/4] drm/i915/tgl: Introduce gen12 forcewake ranges

Submitted by Mika Kuoppala on Sept. 12, 2019, 1:38 p.m.

Details

Message ID 20190912133816.1382-1-mika.kuoppala@linux.intel.com
State New
Headers show
Series "Series without cover letter" ( rev: 3 2 1 ) in Intel GFX

Not browsing as part of any series.

Commit Message

Mika Kuoppala Sept. 12, 2019, 1:38 p.m.
From: Michel Thierry <michel.thierry@intel.com>

The media ranges extend beyond what gen11 gives so we can't piggypack
on gen11 ranges, even on read side.

Introduce a table for gen12 and accessors for it.

v2: correctly implement gen12_fwtable_write/read (Daniele)
v3: update with ranges from bspec.
v4: avoid GEN11_NEEDS_FORCEWAKE on read size (Mika)

BSpec: 18331.
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Michel Thierry <michel.thierry@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_uncore.c           | 75 ++++++++++++++++++-
 drivers/gpu/drm/i915/selftests/intel_uncore.c |  2 +
 2 files changed, 76 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
index 9e583f13a9e4..18e8314641a8 100644
--- a/drivers/gpu/drm/i915/intel_uncore.c
+++ b/drivers/gpu/drm/i915/intel_uncore.c
@@ -910,6 +910,9 @@  static const struct intel_forcewake_range __vlv_fw_ranges[] = {
 	__fwd; \
 })
 
+#define __gen12_fwtable_reg_read_fw_domains(uncore, offset) \
+	find_fw_domain(uncore, offset)
+
 /* *Must* be sorted by offset! See intel_shadow_table_check(). */
 static const i915_reg_t gen8_shadowed_regs[] = {
 	RING_TAIL(RENDER_RING_BASE),	/* 0x2000 (base) */
@@ -935,6 +938,20 @@  static const i915_reg_t gen11_shadowed_regs[] = {
 	/* TODO: Other registers are not yet used */
 };
 
+static const i915_reg_t gen12_shadowed_regs[] = {
+	RING_TAIL(RENDER_RING_BASE),		/* 0x2000 (base) */
+	GEN6_RPNSWREQ,				/* 0xA008 */
+	GEN6_RC_VIDEO_FREQ,			/* 0xA00C */
+	RING_TAIL(BLT_RING_BASE),		/* 0x22000 (base) */
+	RING_TAIL(GEN11_BSD_RING_BASE),		/* 0x1C0000 (base) */
+	RING_TAIL(GEN11_BSD2_RING_BASE),	/* 0x1C4000 (base) */
+	RING_TAIL(GEN11_VEBOX_RING_BASE),	/* 0x1C8000 (base) */
+	RING_TAIL(GEN11_BSD3_RING_BASE),	/* 0x1D0000 (base) */
+	RING_TAIL(GEN11_BSD4_RING_BASE),	/* 0x1D4000 (base) */
+	RING_TAIL(GEN11_VEBOX2_RING_BASE),	/* 0x1D8000 (base) */
+	/* TODO: Other registers are not yet used */
+};
+
 static int mmio_reg_cmp(u32 key, const i915_reg_t *reg)
 {
 	u32 offset = i915_mmio_reg_offset(*reg);
@@ -957,6 +974,7 @@  static bool is_gen##x##_shadowed(u32 offset) \
 
 __is_genX_shadowed(8)
 __is_genX_shadowed(11)
+__is_genX_shadowed(12)
 
 static enum forcewake_domains
 gen6_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg)
@@ -1010,6 +1028,15 @@  static const struct intel_forcewake_range __chv_fw_ranges[] = {
 	__fwd; \
 })
 
+#define __gen12_fwtable_reg_write_fw_domains(uncore, offset) \
+({ \
+	enum forcewake_domains __fwd = 0; \
+	const u32 __offset = (offset); \
+	if (!is_gen12_shadowed(__offset)) \
+		__fwd = find_fw_domain(uncore, __offset); \
+	__fwd; \
+})
+
 /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
 static const struct intel_forcewake_range __gen9_fw_ranges[] = {
 	GEN_FW_RANGE(0x0, 0xaff, FORCEWAKE_BLITTER),
@@ -1080,6 +1107,46 @@  static const struct intel_forcewake_range __gen11_fw_ranges[] = {
 	GEN_FW_RANGE(0x1d8000, 0x1dbfff, FORCEWAKE_MEDIA_VEBOX1)
 };
 
+/* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
+static const struct intel_forcewake_range __gen12_fw_ranges[] = {
+	GEN_FW_RANGE(0x0, 0xaff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0xb00, 0x1fff, 0), /* uncore range */
+	GEN_FW_RANGE(0x2000, 0x26ff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x2700, 0x2fff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x3000, 0x3fff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x4000, 0x51ff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x5200, 0x7fff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x8000, 0x813f, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x8140, 0x815f, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x8160, 0x82ff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x8300, 0x84ff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x8500, 0x8bff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x8c00, 0x8cff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x8d00, 0x93ff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x9400, 0x97ff, FORCEWAKE_ALL),
+	GEN_FW_RANGE(0x9800, 0xafff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0xb000, 0xb47f, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0xb480, 0xdfff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0xe000, 0xe8ff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0xe900, 0x147ff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x14800, 0x148ff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x14900, 0x19fff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x1a000, 0x1a7ff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x1a800, 0x1afff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x1b000, 0x1bfff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x1c000, 0x243ff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x24400, 0x247ff, FORCEWAKE_RENDER),
+	GEN_FW_RANGE(0x24800, 0x3ffff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x40000, 0x1bffff, 0),
+	GEN_FW_RANGE(0x1c0000, 0x1c3fff, FORCEWAKE_MEDIA_VDBOX0),
+	GEN_FW_RANGE(0x1c4000, 0x1c7fff, FORCEWAKE_MEDIA_VDBOX1),
+	GEN_FW_RANGE(0x1c8000, 0x1cbfff, FORCEWAKE_MEDIA_VEBOX0),
+	GEN_FW_RANGE(0x1cc000, 0x1cffff, FORCEWAKE_BLITTER),
+	GEN_FW_RANGE(0x1d0000, 0x1d3fff, FORCEWAKE_MEDIA_VDBOX2),
+	GEN_FW_RANGE(0x1d4000, 0x1d7fff, FORCEWAKE_MEDIA_VDBOX3),
+	GEN_FW_RANGE(0x1d8000, 0x1dbfff, FORCEWAKE_MEDIA_VEBOX1)
+};
+
 static void
 ilk_dummy_write(struct intel_uncore *uncore)
 {
@@ -1228,6 +1295,7 @@  __gen_read(func, 16) \
 __gen_read(func, 32) \
 __gen_read(func, 64)
 
+__gen_reg_read_funcs(gen12_fwtable);
 __gen_reg_read_funcs(gen11_fwtable);
 __gen_reg_read_funcs(fwtable);
 __gen_reg_read_funcs(gen6);
@@ -1319,6 +1387,7 @@  __gen_write(func, 8) \
 __gen_write(func, 16) \
 __gen_write(func, 32)
 
+__gen_reg_write_funcs(gen12_fwtable);
 __gen_reg_write_funcs(gen11_fwtable);
 __gen_reg_write_funcs(fwtable);
 __gen_reg_write_funcs(gen8);
@@ -1690,10 +1759,14 @@  static int uncore_forcewake_init(struct intel_uncore *uncore)
 		ASSIGN_FW_DOMAINS_TABLE(uncore, __gen9_fw_ranges);
 		ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
 		ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
-	} else {
+	} else if (IS_GEN(i915, 11)) {
 		ASSIGN_FW_DOMAINS_TABLE(uncore, __gen11_fw_ranges);
 		ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen11_fwtable);
 		ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable);
+	} else {
+		ASSIGN_FW_DOMAINS_TABLE(uncore, __gen12_fw_ranges);
+		ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable);
+		ASSIGN_READ_MMIO_VFUNCS(uncore, gen12_fwtable);
 	}
 
 	uncore->pmic_bus_access_nb.notifier_call = i915_pmic_bus_access_notifier;
diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c
index 86815c6072a1..0ffb141eb988 100644
--- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
+++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
@@ -67,6 +67,7 @@  static int intel_shadow_table_check(void)
 	} reg_lists[] = {
 		{ gen8_shadowed_regs, ARRAY_SIZE(gen8_shadowed_regs) },
 		{ gen11_shadowed_regs, ARRAY_SIZE(gen11_shadowed_regs) },
+		{ gen12_shadowed_regs, ARRAY_SIZE(gen12_shadowed_regs) },
 	};
 	const i915_reg_t *reg;
 	unsigned int i, j;
@@ -101,6 +102,7 @@  int intel_uncore_mock_selftests(void)
 		{ __chv_fw_ranges, ARRAY_SIZE(__chv_fw_ranges), false },
 		{ __gen9_fw_ranges, ARRAY_SIZE(__gen9_fw_ranges), true },
 		{ __gen11_fw_ranges, ARRAY_SIZE(__gen11_fw_ranges), true },
+		{ __gen12_fw_ranges, ARRAY_SIZE(__gen12_fw_ranges), true },
 	};
 	int err, i;
 

Comments

On 9/12/19 6:38 AM, Mika Kuoppala wrote:
> From: Michel Thierry <michel.thierry@intel.com>
> 
> The media ranges extend beyond what gen11 gives so we can't piggypack
> on gen11 ranges, even on read side.
> 
> Introduce a table for gen12 and accessors for it.
> 
> v2: correctly implement gen12_fwtable_write/read (Daniele)
> v3: update with ranges from bspec.
> v4: avoid GEN11_NEEDS_FORCEWAKE on read size (Mika)

If we think the overhead of the unneeded BSEARCH is not too bad, should 
we remove this from the other accessors as well? Having only the gen12 
paths behave differently feels inconsistent. We should recoup the cost 
later with the display uncore split (if I manage to find time to get 
back to it).

> 
> BSpec: 18331.

This should be 52078 for TGL.

> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Signed-off-by: Michel Thierry <michel.thierry@intel.com>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/intel_uncore.c           | 75 ++++++++++++++++++-
>   drivers/gpu/drm/i915/selftests/intel_uncore.c |  2 +
>   2 files changed, 76 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index 9e583f13a9e4..18e8314641a8 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -910,6 +910,9 @@ static const struct intel_forcewake_range __vlv_fw_ranges[] = {
>   	__fwd; \
>   })
>   
> +#define __gen12_fwtable_reg_read_fw_domains(uncore, offset) \
> +	find_fw_domain(uncore, offset)
> +
>   /* *Must* be sorted by offset! See intel_shadow_table_check(). */
>   static const i915_reg_t gen8_shadowed_regs[] = {
>   	RING_TAIL(RENDER_RING_BASE),	/* 0x2000 (base) */
> @@ -935,6 +938,20 @@ static const i915_reg_t gen11_shadowed_regs[] = {
>   	/* TODO: Other registers are not yet used */
>   };
>   
> +static const i915_reg_t gen12_shadowed_regs[] = {
> +	RING_TAIL(RENDER_RING_BASE),		/* 0x2000 (base) */
> +	GEN6_RPNSWREQ,				/* 0xA008 */
> +	GEN6_RC_VIDEO_FREQ,			/* 0xA00C */
> +	RING_TAIL(BLT_RING_BASE),		/* 0x22000 (base) */
> +	RING_TAIL(GEN11_BSD_RING_BASE),		/* 0x1C0000 (base) */
> +	RING_TAIL(GEN11_BSD2_RING_BASE),	/* 0x1C4000 (base) */
> +	RING_TAIL(GEN11_VEBOX_RING_BASE),	/* 0x1C8000 (base) */
> +	RING_TAIL(GEN11_BSD3_RING_BASE),	/* 0x1D0000 (base) */
> +	RING_TAIL(GEN11_BSD4_RING_BASE),	/* 0x1D4000 (base) */
> +	RING_TAIL(GEN11_VEBOX2_RING_BASE),	/* 0x1D8000 (base) */
> +	/* TODO: Other registers are not yet used */
> +};
> +
>   static int mmio_reg_cmp(u32 key, const i915_reg_t *reg)
>   {
>   	u32 offset = i915_mmio_reg_offset(*reg);
> @@ -957,6 +974,7 @@ static bool is_gen##x##_shadowed(u32 offset) \
>   
>   __is_genX_shadowed(8)
>   __is_genX_shadowed(11)
> +__is_genX_shadowed(12)
>   
>   static enum forcewake_domains
>   gen6_reg_write_fw_domains(struct intel_uncore *uncore, i915_reg_t reg)
> @@ -1010,6 +1028,15 @@ static const struct intel_forcewake_range __chv_fw_ranges[] = {
>   	__fwd; \
>   })
>   
> +#define __gen12_fwtable_reg_write_fw_domains(uncore, offset) \
> +({ \
> +	enum forcewake_domains __fwd = 0; \
> +	const u32 __offset = (offset); \
> +	if (!is_gen12_shadowed(__offset)) \
> +		__fwd = find_fw_domain(uncore, __offset); \
> +	__fwd; \
> +})
> +
>   /* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
>   static const struct intel_forcewake_range __gen9_fw_ranges[] = {
>   	GEN_FW_RANGE(0x0, 0xaff, FORCEWAKE_BLITTER),
> @@ -1080,6 +1107,46 @@ static const struct intel_forcewake_range __gen11_fw_ranges[] = {
>   	GEN_FW_RANGE(0x1d8000, 0x1dbfff, FORCEWAKE_MEDIA_VEBOX1)
>   };
>   
> +/* *Must* be sorted by offset ranges! See intel_fw_table_check(). */
> +static const struct intel_forcewake_range __gen12_fw_ranges[] = {
> +	GEN_FW_RANGE(0x0, 0xaff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0xb00, 0x1fff, 0), /* uncore range */
> +	GEN_FW_RANGE(0x2000, 0x26ff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x2700, 0x2fff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x3000, 0x3fff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x4000, 0x51ff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x5200, 0x7fff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x8000, 0x813f, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x8140, 0x815f, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x8160, 0x82ff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x8300, 0x84ff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x8500, 0x8bff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x8c00, 0x8cff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x8d00, 0x93ff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x9400, 0x97ff, FORCEWAKE_ALL),
> +	GEN_FW_RANGE(0x9800, 0xafff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0xb000, 0xb47f, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0xb480, 0xdfff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0xe000, 0xe8ff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0xe900, 0x147ff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x14800, 0x148ff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x14900, 0x19fff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x1a000, 0x1a7ff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x1a800, 0x1afff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x1b000, 0x1bfff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x1c000, 0x243ff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x24400, 0x247ff, FORCEWAKE_RENDER),
> +	GEN_FW_RANGE(0x24800, 0x3ffff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x40000, 0x1bffff, 0),
> +	GEN_FW_RANGE(0x1c0000, 0x1c3fff, FORCEWAKE_MEDIA_VDBOX0),
> +	GEN_FW_RANGE(0x1c4000, 0x1c7fff, FORCEWAKE_MEDIA_VDBOX1),
> +	GEN_FW_RANGE(0x1c8000, 0x1cbfff, FORCEWAKE_MEDIA_VEBOX0),
> +	GEN_FW_RANGE(0x1cc000, 0x1cffff, FORCEWAKE_BLITTER),
> +	GEN_FW_RANGE(0x1d0000, 0x1d3fff, FORCEWAKE_MEDIA_VDBOX2),
> +	GEN_FW_RANGE(0x1d4000, 0x1d7fff, FORCEWAKE_MEDIA_VDBOX3),
> +	GEN_FW_RANGE(0x1d8000, 0x1dbfff, FORCEWAKE_MEDIA_VEBOX1)
> +};
> +

Matches the specs. The Gen11 specs also now lists the new 
FORCEWAKE_RENDER ranges, so I was wondering if they were just unused on 
gen11 and we could maybe just add them to the gen11 table, but then I 
noticed that the gen11 table also now has the following ranges marked as 
RENDER (which we currently do not have):

	0xDF00-0xDFFF
	0x16E00-0x16FFF
	0x17000-0x17FFF
	0x18000-0x19FFF

So there is anyway a divergence and we need 2 separate table (and we 
need to fix the gen11 one).

Daniele

>   static void
>   ilk_dummy_write(struct intel_uncore *uncore)
>   {
> @@ -1228,6 +1295,7 @@ __gen_read(func, 16) \
>   __gen_read(func, 32) \
>   __gen_read(func, 64)
>   
> +__gen_reg_read_funcs(gen12_fwtable);
>   __gen_reg_read_funcs(gen11_fwtable);
>   __gen_reg_read_funcs(fwtable);
>   __gen_reg_read_funcs(gen6);
> @@ -1319,6 +1387,7 @@ __gen_write(func, 8) \
>   __gen_write(func, 16) \
>   __gen_write(func, 32)
>   
> +__gen_reg_write_funcs(gen12_fwtable);
>   __gen_reg_write_funcs(gen11_fwtable);
>   __gen_reg_write_funcs(fwtable);
>   __gen_reg_write_funcs(gen8);
> @@ -1690,10 +1759,14 @@ static int uncore_forcewake_init(struct intel_uncore *uncore)
>   		ASSIGN_FW_DOMAINS_TABLE(uncore, __gen9_fw_ranges);
>   		ASSIGN_WRITE_MMIO_VFUNCS(uncore, fwtable);
>   		ASSIGN_READ_MMIO_VFUNCS(uncore, fwtable);
> -	} else {
> +	} else if (IS_GEN(i915, 11)) {
>   		ASSIGN_FW_DOMAINS_TABLE(uncore, __gen11_fw_ranges);
>   		ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen11_fwtable);
>   		ASSIGN_READ_MMIO_VFUNCS(uncore, gen11_fwtable);
> +	} else {
> +		ASSIGN_FW_DOMAINS_TABLE(uncore, __gen12_fw_ranges);
> +		ASSIGN_WRITE_MMIO_VFUNCS(uncore, gen12_fwtable);
> +		ASSIGN_READ_MMIO_VFUNCS(uncore, gen12_fwtable);
>   	}
>   
>   	uncore->pmic_bus_access_nb.notifier_call = i915_pmic_bus_access_notifier;
> diff --git a/drivers/gpu/drm/i915/selftests/intel_uncore.c b/drivers/gpu/drm/i915/selftests/intel_uncore.c
> index 86815c6072a1..0ffb141eb988 100644
> --- a/drivers/gpu/drm/i915/selftests/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/selftests/intel_uncore.c
> @@ -67,6 +67,7 @@ static int intel_shadow_table_check(void)
>   	} reg_lists[] = {
>   		{ gen8_shadowed_regs, ARRAY_SIZE(gen8_shadowed_regs) },
>   		{ gen11_shadowed_regs, ARRAY_SIZE(gen11_shadowed_regs) },
> +		{ gen12_shadowed_regs, ARRAY_SIZE(gen12_shadowed_regs) },
>   	};
>   	const i915_reg_t *reg;
>   	unsigned int i, j;
> @@ -101,6 +102,7 @@ int intel_uncore_mock_selftests(void)
>   		{ __chv_fw_ranges, ARRAY_SIZE(__chv_fw_ranges), false },
>   		{ __gen9_fw_ranges, ARRAY_SIZE(__gen9_fw_ranges), true },
>   		{ __gen11_fw_ranges, ARRAY_SIZE(__gen11_fw_ranges), true },
> +		{ __gen12_fw_ranges, ARRAY_SIZE(__gen12_fw_ranges), true },
>   	};
>   	int err, i;
>   
>