|
@@ -2743,10 +2743,11 @@ static void ilk_update_wm(struct drm_crtc *crtc)
|
|
|
ilk_write_wm_values(dev_priv, &results);
|
|
|
}
|
|
|
|
|
|
-static void ilk_update_sprite_wm(struct drm_plane *plane,
|
|
|
- struct drm_crtc *crtc,
|
|
|
- uint32_t sprite_width, int pixel_size,
|
|
|
- bool enabled, bool scaled)
|
|
|
+static void
|
|
|
+ilk_update_sprite_wm(struct drm_plane *plane,
|
|
|
+ struct drm_crtc *crtc,
|
|
|
+ uint32_t sprite_width, uint32_t sprite_height,
|
|
|
+ int pixel_size, bool enabled, bool scaled)
|
|
|
{
|
|
|
struct drm_device *dev = plane->dev;
|
|
|
struct intel_plane *intel_plane = to_intel_plane(plane);
|
|
@@ -2754,6 +2755,7 @@ static void ilk_update_sprite_wm(struct drm_plane *plane,
|
|
|
intel_plane->wm.enabled = enabled;
|
|
|
intel_plane->wm.scaled = scaled;
|
|
|
intel_plane->wm.horiz_pixels = sprite_width;
|
|
|
+ intel_plane->wm.vert_pixels = sprite_width;
|
|
|
intel_plane->wm.bytes_per_pixel = pixel_size;
|
|
|
|
|
|
/*
|
|
@@ -2888,13 +2890,16 @@ void intel_update_watermarks(struct drm_crtc *crtc)
|
|
|
|
|
|
void intel_update_sprite_watermarks(struct drm_plane *plane,
|
|
|
struct drm_crtc *crtc,
|
|
|
- uint32_t sprite_width, int pixel_size,
|
|
|
+ uint32_t sprite_width,
|
|
|
+ uint32_t sprite_height,
|
|
|
+ int pixel_size,
|
|
|
bool enabled, bool scaled)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = plane->dev->dev_private;
|
|
|
|
|
|
if (dev_priv->display.update_sprite_wm)
|
|
|
- dev_priv->display.update_sprite_wm(plane, crtc, sprite_width,
|
|
|
+ dev_priv->display.update_sprite_wm(plane, crtc,
|
|
|
+ sprite_width, sprite_height,
|
|
|
pixel_size, enabled, scaled);
|
|
|
}
|
|
|
|
|
@@ -3289,7 +3294,9 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
|
|
|
|
|
|
mutex_lock(&dev_priv->rps.hw_lock);
|
|
|
if (dev_priv->rps.enabled) {
|
|
|
- if (IS_VALLEYVIEW(dev))
|
|
|
+ if (IS_CHERRYVIEW(dev))
|
|
|
+ valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
|
|
|
+ else if (IS_VALLEYVIEW(dev))
|
|
|
vlv_set_rps_idle(dev_priv);
|
|
|
else
|
|
|
gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
|
|
@@ -3392,6 +3399,8 @@ static void cherryview_disable_rps(struct drm_device *dev)
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
I915_WRITE(GEN6_RC_CONTROL, 0);
|
|
|
+
|
|
|
+ gen8_disable_rps_interrupts(dev);
|
|
|
}
|
|
|
|
|
|
static void valleyview_disable_rps(struct drm_device *dev)
|
|
@@ -3465,7 +3474,7 @@ static void gen8_enable_rps_interrupts(struct drm_device *dev)
|
|
|
|
|
|
spin_lock_irq(&dev_priv->irq_lock);
|
|
|
WARN_ON(dev_priv->rps.pm_iir);
|
|
|
- bdw_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
|
|
+ gen8_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
|
|
I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events);
|
|
|
spin_unlock_irq(&dev_priv->irq_lock);
|
|
|
}
|
|
@@ -3476,7 +3485,7 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev)
|
|
|
|
|
|
spin_lock_irq(&dev_priv->irq_lock);
|
|
|
WARN_ON(dev_priv->rps.pm_iir);
|
|
|
- snb_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
|
|
+ gen6_enable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
|
|
I915_WRITE(GEN6_PMIIR, dev_priv->pm_rps_events);
|
|
|
spin_unlock_irq(&dev_priv->irq_lock);
|
|
|
}
|
|
@@ -3781,7 +3790,7 @@ void gen6_update_ring_freq(struct drm_device *dev)
|
|
|
mutex_unlock(&dev_priv->rps.hw_lock);
|
|
|
}
|
|
|
|
|
|
-int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)
|
|
|
+static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
u32 val, rp0;
|
|
|
|
|
@@ -3801,7 +3810,17 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv)
|
|
|
return rpe;
|
|
|
}
|
|
|
|
|
|
-int cherryview_rps_min_freq(struct drm_i915_private *dev_priv)
|
|
|
+static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv)
|
|
|
+{
|
|
|
+ u32 val, rp1;
|
|
|
+
|
|
|
+ val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
|
|
|
+ rp1 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) & PUNIT_GPU_STATUS_MAX_FREQ_MASK;
|
|
|
+
|
|
|
+ return rp1;
|
|
|
+}
|
|
|
+
|
|
|
+static int cherryview_rps_min_freq(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
u32 val, rpn;
|
|
|
|
|
@@ -3810,7 +3829,18 @@ int cherryview_rps_min_freq(struct drm_i915_private *dev_priv)
|
|
|
return rpn;
|
|
|
}
|
|
|
|
|
|
-int valleyview_rps_max_freq(struct drm_i915_private *dev_priv)
|
|
|
+static int valleyview_rps_guar_freq(struct drm_i915_private *dev_priv)
|
|
|
+{
|
|
|
+ u32 val, rp1;
|
|
|
+
|
|
|
+ val = vlv_nc_read(dev_priv, IOSF_NC_FB_GFX_FREQ_FUSE);
|
|
|
+
|
|
|
+ rp1 = (val & FB_GFX_FGUARANTEED_FREQ_FUSE_MASK) >> FB_GFX_FGUARANTEED_FREQ_FUSE_SHIFT;
|
|
|
+
|
|
|
+ return rp1;
|
|
|
+}
|
|
|
+
|
|
|
+static int valleyview_rps_max_freq(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
u32 val, rp0;
|
|
|
|
|
@@ -3835,7 +3865,7 @@ static int valleyview_rps_rpe_freq(struct drm_i915_private *dev_priv)
|
|
|
return rpe;
|
|
|
}
|
|
|
|
|
|
-int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
|
|
|
+static int valleyview_rps_min_freq(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
|
|
|
}
|
|
@@ -3952,6 +3982,11 @@ static void valleyview_init_gt_powersave(struct drm_device *dev)
|
|
|
vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
|
|
|
dev_priv->rps.efficient_freq);
|
|
|
|
|
|
+ dev_priv->rps.rp1_freq = valleyview_rps_guar_freq(dev_priv);
|
|
|
+ DRM_DEBUG_DRIVER("RP1(Guar Freq) GPU freq: %d MHz (%u)\n",
|
|
|
+ vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
|
|
|
+ dev_priv->rps.rp1_freq);
|
|
|
+
|
|
|
dev_priv->rps.min_freq = valleyview_rps_min_freq(dev_priv);
|
|
|
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
|
|
|
vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq),
|
|
@@ -3986,6 +4021,11 @@ static void cherryview_init_gt_powersave(struct drm_device *dev)
|
|
|
vlv_gpu_freq(dev_priv, dev_priv->rps.efficient_freq),
|
|
|
dev_priv->rps.efficient_freq);
|
|
|
|
|
|
+ dev_priv->rps.rp1_freq = cherryview_rps_guar_freq(dev_priv);
|
|
|
+ DRM_DEBUG_DRIVER("RP1(Guar) GPU freq: %d MHz (%u)\n",
|
|
|
+ vlv_gpu_freq(dev_priv, dev_priv->rps.rp1_freq),
|
|
|
+ dev_priv->rps.rp1_freq);
|
|
|
+
|
|
|
dev_priv->rps.min_freq = cherryview_rps_min_freq(dev_priv);
|
|
|
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
|
|
|
vlv_gpu_freq(dev_priv, dev_priv->rps.min_freq),
|
|
@@ -4093,6 +4133,8 @@ static void cherryview_enable_rps(struct drm_device *dev)
|
|
|
|
|
|
valleyview_set_rps(dev_priv->dev, dev_priv->rps.efficient_freq);
|
|
|
|
|
|
+ gen8_enable_rps_interrupts(dev);
|
|
|
+
|
|
|
gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
|
|
|
}
|
|
|
|
|
@@ -4934,11 +4976,14 @@ void intel_suspend_gt_powersave(struct drm_device *dev)
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
/* Interrupts should be disabled already to avoid re-arming. */
|
|
|
- WARN_ON(dev->irq_enabled && !dev_priv->pm.irqs_disabled);
|
|
|
+ WARN_ON(intel_irqs_enabled(dev_priv));
|
|
|
|
|
|
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
|
|
|
|
|
|
cancel_work_sync(&dev_priv->rps.work);
|
|
|
+
|
|
|
+ /* Force GPU to min freq during suspend */
|
|
|
+ gen6_rps_idle(dev_priv);
|
|
|
}
|
|
|
|
|
|
void intel_disable_gt_powersave(struct drm_device *dev)
|
|
@@ -4946,7 +4991,7 @@ void intel_disable_gt_powersave(struct drm_device *dev)
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
|
|
|
/* Interrupts should be disabled already to avoid re-arming. */
|
|
|
- WARN_ON(dev->irq_enabled && !dev_priv->pm.irqs_disabled);
|
|
|
+ WARN_ON(intel_irqs_enabled(dev_priv));
|
|
|
|
|
|
if (IS_IRONLAKE_M(dev)) {
|
|
|
ironlake_disable_drps(dev);
|
|
@@ -5684,6 +5729,35 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
|
|
|
static void cherryview_init_clock_gating(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ mutex_lock(&dev_priv->rps.hw_lock);
|
|
|
+ val = vlv_punit_read(dev_priv, CCK_FUSE_REG);
|
|
|
+ mutex_unlock(&dev_priv->rps.hw_lock);
|
|
|
+ switch ((val >> 2) & 0x7) {
|
|
|
+ case 0:
|
|
|
+ case 1:
|
|
|
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_200;
|
|
|
+ dev_priv->mem_freq = 1600;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_267;
|
|
|
+ dev_priv->mem_freq = 1600;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_333;
|
|
|
+ dev_priv->mem_freq = 2000;
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_320;
|
|
|
+ dev_priv->mem_freq = 1600;
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ dev_priv->rps.cz_freq = CHV_CZ_CLOCK_FREQ_MODE_400;
|
|
|
+ dev_priv->mem_freq = 1600;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
|
|
|
|
|
|
I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
|
|
|
|
|
@@ -5924,7 +5998,6 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
|
|
|
static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
struct drm_device *dev = dev_priv->dev;
|
|
|
- unsigned long irqflags;
|
|
|
|
|
|
/*
|
|
|
* After we re-enable the power well, if we touch VGA register 0x3d5
|
|
@@ -5940,21 +6013,8 @@ static void hsw_power_well_post_enable(struct drm_i915_private *dev_priv)
|
|
|
outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
|
|
|
vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
|
|
|
|
|
|
- if (IS_BROADWELL(dev)) {
|
|
|
- spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
|
|
|
- I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_B),
|
|
|
- dev_priv->de_irq_mask[PIPE_B]);
|
|
|
- I915_WRITE(GEN8_DE_PIPE_IER(PIPE_B),
|
|
|
- ~dev_priv->de_irq_mask[PIPE_B] |
|
|
|
- GEN8_PIPE_VBLANK);
|
|
|
- I915_WRITE(GEN8_DE_PIPE_IMR(PIPE_C),
|
|
|
- dev_priv->de_irq_mask[PIPE_C]);
|
|
|
- I915_WRITE(GEN8_DE_PIPE_IER(PIPE_C),
|
|
|
- ~dev_priv->de_irq_mask[PIPE_C] |
|
|
|
- GEN8_PIPE_VBLANK);
|
|
|
- POSTING_READ(GEN8_DE_PIPE_IER(PIPE_C));
|
|
|
- spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
|
|
|
- }
|
|
|
+ if (IS_BROADWELL(dev))
|
|
|
+ gen8_irq_power_well_post_enable(dev_priv);
|
|
|
}
|
|
|
|
|
|
static void hsw_set_power_well(struct drm_i915_private *dev_priv,
|
|
@@ -6881,7 +6941,7 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
+static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
{
|
|
|
int div;
|
|
|
|
|
@@ -6903,7 +6963,7 @@ int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
return DIV_ROUND_CLOSEST(dev_priv->mem_freq * (val + 6 - 0xbd), 4 * div);
|
|
|
}
|
|
|
|
|
|
-int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
+static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
{
|
|
|
int mul;
|
|
|
|
|
@@ -6925,6 +6985,80 @@ int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
return DIV_ROUND_CLOSEST(4 * mul * val, dev_priv->mem_freq) + 0xbd - 6;
|
|
|
}
|
|
|
|
|
|
+static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
+{
|
|
|
+ int div, freq;
|
|
|
+
|
|
|
+ switch (dev_priv->rps.cz_freq) {
|
|
|
+ case 200:
|
|
|
+ div = 5;
|
|
|
+ break;
|
|
|
+ case 267:
|
|
|
+ div = 6;
|
|
|
+ break;
|
|
|
+ case 320:
|
|
|
+ case 333:
|
|
|
+ case 400:
|
|
|
+ div = 8;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ freq = (DIV_ROUND_CLOSEST((dev_priv->rps.cz_freq * val), 2 * div) / 2);
|
|
|
+
|
|
|
+ return freq;
|
|
|
+}
|
|
|
+
|
|
|
+static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
+{
|
|
|
+ int mul, opcode;
|
|
|
+
|
|
|
+ switch (dev_priv->rps.cz_freq) {
|
|
|
+ case 200:
|
|
|
+ mul = 5;
|
|
|
+ break;
|
|
|
+ case 267:
|
|
|
+ mul = 6;
|
|
|
+ break;
|
|
|
+ case 320:
|
|
|
+ case 333:
|
|
|
+ case 400:
|
|
|
+ mul = 8;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ opcode = (DIV_ROUND_CLOSEST((val * 2 * mul), dev_priv->rps.cz_freq) * 2);
|
|
|
+
|
|
|
+ return opcode;
|
|
|
+}
|
|
|
+
|
|
|
+int vlv_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
+{
|
|
|
+ int ret = -1;
|
|
|
+
|
|
|
+ if (IS_CHERRYVIEW(dev_priv->dev))
|
|
|
+ ret = chv_gpu_freq(dev_priv, val);
|
|
|
+ else if (IS_VALLEYVIEW(dev_priv->dev))
|
|
|
+ ret = byt_gpu_freq(dev_priv, val);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+int vlv_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
+{
|
|
|
+ int ret = -1;
|
|
|
+
|
|
|
+ if (IS_CHERRYVIEW(dev_priv->dev))
|
|
|
+ ret = chv_freq_opcode(dev_priv, val);
|
|
|
+ else if (IS_VALLEYVIEW(dev_priv->dev))
|
|
|
+ ret = byt_freq_opcode(dev_priv, val);
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
void intel_pm_setup(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
@@ -6935,5 +7069,5 @@ void intel_pm_setup(struct drm_device *dev)
|
|
|
intel_gen6_powersave_work);
|
|
|
|
|
|
dev_priv->pm.suspended = false;
|
|
|
- dev_priv->pm.irqs_disabled = false;
|
|
|
+ dev_priv->pm._irqs_disabled = false;
|
|
|
}
|