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:
Liam Fraser 2022-06-20 16:28:03 +01:00 committed by GitHub
parent 8f09099757
commit 33818dd0bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 19 additions and 8 deletions

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -17,7 +17,7 @@
// GENERAL CONSTRAINTS:
// Reference clock frequency min=5MHz, max=800MHz
// 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_BITS _u(0x8000013f)
#define PLL_CS_RESET _u(0x00000001)

View File

@ -22367,7 +22367,7 @@
GENERAL CONSTRAINTS:\n
Reference clock frequency min=5MHz, max=800MHz\n
Feedback divider min=16, max=320\n
VCO frequency min=400MHz, max=1600MHz</description>
VCO frequency min=750MHz, max=1600MHz</description>
<fields>
<field>
<access>read-only</access>

View File

@ -148,13 +148,13 @@ void clocks_init(void) {
/// \tag::pll_settings[]
// Configure PLLs
// REF FBDIV VCO POSTDIV
// PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHZ / 6 / 2 = 125MHz
// PLL USB: 12 / 1 = 12MHz * 40 = 480 MHz / 5 / 2 = 48MHz
// PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 6 / 2 = 125MHz
// PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 = 48MHz
/// \end::pll_settings[]
/// \tag::pll_init[]
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[]
// Configure clocks

View File

@ -5,7 +5,7 @@ import argparse
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("--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("output", help="Output frequency in MHz.", type=float)
args = parser.parse_args()

View File

@ -31,6 +31,14 @@ typedef pll_hw_t *PLL;
#define pll_sys pll_sys_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.
* \ingroup hardware_pll
* \param pll pll_sys or pll_usb

View File

@ -13,6 +13,9 @@
void pll_init(PLL pll, uint refdiv, uint vco_freq, uint post_div1, uint post_div2) {
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
// (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);

View File

@ -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;
for (uint fbdiv = 320; fbdiv >= 16; fbdiv--) {
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 postdiv2 = postdiv1; postdiv2 >= 1; postdiv2--) {
uint out = vco / (postdiv1 * postdiv2);