Skip to content

Commit 8deb6b9

Browse files
Adjust the PSRAM clock when over/underclock F_SYS (#2824)
* Adjust the PSRAM clock when over/underclock F_SYS Fixes #2818 * Need to increase PSRAM divider before sysclk increase Per datasheet, when increasing sysclk speed we need to set the qmi clocks first and do a dummy transfer to ensure no invalid speed operations happen on the bus. Handle the logic for this while setting up the overclock.
1 parent 6236d1f commit 8deb6b9

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

cores/rp2040/main.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include <pico/stdlib.h>
2424
#include <pico/multicore.h>
2525
#include <reent.h>
26+
#ifdef RP2350_PSRAM_CS
27+
#include "psram.h"
28+
#endif
2629

2730
RP2040 rp2040;
2831
extern "C" {
@@ -80,7 +83,26 @@ static struct _reent *_impure_ptr1 = nullptr;
8083

8184
extern "C" int main() {
8285
#if (defined(PICO_RP2040) && (F_CPU != 125000000)) || (defined(PICO_RP2350) && (F_CPU != 150000000))
86+
#if defined(RP2350_PSRAM_CS) && (F_CPU > 150000000)
87+
// Need to increase the qmi divider before upping sysclk to ensure we keep the output sck w/in legal bounds
88+
psram_reinit_timing(F_CPU);
89+
// Per datasheet, need to do a dummy access and memory barrier before it takes effect
90+
extern uint8_t __psram_start__;
91+
volatile uint8_t *x = &__psram_start__;
92+
*x ^= 0xff;
93+
*x ^= 0xff;
94+
asm volatile("" ::: "memory");
95+
#endif
8396
set_sys_clock_khz(F_CPU / 1000, true);
97+
#if defined(RP2350_PSRAM_CS) && (F_CPU < 150000000)
98+
psram_reinit_timing();
99+
// Per datasheet, need to do a dummy access and memory barrier before it takes effect
100+
extern uint8_t __psram_start__;
101+
volatile uint8_t *x = &__psram_start__;
102+
*x ^= 0xff;
103+
*x ^= 0xff;
104+
asm volatile("" ::: "memory");
105+
#endif
84106
#endif
85107

86108
// Let rest of core know if we're using FreeRTOS

cores/rp2040/psram.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,7 @@ static size_t __no_inline_not_in_flash_func(get_psram_size)(void) {
195195
///
196196
/// @note This function expects interrupts to be enabled on entry
197197

198-
static void __no_inline_not_in_flash_func(set_psram_timing)(void) {
199-
// Get secs / cycle for the system clock - get before disabling interrupts.
200-
uint32_t sysHz = (uint32_t)clock_get_hz(clk_sys);
201-
198+
static void __no_inline_not_in_flash_func(set_psram_timing)(uint32_t sysHz) {
202199
// Calculate the clock divider - goal to get clock used for PSRAM <= what
203200
// the PSRAM IC can handle - which is defined in SFE_PSRAM_MAX_SCK_HZ
204201
volatile uint8_t clockDivider = (sysHz + SFE_PSRAM_MAX_SCK_HZ - 1) / SFE_PSRAM_MAX_SCK_HZ;
@@ -283,7 +280,7 @@ static void __no_inline_not_in_flash_func(runtime_init_setup_psram)(/*uint32_t p
283280

284281
// check our interrupts and setup the timing
285282
restore_interrupts(intr_stash);
286-
set_psram_timing();
283+
set_psram_timing((uint32_t)clock_get_hz(clk_sys));
287284

288285
// and now stash interrupts again
289286
intr_stash = save_and_disable_interrupts();
@@ -323,8 +320,11 @@ static void __no_inline_not_in_flash_func(runtime_init_setup_psram)(/*uint32_t p
323320
PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_setup_psram, PICO_RUNTIME_INIT_PSRAM);
324321

325322
// update timing -- used if the system clock/timing was changed.
326-
void psram_reinit_timing() {
327-
set_psram_timing();
323+
void psram_reinit_timing(uint32_t hz) {
324+
if (!hz) {
325+
hz = (uint32_t)clock_get_hz(clk_sys);
326+
}
327+
set_psram_timing(hz);
328328
}
329329

330330
static bool __psram_heap_init() {

cores/rp2040/psram.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
#include <Arduino.h>
3333

34-
void psram_reinit_timing();
34+
void psram_reinit_timing(uint32_t hz = 0);
3535
void *__psram_malloc(size_t size);
3636
void __psram_free(void *ptr);
3737
void *__psram_realloc(void *ptr, size_t size);

0 commit comments

Comments
 (0)