arm: tegra: pluto: Fix panel cold boot failure
[linux-2.6.git] / arch / arm / mach-tegra / board-pluto-panel.c
1 /*
2  * arch/arm/mach-tegra/board-pluto-panel.c
3  *
4  * Copyright (c) 2011-2012, 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 #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
30 #include <mach/irqs.h>
31 #include <mach/iomap.h>
32 #include <mach/dc.h>
33
34 #include "board.h"
35 #include "devices.h"
36 #include "gpio-names.h"
37
38 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
39 #include "tegra3_host1x_devices.h"
40 #else
41 #include "tegra11_host1x_devices.h"
42 #endif
43
44 #define TEGRA_PANEL_ENABLE      1
45
46 #if TEGRA_PANEL_ENABLE
47 #define IS_EXTERNAL_PWM         1
48
49 /* PANEL_<diagonal length in inches>_<vendor name>_<resolution> */
50 #define PANEL_5_LG_720_1280     1
51 #define PANEL_4_7_JDI_720_1280  0
52
53 #define DSI_PANEL_RESET         1
54 #define DSI_PANEL_RST_GPIO      TEGRA_GPIO_PH5
55 #define DSI_PANEL_BL_EN_GPIO    TEGRA_GPIO_PH2
56
57 #define DC_CTRL_MODE    TEGRA_DC_OUT_CONTINUOUS_MODE
58
59 static atomic_t sd_brightness = ATOMIC_INIT(255);
60
61 static bool dsi_reg_requested;
62 static bool dsi_gpio_requested;
63
64 /* for PANEL_5_LG_720_1280 and PANEL_4_7_JDI_720_1280 */
65 static struct regulator *vdd_lcd_s_1v8;
66 static struct regulator *vdd_sys_bl_3v7;
67 static struct regulator *avdd_lcd_3v0_2v8;
68
69 /* for PANEL_5_LG_720_1280 */
70 static struct regulator *avdd_ts_3v0;
71
72 /* hdmi pins for hotplug */
73 #define pluto_hdmi_hpd          TEGRA_GPIO_PN7
74
75 /* hdmi related regulators */
76 #ifdef CONFIG_TEGRA_DC
77 static struct regulator *pluto_hdmi_vddio;
78 #endif
79
80 static struct resource pluto_disp1_resources[] __initdata = {
81         {
82                 .name   = "irq",
83                 .start  = INT_DISPLAY_GENERAL,
84                 .end    = INT_DISPLAY_GENERAL,
85                 .flags  = IORESOURCE_IRQ,
86         },
87         {
88                 .name   = "regs",
89                 .start  = TEGRA_DISPLAY_BASE,
90                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
91                 .flags  = IORESOURCE_MEM,
92         },
93         {
94                 .name   = "fbmem",
95                 .start  = 0, /* Filled in by pluto_panel_init() */
96                 .end    = 0, /* Filled in by pluto_panel_init() */
97                 .flags  = IORESOURCE_MEM,
98         },
99         {
100                 .name   = "dsi_regs",
101                 .start  = TEGRA_DSI_BASE,
102                 .end    = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
103                 .flags  = IORESOURCE_MEM,
104         },
105 };
106
107 static struct resource pluto_disp2_resources[] __initdata = {
108         {
109                 .name   = "irq",
110                 .start  = INT_DISPLAY_B_GENERAL,
111                 .end    = INT_DISPLAY_B_GENERAL,
112                 .flags  = IORESOURCE_IRQ,
113         },
114         {
115                 .name   = "regs",
116                 .start  = TEGRA_DISPLAY2_BASE,
117                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
118                 .flags  = IORESOURCE_MEM,
119         },
120         {
121                 .name   = "fbmem",
122                 .start  = 0, /* Filled in by pluto_panel_init() */
123                 .end    = 0, /* Filled in by pluto_panel_init() */
124                 .flags  = IORESOURCE_MEM,
125         },
126         {
127                 .name   = "hdmi_regs",
128                 .start  = TEGRA_HDMI_BASE,
129                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
130                 .flags  = IORESOURCE_MEM,
131         },
132 };
133
134 #if PANEL_5_LG_720_1280
135 static u8 panel_dsi_config[] = {0xe0, 0x43, 0x0, 0x80, 0x0, 0x0};
136 static u8 panel_disp_ctrl1[] = {0xb5, 0x34, 0x20, 0x40, 0x0, 0x20};
137 static u8 panel_disp_ctrl2[] = {0xb6, 0x04, 0x74, 0x0f, 0x16, 0x13};
138 static u8 panel_internal_clk[] = {0xc0, 0x01, 0x08};
139 static u8 panel_pwr_ctrl3[] =
140         {0xc3, 0x0, 0x09, 0x10, 0x02, 0x0, 0x66, 0x20, 0x13, 0x0};
141 static u8 panel_pwr_ctrl4[] = {0xc4, 0x23, 0x24, 0x17, 0x17, 0x59};
142 static u8 panel_positive_gamma_red[] =
143         {0xd0, 0x21, 0x13, 0x67, 0x37, 0x0c, 0x06, 0x62, 0x23, 0x03};
144 static u8 panel_negetive_gamma_red[] =
145         {0xd1, 0x32, 0x13, 0x66, 0x37, 0x02, 0x06, 0x62, 0x23, 0x03};
146 static u8 panel_positive_gamma_green[] =
147         {0xd2, 0x41, 0x14, 0x56, 0x37, 0x0c, 0x06, 0x62, 0x23, 0x03};
148 static u8 panel_negetive_gamma_green[] =
149         {0xd3, 0x52, 0x14, 0x55, 0x37, 0x02, 0x06, 0x62, 0x23, 0x03};
150 static u8 panel_positive_gamma_blue[] =
151         {0xd4, 0x41, 0x14, 0x56, 0x37, 0x0c, 0x06, 0x62, 0x23, 0x03};
152 static u8 panel_negetive_gamma_blue[] =
153         {0xd5, 0x52, 0x14, 0x55, 0x37, 0x02, 0x06, 0x62, 0x23, 0x03};
154 static u8 panel_ce2[] = {0x71, 0x0, 0x0, 0x01, 0x01};
155 static u8 panel_ce3[] = {0x72, 0x01, 0x0e};
156 static u8 panel_ce4[] = {0x73, 0x34, 0x52, 0x0};
157 static u8 panel_ce5[] = {0x74, 0x05, 0x0, 0x06};
158 static u8 panel_ce6[] = {0x75, 0x03, 0x0, 0x07};
159 static u8 panel_ce7[] = {0x76, 0x07, 0x0, 0x06};
160 static u8 panel_ce8[] = {0x77, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f};
161 static u8 panel_ce9[] = {0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
162 static u8 panel_ce10[] =
163         {0x79, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
164 static u8 panel_ce11[] = {0x7a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
165 static u8 panel_ce12[] = {0x7b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
166 static u8 panel_ce13[] = {0x7c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
167 #endif
168
169 static struct tegra_dsi_cmd dsi_init_cmd[] = {
170 #if PANEL_5_LG_720_1280
171         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_dsi_config),
172
173         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_disp_ctrl1),
174         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_disp_ctrl2),
175
176         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_internal_clk),
177
178         /*  panel power control 1 */
179         DSI_CMD_SHORT(DSI_GENERIC_SHORT_WRITE_2_PARAMS, 0xc1, 0x0),
180         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_pwr_ctrl3),
181         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_pwr_ctrl4),
182
183         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_positive_gamma_red),
184         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_negetive_gamma_red),
185         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_positive_gamma_green),
186         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_negetive_gamma_green),
187         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_positive_gamma_blue),
188         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_negetive_gamma_blue),
189
190         DSI_CMD_SHORT(DSI_DCS_WRITE_1_PARAM, DSI_DCS_SET_ADDR_MODE, 0x08),
191
192         /* panel OTP 2 */
193         DSI_CMD_SHORT(DSI_GENERIC_SHORT_WRITE_2_PARAMS, 0xf9, 0x0),
194
195         /* panel CE 1 */
196         DSI_CMD_SHORT(DSI_GENERIC_SHORT_WRITE_2_PARAMS, 0x70, 0x0),
197         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce2),
198         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce3),
199         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce4),
200         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce5),
201         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce6),
202         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce7),
203         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce8),
204         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce9),
205         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce10),
206         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce11),
207         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce12),
208         DSI_CMD_LONG(DSI_GENERIC_LONG_WRITE, panel_ce13),
209
210         /* panel power control 2 */
211         DSI_CMD_SHORT(DSI_GENERIC_SHORT_WRITE_2_PARAMS, 0xc2, 0x02),
212         DSI_DLY_MS(15),
213         /* panel power control 2 */
214         DSI_CMD_SHORT(DSI_GENERIC_SHORT_WRITE_2_PARAMS, 0xc2, 0x06),
215         DSI_DLY_MS(15),
216         /* panel power control 2 */
217         DSI_CMD_SHORT(DSI_GENERIC_SHORT_WRITE_2_PARAMS, 0xc2, 0x4e),
218         DSI_DLY_MS(85),
219
220         DSI_CMD_SHORT(DSI_DCS_WRITE_0_PARAM, DSI_DCS_EXIT_SLEEP_MODE, 0x0),
221         DSI_DLY_MS(15),
222
223         /* panel OTP 2 */
224         DSI_CMD_SHORT(DSI_GENERIC_SHORT_WRITE_2_PARAMS, 0xf9, 0x80),
225         DSI_DLY_MS(15),
226
227         DSI_CMD_SHORT(DSI_DCS_WRITE_0_PARAM, DSI_DCS_SET_DISPLAY_ON, 0x0),
228 #endif
229 #if PANEL_4_7_JDI_720_1280
230         DSI_CMD_SHORT(DSI_DCS_WRITE_0_PARAM, DSI_DCS_EXIT_SLEEP_MODE, 0x00),
231         DSI_DLY_MS(15),
232         DSI_CMD_SHORT(DSI_DCS_WRITE_0_PARAM, DSI_DCS_SET_DISPLAY_ON, 0x00),
233 #endif
234 };
235
236 static struct tegra_dsi_out pluto_dsi = {
237 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
238         .n_data_lanes = 2,
239         .controller_vs = DSI_VS_0,
240         .dsi_instance = DSI_INSTANCE_0,
241 #else
242 #if PANEL_4_7_JDI_720_1280
243         .n_data_lanes = 3,
244         .dsi_instance = DSI_INSTANCE_1,
245 #else
246         .n_data_lanes = 4,
247         .dsi_instance = DSI_INSTANCE_0,
248 #endif
249         .controller_vs = DSI_VS_1,
250 #endif
251         .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
252         .refresh_rate = 60,
253         .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
254
255         .panel_reset = DSI_PANEL_RESET,
256         .power_saving_suspend = true,
257 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
258         .video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
259 #else
260         .video_data_type = TEGRA_DSI_VIDEO_TYPE_VIDEO_MODE,
261         .video_clock_mode = TEGRA_DSI_VIDEO_CLOCK_CONTINUOUS,
262         .video_burst_mode = TEGRA_DSI_VIDEO_NONE_BURST_MODE_WITH_SYNC_END,
263 #endif
264         .dsi_init_cmd = dsi_init_cmd,
265         .n_init_cmd = ARRAY_SIZE(dsi_init_cmd),
266 };
267
268 static int pluto_dsi_regulator_get(void)
269 {
270         int err = 0;
271
272         if (dsi_reg_requested)
273                 return 0;
274
275 #if PANEL_5_LG_720_1280
276         avdd_ts_3v0 = regulator_get(NULL, "avdd_ts_3v0");
277         if (IS_ERR_OR_NULL(avdd_ts_3v0)) {
278                 pr_err("avdd_ts_3v0 regulator get failed\n");
279                 err = PTR_ERR(avdd_ts_3v0);
280                 avdd_ts_3v0 = NULL;
281                 goto fail;
282         }
283 #endif
284 #if PANEL_5_LG_720_1280 || PANEL_4_7_JDI_720_1280
285         avdd_lcd_3v0_2v8 = regulator_get(NULL, "avdd_lcd");
286         if (IS_ERR_OR_NULL(avdd_lcd_3v0_2v8)) {
287                 pr_err("avdd_lcd regulator get failed\n");
288                 err = PTR_ERR(avdd_lcd_3v0_2v8);
289                 avdd_lcd_3v0_2v8 = NULL;
290                 goto fail;
291         }
292
293         vdd_lcd_s_1v8 = regulator_get(NULL, "vdd_lcd_1v8_s");
294         if (IS_ERR_OR_NULL(vdd_lcd_s_1v8)) {
295                 pr_err("vdd_lcd_1v8_s regulator get failed\n");
296                 err = PTR_ERR(vdd_lcd_s_1v8);
297                 vdd_lcd_s_1v8 = NULL;
298                 goto fail;
299         }
300
301         vdd_sys_bl_3v7 = regulator_get(NULL, "vdd_sys_bl");
302         if (IS_ERR_OR_NULL(vdd_sys_bl_3v7)) {
303                 pr_err("vdd_sys_bl regulator get failed\n");
304                 err = PTR_ERR(vdd_sys_bl_3v7);
305                 vdd_sys_bl_3v7 = NULL;
306                 goto fail;
307         }
308 #endif
309         dsi_reg_requested = true;
310         return 0;
311 fail:
312         return err;
313 }
314
315 static int pluto_dsi_gpio_get(void)
316 {
317         int err = 0;
318
319         if (dsi_gpio_requested)
320                 return 0;
321
322         err = gpio_request(DSI_PANEL_RST_GPIO, "panel rst");
323         if (err < 0) {
324                 pr_err("panel reset gpio request failed\n");
325                 goto fail;
326         }
327
328         err = gpio_request(DSI_PANEL_BL_EN_GPIO, "panel backlight");
329         if (err < 0) {
330                 pr_err("panel backlight gpio request failed\n");
331                 goto fail;
332         }
333
334         dsi_gpio_requested = true;
335         return 0;
336 fail:
337         return err;
338 }
339
340 static int pluto_dsi_panel_enable(void)
341 {
342         int err = 0;
343
344         err = pluto_dsi_regulator_get();
345         if (err < 0) {
346                 pr_err("dsi regulator get failed\n");
347                 goto fail;
348         }
349
350         err = pluto_dsi_gpio_get();
351         if (err < 0) {
352                 pr_err("dsi gpio request failed\n");
353                 goto fail;
354         }
355
356         if (avdd_lcd_3v0_2v8) {
357                 err = regulator_enable(avdd_lcd_3v0_2v8);
358                 if (err < 0) {
359                         pr_err("avdd_lcd regulator enable failed\n");
360                         goto fail;
361                 }
362 #if PANEL_5_LG_720_1280
363                 regulator_set_voltage(avdd_lcd_3v0_2v8, 2800000, 2800000);
364 #endif
365 #if PANEL_4_7_JDI_720_1280
366                 regulator_set_voltage(avdd_lcd_3v0_2v8, 3000000, 3000000);
367 #endif
368         }
369
370         if (avdd_ts_3v0) {
371                 err = regulator_enable(avdd_ts_3v0);
372                 if (err < 0) {
373                         pr_err("avdd_ts_3v0 regulator enable failed\n");
374                         goto fail;
375                 }
376         }
377
378         if (vdd_lcd_s_1v8) {
379                 err = regulator_enable(vdd_lcd_s_1v8);
380                 if (err < 0) {
381                         pr_err("vdd_lcd_1v8_s regulator enable failed\n");
382                         goto fail;
383                 }
384         }
385
386         if (vdd_sys_bl_3v7) {
387                 err = regulator_enable(vdd_sys_bl_3v7);
388                 if (err < 0) {
389                         pr_err("vdd_sys_bl regulator enable failed\n");
390                         goto fail;
391                 }
392         }
393
394 #if DSI_PANEL_RESET
395         gpio_direction_output(DSI_PANEL_RST_GPIO, 1);
396         usleep_range(1000, 5000);
397         gpio_set_value(DSI_PANEL_RST_GPIO, 0);
398         usleep_range(1000, 5000);
399         gpio_set_value(DSI_PANEL_RST_GPIO, 1);
400         msleep(20);
401 #endif
402         gpio_direction_output(DSI_PANEL_BL_EN_GPIO, 1);
403         gpio_direction_output(TEGRA_GPIO_PH1, 1);
404
405         return 0;
406 fail:
407         return err;
408 }
409
410 static int pluto_dsi_panel_disable(void)
411 {
412         gpio_set_value(DSI_PANEL_BL_EN_GPIO, 0);
413
414         if (vdd_sys_bl_3v7)
415                 regulator_disable(vdd_sys_bl_3v7);
416
417         if (vdd_lcd_s_1v8)
418                 regulator_disable(vdd_lcd_s_1v8);
419
420         if (avdd_ts_3v0)
421                 regulator_disable(avdd_ts_3v0);
422
423         if (avdd_lcd_3v0_2v8)
424                 regulator_disable(avdd_lcd_3v0_2v8);
425
426         return 0;
427 }
428
429 static int pluto_dsi_panel_postsuspend(void)
430 {
431         /* TODO */
432         return 0;
433 }
434
435 static struct tegra_dc_mode pluto_dsi_modes[] = {
436 #if PANEL_5_LG_720_1280
437         {
438                 .pclk = 10000000,
439                 .h_ref_to_sync = 4,
440                 .v_ref_to_sync = 1,
441                 .h_sync_width = 4,
442                 .v_sync_width = 4,
443                 .h_back_porch = 82,
444                 .v_back_porch = 7,
445                 .h_active = 720,
446                 .v_active = 1280,
447                 .h_front_porch = 4,
448                 .v_front_porch = 20,
449         },
450 #endif
451 #if PANEL_4_7_JDI_720_1280
452         {
453                 .pclk = 10000000,
454                 .h_ref_to_sync = 4,
455                 .v_ref_to_sync = 1,
456                 .h_sync_width = 16,
457                 .v_sync_width = 4,
458                 .h_back_porch = 32,
459                 .v_back_porch = 4,
460                 .h_active = 720,
461                 .v_active = 1280,
462                 .h_front_porch = 48,
463                 .v_front_porch = 4,
464         },
465 #endif
466 };
467
468 static struct tegra_dc_out pluto_disp1_out = {
469         .type           = TEGRA_DC_OUT_DSI,
470         .dsi            = &pluto_dsi,
471
472         .flags          = DC_CTRL_MODE,
473
474         .modes          = pluto_dsi_modes,
475         .n_modes        = ARRAY_SIZE(pluto_dsi_modes),
476
477         .enable         = pluto_dsi_panel_enable,
478         .disable        = pluto_dsi_panel_disable,
479         .postsuspend    = pluto_dsi_panel_postsuspend,
480
481 #if PANEL_5_LG_720_1280
482         .width          = 62,
483         .height         = 110,
484 #endif
485 #if PANEL_4_7_JDI_720_1280
486         .width = 58,
487         .height = 103,
488 #endif
489 };
490
491 static int pluto_hdmi_enable(void)
492 {
493         /* TODO */
494         return 0;
495 }
496
497 static int pluto_hdmi_disable(void)
498 {
499         /* TODO */
500         return 0;
501 }
502
503 static int pluto_hdmi_postsuspend(void)
504 {
505         if (pluto_hdmi_vddio) {
506                 regulator_disable(pluto_hdmi_vddio);
507                 regulator_put(pluto_hdmi_vddio);
508                 pluto_hdmi_vddio = NULL;
509         }
510         return 0;
511 }
512
513 static int pluto_hdmi_hotplug_init(void)
514 {
515         int ret = 0;
516         if (!pluto_hdmi_vddio) {
517                 pluto_hdmi_vddio = regulator_get(NULL, "vdd_hdmi_5v0");
518                 if (IS_ERR_OR_NULL(pluto_hdmi_vddio)) {
519                         ret = PTR_ERR(pluto_hdmi_vddio);
520                         pr_err("hdmi: couldn't get regulator vdd_hdmi_5v0\n");
521                         pluto_hdmi_vddio = NULL;
522                         return ret;
523                 }
524         }
525         ret = regulator_enable(pluto_hdmi_vddio);
526         if (ret < 0) {
527                 pr_err("hdmi: couldn't enable regulator vdd_hdmi_5v0\n");
528                 regulator_put(pluto_hdmi_vddio);
529                 pluto_hdmi_vddio = NULL;
530                 return ret;
531         }
532         return ret;
533 }
534
535 static struct tegra_dc_out pluto_disp2_out = {
536         .type           = TEGRA_DC_OUT_HDMI,
537         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
538         .parent_clk     = "pll_d2_out0",
539
540         .dcc_bus        = 3,
541         .hotplug_gpio   = pluto_hdmi_hpd,
542
543         .max_pixclock   = KHZ2PICOS(148500),
544
545         .enable         = pluto_hdmi_enable,
546         .disable        = pluto_hdmi_disable,
547         .postsuspend    = pluto_hdmi_postsuspend,
548         .hotplug_init   = pluto_hdmi_hotplug_init,
549 };
550
551 static struct tegra_fb_data pluto_disp1_fb_data = {
552         .win            = 0,
553         .bits_per_pixel = 32,
554         .flags          = TEGRA_FB_FLIP_ON_PROBE,
555 #if PANEL_5_LG_720_1280 || PANEL_4_7_JDI_720_1280
556         .xres           = 720,
557         .yres           = 1280,
558 #endif
559 };
560
561 static struct tegra_dc_platform_data pluto_disp1_pdata = {
562         .flags          = TEGRA_DC_FLAG_ENABLED,
563         .default_out    = &pluto_disp1_out,
564         .fb             = &pluto_disp1_fb_data,
565         .emc_clk_rate   = 204000000,
566 };
567
568 static struct tegra_fb_data pluto_disp2_fb_data = {
569         .win            = 0,
570         .xres           = 1024,
571         .yres           = 600,
572         .bits_per_pixel = 32,
573         .flags          = TEGRA_FB_FLIP_ON_PROBE,
574 };
575
576 static struct tegra_dc_platform_data pluto_disp2_pdata = {
577         .flags          = TEGRA_DC_FLAG_ENABLED,
578         .default_out    = &pluto_disp2_out,
579         .fb             = &pluto_disp2_fb_data,
580         .emc_clk_rate   = 300000000,
581 };
582
583 static struct nvhost_device pluto_disp2_device __initdata = {
584         .name           = "tegradc",
585         .id             = 1,
586         .resource       = pluto_disp2_resources,
587         .num_resources  = ARRAY_SIZE(pluto_disp2_resources),
588         .dev = {
589                 .platform_data = &pluto_disp2_pdata,
590         },
591 };
592
593 static struct nvhost_device pluto_disp1_device __initdata = {
594         .name           = "tegradc",
595         .id             = 0,
596         .resource       = pluto_disp1_resources,
597         .num_resources  = ARRAY_SIZE(pluto_disp1_resources),
598         .dev = {
599                 .platform_data = &pluto_disp1_pdata,
600         },
601 };
602
603 static struct nvmap_platform_carveout pluto_carveouts[] = {
604         [0] = {
605                 .name           = "iram",
606                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
607                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
608                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
609                 .buddy_size     = 0, /* no buddy allocation for IRAM */
610         },
611         [1] = {
612                 .name           = "generic-0",
613                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
614                 .base           = 0, /* Filled in by pluto_panel_init() */
615                 .size           = 0, /* Filled in by pluto_panel_init() */
616                 .buddy_size     = SZ_32K,
617         },
618         [2] = {
619                 .name           = "vpr",
620                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
621                 .base           = 0, /* Filled in by pluto_panel_init() */
622                 .size           = 0, /* Filled in by pluto_panel_init() */
623                 .buddy_size     = SZ_32K,
624         },
625 };
626
627 static struct nvmap_platform_data pluto_nvmap_data = {
628         .carveouts      = pluto_carveouts,
629         .nr_carveouts   = ARRAY_SIZE(pluto_carveouts),
630 };
631
632 static struct platform_device pluto_nvmap_device __initdata = {
633         .name   = "tegra-nvmap",
634         .id     = -1,
635         .dev    = {
636                 .platform_data = &pluto_nvmap_data,
637         },
638 };
639
640 static int pluto_disp1_bl_notify(struct device *unused, int brightness)
641 {
642         int cur_sd_brightness = atomic_read(&sd_brightness);
643
644         /* SD brightness is a percentage */
645         brightness = (brightness * cur_sd_brightness) / 255;
646
647         /* Apply any backlight response curve */
648         if (brightness > 255)
649                 pr_info("Error: Brightness > 255!\n");
650         else
651                 /* TODO: backlight response LUT */
652                 brightness = brightness;
653
654         return brightness;
655 }
656
657 static int pluto_disp1_check_fb(struct device *dev, struct fb_info *info)
658 {
659         return info->device == &pluto_disp1_device.dev;
660 }
661
662 static struct platform_tegra_pwm_backlight_data pluto_disp1_bl_data = {
663         .which_dc               = 0,
664         .which_pwm              = TEGRA_PWM_PM1,
665         .gpio_conf_to_sfio      = TEGRA_GPIO_PH1,
666         .max_brightness         = 255,
667         .dft_brightness         = 224,
668         .notify                 = pluto_disp1_bl_notify,
669         .period                 = 0x3F,
670         .clk_div                = 0x3FF,
671         .clk_select             = 0,
672         /* Only toggle backlight on fb blank notifications for disp1 */
673         .check_fb               = pluto_disp1_check_fb,
674 };
675
676 static struct platform_device __maybe_unused pluto_disp1_bl_device __initdata = {
677         .name   = "tegra-pwm-bl",
678         .id     = -1,
679         .dev    = {
680                 .platform_data = &pluto_disp1_bl_data,
681         },
682 };
683
684 int __init pluto_panel_init(void)
685 {
686         int err = 0;
687         struct resource __maybe_unused *res;
688
689 #ifdef CONFIG_TEGRA_NVMAP
690         pluto_carveouts[1].base = tegra_carveout_start;
691         pluto_carveouts[1].size = tegra_carveout_size;
692         pluto_carveouts[2].base = tegra_vpr_start;
693         pluto_carveouts[2].size = tegra_vpr_size;
694
695         err = platform_device_register(&pluto_nvmap_device);
696         if (err) {
697                 pr_err("nvmap device registration failed\n");
698                 return err;
699         }
700 #endif
701         gpio_request(pluto_hdmi_hpd, "hdmi_hpd");
702         gpio_direction_input(pluto_hdmi_hpd);
703
704 #ifdef CONFIG_TEGRA_GRHOST
705 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
706         err = tegra3_register_host1x_devices();
707 #else
708         err = tegra11_register_host1x_devices();
709 #endif
710         if (err) {
711                 pr_err("host1x devices registration failed\n");
712                 return err;
713         }
714
715 #ifdef CONFIG_TEGRA_DC
716         res = nvhost_get_resource_byname(&pluto_disp1_device,
717                                          IORESOURCE_MEM, "fbmem");
718         res->start = tegra_fb_start;
719         res->end = tegra_fb_start + tegra_fb_size - 1;
720
721         res = nvhost_get_resource_byname(&pluto_disp2_device,
722                                          IORESOURCE_MEM, "fbmem");
723         res->start = tegra_fb2_start;
724         res->end = tegra_fb2_start + tegra_fb2_size - 1;
725
726         err = nvhost_device_register(&pluto_disp1_device);
727         if (err) {
728                 pr_err("disp1 device registration failed\n");
729                 return err;
730         }
731
732         err = nvhost_device_register(&pluto_disp2_device);
733         if (err) {
734                 pr_err("disp2 device registration failed\n");
735                 return err;
736         }
737
738 #if !IS_EXTERNAL_PWM
739         err = platform_device_register(&pluto_disp1_bl_device);
740         if (err) {
741                 pr_err("disp1 bl device registration failed");
742                 return err;
743         }
744 #endif
745 #endif
746
747 #ifdef CONFIG_TEGRA_NVAVP
748         err = nvhost_device_register(&nvavp_device);
749         if (err) {
750                 pr_err("nvavp device registration failed\n");
751                 return err;
752         }
753 #endif
754 #endif
755         return err;
756 }
757 #else
758 int __init pluto_panel_init(void)
759 {
760         return -ENODEV;
761 }
762 #endif