Ventana: KBC: Removing the KBC usage on ventana
[linux-2.6.git] / arch / arm / mach-tegra / board-whistler-panel.c
1 /*
2  * arch/arm/mach-tegra/board-whistler-panel.c
3  *
4  * Copyright (c) 2010-2011, NVIDIA Corporation.
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 as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20
21 #include <linux/delay.h>
22 #include <linux/gpio.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/resource.h>
25 #include <asm/mach-types.h>
26 #include <linux/platform_device.h>
27 #include <linux/pwm_backlight.h>
28 #include <linux/tegra_pwm_bl.h>
29 #include <linux/nvhost.h>
30 #include <mach/nvmap.h>
31 #include <mach/irqs.h>
32 #include <mach/iomap.h>
33 #include <mach/dc.h>
34 #include <mach/fb.h>
35
36 #include "devices.h"
37 #include "gpio-names.h"
38 #include "board.h"
39
40 #define whistler_hdmi_hpd       TEGRA_GPIO_PN7
41
42 static struct regulator *whistler_hdmi_reg = NULL;
43 static struct regulator *whistler_hdmi_pll = NULL;
44
45 /*
46  * In case which_pwm is TEGRA_PWM_PM0,
47  * gpio_conf_to_sfio should be TEGRA_GPIO_PW0: set LCD_CS1_N pin to SFIO
48  * In case which_pwm is TEGRA_PWM_PM1,
49  * gpio_conf_to_sfio should be TEGRA_GPIO_PW1: set LCD_M1 pin to SFIO
50  */
51 static struct platform_tegra_pwm_backlight_data whistler_disp1_backlight_data = {
52         .which_dc = 0,
53         .which_pwm = TEGRA_PWM_PM1,
54         .max_brightness = 256,
55         .dft_brightness = 77,
56         .gpio_conf_to_sfio      = TEGRA_GPIO_PW1,
57         .switch_to_sfio         = &tegra_gpio_disable,
58         .period = 0x1F,
59         .clk_div = 3,
60         .clk_select = 2,
61 };
62
63 static struct platform_device whistler_disp1_backlight_device = {
64         .name   = "tegra-pwm-bl",
65         .id     = -1,
66         .dev    = {
67                 .platform_data = &whistler_disp1_backlight_data,
68         },
69 };
70
71 static int whistler_hdmi_enable(void)
72 {
73         if (!whistler_hdmi_reg) {
74                 whistler_hdmi_reg = regulator_get(NULL, "avdd_hdmi"); /* LD011 */
75                 if (IS_ERR_OR_NULL(whistler_hdmi_reg)) {
76                         pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
77                         whistler_hdmi_reg = NULL;
78                         return PTR_ERR(whistler_hdmi_reg);
79                 }
80         }
81         regulator_enable(whistler_hdmi_reg);
82
83         if (!whistler_hdmi_pll) {
84                 whistler_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll"); /* LD06 */
85                 if (IS_ERR_OR_NULL(whistler_hdmi_pll)) {
86                         pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
87                         whistler_hdmi_pll = NULL;
88                         regulator_disable(whistler_hdmi_reg);
89                         whistler_hdmi_reg = NULL;
90                         return PTR_ERR(whistler_hdmi_pll);
91                 }
92         }
93         regulator_enable(whistler_hdmi_pll);
94         return 0;
95 }
96
97 static int whistler_hdmi_disable(void)
98 {
99         regulator_disable(whistler_hdmi_reg);
100         regulator_disable(whistler_hdmi_pll);
101         return 0;
102 }
103
104 static struct resource whistler_disp1_resources[] = {
105         {
106                 .name   = "irq",
107                 .start  = INT_DISPLAY_GENERAL,
108                 .end    = INT_DISPLAY_GENERAL,
109                 .flags  = IORESOURCE_IRQ,
110         },
111         {
112                 .name   = "regs",
113                 .start  = TEGRA_DISPLAY_BASE,
114                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
115                 .flags  = IORESOURCE_MEM,
116         },
117         {
118                 .name   = "fbmem",
119                 .flags  = IORESOURCE_MEM,
120         },
121 };
122
123 static struct resource whistler_disp2_resources[] = {
124         {
125                 .name   = "irq",
126                 .start  = INT_DISPLAY_B_GENERAL,
127                 .end    = INT_DISPLAY_B_GENERAL,
128                 .flags  = IORESOURCE_IRQ,
129         },
130         {
131                 .name   = "regs",
132                 .start  = TEGRA_DISPLAY2_BASE,
133                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
134                 .flags  = IORESOURCE_MEM,
135         },
136         {
137                 .name   = "fbmem",
138                 .flags  = IORESOURCE_MEM,
139         },
140         {
141                 .name   = "hdmi_regs",
142                 .start  = TEGRA_HDMI_BASE,
143                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
144                 .flags  = IORESOURCE_MEM,
145         },
146 };
147
148 static struct tegra_dc_mode whistler_panel_modes[] = {
149         {
150                 .pclk = 27000000,
151                 .h_ref_to_sync = 4,
152                 .v_ref_to_sync = 2,
153                 .h_sync_width = 10,
154                 .v_sync_width = 3,
155                 .h_back_porch = 20,
156                 .v_back_porch = 3,
157                 .h_active = 800,
158                 .v_active = 480,
159                 .h_front_porch = 70,
160                 .v_front_porch = 3,
161         },
162 };
163
164 static struct tegra_dc_out_pin whistler_dc_out_pins[] = {
165         {
166                 .name   = TEGRA_DC_OUT_PIN_H_SYNC,
167                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
168         },
169         {
170                 .name   = TEGRA_DC_OUT_PIN_V_SYNC,
171                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
172         },
173         {
174                 .name   = TEGRA_DC_OUT_PIN_PIXEL_CLOCK,
175                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
176         },
177 };
178
179 static u8 whistler_dc_out_pin_sel_config[] = {
180         TEGRA_PIN_OUT_CONFIG_SEL_LM1_PM1,
181 };
182
183 static struct tegra_dc_out whistler_disp1_out = {
184         .type           = TEGRA_DC_OUT_RGB,
185
186         .align          = TEGRA_DC_ALIGN_MSB,
187         .order          = TEGRA_DC_ORDER_RED_BLUE,
188
189         .modes          = whistler_panel_modes,
190         .n_modes        = ARRAY_SIZE(whistler_panel_modes),
191
192         .out_pins       = whistler_dc_out_pins,
193         .n_out_pins     = ARRAY_SIZE(whistler_dc_out_pins),
194
195         .out_sel_configs   = whistler_dc_out_pin_sel_config,
196         .n_out_sel_configs = ARRAY_SIZE(whistler_dc_out_pin_sel_config),
197 };
198
199 static struct tegra_dc_out whistler_disp2_out = {
200         .type           = TEGRA_DC_OUT_HDMI,
201         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
202
203         .dcc_bus        = 1,
204         .hotplug_gpio   = whistler_hdmi_hpd,
205
206         .max_pixclock   = KHZ2PICOS(148500),
207
208         .align          = TEGRA_DC_ALIGN_MSB,
209         .order          = TEGRA_DC_ORDER_RED_BLUE,
210
211         .enable         = whistler_hdmi_enable,
212         .disable        = whistler_hdmi_disable,
213 };
214
215 static struct tegra_fb_data whistler_fb_data = {
216         .win            = 0,
217         .xres           = 800,
218         .yres           = 480,
219         .bits_per_pixel = 32,
220         .flags          = TEGRA_FB_FLIP_ON_PROBE,
221 };
222
223 static struct tegra_fb_data whistler_hdmi_fb_data = {
224         .win            = 0,
225         .xres           = 800,
226         .yres           = 480,
227         .bits_per_pixel = 32,
228         .flags          = TEGRA_FB_FLIP_ON_PROBE,
229 };
230
231
232 static struct tegra_dc_platform_data whistler_disp1_pdata = {
233         .flags          = TEGRA_DC_FLAG_ENABLED,
234         .default_out    = &whistler_disp1_out,
235         .fb             = &whistler_fb_data,
236 };
237
238 static struct nvhost_device whistler_disp1_device = {
239         .name           = "tegradc",
240         .id             = 0,
241         .resource       = whistler_disp1_resources,
242         .num_resources  = ARRAY_SIZE(whistler_disp1_resources),
243         .dev = {
244                 .platform_data = &whistler_disp1_pdata,
245         },
246 };
247
248 static struct tegra_dc_platform_data whistler_disp2_pdata = {
249         .flags          = 0,
250         .default_out    = &whistler_disp2_out,
251         .fb             = &whistler_hdmi_fb_data,
252 };
253
254 static struct nvhost_device whistler_disp2_device = {
255         .name           = "tegradc",
256         .id             = 1,
257         .resource       = whistler_disp2_resources,
258         .num_resources  = ARRAY_SIZE(whistler_disp2_resources),
259         .dev = {
260                 .platform_data = &whistler_disp2_pdata,
261         },
262 };
263
264 static struct nvmap_platform_carveout whistler_carveouts[] = {
265         [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
266         [1] = {
267                 .name           = "generic-0",
268                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
269                 .base           = 0x18C00000,
270                 .size           = SZ_128M - 0xC00000,
271                 .buddy_size     = SZ_32K,
272         },
273 };
274
275 static struct nvmap_platform_data whistler_nvmap_data = {
276         .carveouts      = whistler_carveouts,
277         .nr_carveouts   = ARRAY_SIZE(whistler_carveouts),
278 };
279
280 static struct platform_device whistler_nvmap_device = {
281         .name   = "tegra-nvmap",
282         .id     = -1,
283         .dev    = {
284                 .platform_data = &whistler_nvmap_data,
285         },
286 };
287
288 static struct platform_device *whistler_gfx_devices[] __initdata = {
289         &whistler_nvmap_device,
290         &tegra_grhost_device,
291         &whistler_disp1_backlight_device,
292 };
293
294 int __init whistler_panel_init(void)
295 {
296         int err;
297         struct resource *res;
298
299         tegra_gpio_enable(whistler_hdmi_hpd);
300         gpio_request(whistler_hdmi_hpd, "hdmi_hpd");
301         gpio_direction_input(whistler_hdmi_hpd);
302
303         whistler_carveouts[1].base = tegra_carveout_start;
304         whistler_carveouts[1].size = tegra_carveout_size;
305
306         err = platform_add_devices(whistler_gfx_devices,
307                                    ARRAY_SIZE(whistler_gfx_devices));
308
309         res = nvhost_get_resource_byname(&whistler_disp1_device,
310                                          IORESOURCE_MEM, "fbmem");
311         res->start = tegra_fb_start;
312         res->end = tegra_fb_start + tegra_fb_size - 1;
313
314         /* Copy the bootloader fb to the fb. */
315         tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
316                 min(tegra_fb_size, tegra_bootloader_fb_size));
317
318         res = nvhost_get_resource_byname(&whistler_disp2_device,
319                                          IORESOURCE_MEM, "fbmem");
320         res->start = tegra_fb2_start;
321         res->end = tegra_fb2_start + tegra_fb2_size - 1;
322
323         if (!err)
324                 err = nvhost_device_register(&whistler_disp1_device);
325
326         if (!err)
327                 err = nvhost_device_register(&whistler_disp2_device);
328
329         return err;
330 }
331