|
@@ -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);
|