arm:tegra:loki:update hdmi drive_current settings
[linux-3.10.git] / arch / arm / mach-tegra / board-loki-panel.c
1 /*
2  * arch/arm/mach-tegra/board-loki-panel.c
3  *
4  * Copyright (c) 2011-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
31 #include <mach/irqs.h>
32 #include <mach/dc.h>
33 #include <mach/pinmux-t12.h>
34
35 #include "board.h"
36 #include "devices.h"
37 #include "gpio-names.h"
38 #include "iomap.h"
39 #include "tegra12_host1x_devices.h"
40 #include "board-panel.h"
41 #include "common.h"
42
43 struct platform_device * __init loki_host1x_init(void)
44 {
45         struct platform_device *pdev = NULL;
46
47 #ifdef CONFIG_TEGRA_GRHOST
48         pdev = tegra12_register_host1x_devices();
49
50         if (!pdev) {
51                 pr_err("host1x devices registration failed\n");
52                 return NULL;
53         }
54 #endif
55         return pdev;
56 }
57
58 #ifdef CONFIG_TEGRA_DC
59
60 #define DSI_PANEL_RST_GPIO      TEGRA_GPIO_PH3
61 #define DSI_PANEL_BL_PWM_GPIO   TEGRA_GPIO_PH1
62
63 /* HDMI Hotplug detection pin */
64 #define loki_hdmi_hpd   TEGRA_GPIO_PN7
65
66 static struct regulator *loki_hdmi_reg;
67 static struct regulator *loki_hdmi_pll;
68 static struct regulator *loki_hdmi_vddio;
69
70 static struct resource loki_disp1_resources[] = {
71         {
72                 .name   = "irq",
73                 .start  = INT_DISPLAY_GENERAL,
74                 .end    = INT_DISPLAY_GENERAL,
75                 .flags  = IORESOURCE_IRQ,
76         },
77         {
78                 .name   = "regs",
79                 .start  = TEGRA_DISPLAY_BASE,
80                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
81                 .flags  = IORESOURCE_MEM,
82         },
83         {
84                 .name   = "fbmem",
85                 .start  = 0, /* Filled in by loki_panel_init() */
86                 .end    = 0, /* Filled in by loki_panel_init() */
87                 .flags  = IORESOURCE_MEM,
88         },
89         {
90                 .name   = "dsi_regs",
91                 .start  = TEGRA_DSI_BASE,
92                 .end    = TEGRA_DSI_BASE + TEGRA_DSI_SIZE - 1,
93                 .flags  = IORESOURCE_MEM,
94         },
95         {
96                 .name   = "mipi_cal",
97                 .start  = TEGRA_MIPI_CAL_BASE,
98                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
99                 .flags  = IORESOURCE_MEM,
100         },
101 };
102
103 static struct resource loki_disp2_resources[] = {
104         {
105                 .name   = "irq",
106                 .start  = INT_DISPLAY_B_GENERAL,
107                 .end    = INT_DISPLAY_B_GENERAL,
108                 .flags  = IORESOURCE_IRQ,
109         },
110         {
111                 .name   = "regs",
112                 .start  = TEGRA_DISPLAY2_BASE,
113                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
114                 .flags  = IORESOURCE_MEM,
115         },
116         {
117                 .name   = "fbmem",
118                 .start  = 0, /* Filled in by loki_panel_init() */
119                 .end    = 0, /* Filled in by loki_panel_init() */
120                 .flags  = IORESOURCE_MEM,
121         },
122         {
123                 .name   = "hdmi_regs",
124                 .start  = TEGRA_HDMI_BASE,
125                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
126                 .flags  = IORESOURCE_MEM,
127         },
128 };
129
130 static struct tegra_dc_sd_settings sd_settings;
131
132 static struct tegra_dc_out loki_disp1_out = {
133         .type           = TEGRA_DC_OUT_DSI,
134         .sd_settings    = &sd_settings,
135 };
136
137 static int loki_hdmi_enable(struct device *dev)
138 {
139         int ret;
140         if (!loki_hdmi_reg) {
141                 loki_hdmi_reg = regulator_get(dev, "avdd_hdmi");
142                 if (IS_ERR_OR_NULL(loki_hdmi_reg)) {
143                         pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
144                         loki_hdmi_reg = NULL;
145                         return PTR_ERR(loki_hdmi_reg);
146                 }
147         }
148         ret = regulator_enable(loki_hdmi_reg);
149         if (ret < 0) {
150                 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
151                 return ret;
152         }
153         if (!loki_hdmi_pll) {
154                 loki_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
155                 if (IS_ERR_OR_NULL(loki_hdmi_pll)) {
156                         pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
157                         loki_hdmi_pll = NULL;
158                         regulator_put(loki_hdmi_reg);
159                         loki_hdmi_reg = NULL;
160                         return PTR_ERR(loki_hdmi_pll);
161                 }
162         }
163         ret = regulator_enable(loki_hdmi_pll);
164         if (ret < 0) {
165                 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
166                 return ret;
167         }
168         return 0;
169 }
170
171 static int loki_hdmi_disable(void)
172 {
173         if (loki_hdmi_reg) {
174                 regulator_disable(loki_hdmi_reg);
175                 regulator_put(loki_hdmi_reg);
176                 loki_hdmi_reg = NULL;
177         }
178
179         if (loki_hdmi_pll) {
180                 regulator_disable(loki_hdmi_pll);
181                 regulator_put(loki_hdmi_pll);
182                 loki_hdmi_pll = NULL;
183         }
184
185         return 0;
186 }
187
188 static int loki_hdmi_postsuspend(void)
189 {
190         if (loki_hdmi_vddio) {
191                 regulator_disable(loki_hdmi_vddio);
192                 regulator_put(loki_hdmi_vddio);
193                 loki_hdmi_vddio = NULL;
194         }
195         return 0;
196 }
197
198 static int loki_hdmi_hotplug_init(struct device *dev)
199 {
200         if (!loki_hdmi_vddio) {
201                 loki_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
202                 if (WARN_ON(IS_ERR(loki_hdmi_vddio))) {
203                         pr_err("%s: couldn't get regulator vdd_hdmi_5v0: %ld\n",
204                                         __func__, PTR_ERR(loki_hdmi_vddio));
205                         loki_hdmi_vddio = NULL;
206                 } else
207                         regulator_enable(loki_hdmi_vddio);
208         }
209         return 0;
210 }
211
212 /* Table of electrical characteristics for Roth HDMI.
213  * All modes must be declared here
214  */
215 struct tmds_config loki_tmds_config[] = {
216         { /* 720p / 74.25MHz modes */
217                 .pclk = 74250000,
218                 .pll0 = 0x01003f10,
219                 .pll1 = 0x10300b00,
220                 .pe_current = 0x00000000,
221                 .drive_current = 0x32323232,
222                 .peak_current = 0x05050505,
223         },
224         { /* 1080p / 148.5MHz modes */
225                 .pclk = 148500000,
226                 .pll0 = 0x01003f10,
227                 .pll1 = 0x10300b00,
228                 .pe_current = 0x00000000,
229                 .drive_current = 0x32323232,
230                 .peak_current = 0x05050505,
231         },
232         { /* 297MHz modes */
233                 .pclk = INT_MAX,
234                 .pll0 = 0x01003f10,
235                 .pll1 = 0x13300b00,
236                 .pe_current = 0x00000000,
237                 .drive_current = 0x36363636,
238                 .peak_current = 0x07070707,
239         },
240 };
241
242 struct tegra_hdmi_out loki_hdmi_out = {
243         .tmds_config = loki_tmds_config,
244         .n_tmds_config = 3,
245 };
246
247 static void loki_hdmi_hotplug_report(bool state)
248 {
249         if (state) {
250                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SDA,
251                                                 TEGRA_PUPD_PULL_DOWN);
252                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SCL,
253                                                 TEGRA_PUPD_PULL_DOWN);
254         } else {
255                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SDA,
256                                                 TEGRA_PUPD_NORMAL);
257                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SCL,
258                                                 TEGRA_PUPD_NORMAL);
259         }
260 }
261
262 static struct tegra_dc_out loki_disp2_out = {
263         .type           = TEGRA_DC_OUT_HDMI,
264         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
265         .parent_clk     = "pll_d2",
266
267         .dcc_bus        = 3,
268         .hotplug_gpio   = loki_hdmi_hpd,
269
270         .max_pixclock   = KHZ2PICOS(297000),
271
272         .align          = TEGRA_DC_ALIGN_MSB,
273         .order          = TEGRA_DC_ORDER_RED_BLUE,
274
275         .enable         = loki_hdmi_enable,
276         .disable        = loki_hdmi_disable,
277         .postsuspend    = loki_hdmi_postsuspend,
278         .hotplug_init   = loki_hdmi_hotplug_init,
279         .hotplug_report = loki_hdmi_hotplug_report,
280 };
281
282 static struct tegra_fb_data loki_disp1_fb_data = {
283         .win            = 0,
284         .bits_per_pixel = 32,
285         .flags          = TEGRA_FB_FLIP_ON_PROBE,
286 };
287
288 static struct tegra_dc_platform_data loki_disp1_pdata = {
289         .flags          = TEGRA_DC_FLAG_ENABLED,
290         .default_out    = &loki_disp1_out,
291         .fb             = &loki_disp1_fb_data,
292         .emc_clk_rate   = 204000000,
293 #ifdef CONFIG_TEGRA_DC_CMU
294         .cmu_enable     = 1,
295 #endif
296 };
297
298 static struct tegra_fb_data loki_disp2_fb_data = {
299         .win            = 0,
300         .xres           = 1024,
301         .yres           = 600,
302         .bits_per_pixel = 32,
303         .flags          = TEGRA_FB_FLIP_ON_PROBE,
304 };
305
306 static struct tegra_dc_platform_data loki_disp2_pdata = {
307         .flags          = TEGRA_DC_FLAG_ENABLED,
308         .default_out    = &loki_disp2_out,
309         .fb             = &loki_disp2_fb_data,
310         .emc_clk_rate   = 300000000,
311 #ifdef CONFIG_TEGRA_DC_CMU
312         .cmu_enable     = 1,
313 #endif
314 };
315
316 static struct platform_device loki_disp2_device = {
317         .name           = "tegradc",
318         .id             = 1,
319         .resource       = loki_disp2_resources,
320         .num_resources  = ARRAY_SIZE(loki_disp2_resources),
321         .dev = {
322                 .platform_data = &loki_disp2_pdata,
323         },
324 };
325
326 static struct platform_device loki_disp1_device = {
327         .name           = "tegradc",
328         .id             = 0,
329         .resource       = loki_disp1_resources,
330         .num_resources  = ARRAY_SIZE(loki_disp1_resources),
331         .dev = {
332                 .platform_data = &loki_disp1_pdata,
333         },
334 };
335
336 static struct nvmap_platform_carveout loki_carveouts[] = {
337         [0] = {
338                 .name           = "iram",
339                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
340                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
341                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
342         },
343         [1] = {
344                 .name           = "generic-0",
345                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
346                 .base           = 0, /* Filled in by loki_panel_init() */
347                 .size           = 0, /* Filled in by loki_panel_init() */
348         },
349         [2] = {
350                 .name           = "vpr",
351                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
352                 .base           = 0, /* Filled in by loki_panel_init() */
353                 .size           = 0, /* Filled in by loki_panel_init() */
354         },
355 };
356
357 static struct nvmap_platform_data loki_nvmap_data = {
358         .carveouts      = loki_carveouts,
359         .nr_carveouts   = ARRAY_SIZE(loki_carveouts),
360 };
361
362 static struct platform_device loki_nvmap_device = {
363         .name   = "tegra-nvmap",
364         .id     = -1,
365         .dev    = {
366                 .platform_data = &loki_nvmap_data,
367         },
368 };
369
370 static struct tegra_dc_sd_settings loki_sd_settings = {
371         .enable = 0, /* disabled by default. */
372         .use_auto_pwm = false,
373         .hw_update_delay = 0,
374         .bin_width = -1,
375         .aggressiveness = 1,
376         .use_vid_luma = false,
377         .phase_in_adjustments = 0,
378         .k_limit_enable = true,
379         .k_limit = 180,
380         .sd_window_enable = false,
381         .soft_clipping_enable = true,
382         /* Low soft clipping threshold to compensate for aggressive k_limit */
383         .soft_clipping_threshold = 128,
384         .smooth_k_enable = true,
385         .smooth_k_incr = 128,
386         /* Default video coefficients */
387         .coeff = {5, 9, 2},
388         .fc = {0, 0},
389         /* Immediate backlight changes */
390         .blp = {1024, 255},
391         /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
392         /* Default BL TF */
393         .bltf = {
394                         {
395                                 {57, 65, 73, 82},
396                                 {92, 103, 114, 125},
397                                 {138, 150, 164, 178},
398                                 {193, 208, 224, 241},
399                         },
400                 },
401         /* Default LUT */
402         .lut = {
403                         {
404                                 {255, 255, 255},
405                                 {199, 199, 199},
406                                 {153, 153, 153},
407                                 {116, 116, 116},
408                                 {85, 85, 85},
409                                 {59, 59, 59},
410                                 {36, 36, 36},
411                                 {17, 17, 17},
412                                 {0, 0, 0},
413                         },
414                 },
415         .sd_brightness = &sd_brightness,
416 };
417
418 static void loki_panel_select(void)
419 {
420         struct tegra_panel *panel;
421         struct board_info board;
422         u8 dsi_instance = DSI_INSTANCE_0;
423
424         tegra_get_display_board_info(&board);
425
426         switch (board.fab) {
427         case 0x1:
428                 panel = &dsi_j_1440_810_5_8;
429                 break;
430         case 0x0:
431         default:
432                 panel = &dsi_l_720p_5_loki;
433                 break;
434         }
435         if (panel) {
436                 if (panel->init_sd_settings)
437                         panel->init_sd_settings(&sd_settings);
438
439                 if (panel->init_dc_out) {
440                         panel->init_dc_out(&loki_disp1_out);
441                         loki_disp1_out.dsi->dsi_instance = dsi_instance;
442                         loki_disp1_out.dsi->dsi_panel_rst_gpio =
443                                 DSI_PANEL_RST_GPIO;
444                         loki_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
445                                 DSI_PANEL_BL_PWM_GPIO;
446                         tegra_dsi_update_init_cmd_gpio_rst(&loki_disp1_out);
447                 }
448
449                 if (panel->init_fb_data)
450                         panel->init_fb_data(&loki_disp1_fb_data);
451
452                 if (panel->init_cmu_data)
453                         panel->init_cmu_data(&loki_disp1_pdata);
454
455                 if (panel->set_disp_device)
456                         panel->set_disp_device(&loki_disp1_device);
457
458                 if (panel->register_bl_dev)
459                         panel->register_bl_dev();
460         }
461 }
462
463 int __init loki_panel_init(int board_id)
464 {
465         int err = 0;
466         struct resource __maybe_unused *res;
467         struct platform_device *phost1x = NULL;
468
469         sd_settings = loki_sd_settings;
470
471         loki_panel_select();
472
473 #ifdef CONFIG_TEGRA_NVMAP
474         loki_carveouts[1].base = tegra_carveout_start;
475         loki_carveouts[1].size = tegra_carveout_size;
476         loki_carveouts[2].base = tegra_vpr_start;
477         loki_carveouts[2].size = tegra_vpr_size;
478 #ifdef CONFIG_NVMAP_USE_CMA_FOR_CARVEOUT
479         loki_carveouts[1].cma_dev = &tegra_generic_cma_dev;
480         loki_carveouts[1].resize = false;
481         loki_carveouts[2].cma_dev = &tegra_vpr_cma_dev;
482         loki_carveouts[2].resize = true;
483         loki_carveouts[2].cma_chunk_size = SZ_32M;
484 #endif
485
486         err = platform_device_register(&loki_nvmap_device);
487         if (err) {
488                 pr_err("nvmap device registration failed\n");
489                 return err;
490         }
491 #endif
492
493         phost1x = loki_host1x_init();
494         if (!phost1x) {
495                 pr_err("host1x devices registration failed\n");
496                 return -EINVAL;
497         }
498
499         res = platform_get_resource_byname(&loki_disp1_device,
500                                          IORESOURCE_MEM, "fbmem");
501         res->start = tegra_fb_start;
502         res->end = tegra_fb_start + tegra_fb_size - 1;
503
504         /* Copy the bootloader fb to the fb. */
505         __tegra_move_framebuffer(&loki_nvmap_device,
506                 tegra_fb_start, tegra_bootloader_fb_start,
507                         min(tegra_fb_size, tegra_bootloader_fb_size));
508
509         res = platform_get_resource_byname(&loki_disp2_device,
510                                          IORESOURCE_MEM, "fbmem");
511         res->start = tegra_fb2_start;
512         res->end = tegra_fb2_start + tegra_fb2_size - 1;
513
514         loki_disp1_device.dev.parent = &phost1x->dev;
515         err = platform_device_register(&loki_disp1_device);
516         if (err) {
517                 pr_err("disp1 device registration failed\n");
518                 return err;
519         }
520
521         loki_disp2_device.dev.parent = &phost1x->dev;
522         loki_disp2_out.hdmi_out = &loki_hdmi_out;
523         err = platform_device_register(&loki_disp2_device);
524         if (err) {
525                 pr_err("disp2 device registration failed\n");
526                 return err;
527         }
528
529 #ifdef CONFIG_TEGRA_NVAVP
530         nvavp_device.dev.parent = &phost1x->dev;
531         err = platform_device_register(&nvavp_device);
532         if (err) {
533                 pr_err("nvavp device registration failed\n");
534                 return err;
535         }
536 #endif
537         return err;
538 }
539 #else
540 int __init loki_panel_init(void)
541 {
542         if (loki_host1x_init())
543                 return 0;
544         else
545                 return -EINVAL;
546 }
547 #endif