aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/dsi.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2010-07-30 05:39:34 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-05-11 07:20:13 -0400
commit2a89dc15331983621b772240ebef9dea2cbe5322 (patch)
tree04e174e0dc817d8acbed70d1122617b50f3f309e /drivers/video/omap2/dss/dsi.c
parent40885ab31f754426c2e9a40362e568778baa5e82 (diff)
OMAP: DSS2: DSI: add option to leave DSI lanes powered on
The DSI pins are powered by VDDS_DSI. If VDDS_DSI is off, the DSI pins are floating even if they are pinmuxed to, say, safe mode and there's a pull down/up. This patch gives the panel drivers an option to leave the VDDS_DSI power enabled while the DSS itself is turned off. This can be used to keep the DSI lanes in a valid state while DSS is off, if the DSI pins are muxed for pull down (not done in this patch). There will be a slight power consumption increase (~100 uA?) when the VDDS_DSI is left on, but because this option is used when the panel is left on, the regulator consumption is negligible compared to panel power consumption. When the panel is fully turned off the VDDS_DSI is also turned off. As an added bonus this will give us faster start up time when starting up the DSS and the regulator is already enabled. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2/dss/dsi.c')
-rw-r--r--drivers/video/omap2/dss/dsi.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index e2ae1e7372f2..9befbceba10c 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -246,6 +246,7 @@ static struct
246 246
247 struct dsi_clock_info current_cinfo; 247 struct dsi_clock_info current_cinfo;
248 248
249 bool vdds_dsi_enabled;
249 struct regulator *vdds_dsi_reg; 250 struct regulator *vdds_dsi_reg;
250 251
251 struct { 252 struct {
@@ -1445,9 +1446,12 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1445 enable_clocks(1); 1446 enable_clocks(1);
1446 dsi_enable_pll_clock(1); 1447 dsi_enable_pll_clock(1);
1447 1448
1448 r = regulator_enable(dsi.vdds_dsi_reg); 1449 if (!dsi.vdds_dsi_enabled) {
1449 if (r) 1450 r = regulator_enable(dsi.vdds_dsi_reg);
1450 goto err0; 1451 if (r)
1452 goto err0;
1453 dsi.vdds_dsi_enabled = true;
1454 }
1451 1455
1452 /* XXX PLL does not come out of reset without this... */ 1456 /* XXX PLL does not come out of reset without this... */
1453 dispc_pck_free_enable(1); 1457 dispc_pck_free_enable(1);
@@ -1481,21 +1485,28 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk,
1481 1485
1482 return 0; 1486 return 0;
1483err1: 1487err1:
1484 regulator_disable(dsi.vdds_dsi_reg); 1488 if (dsi.vdds_dsi_enabled) {
1489 regulator_disable(dsi.vdds_dsi_reg);
1490 dsi.vdds_dsi_enabled = false;
1491 }
1485err0: 1492err0:
1486 enable_clocks(0); 1493 enable_clocks(0);
1487 dsi_enable_pll_clock(0); 1494 dsi_enable_pll_clock(0);
1488 return r; 1495 return r;
1489} 1496}
1490 1497
1491void dsi_pll_uninit(void) 1498void dsi_pll_uninit(bool disconnect_lanes)
1492{ 1499{
1493 enable_clocks(0); 1500 enable_clocks(0);
1494 dsi_enable_pll_clock(0); 1501 dsi_enable_pll_clock(0);
1495 1502
1496 dsi.pll_locked = 0; 1503 dsi.pll_locked = 0;
1497 dsi_pll_power(DSI_PLL_POWER_OFF); 1504 dsi_pll_power(DSI_PLL_POWER_OFF);
1498 regulator_disable(dsi.vdds_dsi_reg); 1505 if (disconnect_lanes) {
1506 WARN_ON(!dsi.vdds_dsi_enabled);
1507 regulator_disable(dsi.vdds_dsi_reg);
1508 dsi.vdds_dsi_enabled = false;
1509 }
1499 DSSDBG("PLL uninit done\n"); 1510 DSSDBG("PLL uninit done\n");
1500} 1511}
1501 1512
@@ -3642,12 +3653,13 @@ err2:
3642 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 3653 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
3643 dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK); 3654 dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
3644err1: 3655err1:
3645 dsi_pll_uninit(); 3656 dsi_pll_uninit(true);
3646err0: 3657err0:
3647 return r; 3658 return r;
3648} 3659}
3649 3660
3650static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) 3661static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
3662 bool disconnect_lanes)
3651{ 3663{
3652 if (!dsi.ulps_enabled) 3664 if (!dsi.ulps_enabled)
3653 dsi_enter_ulps(); 3665 dsi_enter_ulps();
@@ -3662,7 +3674,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev)
3662 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); 3674 dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
3663 dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK); 3675 dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK);
3664 dsi_complexio_uninit(); 3676 dsi_complexio_uninit();
3665 dsi_pll_uninit(); 3677 dsi_pll_uninit(disconnect_lanes);
3666} 3678}
3667 3679
3668static int dsi_core_init(void) 3680static int dsi_core_init(void)
@@ -3731,7 +3743,8 @@ err0:
3731} 3743}
3732EXPORT_SYMBOL(omapdss_dsi_display_enable); 3744EXPORT_SYMBOL(omapdss_dsi_display_enable);
3733 3745
3734void omapdss_dsi_display_disable(struct omap_dss_device *dssdev) 3746void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
3747 bool disconnect_lanes)
3735{ 3748{
3736 DSSDBG("dsi_display_disable\n"); 3749 DSSDBG("dsi_display_disable\n");
3737 3750
@@ -3741,7 +3754,7 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev)
3741 3754
3742 dsi_display_uninit_dispc(dssdev); 3755 dsi_display_uninit_dispc(dssdev);
3743 3756
3744 dsi_display_uninit_dsi(dssdev); 3757 dsi_display_uninit_dsi(dssdev, disconnect_lanes);
3745 3758
3746 enable_clocks(0); 3759 enable_clocks(0);
3747 dsi_enable_pll_clock(0); 3760 dsi_enable_pll_clock(0);