vcm30t124: Disable HDMI modeset on bootup
[linux-3.10.git] / arch / arm / mach-tegra / board-vcm30_t124-panel.c
1 /*
2  * arch/arm/mach-tegra/board-vcm30_t124-panel.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
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 #include <linux/ioport.h>
21 #include <linux/fb.h>
22 #include <linux/nvmap.h>
23 #include <linux/nvhost.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/gpio.h>
27 #include <linux/of.h>
28
29 #include <mach/irqs.h>
30 #include <mach/dc.h>
31
32 #include "board.h"
33 #include "devices.h"
34 #include "gpio-names.h"
35 #include "board-vcm30_t124.h"
36 #include "board-panel.h"
37 #include "common.h"
38 #include "iomap.h"
39 #include "tegra12_host1x_devices.h"
40
41
42 struct platform_device * __init vcm30_t124_host1x_init(void)
43 {
44         struct platform_device *pdev = NULL;
45
46 #ifdef CONFIG_TEGRA_GRHOST
47         if (!of_have_populated_dt())
48                 pdev = tegra12_register_host1x_devices();
49         else
50                 pdev = to_platform_device(bus_find_device_by_name(
51                         &platform_bus_type, NULL, "host1x"));
52
53         if (!pdev) {
54                 pr_err("host1x devices registration failed\n");
55                 return NULL;
56         }
57 #endif
58         return pdev;
59 }
60
61 /* XXX: EDP is not functionally tested yet */
62 static struct resource vcm30_t124_disp1_resources[] = {
63         {
64                 .name   = "irq",
65                 .start  = INT_DISPLAY_GENERAL,
66                 .end    = INT_DISPLAY_GENERAL,
67                 .flags  = IORESOURCE_IRQ,
68         },
69         {
70                 .name   = "regs",
71                 .start  = TEGRA_DISPLAY_BASE,
72                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
73                 .flags  = IORESOURCE_MEM,
74         },
75         {
76                 .name   = "fbmem",
77                 .start  = 0, /* Filled in by vcm30_t124_panel_init() */
78                 .end    = 0, /* Filled in by vcm30_t124_panel_init() */
79                 .flags  = IORESOURCE_MEM,
80         },
81         {
82                 .name   = "mipi_cal",
83                 .start  = TEGRA_MIPI_CAL_BASE,
84                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
85                 .flags  = IORESOURCE_MEM,
86         },
87         {
88                 .name   = "sor",
89                 .start  = TEGRA_SOR_BASE,
90                 .end    = TEGRA_SOR_BASE + TEGRA_SOR_SIZE - 1,
91                 .flags  = IORESOURCE_MEM,
92         },
93         {
94                 .name   = "dpaux",
95                 .start  = TEGRA_DPAUX_BASE,
96                 .end    = TEGRA_DPAUX_BASE + TEGRA_DPAUX_SIZE - 1,
97                 .flags  = IORESOURCE_MEM,
98         },
99         {
100                 .name   = "irq_dp",
101                 .start  = INT_DPAUX,
102                 .end    = INT_DPAUX,
103                 .flags  = IORESOURCE_IRQ,
104         },
105 };
106
107 static struct tegra_fb_data vcm30_t124_disp1_fb_data = {
108         .win            = 0,
109         .bits_per_pixel = 32,
110 };
111
112 static struct tegra_dc_out vcm30_t124_disp1_out = {
113         .type           = TEGRA_DC_OUT_DP,
114 };
115
116 static struct tegra_dc_platform_data vcm30_t124_disp1_pdata = {
117         .flags          = TEGRA_DC_FLAG_ENABLED,
118         .default_out    = &vcm30_t124_disp1_out,
119         .fb             = &vcm30_t124_disp1_fb_data,
120         .emc_clk_rate   = 204000000,
121 #ifdef CONFIG_TEGRA_DC_CMU
122         .cmu_enable     = 1,
123 #endif
124 };
125
126 static struct platform_device vcm30_t124_disp1_device = {
127         .name           = "tegradc",
128         .id             = 0,
129         .resource       = vcm30_t124_disp1_resources,
130         .num_resources  = ARRAY_SIZE(vcm30_t124_disp1_resources),
131         .dev = {
132                 .platform_data = &vcm30_t124_disp1_pdata,
133         },
134 };
135
136 static struct resource vcm30_t124_disp2_resources[] = {
137         {
138                 .name   = "irq",
139                 .start  = INT_DISPLAY_B_GENERAL,
140                 .end    = INT_DISPLAY_B_GENERAL,
141                 .flags  = IORESOURCE_IRQ,
142         },
143         {
144                 .name   = "regs",
145                 .start  = TEGRA_DISPLAY2_BASE,
146                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
147                 .flags  = IORESOURCE_MEM,
148         },
149         {
150                 .name   = "fbmem",
151                 .start  = 0, /* Filled in by tegra_init_hdmi() */
152                 .end    = 0, /* Filled in by tegra_init_hdmi() */
153                 .flags  = IORESOURCE_MEM,
154         },
155         {
156                 .name   = "hdmi_regs",
157                 .start  = TEGRA_HDMI_BASE,
158                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
159                 .flags  = IORESOURCE_MEM,
160         },
161 };
162
163 static int vcm30_t124_hdmi_enable(struct device *dev)
164 {
165         return 0;
166 }
167
168 static int vcm30_t124_hdmi_disable(void)
169 {
170         return 0;
171 }
172
173 static int vcm30_t124_hdmi_postsuspend(void)
174 {
175         return 0;
176 }
177
178 static int vcm30_t124_hdmi_hotplug_init(struct device *dev)
179 {
180         return 0;
181 }
182
183 /* XXX: These values are taken from ardbeg. To be fixed after VCM char */
184 struct tmds_config vcm30_t124_tmds_config[] = {
185         { /* 480p/576p / 25.2MHz/27MHz modes */
186         .pclk = 27000000,
187         .pll0 = 0x01003110,
188         .pll1 = 0x00300F00,
189         .pe_current = 0x08080808,
190         .drive_current = 0x2e2e2e2e,
191         .peak_current = 0x00000000,
192         },
193         { /* 720p / 74.25MHz modes */
194         .pclk = 74250000,
195         .pll0 =  0x01003310,
196         .pll1 = 0x10300F00,
197         .pe_current = 0x08080808,
198         .drive_current = 0x20202020,
199         .peak_current = 0x00000000,
200         },
201         { /* 1080p / 148.5MHz modes */
202         .pclk = 148500000,
203         .pll0 = 0x01003310,
204         .pll1 = 0x10300F00,
205         .pe_current = 0x08080808,
206         .drive_current = 0x20202020,
207         .peak_current = 0x00000000,
208         },
209         {
210         .pclk = INT_MAX,
211         .pll0 = 0x01003310,
212         .pll1 = 0x10300F00,
213         .pe_current = 0x08080808,
214         .drive_current = 0x3A353536, /* lane3 needs a slightly lower current */
215         .peak_current = 0x00000000,
216         },
217 };
218
219 struct tegra_hdmi_out vcm30_t124_hdmi_out = {
220         .tmds_config = vcm30_t124_tmds_config,
221         .n_tmds_config = ARRAY_SIZE(vcm30_t124_tmds_config),
222 };
223
224 #define VCM30_T124_HDMI_HPD  TEGRA_GPIO_PN7
225 static struct tegra_dc_out vcm30_t124_disp2_out = {
226         .type           = TEGRA_DC_OUT_HDMI,
227         .flags          = TEGRA_DC_OUT_HOTPLUG_LOW |
228                           TEGRA_DC_OUT_NVHDCP_POLICY_ON_DEMAND,
229         .parent_clk     = "pll_d2",
230
231         .dcc_bus        = 3,
232         .hotplug_gpio   = VCM30_T124_HDMI_HPD,
233         .hdmi_out       = &vcm30_t124_hdmi_out,
234
235         /* TODO: update max pclk to POR */
236         .max_pixclock   = KHZ2PICOS(297000),
237
238         .align          = TEGRA_DC_ALIGN_MSB,
239         .order          = TEGRA_DC_ORDER_RED_BLUE,
240
241         .enable         = vcm30_t124_hdmi_enable,
242         .disable        = vcm30_t124_hdmi_disable,
243         .postsuspend    = vcm30_t124_hdmi_postsuspend,
244         .hotplug_init   = vcm30_t124_hdmi_hotplug_init,
245 };
246
247 static struct tegra_fb_data vcm30_t124_disp2_fb_data = {
248         .win            = 0,
249         .xres           = 1280,
250         .yres           = 720,
251         .bits_per_pixel = 32,
252 };
253
254 static struct tegra_dc_platform_data vcm30_t124_disp2_pdata = {
255         .default_out    = &vcm30_t124_disp2_out,
256         .fb             = &vcm30_t124_disp2_fb_data,
257         .emc_clk_rate   = 300000000,
258 };
259
260 static struct platform_device vcm30_t124_disp2_device = {
261         .name           = "tegradc",
262         .id             = 1,
263         .resource       = vcm30_t124_disp2_resources,
264         .num_resources  = ARRAY_SIZE(vcm30_t124_disp2_resources),
265         .dev = {
266                 .platform_data = &vcm30_t124_disp2_pdata,
267         },
268 };
269
270 static struct nvmap_platform_carveout vcm30_t124_carveouts[] = {
271         [0] = {
272                 .name           = "iram",
273                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
274                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
275                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
276         },
277         [1] = {
278                 .name           = "generic-0",
279                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
280                 .base           = 0, /* Filled in by vcm30_t124_panel_init() */
281                 .size           = 0, /* Filled in by vcm30_t124_panel_init() */
282         },
283         [2] = {
284                 .name           = "vpr",
285                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
286                 .base           = 0, /* Filled in by vcm30_t124_panel_init() */
287                 .size           = 0, /* Filled in by vcm30_t124_panel_init() */
288         },
289 };
290
291 static struct nvmap_platform_data vcm30_t124_nvmap_data = {
292         .carveouts      = vcm30_t124_carveouts,
293         .nr_carveouts   = ARRAY_SIZE(vcm30_t124_carveouts),
294 };
295 static struct platform_device vcm30_t124_nvmap_device  = {
296         .name   = "tegra-nvmap",
297         .id     = -1,
298         .dev    = {
299                 .platform_data = &vcm30_t124_nvmap_data,
300         },
301 };
302
303 int __init vcm30_t124_panel_init(void)
304 {
305         int err = 0;
306         struct resource *res;
307         struct platform_device *phost1x = NULL;
308
309 #ifdef CONFIG_TEGRA_NVMAP
310         vcm30_t124_carveouts[1].base = tegra_carveout_start;
311         vcm30_t124_carveouts[1].size = tegra_carveout_size;
312         vcm30_t124_carveouts[2].base = tegra_vpr_start;
313         vcm30_t124_carveouts[2].size = tegra_vpr_size;
314
315         err = platform_device_register(&vcm30_t124_nvmap_device);
316         if (err) {
317                 pr_err("nvmap device registration failed\n");
318                 return err;
319         }
320 #endif
321
322         phost1x = vcm30_t124_host1x_init();
323         if (!phost1x) {
324                 pr_err("host1x devices registration failed\n");
325                 return -EINVAL;
326         }
327
328         res = platform_get_resource_byname(&vcm30_t124_disp1_device,
329                                          IORESOURCE_MEM, "fbmem");
330         res->start = tegra_fb_start;
331         res->end = tegra_fb_start + tegra_fb_size - 1;
332
333         /* Copy the bootloader fb to the fb. */
334         __tegra_move_framebuffer(&vcm30_t124_nvmap_device,
335                 tegra_fb_start, tegra_bootloader_fb_start,
336                         min(tegra_fb_size, tegra_bootloader_fb_size));
337
338         vcm30_t124_disp1_device.dev.parent = &phost1x->dev;
339         err = platform_device_register(&vcm30_t124_disp1_device);
340         if (err) {
341                 pr_err("disp1 device registration failed\n");
342                 return err;
343         }
344
345         err = tegra_init_hdmi(&vcm30_t124_disp2_device, phost1x);
346         if (err)
347                 return err;
348
349 #ifdef CONFIG_TEGRA_NVAVP
350         nvavp_device.dev.parent = &phost1x->dev;
351         err = platform_device_register(&nvavp_device);
352         if (err) {
353                 pr_err("nvavp device registration failed\n");
354                 return err;
355         }
356 #endif
357         return err;
358 }