Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
[pandora-kernel.git] / arch / arm / mach-vt8500 / devices.c
1 /* linux/arch/arm/mach-vt8500/devices.c
2  *
3  * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/io.h>
18 #include <linux/device.h>
19 #include <linux/dma-mapping.h>
20 #include <linux/platform_device.h>
21 #include <linux/pwm_backlight.h>
22 #include <linux/memblock.h>
23
24 #include <asm/mach/arch.h>
25
26 #include <mach/vt8500fb.h>
27 #include <mach/i8042.h>
28 #include "devices.h"
29
30 /* These can't use resources currently */
31 unsigned long wmt_ic_base __initdata;
32 unsigned long wmt_sic_base __initdata;
33 unsigned long wmt_gpio_base __initdata;
34 unsigned long wmt_pmc_base __initdata;
35 unsigned long wmt_i8042_base __initdata;
36
37 int wmt_nr_irqs __initdata;
38 int wmt_timer_irq __initdata;
39 int wmt_gpio_ext_irq[8] __initdata;
40
41 /* Should remain accessible after init.
42  * i8042 driver desperately calls for attention...
43  */
44 int wmt_i8042_kbd_irq;
45 int wmt_i8042_aux_irq;
46
47 static u64 fb_dma_mask = DMA_BIT_MASK(32);
48
49 struct platform_device vt8500_device_lcdc = {
50         .name           = "vt8500-lcd",
51         .id             = 0,
52         .dev            = {
53                 .dma_mask       = &fb_dma_mask,
54                 .coherent_dma_mask = DMA_BIT_MASK(32),
55         },
56 };
57
58 struct platform_device vt8500_device_wm8505_fb = {
59         .name           = "wm8505-fb",
60         .id             = 0,
61 };
62
63 /* Smallest to largest */
64 static struct vt8500fb_platform_data panels[] = {
65 #ifdef CONFIG_WMT_PANEL_800X480
66 {
67         .xres_virtual   = 800,
68         .yres_virtual   = 480 * 2,
69         .mode           = {
70                 .name           = "800x480",
71                 .xres           = 800,
72                 .yres           = 480,
73                 .left_margin    = 88,
74                 .right_margin   = 40,
75                 .upper_margin   = 32,
76                 .lower_margin   = 11,
77                 .hsync_len      = 0,
78                 .vsync_len      = 1,
79                 .vmode          = FB_VMODE_NONINTERLACED,
80         },
81 },
82 #endif
83 #ifdef CONFIG_WMT_PANEL_800X600
84 {
85         .xres_virtual   = 800,
86         .yres_virtual   = 600 * 2,
87         .mode           = {
88                 .name           = "800x600",
89                 .xres           = 800,
90                 .yres           = 600,
91                 .left_margin    = 88,
92                 .right_margin   = 40,
93                 .upper_margin   = 32,
94                 .lower_margin   = 11,
95                 .hsync_len      = 0,
96                 .vsync_len      = 1,
97                 .vmode          = FB_VMODE_NONINTERLACED,
98         },
99 },
100 #endif
101 #ifdef CONFIG_WMT_PANEL_1024X576
102 {
103         .xres_virtual   = 1024,
104         .yres_virtual   = 576 * 2,
105         .mode           = {
106                 .name           = "1024x576",
107                 .xres           = 1024,
108                 .yres           = 576,
109                 .left_margin    = 40,
110                 .right_margin   = 24,
111                 .upper_margin   = 32,
112                 .lower_margin   = 11,
113                 .hsync_len      = 96,
114                 .vsync_len      = 2,
115                 .vmode          = FB_VMODE_NONINTERLACED,
116         },
117 },
118 #endif
119 #ifdef CONFIG_WMT_PANEL_1024X600
120 {
121         .xres_virtual   = 1024,
122         .yres_virtual   = 600 * 2,
123         .mode           = {
124                 .name           = "1024x600",
125                 .xres           = 1024,
126                 .yres           = 600,
127                 .left_margin    = 66,
128                 .right_margin   = 2,
129                 .upper_margin   = 19,
130                 .lower_margin   = 1,
131                 .hsync_len      = 23,
132                 .vsync_len      = 8,
133                 .vmode          = FB_VMODE_NONINTERLACED,
134         },
135 },
136 #endif
137 };
138
139 static int current_panel_idx __initdata = ARRAY_SIZE(panels) - 1;
140
141 static int __init panel_setup(char *str)
142 {
143         int i;
144
145         for (i = 0; i < ARRAY_SIZE(panels); i++) {
146                 if (strcmp(panels[i].mode.name, str) == 0) {
147                         current_panel_idx = i;
148                         break;
149                 }
150         }
151         return 0;
152 }
153
154 early_param("panel", panel_setup);
155
156 static inline void preallocate_fb(struct vt8500fb_platform_data *p,
157                                   unsigned long align) {
158         p->video_mem_len = (p->xres_virtual * p->yres_virtual * 4) >>
159                         (p->bpp > 16 ? 0 : (p->bpp > 8 ? 1 :
160                                         (8 / p->bpp) + 1));
161         p->video_mem_phys = (unsigned long)memblock_alloc(p->video_mem_len,
162                                                           align);
163         p->video_mem_virt = phys_to_virt(p->video_mem_phys);
164 }
165
166 struct platform_device vt8500_device_uart0 = {
167         .name           = "vt8500_serial",
168         .id             = 0,
169 };
170
171 struct platform_device vt8500_device_uart1 = {
172         .name           = "vt8500_serial",
173         .id             = 1,
174 };
175
176 struct platform_device vt8500_device_uart2 = {
177         .name           = "vt8500_serial",
178         .id             = 2,
179 };
180
181 struct platform_device vt8500_device_uart3 = {
182         .name           = "vt8500_serial",
183         .id             = 3,
184 };
185
186 struct platform_device vt8500_device_uart4 = {
187         .name           = "vt8500_serial",
188         .id             = 4,
189 };
190
191 struct platform_device vt8500_device_uart5 = {
192         .name           = "vt8500_serial",
193         .id             = 5,
194 };
195
196 static u64 ehci_dma_mask = DMA_BIT_MASK(32);
197
198 struct platform_device vt8500_device_ehci = {
199         .name           = "vt8500-ehci",
200         .id             = 0,
201         .dev            = {
202                 .dma_mask       = &ehci_dma_mask,
203                 .coherent_dma_mask = DMA_BIT_MASK(32),
204         },
205 };
206
207 struct platform_device vt8500_device_ge_rops = {
208         .name           = "wmt_ge_rops",
209         .id             = -1,
210 };
211
212 struct platform_device vt8500_device_pwm = {
213         .name           = "vt8500-pwm",
214         .id             = 0,
215 };
216
217 static struct platform_pwm_backlight_data vt8500_pwmbl_data = {
218         .pwm_id         = 0,
219         .max_brightness = 128,
220         .dft_brightness = 70,
221         .pwm_period_ns  = 250000, /* revisit when clocks are implemented */
222 };
223
224 struct platform_device vt8500_device_pwmbl = {
225         .name           = "pwm-backlight",
226         .id             = 0,
227         .dev            = {
228                 .platform_data = &vt8500_pwmbl_data,
229         },
230 };
231
232 struct platform_device vt8500_device_rtc = {
233         .name           = "vt8500-rtc",
234         .id             = 0,
235 };
236
237 struct map_desc wmt_io_desc[] __initdata = {
238         /* SoC MMIO registers */
239         [0] = {
240                 .virtual        = 0xf8000000,
241                 .pfn            = __phys_to_pfn(0xd8000000),
242                 .length         = 0x00390000, /* max of all chip variants */
243                 .type           = MT_DEVICE
244         },
245         /* PCI I/O space, numbers tied to those in <mach/io.h> */
246         [1] = {
247                 .virtual        = 0xf0000000,
248                 .pfn            = __phys_to_pfn(0xc0000000),
249                 .length         = SZ_64K,
250                 .type           = MT_DEVICE
251         },
252 };
253
254 void __init vt8500_reserve_mem(void)
255 {
256 #ifdef CONFIG_FB_VT8500
257         panels[current_panel_idx].bpp = 16; /* Always use RGB565 */
258         preallocate_fb(&panels[current_panel_idx], SZ_4M);
259         vt8500_device_lcdc.dev.platform_data = &panels[current_panel_idx];
260 #endif
261 }
262
263 void __init wm8505_reserve_mem(void)
264 {
265 #if defined CONFIG_FB_WM8505
266         panels[current_panel_idx].bpp = 32; /* Always use RGB888 */
267         preallocate_fb(&panels[current_panel_idx], 32);
268         vt8500_device_wm8505_fb.dev.platform_data = &panels[current_panel_idx];
269 #endif
270 }