@@ -115,13 +115,27 @@ static uint8_t flash_page_cache[FLASH_PAGE_SIZE];
115115# error "wolfBoot LPC54S018M HAL: WRITEONCE not supported on SPIFI flash."
116116#endif
117117
118+ /* -------------------------------------------------------------------------- */
119+ /* SYSCON registers (shared across clock + UART) */
120+ /* -------------------------------------------------------------------------- */
121+ #define SYSCON_BASE 0x40000000
122+ #define SYSCON_PDRUNCFGCLR0 (*(volatile uint32_t *)(SYSCON_BASE + 0x04C))
123+ #define SYSCON_MAINCLKSELA (*(volatile uint32_t *)(SYSCON_BASE + 0x280))
124+ #define SYSCON_MAINCLKSELB (*(volatile uint32_t *)(SYSCON_BASE + 0x284))
125+ #define SYSCON_AHBCLKDIV (*(volatile uint32_t *)(SYSCON_BASE + 0x380))
126+ #define SYSCON_FROCTRL (*(volatile uint32_t *)(SYSCON_BASE + 0x550))
127+
128+ /* FROCTRL bits */
129+ #define FROCTRL_SEL_96MHZ (1UL << 14) /* 0=48MHz, 1=96MHz */
130+ #define FROCTRL_HSPDCLK (1UL << 30) /* Enable FRO high-speed output */
131+ #define FROCTRL_WRTRIM (1UL << 31) /* Write trim enable */
132+
118133/* -------------------------------------------------------------------------- */
119134/* UART via Flexcomm0 (bare-metal, no SDK) */
120135/* -------------------------------------------------------------------------- */
121136#ifdef DEBUG_UART
122137
123138/* SYSCON registers for clock gating and peripheral reset */
124- #define SYSCON_BASE 0x40000000
125139#define SYSCON_AHBCLKCTRL0 (*(volatile uint32_t *)(SYSCON_BASE + 0x200))
126140#define SYSCON_AHBCLKCTRL1 (*(volatile uint32_t *)(SYSCON_BASE + 0x204))
127141#define SYSCON_PRESETCTRL1 (*(volatile uint32_t *)(SYSCON_BASE + 0x104))
@@ -193,12 +207,13 @@ void uart_init(void)
193207 /* Enable Flexcomm0 clock (use atomic SET register) */
194208 SYSCON_AHBCLKCTRLSET1 = AHBCLKCTRL1_FC0 ;
195209
196- /* Reset Flexcomm0 using atomic CLR/SET registers (NXP SDK pattern) */
197- SYSCON_PRESETCTRLCLR1 = PRESETCTRL1_FC0 ; /* Assert reset */
198- while (SYSCON_PRESETCTRL1 & PRESETCTRL1_FC0 ) /* Wait for assert */
210+ /* Reset Flexcomm0: NXP PRESETCTRL polarity is bit=1 means IN reset,
211+ * bit=0 means OUT of reset. Use SET to assert, CLR to deassert. */
212+ SYSCON_PRESETCTRLSET1 = PRESETCTRL1_FC0 ; /* Assert reset (bit→1) */
213+ while (!(SYSCON_PRESETCTRL1 & PRESETCTRL1_FC0 )) /* Wait for bit=1 */
199214 ;
200- SYSCON_PRESETCTRLSET1 = PRESETCTRL1_FC0 ; /* Deassert reset */
201- while (!( SYSCON_PRESETCTRL1 & PRESETCTRL1_FC0 )) /* Wait for deassert */
215+ SYSCON_PRESETCTRLCLR1 = PRESETCTRL1_FC0 ; /* Deassert reset (bit→0) */
216+ while (SYSCON_PRESETCTRL1 & PRESETCTRL1_FC0 ) /* Wait for bit=0 */
202217 ;
203218
204219 /* Small delay after reset deassertion for peripheral to stabilize */
@@ -209,7 +224,7 @@ void uart_init(void)
209224 FC0_PSELID = 1 ;
210225
211226 /* Verify Flexcomm0 is accessible — if PSELID reads 0, peripheral is
212- * not responding (observed on some LPC54S018M boards) . Skip UART. */
227+ * not responding. Skip UART. */
213228 if ((FC0_PSELID & 0x71 ) == 0 ) {
214229 return ;
215230 }
@@ -277,17 +292,55 @@ void __assert_func(const char *a, int b, const char *c, const char *d)
277292 ;
278293}
279294
295+ /* Forward declaration — defined later in the file as RAMFUNCTION */
296+ static void RAMFUNCTION spifi_enter_memmode (void );
297+
298+ /*
299+ * Boost main clock from FRO 12MHz to FRO_HF 96MHz (8x speedup).
300+ * Must run from RAM because changing MAINCLK affects the SPIFI XIP clock.
301+ * UART is unaffected: FCLKSEL0=0 selects FRO 12MHz for Flexcomm0 independently.
302+ */
303+ static void RAMFUNCTION hal_clock_boost (void )
304+ {
305+ /* Ensure FRO, ROM, and VD6 (OTP) power domains are enabled.
306+ * Boot ROM usually leaves these on, but clearing is idempotent. */
307+ SYSCON_PDRUNCFGCLR0 = (1UL << 4 ) | (1UL << 17 ) | (1UL << 29 );
308+
309+ /* Confirm main clock is FRO 12MHz (safety before frequency change). */
310+ SYSCON_MAINCLKSELA = 0U ;
311+ SYSCON_MAINCLKSELB = 0U ;
312+
313+ /* Enable FRO_HF directly via FROCTRL (bypass ROM API which faults
314+ * on this silicon). Set HSPDCLK + SEL=96MHz with FREQTRIM=0; the FRO
315+ * will operate at nominal 96MHz with reduced accuracy (no OTP trim),
316+ * which is fine for crypto acceleration. */
317+ SYSCON_FROCTRL = FROCTRL_HSPDCLK | FROCTRL_SEL_96MHZ ;
318+
319+ /* Brief delay for FRO_HF to stabilize */
320+ {
321+ volatile int i ;
322+ for (i = 0 ; i < 1000 ; i ++ ) ;
323+ }
324+
325+ /* AHB divider = /1 (96MHz AHB clock). */
326+ SYSCON_AHBCLKDIV = 0U ;
327+
328+ /* Switch main clock to FRO_HF. SPIFI clock (SPIFICLKSEL=MAIN_CLK,
329+ * SPIFICLKDIV=/1) auto-scales to 96MHz — within W25Q32JV quad I/O
330+ * limit of 104MHz. Boot ROM's MCMD already has 6 dummy cycles
331+ * (INTLEN=3 in quad mode) which covers the full speed range. */
332+ SYSCON_MAINCLKSELA = 3U ;
333+
334+ /* Re-enter SPIFI memory mode at new clock. */
335+ spifi_enter_memmode ();
336+ }
337+
280338void hal_init (void )
281339{
282- /* The boot ROM has already configured basic clocks and SPIFI for XIP.
283- * We must NOT reconfigure clocks or SPIFI from flash (XIP) because
284- * changing the clock source or SPIFI controller while executing from
285- * SPIFI flash will cause an instruction fetch fault.
286- *
287- * Clock and SPIFI reconfiguration can only be done from RAM functions.
288- * The flash erase/write paths (all RAMFUNCTION) handle SPIFI mode
289- * switching as needed.
290- */
340+ /* Boost from FRO 12MHz to FRO_HF 96MHz before anything else.
341+ * Runs from RAM because changing MAINCLK affects SPIFI XIP. */
342+ hal_clock_boost ();
343+
291344#ifdef DEBUG_UART
292345 uart_init ();
293346#endif
0 commit comments