[arm]: tegra:cardhu Creating board files
[linux-2.6.git] / arch / arm / mach-tegra / board-cardhu-panel.c
1 /*
2  * arch/arm/mach-tegra/board-cardhu-panel.c
3  *
4  * Copyright (c) 2010, 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 <mach/nvhost.h>
29 #include <mach/nvmap.h>
30 #include <mach/irqs.h>
31 #include <mach/iomap.h>
32 #include <mach/dc.h>
33 #include <mach/fb.h>
34
35 #include "devices.h"
36 #include "gpio-names.h"
37
38 #define PMC_SCRATCH20   0xa0
39
40 #define cardhu_lvds_shutdown    TEGRA_GPIO_PB2
41
42 static int cardhu_panel_enable(void)
43 {
44         static struct regulator *reg = NULL;
45
46         if (reg == NULL) {
47                 reg = regulator_get(NULL, "avdd_lvds");
48                 if (WARN_ON(IS_ERR(reg)))
49                         pr_err("%s: couldn't get regulator avdd_lvds: %ld\n",
50                                __func__, PTR_ERR(reg));
51                 else
52                         regulator_enable(reg);
53         }
54
55         gpio_set_value(cardhu_lvds_shutdown, 1);
56         return 0;
57 }
58
59 static int cardhu_panel_disable(void)
60 {
61         gpio_set_value(cardhu_lvds_shutdown, 0);
62         return 0;
63 }
64
65 static struct resource cardhu_disp1_resources[] = {
66         {
67                 .name   = "irq",
68                 .start  = INT_DISPLAY_GENERAL,
69                 .end    = INT_DISPLAY_GENERAL,
70                 .flags  = IORESOURCE_IRQ,
71         },
72         {
73                 .name   = "regs",
74                 .start  = TEGRA_DISPLAY_BASE,
75                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
76                 .flags  = IORESOURCE_MEM,
77         },
78         {
79                 .name   = "fbmem",
80                 .start  = 0,    /* Filled in by fbmem_set() */
81                 .end    = 0,    /* Filled in by fbmem_set() */
82                 .flags  = IORESOURCE_MEM,
83         },
84 };
85
86 static struct tegra_dc_mode cardhu_panel_modes[] = {
87         {
88                 .pclk = 18000000,
89                 .h_ref_to_sync = 8,
90                 .v_ref_to_sync = 2,
91                 .h_sync_width = 4,
92                 .v_sync_width = 1,
93                 .h_back_porch = 20,
94                 .v_back_porch = 7,
95                 .h_active = 480,
96                 .v_active = 640,
97                 .h_front_porch = 8,
98                 .v_front_porch = 8,
99         },
100 };
101
102 static struct tegra_fb_data cardhu_fb_data = {
103         .win            = 0,
104         .xres           = 1366,
105         .yres           = 768,
106         .bits_per_pixel = 16,
107 };
108
109 static struct tegra_dc_out cardhu_disp1_out = {
110         .type           = TEGRA_DC_OUT_RGB,
111
112         .align          = TEGRA_DC_ALIGN_MSB,
113         .order          = TEGRA_DC_ORDER_RED_BLUE,
114
115         .modes          = cardhu_panel_modes,
116         .n_modes        = ARRAY_SIZE(cardhu_panel_modes),
117
118         .enable         = cardhu_panel_enable,
119         .disable        = cardhu_panel_disable,
120 };
121
122 static struct tegra_dc_platform_data cardhu_disp1_pdata = {
123         .flags          = TEGRA_DC_FLAG_ENABLED,
124         .default_out    = &cardhu_disp1_out,
125         .fb             = &cardhu_fb_data,
126 };
127
128 static struct nvhost_device cardhu_disp1_device = {
129         .name           = "tegradc",
130         .id             = 0,
131         .resource       = cardhu_disp1_resources,
132         .num_resources  = ARRAY_SIZE(cardhu_disp1_resources),
133         .dev = {
134                 .platform_data = &cardhu_disp1_pdata,
135         },
136 };
137
138 static struct nvmap_platform_carveout cardhu_carveouts[] = {
139         [0] = {
140                 .name           = "iram",
141                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
142                 .base           = TEGRA_IRAM_BASE,
143                 .size           = TEGRA_IRAM_SIZE,
144                 .buddy_size     = 0, /* no buddy allocation for IRAM */
145         },
146         [1] = {
147                 .name           = "generic-0",
148                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
149                 .base           = 0,    /* Filled in by carveout_set() */
150                 .size           = 0,    /* Filled in by carveout_set() */
151                 .buddy_size     = SZ_32K,
152         },
153 };
154
155 static struct nvmap_platform_data cardhu_nvmap_data = {
156         .carveouts      = cardhu_carveouts,
157         .nr_carveouts   = ARRAY_SIZE(cardhu_carveouts),
158 };
159
160 static struct platform_device cardhu_nvmap_device = {
161         .name   = "tegra-nvmap",
162         .id     = -1,
163         .dev    = {
164                 .platform_data = &cardhu_nvmap_data,
165         },
166 };
167
168 static struct platform_device *cardhu_gfx_devices[] __initdata = {
169         &cardhu_nvmap_device,
170         &tegra_grhost_device,
171 };
172
173
174 static inline u32 pmc_readl(unsigned long offset)
175 {
176         return readl(IO_TO_VIRT(TEGRA_PMC_BASE + offset));
177 }
178
179 static void fbmem_set(struct resource *res, int num_res,
180                                 u32 start, resource_size_t size)
181 {
182         int i;
183         for (i = 0; i < num_res ; i++) {
184                 if (!strcmp(res[i].name, "fbmem")) {
185                         res[i].start = start;
186                         res[i].end = start + size - 1;
187                         return;
188                 }
189         }
190         /* Didn't find a framebuffer memory resource */
191         BUG();
192 }
193
194 static void carveout_set(struct nvmap_platform_carveout *res, int num_res,
195                                 u32 base, resource_size_t size)
196 {
197         int i;
198         for (i = 0; i < num_res ; i++) {
199                 if (!strcmp(res[i].name, "generic-0")) {
200                         res[i].base = base;
201                         res[i].size = size;
202                         return;
203                 }
204         }
205         /* Didn't find a carveout memory resource */
206         BUG();
207 }
208
209 int __init cardhu_panel_init(void)
210 {
211         int err;
212         u32 odm_data = pmc_readl(PMC_SCRATCH20);
213
214         /* !!!FIXME!!!  HAVE TO USE HARD-CODED FRAME BUFFER AND CARVEOUT
215                         ADDRESSES FOR NOW -- BUG 769986 */
216         switch (odm_data & 0x70000000) {
217         case 0x10000000:
218                 /* 256MB LPDDR2 */
219                 fbmem_set(cardhu_disp1_resources,
220                                 ARRAY_SIZE(cardhu_disp1_resources),
221                                 0x8E010000,
222                                 0x0012C3C0);
223                 carveout_set(cardhu_carveouts,
224                                 ARRAY_SIZE(cardhu_carveouts),
225                                 0x8EC00000, /* 256MB mem - 32MB carveout + 0xC00000 ?*/
226                                 SZ_32M - 0xC00000);
227                 break;
228         case 0x40000000:
229                 /* 1GB DDR3 -- NOTE: The bootloader cannot map more than 512MB
230                    of physical memory. Therefore, the frame buffer and carveout
231                    must be completely below the 512MB boundary. */
232                 fbmem_set(cardhu_disp1_resources,
233                                 ARRAY_SIZE(cardhu_disp1_resources),
234                                 0x9E010000,
235                                 0x0012C3C0);
236                 carveout_set(cardhu_carveouts,
237                                 ARRAY_SIZE(cardhu_carveouts),
238                                 0x9EC00000, /* 512MB mem - 32MB carveout + 0xC00000 ?*/
239                                 SZ_32M - 0xC00000);
240                 break;
241         default:
242                 BUG();
243         }
244
245         err = platform_add_devices(cardhu_gfx_devices,
246                                    ARRAY_SIZE(cardhu_gfx_devices));
247
248         if (!err)
249                 err = nvhost_device_register(&cardhu_disp1_device);
250
251         return err;
252 }