summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
authorHeiko Schocher <hs@denx.de>2016-06-07 08:31:19 +0200
committerTom Rini <trini@konsulko.com>2016-06-09 13:53:07 -0400
commit694607b563df4425b2d50d220048cc3299a6e947 (patch)
tree1446df3e71e90284728b42115fd53304c0b539ec /arch/arm/cpu/armv7
parentc01bc75e7d2c8b31fc130762ee596b53f88729e7 (diff)
arm, am335x: Enable Spread Spectrum for the MPU
Enable Spread Spectrum for the MPU by calculating the required values and setting the registers accordingly. Signed-off-by: Heiko Schocher <hs@denx.de> Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/am33xx/clock_am33xx.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
index 92142c8934..7b841b2d55 100644
--- a/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
+++ b/arch/arm/cpu/armv7/am33xx/clock_am33xx.c
@@ -159,3 +159,76 @@ void enable_basic_clocks(void)
/* Select the Master osc 24 MHZ as Timer2 clock source */
writel(0x1, &cmdpll->clktimer2clk);
}
+
+/*
+ * Enable Spread Spectrum for the MPU by calculating the required
+ * values and setting the registers accordingly.
+ * @param permille The spreading in permille (10th of a percent)
+ */
+void set_mpu_spreadspectrum(int permille)
+{
+ u32 multiplier_m;
+ u32 predivider_n;
+ u32 cm_clksel_dpll_mpu;
+ u32 cm_clkmode_dpll_mpu;
+ u32 ref_clock;
+ u32 pll_bandwidth;
+ u32 mod_freq_divider;
+ u32 exponent;
+ u32 mantissa;
+ u32 delta_m_step;
+
+ printf("Enabling Spread Spectrum of %d permille for MPU\n",
+ permille);
+
+ /* Read PLL parameter m and n */
+ cm_clksel_dpll_mpu = readl(&cmwkup->clkseldpllmpu);
+ multiplier_m = (cm_clksel_dpll_mpu >> 8) & 0x3FF;
+ predivider_n = cm_clksel_dpll_mpu & 0x7F;
+
+ /*
+ * Calculate reference clock (clock after pre-divider),
+ * its max. PLL bandwidth,
+ * and resulting mod_freq_divider
+ */
+ ref_clock = V_OSCK / (predivider_n + 1);
+ pll_bandwidth = ref_clock / 70;
+ mod_freq_divider = ref_clock / (4 * pll_bandwidth);
+
+ /* Calculate Mantissa/Exponent */
+ exponent = 0;
+ mantissa = mod_freq_divider;
+ while ((mantissa > 127) && (exponent < 7)) {
+ exponent++;
+ mantissa /= 2;
+ }
+ if (mantissa > 127)
+ mantissa = 127;
+
+ mod_freq_divider = mantissa << exponent;
+
+ /*
+ * Calculate Modulation steps
+ * As we use Downspread only, the spread is twice the value of
+ * permille, so Div2!
+ * As it takes the value in percent, divide by ten!
+ */
+ delta_m_step = ((u32)((multiplier_m * permille) / 10 / 2)) << 18;
+ delta_m_step /= 100;
+ delta_m_step /= mod_freq_divider;
+ if (delta_m_step > 0xFFFFF)
+ delta_m_step = 0xFFFFF;
+
+ /* Setup Spread Spectrum */
+ writel(delta_m_step, &cmwkup->sscdeltamstepdllmpu);
+ writel((exponent << 8) | mantissa, &cmwkup->sscmodfreqdivdpllmpu);
+ cm_clkmode_dpll_mpu = readl(&cmwkup->clkmoddpllmpu);
+ /* clear all SSC flags */
+ cm_clkmode_dpll_mpu &= ~(0xF << CM_CLKMODE_DPLL_SSC_EN_SHIFT);
+ /* enable SSC with Downspread only */
+ cm_clkmode_dpll_mpu |= CM_CLKMODE_DPLL_SSC_EN_MASK |
+ CM_CLKMODE_DPLL_SSC_DOWNSPREAD_MASK;
+ writel(cm_clkmode_dpll_mpu, &cmwkup->clkmoddpllmpu);
+ while (!(readl(&cmwkup->clkmoddpllmpu) & 0x2000))
+ ;
+}