diff options
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_crtc.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_crtc.c | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 119 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_display.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 50 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 13 | ||||
-rw-r--r-- | include/drm/drm_crtc_helper.h | 3 |
11 files changed, 265 insertions, 73 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 6a5e403f9aa1..625a2d551d6a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -263,7 +263,8 @@ int drm_fb_helper_debug_enter(struct fb_info *info) | |||
263 | funcs->mode_set_base_atomic(mode_set->crtc, | 263 | funcs->mode_set_base_atomic(mode_set->crtc, |
264 | mode_set->fb, | 264 | mode_set->fb, |
265 | mode_set->x, | 265 | mode_set->x, |
266 | mode_set->y); | 266 | mode_set->y, |
267 | 1); | ||
267 | 268 | ||
268 | } | 269 | } |
269 | } | 270 | } |
@@ -309,7 +310,7 @@ int drm_fb_helper_debug_leave(struct fb_info *info) | |||
309 | } | 310 | } |
310 | 311 | ||
311 | funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x, | 312 | funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x, |
312 | crtc->y); | 313 | crtc->y, 0); |
313 | } | 314 | } |
314 | 315 | ||
315 | return 0; | 316 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 69c54c5a4254..9109c00f3ead 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1492,7 +1492,7 @@ err_unpin: | |||
1492 | /* Assume fb object is pinned & idle & fenced and just update base pointers */ | 1492 | /* Assume fb object is pinned & idle & fenced and just update base pointers */ |
1493 | static int | 1493 | static int |
1494 | intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 1494 | intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
1495 | int x, int y) | 1495 | int x, int y, int enter) |
1496 | { | 1496 | { |
1497 | struct drm_device *dev = crtc->dev; | 1497 | struct drm_device *dev = crtc->dev; |
1498 | struct drm_i915_private *dev_priv = dev->dev_private; | 1498 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -1614,7 +1614,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1614 | atomic_read(&obj_priv->pending_flip) == 0); | 1614 | atomic_read(&obj_priv->pending_flip) == 0); |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); | 1617 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, 0); |
1618 | if (ret) { | 1618 | if (ret) { |
1619 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | 1619 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); |
1620 | mutex_unlock(&dev->struct_mutex); | 1620 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index d2047713dc59..c5afd146aeb2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -104,6 +104,8 @@ static struct fb_ops nouveau_fbcon_ops = { | |||
104 | .fb_pan_display = drm_fb_helper_pan_display, | 104 | .fb_pan_display = drm_fb_helper_pan_display, |
105 | .fb_blank = drm_fb_helper_blank, | 105 | .fb_blank = drm_fb_helper_blank, |
106 | .fb_setcmap = drm_fb_helper_setcmap, | 106 | .fb_setcmap = drm_fb_helper_setcmap, |
107 | .fb_debug_enter = drm_fb_helper_debug_enter, | ||
108 | .fb_debug_leave = drm_fb_helper_debug_leave, | ||
107 | }; | 109 | }; |
108 | 110 | ||
109 | static struct fb_ops nv04_fbcon_ops = { | 111 | static struct fb_ops nv04_fbcon_ops = { |
@@ -117,6 +119,8 @@ static struct fb_ops nv04_fbcon_ops = { | |||
117 | .fb_pan_display = drm_fb_helper_pan_display, | 119 | .fb_pan_display = drm_fb_helper_pan_display, |
118 | .fb_blank = drm_fb_helper_blank, | 120 | .fb_blank = drm_fb_helper_blank, |
119 | .fb_setcmap = drm_fb_helper_setcmap, | 121 | .fb_setcmap = drm_fb_helper_setcmap, |
122 | .fb_debug_enter = drm_fb_helper_debug_enter, | ||
123 | .fb_debug_leave = drm_fb_helper_debug_leave, | ||
120 | }; | 124 | }; |
121 | 125 | ||
122 | static struct fb_ops nv50_fbcon_ops = { | 126 | static struct fb_ops nv50_fbcon_ops = { |
@@ -130,6 +134,8 @@ static struct fb_ops nv50_fbcon_ops = { | |||
130 | .fb_pan_display = drm_fb_helper_pan_display, | 134 | .fb_pan_display = drm_fb_helper_pan_display, |
131 | .fb_blank = drm_fb_helper_blank, | 135 | .fb_blank = drm_fb_helper_blank, |
132 | .fb_setcmap = drm_fb_helper_setcmap, | 136 | .fb_setcmap = drm_fb_helper_setcmap, |
137 | .fb_debug_enter = drm_fb_helper_debug_enter, | ||
138 | .fb_debug_leave = drm_fb_helper_debug_leave, | ||
133 | }; | 139 | }; |
134 | 140 | ||
135 | static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | 141 | static void nouveau_fbcon_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
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 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 3f2fb4ec63ab..ba91befd3734 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -487,8 +487,9 @@ nv50_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
487 | } | 487 | } |
488 | 488 | ||
489 | static int | 489 | static int |
490 | nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, | 490 | nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, |
491 | struct drm_framebuffer *old_fb, bool update) | 491 | struct drm_framebuffer *passed_fb, |
492 | int x, int y, bool update, bool atomic) | ||
492 | { | 493 | { |
493 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 494 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
494 | struct drm_device *dev = nv_crtc->base.dev; | 495 | struct drm_device *dev = nv_crtc->base.dev; |
@@ -500,6 +501,28 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
500 | 501 | ||
501 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); | 502 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
502 | 503 | ||
504 | /* If atomic, we want to switch to the fb we were passed, so | ||
505 | * now we update pointers to do that. (We don't pin; just | ||
506 | * assume we're already pinned and update the base address.) | ||
507 | */ | ||
508 | if (atomic) { | ||
509 | drm_fb = passed_fb; | ||
510 | fb = nouveau_framebuffer(passed_fb); | ||
511 | } | ||
512 | else { | ||
513 | /* If not atomic, we can go ahead and pin, and unpin the | ||
514 | * old fb we were passed. | ||
515 | */ | ||
516 | ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); | ||
517 | if (ret) | ||
518 | return ret; | ||
519 | |||
520 | if (passed_fb) { | ||
521 | struct nouveau_framebuffer *ofb = nouveau_framebuffer(passed_fb); | ||
522 | nouveau_bo_unpin(ofb->nvbo); | ||
523 | } | ||
524 | } | ||
525 | |||
503 | switch (drm_fb->depth) { | 526 | switch (drm_fb->depth) { |
504 | case 8: | 527 | case 8: |
505 | format = NV50_EVO_CRTC_FB_DEPTH_8; | 528 | format = NV50_EVO_CRTC_FB_DEPTH_8; |
@@ -522,15 +545,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
522 | return -EINVAL; | 545 | return -EINVAL; |
523 | } | 546 | } |
524 | 547 | ||
525 | ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM); | ||
526 | if (ret) | ||
527 | return ret; | ||
528 | |||
529 | if (old_fb) { | ||
530 | struct nouveau_framebuffer *ofb = nouveau_framebuffer(old_fb); | ||
531 | nouveau_bo_unpin(ofb->nvbo); | ||
532 | } | ||
533 | |||
534 | nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; | 548 | nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; |
535 | nv_crtc->fb.tile_flags = fb->nvbo->tile_flags; | 549 | nv_crtc->fb.tile_flags = fb->nvbo->tile_flags; |
536 | nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; | 550 | nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; |
@@ -681,14 +695,22 @@ nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
681 | nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false); | 695 | nv_crtc->set_dither(nv_crtc, nv_connector->use_dithering, false); |
682 | nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false); | 696 | nv_crtc->set_scale(nv_crtc, nv_connector->scaling_mode, false); |
683 | 697 | ||
684 | return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, false); | 698 | return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, false, false); |
685 | } | 699 | } |
686 | 700 | ||
687 | static int | 701 | static int |
688 | nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | 702 | nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, |
689 | struct drm_framebuffer *old_fb) | 703 | struct drm_framebuffer *old_fb) |
690 | { | 704 | { |
691 | return nv50_crtc_do_mode_set_base(crtc, x, y, old_fb, true); | 705 | return nv50_crtc_do_mode_set_base(crtc, old_fb, x, y, true, false); |
706 | } | ||
707 | |||
708 | static int | ||
709 | nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc, | ||
710 | struct drm_framebuffer *fb, | ||
711 | int x, int y, int enter) | ||
712 | { | ||
713 | return nv50_crtc_do_mode_set_base(crtc, fb, x, y, true, true); | ||
692 | } | 714 | } |
693 | 715 | ||
694 | static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { | 716 | static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { |
@@ -698,6 +720,7 @@ static const struct drm_crtc_helper_funcs nv50_crtc_helper_funcs = { | |||
698 | .mode_fixup = nv50_crtc_mode_fixup, | 720 | .mode_fixup = nv50_crtc_mode_fixup, |
699 | .mode_set = nv50_crtc_mode_set, | 721 | .mode_set = nv50_crtc_mode_set, |
700 | .mode_set_base = nv50_crtc_mode_set_base, | 722 | .mode_set_base = nv50_crtc_mode_set_base, |
723 | .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic, | ||
701 | .load_lut = nv50_crtc_lut_load, | 724 | .load_lut = nv50_crtc_lut_load, |
702 | }; | 725 | }; |
703 | 726 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index cd0290f946cf..501e5286ec3f 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -854,13 +854,15 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
854 | 854 | ||
855 | } | 855 | } |
856 | 856 | ||
857 | static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 857 | static int evergreen_crtc_do_set_base(struct drm_crtc *crtc, |
858 | struct drm_framebuffer *old_fb) | 858 | struct drm_framebuffer *fb, |
859 | int x, int y, int atomic) | ||
859 | { | 860 | { |
860 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 861 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
861 | struct drm_device *dev = crtc->dev; | 862 | struct drm_device *dev = crtc->dev; |
862 | struct radeon_device *rdev = dev->dev_private; | 863 | struct radeon_device *rdev = dev->dev_private; |
863 | struct radeon_framebuffer *radeon_fb; | 864 | struct radeon_framebuffer *radeon_fb; |
865 | struct drm_framebuffer *target_fb; | ||
864 | struct drm_gem_object *obj; | 866 | struct drm_gem_object *obj; |
865 | struct radeon_bo *rbo; | 867 | struct radeon_bo *rbo; |
866 | uint64_t fb_location; | 868 | uint64_t fb_location; |
@@ -868,28 +870,43 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
868 | int r; | 870 | int r; |
869 | 871 | ||
870 | /* no fb bound */ | 872 | /* no fb bound */ |
871 | if (!crtc->fb) { | 873 | if (!atomic && !crtc->fb) { |
872 | DRM_DEBUG_KMS("No FB bound\n"); | 874 | DRM_DEBUG_KMS("No FB bound\n"); |
873 | return 0; | 875 | return 0; |
874 | } | 876 | } |
875 | 877 | ||
876 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 878 | if (atomic) { |
879 | radeon_fb = to_radeon_framebuffer(fb); | ||
880 | target_fb = fb; | ||
881 | } | ||
882 | else { | ||
883 | radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
884 | target_fb = crtc->fb; | ||
885 | } | ||
877 | 886 | ||
878 | /* Pin framebuffer & get tilling informations */ | 887 | /* If atomic, assume fb object is pinned & idle & fenced and |
888 | * just update base pointers | ||
889 | */ | ||
879 | obj = radeon_fb->obj; | 890 | obj = radeon_fb->obj; |
880 | rbo = obj->driver_private; | 891 | rbo = obj->driver_private; |
881 | r = radeon_bo_reserve(rbo, false); | 892 | r = radeon_bo_reserve(rbo, false); |
882 | if (unlikely(r != 0)) | 893 | if (unlikely(r != 0)) |
883 | return r; | 894 | return r; |
884 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | 895 | |
885 | if (unlikely(r != 0)) { | 896 | if (atomic) |
886 | radeon_bo_unreserve(rbo); | 897 | fb_location = radeon_bo_gpu_offset(rbo); |
887 | return -EINVAL; | 898 | else { |
899 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | ||
900 | if (unlikely(r != 0)) { | ||
901 | radeon_bo_unreserve(rbo); | ||
902 | return -EINVAL; | ||
903 | } | ||
888 | } | 904 | } |
905 | |||
889 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | 906 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); |
890 | radeon_bo_unreserve(rbo); | 907 | radeon_bo_unreserve(rbo); |
891 | 908 | ||
892 | switch (crtc->fb->bits_per_pixel) { | 909 | switch (target_fb->bits_per_pixel) { |
893 | case 8: | 910 | case 8: |
894 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | | 911 | fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_8BPP) | |
895 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); | 912 | EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_INDEXED)); |
@@ -909,7 +926,7 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
909 | break; | 926 | break; |
910 | default: | 927 | default: |
911 | DRM_ERROR("Unsupported screen depth %d\n", | 928 | DRM_ERROR("Unsupported screen depth %d\n", |
912 | crtc->fb->bits_per_pixel); | 929 | target_fb->bits_per_pixel); |
913 | return -EINVAL; | 930 | return -EINVAL; |
914 | } | 931 | } |
915 | 932 | ||
@@ -955,10 +972,10 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
955 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 972 | WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
956 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); | 973 | WREG32(EVERGREEN_GRPH_X_START + radeon_crtc->crtc_offset, 0); |
957 | WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); | 974 | WREG32(EVERGREEN_GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
958 | WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); | 975 | WREG32(EVERGREEN_GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
959 | WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); | 976 | WREG32(EVERGREEN_GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
960 | 977 | ||
961 | fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); | 978 | fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
962 | WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); | 979 | WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
963 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 980 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
964 | 981 | ||
@@ -977,8 +994,8 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
977 | else | 994 | else |
978 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | 995 | WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
979 | 996 | ||
980 | if (old_fb && old_fb != crtc->fb) { | 997 | if (!atomic && fb && fb != crtc->fb) { |
981 | radeon_fb = to_radeon_framebuffer(old_fb); | 998 | radeon_fb = to_radeon_framebuffer(fb); |
982 | rbo = radeon_fb->obj->driver_private; | 999 | rbo = radeon_fb->obj->driver_private; |
983 | r = radeon_bo_reserve(rbo, false); | 1000 | r = radeon_bo_reserve(rbo, false); |
984 | if (unlikely(r != 0)) | 1001 | if (unlikely(r != 0)) |
@@ -993,8 +1010,9 @@ static int evergreen_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
993 | return 0; | 1010 | return 0; |
994 | } | 1011 | } |
995 | 1012 | ||
996 | static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 1013 | static int avivo_crtc_do_set_base(struct drm_crtc *crtc, |
997 | struct drm_framebuffer *old_fb) | 1014 | struct drm_framebuffer *fb, |
1015 | int x, int y, int atomic) | ||
998 | { | 1016 | { |
999 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1017 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1000 | struct drm_device *dev = crtc->dev; | 1018 | struct drm_device *dev = crtc->dev; |
@@ -1002,33 +1020,48 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1002 | struct radeon_framebuffer *radeon_fb; | 1020 | struct radeon_framebuffer *radeon_fb; |
1003 | struct drm_gem_object *obj; | 1021 | struct drm_gem_object *obj; |
1004 | struct radeon_bo *rbo; | 1022 | struct radeon_bo *rbo; |
1023 | struct drm_framebuffer *target_fb; | ||
1005 | uint64_t fb_location; | 1024 | uint64_t fb_location; |
1006 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; | 1025 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
1007 | int r; | 1026 | int r; |
1008 | 1027 | ||
1009 | /* no fb bound */ | 1028 | /* no fb bound */ |
1010 | if (!crtc->fb) { | 1029 | if (!atomic && !crtc->fb) { |
1011 | DRM_DEBUG_KMS("No FB bound\n"); | 1030 | DRM_DEBUG_KMS("No FB bound\n"); |
1012 | return 0; | 1031 | return 0; |
1013 | } | 1032 | } |
1014 | 1033 | ||
1015 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 1034 | if (atomic) { |
1035 | radeon_fb = to_radeon_framebuffer(fb); | ||
1036 | target_fb = fb; | ||
1037 | } | ||
1038 | else { | ||
1039 | radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
1040 | target_fb = crtc->fb; | ||
1041 | } | ||
1016 | 1042 | ||
1017 | /* Pin framebuffer & get tilling informations */ | ||
1018 | obj = radeon_fb->obj; | 1043 | obj = radeon_fb->obj; |
1019 | rbo = obj->driver_private; | 1044 | rbo = obj->driver_private; |
1020 | r = radeon_bo_reserve(rbo, false); | 1045 | r = radeon_bo_reserve(rbo, false); |
1021 | if (unlikely(r != 0)) | 1046 | if (unlikely(r != 0)) |
1022 | return r; | 1047 | return r; |
1023 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | 1048 | |
1024 | if (unlikely(r != 0)) { | 1049 | /* If atomic, assume fb object is pinned & idle & fenced and |
1025 | radeon_bo_unreserve(rbo); | 1050 | * just update base pointers |
1026 | return -EINVAL; | 1051 | */ |
1052 | if (atomic) | ||
1053 | fb_location = radeon_bo_gpu_offset(rbo); | ||
1054 | else { | ||
1055 | r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location); | ||
1056 | if (unlikely(r != 0)) { | ||
1057 | radeon_bo_unreserve(rbo); | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1027 | } | 1060 | } |
1028 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); | 1061 | radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); |
1029 | radeon_bo_unreserve(rbo); | 1062 | radeon_bo_unreserve(rbo); |
1030 | 1063 | ||
1031 | switch (crtc->fb->bits_per_pixel) { | 1064 | switch (target_fb->bits_per_pixel) { |
1032 | case 8: | 1065 | case 8: |
1033 | fb_format = | 1066 | fb_format = |
1034 | AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | | 1067 | AVIVO_D1GRPH_CONTROL_DEPTH_8BPP | |
@@ -1052,7 +1085,7 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1052 | break; | 1085 | break; |
1053 | default: | 1086 | default: |
1054 | DRM_ERROR("Unsupported screen depth %d\n", | 1087 | DRM_ERROR("Unsupported screen depth %d\n", |
1055 | crtc->fb->bits_per_pixel); | 1088 | target_fb->bits_per_pixel); |
1056 | return -EINVAL; | 1089 | return -EINVAL; |
1057 | } | 1090 | } |
1058 | 1091 | ||
@@ -1093,10 +1126,10 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1093 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); | 1126 | WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0); |
1094 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); | 1127 | WREG32(AVIVO_D1GRPH_X_START + radeon_crtc->crtc_offset, 0); |
1095 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); | 1128 | WREG32(AVIVO_D1GRPH_Y_START + radeon_crtc->crtc_offset, 0); |
1096 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, crtc->fb->width); | 1129 | WREG32(AVIVO_D1GRPH_X_END + radeon_crtc->crtc_offset, target_fb->width); |
1097 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, crtc->fb->height); | 1130 | WREG32(AVIVO_D1GRPH_Y_END + radeon_crtc->crtc_offset, target_fb->height); |
1098 | 1131 | ||
1099 | fb_pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); | 1132 | fb_pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
1100 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); | 1133 | WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels); |
1101 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 1134 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
1102 | 1135 | ||
@@ -1115,8 +1148,8 @@ static int avivo_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1115 | else | 1148 | else |
1116 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); | 1149 | WREG32(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, 0); |
1117 | 1150 | ||
1118 | if (old_fb && old_fb != crtc->fb) { | 1151 | if (!atomic && fb && fb != crtc->fb) { |
1119 | radeon_fb = to_radeon_framebuffer(old_fb); | 1152 | radeon_fb = to_radeon_framebuffer(fb); |
1120 | rbo = radeon_fb->obj->driver_private; | 1153 | rbo = radeon_fb->obj->driver_private; |
1121 | r = radeon_bo_reserve(rbo, false); | 1154 | r = radeon_bo_reserve(rbo, false); |
1122 | if (unlikely(r != 0)) | 1155 | if (unlikely(r != 0)) |
@@ -1138,11 +1171,26 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
1138 | struct radeon_device *rdev = dev->dev_private; | 1171 | struct radeon_device *rdev = dev->dev_private; |
1139 | 1172 | ||
1140 | if (ASIC_IS_DCE4(rdev)) | 1173 | if (ASIC_IS_DCE4(rdev)) |
1141 | return evergreen_crtc_set_base(crtc, x, y, old_fb); | 1174 | return evergreen_crtc_do_set_base(crtc, old_fb, x, y, 0); |
1175 | else if (ASIC_IS_AVIVO(rdev)) | ||
1176 | return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0); | ||
1177 | else | ||
1178 | return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0); | ||
1179 | } | ||
1180 | |||
1181 | int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, | ||
1182 | struct drm_framebuffer *fb, | ||
1183 | int x, int y, int enter) | ||
1184 | { | ||
1185 | struct drm_device *dev = crtc->dev; | ||
1186 | struct radeon_device *rdev = dev->dev_private; | ||
1187 | |||
1188 | if (ASIC_IS_DCE4(rdev)) | ||
1189 | return evergreen_crtc_do_set_base(crtc, fb, x, y, 1); | ||
1142 | else if (ASIC_IS_AVIVO(rdev)) | 1190 | else if (ASIC_IS_AVIVO(rdev)) |
1143 | return avivo_crtc_set_base(crtc, x, y, old_fb); | 1191 | return avivo_crtc_do_set_base(crtc, fb, x, y, 1); |
1144 | else | 1192 | else |
1145 | return radeon_crtc_set_base(crtc, x, y, old_fb); | 1193 | return radeon_crtc_do_set_base(crtc, fb, x, y, 1); |
1146 | } | 1194 | } |
1147 | 1195 | ||
1148 | /* properly set additional regs when using atombios */ | 1196 | /* properly set additional regs when using atombios */ |
@@ -1311,6 +1359,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | |||
1311 | .mode_fixup = atombios_crtc_mode_fixup, | 1359 | .mode_fixup = atombios_crtc_mode_fixup, |
1312 | .mode_set = atombios_crtc_mode_set, | 1360 | .mode_set = atombios_crtc_mode_set, |
1313 | .mode_set_base = atombios_crtc_set_base, | 1361 | .mode_set_base = atombios_crtc_set_base, |
1362 | .mode_set_base_atomic = atombios_crtc_set_base_atomic, | ||
1314 | .prepare = atombios_crtc_prepare, | 1363 | .prepare = atombios_crtc_prepare, |
1315 | .commit = atombios_crtc_commit, | 1364 | .commit = atombios_crtc_commit, |
1316 | .load_lut = radeon_crtc_load_lut, | 1365 | .load_lut = radeon_crtc_load_lut, |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index b92d2f2fcbed..26935cf2c3b3 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -138,6 +138,38 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc) | |||
138 | legacy_crtc_load_lut(crtc); | 138 | legacy_crtc_load_lut(crtc); |
139 | } | 139 | } |
140 | 140 | ||
141 | void radeon_crtc_save_lut(struct drm_crtc *crtc) | ||
142 | { | ||
143 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
144 | int i; | ||
145 | |||
146 | if (!crtc->enabled) | ||
147 | return; | ||
148 | |||
149 | for (i = 0; i < 256; i++) { | ||
150 | radeon_crtc->lut_r_copy[i] = radeon_crtc->lut_r[i]; | ||
151 | radeon_crtc->lut_g_copy[i] = radeon_crtc->lut_g[i]; | ||
152 | radeon_crtc->lut_b_copy[i] = radeon_crtc->lut_b[i]; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | void radeon_crtc_restore_lut(struct drm_crtc *crtc) | ||
157 | { | ||
158 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
159 | int i; | ||
160 | |||
161 | if (!crtc->enabled) | ||
162 | return; | ||
163 | |||
164 | for (i = 0; i < 256; i++) { | ||
165 | radeon_crtc->lut_r[i] = radeon_crtc->lut_r_copy[i]; | ||
166 | radeon_crtc->lut_g[i] = radeon_crtc->lut_g_copy[i]; | ||
167 | radeon_crtc->lut_b[i] = radeon_crtc->lut_b_copy[i]; | ||
168 | } | ||
169 | |||
170 | radeon_crtc_load_lut(crtc); | ||
171 | } | ||
172 | |||
141 | /** Sets the color ramps on behalf of fbcon */ | 173 | /** Sets the color ramps on behalf of fbcon */ |
142 | void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | 174 | void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, |
143 | u16 blue, int regno) | 175 | u16 blue, int regno) |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 9cdf6a35bc2c..bc61c5adb56d 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -59,6 +59,8 @@ static struct fb_ops radeonfb_ops = { | |||
59 | .fb_pan_display = drm_fb_helper_pan_display, | 59 | .fb_pan_display = drm_fb_helper_pan_display, |
60 | .fb_blank = drm_fb_helper_blank, | 60 | .fb_blank = drm_fb_helper_blank, |
61 | .fb_setcmap = drm_fb_helper_setcmap, | 61 | .fb_setcmap = drm_fb_helper_setcmap, |
62 | .fb_debug_enter = drm_fb_helper_debug_enter, | ||
63 | .fb_debug_leave = drm_fb_helper_debug_leave, | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | 66 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 305049afde15..42954785247f 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -348,10 +348,30 @@ void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
348 | int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 348 | int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
349 | struct drm_framebuffer *old_fb) | 349 | struct drm_framebuffer *old_fb) |
350 | { | 350 | { |
351 | return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0); | ||
352 | } | ||
353 | |||
354 | int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, | ||
355 | struct drm_framebuffer *fb, | ||
356 | int x, int y, int enter) | ||
357 | { | ||
358 | if (enter) | ||
359 | radeon_crtc_save_lut(crtc); | ||
360 | else | ||
361 | radeon_crtc_restore_lut(crtc); | ||
362 | |||
363 | return radeon_crtc_do_set_base(crtc, fb, x, y, 1); | ||
364 | } | ||
365 | |||
366 | int radeon_crtc_do_set_base(struct drm_crtc *crtc, | ||
367 | struct drm_framebuffer *fb, | ||
368 | int x, int y, int atomic) | ||
369 | { | ||
351 | struct drm_device *dev = crtc->dev; | 370 | struct drm_device *dev = crtc->dev; |
352 | struct radeon_device *rdev = dev->dev_private; | 371 | struct radeon_device *rdev = dev->dev_private; |
353 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 372 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
354 | struct radeon_framebuffer *radeon_fb; | 373 | struct radeon_framebuffer *radeon_fb; |
374 | struct drm_framebuffer *target_fb; | ||
355 | struct drm_gem_object *obj; | 375 | struct drm_gem_object *obj; |
356 | struct radeon_bo *rbo; | 376 | struct radeon_bo *rbo; |
357 | uint64_t base; | 377 | uint64_t base; |
@@ -364,14 +384,21 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
364 | 384 | ||
365 | DRM_DEBUG_KMS("\n"); | 385 | DRM_DEBUG_KMS("\n"); |
366 | /* no fb bound */ | 386 | /* no fb bound */ |
367 | if (!crtc->fb) { | 387 | if (!atomic && !crtc->fb) { |
368 | DRM_DEBUG_KMS("No FB bound\n"); | 388 | DRM_DEBUG_KMS("No FB bound\n"); |
369 | return 0; | 389 | return 0; |
370 | } | 390 | } |
371 | 391 | ||
372 | radeon_fb = to_radeon_framebuffer(crtc->fb); | 392 | if (atomic) { |
393 | radeon_fb = to_radeon_framebuffer(fb); | ||
394 | target_fb = fb; | ||
395 | } | ||
396 | else { | ||
397 | radeon_fb = to_radeon_framebuffer(crtc->fb); | ||
398 | target_fb = crtc->fb; | ||
399 | } | ||
373 | 400 | ||
374 | switch (crtc->fb->bits_per_pixel) { | 401 | switch (target_fb->bits_per_pixel) { |
375 | case 8: | 402 | case 8: |
376 | format = 2; | 403 | format = 2; |
377 | break; | 404 | break; |
@@ -415,10 +442,10 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
415 | 442 | ||
416 | crtc_offset_cntl = 0; | 443 | crtc_offset_cntl = 0; |
417 | 444 | ||
418 | pitch_pixels = crtc->fb->pitch / (crtc->fb->bits_per_pixel / 8); | 445 | pitch_pixels = target_fb->pitch / (target_fb->bits_per_pixel / 8); |
419 | crtc_pitch = (((pitch_pixels * crtc->fb->bits_per_pixel) + | 446 | crtc_pitch = (((pitch_pixels * target_fb->bits_per_pixel) + |
420 | ((crtc->fb->bits_per_pixel * 8) - 1)) / | 447 | ((target_fb->bits_per_pixel * 8) - 1)) / |
421 | (crtc->fb->bits_per_pixel * 8)); | 448 | (target_fb->bits_per_pixel * 8)); |
422 | crtc_pitch |= crtc_pitch << 16; | 449 | crtc_pitch |= crtc_pitch << 16; |
423 | 450 | ||
424 | 451 | ||
@@ -443,14 +470,14 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
443 | crtc_tile_x0_y0 = x | (y << 16); | 470 | crtc_tile_x0_y0 = x | (y << 16); |
444 | base &= ~0x7ff; | 471 | base &= ~0x7ff; |
445 | } else { | 472 | } else { |
446 | int byteshift = crtc->fb->bits_per_pixel >> 4; | 473 | int byteshift = target_fb->bits_per_pixel >> 4; |
447 | int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11; | 474 | int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11; |
448 | base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); | 475 | base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); |
449 | crtc_offset_cntl |= (y % 16); | 476 | crtc_offset_cntl |= (y % 16); |
450 | } | 477 | } |
451 | } else { | 478 | } else { |
452 | int offset = y * pitch_pixels + x; | 479 | int offset = y * pitch_pixels + x; |
453 | switch (crtc->fb->bits_per_pixel) { | 480 | switch (target_fb->bits_per_pixel) { |
454 | case 8: | 481 | case 8: |
455 | offset *= 1; | 482 | offset *= 1; |
456 | break; | 483 | break; |
@@ -496,8 +523,8 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | |||
496 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); | 523 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset); |
497 | WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); | 524 | WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch); |
498 | 525 | ||
499 | if (old_fb && old_fb != crtc->fb) { | 526 | if (!atomic && fb && fb != crtc->fb) { |
500 | radeon_fb = to_radeon_framebuffer(old_fb); | 527 | radeon_fb = to_radeon_framebuffer(fb); |
501 | rbo = radeon_fb->obj->driver_private; | 528 | rbo = radeon_fb->obj->driver_private; |
502 | r = radeon_bo_reserve(rbo, false); | 529 | r = radeon_bo_reserve(rbo, false); |
503 | if (unlikely(r != 0)) | 530 | if (unlikely(r != 0)) |
@@ -1040,6 +1067,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | |||
1040 | .mode_fixup = radeon_crtc_mode_fixup, | 1067 | .mode_fixup = radeon_crtc_mode_fixup, |
1041 | .mode_set = radeon_crtc_mode_set, | 1068 | .mode_set = radeon_crtc_mode_set, |
1042 | .mode_set_base = radeon_crtc_set_base, | 1069 | .mode_set_base = radeon_crtc_set_base, |
1070 | .mode_set_base_atomic = radeon_crtc_set_base_atomic, | ||
1043 | .prepare = radeon_crtc_prepare, | 1071 | .prepare = radeon_crtc_prepare, |
1044 | .commit = radeon_crtc_commit, | 1072 | .commit = radeon_crtc_commit, |
1045 | .load_lut = radeon_crtc_load_lut, | 1073 | .load_lut = radeon_crtc_load_lut, |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 17a6602b5885..2f78615f02aa 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -267,6 +267,7 @@ struct radeon_crtc { | |||
267 | struct drm_crtc base; | 267 | struct drm_crtc base; |
268 | int crtc_id; | 268 | int crtc_id; |
269 | u16 lut_r[256], lut_g[256], lut_b[256]; | 269 | u16 lut_r[256], lut_g[256], lut_b[256]; |
270 | u16 lut_r_copy[256], lut_g_copy[256], lut_b_copy[256]; | ||
270 | bool enabled; | 271 | bool enabled; |
271 | bool can_tile; | 272 | bool can_tile; |
272 | uint32_t crtc_offset; | 273 | uint32_t crtc_offset; |
@@ -512,8 +513,13 @@ extern int atombios_get_encoder_mode(struct drm_encoder *encoder); | |||
512 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); | 513 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); |
513 | 514 | ||
514 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); | 515 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); |
516 | extern void radeon_crtc_save_lut(struct drm_crtc *crtc); | ||
517 | extern void radeon_crtc_restore_lut(struct drm_crtc *crtc); | ||
515 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 518 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
516 | struct drm_framebuffer *old_fb); | 519 | struct drm_framebuffer *old_fb); |
520 | extern int atombios_crtc_set_base_atomic(struct drm_crtc *crtc, | ||
521 | struct drm_framebuffer *fb, | ||
522 | int x, int y, int enter); | ||
517 | extern int atombios_crtc_mode_set(struct drm_crtc *crtc, | 523 | extern int atombios_crtc_mode_set(struct drm_crtc *crtc, |
518 | struct drm_display_mode *mode, | 524 | struct drm_display_mode *mode, |
519 | struct drm_display_mode *adjusted_mode, | 525 | struct drm_display_mode *adjusted_mode, |
@@ -523,7 +529,12 @@ extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode); | |||
523 | 529 | ||
524 | extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 530 | extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
525 | struct drm_framebuffer *old_fb); | 531 | struct drm_framebuffer *old_fb); |
526 | 532 | extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc, | |
533 | struct drm_framebuffer *fb, | ||
534 | int x, int y, int enter); | ||
535 | extern int radeon_crtc_do_set_base(struct drm_crtc *crtc, | ||
536 | struct drm_framebuffer *fb, | ||
537 | int x, int y, int atomic); | ||
527 | extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, | 538 | extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, |
528 | struct drm_file *file_priv, | 539 | struct drm_file *file_priv, |
529 | uint32_t handle, | 540 | uint32_t handle, |
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 59b7073b13fe..6a9f3935ea0b 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h | |||
@@ -61,7 +61,8 @@ struct drm_crtc_helper_funcs { | |||
61 | int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, | 61 | int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, |
62 | struct drm_framebuffer *old_fb); | 62 | struct drm_framebuffer *old_fb); |
63 | int (*mode_set_base_atomic)(struct drm_crtc *crtc, | 63 | int (*mode_set_base_atomic)(struct drm_crtc *crtc, |
64 | struct drm_framebuffer *fb, int x, int y); | 64 | struct drm_framebuffer *fb, int x, int y, |
65 | int is_enter); | ||
65 | 66 | ||
66 | /* reload the current crtc LUT */ | 67 | /* reload the current crtc LUT */ |
67 | void (*load_lut)(struct drm_crtc *crtc); | 68 | void (*load_lut)(struct drm_crtc *crtc); |