diff options
Diffstat (limited to 'drivers/video/omap2/dss/hdmi.c')
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 162 |
1 files changed, 40 insertions, 122 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 1bbf31329c7..b0555f4f0a7 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -29,9 +29,6 @@ #include <linux/mutex.h> #include <linux/delay.h> #include <linux/string.h> -#include <linux/platform_device.h> -#include <linux/pm_runtime.h> -#include <linux/clk.h> #include <video/omapdss.h> #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) @@ -54,9 +51,6 @@ static struct { u8 edid_set; bool custom_set; struct hdmi_config cfg; - - struct clk *sys_clk; - struct clk *hdmi_clk; } hdmi; /* @@ -168,27 +162,6 @@ static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx, return val; } -static int hdmi_runtime_get(void) -{ - int r; - - DSSDBG("hdmi_runtime_get\n"); - - r = pm_runtime_get_sync(&hdmi.pdev->dev); - WARN_ON(r < 0); - return r < 0 ? r : 0; -} - -static void hdmi_runtime_put(void) -{ - int r; - - DSSDBG("hdmi_runtime_put\n"); - - r = pm_runtime_put(&hdmi.pdev->dev); - WARN_ON(r < 0); -} - int hdmi_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); @@ -338,11 +311,30 @@ static int hdmi_phy_init(void) return 0; } +static int hdmi_wait_softreset(void) +{ + /* reset W1 */ + REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0); + + /* wait till SOFTRESET == 0 */ + if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) { + DSSERR("sysconfig reset failed\n"); + return -ETIMEDOUT; + } + + return 0; +} + static int hdmi_pll_program(struct hdmi_pll_info *fmt) { u16 r = 0; enum hdmi_clk_refsel refsel; + /* wait for wrapper reset */ + r = hdmi_wait_softreset(); + if (r) + return r; + r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); if (r) return r; @@ -1072,7 +1064,7 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, unsigned long clkin, refclk; u32 mf; - clkin = clk_get_rate(hdmi.sys_clk) / 10000; + clkin = dss_clk_get_rate(DSS_CLK_SYSCK) / 10000; /* * Input clock is predivided by N + 1 * out put of which is reference clk @@ -1106,6 +1098,16 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); } +static void hdmi_enable_clocks(int enable) +{ + if (enable) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | + DSS_CLK_SYSCK | DSS_CLK_VIDFCK); + else + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | + DSS_CLK_SYSCK | DSS_CLK_VIDFCK); +} + static int hdmi_power_on(struct omap_dss_device *dssdev) { int r, code = 0; @@ -1113,9 +1115,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) struct omap_video_timings *p; unsigned long phy; - r = hdmi_runtime_get(); - if (r) - return r; + hdmi_enable_clocks(1); dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); @@ -1180,7 +1180,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) return 0; err: - hdmi_runtime_put(); + hdmi_enable_clocks(0); return -EIO; } @@ -1191,7 +1191,7 @@ static void hdmi_power_off(struct omap_dss_device *dssdev) hdmi_wp_video_start(0); hdmi_phy_off(); hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); - hdmi_runtime_put(); + hdmi_enable_clocks(0); hdmi.edid_set = 0; } @@ -1686,43 +1686,14 @@ static struct snd_soc_dai_driver hdmi_codec_dai_drv = { }; #endif -static int hdmi_get_clocks(struct platform_device *pdev) -{ - struct clk *clk; - - clk = clk_get(&pdev->dev, "sys_clk"); - if (IS_ERR(clk)) { - DSSERR("can't get sys_clk\n"); - return PTR_ERR(clk); - } - - hdmi.sys_clk = clk; - - clk = clk_get(&pdev->dev, "hdmi_clk"); - if (IS_ERR(clk)) { - DSSERR("can't get hdmi_clk\n"); - clk_put(hdmi.sys_clk); - return PTR_ERR(clk); - } - - hdmi.hdmi_clk = clk; - - return 0; -} - -static void hdmi_put_clocks(void) -{ - if (hdmi.sys_clk) - clk_put(hdmi.sys_clk); - if (hdmi.hdmi_clk) - clk_put(hdmi.hdmi_clk); -} - /* HDMI HW IP initialisation */ static int omapdss_hdmihw_probe(struct platform_device *pdev) { struct resource *hdmi_mem; - int r; +#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ + defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) + int ret; +#endif hdmi.pdata = pdev->dev.platform_data; hdmi.pdev = pdev; @@ -1742,25 +1713,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) return -ENOMEM; } - r = hdmi_get_clocks(pdev); - if (r) { - iounmap(hdmi.base_wp); - return r; - } - - pm_runtime_enable(&pdev->dev); - hdmi_panel_init(); #if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) /* Register ASoC codec DAI */ - r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, + ret = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, &hdmi_codec_dai_drv, 1); - if (r) { + if (ret) { DSSERR("can't register ASoC HDMI audio codec\n"); - return r; + return ret; } #endif return 0; @@ -1775,62 +1738,17 @@ static int omapdss_hdmihw_remove(struct platform_device *pdev) snd_soc_unregister_codec(&pdev->dev); #endif - pm_runtime_disable(&pdev->dev); - - hdmi_put_clocks(); - iounmap(hdmi.base_wp); return 0; } -static int hdmi_runtime_suspend(struct device *dev) -{ - clk_disable(hdmi.hdmi_clk); - clk_disable(hdmi.sys_clk); - - dispc_runtime_put(); - dss_runtime_put(); - - return 0; -} - -static int hdmi_runtime_resume(struct device *dev) -{ - int r; - - r = dss_runtime_get(); - if (r < 0) - goto err_get_dss; - - r = dispc_runtime_get(); - if (r < 0) - goto err_get_dispc; - - - clk_enable(hdmi.sys_clk); - clk_enable(hdmi.hdmi_clk); - - return 0; - -err_get_dispc: - dss_runtime_put(); -err_get_dss: - return r; -} - -static const struct dev_pm_ops hdmi_pm_ops = { - .runtime_suspend = hdmi_runtime_suspend, - .runtime_resume = hdmi_runtime_resume, -}; - static struct platform_driver omapdss_hdmihw_driver = { .probe = omapdss_hdmihw_probe, .remove = omapdss_hdmihw_remove, .driver = { .name = "omapdss_hdmi", .owner = THIS_MODULE, - .pm = &hdmi_pm_ops, }, }; |