Commit 5f4a46d3 authored by Russell King's avatar Russell King

[ARM] Convert ARM video drivers to use (ARM extended) DMA API.

parent 9bacd63e
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -1254,6 +1256,11 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end) ...@@ -1254,6 +1256,11 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
printk("acornfb: freed %dK memory\n", mb_freed); printk("acornfb: freed %dK memory\n", mb_freed);
} }
static struct device acornfb_device = {
.bus_id = "acornfb",
.coherent_dma_mask = 0xffffffff,
};
int __init int __init
acornfb_init(void) acornfb_init(void)
{ {
...@@ -1263,6 +1270,8 @@ acornfb_init(void) ...@@ -1263,6 +1270,8 @@ acornfb_init(void)
acornfb_init_fbinfo(); acornfb_init_fbinfo();
current_par.dev = &acornfb_device;
if (current_par.montype == -1) if (current_par.montype == -1)
current_par.montype = acornfb_detect_monitortype(); current_par.montype = acornfb_detect_monitortype();
...@@ -1323,37 +1332,30 @@ acornfb_init(void) ...@@ -1323,37 +1332,30 @@ acornfb_init(void)
#if defined(HAS_VIDC20) #if defined(HAS_VIDC20)
if (!current_par.using_vram) { if (!current_par.using_vram) {
dma_addr_t handle;
void *base;
/* /*
* RiscPC needs to allocate the DRAM memory * RiscPC needs to allocate the DRAM memory
* for the framebuffer if we are not using * for the framebuffer if we are not using
* VRAM. Archimedes/A5000 machines use a * VRAM.
* fixed address for their framebuffers.
*/ */
unsigned long page, top, base; base = dma_alloc_writecombine(current_par.dev, size, &handle,
int order = get_order(size); GFP_KERNEL);
if (base == NULL) {
base = __get_free_pages(GFP_KERNEL, order);
if (base == 0) {
printk(KERN_ERR "acornfb: unable to allocate screen " printk(KERN_ERR "acornfb: unable to allocate screen "
"memory\n"); "memory\n");
return -ENOMEM; return -ENOMEM;
} }
top = base + (PAGE_SIZE << order);
/* Mark the framebuffer pages as reserved so mmap will work. */
for (page = base; page < PAGE_ALIGN(base + size); page += PAGE_SIZE)
SetPageReserved(virt_to_page(page));
/* Hand back any excess pages that we allocated. */
for (page = base + size; page < top; page += PAGE_SIZE)
free_page(page);
fb_info.screen_base = (char *)base; fb_info.screen_base = base;
fb_info.fix.smem_start = virt_to_phys(fb_info.screen_base); fb_info.fix.smem_start = handle;
} }
#endif #endif
#if defined(HAS_VIDC) #if defined(HAS_VIDC)
/* /*
* Free unused pages * Archimedes/A5000 machines use a fixed address for their
* framebuffers. Free unused pages
*/ */
free_unused_pages(PAGE_OFFSET + size, PAGE_OFFSET + MAX_SIZE); free_unused_pages(PAGE_OFFSET + size, PAGE_OFFSET + MAX_SIZE);
#endif #endif
......
...@@ -47,6 +47,7 @@ union palette { ...@@ -47,6 +47,7 @@ union palette {
}; };
struct acornfb_par { struct acornfb_par {
struct device *dev;
unsigned long screen_end; unsigned long screen_end;
unsigned int dram_size; unsigned int dram_size;
unsigned int vram_half_sam; unsigned int vram_half_sam;
......
...@@ -1595,12 +1595,18 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi) ...@@ -1595,12 +1595,18 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
* of the framebuffer. * of the framebuffer.
*/ */
fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE); fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
fbi->map_cpu = consistent_alloc(GFP_KERNEL, fbi->map_size, fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
&fbi->map_dma, PTE_BUFFERABLE); &fbi->map_dma, GFP_KERNEL);
if (fbi->map_cpu) { if (fbi->map_cpu) {
fbi->fb.screen_base = fbi->map_cpu + PAGE_SIZE; fbi->fb.screen_base = fbi->map_cpu + PAGE_SIZE;
fbi->screen_dma = fbi->map_dma + PAGE_SIZE; fbi->screen_dma = fbi->map_dma + PAGE_SIZE;
/*
* FIXME: this is actually the wrong thing to place in
* smem_start. But fbdev suffers from the problem that
* it needs an API which doesn't exist (in this case,
* dma_writecombine_mmap)
*/
fbi->fb.fix.smem_start = fbi->screen_dma; fbi->fb.fix.smem_start = fbi->screen_dma;
} }
...@@ -1613,7 +1619,7 @@ static struct fb_monspecs monspecs __initdata = { ...@@ -1613,7 +1619,7 @@ static struct fb_monspecs monspecs __initdata = {
}; };
static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void) static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
{ {
struct sa1100fb_mach_info *inf; struct sa1100fb_mach_info *inf;
struct sa1100fb_info *fbi; struct sa1100fb_info *fbi;
...@@ -1624,6 +1630,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void) ...@@ -1624,6 +1630,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
return NULL; return NULL;
memset(fbi, 0, sizeof(struct sa1100fb_info)); memset(fbi, 0, sizeof(struct sa1100fb_info));
fbi->dev = dev;
strcpy(fbi->fb.fix.id, SA1100_NAME); strcpy(fbi->fb.fix.id, SA1100_NAME);
...@@ -1703,7 +1710,7 @@ static int __init sa1100fb_probe(struct device *dev) ...@@ -1703,7 +1710,7 @@ static int __init sa1100fb_probe(struct device *dev)
if (!request_mem_region(0xb0100000, 0x10000, "LCD")) if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
return -EBUSY; return -EBUSY;
fbi = sa1100fb_init_fbinfo(); fbi = sa1100fb_init_fbinfo(dev);
ret = -ENOMEM; ret = -ENOMEM;
if (!fbi) if (!fbi)
goto failed; goto failed;
......
...@@ -63,6 +63,7 @@ struct sa1100fb_lcd_reg { ...@@ -63,6 +63,7 @@ struct sa1100fb_lcd_reg {
struct sa1100fb_info { struct sa1100fb_info {
struct fb_info fb; struct fb_info fb;
struct device *dev;
struct sa1100fb_rgb *rgb[NR_RGB]; struct sa1100fb_rgb *rgb[NR_RGB];
u_int max_bpp; u_int max_bpp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment