X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fvideo%2Fxilinxfb.c;h=7b3a8423f485e340afffb81d6f0dbc4c933eec83;hb=a217656cb26c5b7ebe9900354b2e808c1f74b470;hp=dec602c2307553f85b2faf00825877fecdaf35d3;hpb=8087ebd5a121ac6bf5a8eba2459c01d3659c3e31;p=linux-2.6-omap-h63xx.git diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index dec602c2307..7b3a8423f48 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -70,12 +70,6 @@ */ #define BYTES_PER_PIXEL 4 #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) -#define XRES 640 -#define YRES 480 -#define XRES_VIRTUAL 1024 -#define YRES_VIRTUAL YRES -#define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL) -#define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH) #define RED_SHIFT 16 #define GREEN_SHIFT 8 @@ -83,6 +77,16 @@ #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */ +/* + * Default xilinxfb configuration + */ +static struct xilinxfb_platform_data xilinx_fb_default_pdata = { + .xres = 640, + .yres = 480, + .xvirt = 1024, + .yvirt = 480, +}; + /* * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures */ @@ -90,17 +94,10 @@ static struct fb_fix_screeninfo xilinx_fb_fix = { .id = "Xilinx", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, - .smem_len = FB_SIZE, - .line_length = LINE_LENGTH, .accel = FB_ACCEL_NONE }; static struct fb_var_screeninfo xilinx_fb_var = { - .xres = XRES, - .yres = YRES, - .xres_virtual = XRES_VIRTUAL, - .yres_virtual = YRES_VIRTUAL, - .bits_per_pixel = BITS_PER_PIXEL, .red = { RED_SHIFT, 8, 0 }, @@ -120,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; @@ -207,10 +205,11 @@ static struct fb_ops xilinxfb_ops = */ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, - int width_mm, int height_mm, int rotate) + struct xilinxfb_platform_data *pdata) { struct xilinxfb_drvdata *drvdata; int rc; + int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; /* Allocate the driver data region */ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); @@ -237,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(FB_SIZE), - &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; @@ -246,14 +252,14 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, } /* Clear (turn to black) the framebuffer */ - memset_io((void __iomem *)drvdata->fb_virt, 0, FB_SIZE); + memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); /* Tell the hardware where the frame buffer is */ xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); /* Turn on the display */ drvdata->reg_ctrl_default = REG_CTRL_ENABLE; - if (rotate) + if (pdata->rotate_screen) drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); @@ -263,12 +269,18 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, drvdata->info.fbops = &xilinxfb_ops; drvdata->info.fix = xilinx_fb_fix; drvdata->info.fix.smem_start = drvdata->fb_phys; + drvdata->info.fix.smem_len = fbsize; + drvdata->info.fix.line_length = pdata->xvirt * BYTES_PER_PIXEL; + drvdata->info.pseudo_palette = drvdata->pseudo_palette; drvdata->info.flags = FBINFO_DEFAULT; drvdata->info.var = xilinx_fb_var; - - xilinx_fb_var.height = height_mm; - xilinx_fb_var.width = width_mm; + drvdata->info.var.height = pdata->screen_height_mm; + drvdata->info.var.width = pdata->screen_width_mm; + drvdata->info.var.xres = pdata->xres; + drvdata->info.var.yres = pdata->yres; + drvdata->info.var.xres_virtual = pdata->xvirt; + drvdata->info.var.yres_virtual = pdata->yvirt; /* Allocate a colour map */ rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); @@ -288,15 +300,17 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, /* Put a banner in the log (for DEBUG) */ dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", - (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); + (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize); + return 0; /* success */ err_regfb: fb_dealloc_cmap(&drvdata->info.cmap); err_cmap: - dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), 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); @@ -325,8 +339,9 @@ static int xilinxfb_release(struct device *dev) fb_dealloc_cmap(&drvdata->info.cmap); - dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), 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); @@ -349,9 +364,6 @@ xilinxfb_platform_probe(struct platform_device *pdev) { struct xilinxfb_platform_data *pdata; struct resource *res; - int width_mm = 0; - int height_mm = 0; - int rotate = 0; /* Find the registers address */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -361,15 +373,20 @@ xilinxfb_platform_probe(struct platform_device *pdev) } /* If a pdata structure is provided, then extract the parameters */ - pdata = pdev->dev.platform_data; - if (pdata) { - height_mm = pdata->screen_height_mm; - width_mm = pdata->screen_width_mm; - rotate = pdata->rotate_screen ? 1 : 0; + pdata = &xilinx_fb_default_pdata; + if (pdev->dev.platform_data) { + pdata = pdev->dev.platform_data; + if (!pdata->xres) + pdata->xres = xilinx_fb_default_pdata.xres; + if (!pdata->yres) + pdata->yres = xilinx_fb_default_pdata.yres; + if (!pdata->xvirt) + pdata->xvirt = xilinx_fb_default_pdata.xvirt; + if (!pdata->yvirt) + pdata->yvirt = xilinx_fb_default_pdata.yvirt; } - return xilinxfb_assign(&pdev->dev, res->start, width_mm, height_mm, - rotate); + return xilinxfb_assign(&pdev->dev, res->start, pdata); } static int @@ -398,9 +415,12 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) { struct resource res; const u32 *prop; - int width = 0, height = 0, rotate = 0; + struct xilinxfb_platform_data pdata; int size, rc; + /* Copy with the default pdata (not a ptr reference!) */ + pdata = xilinx_fb_default_pdata; + dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); rc = of_address_to_resource(op->node, 0, &res); @@ -409,16 +429,28 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) return rc; } - prop = of_get_property(op->node, "display-number", &size); + prop = of_get_property(op->node, "phys-size", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + pdata.screen_width_mm = prop[0]; + pdata.screen_height_mm = prop[1]; + } + + prop = of_get_property(op->node, "resolution", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + pdata.xres = prop[0]; + pdata.yres = prop[1]; + } + + prop = of_get_property(op->node, "virtual-resolution", &size); if ((prop) && (size >= sizeof(u32)*2)) { - width = prop[0]; - height = prop[1]; + pdata.xvirt = prop[0]; + pdata.yvirt = prop[1]; } if (of_find_property(op->node, "rotate-display", NULL)) - rotate = 1; + pdata.rotate_screen = 1; - return xilinxfb_assign(&op->dev, res.start, width, height, rotate); + return xilinxfb_assign(&op->dev, res.start, &pdata); } static int __devexit xilinxfb_of_remove(struct of_device *op) @@ -427,8 +459,8 @@ static int __devexit xilinxfb_of_remove(struct of_device *op) } /* Match table for of_platform binding */ -static struct of_device_id __devinit xilinxfb_of_match[] = { - { .compatible = "xilinx,ml300-fb", }, +static struct of_device_id xilinxfb_of_match[] __devinitdata = { + { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", }, {}, }; MODULE_DEVICE_TABLE(of, xilinxfb_of_match);