From 24c1ae4191e911caa08b31079d61ff4db319a101 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 13 Apr 2011 17:12:52 +0300 Subject: [PATCH] OMAP: DSS2: DSI: implement enable/disable SCP clk SCP clock is needed for CIO on OMAP3, and for CIO and PLL on OMAP4. Current driver enables the CIO clock always when DSI display is initialized. However, if a DPI display tries to use DSI PLL, the SCP clock is never enabled. This patch implements simple ref counting enable/disable functions for SCP clock. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 186a228f9f24..1198974c8892 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -305,6 +305,8 @@ static struct unsigned long regm_dispc_max, regm_dsi_max; unsigned long fint_min, fint_max; unsigned long lpdiv_max; + + unsigned scp_clk_refcount; } dsi; #ifdef DEBUG @@ -1073,6 +1075,18 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) return 0; } +static void dsi_enable_scp_clk(void) +{ + if (dsi.scp_clk_refcount++ == 0) + REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */ +} + +static void dsi_disable_scp_clk(void) +{ + WARN_ON(dsi.scp_clk_refcount == 0); + if (--dsi.scp_clk_refcount == 0) + REG_FLD_MOD(DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */ +} enum dsi_pll_power_state { DSI_PLL_POWER_OFF = 0x0, @@ -1458,6 +1472,10 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, enable_clocks(1); dsi_enable_pll_clock(1); + /* + * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. + */ + dsi_enable_scp_clk(); if (!dsi.vdds_dsi_enabled) { r = regulator_enable(dsi.vdds_dsi_reg); @@ -1503,6 +1521,7 @@ err1: dsi.vdds_dsi_enabled = false; } err0: + dsi_disable_scp_clk(); enable_clocks(0); dsi_enable_pll_clock(0); return r; @@ -1510,9 +1529,6 @@ err0: void dsi_pll_uninit(bool disconnect_lanes) { - enable_clocks(0); - dsi_enable_pll_clock(0); - dsi.pll_locked = 0; dsi_pll_power(DSI_PLL_POWER_OFF); if (disconnect_lanes) { @@ -1520,6 +1536,11 @@ void dsi_pll_uninit(bool disconnect_lanes) regulator_disable(dsi.vdds_dsi_reg); dsi.vdds_dsi_enabled = false; } + + dsi_disable_scp_clk(); + enable_clocks(0); + dsi_enable_pll_clock(0); + DSSDBG("PLL uninit done\n"); } @@ -3611,8 +3632,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) int r; /* The SCPClk is required for both PLL and CIO registers on OMAP4 */ - /* CIO_CLK_ICG, enable L3 clk to CIO */ - REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); + dsi_enable_scp_clk(); _dsi_print_reset_status(); @@ -3668,6 +3688,7 @@ err2: err1: dsi_pll_uninit(true); err0: + dsi_disable_scp_clk(); return r; } @@ -3688,6 +3709,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, dss_select_dsi_clk_source(OMAP_DSS_CLK_SRC_FCK); dsi_cio_uninit(); dsi_pll_uninit(disconnect_lanes); + dsi_disable_scp_clk(); } static int dsi_core_init(void) @@ -4013,6 +4035,7 @@ err_dsi: static int omap_dsi1hw_remove(struct platform_device *pdev) { dsi_exit(); + WARN_ON(dsi.scp_clk_refcount > 0); return 0; } -- 2.34.1