Skip to content

Commit 26376a7

Browse files
Oscar Mateomikuint
authored andcommitted
drm/i915/icl: Check for fused-off VDBOX and VEBOX instances
In Gen11, the Video Decode engines (aka VDBOX, aka VCS, aka BSD) and the Video Enhancement engines (aka VEBOX, aka VECS) could be fused off. Also, each VDBOX and VEBOX has its own power well, which only exist if the related engine exists in the HW. Unfortunately, we have a Catch-22 situation going on: we need the blitter forcewake to read the register with the fuse info, but we cannot initialize the forcewake domains without knowin about the engines present in the HW. We workaround this problem by allowing the initialization of all forcewake domains and then pruning the fused off ones, as per the fuse information. Bspec: 20680 v2: We were shifting incorrectly for vebox disable (Vinay) v3: Assert mmio is ready and warn if we have attempted to initialize forcewake for fused-off engines (Paulo) v4: - Use INTEL_GEN in new code (Tvrtko) - Shorter local variable (Tvrtko, Michal) - Keep "if (!...) continue" style (Tvrtko) - No unnecessary BUG_ON (Tvrtko) - WARN_ON and cleanup if wrong mask (Tvrtko, Michal) - Use I915_READ_FW (Michal) - Use I915_MAX_VCS/VECS macros (Michal) v5: Rebased by Rodrigo fixing conflicts on top of: "drm/i915: Simplify intel_engines_init" v6: Fix v5. Remove info->num_rings. (by Oscar) v7: Rebase (Rodrigo). v8: - s/intel_device_info_fused_off_engines/ intel_device_info_init_mmio (Chris) - Make vdbox_disable & vebox_disable local variables (Chris) v9: - Move function declaration to intel_device_info.h (Michal) - Missing indent in bit fields definitions (Michal) - When RC6 is enabled by BIOS, the fuse register cannot be read until the blitter powerwell is awake. Shuffle where the fuse is read, prune the forcewake domains after the fact and change the commit message accordingly (Vinay, Sagar, Chris). v10: - Improved commit message (Sagar) - New line in header file (Sagar) - Specify the message in fw_domain_reset applies to ICL+ (Sagar) Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Cc: Vinay Belgaumkar <vinay.belgaumkar@intel.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Oscar Mateo <oscar.mateo@intel.com> Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180316121456.11577-1-mika.kuoppala@linux.intel.com [Mika: soothe checkpatch on commit msg] Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
1 parent 91b00df commit 26376a7

File tree

6 files changed

+115
-0
lines changed

6 files changed

+115
-0
lines changed

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,10 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
10331033

10341034
intel_uncore_init(dev_priv);
10351035

1036+
intel_device_info_init_mmio(dev_priv);
1037+
1038+
intel_uncore_prune(dev_priv);
1039+
10361040
intel_uc_init_mmio(dev_priv);
10371041

10381042
ret = intel_engines_init_mmio(dev_priv);

drivers/gpu/drm/i915/i915_reg.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2545,6 +2545,11 @@ enum i915_power_well_id {
25452545
#define GEN10_EU_DISABLE3 _MMIO(0x9140)
25462546
#define GEN10_EU_DIS_SS_MASK 0xff
25472547

2548+
#define GEN11_GT_VEBOX_VDBOX_DISABLE _MMIO(0x9140)
2549+
#define GEN11_GT_VDBOX_DISABLE_MASK 0xff
2550+
#define GEN11_GT_VEBOX_DISABLE_SHIFT 16
2551+
#define GEN11_GT_VEBOX_DISABLE_MASK (0xff << GEN11_GT_VEBOX_DISABLE_SHIFT)
2552+
25482553
#define GEN6_BSD_SLEEP_PSMI_CONTROL _MMIO(0x12050)
25492554
#define GEN6_BSD_SLEEP_MSG_DISABLE (1 << 0)
25502555
#define GEN6_BSD_SLEEP_FLUSH_DISABLE (1 << 2)

drivers/gpu/drm/i915/intel_device_info.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,3 +780,50 @@ void intel_driver_caps_print(const struct intel_driver_caps *caps,
780780
{
781781
drm_printf(p, "scheduler: %x\n", caps->scheduler);
782782
}
783+
784+
/*
785+
* Determine which engines are fused off in our particular hardware. Since the
786+
* fuse register is in the blitter powerwell, we need forcewake to be ready at
787+
* this point (but later we need to prune the forcewake domains for engines that
788+
* are indeed fused off).
789+
*/
790+
void intel_device_info_init_mmio(struct drm_i915_private *dev_priv)
791+
{
792+
struct intel_device_info *info = mkwrite_device_info(dev_priv);
793+
u8 vdbox_disable, vebox_disable;
794+
u32 media_fuse;
795+
int i;
796+
797+
if (INTEL_GEN(dev_priv) < 11)
798+
return;
799+
800+
media_fuse = I915_READ(GEN11_GT_VEBOX_VDBOX_DISABLE);
801+
802+
vdbox_disable = media_fuse & GEN11_GT_VDBOX_DISABLE_MASK;
803+
vebox_disable = (media_fuse & GEN11_GT_VEBOX_DISABLE_MASK) >>
804+
GEN11_GT_VEBOX_DISABLE_SHIFT;
805+
806+
DRM_DEBUG_DRIVER("vdbox disable: %04x\n", vdbox_disable);
807+
for (i = 0; i < I915_MAX_VCS; i++) {
808+
if (!HAS_ENGINE(dev_priv, _VCS(i)))
809+
continue;
810+
811+
if (!(BIT(i) & vdbox_disable))
812+
continue;
813+
814+
info->ring_mask &= ~ENGINE_MASK(_VCS(i));
815+
DRM_DEBUG_DRIVER("vcs%u fused off\n", i);
816+
}
817+
818+
DRM_DEBUG_DRIVER("vebox disable: %04x\n", vebox_disable);
819+
for (i = 0; i < I915_MAX_VECS; i++) {
820+
if (!HAS_ENGINE(dev_priv, _VECS(i)))
821+
continue;
822+
823+
if (!(BIT(i) & vebox_disable))
824+
continue;
825+
826+
info->ring_mask &= ~ENGINE_MASK(_VECS(i));
827+
DRM_DEBUG_DRIVER("vecs%u fused off\n", i);
828+
}
829+
}

drivers/gpu/drm/i915/intel_device_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,8 @@ void intel_device_info_dump_runtime(const struct intel_device_info *info,
247247
void intel_device_info_dump_topology(const struct sseu_dev_info *sseu,
248248
struct drm_printer *p);
249249

250+
void intel_device_info_init_mmio(struct drm_i915_private *dev_priv);
251+
250252
void intel_driver_caps_print(const struct intel_driver_caps *caps,
251253
struct drm_printer *p);
252254

drivers/gpu/drm/i915/intel_uncore.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ static inline void
6262
fw_domain_reset(struct drm_i915_private *i915,
6363
const struct intel_uncore_forcewake_domain *d)
6464
{
65+
/*
66+
* We don't really know if the powerwell for the forcewake domain we are
67+
* trying to reset here does exist at this point (engines could be fused
68+
* off in ICL+), so no waiting for acks
69+
*/
6570
__raw_i915_write32(i915, d->reg_set, i915->uncore.fw_reset);
6671
}
6772

@@ -1353,6 +1358,23 @@ static void fw_domain_init(struct drm_i915_private *dev_priv,
13531358
fw_domain_reset(dev_priv, d);
13541359
}
13551360

1361+
static void fw_domain_fini(struct drm_i915_private *dev_priv,
1362+
enum forcewake_domain_id domain_id)
1363+
{
1364+
struct intel_uncore_forcewake_domain *d;
1365+
1366+
if (WARN_ON(domain_id >= FW_DOMAIN_ID_COUNT))
1367+
return;
1368+
1369+
d = &dev_priv->uncore.fw_domain[domain_id];
1370+
1371+
WARN_ON(d->wake_count);
1372+
WARN_ON(hrtimer_cancel(&d->timer));
1373+
memset(d, 0, sizeof(*d));
1374+
1375+
dev_priv->uncore.fw_domains &= ~BIT(domain_id);
1376+
}
1377+
13561378
static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
13571379
{
13581380
if (INTEL_GEN(dev_priv) <= 5 || intel_vgpu_active(dev_priv))
@@ -1565,6 +1587,40 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
15651587
&dev_priv->uncore.pmic_bus_access_nb);
15661588
}
15671589

1590+
/*
1591+
* We might have detected that some engines are fused off after we initialized
1592+
* the forcewake domains. Prune them, to make sure they only reference existing
1593+
* engines.
1594+
*/
1595+
void intel_uncore_prune(struct drm_i915_private *dev_priv)
1596+
{
1597+
if (INTEL_GEN(dev_priv) >= 11) {
1598+
enum forcewake_domains fw_domains = dev_priv->uncore.fw_domains;
1599+
enum forcewake_domain_id domain_id;
1600+
int i;
1601+
1602+
for (i = 0; i < I915_MAX_VCS; i++) {
1603+
domain_id = FW_DOMAIN_ID_MEDIA_VDBOX0 + i;
1604+
1605+
if (HAS_ENGINE(dev_priv, _VCS(i)))
1606+
continue;
1607+
1608+
if (fw_domains & BIT(domain_id))
1609+
fw_domain_fini(dev_priv, domain_id);
1610+
}
1611+
1612+
for (i = 0; i < I915_MAX_VECS; i++) {
1613+
domain_id = FW_DOMAIN_ID_MEDIA_VEBOX0 + i;
1614+
1615+
if (HAS_ENGINE(dev_priv, _VECS(i)))
1616+
continue;
1617+
1618+
if (fw_domains & BIT(domain_id))
1619+
fw_domain_fini(dev_priv, domain_id);
1620+
}
1621+
}
1622+
}
1623+
15681624
void intel_uncore_fini(struct drm_i915_private *dev_priv)
15691625
{
15701626
/* Paranoia: make sure we have disabled everything before we exit. */

drivers/gpu/drm/i915/intel_uncore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ struct intel_uncore {
140140

141141
void intel_uncore_sanitize(struct drm_i915_private *dev_priv);
142142
void intel_uncore_init(struct drm_i915_private *dev_priv);
143+
void intel_uncore_prune(struct drm_i915_private *dev_priv);
143144
bool intel_uncore_unclaimed_mmio(struct drm_i915_private *dev_priv);
144145
bool intel_uncore_arm_unclaimed_mmio_detection(struct drm_i915_private *dev_priv);
145146
void intel_uncore_fini(struct drm_i915_private *dev_priv);

0 commit comments

Comments
 (0)