ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / board-dalmore-panel.c
1 /*
2  * arch/arm/mach-tegra/board-dalmore-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 it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 #include <linux/ioport.h>
19 #include <linux/fb.h>
20 #include <linux/nvmap.h>
21 #include <linux/nvhost.h>
22 #include <linux/init.h>
23 #include <linux/delay.h>
24 #include <linux/gpio.h>
25 #include <linux/tegra_pwm_bl.h>
26 #include <linux/regulator/consumer.h>
27 #include <linux/pwm_backlight.h>
28 #include <linux/of.h>
29
30 #include <mach/irqs.h>
31 #include <mach/dc.h>
32 #include <mach/pinmux.h>
33 #include <mach/pinmux-t11.h>
34
35 #include "board.h"
36 #include "devices.h"
37 #include "gpio-names.h"
38 #include "board-panel.h"
39 #include "common.h"
40 #include "iomap.h"
41 #include "tegra11_host1x_devices.h"
42
43 #define DSI_PANEL_RST_GPIO      TEGRA_GPIO_PH3
44 #define DSI_PANEL_BL_PWM_GPIO   TEGRA_GPIO_PH1
45
46 struct platform_device * __init dalmore_host1x_init(void)
47 {
48         struct platform_device *pdev = NULL;
49
50 #ifdef CONFIG_TEGRA_GRHOST
51         if (!of_have_populated_dt())
52                 pdev = tegra11_register_host1x_devices();
53         else
54                 pdev = to_platform_device(bus_find_device_by_name(
55                         &platform_bus_type, NULL, "host1x"));
56 #endif
57         return pdev;
58 }
59
60 /* HDMI Hotplug detection pin */
61 #define dalmore_hdmi_hpd        TEGRA_GPIO_PN7
62
63 static struct regulator *dalmore_hdmi_reg;
64 static struct regulator *dalmore_hdmi_pll;
65 static struct regulator *dalmore_hdmi_vddio;
66
67 static struct resource dalmore_disp1_resources[] = {
68         {
69                 .name   = "irq",
70                 .start  = INT_DISPLAY_GENERAL,
71                 .end    = INT_DISPLAY_GENERAL,
72                 .flags  = IORESOURCE_IRQ,
73         },
74         {
75                 .name   = "regs",
76                 .start  = TEGRA_DISPLAY_BASE,
77                 .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
78                 .flags  = IORESOURCE_MEM,
79         },
80         {
81                 .name   = "fbmem",
82                 .start  = 0, /* Filled in by dalmore_panel_init() */
83                 .end    = 0, /* Filled in by dalmore_panel_init() */
84                 .flags  = IORESOURCE_MEM,
85         },
86         {
87                 .name   = "ganged_dsia_regs",
88                 .start  = 0, /* Filled in the panel file by init_resources() */
89                 .end    = 0, /* Filled in the panel file by init_resources() */
90                 .flags  = IORESOURCE_MEM,
91         },
92         {
93                 .name   = "ganged_dsib_regs",
94                 .start  = 0, /* Filled in the panel file by init_resources() */
95                 .end    = 0, /* Filled in the panel file by init_resources() */
96                 .flags  = IORESOURCE_MEM,
97         },
98         {
99                 .name   = "dsi_regs",
100                 .start  = 0, /* Filled in the panel file by init_resources() */
101                 .end    = 0, /* Filled in the panel file by init_resources() */
102                 .flags  = IORESOURCE_MEM,
103         },
104         {
105                 .name   = "mipi_cal",
106                 .start  = TEGRA_MIPI_CAL_BASE,
107                 .end    = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
108                 .flags  = IORESOURCE_MEM,
109         },
110 };
111
112 static struct resource dalmore_disp2_resources[] = {
113         {
114                 .name   = "irq",
115                 .start  = INT_DISPLAY_B_GENERAL,
116                 .end    = INT_DISPLAY_B_GENERAL,
117                 .flags  = IORESOURCE_IRQ,
118         },
119         {
120                 .name   = "regs",
121                 .start  = TEGRA_DISPLAY2_BASE,
122                 .end    = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
123                 .flags  = IORESOURCE_MEM,
124         },
125         {
126                 .name   = "fbmem",
127                 .start  = 0, /* Filled in by dalmore_panel_init() */
128                 .end    = 0, /* Filled in by dalmore_panel_init() */
129                 .flags  = IORESOURCE_MEM,
130         },
131         {
132                 .name   = "hdmi_regs",
133                 .start  = TEGRA_HDMI_BASE,
134                 .end    = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
135                 .flags  = IORESOURCE_MEM,
136         },
137 };
138
139
140 static struct tegra_dc_sd_settings sd_settings;
141
142 static struct tegra_dc_out dalmore_disp1_out = {
143         .type           = TEGRA_DC_OUT_DSI,
144         .sd_settings    = &sd_settings,
145 };
146
147 static int dalmore_hdmi_enable(struct device *dev)
148 {
149         int ret;
150         if (!dalmore_hdmi_reg) {
151                 dalmore_hdmi_reg = regulator_get(dev, "avdd_hdmi");
152                 if (IS_ERR(dalmore_hdmi_reg)) {
153                         pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
154                         dalmore_hdmi_reg = NULL;
155                         return PTR_ERR(dalmore_hdmi_reg);
156                 }
157         }
158         ret = regulator_enable(dalmore_hdmi_reg);
159         if (ret < 0) {
160                 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
161                 return ret;
162         }
163         if (!dalmore_hdmi_pll) {
164                 dalmore_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
165                 if (IS_ERR(dalmore_hdmi_pll)) {
166                         pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
167                         dalmore_hdmi_pll = NULL;
168                         regulator_put(dalmore_hdmi_reg);
169                         dalmore_hdmi_reg = NULL;
170                         return PTR_ERR(dalmore_hdmi_pll);
171                 }
172         }
173         ret = regulator_enable(dalmore_hdmi_pll);
174         if (ret < 0) {
175                 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
176                 return ret;
177         }
178         return 0;
179 }
180
181 static int dalmore_hdmi_disable(void)
182 {
183         if (dalmore_hdmi_reg) {
184                 regulator_disable(dalmore_hdmi_reg);
185                 regulator_put(dalmore_hdmi_reg);
186                 dalmore_hdmi_reg = NULL;
187         }
188
189         if (dalmore_hdmi_pll) {
190                 regulator_disable(dalmore_hdmi_pll);
191                 regulator_put(dalmore_hdmi_pll);
192                 dalmore_hdmi_pll = NULL;
193         }
194
195         return 0;
196 }
197
198 static int dalmore_hdmi_postsuspend(void)
199 {
200         if (dalmore_hdmi_vddio) {
201                 regulator_disable(dalmore_hdmi_vddio);
202                 regulator_put(dalmore_hdmi_vddio);
203                 dalmore_hdmi_vddio = NULL;
204         }
205         return 0;
206 }
207
208 static int dalmore_hdmi_hotplug_init(struct device *dev)
209 {
210         int e = 0;
211
212         if (!dalmore_hdmi_vddio) {
213                 dalmore_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
214                 if (WARN_ON(IS_ERR(dalmore_hdmi_vddio))) {
215                         e = PTR_ERR(dalmore_hdmi_vddio);
216                         pr_err("%s: couldn't get regulator vdd_hdmi_5v0: %d\n",
217                                 __func__, e);
218                         dalmore_hdmi_vddio = NULL;
219                 } else {
220                         e = regulator_enable(dalmore_hdmi_vddio);
221                 }
222         }
223
224         return e;
225 }
226
227 static void dalmore_hdmi_hotplug_report(bool state)
228 {
229         if (state) {
230                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SDA,
231                                                 TEGRA_PUPD_PULL_DOWN);
232                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SCL,
233                                                 TEGRA_PUPD_PULL_DOWN);
234         } else {
235                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SDA,
236                                                 TEGRA_PUPD_NORMAL);
237                 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SCL,
238                                                 TEGRA_PUPD_NORMAL);
239         }
240 }
241
242 /* Electrical characteristics for HDMI, all modes must be declared here */
243 struct tmds_config dalmore_tmds_config[] = {
244         { /* 480p : 27 MHz and below */
245                 .pclk = 27000000,
246                 .pll0 = 0x01003010,
247                 .pll1 = 0x00301b00,
248                 .drive_current = 0x23232323,
249                 .pe_current = 0x00000000,
250                 .peak_current = 0x00000000,
251         },
252         { /* 720p : 74.25MHz modes */
253                 .pclk = 74250000,
254                 .pll0 = 0x01003110,
255                 .pll1 = 0x00301b00,
256                 .drive_current = 0x25252525,
257                 .pe_current = 0x00000000,
258                 .peak_current = 0x03030303,
259         },
260         { /* 1080p : 148.5MHz modes */
261                 .pclk = 148500000,
262                 .pll0 = 0x01003310,
263                 .pll1 = 0x00301b00,
264                 .drive_current = 0x27272727,
265                 .pe_current = 0x00000000,
266                 .peak_current = 0x03030303,
267         },
268         { /* 4K : 297MHz modes */
269                 .pclk = INT_MAX,
270                 .pll0 = 0x01003f10,
271                 .pll1 = 0x00300f00,
272                 .drive_current = 0x303f3f3f,
273                 .pe_current = 0x00000000,
274                 .peak_current = 0x040f0f0f,
275         },
276 };
277
278 struct tegra_hdmi_out dalmore_hdmi_out = {
279         .tmds_config = dalmore_tmds_config,
280         .n_tmds_config = ARRAY_SIZE(dalmore_tmds_config),
281 };
282
283 static struct tegra_dc_out dalmore_disp2_out = {
284         .type           = TEGRA_DC_OUT_HDMI,
285         .flags          = TEGRA_DC_OUT_HOTPLUG_HIGH,
286         .parent_clk     = "pll_d2_out0",
287
288         .dcc_bus        = 3,
289         .hotplug_gpio   = dalmore_hdmi_hpd,
290         .hdmi_out       = &dalmore_hdmi_out,
291
292         .max_pixclock   = KHZ2PICOS(297000),
293
294         .align          = TEGRA_DC_ALIGN_MSB,
295         .order          = TEGRA_DC_ORDER_RED_BLUE,
296
297         .enable         = dalmore_hdmi_enable,
298         .disable        = dalmore_hdmi_disable,
299         .postsuspend    = dalmore_hdmi_postsuspend,
300         .hotplug_init   = dalmore_hdmi_hotplug_init,
301         .hotplug_report = dalmore_hdmi_hotplug_report,
302 };
303
304 static struct tegra_fb_data dalmore_disp1_fb_data = {
305         .win            = 0,
306         .bits_per_pixel = 32,
307         .flags          = TEGRA_FB_FLIP_ON_PROBE,
308 };
309
310 static struct tegra_dc_platform_data dalmore_disp1_pdata = {
311         .flags          = TEGRA_DC_FLAG_ENABLED,
312         .default_out    = &dalmore_disp1_out,
313         .fb             = &dalmore_disp1_fb_data,
314         .emc_clk_rate   = 204000000,
315 #ifdef CONFIG_TEGRA_DC_CMU
316         .cmu_enable     = 1,
317 #endif
318 };
319
320 static struct tegra_fb_data dalmore_disp2_fb_data = {
321         .win            = 0,
322         .xres           = 1280,
323         .yres           = 720,
324         .bits_per_pixel = 32,
325         .flags          = TEGRA_FB_FLIP_ON_PROBE,
326 };
327
328 static struct tegra_dc_platform_data dalmore_disp2_pdata = {
329         .flags          = TEGRA_DC_FLAG_ENABLED,
330         .default_out    = &dalmore_disp2_out,
331         .fb             = &dalmore_disp2_fb_data,
332         .emc_clk_rate   = 300000000,
333 #ifdef CONFIG_TEGRA_DC_CMU
334         .cmu_enable     = 1,
335 #endif
336 };
337
338 static struct platform_device dalmore_disp2_device = {
339         .name           = "tegradc",
340         .id             = 1,
341         .resource       = dalmore_disp2_resources,
342         .num_resources  = ARRAY_SIZE(dalmore_disp2_resources),
343         .dev = {
344                 .platform_data = &dalmore_disp2_pdata,
345         },
346 };
347
348 static struct platform_device dalmore_disp1_device = {
349         .name           = "tegradc",
350         .id             = 0,
351         .resource       = dalmore_disp1_resources,
352         .num_resources  = ARRAY_SIZE(dalmore_disp1_resources),
353         .dev = {
354                 .platform_data = &dalmore_disp1_pdata,
355         },
356 };
357
358 static struct nvmap_platform_carveout dalmore_carveouts[] = {
359         [0] = {
360                 .name           = "iram",
361                 .usage_mask     = NVMAP_HEAP_CARVEOUT_IRAM,
362                 .base           = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
363                 .size           = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
364         },
365         [1] = {
366                 .name           = "generic-0",
367                 .usage_mask     = NVMAP_HEAP_CARVEOUT_GENERIC,
368                 .base           = 0, /* Filled in by dalmore_panel_init() */
369                 .size           = 0, /* Filled in by dalmore_panel_init() */
370         },
371         [2] = {
372                 .name           = "vpr",
373                 .usage_mask     = NVMAP_HEAP_CARVEOUT_VPR,
374                 .base           = 0, /* Filled in by dalmore_panel_init() */
375                 .size           = 0, /* Filled in by dalmore_panel_init() */
376         },
377 };
378
379 static struct nvmap_platform_data dalmore_nvmap_data = {
380         .carveouts      = dalmore_carveouts,
381         .nr_carveouts   = ARRAY_SIZE(dalmore_carveouts),
382 };
383 static struct platform_device dalmore_nvmap_device = {
384         .name   = "tegra-nvmap",
385         .id     = -1,
386         .dev    = {
387                 .platform_data = &dalmore_nvmap_data,
388         },
389 };
390
391 static void dalmore_panel_select(void)
392 {
393         struct tegra_panel *panel = NULL;
394         struct board_info board;
395         u8 dsi_instance;
396
397         tegra_get_display_board_info(&board);
398
399         switch (board.board_id) {
400         case BOARD_E1639:
401                 panel = &dsi_s_wqxga_10_1;
402                 /* FIXME: panel used ganged mode,need to check if
403                  * the dsi_instance is useful in this case
404                  */
405                 dsi_instance = DSI_INSTANCE_0;
406                 break;
407         case BOARD_E1631:
408                 panel = &dsi_a_1080p_11_6;
409                 dsi_instance = DSI_INSTANCE_0;
410                 break;
411         case BOARD_E1627:
412         /* fall through */
413         default:
414                 panel = &dsi_p_wuxga_10_1;
415                 dsi_instance = DSI_INSTANCE_0;
416                 break;
417         }
418         if (panel) {
419                 if (panel->init_sd_settings)
420                         panel->init_sd_settings(&sd_settings);
421
422                 if (panel->init_dc_out) {
423                         panel->init_dc_out(&dalmore_disp1_out);
424                         dalmore_disp1_out.dsi->dsi_instance = dsi_instance;
425                         dalmore_disp1_out.dsi->dsi_panel_rst_gpio =
426                                 DSI_PANEL_RST_GPIO;
427                         dalmore_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
428                                 DSI_PANEL_BL_PWM_GPIO;
429                 }
430
431                 if (panel->init_fb_data)
432                         panel->init_fb_data(&dalmore_disp1_fb_data);
433
434                 if (panel->init_cmu_data)
435                         panel->init_cmu_data(&dalmore_disp1_pdata);
436
437                 if (panel->set_disp_device)
438                         panel->set_disp_device(&dalmore_disp1_device);
439
440                 tegra_dsi_resources_init(dsi_instance, dalmore_disp1_resources,
441                         ARRAY_SIZE(dalmore_disp1_resources));
442
443                 if (panel->register_bl_dev)
444                         panel->register_bl_dev();
445
446                 if (panel->register_i2c_bridge)
447                         panel->register_i2c_bridge();
448         }
449
450 }
451 int __init dalmore_panel_init(void)
452 {
453         int err = 0;
454         struct resource __maybe_unused *res;
455         struct platform_device *phost1x = NULL;
456
457         dalmore_panel_select();
458
459 #ifdef CONFIG_TEGRA_NVMAP
460         dalmore_carveouts[1].base = tegra_carveout_start;
461         dalmore_carveouts[1].size = tegra_carveout_size;
462         dalmore_carveouts[2].base = tegra_vpr_start;
463         dalmore_carveouts[2].size = tegra_vpr_size;
464 #ifdef CONFIG_NVMAP_USE_CMA_FOR_CARVEOUT
465         dalmore_carveouts[1].cma_dev =  &tegra_generic_cma_dev;
466         dalmore_carveouts[1].resize = false;
467         dalmore_carveouts[2].cma_dev =  &tegra_vpr_cma_dev;
468         dalmore_carveouts[2].resize = true;
469         dalmore_carveouts[2].cma_chunk_size = SZ_32M;
470 #endif
471
472         err = platform_device_register(&dalmore_nvmap_device);
473         if (err) {
474                 pr_err("nvmap device registration failed\n");
475                 return err;
476         }
477 #endif
478
479         phost1x = dalmore_host1x_init();
480         if (!phost1x) {
481                 pr_err("host1x devices registration failed\n");
482                 return -EINVAL;
483         }
484
485         res = platform_get_resource_byname(&dalmore_disp1_device,
486                                          IORESOURCE_MEM, "fbmem");
487         res->start = tegra_fb_start;
488         res->end = tegra_fb_start + tegra_fb_size - 1;
489
490         /* Copy the bootloader fb to the fb. */
491         if (tegra_bootloader_fb_size)
492                 __tegra_move_framebuffer(&dalmore_nvmap_device,
493                                 tegra_fb_start, tegra_bootloader_fb_start,
494                                 min(tegra_fb_size, tegra_bootloader_fb_size));
495         else
496                 __tegra_clear_framebuffer(&dalmore_nvmap_device,
497                                           tegra_fb_start, tegra_fb_size);
498
499         dalmore_disp1_device.dev.parent = &phost1x->dev;
500         err = platform_device_register(&dalmore_disp1_device);
501         if (err) {
502                 pr_err("disp1 device registration failed\n");
503                 return err;
504         }
505
506         err = tegra_init_hdmi(&dalmore_disp2_device, phost1x);
507         if (err)
508                 return err;
509
510 #ifdef CONFIG_TEGRA_NVAVP
511         nvavp_device.dev.parent = &phost1x->dev;
512         err = platform_device_register(&nvavp_device);
513         if (err) {
514                 pr_err("nvavp device registration failed\n");
515                 return err;
516         }
517 #endif
518         return err;
519 }