2 * arch/arm/mach-tegra/board-ardbeg-panel.c
4 * Copyright (c) 2013, NVIDIA Corporation. All rights reserved
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.
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
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.
20 #include <linux/ioport.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>
32 #include <mach/irqs.h>
37 #include "gpio-names.h"
38 #include "board-ardbeg.h"
39 #include "board-panel.h"
43 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
44 #include "tegra11_host1x_devices.h"
46 #include "tegra12_host1x_devices.h"
49 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
50 #define DSI_PANEL_RST_GPIO TEGRA_GPIO_PH3
51 #define DSI_PANEL_BL_PWM_GPIO TEGRA_GPIO_PH1
53 /* TODO: update gpio for t124 ardbeg */
54 #define DSI_PANEL_RST_GPIO TEGRA_GPIO_PH3
55 #define DSI_PANEL_BL_PWM_GPIO TEGRA_GPIO_PH1
58 struct platform_device * __init ardbeg_host1x_init(void)
60 struct platform_device *pdev = NULL;
62 #ifdef CONFIG_TEGRA_GRHOST
63 if (!of_have_populated_dt()) {
64 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
65 pdev = tegra11_register_host1x_devices();
67 pdev = tegra12_register_host1x_devices();
70 pdev = to_platform_device(bus_find_device_by_name(
71 &platform_bus_type, NULL, "host1x"));
75 pr_err("host1x devices registration failed\n");
82 #ifdef CONFIG_TEGRA_DC
84 /* HDMI Hotplug detection pin */
85 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
86 #define ardbeg_hdmi_hpd TEGRA_GPIO_PN7
88 /* TODO: update for t124 ardbeg */
89 #define ardbeg_hdmi_hpd TEGRA_GPIO_PN7
92 /* hdmi related regulators */
93 static struct regulator *ardbeg_hdmi_reg;
94 static struct regulator *ardbeg_hdmi_pll;
95 static struct regulator *ardbeg_hdmi_vddio;
97 static struct resource ardbeg_disp1_resources[] = {
100 .start = INT_DISPLAY_GENERAL,
101 .end = INT_DISPLAY_GENERAL,
102 .flags = IORESOURCE_IRQ,
106 .start = TEGRA_DISPLAY_BASE,
107 .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
108 .flags = IORESOURCE_MEM,
112 .start = 0, /* Filled in by ardbeg_panel_init() */
113 .end = 0, /* Filled in by ardbeg_panel_init() */
114 .flags = IORESOURCE_MEM,
117 .name = "ganged_dsia_regs",
118 .start = 0, /* Filled in the panel file by init_resources() */
119 .end = 0, /* Filled in the panel file by init_resources() */
120 .flags = IORESOURCE_MEM,
123 .name = "ganged_dsib_regs",
124 .start = 0, /* Filled in the panel file by init_resources() */
125 .end = 0, /* Filled in the panel file by init_resources() */
126 .flags = IORESOURCE_MEM,
130 .start = 0, /* Filled in the panel file by init_resources() */
131 .end = 0, /* Filled in the panel file by init_resources() */
132 .flags = IORESOURCE_MEM,
136 .start = TEGRA_MIPI_CAL_BASE,
137 .end = TEGRA_MIPI_CAL_BASE + TEGRA_MIPI_CAL_SIZE - 1,
138 .flags = IORESOURCE_MEM,
142 static struct resource ardbeg_disp2_resources[] = {
145 .start = INT_DISPLAY_B_GENERAL,
146 .end = INT_DISPLAY_B_GENERAL,
147 .flags = IORESOURCE_IRQ,
151 .start = TEGRA_DISPLAY2_BASE,
152 .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
153 .flags = IORESOURCE_MEM,
157 .start = 0, /* Filled in by ardbeg_panel_init() */
158 .end = 0, /* Filled in by ardbeg_panel_init() */
159 .flags = IORESOURCE_MEM,
163 .start = TEGRA_HDMI_BASE,
164 .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
165 .flags = IORESOURCE_MEM,
170 static struct tegra_dc_sd_settings sd_settings;
172 static struct tegra_dc_out ardbeg_disp1_out = {
173 .type = TEGRA_DC_OUT_DSI,
174 .sd_settings = &sd_settings,
177 static int ardbeg_hdmi_enable(struct device *dev)
180 if (!ardbeg_hdmi_reg) {
181 ardbeg_hdmi_reg = regulator_get(dev, "avdd_hdmi");
182 if (IS_ERR_OR_NULL(ardbeg_hdmi_reg)) {
183 pr_err("hdmi: couldn't get regulator avdd_hdmi\n");
184 ardbeg_hdmi_reg = NULL;
185 return PTR_ERR(ardbeg_hdmi_reg);
188 ret = regulator_enable(ardbeg_hdmi_reg);
190 pr_err("hdmi: couldn't enable regulator avdd_hdmi\n");
193 if (!ardbeg_hdmi_pll) {
194 ardbeg_hdmi_pll = regulator_get(dev, "avdd_hdmi_pll");
195 if (IS_ERR_OR_NULL(ardbeg_hdmi_pll)) {
196 pr_err("hdmi: couldn't get regulator avdd_hdmi_pll\n");
197 ardbeg_hdmi_pll = NULL;
198 regulator_put(ardbeg_hdmi_reg);
199 ardbeg_hdmi_reg = NULL;
200 return PTR_ERR(ardbeg_hdmi_pll);
203 ret = regulator_enable(ardbeg_hdmi_pll);
205 pr_err("hdmi: couldn't enable regulator avdd_hdmi_pll\n");
211 static int ardbeg_hdmi_disable(void)
213 if (ardbeg_hdmi_reg) {
214 regulator_disable(ardbeg_hdmi_reg);
215 regulator_put(ardbeg_hdmi_reg);
216 ardbeg_hdmi_reg = NULL;
219 if (ardbeg_hdmi_pll) {
220 regulator_disable(ardbeg_hdmi_pll);
221 regulator_put(ardbeg_hdmi_pll);
222 ardbeg_hdmi_pll = NULL;
227 static int ardbeg_hdmi_postsuspend(void)
229 if (ardbeg_hdmi_vddio) {
230 regulator_disable(ardbeg_hdmi_vddio);
231 regulator_put(ardbeg_hdmi_vddio);
232 ardbeg_hdmi_vddio = NULL;
237 static int ardbeg_hdmi_hotplug_init(struct device *dev)
239 if (!ardbeg_hdmi_vddio) {
240 ardbeg_hdmi_vddio = regulator_get(dev, "vdd_hdmi_5v0");
241 if (WARN_ON(IS_ERR(ardbeg_hdmi_vddio))) {
242 pr_err("%s: couldn't get regulator vdd_hdmi_5v0: %ld\n",
243 __func__, PTR_ERR(ardbeg_hdmi_vddio));
244 ardbeg_hdmi_vddio = NULL;
246 regulator_enable(ardbeg_hdmi_vddio);
253 static struct tegra_dc_out ardbeg_disp2_out = {
254 .type = TEGRA_DC_OUT_HDMI,
255 .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
256 .parent_clk = "pll_d2_out0",
259 .hotplug_gpio = ardbeg_hdmi_hpd,
261 /* TODO: update max pclk to POR */
262 .max_pixclock = KHZ2PICOS(297000),
264 .align = TEGRA_DC_ALIGN_MSB,
265 .order = TEGRA_DC_ORDER_RED_BLUE,
267 .enable = ardbeg_hdmi_enable,
268 .disable = ardbeg_hdmi_disable,
269 .postsuspend = ardbeg_hdmi_postsuspend,
270 .hotplug_init = ardbeg_hdmi_hotplug_init,
273 static struct tegra_fb_data ardbeg_disp1_fb_data = {
275 .bits_per_pixel = 32,
276 .flags = TEGRA_FB_FLIP_ON_PROBE,
279 static struct tegra_dc_platform_data ardbeg_disp1_pdata = {
280 .flags = TEGRA_DC_FLAG_ENABLED,
281 .default_out = &ardbeg_disp1_out,
282 .fb = &ardbeg_disp1_fb_data,
283 .emc_clk_rate = 204000000,
284 #ifdef CONFIG_TEGRA_DC_CMU
289 static struct tegra_fb_data ardbeg_disp2_fb_data = {
293 .bits_per_pixel = 32,
294 .flags = TEGRA_FB_FLIP_ON_PROBE,
297 static struct tegra_dc_platform_data ardbeg_disp2_pdata = {
298 .flags = TEGRA_DC_FLAG_ENABLED,
299 .default_out = &ardbeg_disp2_out,
300 .fb = &ardbeg_disp2_fb_data,
301 .emc_clk_rate = 300000000,
304 static struct platform_device ardbeg_disp2_device = {
307 .resource = ardbeg_disp2_resources,
308 .num_resources = ARRAY_SIZE(ardbeg_disp2_resources),
310 .platform_data = &ardbeg_disp2_pdata,
314 static struct platform_device ardbeg_disp1_device = {
317 .resource = ardbeg_disp1_resources,
318 .num_resources = ARRAY_SIZE(ardbeg_disp1_resources),
320 .platform_data = &ardbeg_disp1_pdata,
324 static struct nvmap_platform_carveout ardbeg_carveouts[] = {
327 .usage_mask = NVMAP_HEAP_CARVEOUT_IRAM,
328 .base = TEGRA_IRAM_BASE + TEGRA_RESET_HANDLER_SIZE,
329 .size = TEGRA_IRAM_SIZE - TEGRA_RESET_HANDLER_SIZE,
330 .buddy_size = 0, /* no buddy allocation for IRAM */
334 .usage_mask = NVMAP_HEAP_CARVEOUT_GENERIC,
335 .base = 0, /* Filled in by ardbeg_panel_init() */
336 .size = 0, /* Filled in by ardbeg_panel_init() */
337 .buddy_size = SZ_32K,
341 .usage_mask = NVMAP_HEAP_CARVEOUT_VPR,
342 .base = 0, /* Filled in by ardbeg_panel_init() */
343 .size = 0, /* Filled in by ardbeg_panel_init() */
344 .buddy_size = SZ_32K,
348 static struct nvmap_platform_data ardbeg_nvmap_data = {
349 .carveouts = ardbeg_carveouts,
350 .nr_carveouts = ARRAY_SIZE(ardbeg_carveouts),
352 static struct platform_device ardbeg_nvmap_device = {
353 .name = "tegra-nvmap",
356 .platform_data = &ardbeg_nvmap_data,
360 static struct tegra_dc_sd_settings ardbeg_sd_settings = {
361 .enable = 1, /* enabled by default. */
362 .use_auto_pwm = false,
363 .hw_update_delay = 0,
366 .use_vid_luma = false,
367 .phase_in_adjustments = 0,
368 .k_limit_enable = true,
370 .sd_window_enable = false,
371 .soft_clipping_enable = true,
372 /* Low soft clipping threshold to compensate for aggressive k_limit */
373 .soft_clipping_threshold = 128,
374 .smooth_k_enable = false,
376 /* Default video coefficients */
379 /* Immediate backlight changes */
381 /* Gammas: R: 2.2 G: 2.2 B: 2.2 */
387 {138, 150, 164, 178},
388 {193, 208, 224, 241},
405 .sd_brightness = &sd_brightness,
409 static void ardbeg_panel_select(void)
411 struct tegra_panel *panel = NULL;
412 struct board_info board;
415 tegra_get_display_board_info(&board);
417 switch (board.board_id) {
419 panel = &dsi_s_wqxga_10_1;
420 dsi_instance = DSI_INSTANCE_0;
423 panel = &dsi_a_1080p_14_0;
424 dsi_instance = DSI_INSTANCE_0;
429 panel = &dsi_p_wuxga_10_1;
430 dsi_instance = DSI_INSTANCE_0;
435 if (panel->init_sd_settings)
436 panel->init_sd_settings(&sd_settings);
438 if (panel->init_dc_out) {
439 panel->init_dc_out(&ardbeg_disp1_out);
440 ardbeg_disp1_out.dsi->dsi_instance = dsi_instance;
441 ardbeg_disp1_out.dsi->dsi_panel_rst_gpio =
443 ardbeg_disp1_out.dsi->dsi_panel_bl_pwm_gpio =
444 DSI_PANEL_BL_PWM_GPIO;
447 if (panel->init_fb_data)
448 panel->init_fb_data(&ardbeg_disp1_fb_data);
450 if (panel->init_cmu_data)
451 panel->init_cmu_data(&ardbeg_disp1_pdata);
453 if (panel->set_disp_device)
454 panel->set_disp_device(&ardbeg_disp1_device);
456 tegra_dsi_resources_init(dsi_instance, ardbeg_disp1_resources,
457 ARRAY_SIZE(ardbeg_disp1_resources));
459 if (panel->register_bl_dev)
460 panel->register_bl_dev();
462 if (panel->register_i2c_bridge)
463 panel->register_i2c_bridge();
467 int __init ardbeg_panel_init(void)
470 struct resource __maybe_unused *res;
471 struct platform_device *phost1x = NULL;
473 sd_settings = ardbeg_sd_settings;
475 ardbeg_panel_select();
477 #ifdef CONFIG_TEGRA_NVMAP
478 ardbeg_carveouts[1].base = tegra_carveout_start;
479 ardbeg_carveouts[1].size = tegra_carveout_size;
480 ardbeg_carveouts[2].base = tegra_vpr_start;
481 ardbeg_carveouts[2].size = tegra_vpr_size;
483 err = platform_device_register(&ardbeg_nvmap_device);
485 pr_err("nvmap device registration failed\n");
490 phost1x = ardbeg_host1x_init();
492 pr_err("host1x devices registration failed\n");
496 res = platform_get_resource_byname(&ardbeg_disp1_device,
497 IORESOURCE_MEM, "fbmem");
498 res->start = tegra_fb_start;
499 res->end = tegra_fb_start + tegra_fb_size - 1;
501 /* Copy the bootloader fb to the fb. */
502 __tegra_move_framebuffer(&ardbeg_nvmap_device,
503 tegra_fb_start, tegra_bootloader_fb_start,
504 min(tegra_fb_size, tegra_bootloader_fb_size));
506 res = platform_get_resource_byname(&ardbeg_disp2_device,
507 IORESOURCE_MEM, "fbmem");
509 res->start = tegra_fb2_start;
510 res->end = tegra_fb2_start + tegra_fb2_size - 1;
512 ardbeg_disp1_device.dev.parent = &phost1x->dev;
513 err = platform_device_register(&ardbeg_disp1_device);
515 pr_err("disp1 device registration failed\n");
519 ardbeg_disp2_device.dev.parent = &phost1x->dev;
520 err = platform_device_register(&ardbeg_disp2_device);
522 pr_err("disp2 device registration failed\n");
526 #ifdef CONFIG_TEGRA_NVAVP
527 nvavp_device.dev.parent = &phost1x->dev;
528 err = platform_device_register(&nvavp_device);
530 pr_err("nvavp device registration failed\n");
537 int __init ardbeg_panel_init(void)
539 if (ardbeg_host1x_init())