drm/i915: Extract knowledge of register forcewake domains

Knowledge of which register per platform belonds in which
forcewake domain was embedded in the MMIO accessors themselves.

Extract it into standalone macros so they can be used from
new code in the following patches.

This causes GCC to compile some of the MMIO accessors slightly
differently and grows the code a tiny amount. But none of the
growth is on the fast-path so it does not matter hugely.

Affected sizes before:

00000000000026f0 00000000000001a5 t gen6_read16
0000000000002390 00000000000001a5 t gen6_read32
00000000000028a0 00000000000001a5 t gen6_read64

00000000000061d0 000000000000019e t gen8_write16
0000000000006510 000000000000019d t gen8_write32
0000000000006370 000000000000019d t gen8_write64
00000000000021f0 000000000000019d t gen8_write8

Affected sizes after:

0000000000002840 00000000000001aa t gen6_read16
00000000000024e0 00000000000001a9 t gen6_read32
00000000000029f0 00000000000001a9 t gen6_read64

0000000000004f20 00000000000001b5 t gen8_write16
0000000000004ba0 00000000000001b4 t gen8_write32
00000000000050e0 00000000000001b4 t gen8_write64
0000000000004d60 00000000000001b4 t gen8_write8

Other MMIO accessors are not affected in size.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Tvrtko Ursulin 2016-04-12 14:37:29 +01:00
parent 4e1176dd61
commit 6863b76c62
1 changed files with 155 additions and 100 deletions

View File

@ -552,6 +552,16 @@ void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
/* We give fast paths for the really cool registers */ /* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(reg) ((reg) < 0x40000) #define NEEDS_FORCE_WAKE(reg) ((reg) < 0x40000)
#define __gen6_reg_read_fw_domains(offset) \
({ \
enum forcewake_domains __fwd; \
if (NEEDS_FORCE_WAKE(offset)) \
__fwd = FORCEWAKE_RENDER; \
else \
__fwd = 0; \
__fwd; \
})
#define REG_RANGE(reg, start, end) ((reg) >= (start) && (reg) < (end)) #define REG_RANGE(reg, start, end) ((reg) >= (start) && (reg) < (end))
#define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \ #define FORCEWAKE_VLV_RENDER_RANGE_OFFSET(reg) \
@ -565,6 +575,49 @@ void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
REG_RANGE((reg), 0x22000, 0x24000) || \ REG_RANGE((reg), 0x22000, 0x24000) || \
REG_RANGE((reg), 0x30000, 0x40000)) REG_RANGE((reg), 0x30000, 0x40000))
#define __vlv_reg_read_fw_domains(offset) \
({ \
enum forcewake_domains __fwd = 0; \
if (!NEEDS_FORCE_WAKE(offset)) \
__fwd = 0; \
else if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER; \
else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_MEDIA; \
__fwd; \
})
static const i915_reg_t gen8_shadowed_regs[] = {
FORCEWAKE_MT,
GEN6_RPNSWREQ,
GEN6_RC_VIDEO_FREQ,
RING_TAIL(RENDER_RING_BASE),
RING_TAIL(GEN6_BSD_RING_BASE),
RING_TAIL(VEBOX_RING_BASE),
RING_TAIL(BLT_RING_BASE),
/* TODO: Other registers are not yet used */
};
static bool is_gen8_shadowed(u32 offset)
{
int i;
for (i = 0; i < ARRAY_SIZE(gen8_shadowed_regs); i++)
if (offset == gen8_shadowed_regs[i].reg)
return true;
return false;
}
#define __gen8_reg_write_fw_domains(offset) \
({ \
enum forcewake_domains __fwd; \
if (NEEDS_FORCE_WAKE(offset) && !is_gen8_shadowed(offset)) \
__fwd = FORCEWAKE_RENDER; \
else \
__fwd = 0; \
__fwd; \
})
#define FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg) \ #define FORCEWAKE_CHV_RENDER_RANGE_OFFSET(reg) \
(REG_RANGE((reg), 0x2000, 0x4000) || \ (REG_RANGE((reg), 0x2000, 0x4000) || \
REG_RANGE((reg), 0x5200, 0x8000) || \ REG_RANGE((reg), 0x5200, 0x8000) || \
@ -587,6 +640,34 @@ void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
REG_RANGE((reg), 0x9000, 0xB000) || \ REG_RANGE((reg), 0x9000, 0xB000) || \
REG_RANGE((reg), 0xF000, 0x10000)) REG_RANGE((reg), 0xF000, 0x10000))
#define __chv_reg_read_fw_domains(offset) \
({ \
enum forcewake_domains __fwd = 0; \
if (!NEEDS_FORCE_WAKE(offset)) \
__fwd = 0; \
else if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER; \
else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
__fwd; \
})
#define __chv_reg_write_fw_domains(offset) \
({ \
enum forcewake_domains __fwd = 0; \
if (!NEEDS_FORCE_WAKE(offset) || is_gen8_shadowed(offset)) \
__fwd = 0; \
else if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER; \
else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
__fwd; \
})
#define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \ #define FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg) \
REG_RANGE((reg), 0xB00, 0x2000) REG_RANGE((reg), 0xB00, 0x2000)
@ -619,6 +700,64 @@ void assert_forcewakes_inactive(struct drm_i915_private *dev_priv)
!FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \ !FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(reg) && \
!FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg)) !FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(reg))
#define SKL_NEEDS_FORCE_WAKE(reg) \
((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg))
#define __gen9_reg_read_fw_domains(offset) \
({ \
enum forcewake_domains __fwd; \
if (!SKL_NEEDS_FORCE_WAKE(offset)) \
__fwd = 0; \
else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER; \
else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
else \
__fwd = FORCEWAKE_BLITTER; \
__fwd; \
})
static const i915_reg_t gen9_shadowed_regs[] = {
RING_TAIL(RENDER_RING_BASE),
RING_TAIL(GEN6_BSD_RING_BASE),
RING_TAIL(VEBOX_RING_BASE),
RING_TAIL(BLT_RING_BASE),
FORCEWAKE_BLITTER_GEN9,
FORCEWAKE_RENDER_GEN9,
FORCEWAKE_MEDIA_GEN9,
GEN6_RPNSWREQ,
GEN6_RC_VIDEO_FREQ,
/* TODO: Other registers are not yet used */
};
static bool is_gen9_shadowed(u32 offset)
{
int i;
for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
if (offset == gen9_shadowed_regs[i].reg)
return true;
return false;
}
#define __gen9_reg_write_fw_domains(offset) \
({ \
enum forcewake_domains __fwd; \
if (!SKL_NEEDS_FORCE_WAKE(offset) || is_gen9_shadowed(offset)) \
__fwd = 0; \
else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER; \
else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(offset)) \
__fwd = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
else \
__fwd = FORCEWAKE_BLITTER; \
__fwd; \
})
static void static void
ilk_dummy_write(struct drm_i915_private *dev_priv) ilk_dummy_write(struct drm_i915_private *dev_priv)
{ {
@ -742,9 +881,11 @@ static inline void __force_wake_auto(struct drm_i915_private *dev_priv,
#define __gen6_read(x) \ #define __gen6_read(x) \
static u##x \ static u##x \
gen6_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ gen6_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
enum forcewake_domains fw_engine; \
GEN6_READ_HEADER(x); \ GEN6_READ_HEADER(x); \
if (NEEDS_FORCE_WAKE(offset)) \ fw_engine = __gen6_reg_read_fw_domains(offset); \
__force_wake_auto(dev_priv, FORCEWAKE_RENDER); \ if (fw_engine) \
__force_wake_auto(dev_priv, fw_engine); \
val = __raw_i915_read##x(dev_priv, reg); \ val = __raw_i915_read##x(dev_priv, reg); \
GEN6_READ_FOOTER; \ GEN6_READ_FOOTER; \
} }
@ -752,14 +893,9 @@ gen6_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
#define __vlv_read(x) \ #define __vlv_read(x) \
static u##x \ static u##x \
vlv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ vlv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
enum forcewake_domains fw_engine = 0; \ enum forcewake_domains fw_engine; \
GEN6_READ_HEADER(x); \ GEN6_READ_HEADER(x); \
if (!NEEDS_FORCE_WAKE(offset)) \ fw_engine = __vlv_reg_read_fw_domains(offset); \
fw_engine = 0; \
else if (FORCEWAKE_VLV_RENDER_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER; \
else if (FORCEWAKE_VLV_MEDIA_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_MEDIA; \
if (fw_engine) \ if (fw_engine) \
__force_wake_auto(dev_priv, fw_engine); \ __force_wake_auto(dev_priv, fw_engine); \
val = __raw_i915_read##x(dev_priv, reg); \ val = __raw_i915_read##x(dev_priv, reg); \
@ -769,40 +905,21 @@ vlv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
#define __chv_read(x) \ #define __chv_read(x) \
static u##x \ static u##x \
chv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ chv_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
enum forcewake_domains fw_engine = 0; \ enum forcewake_domains fw_engine; \
GEN6_READ_HEADER(x); \ GEN6_READ_HEADER(x); \
if (!NEEDS_FORCE_WAKE(offset)) \ fw_engine = __chv_reg_read_fw_domains(offset); \
fw_engine = 0; \
else if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER; \
else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
if (fw_engine) \ if (fw_engine) \
__force_wake_auto(dev_priv, fw_engine); \ __force_wake_auto(dev_priv, fw_engine); \
val = __raw_i915_read##x(dev_priv, reg); \ val = __raw_i915_read##x(dev_priv, reg); \
GEN6_READ_FOOTER; \ GEN6_READ_FOOTER; \
} }
#define SKL_NEEDS_FORCE_WAKE(reg) \
((reg) < 0x40000 && !FORCEWAKE_GEN9_UNCORE_RANGE_OFFSET(reg))
#define __gen9_read(x) \ #define __gen9_read(x) \
static u##x \ static u##x \
gen9_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \ gen9_read##x(struct drm_i915_private *dev_priv, i915_reg_t reg, bool trace) { \
enum forcewake_domains fw_engine; \ enum forcewake_domains fw_engine; \
GEN6_READ_HEADER(x); \ GEN6_READ_HEADER(x); \
if (!SKL_NEEDS_FORCE_WAKE(offset)) \ fw_engine = __gen9_reg_read_fw_domains(offset); \
fw_engine = 0; \
else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER; \
else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
else \
fw_engine = FORCEWAKE_BLITTER; \
if (fw_engine) \ if (fw_engine) \
__force_wake_auto(dev_priv, fw_engine); \ __force_wake_auto(dev_priv, fw_engine); \
val = __raw_i915_read##x(dev_priv, reg); \ val = __raw_i915_read##x(dev_priv, reg); \
@ -941,34 +1058,14 @@ hsw_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool t
GEN6_WRITE_FOOTER; \ GEN6_WRITE_FOOTER; \
} }
static const i915_reg_t gen8_shadowed_regs[] = {
FORCEWAKE_MT,
GEN6_RPNSWREQ,
GEN6_RC_VIDEO_FREQ,
RING_TAIL(RENDER_RING_BASE),
RING_TAIL(GEN6_BSD_RING_BASE),
RING_TAIL(VEBOX_RING_BASE),
RING_TAIL(BLT_RING_BASE),
/* TODO: Other registers are not yet used */
};
static bool is_gen8_shadowed(struct drm_i915_private *dev_priv,
i915_reg_t reg)
{
int i;
for (i = 0; i < ARRAY_SIZE(gen8_shadowed_regs); i++)
if (i915_mmio_reg_equal(reg, gen8_shadowed_regs[i]))
return true;
return false;
}
#define __gen8_write(x) \ #define __gen8_write(x) \
static void \ static void \
gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \ gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
enum forcewake_domains fw_engine; \
GEN6_WRITE_HEADER; \ GEN6_WRITE_HEADER; \
if (NEEDS_FORCE_WAKE(offset) && !is_gen8_shadowed(dev_priv, reg)) \ fw_engine = __gen8_reg_write_fw_domains(offset); \
__force_wake_auto(dev_priv, FORCEWAKE_RENDER); \ if (fw_engine) \
__force_wake_auto(dev_priv, fw_engine); \
__raw_i915_write##x(dev_priv, reg, val); \ __raw_i915_write##x(dev_priv, reg, val); \
GEN6_WRITE_FOOTER; \ GEN6_WRITE_FOOTER; \
} }
@ -976,64 +1073,22 @@ gen8_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool
#define __chv_write(x) \ #define __chv_write(x) \
static void \ static void \
chv_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \ chv_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, bool trace) { \
enum forcewake_domains fw_engine = 0; \ enum forcewake_domains fw_engine; \
GEN6_WRITE_HEADER; \ GEN6_WRITE_HEADER; \
if (!NEEDS_FORCE_WAKE(offset) || \ fw_engine = __chv_reg_write_fw_domains(offset); \
is_gen8_shadowed(dev_priv, reg)) \
fw_engine = 0; \
else if (FORCEWAKE_CHV_RENDER_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER; \
else if (FORCEWAKE_CHV_MEDIA_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_CHV_COMMON_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
if (fw_engine) \ if (fw_engine) \
__force_wake_auto(dev_priv, fw_engine); \ __force_wake_auto(dev_priv, fw_engine); \
__raw_i915_write##x(dev_priv, reg, val); \ __raw_i915_write##x(dev_priv, reg, val); \
GEN6_WRITE_FOOTER; \ GEN6_WRITE_FOOTER; \
} }
static const i915_reg_t gen9_shadowed_regs[] = {
RING_TAIL(RENDER_RING_BASE),
RING_TAIL(GEN6_BSD_RING_BASE),
RING_TAIL(VEBOX_RING_BASE),
RING_TAIL(BLT_RING_BASE),
FORCEWAKE_BLITTER_GEN9,
FORCEWAKE_RENDER_GEN9,
FORCEWAKE_MEDIA_GEN9,
GEN6_RPNSWREQ,
GEN6_RC_VIDEO_FREQ,
/* TODO: Other registers are not yet used */
};
static bool is_gen9_shadowed(struct drm_i915_private *dev_priv,
i915_reg_t reg)
{
int i;
for (i = 0; i < ARRAY_SIZE(gen9_shadowed_regs); i++)
if (i915_mmio_reg_equal(reg, gen9_shadowed_regs[i]))
return true;
return false;
}
#define __gen9_write(x) \ #define __gen9_write(x) \
static void \ static void \
gen9_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, \ gen9_write##x(struct drm_i915_private *dev_priv, i915_reg_t reg, u##x val, \
bool trace) { \ bool trace) { \
enum forcewake_domains fw_engine; \ enum forcewake_domains fw_engine; \
GEN6_WRITE_HEADER; \ GEN6_WRITE_HEADER; \
if (!SKL_NEEDS_FORCE_WAKE(offset) || \ fw_engine = __gen9_reg_write_fw_domains(offset); \
is_gen9_shadowed(dev_priv, reg)) \
fw_engine = 0; \
else if (FORCEWAKE_GEN9_RENDER_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER; \
else if (FORCEWAKE_GEN9_MEDIA_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_MEDIA; \
else if (FORCEWAKE_GEN9_COMMON_RANGE_OFFSET(offset)) \
fw_engine = FORCEWAKE_RENDER | FORCEWAKE_MEDIA; \
else \
fw_engine = FORCEWAKE_BLITTER; \
if (fw_engine) \ if (fw_engine) \
__force_wake_auto(dev_priv, fw_engine); \ __force_wake_auto(dev_priv, fw_engine); \
__raw_i915_write##x(dev_priv, reg, val); \ __raw_i915_write##x(dev_priv, reg, val); \