aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/wm8505fb.c
diff options
context:
space:
mode:
authorTony Prisk <linux@prisktech.co.nz>2012-08-03 04:58:22 -0400
committerTony Prisk <linux@prisktech.co.nz>2012-09-21 03:23:56 -0400
commite7b995371fe1e29838321fcdc3cfe35bb0d6bfc4 (patch)
treedef3385d58244aa0c4da4098d0d99b92353a3416 /drivers/video/wm8505fb.c
parent4001130df1a74948cfa8be02b420953a84ab83e8 (diff)
video: vt8500: Add devicetree support for vt8500-fb and wm8505-fb
Update vt8500-fb, wm8505-fb and wmt-ge-rops to support device tree bindings. Small change in wm8505-fb.c to support WM8650 framebuffer color format. Signed-off-by: Tony Prisk <linux@prisktech.co.nz>
Diffstat (limited to 'drivers/video/wm8505fb.c')
-rw-r--r--drivers/video/wm8505fb.c97
1 files changed, 82 insertions, 15 deletions
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
index c8703bd61b7..ec474244210 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/wm8505fb.c
@@ -28,6 +28,9 @@
28#include <linux/dma-mapping.h> 28#include <linux/dma-mapping.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/wait.h> 30#include <linux/wait.h>
31#include <linux/of.h>
32#include <linux/of_fdt.h>
33#include <linux/memblock.h>
31 34
32#include <mach/vt8500fb.h> 35#include <mach/vt8500fb.h>
33 36
@@ -59,8 +62,12 @@ static int wm8505fb_init_hw(struct fb_info *info)
59 writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR); 62 writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR);
60 writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR1); 63 writel(fbi->fb.fix.smem_start, fbi->regbase + WMT_GOVR_FBADDR1);
61 64
62 /* Set in-memory picture format to RGB 32bpp */ 65 /*
63 writel(0x1c, fbi->regbase + WMT_GOVR_COLORSPACE); 66 * Set in-memory picture format to RGB
67 * 0x31C sets the correct color mode (RGB565) for WM8650
68 * Bit 8+9 (0x300) are ignored on WM8505 as reserved
69 */
70 writel(0x31c, fbi->regbase + WMT_GOVR_COLORSPACE);
64 writel(1, fbi->regbase + WMT_GOVR_COLORSPACE1); 71 writel(1, fbi->regbase + WMT_GOVR_COLORSPACE1);
65 72
66 /* Virtual buffer size */ 73 /* Virtual buffer size */
@@ -127,6 +134,18 @@ static int wm8505fb_set_par(struct fb_info *info)
127 info->var.blue.msb_right = 0; 134 info->var.blue.msb_right = 0;
128 info->fix.visual = FB_VISUAL_TRUECOLOR; 135 info->fix.visual = FB_VISUAL_TRUECOLOR;
129 info->fix.line_length = info->var.xres_virtual << 2; 136 info->fix.line_length = info->var.xres_virtual << 2;
137 } else if (info->var.bits_per_pixel == 16) {
138 info->var.red.offset = 11;
139 info->var.red.length = 5;
140 info->var.red.msb_right = 0;
141 info->var.green.offset = 5;
142 info->var.green.length = 6;
143 info->var.green.msb_right = 0;
144 info->var.blue.offset = 0;
145 info->var.blue.length = 5;
146 info->var.blue.msb_right = 0;
147 info->fix.visual = FB_VISUAL_TRUECOLOR;
148 info->fix.line_length = info->var.xres_virtual << 1;
130 } 149 }
131 150
132 wm8505fb_set_timing(info); 151 wm8505fb_set_timing(info);
@@ -246,16 +265,20 @@ static int __devinit wm8505fb_probe(struct platform_device *pdev)
246 struct wm8505fb_info *fbi; 265 struct wm8505fb_info *fbi;
247 struct resource *res; 266 struct resource *res;
248 void *addr; 267 void *addr;
249 struct vt8500fb_platform_data *pdata;
250 int ret; 268 int ret;
251 269
252 pdata = pdev->dev.platform_data; 270 struct fb_videomode of_mode;
271 struct device_node *np;
272 u32 bpp;
273 dma_addr_t fb_mem_phys;
274 unsigned long fb_mem_len;
275 void *fb_mem_virt;
253 276
254 ret = -ENOMEM; 277 ret = -ENOMEM;
255 fbi = NULL; 278 fbi = NULL;
256 279
257 fbi = kzalloc(sizeof(struct wm8505fb_info) + sizeof(u32) * 16, 280 fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) +
258 GFP_KERNEL); 281 sizeof(u32) * 16, GFP_KERNEL);
259 if (!fbi) { 282 if (!fbi) {
260 dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); 283 dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
261 ret = -ENOMEM; 284 ret = -ENOMEM;
@@ -305,21 +328,58 @@ static int __devinit wm8505fb_probe(struct platform_device *pdev)
305 goto failed_free_res; 328 goto failed_free_res;
306 } 329 }
307 330
308 fb_videomode_to_var(&fbi->fb.var, &pdata->mode); 331 np = of_parse_phandle(pdev->dev.of_node, "default-mode", 0);
332 if (!np) {
333 pr_err("%s: No display description in Device Tree\n", __func__);
334 ret = -EINVAL;
335 goto failed_free_res;
336 }
337
338 /*
339 * This code is copied from Sascha Hauer's of_videomode helper
340 * and can be replaced with a call to the helper once mainlined
341 */
342 ret = 0;
343 ret |= of_property_read_u32(np, "hactive", &of_mode.xres);
344 ret |= of_property_read_u32(np, "vactive", &of_mode.yres);
345 ret |= of_property_read_u32(np, "hback-porch", &of_mode.left_margin);
346 ret |= of_property_read_u32(np, "hfront-porch", &of_mode.right_margin);
347 ret |= of_property_read_u32(np, "hsync-len", &of_mode.hsync_len);
348 ret |= of_property_read_u32(np, "vback-porch", &of_mode.upper_margin);
349 ret |= of_property_read_u32(np, "vfront-porch", &of_mode.lower_margin);
350 ret |= of_property_read_u32(np, "vsync-len", &of_mode.vsync_len);
351 ret |= of_property_read_u32(np, "bpp", &bpp);
352 if (ret) {
353 pr_err("%s: Unable to read display properties\n", __func__);
354 goto failed_free_res;
355 }
356
357 of_mode.vmode = FB_VMODE_NONINTERLACED;
358 fb_videomode_to_var(&fbi->fb.var, &of_mode);
309 359
310 fbi->fb.var.nonstd = 0; 360 fbi->fb.var.nonstd = 0;
311 fbi->fb.var.activate = FB_ACTIVATE_NOW; 361 fbi->fb.var.activate = FB_ACTIVATE_NOW;
312 362
313 fbi->fb.var.height = -1; 363 fbi->fb.var.height = -1;
314 fbi->fb.var.width = -1; 364 fbi->fb.var.width = -1;
315 fbi->fb.var.xres_virtual = pdata->xres_virtual;
316 fbi->fb.var.yres_virtual = pdata->yres_virtual;
317 fbi->fb.var.bits_per_pixel = pdata->bpp;
318 365
319 fbi->fb.fix.smem_start = pdata->video_mem_phys; 366 /* try allocating the framebuffer */
320 fbi->fb.fix.smem_len = pdata->video_mem_len; 367 fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
321 fbi->fb.screen_base = pdata->video_mem_virt; 368 fb_mem_virt = dma_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys,
322 fbi->fb.screen_size = pdata->video_mem_len; 369 GFP_KERNEL);
370 if (!fb_mem_virt) {
371 pr_err("%s: Failed to allocate framebuffer\n", __func__);
372 return -ENOMEM;
373 };
374
375 fbi->fb.var.xres_virtual = of_mode.xres;
376 fbi->fb.var.yres_virtual = of_mode.yres * 2;
377 fbi->fb.var.bits_per_pixel = bpp;
378
379 fbi->fb.fix.smem_start = fb_mem_phys;
380 fbi->fb.fix.smem_len = fb_mem_len;
381 fbi->fb.screen_base = fb_mem_virt;
382 fbi->fb.screen_size = fb_mem_len;
323 383
324 if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { 384 if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) {
325 dev_err(&pdev->dev, "Failed to allocate color map\n"); 385 dev_err(&pdev->dev, "Failed to allocate color map\n");
@@ -395,12 +455,18 @@ static int __devexit wm8505fb_remove(struct platform_device *pdev)
395 return 0; 455 return 0;
396} 456}
397 457
458static const struct of_device_id wmt_dt_ids[] = {
459 { .compatible = "wm,wm8505-fb", },
460 {}
461};
462
398static struct platform_driver wm8505fb_driver = { 463static struct platform_driver wm8505fb_driver = {
399 .probe = wm8505fb_probe, 464 .probe = wm8505fb_probe,
400 .remove = __devexit_p(wm8505fb_remove), 465 .remove = __devexit_p(wm8505fb_remove),
401 .driver = { 466 .driver = {
402 .owner = THIS_MODULE, 467 .owner = THIS_MODULE,
403 .name = DRIVER_NAME, 468 .name = DRIVER_NAME,
469 .of_match_table = of_match_ptr(wmt_dt_ids),
404 }, 470 },
405}; 471};
406 472
@@ -408,4 +474,5 @@ module_platform_driver(wm8505fb_driver);
408 474
409MODULE_AUTHOR("Ed Spiridonov <edo.rus@gmail.com>"); 475MODULE_AUTHOR("Ed Spiridonov <edo.rus@gmail.com>");
410MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505"); 476MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505");
411MODULE_LICENSE("GPL"); 477MODULE_LICENSE("GPL v2");
478MODULE_DEVICE_TABLE(of, wmt_dt_ids);