OMAPFB: use dma_alloc_attrs to allocate memory
[pandora-kernel.git] / drivers / video / omap2 / omapfb / omapfb-main.c
index 70aa47d..fadb1be 100644 (file)
@@ -48,6 +48,7 @@ static int def_rotate;
 static int def_mirror;
 static bool auto_update;
 static unsigned int auto_update_freq;
+static bool def_vram_cache = true;
 module_param(auto_update, bool, 0);
 module_param(auto_update_freq, uint, 0644);
 
@@ -1119,7 +1120,10 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 
        vma->vm_pgoff = off >> PAGE_SHIFT;
        vma->vm_flags |= VM_IO | VM_RESERVED;
-       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+       if (def_vram_cache)
+               vma->vm_page_prot = pgprot_writethrough(vma->vm_page_prot);
+       else
+               vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
        vma->vm_ops = &mmap_user_ops;
        vma->vm_private_data = rg;
        if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
@@ -1183,7 +1187,7 @@ static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,
                        break;
 
                if (regno < 16) {
-                       u16 pal;
+                       u32 pal;
                        pal = ((red >> (16 - var->red.length)) <<
                                        var->red.offset) |
                                ((green >> (16 - var->green.length)) <<
@@ -1326,24 +1330,25 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
 
        rg = ofbi->region;
 
-       WARN_ON(atomic_read(&rg->map_count));
-
-       if (rg->paddr)
-               if (omap_vram_free(rg->paddr, rg->size))
-                       dev_err(fbdev->dev, "VRAM FREE failed\n");
+       if (rg->token == NULL)
+               return;
 
-       if (rg->vaddr)
-               iounmap(rg->vaddr);
+       WARN_ON(atomic_read(&rg->map_count));
 
        if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
                /* unmap the 0 angle rotation */
                if (rg->vrfb.vaddr[0]) {
                        iounmap(rg->vrfb.vaddr[0]);
-                       omap_vrfb_release_ctx(&rg->vrfb);
                        rg->vrfb.vaddr[0] = NULL;
                }
+
+               omap_vrfb_release_ctx(&rg->vrfb);
        }
 
+       dma_free_attrs(fbdev->dev, rg->size, rg->token, rg->dma_handle,
+                       &rg->attrs);
+
+       rg->token = NULL;
        rg->vaddr = NULL;
        rg->paddr = 0;
        rg->alloc = 0;
@@ -1378,7 +1383,9 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
        struct omapfb_info *ofbi = FB2OFB(fbi);
        struct omapfb2_device *fbdev = ofbi->fbdev;
        struct omapfb2_mem_region *rg;
-       void __iomem *vaddr;
+       void *token;
+       DEFINE_DMA_ATTRS(attrs);
+       dma_addr_t dma_handle;
        int r;
 
        rg = ofbi->region;
@@ -1393,42 +1400,43 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
 
        size = PAGE_ALIGN(size);
 
-       if (!paddr) {
-               DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
-               r = omap_vram_alloc(OMAP_VRAM_MEMTYPE_SDRAM, size, &paddr);
-       } else {
-               DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
-                               ofbi->id);
-               r = omap_vram_reserve(paddr, size);
-       }
+       WARN_ONCE(paddr,
+               "reserving memory at predefined address not supported\n");
 
-       if (r) {
+       dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
+
+       if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+               dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
+
+       DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
+
+       token = dma_alloc_attrs(fbdev->dev, size, &dma_handle,
+                       GFP_KERNEL, &attrs);
+
+       if (token == NULL) {
                dev_err(fbdev->dev, "failed to allocate framebuffer\n");
                return -ENOMEM;
        }
 
-       if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) {
-               vaddr = ioremap_wc(paddr, size);
+       DBG("allocated VRAM paddr %lx, vaddr %p\n",
+                       (unsigned long)dma_handle, token);
 
-               if (!vaddr) {
-                       dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
-                       omap_vram_free(paddr, size);
-                       return -ENOMEM;
-               }
-
-               DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
-       } else {
+       if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
                r = omap_vrfb_request_ctx(&rg->vrfb);
                if (r) {
+                       dma_free_attrs(fbdev->dev, size, token, dma_handle,
+                                       &attrs);
                        dev_err(fbdev->dev, "vrfb create ctx failed\n");
                        return r;
                }
-
-               vaddr = NULL;
        }
 
-       rg->paddr = paddr;
-       rg->vaddr = vaddr;
+       rg->attrs = attrs;
+       rg->token = token;
+       rg->dma_handle = dma_handle;
+
+       rg->paddr = (unsigned long)dma_handle;
+       rg->vaddr = (void __iomem *)token;
        rg->size = size;
        rg->alloc = 1;
 
@@ -2584,6 +2592,7 @@ module_param_named(vram, def_vram, charp, 0);
 module_param_named(rotate, def_rotate, int, 0);
 module_param_named(vrfb, def_vrfb, bool, 0);
 module_param_named(mirror, def_mirror, bool, 0);
+module_param_named(vram_cache, def_vram_cache, bool, 0644);
 
 /* late_initcall to let panel/ctrl drivers loaded first.
  * I guess better option would be a more dynamic approach,