mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
UPSTREAM: rockchip/rk3399: enable DPLL SSC for DDR EMI test on bob
Spread Spectrum Modulator (SSMOD) is a fully-digital circuit used to modulate the frequency of the Silicon Creations Fractional PLL in order to reduce EMI. We need to turn the DPLL spread spectrum feature on to reduce the EMI noise for DDR on bob. BRANCH=none BUG=b:37262721 TEST=mem checks the register value on bob. localhost / # mem r 0xff76004c ---> 0x00000100 localhost / # mem r 0xff760050 ---> 0x00000860 TEST=Tested with memtester/s2r/reboot on bob. Change-Id: I75461d4235bcf55324e6664a1220754e770b4786 Original-Change-Id: I75461d4235bcf55324e6664a1220754e770b4786 Original-Signed-off-by: Xing Zheng <zhengxing@rock-chips.com> Original-Signed-off-by: Caesar Wang <wxt@rock-chips.com> Original-Reviewed-on: https://review.coreboot.org/19557 Original-Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/377691 Commit-Ready: Caesar Wang <wxt@rock-chips.com> Tested-by: Caesar Wang <wxt@rock-chips.com> Reviewed-by: Philip Chen <philipchen@chromium.org>
This commit is contained in:
parent
f98168ef5d
commit
fbd5b8f5af
3 changed files with 104 additions and 0 deletions
|
@ -38,6 +38,7 @@ config BOARD_SPECIFIC_OPTIONS
|
|||
select MAINBOARD_HAS_CHROMEOS
|
||||
select MAINBOARD_HAS_NATIVE_VGA_INIT
|
||||
select RAM_CODE_SUPPORT
|
||||
select RK3399_SPREAD_SPECTRUM_DDR if BOARD_GOOGLE_BOB
|
||||
select RTC
|
||||
select SOC_ROCKCHIP_RK3399
|
||||
select SPI_FLASH
|
||||
|
|
|
@ -24,4 +24,12 @@ config PMIC_BUS
|
|||
int
|
||||
default -1
|
||||
|
||||
config RK3399_SPREAD_SPECTRUM_DDR
|
||||
bool "Spread-spectrum DDR clock"
|
||||
default n
|
||||
help
|
||||
Select Spread Spectrum Modulator (SSMOD) is a fully-digital circuit
|
||||
used to modulate the frequency of the Silicon Creations’ Fractional
|
||||
PLL in order to reduce EMI.
|
||||
|
||||
endif
|
||||
|
|
|
@ -82,8 +82,23 @@ enum {
|
|||
PLL_MODE_DEEP,
|
||||
PLL_DSMPD_MASK = 1,
|
||||
PLL_DSMPD_SHIFT = 3,
|
||||
PLL_FRAC_MODE = 0,
|
||||
PLL_INTEGER_MODE = 1,
|
||||
|
||||
/* PLL_CON4 */
|
||||
PLL_SSMOD_BP_MASK = 1,
|
||||
PLL_SSMOD_BP_SHIFT = 0,
|
||||
PLL_SSMOD_DIS_SSCG_MASK = 1,
|
||||
PLL_SSMOD_DIS_SSCG_SHIFT = 1,
|
||||
PLL_SSMOD_RESET_MASK = 1,
|
||||
PLL_SSMOD_RESET_SHIFT = 2,
|
||||
PLL_SSMOD_DOWNSPEAD_MASK = 1,
|
||||
PLL_SSMOD_DOWNSPEAD_SHIFT = 3,
|
||||
PLL_SSMOD_DIVVAL_MASK = 0Xf,
|
||||
PLL_SSMOD_DIVVAL_SHIFT = 4,
|
||||
PLL_SSMOD_SPREADAMP_MASK = 0x1f,
|
||||
PLL_SSMOD_SPREADAMP_SHIFT = 8,
|
||||
|
||||
/* PMUCRU_CLKSEL_CON0 */
|
||||
PMU_PCLK_DIV_CON_MASK = 0x1f,
|
||||
PMU_PCLK_DIV_CON_SHIFT = 0,
|
||||
|
@ -326,6 +341,83 @@ static void rkclk_set_pll(u32 *pll_con, const struct pll_div *div)
|
|||
PLL_MODE_NORM << PLL_MODE_SHIFT));
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure the DPLL spread spectrum feature on memory clock.
|
||||
* Configure sequence:
|
||||
* 1. PLL been configured as frac mode, and DACPD should be set to 1’b0.
|
||||
* 2. Configure DOWNSPERAD, SPREAD, DIVVAL(option: configure xPLL_CON5 with
|
||||
* extern wave table).
|
||||
* 3. set ssmod_disable_sscg = 1’b0, and set ssmod_bp = 1’b0.
|
||||
* 4. Assert RESET = 1’b1 to SSMOD.
|
||||
* 5. RESET = 1’b0 on SSMOD.
|
||||
* 6. Adjust SPREAD/DIVVAL/DOWNSPREAD.
|
||||
*/
|
||||
static void rkclk_set_dpllssc(struct pll_div *dpll_cfg)
|
||||
{
|
||||
u32 divval;
|
||||
|
||||
/*
|
||||
* TODO find the root cause why is the delay needed, otherwise sometimes
|
||||
* hang somewhere with reboot tests.
|
||||
*/
|
||||
udelay(30);
|
||||
assert(dpll_cfg->refdiv && dpll_cfg->refdiv <= 6);
|
||||
|
||||
/*
|
||||
* Need to acquire ~30kHZ which is the target modulation frequency.
|
||||
* The modulation frequency ~ 30kHz= OSC_HZ/revdiv/128/divval
|
||||
* (the 128 is the number points in the query table).
|
||||
*/
|
||||
divval = OSC_HZ / 128 / (30 * KHz) / dpll_cfg->refdiv;
|
||||
|
||||
/*
|
||||
* Use frac mode.
|
||||
* Make sure the output frequency isn't offset, set 0 for Fractional
|
||||
* part of feedback divide.
|
||||
*/
|
||||
write32(&cru_ptr->dpll_con[3],
|
||||
RK_CLRSETBITS(PLL_DSMPD_MASK << PLL_DSMPD_SHIFT,
|
||||
PLL_FRAC_MODE << PLL_DSMPD_SHIFT));
|
||||
clrsetbits_le32(&cru_ptr->dpll_con[2],
|
||||
PLL_FRACDIV_MASK << PLL_FRACDIV_SHIFT,
|
||||
0 << PLL_FRACDIV_SHIFT);
|
||||
|
||||
/*
|
||||
* Configure SSC divval.
|
||||
* Spread amplitude range = 0.1 * SPREAD[4:0] (%).
|
||||
* The below 8 means SPREAD[4:0] that appears to mitigate EMI on boards
|
||||
* tested. Center and down spread modulation amplitudes based on the
|
||||
* value of SPREAD.
|
||||
* SPREAD[4:0] Center Spread Down Spread
|
||||
* 0 0 0
|
||||
* 1 ±0.1% -0.10%
|
||||
* 2 ±0.2% -0.20%
|
||||
* 3 ±0.3% -0.30%
|
||||
* 4 ±0.4% -0.40%
|
||||
* 5 ±0.5% -0.50%
|
||||
* ...
|
||||
* 31 ±3.1% -3.10%
|
||||
*/
|
||||
write32(&cru_ptr->dpll_con[4],
|
||||
RK_CLRSETBITS(PLL_SSMOD_DIVVAL_MASK << PLL_SSMOD_DIVVAL_SHIFT,
|
||||
divval << PLL_SSMOD_DIVVAL_SHIFT));
|
||||
write32(&cru_ptr->dpll_con[4],
|
||||
RK_CLRSETBITS(PLL_SSMOD_SPREADAMP_MASK <<
|
||||
PLL_SSMOD_SPREADAMP_SHIFT,
|
||||
8 << PLL_SSMOD_SPREADAMP_SHIFT));
|
||||
|
||||
/* Enable SSC for DPLL */
|
||||
write32(&cru_ptr->dpll_con[4],
|
||||
RK_CLRBITS(PLL_SSMOD_BP_MASK << PLL_SSMOD_BP_SHIFT |
|
||||
PLL_SSMOD_DIS_SSCG_MASK << PLL_SSMOD_DIS_SSCG_SHIFT));
|
||||
|
||||
/* Deassert reset SSMOD */
|
||||
write32(&cru_ptr->dpll_con[4],
|
||||
RK_CLRBITS(PLL_SSMOD_RESET_MASK << PLL_SSMOD_RESET_SHIFT));
|
||||
|
||||
udelay(20);
|
||||
}
|
||||
|
||||
static int pll_para_config(u32 freq_hz, struct pll_div *div)
|
||||
{
|
||||
u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
|
||||
|
@ -571,6 +663,9 @@ void rkclk_configure_ddr(unsigned int hz)
|
|||
die("Unsupported SDRAM frequency, add to clock.c!");
|
||||
}
|
||||
rkclk_set_pll(&cru_ptr->dpll_con[0], &dpll_cfg);
|
||||
|
||||
if (IS_ENABLED(CONFIG_RK3399_SPREAD_SPECTRUM_DDR))
|
||||
rkclk_set_dpllssc(&dpll_cfg);
|
||||
}
|
||||
|
||||
#define SPI_CLK_REG_VALUE(bus, clk_div) \
|
||||
|
|
Loading…
Add table
Reference in a new issue