Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+41 −0
Original line number Diff line number Diff line
@@ -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;
}
+7 −28
Original line number Diff line number Diff line
@@ -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;
	pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
	fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
			sizes->surface_height, pitch, format);

	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)) {
		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;
	}