diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 82918eec6d2e7ecdd51aa7b82bca10615b8d79fb..791e1cb7c0bcd4bf2fd20cc46fc78617b12cc268 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,10 @@ static struct { struct clk *dss_54m_fck; struct clk *dss_96m_fck; unsigned num_clks_enabled; + + struct regulator *vdds_dsi_reg; + struct regulator *vdds_sdi_reg; + struct regulator *vdda_dac_reg; } core; static void dss_clk_enable_all_no_ctx(void); @@ -352,6 +357,50 @@ static void dss_clk_disable_all(void) dss_clk_disable(clks); } +/* REGULATORS */ + +struct regulator *dss_get_vdds_dsi(void) +{ + struct regulator *reg; + + if (core.vdds_dsi_reg != NULL) + return core.vdds_dsi_reg; + + reg = regulator_get(&core.pdev->dev, "vdds_dsi"); + if (!IS_ERR(reg)) + core.vdds_dsi_reg = reg; + + return reg; +} + +struct regulator *dss_get_vdds_sdi(void) +{ + struct regulator *reg; + + if (core.vdds_sdi_reg != NULL) + return core.vdds_sdi_reg; + + reg = regulator_get(&core.pdev->dev, "vdds_sdi"); + if (!IS_ERR(reg)) + core.vdds_sdi_reg = reg; + + return reg; +} + +struct regulator *dss_get_vdda_dac(void) +{ + struct regulator *reg; + + if (core.vdda_dac_reg != NULL) + return core.vdda_dac_reg; + + reg = regulator_get(&core.pdev->dev, "vdda_dac"); + if (!IS_ERR(reg)) + core.vdda_dac_reg = reg; + + return reg; +} + /* DEBUGFS */ #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) static void dss_debug_dump_clocks(struct seq_file *s) @@ -473,7 +522,7 @@ static int omap_dss_probe(struct platform_device *pdev) } #endif - r = dpi_init(); + r = dpi_init(pdev); if (r) { DSSERR("Failed to initialize dpi\n"); goto fail0; @@ -901,6 +950,21 @@ static int __init omap_dss_init(void) static void __exit omap_dss_exit(void) { + if (core.vdds_dsi_reg != NULL) { + regulator_put(core.vdds_dsi_reg); + core.vdds_dsi_reg = NULL; + } + + if (core.vdds_sdi_reg != NULL) { + regulator_put(core.vdds_sdi_reg); + core.vdds_sdi_reg = NULL; + } + + if (core.vdda_dac_reg != NULL) { + regulator_put(core.vdda_dac_reg); + core.vdda_dac_reg = NULL; + } + platform_driver_unregister(&omap_dss_driver); omap_dss_bus_unregister(); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 2d71031baa2551d09b723f34781136ea80674467..69ce31ae2a2fe4d8037db48667eaf187f8ecd6ea 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -25,7 +25,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -34,6 +37,7 @@ static struct { int update_enabled; + struct regulator *vdds_dsi_reg; } dpi; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL @@ -166,21 +170,27 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) goto err1; } + if (cpu_is_omap34xx()) { + r = regulator_enable(dpi.vdds_dsi_reg); + if (r) + goto err2; + } + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); r = dpi_basic_init(dssdev); if (r) - goto err2; + goto err3; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dss_clk_enable(DSS_CLK_FCK2); r = dsi_pll_init(dssdev, 0, 1); if (r) - goto err3; + goto err4; #endif r = dpi_set_mode(dssdev); if (r) - goto err4; + goto err5; mdelay(2); @@ -188,22 +198,25 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) r = dssdev->driver->enable(dssdev); if (r) - goto err5; + goto err6; dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; return 0; -err5: +err6: dispc_enable_lcd_out(0); -err4: +err5: #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dsi_pll_uninit(); -err3: +err4: dss_clk_disable(DSS_CLK_FCK2); #endif -err2: +err3: dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +err2: + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); err1: omap_dss_stop_device(dssdev); err0: @@ -232,6 +245,9 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; omap_dss_stop_device(dssdev); @@ -251,6 +267,9 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; @@ -258,11 +277,19 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev) static int dpi_display_resume(struct omap_dss_device *dssdev) { + int r; + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) return -EINVAL; DSSDBG("dpi_display_resume\n"); + if (cpu_is_omap34xx()) { + r = regulator_enable(dpi.vdds_dsi_reg); + if (r) + goto err0; + } + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); dispc_enable_lcd_out(1); @@ -273,6 +300,8 @@ static int dpi_display_resume(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; return 0; +err0: + return r; } static void dpi_set_timings(struct omap_dss_device *dssdev, @@ -388,8 +417,16 @@ int dpi_init_display(struct omap_dss_device *dssdev) return 0; } -int dpi_init(void) +int dpi_init(struct platform_device *pdev) { + if (cpu_is_omap34xx()) { + dpi.vdds_dsi_reg = dss_get_vdds_dsi(); + if (IS_ERR(dpi.vdds_dsi_reg)) { + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(dpi.vdds_dsi_reg); + } + } + return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 6122178f5f8528af89b229b13bcefa4fb6b62e25..036f4221e3df001b4a224931df55d001d3d75d4f 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3799,7 +3799,7 @@ int dsi_init(struct platform_device *pdev) goto err1; } - dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); + dsi.vdds_dsi_reg = dss_get_vdds_dsi(); if (IS_ERR(dsi.vdds_dsi_reg)) { iounmap(dsi.base); DSSERR("can't get VDDS_DSI regulator\n"); @@ -3830,8 +3830,6 @@ void dsi_exit(void) { kthread_stop(dsi.thread); - regulator_put(dsi.vdds_dsi_reg); - iounmap(dsi.base); DSSDBG("omap_dsi_exit\n"); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 2bcb1245d6c2bc18c17b59047dd12d87223f8820..41145af36353cc642c6cce55824dce997d72f767 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -169,6 +169,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk); int dss_need_ctx_restore(void); void dss_dump_clocks(struct seq_file *s); struct bus_type *dss_get_bus(void); +struct regulator *dss_get_vdds_dsi(void); +struct regulator *dss_get_vdds_sdi(void); +struct regulator *dss_get_vdda_dac(void); /* display */ int dss_suspend_all_devices(void); @@ -261,7 +264,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high); /* DPI */ -int dpi_init(void); +int dpi_init(struct platform_device *pdev); void dpi_exit(void); int dpi_init_display(struct omap_dss_device *dssdev); diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 749a5a0f5be476fb49f3abb56505a0537e7a337b..44b4998c2052db6cc582d195c87cc50dabf968d2 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -482,7 +482,7 @@ int venc_init(struct platform_device *pdev) return -ENOMEM; } - venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac"); + venc.vdda_dac_reg = dss_get_vdda_dac(); if (IS_ERR(venc.vdda_dac_reg)) { iounmap(venc.base); DSSERR("can't get VDDA_DAC regulator\n"); @@ -503,8 +503,6 @@ void venc_exit(void) { omap_dss_unregister_driver(&venc_driver); - regulator_put(venc.vdda_dac_reg); - iounmap(venc.base); }