mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 01:51:53 +00:00
Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel into drm-intel-fixes
Daniel Vetter writes: 3 regression fixes: - disable gmbus again, too broken for 3.4, we'll try again for 3.5 - dp bandwidth computation fix, we've lost the 6bpc dithering flag sometimes, this is a 3.3 regression (maybe even earlier for some configurations). - fix resume regression caused by the gen2/3 fencing fix merged into -rc2. And a few other fixes: - gpu hang fix for i845 (Chris) - sprite fix (Armin Reese) - crtc disable vs. scanlinewait race fix (Chris) - rc6 module option read-only, it confused testers (Jesse) - fbc related blitter death hw workaround, note that we disable fbc on snb by default anyway. With these fixes we have one 3.4 regression outstanding: One of the cleanup patches for the interlaced support managed to confuse the lvds panel fitter when upscaling. The root-cause is still unclear, but test patches are awaiting feedback from the reporter. * 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel: drm/i915: clear fencing tracking state when retiring requests drm/i915: make rc6 module parameter read-only drm/i915: implement ColorBlt w/a drm/i915/ringbuffer: Exclude last 2 cachlines of ring on 845g Revert "drm/i915: reenable gmbus on gen3+ again" drm/i915: properly compute dp dithering for user-created modes drm/i915: Finish any pending operations on the framebuffer before disabling drm/i915: Removed IVB forced enable of sprite dest key.
This commit is contained in:
commit
19e5c4e72c
@ -64,7 +64,7 @@ MODULE_PARM_DESC(semaphores,
|
||||
"Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))");
|
||||
|
||||
int i915_enable_rc6 __read_mostly = -1;
|
||||
module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
|
||||
module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0400);
|
||||
MODULE_PARM_DESC(i915_enable_rc6,
|
||||
"Enable power-saving render C-state 6. "
|
||||
"Different stages can be selected via bitmask values "
|
||||
|
@ -1493,6 +1493,7 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj)
|
||||
{
|
||||
list_del_init(&obj->ring_list);
|
||||
obj->last_rendering_seqno = 0;
|
||||
obj->last_fenced_seqno = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1521,6 +1522,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj)
|
||||
BUG_ON(!list_empty(&obj->gpu_write_list));
|
||||
BUG_ON(!obj->active);
|
||||
obj->ring = NULL;
|
||||
obj->last_fenced_ring = NULL;
|
||||
|
||||
i915_gem_object_move_off_active(obj);
|
||||
obj->fenced_gpu_access = false;
|
||||
|
@ -3728,6 +3728,9 @@
|
||||
#define GT_FIFO_FREE_ENTRIES 0x120008
|
||||
#define GT_FIFO_NUM_RESERVED_ENTRIES 20
|
||||
|
||||
#define GEN6_UCGCTL1 0x9400
|
||||
# define GEN6_BLBUNIT_CLOCK_GATE_DISABLE (1 << 5)
|
||||
|
||||
#define GEN6_UCGCTL2 0x9404
|
||||
# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13)
|
||||
# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12)
|
||||
|
@ -2244,6 +2244,33 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_finish_fb(struct drm_framebuffer *old_fb)
|
||||
{
|
||||
struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
|
||||
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
|
||||
bool was_interruptible = dev_priv->mm.interruptible;
|
||||
int ret;
|
||||
|
||||
wait_event(dev_priv->pending_flip_queue,
|
||||
atomic_read(&dev_priv->mm.wedged) ||
|
||||
atomic_read(&obj->pending_flip) == 0);
|
||||
|
||||
/* Big Hammer, we also need to ensure that any pending
|
||||
* MI_WAIT_FOR_EVENT inside a user batch buffer on the
|
||||
* current scanout is retired before unpinning the old
|
||||
* framebuffer.
|
||||
*
|
||||
* This should only fail upon a hung GPU, in which case we
|
||||
* can safely continue.
|
||||
*/
|
||||
dev_priv->mm.interruptible = false;
|
||||
ret = i915_gem_object_finish_gpu(obj);
|
||||
dev_priv->mm.interruptible = was_interruptible;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
struct drm_framebuffer *old_fb)
|
||||
@ -2282,25 +2309,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (old_fb) {
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj;
|
||||
|
||||
wait_event(dev_priv->pending_flip_queue,
|
||||
atomic_read(&dev_priv->mm.wedged) ||
|
||||
atomic_read(&obj->pending_flip) == 0);
|
||||
|
||||
/* Big Hammer, we also need to ensure that any pending
|
||||
* MI_WAIT_FOR_EVENT inside a user batch buffer on the
|
||||
* current scanout is retired before unpinning the old
|
||||
* framebuffer.
|
||||
*
|
||||
* This should only fail upon a hung GPU, in which case we
|
||||
* can safely continue.
|
||||
*/
|
||||
ret = i915_gem_object_finish_gpu(obj);
|
||||
(void) ret;
|
||||
}
|
||||
if (old_fb)
|
||||
intel_finish_fb(old_fb);
|
||||
|
||||
ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y,
|
||||
LEAVE_ATOMIC_MODE_SET);
|
||||
@ -3371,6 +3381,23 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
|
||||
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
||||
struct drm_device *dev = crtc->dev;
|
||||
|
||||
/* Flush any pending WAITs before we disable the pipe. Note that
|
||||
* we need to drop the struct_mutex in order to acquire it again
|
||||
* during the lowlevel dpms routines around a couple of the
|
||||
* operations. It does not look trivial nor desirable to move
|
||||
* that locking higher. So instead we leave a window for the
|
||||
* submission of further commands on the fb before we can actually
|
||||
* disable it. This race with userspace exists anyway, and we can
|
||||
* only rely on the pipe being disabled by userspace after it
|
||||
* receives the hotplug notification and has flushed any pending
|
||||
* batches.
|
||||
*/
|
||||
if (crtc->fb) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
intel_finish_fb(crtc->fb);
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
}
|
||||
|
||||
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||
assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
|
||||
assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
|
||||
@ -8529,6 +8556,10 @@ static void gen6_init_clock_gating(struct drm_device *dev)
|
||||
I915_WRITE(WM2_LP_ILK, 0);
|
||||
I915_WRITE(WM1_LP_ILK, 0);
|
||||
|
||||
I915_WRITE(GEN6_UCGCTL1,
|
||||
I915_READ(GEN6_UCGCTL1) |
|
||||
GEN6_BLBUNIT_CLOCK_GATE_DISABLE);
|
||||
|
||||
/* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
|
||||
* gating disable must be set. Failure to set it results in
|
||||
* flickering pixels due to Z write ordering failures after
|
||||
|
@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
|
||||
return (max_link_clock * max_lanes * 8) / 10;
|
||||
}
|
||||
|
||||
static bool
|
||||
intel_dp_adjust_dithering(struct intel_dp *intel_dp,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
|
||||
int max_lanes = intel_dp_max_lane_count(intel_dp);
|
||||
int max_rate, mode_rate;
|
||||
|
||||
mode_rate = intel_dp_link_required(mode->clock, 24);
|
||||
max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
|
||||
|
||||
if (mode_rate > max_rate) {
|
||||
mode_rate = intel_dp_link_required(mode->clock, 18);
|
||||
if (mode_rate > max_rate)
|
||||
return false;
|
||||
|
||||
if (adjusted_mode)
|
||||
adjusted_mode->private_flags
|
||||
|= INTEL_MODE_DP_FORCE_6BPC;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_dp_mode_valid(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode)
|
||||
{
|
||||
struct intel_dp *intel_dp = intel_attached_dp(connector);
|
||||
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
|
||||
int max_lanes = intel_dp_max_lane_count(intel_dp);
|
||||
int max_rate, mode_rate;
|
||||
|
||||
if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
|
||||
if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
|
||||
@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
|
||||
return MODE_PANEL;
|
||||
}
|
||||
|
||||
mode_rate = intel_dp_link_required(mode->clock, 24);
|
||||
max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
|
||||
|
||||
if (mode_rate > max_rate) {
|
||||
mode_rate = intel_dp_link_required(mode->clock, 18);
|
||||
if (mode_rate > max_rate)
|
||||
if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
|
||||
return MODE_CLOCK_HIGH;
|
||||
else
|
||||
mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC;
|
||||
}
|
||||
|
||||
if (mode->clock < 10000)
|
||||
return MODE_CLOCK_LOW;
|
||||
@ -672,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
||||
int lane_count, clock;
|
||||
int max_lane_count = intel_dp_max_lane_count(intel_dp);
|
||||
int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
|
||||
int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
|
||||
int bpp;
|
||||
static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
|
||||
|
||||
if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
|
||||
@ -686,6 +702,11 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
||||
mode->clock = intel_dp->panel_fixed_mode->clock;
|
||||
}
|
||||
|
||||
if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
|
||||
return false;
|
||||
|
||||
bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
|
||||
|
||||
for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
|
||||
for (clock = 0; clock <= max_clock; clock++) {
|
||||
int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);
|
||||
|
@ -390,7 +390,7 @@ int intel_setup_gmbus(struct drm_device *dev)
|
||||
bus->has_gpio = intel_gpio_setup(bus, i);
|
||||
|
||||
/* XXX force bit banging until GMBUS is fully debugged */
|
||||
if (bus->has_gpio && IS_GEN2(dev))
|
||||
if (bus->has_gpio)
|
||||
bus->force_bit = true;
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ int intel_init_ring_buffer(struct drm_device *dev,
|
||||
* of the buffer.
|
||||
*/
|
||||
ring->effective_size = ring->size;
|
||||
if (IS_I830(ring->dev))
|
||||
if (IS_I830(ring->dev) || IS_845G(ring->dev))
|
||||
ring->effective_size -= 128;
|
||||
|
||||
return 0;
|
||||
|
@ -95,7 +95,6 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb,
|
||||
/* must disable */
|
||||
sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
|
||||
sprctl |= SPRITE_ENABLE;
|
||||
sprctl |= SPRITE_DEST_KEY;
|
||||
|
||||
/* Sizes are 0 based */
|
||||
src_w--;
|
||||
|
Loading…
Reference in New Issue
Block a user