Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[pandora-kernel.git] / drivers / staging / msm / staging-devices.c
1 #include <linux/kernel.h>
2 #include <linux/irq.h>
3 #include <linux/gpio.h>
4 #include <linux/platform_device.h>
5 #include <linux/bootmem.h>
6 #include <linux/delay.h>
7
8 #include <asm/mach-types.h>
9 #include <asm/mach/arch.h>
10 #include <asm/io.h>
11 #include <asm/setup.h>
12
13 #include <mach/board.h>
14 #include <mach/irqs.h>
15 #include <mach/sirc.h>
16 #include <mach/gpio.h>
17
18 #include "msm_mdp.h"
19 #include "memory_ll.h"
20 //#include "android_pmem.h"
21 #include <mach/board.h>
22
23 #ifdef CONFIG_MSM_SOC_REV_A
24 #define MSM_SMI_BASE 0xE0000000
25 #else
26 #define MSM_SMI_BASE 0x00000000
27 #endif
28
29
30 #define TOUCHPAD_SUSPEND        34
31 #define TOUCHPAD_IRQ            38
32
33 #define MSM_PMEM_MDP_SIZE       0x1591000
34
35 #ifdef CONFIG_MSM_SOC_REV_A
36 #define SMEM_SPINLOCK_I2C       "D:I2C02000021"
37 #else
38 #define SMEM_SPINLOCK_I2C       "S:6"
39 #endif
40
41 #define MSM_PMEM_ADSP_SIZE      0x1C00000
42
43 #define MSM_FB_SIZE             0x500000
44 #define MSM_FB_SIZE_ST15        0x800000
45 #define MSM_AUDIO_SIZE          0x80000
46 #define MSM_GPU_PHYS_SIZE       SZ_2M
47
48 #ifdef CONFIG_MSM_SOC_REV_A
49 #define MSM_SMI_BASE            0xE0000000
50 #else
51 #define MSM_SMI_BASE            0x00000000
52 #endif
53
54 #define MSM_SHARED_RAM_PHYS     (MSM_SMI_BASE + 0x00100000)
55
56 #define MSM_PMEM_SMI_BASE       (MSM_SMI_BASE + 0x02B00000)
57 #define MSM_PMEM_SMI_SIZE       0x01500000
58
59 #define MSM_FB_BASE             MSM_PMEM_SMI_BASE
60 #define MSM_GPU_PHYS_BASE       (MSM_FB_BASE + MSM_FB_SIZE)
61 #define MSM_PMEM_SMIPOOL_BASE   (MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE)
62 #define MSM_PMEM_SMIPOOL_SIZE   (MSM_PMEM_SMI_SIZE - MSM_FB_SIZE \
63                                         - MSM_GPU_PHYS_SIZE)
64
65 #if defined(CONFIG_FB_MSM_MDP40)
66 #define MDP_BASE          0xA3F00000
67 #define PMDH_BASE         0xAD600000
68 #define EMDH_BASE         0xAD700000
69 #define TVENC_BASE        0xAD400000
70 #else
71 #define MDP_BASE          0xAA200000
72 #define PMDH_BASE         0xAA600000
73 #define EMDH_BASE         0xAA700000
74 #define TVENC_BASE        0xAA400000
75 #endif
76
77 #define PMEM_KERNEL_EBI1_SIZE   (CONFIG_PMEM_KERNEL_SIZE * 1024 * 1024)
78
79 static struct resource msm_fb_resources[] = {
80         {
81                 .flags  = IORESOURCE_DMA,
82         }
83 };
84
85 static struct resource msm_mdp_resources[] = {
86         {
87                 .name   = "mdp",
88                 .start  = MDP_BASE,
89                 .end    = MDP_BASE + 0x000F0000 - 1,
90                 .flags  = IORESOURCE_MEM,
91         }
92 };
93
94 static struct platform_device msm_mdp_device = {
95         .name   = "mdp",
96         .id     = 0,
97         .num_resources  = ARRAY_SIZE(msm_mdp_resources),
98         .resource       = msm_mdp_resources,
99 };
100
101 static struct platform_device msm_lcdc_device = {
102         .name   = "lcdc",
103         .id     = 0,
104 };
105
106 static int msm_fb_detect_panel(const char *name)
107 {
108         int ret = -EPERM;
109
110         if (machine_is_qsd8x50_ffa() || machine_is_qsd8x50a_ffa()) {
111                 if (!strncmp(name, "mddi_toshiba_wvga_pt", 20))
112                         ret = 0;
113                 else
114                         ret = -ENODEV;
115         } else if ((machine_is_qsd8x50_surf() || machine_is_qsd8x50a_surf())
116                         && !strcmp(name, "lcdc_external"))
117                 ret = 0;
118         else if (0 /*machine_is_qsd8x50_grapefruit() */) {
119                 if (!strcmp(name, "lcdc_grapefruit_vga"))
120                         ret = 0;
121                 else
122                         ret = -ENODEV;
123         } else if (machine_is_qsd8x50_st1()) {
124                 if (!strcmp(name, "lcdc_st1_wxga"))
125                         ret = 0;
126                 else
127                         ret = -ENODEV;
128         } else if (machine_is_qsd8x50a_st1_5()) {
129                 if (!strcmp(name, "lcdc_st15") ||
130                     !strcmp(name, "hdmi_sii9022"))
131                         ret = 0;
132                 else
133                         ret = -ENODEV;
134         }
135
136         return ret;
137 }
138
139 /* Only allow a small subset of machines to set the offset via
140    FB PAN_DISPLAY */
141
142 static int msm_fb_allow_set_offset(void)
143 {
144         return (machine_is_qsd8x50_st1() ||
145                 machine_is_qsd8x50a_st1_5()) ? 1 : 0;
146 }
147
148
149 static struct msm_fb_platform_data msm_fb_pdata = {
150         .detect_client = msm_fb_detect_panel,
151         .allow_set_offset = msm_fb_allow_set_offset,
152 };
153
154 static struct platform_device msm_fb_device = {
155         .name   = "msm_fb",
156         .id     = 0,
157         .num_resources  = ARRAY_SIZE(msm_fb_resources),
158         .resource       = msm_fb_resources,
159         .dev    = {
160                 .platform_data = &msm_fb_pdata,
161         }
162 };
163
164 static void __init qsd8x50_allocate_memory_regions(void)
165 {
166         void *addr;
167         unsigned long size;
168         if (machine_is_qsd8x50a_st1_5())
169                 size = MSM_FB_SIZE_ST15;
170         else
171                 size = MSM_FB_SIZE;
172
173         addr = alloc_bootmem(size); // (void *)MSM_FB_BASE;
174         if (!addr)
175                 printk("Failed to allocate bootmem for framebuffer\n");
176
177
178         msm_fb_resources[0].start = __pa(addr);
179         msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
180         pr_info(KERN_ERR "using %lu bytes of SMI at %lx physical for fb\n",
181                 size, (unsigned long)addr);
182 }
183
184 static int msm_fb_lcdc_gpio_config(int on)
185 {
186 //      return 0;
187         if (machine_is_qsd8x50_st1()) {
188                 if (on) {
189                         gpio_set_value(32, 1);
190                         mdelay(100);
191                         gpio_set_value(20, 1);
192                         gpio_set_value(17, 1);
193                         gpio_set_value(19, 1);
194                 } else {
195                         gpio_set_value(17, 0);
196                         gpio_set_value(19, 0);
197                         gpio_set_value(20, 0);
198                         mdelay(100);
199                         gpio_set_value(32, 0);
200                 }
201         } else if (machine_is_qsd8x50a_st1_5()) {
202                 if (on) {
203                         gpio_set_value(17, 1);
204                         gpio_set_value(19, 1);
205                         gpio_set_value(20, 1);
206                         gpio_set_value(22, 0);
207                         gpio_set_value(32, 1);
208                         gpio_set_value(155, 1);
209                         //st15_hdmi_power(1);
210                         gpio_set_value(22, 1);
211
212                 } else {
213                         gpio_set_value(17, 0);
214                         gpio_set_value(19, 0);
215                         gpio_set_value(22, 0);
216                         gpio_set_value(32, 0);
217                         gpio_set_value(155, 0);
218                 //      st15_hdmi_power(0);
219                 }
220         }
221         return 0;
222 }
223
224
225 static struct lcdc_platform_data lcdc_pdata = {
226         .lcdc_gpio_config = msm_fb_lcdc_gpio_config,
227 };
228
229 static struct msm_gpio msm_fb_st15_gpio_config_data[] = {
230         { GPIO_CFG(17, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en0" },
231         { GPIO_CFG(19, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "dat_pwr_sv" },
232         { GPIO_CFG(20, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lvds_pwr_dn" },
233         { GPIO_CFG(22, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en1" },
234         { GPIO_CFG(32, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "lcdc_en2" },
235         { GPIO_CFG(103, 0, GPIO_INPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_irq" },
236         { GPIO_CFG(155, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), "hdmi_3v3" },
237 };
238
239 static struct msm_panel_common_pdata mdp_pdata = {
240         .gpio = 98,
241 };
242
243 static struct platform_device *devices[] __initdata = {
244         &msm_fb_device,
245 };
246
247
248 static void __init msm_register_device(struct platform_device *pdev, void *data)
249 {
250         int ret;
251
252         pdev->dev.platform_data = data;
253
254         ret = platform_device_register(pdev);
255         if (ret)
256                 dev_err(&pdev->dev,
257                           "%s: platform_device_register() failed = %d\n",
258                           __func__, ret);
259 }
260
261 void __init msm_fb_register_device(char *name, void *data)
262 {
263         if (!strncmp(name, "mdp", 3))
264                 msm_register_device(&msm_mdp_device, data);
265 /*
266         else if (!strncmp(name, "pmdh", 4))
267                 msm_register_device(&msm_mddi_device, data);
268         else if (!strncmp(name, "emdh", 4))
269                 msm_register_device(&msm_mddi_ext_device, data);
270         else if (!strncmp(name, "ebi2", 4))
271                 msm_register_device(&msm_ebi2_lcd_device, data);
272         else if (!strncmp(name, "tvenc", 5))
273                 msm_register_device(&msm_tvenc_device, data);
274         else */
275
276         if (!strncmp(name, "lcdc", 4))
277                 msm_register_device(&msm_lcdc_device, data);
278         /*else
279                 printk(KERN_ERR "%s: unknown device! %s\n", __func__, name);
280 */
281 }
282
283 static void __init msm_fb_add_devices(void)
284 {
285         int rc;
286         msm_fb_register_device("mdp", &mdp_pdata);
287 //      msm_fb_register_device("pmdh", &mddi_pdata);
288 //      msm_fb_register_device("emdh", &mddi_pdata);
289 //      msm_fb_register_device("tvenc", 0);
290
291         if (machine_is_qsd8x50a_st1_5()) {
292 /*              rc = st15_hdmi_vreg_init();
293                 if (rc)
294                         return;
295 */
296                 rc = msm_gpios_request_enable(
297                         msm_fb_st15_gpio_config_data,
298                         ARRAY_SIZE(msm_fb_st15_gpio_config_data));
299                 if (rc) {
300                         printk(KERN_ERR "%s: unable to init lcdc gpios\n",
301                                __func__);
302                         return;
303                 }
304                 msm_fb_register_device("lcdc", &lcdc_pdata);
305         } else
306                 msm_fb_register_device("lcdc", 0);
307 }
308
309 int __init staging_init_pmem(void)
310 {
311         qsd8x50_allocate_memory_regions();
312         return 0;
313 }
314
315 int __init staging_init_devices(void)
316 {
317         platform_add_devices(devices, ARRAY_SIZE(devices));
318         msm_fb_add_devices();
319         return 0;
320 }
321
322 arch_initcall(staging_init_pmem);
323 arch_initcall(staging_init_devices);