diff options
-rw-r--r-- | drivers/video/xilinxfb.c | 71 | ||||
-rw-r--r-- | include/linux/xilinxfb.h | 6 |
2 files changed, 49 insertions, 28 deletions
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index b3b57f4a35a2..c6174125f52b 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c | |||
@@ -70,12 +70,6 @@ | |||
70 | */ | 70 | */ |
71 | #define BYTES_PER_PIXEL 4 | 71 | #define BYTES_PER_PIXEL 4 |
72 | #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) | 72 | #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) |
73 | #define XRES 640 | ||
74 | #define YRES 480 | ||
75 | #define XRES_VIRTUAL 1024 | ||
76 | #define YRES_VIRTUAL YRES | ||
77 | #define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL) | ||
78 | #define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH) | ||
79 | 73 | ||
80 | #define RED_SHIFT 16 | 74 | #define RED_SHIFT 16 |
81 | #define GREEN_SHIFT 8 | 75 | #define GREEN_SHIFT 8 |
@@ -87,6 +81,10 @@ | |||
87 | * Default xilinxfb configuration | 81 | * Default xilinxfb configuration |
88 | */ | 82 | */ |
89 | static struct xilinxfb_platform_data xilinx_fb_default_pdata = { | 83 | static struct xilinxfb_platform_data xilinx_fb_default_pdata = { |
84 | .xres = 640, | ||
85 | .yres = 480, | ||
86 | .xvirt = 1024, | ||
87 | .yvirt = 480; | ||
90 | }; | 88 | }; |
91 | 89 | ||
92 | /* | 90 | /* |
@@ -96,17 +94,10 @@ static struct fb_fix_screeninfo xilinx_fb_fix = { | |||
96 | .id = "Xilinx", | 94 | .id = "Xilinx", |
97 | .type = FB_TYPE_PACKED_PIXELS, | 95 | .type = FB_TYPE_PACKED_PIXELS, |
98 | .visual = FB_VISUAL_TRUECOLOR, | 96 | .visual = FB_VISUAL_TRUECOLOR, |
99 | .smem_len = FB_SIZE, | ||
100 | .line_length = LINE_LENGTH, | ||
101 | .accel = FB_ACCEL_NONE | 97 | .accel = FB_ACCEL_NONE |
102 | }; | 98 | }; |
103 | 99 | ||
104 | static struct fb_var_screeninfo xilinx_fb_var = { | 100 | static struct fb_var_screeninfo xilinx_fb_var = { |
105 | .xres = XRES, | ||
106 | .yres = YRES, | ||
107 | .xres_virtual = XRES_VIRTUAL, | ||
108 | .yres_virtual = YRES_VIRTUAL, | ||
109 | |||
110 | .bits_per_pixel = BITS_PER_PIXEL, | 101 | .bits_per_pixel = BITS_PER_PIXEL, |
111 | 102 | ||
112 | .red = { RED_SHIFT, 8, 0 }, | 103 | .red = { RED_SHIFT, 8, 0 }, |
@@ -217,6 +208,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
217 | { | 208 | { |
218 | struct xilinxfb_drvdata *drvdata; | 209 | struct xilinxfb_drvdata *drvdata; |
219 | int rc; | 210 | int rc; |
211 | int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; | ||
220 | 212 | ||
221 | /* Allocate the driver data region */ | 213 | /* Allocate the driver data region */ |
222 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); | 214 | drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); |
@@ -243,7 +235,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
243 | } | 235 | } |
244 | 236 | ||
245 | /* Allocate the framebuffer memory */ | 237 | /* Allocate the framebuffer memory */ |
246 | drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE), | 238 | drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize), |
247 | &drvdata->fb_phys, GFP_KERNEL); | 239 | &drvdata->fb_phys, GFP_KERNEL); |
248 | if (!drvdata->fb_virt) { | 240 | if (!drvdata->fb_virt) { |
249 | dev_err(dev, "Could not allocate frame buffer memory\n"); | 241 | dev_err(dev, "Could not allocate frame buffer memory\n"); |
@@ -252,7 +244,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
252 | } | 244 | } |
253 | 245 | ||
254 | /* Clear (turn to black) the framebuffer */ | 246 | /* Clear (turn to black) the framebuffer */ |
255 | memset_io((void __iomem *)drvdata->fb_virt, 0, FB_SIZE); | 247 | memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); |
256 | 248 | ||
257 | /* Tell the hardware where the frame buffer is */ | 249 | /* Tell the hardware where the frame buffer is */ |
258 | xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); | 250 | xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); |
@@ -269,12 +261,18 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
269 | drvdata->info.fbops = &xilinxfb_ops; | 261 | drvdata->info.fbops = &xilinxfb_ops; |
270 | drvdata->info.fix = xilinx_fb_fix; | 262 | drvdata->info.fix = xilinx_fb_fix; |
271 | drvdata->info.fix.smem_start = drvdata->fb_phys; | 263 | drvdata->info.fix.smem_start = drvdata->fb_phys; |
264 | drvdata->info.fix.smem_len = fbsize; | ||
265 | drvdata->info.fix.line_length = pdata->xvirt * BYTES_PER_PIXEL; | ||
266 | |||
272 | drvdata->info.pseudo_palette = drvdata->pseudo_palette; | 267 | drvdata->info.pseudo_palette = drvdata->pseudo_palette; |
273 | drvdata->info.flags = FBINFO_DEFAULT; | 268 | drvdata->info.flags = FBINFO_DEFAULT; |
274 | drvdata->info.var = xilinx_fb_var; | 269 | drvdata->info.var = xilinx_fb_var; |
275 | 270 | drvdata->info.var.height = pdata->screen_height_mm; | |
276 | xilinx_fb_var.height = pdata->screen_height_mm; | 271 | drvdata->info.var.width = pdata->screen_width_mm; |
277 | xilinx_fb_var.width = pdata->screen_width_mm; | 272 | drvdata->info.var.xres = pdata->xres; |
273 | drvdata->info.var.yres = pdata->yres; | ||
274 | drvdata->info.var.xres_virtual = pdata->xvirt; | ||
275 | drvdata->info.var.yres_virtual = pdata->yvirt; | ||
278 | 276 | ||
279 | /* Allocate a colour map */ | 277 | /* Allocate a colour map */ |
280 | rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); | 278 | rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); |
@@ -294,14 +292,15 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, | |||
294 | /* Put a banner in the log (for DEBUG) */ | 292 | /* Put a banner in the log (for DEBUG) */ |
295 | dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); | 293 | dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); |
296 | dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", | 294 | dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", |
297 | (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); | 295 | (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize); |
296 | |||
298 | return 0; /* success */ | 297 | return 0; /* success */ |
299 | 298 | ||
300 | err_regfb: | 299 | err_regfb: |
301 | fb_dealloc_cmap(&drvdata->info.cmap); | 300 | fb_dealloc_cmap(&drvdata->info.cmap); |
302 | 301 | ||
303 | err_cmap: | 302 | err_cmap: |
304 | dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, | 303 | dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, |
305 | drvdata->fb_phys); | 304 | drvdata->fb_phys); |
306 | /* Turn off the display */ | 305 | /* Turn off the display */ |
307 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | 306 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); |
@@ -331,8 +330,8 @@ static int xilinxfb_release(struct device *dev) | |||
331 | 330 | ||
332 | fb_dealloc_cmap(&drvdata->info.cmap); | 331 | fb_dealloc_cmap(&drvdata->info.cmap); |
333 | 332 | ||
334 | dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, | 333 | dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), |
335 | drvdata->fb_phys); | 334 | drvdata->fb_virt, drvdata->fb_phys); |
336 | 335 | ||
337 | /* Turn off the display */ | 336 | /* Turn off the display */ |
338 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); | 337 | xilinx_fb_out_be32(drvdata, REG_CTRL, 0); |
@@ -364,10 +363,18 @@ xilinxfb_platform_probe(struct platform_device *pdev) | |||
364 | } | 363 | } |
365 | 364 | ||
366 | /* If a pdata structure is provided, then extract the parameters */ | 365 | /* If a pdata structure is provided, then extract the parameters */ |
367 | if (pdev->dev.platform_data) | 366 | pdata = &xilinx_fb_default_pdata; |
367 | if (pdev->dev.platform_data) { | ||
368 | pdata = pdev->dev.platform_data; | 368 | pdata = pdev->dev.platform_data; |
369 | else | 369 | if (!pdata->xres) |
370 | pdata = &xilinx_fb_default_pdata; | 370 | pdata->xres = xilinx_fb_default_pdata.xres; |
371 | if (!pdata->yres) | ||
372 | pdata->yres = xilinx_fb_default_pdata.yres; | ||
373 | if (!pdata->xvirt) | ||
374 | pdata->xvirt = xilinx_fb_default_pdata.xvirt; | ||
375 | if (!pdata->yvirt) | ||
376 | pdata->yvirt = xilinx_fb_default_pdata.yvirt; | ||
377 | } | ||
371 | 378 | ||
372 | return xilinxfb_assign(&pdev->dev, res->start, pdata); | 379 | return xilinxfb_assign(&pdev->dev, res->start, pdata); |
373 | } | 380 | } |
@@ -412,12 +419,24 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) | |||
412 | return rc; | 419 | return rc; |
413 | } | 420 | } |
414 | 421 | ||
415 | prop = of_get_property(op->node, "display-number", &size); | 422 | prop = of_get_property(op->node, "phys-size", &size); |
416 | if ((prop) && (size >= sizeof(u32)*2)) { | 423 | if ((prop) && (size >= sizeof(u32)*2)) { |
417 | pdata.screen_width_mm = prop[0]; | 424 | pdata.screen_width_mm = prop[0]; |
418 | pdata.screen_height_mm = prop[1]; | 425 | pdata.screen_height_mm = prop[1]; |
419 | } | 426 | } |
420 | 427 | ||
428 | prop = of_get_property(op->node, "resolution", &size); | ||
429 | if ((prop) && (size >= sizeof(u32)*2)) { | ||
430 | pdata.xres = prop[0]; | ||
431 | pdata.yres = prop[1]; | ||
432 | } | ||
433 | |||
434 | prop = of_get_property(op->node, "virtual-resolution", &size); | ||
435 | if ((prop) && (size >= sizeof(u32)*2)) { | ||
436 | pdata.xvirt = prop[0]; | ||
437 | pdata.yvirt = prop[1]; | ||
438 | } | ||
439 | |||
421 | if (of_find_property(op->node, "rotate-display", NULL)) | 440 | if (of_find_property(op->node, "rotate-display", NULL)) |
422 | pdata.rotate_screen = 1; | 441 | pdata.rotate_screen = 1; |
423 | 442 | ||
diff --git a/include/linux/xilinxfb.h b/include/linux/xilinxfb.h index 9ad984d22c38..199a1eedf223 100644 --- a/include/linux/xilinxfb.h +++ b/include/linux/xilinxfb.h | |||
@@ -15,9 +15,11 @@ | |||
15 | 15 | ||
16 | /* ML300/403 reference design framebuffer driver platform data struct */ | 16 | /* ML300/403 reference design framebuffer driver platform data struct */ |
17 | struct xilinxfb_platform_data { | 17 | struct xilinxfb_platform_data { |
18 | u32 rotate_screen; | 18 | u32 rotate_screen; /* Flag to rotate display 180 degrees */ |
19 | u32 screen_height_mm; | 19 | u32 screen_height_mm; /* Physical dimentions of screen in mm */ |
20 | u32 screen_width_mm; | 20 | u32 screen_width_mm; |
21 | u32 xres, yres; /* resolution of screen in pixels */ | ||
22 | u32 xvirt, yvirt; /* resolution of memory buffer */ | ||
21 | }; | 23 | }; |
22 | 24 | ||
23 | #endif /* __XILINXFB_H__ */ | 25 | #endif /* __XILINXFB_H__ */ |