aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-enterprise-panel.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/mach-tegra/board-enterprise-panel.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/arm/mach-tegra/board-enterprise-panel.c')
-rw-r--r--arch/arm/mach-tegra/board-enterprise-panel.c905
1 files changed, 905 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-enterprise-panel.c b/arch/arm/mach-tegra/board-enterprise-panel.c
new file mode 100644
index 00000000000..9dc5da1f28d
--- /dev/null
+++ b/arch/arm/mach-tegra/board-enterprise-panel.c
@@ -0,0 +1,905 @@
1/*
2 * arch/arm/mach-tegra/board-enterprise-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
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/earlysuspend.h>
28#include <linux/tegra_pwm_bl.h>
29#include <asm/atomic.h>
30#include <linux/nvhost.h>
31#include <mach/nvmap.h>
32#include <mach/irqs.h>
33#include <mach/iomap.h>
34#include <mach/dc.h>
35#include <mach/fb.h>
36#include <mach/hardware.h>
37
38#include "board.h"
39#include "board-enterprise.h"
40#include "devices.h"
41#include "gpio-names.h"
42
43#define DC_CTRL_MODE TEGRA_DC_OUT_ONE_SHOT_MODE
44
45/* Select panel to be used. */
46#define AVDD_LCD PMU_TCA6416_GPIO_PORT17
47#define DSI_PANEL_RESET 1
48
49#define enterprise_lvds_shutdown TEGRA_GPIO_PL2
50#define enterprise_hdmi_hpd TEGRA_GPIO_PN7
51
52#define enterprise_dsi_panel_reset TEGRA_GPIO_PW0
53
54#define enterprise_lcd_2d_3d TEGRA_GPIO_PH1
55#define ENTERPRISE_STEREO_3D 0
56#define ENTERPRISE_STEREO_2D 1
57
58#define enterprise_lcd_swp_pl TEGRA_GPIO_PH2
59#define ENTERPRISE_STEREO_LANDSCAPE 0
60#define ENTERPRISE_STEREO_PORTRAIT 1
61
62#define enterprise_lcd_te TEGRA_GPIO_PJ1
63
64#ifdef CONFIG_TEGRA_DC
65static struct regulator *enterprise_dsi_reg;
66static struct regulator *enterprise_lcd_reg;
67
68static struct regulator *enterprise_hdmi_reg;
69static struct regulator *enterprise_hdmi_pll;
70static struct regulator *enterprise_hdmi_vddio;
71#endif
72
73static atomic_t sd_brightness = ATOMIC_INIT(255);
74
75static tegra_dc_bl_output enterprise_bl_output_measured_a02 = {
76 1, 5, 9, 10, 11, 12, 12, 13,
77 13, 14, 14, 15, 15, 16, 16, 17,
78 17, 18, 18, 19, 19, 20, 21, 21,
79 22, 22, 23, 24, 24, 25, 26, 26,
80 27, 27, 28, 29, 29, 31, 31, 32,
81 32, 33, 34, 35, 36, 36, 37, 38,
82 39, 39, 40, 41, 41, 42, 43, 43,
83 44, 45, 45, 46, 47, 47, 48, 49,
84 49, 50, 51, 51, 52, 53, 53, 54,
85 55, 56, 56, 57, 58, 59, 60, 61,
86 61, 62, 63, 64, 65, 65, 66, 67,
87 67, 68, 69, 69, 70, 71, 71, 72,
88 73, 73, 74, 74, 75, 76, 76, 77,
89 77, 78, 79, 79, 80, 81, 82, 83,
90 83, 84, 85, 85, 86, 86, 88, 89,
91 90, 91, 91, 92, 93, 93, 94, 95,
92 95, 96, 97, 97, 98, 99, 99, 100,
93 101, 101, 102, 103, 103, 104, 105, 105,
94 107, 107, 108, 109, 110, 111, 111, 112,
95 113, 113, 114, 115, 115, 116, 117, 117,
96 118, 119, 119, 120, 121, 122, 123, 124,
97 124, 125, 126, 126, 127, 128, 129, 129,
98 130, 131, 131, 132, 133, 133, 134, 135,
99 135, 136, 137, 137, 138, 139, 139, 140,
100 142, 142, 143, 144, 145, 146, 147, 147,
101 148, 149, 149, 150, 151, 152, 153, 153,
102 153, 154, 155, 156, 157, 158, 158, 159,
103 160, 161, 162, 163, 163, 164, 165, 165,
104 166, 166, 167, 168, 169, 169, 170, 170,
105 171, 172, 173, 173, 174, 175, 175, 176,
106 176, 178, 178, 179, 180, 181, 182, 182,
107 183, 184, 185, 186, 186, 187, 188, 188
108};
109
110/* TODO: Measure BL response for this table */
111static tegra_dc_bl_output enterprise_bl_output_measured_a03 = {
112 0, 1, 2, 3, 4, 5, 6, 7,
113 8, 9, 10, 11, 12, 13, 14, 15,
114 16, 17, 18, 19, 20, 21, 22, 23,
115 24, 25, 26, 27, 28, 29, 30, 31,
116 32, 33, 34, 35, 36, 37, 38, 39,
117 40, 41, 42, 43, 44, 45, 46, 47,
118 48, 49, 50, 51, 52, 53, 54, 55,
119 56, 57, 58, 59, 60, 61, 62, 63,
120 64, 65, 66, 67, 68, 69, 70, 71,
121 72, 73, 74, 75, 76, 77, 78, 79,
122 80, 81, 82, 83, 84, 85, 86, 87,
123 88, 89, 90, 91, 92, 93, 94, 95,
124 96, 97, 98, 99, 100, 101, 102, 103,
125 104, 105, 106, 107, 108, 109, 110, 111,
126 112, 113, 114, 115, 116, 117, 118, 119,
127 120, 121, 122, 123, 124, 125, 126, 127,
128 128, 129, 130, 131, 132, 133, 134, 135,
129 136, 137, 138, 139, 140, 141, 142, 143,
130 144, 145, 146, 147, 148, 149, 150, 151,
131 152, 153, 154, 155, 156, 157, 158, 159,
132 160, 161, 162, 163, 164, 165, 166, 167,
133 168, 169, 170, 171, 172, 173, 174, 175,
134 176, 177, 178, 179, 180, 181, 182, 183,
135 184, 185, 186, 187, 188, 189, 190, 191,
136 192, 193, 194, 195, 196, 197, 198, 199,
137 200, 201, 202, 203, 204, 205, 206, 207,
138 208, 209, 210, 211, 212, 213, 214, 215,
139 216, 217, 218, 219, 220, 221, 222, 223,
140 224, 225, 226, 227, 228, 229, 230, 231,
141 232, 233, 234, 235, 236, 237, 238, 239,
142 240, 241, 242, 243, 244, 245, 246, 247,
143 248, 249, 250, 251, 252, 253, 254, 255,
144};
145
146static p_tegra_dc_bl_output bl_output;
147
148static bool kernel_1st_panel_init = true;
149
150static int enterprise_backlight_notify(struct device *unused, int brightness)
151{
152 int cur_sd_brightness = atomic_read(&sd_brightness);
153 int orig_brightness = brightness;
154
155 /* SD brightness is a percentage, 8-bit value. */
156 brightness = (brightness * cur_sd_brightness) / 255;
157
158 /* Apply any backlight response curve */
159 if (brightness > 255)
160 pr_info("Error: Brightness > 255!\n");
161 else
162 brightness = bl_output[brightness];
163
164 return brightness;
165}
166
167static int enterprise_disp1_check_fb(struct device *dev, struct fb_info *info);
168
169/*
170 * In case which_pwm is TEGRA_PWM_PM0,
171 * gpio_conf_to_sfio should be TEGRA_GPIO_PW0: set LCD_CS1_N pin to SFIO
172 * In case which_pwm is TEGRA_PWM_PM1,
173 * gpio_conf_to_sfio should be TEGRA_GPIO_PW1: set LCD_M1 pin to SFIO
174 */
175static struct platform_tegra_pwm_backlight_data enterprise_disp1_backlight_data = {
176 .which_dc = 0,
177 .which_pwm = TEGRA_PWM_PM1,
178 .gpio_conf_to_sfio = TEGRA_GPIO_PW1,
179 .switch_to_sfio = &tegra_gpio_disable,
180 .max_brightness = 255,
181 .dft_brightness = 224,
182 .notify = enterprise_backlight_notify,
183 .period = 0xFF,
184 .clk_div = 0x3FF,
185 .clk_select = 0,
186 /* Only toggle backlight on fb blank notifications for disp1 */
187 .check_fb = enterprise_disp1_check_fb,
188};
189
190static struct platform_device enterprise_disp1_backlight_device = {
191 .name = "tegra-pwm-bl",
192 .id = -1,
193 .dev = {
194 .platform_data = &enterprise_disp1_backlight_data,
195 },
196};
197
198#ifdef CONFIG_TEGRA_DC
199static int enterprise_hdmi_vddio_enable(void)
200{
201 int ret;
202 if (!enterprise_hdmi_vddio) {
203 enterprise_hdmi_vddio = regulator_get(NULL, "hdmi_5v0");
204 if (IS_ERR_OR_NULL(enterprise_hdmi_vddio)) {
205 ret = PTR_ERR(enterprise_hdmi_vddio);
206 pr_err("hdmi: couldn't get regulator hdmi_5v0\n");
207 enterprise_hdmi_vddio = NULL;
208 return ret;
209 }
210 }
211 ret = regulator_enable(enterprise_hdmi_vddio);
212 if (ret < 0) {
213 pr_err("hdmi: couldn't enable regulator hdmi_5v0\n");
214 regulator_put(enterprise_hdmi_vddio);
215 enterprise_hdmi_vddio = NULL;
216 return ret;
217 }
218 return ret;
219}
220
221static int enterprise_hdmi_vddio_disable(void)
222{
223 if (enterprise_hdmi_vddio) {
224 regulator_disable(enterprise_hdmi_vddio);
225 regulator_put(enterprise_hdmi_vddio);
226 enterprise_hdmi_vddio = NULL;
227 }
228 return 0;
229}
230
231static int enterprise_hdmi_enable(void)
232{
233 int ret;
234 if (!enterprise_hdmi_reg) {
235 enterprise_hdmi_reg = regulator_get(NULL, "avdd_hdmi");
236 if (IS_ERR_OR_NULL(enterprise_hdmi_reg)) {
237 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
238 enterprise_hdmi_reg = NULL;
239 return PTR_ERR(enterprise_hdmi_reg);
240 }
241 }
242 ret = regulator_enable(enterprise_hdmi_reg);
243 if (ret < 0) {
244 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
245 return ret;
246 }
247 if (!enterprise_hdmi_pll) {
248 enterprise_hdmi_pll = regulator_get(NULL, "avdd_hdmi_pll");
249 if (IS_ERR_OR_NULL(enterprise_hdmi_pll)) {
250 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
251 enterprise_hdmi_pll = NULL;
252 regulator_put(enterprise_hdmi_reg);
253 enterprise_hdmi_reg = NULL;
254 return PTR_ERR(enterprise_hdmi_pll);
255 }
256 }
257 ret = regulator_enable(enterprise_hdmi_pll);
258 if (ret < 0) {
259 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
260 return ret;
261 }
262 return 0;
263}
264
265static int enterprise_hdmi_disable(void)
266{
267
268 regulator_disable(enterprise_hdmi_reg);
269 regulator_put(enterprise_hdmi_reg);
270 enterprise_hdmi_reg = NULL;
271
272 regulator_disable(enterprise_hdmi_pll);
273 regulator_put(enterprise_hdmi_pll);
274 enterprise_hdmi_pll = NULL;
275
276 return 0;
277}
278static struct resource enterprise_disp1_resources[] = {
279 {
280 .name = "irq",
281 .start = INT_DISPLAY_GENERAL,
282 .end = INT_DISPLAY_GENERAL,
283 .flags = IORESOURCE_IRQ,
284 },
285 {
286 .name = "regs",
287 .start = TEGRA_DISPLAY_BASE,
288 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
289 .flags = IORESOURCE_MEM,
290 },
291 {
292 .name = "fbmem",
293 .start = 0, /* Filled in by enterprise_panel_init() */
294 .end = 0, /* Filled in by enterprise_panel_init() */
295 .flags = IORESOURCE_MEM,
296 },
297 {
298 .name = "dsi_regs",
299 .start = TEGRA_DSI_BASE,
300 .end = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
301 .flags = IORESOURCE_MEM,
302 },
303};
304
305static struct resource enterprise_disp2_resources[] = {
306 {
307 .name = "irq",
308 .start = INT_DISPLAY_B_GENERAL,
309 .end = INT_DISPLAY_B_GENERAL,
310 .flags = IORESOURCE_IRQ,
311 },
312 {
313 .name = "regs",
314 .start = TEGRA_DISPLAY2_BASE,
315 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
316 .flags = IORESOURCE_MEM,
317 },
318 {
319 .name = "fbmem",
320 .flags = IORESOURCE_MEM,
321 .start = 0,
322 .end = 0,
323 },
324 {
325 .name = "hdmi_regs",
326 .start = TEGRA_HDMI_BASE,
327 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
328 .flags = IORESOURCE_MEM,
329 },
330};
331
332static struct tegra_dc_sd_settings enterprise_sd_settings = {
333 .enable = 1, /* Normal mode operation */
334 .use_auto_pwm = false,
335 .hw_update_delay = 0,
336 .bin_width = -1,
337 .aggressiveness = 1,
338 .phase_in_adjustments = true,
339 .use_vid_luma = false,
340 /* Default video coefficients */
341 .coeff = {5, 9, 2},
342 .fc = {0, 0},
343 /* Immediate backlight changes */
344 .blp = {1024, 255},
345 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
346 /* Default BL TF */
347 .bltf = {
348 {
349 {57, 65, 74, 83},
350 {93, 103, 114, 126},
351 {138, 151, 165, 179},
352 {194, 209, 225, 242},
353 },
354 {
355 {58, 66, 75, 84},
356 {94, 105, 116, 127},
357 {140, 153, 166, 181},
358 {196, 211, 227, 244},
359 },
360 {
361 {60, 68, 77, 87},
362 {97, 107, 119, 130},
363 {143, 156, 170, 184},
364 {199, 215, 231, 248},
365 },
366 {
367 {64, 73, 82, 91},
368 {102, 113, 124, 137},
369 {149, 163, 177, 192},
370 {207, 223, 240, 255},
371 },
372 },
373 /* Default LUT */
374 .lut = {
375 {
376 {250, 250, 250},
377 {194, 194, 194},
378 {149, 149, 149},
379 {113, 113, 113},
380 {82, 82, 82},
381 {56, 56, 56},
382 {34, 34, 34},
383 {15, 15, 15},
384 {0, 0, 0},
385 },
386 {
387 {246, 246, 246},
388 {191, 191, 191},
389 {147, 147, 147},
390 {111, 111, 111},
391 {80, 80, 80},
392 {55, 55, 55},
393 {33, 33, 33},
394 {14, 14, 14},
395 {0, 0, 0},
396 },
397 {
398 {239, 239, 239},
399 {185, 185, 185},
400 {142, 142, 142},
401 {107, 107, 107},
402 {77, 77, 77},
403 {52, 52, 52},
404 {30, 30, 30},
405 {12, 12, 12},
406 {0, 0, 0},
407 },
408 {
409 {224, 224, 224},
410 {173, 173, 173},
411 {133, 133, 133},
412 {99, 99, 99},
413 {70, 70, 70},
414 {46, 46, 46},
415 {25, 25, 25},
416 {7, 7, 7},
417 {0, 0, 0},
418 },
419 },
420 .sd_brightness = &sd_brightness,
421 .bl_device = &enterprise_disp1_backlight_device,
422};
423
424static struct tegra_fb_data enterprise_hdmi_fb_data = {
425 .win = 0,
426 .xres = 1366,
427 .yres = 768,
428 .bits_per_pixel = 32,
429 .flags = TEGRA_FB_FLIP_ON_PROBE,
430};
431
432static struct tegra_dc_out enterprise_disp2_out = {
433 .type = TEGRA_DC_OUT_HDMI,
434 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
435 .parent_clk = "pll_d2_out0",
436
437 .dcc_bus = 3,
438 .hotplug_gpio = enterprise_hdmi_hpd,
439
440 .max_pixclock = KHZ2PICOS(148500),
441
442 .align = TEGRA_DC_ALIGN_MSB,
443 .order = TEGRA_DC_ORDER_RED_BLUE,
444
445 .enable = enterprise_hdmi_enable,
446 .disable = enterprise_hdmi_disable,
447 .postsuspend = enterprise_hdmi_vddio_disable,
448 .hotplug_init = enterprise_hdmi_vddio_enable,
449};
450
451static struct tegra_dc_platform_data enterprise_disp2_pdata = {
452 .flags = 0,
453 .default_out = &enterprise_disp2_out,
454 .fb = &enterprise_hdmi_fb_data,
455 .emc_clk_rate = 300000000,
456};
457
458static int enterprise_dsi_panel_enable(void)
459{
460 int ret;
461 struct board_info board_info;
462
463 tegra_get_board_info(&board_info);
464
465 if (enterprise_dsi_reg == NULL) {
466 enterprise_dsi_reg = regulator_get(NULL, "avdd_dsi_csi");
467 if (IS_ERR_OR_NULL(enterprise_dsi_reg)) {
468 pr_err("dsi: Could not get regulator avdd_dsi_csi\n");
469 enterprise_dsi_reg = NULL;
470 return PTR_ERR(enterprise_dsi_reg);
471 }
472 }
473 ret = regulator_enable(enterprise_dsi_reg);
474 if (ret < 0) {
475 printk(KERN_ERR
476 "DSI regulator avdd_dsi_csi could not be enabled\n");
477 return ret;
478 }
479
480#if DSI_PANEL_RESET
481
482 if (board_info.fab >= BOARD_FAB_A03) {
483 if (enterprise_lcd_reg == NULL) {
484 enterprise_lcd_reg = regulator_get(NULL, "lcd_vddio_en");
485 if (IS_ERR_OR_NULL(enterprise_lcd_reg)) {
486 pr_err("Could not get regulator lcd_vddio_en\n");
487 ret = PTR_ERR(enterprise_lcd_reg);
488 enterprise_lcd_reg = NULL;
489 return ret;
490 }
491 }
492 if (enterprise_lcd_reg != NULL) {
493 ret = regulator_enable(enterprise_lcd_reg);
494 if (ret < 0) {
495 pr_err("Could not enable lcd_vddio_en\n");
496 return ret;
497 }
498 }
499 }
500
501 if (kernel_1st_panel_init != true) {
502 ret = gpio_request(enterprise_dsi_panel_reset, "panel reset");
503 if (ret < 0)
504 return ret;
505
506 ret = gpio_direction_output(enterprise_dsi_panel_reset, 0);
507 if (ret < 0) {
508 gpio_free(enterprise_dsi_panel_reset);
509 return ret;
510 }
511 tegra_gpio_enable(enterprise_dsi_panel_reset);
512
513 gpio_set_value(enterprise_dsi_panel_reset, 0);
514 udelay(2000);
515 gpio_set_value(enterprise_dsi_panel_reset, 1);
516 mdelay(20);
517 }
518#endif
519
520 return ret;
521}
522
523static int enterprise_dsi_panel_disable(void)
524{
525 if (enterprise_lcd_reg != NULL)
526 regulator_disable(enterprise_lcd_reg);
527
528#if DSI_PANEL_RESET
529 if (kernel_1st_panel_init != true) {
530 tegra_gpio_disable(enterprise_dsi_panel_reset);
531 gpio_free(enterprise_dsi_panel_reset);
532 } else
533 kernel_1st_panel_init = false;
534#endif
535 return 0;
536}
537#endif
538
539static void enterprise_stereo_set_mode(int mode)
540{
541 switch (mode) {
542 case TEGRA_DC_STEREO_MODE_2D:
543 gpio_set_value(TEGRA_GPIO_PH1, ENTERPRISE_STEREO_2D);
544 break;
545 case TEGRA_DC_STEREO_MODE_3D:
546 gpio_set_value(TEGRA_GPIO_PH1, ENTERPRISE_STEREO_3D);
547 break;
548 }
549}
550
551static void enterprise_stereo_set_orientation(int mode)
552{
553 switch (mode) {
554 case TEGRA_DC_STEREO_LANDSCAPE:
555 gpio_set_value(TEGRA_GPIO_PH2, ENTERPRISE_STEREO_LANDSCAPE);
556 break;
557 case TEGRA_DC_STEREO_PORTRAIT:
558 gpio_set_value(TEGRA_GPIO_PH2, ENTERPRISE_STEREO_PORTRAIT);
559 break;
560 }
561}
562
563#ifdef CONFIG_TEGRA_DC
564static int enterprise_dsi_panel_postsuspend(void)
565{
566 /* Do nothing for enterprise dsi panel */
567 return 0;
568}
569#endif
570
571static struct tegra_dsi_cmd dsi_init_cmd[]= {
572 DSI_CMD_SHORT(0x05, 0x11, 0x00),
573 DSI_DLY_MS(20),
574#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
575 DSI_CMD_SHORT(0x15, 0x35, 0x00),
576#endif
577 DSI_CMD_SHORT(0x05, 0x29, 0x00),
578 DSI_DLY_MS(20),
579};
580
581static struct tegra_dsi_cmd dsi_early_suspend_cmd[] = {
582 DSI_CMD_SHORT(0x05, 0x28, 0x00),
583 DSI_DLY_MS(20),
584#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
585 DSI_CMD_SHORT(0x05, 0x34, 0x00),
586#endif
587};
588
589static struct tegra_dsi_cmd dsi_late_resume_cmd[] = {
590#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
591 DSI_CMD_SHORT(0x15, 0x35, 0x00),
592#endif
593 DSI_CMD_SHORT(0x05, 0x29, 0x00),
594 DSI_DLY_MS(20),
595};
596
597static struct tegra_dsi_cmd dsi_suspend_cmd[] = {
598 DSI_CMD_SHORT(0x05, 0x28, 0x00),
599 DSI_DLY_MS(20),
600#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
601 DSI_CMD_SHORT(0x05, 0x34, 0x00),
602#endif
603 DSI_CMD_SHORT(0x05, 0x10, 0x00),
604 DSI_DLY_MS(5),
605};
606
607struct tegra_dsi_out enterprise_dsi = {
608 .n_data_lanes = 2,
609 .pixel_format = TEGRA_DSI_PIXEL_FORMAT_24BIT_P,
610#if(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
611 /* For one-shot mode, actual refresh rate is decided by the
612 * frequency of TE signal. Although the frequency of TE is
613 * expected running at rated_refresh_rate (typically 60Hz),
614 * it may vary. Mismatch between freq of DC and TE signal
615 * would cause frame drop. We increase refresh_rate to the
616 * value larger than maximum TE frequency to avoid missing
617 * any TE signal. The value of refresh_rate is also used to
618 * calculate the pixel clock.
619 */
620 .refresh_rate = 66,
621 .rated_refresh_rate = 60,
622#else
623 .refresh_rate = 60,
624#endif
625 .virtual_channel = TEGRA_DSI_VIRTUAL_CHANNEL_0,
626
627 .panel_has_frame_buffer = true,
628 .dsi_instance = 0,
629
630 .panel_reset = DSI_PANEL_RESET,
631 .power_saving_suspend = true,
632 .n_init_cmd = ARRAY_SIZE(dsi_init_cmd),
633 .dsi_init_cmd = dsi_init_cmd,
634
635 .n_early_suspend_cmd = ARRAY_SIZE(dsi_early_suspend_cmd),
636 .dsi_early_suspend_cmd = dsi_early_suspend_cmd,
637
638 .n_late_resume_cmd = ARRAY_SIZE(dsi_late_resume_cmd),
639 .dsi_late_resume_cmd = dsi_late_resume_cmd,
640
641 .n_suspend_cmd = ARRAY_SIZE(dsi_suspend_cmd),
642 .dsi_suspend_cmd = dsi_suspend_cmd,
643
644 .video_data_type = TEGRA_DSI_VIDEO_TYPE_COMMAND_MODE,
645 .lp_cmd_mode_freq_khz = 20000,
646
647 /* TODO: Get the vender recommended freq */
648 .lp_read_cmd_mode_freq_khz = 200000,
649};
650
651static struct tegra_stereo_out enterprise_stereo = {
652 .set_mode = &enterprise_stereo_set_mode,
653 .set_orientation = &enterprise_stereo_set_orientation,
654};
655
656#ifdef CONFIG_TEGRA_DC
657static struct tegra_dc_mode enterprise_dsi_modes[] = {
658 {
659 .pclk = 10000000,
660 .h_ref_to_sync = 4,
661 .v_ref_to_sync = 1,
662 .h_sync_width = 16,
663 .v_sync_width = 1,
664 .h_back_porch = 32,
665 .v_back_porch = 1,
666 .h_active = 540,
667 .v_active = 960,
668 .h_front_porch = 32,
669 .v_front_porch = 2,
670 },
671};
672
673static struct tegra_fb_data enterprise_dsi_fb_data = {
674 .win = 0,
675 .xres = 540,
676 .yres = 960,
677 .bits_per_pixel = 32,
678 .flags = TEGRA_FB_FLIP_ON_PROBE,
679};
680
681static struct tegra_dc_out enterprise_disp1_out = {
682 .align = TEGRA_DC_ALIGN_MSB,
683 .order = TEGRA_DC_ORDER_RED_BLUE,
684 .sd_settings = &enterprise_sd_settings,
685
686 .flags = DC_CTRL_MODE,
687
688 .type = TEGRA_DC_OUT_DSI,
689
690 .modes = enterprise_dsi_modes,
691 .n_modes = ARRAY_SIZE(enterprise_dsi_modes),
692
693 .dsi = &enterprise_dsi,
694 .stereo = &enterprise_stereo,
695
696 .enable = enterprise_dsi_panel_enable,
697 .disable = enterprise_dsi_panel_disable,
698 .postsuspend = enterprise_dsi_panel_postsuspend,
699
700 .width = 53,
701 .height = 95,
702};
703static struct tegra_dc_platform_data enterprise_disp1_pdata = {
704 .flags = TEGRA_DC_FLAG_ENABLED,
705 .default_out = &enterprise_disp1_out,
706 .emc_clk_rate = 204000000,
707 .fb = &enterprise_dsi_fb_data,
708};
709
710static struct nvhost_device enterprise_disp1_device = {
711 .name = "tegradc",
712 .id = 0,
713 .resource = enterprise_disp1_resources,
714 .num_resources = ARRAY_SIZE(enterprise_disp1_resources),
715 .dev = {
716 .platform_data = &enterprise_disp1_pdata,
717 },
718};
719
720static int enterprise_disp1_check_fb(struct device *dev, struct fb_info *info)
721{
722 return info->device == &enterprise_disp1_device.dev;
723}
724
725static struct nvhost_device enterprise_disp2_device = {
726 .name = "tegradc",
727 .id = 1,
728 .resource = enterprise_disp2_resources,
729 .num_resources = ARRAY_SIZE(enterprise_disp2_resources),
730 .dev = {
731 .platform_data = &enterprise_disp2_pdata,
732 },
733};
734#endif
735
736#if defined(CONFIG_TEGRA_NVMAP)
737static struct nvmap_platform_carveout enterprise_carveouts[] = {
738 [0] = NVMAP_HEAP_CARVEOUT_IRAM_INIT,
739 [1] = {
740 .name = "generic-0",
741 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
742 .base = 0, /* Filled in by enterprise_panel_init() */
743 .size = 0, /* Filled in by enterprise_panel_init() */
744 .buddy_size = SZ_32K,
745 },
746};
747
748static struct nvmap_platform_data enterprise_nvmap_data = {
749 .carveouts = enterprise_carveouts,
750 .nr_carveouts = ARRAY_SIZE(enterprise_carveouts),
751};
752
753static struct platform_device enterprise_nvmap_device = {
754 .name = "tegra-nvmap",
755 .id = -1,
756 .dev = {
757 .platform_data = &enterprise_nvmap_data,
758 },
759};
760#endif
761
762static struct platform_device *enterprise_gfx_devices[] __initdata = {
763#if defined(CONFIG_TEGRA_NVMAP)
764 &enterprise_nvmap_device,
765#endif
766 &tegra_pwfm0_device,
767};
768
769static struct platform_device *enterprise_bl_devices[] = {
770 &enterprise_disp1_backlight_device,
771};
772
773#ifdef CONFIG_HAS_EARLYSUSPEND
774/* put early_suspend/late_resume handlers here for the display in order
775 * to keep the code out of the display driver, keeping it closer to upstream
776 */
777struct early_suspend enterprise_panel_early_suspender;
778
779static void enterprise_panel_early_suspend(struct early_suspend *h)
780{
781 /* power down LCD, add use a black screen for HDMI */
782 if (num_registered_fb > 0)
783 fb_blank(registered_fb[0], FB_BLANK_POWERDOWN);
784 if (num_registered_fb > 1)
785 fb_blank(registered_fb[1], FB_BLANK_NORMAL);
786#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
787 cpufreq_save_default_governor();
788 cpufreq_set_conservative_governor();
789 cpufreq_set_conservative_governor_param("up_threshold",
790 SET_CONSERVATIVE_GOVERNOR_UP_THRESHOLD);
791
792 cpufreq_set_conservative_governor_param("down_threshold",
793 SET_CONSERVATIVE_GOVERNOR_DOWN_THRESHOLD);
794
795 cpufreq_set_conservative_governor_param("freq_step",
796 SET_CONSERVATIVE_GOVERNOR_FREQ_STEP);
797#endif
798}
799
800static void enterprise_panel_late_resume(struct early_suspend *h)
801{
802 unsigned i;
803
804#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
805 cpufreq_restore_default_governor();
806#endif
807 for (i = 0; i < num_registered_fb; i++)
808 fb_blank(registered_fb[i], FB_BLANK_UNBLANK);
809}
810#endif
811
812int __init enterprise_panel_init(void)
813{
814 int err;
815 struct resource __maybe_unused *res;
816 struct board_info board_info;
817
818 tegra_get_board_info(&board_info);
819
820 BUILD_BUG_ON(ARRAY_SIZE(enterprise_bl_output_measured_a03) != 256);
821 BUILD_BUG_ON(ARRAY_SIZE(enterprise_bl_output_measured_a02) != 256);
822
823 if (board_info.fab >= BOARD_FAB_A03) {
824 enterprise_disp1_backlight_data.clk_div = 0x1D;
825 bl_output = enterprise_bl_output_measured_a03;
826 } else
827 bl_output = enterprise_bl_output_measured_a02;
828
829 enterprise_dsi.chip_id = tegra_get_chipid();
830 enterprise_dsi.chip_rev = tegra_get_revision();
831
832#if defined(CONFIG_TEGRA_NVMAP)
833 enterprise_carveouts[1].base = tegra_carveout_start;
834 enterprise_carveouts[1].size = tegra_carveout_size;
835#endif
836
837 tegra_gpio_enable(enterprise_hdmi_hpd);
838 gpio_request(enterprise_hdmi_hpd, "hdmi_hpd");
839 gpio_direction_input(enterprise_hdmi_hpd);
840
841 tegra_gpio_enable(enterprise_lcd_2d_3d);
842 gpio_request(enterprise_lcd_2d_3d, "lcd_2d_3d");
843 gpio_direction_output(enterprise_lcd_2d_3d, 0);
844 enterprise_stereo_set_mode(enterprise_stereo.mode_2d_3d);
845
846 tegra_gpio_enable(enterprise_lcd_swp_pl);
847 gpio_request(enterprise_lcd_swp_pl, "lcd_swp_pl");
848 gpio_direction_output(enterprise_lcd_swp_pl, 0);
849 enterprise_stereo_set_orientation(enterprise_stereo.orientation);
850
851#if !(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
852 tegra_gpio_enable(enterprise_lcd_te);
853 gpio_request(enterprise_lcd_swp_pl, "lcd_te");
854 gpio_direction_input(enterprise_lcd_te);
855#endif
856
857#ifdef CONFIG_HAS_EARLYSUSPEND
858 enterprise_panel_early_suspender.suspend = enterprise_panel_early_suspend;
859 enterprise_panel_early_suspender.resume = enterprise_panel_late_resume;
860 enterprise_panel_early_suspender.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
861 register_early_suspend(&enterprise_panel_early_suspender);
862#endif
863
864#ifdef CONFIG_TEGRA_GRHOST
865 err = nvhost_device_register(&tegra_grhost_device);
866 if (err)
867 return err;
868#endif
869
870 err = platform_add_devices(enterprise_gfx_devices,
871 ARRAY_SIZE(enterprise_gfx_devices));
872
873#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
874 res = nvhost_get_resource_byname(&enterprise_disp1_device,
875 IORESOURCE_MEM, "fbmem");
876 res->start = tegra_fb_start;
877 res->end = tegra_fb_start + tegra_fb_size - 1;
878#endif
879
880 /* Copy the bootloader fb to the fb. */
881 tegra_move_framebuffer(tegra_fb_start, tegra_bootloader_fb_start,
882 min(tegra_fb_size, tegra_bootloader_fb_size));
883
884#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_DC)
885 if (!err)
886 err = nvhost_device_register(&enterprise_disp1_device);
887
888 res = nvhost_get_resource_byname(&enterprise_disp2_device,
889 IORESOURCE_MEM, "fbmem");
890 res->start = tegra_fb2_start;
891 res->end = tegra_fb2_start + tegra_fb2_size - 1;
892 if (!err)
893 err = nvhost_device_register(&enterprise_disp2_device);
894#endif
895
896#if defined(CONFIG_TEGRA_GRHOST) && defined(CONFIG_TEGRA_NVAVP)
897 if (!err)
898 err = nvhost_device_register(&nvavp_device);
899#endif
900
901 if (!err)
902 err = platform_add_devices(enterprise_bl_devices,
903 ARRAY_SIZE(enterprise_bl_devices));
904 return err;
905}