diff options
author | Adrian Alonso <aalonso@freescale.com> | 2012-02-16 18:35:49 -0600 |
---|---|---|
committer | Adrian Alonso <aalonso@freescale.com> | 2012-02-21 16:40:50 -0600 |
commit | fc60a6de546145b0520111db1fb78979d679be6e (patch) | |
tree | 2860b6ae999091ee6299cc85ce32354f936af150 | |
parent | 7f360988d8cfced7352702384c297ae88ae56246 (diff) |
ENGR00171079-7 mx6q clock anaclk input source clock
* Add mx6q anaclk_1/2 clock input source clock support
* anaclk can be bypassed to pll4_audio.
* _clk_audio_video_set_parent allows to bypass anaclk input
clock source, for sabreauto platform anaclk_2 is the clock
source for cs42888 and this clock needs to be bypassed to
esai to supply the same master clk signal.
Signed-off-by: Adrian Alonso <aalonso@freescale.com>
-rw-r--r-- | arch/arm/mach-mx6/clock.c | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 26ced126ac4d..a75011e5d23a 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -98,6 +98,7 @@ static int cpu_op_nr; /* External clock values passed-in by the board code */ static unsigned long external_high_reference, external_low_reference; static unsigned long oscillator_reference, ckih2_reference; +static unsigned long anaclk_1_reference, anaclk_2_reference; /* For MX 6DL/S, Video PLL may be used by synchronous display devices, * such as HDMI or LVDS, and also by the EPDC. If EPDC is in use, @@ -281,6 +282,28 @@ static unsigned long get_ckih2_reference_clock_rate(struct clk *clk) return ckih2_reference; } +static unsigned long _clk_anaclk_1_get_rate(struct clk *clk) +{ + return anaclk_1_reference; +} + +static int _clk_anaclk_1_set_rate(struct clk *clk, unsigned long rate) +{ + anaclk_1_reference = rate; + return 0; +} + +static unsigned long _clk_anaclk_2_get_rate(struct clk *clk) +{ + return anaclk_2_reference; +} + +static int _clk_anaclk_2_set_rate(struct clk *clk, unsigned long rate) +{ + anaclk_2_reference = rate; + return 0; +} + /* External high frequency clock */ static struct clk ckih_clk = { __INIT_CLK_DEBUG(ckih_clk) @@ -303,6 +326,18 @@ static struct clk ckil_clk = { .get_rate = get_low_reference_clock_rate, }; +static struct clk anaclk_1 = { + __INIT_CLK_DEBUG(anaclk_1) + .get_rate = _clk_anaclk_1_get_rate, + .set_rate = _clk_anaclk_1_set_rate, +}; + +static struct clk anaclk_2 = { + __INIT_CLK_DEBUG(anaclk_2) + .get_rate = _clk_anaclk_2_get_rate, + .set_rate = _clk_anaclk_2_set_rate, +}; + static unsigned long pfd_round_rate(struct clk *clk, unsigned long rate) { u32 frac; @@ -957,6 +992,38 @@ static unsigned long _clk_audio_video_round_rate(struct clk *clk, return final_rate; } +static int _clk_audio_video_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + int mux; + void __iomem *pllbase; + + if (clk == &pll4_audio_main_clk) + pllbase = PLL4_AUDIO_BASE_ADDR; + else + pllbase = PLL5_VIDEO_BASE_ADDR; + + reg = __raw_readl(pllbase) & ~ANADIG_PLL_BYPASS_CLK_SRC_MASK; + mux = _get_mux6(parent, &osc_clk, &anaclk_1, &anaclk_2, + NULL, NULL, NULL); + reg |= mux << ANADIG_PLL_BYPASS_CLK_SRC_OFFSET; + __raw_writel(reg, pllbase); + + /* Set anaclk_x as input */ + if (parent == &anaclk_1) { + reg = __raw_readl(ANADIG_MISC1_REG); + reg |= (ANATOP_LVDS_CLK1_IBEN_MASK & + ~ANATOP_LVDS_CLK1_OBEN_MASK); + __raw_writel(reg, ANADIG_MISC1_REG); + } else if (parent == &anaclk_2) { + reg = __raw_readl(ANADIG_MISC1_REG); + reg |= (ANATOP_LVDS_CLK2_IBEN_MASK & + ~ANATOP_LVDS_CLK2_OBEN_MASK); + __raw_writel(reg, ANADIG_MISC1_REG); + } + + return 0; +} static struct clk pll4_audio_main_clk = { __INIT_CLK_DEBUG(pll4_audio_main_clk) @@ -966,9 +1033,9 @@ static struct clk pll4_audio_main_clk = { .set_rate = _clk_audio_video_set_rate, .get_rate = _clk_audio_video_get_rate, .round_rate = _clk_audio_video_round_rate, + .set_parent = _clk_audio_video_set_parent, }; - static struct clk pll5_video_main_clk = { __INIT_CLK_DEBUG(pll5_video_main_clk) .parent = &osc_clk, @@ -977,6 +1044,7 @@ static struct clk pll5_video_main_clk = { .set_rate = _clk_audio_video_set_rate, .get_rate = _clk_audio_video_get_rate, .round_rate = _clk_audio_video_round_rate, + .set_parent = _clk_audio_video_set_parent, }; static int _clk_pll_mlb_main_enable(struct clk *clk) @@ -5136,6 +5204,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk), _REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk), _REGISTER_CLOCK(NULL, "mlb150_clk", mlb150_clk), + _REGISTER_CLOCK(NULL, "anaclk_1", anaclk_1), + _REGISTER_CLOCK(NULL, "anaclk_2", anaclk_2), }; static void clk_tree_init(void) |