Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / arch / arm / mach-nspire / clcd.c
1 /*
2  *      linux/arch/arm/mach-nspire/clcd.c
3  *
4  *      Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2, as
8  * published by the Free Software Foundation.
9  *
10  */
11
12 #include <linux/init.h>
13 #include <linux/of.h>
14 #include <linux/amba/bus.h>
15 #include <linux/amba/clcd.h>
16 #include <linux/dma-mapping.h>
17
18 static struct clcd_panel nspire_cx_lcd_panel = {
19         .mode           = {
20                 .name           = "Color LCD",
21                 .refresh        = 60,
22                 .xres           = 320,
23                 .yres           = 240,
24                 .sync           = 0,
25                 .vmode          = FB_VMODE_NONINTERLACED,
26                 .pixclock       = 1,
27                 .hsync_len      = 6,
28                 .vsync_len      = 1,
29                 .right_margin   = 50,
30                 .left_margin    = 38,
31                 .lower_margin   = 3,
32                 .upper_margin   = 17,
33         },
34         .width          = 65, /* ~6.50 cm */
35         .height         = 49, /* ~4.87 cm */
36         .tim2           = TIM2_IPC,
37         .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
38         .bpp            = 16,
39         .caps           = CLCD_CAP_565,
40 };
41
42 static struct clcd_panel nspire_classic_lcd_panel = {
43         .mode           = {
44                 .name           = "Grayscale LCD",
45                 .refresh        = 60,
46                 .xres           = 320,
47                 .yres           = 240,
48                 .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
49                 .vmode          = FB_VMODE_NONINTERLACED,
50                 .pixclock       = 1,
51                 .hsync_len      = 6,
52                 .vsync_len      = 1,
53                 .right_margin   = 6,
54                 .left_margin    = 6,
55         },
56         .width          = 71, /* 7.11cm */
57         .height         = 53, /* 5.33cm */
58         .tim2           = 0x80007d0,
59         .cntl           = CNTL_LCDMONO8,
60         .bpp            = 8,
61         .grayscale      = 1,
62         .caps           = CLCD_CAP_5551,
63 };
64
65 int nspire_clcd_setup(struct clcd_fb *fb)
66 {
67         struct clcd_panel *panel;
68         size_t panel_size;
69         const char *type;
70         dma_addr_t dma;
71         int err;
72
73         BUG_ON(!fb->dev->dev.of_node);
74
75         err = of_property_read_string(fb->dev->dev.of_node, "lcd-type", &type);
76         if (err) {
77                 pr_err("CLCD: Could not find lcd-type property\n");
78                 return err;
79         }
80
81         if (!strcmp(type, "cx")) {
82                 panel = &nspire_cx_lcd_panel;
83         } else if (!strcmp(type, "classic")) {
84                 panel = &nspire_classic_lcd_panel;
85         } else {
86                 pr_err("CLCD: Unknown lcd-type %s\n", type);
87                 return -EINVAL;
88         }
89
90         panel_size = ((panel->mode.xres * panel->mode.yres) * panel->bpp) / 8;
91         panel_size = ALIGN(panel_size, PAGE_SIZE);
92
93         fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev,
94                 panel_size, &dma, GFP_KERNEL);
95
96         if (!fb->fb.screen_base) {
97                 pr_err("CLCD: unable to map framebuffer\n");
98                 return -ENOMEM;
99         }
100
101         fb->fb.fix.smem_start = dma;
102         fb->fb.fix.smem_len = panel_size;
103         fb->panel = panel;
104
105         return 0;
106 }
107
108 int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
109 {
110         return dma_mmap_writecombine(&fb->dev->dev, vma,
111                 fb->fb.screen_base, fb->fb.fix.smem_start,
112                 fb->fb.fix.smem_len);
113 }
114
115 void nspire_clcd_remove(struct clcd_fb *fb)
116 {
117         dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,
118                 fb->fb.screen_base, fb->fb.fix.smem_start);
119 }