aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-cardhu-panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-cardhu-panel.c')
-rw-r--r--arch/arm/mach-tegra/board-cardhu-panel.c1288
1 files changed, 1288 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-cardhu-panel.c b/arch/arm/mach-tegra/board-cardhu-panel.c
new file mode 100644
index 00000000000..8636a4d6743
--- /dev/null
+++ b/arch/arm/mach-tegra/board-cardhu-panel.c
@@ -0,0 +1,1288 @@
1/*
2 * arch/arm/mach-tegra/board-cardhu-panel.c
3 *
4 * Copyright (c) 2010-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
21#include <linux/delay.h>
22#include <linux/ion.h>
23#include <linux/tegra_ion.h>
24#include <linux/gpio.h>
25#include <linux/regulator/consumer.h>
26#include <linux/resource.h>
27#include <asm/mach-types.h>
28#include <linux/platform_device.h>
29#include <linux/earlysuspend.h>
30#include <linux/pwm_backlight.h>
31#include <asm/atomic.h>
32#include <linux/nvhost.h>
33#include <mach/nvmap.h>
34#include <mach/irqs.h>
35#include <mach/iomap.h>
36#include <mach/dc.h>
37#include <mach/fb.h>
38#include <mach/smmu.h>
39
40#include "board.h"
41#include "board-cardhu.h"
42#include "devices.h"
43#include "gpio-names.h"
44
45/* Select panel to be used. */
46#define DSI_PANEL_219 1
47#define DSI_PANEL_218 0
48#define AVDD_LCD PMU_TCA6416_GPIO_PORT17
49#define DSI_PANEL_RESET 1
50
51/* Select LVDS panel resolution. 13X7 is default */
52#define PM313_LVDS_PANEL_19X12 1
53#define PM313_LVDS_PANEL_BPP 0 /* 0:24bpp, 1:18bpp */
54
55/* PM313 display board specific pins */
56#define pm313_R_FDE TEGRA_GPIO_PW0
57#define pm313_R_FB TEGRA_GPIO_PN4
58#define pm313_MODE0 TEGRA_GPIO_PZ4
59#define pm313_MODE1 TEGRA_GPIO_PW1
60#define pm313_BPP TEGRA_GPIO_PN6 /* 0:24bpp, 1:18bpp */
61#define pm313_lvds_shutdown TEGRA_GPIO_PH1
62
63/* E1247 reworked for pm269 pins */
64#define e1247_pm269_lvds_shutdown TEGRA_GPIO_PN6
65
66/* E1247 cardhu default display board pins */
67#define cardhu_lvds_shutdown TEGRA_GPIO_PL2
68
69/* common pins( backlight ) for all display boards */
70#define cardhu_bl_enb TEGRA_GPIO_PH2
71#define cardhu_bl_pwm TEGRA_GPIO_PH0
72#define cardhu_hdmi_hpd TEGRA_GPIO_PN7
73
74#if defined(DSI_PANEL_219) || defined(DSI_PANEL_218)
75#define cardhu_dsia_bl_enb TEGRA_GPIO_PW1
76#define cardhu_dsib_bl_enb TEGRA_GPIO_PW0
77#define cardhu_dsi_218_panel_reset TEGRA_GPIO_PD2
78#define cardhu_dsi_219_panel_reset TEGRA_GPIO_PW0
79#endif
80
81#ifdef CONFIG_TEGRA_DC
82static struct regulator *cardhu_hdmi_reg = NULL;
83static struct regulator *cardhu_hdmi_pll = NULL;
84static struct regulator *cardhu_hdmi_vddio = NULL;
85#endif
86
87static atomic_t sd_brightness = ATOMIC_INIT(255);
88
89#ifdef CONFIG_TEGRA_CARDHU_DSI
90static struct regulator *cardhu_dsi_reg = NULL;
91#else
92static struct regulator *cardhu_lvds_reg = NULL;
93static struct regulator *cardhu_lvds_vdd_bl = NULL;
94static struct regulator *cardhu_lvds_vdd_panel = NULL;
95#endif
96
97static struct board_info board_info;
98static struct board_info display_board_info;
99
100static tegra_dc_bl_output cardhu_bl_output_measured = {
101 0, 1, 2, 3, 4, 5, 6, 7,
102 8, 9, 10, 11, 12, 13, 14, 15,
103 16, 17, 18, 19, 20, 21, 22, 23,
104 24, 25, 26, 27, 28, 29, 30, 31,
105 32, 33, 34, 35, 36, 37, 38, 39,
106 40, 41, 42, 43, 44, 45, 46, 47,
107 48, 49, 49, 50, 51, 52, 53, 54,
108 55, 56, 57, 58, 59, 60, 61, 62,
109 63, 64, 65, 66, 67, 68, 69, 70,
110 70, 72, 73, 74, 75, 76, 77, 78,
111 79, 80, 81, 82, 83, 84, 85, 86,
112 87, 88, 89, 90, 91, 92, 93, 94,
113 95, 96, 97, 98, 99, 100, 101, 102,
114 103, 104, 105, 106, 107, 108, 110, 111,
115 112, 113, 114, 115, 116, 117, 118, 119,
116 120, 121, 122, 123, 124, 124, 125, 126,
117 127, 128, 129, 130, 131, 132, 133, 133,
118 134, 135, 136, 137, 138, 139, 140, 141,
119 142, 143, 144, 145, 146, 147, 148, 148,
120 149, 150, 151, 152, 153, 154, 155, 156,
121 157, 158, 159, 160, 161, 162, 163, 164,
122 165, 166, 167, 168, 169, 170, 171, 172,
123 173, 174, 175, 176, 177, 179, 180, 181,
124 182, 184, 185, 186, 187, 188, 189, 190,
125 191, 192, 193, 194, 195, 196, 197, 198,
126 199, 200, 201, 202, 203, 204, 205, 206,
127 207, 208, 209, 211, 212, 213, 214, 215,
128 216, 217, 218, 219, 220, 221, 222, 223,
129 224, 225, 226, 227, 228, 229, 230, 231,
130 232, 233, 234, 235, 236, 237, 238, 239,
131 240, 241, 242, 243, 244, 245, 246, 247,
132 248, 249, 250, 251, 252, 253, 254, 255
133};
134
135static p_tegra_dc_bl_output bl_output;
136
137static int cardhu_backlight_init(struct device *dev)
138{
139 int ret;
140
141 bl_output = cardhu_bl_output_measured;
142
143 if (WARN_ON(ARRAY_SIZE(cardhu_bl_output_measured) != 256))
144 pr_err("bl_output array does not have 256 elements\n");
145
146#ifndef CONFIG_TEGRA_CARDHU_DSI
147 tegra_gpio_disable(cardhu_bl_pwm);
148
149 ret = gpio_request(cardhu_bl_enb, "backlight_enb");
150 if (ret < 0)
151 return ret;
152
153 ret = gpio_direction_output(cardhu_bl_enb, 1);
154 if (ret < 0)
155 gpio_free(cardhu_bl_enb);
156 else
157 tegra_gpio_enable(cardhu_bl_enb);
158
159 return ret;
160#endif
161
162#if DSI_PANEL_218
163 /* Enable back light for DSIa panel */
164 ret = gpio_request(cardhu_dsia_bl_enb, "dsia_bl_enable");
165 if (ret < 0)
166 return ret;
167
168 ret = gpio_direction_output(cardhu_dsia_bl_enb, 1);
169 if (ret < 0)
170 gpio_free(cardhu_dsia_bl_enb);
171 else
172 tegra_gpio_enable(cardhu_dsia_bl_enb);
173
174 /* Enable back light for DSIb panel */
175 ret = gpio_request(cardhu_dsib_bl_enb, "dsib_bl_enable");
176 if (ret < 0)
177 return ret;
178
179 ret = gpio_direction_output(cardhu_dsib_bl_enb, 1);
180 if (ret < 0)
181 gpio_free(cardhu_dsib_bl_enb);
182 else
183 tegra_gpio_enable(cardhu_dsib_bl_enb);
184#endif
185
186#if DSI_PANEL_219
187 /* Enable back light for DSIa panel */
188 ret = gpio_request(cardhu_dsia_bl_enb, "dsia_bl_enable");
189 if (ret < 0)
190 return ret;
191
192 ret = gpio_direction_output(cardhu_dsia_bl_enb, 1);
193 if (ret < 0)
194 gpio_free(cardhu_dsia_bl_enb);
195 else
196 tegra_gpio_enable(cardhu_dsia_bl_enb);
197#endif
198
199 return ret;
200};
201
202static void cardhu_backlight_exit(struct device *dev)
203{
204#ifndef CONFIG_TEGRA_CARDHU_DSI
205 /* int ret; */
206 /*ret = gpio_request(cardhu_bl_enb, "backlight_enb");*/
207 gpio_set_value(cardhu_bl_enb, 0);
208 gpio_free(cardhu_bl_enb);
209 tegra_gpio_disable(cardhu_bl_enb);
210 return;
211#endif
212
213#if DSI_PANEL_218
214 /* Disable back light for DSIa panel */
215 gpio_set_value(cardhu_dsia_bl_enb, 0);
216 gpio_free(cardhu_dsia_bl_enb);
217 tegra_gpio_disable(cardhu_dsia_bl_enb);
218
219 /* Disable back light for DSIb panel */
220 gpio_set_value(cardhu_dsib_bl_enb, 0);
221 gpio_free(cardhu_dsib_bl_enb);
222 tegra_gpio_disable(cardhu_dsib_bl_enb);
223
224 gpio_set_value(cardhu_lvds_shutdown, 1);
225 mdelay(20);
226#endif
227
228#if DSI_PANEL_219
229 /* Disable back light for DSIa panel */
230 gpio_set_value(cardhu_dsia_bl_enb, 0);
231 gpio_free(cardhu_dsia_bl_enb);
232 tegra_gpio_disable(cardhu_dsia_bl_enb);
233
234 gpio_set_value(cardhu_lvds_shutdown, 1);
235 mdelay(20);
236#endif
237}
238
239static int cardhu_backlight_notify(struct device *unused, int brightness)
240{
241 int cur_sd_brightness = atomic_read(&sd_brightness);
242
243#ifndef CONFIG_TEGRA_CARDHU_DSI
244 /* Set the backlight GPIO pin mode to 'backlight_enable' */
245 gpio_set_value(cardhu_bl_enb, !!brightness);
246#elif DSI_PANEL_218
247 /* DSIa */
248 gpio_set_value(cardhu_dsia_bl_enb, !!brightness);
249
250 /* DSIb */
251 gpio_set_value(cardhu_dsib_bl_enb, !!brightness);
252#elif DSI_PANEL_219
253 /* DSIa */
254 gpio_set_value(cardhu_dsia_bl_enb, !!brightness);
255#endif
256
257 /* SD brightness is a percentage, 8-bit value. */
258 brightness = (brightness * cur_sd_brightness) / 255;
259
260 /* Apply any backlight response curve */
261 if (brightness > 255) {
262 pr_info("Error: Brightness > 255!\n");
263 } else {
264 /* This value depends on the panel.
265 Current 19X12 panel with PM313 gets
266 full brightness when the output is 0. */
267 if (display_board_info.board_id == BOARD_DISPLAY_PM313)
268 brightness = 255 - bl_output[brightness];
269 else
270 brightness = bl_output[brightness];
271 }
272
273 return brightness;
274}
275
276static int cardhu_disp1_check_fb(struct device *dev, struct fb_info *info);
277
278static struct platform_pwm_backlight_data cardhu_backlight_data = {
279 .pwm_id = 0,
280 .max_brightness = 255,
281 .dft_brightness = 224,
282 .pwm_period_ns = 1000000,
283 .init = cardhu_backlight_init,
284 .exit = cardhu_backlight_exit,
285 .notify = cardhu_backlight_notify,
286 /* Only toggle backlight on fb blank notifications for disp1 */
287 .check_fb = cardhu_disp1_check_fb,
288};
289
290static struct platform_device cardhu_backlight_device = {
291 .name = "pwm-backlight",
292 .id = -1,
293 .dev = {
294 .platform_data = &cardhu_backlight_data,
295 },
296};
297
298#ifndef CONFIG_TEGRA_CARDHU_DSI
299static int cardhu_panel_enable(void)
300{
301 if (cardhu_lvds_reg == NULL) {
302 cardhu_lvds_reg = regulator_get(NULL, "vdd_lvds");
303 if (WARN_ON(IS_ERR(cardhu_lvds_reg)))
304 pr_err("%s: couldn't get regulator vdd_lvds: %ld\n",
305 __func__, PTR_ERR(cardhu_lvds_reg));
306 else
307 regulator_enable(cardhu_lvds_reg);
308 }
309
310 if (cardhu_lvds_vdd_bl == NULL) {
311 cardhu_lvds_vdd_bl = regulator_get(NULL, "vdd_backlight");
312 if (WARN_ON(IS_ERR(cardhu_lvds_vdd_bl)))
313 pr_err("%s: couldn't get regulator vdd_backlight: %ld\n",
314 __func__, PTR_ERR(cardhu_lvds_vdd_bl));
315 else
316 regulator_enable(cardhu_lvds_vdd_bl);
317 }
318
319 if (cardhu_lvds_vdd_panel == NULL) {
320 cardhu_lvds_vdd_panel = regulator_get(NULL, "vdd_lcd_panel");
321 if (WARN_ON(IS_ERR(cardhu_lvds_vdd_panel)))
322 pr_err("%s: couldn't get regulator vdd_lcd_panel: %ld\n",
323 __func__, PTR_ERR(cardhu_lvds_vdd_panel));
324 else
325 regulator_enable(cardhu_lvds_vdd_panel);
326 }
327
328 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
329 /* lvds configuration */
330 gpio_set_value(pm313_R_FDE, 1);
331 gpio_set_value(pm313_R_FB, 1);
332 gpio_set_value(pm313_MODE0, 1);
333 gpio_set_value(pm313_MODE1, 0);
334 gpio_set_value(pm313_BPP, PM313_LVDS_PANEL_BPP);
335
336 /* FIXME : it may require more or less delay for latching
337 values correctly before enabling RGB2LVDS */
338 mdelay(100);
339 gpio_set_value(pm313_lvds_shutdown, 1);
340 } else if ((display_board_info.board_id == BOARD_DISPLAY_E1247 &&
341 board_info.board_id == BOARD_PM269) ||
342 (board_info.board_id == BOARD_E1257) ||
343 (board_info.board_id == BOARD_PM305) ||
344 (board_info.board_id == BOARD_PM311))
345 gpio_set_value(e1247_pm269_lvds_shutdown, 1);
346 else
347 gpio_set_value(cardhu_lvds_shutdown, 1);
348
349 return 0;
350}
351
352static int cardhu_panel_disable(void)
353{
354 regulator_disable(cardhu_lvds_reg);
355 regulator_put(cardhu_lvds_reg);
356 cardhu_lvds_reg = NULL;
357
358 regulator_disable(cardhu_lvds_vdd_bl);
359 regulator_put(cardhu_lvds_vdd_bl);
360 cardhu_lvds_vdd_bl = NULL;
361
362 regulator_disable(cardhu_lvds_vdd_panel);
363 regulator_put(cardhu_lvds_vdd_panel);
364
365 cardhu_lvds_vdd_panel= NULL;
366
367 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
368 gpio_set_value(pm313_lvds_shutdown, 0);
369 } else if ((display_board_info.board_id == BOARD_DISPLAY_E1247 &&
370 board_info.board_id == BOARD_PM269) ||
371 (board_info.board_id == BOARD_E1257) ||
372 (board_info.board_id == BOARD_PM305) ||
373 (board_info.board_id == BOARD_PM311)) {
374 gpio_set_value(e1247_pm269_lvds_shutdown, 0);
375 } else {
376 gpio_set_value(cardhu_lvds_shutdown, 0);
377 }
378 return 0;
379}
380#endif
381
382#ifdef CONFIG_TEGRA_DC
383static int cardhu_hdmi_vddio_enable(void)
384{
385 int ret;
386 if (!cardhu_hdmi_vddio) {
387 cardhu_hdmi_vddio = regulator_get(NULL, "vdd_hdmi_con");
388 if (IS_ERR_OR_NULL(cardhu_hdmi_vddio)) {
389 ret = PTR_ERR(cardhu_hdmi_vddio);
390 pr_err("hdmi: couldn't get regulator vdd_hdmi_con\n");
391 cardhu_hdmi_vddio = NULL;
392 return ret;
393 }
394 }
395 ret = regulator_enable(cardhu_hdmi_vddio);
396 if (ret < 0) {
397 pr_err("hdmi: couldn't enable regulator vdd_hdmi_con\n");
398 regulator_put(cardhu_hdmi_vddio);
399 cardhu_hdmi_vddio = NULL;
400 return ret;
401 }
402 return ret;
403}
404
405static int cardhu_hdmi_vddio_disable(void)
406{
407 if (cardhu_hdmi_vddio) {
408 regulator_disable(cardhu_hdmi_vddio);
409 regulator_put(cardhu_hdmi_vddio);
410 cardhu_hdmi_vddio = NULL;
411 }
412 return 0;
413}
414
415static int cardhu_hdmi_enable(void)
416{
417 int ret;
418 if (!cardhu_hdmi_reg) {
419 cardhu_hdmi_reg = regulator_get(NULL, "avdd_hdmi");
420 if (IS_ERR_OR_NULL(cardhu_hdmi_reg)) {
421 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
422 cardhu_hdmi_reg = NULL;
423 return PTR_ERR(cardhu_hdmi_reg);
424 }
425 }
426 ret = regulator_enable(cardhu_hdmi_reg);
427 if (ret < 0) {
428 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
429 return ret;
430 }
431 if (!cardhu_hdmi_pll) {
432 cardhu_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll");
433 if (IS_ERR_OR_NULL(cardhu_hdmi_pll)) {
434 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
435 cardhu_hdmi_pll = NULL;
436 regulator_put(cardhu_hdmi_reg);
437 cardhu_hdmi_reg = NULL;
438 return PTR_ERR(cardhu_hdmi_pll);
439 }
440 }
441 ret = regulator_enable(cardhu_hdmi_pll);
442 if (ret < 0) {
443 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
444 return ret;
445 }
446 return 0;
447}
448
449static int cardhu_hdmi_disable(void)
450{
451 regulator_disable(cardhu_hdmi_reg);
452 regulator_put(cardhu_hdmi_reg);
453 cardhu_hdmi_reg = NULL;
454
455 regulator_disable(cardhu_hdmi_pll);
456 regulator_put(cardhu_hdmi_pll);
457 cardhu_hdmi_pll = NULL;
458 return 0;
459}
460
461static struct resource cardhu_disp1_resources[] = {
462 {
463 .name = "irq",
464 .start = INT_DISPLAY_GENERAL,
465 .end = INT_DISPLAY_GENERAL,
466 .flags = IORESOURCE_IRQ,
467 },
468 {
469 .name = "regs",
470 .start = TEGRA_DISPLAY_BASE,
471 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
472 .flags = IORESOURCE_MEM,
473 },
474 {
475 .name = "fbmem",
476 .start = 0, /* Filled in by cardhu_panel_init() */
477 .end = 0, /* Filled in by cardhu_panel_init() */
478 .flags = IORESOURCE_MEM,
479 },
480#ifdef CONFIG_TEGRA_DSI_INSTANCE_1
481 {
482 .name = "dsi_regs",
483 .start = TEGRA_DSIB_BASE,
484 .end = TEGRA_DSIB_BASE + TEGRA_DSIB_SIZE - 1,
485 .flags = IORESOURCE_MEM,
486 },
487#else
488 {
489 .name = "dsi_regs",
490 .start = TEGRA_DSI_BASE,
491 .end = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
492 .flags = IORESOURCE_MEM,
493 },
494#endif
495};
496
497static struct resource cardhu_disp2_resources[] = {
498 {
499 .name = "irq",
500 .start = INT_DISPLAY_B_GENERAL,
501 .end = INT_DISPLAY_B_GENERAL,
502 .flags = IORESOURCE_IRQ,
503 },
504 {
505 .name = "regs",
506 .start = TEGRA_DISPLAY2_BASE,
507 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
508 .flags = IORESOURCE_MEM,
509 },
510 {
511 .name = "fbmem",
512 .flags = IORESOURCE_MEM,
513 .start = 0,
514 .end = 0,
515 },
516 {
517 .name = "hdmi_regs",
518 .start = TEGRA_HDMI_BASE,
519 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
520 .flags = IORESOURCE_MEM,
521 },
522};
523#endif
524
525#ifndef CONFIG_TEGRA_CARDHU_DSI
526static struct tegra_dc_mode panel_19X12_modes[] = {
527 {
528 .pclk = 154000000,
529 .h_ref_to_sync = 11,
530 .v_ref_to_sync = 1,
531 .h_sync_width = 32,
532 .v_sync_width = 6,
533 .h_back_porch = 80,
534 .v_back_porch = 26,
535 .h_active = 1920,
536 .v_active = 1200,
537 .h_front_porch = 48,
538 .v_front_porch = 3,
539 },
540};
541
542static struct tegra_dc_mode cardhu_panel_modes[] = {
543 {
544 /* 1366x768@60Hz */
545 .pclk = 74180000,
546 .h_ref_to_sync = 1,
547 .v_ref_to_sync = 1,
548 .h_sync_width = 30,
549 .v_sync_width = 5,
550 .h_back_porch = 52,
551 .v_back_porch = 20,
552 .h_active = 1366,
553 .v_active = 768,
554 .h_front_porch = 64,
555 .v_front_porch = 25,
556 },
557};
558
559static struct tegra_dc_mode cardhu_panel_modes_55hz[] = {
560 {
561 /* 1366x768p 55Hz */
562 .pclk = 68000000,
563 .h_ref_to_sync = 0,
564 .v_ref_to_sync = 12,
565 .h_sync_width = 30,
566 .v_sync_width = 5,
567 .h_back_porch = 52,
568 .v_back_porch = 20,
569 .h_active = 1366,
570 .v_active = 768,
571 .h_front_porch = 64,
572 .v_front_porch = 25,
573 },
574};
575#endif
576
577static struct tegra_dc_sd_settings cardhu_sd_settings = {
578 .enable = 1, /* enabled by default. */
579 .use_auto_pwm = false,
580 .hw_update_delay = 0,
581 .bin_width = -1,
582 .aggressiveness = 1,
583 .phase_in_adjustments = true,
584 .use_vid_luma = false,
585 /* Default video coefficients */
586 .coeff = {5, 9, 2},
587 .fc = {0, 0},
588 /* Immediate backlight changes */
589 .blp = {1024, 255},
590 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
591 /* Default BL TF */
592 .bltf = {
593 {
594 {57, 65, 74, 83},
595 {93, 103, 114, 126},
596 {138, 151, 165, 179},
597 {194, 209, 225, 242},
598 },
599 {
600 {58, 66, 75, 84},
601 {94, 105, 116, 127},
602 {140, 153, 166, 181},
603 {196, 211, 227, 244},
604 },
605 {
606 {60, 68, 77, 87},
607 {97, 107, 119, 130},
608 {143, 156, 170, 184},
609 {199, 215, 231, 248},
610 },
611 {
612 {64, 73, 82, 91},
613 {102, 113, 124, 137},
614 {149, 163, 177, 192},
615 {207, 223, 240, 255},
616 },
617 },
618 /* Default LUT */
619 .lut = {
620 {
621 {250, 250, 250},
622 {194, 194, 194},
623 {149, 149, 149},
624 {113, 113, 113},
625 {82, 82, 82},
626 {56, 56, 56},
627 {34, 34, 34},
628 {15, 15, 15},
629 {0, 0, 0},
630 },
631 {
632 {246, 246, 246},
633 {191, 191, 191},
634 {147, 147, 147},
635 {111, 111, 111},
636 {80, 80, 80},
637 {55, 55, 55},
638 {33, 33, 33},
639 {14, 14, 14},
640 {0, 0, 0},
641 },
642 {
643 {239, 239, 239},
644 {185, 185, 185},
645 {142, 142, 142},
646 {107, 107, 107},
647 {77, 77, 77},
648 {52, 52, 52},
649 {30, 30, 30},
650 {12, 12, 12},
651 {0, 0, 0},
652 },
653 {
654 {224, 224, 224},
655 {173, 173, 173},
656 {133, 133, 133},
657 {99, 99, 99},
658 {70, 70, 70},
659 {46, 46, 46},
660 {25, 25, 25},
661 {7, 7, 7},
662 {0, 0, 0},
663 },
664 },
665 .sd_brightness = &sd_brightness,
666 .bl_device = &cardhu_backlight_device,
667};
668
669#ifdef CONFIG_TEGRA_DC
670#ifndef CONFIG_TEGRA_CARDHU_DSI
671static struct tegra_fb_data cardhu_fb_data = {
672 .win = 0,
673 .xres = 1366,
674 .yres = 768,
675 .bits_per_pixel = 32,
676 .flags = TEGRA_FB_FLIP_ON_PROBE,
677};
678#endif
679
680static struct tegra_fb_data cardhu_hdmi_fb_data = {
681 .win = 0,
682 .xres = 1366,
683 .yres = 768,
684 .bits_per_pixel = 32,
685 .flags = TEGRA_FB_FLIP_ON_PROBE,
686};
687
688static struct tegra_dc_out cardhu_disp2_out = {
689 .type = TEGRA_DC_OUT_HDMI,
690 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
691
692 .dcc_bus = 3,
693 .hotplug_gpio = cardhu_hdmi_hpd,
694
695 .max_pixclock = KHZ2PICOS(148500),
696
697 .align = TEGRA_DC_ALIGN_MSB,
698 .order = TEGRA_DC_ORDER_RED_BLUE,
699
700 .enable = cardhu_hdmi_enable,
701 .disable = cardhu_hdmi_disable,
702
703 .postsuspend = cardhu_hdmi_vddio_disable,
704 .hotplug_init = cardhu_hdmi_vddio_enable,
705};
706
707static struct tegra_dc_platform_data cardhu_disp2_pdata = {
708 .flags = 0,
709 .default_out = &cardhu_disp2_out,
710 .fb = &cardhu_hdmi_fb_data,
711 .emc_clk_rate = 300000000,
712};
713#endif
714
715#ifdef CONFIG_TEGRA_CARDHU_DSI
716static int cardhu_dsi_panel_enable(void)
717{
718 int ret;
719
720 if (cardhu_dsi_reg == NULL) {
721 cardhu_dsi_reg = regulator_get(NULL, "avdd_dsi_csi");
722 if (IS_ERR_OR_NULL(cardhu_dsi_reg)) {
723 pr_err("dsi: Could not get regulator avdd_dsi_csi\n");
724 cardhu_dsi_reg = NULL;
725 return PTR_ERR(cardhu_dsi_reg);
726 }
727 }
728 regulator_enable(cardhu_dsi_reg);
729
730 ret = gpio_request(AVDD_LCD, "avdd_lcd");
731 if (ret < 0)
732 gpio_free(AVDD_LCD);
733 ret = gpio_direction_output(AVDD_LCD, 1);
734 if (ret < 0)
735 gpio_free(AVDD_LCD);
736 else
737 tegra_gpio_enable(AVDD_LCD);
738
739#if DSI_PANEL_219
740
741 ret = gpio_request(cardhu_bl_pwm, "bl_pwm");
742 if (ret < 0)
743 return ret;
744 ret = gpio_direction_output(cardhu_bl_pwm, 0);
745 if (ret < 0) {
746 gpio_free(cardhu_bl_pwm);
747 return ret;
748 } else
749 tegra_gpio_enable(cardhu_bl_pwm);
750
751 ret = gpio_request(cardhu_bl_enb, "bl_enb");
752 if (ret < 0)
753 return ret;
754 ret = gpio_direction_output(cardhu_bl_enb, 0);
755 if (ret < 0) {
756 gpio_free(cardhu_bl_enb);
757 return ret;
758 } else
759 tegra_gpio_enable(cardhu_bl_enb);
760
761 gpio_set_value(cardhu_lvds_shutdown, 1);
762 mdelay(20);
763 gpio_set_value(cardhu_bl_pwm, 1);
764 mdelay(10);
765 gpio_set_value(cardhu_bl_enb, 1);
766 mdelay(15);
767#endif
768
769#if DSI_PANEL_RESET
770#if DSI_PANEL_218
771 ret = gpio_request(cardhu_dsi_218_panel_reset, "dsi_panel_reset");
772 if (ret < 0) {
773 return ret;
774 }
775 ret = gpio_direction_output(cardhu_dsi_218_panel_reset, 0);
776 if (ret < 0) {
777 gpio_free(cardhu_dsi_218_panel_reset);
778 return ret;
779 } else
780 tegra_gpio_enable(cardhu_dsi_218_panel_reset);
781
782 gpio_set_value(cardhu_dsi_218_panel_reset, 1);
783 gpio_set_value(cardhu_dsi_218_panel_reset, 0);
784 mdelay(2);
785 gpio_set_value(cardhu_dsi_218_panel_reset, 1);
786 mdelay(2);
787#endif
788
789#if DSI_PANEL_219
790 ret = gpio_request(cardhu_dsi_219_panel_reset, "dsi_panel_reset");
791 if (ret < 0)
792 return ret;
793 ret = gpio_direction_output(cardhu_dsi_219_panel_reset, 0);
794 if (ret < 0) {
795 gpio_free(cardhu_dsi_219_panel_reset);
796 return ret;
797 } else
798 tegra_gpio_enable(cardhu_dsi_219_panel_reset);
799
800 gpio_set_value(cardhu_dsi_219_panel_reset, 0);
801 gpio_set_value(cardhu_dsi_219_panel_reset, 1);
802 mdelay(10);
803 gpio_set_value(cardhu_dsi_219_panel_reset, 0);
804 mdelay(10);
805 gpio_set_value(cardhu_dsi_219_panel_reset, 1);
806 mdelay(15);
807#endif
808#endif
809
810 return 0;
811}
812
813static int cardhu_dsi_panel_disable(void)
814{
815 int err;
816
817 err = 0;
818 printk(KERN_INFO "DSI panel disable\n");
819
820#if DSI_PANEL_219
821 tegra_gpio_disable(cardhu_dsi_219_panel_reset);
822 gpio_free(cardhu_dsi_219_panel_reset);
823 tegra_gpio_disable(cardhu_bl_enb);
824 gpio_free(cardhu_bl_enb);
825 tegra_gpio_disable(cardhu_bl_pwm);
826 gpio_free(cardhu_bl_pwm);
827 tegra_gpio_disable(cardhu_lvds_shutdown);
828 gpio_free(cardhu_lvds_shutdown);
829#endif
830
831#if DSI_PANEL_218
832 tegra_gpio_disable(cardhu_dsi_218_panel_reset);
833 gpio_free(cardhu_dsi_218_panel_reset);
834#endif
835
836 return err;
837}
838
839static int cardhu_dsi_panel_postsuspend(void)
840{
841 int err;
842
843 err = 0;
844 printk(KERN_INFO "DSI panel postsuspend\n");
845
846 if (cardhu_dsi_reg) {
847 err = regulator_disable(cardhu_dsi_reg);
848 if (err < 0)
849 printk(KERN_ERR
850 "DSI regulator avdd_dsi_csi disable failed\n");
851 regulator_put(cardhu_dsi_reg);
852 cardhu_dsi_reg = NULL;
853 }
854
855#if DSI_PANEL_218
856 tegra_gpio_disable(AVDD_LCD);
857 gpio_free(AVDD_LCD);
858#endif
859
860 return err;
861}
862
863static struct tegra_dsi_cmd dsi_init_cmd[] = {
864 DSI_CMD_SHORT(0x05, 0x11, 0x00),
865 DSI_DLY_MS(150),
866 DSI_CMD_SHORT(0x05, 0x29, 0x00),
867 DSI_DLY_MS(20),
868};
869
870static struct tegra_dsi_cmd dsi_suspend_cmd[] = {
871 DSI_CMD_SHORT(0x05, 0x28, 0x00),
872 DSI_DLY_MS(20),
873 DSI_CMD_SHORT(0x05, 0x10, 0x00),
874 DSI_DLY_MS(5),
875};
876
877struct tegra_dsi_out cardhu_dsi = {
878 .n_data_lanes = 2,
879 .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
880 .refresh_rate = 60,
881 .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
882
883 .panel_has_frame_buffer = true,
884#ifdef CONFIG_TEGRA_DSI_INSTANCE_1
885 .dsi_instance = 1,
886#else
887 .dsi_instance = 0,
888#endif
889 .panel_reset = DSI_PANEL_RESET,
890 .power_saving_suspend = true,
891
892 .n_init_cmd = ARRAY_SIZE(dsi_init_cmd),
893 .dsi_init_cmd = dsi_init_cmd,
894
895 .n_suspend_cmd = ARRAY_SIZE(dsi_suspend_cmd),
896 .dsi_suspend_cmd = dsi_suspend_cmd,
897
898 .video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
899 .lp_cmd_mode_freq_khz = 430000,
900};
901
902static struct tegra_dc_mode cardhu_dsi_modes[] = {
903#if DSI_PANEL_219
904 {
905 .pclk = 10000000,
906 .h_ref_to_sync = 4,
907 .v_ref_to_sync = 1,
908 .h_sync_width = 16,
909 .v_sync_width = 1,
910 .h_back_porch = 32,
911 .v_back_porch = 1,
912 .h_active = 540,
913 .v_active = 960,
914 .h_front_porch = 32,
915 .v_front_porch = 2,
916 },
917#endif
918
919#if DSI_PANEL_218
920 {
921 .pclk = 323000000,
922 .h_ref_to_sync = 11,
923 .v_ref_to_sync = 1,
924 .h_sync_width = 16,
925 .v_sync_width = 4,
926 .h_back_porch = 16,
927 .v_back_porch = 4,
928 .h_active = 864,
929 .v_active = 480,
930 .h_front_porch = 16,
931 .v_front_porch = 4,
932 },
933#endif
934
935};
936
937
938static struct tegra_fb_data cardhu_dsi_fb_data = {
939#if DSI_PANEL_219
940 .win = 0,
941 .xres = 540,
942 .yres = 960,
943 .bits_per_pixel = 32,
944#endif
945
946#if DSI_PANEL_218
947 .win = 0,
948 .xres = 864,
949 .yres = 480,
950 .bits_per_pixel = 32,
951#endif
952 .flags = TEGRA_FB_FLIP_ON_PROBE,
953};
954#endif
955
956static struct tegra_dc_out cardhu_disp1_out = {
957 .align = TEGRA_DC_ALIGN_MSB,
958 .order = TEGRA_DC_ORDER_RED_BLUE,
959 .sd_settings = &cardhu_sd_settings,
960
961#ifndef CONFIG_TEGRA_CARDHU_DSI
962 .parent_clk = "pll_p",
963 .parent_clk_backup = "pll_d2_out0",
964
965 .type = TEGRA_DC_OUT_RGB,
966#ifdef CONFIG_TEGRA_LVDS_18_BITS
967 .depth = 18,
968#endif
969#ifdef CONFIG_TEGRA_LVDS_24_BITS
970 .depth = 24,
971#endif
972 .dither = TEGRA_DC_ORDERED_DITHER,
973
974 .modes = cardhu_panel_modes,
975 .n_modes = ARRAY_SIZE(cardhu_panel_modes),
976
977 .enable = cardhu_panel_enable,
978 .disable = cardhu_panel_disable,
979#else
980 .type = TEGRA_DC_OUT_DSI,
981
982 .modes = cardhu_dsi_modes,
983 .n_modes = ARRAY_SIZE(cardhu_dsi_modes),
984
985 .dsi = &cardhu_dsi,
986
987 .enable = cardhu_dsi_panel_enable,
988 .disable = cardhu_dsi_panel_disable,
989 .postsuspend = cardhu_dsi_panel_postsuspend,
990#endif
991};
992
993#ifdef CONFIG_TEGRA_DC
994static struct tegra_dc_platform_data cardhu_disp1_pdata = {
995 .flags = TEGRA_DC_FLAG_ENABLED,
996 .default_out = &cardhu_disp1_out,
997 .emc_clk_rate = 300000000,
998#ifndef CONFIG_TEGRA_CARDHU_DSI
999 .fb = &cardhu_fb_data,
1000#else
1001 .fb = &cardhu_dsi_fb_data,
1002#endif
1003};
1004
1005static struct nvhost_device cardhu_disp1_device = {
1006 .name = "tegradc",
1007 .id = 0,
1008 .resource = cardhu_disp1_resources,
1009 .num_resources = ARRAY_SIZE(cardhu_disp1_resources),
1010 .dev = {
1011 .platform_data = &cardhu_disp1_pdata,
1012 },
1013};
1014
1015static int cardhu_disp1_check_fb(struct device *dev, struct fb_info *info)
1016{
1017 return info->device == &cardhu_disp1_device.dev;
1018}
1019
1020static struct nvhost_device cardhu_disp2_device = {
1021 .name = "tegradc",
1022 .id = 1,
1023 .resource = cardhu_disp2_resources,
1024 .num_resources = ARRAY_SIZE(cardhu_disp2_resources),
1025 .dev = {
1026 .platform_data = &cardhu_disp2_pdata,
1027 },
1028};
1029#else
1030static int cardhu_disp1_check_fb(struct device *dev, struct fb_info *info)
1031{
1032 return 0;
1033}
1034#endif
1035
1036#if defined(CONFIG_TEGRA_NVMAP)
1037static struct nvmap_platform_carveout cardhu_carveouts[] = {
1038 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
1039 [1] = {
1040 .name = "generic-0",
1041 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
1042 .base = 0, /* Filled in by cardhu_panel_init() */
1043 .size = 0, /* Filled in by cardhu_panel_init() */
1044 .buddy_size = SZ_32K,
1045 },
1046};
1047
1048static struct nvmap_platform_data cardhu_nvmap_data = {
1049 .carveouts = cardhu_carveouts,
1050 .nr_carveouts = ARRAY_SIZE(cardhu_carveouts),
1051};
1052
1053static struct platform_device cardhu_nvmap_device = {
1054 .name = "tegra-nvmap",
1055 .id = -1,
1056 .dev = {
1057 .platform_data = &cardhu_nvmap_data,
1058 },
1059};
1060#endif
1061
1062#if defined(CONFIG_ION_TEGRA)
1063
1064static struct platform_device tegra_iommu_device = {
1065 .name = "tegra_iommu_device",
1066 .id = -1,
1067 .dev = {
1068 .platform_data = (void *)((1 << HWGRP_COUNT) - 1),
1069 },
1070};
1071
1072static struct ion_platform_data tegra_ion_data = {
1073 .nr = 4,
1074 .heaps = {
1075 {
1076 .type = ION_HEAP_TYPE_CARVEOUT,
1077 .id = TEGRA_ION_HEAP_CARVEOUT,
1078 .name = "carveout",
1079 .base = 0,
1080 .size = 0,
1081 },
1082 {
1083 .type = ION_HEAP_TYPE_CARVEOUT,
1084 .id = TEGRA_ION_HEAP_IRAM,
1085 .name = "iram",
1086 .base = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
1087 .size = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
1088 },
1089 {
1090 .type = ION_HEAP_TYPE_CARVEOUT,
1091 .id = TEGRA_ION_HEAP_VPR,
1092 .name = "vpr",
1093 .base = 0,
1094 .size = 0,
1095 },
1096 {
1097 .type = ION_HEAP_TYPE_IOMMU,
1098 .id = TEGRA_ION_HEAP_IOMMU,
1099 .name = "iommu",
1100 .base = TEGRA_SMMU_BASE,
1101 .size = TEGRA_SMMU_SIZE,
1102 .priv = &tegra_iommu_device.dev,
1103 },
1104 },
1105};
1106
1107static struct platform_device tegra_ion_device = {
1108 .name = "ion-tegra",
1109 .id = -1,
1110 .dev = {
1111 .platform_data = &tegra_ion_data,
1112 },
1113};
1114#endif
1115
1116static struct platform_device *cardhu_gfx_devices[] __initdata = {
1117#if defined(CONFIG_TEGRA_NVMAP)
1118 &cardhu_nvmap_device,
1119#endif
1120#if defined(CONFIG_ION_TEGRA)
1121 &tegra_ion_device,
1122#endif
1123 &tegra_pwfm0_device,
1124 &cardhu_backlight_device,
1125};
1126
1127
1128#ifdef CONFIG_HAS_EARLYSUSPEND
1129/* put early_suspend/late_resume handlers here for the display in order
1130 * to keep the code out of the display driver, keeping it closer to upstream
1131 */
1132struct early_suspend cardhu_panel_early_suspender;
1133
1134static void cardhu_panel_early_suspend(struct early_suspend *h)
1135{
1136 /* power down LCD, add use a black screen for HDMI */
1137 if (num_registered_fb > 0)
1138 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
1139 if (num_registered_fb > 1)
1140 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
1141}
1142
1143static void cardhu_panel_late_resume(struct early_suspend *h)
1144{
1145 unsigned i;
1146 for (i = 0; i < num_registered_fb; i++)
1147 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
1148}
1149#endif
1150
1151int __init cardhu_panel_init(void)
1152{
1153 int err;
1154 struct resource __maybe_unused *res;
1155
1156 tegra_get_board_info(&board_info);
1157 tegra_get_display_board_info(&display_board_info);
1158
1159#if defined(CONFIG_TEGRA_NVMAP)
1160 cardhu_carveouts[1].base = tegra_carveout_start;
1161 cardhu_carveouts[1].size = tegra_carveout_size;
1162#endif
1163
1164#if defined(CONFIG_ION_TEGRA)
1165 tegra_ion_data.heaps[0].base = tegra_carveout_start;
1166 tegra_ion_data.heaps[0].size = tegra_carveout_size;
1167#endif
1168
1169#if defined(CONFIG_TEGRA_DC) && !defined(CONFIG_TEGRA_CARDHU_DSI)
1170 if (board_info.board_id == BOARD_E1291 &&
1171 ((board_info.sku & SKU_TOUCHSCREEN_MECH_FIX) == 0)) {
1172 /* use 55Hz panel timings to reduce noise on sensitive touch */
1173 printk("Using cardhu_panel_modes_55hz\n");
1174 cardhu_disp1_out.modes = cardhu_panel_modes_55hz;
1175 cardhu_disp1_out.n_modes = ARRAY_SIZE(cardhu_panel_modes_55hz);
1176 }
1177
1178 if (display_board_info.board_id == BOARD_DISPLAY_PM313) {
1179 /* initialize the values */
1180#if defined(PM313_LVDS_PANEL_19X12)
1181 cardhu_disp1_out.modes = panel_19X12_modes;
1182 cardhu_disp1_out.n_modes = ARRAY_SIZE(panel_19X12_modes);
1183 cardhu_disp1_out.parent_clk = "pll_d_out0";
1184#if (PM313_LVDS_PANEL_BPP == 1)
1185 cardhu_disp1_out.depth = 18;
1186#else
1187 cardhu_disp1_out.depth = 24;
1188#endif
1189 cardhu_fb_data.xres = 1920;
1190 cardhu_fb_data.yres = 1200;
1191
1192 cardhu_disp2_out.parent_clk = "pll_d2_out0";
1193 cardhu_hdmi_fb_data.xres = 1920;
1194 cardhu_hdmi_fb_data.yres = 1200;
1195#endif
1196
1197 /* lvds configuration */
1198 err = gpio_request(pm313_R_FDE, "R_FDE");
1199 err |= gpio_direction_output(pm313_R_FDE, 1);
1200 tegra_gpio_enable(pm313_R_FDE);
1201
1202 err |= gpio_request(pm313_R_FB, "R_FB");
1203 err |= gpio_direction_output(pm313_R_FB, 1);
1204 tegra_gpio_enable(pm313_R_FB);
1205
1206 err |= gpio_request(pm313_MODE0, "MODE0");
1207 err |= gpio_direction_output(pm313_MODE0, 1);
1208 tegra_gpio_enable(pm313_MODE0);
1209
1210 err |= gpio_request(pm313_MODE1, "MODE1");
1211 err |= gpio_direction_output(pm313_MODE1, 0);
1212 tegra_gpio_enable(pm313_MODE1);
1213
1214 err |= gpio_request(pm313_BPP, "BPP");
1215 err |= gpio_direction_output(pm313_BPP, PM313_LVDS_PANEL_BPP);
1216 tegra_gpio_enable(pm313_BPP);
1217
1218 err = gpio_request(pm313_lvds_shutdown, "lvds_shutdown");
1219 /* free ride provided by bootloader */
1220 err |= gpio_direction_output(pm313_lvds_shutdown, 1);
1221 tegra_gpio_enable(pm313_lvds_shutdown);
1222
1223 if (err)
1224 printk(KERN_ERR "ERROR(s) in LVDS configuration\n");
1225 } else if ((display_board_info.board_id == BOARD_DISPLAY_E1247 &&
1226 board_info.board_id == BOARD_PM269) ||
1227 (board_info.board_id == BOARD_E1257) ||
1228 (board_info.board_id == BOARD_PM305) ||
1229 (board_info.board_id == BOARD_PM311)) {
1230 gpio_request(e1247_pm269_lvds_shutdown, "lvds_shutdown");
1231 gpio_direction_output(e1247_pm269_lvds_shutdown, 1);
1232 tegra_gpio_enable(e1247_pm269_lvds_shutdown);
1233 } else {
1234 gpio_request(cardhu_lvds_shutdown, "lvds_shutdown");
1235 gpio_direction_output(cardhu_lvds_shutdown, 1);
1236 tegra_gpio_enable(cardhu_lvds_shutdown);
1237 }
1238#endif
1239
1240 tegra_gpio_enable(cardhu_hdmi_hpd);
1241 gpio_request(cardhu_hdmi_hpd, "hdmi_hpd");
1242 gpio_direction_input(cardhu_hdmi_hpd);
1243
1244#ifdef CONFIG_HAS_EARLYSUSPEND
1245 cardhu_panel_early_suspender.suspend = cardhu_panel_early_suspend;
1246 cardhu_panel_early_suspender.resume = cardhu_panel_late_resume;
1247 cardhu_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
1248 register_early_suspend(&cardhu_panel_early_suspender);
1249#endif
1250
1251#ifdef CONFIG_TEGRA_GRHOST
1252 err = nvhost_device_register(&tegra_grhost_device);
1253 if (err)
1254 return err;
1255#endif
1256
1257 err = platform_add_devices(cardhu_gfx_devices,
1258 ARRAY_SIZE(cardhu_gfx_devices));
1259
1260#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
1261 res = nvhost_get_resource_byname(&cardhu_disp1_device,
1262 IORESOURCE_MEM, "fbmem");
1263 res->start = tegra_fb_start;
1264 res->end = tegra_fb_start + tegra_fb_size - 1;
1265#endif
1266
1267 /* Copy the bootloader fb to the fb. */
1268 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
1269 min(tegra_fb_size, tegra_bootloader_fb_size));
1270
1271#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
1272 if (!err)
1273 err = nvhost_device_register(&cardhu_disp1_device);
1274
1275 res = nvhost_get_resource_byname(&cardhu_disp2_device,
1276 IORESOURCE_MEM, "fbmem");
1277 res->start = tegra_fb2_start;
1278 res->end = tegra_fb2_start + tegra_fb2_size - 1;
1279 if (!err)
1280 err = nvhost_device_register(&cardhu_disp2_device);
1281#endif
1282
1283#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_NVAVP)
1284 if (!err)
1285 err = nvhost_device_register(&nvavp_device);
1286#endif
1287 return err;
1288}