]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/msm/msm_fb.c
drm/msm: add helper to allocate stolen fb
[linux.git] / drivers / gpu / drm / msm / msm_fb.c
index 6ecb7b17031631ceb34eca0a5b7a22ee23d7f0a4..c87dd3e321ec6a17c0d1ccd87a61f5dd6ce99e24 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "msm_drv.h"
 #include "msm_kms.h"
+#include "msm_gem.h"
 
 struct msm_framebuffer {
        struct drm_framebuffer base;
@@ -237,3 +238,43 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 
        return ERR_PTR(ret);
 }
+
+struct drm_framebuffer *
+msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format)
+{
+       struct drm_mode_fb_cmd2 mode_cmd = {
+               .pixel_format = format,
+               .width = w,
+               .height = h,
+               .pitches = { p },
+       };
+       struct drm_gem_object *bo;
+       struct drm_framebuffer *fb;
+       int size;
+
+       /* allocate backing bo */
+       size = mode_cmd.pitches[0] * mode_cmd.height;
+       DBG("allocating %d bytes for fb %d", size, dev->primary->index);
+       bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN);
+       if (IS_ERR(bo)) {
+               dev_warn(dev->dev, "could not allocate stolen bo\n");
+               /* try regular bo: */
+               bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
+       }
+       if (IS_ERR(bo)) {
+               dev_err(dev->dev, "failed to allocate buffer object\n");
+               return ERR_CAST(bo);
+       }
+
+       fb = msm_framebuffer_init(dev, &mode_cmd, &bo);
+       if (IS_ERR(fb)) {
+               dev_err(dev->dev, "failed to allocate fb\n");
+               /* note: if fb creation failed, we can't rely on fb destroy
+                * to unref the bo:
+                */
+               drm_gem_object_unreference_unlocked(bo);
+               return ERR_CAST(fb);
+       }
+
+       return fb;
+}