summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c18
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c18
-rw-r--r--arch/arm/mach-omap2/display.c4
-rw-r--r--drivers/video/atmel_lcdfb.c2
-rw-r--r--drivers/video/fsl-diu-fb.c4
-rw-r--r--drivers/video/intelfb/intelfbdrv.c1
-rw-r--r--drivers/video/omap2/dss/dispc.c2
-rw-r--r--drivers/video/omap2/dss/dsi.c2
-rw-r--r--drivers/video/omap2/dss/dss.c2
-rw-r--r--drivers/video/omap2/dss/hdmi.c5
-rw-r--r--drivers/video/omap2/dss/rfbi.c2
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h4
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c68
-rw-r--r--drivers/video/omap2/dss/venc.c2
-rw-r--r--include/video/omapdss.h5
15 files changed, 113 insertions, 26 deletions
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 39fba9d..21fc876 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -52,8 +52,9 @@
#define ETH_KS8851_QUART 138
#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184
#define OMAP4_SFH7741_ENABLE_GPIO 188
-#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
#define DISPLAY_SEL_GPIO 59 /* LCD2/PicoDLP switch */
#define DLP_POWER_ON_GPIO 40
@@ -603,8 +604,9 @@ static void __init omap_sfh7741prox_init(void)
}
static struct gpio sdp4430_hdmi_gpios[] = {
- { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
};
static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
@@ -621,8 +623,7 @@ static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
{
- gpio_free(HDMI_GPIO_LS_OE);
- gpio_free(HDMI_GPIO_HPD);
+ gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
}
static struct nokia_dsi_panel_data dsi1_panel = {
@@ -738,6 +739,10 @@ static void sdp4430_lcd_init(void)
pr_err("%s: Could not get lcd2_reset_gpio\n", __func__);
}
+static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
static struct omap_dss_device sdp4430_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
@@ -745,6 +750,7 @@ static struct omap_dss_device sdp4430_hdmi_device = {
.platform_enable = sdp4430_panel_enable_hdmi,
.platform_disable = sdp4430_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &sdp4430_hdmi_data,
};
static struct picodlp_panel_data sdp4430_picodlp_pdata = {
@@ -829,6 +835,10 @@ static void omap_4430sdp_display_init(void)
omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
else
omap_hdmi_init(0);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
}
#ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 30ad40d..b7779c20 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -51,8 +51,9 @@
#define GPIO_HUB_NRESET 62
#define GPIO_WIFI_PMENA 43
#define GPIO_WIFI_IRQ 53
-#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_CT_CP_HPD 60 /* HPD mode enable/disable */
#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
+#define HDMI_GPIO_HPD 63 /* Hotplug detect */
/* wl127x BT, FM, GPS connectivity chip */
static int wl1271_gpios[] = {46, -1, -1};
@@ -413,8 +414,9 @@ int __init omap4_panda_dvi_init(void)
}
static struct gpio panda_hdmi_gpios[] = {
- { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
+ { HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+ { HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
};
static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
@@ -431,10 +433,13 @@ static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
{
- gpio_free(HDMI_GPIO_LS_OE);
- gpio_free(HDMI_GPIO_HPD);
+ gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
}
+static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+ .hpd_gpio = HDMI_GPIO_HPD,
+};
+
static struct omap_dss_device omap4_panda_hdmi_device = {
.name = "hdmi",
.driver_name = "hdmi_panel",
@@ -442,6 +447,7 @@ static struct omap_dss_device omap4_panda_hdmi_device = {
.platform_enable = omap4_panda_panel_enable_hdmi,
.platform_disable = omap4_panda_panel_disable_hdmi,
.channel = OMAP_DSS_CHANNEL_DIGIT,
+ .data = &omap4_panda_hdmi_data,
};
static struct omap_dss_device *omap4_panda_dss_devices[] = {
@@ -473,6 +479,10 @@ void omap4_panda_display_init(void)
omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
else
omap_hdmi_init(0);
+
+ omap_mux_init_gpio(HDMI_GPIO_LS_OE, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_CT_CP_HPD, OMAP_PIN_OUTPUT);
+ omap_mux_init_gpio(HDMI_GPIO_HPD, OMAP_PIN_INPUT_PULLDOWN);
}
static void __init omap4_panda_init(void)
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 3c446d1..3677b1f 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -103,12 +103,8 @@ static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
u32 reg;
u16 control_i2c_1;
- /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
- omap_mux_init_signal("hdmi_hpd",
- OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("hdmi_cec",
OMAP_PIN_INPUT_PULLUP);
- /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
omap_mux_init_signal("hdmi_ddc_scl",
OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("hdmi_ddc_sda",
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 0d7b20d..e40c00f 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -1108,7 +1108,7 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
*/
lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
- sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
+ sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR);
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
if (sinfo->atmel_lcdfb_power_control)
sinfo->atmel_lcdfb_power_control(0);
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index acf292b..6af3f16 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1432,7 +1432,7 @@ static int fsl_diu_suspend(struct platform_device *ofdev, pm_message_t state)
struct fsl_diu_data *data;
data = dev_get_drvdata(&ofdev->dev);
- disable_lcdc(data->fsl_diu_info[0]);
+ disable_lcdc(data->fsl_diu_info);
return 0;
}
@@ -1442,7 +1442,7 @@ static int fsl_diu_resume(struct platform_device *ofdev)
struct fsl_diu_data *data;
data = dev_get_drvdata(&ofdev->dev);
- enable_lcdc(data->fsl_diu_info[0]);
+ enable_lcdc(data->fsl_diu_info);
return 0;
}
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index c6afa33..02fd226 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -529,7 +529,6 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
ERR_MSG("Could not allocate cmap for intelfb_info.\n");
goto err_out_cmap;
- return -ENODEV;
}
dinfo = info->par;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a5ec7f3..e1626a1 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -401,7 +401,7 @@ void dispc_runtime_put(void)
DSSDBG("dispc_runtime_put\n");
- r = pm_runtime_put(&dispc.pdev->dev);
+ r = pm_runtime_put_sync(&dispc.pdev->dev);
WARN_ON(r < 0);
}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d4d676c..52f36ec 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1079,7 +1079,7 @@ void dsi_runtime_put(struct platform_device *dsidev)
DSSDBG("dsi_runtime_put\n");
- r = pm_runtime_put(&dsi->pdev->dev);
+ r = pm_runtime_put_sync(&dsi->pdev->dev);
WARN_ON(r < 0);
}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 1703345..77c2b5a 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -720,7 +720,7 @@ void dss_runtime_put(void)
DSSDBG("dss_runtime_put\n");
- r = pm_runtime_put(&dss.pdev->dev);
+ r = pm_runtime_put_sync(&dss.pdev->dev);
WARN_ON(r < 0);
}
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index b4c270e..d7aa3b0 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -176,7 +176,7 @@ static void hdmi_runtime_put(void)
DSSDBG("hdmi_runtime_put\n");
- r = pm_runtime_put(&hdmi.pdev->dev);
+ r = pm_runtime_put_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
}
@@ -497,6 +497,7 @@ bool omapdss_hdmi_detect(void)
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
{
+ struct omap_dss_hdmi_data *priv = dssdev->data;
int r = 0;
DSSDBG("ENTER hdmi_display_enable\n");
@@ -509,6 +510,8 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
+ hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
+
r = omap_dss_start_device(dssdev);
if (r) {
DSSERR("failed to start device\n");
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 814bb95..55f3980 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -140,7 +140,7 @@ static void rfbi_runtime_put(void)
DSSDBG("rfbi_runtime_put\n");
- r = pm_runtime_put(&rfbi.pdev->dev);
+ r = pm_runtime_put_sync(&rfbi.pdev->dev);
WARN_ON(r < 0);
}
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index 7503f7f..50dadba 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -126,6 +126,10 @@ struct hdmi_ip_data {
const struct ti_hdmi_ip_ops *ops;
struct hdmi_config cfg;
struct hdmi_pll_info pll_data;
+
+ /* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
+ int hpd_gpio;
+ bool phy_tx_enabled;
};
int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 9af81f1..2d72334 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/seq_file.h>
+#include <linux/gpio.h>
#include "ti_hdmi_4xxx_ip.h"
#include "dss.h"
@@ -223,6 +224,49 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
}
+static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
+{
+ unsigned long flags;
+ bool hpd;
+ int r;
+ /* this should be in ti_hdmi_4xxx_ip private data */
+ static DEFINE_SPINLOCK(phy_tx_lock);
+
+ spin_lock_irqsave(&phy_tx_lock, flags);
+
+ hpd = gpio_get_value(ip_data->hpd_gpio);
+
+ if (hpd == ip_data->phy_tx_enabled) {
+ spin_unlock_irqrestore(&phy_tx_lock, flags);
+ return 0;
+ }
+
+ if (hpd)
+ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
+ else
+ r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
+
+ if (r) {
+ DSSERR("Failed to %s PHY TX power\n",
+ hpd ? "enable" : "disable");
+ goto err;
+ }
+
+ ip_data->phy_tx_enabled = hpd;
+err:
+ spin_unlock_irqrestore(&phy_tx_lock, flags);
+ return r;
+}
+
+static irqreturn_t hpd_irq_handler(int irq, void *data)
+{
+ struct hdmi_ip_data *ip_data = data;
+
+ hdmi_check_hpd_state(ip_data);
+
+ return IRQ_HANDLED;
+}
+
int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
{
u16 r = 0;
@@ -232,10 +276,6 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
if (r)
return r;
- r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
- if (r)
- return r;
-
/*
* Read address 0 in order to get the SCP reset done completed
* Dummy access performed to make sure reset is done
@@ -257,12 +297,32 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
/* Write to phy address 3 to change the polarity control */
REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
+ r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio),
+ NULL, hpd_irq_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING, "hpd", ip_data);
+ if (r) {
+ DSSERR("HPD IRQ request failed\n");
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
+ return r;
+ }
+
+ r = hdmi_check_hpd_state(ip_data);
+ if (r) {
+ free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
+ return r;
+ }
+
return 0;
}
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
{
+ free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
+
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
+ ip_data->phy_tx_enabled = false;
}
static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index b3e9f90..5c3d0f9 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -401,7 +401,7 @@ static void venc_runtime_put(void)
DSSDBG("venc_runtime_put\n");
- r = pm_runtime_put(&venc.pdev->dev);
+ r = pm_runtime_put_sync(&venc.pdev->dev);
WARN_ON(r < 0);
}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 062b3b2..483f67c 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -590,6 +590,11 @@ struct omap_dss_device {
int (*get_backlight)(struct omap_dss_device *dssdev);
};
+struct omap_dss_hdmi_data
+{
+ int hpd_gpio;
+};
+
struct omap_dss_driver {
struct device_driver driver;
OpenPOWER on IntegriCloud