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

Commit 9886eb59 authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman
Browse files

gma500: allow non stolen page backed framebuffer



For Moorestown at least we may not have stolen RAM with which to back the
initial framebuffer. Allow a GEM backing.

At this point we should have all the bits in place needed to make it work once
it has been debugged.

Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 541c81ab
Loading
Loading
Loading
Loading
+40 −3
Original line number Diff line number Diff line
@@ -335,6 +335,38 @@ static struct drm_framebuffer *psb_framebuffer_create
	return NULL;
}

/**
 *	psbfb_alloc		-	allocate frame buffer memory
 *	@dev: the DRM device
 *	@aligned_size: space needed
 *
 *	Allocate the frame buffer. In the usual case we get a GTT range that
 *	is stolen memory backed and life is simple. If there isn't sufficient
 *	stolen memory or the system has no stolen memory we allocate a range
 *	and back it with a GEM object.
 *
 *	In this case the GEM object has no handle. 
 */
static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
{
	struct gtt_range *backing;
	/* Begin by trying to use stolen memory backing */
	backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
	if (backing)
		return backing;
	/* Next try using GEM host memory */
	backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0);
	if (backing == NULL)
		return NULL;

	/* Now back it with an object */
	if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) {
		psb_gtt_free_range(dev, backing);
		return NULL;
	}
	return backing;
}
	
/**
 *	psbfb_create		-	create a framebuffer
 *	@fbdev: the framebuffer device
@@ -368,7 +400,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
	aligned_size = ALIGN(size, PAGE_SIZE);

	/* Allocate the framebuffer in the GTT with stolen page backing */
	backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
	backing = psbfb_alloc(dev, aligned_size);
	if (backing == NULL)
	        return -ENOMEM;

@@ -523,7 +555,13 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)

	if (fbdev->psb_fb_helper.fbdev) {
		info = fbdev->psb_fb_helper.fbdev;
		/* FIXME: this is a bit more inside knowledge than I'd like
		   but I don't see how to make a fake GEM object of the
		   stolen space nicely */
		if (psbfb->gtt->stolen)
			psb_gtt_free_range(dev, psbfb->gtt);
		else
			drm_gem_object_unreference(&psbfb->gtt->gem);
		unregister_framebuffer(info);
		iounmap(info->screen_base);
		framebuffer_release(info);
@@ -571,7 +609,6 @@ void psb_fbdev_fini(struct drm_device *dev)
	dev_priv->fbdev = NULL;
}


static void psbfb_output_poll_changed(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
+2 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ int psb_gem_init_object(struct drm_gem_object *obj)

void psb_gem_free_object(struct drm_gem_object *obj)
{
	struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
	psb_gtt_free_range(obj->dev, gtt);
	drm_gem_object_release(obj);
}

+0 −1
Original line number Diff line number Diff line
@@ -298,7 +298,6 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
	return NULL;
}


static void psb_gtt_destroy(struct kref *kref)
{
	struct gtt_range *gt = container_of(kref, struct gtt_range, kref);
+23 −13
Original line number Diff line number Diff line
@@ -361,7 +361,13 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
	if (!gma_power_begin(dev, true))
		return 0;

	/* We are displaying this buffer, make sure it is actually loaded
	   into the GTT */
	ret = psb_gtt_pin(dev, psbfb->gtt);
	if (ret < 0)
		goto psb_intel_pipe_set_base_exit;
	start = psbfb->gtt->offset;

	offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);

	REG_WRITE(dspstride, crtc->fb->pitch);
@@ -386,10 +392,12 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
	default:
		DRM_ERROR("Unknown color depth\n");
		ret = -EINVAL;
		psb_gtt_unpin(dev, psbfb->gtt);
		goto psb_intel_pipe_set_base_exit;
	}
	REG_WRITE(dspcntr_reg, dspcntr);


	DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
	if (0 /* FIXMEAC - check what PSB needs */) {
		REG_WRITE(dspbase, offset);
@@ -401,10 +409,12 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
		REG_READ(dspbase);
	}

psb_intel_pipe_set_base_exit:
	/* If there was a previous display we can now unpin it */
	if (old_fb)
		psb_gtt_unpin(dev, to_psb_fb(old_fb)->gtt);

psb_intel_pipe_set_base_exit:
	gma_power_end(dev);

	return ret;
}