aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2007-10-11 04:31:56 +1000
committerPaul Mackerras <paulus@samba.org>2007-10-12 14:05:17 +1000
commit287e5d6fcccfa38b953cebe307e1ddfd32363355 (patch)
treef06b288f7f2e5a1eecc093ba977141c9035d3534
parentb4d6a7268fc754eefb196cabc0ccfa2e97022af2 (diff)
[POWERPC] XilinxFB: Allow fixed framebuffer base address
Allow a fixed framebuffer address to be assigned to the framebuffer device instead of allocating the framebuffer from the consistent memory pool. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--drivers/video/xilinxfb.c22
-rw-r--r--include/linux/xilinxfb.h5
2 files changed, 21 insertions, 6 deletions
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index c6174125f52..6ef99b2d13c 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -117,6 +117,7 @@ struct xilinxfb_drvdata {
void *fb_virt; /* virt. address of the frame buffer */
dma_addr_t fb_phys; /* phys. address of the frame buffer */
+ int fb_alloced; /* Flag, was the fb memory alloced? */
u32 reg_ctrl_default;
@@ -235,8 +236,15 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
}
/* Allocate the framebuffer memory */
- drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize),
- &drvdata->fb_phys, GFP_KERNEL);
+ if (pdata->fb_phys) {
+ drvdata->fb_phys = pdata->fb_phys;
+ drvdata->fb_virt = ioremap(pdata->fb_phys, fbsize);
+ } else {
+ drvdata->fb_alloced = 1;
+ drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize),
+ &drvdata->fb_phys, GFP_KERNEL);
+ }
+
if (!drvdata->fb_virt) {
dev_err(dev, "Could not allocate frame buffer memory\n");
rc = -ENOMEM;
@@ -300,8 +308,9 @@ err_regfb:
fb_dealloc_cmap(&drvdata->info.cmap);
err_cmap:
- dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt,
- drvdata->fb_phys);
+ if (drvdata->fb_alloced)
+ dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt,
+ drvdata->fb_phys);
/* Turn off the display */
xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
@@ -330,8 +339,9 @@ static int xilinxfb_release(struct device *dev)
fb_dealloc_cmap(&drvdata->info.cmap);
- dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len),
- drvdata->fb_virt, drvdata->fb_phys);
+ if (drvdata->fb_alloced)
+ dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len),
+ drvdata->fb_virt, drvdata->fb_phys);
/* Turn off the display */
xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
diff --git a/include/linux/xilinxfb.h b/include/linux/xilinxfb.h
index 199a1eedf22..f2463f559fb 100644
--- a/include/linux/xilinxfb.h
+++ b/include/linux/xilinxfb.h
@@ -20,6 +20,11 @@ struct xilinxfb_platform_data {
u32 screen_width_mm;
u32 xres, yres; /* resolution of screen in pixels */
u32 xvirt, yvirt; /* resolution of memory buffer */
+
+ /* Physical address of framebuffer memory; If non-zero, driver
+ * will use provided memory address instead of allocating one from
+ * the consistent pool. */
+ u32 fb_phys;
};
#endif /* __XILINXFB_H__ */