Skip to content

novatek: stay below 64 MiB; the rest of the vendor board set-up - #97

Merged
dimerr merged 3 commits into
openipc-novatekfrom
novatek/below-64m
Oct 30, 2026
Merged

dimerr merged 3 commits into
openipc-novatekfrom
novatek/below-64m

Conversation

@dimerr

@dimerr dimerr commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Addresses #95 (NT98566, XM N8S: link up, then eqos: Tx timed out from the first frame).

novatek: stay in the loader's U-Boot region, below 64 MiB
U-Boot relocated to the top of the DDR, which on the NT98566 is past 64 MiB, so the MAC's descriptors and buffers went there too. The vendor U-Boot never leaves /nvt_memory_cfg/uboot (0x3900000, 6.75 MiB). U-Boot now relocates to the top of that region. The DDR size, the osmem split and the lmb reservations don't change. On the NT98562 this also keeps U-Boot off core2entry2.

novatek: the rest of the vendor U-Boot's board set-up
What nvt_ivot_hw_init_early() / nvt_ivot_hw_init() do, in their order:

  • OTP timing
  • CG 0x70 bit 16
  • CPU clock from the loader's device tree (960 MHz), and APB if named
  • AXI bridge timeouts
  • USB PHY set-up and power-down

The EVB-only PHY reset on D_GPIO(1) stays out.

Verified under qemu-hisilicon, nt98562 and nt98566:

  • relocaddr 0x3f6b000
  • a 3 MB tftpboot with matching crc32, and ping
  • boot to login with the nt9856x_lite kernel and rootfs
  • Linux's driver gets its lease

Not yet on silicon. Whether #95 is fixed is for the reporter to confirm.

U-Boot relocated to the top of the DDR. On the NT98566 that is past
64 MiB, so the MAC's descriptors and buffers went there too, and on an
XM N8S board the Tx DMA never took the first descriptor: the link came
up, then "eqos: Tx timed out" on every frame (#95). The
vendor U-Boot never leaves /nvt_memory_cfg/uboot (0x3900000, 6.75 MiB):
its ram_size is that region. Relocate to its top, as the vendor does;
the DDR size, the osmem split and the lmb reservations are unchanged.
On the NT98562 this also keeps U-Boot off core2entry2, just above.

Verified under qemu-hisilicon, nt98562 and nt98566: relocaddr
0x3f6b000, a 3 MB tftpboot with matching crc32, ping, boot to login from
an 8 MiB image with the nt9856x_lite kernel and rootfs, Linux's driver
gets its lease. Not yet on silicon: whether this fixes #95 is for the
reporter to confirm.
What the vendor U-Boot's nvt_ivot_hw_init_early() and nvt_ivot_hw_init()
(nvt-na51089/na51089_hw_init.c) do, in board_init(), in their order:

- the OTP controller's timing for the APB clock, and CG 0x70 bit 16
  cleared;
- the CPU clock the loader's device tree asks for (/cpus/cpu@0
  clock-frequency, 960 MHz on the Xiongmai trees: PLL8 at ratio
  0xA00000), and the APB clock if it names one, as nvt_cpu_freq and
  nvt_apb_freq do; their polls get a timeout;
- the AXI bridge timeouts (0xF0012018, 0xF0013018);
- the USB PHY set-up by chip revision, then its power-down.

Its PHY reset on D_GPIO(1) stays out: the pin is set in the EVB's
header, nvt-na51089-evb.h, and may be anything on another board.

Verified under qemu-hisilicon, nt98562 and nt98566: boot to login from
an 8 MiB image with the nt9856x_lite kernel and rootfs, a 3 MB tftpboot
with matching crc32, ping, Linux's driver gets its lease. qemu does not
model the clock switch or the bridges; not yet on silicon.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Novatek: relocate below 64 MiB and complete vendor board setup

🐞 Bug fix ✨ Enhancement 🕐 20-40 Minutes

Grey Divider

AI Description

• Keep U-Boot in the loader’s region to avoid high-memory Ethernet DMA timeouts.
• Apply vendor-ordered clock, OTP, AXI, and USB PHY setup without the EVB-only PHY reset.
• Verify network transfers and Linux boot in emulation; silicon confirmation remains outstanding.
Diagram

graph TD
  L["Novatek loader"] --> R[("U-Boot region")] --> T["RAM top hook"] --> U["Relocated U-Boot"] --> M["EQOS DMA"]
  L --> F[("Loader FDT")] --> B["Board init"] --> H["SoC setup"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Constrain only Ethernet DMA allocations
  • ➕ Preserves relocation near the top of DDR.
  • ➖ Requires driver-specific memory management and does not avoid the NT98562 core2entry2 region.
2. Report only the loader region as RAM
  • ➕ Uses the default U-Boot relocation behavior.
  • ➖ Would alter the DDR size exposed to existing memory-split and reservation logic.

Recommendation: Keep the targeted RAM-top hook: it follows the loader’s U-Boot boundary without changing reported DDR or Linux reservations. Review the register sequence carefully and seek silicon confirmation before treating the Ethernet timeout as resolved.

Files changed (2) +143 / -1

Enhancement (1) +140 / -1
na51089.cBound relocation and add vendor-ordered SoC initialization +140/-1

Bound relocation and add vendor-ordered SoC initialization

• Caps U-Boot relocation at the loader region’s end, keeping its Ethernet allocations below 64 MiB without changing reported DDR or reservations. Adds OTP timing, clock selection from the loader FDT, AXI timeouts, and revision-specific USB PHY setup and power-down; leaves out the EVB-only PHY reset.

board/novatek/na51089/na51089.c

Bug fix (1) +3 / -0
na51089.hDefine the loader-designated U-Boot memory region +3/-0

Define the loader-designated U-Boot memory region

• Adds the base and size of the loader’s U-Boot region for use as the relocation boundary.

arch/arm/mach-novatek/include/mach/na51089.h

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. eFuse timing can mismatch the bus clock ✓ Resolved
Description
board_init() programs OTP_TIMING from the current APB selector before nvt_set_clocks() can
change that selector. When the loader's device tree supplies apb-frequenccy for a different APB
speed, the eFuse controller retains timing values for the old speed, with no later update.
Code

board/novatek/na51089/na51089.c[130]

+	writel(otp_timing[(readl(CG_SYSCLK) >> 8) & 3], OTP_TIMING);
Evidence
The timing table is indexed by CG_SYSCLK bits 9:8 before the clock setup call; the FDT-driven APB
setter subsequently writes those same bits. The defined timing register is within the loader's eFuse
controller, and no later timing write corrects the mismatch. The checked-in tree lacks the optional
property, so the failure is conditional on a loader tree that supplies it.

board/novatek/na51089/na51089.c[89-95]
board/novatek/na51089/na51089.c[113-119]
board/novatek/na51089/na51089.c[124-134]
board/novatek/na51089/loader/Include/Driver/Memory.h[49-52]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The eFuse timing write uses the APB selector before the loader-requested APB clock change, leaving stale timing when the selected speed changes.
## Fix Focus Areas
- board/novatek/na51089/na51089.c[124-134]
- board/novatek/na51089/na51089.c[89-95]
## Recommended Fix
Keep the initial timing setup if needed for early initialization, but update the eFuse timing register using the new selector whenever the APB clock is changed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. A failed clock lock can still be selected ✓ Resolved
Description
nvt_wait_set() returns no success status when its bounded wait expires, so nvt_set_cpu_mhz() can
select PLL8 without confirming that it locked. A failed PLL status wait or clock-switch
acknowledgment therefore lets boot continue through a clock transition that was not confirmed.
Code

board/novatek/na51089/na51089.c[R49-51]

+	for (i = 0; i < 100000 && !(readl(reg) & mask); i++)
+		udelay(1);
+}
Evidence
The wait loop has a fixed limit and no result. Both the PLL-enable path and the clock-switch
handshake call it, then proceed unconditionally to their next register write.

board/novatek/na51089/na51089.c[44-60]
board/novatek/na51089/na51089.c[75-82]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The bounded clock waits silently expire, but their callers proceed with PLL selection or finish the clock-switch handshake.
## Fix Focus Areas
- board/novatek/na51089/na51089.c[44-60]
- board/novatek/na51089/na51089.c[63-87]
## Recommended Fix
Return a success or timeout result from the wait helper. Check PLL lock before selecting PLL8, including when it was already enabled, and check the clock-switch acknowledgment before completing the transition; report failure and avoid proceeding with an unconfirmed clock source.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can route each severity your way: inline, summary, both, or drop

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread board/novatek/na51089/na51089.c Resolved
Comment thread board/novatek/na51089/na51089.c Resolved
From the review of the board set-up:

- the waits return a status: the CPU is not switched to a PLL8 that did
  not lock (the clock stays as the loader left it, with a message), and
  an unacknowledged switch says so; the vendor waits for ever;
- the eFuse controller's timing is set again when the device tree
  changes the APB clock; the vendor leaves it at the old clock's. No
  Xiongmai tree names an APB clock, so this only matters for others.

Verified under qemu-hisilicon, nt98562 and nt98566: boot to login, a
3 MB tftpboot with matching crc32, ping, Linux's lease.
@dimerr
dimerr merged commit e49cdf2 into openipc-novatek Oct 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant