i.MX28 FEC Ethernet on DeviceTree with RMII PHY
Stuart Longland VK4MSL
me at vk4msl.com
Sun Jun 7 09:43:35 CEST 2026
On 5/6/26 14:47, Stuart Longland VK4MSL wrote:
>
> I'm re-visiting some old work I did back around 2015 or so, where I
> ported U-Boot to a Technologic Systems TS-7670 single-board computer.
>
…snip…
>
> Has anyone gotten a i.MX28 machine with RMII PHY talking on the network
> with current U-Boot and have some insights to share?
So after much cursing, I stumbled on the answer. The clock is
initialised in `cpu_eth_init` defined in `arch/arm/cpu/arm926ejs/mxs/mxs.c`.
With the deprecation of `board_eth_init()` this routine is never called,
so the clock never gets turned on.
No idea where I access the `bis` parameter this function theoretically
asks for, but in practice for the MXS series CPUs (i.MX23 and i.MX27)
the function actually never touches it, so we can pass `NULL` here. If
I do it in the board early init:
int board_early_init_f(void)
{
/* IO0 clock at 480MHz */
mxs_set_ioclk(MXC_IOCLK0, 480000);
/* IO1 clock at 480MHz */
mxs_set_ioclk(MXC_IOCLK1, 480000);
/* SSP clocks at 96MHz */
mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
/* SSP clocks at 96MHz */
mxs_set_sspclk(MXC_SSPCLK1, 96000, 0);
/* SSP2 clock at 160MHz */
mxs_set_sspclk(MXC_SSPCLK2, 160000, 0);
/* Power-cycle eMMC */
mxs_iomux_setup_pad(TS7670D_V2_EN_SDPWR);
gpio_direction_output(TS7670D_V2_EN_SDPWR, 1); // EN_SD_POWER#
udelay(1000);
gpio_direction_output(TS7670D_V2_EN_SDPWR, 0);
/* Wait a little bit for the card to wake up fully */
udelay(1000000);
/* Initialise Ethernet clocks */
cpu_eth_init(NULL);
return 0;
}
I see this in my console on boot:
HTLLCLLC
U-Boot 2026.07-rc3-00557-g082f0e9a2be0-dirty (Jun 07 2026 - 17:33:06 +1000)
CPU: Freescale i.MX28 rev1.2 at 454 MHz
BOOT: SSP SD/MMC #0, 3V3
Model: embeddedTS i.MX28 TS-7670 (Default Device Tree)
DRAM: 128 MiB
Core: 114 devices, 18 uclasses, devicetree: separate
WDT: Started watchdog at 78 with servicing every 1000ms (500s timeout)
MMC: MXS MMC: 0, MXS MMC: 1, MXS MMC: 2
Loading Environment from EXT4... OK
In: serial
Out: serial
Err: serial
Reading Ethernet address from fuses: 00:d0:69:49:ef:e3 ${enetaddr} set
Net: Enable RMII clock
Enable PHY
eth0: ethernet at 800f0000
Press Ctrl+C to abort autoboot in 2 second(s)
=> <INTERRUPT>
…and the Ethernet works!
=> mdio list
FEC0:
0 - SMSC LAN8710/LAN8720 <--> ethernet at 800f0000
=> mdio read 0
Reading from bus FEC0
PHY at address 0:
0 - 0x3000
=> dhcp
ethernet at 800f0000 Waiting for PHY auto negotiation to complete. done (5ms)
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
BOOTP broadcast 4
BOOTP broadcast 5
DHCP client bound to address 192.168.65.123 (4801 ms)
Using ethernet at 800f0000 device
TFTP from server 192.168.64.48; our IP address is 192.168.65.123
Filename 'netbsd-INSTALL32_IP3x'.
Load address: 0x42000000
Loading: *
ARP Retry count exceeded; starting again
=>
(Okay, it just tried and failed to load a NetBSD/sgimips image, but hey,
it wouldn't have known to try and load that file had it not spoken to my
DHCP server!)
So the question I guess remains, where is `cpu_eth_init` supposed to be
called, and how?
--
Stuart Longland (aka Redhatter, VK4MSL)
I haven't lost my mind...
...it's backed up on a tape somewhere.
More information about the U-Boot
mailing list