[PATCH 3/3] XilinxFB: Allow fixed framebuffer base address

Grant Likely grant.likely at secretlab.ca
Thu Oct 11 04:31:56 EST 2007


From: Grant Likely <grant.likely at secretlab.ca>

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 at secretlab.ca>
---

 drivers/video/xilinxfb.c |   22 ++++++++++++++++------
 include/linux/xilinxfb.h |    5 +++++
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index c617412..6ef99b2 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 199a1ee..f2463f5 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__ */




More information about the Linuxppc-dev mailing list