Xilinx framebuffer device driver - 3d version
Subsystems (2)
PATCH 1/1 Xilinx framebuffer device driver - 3d version
Add support for the video controller IP block included into Xilinx ML300 and ML403 reference designs.
-----
The driver has been tested with Xilinx ML300 and ML403 reference designs.
The two first version has been posted to linuxppc-embedded, and this version tries to address all the comments and criticism received.
The platform device registration for Xilinx ML300 and ML403 moved into separate patch (will be posted to linuxppc-embedded in couple minutes).
Would be nice to get this driver into mainline for the 2.6.22. Reviews and comments are welcome.
Thanks,
Andrei
Add support for the video controller IP block included into Xilinx ML300 and ML403 reference designs.
arch/ppc/syslib/virtex_devices.h | 7 drivers/video/Kconfig | 11 + drivers/video/Makefile | 1 drivers/video/xilinxfb.c | 389 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 408 insertions(+)
drivers/video/Kconfig +11 -0
@@ -1633,6 +1633,17 @@ config FB_PS3_DEFAULT_SIZE_M The default value can be overridden on the kernel command line using the "ps3fb" option (e.g. "ps3fb=9M"); +config FB_XILINX + tristate "Xilinx frame buffer support" + depends on FB && XILINX_VIRTEX + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Include support for the Xilinx ML300/ML403 reference design + framebuffer. ML300 carries a 640*480 LCD display on the board, + ML403 uses a standard DB15 VGA connector. + config FB_VIRTUAL tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" depends on FB
drivers/video/Makefile +1 -0
@@ -99,6 +99,7 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o +obj-$(CONFIG_FB_XILINX) += xilinxfb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o
drivers/video/xilinxfb.c new file +389 -0
389 lines not on this page · raw message
arch/ppc/syslib/virtex_devices.h +7 -0
@@ -13,6 +13,13 @@#include <linux/platform_device.h> +/* ML300/403 reference design framebuffer driver platform data struct */ +struct xilinxfb_platform_data { +u32 rotate_screen; +u32 screen_height_mm; +u32 screen_width_mm; +}; +void __init virtex_early_serial_map (void );/* Prototype for device fixup routine. Implement this routine in the
Hello,
Quoted 8 lines · Andrei Konovalov
Add support for the video controller IP block included into Xilinx ML300 and ML403 reference designs.
Signed-off-by Andrei Konovalov <[email protected]>-----
The driver has been tested with Xilinx ML300 and ML403 reference designs.
Quoted 6 lines
The two first version has been posted to linuxppc-embedded, and this version tries to address all the comments and criticism received.
The platform device registration for Xilinx ML300 and ML403 moved into separate patch (will be posted to linuxppc-embedded in couple minutes).
Here is the platform device registration part.
Thanks,
Andrei
arch/ppc/platforms/4xx/xilinx_ml403.c +17 -0
@@ -118,3 +118,20 @@ platform_init(unsigned long r3, unsigned#endif } +static struct xilinxfb_platform_data xilinxfb_ml403_pdata = { + .rotate_screen =0 , + .screen_height_mm =-1 , + .screen_width_mm =-1 , +}; + +int __init virtex_device_fixup (struct platform_device *dev) +{ +if (strcmp (dev->name,"xilinxfb" ) ==0 ) { +if (dev->id !=0 )/* paranoic */ +return 1 ; + dev->dev.platform_data = &xilinxfb_ml403_pdata; +return 0 ; + } +return 0 ; +} +
arch/ppc/platforms/4xx/xilinx_ml300.c +17 -0
@@ -116,3 +116,20 @@ platform_init(unsigned long r3, unsigned#endif } +static struct xilinxfb_platform_data xilinxfb_ml300_pdata = { + .rotate_screen =1 , + .screen_height_mm =99 , + .screen_width_mm =132 , +}; + +int __init virtex_device_fixup (struct platform_device *dev) +{ +if (strcmp (dev->name,"xilinxfb" ) ==0 ) { +if (dev->id !=0 )/* paranoic */ +return 1 ; + dev->dev.platform_data = &xilinxfb_ml300_pdata; +return 0 ; + } +return 0 ; +} +
arch/ppc/syslib/virtex_devices.c +21 -13
@@ -71,7 +71,23 @@ }, \ } +/* +* ML300/ML403 Video Device: shortcut macro for single instance +*/ +#define XPAR_TFT (num) { \ + .name = "xilinxfb", \ + .id = num, \ + .num_resources = 1, \ + .resource = (struct resource[]) { \ + { \ + .start = XPAR_TFT_##num##_BASEADDR, \ + .end = XPAR_TFT_##num##_BASEADDR+7, \ + .flags = IORESOURCE_IO, \ + }, \ + }, \ +} +/* UART 8250 driver platform data table */ struct plat_serial8250_port virtex_serial_platform_data[] = {#if defined(XPAR_UARTNS550_0_BASEADDR )
@@ -146,20 +162,12 @@ struct platform_device virtex_platform_d XPAR_SYSACE(1),#endif -/* ML300/403 reference design framebuffer */ +/* ML300/ML403 reference design framebuffer */ #if defined(XPAR_TFT_0_BASEADDR ) - { - .name = "xilinxfb", - .id = 0, - .num_resources = 1, - .resource = (struct resource[]) { - { - .start = XPAR_TFT_0_BASEADDR, - .end = XPAR_TFT_0_BASEADDR+7, - .flags = IORESOURCE_IO, - }, - }, - }, + XPAR_TFT(0), +#endif +#if defined(XPAR_TFT_1_BASEADDR ) + XPAR_TFT(1),#endif };
Quoted 11 lines · Andrei Konovalov
Add support for the video controller IP block included into Xilinx ML300 and ML403 reference designs.
Signed-off-by Andrei Konovalov <[email protected]>-----
The driver has been tested with Xilinx ML300 and ML403 reference designs.The two first version has been posted to linuxppc-embedded, and this version tries to address all the comments and criticism received.
Quoted 6 lines
The platform device registration for Xilinx ML300 and ML403 moved into separate patch (will be posted to linuxppc-embedded in couple minutes).
Would be nice to get this driver into mainline for the 2.6.22. Reviews and comments are welcome.
It's hard to make comments when you submit patches as attachment, but here goes.
+static int
+xilinx_fb_blank(int blank_mode, struct fb_info *fbi) +{
+ struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi);
+
+ switch (blank_mode) {
+ case VESA_NO_BLANKING:
+ /* turn on panel */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+ break;
+
+ case VESA_VSYNC_SUSPEND:
+ case VESA_HSYNC_SUSPEND:
+ case VESA_POWERDOWN:
+ /* turn off panel */
+ xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
+ default:
+ break;
+
+ }
+ return 0; /* success */
+}
+
Use the FB_BLANK_* constants defined in include/linux/fb.h instead of the VESA_* constants.
+static int
+xilinx_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
+{
+ if (var->xoffset != 0 || var->yoffset != 0)
+ return -EINVAL;
+
+ return 0;
+}
+
This silently succeeds. If you don't have a pan_display() hook, might as well remove it.
+static int
+xilinxfb_drv_probe(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct xilinxfb_platform_data *pdata;
+ struct xilinxfb_drvdata *drvdata;
+ struct resource *regs_res;
+ int retval;
+
+ if (!dev)
+ return -EINVAL;
+
+ pdev = to_platform_device(dev);
+ pdata = (struct xilinxfb_platform_data *)pdev->dev.platform_data;
Is the cast really needed?
+
+ if (pdata == NULL) {
+ printk(KERN_ERR "Couldn't find platform data.\n");
+ return -EFAULT;
+ }
+
+ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata) {
+ printk(KERN_ERR "Couldn't allocate device private record\n");
+ return -ENOMEM;
+ }
+ dev_set_drvdata(dev, (void *)drvdata);
Here also.
+
+ /* Map the control registers in */
+ regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) {
+ printk(KERN_ERR "Couldn't get registers resource\n");
+ retval = -EFAULT;
+ goto failed1;
+ }
+
+ if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) {
+ printk(KERN_ERR
+ "Couldn't lock memory region at 0x%08X\n",
+ regs_res->start);
+ retval = -EBUSY;
+ goto failed1;
+ }
+ drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8);
+ drvdata->regs_phys = regs_res->start;
+
+ /* Allocate the framebuffer memory */
+ drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE),
+ &drvdata->fb_phys, GFP_KERNEL);
+ if (!drvdata->fb_virt) {
+ printk(KERN_ERR "Could not allocate frame buffer memory\n");
+ retval = -ENOMEM;
+ goto failed2;
+ }
+
+ /* Clear (turn to black) the framebuffer */
+ memset((void *) drvdata->fb_virt, 0, FB_SIZE);
memset() or memset_io()?
+
+ /* Tell the hardware where the frame buffer is */
+ xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
+
+ /* Turn on the display */
+ if (pdata->rotate_screen) {
+ drvdata->reg_ctrl_default = REG_CTRL_ENABLE | REG_CTRL_ROTATE;
+ } else {
+ drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
+ }
+ xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+
+ /* Fill struct fb_info */
+ drvdata->info.screen_base = drvdata->fb_virt;
+ drvdata->info.fbops = &xilinxfb_ops;
+ drvdata->info.fix = xilinx_fb_fix;
+ drvdata->info.fix.smem_start = drvdata->fb_phys;
+ drvdata->info.pseudo_palette = drvdata->pseudo_palette;
If you cannot use framebuffer_alloc()/release(), set drvdata->info.device so your driver shows up in /sys/class/graphics.
Tony