ARM: mach-tegra: Add LVDS panel support to bonaire
[linux-3.10.git] / arch / arm / mach-tegra / board-bonaire-panel.c
1 /*
2  * arch/arm/mach-tegra/board-bonaire-panel.c
3  *
4  * Copyright (c) 2013, 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 <linux/nvhost.h>
29 #include <linux/nvmap.h>
30 #include <mach/gpio-tegra.h>
31 #include <mach/irqs.h>
32 #include <mach/iomap.h>
33 #include <mach/dc.h>
34 #include <mach/fb.h>
35 #include <mach/hardware.h>
36
37 #include "board.h"
38 #include "board-bonaire.h"
39 #include "devices.h"
40 #include "gpio-names.h"
41 #include "tegra12_host1x_devices.h"
42
43 /* Select panel to be used. */
44 #define DSI_PANEL_219 0
45 #define DSI_PANEL_218 1
46 #define AVDD_LCD PMU_TCA6416_GPIO_PORT17
47 #define DSI_PANEL_RESET 0
48
49 #define bonaire_lvds_shutdown   TEGRA_GPIO_PB2
50 #define bonaire_bl_enb          TEGRA_GPIO_PW1
51 #define bonaire_bl_pwm          TEGRA_GPIO_PH0
52
53 #if defined(DSI_PANEL_219) || defined(DSI_PANEL_218)
54 #define bonaire_dsia_bl_enb     TEGRA_GPIO_PW1
55 #define bonaire_dsib_bl_enb     TEGRA_GPIO_PW0
56 #define bonaire_dsi_panel_reset TEGRA_GPIO_PD2
57 #endif
58
59 struct platform_device * __init bonaire_host1x_init(void)
60 {
61         struct platform_device *pdev = NULL;
62
63 #ifdef CONFIG_TEGRA_GRHOST
64         if (!of_have_populated_dt())
65                 pdev = tegra12_register_host1x_devices();
66         else
67                 pdev = to_platform_device(bus_find_device_by_name(
68                         &platform_bus_type, NULL, "host1x"));
69 #endif
70         return pdev;
71 }
72
73 static struct regulator *bonaire_dsi_reg;
74
75 static atomic_t sd_brightness = ATOMIC_INIT(255);
76
77 static int bonaire_backlight_init(struct device *dev)
78 {
79         int ret;
80
81 #ifndef CONFIG_TEGRA_BONAIRE_DSI
82
83         ret = gpio_request(bonaire_bl_enb, "backlight_enb");
84         if (ret < 0)
85                 return ret;
86
87         ret = gpio_direction_output(bonaire_bl_enb, 1);
88         if (ret < 0)
89                 gpio_free(bonaire_bl_enb);
90
91         return ret;
92 #endif
93
94 #if DSI_PANEL_219 || DSI_PANEL_218
95         /* Enable back light for DSIa panel */
96         printk("bonaire_dsi_backlight_init\n");
97         ret = gpio_request(bonaire_dsia_bl_enb, "dsia_bl_enable");
98         if (ret < 0)
99                 return ret;
100
101         ret = gpio_direction_output(bonaire_dsia_bl_enb, 1);
102         if (ret < 0)
103                 gpio_free(bonaire_dsia_bl_enb);
104
105         /* Enable back light for DSIb panel */
106         ret = gpio_request(bonaire_dsib_bl_enb, "dsib_bl_enable");
107         if (ret < 0)
108                 return ret;
109
110         ret = gpio_direction_output(bonaire_dsib_bl_enb, 1);
111         if (ret < 0)
112                 gpio_free(bonaire_dsib_bl_enb);
113
114 #endif
115
116         return ret;
117 };
118
119 static void bonaire_backlight_exit(struct device *dev)
120 {
121 #ifndef CONFIG_TEGRA_BONAIRE_DSI
122         gpio_set_value(bonaire_bl_enb, 0);
123         gpio_free(bonaire_bl_enb);
124
125         return;
126 #endif
127 #if DSI_PANEL_219 || DSI_PANEL_218
128         /* Disable back light for DSIa panel */
129         gpio_set_value(bonaire_dsia_bl_enb, 0);
130         gpio_free(bonaire_dsia_bl_enb);
131
132         /* Disable back light for DSIb panel */
133         gpio_set_value(bonaire_dsib_bl_enb, 0);
134         gpio_free(bonaire_dsib_bl_enb);
135
136         gpio_set_value(bonaire_lvds_shutdown, 1);
137         mdelay(20);
138 #endif
139 }
140
141 static int bonaire_backlight_notify(struct device *unused, int brightness)
142 {
143         int cur_sd_brightness = atomic_read(&sd_brightness);
144         int orig_brightness = brightness;
145
146 #ifndef CONFIG_TEGRA_BONAIRE_DSI
147         /* Set the backlight GPIO pin mode to 'backlight_enable' */
148         gpio_request(bonaire_bl_enb, "backlight_enb");
149         gpio_set_value(bonaire_bl_enb, !!brightness);
150         goto final;
151 #endif
152 #if DSI_PANEL_219 || DSI_PANEL_218
153         /* DSIa */
154         gpio_set_value(bonaire_dsia_bl_enb, !!brightness);
155
156         /* DSIb */
157         gpio_set_value(bonaire_dsib_bl_enb, !!brightness);
158 #endif
159
160 final:
161         /* SD brightness is a percentage, 8-bit value. */
162         brightness = (brightness * cur_sd_brightness) / 255;
163         if (cur_sd_brightness != 255) {
164                 printk("NVSD BL - in: %d, sd: %d, out: %d\n",
165                         orig_brightness, cur_sd_brightness, brightness);
166         }
167
168         return brightness;
169 }
170
171 static struct platform_pwm_backlight_data bonaire_backlight_data = {
172         .pwm_id         = 2,
173         .max_brightness = 255,
174         .dft_brightness = 224,
175         .pwm_period_ns  = 5000000,
176         .init           = bonaire_backlight_init,
177         .exit           = bonaire_backlight_exit,
178         .notify         = bonaire_backlight_notify,
179 };
180
181 static struct platform_device bonaire_backlight_device = {
182         .name   = "pwm-backlight",
183         .id     = -1,
184         .dev    = {
185                 .platform_data = &bonaire_backlight_data,
186         },
187 };
188
189 static int bonaire_panel_enable(struct device *dev)
190 {
191         static struct regulator *reg;
192
193         if (reg == NULL) {
194                 reg = regulator_get(NULL, "avdd_lvds");
195                 if (WARN_ON(IS_ERR(reg)))
196                         pr_err("%s: couldn't get regulator avdd_lvds: %ld\n",
197                                __func__, PTR_ERR(reg));
198                 else
199                         regulator_enable(reg);
200         }
201
202         gpio_set_value(bonaire_lvds_shutdown, 1);
203         return 0;
204 }
205
206 static int bonaire_panel_disable(void)
207 {
208         gpio_set_value(bonaire_lvds_shutdown, 0);
209         return 0;
210 }
211
212 #if defined(CONFIG_TEGRA_DP)
213 static struct tegra_dc_out_pin edp_out_pins[] = {
214         {
215                 .name   = TEGRA_DC_OUT_PIN_H_SYNC,
216                 .pol    = TEGRA_DC_OUT_PIN_POL_HIGH,
217         },
218         {
219                 .name   = TEGRA_DC_OUT_PIN_V_SYNC,
220                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
221         },
222         {
223                 .name   = TEGRA_DC_OUT_PIN_PIXEL_CLOCK,
224                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
225         },
226         {
227                 .name   = TEGRA_DC_OUT_PIN_DATA_ENABLE,
228                 .pol    = TEGRA_DC_OUT_PIN_POL_HIGH,
229         },
230 };
231 #endif
232
233 #if defined(CONFIG_TEGRA_LVDS)
234 static struct tegra_dc_out_pin lvds_out_pins[] = {
235         {
236                 .name   = TEGRA_DC_OUT_PIN_H_SYNC,
237                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
238         },
239         {
240                 .name   = TEGRA_DC_OUT_PIN_V_SYNC,
241                 .pol    = TEGRA_DC_OUT_PIN_POL_LOW,
242         },
243         {
244                 .name   = TEGRA_DC_OUT_PIN_PIXEL_CLOCK,
245                 .pol    = TEGRA_DC_OUT_PIN_POL_HIGH,
246         },
247         {
248                 .name   = TEGRA_DC_OUT_PIN_DATA_ENABLE,
249                 .pol    = TEGRA_DC_OUT_PIN_POL_HIGH,
250         },
251 };
252 #endif
253
254 static struct resource bonaire_disp1_resources[] = {
255         {
256                 .name   = "irq",
257                 .start  = INT_DISPLAY_GENERAL,
258                 .end    = INT_DISPLAY_GENERAL,
259                 .flags  = IORESOURCE_IRQ,
260         },
261         {
262                 .name   = "regs",
263                 .start  = TEGRA_DISPLAY_BASE,
264                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
265                 .flags  = IORESOURCE_MEM,
266         },
267         {
268                 .name   = "fbmem",
269                 .start  = 0,    /* Filled in by bonaire_panel_init() */
270                 .end    = 0,    /* Filled in by bonaire_panel_init() */
271                 .flags  = IORESOURCE_MEM,
272         },
273 #ifdef CONFIG_TEGRA_DSI_INSTANCE_1
274         {
275                 .name   = "dsi_regs",
276                 .start  = TEGRA_DSIB_BASE,
277                 .end    = TEGRA_DSIB_BASE + TEGRA_DSIB_SIZE - 1,
278                 .flags  = IORESOURCE_MEM,
279         },
280 #else
281         {
282                 .name   = "dsi_regs",
283                 .start  = TEGRA_DSI_BASE,
284                 .end    = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
285                 .flags  = IORESOURCE_MEM,
286         },
287 #endif
288 #if defined(CONFIG_TEGRA_DP) || defined(CONFIG_TEGRA_LVDS)
289         {
290                 .name   = "sor",
291                 .start  = TEGRA_SOR_BASE,
292                 .end    = TEGRA_SOR_BASE + TEGRA_SOR_SIZE - 1,
293                 .flags  = IORESOURCE_MEM,
294         },
295 #endif
296 #if defined(CONFIG_TEGRA_DP)
297         {
298                 .name   = "dpaux",
299                 .start  = TEGRA_DPAUX_BASE,
300                 .end    = TEGRA_DPAUX_BASE + TEGRA_DPAUX_SIZE - 1,
301                 .flags  = IORESOURCE_MEM,
302         },
303 #endif
304 };
305
306 static struct resource bonaire_disp2_resources[] = {
307         {
308                 .name   = "irq",
309                 .start  = INT_DISPLAY_B_GENERAL,
310                 .end    = INT_DISPLAY_B_GENERAL,
311                 .flags  = IORESOURCE_IRQ,
312         },
313         {
314                 .name   = "regs",
315                 .start  = TEGRA_DISPLAY2_BASE,
316                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE-1,
317                 .flags  = IORESOURCE_MEM,
318         },
319         {
320                 .name   = "fbmem",
321                 .start  = 0,    /* Filled in by bonaire_panel_init() */
322                 .end    = 0,    /* Filled in by bonaire_panel_init() */
323                 .flags  = IORESOURCE_MEM,
324         },
325 #ifdef CONFIG_TEGRA_DSI_INSTANCE_1
326         {
327                 .name   = "dsi_regs",
328                 .start  = TEGRA_DSIB_BASE,
329                 .end    = TEGRA_DSIB_BASE + TEGRA_DSIB_SIZE - 1,
330                 .flags  = IORESOURCE_MEM,
331         },
332 #else
333         {
334                 .name   = "dsi_regs",
335                 .start  = TEGRA_DSI_BASE,
336                 .end    = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
337                 .flags  = IORESOURCE_MEM,
338         },
339 #endif
340 #if defined(CONFIG_TEGRA_DP) || defined(CONFIG_TEGRA_LVDS)
341         {
342                 .name   = "sor",
343                 .start  = TEGRA_SOR_BASE,
344                 .end    = TEGRA_SOR_BASE + TEGRA_SOR_SIZE - 1,
345
346                 .flags  = IORESOURCE_MEM,
347         },
348 #endif
349 #if defined(CONFIG_TEGRA_DP)
350         {
351                 .name   = "dpaux",
352                 .start  = TEGRA_DPAUX_BASE,
353                 .end    = TEGRA_DPAUX_BASE + TEGRA_DPAUX_SIZE - 1,
354                 .flags  = IORESOURCE_MEM,
355         },
356 #endif
357 };
358
359 static struct tegra_dc_mode bonaire_panel_modes[] = {
360         {
361                 .pclk = 27000000,
362                 .h_ref_to_sync = 1,
363                 .v_ref_to_sync = 1,
364                 .h_sync_width = 34,
365                 .v_sync_width = 6,
366                 .h_back_porch = 64,
367                 .v_back_porch = 4,
368 #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
369                 .h_active = 120,
370                 .v_active = 160,
371 #else
372                 .h_active = 1366,
373                 .v_active = 768,
374 #endif
375                 .h_front_porch = 16,
376                 .v_front_porch = 2,
377         },
378 };
379
380 #if defined(CONFIG_TEGRA_LVDS)
381 static struct tegra_dc_mode bonaire_lvds_panel_modes[] = {
382         {
383                 .pclk          = 27000000,
384                 .h_ref_to_sync = 1,
385                 .v_ref_to_sync = 1,
386                 .h_sync_width  = 32,
387                 .v_sync_width  = 5,
388                 .h_back_porch  = 20,
389                 .v_back_porch  = 12,
390                 .h_active      = 1366,
391                 .v_active      = 768,
392                 .h_front_porch = 48,
393                 .v_front_porch = 3,
394         },
395 };
396 #endif
397
398 static struct tegra_fb_data bonaire_fb_data = {
399         .win            = 0,
400 #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
401         .xres           = 120,
402         .yres           = 160,
403         .bits_per_pixel = 16,
404         .flags          = 0,
405 #else
406         .xres           = 1366,
407         .yres           = 768,
408         .bits_per_pixel = 16,
409         .flags          = TEGRA_FB_FLIP_ON_PROBE,
410 #endif
411 };
412
413 static int bonaire_dsi_panel_enable(void)
414 {
415         int ret;
416
417         if (bonaire_dsi_reg == NULL) {
418                 bonaire_dsi_reg = regulator_get(NULL, "avdd_dsi_csi");
419                 if (IS_ERR_OR_NULL(bonaire_dsi_reg)) {
420                 pr_err("dsi: Could not get regulator avdd_dsi_csi\n");
421                         bonaire_dsi_reg = NULL;
422                         return PTR_ERR(bonaire_dsi_reg);
423                 }
424         }
425         regulator_enable(bonaire_dsi_reg);
426
427         ret = gpio_request(TEGRA_GPIO_PJ1, "DSI TE");
428         if (ret < 0)
429                 return ret;
430
431         ret = gpio_direction_input(TEGRA_GPIO_PJ1);
432         if (ret < 0) {
433                 gpio_free(TEGRA_GPIO_PJ1);
434                 return ret;
435         }
436
437
438 #if DSI_PANEL_219
439
440         ret = gpio_request(TEGRA_GPIO_PH0, "ph0");
441         if (ret < 0)
442                 return ret;
443         ret = gpio_direction_output(TEGRA_GPIO_PH0, 0);
444         if (ret < 0) {
445                 gpio_free(TEGRA_GPIO_PH0);
446                 return ret;
447         }
448
449         ret = gpio_request(TEGRA_GPIO_PH2, "ph2");
450         if (ret < 0)
451                 return ret;
452         ret = gpio_direction_output(TEGRA_GPIO_PH2, 0);
453         if (ret < 0) {
454                 gpio_free(TEGRA_GPIO_PH2);
455                 return ret;
456         }
457
458         ret = gpio_request(TEGRA_GPIO_PU2, "pu2");
459         if (ret < 0)
460                 return ret;
461         ret = gpio_direction_output(TEGRA_GPIO_PU2, 0);
462         if (ret < 0) {
463                 gpio_free(TEGRA_GPIO_PU2);
464                 return ret;
465         }
466
467         gpio_set_value(bonaire_lvds_shutdown, 1);
468         mdelay(20);
469         gpio_set_value(TEGRA_GPIO_PH0, 1);
470         mdelay(10);
471         gpio_set_value(TEGRA_GPIO_PH2, 1);
472         mdelay(15);
473         gpio_set_value(TEGRA_GPIO_PU2, 0);
474         gpio_set_value(TEGRA_GPIO_PU2, 1);
475         mdelay(10);
476         gpio_set_value(TEGRA_GPIO_PU2, 0);
477         mdelay(10);
478         gpio_set_value(TEGRA_GPIO_PU2, 1);
479         mdelay(15);
480 #endif
481
482 #if DSI_PANEL_218
483         printk("DSI_PANEL_218 is enabled\n");
484         ret = gpio_request(AVDD_LCD, "avdd_lcd");
485         if (ret < 0)
486                 gpio_free(AVDD_LCD);
487         ret = gpio_direction_output(AVDD_LCD, 1);
488         if (ret < 0)
489                 gpio_free(AVDD_LCD);
490
491
492 #if DSI_PANEL_RESET
493         ret = gpio_request(TEGRA_GPIO_PD2, "pd2");
494         if (ret < 0) {
495                 return ret;
496         }
497         ret = gpio_direction_output(TEGRA_GPIO_PD2, 0);
498         if (ret < 0) {
499                 gpio_free(TEGRA_GPIO_PD2);
500                 return ret;
501         }
502
503         gpio_set_value(TEGRA_GPIO_PD2, 1);
504         gpio_set_value(TEGRA_GPIO_PD2, 0);
505         mdelay(2);
506         gpio_set_value(TEGRA_GPIO_PD2, 1);
507         mdelay(2);
508 #endif
509 #endif
510
511         return 0;
512 }
513
514 static int bonaire_dsi_panel_disable(void)
515 {
516         int err;
517
518         err = 0;
519         printk(KERN_INFO "DSI panel disable\n");
520
521 #if DSI_PANEL_219
522         gpio_free(TEGRA_GPIO_PU2);
523         gpio_free(TEGRA_GPIO_PH2);
524         gpio_free(TEGRA_GPIO_PH0);
525         gpio_free(TEGRA_GPIO_PL2);
526 #endif
527
528 #if DSI_PANEL_218
529         gpio_free(TEGRA_GPIO_PD2);
530 #endif
531
532         return err;
533 }
534
535 static int bonaire_dsi_panel_postsuspend(void)
536 {
537         int err;
538
539         err = 0;
540         printk(KERN_INFO "DSI panel postsuspend\n");
541
542         if (bonaire_dsi_reg) {
543                 err = regulator_disable(bonaire_dsi_reg);
544                 if (err < 0)
545                         printk(KERN_ERR
546                         "DSI regulator avdd_dsi_csi disable failed\n");
547                 regulator_put(bonaire_dsi_reg);
548                 bonaire_dsi_reg = NULL;
549         }
550
551 #if DSI_PANEL_218
552         gpio_free(AVDD_LCD);
553 #endif
554
555         return err;
556 }
557
558 static struct tegra_dsi_cmd dsi_init_cmd[] = {
559         DSI_CMD_SHORT(0x05, 0x11, 0x00),
560         DSI_DLY_MS(150),
561         DSI_CMD_SHORT(0x05, 0x29, 0x00),
562         DSI_DLY_MS(20),
563 };
564
565 static struct tegra_dsi_cmd dsi_suspend_cmd[] = {
566         DSI_CMD_SHORT(0x05, 0x28, 0x00),
567         DSI_DLY_MS(20),
568         DSI_CMD_SHORT(0x05, 0x10, 0x00),
569         DSI_DLY_MS(5),
570 };
571
572 struct tegra_dsi_out bonaire_dsi = {
573         .n_data_lanes = 2,
574 #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
575         .pixel_format = TEGRA_DSI_PIXEL_FORMAT_16BIT_P,
576 #else
577         .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
578 #endif
579         .refresh_rate = 60,
580         .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
581
582         .panel_has_frame_buffer = true,
583 #ifdef CONFIG_TEGRA_DSI_INSTANCE_1
584         .dsi_instance = 1,
585 #else
586         .dsi_instance = 0,
587 #endif
588         .panel_reset = DSI_PANEL_RESET,
589
590         .n_init_cmd = ARRAY_SIZE(dsi_init_cmd),
591         .dsi_init_cmd = dsi_init_cmd,
592
593         .n_suspend_cmd = ARRAY_SIZE(dsi_suspend_cmd),
594         .dsi_suspend_cmd = dsi_suspend_cmd,
595
596 #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
597         .video_data_type = TEGRA_DSI_VIDEO_TYPE_VIDEO_MODE,
598 #else
599         .video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
600 #endif
601         .lp_cmd_mode_freq_khz = 430000,
602 };
603
604 static struct tegra_dc_mode bonaire_dsi_modes[] = {
605 #if DSI_PANEL_219
606         {
607                 .pclk = 10000000,
608                 .h_ref_to_sync = 4,
609                 .v_ref_to_sync = 1,
610                 .h_sync_width = 16,
611                 .v_sync_width = 1,
612                 .h_back_porch = 32,
613                 .v_back_porch = 1,
614                 .h_active = 540,
615                 .v_active = 960,
616                 .h_front_porch = 32,
617                 .v_front_porch = 2,
618         },
619 #endif
620
621 #if DSI_PANEL_218
622         {
623                 .pclk = 323000000,
624                 .h_ref_to_sync = 11,
625                 .v_ref_to_sync = 1,
626                 .h_sync_width = 16,
627                 .v_sync_width = 4,
628                 .h_back_porch = 16,
629                 .v_back_porch = 4,
630 #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
631                 .h_active = 320,
632                 .v_active = 240,
633 #else
634                 .h_active = 864,
635                 .v_active = 480,
636 #endif
637                 .h_front_porch = 16,
638                 .v_front_porch = 4,
639         },
640 #endif
641
642 };
643
644 static struct tegra_fb_data bonaire_dsi_fb_data = {
645 #if DSI_PANEL_219
646         .win            = 0,
647         .xres           = 540,
648         .yres           = 960,
649         .bits_per_pixel = 32,
650 #endif
651
652 #if DSI_PANEL_218
653         .win            = 0,
654 #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
655         .xres           = 320,
656         .yres           = 240,
657         .bits_per_pixel = 16,
658 #else
659         .xres           = 864,
660         .yres           = 480,
661         .bits_per_pixel = 32,
662 #endif
663 #endif
664 };
665
666 static struct tegra_dc_out bonaire_disp_out = {
667         .align          = TEGRA_DC_ALIGN_MSB,
668         .order          = TEGRA_DC_ORDER_RED_BLUE,
669         .flags          = TEGRA_DC_OUT_CONTINUOUS_MODE,
670 #if defined (CONFIG_TEGRA_DC_TEMPORAL_DITHER) /* mds hack */
671         .dither         = TEGRA_DC_TEMPORAL_DITHER,
672 #endif
673
674 #if defined(CONFIG_TEGRA_DP)
675         .type           = TEGRA_DC_OUT_DP,
676
677         .modes          = bonaire_panel_modes,
678         .n_modes        = ARRAY_SIZE(bonaire_panel_modes),
679         .out_pins       = edp_out_pins,
680         .n_out_pins     = ARRAY_SIZE(edp_out_pins),
681 #elif defined(CONFIG_TEGRA_LVDS)
682         .type           = TEGRA_DC_OUT_LVDS,
683
684         .modes          = bonaire_lvds_panel_modes,
685         .n_modes        = ARRAY_SIZE(bonaire_lvds_panel_modes),
686         .out_pins       = lvds_out_pins,
687         .n_out_pins     = ARRAY_SIZE(lvds_out_pins),
688 #elif defined(CONFIG_TEGRA_BONAIRE_DSI)
689         .type           = TEGRA_DC_OUT_DSI,
690
691         .modes          = bonaire_dsi_modes,
692         .n_modes        = ARRAY_SIZE(bonaire_dsi_modes),
693
694         .dsi            = &bonaire_dsi,
695
696         .enable         = bonaire_dsi_panel_enable,
697         .disable        = bonaire_dsi_panel_disable,
698         .postsuspend    = bonaire_dsi_panel_postsuspend,
699 #else
700         .type           = TEGRA_DC_OUT_RGB,
701
702         .modes          = bonaire_panel_modes,
703         .n_modes        = ARRAY_SIZE(bonaire_panel_modes),
704
705         .enable         = bonaire_panel_enable,
706         .disable        = bonaire_panel_disable,
707 #endif
708 };
709
710 static struct tegra_dc_platform_data bonaire_disp_pdata = {
711         .flags          = TEGRA_DC_FLAG_ENABLED,
712         .default_out    = &bonaire_disp_out,
713         .emc_clk_rate   = 300000000,
714 #ifndef CONFIG_TEGRA_BONAIRE_DSI
715         .fb             = &bonaire_fb_data,
716 #else
717         .fb             = &bonaire_dsi_fb_data,
718 #endif
719 };
720
721 static struct platform_device bonaire_disp1_device = {
722         .name           = "tegradc",
723         .id             = 0,
724         .resource       = bonaire_disp1_resources,
725         .num_resources  = ARRAY_SIZE(bonaire_disp1_resources),
726         .dev = {
727                 .platform_data = &bonaire_disp_pdata,
728         },
729 };
730
731 static struct platform_device bonaire_disp2_device = {
732         .name           = "tegradc",
733         .id             = 1,
734         .resource       = bonaire_disp2_resources,
735         .num_resources  = ARRAY_SIZE(bonaire_disp2_resources),
736         .dev = {
737                 .platform_data = &bonaire_disp_pdata,
738         },
739 };
740
741 static struct nvmap_platform_carveout bonaire_carveouts[] = {
742         [0] = {
743                 .name           = "iram",
744                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
745                 .base           = TEGRA_IRAM_BASE,
746 #ifdef CONFIG_TEGRA_SIMULATION_PLATFORM
747                 .size           = 0, /* DMA won't work in ASIM IRAM */
748 #else
749                 .size           = TEGRA_IRAM_SIZE,
750 #endif
751                 .buddy_size     = 0, /* no buddy allocation for IRAM */
752         },
753         [1] = {
754                 .name           = "generic-0",
755                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
756                 .base           = 0,    /* Filled in by bonaire_panel_init() */
757                 .size           = 0,    /* Filled in by bonaire_panel_init() */
758                 .buddy_size     = SZ_32K,
759         },
760         [2] = {
761                 .name           = "vpr",
762                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
763                 .base           = 0,    /* Filled in by bonaire_panel_init() */
764                 .size           = 0,    /* Filled in by bonaire_panel_init() */
765                 .buddy_size     = SZ_32K,
766         },
767 };
768
769 static struct nvmap_platform_data bonaire_nvmap_data = {
770         .carveouts      = bonaire_carveouts,
771         .nr_carveouts   = ARRAY_SIZE(bonaire_carveouts),
772 };
773
774 static struct platform_device bonaire_nvmap_device = {
775         .name   = "tegra-nvmap",
776         .id     = -1,
777         .dev    = {
778                 .platform_data = &bonaire_nvmap_data,
779         },
780 };
781
782 static struct platform_device *bonaire_gfx_devices[] __initdata = {
783         &bonaire_nvmap_device,
784         &tegra_pwfm_device,
785         &bonaire_backlight_device,
786 };
787
788 int __init bonaire_panel_init(void)
789 {
790         int err;
791         struct resource *res;
792 #if defined(CONFIG_TEGRA_GRHOST)
793         struct platform_device *phost1x;
794 #endif
795
796         bonaire_carveouts[1].base = tegra_carveout_start;
797         bonaire_carveouts[1].size = tegra_carveout_size;
798         bonaire_carveouts[2].base = tegra_vpr_start;
799         bonaire_carveouts[2].size = tegra_vpr_size;
800
801         err = platform_add_devices(bonaire_gfx_devices,
802                                    ARRAY_SIZE(bonaire_gfx_devices));
803
804 #ifdef CONFIG_TEGRA_GRHOST
805         phost1x = bonaire_host1x_init();
806         if (!phost1x)
807                 return -EINVAL;
808 #endif
809
810 #if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
811         if (!tegra_platform_is_fpga()) {
812                 res = platform_get_resource_byname(&bonaire_disp1_device,
813                         IORESOURCE_MEM, "fbmem");
814                 res->start = tegra_fb_start;
815                 res->end = tegra_fb_start + tegra_fb_size - 1;
816
817 #ifdef CONFIG_TEGRA_IOMMU_SMMU
818                 /* Copy the bootloader fb to the fb. */
819                 __tegra_move_framebuffer(&bonaire_nvmap_device,
820                         tegra_fb_start, tegra_bootloader_fb_start,
821                         tegra_fb_size);
822 #endif
823
824                 if (!err) {
825                         bonaire_disp1_device.dev.parent = &phost1x->dev;
826                         err = platform_device_register(&bonaire_disp1_device);
827                 }
828         } else {
829                 /* FPGA only has disp2 support */
830                 res = platform_get_resource_byname(&bonaire_disp2_device,
831                         IORESOURCE_MEM, "fbmem");
832                 res->start = tegra_fb_start;
833                 res->end = tegra_fb_start + tegra_fb_size - 1;
834
835 #ifdef CONFIG_TEGRA_IOMMU_SMMU
836                 /* Copy the bootloader fb to the fb. */
837                 __tegra_move_framebuffer(&bonaire_nvmap_device,
838                         tegra_fb_start, tegra_bootloader_fb_start,
839                         tegra_fb_size);
840 #endif
841
842                 if (!err) {
843                         bonaire_disp2_device.dev.parent = &phost1x->dev;
844                         err = platform_device_register(&bonaire_disp2_device);
845                 }
846         }
847
848 #endif
849
850 #ifdef CONFIG_TEGRA_NVAVP
851         nvavp_device.dev.parent = &phost1x->dev;
852         err = platform_device_register(&nvavp_device);
853         if (err) {
854                 pr_err("nvavp device registration failed\n");
855                 return err;
856         }
857 #endif
858         return err;
859 }