Commit 562d9bae authored by Sagar Arun Kamble's avatar Sagar Arun Kamble Committed by Chris Wilson

drm/i915: Name structure in dev_priv that contains RPS/RC6 state as "gt_pm"

Prepared substructure rps for RPS related state. autoenable_work is
used for RC6 too hence it is defined outside rps structure. As we do
this lot many functions are refactored to use intel_rps *rps to access
rps related members. Hence renamed intel_rps_client pointer variables
to rps_client in various functions.

v2: Rebase.

v3: s/pm/gt_pm (Chris)
Refactored access to rps structure by declaring struct intel_rps * in
many functions.
Signed-off-by: default avatarSagar Arun Kamble <sagar.a.kamble@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Reviewed-by: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com> #1
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/1507360055-19948-9-git-send-email-sagar.a.kamble@intel.comAcked-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20171010213010.7415-8-chris@chris-wilson.co.uk
parent 9f817501
...@@ -1080,6 +1080,7 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops, ...@@ -1080,6 +1080,7 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops,
static int i915_frequency_info(struct seq_file *m, void *unused) static int i915_frequency_info(struct seq_file *m, void *unused)
{ {
struct drm_i915_private *dev_priv = node_to_i915(m->private); struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct intel_rps *rps = &dev_priv->gt_pm.rps;
int ret = 0; int ret = 0;
intel_runtime_pm_get(dev_priv); intel_runtime_pm_get(dev_priv);
...@@ -1116,20 +1117,20 @@ static int i915_frequency_info(struct seq_file *m, void *unused) ...@@ -1116,20 +1117,20 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff)); intel_gpu_freq(dev_priv, (freq_sts >> 8) & 0xff));
seq_printf(m, "current GPU freq: %d MHz\n", seq_printf(m, "current GPU freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); intel_gpu_freq(dev_priv, rps->cur_freq));
seq_printf(m, "max GPU freq: %d MHz\n", seq_printf(m, "max GPU freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); intel_gpu_freq(dev_priv, rps->max_freq));
seq_printf(m, "min GPU freq: %d MHz\n", seq_printf(m, "min GPU freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.min_freq)); intel_gpu_freq(dev_priv, rps->min_freq));
seq_printf(m, "idle GPU freq: %d MHz\n", seq_printf(m, "idle GPU freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq)); intel_gpu_freq(dev_priv, rps->idle_freq));
seq_printf(m, seq_printf(m,
"efficient (RPe) frequency: %d MHz\n", "efficient (RPe) frequency: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq)); intel_gpu_freq(dev_priv, rps->efficient_freq));
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
} else if (INTEL_GEN(dev_priv) >= 6) { } else if (INTEL_GEN(dev_priv) >= 6) {
u32 rp_state_limits; u32 rp_state_limits;
...@@ -1210,7 +1211,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) ...@@ -1210,7 +1211,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n", seq_printf(m, "PM IER=0x%08x IMR=0x%08x ISR=0x%08x IIR=0x%08x, MASK=0x%08x\n",
pm_ier, pm_imr, pm_isr, pm_iir, pm_mask); pm_ier, pm_imr, pm_isr, pm_iir, pm_mask);
seq_printf(m, "pm_intrmsk_mbz: 0x%08x\n", seq_printf(m, "pm_intrmsk_mbz: 0x%08x\n",
dev_priv->rps.pm_intrmsk_mbz); rps->pm_intrmsk_mbz);
seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
seq_printf(m, "Render p-state ratio: %d\n", seq_printf(m, "Render p-state ratio: %d\n",
(gt_perf_status & (INTEL_GEN(dev_priv) >= 9 ? 0x1ff00 : 0xff00)) >> 8); (gt_perf_status & (INTEL_GEN(dev_priv) >= 9 ? 0x1ff00 : 0xff00)) >> 8);
...@@ -1230,8 +1231,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) ...@@ -1230,8 +1231,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup)); rpcurup, GT_PM_INTERVAL_TO_US(dev_priv, rpcurup));
seq_printf(m, "RP PREV UP: %d (%dus)\n", seq_printf(m, "RP PREV UP: %d (%dus)\n",
rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup)); rpprevup, GT_PM_INTERVAL_TO_US(dev_priv, rpprevup));
seq_printf(m, "Up threshold: %d%%\n", seq_printf(m, "Up threshold: %d%%\n", rps->up_threshold);
dev_priv->rps.up_threshold);
seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n", seq_printf(m, "RP CUR DOWN EI: %d (%dus)\n",
rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei)); rpdownei, GT_PM_INTERVAL_TO_US(dev_priv, rpdownei));
...@@ -1239,8 +1239,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused) ...@@ -1239,8 +1239,7 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown)); rpcurdown, GT_PM_INTERVAL_TO_US(dev_priv, rpcurdown));
seq_printf(m, "RP PREV DOWN: %d (%dus)\n", seq_printf(m, "RP PREV DOWN: %d (%dus)\n",
rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown)); rpprevdown, GT_PM_INTERVAL_TO_US(dev_priv, rpprevdown));
seq_printf(m, "Down threshold: %d%%\n", seq_printf(m, "Down threshold: %d%%\n", rps->down_threshold);
dev_priv->rps.down_threshold);
max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 : max_freq = (IS_GEN9_LP(dev_priv) ? rp_state_cap >> 0 :
rp_state_cap >> 16) & 0xff; rp_state_cap >> 16) & 0xff;
...@@ -1262,22 +1261,22 @@ static int i915_frequency_info(struct seq_file *m, void *unused) ...@@ -1262,22 +1261,22 @@ static int i915_frequency_info(struct seq_file *m, void *unused)
seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
intel_gpu_freq(dev_priv, max_freq)); intel_gpu_freq(dev_priv, max_freq));
seq_printf(m, "Max overclocked frequency: %dMHz\n", seq_printf(m, "Max overclocked frequency: %dMHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); intel_gpu_freq(dev_priv, rps->max_freq));
seq_printf(m, "Current freq: %d MHz\n", seq_printf(m, "Current freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); intel_gpu_freq(dev_priv, rps->cur_freq));
seq_printf(m, "Actual freq: %d MHz\n", cagf); seq_printf(m, "Actual freq: %d MHz\n", cagf);
seq_printf(m, "Idle freq: %d MHz\n", seq_printf(m, "Idle freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq)); intel_gpu_freq(dev_priv, rps->idle_freq));
seq_printf(m, "Min freq: %d MHz\n", seq_printf(m, "Min freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.min_freq)); intel_gpu_freq(dev_priv, rps->min_freq));
seq_printf(m, "Boost freq: %d MHz\n", seq_printf(m, "Boost freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq)); intel_gpu_freq(dev_priv, rps->boost_freq));
seq_printf(m, "Max freq: %d MHz\n", seq_printf(m, "Max freq: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); intel_gpu_freq(dev_priv, rps->max_freq));
seq_printf(m, seq_printf(m,
"efficient (RPe) frequency: %d MHz\n", "efficient (RPe) frequency: %d MHz\n",
intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq)); intel_gpu_freq(dev_priv, rps->efficient_freq));
} else { } else {
seq_puts(m, "no P-state info available\n"); seq_puts(m, "no P-state info available\n");
} }
...@@ -1831,6 +1830,7 @@ static int i915_emon_status(struct seq_file *m, void *unused) ...@@ -1831,6 +1830,7 @@ static int i915_emon_status(struct seq_file *m, void *unused)
static int i915_ring_freq_table(struct seq_file *m, void *unused) static int i915_ring_freq_table(struct seq_file *m, void *unused)
{ {
struct drm_i915_private *dev_priv = node_to_i915(m->private); struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct intel_rps *rps = &dev_priv->gt_pm.rps;
int ret = 0; int ret = 0;
int gpu_freq, ia_freq; int gpu_freq, ia_freq;
unsigned int max_gpu_freq, min_gpu_freq; unsigned int max_gpu_freq, min_gpu_freq;
...@@ -1848,13 +1848,11 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused) ...@@ -1848,13 +1848,11 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Convert GT frequency to 50 HZ units */ /* Convert GT frequency to 50 HZ units */
min_gpu_freq = min_gpu_freq = rps->min_freq_softlimit / GEN9_FREQ_SCALER;
dev_priv->rps.min_freq_softlimit / GEN9_FREQ_SCALER; max_gpu_freq = rps->max_freq_softlimit / GEN9_FREQ_SCALER;
max_gpu_freq =
dev_priv->rps.max_freq_softlimit / GEN9_FREQ_SCALER;
} else { } else {
min_gpu_freq = dev_priv->rps.min_freq_softlimit; min_gpu_freq = rps->min_freq_softlimit;
max_gpu_freq = dev_priv->rps.max_freq_softlimit; max_gpu_freq = rps->max_freq_softlimit;
} }
seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n"); seq_puts(m, "GPU freq (MHz)\tEffective CPU freq (MHz)\tEffective Ring freq (MHz)\n");
...@@ -2307,25 +2305,26 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) ...@@ -2307,25 +2305,26 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
{ {
struct drm_i915_private *dev_priv = node_to_i915(m->private); struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct drm_device *dev = &dev_priv->drm; struct drm_device *dev = &dev_priv->drm;
struct intel_rps *rps = &dev_priv->gt_pm.rps;
struct drm_file *file; struct drm_file *file;
seq_printf(m, "RPS enabled? %d\n", dev_priv->rps.enabled); seq_printf(m, "RPS enabled? %d\n", rps->enabled);
seq_printf(m, "GPU busy? %s [%d requests]\n", seq_printf(m, "GPU busy? %s [%d requests]\n",
yesno(dev_priv->gt.awake), dev_priv->gt.active_requests); yesno(dev_priv->gt.awake), dev_priv->gt.active_requests);
seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv)); seq_printf(m, "CPU waiting? %d\n", count_irq_waiters(dev_priv));
seq_printf(m, "Boosts outstanding? %d\n", seq_printf(m, "Boosts outstanding? %d\n",
atomic_read(&dev_priv->rps.num_waiters)); atomic_read(&rps->num_waiters));
seq_printf(m, "Frequency requested %d\n", seq_printf(m, "Frequency requested %d\n",
intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq)); intel_gpu_freq(dev_priv, rps->cur_freq));
seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n", seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n",
intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), intel_gpu_freq(dev_priv, rps->min_freq),
intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit), intel_gpu_freq(dev_priv, rps->min_freq_softlimit),
intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit), intel_gpu_freq(dev_priv, rps->max_freq_softlimit),
intel_gpu_freq(dev_priv, dev_priv->rps.max_freq)); intel_gpu_freq(dev_priv, rps->max_freq));
seq_printf(m, " idle:%d, efficient:%d, boost:%d\n", seq_printf(m, " idle:%d, efficient:%d, boost:%d\n",
intel_gpu_freq(dev_priv, dev_priv->rps.idle_freq), intel_gpu_freq(dev_priv, rps->idle_freq),
intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), intel_gpu_freq(dev_priv, rps->efficient_freq),
intel_gpu_freq(dev_priv, dev_priv->rps.boost_freq)); intel_gpu_freq(dev_priv, rps->boost_freq));
mutex_lock(&dev->filelist_mutex); mutex_lock(&dev->filelist_mutex);
list_for_each_entry_reverse(file, &dev->filelist, lhead) { list_for_each_entry_reverse(file, &dev->filelist, lhead) {
...@@ -2337,15 +2336,15 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) ...@@ -2337,15 +2336,15 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
seq_printf(m, "%s [%d]: %d boosts\n", seq_printf(m, "%s [%d]: %d boosts\n",
task ? task->comm : "<unknown>", task ? task->comm : "<unknown>",
task ? task->pid : -1, task ? task->pid : -1,
atomic_read(&file_priv->rps.boosts)); atomic_read(&file_priv->rps_client.boosts));
rcu_read_unlock(); rcu_read_unlock();
} }
seq_printf(m, "Kernel (anonymous) boosts: %d\n", seq_printf(m, "Kernel (anonymous) boosts: %d\n",
atomic_read(&dev_priv->rps.boosts)); atomic_read(&rps->boosts));
mutex_unlock(&dev->filelist_mutex); mutex_unlock(&dev->filelist_mutex);
if (INTEL_GEN(dev_priv) >= 6 && if (INTEL_GEN(dev_priv) >= 6 &&
dev_priv->rps.enabled && rps->enabled &&
dev_priv->gt.active_requests) { dev_priv->gt.active_requests) {
u32 rpup, rpupei; u32 rpup, rpupei;
u32 rpdown, rpdownei; u32 rpdown, rpdownei;
...@@ -2358,13 +2357,13 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) ...@@ -2358,13 +2357,13 @@ static int i915_rps_boost_info(struct seq_file *m, void *data)
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL); intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n", seq_printf(m, "\nRPS Autotuning (current \"%s\" window):\n",
rps_power_to_str(dev_priv->rps.power)); rps_power_to_str(rps->power));
seq_printf(m, " Avg. up: %d%% [above threshold? %d%%]\n", seq_printf(m, " Avg. up: %d%% [above threshold? %d%%]\n",
rpup && rpupei ? 100 * rpup / rpupei : 0, rpup && rpupei ? 100 * rpup / rpupei : 0,
dev_priv->rps.up_threshold); rps->up_threshold);
seq_printf(m, " Avg. down: %d%% [below threshold? %d%%]\n", seq_printf(m, " Avg. down: %d%% [below threshold? %d%%]\n",
rpdown && rpdownei ? 100 * rpdown / rpdownei : 0, rpdown && rpdownei ? 100 * rpdown / rpdownei : 0,
dev_priv->rps.down_threshold); rps->down_threshold);
} else { } else {
seq_puts(m, "\nRPS Autotuning inactive\n"); seq_puts(m, "\nRPS Autotuning inactive\n");
} }
...@@ -4304,7 +4303,7 @@ i915_max_freq_get(void *data, u64 *val) ...@@ -4304,7 +4303,7 @@ i915_max_freq_get(void *data, u64 *val)
if (INTEL_GEN(dev_priv) < 6) if (INTEL_GEN(dev_priv) < 6)
return -ENODEV; return -ENODEV;
*val = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit); *val = intel_gpu_freq(dev_priv, dev_priv->gt_pm.rps.max_freq_softlimit);
return 0; return 0;
} }
...@@ -4312,6 +4311,7 @@ static int ...@@ -4312,6 +4311,7 @@ static int
i915_max_freq_set(void *data, u64 val) i915_max_freq_set(void *data, u64 val)
{ {
struct drm_i915_private *dev_priv = data; struct drm_i915_private *dev_priv = data;
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 hw_max, hw_min; u32 hw_max, hw_min;
int ret; int ret;
...@@ -4329,15 +4329,15 @@ i915_max_freq_set(void *data, u64 val) ...@@ -4329,15 +4329,15 @@ i915_max_freq_set(void *data, u64 val)
*/ */
val = intel_freq_opcode(dev_priv, val); val = intel_freq_opcode(dev_priv, val);
hw_max = dev_priv->rps.max_freq; hw_max = rps->max_freq;
hw_min = dev_priv->rps.min_freq; hw_min = rps->min_freq;
if (val < hw_min || val > hw_max || val < dev_priv->rps.min_freq_softlimit) { if (val < hw_min || val > hw_max || val < rps->min_freq_softlimit) {
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
return -EINVAL; return -EINVAL;
} }
dev_priv->rps.max_freq_softlimit = val; rps->max_freq_softlimit = val;
if (intel_set_rps(dev_priv, val)) if (intel_set_rps(dev_priv, val))
DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n"); DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
...@@ -4359,7 +4359,7 @@ i915_min_freq_get(void *data, u64 *val) ...@@ -4359,7 +4359,7 @@ i915_min_freq_get(void *data, u64 *val)
if (INTEL_GEN(dev_priv) < 6) if (INTEL_GEN(dev_priv) < 6)
return -ENODEV; return -ENODEV;
*val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit); *val = intel_gpu_freq(dev_priv, dev_priv->gt_pm.rps.min_freq_softlimit);
return 0; return 0;
} }
...@@ -4367,6 +4367,7 @@ static int ...@@ -4367,6 +4367,7 @@ static int
i915_min_freq_set(void *data, u64 val) i915_min_freq_set(void *data, u64 val)
{ {
struct drm_i915_private *dev_priv = data; struct drm_i915_private *dev_priv = data;
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 hw_max, hw_min; u32 hw_max, hw_min;
int ret; int ret;
...@@ -4384,16 +4385,16 @@ i915_min_freq_set(void *data, u64 val) ...@@ -4384,16 +4385,16 @@ i915_min_freq_set(void *data, u64 val)
*/ */
val = intel_freq_opcode(dev_priv, val); val = intel_freq_opcode(dev_priv, val);
hw_max = dev_priv->rps.max_freq; hw_max = rps->max_freq;
hw_min = dev_priv->rps.min_freq; hw_min = rps->min_freq;
if (val < hw_min || if (val < hw_min ||
val > hw_max || val > dev_priv->rps.max_freq_softlimit) { val > hw_max || val > rps->max_freq_softlimit) {
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
return -EINVAL; return -EINVAL;
} }
dev_priv->rps.min_freq_softlimit = val; rps->min_freq_softlimit = val;
if (intel_set_rps(dev_priv, val)) if (intel_set_rps(dev_priv, val))
DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n"); DRM_DEBUG_DRIVER("failed to update RPS to new softlimit\n");
......
...@@ -2502,7 +2502,7 @@ static int intel_runtime_suspend(struct device *kdev) ...@@ -2502,7 +2502,7 @@ static int intel_runtime_suspend(struct device *kdev)
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
int ret; int ret;
if (WARN_ON_ONCE(!(dev_priv->rps.enabled && intel_enable_rc6()))) if (WARN_ON_ONCE(!(dev_priv->gt_pm.rps.enabled && intel_enable_rc6())))
return -ENODEV; return -ENODEV;
if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv))) if (WARN_ON_ONCE(!HAS_RUNTIME_PM(dev_priv)))
......
...@@ -609,7 +609,7 @@ struct drm_i915_file_private { ...@@ -609,7 +609,7 @@ struct drm_i915_file_private {
struct intel_rps_client { struct intel_rps_client {
atomic_t boosts; atomic_t boosts;
} rps; } rps_client;
unsigned int bsd_engine; unsigned int bsd_engine;
...@@ -1317,7 +1317,7 @@ struct intel_rps_ei { ...@@ -1317,7 +1317,7 @@ struct intel_rps_ei {
u32 media_c0; u32 media_c0;
}; };
struct intel_gen6_power_mgmt { struct intel_rps {
/* /*
* work, interrupts_enabled and pm_iir are protected by * work, interrupts_enabled and pm_iir are protected by
* dev_priv->irq_lock * dev_priv->irq_lock
...@@ -1358,7 +1358,6 @@ struct intel_gen6_power_mgmt { ...@@ -1358,7 +1358,6 @@ struct intel_gen6_power_mgmt {
enum { LOW_POWER, BETWEEN, HIGH_POWER } power; enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
bool enabled; bool enabled;
struct delayed_work autoenable_work;
atomic_t num_waiters; atomic_t num_waiters;
atomic_t boosts; atomic_t boosts;
...@@ -1366,6 +1365,11 @@ struct intel_gen6_power_mgmt { ...@@ -1366,6 +1365,11 @@ struct intel_gen6_power_mgmt {
struct intel_rps_ei ei; struct intel_rps_ei ei;
}; };
struct intel_gen6_power_mgmt {
struct intel_rps rps;
struct delayed_work autoenable_work;
};
/* defined intel_pm.c */ /* defined intel_pm.c */
extern spinlock_t mchdev_lock; extern spinlock_t mchdev_lock;
...@@ -2421,8 +2425,8 @@ struct drm_i915_private { ...@@ -2421,8 +2425,8 @@ struct drm_i915_private {
*/ */
struct mutex pcu_lock; struct mutex pcu_lock;
/* gen6+ rps state */ /* gen6+ GT PM state */
struct intel_gen6_power_mgmt rps; struct intel_gen6_power_mgmt gt_pm;
/* ilk-only ips/rps state. Everything in here is protected by the global /* ilk-only ips/rps state. Everything in here is protected by the global
* mchdev_lock in intel_pm.c */ * mchdev_lock in intel_pm.c */
......
...@@ -358,7 +358,7 @@ static long ...@@ -358,7 +358,7 @@ static long
i915_gem_object_wait_fence(struct dma_fence *fence, i915_gem_object_wait_fence(struct dma_fence *fence,
unsigned int flags, unsigned int flags,
long timeout, long timeout,
struct intel_rps_client *rps) struct intel_rps_client *rps_client)
{ {
struct drm_i915_gem_request *rq; struct drm_i915_gem_request *rq;
...@@ -391,11 +391,11 @@ i915_gem_object_wait_fence(struct dma_fence *fence, ...@@ -391,11 +391,11 @@ i915_gem_object_wait_fence(struct dma_fence *fence,
* forcing the clocks too high for the whole system, we only allow * forcing the clocks too high for the whole system, we only allow
* each client to waitboost once in a busy period. * each client to waitboost once in a busy period.
*/ */
if (rps) { if (rps_client) {
if (INTEL_GEN(rq->i915) >= 6) if (INTEL_GEN(rq->i915) >= 6)
gen6_rps_boost(rq, rps); gen6_rps_boost(rq, rps_client);
else else
rps = NULL; rps_client = NULL;
} }
timeout = i915_wait_request(rq, flags, timeout); timeout = i915_wait_request(rq, flags, timeout);
...@@ -411,7 +411,7 @@ static long ...@@ -411,7 +411,7 @@ static long
i915_gem_object_wait_reservation(struct reservation_object *resv, i915_gem_object_wait_reservation(struct reservation_object *resv,
unsigned int flags, unsigned int flags,
long timeout, long timeout,
struct intel_rps_client *rps) struct intel_rps_client *rps_client)
{ {
unsigned int seq = __read_seqcount_begin(&resv->seq); unsigned int seq = __read_seqcount_begin(&resv->seq);
struct dma_fence *excl; struct dma_fence *excl;
...@@ -430,7 +430,7 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, ...@@ -430,7 +430,7 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
timeout = i915_gem_object_wait_fence(shared[i], timeout = i915_gem_object_wait_fence(shared[i],
flags, timeout, flags, timeout,
rps); rps_client);
if (timeout < 0) if (timeout < 0)
break; break;
...@@ -447,7 +447,8 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, ...@@ -447,7 +447,8 @@ i915_gem_object_wait_reservation(struct reservation_object *resv,
} }
if (excl && timeout >= 0) { if (excl && timeout >= 0) {
timeout = i915_gem_object_wait_fence(excl, flags, timeout, rps); timeout = i915_gem_object_wait_fence(excl, flags, timeout,
rps_client);
prune_fences = timeout >= 0; prune_fences = timeout >= 0;
} }
...@@ -543,7 +544,7 @@ int ...@@ -543,7 +544,7 @@ int
i915_gem_object_wait(struct drm_i915_gem_object *obj, i915_gem_object_wait(struct drm_i915_gem_object *obj,
unsigned int flags, unsigned int flags,
long timeout, long timeout,
struct intel_rps_client *rps) struct intel_rps_client *rps_client)
{ {
might_sleep(); might_sleep();
#if IS_ENABLED(CONFIG_LOCKDEP) #if IS_ENABLED(CONFIG_LOCKDEP)
...@@ -555,7 +556,7 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj, ...@@ -555,7 +556,7 @@ i915_gem_object_wait(struct drm_i915_gem_object *obj,
timeout = i915_gem_object_wait_reservation(obj->resv, timeout = i915_gem_object_wait_reservation(obj->resv,
flags, timeout, flags, timeout,
rps); rps_client);
return timeout < 0 ? timeout : 0; return timeout < 0 ? timeout : 0;
} }
...@@ -563,7 +564,7 @@ static struct intel_rps_client *to_rps_client(struct drm_file *file) ...@@ -563,7 +564,7 @@ static struct intel_rps_client *to_rps_client(struct drm_file *file)
{ {
struct drm_i915_file_private *fpriv = file->driver_priv; struct drm_i915_file_private *fpriv = file->driver_priv;
return &fpriv->rps; return &fpriv->rps_client;
} }
static int static int
......
...@@ -416,7 +416,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request) ...@@ -416,7 +416,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
spin_lock_irq(&request->lock); spin_lock_irq(&request->lock);
if (request->waitboost) if (request->waitboost)
atomic_dec(&request->i915->rps.num_waiters); atomic_dec(&request->i915->gt_pm.rps.num_waiters);
dma_fence_signal_locked(&request->fence); dma_fence_signal_locked(&request->fence);
spin_unlock_irq(&request->lock); spin_unlock_irq(&request->lock);
......
...@@ -1028,6 +1028,7 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv) ...@@ -1028,6 +1028,7 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv)
static void guc_interrupts_capture(struct drm_i915_private *dev_priv) static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
enum intel_engine_id id; enum intel_engine_id id;
int irqs; int irqs;
...@@ -1064,12 +1065,13 @@ static void guc_interrupts_capture(struct drm_i915_private *dev_priv) ...@@ -1064,12 +1065,13 @@ static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
* Here we CLEAR REDIRECT_TO_GUC bit in pm_intrmsk_mbz, which will * Here we CLEAR REDIRECT_TO_GUC bit in pm_intrmsk_mbz, which will
* result in the register bit being left SET! * result in the register bit being left SET!
*/ */
dev_priv->rps.pm_intrmsk_mbz |= ARAT_EXPIRED_INTRMSK; rps->pm_intrmsk_mbz |= ARAT_EXPIRED_INTRMSK;
dev_priv->rps.pm_intrmsk_mbz &= ~GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; rps->pm_intrmsk_mbz &= ~GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
} }
static void guc_interrupts_release(struct drm_i915_private *dev_priv) static void guc_interrupts_release(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
enum intel_engine_id id; enum intel_engine_id id;
int irqs; int irqs;
...@@ -1088,8 +1090,8 @@ static void guc_interrupts_release(struct drm_i915_private *dev_priv) ...@@ -1088,8 +1090,8 @@ static void guc_interrupts_release(struct drm_i915_private *dev_priv)
I915_WRITE(GUC_VCS2_VCS1_IER, 0); I915_WRITE(GUC_VCS2_VCS1_IER, 0);
I915_WRITE(GUC_WD_VECS_IER, 0); I915_WRITE(GUC_WD_VECS_IER, 0);
dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; rps->pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
dev_priv->rps.pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK; rps->pm_intrmsk_mbz &= ~ARAT_EXPIRED_INTRMSK;
} }
int i915_guc_submission_enable(struct drm_i915_private *dev_priv) int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
......
...@@ -404,19 +404,21 @@ void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv) ...@@ -404,19 +404,21 @@ void gen6_reset_rps_interrupts(struct drm_i915_private *dev_priv)
{ {
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
gen6_reset_pm_iir(dev_priv, dev_priv->pm_rps_events); gen6_reset_pm_iir(dev_priv, dev_priv->pm_rps_events);
dev_priv->rps.pm_iir = 0; dev_priv->gt_pm.rps.pm_iir = 0;
spin_unlock_irq(&dev_priv->irq_lock); spin_unlock_irq(&dev_priv->irq_lock);
} }
void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv)
{ {
if (READ_ONCE(dev_priv->rps.interrupts_enabled)) struct intel_rps *rps = &dev_priv->gt_pm.rps;
if (READ_ONCE(rps->interrupts_enabled))
return; return;
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
WARN_ON_ONCE(dev_priv->rps.pm_iir); WARN_ON_ONCE(rps->pm_iir);
WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events); WARN_ON_ONCE(I915_READ(gen6_pm_iir(dev_priv)) & dev_priv->pm_rps_events);
dev_priv->rps.interrupts_enabled = true; rps->interrupts_enabled = true;
gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events); gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
spin_unlock_irq(&dev_priv->irq_lock); spin_unlock_irq(&dev_priv->irq_lock);
...@@ -424,11 +426,13 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv) ...@@ -424,11 +426,13 @@ void gen6_enable_rps_interrupts(struct drm_i915_private *dev_priv)
void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
{ {
if (!READ_ONCE(dev_priv->rps.interrupts_enabled)) struct intel_rps *rps = &dev_priv->gt_pm.rps;
if (!READ_ONCE(rps->interrupts_enabled))
return; return;
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
dev_priv->rps.interrupts_enabled = false; rps->interrupts_enabled = false;
I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u)); I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u));
...@@ -442,7 +446,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) ...@@ -442,7 +446,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv)
* we will reset the GPU to minimum frequencies, so the current * we will reset the GPU to minimum frequencies, so the current
* state of the worker can be discarded. * state of the worker can be discarded.
*/ */
cancel_work_sync(&dev_priv->rps.work); cancel_work_sync(&rps->work);
gen6_reset_rps_interrupts(dev_priv); gen6_reset_rps_interrupts(dev_priv);
} }
...@@ -1119,12 +1123,13 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv, ...@@ -1119,12 +1123,13 @@ static void vlv_c0_read(struct drm_i915_private *dev_priv,
void gen6_rps_reset_ei(struct drm_i915_private *dev_priv) void gen6_rps_reset_ei(struct drm_i915_private *dev_priv)
{ {
memset(&dev_priv->rps.ei, 0, sizeof(dev_priv->rps.ei)); memset(&dev_priv->gt_pm.rps.ei, 0, sizeof(dev_priv->gt_pm.rps.ei));
} }
static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
{ {
const struct intel_rps_ei *prev = &dev_priv->rps.ei; struct intel_rps *rps = &dev_priv->gt_pm.rps;
const struct intel_rps_ei *prev = &rps->ei;
struct intel_rps_ei now; struct intel_rps_ei now;
u32 events = 0; u32 events = 0;
...@@ -1151,28 +1156,29 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir) ...@@ -1151,28 +1156,29 @@ static u32 vlv_wa_c0_ei(struct drm_i915_private *dev_priv, u32 pm_iir)
c0 = max(render, media); c0 = max(render, media);
c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */ c0 *= 1000 * 100 << 8; /* to usecs and scale to threshold% */
if (c0 > time * dev_priv->rps.up_threshold) if (c0 > time * rps->up_threshold)
events = GEN6_PM_RP_UP_THRESHOLD; events = GEN6_PM_RP_UP_THRESHOLD;
else if (c0 < time * dev_priv->rps.down_threshold) else if (c0 < time * rps->down_threshold)
events = GEN6_PM_RP_DOWN_THRESHOLD; events = GEN6_PM_RP_DOWN_THRESHOLD;
} }
dev_priv->rps.ei = now; rps->ei = now;
return events; return events;
} }
static void gen6_pm_rps_work(struct work_struct *work) static void gen6_pm_rps_work(struct work_struct *work)
{ {
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
container_of(work, struct drm_i915_private, rps.work); container_of(work, struct drm_i915_private, gt_pm.rps.work);
struct intel_rps *rps = &dev_priv->gt_pm.rps;
bool client_boost = false; bool client_boost = false;
int new_delay, adj, min, max; int new_delay, adj, min, max;
u32 pm_iir = 0; u32 pm_iir = 0;
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
if (dev_priv->rps.interrupts_enabled) { if (rps->interrupts_enabled) {
pm_iir = fetch_and_zero(&dev_priv->rps.pm_iir); pm_iir = fetch_and_zero(&rps->pm_iir);
client_boost = atomic_read(&dev_priv->rps.num_waiters); client_boost = atomic_read(&rps->num_waiters);
} }
spin_unlock_irq(&dev_priv->irq_lock); spin_unlock_irq(&dev_priv->irq_lock);
...@@ -1185,14 +1191,14 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -1185,14 +1191,14 @@ static void gen6_pm_rps_work(struct work_struct *work)
pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir); pm_iir |= vlv_wa_c0_ei(dev_priv, pm_iir);
adj = dev_priv->rps.last_adj; adj = rps->last_adj;
new_delay = dev_priv->rps.cur_freq; new_delay = rps->cur_freq;
min = dev_priv->rps.min_freq_softlimit; min = rps->min_freq_softlimit;
max = dev_priv->rps.max_freq_softlimit; max = rps->max_freq_softlimit;
if (client_boost) if (client_boost)
max = dev_priv->rps.max_freq; max = rps->max_freq;
if (client_boost && new_delay < dev_priv->rps.boost_freq) { if (client_boost && new_delay < rps->boost_freq) {
new_delay = dev_priv->rps.boost_freq; new_delay = rps->boost_freq;
adj = 0; adj = 0;
} else if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { } else if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
if (adj > 0) if (adj > 0)
...@@ -1200,15 +1206,15 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -1200,15 +1206,15 @@ static void gen6_pm_rps_work(struct work_struct *work)
else /* CHV needs even encode values */ else /* CHV needs even encode values */
adj = IS_CHERRYVIEW(dev_priv) ? 2 : 1; adj = IS_CHERRYVIEW(dev_priv) ? 2 : 1;
if (new_delay >= dev_priv->rps.max_freq_softlimit) if (new_delay >= rps->max_freq_softlimit)
adj = 0; adj = 0;
} else if (client_boost) { } else if (client_boost) {
adj = 0; adj = 0;
} else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) { } else if (pm_iir & GEN6_PM_RP_DOWN_TIMEOUT) {
if (dev_priv->rps.cur_freq > dev_priv->rps.efficient_freq) if (rps->cur_freq > rps->efficient_freq)
new_delay = dev_priv->rps.efficient_freq; new_delay = rps->efficient_freq;
else if (dev_priv->rps.cur_freq > dev_priv->rps.min_freq_softlimit) else if (rps->cur_freq > rps->min_freq_softlimit)
new_delay = dev_priv->rps.min_freq_softlimit; new_delay = rps->min_freq_softlimit;
adj = 0; adj = 0;
} else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) { } else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
if (adj < 0) if (adj < 0)
...@@ -1216,13 +1222,13 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -1216,13 +1222,13 @@ static void gen6_pm_rps_work(struct work_struct *work)
else /* CHV needs even encode values */ else /* CHV needs even encode values */
adj = IS_CHERRYVIEW(dev_priv) ? -2 : -1; adj = IS_CHERRYVIEW(dev_priv) ? -2 : -1;
if (new_delay <= dev_priv->rps.min_freq_softlimit) if (new_delay <= rps->min_freq_softlimit)
adj = 0; adj = 0;
} else { /* unknown event */ } else { /* unknown event */
adj = 0; adj = 0;
} }
dev_priv->rps.last_adj = adj; rps->last_adj = adj;
/* sysfs frequency interfaces may have snuck in while servicing the /* sysfs frequency interfaces may have snuck in while servicing the
* interrupt * interrupt
...@@ -1232,7 +1238,7 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -1232,7 +1238,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
if (intel_set_rps(dev_priv, new_delay)) { if (intel_set_rps(dev_priv, new_delay)) {
DRM_DEBUG_DRIVER("Failed to set new GPU frequency\n"); DRM_DEBUG_DRIVER("Failed to set new GPU frequency\n");
dev_priv->rps.last_adj = 0; rps->last_adj = 0;
} }
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
...@@ -1240,7 +1246,7 @@ static void gen6_pm_rps_work(struct work_struct *work) ...@@ -1240,7 +1246,7 @@ static void gen6_pm_rps_work(struct work_struct *work)
out: out:
/* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */ /* Make sure not to corrupt PMIMR state used by ringbuffer on GEN6 */
spin_lock_irq(&dev_priv->irq_lock); spin_lock_irq(&dev_priv->irq_lock);
if (dev_priv->rps.interrupts_enabled) if (rps->interrupts_enabled)
gen6_unmask_pm_irq(dev_priv, dev_priv->pm_rps_events); gen6_unmask_pm_irq(dev_priv, dev_priv->pm_rps_events);
spin_unlock_irq(&dev_priv->irq_lock); spin_unlock_irq(&dev_priv->irq_lock);
} }
...@@ -1721,12 +1727,14 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, ...@@ -1721,12 +1727,14 @@ static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv,
* the work queue. */ * the work queue. */
static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
if (pm_iir & dev_priv->pm_rps_events) { if (pm_iir & dev_priv->pm_rps_events) {
spin_lock(&dev_priv->irq_lock); spin_lock(&dev_priv->irq_lock);
gen6_mask_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); gen6_mask_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events);
if (dev_priv->rps.interrupts_enabled) { if (rps->interrupts_enabled) {
dev_priv->rps.pm_iir |= pm_iir & dev_priv->pm_rps_events; rps->pm_iir |= pm_iir & dev_priv->pm_rps_events;
schedule_work(&dev_priv->rps.work); schedule_work(&rps->work);
} }
spin_unlock(&dev_priv->irq_lock); spin_unlock(&dev_priv->irq_lock);
} }
...@@ -4007,11 +4015,12 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) ...@@ -4007,11 +4015,12 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
void intel_irq_init(struct drm_i915_private *dev_priv) void intel_irq_init(struct drm_i915_private *dev_priv)
{ {
struct drm_device *dev = &dev_priv->drm; struct drm_device *dev = &dev_priv->drm;
struct intel_rps *rps = &dev_priv->gt_pm.rps;
int i; int i;
intel_hpd_init_work(dev_priv); intel_hpd_init_work(dev_priv);
INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); INIT_WORK(&rps->work, gen6_pm_rps_work);
INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work);
for (i = 0; i < MAX_L3_SLICES; ++i) for (i = 0; i < MAX_L3_SLICES; ++i)
...@@ -4027,7 +4036,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) ...@@ -4027,7 +4036,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
else else
dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS;
dev_priv->rps.pm_intrmsk_mbz = 0; rps->pm_intrmsk_mbz = 0;
/* /*
* SNB,IVB,HSW can while VLV,CHV may hard hang on looping batchbuffer * SNB,IVB,HSW can while VLV,CHV may hard hang on looping batchbuffer
...@@ -4036,10 +4045,10 @@ void intel_irq_init(struct drm_i915_private *dev_priv) ...@@ -4036,10 +4045,10 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
* TODO: verify if this can be reproduced on VLV,CHV. * TODO: verify if this can be reproduced on VLV,CHV.
*/ */
if (INTEL_GEN(dev_priv) <= 7) if (INTEL_GEN(dev_priv) <= 7)
dev_priv->rps.pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED; rps->pm_intrmsk_mbz |= GEN6_PM_RP_UP_EI_EXPIRED;
if (INTEL_GEN(dev_priv) >= 8) if (INTEL_GEN(dev_priv) >= 8)
dev_priv->rps.pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC; rps->pm_intrmsk_mbz |= GEN8_PMINTR_DISABLE_REDIRECT_TO_GUC;
if (IS_GEN2(dev_priv)) { if (IS_GEN2(dev_priv)) {
/* Gen2 doesn't have a hardware frame counter */ /* Gen2 doesn't have a hardware frame counter */
......
...@@ -275,7 +275,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev, ...@@ -275,7 +275,7 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
return snprintf(buf, PAGE_SIZE, "%d\n", return snprintf(buf, PAGE_SIZE, "%d\n",
intel_gpu_freq(dev_priv, intel_gpu_freq(dev_priv,
dev_priv->rps.cur_freq)); dev_priv->gt_pm.rps.cur_freq));
} }
static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
...@@ -284,7 +284,7 @@ static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribu ...@@ -284,7 +284,7 @@ static ssize_t gt_boost_freq_mhz_show(struct device *kdev, struct device_attribu
return snprintf(buf, PAGE_SIZE, "%d\n", return snprintf(buf, PAGE_SIZE, "%d\n",
intel_gpu_freq(dev_priv, intel_gpu_freq(dev_priv,
dev_priv->rps.boost_freq)); dev_priv->gt_pm.rps.boost_freq));
} }
static ssize_t gt_boost_freq_mhz_store(struct device *kdev, static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
...@@ -292,6 +292,7 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev, ...@@ -292,6 +292,7 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 val; u32 val;
ssize_t ret; ssize_t ret;
...@@ -301,11 +302,11 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev, ...@@ -301,11 +302,11 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev,
/* Validate against (static) hardware limits */ /* Validate against (static) hardware limits */
val = intel_freq_opcode(dev_priv, val); val = intel_freq_opcode(dev_priv, val);
if (val < dev_priv->rps.min_freq || val > dev_priv->rps.max_freq) if (val < rps->min_freq || val > rps->max_freq)
return -EINVAL; return -EINVAL;
mutex_lock(&dev_priv->pcu_lock); mutex_lock(&dev_priv->pcu_lock);
dev_priv->rps.boost_freq = val; rps->boost_freq = val;
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
return count; return count;
...@@ -318,7 +319,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, ...@@ -318,7 +319,7 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev,
return snprintf(buf, PAGE_SIZE, "%d\n", return snprintf(buf, PAGE_SIZE, "%d\n",
intel_gpu_freq(dev_priv, intel_gpu_freq(dev_priv,
dev_priv->rps.efficient_freq)); dev_priv->gt_pm.rps.efficient_freq));
} }
static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
...@@ -327,7 +328,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute ...@@ -327,7 +328,7 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
return snprintf(buf, PAGE_SIZE, "%d\n", return snprintf(buf, PAGE_SIZE, "%d\n",
intel_gpu_freq(dev_priv, intel_gpu_freq(dev_priv,
dev_priv->rps.max_freq_softlimit)); dev_priv->gt_pm.rps.max_freq_softlimit));
} }
static ssize_t gt_max_freq_mhz_store(struct device *kdev, static ssize_t gt_max_freq_mhz_store(struct device *kdev,
...@@ -335,6 +336,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, ...@@ -335,6 +336,7 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 val; u32 val;
ssize_t ret; ssize_t ret;
...@@ -348,23 +350,23 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, ...@@ -348,23 +350,23 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
val = intel_freq_opcode(dev_priv, val); val = intel_freq_opcode(dev_priv, val);
if (val < dev_priv->rps.min_freq || if (val < rps->min_freq ||
val > dev_priv->rps.max_freq || val > rps->max_freq ||
val < dev_priv->rps.min_freq_softlimit) { val < rps->min_freq_softlimit) {
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
return -EINVAL; return -EINVAL;
} }
if (val > dev_priv->rps.rp0_freq) if (val > rps->rp0_freq)
DRM_DEBUG("User requested overclocking to %d\n", DRM_DEBUG("User requested overclocking to %d\n",
intel_gpu_freq(dev_priv, val)); intel_gpu_freq(dev_priv, val));
dev_priv->rps.max_freq_softlimit = val; rps->max_freq_softlimit = val;
val = clamp_t(int, dev_priv->rps.cur_freq, val = clamp_t(int, rps->cur_freq,
dev_priv->rps.min_freq_softlimit, rps->min_freq_softlimit,
dev_priv->rps.max_freq_softlimit); rps->max_freq_softlimit);
/* We still need *_set_rps to process the new max_delay and /* We still need *_set_rps to process the new max_delay and
* update the interrupt limits and PMINTRMSK even though * update the interrupt limits and PMINTRMSK even though
...@@ -384,7 +386,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute ...@@ -384,7 +386,7 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute
return snprintf(buf, PAGE_SIZE, "%d\n", return snprintf(buf, PAGE_SIZE, "%d\n",
intel_gpu_freq(dev_priv, intel_gpu_freq(dev_priv,
dev_priv->rps.min_freq_softlimit)); dev_priv->gt_pm.rps.min_freq_softlimit));
} }
static ssize_t gt_min_freq_mhz_store(struct device *kdev, static ssize_t gt_min_freq_mhz_store(struct device *kdev,
...@@ -392,6 +394,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, ...@@ -392,6 +394,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 val; u32 val;
ssize_t ret; ssize_t ret;
...@@ -405,19 +408,19 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, ...@@ -405,19 +408,19 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
val = intel_freq_opcode(dev_priv, val); val = intel_freq_opcode(dev_priv, val);
if (val < dev_priv->rps.min_freq || if (val < rps->min_freq ||
val > dev_priv->rps.max_freq || val > rps->max_freq ||
val > dev_priv->rps.max_freq_softlimit) { val > rps->max_freq_softlimit) {
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
return -EINVAL; return -EINVAL;
} }
dev_priv->rps.min_freq_softlimit = val; rps->min_freq_softlimit = val;
val = clamp_t(int, dev_priv->rps.cur_freq, val = clamp_t(int, rps->cur_freq,
dev_priv->rps.min_freq_softlimit, rps->min_freq_softlimit,
dev_priv->rps.max_freq_softlimit); rps->max_freq_softlimit);
/* We still need *_set_rps to process the new min_delay and /* We still need *_set_rps to process the new min_delay and
* update the interrupt limits and PMINTRMSK even though * update the interrupt limits and PMINTRMSK even though
...@@ -448,14 +451,15 @@ static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL); ...@@ -448,14 +451,15 @@ static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL);
static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf)
{ {
struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev);
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 val; u32 val;
if (attr == &dev_attr_gt_RP0_freq_mhz) if (attr == &dev_attr_gt_RP0_freq_mhz)
val = intel_gpu_freq(dev_priv, dev_priv->rps.rp0_freq); val = intel_gpu_freq(dev_priv, rps->rp0_freq);
else if (attr == &dev_attr_gt_RP1_freq_mhz) else if (attr == &dev_attr_gt_RP1_freq_mhz)
val = intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq); val = intel_gpu_freq(dev_priv, rps->rp1_freq);
else if (attr == &dev_attr_gt_RPn_freq_mhz) else if (attr == &dev_attr_gt_RPn_freq_mhz)
val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq); val = intel_gpu_freq(dev_priv, rps->min_freq);
else else
BUG(); BUG();
......
...@@ -1243,7 +1243,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv); ...@@ -1243,7 +1243,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv);
static inline u32 gen6_sanitize_rps_pm_mask(const struct drm_i915_private *i915, static inline u32 gen6_sanitize_rps_pm_mask(const struct drm_i915_private *i915,
u32 mask) u32 mask)
{ {
return mask & ~i915->rps.pm_intrmsk_mbz; return mask & ~i915->gt_pm.rps.pm_intrmsk_mbz;
} }
void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv); void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv);
......
...@@ -5988,6 +5988,7 @@ static void ironlake_disable_drps(struct drm_i915_private *dev_priv) ...@@ -5988,6 +5988,7 @@ static void ironlake_disable_drps(struct drm_i915_private *dev_priv)
*/ */
static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 limits; u32 limits;
/* Only set the down limit when we've reached the lowest level to avoid /* Only set the down limit when we've reached the lowest level to avoid
...@@ -5997,13 +5998,13 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) ...@@ -5997,13 +5998,13 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
* frequency, if the down threshold expires in that window we will not * frequency, if the down threshold expires in that window we will not
* receive a down interrupt. */ * receive a down interrupt. */
if (INTEL_GEN(dev_priv) >= 9) { if (INTEL_GEN(dev_priv) >= 9) {
limits = (dev_priv->rps.max_freq_softlimit) << 23; limits = (rps->max_freq_softlimit) << 23;
if (val <= dev_priv->rps.min_freq_softlimit) if (val <= rps->min_freq_softlimit)
limits |= (dev_priv->rps.min_freq_softlimit) << 14; limits |= (rps->min_freq_softlimit) << 14;
} else { } else {
limits = dev_priv->rps.max_freq_softlimit << 24; limits = rps->max_freq_softlimit << 24;
if (val <= dev_priv->rps.min_freq_softlimit) if (val <= rps->min_freq_softlimit)
limits |= dev_priv->rps.min_freq_softlimit << 16; limits |= rps->min_freq_softlimit << 16;
} }
return limits; return limits;
...@@ -6011,39 +6012,40 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val) ...@@ -6011,39 +6012,40 @@ static u32 intel_rps_limits(struct drm_i915_private *dev_priv, u8 val)
static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
int new_power; int new_power;
u32 threshold_up = 0, threshold_down = 0; /* in % */ u32 threshold_up = 0, threshold_down = 0; /* in % */
u32 ei_up = 0, ei_down = 0; u32 ei_up = 0, ei_down = 0;
new_power = dev_priv->rps.power; new_power = rps->power;
switch (dev_priv->rps.power) { switch (rps->power) {
case LOW_POWER: case LOW_POWER:
if (val > dev_priv->rps.efficient_freq + 1 && if (val > rps->efficient_freq + 1 &&
val > dev_priv->rps.cur_freq) val > rps->cur_freq)
new_power = BETWEEN; new_power = BETWEEN;
break; break;
case BETWEEN: case BETWEEN:
if (val <= dev_priv->rps.efficient_freq && if (val <= rps->efficient_freq &&
val < dev_priv->rps.cur_freq) val < rps->cur_freq)
new_power = LOW_POWER; new_power = LOW_POWER;
else if (val >= dev_priv->rps.rp0_freq && else if (val >= rps->rp0_freq &&
val > dev_priv->rps.cur_freq) val > rps->cur_freq)
new_power = HIGH_POWER; new_power = HIGH_POWER;
break; break;
case HIGH_POWER: case HIGH_POWER:
if (val < (dev_priv->rps.rp1_freq + dev_priv->rps.rp0_freq) >> 1 && if (val < (rps->rp1_freq + rps->rp0_freq) >> 1 &&
val < dev_priv->rps.cur_freq) val < rps->cur_freq)
new_power = BETWEEN; new_power = BETWEEN;
break; break;
} }
/* Max/min bins are special */ /* Max/min bins are special */
if (val <= dev_priv->rps.min_freq_softlimit) if (val <= rps->min_freq_softlimit)
new_power = LOW_POWER; new_power = LOW_POWER;
if (val >= dev_priv->rps.max_freq_softlimit) if (val >= rps->max_freq_softlimit)
new_power = HIGH_POWER; new_power = HIGH_POWER;
if (new_power == dev_priv->rps.power) if (new_power == rps->power)
return; return;
/* Note the units here are not exactly 1us, but 1280ns. */ /* Note the units here are not exactly 1us, but 1280ns. */
...@@ -6106,20 +6108,21 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) ...@@ -6106,20 +6108,21 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
GEN6_RP_DOWN_IDLE_AVG); GEN6_RP_DOWN_IDLE_AVG);
skip_hw_write: skip_hw_write:
dev_priv->rps.power = new_power; rps->power = new_power;
dev_priv->rps.up_threshold = threshold_up; rps->up_threshold = threshold_up;
dev_priv->rps.down_threshold = threshold_down; rps->down_threshold = threshold_down;
dev_priv->rps.last_adj = 0; rps->last_adj = 0;
} }
static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 mask = 0; u32 mask = 0;
/* We use UP_EI_EXPIRED interupts for both up/down in manual mode */ /* We use UP_EI_EXPIRED interupts for both up/down in manual mode */
if (val > dev_priv->rps.min_freq_softlimit) if (val > rps->min_freq_softlimit)
mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT; mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT;
if (val < dev_priv->rps.max_freq_softlimit) if (val < rps->max_freq_softlimit)
mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD; mask |= GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_UP_THRESHOLD;
mask &= dev_priv->pm_rps_events; mask &= dev_priv->pm_rps_events;
...@@ -6132,10 +6135,12 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val) ...@@ -6132,10 +6135,12 @@ static u32 gen6_rps_pm_mask(struct drm_i915_private *dev_priv, u8 val)
* update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */ * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */
static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val) static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* min/max delay may still have been modified so be sure to /* min/max delay may still have been modified so be sure to
* write the limits value. * write the limits value.
*/ */
if (val != dev_priv->rps.cur_freq) { if (val != rps->cur_freq) {
gen6_set_rps_thresholds(dev_priv, val); gen6_set_rps_thresholds(dev_priv, val);
if (INTEL_GEN(dev_priv) >= 9) if (INTEL_GEN(dev_priv) >= 9)
...@@ -6157,7 +6162,7 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val) ...@@ -6157,7 +6162,7 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val)
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val)); I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, intel_rps_limits(dev_priv, val));
I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
dev_priv->rps.cur_freq = val; rps->cur_freq = val;
trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
return 0; return 0;
...@@ -6173,7 +6178,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val) ...@@ -6173,7 +6178,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val));
if (val != dev_priv->rps.cur_freq) { if (val != dev_priv->gt_pm.rps.cur_freq) {
err = vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); err = vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val);
if (err) if (err)
return err; return err;
...@@ -6181,7 +6186,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val) ...@@ -6181,7 +6186,7 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
gen6_set_rps_thresholds(dev_priv, val); gen6_set_rps_thresholds(dev_priv, val);
} }
dev_priv->rps.cur_freq = val; dev_priv->gt_pm.rps.cur_freq = val;
trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val)); trace_intel_gpu_freq_change(intel_gpu_freq(dev_priv, val));
return 0; return 0;
...@@ -6196,10 +6201,11 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val) ...@@ -6196,10 +6201,11 @@ static int valleyview_set_rps(struct drm_i915_private *dev_priv, u8 val)
*/ */
static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
{ {
u32 val = dev_priv->rps.idle_freq; struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 val = rps->idle_freq;
int err; int err;
if (dev_priv->rps.cur_freq <= val) if (rps->cur_freq <= val)
return; return;
/* The punit delays the write of the frequency and voltage until it /* The punit delays the write of the frequency and voltage until it
...@@ -6224,27 +6230,29 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) ...@@ -6224,27 +6230,29 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
void gen6_rps_busy(struct drm_i915_private *dev_priv) void gen6_rps_busy(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
mutex_lock(&dev_priv->pcu_lock); mutex_lock(&dev_priv->pcu_lock);
if (dev_priv->rps.enabled) { if (rps->enabled) {
u8 freq; u8 freq;
if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED) if (dev_priv->pm_rps_events & GEN6_PM_RP_UP_EI_EXPIRED)
gen6_rps_reset_ei(dev_priv); gen6_rps_reset_ei(dev_priv);
I915_WRITE(GEN6_PMINTRMSK, I915_WRITE(GEN6_PMINTRMSK,
gen6_rps_pm_mask(dev_priv, dev_priv->rps.cur_freq)); gen6_rps_pm_mask(dev_priv, rps->cur_freq));
gen6_enable_rps_interrupts(dev_priv); gen6_enable_rps_interrupts(dev_priv);
/* Use the user's desired frequency as a guide, but for better /* Use the user's desired frequency as a guide, but for better
* performance, jump directly to RPe as our starting frequency. * performance, jump directly to RPe as our starting frequency.
*/ */
freq = max(dev_priv->rps.cur_freq, freq = max(rps->cur_freq,
dev_priv->rps.efficient_freq); rps->efficient_freq);
if (intel_set_rps(dev_priv, if (intel_set_rps(dev_priv,
clamp(freq, clamp(freq,
dev_priv->rps.min_freq_softlimit, rps->min_freq_softlimit,
dev_priv->rps.max_freq_softlimit))) rps->max_freq_softlimit)))
DRM_DEBUG_DRIVER("Failed to set idle frequency\n"); DRM_DEBUG_DRIVER("Failed to set idle frequency\n");
} }
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
...@@ -6252,6 +6260,8 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) ...@@ -6252,6 +6260,8 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv)
void gen6_rps_idle(struct drm_i915_private *dev_priv) void gen6_rps_idle(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* Flush our bottom-half so that it does not race with us /* Flush our bottom-half so that it does not race with us
* setting the idle frequency and so that it is bounded by * setting the idle frequency and so that it is bounded by
* our rpm wakeref. And then disable the interrupts to stop any * our rpm wakeref. And then disable the interrupts to stop any
...@@ -6260,12 +6270,12 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) ...@@ -6260,12 +6270,12 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
gen6_disable_rps_interrupts(dev_priv); gen6_disable_rps_interrupts(dev_priv);
mutex_lock(&dev_priv->pcu_lock); mutex_lock(&dev_priv->pcu_lock);
if (dev_priv->rps.enabled) { if (rps->enabled) {
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
vlv_set_rps_idle(dev_priv); vlv_set_rps_idle(dev_priv);
else else
gen6_set_rps(dev_priv, dev_priv->rps.idle_freq); gen6_set_rps(dev_priv, rps->idle_freq);
dev_priv->rps.last_adj = 0; rps->last_adj = 0;
I915_WRITE(GEN6_PMINTRMSK, I915_WRITE(GEN6_PMINTRMSK,
gen6_sanitize_rps_pm_mask(dev_priv, ~0)); gen6_sanitize_rps_pm_mask(dev_priv, ~0));
} }
...@@ -6273,22 +6283,22 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) ...@@ -6273,22 +6283,22 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
} }
void gen6_rps_boost(struct drm_i915_gem_request *rq, void gen6_rps_boost(struct drm_i915_gem_request *rq,
struct intel_rps_client *rps) struct intel_rps_client *rps_client)
{ {
struct drm_i915_private *i915 = rq->i915; struct intel_rps *rps = &rq->i915->gt_pm.rps;
unsigned long flags; unsigned long flags;
bool boost; bool boost;
/* This is intentionally racy! We peek at the state here, then /* This is intentionally racy! We peek at the state here, then
* validate inside the RPS worker. * validate inside the RPS worker.
*/ */
if (!i915->rps.enabled) if (!rps->enabled)
return; return;
boost = false; boost = false;
spin_lock_irqsave(&rq->lock, flags); spin_lock_irqsave(&rq->lock, flags);
if (!rq->waitboost && !i915_gem_request_completed(rq)) { if (!rq->waitboost && !i915_gem_request_completed(rq)) {
atomic_inc(&i915->rps.num_waiters); atomic_inc(&rps->num_waiters);
rq->waitboost = true; rq->waitboost = true;
boost = true; boost = true;
} }
...@@ -6296,22 +6306,23 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq, ...@@ -6296,22 +6306,23 @@ void gen6_rps_boost(struct drm_i915_gem_request *rq,
if (!boost) if (!boost)
return; return;
if (READ_ONCE(i915->rps.cur_freq) < i915->rps.boost_freq) if (READ_ONCE(rps->cur_freq) < rps->boost_freq)
schedule_work(&i915->rps.work); schedule_work(&rps->work);
atomic_inc(rps ? &rps->boosts : &i915->rps.boosts); atomic_inc(rps_client ? &rps_client->boosts : &rps->boosts);
} }
int intel_set_rps(struct drm_i915_private *dev_priv, u8 val) int intel_set_rps(struct drm_i915_private *dev_priv, u8 val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
int err; int err;
lockdep_assert_held(&dev_priv->pcu_lock); lockdep_assert_held(&dev_priv->pcu_lock);
GEM_BUG_ON(val > dev_priv->rps.max_freq); GEM_BUG_ON(val > rps->max_freq);
GEM_BUG_ON(val < dev_priv->rps.min_freq); GEM_BUG_ON(val < rps->min_freq);
if (!dev_priv->rps.enabled) { if (!rps->enabled) {
dev_priv->rps.cur_freq = val; rps->cur_freq = val;
return 0; return 0;
} }
...@@ -6493,24 +6504,26 @@ int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6) ...@@ -6493,24 +6504,26 @@ int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6)
static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv) static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* All of these values are in units of 50MHz */ /* All of these values are in units of 50MHz */
/* static values from HW: RP0 > RP1 > RPn (min_freq) */ /* static values from HW: RP0 > RP1 > RPn (min_freq) */
if (IS_GEN9_LP(dev_priv)) { if (IS_GEN9_LP(dev_priv)) {
u32 rp_state_cap = I915_READ(BXT_RP_STATE_CAP); u32 rp_state_cap = I915_READ(BXT_RP_STATE_CAP);
dev_priv->rps.rp0_freq = (rp_state_cap >> 16) & 0xff; rps->rp0_freq = (rp_state_cap >> 16) & 0xff;
dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; rps->rp1_freq = (rp_state_cap >> 8) & 0xff;
dev_priv->rps.min_freq = (rp_state_cap >> 0) & 0xff; rps->min_freq = (rp_state_cap >> 0) & 0xff;
} else { } else {
u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
dev_priv->rps.rp0_freq = (rp_state_cap >> 0) & 0xff; rps->rp0_freq = (rp_state_cap >> 0) & 0xff;
dev_priv->rps.rp1_freq = (rp_state_cap >> 8) & 0xff; rps->rp1_freq = (rp_state_cap >> 8) & 0xff;
dev_priv->rps.min_freq = (rp_state_cap >> 16) & 0xff; rps->min_freq = (rp_state_cap >> 16) & 0xff;
} }
/* hw_max = RP0 until we check for overclocking */ /* hw_max = RP0 until we check for overclocking */
dev_priv->rps.max_freq = dev_priv->rps.rp0_freq; rps->max_freq = rps->rp0_freq;
dev_priv->rps.efficient_freq = dev_priv->rps.rp1_freq; rps->efficient_freq = rps->rp1_freq;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) || if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
u32 ddcc_status = 0; u32 ddcc_status = 0;
...@@ -6518,33 +6531,34 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv) ...@@ -6518,33 +6531,34 @@ static void gen6_init_rps_frequencies(struct drm_i915_private *dev_priv)
if (sandybridge_pcode_read(dev_priv, if (sandybridge_pcode_read(dev_priv,
HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL, HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL,
&ddcc_status) == 0) &ddcc_status) == 0)
dev_priv->rps.efficient_freq = rps->efficient_freq =
clamp_t(u8, clamp_t(u8,
((ddcc_status >> 8) & 0xff), ((ddcc_status >> 8) & 0xff),
dev_priv->rps.min_freq, rps->min_freq,
dev_priv->rps.max_freq); rps->max_freq);
} }
if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Store the frequency values in 16.66 MHZ units, which is /* Store the frequency values in 16.66 MHZ units, which is
* the natural hardware unit for SKL * the natural hardware unit for SKL
*/ */
dev_priv->rps.rp0_freq *= GEN9_FREQ_SCALER; rps->rp0_freq *= GEN9_FREQ_SCALER;
dev_priv->rps.rp1_freq *= GEN9_FREQ_SCALER; rps->rp1_freq *= GEN9_FREQ_SCALER;
dev_priv->rps.min_freq *= GEN9_FREQ_SCALER; rps->min_freq *= GEN9_FREQ_SCALER;
dev_priv->rps.max_freq *= GEN9_FREQ_SCALER; rps->max_freq *= GEN9_FREQ_SCALER;
dev_priv->rps.efficient_freq *= GEN9_FREQ_SCALER; rps->efficient_freq *= GEN9_FREQ_SCALER;
} }
} }
static void reset_rps(struct drm_i915_private *dev_priv, static void reset_rps(struct drm_i915_private *dev_priv,
int (*set)(struct drm_i915_private *, u8)) int (*set)(struct drm_i915_private *, u8))
{ {
u8 freq = dev_priv->rps.cur_freq; struct intel_rps *rps = &dev_priv->gt_pm.rps;
u8 freq = rps->cur_freq;
/* force a reset */ /* force a reset */
dev_priv->rps.power = -1; rps->power = -1;
dev_priv->rps.cur_freq = -1; rps->cur_freq = -1;
if (set(dev_priv, freq)) if (set(dev_priv, freq))
DRM_ERROR("Failed to reset RPS to initial values\n"); DRM_ERROR("Failed to reset RPS to initial values\n");
...@@ -6557,7 +6571,7 @@ static void gen9_enable_rps(struct drm_i915_private *dev_priv) ...@@ -6557,7 +6571,7 @@ static void gen9_enable_rps(struct drm_i915_private *dev_priv)
/* Program defaults and thresholds for RPS*/ /* Program defaults and thresholds for RPS*/
I915_WRITE(GEN6_RC_VIDEO_FREQ, I915_WRITE(GEN6_RC_VIDEO_FREQ,
GEN9_FREQUENCY(dev_priv->rps.rp1_freq)); GEN9_FREQUENCY(dev_priv->gt_pm.rps.rp1_freq));
/* 1 second timeout*/ /* 1 second timeout*/
I915_WRITE(GEN6_RP_DOWN_TIMEOUT, I915_WRITE(GEN6_RP_DOWN_TIMEOUT,
...@@ -6670,20 +6684,22 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv) ...@@ -6670,20 +6684,22 @@ static void gen8_enable_rc6(struct drm_i915_private *dev_priv)
static void gen8_enable_rps(struct drm_i915_private *dev_priv) static void gen8_enable_rps(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
/* 1 Program defaults and thresholds for RPS*/ /* 1 Program defaults and thresholds for RPS*/
I915_WRITE(GEN6_RPNSWREQ, I915_WRITE(GEN6_RPNSWREQ,
HSW_FREQUENCY(dev_priv->rps.rp1_freq)); HSW_FREQUENCY(rps->rp1_freq));
I915_WRITE(GEN6_RC_VIDEO_FREQ, I915_WRITE(GEN6_RC_VIDEO_FREQ,
HSW_FREQUENCY(dev_priv->rps.rp1_freq)); HSW_FREQUENCY(rps->rp1_freq));
/* NB: Docs say 1s, and 1000000 - which aren't equivalent */ /* NB: Docs say 1s, and 1000000 - which aren't equivalent */
I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */ I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */
/* Docs recommend 900MHz, and 300 MHz respectively */ /* Docs recommend 900MHz, and 300 MHz respectively */
I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
dev_priv->rps.max_freq_softlimit << 24 | rps->max_freq_softlimit << 24 |
dev_priv->rps.min_freq_softlimit << 16); rps->min_freq_softlimit << 16);
I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */ I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */
I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/ I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/
...@@ -6810,6 +6826,7 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv) ...@@ -6810,6 +6826,7 @@ static void gen6_enable_rps(struct drm_i915_private *dev_priv)
static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
int min_freq = 15; int min_freq = 15;
unsigned int gpu_freq; unsigned int gpu_freq;
unsigned int max_ia_freq, min_ring_freq; unsigned int max_ia_freq, min_ring_freq;
...@@ -6840,11 +6857,11 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv) ...@@ -6840,11 +6857,11 @@ static void gen6_update_ring_freq(struct drm_i915_private *dev_priv)
if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
/* Convert GT frequency to 50 HZ units */ /* Convert GT frequency to 50 HZ units */
min_gpu_freq = dev_priv->rps.min_freq / GEN9_FREQ_SCALER; min_gpu_freq = rps->min_freq / GEN9_FREQ_SCALER;
max_gpu_freq = dev_priv->rps.max_freq / GEN9_FREQ_SCALER; max_gpu_freq = rps->max_freq / GEN9_FREQ_SCALER;
} else { } else {
min_gpu_freq = dev_priv->rps.min_freq; min_gpu_freq = rps->min_freq;
max_gpu_freq = dev_priv->rps.max_freq; max_gpu_freq = rps->max_freq;
} }
/* /*
...@@ -7095,17 +7112,18 @@ static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv) ...@@ -7095,17 +7112,18 @@ static void valleyview_cleanup_pctx(struct drm_i915_private *dev_priv)
static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv) static void vlv_init_gpll_ref_freq(struct drm_i915_private *dev_priv)
{ {
dev_priv->rps.gpll_ref_freq = dev_priv->gt_pm.rps.gpll_ref_freq =
vlv_get_cck_clock(dev_priv, "GPLL ref", vlv_get_cck_clock(dev_priv, "GPLL ref",
CCK_GPLL_CLOCK_CONTROL, CCK_GPLL_CLOCK_CONTROL,
dev_priv->czclk_freq); dev_priv->czclk_freq);
DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n", DRM_DEBUG_DRIVER("GPLL reference freq: %d kHz\n",
dev_priv->rps.gpll_ref_freq); dev_priv->gt_pm.rps.gpll_ref_freq);
} }
static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv) static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 val; u32 val;
valleyview_setup_pctx(dev_priv); valleyview_setup_pctx(dev_priv);
...@@ -7127,30 +7145,31 @@ static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7127,30 +7145,31 @@ static void valleyview_init_gt_powersave(struct drm_i915_private *dev_priv)
} }
DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
dev_priv->rps.max_freq = valleyview_rps_max_freq(dev_priv); rps->max_freq = valleyview_rps_max_freq(dev_priv);
dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; rps->rp0_freq = rps->max_freq;
DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.max_freq), intel_gpu_freq(dev_priv, rps->max_freq),
dev_priv->rps.max_freq); rps->max_freq);
dev_priv->rps.efficient_freq = valleyview_rps_rpe_freq(dev_priv); rps->efficient_freq = valleyview_rps_rpe_freq(dev_priv);
DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), intel_gpu_freq(dev_priv, rps->efficient_freq),
dev_priv->rps.efficient_freq); rps->efficient_freq);
dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv); rps->rp1_freq = valleyview_rps_guar_freq(dev_priv);
DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), intel_gpu_freq(dev_priv, rps->rp1_freq),
dev_priv->rps.rp1_freq); rps->rp1_freq);
dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv); rps->min_freq = valleyview_rps_min_freq(dev_priv);
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), intel_gpu_freq(dev_priv, rps->min_freq),
dev_priv->rps.min_freq); rps->min_freq);
} }
static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv) static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
u32 val; u32 val;
cherryview_setup_pctx(dev_priv); cherryview_setup_pctx(dev_priv);
...@@ -7171,31 +7190,29 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7171,31 +7190,29 @@ static void cherryview_init_gt_powersave(struct drm_i915_private *dev_priv)
} }
DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq); DRM_DEBUG_DRIVER("DDR speed: %d MHz\n", dev_priv->mem_freq);
dev_priv->rps.max_freq = cherryview_rps_max_freq(dev_priv); rps->max_freq = cherryview_rps_max_freq(dev_priv);
dev_priv->rps.rp0_freq = dev_priv->rps.max_freq; rps->rp0_freq = rps->max_freq;
DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.max_freq), intel_gpu_freq(dev_priv, rps->max_freq),
dev_priv->rps.max_freq); rps->max_freq);
dev_priv->rps.efficient_freq = cherryview_rps_rpe_freq(dev_priv); rps->efficient_freq = cherryview_rps_rpe_freq(dev_priv);
DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq), intel_gpu_freq(dev_priv, rps->efficient_freq),
dev_priv->rps.efficient_freq); rps->efficient_freq);
dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv); rps->rp1_freq = cherryview_rps_guar_freq(dev_priv);
DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq), intel_gpu_freq(dev_priv, rps->rp1_freq),
dev_priv->rps.rp1_freq); rps->rp1_freq);
dev_priv->rps.min_freq = cherryview_rps_min_freq(dev_priv); rps->min_freq = cherryview_rps_min_freq(dev_priv);
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n", DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
intel_gpu_freq(dev_priv, dev_priv->rps.min_freq), intel_gpu_freq(dev_priv, rps->min_freq),
dev_priv->rps.min_freq); rps->min_freq);
WARN_ONCE((dev_priv->rps.max_freq | WARN_ONCE((rps->max_freq | rps->efficient_freq | rps->rp1_freq |
dev_priv->rps.efficient_freq | rps->min_freq) & 1,
dev_priv->rps.rp1_freq |
dev_priv->rps.min_freq) & 1,
"Odd GPU freq values\n"); "Odd GPU freq values\n");
} }
...@@ -7584,7 +7601,7 @@ static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv) ...@@ -7584,7 +7601,7 @@ static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv)
lockdep_assert_held(&mchdev_lock); lockdep_assert_held(&mchdev_lock);
pxvid = I915_READ(PXVFREQ(dev_priv->rps.cur_freq)); pxvid = I915_READ(PXVFREQ(dev_priv->gt_pm.rps.cur_freq));
pxvid = (pxvid >> 24) & 0x7f; pxvid = (pxvid >> 24) & 0x7f;
ext_v = pvid_to_extvid(dev_priv, pxvid); ext_v = pvid_to_extvid(dev_priv, pxvid);
...@@ -7871,6 +7888,8 @@ static void intel_init_emon(struct drm_i915_private *dev_priv) ...@@ -7871,6 +7888,8 @@ static void intel_init_emon(struct drm_i915_private *dev_priv)
void intel_init_gt_powersave(struct drm_i915_private *dev_priv) void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* /*
* RPM depends on RC6 to save restore the GT HW context, so make RC6 a * RPM depends on RC6 to save restore the GT HW context, so make RC6 a
* requirement. * requirement.
...@@ -7892,16 +7911,16 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7892,16 +7911,16 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
gen6_init_rps_frequencies(dev_priv); gen6_init_rps_frequencies(dev_priv);
/* Derive initial user preferences/limits from the hardware limits */ /* Derive initial user preferences/limits from the hardware limits */
dev_priv->rps.idle_freq = dev_priv->rps.min_freq; rps->idle_freq = rps->min_freq;
dev_priv->rps.cur_freq = dev_priv->rps.idle_freq; rps->cur_freq = rps->idle_freq;
dev_priv->rps.max_freq_softlimit = dev_priv->rps.max_freq; rps->max_freq_softlimit = rps->max_freq;
dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; rps->min_freq_softlimit = rps->min_freq;
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
dev_priv->rps.min_freq_softlimit = rps->min_freq_softlimit =
max_t(int, max_t(int,
dev_priv->rps.efficient_freq, rps->efficient_freq,
intel_freq_opcode(dev_priv, 450)); intel_freq_opcode(dev_priv, 450));
/* After setting max-softlimit, find the overclock max freq */ /* After setting max-softlimit, find the overclock max freq */
...@@ -7912,14 +7931,14 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7912,14 +7931,14 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv)
sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &params); sandybridge_pcode_read(dev_priv, GEN6_READ_OC_PARAMS, &params);
if (params & BIT(31)) { /* OC supported */ if (params & BIT(31)) { /* OC supported */
DRM_DEBUG_DRIVER("Overclocking supported, max: %dMHz, overclock: %dMHz\n", DRM_DEBUG_DRIVER("Overclocking supported, max: %dMHz, overclock: %dMHz\n",
(dev_priv->rps.max_freq & 0xff) * 50, (rps->max_freq & 0xff) * 50,
(params & 0xff) * 50); (params & 0xff) * 50);
dev_priv->rps.max_freq = params & 0xff; rps->max_freq = params & 0xff;
} }
} }
/* Finally allow us to boost to max by default */ /* Finally allow us to boost to max by default */
dev_priv->rps.boost_freq = dev_priv->rps.max_freq; rps->boost_freq = rps->max_freq;
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
mutex_unlock(&dev_priv->drm.struct_mutex); mutex_unlock(&dev_priv->drm.struct_mutex);
...@@ -7949,7 +7968,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7949,7 +7968,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
if (INTEL_GEN(dev_priv) < 6) if (INTEL_GEN(dev_priv) < 6)
return; return;
if (cancel_delayed_work_sync(&dev_priv->rps.autoenable_work)) if (cancel_delayed_work_sync(&dev_priv->gt_pm.autoenable_work))
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
/* gen6_rps_idle() will be called later to disable interrupts */ /* gen6_rps_idle() will be called later to disable interrupts */
...@@ -7957,7 +7976,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7957,7 +7976,7 @@ void intel_suspend_gt_powersave(struct drm_i915_private *dev_priv)
void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
{ {
dev_priv->rps.enabled = true; /* force disabling */ dev_priv->gt_pm.rps.enabled = true; /* force disabling */
intel_disable_gt_powersave(dev_priv); intel_disable_gt_powersave(dev_priv);
gen6_reset_rps_interrupts(dev_priv); gen6_reset_rps_interrupts(dev_priv);
...@@ -7965,7 +7984,9 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7965,7 +7984,9 @@ void intel_sanitize_gt_powersave(struct drm_i915_private *dev_priv)
void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
{ {
if (!READ_ONCE(dev_priv->rps.enabled)) struct intel_rps *rps = &dev_priv->gt_pm.rps;
if (!READ_ONCE(rps->enabled))
return; return;
mutex_lock(&dev_priv->pcu_lock); mutex_lock(&dev_priv->pcu_lock);
...@@ -7986,16 +8007,18 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -7986,16 +8007,18 @@ void intel_disable_gt_powersave(struct drm_i915_private *dev_priv)
ironlake_disable_drps(dev_priv); ironlake_disable_drps(dev_priv);
} }
dev_priv->rps.enabled = false; rps->enabled = false;
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
} }
void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* We shouldn't be disabling as we submit, so this should be less /* We shouldn't be disabling as we submit, so this should be less
* racy than it appears! * racy than it appears!
*/ */
if (READ_ONCE(dev_priv->rps.enabled)) if (READ_ONCE(rps->enabled))
return; return;
/* Powersaving is controlled by the host when inside a VM */ /* Powersaving is controlled by the host when inside a VM */
...@@ -8028,24 +8051,26 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -8028,24 +8051,26 @@ void intel_enable_gt_powersave(struct drm_i915_private *dev_priv)
intel_init_emon(dev_priv); intel_init_emon(dev_priv);
} }
WARN_ON(dev_priv->rps.max_freq < dev_priv->rps.min_freq); WARN_ON(rps->max_freq < rps->min_freq);
WARN_ON(dev_priv->rps.idle_freq > dev_priv->rps.max_freq); WARN_ON(rps->idle_freq > rps->max_freq);
WARN_ON(dev_priv->rps.efficient_freq < dev_priv->rps.min_freq); WARN_ON(rps->efficient_freq < rps->min_freq);
WARN_ON(dev_priv->rps.efficient_freq > dev_priv->rps.max_freq); WARN_ON(rps->efficient_freq > rps->max_freq);
dev_priv->rps.enabled = true; rps->enabled = true;
mutex_unlock(&dev_priv->pcu_lock); mutex_unlock(&dev_priv->pcu_lock);
} }
static void __intel_autoenable_gt_powersave(struct work_struct *work) static void __intel_autoenable_gt_powersave(struct work_struct *work)
{ {
struct drm_i915_private *dev_priv = struct drm_i915_private *dev_priv =
container_of(work, typeof(*dev_priv), rps.autoenable_work.work); container_of(work,
typeof(*dev_priv),
gt_pm.autoenable_work.work);
struct intel_engine_cs *rcs; struct intel_engine_cs *rcs;
struct drm_i915_gem_request *req; struct drm_i915_gem_request *req;
if (READ_ONCE(dev_priv->rps.enabled)) if (READ_ONCE(dev_priv->gt_pm.rps.enabled))
goto out; goto out;
rcs = dev_priv->engine[RCS]; rcs = dev_priv->engine[RCS];
...@@ -8075,7 +8100,7 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work) ...@@ -8075,7 +8100,7 @@ static void __intel_autoenable_gt_powersave(struct work_struct *work)
void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
{ {
if (READ_ONCE(dev_priv->rps.enabled)) if (READ_ONCE(dev_priv->gt_pm.rps.enabled))
return; return;
if (IS_IRONLAKE_M(dev_priv)) { if (IS_IRONLAKE_M(dev_priv)) {
...@@ -8095,7 +8120,7 @@ void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv) ...@@ -8095,7 +8120,7 @@ void intel_autoenable_gt_powersave(struct drm_i915_private *dev_priv)
* runtime resume it's necessary). * runtime resume it's necessary).
*/ */
if (queue_delayed_work(dev_priv->wq, if (queue_delayed_work(dev_priv->wq,
&dev_priv->rps.autoenable_work, &dev_priv->gt_pm.autoenable_work,
round_jiffies_up_relative(HZ))) round_jiffies_up_relative(HZ)))
intel_runtime_pm_get_noresume(dev_priv); intel_runtime_pm_get_noresume(dev_priv);
} }
...@@ -9289,31 +9314,39 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request, ...@@ -9289,31 +9314,39 @@ int skl_pcode_request(struct drm_i915_private *dev_priv, u32 mbox, u32 request,
static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val) static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* /*
* N = val - 0xb7 * N = val - 0xb7
* Slow = Fast = GPLL ref * N * Slow = Fast = GPLL ref * N
*/ */
return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * (val - 0xb7), 1000); return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * (val - 0xb7), 1000);
} }
static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val) static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
{ {
return DIV_ROUND_CLOSEST(1000 * val, dev_priv->rps.gpll_ref_freq) + 0xb7; struct intel_rps *rps = &dev_priv->gt_pm.rps;
return DIV_ROUND_CLOSEST(1000 * val, rps->gpll_ref_freq) + 0xb7;
} }
static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val) static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* /*
* N = val / 2 * N = val / 2
* CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2 * CU (slow) = CU2x (fast) / 2 = GPLL ref * N / 2
*/ */
return DIV_ROUND_CLOSEST(dev_priv->rps.gpll_ref_freq * val, 2 * 2 * 1000); return DIV_ROUND_CLOSEST(rps->gpll_ref_freq * val, 2 * 2 * 1000);
} }
static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val) static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
{ {
struct intel_rps *rps = &dev_priv->gt_pm.rps;
/* CHV needs even values */ /* CHV needs even values */
return DIV_ROUND_CLOSEST(2 * 1000 * val, dev_priv->rps.gpll_ref_freq) * 2; return DIV_ROUND_CLOSEST(2 * 1000 * val, rps->gpll_ref_freq) * 2;
} }
int intel_gpu_freq(struct drm_i915_private *dev_priv, int val) int intel_gpu_freq(struct drm_i915_private *dev_priv, int val)
...@@ -9346,9 +9379,9 @@ void intel_pm_setup(struct drm_i915_private *dev_priv) ...@@ -9346,9 +9379,9 @@ void intel_pm_setup(struct drm_i915_private *dev_priv)
{ {
mutex_init(&dev_priv->pcu_lock); mutex_init(&dev_priv->pcu_lock);
INIT_DELAYED_WORK(&dev_priv->rps.autoenable_work, INIT_DELAYED_WORK(&dev_priv->gt_pm.autoenable_work,
__intel_autoenable_gt_powersave); __intel_autoenable_gt_powersave);
atomic_set(&dev_priv->rps.num_waiters, 0); atomic_set(&dev_priv->gt_pm.rps.num_waiters, 0);
dev_priv->runtime_pm.suspended = false; dev_priv->runtime_pm.suspended = false;
atomic_set(&dev_priv->runtime_pm.wakeref_count, 0); atomic_set(&dev_priv->runtime_pm.wakeref_count, 0);
......
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