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