Commit 466e5606 authored by Rob Clark's avatar Rob Clark

drm/msm: add helper to allocate stolen fb

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: default avatarRob Clark <robdclark@gmail.com>
parent 38958bab
...@@ -256,6 +256,8 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, ...@@ -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); 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_framebuffer *msm_framebuffer_create(struct drm_device *dev,
struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd); 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); struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
void msm_fbdev_free(struct drm_device *dev); void msm_fbdev_free(struct drm_device *dev);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "msm_drv.h" #include "msm_drv.h"
#include "msm_kms.h" #include "msm_kms.h"
#include "msm_gem.h"
struct msm_framebuffer { struct msm_framebuffer {
struct drm_framebuffer base; struct drm_framebuffer base;
...@@ -237,3 +238,43 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, ...@@ -237,3 +238,43 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
return ERR_PTR(ret); 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;
}
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include "msm_drv.h" #include "msm_drv.h"
#include "msm_gem.h"
#include "msm_kms.h" #include "msm_kms.h"
extern int msm_gem_mmap_obj(struct drm_gem_object *obj, 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, ...@@ -77,42 +76,22 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
struct drm_framebuffer *fb = NULL; struct drm_framebuffer *fb = NULL;
struct drm_gem_object *bo; struct drm_gem_object *bo;
struct fb_info *fbi = NULL; struct fb_info *fbi = NULL;
struct drm_mode_fb_cmd2 mode_cmd = {0};
uint64_t paddr; 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, DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
sizes->surface_height, sizes->surface_bpp, sizes->surface_height, sizes->surface_bpp,
sizes->fb_width, sizes->fb_height); sizes->fb_width, sizes->fb_height);
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
sizes->surface_depth); fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
sizes->surface_height, pitch, format);
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;
}
fb = msm_framebuffer_init(dev, &mode_cmd, &bo);
if (IS_ERR(fb)) { if (IS_ERR(fb)) {
dev_err(dev->dev, "failed to allocate fb\n"); 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); ret = PTR_ERR(fb);
goto fail; goto fail;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment