drm/msm: add helper to allocate stolen fb
authorRob Clark <robdclark@gmail.com>
Tue, 11 Jul 2017 14:40:13 +0000 (10:40 -0400)
committerRob Clark <robdclark@gmail.com>
Tue, 22 Aug 2017 17:20:39 +0000 (13:20 -0400)
We'll later want to re-use this for state-readback when bootloader
enables display, so that we can create an fb for the initial
plane->state->fb.

Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/msm_drv.h
drivers/gpu/drm/msm/msm_fb.c
drivers/gpu/drm/msm/msm_fbdev.c

index 1b627f2aab8d44bd30fd49eb0145c00eea90d7a1..db137f3e7decce8b81ada895b735e13fb9edc7a7 100644 (file)
@@ -256,6 +256,8 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
                const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
 struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
                struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
+struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
+               int w, int h, int p, uint32_t format);
 
 struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
 void msm_fbdev_free(struct drm_device *dev);
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 @@ fail:
 
        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;
+}
index 53dc3ee41177991c0c46960e9d532734fcc130d3..5dc0ae3089354f3451b8bb91d1108aa91c3159cf 100644 (file)
@@ -19,7 +19,6 @@
 #include <drm/drm_fb_helper.h>
 
 #include "msm_drv.h"
-#include "msm_gem.h"
 #include "msm_kms.h"
 
 extern int msm_gem_mmap_obj(struct drm_gem_object *obj,
@@ -77,42 +76,22 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
        struct drm_framebuffer *fb = NULL;
        struct drm_gem_object *bo;
        struct fb_info *fbi = NULL;
-       struct drm_mode_fb_cmd2 mode_cmd = {0};
        uint64_t paddr;
-       int ret, size;
+       uint32_t format;
+       int ret, pitch;
+
+       format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
 
        DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
                        sizes->surface_height, sizes->surface_bpp,
                        sizes->fb_width, sizes->fb_height);
 
-       mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
-                       sizes->surface_depth);
-
-       mode_cmd.width = sizes->surface_width;
-       mode_cmd.height = sizes->surface_height;
-
-       mode_cmd.pitches[0] = align_pitch(
-                       mode_cmd.width, sizes->surface_bpp);
-
-       /* 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)) {
-               ret = PTR_ERR(bo);
-               bo = NULL;
-               dev_err(dev->dev, "failed to allocate buffer object: %d\n", ret);
-               goto fail;
-       }
+       pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
+       fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
+                       sizes->surface_height, pitch, format);
 
-       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);
                ret = PTR_ERR(fb);
                goto fail;
        }