Commit 42014f69 authored by Andi Shyti's avatar Andi Shyti Committed by Chris Wilson

drm/i915: Hook up GT power management

Refactor the GT power management interface to work through the GT now
that it is under the control of gt/

Based on a patch by Chris Wilson.
Signed-off-by: default avatarAndi Shyti <andi.shyti@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190905111403.10071-1-andi.shyti@intel.com
parent 5bf05dc5
...@@ -137,6 +137,7 @@ static bool switch_to_kernel_context_sync(struct intel_gt *gt) ...@@ -137,6 +137,7 @@ static bool switch_to_kernel_context_sync(struct intel_gt *gt)
bool i915_gem_load_power_context(struct drm_i915_private *i915) bool i915_gem_load_power_context(struct drm_i915_private *i915)
{ {
intel_gt_pm_enable(&i915->gt);
return switch_to_kernel_context_sync(&i915->gt); return switch_to_kernel_context_sync(&i915->gt);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "intel_gt.h" #include "intel_gt.h"
#include "intel_gt_pm.h" #include "intel_gt_pm.h"
#include "intel_uncore.h" #include "intel_uncore.h"
#include "intel_pm.h"
void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
{ {
...@@ -27,6 +28,9 @@ void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915) ...@@ -27,6 +28,9 @@ void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
void intel_gt_init_hw(struct drm_i915_private *i915) void intel_gt_init_hw(struct drm_i915_private *i915)
{ {
i915->gt.ggtt = &i915->ggtt; i915->gt.ggtt = &i915->ggtt;
/* BIOS often leaves RC6 enabled, but disable it for hw init */
intel_gt_pm_disable(&i915->gt);
} }
static void rmw_set(struct intel_uncore *uncore, i915_reg_t reg, u32 set) static void rmw_set(struct intel_uncore *uncore, i915_reg_t reg, u32 set)
...@@ -222,7 +226,13 @@ void intel_gt_chipset_flush(struct intel_gt *gt) ...@@ -222,7 +226,13 @@ void intel_gt_chipset_flush(struct intel_gt *gt)
intel_gtt_chipset_flush(); intel_gtt_chipset_flush();
} }
int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size) void intel_gt_driver_register(struct intel_gt *gt)
{
if (IS_GEN(gt->i915, 5))
intel_gpu_ips_init(gt->i915);
}
static int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size)
{ {
struct drm_i915_private *i915 = gt->i915; struct drm_i915_private *i915 = gt->i915;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
...@@ -256,11 +266,42 @@ int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size) ...@@ -256,11 +266,42 @@ int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size)
return ret; return ret;
} }
void intel_gt_fini_scratch(struct intel_gt *gt) static void intel_gt_fini_scratch(struct intel_gt *gt)
{ {
i915_vma_unpin_and_release(&gt->scratch, 0); i915_vma_unpin_and_release(&gt->scratch, 0);
} }
int intel_gt_init(struct intel_gt *gt)
{
int err;
err = intel_gt_init_scratch(gt, IS_GEN(gt->i915, 2) ? SZ_256K : SZ_4K);
if (err)
return err;
return 0;
}
void intel_gt_driver_remove(struct intel_gt *gt)
{
GEM_BUG_ON(gt->awake);
intel_gt_pm_disable(gt);
}
void intel_gt_driver_unregister(struct intel_gt *gt)
{
intel_gpu_ips_teardown();
}
void intel_gt_driver_release(struct intel_gt *gt)
{
/* Paranoia: make sure we have disabled everything before we exit. */
intel_gt_pm_disable(gt);
intel_cleanup_gt_powersave(gt->i915);
intel_gt_fini_scratch(gt);
}
void intel_gt_driver_late_release(struct intel_gt *gt) void intel_gt_driver_late_release(struct intel_gt *gt)
{ {
intel_uc_driver_late_release(&gt->uc); intel_uc_driver_late_release(&gt->uc);
......
...@@ -29,6 +29,12 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc) ...@@ -29,6 +29,12 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915); void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915);
void intel_gt_init_hw(struct drm_i915_private *i915); void intel_gt_init_hw(struct drm_i915_private *i915);
int intel_gt_init(struct intel_gt *gt);
void intel_gt_driver_register(struct intel_gt *gt);
void intel_gt_driver_unregister(struct intel_gt *gt);
void intel_gt_driver_remove(struct intel_gt *gt);
void intel_gt_driver_release(struct intel_gt *gt);
void intel_gt_driver_late_release(struct intel_gt *gt); void intel_gt_driver_late_release(struct intel_gt *gt);
...@@ -41,9 +47,6 @@ void intel_gt_chipset_flush(struct intel_gt *gt); ...@@ -41,9 +47,6 @@ void intel_gt_chipset_flush(struct intel_gt *gt);
void intel_gt_init_hangcheck(struct intel_gt *gt); void intel_gt_init_hangcheck(struct intel_gt *gt);
int intel_gt_init_scratch(struct intel_gt *gt, unsigned int size);
void intel_gt_fini_scratch(struct intel_gt *gt);
static inline u32 intel_gt_scratch_offset(const struct intel_gt *gt, static inline u32 intel_gt_scratch_offset(const struct intel_gt *gt,
enum intel_gt_scratch_field field) enum intel_gt_scratch_field field)
{ {
......
...@@ -124,6 +124,42 @@ void intel_gt_sanitize(struct intel_gt *gt, bool force) ...@@ -124,6 +124,42 @@ void intel_gt_sanitize(struct intel_gt *gt, bool force)
__intel_engine_reset(engine, false); __intel_engine_reset(engine, false);
} }
static bool is_mock_device(const struct intel_gt *gt)
{
return I915_SELFTEST_ONLY(gt->awake == -1);
}
void intel_gt_pm_enable(struct intel_gt *gt)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;
/* Powersaving is controlled by the host when inside a VM */
if (intel_vgpu_active(gt->i915))
return;
if (is_mock_device(gt))
return;
intel_gt_pm_get(gt);
for_each_engine(engine, gt->i915, id) {
intel_engine_pm_get(engine);
engine->serial++; /* force kernel context reload */
intel_engine_pm_put(engine);
}
intel_gt_pm_put(gt);
}
void intel_gt_pm_disable(struct intel_gt *gt)
{
if (is_mock_device(gt))
return;
intel_sanitize_gt_powersave(gt->i915);
}
int intel_gt_resume(struct intel_gt *gt) int intel_gt_resume(struct intel_gt *gt)
{ {
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
......
...@@ -43,6 +43,8 @@ static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt) ...@@ -43,6 +43,8 @@ static inline int intel_gt_pm_wait_for_idle(struct intel_gt *gt)
} }
void intel_gt_pm_init_early(struct intel_gt *gt); void intel_gt_pm_init_early(struct intel_gt *gt);
void intel_gt_pm_enable(struct intel_gt *gt);
void intel_gt_pm_disable(struct intel_gt *gt);
void intel_gt_sanitize(struct intel_gt *gt, bool force); void intel_gt_sanitize(struct intel_gt *gt, bool force);
int intel_gt_resume(struct intel_gt *gt); int intel_gt_resume(struct intel_gt *gt);
......
...@@ -1316,9 +1316,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) ...@@ -1316,9 +1316,6 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv)
pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_DEFAULT_VALUE); PM_QOS_DEFAULT_VALUE);
/* BIOS often leaves RC6 enabled, but disable it for hw init */
intel_sanitize_gt_powersave(dev_priv);
intel_gt_init_workarounds(dev_priv); intel_gt_init_workarounds(dev_priv);
/* On the 945G/GM, the chipset reports the MSI capability on the /* On the 945G/GM, the chipset reports the MSI capability on the
...@@ -1424,8 +1421,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) ...@@ -1424,8 +1421,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
acpi_video_register(); acpi_video_register();
} }
if (IS_GEN(dev_priv, 5)) intel_gt_driver_register(&dev_priv->gt);
intel_gpu_ips_init(dev_priv);
intel_audio_init(dev_priv); intel_audio_init(dev_priv);
...@@ -1468,7 +1464,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv) ...@@ -1468,7 +1464,7 @@ static void i915_driver_unregister(struct drm_i915_private *dev_priv)
*/ */
drm_kms_helper_poll_fini(&dev_priv->drm); drm_kms_helper_poll_fini(&dev_priv->drm);
intel_gpu_ips_teardown(); intel_gt_driver_unregister(&dev_priv->gt);
acpi_video_unregister(); acpi_video_unregister();
intel_opregion_unregister(dev_priv); intel_opregion_unregister(dev_priv);
...@@ -1612,9 +1608,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1612,9 +1608,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_cleanup_hw: out_cleanup_hw:
i915_driver_hw_remove(dev_priv); i915_driver_hw_remove(dev_priv);
i915_ggtt_driver_release(dev_priv); i915_ggtt_driver_release(dev_priv);
/* Paranoia: make sure we have disabled everything before we exit. */
intel_sanitize_gt_powersave(dev_priv);
out_cleanup_mmio: out_cleanup_mmio:
i915_driver_mmio_release(dev_priv); i915_driver_mmio_release(dev_priv);
out_runtime_pm_put: out_runtime_pm_put:
...@@ -1685,9 +1678,6 @@ static void i915_driver_release(struct drm_device *dev) ...@@ -1685,9 +1678,6 @@ static void i915_driver_release(struct drm_device *dev)
i915_ggtt_driver_release(dev_priv); i915_ggtt_driver_release(dev_priv);
/* Paranoia: make sure we have disabled everything before we exit. */
intel_sanitize_gt_powersave(dev_priv);
i915_driver_mmio_release(dev_priv); i915_driver_mmio_release(dev_priv);
enable_rpm_wakeref_asserts(rpm); enable_rpm_wakeref_asserts(rpm);
...@@ -1916,7 +1906,7 @@ static int i915_drm_resume(struct drm_device *dev) ...@@ -1916,7 +1906,7 @@ static int i915_drm_resume(struct drm_device *dev)
int ret; int ret;
disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
intel_sanitize_gt_powersave(dev_priv); intel_gt_pm_disable(&dev_priv->gt);
i915_gem_sanitize(dev_priv); i915_gem_sanitize(dev_priv);
...@@ -2044,7 +2034,7 @@ static int i915_drm_resume_early(struct drm_device *dev) ...@@ -2044,7 +2034,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
intel_display_power_resume_early(dev_priv); intel_display_power_resume_early(dev_priv);
intel_sanitize_gt_powersave(dev_priv); intel_gt_pm_disable(&dev_priv->gt);
intel_power_domains_resume(dev_priv); intel_power_domains_resume(dev_priv);
...@@ -2588,9 +2578,6 @@ static int intel_runtime_suspend(struct device *kdev) ...@@ -2588,9 +2578,6 @@ static int intel_runtime_suspend(struct device *kdev)
struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; struct intel_runtime_pm *rpm = &dev_priv->runtime_pm;
int ret = 0; int ret = 0;
if (WARN_ON_ONCE(!(dev_priv->gt_pm.rc6.enabled && HAS_RC6(dev_priv))))
return -ENODEV;
if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
return -ENODEV; return -ENODEV;
......
...@@ -1375,17 +1375,6 @@ static int __intel_engines_record_defaults(struct drm_i915_private *i915) ...@@ -1375,17 +1375,6 @@ static int __intel_engines_record_defaults(struct drm_i915_private *i915)
return err; return err;
} }
static int
i915_gem_init_scratch(struct drm_i915_private *i915, unsigned int size)
{
return intel_gt_init_scratch(&i915->gt, size);
}
static void i915_gem_fini_scratch(struct drm_i915_private *i915)
{
intel_gt_fini_scratch(&i915->gt);
}
static int intel_engines_verify_workarounds(struct drm_i915_private *i915) static int intel_engines_verify_workarounds(struct drm_i915_private *i915)
{ {
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
...@@ -1436,12 +1425,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv) ...@@ -1436,12 +1425,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
goto err_unlock; goto err_unlock;
} }
ret = i915_gem_init_scratch(dev_priv, intel_gt_init(&dev_priv->gt);
IS_GEN(dev_priv, 2) ? SZ_256K : PAGE_SIZE);
if (ret) {
GEM_BUG_ON(ret == -EIO);
goto err_ggtt;
}
ret = intel_engines_setup(dev_priv); ret = intel_engines_setup(dev_priv);
if (ret) { if (ret) {
...@@ -1527,15 +1511,13 @@ int i915_gem_init(struct drm_i915_private *dev_priv) ...@@ -1527,15 +1511,13 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
err_uc_init: err_uc_init:
if (ret != -EIO) { if (ret != -EIO) {
intel_uc_fini(&dev_priv->gt.uc); intel_uc_fini(&dev_priv->gt.uc);
intel_cleanup_gt_powersave(dev_priv);
intel_engines_cleanup(dev_priv); intel_engines_cleanup(dev_priv);
} }
err_context: err_context:
if (ret != -EIO) if (ret != -EIO)
i915_gem_contexts_fini(dev_priv); i915_gem_contexts_fini(dev_priv);
err_scratch: err_scratch:
i915_gem_fini_scratch(dev_priv); intel_gt_driver_release(&dev_priv->gt);
err_ggtt:
err_unlock: err_unlock:
intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL); intel_uncore_forcewake_put(&dev_priv->uncore, FORCEWAKE_ALL);
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
...@@ -1587,12 +1569,10 @@ void i915_gem_driver_unregister(struct drm_i915_private *i915) ...@@ -1587,12 +1569,10 @@ void i915_gem_driver_unregister(struct drm_i915_private *i915)
void i915_gem_driver_remove(struct drm_i915_private *dev_priv) void i915_gem_driver_remove(struct drm_i915_private *dev_priv)
{ {
GEM_BUG_ON(dev_priv->gt.awake);
intel_wakeref_auto_fini(&dev_priv->ggtt.userfault_wakeref); intel_wakeref_auto_fini(&dev_priv->ggtt.userfault_wakeref);
i915_gem_suspend_late(dev_priv); i915_gem_suspend_late(dev_priv);
intel_disable_gt_powersave(dev_priv); intel_gt_driver_remove(&dev_priv->gt);
/* Flush any outstanding unpin_work. */ /* Flush any outstanding unpin_work. */
i915_gem_drain_workqueue(dev_priv); i915_gem_drain_workqueue(dev_priv);
...@@ -1610,13 +1590,11 @@ void i915_gem_driver_release(struct drm_i915_private *dev_priv) ...@@ -1610,13 +1590,11 @@ void i915_gem_driver_release(struct drm_i915_private *dev_priv)
mutex_lock(&dev_priv->drm.struct_mutex); mutex_lock(&dev_priv->drm.struct_mutex);
intel_engines_cleanup(dev_priv); intel_engines_cleanup(dev_priv);
i915_gem_contexts_fini(dev_priv); i915_gem_contexts_fini(dev_priv);
i915_gem_fini_scratch(dev_priv); intel_gt_driver_release(&dev_priv->gt);
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
intel_wa_list_free(&dev_priv->gt_wa_list); intel_wa_list_free(&dev_priv->gt_wa_list);
intel_cleanup_gt_powersave(dev_priv);
intel_uc_cleanup_firmwares(&dev_priv->gt.uc); intel_uc_cleanup_firmwares(&dev_priv->gt.uc);
i915_gem_cleanup_userptr(dev_priv); i915_gem_cleanup_userptr(dev_priv);
intel_timelines_fini(dev_priv); intel_timelines_fini(dev_priv);
......
...@@ -8671,7 +8671,9 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -8671,7 +8671,9 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
{ {
mutex_lock(&dev_priv->gt_pm.rps.lock); mutex_lock(&dev_priv->gt_pm.rps.lock);
intel_disable_rc6(dev_priv); if (HAS_RC6(dev_priv))
intel_disable_rc6(dev_priv);
intel_disable_rps(dev_priv); intel_disable_rps(dev_priv);
if (HAS_LLC(dev_priv)) if (HAS_LLC(dev_priv))
intel_disable_llc_pstate(dev_priv); intel_disable_llc_pstate(dev_priv);
......
...@@ -192,7 +192,7 @@ struct drm_i915_private *mock_gem_device(void) ...@@ -192,7 +192,7 @@ struct drm_i915_private *mock_gem_device(void)
INIT_DELAYED_WORK(&i915->gem.retire_work, mock_retire_work_handler); INIT_DELAYED_WORK(&i915->gem.retire_work, mock_retire_work_handler);
INIT_WORK(&i915->gem.idle_work, mock_idle_work_handler); INIT_WORK(&i915->gem.idle_work, mock_idle_work_handler);
i915->gt.awake = true; i915->gt.awake = -1;
intel_timelines_init(i915); intel_timelines_init(i915);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment