Hello,
I'm working on reducing the electromagnetic interference (EMI) on a medical product, but i just CANNOT enable SSC.
I'm currently having some problems with the Video Pixel Clock (VDO2 at 108MHz), therefore I want to enable SSC to reduce de emission.
First, neither the Datasheet or TRM have Information about the SSC functions and configurations. After searching around the forum ( [1], [2] ) and reading other Sitara documentations I got a bare understanding about the AM3874 SSC.
The SSC registers, associated with VIDEO1, are mainly three: VIDEO1PLL_CLKCTRL, VIDEO1PLL_FRACCTRL and VIDEO1PLL_STATUS as named at AM3874 TRM.
I searched the linux video drivers, where I found the PLL config function "system_platformpllcfg" at "$(LINUX_SOURCE)/drivers/video/ti81xx/vpss/system.c" .
I added this code to calculate e config the registers:
printk(KERN_INFO "PLL Values: M = %d, N = %d, M2 = %d\n", m,n,m2);
#define SPREAD_PERCENT 2
//Watch out for u32 MAXSIZE, may overflow
F_out = ((TI814X_OSC_FREQ) / ((n+1) * m2)) * m;
F_ref = TI814X_OSC_FREQ / (n+1);
//10dB Attenuation = /100; Percent = /100
F_mod = (F_out * SPREAD_PERCENT) / (100 * 100);
printk(KERN_INFO "Freq Values: Out = %d, Ref = %d, Mod = %d\n", F_out, F_ref, F_mod);
ModFreqDivider = (F_ref / (4 * F_mod));
ModFreqDiv_Mantissa = ModFreqDivider;
ModFreqDiv_Exponent = 0;
while ( ModFreqDiv_Mantissa & 0xFFFFFF80 ) {
ModFreqDiv_Mantissa = ModFreqDiv_Mantissa >> 1;
ModFreqDiv_Exponent++;
}
// DELTA M = (m * (SPREAD_PERCENT/100);
DeltaMStep_Divider = ( ModFreqDiv_Exponent <= 3) ? ModFreqDivider : (8 * ModFreqDiv_Mantissa);
DeltaMStep_Integer = ( m * SPREAD_PERCENT ) / ( DeltaMStep_Divider * 100 );
DeltaMStep_Remainder = ( m * SPREAD_PERCENT ) % ( DeltaMStep_Divider * 100 );
DeltaMStep_Fraction = (DeltaMStep_Remainder << 18) / ( DeltaMStep_Divider * 100 );
printk(KERN_INFO"Spread Values: ModFreqDiv_Exponent = %d, ModFreqDiv_Mantissa = %d, DeltaMStep_Integer = %d, DeltaMStep_Fraction = %d\n",
ModFreqDiv_Exponent, ModFreqDiv_Mantissa, DeltaMStep_Integer, DeltaMStep_Fraction);
#define DOWNSPREAD 0
FracCtrl = (DOWNSPREAD << 31)|((ModFreqDiv_Exponent) << 28)|(ModFreqDiv_Mantissa << 21)|(DeltaMStep_Integer << 18)|(DeltaMStep_Fraction << 0);
__raw_writel(FracCtrl, (base + FRACCTRL));
printk(KERN_INFO "FRACTRL Value: %x, Address = %x\n", FracCtrl, (base + FRACCTRL));
read_clkctrl = __raw_readl(base + CLKCTRL);
__raw_writel((read_clkctrl & ~(1<<30)), (base + CLKCTRL) );
I got as result:
PLL Values: M = 432, N = 7, M2 = 10
Freq Values: Out = 108000000, Ref = 2500000, Mod = 21600
Spread Values: ModFreqDiv_Exponent = 0, ModFreqDiv_Mantissa = 28, DeltaMStep_Integer = 0, DeltaMStep_Fraction = 80890
FRACTRL Value: 3813bfa, Address = fa1c51f0
CLKCTRL: 791080e
CLKCTRL: 711100f
STATUS: c0000638
Yet we can see VIDEO1PLL_STATUS[2] = 0, so there is no SSCACK
What I'm doing wrong? When shoud I config the registers?
Thank You,
Tiago Bonetti