diff --git a/misoclib/com/liteeth/phy/gmii_mii.py b/misoclib/com/liteeth/phy/gmii_mii.py index 5cf8669d6..91a122d5f 100644 --- a/misoclib/com/liteeth/phy/gmii_mii.py +++ b/misoclib/com/liteeth/phy/gmii_mii.py @@ -1,10 +1,11 @@ from migen.genlib.io import DDROutput from migen.flow.plumbing import Multiplexer, Demultiplexer +from migen.genlib.cdc import MultiReg from misoclib.com.liteeth.common import * from misoclib.com.liteeth.generic import * -from misoclib.com.liteeth.phy.gmii import LiteEthPHYGMIIMIICRG +from misoclib.com.liteeth.phy.gmii import LiteEthPHYGMIICRG from misoclib.com.liteeth.phy.mii import LiteEthPHYMIITX, LiteEthPHYMIIRX from misoclib.com.liteeth.phy.gmii import LiteEthPHYGMIITX, LiteEthPHYGMIIRX @@ -67,6 +68,19 @@ class LiteEthPHYGMIIMIIRX(Module): Record.connect(mux.source, source) ] +class LiteEthGMIIMIIClockCounter(Module, AutoCSR): + def __init__(self): + self._reset = CSRStorage() + self._value = CSRStatus(32) + ### + counter = RenameClockDomains(Counter(32), "eth_rx") + self.submodules += counter + self.comb += [ + counter.reset.eq(self._reset.storage), #slow, don't need CDC + counter.ce.eq(1), + ] + self.specials += MultiReg(counter.value, self._value.status) + class LiteEthPHYGMIIMII(Module, AutoCSR): def __init__(self, clock_pads, pads, with_hw_init_reset=True): self.dw = 8 @@ -74,6 +88,7 @@ class LiteEthPHYGMIIMII(Module, AutoCSR): mode = self._mode.storage # Note: we can use GMII CRG since it also handles tx clock pad used for MII self.submodules.crg = LiteEthPHYGMIICRG(clock_pads, pads, with_hw_init_reset) + self.submodules.clock_counter = LiteEthGMIIMIIClockCounter() self.submodules.tx = RenameClockDomains(LiteEthPHYGMIIMIITX(pads, mode), "eth_tx") self.submodules.rx = RenameClockDomains(LiteEthPHYGMIIMIIRX(pads, mode), "eth_rx") self.sink, self.source = self.tx.sink, self.rx.source diff --git a/software/bios/main.c b/software/bios/main.c index 5c92b93e8..28f79dfc8 100644 --- a/software/bios/main.c +++ b/software/bios/main.c @@ -502,6 +502,9 @@ static void boot_sequence(void) flashboot(); #endif serialboot(); +#ifdef CSR_ETHPHY_MODE_ADDR + ethmode(); +#endif #ifdef CSR_ETHMAC_BASE netboot(); #endif diff --git a/software/include/net/microudp.h b/software/include/net/microudp.h index f9b339800..15c2a47dc 100644 --- a/software/include/net/microudp.h +++ b/software/include/net/microudp.h @@ -15,5 +15,6 @@ void microudp_set_callback(udp_callback callback); void microudp_service(void); void ethreset(void); +void ethmode(void); #endif /* __MICROUDP_H */ diff --git a/software/libnet/microudp.c b/software/libnet/microudp.c index 8720407e1..2e6bceb23 100644 --- a/software/libnet/microudp.c +++ b/software/libnet/microudp.c @@ -444,4 +444,27 @@ void ethreset(void) busy_wait(2); } +void ethmode(void) +{ + ethphy_clock_counter_reset_write(1); + busy_wait(1); + ethphy_clock_counter_reset_write(0); + busy_wait(1); + + printf("Ethernet phy mode: "); + /* if freq > 120 MHz, use GMII (5MHz margin)*/ + if (ethphy_clock_counter_value_read() > 120000000/10) { + ethphy_mode_write(0); + printf("GMII"); + /* else use MII */ + } else { + ethphy_mode_write(1); + printf("MII"); + } + printf("\n"); + + ethphy_clock_counter_reset_write(1); +} + #endif +