summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi.h6
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c75
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_phy.c70
3 files changed, 71 insertions, 80 deletions
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 4e5c44e7eeb3..d784b2cced9d 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -351,8 +351,6 @@ struct hdmi_pll_data {
struct hdmi_phy_data {
void __iomem *base;
- int irq;
-
u8 lane_function[4];
u8 lane_polarity[4];
};
@@ -420,9 +418,7 @@ void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy);
int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll);
/* HDMI PHY funcs */
-int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp,
- struct hdmi_config *cfg);
-void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp);
+int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg);
void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 5c7dd5c06593..626aad2bef46 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -81,6 +81,37 @@ static void hdmi_runtime_put(void)
WARN_ON(r < 0 && r != -ENOSYS);
}
+static irqreturn_t hdmi_irq_handler(int irq, void *data)
+{
+ struct hdmi_wp_data *wp = data;
+ u32 irqstatus;
+
+ irqstatus = hdmi_wp_get_irqstatus(wp);
+ hdmi_wp_set_irqstatus(wp, irqstatus);
+
+ if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
+ irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
+ /*
+ * If we get both connect and disconnect interrupts at the same
+ * time, turn off the PHY, clear interrupts, and restart, which
+ * raises connect interrupt if a cable is connected, or nothing
+ * if cable is not connected.
+ */
+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
+
+ hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
+ HDMI_IRQ_LINK_DISCONNECT);
+
+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
+ } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
+ } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
+ hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
+ }
+
+ return IRQ_HANDLED;
+}
+
static int hdmi_init_regulator(void)
{
int r;
@@ -150,11 +181,16 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
struct omap_video_timings *p;
struct omap_overlay_manager *mgr = hdmi.output.manager;
unsigned long phy;
+ struct hdmi_wp_data *wp = &hdmi.wp;
r = hdmi_power_on_core(dssdev);
if (r)
return r;
+ /* disable and clear irqs */
+ hdmi_wp_clear_irqenable(wp, 0xffffffff);
+ hdmi_wp_set_irqstatus(wp, 0xffffffff);
+
p = &hdmi.cfg.timings;
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
@@ -171,12 +207,16 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
goto err_pll_enable;
}
- r = hdmi_phy_enable(&hdmi.phy, &hdmi.wp, &hdmi.cfg);
+ r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
if (r) {
- DSSDBG("Failed to start PHY\n");
- goto err_phy_enable;
+ DSSDBG("Failed to configure PHY\n");
+ goto err_phy_cfg;
}
+ r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
+ if (r)
+ goto err_phy_pwr;
+
hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
/* bypass TV gamma table */
@@ -193,13 +233,17 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
if (r)
goto err_mgr_enable;
+ hdmi_wp_set_irqenable(wp,
+ HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
+
return 0;
err_mgr_enable:
hdmi_wp_video_stop(&hdmi.wp);
err_vid_enable:
- hdmi_phy_disable(&hdmi.phy, &hdmi.wp);
-err_phy_enable:
+err_phy_cfg:
+ hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
+err_phy_pwr:
hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
err_pll_enable:
hdmi_power_off_core(dssdev);
@@ -210,10 +254,14 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
{
struct omap_overlay_manager *mgr = hdmi.output.manager;
+ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
+
dss_mgr_disable(mgr);
hdmi_wp_video_stop(&hdmi.wp);
- hdmi_phy_disable(&hdmi.phy, &hdmi.wp);
+
+ hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
+
hdmi_pll_disable(&hdmi.pll, &hdmi.wp);
hdmi_power_off_core(dssdev);
@@ -636,6 +684,7 @@ err:
static int omapdss_hdmihw_probe(struct platform_device *pdev)
{
int r;
+ int irq;
hdmi.pdev = pdev;
@@ -669,6 +718,20 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
return r;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ DSSERR("platform_get_irq failed\n");
+ return -ENODEV;
+ }
+
+ r = devm_request_threaded_irq(&pdev->dev, irq,
+ NULL, hdmi_irq_handler,
+ IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
+ if (r) {
+ DSSERR("HDMI IRQ request failed\n");
+ return r;
+ }
+
pm_runtime_enable(&pdev->dev);
hdmi_init_output(pdev);
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
index c1c65624fd5d..8d13e422de5e 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_phy.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
@@ -28,37 +28,6 @@ void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s)
DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL);
}
-static irqreturn_t hdmi_irq_handler(int irq, void *data)
-{
- struct hdmi_wp_data *wp = data;
- u32 irqstatus;
-
- irqstatus = hdmi_wp_get_irqstatus(wp);
- hdmi_wp_set_irqstatus(wp, irqstatus);
-
- if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
- irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
- /*
- * If we get both connect and disconnect interrupts at the same
- * time, turn off the PHY, clear interrupts, and restart, which
- * raises connect interrupt if a cable is connected, or nothing
- * if cable is not connected.
- */
- hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
-
- hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
- HDMI_IRQ_LINK_DISCONNECT);
-
- hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
- } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
- hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
- } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
- hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
- }
-
- return IRQ_HANDLED;
-}
-
int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes)
{
int i;
@@ -150,21 +119,8 @@ static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy)
REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, pol_val, 30, 27);
}
-int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp,
- struct hdmi_config *cfg)
+int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
{
- u16 r = 0;
- u32 irqstatus;
-
- hdmi_wp_clear_irqenable(wp, 0xffffffff);
-
- irqstatus = hdmi_wp_get_irqstatus(wp);
- hdmi_wp_set_irqstatus(wp, irqstatus);
-
- r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
- 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
@@ -185,27 +141,9 @@ int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp,
hdmi_phy_configure_lanes(phy);
- r = request_threaded_irq(phy->irq, NULL, hdmi_irq_handler,
- IRQF_ONESHOT, "OMAP HDMI", wp);
- if (r) {
- DSSERR("HDMI IRQ request failed\n");
- hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
- return r;
- }
-
- hdmi_wp_set_irqenable(wp,
- HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
-
return 0;
}
-void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp)
-{
- free_irq(phy->irq, wp);
-
- hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
-}
-
#define PHY_OFFSET 0x300
#define PHY_SIZE 0x100
@@ -240,11 +178,5 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
return -ENOMEM;
}
- phy->irq = platform_get_irq(pdev, 0);
- if (phy->irq < 0) {
- DSSERR("platform_get_irq failed\n");
- return -ENODEV;
- }
-
return 0;
}