@@ -6536,6 +6536,8 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
6536
6536
dev_priv -> rps .boost_freq = dev_priv -> rps .max_freq ;
6537
6537
6538
6538
mutex_unlock (& dev_priv -> rps .hw_lock );
6539
+
6540
+ intel_autoenable_gt_powersave (dev_priv );
6539
6541
}
6540
6542
6541
6543
void intel_cleanup_gt_powersave (struct drm_i915_private * dev_priv )
@@ -6549,13 +6551,6 @@ void intel_cleanup_gt_powersave(struct drm_i915_private *dev_priv)
6549
6551
intel_runtime_pm_put (dev_priv );
6550
6552
}
6551
6553
6552
- static void gen6_suspend_rps (struct drm_i915_private * dev_priv )
6553
- {
6554
- flush_delayed_work (& dev_priv -> rps .delayed_resume_work );
6555
-
6556
- gen6_disable_rps_interrupts (dev_priv );
6557
- }
6558
-
6559
6554
/**
6560
6555
* intel_suspend_gt_powersave - suspend PM work and helper threads
6561
6556
* @dev_priv: i915 device
@@ -6569,60 +6564,76 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
6569
6564
if (INTEL_GEN (dev_priv ) < 6 )
6570
6565
return ;
6571
6566
6572
- gen6_suspend_rps (dev_priv );
6567
+ if (cancel_delayed_work_sync (& dev_priv -> rps .autoenable_work ))
6568
+ intel_runtime_pm_put (dev_priv );
6573
6569
6574
- /* Force GPU to min freq during suspend */
6575
- gen6_rps_idle (dev_priv );
6570
+ /* gen6_rps_idle() will be called later to disable interrupts */
6571
+ }
6572
+
6573
+ void intel_sanitize_gt_powersave (struct drm_i915_private * dev_priv )
6574
+ {
6575
+ dev_priv -> rps .enabled = true; /* force disabling */
6576
+ intel_disable_gt_powersave (dev_priv );
6577
+
6578
+ gen6_reset_rps_interrupts (dev_priv );
6576
6579
}
6577
6580
6578
6581
void intel_disable_gt_powersave (struct drm_i915_private * dev_priv )
6579
6582
{
6580
- if (IS_IRONLAKE_M (dev_priv )) {
6581
- ironlake_disable_drps (dev_priv );
6582
- } else if (INTEL_INFO (dev_priv )-> gen >= 6 ) {
6583
- intel_suspend_gt_powersave (dev_priv );
6583
+ if (!READ_ONCE (dev_priv -> rps .enabled ))
6584
+ return ;
6584
6585
6585
- mutex_lock (& dev_priv -> rps .hw_lock );
6586
- if (INTEL_INFO (dev_priv )-> gen >= 9 ) {
6587
- gen9_disable_rc6 (dev_priv );
6588
- gen9_disable_rps (dev_priv );
6589
- } else if (IS_CHERRYVIEW (dev_priv ))
6590
- cherryview_disable_rps (dev_priv );
6591
- else if (IS_VALLEYVIEW (dev_priv ))
6592
- valleyview_disable_rps (dev_priv );
6593
- else
6594
- gen6_disable_rps (dev_priv );
6586
+ mutex_lock (& dev_priv -> rps .hw_lock );
6595
6587
6596
- dev_priv -> rps .enabled = false;
6597
- mutex_unlock (& dev_priv -> rps .hw_lock );
6588
+ if (INTEL_GEN (dev_priv ) >= 9 ) {
6589
+ gen9_disable_rc6 (dev_priv );
6590
+ gen9_disable_rps (dev_priv );
6591
+ } else if (IS_CHERRYVIEW (dev_priv )) {
6592
+ cherryview_disable_rps (dev_priv );
6593
+ } else if (IS_VALLEYVIEW (dev_priv )) {
6594
+ valleyview_disable_rps (dev_priv );
6595
+ } else if (INTEL_GEN (dev_priv ) >= 6 ) {
6596
+ gen6_disable_rps (dev_priv );
6597
+ } else if (IS_IRONLAKE_M (dev_priv )) {
6598
+ ironlake_disable_drps (dev_priv );
6598
6599
}
6600
+
6601
+ dev_priv -> rps .enabled = false;
6602
+ mutex_unlock (& dev_priv -> rps .hw_lock );
6599
6603
}
6600
6604
6601
- static void intel_gen6_powersave_work (struct work_struct * work )
6605
+ void intel_enable_gt_powersave (struct drm_i915_private * dev_priv )
6602
6606
{
6603
- struct drm_i915_private * dev_priv =
6604
- container_of (work , struct drm_i915_private ,
6605
- rps .delayed_resume_work .work );
6607
+ /* We shouldn't be disabling as we submit, so this should be less
6608
+ * racy than it appears!
6609
+ */
6610
+ if (READ_ONCE (dev_priv -> rps .enabled ))
6611
+ return ;
6606
6612
6607
- mutex_lock (& dev_priv -> rps .hw_lock );
6613
+ /* Powersaving is controlled by the host when inside a VM */
6614
+ if (intel_vgpu_active (dev_priv ))
6615
+ return ;
6608
6616
6609
- gen6_reset_rps_interrupts ( dev_priv );
6617
+ mutex_lock ( & dev_priv -> rps . hw_lock );
6610
6618
6611
6619
if (IS_CHERRYVIEW (dev_priv )) {
6612
6620
cherryview_enable_rps (dev_priv );
6613
6621
} else if (IS_VALLEYVIEW (dev_priv )) {
6614
6622
valleyview_enable_rps (dev_priv );
6615
- } else if (INTEL_INFO (dev_priv )-> gen >= 9 ) {
6623
+ } else if (INTEL_GEN (dev_priv ) >= 9 ) {
6616
6624
gen9_enable_rc6 (dev_priv );
6617
6625
gen9_enable_rps (dev_priv );
6618
6626
if (IS_SKYLAKE (dev_priv ) || IS_KABYLAKE (dev_priv ))
6619
6627
__gen6_update_ring_freq (dev_priv );
6620
6628
} else if (IS_BROADWELL (dev_priv )) {
6621
6629
gen8_enable_rps (dev_priv );
6622
6630
__gen6_update_ring_freq (dev_priv );
6623
- } else {
6631
+ } else if ( INTEL_GEN ( dev_priv ) >= 6 ) {
6624
6632
gen6_enable_rps (dev_priv );
6625
6633
__gen6_update_ring_freq (dev_priv );
6634
+ } else if (IS_IRONLAKE_M (dev_priv )) {
6635
+ ironlake_enable_drps (dev_priv );
6636
+ intel_init_emon (dev_priv );
6626
6637
}
6627
6638
6628
6639
WARN_ON (dev_priv -> rps .max_freq < dev_priv -> rps .min_freq );
@@ -6632,18 +6643,47 @@ static void intel_gen6_powersave_work(struct work_struct *work)
6632
6643
WARN_ON (dev_priv -> rps .efficient_freq > dev_priv -> rps .max_freq );
6633
6644
6634
6645
dev_priv -> rps .enabled = true;
6646
+ mutex_unlock (& dev_priv -> rps .hw_lock );
6647
+ }
6635
6648
6636
- gen6_enable_rps_interrupts (dev_priv );
6649
+ static void __intel_autoenable_gt_powersave (struct work_struct * work )
6650
+ {
6651
+ struct drm_i915_private * dev_priv =
6652
+ container_of (work , typeof (* dev_priv ), rps .autoenable_work .work );
6653
+ struct intel_engine_cs * rcs ;
6654
+ struct drm_i915_gem_request * req ;
6637
6655
6638
- mutex_unlock (& dev_priv -> rps .hw_lock );
6656
+ if (READ_ONCE (dev_priv -> rps .enabled ))
6657
+ goto out ;
6658
+
6659
+ rcs = & dev_priv -> engine [RCS ];
6660
+ if (rcs -> last_context )
6661
+ goto out ;
6662
+
6663
+ if (!rcs -> init_context )
6664
+ goto out ;
6639
6665
6666
+ mutex_lock (& dev_priv -> drm .struct_mutex );
6667
+
6668
+ req = i915_gem_request_alloc (rcs , dev_priv -> kernel_context );
6669
+ if (IS_ERR (req ))
6670
+ goto unlock ;
6671
+
6672
+ if (!i915 .enable_execlists && i915_switch_context (req ) == 0 )
6673
+ rcs -> init_context (req );
6674
+
6675
+ /* Mark the device busy, calling intel_enable_gt_powersave() */
6676
+ i915_add_request_no_flush (req );
6677
+
6678
+ unlock :
6679
+ mutex_unlock (& dev_priv -> drm .struct_mutex );
6680
+ out :
6640
6681
intel_runtime_pm_put (dev_priv );
6641
6682
}
6642
6683
6643
- void intel_enable_gt_powersave (struct drm_i915_private * dev_priv )
6684
+ void intel_autoenable_gt_powersave (struct drm_i915_private * dev_priv )
6644
6685
{
6645
- /* Powersaving is controlled by the host when inside a VM */
6646
- if (intel_vgpu_active (dev_priv ))
6686
+ if (READ_ONCE (dev_priv -> rps .enabled ))
6647
6687
return ;
6648
6688
6649
6689
if (IS_IRONLAKE_M (dev_priv )) {
@@ -6664,21 +6704,13 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
6664
6704
* paths, so the _noresume version is enough (and in case of
6665
6705
* runtime resume it's necessary).
6666
6706
*/
6667
- if (schedule_delayed_work (& dev_priv -> rps .delayed_resume_work ,
6668
- round_jiffies_up_relative (HZ )))
6707
+ if (queue_delayed_work (dev_priv -> wq ,
6708
+ & dev_priv -> rps .autoenable_work ,
6709
+ round_jiffies_up_relative (HZ )))
6669
6710
intel_runtime_pm_get_noresume (dev_priv );
6670
6711
}
6671
6712
}
6672
6713
6673
- void intel_reset_gt_powersave (struct drm_i915_private * dev_priv )
6674
- {
6675
- if (INTEL_INFO (dev_priv )-> gen < 6 )
6676
- return ;
6677
-
6678
- gen6_suspend_rps (dev_priv );
6679
- dev_priv -> rps .enabled = false;
6680
- }
6681
-
6682
6714
static void ibx_init_clock_gating (struct drm_device * dev )
6683
6715
{
6684
6716
struct drm_i915_private * dev_priv = to_i915 (dev );
@@ -7785,8 +7817,8 @@ void intel_pm_setup(struct drm_device *dev)
7785
7817
mutex_init (& dev_priv -> rps .hw_lock );
7786
7818
spin_lock_init (& dev_priv -> rps .client_lock );
7787
7819
7788
- INIT_DELAYED_WORK (& dev_priv -> rps .delayed_resume_work ,
7789
- intel_gen6_powersave_work );
7820
+ INIT_DELAYED_WORK (& dev_priv -> rps .autoenable_work ,
7821
+ __intel_autoenable_gt_powersave );
7790
7822
INIT_LIST_HEAD (& dev_priv -> rps .clients );
7791
7823
INIT_LIST_HEAD (& dev_priv -> rps .semaphores .link );
7792
7824
INIT_LIST_HEAD (& dev_priv -> rps .mmioflips .link );
0 commit comments