From ad9018e4090a6eac4503e91eb342838ae828772a Mon Sep 17 00:00:00 2001 From: Marcin Wojtas Date: Fri, 12 May 2017 19:43:01 +0200 Subject: Marvell/Drivers: Pp2Dxe: Rework PHY handling Hitherto PHY handling in Pp2Dxe was not flexible. It allowed for using only single MDIO controller, which may not be true on Armada 80x0 SoCs. For this purpose introduce the MDIO description, using the new structures and template in MvHwDescLib. This change enables addition of multiple CP110 hardware blocks with MDIO controllers. This change required different PHY handling and obtaining data over desired MDIO bus. Now given Pp2 port is matched with the PHY via its index in gMarvellTokenSpaceGuid.PcdPhyDeviceIds. The PHY itself is mapped to the MDIO controller, using gMarvellTokenSpaceGuid.PcdPhy2MdioController. Also obtaining SMI addresses was moved to the PHY initialization routine. All above allow for much cleaner and logical PHY description in the .dsc file, which now uses macros for connection type and speed. Update PortingGuide documentation accordingly and Armada 70x0 DB NIC/PHY description. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Marcin Wojtas Reviewed-by: Ard Biesheuvel Reviewed-by: Leif Lindholm --- Platform/Marvell/Armada/Armada.dsc.inc | 18 +++ Platform/Marvell/Armada/Armada70x0.dsc | 10 +- Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.c | 35 ++++-- .../Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf | 3 - .../Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c | 122 ++++++++++++--------- .../Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h | 2 - .../Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf | 4 +- Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.c | 16 +-- Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.h | 2 +- Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.inf | 4 +- Platform/Marvell/Include/Library/MvHwDescLib.h | 23 ++++ Platform/Marvell/Include/Protocol/Mdio.h | 6 + Platform/Marvell/Include/Protocol/MvPhy.h | 1 + Platform/Marvell/Marvell.dec | 8 +- Silicon/Marvell/Documentation/PortingGuide.txt | 66 +++++------ 15 files changed, 203 insertions(+), 117 deletions(-) diff --git a/Platform/Marvell/Armada/Armada.dsc.inc b/Platform/Marvell/Armada/Armada.dsc.inc index 7d0dc3916f..72580172df 100644 --- a/Platform/Marvell/Armada/Armada.dsc.inc +++ b/Platform/Marvell/Armada/Armada.dsc.inc @@ -524,6 +524,24 @@ DEFINE CP_RXAUI1 = 0x16 DEFINE CP_SFI = 0x17 + #Network interface speed + DEFINE PHY_SPEED_10 = 0x1 + DEFINE PHY_SPEED_100 = 0x2 + DEFINE PHY_SPEED_1000 = 0x3 + DEFINE PHY_SPEED_2500 = 0x4 + DEFINE PHY_SPEED_10000 = 0x5 + + #Network PHY type + DEFINE PHY_RGMII = 0x0 + DEFINE PHY_RGMII_ID = 0x1 + DEFINE PHY_RGMII_TXID = 0x2 + DEFINE PHY_RGMII_RXID = 0x3 + DEFINE PHY_SGMII = 0x4 + DEFINE PHY_RTBI = 0x5 + DEFINE PHY_XAUI = 0x6 + DEFINE PHY_RXAUI = 0x7 + DEFINE PHY_SFI = 0x8 + #UTMI PHY connection type DEFINE UTMI_USB_HOST0 = 0x0 DEFINE UTMI_USB_HOST1 = 0x1 diff --git a/Platform/Marvell/Armada/Armada70x0.dsc b/Platform/Marvell/Armada/Armada70x0.dsc index b40766b9e9..430803c593 100644 --- a/Platform/Marvell/Armada/Armada70x0.dsc +++ b/Platform/Marvell/Armada/Armada70x0.dsc @@ -115,18 +115,20 @@ gMarvellTokenSpaceGuid.PcdUtmiPortType|{ $(UTMI_USB_HOST0), $(UTMI_USB_HOST1) } #MDIO - gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0xF212A200 + gMarvellTokenSpaceGuid.PcdMdioControllersEnabled|{ 0x1, 0x0 } #PHY - gMarvellTokenSpaceGuid.PcdPhyConnectionTypes|{ 0x8, 0x4, 0x0 } + gMarvellTokenSpaceGuid.PcdPhy2MdioController|{ 0x0, 0x0 } gMarvellTokenSpaceGuid.PcdPhyDeviceIds|{ 0x0, 0x0 } + gMarvellTokenSpaceGuid.PcdPhySmiAddresses|{ 0x0, 0x1 } gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE #NET - gMarvellTokenSpaceGuid.PcdPhySmiAddresses|{ 0xff, 0x0, 0x1 } gMarvellTokenSpaceGuid.PcdPp2GopIndexes|{ 0x0, 0x2, 0x3 } gMarvellTokenSpaceGuid.PcdPp2InterfaceAlwaysUp|{ 0x0, 0x0, 0x0 } - gMarvellTokenSpaceGuid.PcdPp2InterfaceSpeed|{ 0x5, 0x3, 0x3 } + gMarvellTokenSpaceGuid.PcdPp2InterfaceSpeed|{ $(PHY_SPEED_10000), $(PHY_SPEED_1000), $(PHY_SPEED_1000) } + gMarvellTokenSpaceGuid.PcdPp2PhyConnectionTypes|{ $(PHY_SFI), $(PHY_SGMII), $(PHY_RGMII) } + gMarvellTokenSpaceGuid.PcdPp2PhyIndexes|{ 0xFF, 0x0, 0x1 } gMarvellTokenSpaceGuid.PcdPp2Port2Controller|{ 0x0, 0x0, 0x0 } gMarvellTokenSpaceGuid.PcdPp2PortIds|{ 0x0, 0x1, 0x2 } gMarvellTokenSpaceGuid.PcdPp2Controllers|{ 0x1 } diff --git a/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.c b/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.c index ae466d7019..12aabad0f3 100644 --- a/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.c +++ b/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.c @@ -46,7 +46,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "MvMdioDxe.h" -UINT64 MdioBase = 0; +DECLARE_A7K8K_MDIO_TEMPLATE; STATIC EFI_STATUS @@ -70,7 +70,7 @@ MdioCheckParam ( STATIC EFI_STATUS MdioWaitReady ( - VOID + UINT32 MdioBase ) { UINT32 Timeout = MVEBU_SMI_TIMEOUT; @@ -92,7 +92,7 @@ MdioWaitReady ( STATIC EFI_STATUS MdioWaitValid ( - VOID + UINT32 MdioBase ) { UINT32 Timeout = MVEBU_SMI_TIMEOUT; @@ -116,11 +116,13 @@ EFI_STATUS MdioOperation ( IN CONST MARVELL_MDIO_PROTOCOL *This, IN UINT32 PhyAddr, + IN UINT32 MdioIndex, IN UINT32 RegOff, IN BOOLEAN Write, IN OUT UINT32 *Data ) { + UINT32 MdioBase = This->BaseAddresses[MdioIndex]; UINT32 MdioReg; EFI_STATUS Status; @@ -131,7 +133,7 @@ MdioOperation ( } /* wait till the SMI is not busy */ - Status = MdioWaitReady (); + Status = MdioWaitReady (MdioBase); if (EFI_ERROR(Status)) { DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n")); return Status; @@ -151,7 +153,7 @@ MdioOperation ( MdioRegWrite32 (MdioReg, MdioBase); /* make sure that the write transaction is over */ - Status = Write ? MdioWaitReady () : MdioWaitValid (); + Status = Write ? MdioWaitReady (MdioBase) : MdioWaitValid (MdioBase); if (EFI_ERROR(Status)) { DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n")); return Status; @@ -169,6 +171,7 @@ EFI_STATUS MvMdioRead ( IN CONST MARVELL_MDIO_PROTOCOL *This, IN UINT32 PhyAddr, + IN UINT32 MdioIndex, IN UINT32 RegOff, IN UINT32 *Data ) @@ -178,6 +181,7 @@ MvMdioRead ( Status = MdioOperation ( This, PhyAddr, + MdioIndex, RegOff, FALSE, Data @@ -190,6 +194,7 @@ EFI_STATUS MvMdioWrite ( IN CONST MARVELL_MDIO_PROTOCOL *This, IN UINT32 PhyAddr, + IN UINT32 MdioIndex, IN UINT32 RegOff, IN UINT32 Data ) @@ -197,6 +202,7 @@ MvMdioWrite ( return MdioOperation ( This, PhyAddr, + MdioIndex, RegOff, TRUE, &Data @@ -210,18 +216,27 @@ MvMdioDxeInitialise ( IN EFI_SYSTEM_TABLE *SystemTable ) { + MVHW_MDIO_DESC *Desc = &mA7k8kMdioDescTemplate; + UINT8 Index; MARVELL_MDIO_PROTOCOL *Mdio; EFI_STATUS Status; EFI_HANDLE Handle = NULL; Mdio = AllocateZeroPool (sizeof (MARVELL_MDIO_PROTOCOL)); + if (Mdio == NULL) { + DEBUG ((DEBUG_ERROR, "MdioDxe: Protocol allocation failed\n")); + return EFI_OUT_OF_RESOURCES; + } + + /* Obtain base addresses of all possible controllers */ + for (Index = 0; Index < Desc->MdioDevCount; Index++) { + Mdio->BaseAddresses[Index] = Desc->MdioBaseAddresses[Index]; + } + + Mdio->ControllerCount = Desc->MdioDevCount; Mdio->Read = MvMdioRead; Mdio->Write = MvMdioWrite; - MdioBase = PcdGet64 (PcdMdioBaseAddress); - if (MdioBase == 0) { - DEBUG((DEBUG_ERROR, "MdioDxe: PcdMdioBaseAddress not set\n")); - return EFI_INVALID_PARAMETER; - } + Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gMarvellMdioProtocolGuid, Mdio, diff --git a/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf b/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf index faab1f70d2..d9878eb31a 100644 --- a/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf +++ b/Platform/Marvell/Drivers/Net/MvMdioDxe/MvMdioDxe.inf @@ -62,8 +62,5 @@ [Protocols] gMarvellMdioProtocolGuid -[Pcd] - gMarvellTokenSpaceGuid.PcdMdioBaseAddress - [Depex] TRUE diff --git a/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c b/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c index aeb6f7a01b..e776a91c1a 100644 --- a/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c +++ b/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c @@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include #include @@ -51,6 +52,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. STATIC MARVELL_MDIO_PROTOCOL *Mdio; +// +// Table with available Mdio controllers +// +STATIC UINT8 * CONST MdioDeviceTable = PcdGetPtr (PcdMdioControllersEnabled); +// +// Table with PHY to Mdio controller mappings +// +STATIC UINT8 * CONST Phy2MdioController = PcdGetPtr (PcdPhy2MdioController); +// +// Table with PHYs' SMI addresses +// +STATIC UINT8 * CONST PhySmiAddresses = PcdGetPtr (PcdPhySmiAddresses); + STATIC MV_PHY_DEVICE MvPhyDevices[] = { { MV_PHY_DEVICE_1512, MvPhyInit1512 }, { 0, NULL } @@ -64,18 +78,18 @@ MvPhyStatus ( EFI_STATUS MvPhyReset ( - IN UINT32 PhyAddr + IN PHY_DEVICE *PhyDev ) { UINT32 Reg = 0; INTN timeout = TIMEOUT; - Mdio->Read(Mdio, PhyAddr, MII_BMCR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMCR, &Reg); Reg |= BMCR_RESET; - Mdio->Write(Mdio, PhyAddr, MII_BMCR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMCR, Reg); while ((Reg & BMCR_RESET) && timeout--) { - Mdio->Read(Mdio, PhyAddr, MII_BMCR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMCR, &Reg); gBS->Stall(1000); } @@ -99,7 +113,7 @@ MvPhyM88e1111sConfig ( (PhyDev->Connection == PHY_CONNECTION_RGMII_ID) || (PhyDev->Connection == PHY_CONNECTION_RGMII_RXID) || (PhyDev->Connection == PHY_CONNECTION_RGMII_TXID)) { - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_CR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_CR, &Reg); if ((PhyDev->Connection == PHY_CONNECTION_RGMII) || (PhyDev->Connection == PHY_CONNECTION_RGMII_ID)) { @@ -112,9 +126,9 @@ MvPhyM88e1111sConfig ( Reg |= MIIM_88E1111_TX_DELAY; } - Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_CR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_CR, Reg); - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, &Reg); Reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); @@ -123,50 +137,50 @@ MvPhyM88e1111sConfig ( else Reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII; - Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, Reg); } if (PhyDev->Connection == PHY_CONNECTION_SGMII) { - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, &Reg); Reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); Reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK; Reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; - Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, Reg); } if (PhyDev->Connection == PHY_CONNECTION_RTBI) { - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_CR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_CR, &Reg); Reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); - Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_CR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_CR, Reg); - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, &Reg); Reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | MIIM_88E1111_HWCFG_FIBER_COPPER_RES); Reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; - Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, Reg); /* Soft reset */ - MvPhyReset(PhyDev->Addr); + MvPhyReset (PhyDev); - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, &Reg); Reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK | MIIM_88E1111_HWCFG_FIBER_COPPER_RES); Reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO; - Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1111_PHY_EXT_SR, Reg); } - Mdio->Read(Mdio, PhyDev->Addr, MII_BMCR, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMCR, &Reg); Reg |= (BMCR_ANENABLE | BMCR_ANRESTART); Reg &= ~BMCR_ISOLATE; - Mdio->Write(Mdio, PhyDev->Addr, MII_BMCR, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMCR, Reg); /* Soft reset */ - MvPhyReset(PhyDev->Addr); + MvPhyReset (PhyDev); - MvPhyReset(PhyDev->Addr); + MvPhyReset (PhyDev); return EFI_SUCCESS; } @@ -179,7 +193,7 @@ MvPhyParseStatus ( UINT32 Data; UINT32 Speed; - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS, &Data); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1xxx_PHY_STATUS, &Data); if ((Data & MIIM_88E1xxx_PHYSTAT_LINK) && !(Data & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { @@ -196,7 +210,7 @@ MvPhyParseStatus ( if ((i++ % 1000) == 0) DEBUG((DEBUG_ERROR, ".")); gBS->Stall(1000); - Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS, &Data); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MIIM_88E1xxx_PHY_STATUS, &Data); } DEBUG((DEBUG_ERROR," done\n")); gBS->Stall(500000); @@ -241,7 +255,7 @@ MvPhyParseStatus ( STATIC VOID MvPhy1512WriteBits ( - IN UINT32 PhyAddr, + IN PHY_DEVICE *PhyDev, IN UINT8 RegNum, IN UINT16 Offset, IN UINT16 Len, @@ -254,19 +268,18 @@ MvPhy1512WriteBits ( else Mask = (1 << (Len + Offset)) - (1 << Offset); - Mdio->Read(Mdio, PhyAddr, RegNum, &Reg); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, RegNum, &Reg); Reg &= ~Mask; Reg |= Data << Offset; - Mdio->Write(Mdio, PhyAddr, RegNum, Reg); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, RegNum, Reg); } STATIC EFI_STATUS MvPhyInit1512 ( IN CONST MARVELL_PHY_PROTOCOL *Snp, - IN UINT32 PhyAddr, IN OUT PHY_DEVICE *PhyDev ) { @@ -278,28 +291,28 @@ MvPhyInit1512 ( * Marvell Release Notes - Alaska 88E1510/88E1518/88E1512 Rev A0, * Errata Section 3.1 - needed in SGMII mode. */ - Mdio->Write(Mdio, PhyAddr, 22, 0x00ff); - Mdio->Write(Mdio, PhyAddr, 17, 0x214B); - Mdio->Write(Mdio, PhyAddr, 16, 0x2144); - Mdio->Write(Mdio, PhyAddr, 17, 0x0C28); - Mdio->Write(Mdio, PhyAddr, 16, 0x2146); - Mdio->Write(Mdio, PhyAddr, 17, 0xB233); - Mdio->Write(Mdio, PhyAddr, 16, 0x214D); - Mdio->Write(Mdio, PhyAddr, 17, 0xCC0C); - Mdio->Write(Mdio, PhyAddr, 16, 0x2159); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 22, 0x00ff); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 17, 0x214B); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 16, 0x2144); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 17, 0x0C28); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 16, 0x2146); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 17, 0xB233); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 16, 0x214D); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 17, 0xCC0C); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 16, 0x2159); /* Reset page selection and select page 0x12 */ - Mdio->Write(Mdio, PhyAddr, 22, 0x0000); - Mdio->Write(Mdio, PhyAddr, 22, 0x0012); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 22, 0x0000); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 22, 0x0012); /* Write HWCFG_MODE = SGMII to Copper */ - MvPhy1512WriteBits(PhyAddr, 20, 0, 3, 1); + MvPhy1512WriteBits(PhyDev, 20, 0, 3, 1); /* Phy reset - necessary after changing mode */ - MvPhy1512WriteBits(PhyAddr, 20, 15, 1, 1); + MvPhy1512WriteBits(PhyDev, 20, 15, 1, 1); /* Reset page selection */ - Mdio->Write(Mdio, PhyAddr, 22, 0x0000); + Mdio->Write (Mdio, PhyDev->Addr, PhyDev->MdioIndex, 22, 0x0000); gBS->Stall(100); } @@ -309,7 +322,7 @@ MvPhyInit1512 ( if (!PcdGetBool (PcdPhyStartupAutoneg)) return EFI_SUCCESS; - Mdio->Read(Mdio, PhyAddr, MII_BMSR, &Data); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMSR, &Data); if ((Data & BMSR_ANEGCAPABLE) && !(Data & BMSR_ANEGCOMPLETE)) { @@ -322,12 +335,12 @@ MvPhyInit1512 ( } gBS->Stall(1000); /* 1 ms */ - Mdio->Read(Mdio, PhyAddr, MII_BMSR, &Data); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMSR, &Data); } PhyDev->LinkUp = TRUE; DEBUG((DEBUG_INFO, "MvPhyDxe: link up\n")); } else { - Mdio->Read(Mdio, PhyAddr, MII_BMSR, &Data); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMSR, &Data); if (Data & BMSR_LSTATUS) { PhyDev->LinkUp = TRUE; @@ -345,7 +358,7 @@ MvPhyInit1512 ( EFI_STATUS MvPhyInit ( IN CONST MARVELL_PHY_PROTOCOL *Snp, - IN UINT32 PhyAddr, + IN UINT32 PhyIndex, IN PHY_CONNECTION PhyConnection, IN OUT PHY_DEVICE **OutPhyDev ) @@ -353,6 +366,7 @@ MvPhyInit ( EFI_STATUS Status; PHY_DEVICE *PhyDev; UINT8 *DeviceIds; + UINT8 MdioIndex; INTN i; Status = gBS->LocateProtocol ( @@ -363,12 +377,20 @@ MvPhyInit ( if (EFI_ERROR(Status)) return Status; + MdioIndex = Phy2MdioController[PhyIndex]; + + /* Verify correctness of PHY <-> MDIO assignment */ + if (!MVHW_DEV_ENABLED (Mdio, MdioIndex) || MdioIndex >= Mdio->ControllerCount) { + DEBUG ((DEBUG_ERROR, "MvPhyDxe: Incorrect Mdio controller assignment for PHY#%d", PhyIndex)); + return EFI_INVALID_PARAMETER; + } + /* perform setup common for all PHYs */ PhyDev = AllocateZeroPool (sizeof (PHY_DEVICE)); - PhyDev->Addr = PhyAddr; + PhyDev->Addr = PhySmiAddresses[PhyIndex]; PhyDev->Connection = PhyConnection; DEBUG((DEBUG_INFO, "MvPhyDxe: PhyAddr is %d, connection %d\n", - PhyAddr, PhyConnection)); + PhyDev->Addr, PhyConnection)); *OutPhyDev = PhyDev; DeviceIds = PcdGetPtr (PcdPhyDeviceIds); @@ -377,7 +399,7 @@ MvPhyInit ( if (MvPhyDevices[i].DevId == DeviceIds[i]) { ASSERT (MvPhyDevices[i].DevInit != NULL); /* proceed with PHY-specific initialization */ - return MvPhyDevices[i].DevInit(Snp, PhyAddr, PhyDev); + return MvPhyDevices[i].DevInit (Snp, PhyDev); } } @@ -395,8 +417,8 @@ MvPhyStatus ( { UINT32 Data; - Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR, &Data); - Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR, &Data); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMSR, &Data); + Mdio->Read (Mdio, PhyDev->Addr, PhyDev->MdioIndex, MII_BMSR, &Data); if ((Data & BMSR_LSTATUS) == 0) { PhyDev->LinkUp = FALSE; diff --git a/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h b/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h index 6bd06c52ed..0c3d935fbd 100644 --- a/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h +++ b/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h @@ -174,7 +174,6 @@ typedef EFI_STATUS (*MV_PHY_DEVICE_INIT) ( IN CONST MARVELL_PHY_PROTOCOL *Snp, - IN UINT32 PhyAddr, IN OUT PHY_DEVICE *PhyDev ); @@ -187,7 +186,6 @@ STATIC EFI_STATUS MvPhyInit1512 ( IN CONST MARVELL_PHY_PROTOCOL *Snp, - IN UINT32 PhyAddr, IN OUT PHY_DEVICE *PhyDev ); diff --git a/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf b/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf index c262ce42b5..2abd673ebe 100644 --- a/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf +++ b/Platform/Marvell/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf @@ -63,8 +63,10 @@ gMarvellPhyProtocolGuid [Pcd] - gMarvellTokenSpaceGuid.PcdPhyConnectionTypes + gMarvellTokenSpaceGuid.PcdMdioControllersEnabled + gMarvellTokenSpaceGuid.PcdPhy2MdioController gMarvellTokenSpaceGuid.PcdPhyDeviceIds + gMarvellTokenSpaceGuid.PcdPhySmiAddresses gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg [Depex] diff --git a/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.c b/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.c index 620bd5c189..2827976420 100644 --- a/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.c +++ b/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.c @@ -519,14 +519,14 @@ Pp2DxePhyInitialize ( return Status; } - if (Pp2Context->Port.PhyAddr == 0xff) { + if (Pp2Context->Port.PhyIndex == 0xff) { /* PHY iniitalization not required */ return EFI_SUCCESS; } Status = Pp2Context->Phy->Init( Pp2Context->Phy, - Pp2Context->Port.PhyAddr, + Pp2Context->Port.PhyIndex, Pp2Context->Port.PhyInterface, &Pp2Context->PhyDev ); @@ -1147,25 +1147,25 @@ Pp2DxeParsePortPcd ( IN INTN Index ) { - UINT8 *PortIds, *GopIndexes, *PhyConnectionTypes, *AlwaysUp, *Speed, *PhyAddresses; + UINT8 *PortIds, *GopIndexes, *PhyConnectionTypes, *AlwaysUp, *Speed, *PhyIndexes; PortIds = PcdGetPtr (PcdPp2PortIds); GopIndexes = PcdGetPtr (PcdPp2GopIndexes); - PhyConnectionTypes = PcdGetPtr (PcdPhyConnectionTypes); - PhyAddresses = PcdGetPtr (PcdPhySmiAddresses); + PhyConnectionTypes = PcdGetPtr (PcdPp2PhyConnectionTypes); + PhyIndexes = PcdGetPtr (PcdPp2PhyIndexes); AlwaysUp = PcdGetPtr (PcdPp2InterfaceAlwaysUp); Speed = PcdGetPtr (PcdPp2InterfaceSpeed); ASSERT (PcdGetSize (PcdPp2GopIndexes) == PcdGetSize (PcdPp2PortIds)); - ASSERT (PcdGetSize (PcdPhyConnectionTypes) == PcdGetSize (PcdPp2PortIds)); + ASSERT (PcdGetSize (PcdPp2PhyConnectionTypes) == PcdGetSize (PcdPp2PortIds)); ASSERT (PcdGetSize (PcdPp2InterfaceAlwaysUp) == PcdGetSize (PcdPp2PortIds)); ASSERT (PcdGetSize (PcdPp2InterfaceSpeed) == PcdGetSize (PcdPp2PortIds)); - ASSERT (PcdGetSize (PcdPhySmiAddresses) == PcdGetSize (PcdPp2PortIds)); + ASSERT (PcdGetSize (PcdPp2PhyIndexes) == PcdGetSize (PcdPp2PortIds)); Pp2Context->Port.Id = PortIds[Index]; Pp2Context->Port.GopIndex = GopIndexes[Index]; Pp2Context->Port.PhyInterface = PhyConnectionTypes[Index]; - Pp2Context->Port.PhyAddr = PhyAddresses[Index]; + Pp2Context->Port.PhyIndex = PhyIndexes[Index]; Pp2Context->Port.AlwaysUp = AlwaysUp[Index]; Pp2Context->Port.Speed = Speed[Index]; } diff --git a/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.h b/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.h index cde2995617..60f40be1f5 100644 --- a/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.h +++ b/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.h @@ -327,7 +327,7 @@ struct Pp2DxePort { UINT16 RxRingSize; INT32 PhyInterface; - UINTN PhyAddr; + UINT32 PhyIndex; BOOLEAN Link; BOOLEAN Duplex; BOOLEAN AlwaysUp; diff --git a/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.inf b/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.inf index 752fcc0400..b4568d89a9 100644 --- a/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.inf +++ b/Platform/Marvell/Drivers/Net/Pp2Dxe/Pp2Dxe.inf @@ -71,12 +71,12 @@ gMarvellPhyProtocolGuid [Pcd] - gMarvellTokenSpaceGuid.PcdPhyConnectionTypes - gMarvellTokenSpaceGuid.PcdPhySmiAddresses gMarvellTokenSpaceGuid.PcdPp2Controllers gMarvellTokenSpaceGuid.PcdPp2GopIndexes gMarvellTokenSpaceGuid.PcdPp2InterfaceAlwaysUp gMarvellTokenSpaceGuid.PcdPp2InterfaceSpeed + gMarvellTokenSpaceGuid.PcdPp2PhyConnectionTypes + gMarvellTokenSpaceGuid.PcdPp2PhyIndexes gMarvellTokenSpaceGuid.PcdPp2Port2Controller gMarvellTokenSpaceGuid.PcdPp2PortIds diff --git a/Platform/Marvell/Include/Library/MvHwDescLib.h b/Platform/Marvell/Include/Library/MvHwDescLib.h index 6ad1bc231e..9ae03d0bbd 100644 --- a/Platform/Marvell/Include/Library/MvHwDescLib.h +++ b/Platform/Marvell/Include/Library/MvHwDescLib.h @@ -69,6 +69,16 @@ typedef struct { UINTN I2cBaseAddresses[MVHW_MAX_I2C_DEVS]; } MVHW_I2C_DESC; +// +// MDIO devices description template definition +// +#define MVHW_MAX_MDIO_DEVS 2 + +typedef struct { + UINT8 MdioDevCount; + UINTN MdioBaseAddresses[MVHW_MAX_MDIO_DEVS]; +} MVHW_MDIO_DESC; + // // NonDiscoverable devices description template definition // @@ -167,6 +177,19 @@ MVHW_I2C_DESC mA7k8kI2cDescTemplate = {\ { MVHW_CP0_I2C0_BASE, MVHW_CP0_I2C1_BASE, MVHW_CP1_I2C0_BASE, MVHW_CP1_I2C1_BASE }\ } +// +// Platform description of MDIO devices +// +#define MVHW_CP0_MDIO_BASE 0xF212A200 +#define MVHW_CP1_MDIO_BASE 0xF412A200 + +#define DECLARE_A7K8K_MDIO_TEMPLATE \ +STATIC \ +MVHW_MDIO_DESC mA7k8kMdioDescTemplate = {\ + 2,\ + { MVHW_CP0_MDIO_BASE, MVHW_CP1_MDIO_BASE }\ +} + // // Platform description of NonDiscoverable devices // diff --git a/Platform/Marvell/Include/Protocol/Mdio.h b/Platform/Marvell/Include/Protocol/Mdio.h index 10acad4cc7..d077a8f74f 100644 --- a/Platform/Marvell/Include/Protocol/Mdio.h +++ b/Platform/Marvell/Include/Protocol/Mdio.h @@ -35,6 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef __MDIO_H__ #define __MDIO_H__ +#include + #define MARVELL_MDIO_PROTOCOL_GUID { 0x40010b03, 0x5f08, 0x496a, { 0xa2, 0x64, 0x10, 0x5e, 0x72, 0xd3, 0x71, 0xaa }} typedef struct _MARVELL_MDIO_PROTOCOL MARVELL_MDIO_PROTOCOL; @@ -44,6 +46,7 @@ EFI_STATUS (EFIAPI *MARVELL_MDIO_READ) ( IN CONST MARVELL_MDIO_PROTOCOL *This, IN UINT32 PhyAddr, + IN UINT32 MdioIndex, IN UINT32 RegOff, IN UINT32 *Data ); @@ -53,6 +56,7 @@ EFI_STATUS (EFIAPI *MARVELL_MDIO_WRITE) ( IN CONST MARVELL_MDIO_PROTOCOL *This, IN UINT32 PhyAddr, + IN UINT32 MdioIndex, IN UINT32 RegOff, IN UINT32 Data ); @@ -60,6 +64,8 @@ EFI_STATUS struct _MARVELL_MDIO_PROTOCOL { MARVELL_MDIO_READ Read; MARVELL_MDIO_WRITE Write; + UINTN BaseAddresses[MVHW_MAX_MDIO_DEVS]; + UINTN ControllerCount; }; extern EFI_GUID gMarvellMdioProtocolGuid; diff --git a/Platform/Marvell/Include/Protocol/MvPhy.h b/Platform/Marvell/Include/Protocol/MvPhy.h index a91759ae31..99c75b36a8 100644 --- a/Platform/Marvell/Include/Protocol/MvPhy.h +++ b/Platform/Marvell/Include/Protocol/MvPhy.h @@ -62,6 +62,7 @@ typedef enum { typedef struct { UINT32 Addr; + UINT8 MdioIndex; BOOLEAN LinkUp; BOOLEAN FullDuplex; BOOLEAN AutoNegotiation; diff --git a/Platform/Marvell/Marvell.dec b/Platform/Marvell/Marvell.dec index e23607fafe..0902086ba0 100644 --- a/Platform/Marvell/Marvell.dec +++ b/Platform/Marvell/Marvell.dec @@ -160,19 +160,21 @@ gMarvellTokenSpaceGuid.PcdUtmiPortType|{ 0x0 }|VOID*|0x30000207 #MDIO - gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0|UINT64|0x3000043 + gMarvellTokenSpaceGuid.PcdMdioControllersEnabled|{ 0x0 }|VOID*|0x3000043 #PHY - gMarvellTokenSpaceGuid.PcdPhyConnectionTypes|{ 0x0 }|VOID*|0x3000044 + gMarvellTokenSpaceGuid.PcdPhy2MdioController|{ 0x0 }|VOID*|0x3000027 gMarvellTokenSpaceGuid.PcdPhyDeviceIds|{ 0x0 }|VOID*|0x3000095 + gMarvellTokenSpaceGuid.PcdPhySmiAddresses|{ 0x0 }|VOID*|0x3000024 gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE|BOOLEAN|0x3000070 #NET - gMarvellTokenSpaceGuid.PcdPhySmiAddresses|{ 0x0 }|VOID*|0x3000024 gMarvellTokenSpaceGuid.PcdPp2Controllers|{ 0x0 }|VOID*|0x3000028 gMarvellTokenSpaceGuid.PcdPp2GopIndexes|{ 0x0 }|VOID*|0x3000029 gMarvellTokenSpaceGuid.PcdPp2InterfaceAlwaysUp|{ 0x0 }|VOID*|0x300002A gMarvellTokenSpaceGuid.PcdPp2InterfaceSpeed|{ 0x0 }|VOID*|0x300002B + gMarvellTokenSpaceGuid.PcdPp2PhyConnectionTypes|{ 0x0 }|VOID*|0x3000044 + gMarvellTokenSpaceGuid.PcdPp2PhyIndexes|{ 0x0 }|VOID*|0x3000045 gMarvellTokenSpaceGuid.PcdPp2Port2Controller|{ 0x0 }|VOID*|0x300002D gMarvellTokenSpaceGuid.PcdPp2PortIds|{ 0x0 }|VOID*|0x300002C diff --git a/Silicon/Marvell/Documentation/PortingGuide.txt b/Silicon/Marvell/Documentation/PortingGuide.txt index fa429d10f6..f0da5153fa 100644 --- a/Silicon/Marvell/Documentation/PortingGuide.txt +++ b/Silicon/Marvell/Documentation/PortingGuide.txt @@ -126,25 +126,15 @@ PHY Driver configuration MvPhyDxe provides basic initialization and status routines for Marvell PHYs. Currently only 1518 series PHYs are supported. Following PCDs are required: - - gMarvellTokenSpaceGuid.PcdPhyConnectionTypes - (list of values corresponding to PHY_CONNECTION enum) - gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg (boolean - if true, driver waits for autonegotiation on startup) - gMarvellTokenSpaceGuid.PcdPhyDeviceIds (list of values corresponding to MV_PHY_DEVICE_ID enum) + - gMarvellTokenSpaceGuid.PcdPhySmiAddresses + (addresses of PHY devices) + - gMarvellTokenSpaceGuid.PcdPhy2MdioController + (Array specifying, which Mdio controller the PHY is attached to) -PHY_CONNECTION enum type is defined as follows: - - typedef enum { - 0 PHY_CONNECTION_RGMII, - 1 PHY_CONNECTION_RGMII_ID, - 2 PHY_CONNECTION_RGMII_TXID, - 3 PHY_CONNECTION_RGMII_RXID, - 4 PHY_CONNECTION_SGMII, - 5 PHY_CONNECTION_RTBI, - 6 PHY_CONNECTION_XAUI, - 7 PHY_CONNECTION_RXAUI - } PHY_CONNECTION; MV_PHY_DEVICE_ID: @@ -153,11 +143,8 @@ MV_PHY_DEVICE_ID: } MV_PHY_DEVICE_ID; It should be extended when adding support for other PHY models. -Thus in order to set RGMII for 1st PHY and SGMII for 2nd, PCD should be: - - gMarvellTokenSpaceGuid.PcdPhyConnectionTypes|{ 0x0, 0x4 } -with disabled autonegotiation: +Disable autonegotiation: gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE @@ -171,8 +158,9 @@ MDIO configuration MDIO driver provides access to network PHYs' registers via EFI_MDIO_READ and EFI_MDIO_WRITE functions (EFI_MDIO_PROTOCOL). Following PCD is required: - - gMarvellTokenSpaceGuid.PcdMdioBaseAddress - (base address of SMI management register) + - gMarvellTokenSpaceGuid.PcdMdioControllers + (Array with used controllers + Set to 0x1 for enabled, 0x0 for disabled) I2C configuration @@ -249,8 +237,24 @@ are required to operate: - gMarvellTokenSpaceGuid.PcdPp2Port2Controller (Array specifying, to which controller the port belongs to) - - gMarvellTokenSpaceGuid.PcdPhySmiAddresses - (Addresses of PHY devices) + - gMarvellTokenSpaceGuid.PcdPp2PhyConnectionTypes + (Indicates speed of the network interface: + + PHY_RGMII 0x0 + PHY_RGMII_ID 0x1 + PHY_RGMII_TXID 0x2 + PHY_RGMII_RXID 0x3 + PHY_SGMII 0x4 + PHY_RTBI 0x5 + PHY_XAUI 0x6 + PHY_RXAUI 0x7 + PHY_SFI 0x8 ) + + - gMarvellTokenSpaceGuid.PcdPp2PhyIndexes + (Array specifying, to which PHY from + gMarvellTokenSpaceGuid.PcdPhyDeviceIds is used. If none, + e.g. in 10G SFI in-band link detection, 0xFF value must + be specified) - gMarvellTokenSpaceGuid.PcdPp2PortIds (Identificators of PP2 ports) @@ -262,17 +266,13 @@ are required to operate: (Set to 0x1 for always-up interface, 0x0 otherwise) - gMarvellTokenSpaceGuid.PcdPp2InterfaceSpeed - (Values corresponding to PHY_SPEED enum. - PHY_SPEED is defined as follows: - - typedef enum { - 0 NO_SPEED, - 1 SPEED_10, - 2 SPEED_100, - 3 SPEED_1000, - 4 SPEED_2500, - 5 SPEED_10000 - } PHY_SPEED; + (Indicates speed of the network interface: + + PHY_SPEED_10 0x1 + PHY_SPEED_100 0x2 + PHY_SPEED_1000 0x3 + PHY_SPEED_2500 0x4 + PHY_SPEED_10000 0x5 ) UTMI PHY configuration -- cgit v1.2.3