2 * arch/arm/mach-tegra/board-dalmore-panel.c
4 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
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.
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
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/>.
18 #include <linux/ioport.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>
30 #include <mach/irqs.h>
32 #include <mach/pinmux.h>
33 #include <mach/pinmux-t11.h>
37 #include "gpio-names.h"
38 #include "board-panel.h"
41 #include "tegra11_host1x_devices.h"
43 #define DSI_PANEL_RST_GPIO TEGRA_GPIO_PH3
44 #define DSI_PANEL_BL_PWM_GPIO TEGRA_GPIO_PH1
46 struct platform_device * __init dalmore_host1x_init(void)
48 struct platform_device *pdev = NULL;
50 #ifdef CONFIG_TEGRA_GRHOST
51 if (!of_have_populated_dt())
52 pdev = tegra11_register_host1x_devices();
54 pdev = to_platform_device(bus_find_device_by_name(
55 &platform_bus_type, NULL, "host1x"));
60 #ifdef CONFIG_TEGRA_DC
62 /* HDMI Hotplug detection pin */
63 #define dalmore_hdmi_hpd TEGRA_GPIO_PN7
65 static struct regulator *dalmore_hdmi_reg;
66 static struct regulator *dalmore_hdmi_pll;
67 static struct regulator *dalmore_hdmi_vddio;
69 static struct resource dalmore_disp1_resources[] = {
72 .start = INT_DISPLAY_GENERAL,
73 .end = INT_DISPLAY_GENERAL,
74 .flags = IORESOURCE_IRQ,
78 .start = TEGRA_DISPLAY_BASE,
79 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
80 .flags = IORESOURCE_MEM,
84 .start = 0, /* Filled in by dalmore_panel_init() */
85 .end = 0, /* Filled in by dalmore_panel_init() */
86 .flags = IORESOURCE_MEM,
89 .name = "ganged_dsia_regs",
90 .start = 0, /* Filled in the panel file by init_resources() */
91 .end = 0, /* Filled in the panel file by init_resources() */
92 .flags = IORESOURCE_MEM,
95 .name = "ganged_dsib_regs",
96 .start = 0, /* Filled in the panel file by init_resources() */
97 .end = 0, /* Filled in the panel file by init_resources() */
98 .flags = IORESOURCE_MEM,
102 .start = 0, /* Filled in the panel file by init_resources() */
103 .end = 0, /* Filled in the panel file by init_resources() */
104 .flags = IORESOURCE_MEM,
108 .start = TEGRA_MIPI_CAL_BASE,
109 .end = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
110 .flags = IORESOURCE_MEM,
114 static struct resource dalmore_disp2_resources[] = {
117 .start = INT_DISPLAY_B_GENERAL,
118 .end = INT_DISPLAY_B_GENERAL,
119 .flags = IORESOURCE_IRQ,
123 .start = TEGRA_DISPLAY2_BASE,
124 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
125 .flags = IORESOURCE_MEM,
129 .start = 0, /* Filled in by dalmore_panel_init() */
130 .end = 0, /* Filled in by dalmore_panel_init() */
131 .flags = IORESOURCE_MEM,
135 .start = TEGRA_HDMI_BASE,
136 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
137 .flags = IORESOURCE_MEM,
142 static struct tegra_dc_sd_settings sd_settings;
144 static struct tegra_dc_out dalmore_disp1_out = {
145 .type = TEGRA_DC_OUT_DSI,
146 .sd_settings = &sd_settings,
149 static int dalmore_hdmi_enable(struct device *dev)
152 if (!dalmore_hdmi_reg) {
153 dalmore_hdmi_reg = regulator_get(dev, "avdd_hdmi");
154 if (IS_ERR_OR_NULL(dalmore_hdmi_reg)) {
155 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
156 dalmore_hdmi_reg = NULL;
157 return PTR_ERR(dalmore_hdmi_reg);
160 ret = regulator_enable(dalmore_hdmi_reg);
162 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
165 if (!dalmore_hdmi_pll) {
166 dalmore_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
167 if (IS_ERR_OR_NULL(dalmore_hdmi_pll)) {
168 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
169 dalmore_hdmi_pll = NULL;
170 regulator_put(dalmore_hdmi_reg);
171 dalmore_hdmi_reg = NULL;
172 return PTR_ERR(dalmore_hdmi_pll);
175 ret = regulator_enable(dalmore_hdmi_pll);
177 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
183 static int dalmore_hdmi_disable(void)
185 if (dalmore_hdmi_reg) {
186 regulator_disable(dalmore_hdmi_reg);
187 regulator_put(dalmore_hdmi_reg);
188 dalmore_hdmi_reg = NULL;
191 if (dalmore_hdmi_pll) {
192 regulator_disable(dalmore_hdmi_pll);
193 regulator_put(dalmore_hdmi_pll);
194 dalmore_hdmi_pll = NULL;
200 static int dalmore_hdmi_postsuspend(void)
202 if (dalmore_hdmi_vddio) {
203 regulator_disable(dalmore_hdmi_vddio);
204 regulator_put(dalmore_hdmi_vddio);
205 dalmore_hdmi_vddio = NULL;
210 static int dalmore_hdmi_hotplug_init(struct device *dev)
214 if (!dalmore_hdmi_vddio) {
215 dalmore_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
216 if (WARN_ON(IS_ERR(dalmore_hdmi_vddio))) {
217 e = PTR_ERR(dalmore_hdmi_vddio);
218 pr_err("%s: couldn't get regulator vdd_hdmi_5v0: %d\n",
220 dalmore_hdmi_vddio = NULL;
222 e = regulator_enable(dalmore_hdmi_vddio);
229 static void dalmore_hdmi_hotplug_report(bool state)
232 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SDA,
233 TEGRA_PUPD_PULL_DOWN);
234 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SCL,
235 TEGRA_PUPD_PULL_DOWN);
237 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SDA,
239 tegra_pinmux_set_pullupdown(TEGRA_PINGROUP_DDC_SCL,
244 /* Electrical characteristics for HDMI, all modes must be declared here */
245 struct tmds_config dalmore_tmds_config[] = {
246 { /* 480p : 27 MHz and below */
250 .drive_current = 0x23232323,
251 .pe_current = 0x00000000,
252 .peak_current = 0x00000000,
254 { /* 720p : 74.25MHz modes */
258 .drive_current = 0x25252525,
259 .pe_current = 0x00000000,
260 .peak_current = 0x03030303,
262 { /* 1080p : 148.5MHz modes */
266 .drive_current = 0x27272727,
267 .pe_current = 0x00000000,
268 .peak_current = 0x03030303,
270 { /* 4K : 297MHz modes */
274 .drive_current = 0x303f3f3f,
275 .pe_current = 0x00000000,
276 .peak_current = 0x040f0f0f,
280 struct tegra_hdmi_out dalmore_hdmi_out = {
281 .tmds_config = dalmore_tmds_config,
282 .n_tmds_config = ARRAY_SIZE(dalmore_tmds_config),
285 static struct tegra_dc_out dalmore_disp2_out = {
286 .type = TEGRA_DC_OUT_HDMI,
287 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
288 .parent_clk = "pll_d2_out0",
291 .hotplug_gpio = dalmore_hdmi_hpd,
292 .hdmi_out = &dalmore_hdmi_out,
294 .max_pixclock = KHZ2PICOS(297000),
296 .align = TEGRA_DC_ALIGN_MSB,
297 .order = TEGRA_DC_ORDER_RED_BLUE,
299 .enable = dalmore_hdmi_enable,
300 .disable = dalmore_hdmi_disable,
301 .postsuspend = dalmore_hdmi_postsuspend,
302 .hotplug_init = dalmore_hdmi_hotplug_init,
303 .hotplug_report = dalmore_hdmi_hotplug_report,
306 static struct tegra_fb_data dalmore_disp1_fb_data = {
308 .bits_per_pixel = 32,
309 .flags = TEGRA_FB_FLIP_ON_PROBE,
312 static struct tegra_dc_platform_data dalmore_disp1_pdata = {
313 .flags = TEGRA_DC_FLAG_ENABLED,
314 .default_out = &dalmore_disp1_out,
315 .fb = &dalmore_disp1_fb_data,
316 .emc_clk_rate = 204000000,
317 #ifdef CONFIG_TEGRA_DC_CMU
322 static struct tegra_fb_data dalmore_disp2_fb_data = {
326 .bits_per_pixel = 32,
327 .flags = TEGRA_FB_FLIP_ON_PROBE,
330 static struct tegra_dc_platform_data dalmore_disp2_pdata = {
331 .flags = TEGRA_DC_FLAG_ENABLED,
332 .default_out = &dalmore_disp2_out,
333 .fb = &dalmore_disp2_fb_data,
334 .emc_clk_rate = 300000000,
335 #ifdef CONFIG_TEGRA_DC_CMU
340 static struct platform_device dalmore_disp2_device = {
343 .resource = dalmore_disp2_resources,
344 .num_resources = ARRAY_SIZE(dalmore_disp2_resources),
346 .platform_data = &dalmore_disp2_pdata,
350 static struct platform_device dalmore_disp1_device = {
353 .resource = dalmore_disp1_resources,
354 .num_resources = ARRAY_SIZE(dalmore_disp1_resources),
356 .platform_data = &dalmore_disp1_pdata,
360 static struct nvmap_platform_carveout dalmore_carveouts[] = {
363 .usage_mask = NVMAP_HEAP_CARVEOUT_IRAM,
364 .base = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
365 .size = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
366 .buddy_size = 0, /* no buddy allocation for IRAM */
370 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
371 .base = 0, /* Filled in by dalmore_panel_init() */
372 .size = 0, /* Filled in by dalmore_panel_init() */
373 .buddy_size = SZ_32K,
377 .usage_mask = NVMAP_HEAP_CARVEOUT_VPR,
378 .base = 0, /* Filled in by dalmore_panel_init() */
379 .size = 0, /* Filled in by dalmore_panel_init() */
380 .buddy_size = SZ_32K,
384 static struct nvmap_platform_data dalmore_nvmap_data = {
385 .carveouts = dalmore_carveouts,
386 .nr_carveouts = ARRAY_SIZE(dalmore_carveouts),
388 static struct platform_device dalmore_nvmap_device = {
389 .name = "tegra-nvmap",
392 .platform_data = &dalmore_nvmap_data,
396 static struct tegra_dc_sd_settings dalmore_sd_settings = {
397 .enable = 1, /* enabled by default. */
398 .use_auto_pwm = false,
399 .hw_update_delay = 0,
402 .use_vid_luma = false,
403 .phase_in_adjustments = 0,
404 .k_limit_enable = true,
406 .sd_window_enable = false,
407 .soft_clipping_enable = true,
408 /* Low soft clipping threshold to compensate for aggressive k_limit */
409 .soft_clipping_threshold = 128,
410 .smooth_k_enable = true,
412 /* Default video coefficients */
415 /* Immediate backlight changes */
417 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
423 {138, 150, 164, 178},
424 {193, 208, 224, 241},
441 .sd_brightness = &sd_brightness,
445 static void dalmore_panel_select(void)
447 struct tegra_panel *panel = NULL;
448 struct board_info board;
451 tegra_get_display_board_info(&board);
453 switch (board.board_id) {
455 panel = &dsi_s_wqxga_10_1;
456 /* FIXME: panel used ganged mode,need to check if
457 * the dsi_instance is useful in this case
459 dsi_instance = DSI_INSTANCE_0;
462 panel = &dsi_a_1080p_11_6;
463 dsi_instance = DSI_INSTANCE_0;
468 panel = &dsi_p_wuxga_10_1;
469 dsi_instance = DSI_INSTANCE_0;
473 if (panel->init_sd_settings)
474 panel->init_sd_settings(&sd_settings);
476 if (panel->init_dc_out) {
477 panel->init_dc_out(&dalmore_disp1_out);
478 dalmore_disp1_out.dsi->dsi_instance = dsi_instance;
479 dalmore_disp1_out.dsi->dsi_panel_rst_gpio =
481 dalmore_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
482 DSI_PANEL_BL_PWM_GPIO;
485 if (panel->init_fb_data)
486 panel->init_fb_data(&dalmore_disp1_fb_data);
488 if (panel->init_cmu_data)
489 panel->init_cmu_data(&dalmore_disp1_pdata);
491 if (panel->set_disp_device)
492 panel->set_disp_device(&dalmore_disp1_device);
494 tegra_dsi_resources_init(dsi_instance, dalmore_disp1_resources,
495 ARRAY_SIZE(dalmore_disp1_resources));
497 if (panel->register_bl_dev)
498 panel->register_bl_dev();
500 if (panel->register_i2c_bridge)
501 panel->register_i2c_bridge();
505 int __init dalmore_panel_init(void)
508 struct resource __maybe_unused *res;
509 struct platform_device *phost1x = NULL;
511 sd_settings = dalmore_sd_settings;
513 dalmore_panel_select();
515 #ifdef CONFIG_TEGRA_NVMAP
516 dalmore_carveouts[1].base = tegra_carveout_start;
517 dalmore_carveouts[1].size = tegra_carveout_size;
518 dalmore_carveouts[2].base = tegra_vpr_start;
519 dalmore_carveouts[2].size = tegra_vpr_size;
521 err = platform_device_register(&dalmore_nvmap_device);
523 pr_err("nvmap device registration failed\n");
528 phost1x = dalmore_host1x_init();
530 pr_err("host1x devices registration failed\n");
534 res = platform_get_resource_byname(&dalmore_disp1_device,
535 IORESOURCE_MEM, "fbmem");
536 res->start = tegra_fb_start;
537 res->end = tegra_fb_start + tegra_fb_size - 1;
539 /* Copy the bootloader fb to the fb. */
540 __tegra_move_framebuffer(&dalmore_nvmap_device,
541 tegra_fb_start, tegra_bootloader_fb_start,
542 min(tegra_fb_size, tegra_bootloader_fb_size));
544 res = platform_get_resource_byname(&dalmore_disp2_device,
545 IORESOURCE_MEM, "fbmem");
547 res->start = tegra_fb2_start;
548 res->end = tegra_fb2_start + tegra_fb2_size - 1;
550 dalmore_disp1_device.dev.parent = &phost1x->dev;
551 err = platform_device_register(&dalmore_disp1_device);
553 pr_err("disp1 device registration failed\n");
557 dalmore_disp2_device.dev.parent = &phost1x->dev;
558 err = platform_device_register(&dalmore_disp2_device);
560 pr_err("disp2 device registration failed\n");
564 #ifdef CONFIG_TEGRA_NVAVP
565 nvavp_device.dev.parent = &phost1x->dev;
566 err = platform_device_register(&nvavp_device);
568 pr_err("nvavp device registration failed\n");
575 int __init dalmore_panel_init(void)
577 if (dalmore_host1x_init())