arm: tegra: ardbeg: add AUO 14" eDP panel support
[linux-3.10.git] / arch / arm / mach-tegra / board-ardbeg-panel.c
1 /*
2  * arch/arm/mach-tegra/board-ardbeg-panel.c
3  *
4  * Copyright (c) 2013, NVIDIA Corporation. All rights reserved
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 #include <linux/ioport.h>
21 #include <linux/fb.h>
22 #include <linux/nvmap.h>
23 #include <linux/nvhost.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/gpio.h>
27 #include <linux/tegra_pwm_bl.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/pwm_backlight.h>
30 #include <linux/of.h>
31
32 #include <mach/irqs.h>
33 #include <mach/dc.h>
34
35 #include "board.h"
36 #include "devices.h"
37 #include "gpio-names.h"
38 #include "board-ardbeg.h"
39 #include "board-panel.h"
40 #include "common.h"
41 #include "iomap.h"
42
43 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
44 #include "tegra11_host1x_devices.h"
45 #else
46 #include "tegra12_host1x_devices.h"
47 #endif
48
49
50 struct platform_device * __init ardbeg_host1x_init(void)
51 {
52         struct platform_device *pdev = NULL;
53
54 #ifdef CONFIG_TEGRA_GRHOST
55         if (!of_have_populated_dt()) {
56 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
57                 pdev = tegra11_register_host1x_devices();
58 #else
59                 pdev = tegra12_register_host1x_devices();
60 #endif
61         } else {
62                 pdev = to_platform_device(bus_find_device_by_name(
63                         &platform_bus_type, NULL, "host1x"));
64         }
65
66         if (!pdev) {
67                 pr_err("host1x devices registration failed\n");
68                 return NULL;
69         }
70 #endif
71         return pdev;
72 }
73
74 #ifdef CONFIG_TEGRA_DC
75
76
77 /* hdmi related regulators */
78 static struct regulator *ardbeg_hdmi_reg;
79 static struct regulator *ardbeg_hdmi_pll;
80 static struct regulator *ardbeg_hdmi_vddio;
81
82 static struct resource ardbeg_disp1_resources[] = {
83         {
84                 .name   = "irq",
85                 .start  = INT_DISPLAY_GENERAL,
86                 .end    = INT_DISPLAY_GENERAL,
87                 .flags  = IORESOURCE_IRQ,
88         },
89         {
90                 .name   = "regs",
91                 .start  = TEGRA_DISPLAY_BASE,
92                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
93                 .flags  = IORESOURCE_MEM,
94         },
95         {
96                 .name   = "fbmem",
97                 .start  = 0, /* Filled in by ardbeg_panel_init() */
98                 .end    = 0, /* Filled in by ardbeg_panel_init() */
99                 .flags  = IORESOURCE_MEM,
100         },
101         {
102                 .name   = "ganged_dsia_regs",
103                 .start  = 0, /* Filled in the panel file by init_resources() */
104                 .end    = 0, /* Filled in the panel file by init_resources() */
105                 .flags  = IORESOURCE_MEM,
106         },
107         {
108                 .name   = "ganged_dsib_regs",
109                 .start  = 0, /* Filled in the panel file by init_resources() */
110                 .end    = 0, /* Filled in the panel file by init_resources() */
111                 .flags  = IORESOURCE_MEM,
112         },
113         {
114                 .name   = "dsi_regs",
115                 .start  = 0, /* Filled in the panel file by init_resources() */
116                 .end    = 0, /* Filled in the panel file by init_resources() */
117                 .flags  = IORESOURCE_MEM,
118         },
119         {
120                 .name   = "mipi_cal",
121                 .start  = TEGRA_MIPI_CAL_BASE,
122                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
123                 .flags  = IORESOURCE_MEM,
124         },
125 };
126
127 static struct resource ardbeg_disp1_edp_resources[] = {
128         {
129                 .name   = "irq",
130                 .start  = INT_DISPLAY_GENERAL,
131                 .end    = INT_DISPLAY_GENERAL,
132                 .flags  = IORESOURCE_IRQ,
133         },
134         {
135                 .name   = "regs",
136                 .start  = TEGRA_DISPLAY_BASE,
137                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
138                 .flags  = IORESOURCE_MEM,
139         },
140         {
141                 .name   = "fbmem",
142                 .start  = 0, /* Filled in by ardbeg_panel_init() */
143                 .end    = 0, /* Filled in by ardbeg_panel_init() */
144                 .flags  = IORESOURCE_MEM,
145         },
146         {
147                 .name   = "mipi_cal",
148                 .start  = TEGRA_MIPI_CAL_BASE,
149                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
150                 .flags  = IORESOURCE_MEM,
151         },
152         {
153                 .name   = "sor",
154                 .start  = TEGRA_SOR_BASE,
155                 .end    = TEGRA_SOR_BASE + TEGRA_SOR_SIZE - 1,
156                 .flags  = IORESOURCE_MEM,
157         },
158         {
159                 .name   = "dpaux",
160                 .start  = TEGRA_DPAUX_BASE,
161                 .end    = TEGRA_DPAUX_BASE + TEGRA_DPAUX_SIZE - 1,
162                 .flags  = IORESOURCE_MEM,
163         },
164 };
165
166 static struct resource ardbeg_disp2_resources[] = {
167         {
168                 .name   = "irq",
169                 .start  = INT_DISPLAY_B_GENERAL,
170                 .end    = INT_DISPLAY_B_GENERAL,
171                 .flags  = IORESOURCE_IRQ,
172         },
173         {
174                 .name   = "regs",
175                 .start  = TEGRA_DISPLAY2_BASE,
176                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
177                 .flags  = IORESOURCE_MEM,
178         },
179         {
180                 .name   = "fbmem",
181                 .start  = 0, /* Filled in by ardbeg_panel_init() */
182                 .end    = 0, /* Filled in by ardbeg_panel_init() */
183                 .flags  = IORESOURCE_MEM,
184         },
185         {
186                 .name   = "hdmi_regs",
187                 .start  = TEGRA_HDMI_BASE,
188                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
189                 .flags  = IORESOURCE_MEM,
190         },
191 };
192
193
194 static struct tegra_dc_sd_settings sd_settings;
195
196 static struct tegra_dc_out ardbeg_disp1_out = {
197         .type           = TEGRA_DC_OUT_DSI,
198         .sd_settings    = &sd_settings,
199 };
200
201 static int ardbeg_hdmi_enable(struct device *dev)
202 {
203         int ret;
204         if (!ardbeg_hdmi_reg) {
205                 ardbeg_hdmi_reg = regulator_get(dev, "avdd_hdmi");
206                 if (IS_ERR_OR_NULL(ardbeg_hdmi_reg)) {
207                         pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
208                         ardbeg_hdmi_reg = NULL;
209                         return PTR_ERR(ardbeg_hdmi_reg);
210                 }
211         }
212         ret = regulator_enable(ardbeg_hdmi_reg);
213         if (ret < 0) {
214                 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
215                 return ret;
216         }
217         if (!ardbeg_hdmi_pll) {
218                 ardbeg_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
219                 if (IS_ERR_OR_NULL(ardbeg_hdmi_pll)) {
220                         pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
221                         ardbeg_hdmi_pll = NULL;
222                         regulator_put(ardbeg_hdmi_reg);
223                         ardbeg_hdmi_reg = NULL;
224                         return PTR_ERR(ardbeg_hdmi_pll);
225                 }
226         }
227         ret = regulator_enable(ardbeg_hdmi_pll);
228         if (ret < 0) {
229                 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
230                 return ret;
231         }
232         return 0;
233 }
234
235 static int ardbeg_hdmi_disable(void)
236 {
237         if (ardbeg_hdmi_reg) {
238                 regulator_disable(ardbeg_hdmi_reg);
239                 regulator_put(ardbeg_hdmi_reg);
240                 ardbeg_hdmi_reg = NULL;
241         }
242
243         if (ardbeg_hdmi_pll) {
244                 regulator_disable(ardbeg_hdmi_pll);
245                 regulator_put(ardbeg_hdmi_pll);
246                 ardbeg_hdmi_pll = NULL;
247         }
248         return 0;
249 }
250
251 static int ardbeg_hdmi_postsuspend(void)
252 {
253         if (ardbeg_hdmi_vddio) {
254                 regulator_disable(ardbeg_hdmi_vddio);
255                 regulator_put(ardbeg_hdmi_vddio);
256                 ardbeg_hdmi_vddio = NULL;
257         }
258         return 0;
259 }
260
261 static int ardbeg_hdmi_hotplug_init(struct device *dev)
262 {
263         if (!ardbeg_hdmi_vddio) {
264                 ardbeg_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
265                 if (WARN_ON(IS_ERR(ardbeg_hdmi_vddio))) {
266                         pr_err("%s: couldn't get regulator vdd_hdmi_5v0: %ld\n",
267                                 __func__, PTR_ERR(ardbeg_hdmi_vddio));
268                                 ardbeg_hdmi_vddio = NULL;
269                 } else {
270                         regulator_enable(ardbeg_hdmi_vddio);
271                 }
272         }
273
274         return 0;
275 }
276
277 /* Electrical characteristics for HDMI, all modes must be declared here */
278 struct tmds_config ardbeg_tmds_config[] = {
279         { /* 480p : 27 MHz and below */
280                 .pclk = 27000000,
281                 .pll0 = 0x01003010,
282                 .pll1 = 0x00301b00,
283                 .drive_current = 0x23232323,
284                 .pe_current = 0x00000000,
285                 .peak_current = 0x00000000,
286         },
287         { /* 720p : 74.25MHz modes */
288                 .pclk = 74250000,
289                 .pll0 = 0x01003110,
290                 .pll1 = 0x00301b00,
291                 .drive_current = 0x25252525,
292                 .pe_current = 0x00000000,
293                 .peak_current = 0x03030303,
294         },
295         { /* 1080p : 148.5MHz modes */
296                 .pclk = 148500000,
297                 .pll0 = 0x01003310,
298                 .pll1 = 0x00301b00,
299                 .drive_current = 0x27272727,
300                 .pe_current = 0x00000000,
301                 .peak_current = 0x03030303,
302         },
303         { /* 4K : 297MHz modes */
304                 .pclk = INT_MAX,
305                 .pll0 = 0x01003f10,
306                 .pll1 = 0x00300f00,
307                 .drive_current = 0x303f3f3f,
308                 .pe_current = 0x00000000,
309                 .peak_current = 0x040f0f0f,
310         },
311 };
312
313 struct tegra_hdmi_out ardbeg_hdmi_out = {
314         .tmds_config = ardbeg_tmds_config,
315         .n_tmds_config = ARRAY_SIZE(ardbeg_tmds_config),
316 };
317
318
319 static struct tegra_dc_out ardbeg_disp2_out = {
320         .type           = TEGRA_DC_OUT_HDMI,
321         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
322         .parent_clk     = "pll_d2",
323
324         .dcc_bus        = 3,
325         .hotplug_gpio   = ardbeg_hdmi_hpd,
326         .hdmi_out       = &ardbeg_hdmi_out,
327
328         /* TODO: update max pclk to POR */
329         .max_pixclock   = KHZ2PICOS(297000),
330
331         .align          = TEGRA_DC_ALIGN_MSB,
332         .order          = TEGRA_DC_ORDER_RED_BLUE,
333
334         .enable         = ardbeg_hdmi_enable,
335         .disable        = ardbeg_hdmi_disable,
336         .postsuspend    = ardbeg_hdmi_postsuspend,
337         .hotplug_init   = ardbeg_hdmi_hotplug_init,
338 };
339
340 static struct tegra_fb_data ardbeg_disp1_fb_data = {
341         .win            = 0,
342         .bits_per_pixel = 32,
343         .flags          = TEGRA_FB_FLIP_ON_PROBE,
344 };
345
346 static struct tegra_dc_platform_data ardbeg_disp1_pdata = {
347         .flags          = TEGRA_DC_FLAG_ENABLED,
348         .default_out    = &ardbeg_disp1_out,
349         .fb             = &ardbeg_disp1_fb_data,
350         .emc_clk_rate   = 204000000,
351 #ifdef CONFIG_TEGRA_DC_CMU
352         .cmu_enable     = 1,
353 #endif
354 };
355
356 static struct tegra_fb_data ardbeg_disp2_fb_data = {
357         .win            = 0,
358         .xres           = 1280,
359         .yres           = 720,
360         .bits_per_pixel = 32,
361         .flags          = TEGRA_FB_FLIP_ON_PROBE,
362 };
363
364 static struct tegra_dc_platform_data ardbeg_disp2_pdata = {
365         .flags          = TEGRA_DC_FLAG_ENABLED,
366         .default_out    = &ardbeg_disp2_out,
367         .fb             = &ardbeg_disp2_fb_data,
368         .emc_clk_rate   = 300000000,
369 };
370
371 static struct platform_device ardbeg_disp2_device = {
372         .name           = "tegradc",
373         .id             = 1,
374         .resource       = ardbeg_disp2_resources,
375         .num_resources  = ARRAY_SIZE(ardbeg_disp2_resources),
376         .dev = {
377                 .platform_data = &ardbeg_disp2_pdata,
378         },
379 };
380
381 static struct platform_device ardbeg_disp1_device = {
382         .name           = "tegradc",
383         .id             = 0,
384         .resource       = ardbeg_disp1_resources,
385         .num_resources  = ARRAY_SIZE(ardbeg_disp1_resources),
386         .dev = {
387                 .platform_data = &ardbeg_disp1_pdata,
388         },
389 };
390
391 static struct nvmap_platform_carveout ardbeg_carveouts[] = {
392         [0] = {
393                 .name           = "iram",
394                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
395                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
396                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
397                 .buddy_size     = 0, /* no buddy allocation for IRAM */
398         },
399         [1] = {
400                 .name           = "generic-0",
401                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
402                 .base           = 0, /* Filled in by ardbeg_panel_init() */
403                 .size           = 0, /* Filled in by ardbeg_panel_init() */
404                 .buddy_size     = SZ_32K,
405         },
406         [2] = {
407                 .name           = "vpr",
408                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
409                 .base           = 0, /* Filled in by ardbeg_panel_init() */
410                 .size           = 0, /* Filled in by ardbeg_panel_init() */
411                 .buddy_size     = SZ_32K,
412         },
413 };
414
415 static struct nvmap_platform_data ardbeg_nvmap_data = {
416         .carveouts      = ardbeg_carveouts,
417         .nr_carveouts   = ARRAY_SIZE(ardbeg_carveouts),
418 };
419 static struct platform_device ardbeg_nvmap_device  = {
420         .name   = "tegra-nvmap",
421         .id     = -1,
422         .dev    = {
423                 .platform_data = &ardbeg_nvmap_data,
424         },
425 };
426
427 static struct tegra_dc_sd_settings ardbeg_sd_settings = {
428         .enable = 1, /* enabled by default. */
429         .use_auto_pwm = false,
430         .hw_update_delay = 0,
431         .bin_width = -1,
432         .aggressiveness = 5,
433         .use_vid_luma = false,
434         .phase_in_adjustments = 0,
435         .k_limit_enable = true,
436         .k_limit = 200,
437         .sd_window_enable = false,
438         .soft_clipping_enable = true,
439         /* Low soft clipping threshold to compensate for aggressive k_limit */
440         .soft_clipping_threshold = 128,
441         .smooth_k_enable = false,
442         .smooth_k_incr = 64,
443         /* Default video coefficients */
444         .coeff = {5, 9, 2},
445         .fc = {0, 0},
446         /* Immediate backlight changes */
447         .blp = {1024, 255},
448         /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
449         /* Default BL TF */
450         .bltf = {
451                         {
452                                 {57, 65, 73, 82},
453                                 {92, 103, 114, 125},
454                                 {138, 150, 164, 178},
455                                 {193, 208, 224, 241},
456                         },
457                 },
458         /* Default LUT */
459         .lut = {
460                         {
461                                 {255, 255, 255},
462                                 {199, 199, 199},
463                                 {153, 153, 153},
464                                 {116, 116, 116},
465                                 {85, 85, 85},
466                                 {59, 59, 59},
467                                 {36, 36, 36},
468                                 {17, 17, 17},
469                                 {0, 0, 0},
470                         },
471                 },
472         .sd_brightness = &sd_brightness,
473         .use_vpulse2 = true,
474 };
475
476 static void ardbeg_panel_select(void)
477 {
478         struct tegra_panel *panel = NULL;
479         struct board_info board;
480         u8 dsi_instance;
481
482         tegra_get_display_board_info(&board);
483
484         switch (board.board_id) {
485         case BOARD_E1639:
486         case BOARD_E1813:
487                 panel = &dsi_s_wqxga_10_1;
488                 dsi_instance = DSI_INSTANCE_0;
489                 break;
490         case BOARD_PM354:
491                 panel = &dsi_a_1080p_14_0;
492                 dsi_instance = DSI_INSTANCE_0;
493                 break;
494         case BOARD_E1627:
495                 panel = &dsi_p_wuxga_10_1;
496                 dsi_instance = DSI_INSTANCE_0;
497                 break;
498         case BOARD_E1824:
499                 panel = &edp_a_1080p_14_0;
500                 ardbeg_disp1_out.type = TEGRA_DC_OUT_DP;
501                 ardbeg_disp1_device.resource = ardbeg_disp1_edp_resources;
502                 ardbeg_disp1_device.num_resources =
503                         ARRAY_SIZE(ardbeg_disp1_edp_resources);
504                 break;
505         /* fall through */
506         default:
507                 panel = &dsi_p_wuxga_10_1;
508                 dsi_instance = DSI_INSTANCE_0;
509                 break;
510         }
511
512         if (panel) {
513                 if (panel->init_sd_settings)
514                         panel->init_sd_settings(&sd_settings);
515
516                 if (panel->init_dc_out) {
517                         panel->init_dc_out(&ardbeg_disp1_out);
518                         if (ardbeg_disp1_out.type == TEGRA_DC_OUT_DSI) {
519                                 ardbeg_disp1_out.dsi->dsi_instance =
520                                         dsi_instance;
521                                 ardbeg_disp1_out.dsi->dsi_panel_rst_gpio =
522                                         DSI_PANEL_RST_GPIO;
523                                 ardbeg_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
524                                         DSI_PANEL_BL_PWM_GPIO;
525                                 ardbeg_disp1_out.dsi->te_gpio = TEGRA_GPIO_PR6;
526                         }
527                 }
528
529                 if (panel->init_fb_data)
530                         panel->init_fb_data(&ardbeg_disp1_fb_data);
531
532                 if (panel->init_cmu_data)
533                         panel->init_cmu_data(&ardbeg_disp1_pdata);
534
535                 if (panel->set_disp_device)
536                         panel->set_disp_device(&ardbeg_disp1_device);
537
538                 if (ardbeg_disp1_out.type == TEGRA_DC_OUT_DSI) {
539                         tegra_dsi_resources_init(dsi_instance,
540                                 ardbeg_disp1_resources,
541                                 ARRAY_SIZE(ardbeg_disp1_resources));
542                 }
543
544                 if (panel->register_bl_dev)
545                         panel->register_bl_dev();
546
547                 if (panel->register_i2c_bridge)
548                         panel->register_i2c_bridge();
549         }
550
551 }
552 int __init ardbeg_panel_init(void)
553 {
554         int err = 0;
555         struct resource __maybe_unused *res;
556         struct platform_device *phost1x = NULL;
557
558         sd_settings = ardbeg_sd_settings;
559
560         ardbeg_panel_select();
561
562 #ifdef CONFIG_TEGRA_NVMAP
563         ardbeg_carveouts[1].base = tegra_carveout_start;
564         ardbeg_carveouts[1].size = tegra_carveout_size;
565         ardbeg_carveouts[2].base = tegra_vpr_start;
566         ardbeg_carveouts[2].size = tegra_vpr_size;
567
568         err = platform_device_register(&ardbeg_nvmap_device);
569         if (err) {
570                 pr_err("nvmap device registration failed\n");
571                 return err;
572         }
573 #endif
574
575         phost1x = ardbeg_host1x_init();
576         if (!phost1x) {
577                 pr_err("host1x devices registration failed\n");
578                 return -EINVAL;
579         }
580
581         res = platform_get_resource_byname(&ardbeg_disp1_device,
582                                          IORESOURCE_MEM, "fbmem");
583         res->start = tegra_fb_start;
584         res->end = tegra_fb_start + tegra_fb_size - 1;
585
586         /* Copy the bootloader fb to the fb. */
587         __tegra_move_framebuffer(&ardbeg_nvmap_device,
588                 tegra_fb_start, tegra_bootloader_fb_start,
589                         min(tegra_fb_size, tegra_bootloader_fb_size));
590
591         res = platform_get_resource_byname(&ardbeg_disp2_device,
592                                          IORESOURCE_MEM, "fbmem");
593
594         res->start = tegra_fb2_start;
595         res->end = tegra_fb2_start + tegra_fb2_size - 1;
596
597         ardbeg_disp1_device.dev.parent = &phost1x->dev;
598         err = platform_device_register(&ardbeg_disp1_device);
599         if (err) {
600                 pr_err("disp1 device registration failed\n");
601                 return err;
602         }
603
604         ardbeg_disp2_device.dev.parent = &phost1x->dev;
605         err = platform_device_register(&ardbeg_disp2_device);
606         if (err) {
607                 pr_err("disp2 device registration failed\n");
608                 return err;
609         }
610
611 #ifdef CONFIG_TEGRA_NVAVP
612         nvavp_device.dev.parent = &phost1x->dev;
613         err = platform_device_register(&nvavp_device);
614         if (err) {
615                 pr_err("nvavp device registration failed\n");
616                 return err;
617         }
618 #endif
619         return err;
620 }
621 #else
622 int __init ardbeg_panel_init(void)
623 {
624         if (ardbeg_host1x_init())
625                 return 0;
626         else
627                 return -EINVAL;
628 }
629 #endif