arm: tegra: remove __initdata keyword for nvmap_device
[linux-3.10.git] / arch / arm / mach-tegra / board-ardbeg-panel.c
1 /*
2  * arch/arm/mach-tegra/board-ardbeg-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/tegra_pwm_bl.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/pwm_backlight.h>
30 #include <linux/of.h>
31
32 #include <mach/irqs.h>
33 #include <mach/dc.h>
34
35 #include "board.h"
36 #include "devices.h"
37 #include "gpio-names.h"
38 #include "board-ardbeg.h"
39 #include "board-panel.h"
40 #include "common.h"
41 #include "iomap.h"
42
43 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
44 #include "tegra11_host1x_devices.h"
45 #else
46 #include "tegra12_host1x_devices.h"
47 #endif
48
49 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
50 #define DSI_PANEL_RST_GPIO      TEGRA_GPIO_PH3
51 #define DSI_PANEL_BL_PWM_GPIO   TEGRA_GPIO_PH1
52 #else
53 /* TODO: update gpio for t124 ardbeg */
54 #define DSI_PANEL_RST_GPIO      TEGRA_GPIO_PH3
55 #define DSI_PANEL_BL_PWM_GPIO   TEGRA_GPIO_PH1
56 #endif
57
58 struct platform_device * __init ardbeg_host1x_init(void)
59 {
60         struct platform_device *pdev = NULL;
61
62 #ifdef CONFIG_TEGRA_GRHOST
63         if (!of_have_populated_dt()) {
64 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
65                 pdev = tegra11_register_host1x_devices();
66 #else
67                 pdev = tegra12_register_host1x_devices();
68 #endif
69         } else {
70                 pdev = to_platform_device(bus_find_device_by_name(
71                         &platform_bus_type, NULL, "host1x"));
72         }
73
74         if (!pdev) {
75                 pr_err("host1x devices registration failed\n");
76                 return NULL;
77         }
78 #endif
79         return pdev;
80 }
81
82 #ifdef CONFIG_TEGRA_DC
83
84 /* HDMI Hotplug detection pin */
85 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
86 #define ardbeg_hdmi_hpd TEGRA_GPIO_PN7
87 #else
88 /* TODO: update for t124 ardbeg */
89 #define ardbeg_hdmi_hpd TEGRA_GPIO_PN7
90 #endif
91
92 /* hdmi related regulators */
93 static struct regulator *ardbeg_hdmi_vddio;
94
95 static struct resource ardbeg_disp1_resources[] = {
96         {
97                 .name   = "irq",
98                 .start  = INT_DISPLAY_GENERAL,
99                 .end    = INT_DISPLAY_GENERAL,
100                 .flags  = IORESOURCE_IRQ,
101         },
102         {
103                 .name   = "regs",
104                 .start  = TEGRA_DISPLAY_BASE,
105                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
106                 .flags  = IORESOURCE_MEM,
107         },
108         {
109                 .name   = "fbmem",
110                 .start  = 0, /* Filled in by ardbeg_panel_init() */
111                 .end    = 0, /* Filled in by ardbeg_panel_init() */
112                 .flags  = IORESOURCE_MEM,
113         },
114         {
115                 .name   = "ganged_dsia_regs",
116                 .start  = 0, /* Filled in the panel file by init_resources() */
117                 .end    = 0, /* Filled in the panel file by init_resources() */
118                 .flags  = IORESOURCE_MEM,
119         },
120         {
121                 .name   = "ganged_dsib_regs",
122                 .start  = 0, /* Filled in the panel file by init_resources() */
123                 .end    = 0, /* Filled in the panel file by init_resources() */
124                 .flags  = IORESOURCE_MEM,
125         },
126         {
127                 .name   = "dsi_regs",
128                 .start  = 0, /* Filled in the panel file by init_resources() */
129                 .end    = 0, /* Filled in the panel file by init_resources() */
130                 .flags  = IORESOURCE_MEM,
131         },
132         {
133                 .name   = "mipi_cal",
134                 .start  = TEGRA_MIPI_CAL_BASE,
135                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
136                 .flags  = IORESOURCE_MEM,
137         },
138 };
139
140 static struct resource ardbeg_disp2_resources[] = {
141         {
142                 .name   = "irq",
143                 .start  = INT_DISPLAY_B_GENERAL,
144                 .end    = INT_DISPLAY_B_GENERAL,
145                 .flags  = IORESOURCE_IRQ,
146         },
147         {
148                 .name   = "regs",
149                 .start  = TEGRA_DISPLAY2_BASE,
150                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
151                 .flags  = IORESOURCE_MEM,
152         },
153         {
154                 .name   = "fbmem",
155                 .start  = 0, /* Filled in by ardbeg_panel_init() */
156                 .end    = 0, /* Filled in by ardbeg_panel_init() */
157                 .flags  = IORESOURCE_MEM,
158         },
159         {
160                 .name   = "hdmi_regs",
161                 .start  = TEGRA_HDMI_BASE,
162                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
163                 .flags  = IORESOURCE_MEM,
164         },
165 };
166
167
168 static struct tegra_dc_sd_settings sd_settings;
169
170 static struct tegra_dc_out ardbeg_disp1_out = {
171         .type           = TEGRA_DC_OUT_DSI,
172         .sd_settings    = &sd_settings,
173 };
174
175 static int ardbeg_hdmi_enable(struct device *dev)
176 {
177         /* TODO */
178         return 0;
179 }
180
181 static int ardbeg_hdmi_disable(void)
182 {
183         /* TODO */
184         return 0;
185 }
186
187 static int ardbeg_hdmi_postsuspend(void)
188 {
189         if (ardbeg_hdmi_vddio) {
190                 regulator_disable(ardbeg_hdmi_vddio);
191                 regulator_put(ardbeg_hdmi_vddio);
192                 ardbeg_hdmi_vddio = NULL;
193         }
194         return 0;
195 }
196
197 static int ardbeg_hdmi_hotplug_init(struct device *dev)
198 {
199         if (!ardbeg_hdmi_vddio) {
200                 ardbeg_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
201                 if (WARN_ON(IS_ERR(ardbeg_hdmi_vddio))) {
202                         pr_err("%s: couldn't get regulator vdd_hdmi_5v0: %ld\n",
203                                 __func__, PTR_ERR(ardbeg_hdmi_vddio));
204                                 ardbeg_hdmi_vddio = NULL;
205                 } else {
206                         regulator_enable(ardbeg_hdmi_vddio);
207                 }
208         }
209
210         return 0;
211 }
212
213 static struct tegra_dc_out ardbeg_disp2_out = {
214         .type           = TEGRA_DC_OUT_HDMI,
215         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
216         .parent_clk     = "pll_d2_out0",
217
218         .dcc_bus        = 3,
219         .hotplug_gpio   = ardbeg_hdmi_hpd,
220
221         /* TODO: update max pclk to POR */
222         .max_pixclock   = KHZ2PICOS(297000),
223
224         .align          = TEGRA_DC_ALIGN_MSB,
225         .order          = TEGRA_DC_ORDER_RED_BLUE,
226
227         .enable         = ardbeg_hdmi_enable,
228         .disable        = ardbeg_hdmi_disable,
229         .postsuspend    = ardbeg_hdmi_postsuspend,
230         .hotplug_init   = ardbeg_hdmi_hotplug_init,
231 };
232
233 static struct tegra_fb_data ardbeg_disp1_fb_data = {
234         .win            = 0,
235         .bits_per_pixel = 32,
236         .flags          = TEGRA_FB_FLIP_ON_PROBE,
237 };
238
239 static struct tegra_dc_platform_data ardbeg_disp1_pdata = {
240         .flags          = TEGRA_DC_FLAG_ENABLED,
241         .default_out    = &ardbeg_disp1_out,
242         .fb             = &ardbeg_disp1_fb_data,
243         .emc_clk_rate   = 204000000,
244 #ifdef CONFIG_TEGRA_DC_CMU
245         .cmu_enable     = 1,
246 #endif
247 };
248
249 static struct tegra_fb_data ardbeg_disp2_fb_data = {
250         .win            = 0,
251         .xres           = 1280,
252         .yres           = 720,
253         .bits_per_pixel = 32,
254         .flags          = TEGRA_FB_FLIP_ON_PROBE,
255 };
256
257 static struct tegra_dc_platform_data ardbeg_disp2_pdata = {
258         .flags          = TEGRA_DC_FLAG_ENABLED,
259         .default_out    = &ardbeg_disp2_out,
260         .fb             = &ardbeg_disp2_fb_data,
261         .emc_clk_rate   = 300000000,
262 };
263
264 static struct platform_device ardbeg_disp2_device = {
265         .name           = "tegradc",
266         .id             = 1,
267         .resource       = ardbeg_disp2_resources,
268         .num_resources  = ARRAY_SIZE(ardbeg_disp2_resources),
269         .dev = {
270                 .platform_data = &ardbeg_disp2_pdata,
271         },
272 };
273
274 static struct platform_device ardbeg_disp1_device = {
275         .name           = "tegradc",
276         .id             = 0,
277         .resource       = ardbeg_disp1_resources,
278         .num_resources  = ARRAY_SIZE(ardbeg_disp1_resources),
279         .dev = {
280                 .platform_data = &ardbeg_disp1_pdata,
281         },
282 };
283
284 static struct nvmap_platform_carveout ardbeg_carveouts[] = {
285         [0] = {
286                 .name           = "iram",
287                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
288                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
289                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
290                 .buddy_size     = 0, /* no buddy allocation for IRAM */
291         },
292         [1] = {
293                 .name           = "generic-0",
294                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
295                 .base           = 0, /* Filled in by ardbeg_panel_init() */
296                 .size           = 0, /* Filled in by ardbeg_panel_init() */
297                 .buddy_size     = SZ_32K,
298         },
299         [2] = {
300                 .name           = "vpr",
301                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
302                 .base           = 0, /* Filled in by ardbeg_panel_init() */
303                 .size           = 0, /* Filled in by ardbeg_panel_init() */
304                 .buddy_size     = SZ_32K,
305         },
306 };
307
308 static struct nvmap_platform_data ardbeg_nvmap_data = {
309         .carveouts      = ardbeg_carveouts,
310         .nr_carveouts   = ARRAY_SIZE(ardbeg_carveouts),
311 };
312 static struct platform_device ardbeg_nvmap_device  = {
313         .name   = "tegra-nvmap",
314         .id     = -1,
315         .dev    = {
316                 .platform_data = &ardbeg_nvmap_data,
317         },
318 };
319
320 static struct tegra_dc_sd_settings ardbeg_sd_settings = {
321         .enable = 1, /* enabled by default. */
322         .use_auto_pwm = false,
323         .hw_update_delay = 0,
324         .bin_width = -1,
325         .aggressiveness = 5,
326         .use_vid_luma = false,
327         .phase_in_adjustments = 0,
328         .k_limit_enable = true,
329         .k_limit = 200,
330         .sd_window_enable = false,
331         .soft_clipping_enable = true,
332         /* Low soft clipping threshold to compensate for aggressive k_limit */
333         .soft_clipping_threshold = 128,
334         .smooth_k_enable = false,
335         .smooth_k_incr = 64,
336         /* Default video coefficients */
337         .coeff = {5, 9, 2},
338         .fc = {0, 0},
339         /* Immediate backlight changes */
340         .blp = {1024, 255},
341         /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
342         /* Default BL TF */
343         .bltf = {
344                         {
345                                 {57, 65, 73, 82},
346                                 {92, 103, 114, 125},
347                                 {138, 150, 164, 178},
348                                 {193, 208, 224, 241},
349                         },
350                 },
351         /* Default LUT */
352         .lut = {
353                         {
354                                 {255, 255, 255},
355                                 {199, 199, 199},
356                                 {153, 153, 153},
357                                 {116, 116, 116},
358                                 {85, 85, 85},
359                                 {59, 59, 59},
360                                 {36, 36, 36},
361                                 {17, 17, 17},
362                                 {0, 0, 0},
363                         },
364                 },
365         .sd_brightness = &sd_brightness,
366         .use_vpulse2 = true,
367 };
368
369 static void ardbeg_panel_select(void)
370 {
371         struct tegra_panel *panel = NULL;
372         struct board_info board;
373         u8 dsi_instance;
374
375         tegra_get_display_board_info(&board);
376
377         switch (board.board_id) {
378         case BOARD_E1639:
379                 panel = &dsi_s_wqxga_10_1;
380                 dsi_instance = DSI_INSTANCE_0;
381                 break;
382         case BOARD_E1627:
383         /* fall through */
384         default:
385                 panel = &dsi_p_wuxga_10_1;
386                 dsi_instance = DSI_INSTANCE_0;
387                 break;
388         }
389
390         if (panel) {
391                 if (panel->init_sd_settings)
392                         panel->init_sd_settings(&sd_settings);
393
394                 if (panel->init_dc_out) {
395                         panel->init_dc_out(&ardbeg_disp1_out);
396                         ardbeg_disp1_out.dsi->dsi_instance = dsi_instance;
397                         ardbeg_disp1_out.dsi->dsi_panel_rst_gpio =
398                                 DSI_PANEL_RST_GPIO;
399                         ardbeg_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
400                                 DSI_PANEL_BL_PWM_GPIO;
401                 }
402
403                 if (panel->init_fb_data)
404                         panel->init_fb_data(&ardbeg_disp1_fb_data);
405
406                 if (panel->init_cmu_data)
407                         panel->init_cmu_data(&ardbeg_disp1_pdata);
408
409                 if (panel->set_disp_device)
410                         panel->set_disp_device(&ardbeg_disp1_device);
411
412                 tegra_dsi_resources_init(dsi_instance, ardbeg_disp1_resources,
413                         ARRAY_SIZE(ardbeg_disp1_resources));
414
415                 if (panel->register_bl_dev)
416                         panel->register_bl_dev();
417
418                 if (panel->register_i2c_bridge)
419                         panel->register_i2c_bridge();
420         }
421
422 }
423 int __init ardbeg_panel_init(void)
424 {
425         int err = 0;
426         struct resource __maybe_unused *res;
427         struct platform_device *phost1x = NULL;
428
429         sd_settings = ardbeg_sd_settings;
430
431         ardbeg_panel_select();
432
433 #ifdef CONFIG_TEGRA_NVMAP
434         ardbeg_carveouts[1].base = tegra_carveout_start;
435         ardbeg_carveouts[1].size = tegra_carveout_size;
436         ardbeg_carveouts[2].base = tegra_vpr_start;
437         ardbeg_carveouts[2].size = tegra_vpr_size;
438
439         err = platform_device_register(&ardbeg_nvmap_device);
440         if (err) {
441                 pr_err("nvmap device registration failed\n");
442                 return err;
443         }
444 #endif
445
446         phost1x = ardbeg_host1x_init();
447         if (!phost1x) {
448                 pr_err("host1x devices registration failed\n");
449                 return -EINVAL;
450         }
451
452         res = platform_get_resource_byname(&ardbeg_disp1_device,
453                                          IORESOURCE_MEM, "fbmem");
454         res->start = tegra_fb_start;
455         res->end = tegra_fb_start + tegra_fb_size - 1;
456
457         /* Copy the bootloader fb to the fb. */
458         __tegra_move_framebuffer(&ardbeg_nvmap_device,
459                 tegra_fb_start, tegra_bootloader_fb_start,
460                         min(tegra_fb_size, tegra_bootloader_fb_size));
461
462         res = platform_get_resource_byname(&ardbeg_disp2_device,
463                                          IORESOURCE_MEM, "fbmem");
464
465         res->start = tegra_fb2_start;
466         res->end = tegra_fb2_start + tegra_fb2_size - 1;
467
468         ardbeg_disp1_device.dev.parent = &phost1x->dev;
469         err = platform_device_register(&ardbeg_disp1_device);
470         if (err) {
471                 pr_err("disp1 device registration failed\n");
472                 return err;
473         }
474
475         ardbeg_disp2_device.dev.parent = &phost1x->dev;
476         err = platform_device_register(&ardbeg_disp2_device);
477         if (err) {
478                 pr_err("disp2 device registration failed\n");
479                 return err;
480         }
481
482 #ifdef CONFIG_TEGRA_NVAVP
483         nvavp_device.dev.parent = &phost1x->dev;
484         err = platform_device_register(&nvavp_device);
485         if (err) {
486                 pr_err("nvavp device registration failed\n");
487                 return err;
488         }
489 #endif
490         return err;
491 }
492 #else
493 int __init ardbeg_panel_init(void)
494 {
495         if (ardbeg_host1x_init())
496                 return 0;
497         else
498                 return -EINVAL;
499 }
500 #endif