[Letux-kernel] [small team RFC v3 07/10] XXX omapdrm: allocate fbdev in TILER

H. Nikolaus Schaller hns at goldelico.com
Mon Feb 5 17:21:02 CET 2018


From: Matthijs van Duin <matthijsvanduin at gmail.com>

For now I'm just forcing its actual width to the container width (8192
pixels).  It's a giant waste of RAM, but it makes the buffer physically
contiguous which ensures easy compatibility with existing fbdev code and
hassle-free mapping into kernel memory.
---
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 21 ++++++++++++++++++---
 drivers/gpu/drm/omapdrm/omap_gem.c   | 16 +++++++++++++---
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 9273118040b7..b181c7e89560 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -118,10 +118,10 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
 
 	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;
 
+#if 0
 	mode_cmd.pitches[0] =
 			DIV_ROUND_UP(mode_cmd.width * sizes->surface_bpp, 8);
 
@@ -137,6 +137,21 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
 	};
 	DBG("allocating %d bytes for fb %d", gsize.bytes, dev->primary->index);
 	fbdev->bo = omap_gem_new(dev, gsize, OMAP_BO_SCANOUT | OMAP_BO_WC);
+#else
+	// XXX needs implementation fix, so disable for now.
+	fbdev->ywrap_enabled = false;
+
+	gsize = (union omap_gem_size){
+		.tiled = {
+			.width = 8192,	// XXX HACK
+			.height = mode_cmd.height,
+		}
+	};
+	fbdev->bo = omap_gem_new(dev, gsize, OMAP_BO_TILED_32 | OMAP_BO_WC);
+
+	mode_cmd.pitches[0] = PAGE_ALIGN(
+			DIV_ROUND_UP(gsize.tiled.width * sizes->surface_bpp, 8));
+#endif
 	if (!fbdev->bo) {
 		dev_err(dev->dev, "failed to allocate buffer object\n");
 		ret = -ENOMEM;
@@ -194,9 +209,9 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
 	dev->mode_config.fb_base = dma_addr;
 
 	fbi->screen_base = omap_gem_vaddr(fbdev->bo);
-	fbi->screen_size = fbdev->bo->size;
+	fbi->screen_size = fb->pitches[0] * sizes->surface_height;
 	fbi->fix.smem_start = dma_addr;
-	fbi->fix.smem_len = fbdev->bo->size;
+	fbi->fix.smem_len = fbi->screen_size;
 
 	/* if we have DMM, then we can use it for scrolling by just
 	 * shuffling pages around in DMM rather than doing sw blit.
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index 670845b19e49..4ef2db367a04 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1020,16 +1020,24 @@ int omap_gem_put_pages(struct drm_gem_object *obj)
 void *omap_gem_vaddr(struct drm_gem_object *obj)
 {
 	struct omap_gem_object *omap_obj = to_omap_bo(obj);
+	void *va = omap_obj->vaddr;
 	WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
-	if (!omap_obj->vaddr) {
+	if (va)
+		return va;
+	if (omap_obj->flags & OMAP_BO_TILED) {
+		// FIXME to avoid contiguous mapping?
+		va = ioremap(omap_obj->dma_addr, obj->size);
+	} else {
 		struct page **pages;
 		int ret = get_pages(obj, &pages);
 		if (ret)
 			return ERR_PTR(ret);
-		omap_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT,
+		va = vmap(pages, obj->size >> PAGE_SHIFT,
 				VM_MAP, pgprot_writecombine(PAGE_KERNEL));
 	}
-	return omap_obj->vaddr;
+	if (!IS_ERR(va))
+		omap_obj->vaddr = va;
+	return va;
 }
 #endif
 
@@ -1151,6 +1159,8 @@ void omap_gem_free_object(struct drm_gem_object *obj)
 	if (omap_obj->flags & OMAP_BO_MEM_DMA_API) {
 		dma_free_wc(dev->dev, obj->size, omap_obj->vaddr,
 			    omap_obj->dma_addr);
+	} else if (omap_obj->flags & OMAP_BO_TILED) {
+		iounmap(omap_obj->vaddr);
 	} else if (omap_obj->vaddr) {
 		vunmap(omap_obj->vaddr);
 	} else if (obj->import_attach) {
-- 
2.12.2



More information about the Letux-kernel mailing list