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