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;
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);
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 */
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);
{
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);
static int omapdss_hdmihw_probe(struct platform_device *pdev)
{
int r;
+ int irq;
hdmi.pdev = 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);
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;
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
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
return -ENOMEM;
}
- phy->irq = platform_get_irq(pdev, 0);
- if (phy->irq < 0) {
- DSSERR("platform_get_irq failed\n");
- return -ENODEV;
- }
-
return 0;
}