Commit cfb3c0ab authored by Daniel Vetter's avatar Daniel Vetter

Merge patches merged by Jani while I was on vacation.

Jani apparently didn't rebase onto latest drm-intel-next so a merge is
in order.
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parents 34882298 57127efa
...@@ -2356,17 +2356,17 @@ static int i915_display_info(struct seq_file *m, void *unused) ...@@ -2356,17 +2356,17 @@ static int i915_display_info(struct seq_file *m, void *unused)
bool active; bool active;
int x, y; int x, y;
seq_printf(m, "CRTC %d: pipe: %c, active: %s\n", seq_printf(m, "CRTC %d: pipe: %c, active=%s (size=%dx%d)\n",
crtc->base.base.id, pipe_name(crtc->pipe), crtc->base.base.id, pipe_name(crtc->pipe),
yesno(crtc->active)); yesno(crtc->active), crtc->config.pipe_src_w, crtc->config.pipe_src_h);
if (crtc->active) { if (crtc->active) {
intel_crtc_info(m, crtc); intel_crtc_info(m, crtc);
active = cursor_position(dev, crtc->pipe, &x, &y); active = cursor_position(dev, crtc->pipe, &x, &y);
seq_printf(m, "\tcursor visible? %s, position (%d, %d), addr 0x%08x, active? %s\n", seq_printf(m, "\tcursor visible? %s, position (%d, %d), size %dx%d, addr 0x%08x, active? %s\n",
yesno(crtc->cursor_base), yesno(crtc->cursor_base),
x, y, crtc->cursor_addr, x, y, crtc->cursor_width, crtc->cursor_height,
yesno(active)); crtc->cursor_addr, yesno(active));
} }
seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s \n", seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s \n",
......
...@@ -520,6 +520,8 @@ static int i915_drm_freeze(struct drm_device *dev) ...@@ -520,6 +520,8 @@ static int i915_drm_freeze(struct drm_device *dev)
return error; return error;
} }
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
intel_runtime_pm_disable_interrupts(dev); intel_runtime_pm_disable_interrupts(dev);
dev_priv->enable_hotplug_processing = false; dev_priv->enable_hotplug_processing = false;
......
...@@ -600,11 +600,12 @@ struct intel_context { ...@@ -600,11 +600,12 @@ struct intel_context {
struct i915_fbc { struct i915_fbc {
unsigned long size; unsigned long size;
unsigned threshold;
unsigned int fb_id; unsigned int fb_id;
enum plane plane; enum plane plane;
int y; int y;
struct drm_mm_node *compressed_fb; struct drm_mm_node compressed_fb;
struct drm_mm_node *compressed_llb; struct drm_mm_node *compressed_llb;
struct intel_fbc_work { struct intel_fbc_work {
...@@ -2487,7 +2488,7 @@ static inline void i915_gem_chipset_flush(struct drm_device *dev) ...@@ -2487,7 +2488,7 @@ static inline void i915_gem_chipset_flush(struct drm_device *dev)
/* i915_gem_stolen.c */ /* i915_gem_stolen.c */
int i915_gem_init_stolen(struct drm_device *dev); int i915_gem_init_stolen(struct drm_device *dev);
int i915_gem_stolen_setup_compression(struct drm_device *dev, int size); int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_cpp);
void i915_gem_stolen_cleanup_compression(struct drm_device *dev); void i915_gem_stolen_cleanup_compression(struct drm_device *dev);
void i915_gem_cleanup_stolen(struct drm_device *dev); void i915_gem_cleanup_stolen(struct drm_device *dev);
struct drm_i915_gem_object * struct drm_i915_gem_object *
......
...@@ -103,30 +103,68 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev) ...@@ -103,30 +103,68 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
return base; return base;
} }
static int i915_setup_compression(struct drm_device *dev, int size) static int find_compression_threshold(struct drm_device *dev,
struct drm_mm_node *node,
int size,
int fb_cpp)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); int compression_threshold = 1;
int ret; int ret;
compressed_fb = kzalloc(sizeof(*compressed_fb), GFP_KERNEL); /* HACK: This code depends on what we will do in *_enable_fbc. If that
if (!compressed_fb) * code changes, this code needs to change as well.
goto err_llb; *
* The enable_fbc code will attempt to use one of our 2 compression
* thresholds, therefore, in that case, we only have 1 resort.
*/
/* Try to over-allocate to reduce reallocations and fragmentation */ /* Try to over-allocate to reduce reallocations and fragmentation. */
ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb, ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,
size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT); size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT);
if (ret) if (ret == 0)
ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb, return compression_threshold;
size >>= 1, 4096,
DRM_MM_SEARCH_DEFAULT); again:
if (ret) /* HW's ability to limit the CFB is 1:4 */
if (compression_threshold > 4 ||
(fb_cpp == 2 && compression_threshold == 2))
return 0;
ret = drm_mm_insert_node(&dev_priv->mm.stolen, node,
size >>= 1, 4096,
DRM_MM_SEARCH_DEFAULT);
if (ret && INTEL_INFO(dev)->gen <= 4) {
return 0;
} else if (ret) {
compression_threshold <<= 1;
goto again;
} else {
return compression_threshold;
}
}
static int i915_setup_compression(struct drm_device *dev, int size, int fb_cpp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mm_node *uninitialized_var(compressed_llb);
int ret;
ret = find_compression_threshold(dev, &dev_priv->fbc.compressed_fb,
size, fb_cpp);
if (!ret)
goto err_llb; goto err_llb;
else if (ret > 1) {
DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
}
dev_priv->fbc.threshold = ret;
if (HAS_PCH_SPLIT(dev)) if (HAS_PCH_SPLIT(dev))
I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start);
else if (IS_GM45(dev)) { else if (IS_GM45(dev)) {
I915_WRITE(DPFC_CB_BASE, compressed_fb->start); I915_WRITE(DPFC_CB_BASE, dev_priv->fbc.compressed_fb.start);
} else { } else {
compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL); compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL);
if (!compressed_llb) if (!compressed_llb)
...@@ -140,13 +178,12 @@ static int i915_setup_compression(struct drm_device *dev, int size) ...@@ -140,13 +178,12 @@ static int i915_setup_compression(struct drm_device *dev, int size)
dev_priv->fbc.compressed_llb = compressed_llb; dev_priv->fbc.compressed_llb = compressed_llb;
I915_WRITE(FBC_CFB_BASE, I915_WRITE(FBC_CFB_BASE,
dev_priv->mm.stolen_base + compressed_fb->start); dev_priv->mm.stolen_base + dev_priv->fbc.compressed_fb.start);
I915_WRITE(FBC_LL_BASE, I915_WRITE(FBC_LL_BASE,
dev_priv->mm.stolen_base + compressed_llb->start); dev_priv->mm.stolen_base + compressed_llb->start);
} }
dev_priv->fbc.compressed_fb = compressed_fb; dev_priv->fbc.size = size / dev_priv->fbc.threshold;
dev_priv->fbc.size = size;
DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n", DRM_DEBUG_KMS("reserved %d bytes of contiguous stolen space for FBC\n",
size); size);
...@@ -155,14 +192,13 @@ static int i915_setup_compression(struct drm_device *dev, int size) ...@@ -155,14 +192,13 @@ static int i915_setup_compression(struct drm_device *dev, int size)
err_fb: err_fb:
kfree(compressed_llb); kfree(compressed_llb);
drm_mm_remove_node(compressed_fb); drm_mm_remove_node(&dev_priv->fbc.compressed_fb);
err_llb: err_llb:
kfree(compressed_fb);
pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size); pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
return -ENOSPC; return -ENOSPC;
} }
int i915_gem_stolen_setup_compression(struct drm_device *dev, int size) int i915_gem_stolen_setup_compression(struct drm_device *dev, int size, int fb_cpp)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -175,7 +211,7 @@ int i915_gem_stolen_setup_compression(struct drm_device *dev, int size) ...@@ -175,7 +211,7 @@ int i915_gem_stolen_setup_compression(struct drm_device *dev, int size)
/* Release any current block */ /* Release any current block */
i915_gem_stolen_cleanup_compression(dev); i915_gem_stolen_cleanup_compression(dev);
return i915_setup_compression(dev, size); return i915_setup_compression(dev, size, fb_cpp);
} }
void i915_gem_stolen_cleanup_compression(struct drm_device *dev) void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
...@@ -185,10 +221,7 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev) ...@@ -185,10 +221,7 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
if (dev_priv->fbc.size == 0) if (dev_priv->fbc.size == 0)
return; return;
if (dev_priv->fbc.compressed_fb) { drm_mm_remove_node(&dev_priv->fbc.compressed_fb);
drm_mm_remove_node(dev_priv->fbc.compressed_fb);
kfree(dev_priv->fbc.compressed_fb);
}
if (dev_priv->fbc.compressed_llb) { if (dev_priv->fbc.compressed_llb) {
drm_mm_remove_node(dev_priv->fbc.compressed_llb); drm_mm_remove_node(dev_priv->fbc.compressed_llb);
......
...@@ -2690,6 +2690,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -2690,6 +2690,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = intel_crtc->pipe;
struct drm_framebuffer *old_fb; struct drm_framebuffer *old_fb;
struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj;
struct drm_i915_gem_object *old_obj;
int ret; int ret;
if (intel_crtc_has_pending_flip(crtc)) { if (intel_crtc_has_pending_flip(crtc)) {
...@@ -2711,11 +2712,12 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, ...@@ -2711,11 +2712,12 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
} }
old_fb = crtc->primary->fb; old_fb = crtc->primary->fb;
old_obj = old_fb ? to_intel_framebuffer(old_fb)->obj : NULL;
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
if (ret == 0) if (ret == 0)
i915_gem_track_fb(to_intel_framebuffer(old_fb)->obj, obj, i915_gem_track_fb(old_obj, obj,
INTEL_FRONTBUFFER_PRIMARY(pipe)); INTEL_FRONTBUFFER_PRIMARY(pipe));
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
if (ret != 0) { if (ret != 0) {
...@@ -6207,8 +6209,8 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc, ...@@ -6207,8 +6209,8 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc,
aligned_height = intel_align_height(dev, crtc->base.primary->fb->height, aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
plane_config->tiled); plane_config->tiled);
plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] * plane_config->size = PAGE_ALIGN(crtc->base.primary->fb->pitches[0] *
aligned_height, PAGE_SIZE); aligned_height);
DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
pipe, plane, crtc->base.primary->fb->width, pipe, plane, crtc->base.primary->fb->width,
...@@ -7227,8 +7229,8 @@ static void ironlake_get_plane_config(struct intel_crtc *crtc, ...@@ -7227,8 +7229,8 @@ static void ironlake_get_plane_config(struct intel_crtc *crtc,
aligned_height = intel_align_height(dev, crtc->base.primary->fb->height, aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
plane_config->tiled); plane_config->tiled);
plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] * plane_config->size = PAGE_ALIGN(crtc->base.primary->fb->pitches[0] *
aligned_height, PAGE_SIZE); aligned_height);
DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n", DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
pipe, plane, crtc->base.primary->fb->width, pipe, plane, crtc->base.primary->fb->width,
...@@ -8316,7 +8318,7 @@ static u32 ...@@ -8316,7 +8318,7 @@ static u32
intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp) intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp)
{ {
u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp); u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp);
return ALIGN(pitch * mode->vdisplay, PAGE_SIZE); return PAGE_ALIGN(pitch * mode->vdisplay);
} }
static struct drm_framebuffer * static struct drm_framebuffer *
......
...@@ -107,7 +107,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, ...@@ -107,7 +107,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
sizes->surface_depth); sizes->surface_depth);
size = mode_cmd.pitches[0] * mode_cmd.height; size = mode_cmd.pitches[0] * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE); size = PAGE_ALIGN(size);
obj = i915_gem_object_create_stolen(dev, size); obj = i915_gem_object_create_stolen(dev, size);
if (obj == NULL) if (obj == NULL)
obj = i915_gem_alloc_object(dev, size); obj = i915_gem_alloc_object(dev, size);
......
...@@ -229,9 +229,20 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc) ...@@ -229,9 +229,20 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc)
dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane); dpfc_ctl = DPFC_CTL_PLANE(intel_crtc->plane);
if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
dev_priv->fbc.threshold++;
switch (dev_priv->fbc.threshold) {
case 4:
case 3:
dpfc_ctl |= DPFC_CTL_LIMIT_4X;
break;
case 2:
dpfc_ctl |= DPFC_CTL_LIMIT_2X; dpfc_ctl |= DPFC_CTL_LIMIT_2X;
else break;
case 1:
dpfc_ctl |= DPFC_CTL_LIMIT_1X; dpfc_ctl |= DPFC_CTL_LIMIT_1X;
break;
}
dpfc_ctl |= DPFC_CTL_FENCE_EN; dpfc_ctl |= DPFC_CTL_FENCE_EN;
if (IS_GEN5(dev)) if (IS_GEN5(dev))
dpfc_ctl |= obj->fence_reg; dpfc_ctl |= obj->fence_reg;
...@@ -285,9 +296,21 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) ...@@ -285,9 +296,21 @@ static void gen7_enable_fbc(struct drm_crtc *crtc)
dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane); dpfc_ctl = IVB_DPFC_CTL_PLANE(intel_crtc->plane);
if (drm_format_plane_cpp(fb->pixel_format, 0) == 2) if (drm_format_plane_cpp(fb->pixel_format, 0) == 2)
dev_priv->fbc.threshold++;
switch (dev_priv->fbc.threshold) {
case 4:
case 3:
dpfc_ctl |= DPFC_CTL_LIMIT_4X;
break;
case 2:
dpfc_ctl |= DPFC_CTL_LIMIT_2X; dpfc_ctl |= DPFC_CTL_LIMIT_2X;
else break;
case 1:
dpfc_ctl |= DPFC_CTL_LIMIT_1X; dpfc_ctl |= DPFC_CTL_LIMIT_1X;
break;
}
dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN; dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;
I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
...@@ -567,7 +590,8 @@ void intel_update_fbc(struct drm_device *dev) ...@@ -567,7 +590,8 @@ void intel_update_fbc(struct drm_device *dev)
if (in_dbg_master()) if (in_dbg_master())
goto out_disable; goto out_disable;
if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size)) { if (i915_gem_stolen_setup_compression(dev, intel_fb->obj->base.size,
drm_format_plane_cpp(fb->pixel_format, 0))) {
if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL)) if (set_no_fbc_reason(dev_priv, FBC_STOLEN_TOO_SMALL))
DRM_DEBUG_KMS("framebuffer too large, disabling compression\n"); DRM_DEBUG_KMS("framebuffer too large, disabling compression\n");
goto out_disable; goto out_disable;
...@@ -3486,15 +3510,23 @@ static void gen8_enable_rps(struct drm_device *dev) ...@@ -3486,15 +3510,23 @@ static void gen8_enable_rps(struct drm_device *dev)
for_each_ring(ring, dev_priv, unused) for_each_ring(ring, dev_priv, unused)
I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10); I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
I915_WRITE(GEN6_RC_SLEEP, 0); I915_WRITE(GEN6_RC_SLEEP, 0);
I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */ if (IS_BROADWELL(dev))
I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us/1.28 for TO */
else
I915_WRITE(GEN6_RC6_THRESHOLD, 50000); /* 50/125ms per EI */
/* 3: Enable RC6 */ /* 3: Enable RC6 */
if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE) if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
rc6_mask = GEN6_RC_CTL_RC6_ENABLE; rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
intel_print_rc6_info(dev, rc6_mask); intel_print_rc6_info(dev, rc6_mask);
I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE | if (IS_BROADWELL(dev))
GEN6_RC_CTL_EI_MODE(1) | I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
rc6_mask); GEN7_RC_CTL_TO_MODE |
rc6_mask);
else
I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
GEN6_RC_CTL_EI_MODE(1) |
rc6_mask);
/* 4 Program defaults and thresholds for RPS*/ /* 4 Program defaults and thresholds for RPS*/
I915_WRITE(GEN6_RPNSWREQ, I915_WRITE(GEN6_RPNSWREQ,
......
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