+
if (INTEL_GEN(i915) >= 11) {
int i;
- uncore->funcs.force_wake_get =
- fw_domains_get_with_fallback;
+ uncore->funcs.force_wake_get = fw_domains_get_with_fallback;
uncore->funcs.force_wake_put = fw_domains_put;
- fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
- FORCEWAKE_RENDER_GEN9,
- FORCEWAKE_ACK_RENDER_GEN9);
- fw_domain_init(uncore, FW_DOMAIN_ID_BLITTER,
- FORCEWAKE_BLITTER_GEN9,
- FORCEWAKE_ACK_BLITTER_GEN9);
+ __fw_domain_init(FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_RENDER_GEN9,
+ FORCEWAKE_ACK_RENDER_GEN9);
+ __fw_domain_init(FW_DOMAIN_ID_BLITTER,
+ FORCEWAKE_BLITTER_GEN9,
+ FORCEWAKE_ACK_BLITTER_GEN9);
+
for (i = 0; i < I915_MAX_VCS; i++) {
if (!HAS_ENGINE(i915, _VCS(i)))
continue;
- fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA_VDBOX0 + i,
- FORCEWAKE_MEDIA_VDBOX_GEN11(i),
- FORCEWAKE_ACK_MEDIA_VDBOX_GEN11(i));
+ __fw_domain_init(FW_DOMAIN_ID_MEDIA_VDBOX0 + i,
+ FORCEWAKE_MEDIA_VDBOX_GEN11(i),
+ FORCEWAKE_ACK_MEDIA_VDBOX_GEN11(i));
}
for (i = 0; i < I915_MAX_VECS; i++) {
if (!HAS_ENGINE(i915, _VECS(i)))
continue;
- fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA_VEBOX0 + i,
- FORCEWAKE_MEDIA_VEBOX_GEN11(i),
- FORCEWAKE_ACK_MEDIA_VEBOX_GEN11(i));
+ __fw_domain_init(FW_DOMAIN_ID_MEDIA_VEBOX0 + i,
+ FORCEWAKE_MEDIA_VEBOX_GEN11(i),
+ FORCEWAKE_ACK_MEDIA_VEBOX_GEN11(i));
}
} else if (IS_GEN_RANGE(i915, 9, 10)) {
- uncore->funcs.force_wake_get =
- fw_domains_get_with_fallback;
+ uncore->funcs.force_wake_get = fw_domains_get_with_fallback;
uncore->funcs.force_wake_put = fw_domains_put;
- fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
- FORCEWAKE_RENDER_GEN9,
- FORCEWAKE_ACK_RENDER_GEN9);
- fw_domain_init(uncore, FW_DOMAIN_ID_BLITTER,
- FORCEWAKE_BLITTER_GEN9,
- FORCEWAKE_ACK_BLITTER_GEN9);
- fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
- FORCEWAKE_MEDIA_GEN9, FORCEWAKE_ACK_MEDIA_GEN9);
+ __fw_domain_init(FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_RENDER_GEN9,
+ FORCEWAKE_ACK_RENDER_GEN9);
+ __fw_domain_init(FW_DOMAIN_ID_BLITTER,
+ FORCEWAKE_BLITTER_GEN9,
+ FORCEWAKE_ACK_BLITTER_GEN9);
+ __fw_domain_init(FW_DOMAIN_ID_MEDIA,
+ FORCEWAKE_MEDIA_GEN9,
+ FORCEWAKE_ACK_MEDIA_GEN9);
} else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
uncore->funcs.force_wake_get = fw_domains_get;
uncore->funcs.force_wake_put = fw_domains_put;
- fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
- FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
- fw_domain_init(uncore, FW_DOMAIN_ID_MEDIA,
- FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
+ __fw_domain_init(FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_VLV, FORCEWAKE_ACK_VLV);
+ __fw_domain_init(FW_DOMAIN_ID_MEDIA,
+ FORCEWAKE_MEDIA_VLV, FORCEWAKE_ACK_MEDIA_VLV);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
uncore->funcs.force_wake_get =
fw_domains_get_with_thread_status;
uncore->funcs.force_wake_put = fw_domains_put;
- fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
- FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
+ __fw_domain_init(FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_MT, FORCEWAKE_ACK_HSW);
} else if (IS_IVYBRIDGE(i915)) {
u32 ecobus;
@@ -1437,8 +1455,8 @@ static void intel_uncore_fw_domains_init(struct
intel_uncore *uncore)
__raw_uncore_write32(uncore, FORCEWAKE, 0);
__raw_posting_read(uncore, ECOBUS);
- fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
- FORCEWAKE_MT, FORCEWAKE_MT_ACK);
+ __fw_domain_init(FW_DOMAIN_ID_RENDER,
+ FORCEWAKE_MT, FORCEWAKE_MT_ACK);
spin_lock_irq(&uncore->lock);
fw_domains_get_with_thread_status(uncore, FORCEWAKE_RENDER);
@@ -1449,19 +1467,27 @@ static void
intel_uncore_fw_domains_init(struct intel_uncore *uncore)
if (!(ecobus & FORCEWAKE_MT_ENABLE)) {
DRM_INFO("No MT forcewake available on Ivybridge, this
can result in issues\n");
DRM_INFO("when using vblank-synced partial screen
updates.\n");
- fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
- FORCEWAKE, FORCEWAKE_ACK);
+ __fw_domain_init(FW_DOMAIN_ID_RENDER,
+ FORCEWAKE, FORCEWAKE_ACK);
}
} else if (IS_GEN(i915, 6)) {
uncore->funcs.force_wake_get =
fw_domains_get_with_thread_status;
uncore->funcs.force_wake_put = fw_domains_put;
- fw_domain_init(uncore, FW_DOMAIN_ID_RENDER,
- FORCEWAKE, FORCEWAKE_ACK);
+ __fw_domain_init(FW_DOMAIN_ID_RENDER,
+ FORCEWAKE, FORCEWAKE_ACK);
}
+#undef __fw_domain_init
+
/* All future platforms are expected to require complex power
gating */
WARN_ON(uncore->fw_domains == 0);
+
+ return 0;
+
+out_clean:
+ intel_uncore_fw_domains_fini(uncore);
+ return ret;
}
#define ASSIGN_FW_DOMAINS_TABLE(uncore, d) \
@@ -1562,13 +1588,17 @@ static void uncore_raw_init(struct
intel_uncore *uncore)
}
}
-static void uncore_forcewake_init(struct intel_uncore *uncore)
+static int uncore_forcewake_init(struct intel_uncore *uncore)
{
struct drm_i915_private *i915 = uncore->i915;
+ int ret;
GEM_BUG_ON(!intel_uncore_has_forcewake(uncore));
- intel_uncore_fw_domains_init(uncore);
+ ret = intel_uncore_fw_domains_init(uncore);
+ if (ret)
+ return ret;
+
forcewake_early_sanitize(uncore, 0);
if (IS_GEN_RANGE(i915, 6, 7)) {
@@ -1601,6 +1631,8 @@ static void uncore_forcewake_init(struct
intel_uncore *uncore)
uncore->pmic_bus_access_nb.notifier_call =
i915_pmic_bus_access_notifier;
iosf_mbi_register_pmic_bus_access_notifier(&uncore->pmic_bus_access_nb);
+
+ return 0;
}
int intel_uncore_init_mmio(struct intel_uncore *uncore)
@@ -1619,10 +1651,13 @@ int intel_uncore_init_mmio(struct
intel_uncore *uncore)
uncore->unclaimed_mmio_check = 1;
- if (!intel_uncore_has_forcewake(uncore))
+ if (!intel_uncore_has_forcewake(uncore)) {
uncore_raw_init(uncore);
- else
- uncore_forcewake_init(uncore);
+ } else {
+ ret = uncore_forcewake_init(uncore);
+ if (ret)
+ goto out_mmio_cleanup;
+ }
/* make sure fw funcs are set if and only if we have fw*/
GEM_BUG_ON(intel_uncore_has_forcewake(uncore) !=
!!uncore->funcs.force_wake_get);
@@ -1644,6 +1679,11 @@ int intel_uncore_init_mmio(struct intel_uncore
*uncore)
DRM_DEBUG("unclaimed mmio detected on uncore init,
clearing\n");
return 0;
+
+out_mmio_cleanup:
+ uncore_mmio_cleanup(uncore);
+
+ return ret;
}
/*
@@ -1689,6 +1729,7 @@ void intel_uncore_fini_mmio(struct intel_uncore
*uncore)
iosf_mbi_unregister_pmic_bus_access_notifier_unlocked(
&uncore->pmic_bus_access_nb);
intel_uncore_forcewake_reset(uncore);
+ intel_uncore_fw_domains_fini(uncore);
iosf_mbi_punit_release();
}
diff --git a/drivers/gpu/drm/i915/intel_uncore.h
b/drivers/gpu/drm/i915/intel_uncore.h
index 879252735bba..bbff281b880d 100644
--- a/drivers/gpu/drm/i915/intel_uncore.h
+++ b/drivers/gpu/drm/i915/intel_uncore.h
@@ -126,6 +126,7 @@ struct intel_uncore {
enum forcewake_domains fw_domains_saved; /* user domains saved
for S3 */
struct intel_uncore_forcewake_domain {
+ struct intel_uncore *uncore;
enum forcewake_domain_id id;
enum forcewake_domains mask;
unsigned int wake_count;
@@ -133,7 +134,7 @@ struct intel_uncore {
struct hrtimer timer;
u32 __iomem *reg_set;
u32 __iomem *reg_ack;
- } fw_domain[FW_DOMAIN_ID_COUNT];
+ } *fw_domain[FW_DOMAIN_ID_COUNT];