ARM: tegra: powermon: Fix copyrights from GPLv3 to GPLv2
[linux-3.10.git] / arch / arm / mach-tegra / board-pluto-panel.c
1 /*
2  * arch/arm/mach-tegra/board-pluto-panel.c
3  *
4  * Copyright (C) 2012-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 version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 #include <linux/ioport.h>
20 #include <linux/fb.h>
21 #include <linux/nvmap.h>
22 #include <linux/nvhost.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/gpio.h>
26 #include <linux/tegra_pwm_bl.h>
27 #include <linux/regulator/consumer.h>
28 #include <linux/pwm_backlight.h>
29 #include <linux/i2c/pca953x.h>
30 #include <linux/of.h>
31 #include <mach/irqs.h>
32 #include <mach/dc.h>
33
34 #include "board.h"
35 #include "devices.h"
36 #include "gpio-names.h"
37 #include "board-pluto.h"
38 #include "board-panel.h"
39 #include "common.h"
40 #include "iomap.h"
41
42 #include "tegra11_host1x_devices.h"
43
44 #define DSI_PANEL_RST_GPIO      TEGRA_GPIO_PH5
45 #define DSI_PANEL_BL_EN_GPIO    TEGRA_GPIO_PH2
46 #define DSI_PANEL_BL_PWM_GPIO   TEGRA_GPIO_PH1
47
48 struct platform_device * __init pluto_host1x_init(void)
49 {
50         struct platform_device *pdev = NULL;
51
52 #ifdef CONFIG_TEGRA_GRHOST
53         if (!of_have_populated_dt())
54                 pdev = tegra11_register_host1x_devices();
55         else
56                 pdev = to_platform_device(bus_find_device_by_name(
57                         &platform_bus_type, NULL, "host1x"));
58 #endif
59         return pdev;
60 }
61
62
63 #ifdef CONFIG_TEGRA_DC
64
65 /* hdmi pins for hotplug */
66 #define pluto_hdmi_hpd          TEGRA_GPIO_PN7
67
68 /* hdmi related regulators */
69 static struct regulator *pluto_hdmi_vddio;
70 static struct regulator *pluto_hdmi_reg;
71 static struct regulator *pluto_hdmi_pll;
72
73 static struct resource pluto_disp1_resources[] = {
74         {
75                 .name   = "irq",
76                 .start  = INT_DISPLAY_GENERAL,
77                 .end    = INT_DISPLAY_GENERAL,
78                 .flags  = IORESOURCE_IRQ,
79         },
80         {
81                 .name   = "regs",
82                 .start  = TEGRA_DISPLAY_BASE,
83                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
84                 .flags  = IORESOURCE_MEM,
85         },
86         {
87                 .name   = "fbmem",
88                 .start  = 0, /* Filled in by pluto_panel_init() */
89                 .end    = 0, /* Filled in by pluto_panel_init() */
90                 .flags  = IORESOURCE_MEM,
91         },
92         {
93                 .name   = "dsi_regs",
94                 .start  = 0, /* Filled in the panel file by init_resources() */
95                 .end    = 0, /* Filled in the panel file by init_resources() */
96                 .flags  = IORESOURCE_MEM,
97         },
98         {
99                 .name   = "mipi_cal",
100                 .start  = TEGRA_MIPI_CAL_BASE,
101                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
102                 .flags  = IORESOURCE_MEM,
103         },
104 };
105
106 static struct resource pluto_disp2_resources[] = {
107         {
108                 .name   = "irq",
109                 .start  = INT_DISPLAY_B_GENERAL,
110                 .end    = INT_DISPLAY_B_GENERAL,
111                 .flags  = IORESOURCE_IRQ,
112         },
113         {
114                 .name   = "regs",
115                 .start  = TEGRA_DISPLAY2_BASE,
116                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
117                 .flags  = IORESOURCE_MEM,
118         },
119         {
120                 .name   = "fbmem",
121                 .start  = 0, /* Filled in by pluto_panel_init() */
122                 .end    = 0, /* Filled in by pluto_panel_init() */
123                 .flags  = IORESOURCE_MEM,
124         },
125         {
126                 .name   = "hdmi_regs",
127                 .start  = TEGRA_HDMI_BASE,
128                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
129                 .flags  = IORESOURCE_MEM,
130         },
131 };
132
133 static struct tegra_dc_sd_settings sd_settings;
134
135 static struct tegra_dc_out pluto_disp1_out = {
136         .type           = TEGRA_DC_OUT_DSI,
137         .sd_settings    = &sd_settings,
138 };
139
140 static int pluto_hdmi_enable(struct device *dev)
141 {
142         int ret;
143         if (!pluto_hdmi_reg) {
144                 pluto_hdmi_reg = regulator_get(dev, "avdd_hdmi");
145                 if (IS_ERR_OR_NULL(pluto_hdmi_reg)) {
146                         pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
147                         pluto_hdmi_reg = NULL;
148                         return PTR_ERR(pluto_hdmi_reg);
149                 }
150         }
151         ret = regulator_enable(pluto_hdmi_reg);
152         if (ret < 0) {
153                 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
154                 return ret;
155         }
156         if (!pluto_hdmi_pll) {
157                 pluto_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
158                 if (IS_ERR_OR_NULL(pluto_hdmi_pll)) {
159                         pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
160                         pluto_hdmi_pll = NULL;
161                         regulator_put(pluto_hdmi_reg);
162                         pluto_hdmi_reg = NULL;
163                         return PTR_ERR(pluto_hdmi_pll);
164                 }
165         }
166         ret = regulator_enable(pluto_hdmi_pll);
167         if (ret < 0) {
168                 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
169                 return ret;
170         }
171         return 0;
172 }
173
174 static int pluto_hdmi_disable(void)
175 {
176         if (pluto_hdmi_reg) {
177                 regulator_disable(pluto_hdmi_reg);
178                 regulator_put(pluto_hdmi_reg);
179                 pluto_hdmi_reg = NULL;
180         }
181
182         if (pluto_hdmi_pll) {
183                 regulator_disable(pluto_hdmi_pll);
184                 regulator_put(pluto_hdmi_pll);
185                 pluto_hdmi_pll = NULL;
186         }
187
188         return 0;
189 }
190
191 static int pluto_hdmi_postsuspend(void)
192 {
193         if (pluto_hdmi_vddio) {
194                 regulator_disable(pluto_hdmi_vddio);
195                 regulator_put(pluto_hdmi_vddio);
196                 pluto_hdmi_vddio = NULL;
197         }
198         return 0;
199 }
200
201 static int pluto_hdmi_hotplug_init(struct device *dev)
202 {
203         int ret = 0;
204         if (!pluto_hdmi_vddio) {
205                 pluto_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
206                 if (IS_ERR_OR_NULL(pluto_hdmi_vddio)) {
207                         ret = PTR_ERR(pluto_hdmi_vddio);
208                         pr_err("hdmi: couldn't get regulator vdd_hdmi_5v0\n");
209                         pluto_hdmi_vddio = NULL;
210                         return ret;
211                 }
212         }
213         ret = regulator_enable(pluto_hdmi_vddio);
214         if (ret < 0) {
215                 pr_err("hdmi: couldn't enable regulator vdd_hdmi_5v0\n");
216                 regulator_put(pluto_hdmi_vddio);
217                 pluto_hdmi_vddio = NULL;
218                 return ret;
219         }
220         return ret;
221 }
222
223 static struct tegra_dc_out pluto_disp2_out = {
224         .type           = TEGRA_DC_OUT_HDMI,
225         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
226         .parent_clk     = "pll_d2_out0",
227
228         .dcc_bus        = 3,
229         .hotplug_gpio   = pluto_hdmi_hpd,
230
231         .max_pixclock   = KHZ2PICOS(297000),
232
233         .enable         = pluto_hdmi_enable,
234         .disable        = pluto_hdmi_disable,
235         .postsuspend    = pluto_hdmi_postsuspend,
236         .hotplug_init   = pluto_hdmi_hotplug_init,
237 };
238
239 static struct tegra_fb_data pluto_disp1_fb_data = {
240         .win            = 0,
241         .bits_per_pixel = 32,
242         .flags          = TEGRA_FB_FLIP_ON_PROBE,
243 };
244
245 static struct tegra_dc_platform_data pluto_disp1_pdata = {
246         .flags          = TEGRA_DC_FLAG_ENABLED,
247         .default_out    = &pluto_disp1_out,
248         .fb             = &pluto_disp1_fb_data,
249         .emc_clk_rate   = 204000000,
250 #ifdef CONFIG_TEGRA_DC_CMU
251         .cmu_enable     = 1,
252 #endif
253 };
254
255 static struct tegra_fb_data pluto_disp2_fb_data = {
256         .win            = 0,
257         .xres           = 1024,
258         .yres           = 600,
259         .bits_per_pixel = 32,
260         .flags          = TEGRA_FB_FLIP_ON_PROBE,
261 };
262
263 static struct tegra_dc_platform_data pluto_disp2_pdata = {
264         .flags          = TEGRA_DC_FLAG_ENABLED,
265         .default_out    = &pluto_disp2_out,
266         .fb             = &pluto_disp2_fb_data,
267         .emc_clk_rate   = 300000000,
268 #ifdef CONFIG_TEGRA_DC_CMU
269         .cmu_enable     = 1,
270 #endif
271 };
272
273 static struct platform_device pluto_disp2_device = {
274         .name           = "tegradc",
275         .id             = 1,
276         .resource       = pluto_disp2_resources,
277         .num_resources  = ARRAY_SIZE(pluto_disp2_resources),
278         .dev = {
279                 .platform_data = &pluto_disp2_pdata,
280         },
281 };
282
283 static struct platform_device pluto_disp1_device = {
284         .name           = "tegradc",
285         .id             = 0,
286         .resource       = pluto_disp1_resources,
287         .num_resources  = ARRAY_SIZE(pluto_disp1_resources),
288         .dev = {
289                 .platform_data = &pluto_disp1_pdata,
290         },
291 };
292
293 static struct nvmap_platform_carveout pluto_carveouts[] = {
294         [0] = {
295                 .name           = "iram",
296                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
297                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
298                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
299                 .buddy_size     = 0, /* no buddy allocation for IRAM */
300         },
301         [1] = {
302                 .name           = "generic-0",
303                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
304                 .base           = 0, /* Filled in by pluto_panel_init() */
305                 .size           = 0, /* Filled in by pluto_panel_init() */
306                 .buddy_size     = SZ_32K,
307         },
308         [2] = {
309                 .name           = "vpr",
310                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
311                 .base           = 0, /* Filled in by pluto_panel_init() */
312                 .size           = 0, /* Filled in by pluto_panel_init() */
313                 .buddy_size     = SZ_32K,
314         },
315 };
316
317 static struct nvmap_platform_data pluto_nvmap_data = {
318         .carveouts      = pluto_carveouts,
319         .nr_carveouts   = ARRAY_SIZE(pluto_carveouts),
320 };
321
322 static struct platform_device pluto_nvmap_device = {
323         .name   = "tegra-nvmap",
324         .id     = -1,
325         .dev    = {
326                 .platform_data = &pluto_nvmap_data,
327         },
328 };
329
330 static struct tegra_dc_sd_settings pluto_sd_settings = {
331         .enable = 1, /* enabled by default */
332         .use_auto_pwm = false,
333         .hw_update_delay = 0,
334         .bin_width = -1,
335         .aggressiveness = 5,
336         .use_vid_luma = false,
337         .phase_in_adjustments = 0,
338         .k_limit_enable = true,
339         .k_limit = 180,
340         .sd_window_enable = false,
341         .soft_clipping_enable = true,
342         /* Low soft clipping threshold to compensate for aggressive k_limit */
343         .soft_clipping_threshold = 128,
344         .smooth_k_enable = true,
345         .smooth_k_incr = 4,
346         /* Default video coefficients */
347         .coeff = {5, 9, 2},
348         .fc = {0, 0},
349         /* Immediate backlight changes */
350         .blp = {1024, 255},
351         /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
352         /* Default BL TF */
353         .bltf = {
354                         {
355                                 {57, 65, 73, 82},
356                                 {92, 103, 114, 125},
357                                 {138, 150, 164, 178},
358                                 {193, 208, 224, 241},
359                         },
360                 },
361         /* Default LUT */
362         .lut = {
363                         {
364                                 {255, 255, 255},
365                                 {199, 199, 199},
366                                 {153, 153, 153},
367                                 {116, 116, 116},
368                                 {85, 85, 85},
369                                 {59, 59, 59},
370                                 {36, 36, 36},
371                                 {17, 17, 17},
372                                 {0, 0, 0},
373                         },
374                 },
375         .sd_brightness = &sd_brightness,
376         .use_vpulse2 = true,
377 };
378
379 static void pluto_panel_select(void)
380 {
381         struct tegra_panel *panel;
382         struct board_info board;
383         u8 dsi_instance = 0;
384
385         tegra_get_display_board_info(&board);
386
387         switch (board.board_id) {
388         case BOARD_E1605:
389                 panel = &dsi_j_720p_4_7;
390                 dsi_instance = DSI_INSTANCE_1;
391                 break;
392         case BOARD_E1577:
393                 panel = &dsi_s_1080p_5;
394                 break;
395         case BOARD_E1582:
396         default:
397                 if (tegra_get_board_panel_id()) {
398                         panel = &dsi_s_1080p_5;
399                         dsi_instance = DSI_INSTANCE_1;
400                 } else {
401                         panel = &dsi_l_720p_5;
402                         dsi_instance = DSI_INSTANCE_0;
403                 }
404                 break;
405         }
406
407         if (panel->init_sd_settings)
408                 panel->init_sd_settings(&sd_settings);
409
410         if (panel->init_dc_out) {
411                 panel->init_dc_out(&pluto_disp1_out);
412                 pluto_disp1_out.dsi->dsi_instance = dsi_instance;
413                 pluto_disp1_out.dsi->dsi_panel_rst_gpio = DSI_PANEL_RST_GPIO;
414                 pluto_disp1_out.dsi->dsi_panel_bl_en_gpio =
415                         DSI_PANEL_BL_EN_GPIO;
416                 pluto_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
417                         DSI_PANEL_BL_PWM_GPIO;
418                 /* update the init cmd if dependent on reset GPIO */
419                 tegra_dsi_update_init_cmd_gpio_rst(&pluto_disp1_out);
420         }
421
422         if (panel->init_fb_data)
423                 panel->init_fb_data(&pluto_disp1_fb_data);
424
425         if (panel->init_cmu_data)
426                 panel->init_cmu_data(&pluto_disp1_pdata);
427
428         if (panel->set_disp_device)
429                 panel->set_disp_device(&pluto_disp1_device);
430
431         tegra_dsi_resources_init(dsi_instance, pluto_disp1_resources,
432                 ARRAY_SIZE(pluto_disp1_resources));
433
434         if (panel->register_bl_dev)
435                 panel->register_bl_dev();
436
437 }
438 int __init pluto_panel_init(void)
439 {
440         int err = 0;
441         struct resource __maybe_unused *res;
442         struct platform_device *phost1x = NULL;
443
444         sd_settings = pluto_sd_settings;
445
446         pluto_panel_select();
447
448 #ifdef CONFIG_TEGRA_NVMAP
449         pluto_carveouts[1].base = tegra_carveout_start;
450         pluto_carveouts[1].size = tegra_carveout_size;
451         pluto_carveouts[2].base = tegra_vpr_start;
452         pluto_carveouts[2].size = tegra_vpr_size;
453
454         err = platform_device_register(&pluto_nvmap_device);
455         if (err) {
456                 pr_err("nvmap device registration failed\n");
457                 return err;
458         }
459 #endif
460         phost1x = pluto_host1x_init();
461         if (!phost1x) {
462                 pr_err("host1x devices registration failed\n");
463                 return -EINVAL;
464         }
465
466         res = platform_get_resource_byname(&pluto_disp1_device,
467                                          IORESOURCE_MEM, "fbmem");
468         res->start = tegra_fb_start;
469         res->end = tegra_fb_start + tegra_fb_size - 1;
470
471         /* Copy the bootloader fb to the fb. */
472         __tegra_move_framebuffer(&pluto_nvmap_device,
473                 tegra_fb_start, tegra_bootloader_fb_start,
474                         min(tegra_fb_size, tegra_bootloader_fb_size));
475
476         res = platform_get_resource_byname(&pluto_disp2_device,
477                                          IORESOURCE_MEM, "fbmem");
478
479         res->start = tegra_fb2_start;
480         res->end = tegra_fb2_start + tegra_fb2_size - 1;
481
482         pluto_disp1_device.dev.parent = &phost1x->dev;
483         err = platform_device_register(&pluto_disp1_device);
484         if (err) {
485                 pr_err("disp1 device registration failed\n");
486                 return err;
487         }
488
489         pluto_disp2_device.dev.parent = &phost1x->dev;
490         err = platform_device_register(&pluto_disp2_device);
491         if (err) {
492                 pr_err("disp2 device registration failed\n");
493                 return err;
494         }
495
496 #ifdef CONFIG_TEGRA_NVAVP
497         nvavp_device.dev.parent = &phost1x->dev;
498         err = platform_device_register(&nvavp_device);
499         if (err) {
500                 pr_err("nvavp device registration failed\n");
501                 return err;
502         }
503 #endif
504         return err;
505 }
506 #else
507 int __init pluto_panel_init(void)
508 {
509         if (pluto_host1x_init())
510                 return 0;
511         else
512                 return -EINVAL;
513 }
514 #endif