aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-kai-panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-kai-panel.c')
-rw-r--r--arch/arm/mach-tegra/board-kai-panel.c740
1 files changed, 740 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-kai-panel.c b/arch/arm/mach-tegra/board-kai-panel.c
new file mode 100644
index 00000000000..71e238fdcdc
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-panel.c
@@ -0,0 +1,740 @@
1/*
2 * arch/arm/mach-tegra/board-kai-panel.c
3 *
4 * Copyright (c) 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 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
20#include <linux/delay.h>
21#include <linux/gpio.h>
22#include <linux/regulator/consumer.h>
23#include <linux/resource.h>
24#include <asm/mach-types.h>
25#include <linux/platform_device.h>
26#include <linux/earlysuspend.h>
27#include <linux/pwm_backlight.h>
28#include <asm/atomic.h>
29#include <linux/nvhost.h>
30#include <mach/nvmap.h>
31#include <mach/irqs.h>
32#include <mach/iomap.h>
33#include <mach/dc.h>
34#include <mach/fb.h>
35
36#include "board.h"
37#include "board-kai.h"
38#include "devices.h"
39#include "gpio-names.h"
40
41/* kai default display board pins */
42#define kai_lvds_avdd_en TEGRA_GPIO_PH6
43#define kai_lvds_stdby TEGRA_GPIO_PG5
44#define kai_lvds_rst TEGRA_GPIO_PG7
45#define kai_lvds_shutdown TEGRA_GPIO_PN6
46#define kai_lvds_rs TEGRA_GPIO_PV6
47#define kai_lvds_lr TEGRA_GPIO_PG1
48
49/* kai A00 display board pins */
50#define kai_lvds_rs_a00 TEGRA_GPIO_PH1
51
52/* common pins( backlight ) for all display boards */
53#define kai_bl_enb TEGRA_GPIO_PH3
54#define kai_bl_pwm TEGRA_GPIO_PH0
55#define kai_hdmi_hpd TEGRA_GPIO_PN7
56
57#ifdef CONFIG_TEGRA_DC
58static struct regulator *kai_hdmi_reg;
59static struct regulator *kai_hdmi_pll;
60static struct regulator *kai_hdmi_vddio;
61#endif
62
63static atomic_t sd_brightness = ATOMIC_INIT(255);
64
65static struct regulator *kai_lvds_reg;
66static struct regulator *kai_lvds_vdd_panel;
67
68static tegra_dc_bl_output kai_bl_output_measured = {
69 0, 1, 2, 3, 4, 5, 6, 7,
70 8, 9, 10, 11, 12, 13, 14, 15,
71 16, 17, 18, 19, 20, 21, 22, 23,
72 24, 25, 26, 27, 28, 29, 30, 31,
73 32, 33, 34, 35, 36, 37, 38, 39,
74 40, 41, 42, 43, 44, 45, 46, 47,
75 48, 49, 49, 50, 51, 52, 53, 54,
76 55, 56, 57, 58, 59, 60, 61, 62,
77 63, 64, 65, 66, 67, 68, 69, 70,
78 70, 72, 73, 74, 75, 76, 77, 78,
79 79, 80, 81, 82, 83, 84, 85, 86,
80 87, 88, 89, 90, 91, 92, 93, 94,
81 95, 96, 97, 98, 99, 100, 101, 102,
82 103, 104, 105, 106, 107, 108, 110, 111,
83 112, 113, 114, 115, 116, 117, 118, 119,
84 120, 121, 122, 123, 124, 124, 125, 126,
85 127, 128, 129, 130, 131, 132, 133, 133,
86 134, 135, 136, 137, 138, 139, 140, 141,
87 142, 143, 144, 145, 146, 147, 148, 148,
88 149, 150, 151, 152, 153, 154, 155, 156,
89 157, 158, 159, 160, 161, 162, 163, 164,
90 165, 166, 167, 168, 169, 170, 171, 172,
91 173, 174, 175, 176, 177, 179, 180, 181,
92 182, 184, 185, 186, 187, 188, 189, 190,
93 191, 192, 193, 194, 195, 196, 197, 198,
94 199, 200, 201, 202, 203, 204, 205, 206,
95 207, 208, 209, 211, 212, 213, 214, 215,
96 216, 217, 218, 219, 220, 221, 222, 223,
97 224, 225, 226, 227, 228, 229, 230, 231,
98 232, 233, 234, 235, 236, 237, 238, 239,
99 240, 241, 242, 243, 244, 245, 246, 247,
100 248, 249, 250, 251, 252, 253, 254, 255
101};
102
103static p_tegra_dc_bl_output bl_output;
104
105static int kai_backlight_init(struct device *dev)
106{
107 int ret;
108
109 bl_output = kai_bl_output_measured;
110
111 if (WARN_ON(ARRAY_SIZE(kai_bl_output_measured) != 256))
112 pr_err("bl_output array does not have 256 elements\n");
113
114 tegra_gpio_disable(kai_bl_pwm);
115
116 ret = gpio_request(kai_bl_enb, "backlight_enb");
117 if (ret < 0)
118 return ret;
119
120 ret = gpio_direction_output(kai_bl_enb, 1);
121 if (ret < 0)
122 gpio_free(kai_bl_enb);
123 else
124 tegra_gpio_enable(kai_bl_enb);
125
126 return ret;
127};
128
129static void kai_backlight_exit(struct device *dev)
130{
131 /* int ret; */
132 /*ret = gpio_request(kai_bl_enb, "backlight_enb");*/
133 gpio_set_value(kai_bl_enb, 0);
134 gpio_free(kai_bl_enb);
135 tegra_gpio_disable(kai_bl_enb);
136 return;
137}
138
139static int kai_backlight_notify(struct device *unused, int brightness)
140{
141 int cur_sd_brightness = atomic_read(&sd_brightness);
142
143 /* Set the backlight GPIO pin mode to 'backlight_enable' */
144 gpio_set_value(kai_bl_enb, !!brightness);
145
146 /* SD brightness is a percentage, 8-bit value. */
147 brightness = (brightness * cur_sd_brightness) / 255;
148
149 /* Apply any backlight response curve */
150 if (brightness > 255)
151 pr_info("Error: Brightness > 255!\n");
152 else
153 brightness = bl_output[brightness];
154
155 return brightness;
156}
157
158static int kai_disp1_check_fb(struct device *dev, struct fb_info *info);
159
160static struct platform_pwm_backlight_data kai_backlight_data = {
161 .pwm_id = 0,
162 .max_brightness = 255,
163 .dft_brightness = 224,
164 .pwm_period_ns = 100000,
165 .init = kai_backlight_init,
166 .exit = kai_backlight_exit,
167 .notify = kai_backlight_notify,
168 /* Only toggle backlight on fb blank notifications for disp1 */
169 .check_fb = kai_disp1_check_fb,
170};
171
172static struct platform_device kai_backlight_device = {
173 .name = "pwm-backlight",
174 .id = -1,
175 .dev = {
176 .platform_data = &kai_backlight_data,
177 },
178};
179
180static int kai_panel_enable(void)
181{
182 if (kai_lvds_reg == NULL) {
183 kai_lvds_reg = regulator_get(NULL, "vdd_lvds");
184 if (WARN_ON(IS_ERR(kai_lvds_reg)))
185 pr_err("%s: couldn't get regulator vdd_lvds: %ld\n",
186 __func__, PTR_ERR(kai_lvds_reg));
187 else
188 regulator_enable(kai_lvds_reg);
189 }
190
191 if (kai_lvds_vdd_panel == NULL) {
192 kai_lvds_vdd_panel = regulator_get(NULL, "vdd_lcd_panel");
193 if (WARN_ON(IS_ERR(kai_lvds_vdd_panel)))
194 pr_err("%s: couldn't get regulator vdd_lcd_panel: %ld\n",
195 __func__, PTR_ERR(kai_lvds_vdd_panel));
196 else
197 regulator_enable(kai_lvds_vdd_panel);
198 }
199
200 mdelay(5);
201
202 gpio_set_value(kai_lvds_avdd_en, 1);
203 mdelay(5);
204
205 gpio_set_value(kai_lvds_stdby, 1);
206 gpio_set_value(kai_lvds_rst, 1);
207 gpio_set_value(kai_lvds_shutdown, 1);
208 gpio_set_value(kai_lvds_lr, 1);
209
210 mdelay(10);
211
212 return 0;
213}
214
215static int kai_panel_disable(void)
216{
217 gpio_set_value(kai_lvds_lr, 0);
218 gpio_set_value(kai_lvds_shutdown, 0);
219 gpio_set_value(kai_lvds_rst, 0);
220 gpio_set_value(kai_lvds_stdby, 0);
221 mdelay(5);
222
223 gpio_set_value(kai_lvds_avdd_en, 0);
224 mdelay(5);
225
226 regulator_disable(kai_lvds_reg);
227 regulator_put(kai_lvds_reg);
228 kai_lvds_reg = NULL;
229
230 regulator_disable(kai_lvds_vdd_panel);
231 regulator_put(kai_lvds_vdd_panel);
232 kai_lvds_vdd_panel = NULL;
233
234 return 0;
235}
236
237#ifdef CONFIG_TEGRA_DC
238static int kai_hdmi_vddio_enable(void)
239{
240 int ret;
241 if (!kai_hdmi_vddio) {
242 kai_hdmi_vddio = regulator_get(NULL, "vdd_hdmi_con");
243 if (IS_ERR_OR_NULL(kai_hdmi_vddio)) {
244 ret = PTR_ERR(kai_hdmi_vddio);
245 pr_err("hdmi: couldn't get regulator vdd_hdmi_con\n");
246 kai_hdmi_vddio = NULL;
247 return ret;
248 }
249 }
250 ret = regulator_enable(kai_hdmi_vddio);
251 if (ret < 0) {
252 pr_err("hdmi: couldn't enable regulator vdd_hdmi_con\n");
253 regulator_put(kai_hdmi_vddio);
254 kai_hdmi_vddio = NULL;
255 return ret;
256 }
257 return ret;
258}
259
260static int kai_hdmi_vddio_disable(void)
261{
262 if (kai_hdmi_vddio) {
263 regulator_disable(kai_hdmi_vddio);
264 regulator_put(kai_hdmi_vddio);
265 kai_hdmi_vddio = NULL;
266 }
267 return 0;
268}
269
270static int kai_hdmi_enable(void)
271{
272 int ret;
273 if (!kai_hdmi_reg) {
274 kai_hdmi_reg = regulator_get(NULL, "avdd_hdmi");
275 if (IS_ERR_OR_NULL(kai_hdmi_reg)) {
276 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
277 kai_hdmi_reg = NULL;
278 return PTR_ERR(kai_hdmi_reg);
279 }
280 }
281 ret = regulator_enable(kai_hdmi_reg);
282 if (ret < 0) {
283 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
284 return ret;
285 }
286 if (!kai_hdmi_pll) {
287 kai_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll");
288 if (IS_ERR_OR_NULL(kai_hdmi_pll)) {
289 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
290 kai_hdmi_pll = NULL;
291 regulator_put(kai_hdmi_reg);
292 kai_hdmi_reg = NULL;
293 return PTR_ERR(kai_hdmi_pll);
294 }
295 }
296 ret = regulator_enable(kai_hdmi_pll);
297 if (ret < 0) {
298 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
299 return ret;
300 }
301 return 0;
302}
303
304static int kai_hdmi_disable(void)
305{
306 regulator_disable(kai_hdmi_reg);
307 regulator_put(kai_hdmi_reg);
308 kai_hdmi_reg = NULL;
309
310 regulator_disable(kai_hdmi_pll);
311 regulator_put(kai_hdmi_pll);
312 kai_hdmi_pll = NULL;
313 return 0;
314}
315
316static struct resource kai_disp1_resources[] = {
317 {
318 .name = "irq",
319 .start = INT_DISPLAY_GENERAL,
320 .end = INT_DISPLAY_GENERAL,
321 .flags = IORESOURCE_IRQ,
322 },
323 {
324 .name = "regs",
325 .start = TEGRA_DISPLAY_BASE,
326 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
327 .flags = IORESOURCE_MEM,
328 },
329 {
330 .name = "fbmem",
331 .start = 0, /* Filled in by kai_panel_init() */
332 .end = 0, /* Filled in by kai_panel_init() */
333 .flags = IORESOURCE_MEM,
334 },
335};
336
337static struct resource kai_disp2_resources[] = {
338 {
339 .name = "irq",
340 .start = INT_DISPLAY_B_GENERAL,
341 .end = INT_DISPLAY_B_GENERAL,
342 .flags = IORESOURCE_IRQ,
343 },
344 {
345 .name = "regs",
346 .start = TEGRA_DISPLAY2_BASE,
347 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
348 .flags = IORESOURCE_MEM,
349 },
350 {
351 .name = "fbmem",
352 .flags = IORESOURCE_MEM,
353 .start = 0,
354 .end = 0,
355 },
356 {
357 .name = "hdmi_regs",
358 .start = TEGRA_HDMI_BASE,
359 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
360 .flags = IORESOURCE_MEM,
361 },
362};
363#endif
364
365static struct tegra_dc_mode kai_panel_modes[] = {
366 {
367 /* 1024x600@60Hz */
368 .pclk = 51206000,
369 .h_ref_to_sync = 11,
370 .v_ref_to_sync = 1,
371 .h_sync_width = 10,
372 .v_sync_width = 5,
373 .h_back_porch = 10,
374 .v_back_porch = 15,
375 .h_active = 1024,
376 .v_active = 600,
377 .h_front_porch = 300,
378 .v_front_porch = 15,
379 },
380};
381
382static struct tegra_dc_sd_settings kai_sd_settings = {
383 .enable = 1, /* enabled by default. */
384 .use_auto_pwm = false,
385 .hw_update_delay = 0,
386 .bin_width = -1,
387 .aggressiveness = 1,
388 .phase_in_adjustments = true,
389 .use_vid_luma = false,
390 /* Default video coefficients */
391 .coeff = {5, 9, 2},
392 .fc = {0, 0},
393 /* Immediate backlight changes */
394 .blp = {1024, 255},
395 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
396 /* Default BL TF */
397 .bltf = {
398 {
399 {57, 65, 74, 83},
400 {93, 103, 114, 126},
401 {138, 151, 165, 179},
402 {194, 209, 225, 242},
403 },
404 {
405 {58, 66, 75, 84},
406 {94, 105, 116, 127},
407 {140, 153, 166, 181},
408 {196, 211, 227, 244},
409 },
410 {
411 {60, 68, 77, 87},
412 {97, 107, 119, 130},
413 {143, 156, 170, 184},
414 {199, 215, 231, 248},
415 },
416 {
417 {64, 73, 82, 91},
418 {102, 113, 124, 137},
419 {149, 163, 177, 192},
420 {207, 223, 240, 255},
421 },
422 },
423 /* Default LUT */
424 .lut = {
425 {
426 {250, 250, 250},
427 {194, 194, 194},
428 {149, 149, 149},
429 {113, 113, 113},
430 {82, 82, 82},
431 {56, 56, 56},
432 {34, 34, 34},
433 {15, 15, 15},
434 {0, 0, 0},
435 },
436 {
437 {246, 246, 246},
438 {191, 191, 191},
439 {147, 147, 147},
440 {111, 111, 111},
441 {80, 80, 80},
442 {55, 55, 55},
443 {33, 33, 33},
444 {14, 14, 14},
445 {0, 0, 0},
446 },
447 {
448 {239, 239, 239},
449 {185, 185, 185},
450 {142, 142, 142},
451 {107, 107, 107},
452 {77, 77, 77},
453 {52, 52, 52},
454 {30, 30, 30},
455 {12, 12, 12},
456 {0, 0, 0},
457 },
458 {
459 {224, 224, 224},
460 {173, 173, 173},
461 {133, 133, 133},
462 {99, 99, 99},
463 {70, 70, 70},
464 {46, 46, 46},
465 {25, 25, 25},
466 {7, 7, 7},
467 {0, 0, 0},
468 },
469 },
470 .sd_brightness = &sd_brightness,
471 .bl_device = &kai_backlight_device,
472};
473
474#ifdef CONFIG_TEGRA_DC
475static struct tegra_fb_data kai_fb_data = {
476 .win = 0,
477 .xres = 1024,
478 .yres = 600,
479 .bits_per_pixel = 32,
480 .flags = TEGRA_FB_FLIP_ON_PROBE,
481};
482
483static struct tegra_fb_data kai_hdmi_fb_data = {
484 .win = 0,
485 .xres = 1024,
486 .yres = 600,
487 .bits_per_pixel = 32,
488 .flags = TEGRA_FB_FLIP_ON_PROBE,
489};
490
491static struct tegra_dc_out kai_disp2_out = {
492 .type = TEGRA_DC_OUT_HDMI,
493 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
494
495 .dcc_bus = 3,
496 .hotplug_gpio = kai_hdmi_hpd,
497
498 .max_pixclock = KHZ2PICOS(148500),
499
500 .align = TEGRA_DC_ALIGN_MSB,
501 .order = TEGRA_DC_ORDER_RED_BLUE,
502
503 .enable = kai_hdmi_enable,
504 .disable = kai_hdmi_disable,
505
506 .postsuspend = kai_hdmi_vddio_disable,
507 .hotplug_init = kai_hdmi_vddio_enable,
508};
509
510static struct tegra_dc_platform_data kai_disp2_pdata = {
511 .flags = 0,
512 .default_out = &kai_disp2_out,
513 .fb = &kai_hdmi_fb_data,
514 .emc_clk_rate = 300000000,
515};
516#endif
517
518static struct tegra_dc_out kai_disp1_out = {
519 .align = TEGRA_DC_ALIGN_MSB,
520 .order = TEGRA_DC_ORDER_RED_BLUE,
521 .sd_settings = &kai_sd_settings,
522 .parent_clk = "pll_p",
523 .parent_clk_backup = "pll_d2_out0",
524
525 .type = TEGRA_DC_OUT_RGB,
526 .depth = 18,
527 .dither = TEGRA_DC_ORDERED_DITHER,
528
529 .modes = kai_panel_modes,
530 .n_modes = ARRAY_SIZE(kai_panel_modes),
531
532 .enable = kai_panel_enable,
533 .disable = kai_panel_disable,
534};
535
536#ifdef CONFIG_TEGRA_DC
537static struct tegra_dc_platform_data kai_disp1_pdata = {
538 .flags = TEGRA_DC_FLAG_ENABLED,
539 .default_out = &kai_disp1_out,
540 .emc_clk_rate = 300000000,
541 .fb = &kai_fb_data,
542};
543
544static struct nvhost_device kai_disp1_device = {
545 .name = "tegradc",
546 .id = 0,
547 .resource = kai_disp1_resources,
548 .num_resources = ARRAY_SIZE(kai_disp1_resources),
549 .dev = {
550 .platform_data = &kai_disp1_pdata,
551 },
552};
553
554static int kai_disp1_check_fb(struct device *dev, struct fb_info *info)
555{
556 return info->device == &kai_disp1_device.dev;
557}
558
559static struct nvhost_device kai_disp2_device = {
560 .name = "tegradc",
561 .id = 1,
562 .resource = kai_disp2_resources,
563 .num_resources = ARRAY_SIZE(kai_disp2_resources),
564 .dev = {
565 .platform_data = &kai_disp2_pdata,
566 },
567};
568#else
569static int kai_disp1_check_fb(struct device *dev, struct fb_info *info)
570{
571 return 0;
572}
573#endif
574
575#if defined(CONFIG_TEGRA_NVMAP)
576static struct nvmap_platform_carveout kai_carveouts[] = {
577 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
578 [1] = {
579 .name = "generic-0",
580 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
581 .base = 0, /* Filled in by kai_panel_init() */
582 .size = 0, /* Filled in by kai_panel_init() */
583 .buddy_size = SZ_32K,
584 },
585};
586
587static struct nvmap_platform_data kai_nvmap_data = {
588 .carveouts = kai_carveouts,
589 .nr_carveouts = ARRAY_SIZE(kai_carveouts),
590};
591
592static struct platform_device kai_nvmap_device = {
593 .name = "tegra-nvmap",
594 .id = -1,
595 .dev = {
596 .platform_data = &kai_nvmap_data,
597 },
598};
599#endif
600
601static struct platform_device *kai_gfx_devices[] __initdata = {
602#if defined(CONFIG_TEGRA_NVMAP)
603 &kai_nvmap_device,
604#endif
605 &tegra_pwfm0_device,
606 &kai_backlight_device,
607};
608
609
610#ifdef CONFIG_HAS_EARLYSUSPEND
611/* put early_suspend/late_resume handlers here for the display in order
612 * to keep the code out of the display driver, keeping it closer to upstream
613 */
614struct early_suspend kai_panel_early_suspender;
615
616static void kai_panel_early_suspend(struct early_suspend *h)
617{
618 /* power down LCD, add use a black screen for HDMI */
619 if (num_registered_fb > 0)
620 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
621 if (num_registered_fb > 1)
622 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
623
624#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
625 cpufreq_save_default_governor();
626 cpufreq_set_conservative_governor();
627 cpufreq_set_conservative_governor_param("up_threshold",
628 SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
629
630 cpufreq_set_conservative_governor_param("down_threshold",
631 SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
632
633 cpufreq_set_conservative_governor_param("freq_step",
634 SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
635#endif
636
637}
638
639static void kai_panel_late_resume(struct early_suspend *h)
640{
641 unsigned i;
642#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
643 cpufreq_restore_default_governor();
644#endif
645 for (i = 0; i < num_registered_fb; i++)
646 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
647}
648#endif
649
650int __init kai_panel_init(void)
651{
652 int err;
653 struct resource __maybe_unused *res;
654 struct board_info board_info;
655
656 tegra_get_board_info(&board_info);
657
658#if defined(CONFIG_TEGRA_NVMAP)
659 kai_carveouts[1].base = tegra_carveout_start;
660 kai_carveouts[1].size = tegra_carveout_size;
661#endif
662 gpio_request(kai_lvds_avdd_en, "lvds_avdd_en");
663 gpio_direction_output(kai_lvds_avdd_en, 1);
664 tegra_gpio_enable(kai_lvds_avdd_en);
665
666 gpio_request(kai_lvds_stdby, "lvds_stdby");
667 gpio_direction_output(kai_lvds_stdby, 1);
668 tegra_gpio_enable(kai_lvds_stdby);
669
670 gpio_request(kai_lvds_rst, "lvds_rst");
671 gpio_direction_output(kai_lvds_rst, 1);
672 tegra_gpio_enable(kai_lvds_rst);
673
674 if (board_info.fab == BOARD_FAB_A00) {
675 gpio_request(kai_lvds_rs_a00, "lvds_rs");
676 gpio_direction_output(kai_lvds_rs_a00, 0);
677 tegra_gpio_enable(kai_lvds_rs_a00);
678 } else {
679 gpio_request(kai_lvds_rs, "lvds_rs");
680 gpio_direction_output(kai_lvds_rs, 0);
681 tegra_gpio_enable(kai_lvds_rs);
682 }
683
684 gpio_request(kai_lvds_lr, "lvds_lr");
685 gpio_direction_output(kai_lvds_lr, 1);
686 tegra_gpio_enable(kai_lvds_lr);
687
688 gpio_request(kai_lvds_shutdown, "lvds_shutdown");
689 gpio_direction_output(kai_lvds_shutdown, 1);
690 tegra_gpio_enable(kai_lvds_shutdown);
691
692 tegra_gpio_enable(kai_hdmi_hpd);
693 gpio_request(kai_hdmi_hpd, "hdmi_hpd");
694 gpio_direction_input(kai_hdmi_hpd);
695
696#ifdef CONFIG_HAS_EARLYSUSPEND
697 kai_panel_early_suspender.suspend = kai_panel_early_suspend;
698 kai_panel_early_suspender.resume = kai_panel_late_resume;
699 kai_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
700 register_early_suspend(&kai_panel_early_suspender);
701#endif
702
703#ifdef CONFIG_TEGRA_GRHOST
704 err = nvhost_device_register(&tegra_grhost_device);
705 if (err)
706 return err;
707#endif
708
709 err = platform_add_devices(kai_gfx_devices,
710 ARRAY_SIZE(kai_gfx_devices));
711
712#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
713 res = nvhost_get_resource_byname(&kai_disp1_device,
714 IORESOURCE_MEM, "fbmem");
715 res->start = tegra_fb_start;
716 res->end = tegra_fb_start + tegra_fb_size - 1;
717#endif
718
719 /* Copy the bootloader fb to the fb. */
720 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
721 min(tegra_fb_size, tegra_bootloader_fb_size));
722
723#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
724 if (!err)
725 err = nvhost_device_register(&kai_disp1_device);
726
727 res = nvhost_get_resource_byname(&kai_disp2_device,
728 IORESOURCE_MEM, "fbmem");
729 res->start = tegra_fb2_start;
730 res->end = tegra_fb2_start + tegra_fb2_size - 1;
731 if (!err)
732 err = nvhost_device_register(&kai_disp2_device);
733#endif
734
735#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_NVAVP)
736 if (!err)
737 err = nvhost_device_register(&nvavp_device);
738#endif
739 return err;
740}