drm/i915: turbo & RC6 support for VLV v7
Uses slightly different interfaces than other platforms. v2: track actual set freq, not requested (Rohit) fix debug prints in init code (Jesse) v3: don't write sleep reg (Jesse) re-add RC6 wake limit write (Ben) fixup thresholds to match other platforms (Ben) clean up mem freq calculation (Ben) clean up debug prints (Ben) v4: move defines from punit patch (Ville) v5: remove writes to nonexistent regs (Jesse) put RP and RC regs together (Jesse) fix RC6 enable (Jesse) v6: use correct fuse reads from NC (Jesse) split out min/max funcs for use in sysfs (Jesse) add debugfs & sysfs freq controls (Jesse) v7: update with Ben's hw_max changes (Jesse) Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> (v6) [danvet: Follow checkpatch sugggestion to use min_t to avoid casting fun.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:

committed by
Daniel Vetter

parent
855ba3be12
commit
0a073b843b
@@ -212,7 +212,10 @@ static ssize_t gt_cur_freq_mhz_show(struct device *kdev,
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->rps.hw_lock);
|
||||
ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER;
|
||||
if (IS_VALLEYVIEW(dev_priv->dev))
|
||||
ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.cur_delay);
|
||||
else
|
||||
ret = dev_priv->rps.cur_delay * GT_FREQUENCY_MULTIPLIER;
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ret);
|
||||
@@ -226,7 +229,10 @@ static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->rps.hw_lock);
|
||||
ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
|
||||
if (IS_VALLEYVIEW(dev_priv->dev))
|
||||
ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.max_delay);
|
||||
else
|
||||
ret = dev_priv->rps.max_delay * GT_FREQUENCY_MULTIPLIER;
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ret);
|
||||
@@ -246,16 +252,25 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val /= GT_FREQUENCY_MULTIPLIER;
|
||||
|
||||
mutex_lock(&dev_priv->rps.hw_lock);
|
||||
|
||||
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
||||
hw_max = dev_priv->rps.hw_max;
|
||||
non_oc_max = (rp_state_cap & 0xff);
|
||||
hw_min = ((rp_state_cap & 0xff0000) >> 16);
|
||||
if (IS_VALLEYVIEW(dev_priv->dev)) {
|
||||
val = vlv_freq_opcode(dev_priv->mem_freq, val);
|
||||
|
||||
if (val < hw_min || val > hw_max || val < dev_priv->rps.min_delay) {
|
||||
hw_max = valleyview_rps_max_freq(dev_priv);
|
||||
hw_min = valleyview_rps_min_freq(dev_priv);
|
||||
non_oc_max = hw_max;
|
||||
} else {
|
||||
val /= GT_FREQUENCY_MULTIPLIER;
|
||||
|
||||
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
||||
hw_max = dev_priv->rps.hw_max;
|
||||
non_oc_max = (rp_state_cap & 0xff);
|
||||
hw_min = ((rp_state_cap & 0xff0000) >> 16);
|
||||
}
|
||||
|
||||
if (val < hw_min || val > hw_max ||
|
||||
val < dev_priv->rps.min_delay) {
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -264,8 +279,12 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev,
|
||||
DRM_DEBUG("User requested overclocking to %d\n",
|
||||
val * GT_FREQUENCY_MULTIPLIER);
|
||||
|
||||
if (dev_priv->rps.cur_delay > val)
|
||||
gen6_set_rps(dev_priv->dev, val);
|
||||
if (dev_priv->rps.cur_delay > val) {
|
||||
if (IS_VALLEYVIEW(dev_priv->dev))
|
||||
valleyview_set_rps(dev_priv->dev, val);
|
||||
else
|
||||
gen6_set_rps(dev_priv->dev, val);
|
||||
}
|
||||
|
||||
dev_priv->rps.max_delay = val;
|
||||
|
||||
@@ -282,7 +301,10 @@ static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute
|
||||
int ret;
|
||||
|
||||
mutex_lock(&dev_priv->rps.hw_lock);
|
||||
ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
|
||||
if (IS_VALLEYVIEW(dev_priv->dev))
|
||||
ret = vlv_gpu_freq(dev_priv->mem_freq, dev_priv->rps.min_delay);
|
||||
else
|
||||
ret = dev_priv->rps.min_delay * GT_FREQUENCY_MULTIPLIER;
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", ret);
|
||||
@@ -302,21 +324,32 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val /= GT_FREQUENCY_MULTIPLIER;
|
||||
|
||||
mutex_lock(&dev_priv->rps.hw_lock);
|
||||
|
||||
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
||||
hw_max = dev_priv->rps.hw_max;
|
||||
hw_min = ((rp_state_cap & 0xff0000) >> 16);
|
||||
if (IS_VALLEYVIEW(dev)) {
|
||||
val = vlv_freq_opcode(dev_priv->mem_freq, val);
|
||||
|
||||
hw_max = valleyview_rps_max_freq(dev_priv);
|
||||
hw_min = valleyview_rps_min_freq(dev_priv);
|
||||
} else {
|
||||
val /= GT_FREQUENCY_MULTIPLIER;
|
||||
|
||||
rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
|
||||
hw_max = dev_priv->rps.hw_max;
|
||||
hw_min = ((rp_state_cap & 0xff0000) >> 16);
|
||||
}
|
||||
|
||||
if (val < hw_min || val > hw_max || val > dev_priv->rps.max_delay) {
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (dev_priv->rps.cur_delay < val)
|
||||
gen6_set_rps(dev_priv->dev, val);
|
||||
if (dev_priv->rps.cur_delay < val) {
|
||||
if (IS_VALLEYVIEW(dev))
|
||||
valleyview_set_rps(dev, val);
|
||||
else
|
||||
gen6_set_rps(dev_priv->dev, val);
|
||||
}
|
||||
|
||||
dev_priv->rps.min_delay = val;
|
||||
|
||||
|
Reference in New Issue
Block a user