aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_display.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-07-22 11:55:54 +1000
committerBen Skeggs <bskeggs@redhat.com>2012-10-03 13:12:55 +1000
commitf589be88caf32501a734e531180d5df5d6089ef3 (patch)
treec6653b5d6aa47aade8abc79c0bb73462f82eef01 /drivers/gpu/drm/nouveau/nouveau_display.c
parentbc9e7b9a61e9e92ddb58920cb2cb5c2e2825ca8a (diff)
drm/nouveau/pageflip: kick flip handling out of engsw and into fence
This is all very much a policy thing, and hence will not belong in SW after the rework. engsw now only handles receiving the event to say "can flip now" and makes a callback to perform the actual work. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 44835c46495..e0a56b27788 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -435,7 +435,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_page_flip_state *s,
struct nouveau_fence **pfence)
{
- struct nouveau_software_chan *swch = chan->engctx[NVOBJ_ENGINE_SW];
+ struct nouveau_fence_chan *fctx = chan->fence;
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct drm_device *dev = chan->dev;
unsigned long flags;
@@ -443,7 +443,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
/* Queue it to the pending list */
spin_lock_irqsave(&dev->event_lock, flags);
- list_add_tail(&s->head, &swch->flip);
+ list_add_tail(&s->head, &fctx->flip);
spin_unlock_irqrestore(&dev->event_lock, flags);
/* Synchronize with the old framebuffer */
@@ -553,20 +553,20 @@ int
nouveau_finish_page_flip(struct nouveau_channel *chan,
struct nouveau_page_flip_state *ps)
{
- struct nouveau_software_chan *swch = chan->engctx[NVOBJ_ENGINE_SW];
+ struct nouveau_fence_chan *fctx = chan->fence;
struct drm_device *dev = chan->dev;
struct nouveau_page_flip_state *s;
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
- if (list_empty(&swch->flip)) {
+ if (list_empty(&fctx->flip)) {
NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id);
spin_unlock_irqrestore(&dev->event_lock, flags);
return -EINVAL;
}
- s = list_first_entry(&swch->flip, struct nouveau_page_flip_state, head);
+ s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
if (s->event) {
struct drm_pending_vblank_event *e = s->event;
struct timeval now;
@@ -589,6 +589,25 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
}
int
+nouveau_flip_complete(void *data)
+{
+ struct nouveau_channel *chan = data;
+ struct drm_device *dev = chan->dev;
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct nouveau_page_flip_state state;
+
+ if (!nouveau_finish_page_flip(chan, &state)) {
+ if (dev_priv->card_type < NV_50) {
+ nv_set_crtc_base(dev, state.crtc, state.offset +
+ state.y * state.pitch +
+ state.x * state.bpp / 8);
+ }
+ }
+
+ return 0;
+}
+
+int
nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
struct drm_mode_create_dumb *args)
{