This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3874 Spread Spectrum Clock (SSC)

Other Parts Discussed in Thread: AM3874

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 

  • Hello again,

    I just found the problem:

    AM3874_TRM_2013_Apr.pdf chapter 2.10.1 every table describing the ENSSC bit of every xxxxxxPLL_CLKCTRL is wrong!

    It says: 

    Controls Clock Spreading
    0x0 : enables clock spreading
    0x1 : disables clock spreading

    But Spread Spectrum is Enable with 0x1 not 0x0So you guys gonna need an errata!

    Thanks,
    Tiago Bonetti