]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/radeon/radeon_display.c
drm/radeon/kms: compute GPU addresses correctly on evergreen
[karo-tx-linux.git] / drivers / gpu / drm / radeon / radeon_display.c
index 5515f1054b29331324bdc15c2b27d4ea6c82fe0a..b25bb2a55814456ba9c47ced12998ca1935d89f5 100644 (file)
@@ -303,8 +303,17 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
        if (update_pending &&
            (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id,
                                                               &vpos, &hpos)) &&
-           (vpos >=0) &&
-           (vpos < (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100)) {
+           ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) ||
+            (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) {
+               /* crtc didn't flip in this target vblank interval,
+                * but flip is pending in crtc. Based on the current
+                * scanout position we know that the current frame is
+                * (nearly) complete and the flip will (likely)
+                * complete before the start of the next frame.
+                */
+               update_pending = 0;
+       }
+       if (update_pending) {
                /* crtc didn't flip in this target vblank interval,
                 * but flip is pending in crtc. It will complete it
                 * in next vblank interval, so complete the flip at
@@ -1078,15 +1087,21 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = {
        .create_handle = radeon_user_framebuffer_create_handle,
 };
 
-void
+int
 radeon_framebuffer_init(struct drm_device *dev,
                        struct radeon_framebuffer *rfb,
                        struct drm_mode_fb_cmd2 *mode_cmd,
                        struct drm_gem_object *obj)
 {
+       int ret;
        rfb->obj = obj;
-       drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
+       ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs);
+       if (ret) {
+               rfb->obj = NULL;
+               return ret;
+       }
        drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd);
+       return 0;
 }
 
 static struct drm_framebuffer *
@@ -1096,6 +1111,7 @@ radeon_user_framebuffer_create(struct drm_device *dev,
 {
        struct drm_gem_object *obj;
        struct radeon_framebuffer *radeon_fb;
+       int ret;
 
        obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]);
        if (obj ==  NULL) {
@@ -1108,7 +1124,12 @@ radeon_user_framebuffer_create(struct drm_device *dev,
        if (radeon_fb == NULL)
                return ERR_PTR(-ENOMEM);
 
-       radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
+       ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj);
+       if (ret) {
+               kfree(radeon_fb);
+               drm_gem_object_unreference_unlocked(obj);
+               return NULL;
+       }
 
        return &radeon_fb->base;
 }
@@ -1240,6 +1261,9 @@ int radeon_modeset_init(struct radeon_device *rdev)
                rdev->ddev->mode_config.max_height = 4096;
        }
 
+       rdev->ddev->mode_config.preferred_depth = 24;
+       rdev->ddev->mode_config.prefer_shadow = 1;
+
        rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
 
        ret = radeon_modeset_create_props(rdev);