static int hdmi_power_on_full(struct omap_dss_device *dssdev) { int r; struct omap_video_timings *p; struct omap_overlay_manager *mgr = hdmi.output.manager; struct dss_pll_clock_info hdmi_cinfo = { 0 }; r = hdmi_power_on_core(dssdev); if (r) return r; p = &hdmi.cfg.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo); /* disable and clear irqs */ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); hdmi_wp_set_irqstatus(&hdmi.wp, hdmi_wp_get_irqstatus(&hdmi.wp)); r = dss_pll_enable(&hdmi.pll.pll); if (r) { DSSERR("Failed to enable PLL\n"); goto err_pll_enable; } r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); if (r) { DSSERR("Failed to configure PLL\n"); goto err_pll_cfg; } r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, hdmi_cinfo.clkout[0]); if (r) { DSSDBG("Failed to start PHY\n"); goto err_phy_cfg; } r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); if (r) goto err_phy_pwr; hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dss_mgr_set_timings(mgr, p); r = hdmi_wp_video_start(&hdmi.wp); if (r) goto err_vid_enable; r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; hdmi_wp_set_irqenable(&hdmi.wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); return 0; err_mgr_enable: hdmi_wp_video_stop(&hdmi.wp); err_vid_enable: hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); err_phy_pwr: err_phy_cfg: err_pll_cfg: dss_pll_disable(&hdmi.pll.pll); err_pll_enable: hdmi_power_off_core(dssdev); return -EIO; }
static int hdmi_power_on_full(struct omap_dss_device *dssdev) { int r; struct omap_video_timings *p; struct omap_overlay_manager *mgr = hdmi.output.manager; struct dss_pll_clock_info hdmi_cinfo = { 0 }; r = hdmi_power_on_core(dssdev); if (r) return r; p = &hdmi.cfg.timings; DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo); /* disable and clear irqs */ hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); hdmi_wp_set_irqstatus(&hdmi.wp, hdmi_wp_get_irqstatus(&hdmi.wp)); r = dss_pll_enable(&hdmi.pll.pll); if (r) { DSSERR("Failed to enable PLL\n"); goto err_pll_enable; } r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); if (r) { DSSERR("Failed to configure PLL\n"); goto err_pll_cfg; } r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, hdmi_cinfo.clkout[0]); if (r) { DSSDBG("Failed to start PHY\n"); goto err_phy_cfg; } r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); if (r) goto err_phy_pwr; hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); /* bypass TV gamma table */ dispc_enable_gamma_table(0); /* tv size */ dss_mgr_set_timings(mgr, p); r = hdmi_wp_video_start(&hdmi.wp); if (r) goto err_vid_enable; /* * XXX Seems that on we easily get a flood of sync-lost errors when * enabling the output. This seems to be related to the time between * HDMI VSYNC and enabling the DISPC output. * * Testing shows that the sync-lost errors do not happen if we enable * the DISPC output very soon after HDMI VBLANK. So wait here for * VBLANK to reduce the chances of sync-losts. */ hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC); while (true) { u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW); if (v & HDMI_IRQ_VIDEO_VSYNC) break; usleep_range(500, 1000); } r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; hdmi_wp_set_irqenable(&hdmi.wp, HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); return 0; err_mgr_enable: hdmi_wp_video_stop(&hdmi.wp); err_vid_enable: hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); err_phy_pwr: err_phy_cfg: err_pll_cfg: dss_pll_disable(&hdmi.pll.pll); err_pll_enable: hdmi_power_off_core(dssdev); return -EIO; }