Increase PLL min VCO from 400MHz to 750MHz for improved stability across operating conditions (#869)
Co-authored-by: graham sanderson <graham.sanderson@raspberrypi.com>
This commit is contained in:
parent
8f09099757
commit
33818dd0bd
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
|
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
@ -17,7 +17,7 @@
|
|||||||
// GENERAL CONSTRAINTS:
|
// GENERAL CONSTRAINTS:
|
||||||
// Reference clock frequency min=5MHz, max=800MHz
|
// Reference clock frequency min=5MHz, max=800MHz
|
||||||
// Feedback divider min=16, max=320
|
// Feedback divider min=16, max=320
|
||||||
// VCO frequency min=400MHz, max=1600MHz
|
// VCO frequency min=750MHz, max=1600MHz
|
||||||
#define PLL_CS_OFFSET _u(0x00000000)
|
#define PLL_CS_OFFSET _u(0x00000000)
|
||||||
#define PLL_CS_BITS _u(0x8000013f)
|
#define PLL_CS_BITS _u(0x8000013f)
|
||||||
#define PLL_CS_RESET _u(0x00000001)
|
#define PLL_CS_RESET _u(0x00000001)
|
||||||
|
@ -22367,7 +22367,7 @@
|
|||||||
GENERAL CONSTRAINTS:\n
|
GENERAL CONSTRAINTS:\n
|
||||||
Reference clock frequency min=5MHz, max=800MHz\n
|
Reference clock frequency min=5MHz, max=800MHz\n
|
||||||
Feedback divider min=16, max=320\n
|
Feedback divider min=16, max=320\n
|
||||||
VCO frequency min=400MHz, max=1600MHz</description>
|
VCO frequency min=750MHz, max=1600MHz</description>
|
||||||
<fields>
|
<fields>
|
||||||
<field>
|
<field>
|
||||||
<access>read-only</access>
|
<access>read-only</access>
|
||||||
|
@ -148,13 +148,13 @@ void clocks_init(void) {
|
|||||||
/// \tag::pll_settings[]
|
/// \tag::pll_settings[]
|
||||||
// Configure PLLs
|
// Configure PLLs
|
||||||
// REF FBDIV VCO POSTDIV
|
// REF FBDIV VCO POSTDIV
|
||||||
// PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
|
// PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 6 / 2 = 125MHz
|
||||||
// PLL USB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz
|
// PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 = 48MHz
|
||||||
/// \end::pll_settings[]
|
/// \end::pll_settings[]
|
||||||
|
|
||||||
/// \tag::pll_init[]
|
/// \tag::pll_init[]
|
||||||
pll_init(pll_sys, 1, 1500 * MHZ, 6, 2);
|
pll_init(pll_sys, 1, 1500 * MHZ, 6, 2);
|
||||||
pll_init(pll_usb, 1, 480 * MHZ, 5, 2);
|
pll_init(pll_usb, 1, 1200 * MHZ, 5, 5);
|
||||||
/// \end::pll_init[]
|
/// \end::pll_init[]
|
||||||
|
|
||||||
// Configure clocks
|
// Configure clocks
|
||||||
|
@ -5,7 +5,7 @@ import argparse
|
|||||||
parser = argparse.ArgumentParser(description="PLL parameter calculator")
|
parser = argparse.ArgumentParser(description="PLL parameter calculator")
|
||||||
parser.add_argument("--input", "-i", default=12, help="Input (reference) frequency. Default 12 MHz", type=float)
|
parser.add_argument("--input", "-i", default=12, help="Input (reference) frequency. Default 12 MHz", type=float)
|
||||||
parser.add_argument("--vco-max", default=1600, help="Override maximum VCO frequency. Default 1600 MHz", type=float)
|
parser.add_argument("--vco-max", default=1600, help="Override maximum VCO frequency. Default 1600 MHz", type=float)
|
||||||
parser.add_argument("--vco-min", default=400, help="Override minimum VCO frequency. Default 400 MHz", type=float)
|
parser.add_argument("--vco-min", default=750, help="Override minimum VCO frequency. Default 750 MHz", type=float)
|
||||||
parser.add_argument("--low-vco", "-l", action="store_true", help="Use a lower VCO frequency when possible. This reduces power consumption, at the cost of increased jitter")
|
parser.add_argument("--low-vco", "-l", action="store_true", help="Use a lower VCO frequency when possible. This reduces power consumption, at the cost of increased jitter")
|
||||||
parser.add_argument("output", help="Output frequency in MHz.", type=float)
|
parser.add_argument("output", help="Output frequency in MHz.", type=float)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -31,6 +31,14 @@ typedef pll_hw_t *PLL;
|
|||||||
#define pll_sys pll_sys_hw
|
#define pll_sys pll_sys_hw
|
||||||
#define pll_usb pll_usb_hw
|
#define pll_usb pll_usb_hw
|
||||||
|
|
||||||
|
#ifndef PICO_PLL_VCO_MIN_FREQ_MHZ
|
||||||
|
#define PICO_PLL_VCO_MIN_FREQ_MHZ 750
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PICO_PLL_VCO_MAX_FREQ_MHZ
|
||||||
|
#define PICO_PLL_VCO_MAX_FREQ_MHZ 1600
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! \brief Initialise specified PLL.
|
/*! \brief Initialise specified PLL.
|
||||||
* \ingroup hardware_pll
|
* \ingroup hardware_pll
|
||||||
* \param pll pll_sys or pll_usb
|
* \param pll pll_sys or pll_usb
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div2) {
|
void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div2) {
|
||||||
uint32_t ref_mhz = XOSC_MHZ / refdiv;
|
uint32_t ref_mhz = XOSC_MHZ / refdiv;
|
||||||
|
|
||||||
|
// Check vco freq is in an acceptable range
|
||||||
|
assert(vco_freq >= (PICO_PLL_VCO_MIN_FREQ_MHZ * MHZ) && vco_freq <= (PICO_PLL_VCO_MAX_FREQ_MHZ * MHZ));
|
||||||
|
|
||||||
// What are we multiplying the reference clock by to get the vco freq
|
// What are we multiplying the reference clock by to get the vco freq
|
||||||
// (The regs are called div, because you divide the vco output and compare it to the refclk)
|
// (The regs are called div, because you divide the vco output and compare it to the refclk)
|
||||||
uint32_t fbdiv = vco_freq / (ref_mhz * MHZ);
|
uint32_t fbdiv = vco_freq / (ref_mhz * MHZ);
|
||||||
|
@ -73,7 +73,7 @@ bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_out, uint *postdiv1_out, u
|
|||||||
uint crystal_freq_khz = clock_get_hz(clk_ref) / 1000;
|
uint crystal_freq_khz = clock_get_hz(clk_ref) / 1000;
|
||||||
for (uint fbdiv = 320; fbdiv >= 16; fbdiv--) {
|
for (uint fbdiv = 320; fbdiv >= 16; fbdiv--) {
|
||||||
uint vco = fbdiv * crystal_freq_khz;
|
uint vco = fbdiv * crystal_freq_khz;
|
||||||
if (vco < 400000 || vco > 1600000) continue;
|
if (vco < PICO_PLL_VCO_MIN_FREQ_MHZ * 1000 || vco > PICO_PLL_VCO_MAX_FREQ_MHZ * 1000) continue;
|
||||||
for (uint postdiv1 = 7; postdiv1 >= 1; postdiv1--) {
|
for (uint postdiv1 = 7; postdiv1 >= 1; postdiv1--) {
|
||||||
for (uint postdiv2 = postdiv1; postdiv2 >= 1; postdiv2--) {
|
for (uint postdiv2 = postdiv1; postdiv2 >= 1; postdiv2--) {
|
||||||
uint out = vco / (postdiv1 * postdiv2);
|
uint out = vco / (postdiv1 * postdiv2);
|
||||||
|
Loading…
Reference in New Issue
Block a user