PolarFire SoC: LPDDR4 init for MPFS250T Video Kit (M-Mode)#774
Draft
dgarske wants to merge 1 commit intowolfSSL:masterfrom
Draft
PolarFire SoC: LPDDR4 init for MPFS250T Video Kit (M-Mode)#774dgarske wants to merge 1 commit intowolfSSL:masterfrom
dgarske wants to merge 1 commit intowolfSSL:masterfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds standalone wolfBoot M-mode support for the PolarFire SoC MPFS250T Video Kit, including LPDDR4 bring-up (replacing HSS in the early boot path) and Linux S-mode handoff plumbing.
Changes:
- Enhance SDHCI diagnostics and reliability workarounds (CMD0→CMD8 delay, single-block read option, capability logging).
- Extend RISC-V M-mode boot flow with a reusable M→S handoff API and MPFS-specific “release U54 hart” implementation.
- Introduce MPFS250 DDR/PHY init infrastructure, build-time enablement via
LIBERO_FPGA_CONFIG_DIR, new config template, and CI build job.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/sdhci.c | Adds richer error logging, controller register dump, and reliability workarounds for Cadence SD4HC. |
| src/boot_riscv.c | Adds trap register dump support (regs frame) and factors M→S handoff into overridable helpers. |
| hal/mpfs250.h | Adds MPFS250 peripheral bits and extensive DDRC/PHY register definitions + DDR init declarations. |
| hal/mpfs250.c | Implements MPFS250 DDR/PLL/PHY init, M→S boot on a U54 via IPI handoff, and UART reinit after PLL. |
| docs/Targets.md | Documents new “M-Mode + DDR” configuration and build-time Libero config integration. |
| config/examples/polarfire_mpfs250_m.config | Adds new example config for M-mode + LPDDR4 + SD + S-mode Linux boot. |
| arch.mk | Enables MPFS DDR init when LIBERO_FPGA_CONFIG_DIR is provided (adds -DMPFS_DDR_INIT and include path). |
| .github/workflows/test-configs.yml | Adds CI build job for the new MPFS250 M-mode + DDR config template. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+561
to
+563
|
|
||
| /* Reinitialize UART for new clock frequency */ | ||
| hal_uart_reinit(); |
Comment on lines
+1953
to
+1965
| uint32_t div0_1_orig = DDR_PLL_REG(PLL_DIV_0_1); | ||
| uint32_t div2_3_orig = DDR_PLL_REG(PLL_DIV_2_3); | ||
| { | ||
| uint32_t div0 = div0_1_orig & 0x3F00UL; | ||
| uint32_t div1 = div0_1_orig & 0x3F000000UL; | ||
| uint32_t div2 = div2_3_orig & 0x3F00UL; | ||
| uint32_t div3 = div2_3_orig & 0x3F000000UL; | ||
| uint32_t mult = 2; | ||
|
|
||
| /* Double the dividers for MR writes */ | ||
| DDR_PLL_REG(PLL_DIV_0_1) = (div0 | div1) * mult; | ||
| DDR_PLL_REG(PLL_DIV_2_3) = (div2 | div3) * mult; | ||
|
|
Comment on lines
+282
to
+291
| /* Simple busy-loop delay | ||
| * Approximately us microseconds at ~40MHz (early boot clock) | ||
| * This is used before the timer is fully reliable */ | ||
| static void ddr_delay(uint32_t us) | ||
| { | ||
| volatile uint32_t i; | ||
| /* At ~40MHz, ~10 loop iterations per microsecond */ | ||
| for (i = 0; i < us * 10; i++) { | ||
| __asm__ volatile("nop"); | ||
| } |
Comment on lines
+1966
to
+1968
| /* Wait for PHY PLL to lock */ | ||
| while ((DDRPHY_REG(PHY_PLL_CTRL_MAIN) & 0x2000000UL) == 0) {} | ||
| ddr_delay(5000); |
|
|
||
| unsigned long WEAKFUNCTION handle_trap(unsigned long cause, unsigned long epc, | ||
| unsigned long tval) | ||
| unsigned long tval, unsigned long *regs) |
Comment on lines
1430
to
+1435
|
|
||
| /* Dump capability + presence registers so the bring-up log shows the | ||
| * controller's reported base clock and whether a card was detected. */ | ||
| wolfBoot_printf("SDHCI: SRS09=0x%08X SRS16=0x%08X SRS17=0x%08X\n", | ||
| SDHCI_REG(SDHCI_SRS09), SDHCI_REG(SDHCI_SRS16), | ||
| SDHCI_REG(SDHCI_SRS17)); |
| uses: ./.github/workflows/test-build-riscv.yml | ||
| with: | ||
| arch: riscv64 | ||
| config-file: ./config/examples/polarfire_mpfs250_m.config |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds standalone wolfBoot M-mode support for the Microchip PolarFire SoC MPFS250T Video Kit, including full LPDDR4 initialization that replaces the Hart Software Services (HSS) bootloader for the early boot path. wolfBoot now runs on the E51 monitor hart from L2 Scratch, brings up the LPDDR4 controller and PHY, runs Microchip's TIP autonomous training to completion, and exposes the trained DDR for Linux S-mode handoff.
What this enables
Boot flow
mpfs_ddr_init()runs:(
config_ddr_io_pull_up_downs_rpc_bitsequivalent).init_ddrcregisterwrites (the csr_custom block @ 0x3C000 is included with the
critical PHY_RESET_CONTROL twin-write handshake).
MR writes via AUTOINIT, CA-VREF, ADDCMD.
train_stat = 0x1D(all four phases done).DDRPHY_MODErewrite to LIBERO value,rpc220 = 0xC, per-laneload_dq, MTC sanity test (256 Bcounting pattern), L2 cache flush via FLUSH64.
do_boot()forWOLFBOOT_RISCV_MMODEdirect M-mode jump to test app, or M->S handoff to Linux on U54 hart 1 (Phase 4A.6 disk-load is still under investigation, see "Known limitations").Build / flash
The
LIBERO_FPGA_CONFIG_DIRMakefile variable (added inarch.mk) is the only project-specific path; the HAL pulls everyLIBERO_SETTING_*value from the standard Libero/HSS-generated fpga_design_config tree, which means a different MPFS board can re-use the HAL just by pointing this variable at its own fpga_design_config and adjusting wolfBoot's load addresses.Verification on hardware
5-cold-boot reliability with this PR (Video Kit, eNVM bootmode 1):
train_stat = 0x1D(BCLK_SCLK + WRLVL + RDGATE + DQ_DQS)All four data lanes reach
wl_dly = 0x31and the controller reportsINIT_DONE = 0x1. The pattern-test halts the boot on completion; disabling it (and disk-loading 19 MB) is currently the open work item described below.