diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv04_crtc.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_crtc.c | 55 |
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 | ||
37 | static int | 38 | static int |
38 | nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | 39 | nv04_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 | ||
771 | static int | 772 | static int |
772 | nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | 773 | nv04_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 | ||
853 | static int | ||
854 | nv04_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 | |||
860 | static int | ||
861 | nv04_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 | |||
838 | static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src, | 876 | static 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 | ||