Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 210192
b: refs/heads/master
c: 4e5359c
h: refs/heads/master
v: v3
  • Loading branch information
Simon Farnsworth authored and Chris Wilson committed Sep 7, 2010
1 parent 22caefc commit 4e7ea1b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8e647a279ca30029f19eca646de08a6338eab924
refs/heads/master: 4e5359cd053bfb7d8dabe4a63624a5726848ffbc
50 changes: 50 additions & 0 deletions trunk/drivers/gpu/drm/i915/i915_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/slab.h>
#include "drmP.h"
#include "drm.h"
#include "intel_drv.h"
#include "i915_drm.h"
#include "i915_drv.h"

Expand Down Expand Up @@ -121,6 +122,54 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
return 0;
}

static int i915_gem_pageflip_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
unsigned long flags;
struct intel_crtc *crtc;

list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
const char *pipe = crtc->pipe ? "B" : "A";
const char *plane = crtc->plane ? "B" : "A";
struct intel_unpin_work *work;

spin_lock_irqsave(&dev->event_lock, flags);
work = crtc->unpin_work;
if (work == NULL) {
seq_printf(m, "No flip due on pipe %s (plane %s)\n",
pipe, plane);
} else {
if (!work->pending) {
seq_printf(m, "Flip queued on pipe %s (plane %s)\n",
pipe, plane);
} else {
seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n",
pipe, plane);
}
if (work->enable_stall_check)
seq_printf(m, "Stall check enabled, ");
else
seq_printf(m, "Stall check waiting for page flip ioctl, ");
seq_printf(m, "%d prepares\n", work->pending);

if (work->old_fb_obj) {
struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj);
if(obj_priv)
seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset );
}
if (work->pending_flip_obj) {
struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj);
if(obj_priv)
seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset );
}
}
spin_unlock_irqrestore(&dev->event_lock, flags);
}

return 0;
}

static int i915_gem_request_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
Expand Down Expand Up @@ -777,6 +826,7 @@ static struct drm_info_list i915_debugfs_list[] = {
{"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST},
{"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST},
{"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST},
{"i915_gem_pageflip", i915_gem_pageflip_info, 0},
{"i915_gem_request", i915_gem_request_info, 0},
{"i915_gem_seqno", i915_gem_seqno_info, 0},
{"i915_gem_fence_regs", i915_gem_fence_regs_info, 0},
Expand Down
51 changes: 49 additions & 2 deletions trunk/drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,49 @@ static void i915_handle_error(struct drm_device *dev, bool wedged)
queue_work(dev_priv->wq, &dev_priv->error_work);
}

static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_gem_object *obj_priv;
struct intel_unpin_work *work;
unsigned long flags;
bool stall_detected;

/* Ignore early vblank irqs */
if (intel_crtc == NULL)
return;

spin_lock_irqsave(&dev->event_lock, flags);
work = intel_crtc->unpin_work;

if (work == NULL || work->pending || !work->enable_stall_check) {
/* Either the pending flip IRQ arrived, or we're too early. Don't check */
spin_unlock_irqrestore(&dev->event_lock, flags);
return;
}

/* Potential stall - if we see that the flip has happened, assume a missed interrupt */
obj_priv = to_intel_bo(work->pending_flip_obj);
if(IS_I965G(dev)) {
int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF;
stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset;
} else {
int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR;
stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset +
crtc->y * crtc->fb->pitch +
crtc->x * crtc->fb->bits_per_pixel/8);
}

spin_unlock_irqrestore(&dev->event_lock, flags);

if (stall_detected) {
DRM_DEBUG_DRIVER("Pageflip stall detected\n");
intel_prepare_page_flip(dev, intel_crtc->plane);
}
}

irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
Expand Down Expand Up @@ -1004,15 +1047,19 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
if (pipea_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 0);
if (!dev_priv->flip_pending_is_done)
if (!dev_priv->flip_pending_is_done) {
i915_pageflip_stall_check(dev, 0);
intel_finish_page_flip(dev, 0);
}
}

if (pipeb_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 1);
if (!dev_priv->flip_pending_is_done)
if (!dev_priv->flip_pending_is_done) {
i915_pageflip_stall_check(dev, 1);
intel_finish_page_flip(dev, 1);
}
}

if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
Expand Down
14 changes: 4 additions & 10 deletions trunk/drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -4864,15 +4864,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
kfree(intel_crtc);
}

struct intel_unpin_work {
struct work_struct work;
struct drm_device *dev;
struct drm_gem_object *old_fb_obj;
struct drm_gem_object *pending_flip_obj;
struct drm_pending_vblank_event *event;
int pending;
};

static void intel_unpin_work_fn(struct work_struct *__work)
{
struct intel_unpin_work *work =
Expand Down Expand Up @@ -4960,7 +4951,8 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)

spin_lock_irqsave(&dev->event_lock, flags);
if (intel_crtc->unpin_work) {
intel_crtc->unpin_work->pending = 1;
if ((++intel_crtc->unpin_work->pending) > 1)
DRM_ERROR("Prepared flip multiple times\n");
} else {
DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
}
Expand Down Expand Up @@ -5044,6 +5036,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
ADVANCE_LP_RING();
}

work->enable_stall_check = true;

/* Offset into the new buffer for cases of shared fbs between CRTCs */
offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;

Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@ struct intel_crtc {
#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)

struct intel_unpin_work {
struct work_struct work;
struct drm_device *dev;
struct drm_gem_object *old_fb_obj;
struct drm_gem_object *pending_flip_obj;
struct drm_pending_vblank_event *event;
int pending;
bool enable_stall_check;
};

struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
const char *name);
void intel_i2c_destroy(struct i2c_adapter *adapter);
Expand Down

0 comments on commit 4e7ea1b

Please sign in to comment.