aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv04_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv04_crtc.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c55
1 files changed, 47 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index ef480281afec..17f7cf0c11a8 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -33,6 +33,7 @@
33#include "nouveau_fb.h" 33#include "nouveau_fb.h"
34#include "nouveau_hw.h" 34#include "nouveau_hw.h"
35#include "nvreg.h" 35#include "nvreg.h"
36#include "nouveau_fbcon.h"
36 37
37static int 38static int
38nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 39nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -769,8 +770,9 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
769} 770}
770 771
771static int 772static int
772nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 773nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
773 struct drm_framebuffer *old_fb) 774 struct drm_framebuffer *passed_fb,
775 int x, int y, bool atomic)
774{ 776{
775 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 777 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
776 struct drm_device *dev = crtc->dev; 778 struct drm_device *dev = crtc->dev;
@@ -781,13 +783,26 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
781 int arb_burst, arb_lwm; 783 int arb_burst, arb_lwm;
782 int ret; 784 int ret;
783 785
784 ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); 786 /* If atomic, we want to switch to the fb we were passed, so
785 if (ret) 787 * now we update pointers to do that. (We don't pin; just
786 return ret; 788 * assume we're already pinned and update the base address.)
789 */
790 if (atomic) {
791 drm_fb = passed_fb;
792 fb = nouveau_framebuffer(passed_fb);
793 }
794 else {
795 /* If not atomic, we can go ahead and pin, and unpin the
796 * old fb we were passed.
797 */
798 ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM);
799 if (ret)
800 return ret;
787 801
788 if (old_fb) { 802 if (passed_fb) {
789 struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb); 803 struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb);
790 nouveau_bo_unpin(ofb->nvbo); 804 nouveau_bo_unpin(ofb->nvbo);
805 }
791 } 806 }
792 807
793 nv_crtc->fb.offset = fb->nvbo->bo.offset; 808 nv_crtc->fb.offset = fb->nvbo->bo.offset;
@@ -835,6 +850,29 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
835 return 0; 850 return 0;
836} 851}
837 852
853static int
854nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
855 struct drm_framebuffer *old_fb)
856{
857 return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
858}
859
860static int
861nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
862 struct drm_framebuffer *fb,
863 int x, int y, int enter)
864{
865 struct drm_nouveau_private *dev_priv = crtc->dev->dev_private;
866 struct drm_device *dev = dev_priv->dev;
867
868 if (enter)
869 nouveau_fbcon_save_disable_accel(dev);
870 else
871 nouveau_fbcon_restore_accel(dev);
872
873 return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true);
874}
875
838static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src, 876static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
839 struct nouveau_bo *dst) 877 struct nouveau_bo *dst)
840{ 878{
@@ -963,6 +1001,7 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = {
963 .mode_fixup = nv_crtc_mode_fixup, 1001 .mode_fixup = nv_crtc_mode_fixup,
964 .mode_set = nv_crtc_mode_set, 1002 .mode_set = nv_crtc_mode_set,
965 .mode_set_base = nv04_crtc_mode_set_base, 1003 .mode_set_base = nv04_crtc_mode_set_base,
1004 .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
966 .load_lut = nv_crtc_gamma_load, 1005 .load_lut = nv_crtc_gamma_load,
967}; 1006};
968 1007