From 694607b563df4425b2d50d220048cc3299a6e947 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 7 Jun 2016 08:31:19 +0200 Subject: 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 Reviewed-by: Tom Rini --- arch/arm/cpu/armv7/am33xx/clock_am33xx.c | 73 ++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'arch/arm/cpu') 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)) + ; +} -- cgit v1.2.1