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