linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Problems using fb_deferred_io with drm_fb_cma_helper
@ 2016-03-23 15:25 Noralf Trønnes
  0 siblings, 0 replies; only message in thread
From: Noralf Trønnes @ 2016-03-23 15:25 UTC (permalink / raw)
  To: linux-fbdev

I'm trying to add deferred io support to 
drivers/gpu/drm/drm_gem_cma_helper.c.
This is a fbdev helper for DRM.

The first problem is that fb_deferred_io_page() requires either a vmalloc
address or a physical address:

         if (is_vmalloc_addr(screen_base + offs))
                 page = vmalloc_to_page(screen_base + offs);
         else
                 page = pfn_to_page((info->fix.smem_start + offs) >> 
PAGE_SHIFT);

However drm_fb_cma_helper allocates memory this way:

         cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size,
                         &cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN);

The name paddr is somewhat misleading here since this is the device address
which isn't always the same as the physical address (Raspberry Pi). Is
there a way to turn the virtual address into a physical one which will work
on all architectures?

I use __va() now, but that is marked as not for use by drivers in
arch/arm/include/asm/memory.h (the same goes for virt_to_phys).

Maybe this is valid for all? page_to_phys(virt_to_page(x))

I have looked at all the users of fb_deferred_io_init() and found only
3 drivers that doesn't use a vmalloc screen buffer:

drivers/gpu/drm/udl/udl_fb.c:
     obj->vmapping = vmap(obj->pages, page_count, 0, PAGE_KERNEL);
         info->screen_base = ufbdev->ufb.obj->vmapping;
         info->fix.smem_start = (unsigned long)ufbdev->ufb.obj->vmapping;
Since it uses vmap() I guess it is_vmalloc_addr().

drivers/video/fbdev/sh_mobile_lcdcfb.c:
         ch->fb_mem = dma_alloc_coherent(dev, ch->fb_size, &ch->dma_handle,
                                         GFP_KERNEL);
         info->screen_base = ch->fb_mem;
         info->fix.smem_start = ch->dma_handle;
It uses dma_mmap_coherent() in it's fb_mmap function, but nothing special
with it's deferred_io use.

drivers/video/fbdev/ssd1307fb.c:
         vmem = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
                                         get_order(vmem_size));
         info->screen_base = (u8 __force __iomem *)vmem;
         info->fix.smem_start = __pa(vmem);

So maybe this could be possible:

  static struct page *fb_deferred_io_page(struct fb_info *info, unsigned 
long offs)
  {
      void *screen_base = (void __force *) info->screen_base;
      struct page *page;

      if (is_vmalloc_addr(screen_base + offs))
          page = vmalloc_to_page(screen_base + offs);
      else
-        page = pfn_to_page((info->fix.smem_start + offs) >> PAGE_SHIFT);
+        page = virt_to_page(screen_base + offs);

      return page;
  }


The second problem I'm facing is that I get short horizontal lines that have
old pixels. My problem goes away if I add this to fb_deferred_io_mmap():

         vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);

Is there a way to add this to fb_deferred_io_mmap() with some kind of if
statement, or perhaps export the function so I can use it like this:

static int drm_fbdev_cma_defio_mmap(struct fb_info *info,
                                     struct vm_area_struct *vma)
{
         fb_deferred_io_mmap(info, vma);
         vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);

         return 0;
}


Thanks,
Noralf Trønnes


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-03-23 15:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-23 15:25 Problems using fb_deferred_io with drm_fb_cma_helper Noralf Trønnes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).