summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nv50_crtc.c
diff options
context:
space:
mode:
authorChris Ball <cjb@laptop.org>2010-09-26 06:47:24 -0500
committerDave Airlie <airlied@redhat.com>2010-10-06 11:50:21 +1000
commitbe64c2bb4731b0e6223a496eed615b816ac879ec (patch)
tree1c2723d354e47167aa3b59d01c011efec9acdb6e /drivers/gpu/drm/nouveau/nv50_crtc.c
parent4dd19b0dd79c2bfe04a7a19bea0caf9284695cb4 (diff)
drm/nouveau/kms: Implement KDB debug hooks for nouveau KMS.
Tested on nv50 and nv04 HW. Signed-off-by: Chris Ball <cjb@laptop.org> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> CC: Jesse Barnes <jbarnes@virtuousgeek.org> CC: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_crtc.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index bfd4ca2fe7ef..f41b44864e80 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -491,8 +491,9 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
}
static int
-nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
- struct drm_framebuffer *old_fb, bool update)
+nv50_crtc_do_mode_set_base(struct drm_crtc *crtc,
+ struct drm_framebuffer *passed_fb,
+ int x, int y, bool update, bool atomic)
{
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct drm_device *dev = nv_crtc->base.dev;
@@ -504,6 +505,28 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index);
+ /* If atomic, we want to switch to the fb we were passed, so
+ * now we update pointers to do that. (We don't pin; just
+ * assume we're already pinned and update the base address.)
+ */
+ if (atomic) {
+ drm_fb = passed_fb;
+ fb = nouveau_framebuffer(passed_fb);
+ }
+ else {
+ /* If not atomic, we can go ahead and pin, and unpin the
+ * old fb we were passed.
+ */
+ ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
+ if (ret)
+ return ret;
+
+ if (passed_fb) {
+ struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
+ nouveau_bo_unpin(ofb->nvbo);
+ }
+ }
+
switch (drm_fb->depth) {
case 8:
format = NV50_EVO_CRTC_FB_DEPTH_8;
@@ -526,15 +549,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y,
return -EINVAL;
}
- ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
- if (ret)
- return ret;
-
- if (old_fb) {
- struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb);
- nouveau_bo_unpin(ofb->nvbo);
- }
-
nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base;
nv_crtc->fb.tile_flags = fb->nvbo->tile_flags;
nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8;
@@ -685,14 +699,22 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false);
nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false);
- return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false);
+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false, false);
}
static int
nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
struct drm_framebuffer *old_fb)
{
- return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true);
+ return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, true, false);
+}
+
+static int
+nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ int x, int y)
+{
+ return nv50_crtc_do_mode_set_base(crtc, fb, x, y, true, true);
}
static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
@@ -702,6 +724,7 @@ static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = {
.mode_fixup = nv50_crtc_mode_fixup,
.mode_set = nv50_crtc_mode_set,
.mode_set_base = nv50_crtc_mode_set_base,
+ .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic,
.load_lut = nv50_crtc_lut_load,
};