summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morell <rmorell@nvidia.com>2011-08-29 17:46:07 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-08-30 19:29:36 -0700
commitbf78b43d6527c52ead5407bb19504a66220f171b (patch)
tree1cdc6dbefd7937ab618b416e79cea57553045f92
parenta2911a372b9eb4b61edf1967afa0aa3f894e679f (diff)
arm: tegra: Add HDMI support for Harmony
This adds the necessary platform data to support HDMI on Harmony devices. Bug 868732 Change-Id: Ia972cd2a9695072563478036a7fd1b9c3fd18135 Reviewed-on: http://git-master/r/49729 Reviewed-by: Robert Morell <rmorell@nvidia.com> Tested-by: Robert Morell <rmorell@nvidia.com> Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/board-harmony-panel.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-harmony-panel.c b/arch/arm/mach-tegra/board-harmony-panel.c
index 1498c44aba4f..5bb70205717d 100644
--- a/arch/arm/mach-tegra/board-harmony-panel.c
+++ b/arch/arm/mach-tegra/board-harmony-panel.c
@@ -40,6 +40,7 @@
#define harmony_en_vdd_pnl TEGRA_GPIO_PC6
#define harmony_bl_vdd TEGRA_GPIO_PW0
#define harmony_bl_pwm TEGRA_GPIO_PB4
+#define harmony_hdmi_hpd TEGRA_GPIO_PN7
static int harmony_backlight_init(struct device *dev)
{
@@ -73,6 +74,8 @@ static int harmony_backlight_notify(struct device *unused, int brightness)
return brightness;
}
+static int harmony_disp1_check_fb(struct device *dev, struct fb_info *info);
+
static struct platform_pwm_backlight_data harmony_backlight_data = {
.pwm_id = 0,
.max_brightness = 255,
@@ -81,6 +84,8 @@ static struct platform_pwm_backlight_data harmony_backlight_data = {
.init = harmony_backlight_init,
.exit = harmony_backlight_exit,
.notify = harmony_backlight_notify,
+ /* Only toggle backlight on fb blank notifications for disp1 */
+ .check_fb = harmony_disp1_check_fb,
};
static struct platform_device harmony_backlight_device = {
@@ -103,6 +108,47 @@ static int harmony_panel_disable(void)
return 0;
}
+static int harmony_set_hdmi_power(bool enable)
+{
+ static struct {
+ struct regulator *regulator;
+ const char *name;
+ } regs[] = {
+ { .name = "avdd_hdmi" },
+ { .name = "avdd_hdmi_pll" },
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(regs); i++) {
+ if (!regs[i].regulator) {
+ regs[i].regulator = regulator_get(NULL, regs[i].name);
+
+ if (IS_ERR(regs[i].regulator)) {
+ int ret = PTR_ERR(regs[i].regulator);
+ regs[i].regulator = NULL;
+ return ret;
+ }
+ }
+
+ if (enable)
+ regulator_enable(regs[i].regulator);
+ else
+ regulator_disable(regs[i].regulator);
+ }
+
+ return 0;
+}
+
+static int harmony_hdmi_enable(void)
+{
+ return harmony_set_hdmi_power(true);
+}
+
+static int harmony_hdmi_disable(void)
+{
+ return harmony_set_hdmi_power(false);
+}
+
static struct resource harmony_disp1_resources[] = {
{
.name = "irq",
@@ -124,6 +170,27 @@ static struct resource harmony_disp1_resources[] = {
},
};
+static struct resource harmony_disp2_resources[] = {
+ {
+ .name = "irq",
+ .start = INT_DISPLAY_B_GENERAL,
+ .end = INT_DISPLAY_B_GENERAL,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "regs",
+ .start = TEGRA_DISPLAY2_BASE,
+ .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "hdmi_regs",
+ .start = TEGRA_HDMI_BASE,
+ .end = TEGRA_HDMI_BASE + TEGRA_HDMI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
static struct tegra_dc_mode harmony_panel_modes[] = {
{
.pclk = 42430000,
@@ -147,6 +214,13 @@ static struct tegra_fb_data harmony_fb_data = {
.bits_per_pixel = 32,
};
+static struct tegra_fb_data harmony_hdmi_fb_data = {
+ .win = 0,
+ .xres = 1280,
+ .yres = 720,
+ .bits_per_pixel = 16,
+};
+
static struct tegra_dc_out harmony_disp1_out = {
.type = TEGRA_DC_OUT_RGB,
@@ -160,12 +234,32 @@ static struct tegra_dc_out harmony_disp1_out = {
.disable = harmony_panel_disable,
};
+static struct tegra_dc_out harmony_disp2_out = {
+ .type = TEGRA_DC_OUT_HDMI,
+ .flags = TEGRA_DC_OUT_HOTPLUG_HIGH,
+
+ .dcc_bus = 1,
+ .hotplug_gpio = harmony_hdmi_hpd,
+
+ .align = TEGRA_DC_ALIGN_MSB,
+ .order = TEGRA_DC_ORDER_RED_BLUE,
+
+ .enable = harmony_hdmi_enable,
+ .disable = harmony_hdmi_disable,
+};
+
static struct tegra_dc_platform_data harmony_disp1_pdata = {
.flags = TEGRA_DC_FLAG_ENABLED,
.default_out = &harmony_disp1_out,
.fb = &harmony_fb_data,
};
+static struct tegra_dc_platform_data harmony_disp2_pdata = {
+ .flags = 0,
+ .default_out = &harmony_disp2_out,
+ .fb = &harmony_hdmi_fb_data,
+};
+
static struct nvhost_device harmony_disp1_device = {
.name = "tegradc",
.id = 0,
@@ -176,6 +270,21 @@ static struct nvhost_device harmony_disp1_device = {
},
};
+static int harmony_disp1_check_fb(struct device *dev, struct fb_info *info)
+{
+ return info->device == &harmony_disp1_device.dev;
+}
+
+static struct nvhost_device harmony_disp2_device = {
+ .name = "tegradc",
+ .id = 1,
+ .resource = harmony_disp2_resources,
+ .num_resources = ARRAY_SIZE(harmony_disp2_resources),
+ .dev = {
+ .platform_data = &harmony_disp2_pdata,
+ },
+};
+
static struct nvmap_platform_carveout harmony_carveouts[] = {
[0] = {
.name = "iram",
@@ -229,12 +338,19 @@ int __init harmony_panel_init(void)
gpio_direction_output(harmony_lvds_shutdown, 1);
tegra_gpio_enable(harmony_lvds_shutdown);
+ gpio_request(harmony_hdmi_hpd, "hdmi_hpd");
+ gpio_direction_input(harmony_hdmi_hpd);
+ tegra_gpio_enable(harmony_hdmi_hpd);
+
err = platform_add_devices(harmony_gfx_devices,
ARRAY_SIZE(harmony_gfx_devices));
if (!err)
err = nvhost_device_register(&harmony_disp1_device);
+ if (!err)
+ err = nvhost_device_register(&harmony_disp2_device);
+
return err;
}