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