From: Matthijs van Duin matthijsvanduin@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) {