summaryrefslogtreecommitdiffstats
path: root/qemu/roms/u-boot/arch/blackfin/lib/clocks.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/u-boot/arch/blackfin/lib/clocks.c')
-rw-r--r--qemu/roms/u-boot/arch/blackfin/lib/clocks.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/arch/blackfin/lib/clocks.c b/qemu/roms/u-boot/arch/blackfin/lib/clocks.c
new file mode 100644
index 000000000..7ed56a727
--- /dev/null
+++ b/qemu/roms/u-boot/arch/blackfin/lib/clocks.c
@@ -0,0 +1,140 @@
+/*
+ * clocks.c - figure out sclk/cclk/vco and such
+ *
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <asm/clock.h>
+
+/* Get the voltage input multiplier */
+u_long get_vco(void)
+{
+ static u_long cached_vco_pll_ctl, cached_vco;
+
+ u_long msel, pll_ctl;
+
+ pll_ctl = bfin_read_PLL_CTL();
+ if (pll_ctl == cached_vco_pll_ctl)
+ return cached_vco;
+ else
+ cached_vco_pll_ctl = pll_ctl;
+
+ msel = (pll_ctl & MSEL) >> MSEL_P;
+ if (0 == msel)
+ msel = (MSEL >> MSEL_P) + 1;
+
+ cached_vco = CONFIG_CLKIN_HZ;
+ cached_vco >>= (pll_ctl & DF);
+ cached_vco *= msel;
+ return cached_vco;
+}
+
+/* Get the Core clock */
+u_long get_cclk(void)
+{
+ static u_long cached_cclk_pll_div, cached_cclk;
+ u_long div, csel;
+#ifndef CGU_DIV
+ u_long ssel;
+#endif
+
+ if (pll_is_bypassed())
+ return CONFIG_CLKIN_HZ;
+
+ div = bfin_read_PLL_DIV();
+ if (div == cached_cclk_pll_div)
+ return cached_cclk;
+ else
+ cached_cclk_pll_div = div;
+
+ csel = (div & CSEL) >> CSEL_P;
+#ifndef CGU_DIV
+ ssel = (div & SSEL) >> SSEL_P;
+ if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
+ cached_cclk = get_vco() / ssel;
+ else
+ cached_cclk = get_vco() >> csel;
+#else
+ cached_cclk = get_vco() / csel;
+#endif
+ return cached_cclk;
+}
+
+/* Get the System clock */
+#ifdef CGU_DIV
+
+static u_long cached_sclk_pll_div, cached_sclk;
+static u_long cached_sclk0, cached_sclk1, cached_dclk;
+static u_long _get_sclk(u_long *cache)
+{
+ u_long div, ssel;
+
+ if (pll_is_bypassed())
+ return CONFIG_CLKIN_HZ;
+
+ div = bfin_read_PLL_DIV();
+ if (div == cached_sclk_pll_div)
+ return *cache;
+ else
+ cached_sclk_pll_div = div;
+
+ ssel = (div & SYSSEL) >> SYSSEL_P;
+ cached_sclk = get_vco() / ssel;
+
+ ssel = (div & S0SEL) >> S0SEL_P;
+ cached_sclk0 = cached_sclk / ssel;
+
+ ssel = (div & S1SEL) >> S1SEL_P;
+ cached_sclk1 = cached_sclk / ssel;
+
+ ssel = (div & DSEL) >> DSEL_P;
+ cached_dclk = get_vco() / ssel;
+
+ return *cache;
+}
+
+u_long get_sclk(void)
+{
+ return _get_sclk(&cached_sclk);
+}
+
+u_long get_sclk0(void)
+{
+ return _get_sclk(&cached_sclk0);
+}
+
+u_long get_sclk1(void)
+{
+ return _get_sclk(&cached_sclk1);
+}
+
+u_long get_dclk(void)
+{
+ return _get_sclk(&cached_dclk);
+}
+#else
+
+u_long get_sclk(void)
+{
+ static u_long cached_sclk_pll_div, cached_sclk;
+ u_long div, ssel;
+
+ if (pll_is_bypassed())
+ return CONFIG_CLKIN_HZ;
+
+ div = bfin_read_PLL_DIV();
+ if (div == cached_sclk_pll_div)
+ return cached_sclk;
+ else
+ cached_sclk_pll_div = div;
+
+ ssel = (div & SSEL) >> SSEL_P;
+ cached_sclk = get_vco() / ssel;
+
+ return cached_sclk;
+}
+
+#endif