Hi,
Here is the third version of a patchset adding network preparation support for Armada 7040 SoC, i.e. SerDes, MDIO and PHY libraries. All comments from v2 are included, more details in changelog below.
The patches are also available in the public github tree: https://github.com/MarvellEmbeddedProcessors/edk2-open-platform/commits/opp-...
Any comments or remarks would be welcome.
Best regards, Marcin
Changelog: v2 -> v3
*ComPhyLib: - Move all calls to GetComPhyPcd macro to separate function, because of its embroiled structure - Clean-up
*MDIO driver - Rename folder Drivers/Net/MdioDxe -> Drivers/Net/MvMdioDxe
* PHY driver - Replace meaningless comments with more proper one - Unify values format written to the phy during intialization
v1 -> v2
* ComPhyLib - Remove obsolete support for Z1 chip - delete SerDes init sequence, which isn't longer executed - Break up long functions with lanes' power up sequence into smaller (atomic) ones - Update documenatation - Minor changes in namings
* MDIO and PHY Library - Change MdioRead interface (use better approach of error handling) - Renaming and sorting - Improve commit messages
* Others - Rebase on top of 07/30 linaro-opp master branch
Bartosz Szczepanek (6): Platforms/Marvell: Include common network modules on Armada SoC's Platforms/Marvell: Add MARVELL_MDIO_PROTOCOL Platforms/Marvell: Enable MDIO driver on Armada70x0 platform Platforms/Marvell: Add MARVELL_PHY_PROTOCOL Drivers/Net: Create PHY driver for Marvell platforms Platforms/Marvell: Enable PHY driver on Armada70x0 platform
Jan Dąbroś (2): Platforms/Marvell: Create ComPhyLib Platforms/Marvell: Enable ComPhy Lib for Armada70x0 platform
Documentation/Marvell/PortingGuide/ComPhy.txt | 85 ++ Documentation/Marvell/PortingGuide/Mdio.txt | 7 + Documentation/Marvell/PortingGuide/Phy.txt | 45 + Drivers/Net/MvMdioDxe/MvMdioDxe.c | 237 +++++ Drivers/Net/MvMdioDxe/MvMdioDxe.h | 57 ++ Drivers/Net/MvMdioDxe/MvMdioDxe.inf | 69 ++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c | 432 ++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h | 194 ++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf | 71 ++ Platforms/Marvell/Armada/Armada.dsc.inc | 20 +- Platforms/Marvell/Armada/Armada70x0.dsc | 20 + Platforms/Marvell/Armada/Armada70x0.fdf | 14 + .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 4 +- .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 1 + Platforms/Marvell/Include/Library/MvComPhyLib.h | 43 + Platforms/Marvell/Include/Protocol/Mdio.h | 66 ++ Platforms/Marvell/Include/Protocol/MvPhy.h | 103 ++ Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 1047 ++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 288 ++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 452 +++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 109 ++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 +++ Platforms/Marvell/Marvell.dec | 60 ++ 23 files changed, 3553 insertions(+), 3 deletions(-) create mode 100644 Documentation/Marvell/PortingGuide/ComPhy.txt create mode 100644 Documentation/Marvell/PortingGuide/Mdio.txt create mode 100644 Documentation/Marvell/PortingGuide/Phy.txt create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.c create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.h create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.inf create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf create mode 100644 Platforms/Marvell/Include/Library/MvComPhyLib.h create mode 100644 Platforms/Marvell/Include/Protocol/Mdio.h create mode 100644 Platforms/Marvell/Include/Protocol/MvPhy.h create mode 100755 Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c
From: Jan Dąbroś jsd@semihalf.com
Marvell SoC's comprise multiplexed pins for SerDes lanes (XHCI, AHCI, SGMII, PCIe) called ComPhy.
ComPhyLib initialize ComPhy and ComPhy Mux. All configurable parameters are provided via set of PCDs.
In order to satisfy preprocessor demands, there are ComPhy PCDs for all of 4 possible chips.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Documentation/Marvell/PortingGuide/ComPhy.txt | 85 ++ Platforms/Marvell/Include/Library/MvComPhyLib.h | 43 + Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 1047 +++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 288 ++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 452 +++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 109 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 +++ Platforms/Marvell/Marvell.dec | 50 + 8 files changed, 2206 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/ComPhy.txt create mode 100644 Platforms/Marvell/Include/Library/MvComPhyLib.h create mode 100755 Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c
diff --git a/Documentation/Marvell/PortingGuide/ComPhy.txt b/Documentation/Marvell/PortingGuide/ComPhy.txt new file mode 100644 index 0000000..b5c4727 --- /dev/null +++ b/Documentation/Marvell/PortingGuide/ComPhy.txt @@ -0,0 +1,85 @@ +COMPHY configuration +--------------------------- +In order to configure ComPhy library, following PCDs are available: + + gMarvellTokenSpaceGuid.PcdComPhyChipCount + +Indicates how many different chips are placed on board. So far, up to 4 chips +are supported. + +Every ComPhy PCD has <Num> part where <Num> stands for chip ID (order is not +important, but configuration will be set for first PcdComPhyChipCount chips). + +Every chip has 8 ComPhy PCDs and three of them concern lanes settings for this +chip. Below is example for the first chip (Chip0). + +General PCDs: + + gMarvellTokenSpaceGuid.PcdChip0Compatible + +Unicode string indicating type of chip - currently supported is +{ L"Cp110" } + + gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress + +Indicates COMPHY unit base address. + + gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress + +Indicates Hpipe3 unit base address. + + gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount + +Indicates number of bits that are allocated for every MUX in the +COMPHY-selector register. + + gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes + +Indicates maximum ComPhy lanes number. + +Next three PCDs are in unicode string format containing settings for up to 10 +lanes. Setting for each one is separated with semicolon. These PCDs form +structure describing outputs of PHY integrated in simple cihp. +Below is example for the first chip (Chip0). + + gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes + +Unicode string indicating PHY types. Currently supported are: + +{ L"unconnected", L"PCIE0", L"PCIE1", L"PCIE2", L"PCIE3", +L"SATA0", L"SATA1", L"SATA2", L"SATA3", L"SGMII0", +L"SGMII1", L"SGMII2", L"SGMII3", L"QSGMII", +L"USB3_HOST0", L"USB3_HOST1", L"USB3_DEVICE", +L"XAUI0", L"XAUI1", L"XAUI2", L"XAUI3", L"RXAUI0", +L"RXAUI1", L"KR" } + +Below documents describes some of above interfaces' types: + +SGMII, QSGMII, XAUI - IEEE 802.3 +KR - IEEE 802.3a +RXAUI - RXAUI Interface and RXAUI Adapter Specification, Marvell + + gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds + +Indicates PHY speeds in MHz. Currently supported are: + +{ 1250, 1500, 2500, 3000, 3125, 5000, 6000, 6250, 10310 } + + gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags + +Indicates lane polarity invert. + +Example +------- + #ComPhy + gMarvellTokenSpaceGuid.PcdComPhyChipCount|1 + + gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes|6 + gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress|0xF2441000 + gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress|0xF2120000 + gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount|4 + gMarvellTokenSpaceGuid.PcdChip0Compatible|L"Cp110" + + gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|L"SGMII2;USB3_HOST0;SGMII0;SATA1;USB3_HOST1;PCIE2" + gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|L"1250;5000;1250;5000;5000;5000" + diff --git a/Platforms/Marvell/Include/Library/MvComPhyLib.h b/Platforms/Marvell/Include/Library/MvComPhyLib.h new file mode 100644 index 0000000..6bd6243 --- /dev/null +++ b/Platforms/Marvell/Include/Library/MvComPhyLib.h @@ -0,0 +1,43 @@ +/******************************************************************************* +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#ifndef __MVCOMPHYLIB_H__ +#define __MVCOMPHYLIB_H__ + +EFI_STATUS +MvComPhyInit ( + VOID + ); + +#endif diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c new file mode 100755 index 0000000..df8731d --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c @@ -0,0 +1,1047 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must Retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include "ComPhyLib.h" + +#define SD_LANE_ADDR_WIDTH 0x1000 +#define HPIPE_ADDR_OFFSET 0x800 +#define COMPHY_ADDR_LANE_WIDTH 0x28 +#define SD_ADDR(base, Lane) (base + SD_LANE_ADDR_WIDTH * Lane) +#define HPIPE_ADDR(base, Lane) (SD_ADDR(base, Lane) + HPIPE_ADDR_OFFSET) +#define COMPHY_ADDR(base, Lane) (base + COMPHY_ADDR_LANE_WIDTH * Lane) + +/* + * For CP-110 we have 2 Selector registers "PHY Selectors" + * and " PIPE Selectors". + * PIPE selector include USB and PCIe options. + * PHY selector include the Ethernet and SATA options, every Ethernet option + * has different options, for example: serdes Lane2 had option Eth_port_0 + * that include (SGMII0, XAUI0, RXAUI0, KR) + */ +COMPHY_MUX_DATA Cp110ComPhyMuxData[] = { + /* Lane 0 */ + {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII2, 0x1}, + {PHY_TYPE_XAUI2, 0x1}, {PHY_TYPE_SATA1, 0x4} } }, + /* Lane 1 */ + {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII3, 0x1}, + {PHY_TYPE_XAUI3, 0x1}, {PHY_TYPE_SATA1, 0x4} } }, + /* Lane 2 */ + {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1}, + {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1}, + {PHY_TYPE_SATA0, 0x4} } }, + /* Lane 3 */ + {8, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1}, + {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1}, + {PHY_TYPE_XAUI1, 0x1}, {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SATA1, 0x4} } }, + /* Lane 4 */ + {7, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x2}, + {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1}, + {PHY_TYPE_SGMII2, 0x1}, {PHY_TYPE_XAUI2, 0x1} } }, + /* Lane 5 */ + {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_XAUI1, 0x1}, + {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SGMII3, 0x1}, {PHY_TYPE_XAUI3, 0x1}, + {PHY_TYPE_SATA1, 0x4} } }, +}; + +COMPHY_MUX_DATA Cp110ComPhyPipeMuxData[] = { + /* Lane 0 */ + {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PCIE0, 0x4} } }, + /* Lane 1 */ + {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST0, 0x1}, + {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PCIE0, 0x4} } }, + /* Lane 2 */ + {3, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST0, 0x1}, + {PHY_TYPE_PCIE0, 0x4} } }, + /* Lane 3 */ + {3, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST1, 0x1}, + {PHY_TYPE_PCIE0, 0x4} } }, + /* Lane 4 */ + {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST1, 0x1}, + {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PCIE1, 0x4} } }, + /* Lane 5 */ + {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PCIE2, 0x4} } }, +}; + +STATIC +VOID +ComPhyPcieRFUConfiguration ( + IN EFI_PHYSICAL_ADDRESS ComPhyAddr +) +{ + UINT32 Mask, Data; + + /* RFU configurations - hard reset ComPhy */ + Mask = COMMON_PHY_CFG1_PWR_UP_MASK; + Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; + Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; + Data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; + Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; + Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; + Mask |= COMMON_PHY_PHY_MODE_MASK; + Data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET; + RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask); + + /* Release from hard reset */ + Mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK; + Data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; + Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; + Data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; + RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask); + + /* Wait 1ms - until band gap and ref clock ready */ + MicroSecondDelay (1000); + MemoryFence (); +} + +STATIC +VOID +ComPhyPciePhyConfiguration ( + IN EFI_PHYSICAL_ADDRESS ComPhyAddr, + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + UINT32 Mask, Data, PcieClk = 0; + + /* Set PIPE soft reset */ + Mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK; + Data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET; + + /* Set PHY Datapath width mode for V0 */ + Mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK; + Data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET; + + /* Set Data bus width USB mode for V0 */ + Mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK; + Data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET; + + /* Set CORE_CLK output frequency for 250Mhz */ + Mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK; + Data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET; + RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, Data, Mask); + + /* Set PLL ready delay for 0x2 */ + RegSet (HpipeAddr + HPIPE_CLK_SRC_LO_REG, + 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET, + HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK); + + /* Set PIPE mode interface to PCIe3 - 0x1 */ + RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG, + 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET, HPIPE_CLK_SRC_HI_MODE_PIPE_MASK); + + /* Config update polarity equalization */ + RegSet (HpipeAddr + HPIPE_LANE_EQ_CFG1_REG, + 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET, HPIPE_CFG_UPDATE_POLARITY_MASK); + + /* Set PIPE version 4 to mode enable */ + RegSet (HpipeAddr + HPIPE_DFE_CTRL_28_REG, + 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET, HPIPE_DFE_CTRL_28_PIPE4_MASK); + + /* Enable PIN clock 100M_125M */ + Mask = HPIPE_MISC_CLK100M_125M_MASK; + Data = 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET; + + /* Set PIN_TXDCLK_2X Clock Frequency Selection for outputs 500MHz clock */ + Mask |= HPIPE_MISC_TXDCLK_2X_MASK; + Data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET; + + /* Enable 500MHz Clock */ + Mask |= HPIPE_MISC_CLK500_EN_MASK; + Data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET; + + if (PcieClk) { + /* Set reference clock comes from group 1 */ + Mask |= HPIPE_MISC_REFCLK_SEL_MASK; + Data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; + } else { + /* Set reference clock comes from group 2 */ + Mask |= HPIPE_MISC_REFCLK_SEL_MASK; + Data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET; + } + RegSet (HpipeAddr + HPIPE_MISC_REG, Data, Mask); + + if (PcieClk) { + /* Set reference frequcency select - 0x2 for 25MHz*/ + Mask = HPIPE_PWR_PLL_REF_FREQ_MASK; + Data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; + } else { + /* Set reference frequcency select - 0x0 for 100MHz*/ + Mask = HPIPE_PWR_PLL_REF_FREQ_MASK; + Data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; + } + + /* Set PHY mode to PCIe */ + Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; + Data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; + RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask); + + /* + * Set the amount of time spent in the LoZ state - set + * for 0x7 only if the PCIe clock is output + */ + if (PcieClk) + RegSet (HpipeAddr + HPIPE_GLOBAL_PM_CTRL, + 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET, + HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK); + + /* Set Maximal PHY Generation Setting (8Gbps) */ + Mask = HPIPE_INTERFACE_GEN_MAX_MASK; + Data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET; + + /* Set Link Train Mode (Tx training control pins are used) */ + Mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK; + Data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET; + RegSet (HpipeAddr + HPIPE_INTERFACE_REG, Data, Mask); + + /* Set Idle_sync enable */ + Mask = HPIPE_PCIE_IDLE_SYNC_MASK; + Data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET; + + /* Select bits for PCIE Gen3(32bit) */ + Mask |= HPIPE_PCIE_SEL_BITS_MASK; + Data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET; + RegSet (HpipeAddr + HPIPE_PCIE_REG0, Data, Mask); + + /* Enable Tx_adapt_g1 */ + Mask = HPIPE_TX_TRAIN_CTRL_G1_MASK; + Data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET; + + /* Enable Tx_adapt_gn1 */ + Mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK; + Data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET; + + /* Disable Tx_adapt_g0 */ + Mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK; + Data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET; + RegSet (HpipeAddr + HPIPE_TX_TRAIN_CTRL_REG, Data, Mask); + + /* Set reg_tx_train_chk_init */ + Mask = HPIPE_TX_TRAIN_CHK_INIT_MASK; + Data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET; + + /* Enable TX_COE_FM_PIN_PCIE3_EN */ + Mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK; + Data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET; + RegSet (HpipeAddr + HPIPE_TX_TRAIN_REG, Data, Mask); +} + +STATIC +VOID +ComPhyPciePhyPowerUp ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + /* Release from PIPE soft reset */ + RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, + 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, + HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); + + /* Wait 15ms - for ComPhy calibration done */ + MicroSecondDelay (15000); + MemoryFence (); +} + +STATIC +EFI_STATUS +ComPhyPcieCheckPll ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Data; + + /* Read Lane status */ + Data = MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG); + if ((Data & HPIPE_LANE_STATUS0_PCLK_EN_MASK) == 0) { + DEBUG((DEBUG_INFO, "ComPhy: Read from reg = %p - value = 0x%x\n", + HpipeAddr + HPIPE_LANE_STATUS0_REG, Data)); + DEBUG((DEBUG_INFO, "ComPhy: HPIPE_LANE_STATUS0_PCLK_EN_MASK is 0\n")); + Status = EFI_D_ERROR; + } + + return Status; +} + +STATIC +EFI_STATUS +ComPhyPciePowerUp ( + IN UINT32 Lane, + IN UINT32 PcieBy4, + IN EFI_PHYSICAL_ADDRESS HpipeBase, + IN EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane); + EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane); + + DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n")); + + ComPhyPcieRFUConfiguration (ComPhyAddr); + + DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n")); + + ComPhyPciePhyConfiguration (ComPhyAddr, HpipeAddr); + + DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n")); + + ComPhyPciePhyPowerUp (HpipeAddr); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n")); + + Status = ComPhyPcieCheckPll (HpipeAddr); + + return Status; +} + +STATIC +VOID +ComPhyUsb3RFUConfiguration ( + IN EFI_PHYSICAL_ADDRESS ComPhyAddr +) +{ + UINT32 Mask, Data; + + /* RFU configurations - hard reset ComPhy */ + Mask = COMMON_PHY_CFG1_PWR_UP_MASK; + Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; + Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; + Data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; + Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; + Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; + Mask |= COMMON_PHY_PHY_MODE_MASK; + Data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET; + RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask); + + /* Release from hard reset */ + Mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK; + Data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; + Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; + Data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; + RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask); + + /* Wait 1ms - until band gap and ref clock ready */ + MicroSecondDelay (1000); + MemoryFence (); +} + +STATIC +VOID +ComPhyUsb3PhyConfiguration ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + UINT32 Mask, Data; + + /* Set PIPE soft reset */ + Mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK; + Data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET; + + /* Set PHY Datapath width mode for V0 */ + Mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK; + Data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET; + + /* Set Data bus width USB mode for V0 */ + Mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK; + Data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET; + + /* Set CORE_CLK output frequency for 250Mhz */ + Mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK; + Data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET; + RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, Data, Mask); + + /* Set PLL ready delay for 0x2 */ + RegSet (HpipeAddr + HPIPE_CLK_SRC_LO_REG, + 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET, + HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK); + + /* Set reference clock to come from group 1 - 25Mhz */ + RegSet (HpipeAddr + HPIPE_MISC_REG, 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, + HPIPE_MISC_REFCLK_SEL_MASK); + + /* Set reference frequcency select - 0x2 */ + Mask = HPIPE_PWR_PLL_REF_FREQ_MASK; + Data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; + + /* Set PHY mode to USB - 0x5 */ + Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; + Data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; + RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask); + + /* Set the amount of time spent in the LoZ state - set for 0x7 */ + RegSet (HpipeAddr + HPIPE_GLOBAL_PM_CTRL, + 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET, + HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK); + + /* Set max PHY generation setting - 5Gbps */ + RegSet (HpipeAddr + HPIPE_INTERFACE_REG, + 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK); + + /* Set select Data width 20Bit (SEL_BITS[2:0]) */ + RegSet (HpipeAddr + HPIPE_LOOPBACK_REG, + 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK); +} + +STATIC +VOID +ComPhyUsb3SetAnalogParameters ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + UINT32 Data, Mask; + + /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */ + Mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK; + Data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET; + + /* Set Override PHY DFE control pins for 0x1 */ + Mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK; + Data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET; + + /* Set Spread Spectrum Clock Enable fot 0x1 */ + Mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK; + Data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET; + RegSet (HpipeAddr + HPIPE_LANE_CFG4_REG, Data, Mask); +} + +STATIC +UINTN +ComphyUsb3PowerUp ( + UINT32 Lane, + EFI_PHYSICAL_ADDRESS HpipeBase, + EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Data; + EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane); + EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane); + + DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n")); + + ComPhyUsb3RFUConfiguration (ComPhyAddr); + + /* Start ComPhy Configuration */ + DEBUG((DEBUG_INFO, "stage: Comphy configuration\n")); + + ComPhyUsb3PhyConfiguration (HpipeAddr); + + /* Start analog paramters from ETP(HW) */ + DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n")); + + ComPhyUsb3SetAnalogParameters (HpipeAddr); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy power up\n")); + + /* Release from PIPE soft reset */ + RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, + 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, + HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); + + /* Wait 15ms - for ComPhy calibration done */ + MicroSecondDelay (15000); + MemoryFence (); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n")); + + /* Read Lane status */ + Data = MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG); + if ((Data & HPIPE_LANE_STATUS0_PCLK_EN_MASK) == 0) { + DEBUG((DEBUG_ERROR, "ComPhy: HPIPE_LANE_STATUS0_PCLK_EN_MASK is 0\n")); + Status = EFI_D_ERROR; + } + + return Status; +} + +STATIC +UINT32 +PollingWithTimeout ( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT32 Val, + IN UINT32 Mask, + IN UINT64 Usec_timeout + ) +{ + UINT32 Data; + + do { + MicroSecondDelay(1); + Data = MmioRead32(Addr) & Mask; + } while (Data != Val && --Usec_timeout > 0); + + if (Usec_timeout == 0) + return Data; + return 0; +} + +STATIC +VOID +ComPhySataMacPowerDown ( + IN EFI_PHYSICAL_ADDRESS SataBase +) +{ + UINT32 Mask, Data; + + /* + * MAC configuration - power down ComPhy + * Use indirect address for vendor specific SATA control register + */ + RegSet (SataBase + SATA3_VENDOR_ADDRESS, + SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, SATA3_VENDOR_ADDR_MASK); + + /* SATA 0 power down */ + Mask = SATA3_CTRL_SATA0_PD_MASK; + Data = 0x1 << SATA3_CTRL_SATA0_PD_OFFSET; + + /* SATA 1 power down */ + Mask |= SATA3_CTRL_SATA1_PD_MASK; + Data |= 0x1 << SATA3_CTRL_SATA1_PD_OFFSET; + + /* SATA SSU disable */ + Mask |= SATA3_CTRL_SATA1_ENABLE_MASK; + Data |= 0x0 << SATA3_CTRL_SATA1_ENABLE_OFFSET; + + /* SATA port 1 disable */ + Mask |= SATA3_CTRL_SATA_SSU_MASK; + Data |= 0x0 << SATA3_CTRL_SATA_SSU_OFFSET; + RegSet (SataBase + SATA3_VENDOR_DATA, Data, Mask); +} + +STATIC +VOID +ComPhySataRFUConfiguration ( + IN EFI_PHYSICAL_ADDRESS ComPhyAddr, + IN EFI_PHYSICAL_ADDRESS SdIpAddr +) +{ + UINT32 Mask, Data; + + /* RFU configurations - hard reset ComPhy */ + Mask = COMMON_PHY_CFG1_PWR_UP_MASK; + Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; + Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; + Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET; + Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET; + RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask); + + /* Set select Data width 40Bit - SATA mode only */ + RegSet (ComPhyAddr + COMMON_PHY_CFG6_REG, + 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET, COMMON_PHY_CFG6_IF_40_SEL_MASK); + + /* Release from hard reset in SD external */ + Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; + Data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; + Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; + Data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; + RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask); + + /* Wait 1ms - until band gap and ref clock ready */ + MicroSecondDelay (1000); + MemoryFence (); +} + +STATIC +VOID +ComPhySataPhyConfiguration ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + UINT32 Mask, Data; + + /* Set reference clock to comes from group 1 - choose 25Mhz */ + RegSet (HpipeAddr + HPIPE_MISC_REG, + 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, HPIPE_MISC_REFCLK_SEL_MASK); + + /* Reference frequency select set 1 (for SATA = 25Mhz) */ + Mask = HPIPE_PWR_PLL_REF_FREQ_MASK; + Data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; + + /* PHY mode select (set SATA = 0x0 */ + Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; + Data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; + RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask); + + /* Set max PHY generation setting - 6Gbps */ + RegSet (HpipeAddr + HPIPE_INTERFACE_REG, + 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK); + + /* Set select Data width 40Bit (SEL_BITS[2:0]) */ + RegSet (HpipeAddr + HPIPE_LOOPBACK_REG, + 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK); +} + +STATIC +VOID +ComPhySataSetAnalogParameters ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + /* DFE reset sequence */ + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK); + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK); + + /* SW reset for interupt logic */ + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK); + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK); +} + +STATIC +VOID +ComPhySataPhyPowerUp ( + IN EFI_PHYSICAL_ADDRESS SataBase +) +{ + UINT32 Data, Mask; + + /* + * MAC configuration - power up ComPhy - power up PLL/TX/RX + * Use indirect address for vendor specific SATA control register + */ + RegSet (SataBase + SATA3_VENDOR_ADDRESS, + SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, SATA3_VENDOR_ADDR_MASK); + + /* SATA 0 power up */ + Mask = SATA3_CTRL_SATA0_PD_MASK; + Data = 0x0 << SATA3_CTRL_SATA0_PD_OFFSET; + + /* SATA 1 power up */ + Mask |= SATA3_CTRL_SATA1_PD_MASK; + Data |= 0x0 << SATA3_CTRL_SATA1_PD_OFFSET; + + /* SATA SSU enable */ + Mask |= SATA3_CTRL_SATA1_ENABLE_MASK; + Data |= 0x1 << SATA3_CTRL_SATA1_ENABLE_OFFSET; + + /* SATA port 1 enable */ + Mask |= SATA3_CTRL_SATA_SSU_MASK; + Data |= 0x1 << SATA3_CTRL_SATA_SSU_OFFSET; + RegSet (SataBase + SATA3_VENDOR_DATA, Data, Mask); + + /* MBUS request size and interface select register */ + RegSet (SataBase + SATA3_VENDOR_ADDRESS, + SATA_MBUS_SIZE_SELECT_REG << SATA3_VENDOR_ADDR_OFSSET, + SATA3_VENDOR_ADDR_MASK); + + /* Mbus regret enable */ + RegSet (SataBase + SATA3_VENDOR_DATA, 0x1 << SATA_MBUS_REGRET_EN_OFFSET, + SATA_MBUS_REGRET_EN_MASK); +} + +STATIC +EFI_STATUS +ComPhySataCheckPll ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr, + IN EFI_PHYSICAL_ADDRESS SdIpAddr +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Data,Mask; + IN EFI_PHYSICAL_ADDRESS Addr; + + Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG; + Data = SD_EXTERNAL_STATUS0_PLL_TX_MASK & SD_EXTERNAL_STATUS0_PLL_RX_MASK; + Mask = Data; + Data = PollingWithTimeout (Addr, Data, Mask, 15000); + + if (Data != 0) { + DEBUG((DEBUG_INFO, "ComPhy: Read from reg = %p - value = 0x%x\n", + HpipeAddr + HPIPE_LANE_STATUS0_REG, Data)); + DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_PLL_TX is %d, SD_EXTERNAL_STATUS0_PLL_RX is %d\n", + (Data & SD_EXTERNAL_STATUS0_PLL_TX_MASK), + (Data & SD_EXTERNAL_STATUS0_PLL_RX_MASK))); + Status = EFI_D_ERROR; + } + + return Status; +} + +STATIC +UINTN +ComPhySataPowerUp ( + IN UINT32 Lane, + IN EFI_PHYSICAL_ADDRESS HpipeBase, + IN EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane); + EFI_PHYSICAL_ADDRESS SdIpAddr = SD_ADDR(HpipeBase, Lane); + EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane); + EFI_PHYSICAL_ADDRESS SataBase; + + SataBase = PcdGet32 (PcdSataBaseAddress); + if (SataBase == 0) { + DEBUG((DEBUG_INFO, "ComPhy: SATA address not defined\n")); + return EFI_D_ERROR; + } + + DEBUG((DEBUG_INFO, "ComPhySataPowerUp: stage: MAC configuration - power down ComPhy\n")); + + ComPhySataMacPowerDown (SataBase); + + DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n")); + + ComPhySataRFUConfiguration (ComPhyAddr, SdIpAddr); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy configuration\n")); + + ComPhySataPhyConfiguration (HpipeAddr); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n")); + + ComPhySataSetAnalogParameters (HpipeAddr); + + DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n")); + + ComPhySataPhyPowerUp (SataBase); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n")); + + Status = ComPhySataCheckPll (HpipeAddr, SdIpAddr); + + return Status; +} + +STATIC +VOID +ComPhySgmiiRFUConfiguration ( + IN EFI_PHYSICAL_ADDRESS ComPhyAddr, + IN EFI_PHYSICAL_ADDRESS SdIpAddr, + IN UINT32 SgmiiSpeed +) +{ + UINT32 Mask, Data; + + Mask = COMMON_PHY_CFG1_PWR_UP_MASK; + Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET; + Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK; + Data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET; + RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask); + + /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */ + Mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; + Data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; + Mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK; + Mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK; + if (SgmiiSpeed == PHY_SPEED_1_25G) { + Data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; + Data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; + } else { + /* 3.125G */ + Data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET; + Data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET; + } + Mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; + Data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; + Mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; + Data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; + Mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK; + Data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET; + RegSet (SdIpAddr + SD_EXTERNAL_CONFIG0_REG, Data, Mask); + + /* Release from hard reset */ + Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; + Data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; + Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; + Data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; + Mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; + Data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; + RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask); + + /* Release from hard reset */ + Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK; + Data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET; + Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK; + Data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET; + RegSet (SdIpAddr+ SD_EXTERNAL_CONFIG1_REG, Data, Mask); + + /* Wait 1ms - until band gap and ref clock ready */ + MicroSecondDelay (1000); + MemoryFence (); +} + +STATIC +VOID +ComPhySgmiiPhyConfiguration ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr +) +{ + UINT32 Mask, Data; + + /* Set reference clock */ + Mask = HPIPE_MISC_REFCLK_SEL_MASK; + Data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET; + RegSet (HpipeAddr + HPIPE_MISC_REG, Data, Mask); + + /* Power and PLL Control */ + Mask = HPIPE_PWR_PLL_REF_FREQ_MASK; + Data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET; + Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK; + Data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET; + RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask); + + /* Loopback register */ + Mask = HPIPE_LOOPBACK_SEL_MASK; + Data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET; + RegSet (HpipeAddr + HPIPE_LOOPBACK_REG, Data, Mask); + + /* Rx control 1 */ + Mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK; + Data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET; + Mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK; + Data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET; + RegSet (HpipeAddr + HPIPE_RX_CONTROL_1_REG, Data, Mask); + + /* DTL Control */ + Mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK; + Data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET; + RegSet (HpipeAddr + HPIPE_PWR_CTR_DTL_REG, Data, Mask); +} + +STATIC +EFI_STATUS +ComPhySgmiiRFUPowerUp ( + IN EFI_PHYSICAL_ADDRESS SdIpAddr +) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Mask, Data; + EFI_PHYSICAL_ADDRESS Addr; + + /* SerDes External Configuration */ + Mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK; + Data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET; + Mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK; + Data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET; + Mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK; + Data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET; + RegSet (SdIpAddr + SD_EXTERNAL_CONFIG0_REG, Data, Mask); + + /* Check PLL rx & tx ready */ + Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG; + Data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | SD_EXTERNAL_STATUS0_PLL_TX_MASK; + Mask = Data; + Data = PollingWithTimeout (Addr, Data, Mask, 15000); + if (Data != 0) { + DEBUG((DEBUG_ERROR, "ComPhy: Read from reg = %p - value = 0x%x\n", + SdIpAddr + SD_EXTERNAL_STATUS0_REG, Data)); + DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n", + (Data & SD_EXTERNAL_STATUS0_PLL_RX_MASK), + (Data & SD_EXTERNAL_STATUS0_PLL_TX_MASK))); + Status = EFI_D_ERROR; + } + + /* RX init */ + Mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; + Data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; + RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask); + + /* Check that RX init done */ + Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG; + Data = SD_EXTERNAL_STATUS0_RX_INIT_MASK; + Mask = Data; + Data = PollingWithTimeout (Addr, Data, Mask, 100); + if (Data != 0) { + DEBUG((DEBUG_ERROR, "ComPhy: Read from reg = %p - value = 0x%x\n", + SdIpAddr + SD_EXTERNAL_STATUS0_REG, Data)); + DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_RX_INIT is 0\n")); + Status = EFI_D_ERROR; + } + Mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK; + Data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET; + Mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK; + Data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET; + RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask); + + return Status; +} + +STATIC +UINTN +ComPhySgmiiPowerUp ( + IN UINT32 Lane, + IN UINT32 SgmiiSpeed, + IN EFI_PHYSICAL_ADDRESS HpipeBase, + IN EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane); + EFI_PHYSICAL_ADDRESS SdIpAddr = SD_ADDR(HpipeBase, Lane); + EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane); + + DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n")); + + ComPhySgmiiRFUConfiguration (ComPhyAddr, SdIpAddr, SgmiiSpeed); + + DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n")); + + ComPhySgmiiPhyConfiguration (HpipeAddr); + + /* Set analog paramters from ETP(HW) - for now use the default data */ + DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n")); + + RegSet (HpipeAddr + HPIPE_G1_SET_0_REG, + 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET, HPIPE_G1_SET_0_G1_TX_EMPH1_MASK); + + DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - Power Up PLL,Tx,Rx\n")); + + Status = ComPhySgmiiRFUPowerUp (SdIpAddr); + + return Status; +} + +STATIC +VOID +ComPhyMuxCp110 ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg, + IN COMPHY_MAP *SerdesMap + ) +{ + EFI_PHYSICAL_ADDRESS ComPhyBaseAddr; + COMPHY_MAP ComPhyMapPipeData[MAX_LANE_OPTIONS]; + COMPHY_MAP ComPhyMapPhyData[MAX_LANE_OPTIONS]; + UINT32 Lane, ComPhyMaxCount; + + ComPhyMaxCount = PtrChipCfg->LanesCount; + ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr; + + /* + * Copy the SerDes map configuration for PIPE map and PHY map. + * The ComPhyMuxInit modifies the Type of the Lane if the Type is not valid. + * Because we have 2 selectors, run the ComPhyMuxInit twice and after + * that, update the original SerdesMap. + */ + for (Lane = 0; Lane < ComPhyMaxCount; Lane++) { + ComPhyMapPipeData[Lane].Type = SerdesMap[Lane].Type; + ComPhyMapPipeData[Lane].Speed = SerdesMap[Lane].Speed; + ComPhyMapPhyData[Lane].Type = SerdesMap[Lane].Type; + ComPhyMapPhyData[Lane].Speed = SerdesMap[Lane].Speed; + } + PtrChipCfg->MuxData = Cp110ComPhyMuxData; + ComPhyMuxInit(PtrChipCfg, ComPhyMapPhyData, ComPhyBaseAddr + + COMMON_SELECTOR_PHY_OFFSET); + + PtrChipCfg->MuxData = Cp110ComPhyPipeMuxData; + ComPhyMuxInit(PtrChipCfg, ComPhyMapPipeData, ComPhyBaseAddr + + COMMON_SELECTOR_PIPE_OFFSET); + + /* Fix the Type after check the PHY and PIPE configuration */ + for (Lane = 0; Lane < ComPhyMaxCount; Lane++) + if ((ComPhyMapPipeData[Lane].Type == PHY_TYPE_UNCONNECTED) && + (ComPhyMapPhyData[Lane].Type == PHY_TYPE_UNCONNECTED)) + SerdesMap[Lane].Type = PHY_TYPE_UNCONNECTED; +} + +EFI_STATUS +ComPhyCp110Init ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg + ) +{ + EFI_STATUS Status; + COMPHY_MAP *PtrComPhyMap, *SerdesMap; + EFI_PHYSICAL_ADDRESS ComPhyBaseAddr, HpipeBaseAddr; + UINT32 ComPhyMaxCount, Lane; + UINT32 PcieBy4 = 1; // Indicating if first 4 lanes set to PCIE + + ComPhyMaxCount = PtrChipCfg->LanesCount; + ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr; + HpipeBaseAddr = PtrChipCfg->Hpipe3BaseAddr; + SerdesMap = PtrChipCfg->MapData; + + /* Config Comphy mux configuration */ + ComPhyMuxCp110(PtrChipCfg, SerdesMap); + + /* Check if the first 4 Lanes configured as By-4 */ + for (Lane = 0, PtrComPhyMap = SerdesMap; Lane < 4; Lane++, PtrComPhyMap++) { + if (PtrComPhyMap->Type != PHY_TYPE_PCIE0) { + PcieBy4 = 0; + break; + } + } + + for (Lane = 0, PtrComPhyMap = SerdesMap; Lane < ComPhyMaxCount; + Lane++, PtrComPhyMap++) { + DEBUG((DEBUG_INFO, "ComPhy: Initialize serdes number %d\n", Lane)); + DEBUG((DEBUG_INFO, "ComPhy: Serdes Type = 0x%x\n", PtrComPhyMap->Type)); + switch (PtrComPhyMap->Type) { + case PHY_TYPE_UNCONNECTED: + continue; + break; + case PHY_TYPE_PCIE0: + case PHY_TYPE_PCIE1: + case PHY_TYPE_PCIE2: + case PHY_TYPE_PCIE3: + Status = ComPhyPciePowerUp(Lane, PcieBy4, HpipeBaseAddr, ComPhyBaseAddr); + break; + case PHY_TYPE_SATA0: + case PHY_TYPE_SATA1: + case PHY_TYPE_SATA2: + case PHY_TYPE_SATA3: + Status = ComPhySataPowerUp(Lane, HpipeBaseAddr, ComPhyBaseAddr); + break; + case PHY_TYPE_USB3_HOST0: + case PHY_TYPE_USB3_HOST1: + Status = ComphyUsb3PowerUp(Lane, HpipeBaseAddr, ComPhyBaseAddr); + break; + case PHY_TYPE_SGMII0: + case PHY_TYPE_SGMII1: + case PHY_TYPE_SGMII2: + case PHY_TYPE_SGMII3: + Status = ComPhySgmiiPowerUp(Lane, PtrComPhyMap->Speed, HpipeBaseAddr, + ComPhyBaseAddr); + break; + default: + DEBUG((DEBUG_ERROR, "Unknown SerDes Type, skip initialize SerDes %d\n", + Lane)); + break; + } + if (EFI_ERROR(Status)) + DEBUG((DEBUG_ERROR, "PLL is not locked - Failed to initialize Lane %d\n", + Lane)); + } + + return EFI_SUCCESS; +} diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c new file mode 100644 index 0000000..1b45bb7 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c @@ -0,0 +1,288 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include "ComPhyLib.h" + +CHAR16 * TypeStringTable [] = {L"unconnected", L"PCIE0", L"PCIE1", L"PCIE2", + L"PCIE3", L"SATA0", L"SATA1", L"SATA2", L"SATA3", + L"SGMII0", L"SGMII1", L"SGMII2", L"SGMII3", + L"QSGMII", L"USB3_HOST0", L"USB3_HOST1", + L"USB3_DEVICE", L"XAUI0", L"XAUI1", L"XAUI2", + L"XAUI3", L"RXAUI0", L"RXAUI1", L"KR"}; + +CHAR16 * SpeedStringTable [] = {L"-", L"1.25 Gbps", L"1.5 Gbps", L"2.5 Gbps", + L"3.0 Gbps", L"3.125 Gbps", L"5 Gbps", + L"6 Gbps", L"6.25 Gbps", L"10.31 Gbps"}; + +CHIP_COMPHY_CONFIG ChipCfgTbl[] = { + { + .ChipType = L"Cp110", + .Init = ComPhyCp110Init + } +}; + +VOID +RegSet ( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT32 Data, + IN UINT32 Mask + ) +{ + DEBUG((DEBUG_INFO, "Write to address = %10x, data = %10x (mask = %10x)" + "- ", Addr, Data, Mask)); + DEBUG((DEBUG_INFO, "old value = %10x ==> ", MmioRead32 (Addr))); + RegSetSilent (Addr, Data, Mask); + DEBUG((DEBUG_INFO, "new value %10x\n", MmioRead32 (Addr))); +} + +VOID +RegSetSilent ( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT32 Data, + IN UINT32 Mask + ) +{ + UINT32 RegData; + + RegData = MmioRead32 (Addr); + RegData &= ~Mask; + RegData |= Data; + MmioWrite32 (Addr, RegData); +} + +VOID +RegSet16 ( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT16 Data, + IN UINT16 Mask + ) +{ + DEBUG((DEBUG_INFO, "Write to address = %#010lx, Data = %#06x (mask = %#06x)" + "- ", Addr, Data, Mask)); + DEBUG((DEBUG_INFO, "old value = %#06x ==> ", MmioRead16 (Addr))); + RegSetSilent16 (Addr, Data, Mask); + DEBUG((DEBUG_INFO, "new value %#06x\n", MmioRead16 (Addr))); +} + +VOID +RegSetSilent16( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT16 Data, + IN UINT16 Mask + ) +{ + UINT16 RegData; + RegData = MmioRead16(Addr); + RegData &= ~Mask; + RegData |= Data; + MmioWrite16 (Addr, RegData); +} + +/* This function returns enum with SerDesType */ +UINT32 +ParseSerdesTypeString ( + CHAR16* String + ) +{ + UINT32 i; + + if (String == NULL) + return PHY_TYPE_INVALID; + + for (i = 0; i < PHY_TYPE_MAX; i++) { + if (StrCmp (String, TypeStringTable[i]) == 0) { + return i; + } + } + + /* PCD string doesn't match any supported SerDes Type */ + return PHY_TYPE_INVALID; +} + +/* This function converts SerDes speed in MHz to enum with SerDesSpeed */ +UINT32 +ParseSerdesSpeed ( + UINT32 Value + ) +{ + UINT32 i; + UINT32 ValueTable [] = {0, 1250, 1500, 2500, 3000, 3125, + 5000, 6000, 6250, 10310}; + + for (i = 0; i < 10; i++) { + if (Value == ValueTable[i]) { + return i; + } + } + + /* PCD SerDes speed value doesn't match any supported SerDes speed */ + return PHY_SPEED_INVALID; +} + +CHAR16 * +GetTypeString ( + UINT32 Type + ) +{ + + if (Type < 0 || Type > PHY_TYPE_MAX) { + return L"invalid"; + } + + return TypeStringTable[Type]; +} + +CHAR16 * +GetSpeedString ( + UINT32 Speed + ) +{ + + if (Speed < 0 || Speed > 10) { + return L"invalid"; + } + + return SpeedStringTable[Speed]; +} + +VOID +ComPhyPrint ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg + ) +{ + UINT32 Lane; + CHAR16 *SpeedStr, *TypeStr; + + for (Lane = 0; Lane < PtrChipCfg->LanesCount; Lane++) { + SpeedStr = GetSpeedString(PtrChipCfg->MapData[Lane].Speed); + TypeStr = GetTypeString(PtrChipCfg->MapData[Lane].Type); + DEBUG((DEBUG_ERROR, "Comphy-%d: %-13s %-10s\n", Lane, TypeStr, SpeedStr)); + } + + DEBUG((DEBUG_ERROR, "\n")); +} + +EFI_STATUS +GetChipComPhyInit ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg + ) +{ + UINTN i, TblSize; + + + TblSize = sizeof(ChipCfgTbl) / sizeof(ChipCfgTbl[0]); + + for (i = 0; i < TblSize ; i++) { + if (StrCmp (PtrChipCfg->ChipType, ChipCfgTbl[i].ChipType) == 0) { + PtrChipCfg->Init = ChipCfgTbl[i].Init; + return EFI_SUCCESS; + } + } + + DEBUG((DEBUG_ERROR, "ComPhy: Empty ChipType string\n")); + return EFI_D_ERROR; +} + +STATIC +VOID +InitComPhyConfig ( + IN OUT CHIP_COMPHY_CONFIG *ChipConfig, + IN OUT PCD_LANE_MAP *LaneData + ) +{ + /* + * Below macro contains variable name concatenation (used to form PCD's name) + * and that's why invoking it cannot be automated, e.g. using for loop. + * Currently up to 4 ComPhys might be configured. + */ + GetComPhyPcd(ChipConfig, LaneData, 0); + GetComPhyPcd(ChipConfig, LaneData, 1); + GetComPhyPcd(ChipConfig, LaneData, 2); + GetComPhyPcd(ChipConfig, LaneData, 3); +} + +EFI_STATUS +MvComPhyInit ( + VOID + ) +{ + EFI_STATUS Status; + CHIP_COMPHY_CONFIG ChipConfig[MAX_CHIPS], *PtrChipCfg; + PCD_LANE_MAP LaneData[MAX_CHIPS]; + UINT32 Lane, ChipCount, i, MaxComphyCount; + + ChipCount = PcdGet32 (PcdComPhyChipCount); + + InitComPhyConfig(ChipConfig, LaneData); + + if (ChipCount <= 0 || ChipCount > MAX_CHIPS) + return EFI_INVALID_PARAMETER; + + for (i = 0; i < ChipCount ; i++) { + PtrChipCfg = &ChipConfig[i]; + + /* Get the count of the SerDes of the specific chip */ + MaxComphyCount = PtrChipCfg->LanesCount; + for (Lane = 0; Lane < MaxComphyCount; Lane++) { + /* Parse PCD with string indicating SerDes Type */ + PtrChipCfg->MapData[Lane].Type = + ParseSerdesTypeString (LaneData[i].TypeStr[Lane]); + PtrChipCfg->MapData[Lane].Speed = + ParseSerdesSpeed (LaneData[i].SpeedValue[Lane]); + PtrChipCfg->MapData[Lane].Invert = (UINT32) LaneData[i].InvFlag[Lane]; + + if ((PtrChipCfg->MapData[Lane].Speed == PHY_SPEED_INVALID) || + (PtrChipCfg->MapData[Lane].Speed == PHY_SPEED_ERROR) || + (PtrChipCfg->MapData[Lane].Type == PHY_TYPE_INVALID)) { + DEBUG((DEBUG_ERROR, "ComPhy: No valid phy speed or type for lane %d, " + "setting lane as unconnected\n", Lane + 1)); + PtrChipCfg->MapData[Lane].Type = PHY_TYPE_UNCONNECTED; + PtrChipCfg->MapData[Lane].Speed = PHY_SPEED_INVALID; + } + }; + + Status = GetChipComPhyInit (PtrChipCfg); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "ComPhy: Invalid Chip%dType name\n", i)); + return Status; + } + + ComPhyPrint (PtrChipCfg); + + /* PHY power UP sequence */ + PtrChipCfg->Init (PtrChipCfg); + } + + return EFI_SUCCESS; +} diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h new file mode 100644 index 0000000..48cafc9 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h @@ -0,0 +1,452 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#ifndef __COMPHY_H__ +#define __COMPHY_H__ + +#include <Library/ArmLib.h> +#include <Library/ArmPlatformLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/TimerLib.h> +#include <Library/ParsePcdLib.h> + +#define MAX_LANE_OPTIONS 10 +#define MAX_CHIPS 4 + +/***** Parsing PCD *****/ +#define GET_TYPE_STRING(id) PcdGetPtr(PcdChip##id##Compatible) +#define GET_LANE_TYPE(id) PcdGetPtr(PcdChip##id##ComPhyTypes) +#define GET_LANE_SPEED(id) PcdGetPtr(PcdChip##id##ComPhySpeeds) +#define GET_LANE_INV(id) PcdGetPtr(PcdChip##id##ComPhyInvFlags) +#define GET_COMPHY_BASE_ADDR(id) PcdGet64(PcdChip##id##ComPhyBaseAddress) +#define GET_HPIPE3_BASE_ADDR(id) PcdGet64(PcdChip##id##Hpipe3BaseAddress) +#define GET_MUX_BIT_COUNT(id) PcdGet32(PcdChip##id##ComPhyMuxBitCount) +#define GET_MAX_LANES(id) PcdGet32(PcdChip##id##ComPhyMaxLanes) + +#define FillLaneMap(chip_struct, lane_struct, id) { \ + ParsePcdString((CHAR16 *) GET_LANE_TYPE(id), chip_struct[id].LanesCount, NULL, lane_struct[id].TypeStr); \ + ParsePcdString((CHAR16 *) GET_LANE_SPEED(id), chip_struct[id].LanesCount, lane_struct[id].SpeedValue, NULL); \ + ParsePcdString((CHAR16 *) GET_LANE_INV(id), chip_struct[id].LanesCount, lane_struct[id].InvFlag, NULL); \ +} + +#define GetComPhyPcd(chip_struct, lane_struct, id) { \ + chip_struct[id].ChipType = (CHAR16 *) GET_TYPE_STRING(id); \ + chip_struct[id].ComPhyBaseAddr = GET_COMPHY_BASE_ADDR(id); \ + chip_struct[id].Hpipe3BaseAddr = GET_HPIPE3_BASE_ADDR(id); \ + chip_struct[id].MuxBitCount = GET_MUX_BIT_COUNT(id); \ + chip_struct[id].LanesCount = GET_MAX_LANES(id); \ + FillLaneMap(chip_struct, lane_struct, id); \ +} + +/***** ComPhy *****/ +#define PHY_SPEED_ERROR 0 +#define PHY_SPEED_1_25G 1 +#define PHY_SPEED_1_5G 2 +#define PHY_SPEED_2_5G 3 +#define PHY_SPEED_3G 4 +#define PHY_SPEED_3_125G 5 +#define PHY_SPEED_5G 6 +#define PHY_SPEED_6G 7 +#define PHY_SPEED_6_25G 8 +#define PHY_SPEED_10_3125G 9 +#define PHY_SPEED_MAX 10 +#define PHY_SPEED_INVALID 0xff + +#define PHY_TYPE_UNCONNECTED 0 +#define PHY_TYPE_PCIE0 1 +#define PHY_TYPE_PCIE1 2 +#define PHY_TYPE_PCIE2 3 +#define PHY_TYPE_PCIE3 4 +#define PHY_TYPE_SATA0 5 +#define PHY_TYPE_SATA1 6 +#define PHY_TYPE_SATA2 7 +#define PHY_TYPE_SATA3 8 +#define PHY_TYPE_SGMII0 9 +#define PHY_TYPE_SGMII1 10 +#define PHY_TYPE_SGMII2 11 +#define PHY_TYPE_SGMII3 12 +#define PHY_TYPE_QSGMII 13 +#define PHY_TYPE_USB3_HOST0 14 +#define PHY_TYPE_USB3_HOST1 15 +#define PHY_TYPE_USB3_DEVICE 16 +#define PHY_TYPE_XAUI0 17 +#define PHY_TYPE_XAUI1 18 +#define PHY_TYPE_XAUI2 19 +#define PHY_TYPE_XAUI3 20 +#define PHY_TYPE_RXAUI0 21 +#define PHY_TYPE_RXAUI1 22 +#define PHY_TYPE_KR 23 +#define PHY_TYPE_MAX 24 +#define PHY_TYPE_INVALID 0xff + +#define PHY_POLARITY_NO_INVERT 0 +#define PHY_POLARITY_TXD_INVERT 1 +#define PHY_POLARITY_RXD_INVERT 2 +#define PHY_POLARITY_ALL_INVERT (PHY_POLARITY_TXD_INVERT | PHY_POLARITY_RXD_INVERT) + +/***** SerDes IP registers *****/ +#define SD_EXTERNAL_CONFIG0_REG 0 +#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET 1 +#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK (1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET 3 +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK (0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET 7 +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK (0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET 11 +#define SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK (1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET 12 +#define SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK (1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET) +#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET 14 +#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK (1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET) + +#define SD_EXTERNAL_CONFIG1_REG 0x4 +#define SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET 3 +#define SD_EXTERNAL_CONFIG1_RESET_IN_MASK (0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET) +#define SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET 4 +#define SD_EXTERNAL_CONFIG1_RX_INIT_MASK (0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET) +#define SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET 5 +#define SD_EXTERNAL_CONFIG1_RESET_CORE_MASK (0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET) +#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET 6 +#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK (0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET) + + +#define SD_EXTERNAL_STATUS0_REG 0x18 +#define SD_EXTERNAL_STATUS0_PLL_TX_OFFSET 2 +#define SD_EXTERNAL_STATUS0_PLL_TX_MASK (0x1 << SD_EXTERNAL_STATUS0_PLL_TX_OFFSET) +#define SD_EXTERNAL_STATUS0_PLL_RX_OFFSET 3 +#define SD_EXTERNAL_STATUS0_PLL_RX_MASK (0x1 << SD_EXTERNAL_STATUS0_PLL_RX_OFFSET) +#define SD_EXTERNAL_STATUS0_RX_INIT_OFFSET 4 +#define SD_EXTERNAL_STATUS0_RX_INIT_MASK (0x1 << SD_EXTERNAL_STATUS0_RX_INIT_OFFSET) + +/***** HPIPE registers *****/ +#define HPIPE_PWR_PLL_REG 0x4 +#define HPIPE_PWR_PLL_REF_FREQ_OFFSET 0 +#define HPIPE_PWR_PLL_REF_FREQ_MASK (0x1f << HPIPE_PWR_PLL_REF_FREQ_OFFSET) +#define HPIPE_PWR_PLL_PHY_MODE_OFFSET 5 +#define HPIPE_PWR_PLL_PHY_MODE_MASK (0x7 << HPIPE_PWR_PLL_PHY_MODE_OFFSET) + +#define HPIPE_KVCO_CALIB_CTRL_REG 0x8 +#define HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET 12 +#define HPIPE_KVCO_CALIB_CTRL_MAX_PLL_MASK (0x1 << HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET) + +#define HPIPE_SQUELCH_FFE_SETTING_REG 0x018 + +#define HPIPE_DFE_REG0 0x01C +#define HPIPE_DFE_RES_FORCE_OFFSET 15 +#define HPIPE_DFE_RES_FORCE_MASK (0x1 << HPIPE_DFE_RES_FORCE_OFFSET) + + +#define HPIPE_DFE_F3_F5_REG 0x028 +#define HPIPE_DFE_F3_F5_DFE_EN_OFFSET 14 +#define HPIPE_DFE_F3_F5_DFE_EN_MASK (0x1 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET) +#define HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET 15 +#define HPIPE_DFE_F3_F5_DFE_CTRL_MASK (0x1 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET) + +#define HPIPE_G1_SET_0_REG 0x034 +#define HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET 7 +#define HPIPE_G1_SET_0_G1_TX_EMPH1_MASK (0xf << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET) + +#define HPIPE_G1_SET_1_REG 0x038 +#define HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET 0 +#define HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK (0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET) +#define HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET 3 +#define HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK (0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET) +#define HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET 10 +#define HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK (0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET) + +#define HPIPE_G2_SETTINGS_1_REG 0x040 + +#define HPIPE_LOOPBACK_REG 0x08c +#define HPIPE_LOOPBACK_SEL_OFFSET 1 +#define HPIPE_LOOPBACK_SEL_MASK (0x7 << HPIPE_LOOPBACK_SEL_OFFSET) + +#define HPIPE_SYNC_PATTERN_REG 0x090 + +#define HPIPE_INTERFACE_REG 0x94 +#define HPIPE_INTERFACE_GEN_MAX_OFFSET 10 +#define HPIPE_INTERFACE_GEN_MAX_MASK (0x3 << HPIPE_INTERFACE_GEN_MAX_OFFSET) +#define HPIPE_INTERFACE_LINK_TRAIN_OFFSET 14 +#define HPIPE_INTERFACE_LINK_TRAIN_MASK (0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET) + +#define HPIPE_ISOLATE_MODE_REG 0x98 +#define HPIPE_ISOLATE_MODE_GEN_RX_OFFSET 0 +#define HPIPE_ISOLATE_MODE_GEN_RX_MASK (0xf << HPIPE_ISOLATE_MODE_GEN_RX_OFFSET) +#define HPIPE_ISOLATE_MODE_GEN_TX_OFFSET 4 +#define HPIPE_ISOLATE_MODE_GEN_TX_MASK (0xf << HPIPE_ISOLATE_MODE_GEN_TX_OFFSET) + +#define HPIPE_VTHIMPCAL_CTRL_REG 0x104 + +#define HPIPE_PCIE_REG0 0x120 +#define HPIPE_PCIE_IDLE_SYNC_OFFSET 12 +#define HPIPE_PCIE_IDLE_SYNC_MASK (0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET) +#define HPIPE_PCIE_SEL_BITS_OFFSET 13 +#define HPIPE_PCIE_SEL_BITS_MASK (0x3 << HPIPE_PCIE_SEL_BITS_OFFSET) + +#define HPIPE_LANE_ALIGN_REG 0x124 +#define HPIPE_LANE_ALIGN_OFF_OFFSET 12 +#define HPIPE_LANE_ALIGN_OFF_MASK (0x1 << HPIPE_LANE_ALIGN_OFF_OFFSET) + +#define HPIPE_MISC_REG 0x13C +#define HPIPE_MISC_CLK100M_125M_OFFSET 4 +#define HPIPE_MISC_CLK100M_125M_MASK (0x1 << HPIPE_MISC_CLK100M_125M_OFFSET) +#define HPIPE_MISC_TXDCLK_2X_OFFSET 6 +#define HPIPE_MISC_TXDCLK_2X_MASK (0x1 << HPIPE_MISC_TXDCLK_2X_OFFSET) +#define HPIPE_MISC_CLK500_EN_OFFSET 7 +#define HPIPE_MISC_CLK500_EN_MASK (0x1 << HPIPE_MISC_CLK500_EN_OFFSET) +#define HPIPE_MISC_REFCLK_SEL_OFFSET 10 +#define HPIPE_MISC_REFCLK_SEL_MASK (0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET) + +#define HPIPE_RX_CONTROL_1_REG 0x140 +#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET 11 +#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK (0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET) +#define HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET 12 +#define HPIPE_RX_CONTROL_1_CLK8T_EN_MASK (0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET) + +#define HPIPE_PWR_CTR_REG 0x148 +#define HPIPE_PWR_CTR_RST_DFE_OFFSET 0 +#define HPIPE_PWR_CTR_RST_DFE_MASK (0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET) +#define HPIPE_PWR_CTR_SFT_RST_OFFSET 10 +#define HPIPE_PWR_CTR_SFT_RST_MASK (0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET) + +#define HPIPE_PLLINTP_REG1 0x150 + +#define HPIPE_PWR_CTR_DTL_REG 0x184 +#define HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET 0x2 +#define HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK (0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET) + +#define HPIPE_RX_REG3 0x188 + +#define HPIPE_TX_TRAIN_CTRL_REG 0x26C +#define HPIPE_TX_TRAIN_CTRL_G1_OFFSET 0 +#define HPIPE_TX_TRAIN_CTRL_G1_MASK (0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET) +#define HPIPE_TX_TRAIN_CTRL_GN1_OFFSET 1 +#define HPIPE_TX_TRAIN_CTRL_GN1_MASK (0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET) +#define HPIPE_TX_TRAIN_CTRL_G0_OFFSET 2 +#define HPIPE_TX_TRAIN_CTRL_G0_MASK (0x1 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET) + +#define HPIPE_PCIE_REG1 0x288 +#define HPIPE_PCIE_REG3 0x290 + +#define HPIPE_TX_TRAIN_REG 0x31C +#define HPIPE_TX_TRAIN_CHK_INIT_OFFSET 4 +#define HPIPE_TX_TRAIN_CHK_INIT_MASK (0x1 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET) +#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET 7 +#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK (0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET) + +#define HPIPE_G1_SETTINGS_3_REG 0x440 +#define HPIPE_G1_SETTINGS_4_REG 0x444 +#define HPIPE_G2_SETTINGS_3_REG 0x448 +#define HPIPE_G2_SETTINGS_4_REG 0x44C + +#define HPIPE_DFE_CTRL_28_REG 0x49C +#define HPIPE_DFE_CTRL_28_PIPE4_OFFSET 7 +#define HPIPE_DFE_CTRL_28_PIPE4_MASK (0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET) + +#define HPIPE_LANE_CONFIG0_REG 0x604 +#define HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET 9 +#define HPIPE_LANE_CONFIG0_MAX_PLL_MASK (0x1 << HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET) +#define HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET 10 +#define HPIPE_LANE_CONFIG0_GEN2_PLL_MASK (0x1 << HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET) + +#define HPIPE_LANE_STATUS0_REG 0x60C +#define HPIPE_LANE_STATUS0_PCLK_EN_OFFSET 0 +#define HPIPE_LANE_STATUS0_PCLK_EN_MASK (0x1 << HPIPE_LANE_STATUS0_PCLK_EN_OFFSET) + +#define HPIPE_LANE_CFG4_REG 0x620 +#define HPIPE_LANE_CFG4_DFE_CTRL_OFFSET 0 +#define HPIPE_LANE_CFG4_DFE_CTRL_MASK (0x7 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET) +#define HPIPE_LANE_CFG4_DFE_OVER_OFFSET 6 +#define HPIPE_LANE_CFG4_DFE_OVER_MASK (0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET) +#define HPIPE_LANE_CFG4_SSC_CTRL_OFFSET 7 +#define HPIPE_LANE_CFG4_SSC_CTRL_MASK (0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET) + +#define HPIPE_LANE_EQ_CFG1_REG 0x6a0 +#define HPIPE_CFG_UPDATE_POLARITY_OFFSET 12 +#define HPIPE_CFG_UPDATE_POLARITY_MASK (0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET) + +#define HPIPE_RST_CLK_CTRL_REG 0x704 +#define HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET 0 +#define HPIPE_RST_CLK_CTRL_PIPE_RST_MASK (0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET) +#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET 2 +#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK (0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET) +#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET 3 +#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK (0x1 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET) +#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET 9 +#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK (0x1 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET) + +#define HPIPE_CLK_SRC_LO_REG 0x70c +#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET 5 +#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK (0x7 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET) + +#define HPIPE_CLK_SRC_HI_REG 0x710 +#define HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET 0 +#define HPIPE_CLK_SRC_HI_LANE_STRT_MASK (0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET) +#define HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET 1 +#define HPIPE_CLK_SRC_HI_LANE_BREAK_MASK (0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET) +#define HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET 2 +#define HPIPE_CLK_SRC_HI_LANE_MASTER_MASK (0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET) +#define HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET 7 +#define HPIPE_CLK_SRC_HI_MODE_PIPE_MASK (0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET) + +#define HPIPE_GLOBAL_MISC_CTRL 0x718 +#define HPIPE_GLOBAL_PM_CTRL 0x740 +#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET 0 +#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK (0xFF << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET) + +/***** COMPHY registers *****/ +#define COMMON_PHY_CFG1_REG 0x0 +#define COMMON_PHY_CFG1_PWR_UP_OFFSET 1 +#define COMMON_PHY_CFG1_PWR_UP_MASK (0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET) +#define COMMON_PHY_CFG1_PIPE_SELECT_OFFSET 2 +#define COMMON_PHY_CFG1_PIPE_SELECT_MASK (0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET) +#define COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET 13 +#define COMMON_PHY_CFG1_PWR_ON_RESET_MASK (0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET) +#define COMMON_PHY_CFG1_CORE_RSTN_OFFSET 14 +#define COMMON_PHY_CFG1_CORE_RSTN_MASK (0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET) +#define COMMON_PHY_PHY_MODE_OFFSET 15 +#define COMMON_PHY_PHY_MODE_MASK (0x1 << COMMON_PHY_PHY_MODE_OFFSET) + +#define COMMON_PHY_CFG6_REG 0x14 +#define COMMON_PHY_CFG6_IF_40_SEL_OFFSET 18 +#define COMMON_PHY_CFG6_IF_40_SEL_MASK (0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET) + +#define COMMON_SELECTOR_PHY_OFFSET 0x140 +#define COMMON_SELECTOR_PIPE_OFFSET 0x144 + +/***** SATA registers *****/ +#define SATA3_VENDOR_ADDRESS 0xA0 +#define SATA3_VENDOR_ADDR_OFSSET 0 +#define SATA3_VENDOR_ADDR_MASK (0xFFFFFFFF << SATA3_VENDOR_ADDR_OFSSET) +#define SATA3_VENDOR_DATA 0xA4 + +#define SATA_CONTROL_REG 0x0 +#define SATA3_CTRL_SATA0_PD_OFFSET 6 +#define SATA3_CTRL_SATA0_PD_MASK (1 << SATA3_CTRL_SATA0_PD_OFFSET) +#define SATA3_CTRL_SATA1_PD_OFFSET 14 +#define SATA3_CTRL_SATA1_PD_MASK (1 << SATA3_CTRL_SATA1_PD_OFFSET) +#define SATA3_CTRL_SATA1_ENABLE_OFFSET 22 +#define SATA3_CTRL_SATA1_ENABLE_MASK (1 << SATA3_CTRL_SATA1_ENABLE_OFFSET) +#define SATA3_CTRL_SATA_SSU_OFFSET 23 +#define SATA3_CTRL_SATA_SSU_MASK (1 << SATA3_CTRL_SATA_SSU_OFFSET) + +#define SATA_MBUS_SIZE_SELECT_REG 0x4 +#define SATA_MBUS_REGRET_EN_OFFSET 7 +#define SATA_MBUS_REGRET_EN_MASK (0x1 << SATA_MBUS_REGRET_EN_OFFSET) + +/***************************/ + +typedef struct _CHIP_COMPHY_CONFIG CHIP_COMPHY_CONFIG; + +typedef struct { + UINT32 Type; + UINT32 MuxValue; +} COMPHY_MUX_OPTIONS; + +typedef struct { + UINT32 MaxLaneValues; + COMPHY_MUX_OPTIONS MuxValues[MAX_LANE_OPTIONS]; +} COMPHY_MUX_DATA; + +typedef struct { + UINT32 Type; + UINT32 Speed; + UINT32 Invert; +} COMPHY_MAP; + +typedef struct { + CHAR16 *TypeStr[MAX_LANE_OPTIONS]; + UINTN SpeedValue[MAX_LANE_OPTIONS]; + UINTN InvFlag[MAX_LANE_OPTIONS]; +} PCD_LANE_MAP; + +typedef +EFI_STATUS +(*COMPHY_CHIP_INIT) ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg + ); + +struct _CHIP_COMPHY_CONFIG { + CHAR16* ChipType; + COMPHY_MAP MapData[MAX_LANE_OPTIONS]; + COMPHY_MUX_DATA *MuxData; + EFI_PHYSICAL_ADDRESS ComPhyBaseAddr; + EFI_PHYSICAL_ADDRESS Hpipe3BaseAddr; + COMPHY_CHIP_INIT Init; + UINT32 LanesCount; + UINT32 MuxBitCount; +}; + +VOID +ComPhyMuxInit ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg, + IN COMPHY_MAP *ComPhyMapData, + IN EFI_PHYSICAL_ADDRESS SelectorBase + ); + +EFI_STATUS +ComPhyCp110Init ( + IN CHIP_COMPHY_CONFIG * First + ); + +VOID +RegSet ( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT32 Data, + IN UINT32 Mask + ); + +VOID +RegSetSilent ( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT32 Data, + IN UINT32 Mask + ); + +VOID +RegSet16 ( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT16 Data, + IN UINT16 Mask + ); + +VOID +RegSetSilent16( + IN EFI_PHYSICAL_ADDRESS Addr, + IN UINT16 Data, + IN UINT16 Mask + ); +#endif // __COMPHY_H__ diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf new file mode 100644 index 0000000..a7ee1f8 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf @@ -0,0 +1,109 @@ +# Copyright (C) 2016 Marvell International Ltd. +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute and/or +# modify this File under the following licensing terms. +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Marvell nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MarvellComPhyLib + FILE_GUID = 3314541a-9647-4a37-b8c6-24e000900e4e + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ComPhyLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + ArmLib + DebugLib + MemoryAllocationLib + PcdLib + IoLib + ParsePcdLib + +[Sources.common] + ComPhyLib.c + ComPhyCp110.c + ComPhyMux.c + +[FixedPcd] + gMarvellTokenSpaceGuid.PcdComPhyChipCount + + #Chip0 + gMarvellTokenSpaceGuid.PcdChip0Compatible + gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress + gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress + gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount + gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes + + gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes + gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds + gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags + + #Chip1 + gMarvellTokenSpaceGuid.PcdChip1Compatible + gMarvellTokenSpaceGuid.PcdChip1ComPhyBaseAddress + gMarvellTokenSpaceGuid.PcdChip1Hpipe3BaseAddress + gMarvellTokenSpaceGuid.PcdChip1ComPhyMuxBitCount + gMarvellTokenSpaceGuid.PcdChip1ComPhyMaxLanes + + gMarvellTokenSpaceGuid.PcdChip1ComPhyTypes + gMarvellTokenSpaceGuid.PcdChip1ComPhySpeeds + gMarvellTokenSpaceGuid.PcdChip1ComPhyInvFlags + + #Chip2 + gMarvellTokenSpaceGuid.PcdChip2Compatible + gMarvellTokenSpaceGuid.PcdChip2ComPhyBaseAddress + gMarvellTokenSpaceGuid.PcdChip2Hpipe3BaseAddress + gMarvellTokenSpaceGuid.PcdChip2ComPhyMuxBitCount + gMarvellTokenSpaceGuid.PcdChip2ComPhyMaxLanes + + gMarvellTokenSpaceGuid.PcdChip2ComPhyTypes + gMarvellTokenSpaceGuid.PcdChip2ComPhySpeeds + gMarvellTokenSpaceGuid.PcdChip2ComPhyInvFlags + + #Chip3 + gMarvellTokenSpaceGuid.PcdChip3Compatible + gMarvellTokenSpaceGuid.PcdChip3ComPhyBaseAddress + gMarvellTokenSpaceGuid.PcdChip3Hpipe3BaseAddress + gMarvellTokenSpaceGuid.PcdChip3ComPhyMuxBitCount + gMarvellTokenSpaceGuid.PcdChip3ComPhyMaxLanes + + gMarvellTokenSpaceGuid.PcdChip3ComPhyTypes + gMarvellTokenSpaceGuid.PcdChip3ComPhySpeeds + gMarvellTokenSpaceGuid.PcdChip3ComPhyInvFlags + + #SATA + gMarvellTokenSpaceGuid.PcdSataBaseAddress diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c new file mode 100644 index 0000000..595745b --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c @@ -0,0 +1,132 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include "ComPhyLib.h" + +STATIC +VOID +ComPhyMuxCheckConfig ( + IN COMPHY_MUX_DATA *MuxData, + IN COMPHY_MAP *ComPhyMapData, + IN UINTN ComPhyMaxLanes + ) +{ + COMPHY_MUX_OPTIONS *PtrMuxOpt; + UINTN Lane, Opt, Valid; + + for (Lane = 0; Lane < ComPhyMaxLanes; Lane++, ComPhyMapData++, MuxData++) { + PtrMuxOpt = MuxData->MuxValues; + for (Opt = 0, Valid = 0; Opt < MuxData->MaxLaneValues; Opt++, PtrMuxOpt++) { + if (PtrMuxOpt->Type == ComPhyMapData->Type) { + Valid = 1; + break; + } + } + if (Valid == 0) { + DEBUG((DEBUG_INFO, "Lane number %d, had invalid Type %d\n", Lane, + ComPhyMapData->Type)); + DEBUG((DEBUG_INFO, "Set Lane %d as Type %d\n", Lane, + PHY_TYPE_UNCONNECTED)); + ComPhyMapData->Type = PHY_TYPE_UNCONNECTED; + } else { + DEBUG((DEBUG_INFO, "Lane number %d, has Type %d\n", Lane, + ComPhyMapData->Type)); + } + } +} + +STATIC +UINT32 +ComPhyMuxGetMuxValue ( + IN COMPHY_MUX_DATA *MuxData, + IN UINT32 Type, + IN UINTN Lane + ) +{ + COMPHY_MUX_OPTIONS *PtrMuxOpt; + UINTN Opt; + UINT32 Value = 0; + + PtrMuxOpt = MuxData->MuxValues; + for (Opt = 0 ; Opt < MuxData->MaxLaneValues; Opt++, PtrMuxOpt++) + if (PtrMuxOpt->Type == Type) { + Value = PtrMuxOpt->MuxValue; + break; + } + + return Value; +} + +STATIC +VOID +ComPhyMuxRegWrite ( + IN COMPHY_MUX_DATA *MuxData, + IN COMPHY_MAP *ComPhyMapData, + IN UINTN ComPhyMaxLanes, + IN EFI_PHYSICAL_ADDRESS SelectorBase, + IN UINT32 BitCount + ) +{ + UINT32 Lane, Value, Offset, Mask; + + for (Lane = 0; Lane < ComPhyMaxLanes; Lane++, ComPhyMapData++, MuxData++) { + Offset = Lane * BitCount; + Mask = (((1 << BitCount) - 1) << Offset); + Value = (ComPhyMuxGetMuxValue (MuxData, ComPhyMapData->Type, Lane) << + Offset); + RegSet (SelectorBase, Value, Mask); + } +} + +VOID +ComPhyMuxInit ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg, + IN COMPHY_MAP *ComPhyMapData, + IN EFI_PHYSICAL_ADDRESS SelectorBase + ) +{ + COMPHY_MUX_DATA *MuxData; + UINT32 MuxBitCount; + UINT32 ComPhyMaxLanes; + + ComPhyMaxLanes = PtrChipCfg->LanesCount; + MuxData = PtrChipCfg->MuxData; + MuxBitCount = PtrChipCfg->MuxBitCount; + + /* Check if the configuration is valid */ + ComPhyMuxCheckConfig (MuxData, ComPhyMapData, ComPhyMaxLanes); + /* Init COMPHY selectors */ + ComPhyMuxRegWrite (MuxData, ComPhyMapData, ComPhyMaxLanes, SelectorBase, + MuxBitCount); +} diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e63add4..70c5cce 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -128,6 +128,56 @@ gMarvellTokenSpaceGuid.PcdSpiFlashPageSize|0|UINT32|0x3000055 gMarvellTokenSpaceGuid.PcdSpiFlashId|0|UINT32|0x3000056
+#ComPhy + #Chip0 + gMarvellTokenSpaceGuid.PcdComPhyChipCount|0|UINT32|0x30000098 + + gMarvellTokenSpaceGuid.PcdChip0Compatible|{ 0 }|VOID*|0x30000064 + gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress|0|UINT64|0x30000065 + gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress|0|UINT64|0x30000066 + gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount|0|UINT32|0x30000067 + gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes|0|UINT32|0x30001267 + + gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|{ 0 }|VOID*|0x30000068 + gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|{ 0 }|VOID*|0x30000069 + gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags|{ 0 }|VOID*|0x30000070 + + #Chip1 + gMarvellTokenSpaceGuid.PcdChip1Compatible|{ 0 }|VOID*|0x30000100 + gMarvellTokenSpaceGuid.PcdChip1ComPhyBaseAddress|0|UINT64|0x30000101 + gMarvellTokenSpaceGuid.PcdChip1Hpipe3BaseAddress|0|UINT64|0x30000102 + gMarvellTokenSpaceGuid.PcdChip1ComPhyMuxBitCount|0|UINT32|0x30000103 + gMarvellTokenSpaceGuid.PcdChip1ComPhyMaxLanes|0|UINT32|0x30001304 + + gMarvellTokenSpaceGuid.PcdChip1ComPhyTypes|{ 0 }|VOID*|0x30000105 + gMarvellTokenSpaceGuid.PcdChip1ComPhySpeeds|{ 0 }|VOID*|0x30000106 + gMarvellTokenSpaceGuid.PcdChip1ComPhyInvFlags|{ 0 }|VOID*|0x30000107 + + #Chip2 + gMarvellTokenSpaceGuid.PcdChip2Compatible|{ 0 }|VOID*|0x30000135 + gMarvellTokenSpaceGuid.PcdChip2ComPhyBaseAddress|0|UINT64|0x30000136 + gMarvellTokenSpaceGuid.PcdChip2Hpipe3BaseAddress|0|UINT64|0x30000137 + gMarvellTokenSpaceGuid.PcdChip2ComPhyMuxBitCount|0|UINT32|0x30000138 + gMarvellTokenSpaceGuid.PcdChip2ComPhyMaxLanes|0|UINT32|0x30000139 + + gMarvellTokenSpaceGuid.PcdChip2ComPhyTypes|{ 0 }|VOID*|0x30000140 + gMarvellTokenSpaceGuid.PcdChip2ComPhySpeeds|{ 0 }|VOID*|0x30000141 + gMarvellTokenSpaceGuid.PcdChip2ComPhyInvFlags|{ 0 }|VOID*|0x30000142 + + #Chip3 + gMarvellTokenSpaceGuid.PcdChip3Compatible|{ 0 }|VOID*|0x30000170 + gMarvellTokenSpaceGuid.PcdChip3ComPhyBaseAddress|0|UINT64|0x30000171 + gMarvellTokenSpaceGuid.PcdChip3Hpipe3BaseAddress|0|UINT64|0x30000172 + gMarvellTokenSpaceGuid.PcdChip3ComPhyMuxBitCount|0|UINT32|0x30000173 + gMarvellTokenSpaceGuid.PcdChip3ComPhyMaxLanes|0|UINT32|0x30000174 + + gMarvellTokenSpaceGuid.PcdChip3ComPhyTypes|{ 0 }|VOID*|0x30000175 + gMarvellTokenSpaceGuid.PcdChip3ComPhySpeeds|{ 0 }|VOID*|0x30000176 + gMarvellTokenSpaceGuid.PcdChip3ComPhyInvFlags|{ 0 }|VOID*|0x30000177 + +#SATA + gMarvellTokenSpaceGuid.PcdSataBaseAddress|0|UINT32|0x4000052 + [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }}
On Thu, Aug 11, 2016 at 11:51:32AM +0200, Marcin Wojtas wrote:
From: Jan Dąbroś jsd@semihalf.com
Marvell SoC's comprise multiplexed pins for SerDes lanes (XHCI, AHCI, SGMII, PCIe) called ComPhy.
ComPhyLib initialize ComPhy and ComPhy Mux. All configurable parameters are provided via set of PCDs.
In order to satisfy preprocessor demands, there are ComPhy PCDs for all of 4 possible chips.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Thank you for addressing all of my comments. Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
Documentation/Marvell/PortingGuide/ComPhy.txt | 85 ++ Platforms/Marvell/Include/Library/MvComPhyLib.h | 43 + Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 1047 +++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 288 ++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 452 +++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 109 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 +++ Platforms/Marvell/Marvell.dec | 50 + 8 files changed, 2206 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/ComPhy.txt create mode 100644 Platforms/Marvell/Include/Library/MvComPhyLib.h create mode 100755 Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c
diff --git a/Documentation/Marvell/PortingGuide/ComPhy.txt b/Documentation/Marvell/PortingGuide/ComPhy.txt new file mode 100644 index 0000000..b5c4727 --- /dev/null +++ b/Documentation/Marvell/PortingGuide/ComPhy.txt @@ -0,0 +1,85 @@ +COMPHY configuration +--------------------------- +In order to configure ComPhy library, following PCDs are available:
- gMarvellTokenSpaceGuid.PcdComPhyChipCount
+Indicates how many different chips are placed on board. So far, up to 4 chips +are supported.
+Every ComPhy PCD has <Num> part where <Num> stands for chip ID (order is not +important, but configuration will be set for first PcdComPhyChipCount chips).
+Every chip has 8 ComPhy PCDs and three of them concern lanes settings for this +chip. Below is example for the first chip (Chip0).
+General PCDs:
- gMarvellTokenSpaceGuid.PcdChip0Compatible
+Unicode string indicating type of chip - currently supported is +{ L"Cp110" }
- gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress
+Indicates COMPHY unit base address.
- gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress
+Indicates Hpipe3 unit base address.
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount
+Indicates number of bits that are allocated for every MUX in the +COMPHY-selector register.
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes
+Indicates maximum ComPhy lanes number.
+Next three PCDs are in unicode string format containing settings for up to 10 +lanes. Setting for each one is separated with semicolon. These PCDs form +structure describing outputs of PHY integrated in simple cihp. +Below is example for the first chip (Chip0).
- gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes
+Unicode string indicating PHY types. Currently supported are:
+{ L"unconnected", L"PCIE0", L"PCIE1", L"PCIE2", L"PCIE3", +L"SATA0", L"SATA1", L"SATA2", L"SATA3", L"SGMII0", +L"SGMII1", L"SGMII2", L"SGMII3", L"QSGMII", +L"USB3_HOST0", L"USB3_HOST1", L"USB3_DEVICE", +L"XAUI0", L"XAUI1", L"XAUI2", L"XAUI3", L"RXAUI0", +L"RXAUI1", L"KR" }
+Below documents describes some of above interfaces' types:
+SGMII, QSGMII, XAUI - IEEE 802.3 +KR - IEEE 802.3a +RXAUI - RXAUI Interface and RXAUI Adapter Specification, Marvell
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds
+Indicates PHY speeds in MHz. Currently supported are:
+{ 1250, 1500, 2500, 3000, 3125, 5000, 6000, 6250, 10310 }
- gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags
+Indicates lane polarity invert.
+Example +-------
- #ComPhy
- gMarvellTokenSpaceGuid.PcdComPhyChipCount|1
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes|6
- gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress|0xF2441000
- gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress|0xF2120000
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount|4
- gMarvellTokenSpaceGuid.PcdChip0Compatible|L"Cp110"
- gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|L"SGMII2;USB3_HOST0;SGMII0;SATA1;USB3_HOST1;PCIE2"
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|L"1250;5000;1250;5000;5000;5000"
diff --git a/Platforms/Marvell/Include/Library/MvComPhyLib.h b/Platforms/Marvell/Include/Library/MvComPhyLib.h new file mode 100644 index 0000000..6bd6243 --- /dev/null +++ b/Platforms/Marvell/Include/Library/MvComPhyLib.h @@ -0,0 +1,43 @@ +/******************************************************************************* +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+* Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#ifndef __MVCOMPHYLIB_H__ +#define __MVCOMPHYLIB_H__
+EFI_STATUS +MvComPhyInit (
- VOID
- );
+#endif diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c new file mode 100755 index 0000000..df8731d --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c @@ -0,0 +1,1047 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
+* Redistributions of source code must Retain the above copyright notice,
- this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+* Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#include "ComPhyLib.h"
+#define SD_LANE_ADDR_WIDTH 0x1000 +#define HPIPE_ADDR_OFFSET 0x800 +#define COMPHY_ADDR_LANE_WIDTH 0x28 +#define SD_ADDR(base, Lane) (base + SD_LANE_ADDR_WIDTH * Lane) +#define HPIPE_ADDR(base, Lane) (SD_ADDR(base, Lane) + HPIPE_ADDR_OFFSET) +#define COMPHY_ADDR(base, Lane) (base + COMPHY_ADDR_LANE_WIDTH * Lane)
+/*
- For CP-110 we have 2 Selector registers "PHY Selectors"
- and " PIPE Selectors".
- PIPE selector include USB and PCIe options.
- PHY selector include the Ethernet and SATA options, every Ethernet option
- has different options, for example: serdes Lane2 had option Eth_port_0
- that include (SGMII0, XAUI0, RXAUI0, KR)
- */
+COMPHY_MUX_DATA Cp110ComPhyMuxData[] = {
- /* Lane 0 */
- {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII2, 0x1},
- {PHY_TYPE_XAUI2, 0x1}, {PHY_TYPE_SATA1, 0x4} } },
- /* Lane 1 */
- {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII3, 0x1},
- {PHY_TYPE_XAUI3, 0x1}, {PHY_TYPE_SATA1, 0x4} } },
- /* Lane 2 */
- {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1},
- {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1},
- {PHY_TYPE_SATA0, 0x4} } },
- /* Lane 3 */
- {8, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x1},
- {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1},
- {PHY_TYPE_XAUI1, 0x1}, {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SATA1, 0x4} } },
- /* Lane 4 */
- {7, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_SGMII0, 0x2},
- {PHY_TYPE_XAUI0, 0x1}, {PHY_TYPE_RXAUI0, 0x1}, {PHY_TYPE_KR, 0x1},
- {PHY_TYPE_SGMII2, 0x1}, {PHY_TYPE_XAUI2, 0x1} } },
- /* Lane 5 */
- {6, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_XAUI1, 0x1},
- {PHY_TYPE_RXAUI1, 0x1}, {PHY_TYPE_SGMII3, 0x1}, {PHY_TYPE_XAUI3, 0x1},
- {PHY_TYPE_SATA1, 0x4} } },
+};
+COMPHY_MUX_DATA Cp110ComPhyPipeMuxData[] = {
- /* Lane 0 */
- {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PCIE0, 0x4} } },
- /* Lane 1 */
- {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST0, 0x1},
- {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PCIE0, 0x4} } },
- /* Lane 2 */
- {3, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST0, 0x1},
- {PHY_TYPE_PCIE0, 0x4} } },
- /* Lane 3 */
- {3, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST1, 0x1},
- {PHY_TYPE_PCIE0, 0x4} } },
- /* Lane 4 */
- {4, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_USB3_HOST1, 0x1},
- {PHY_TYPE_USB3_DEVICE, 0x2}, {PHY_TYPE_PCIE1, 0x4} } },
- /* Lane 5 */
- {2, {{PHY_TYPE_UNCONNECTED, 0x0}, {PHY_TYPE_PCIE2, 0x4} } },
+};
+STATIC +VOID +ComPhyPcieRFUConfiguration (
- IN EFI_PHYSICAL_ADDRESS ComPhyAddr
+) +{
- UINT32 Mask, Data;
- /* RFU configurations - hard reset ComPhy */
- Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
- Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
- Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
- Data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
- Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
- Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
- Mask |= COMMON_PHY_PHY_MODE_MASK;
- Data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
- RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
- /* Release from hard reset */
- Mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
- Data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
- Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
- Data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
- RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
- /* Wait 1ms - until band gap and ref clock ready */
- MicroSecondDelay (1000);
- MemoryFence ();
+}
+STATIC +VOID +ComPhyPciePhyConfiguration (
- IN EFI_PHYSICAL_ADDRESS ComPhyAddr,
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- UINT32 Mask, Data, PcieClk = 0;
- /* Set PIPE soft reset */
- Mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
- Data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
- /* Set PHY Datapath width mode for V0 */
- Mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
- Data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
- /* Set Data bus width USB mode for V0 */
- Mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
- Data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
- /* Set CORE_CLK output frequency for 250Mhz */
- Mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
- Data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, Data, Mask);
- /* Set PLL ready delay for 0x2 */
- RegSet (HpipeAddr + HPIPE_CLK_SRC_LO_REG,
- 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
- HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
- /* Set PIPE mode interface to PCIe3 - 0x1 */
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET, HPIPE_CLK_SRC_HI_MODE_PIPE_MASK);
- /* Config update polarity equalization */
- RegSet (HpipeAddr + HPIPE_LANE_EQ_CFG1_REG,
- 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET, HPIPE_CFG_UPDATE_POLARITY_MASK);
- /* Set PIPE version 4 to mode enable */
- RegSet (HpipeAddr + HPIPE_DFE_CTRL_28_REG,
- 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET, HPIPE_DFE_CTRL_28_PIPE4_MASK);
- /* Enable PIN clock 100M_125M */
- Mask = HPIPE_MISC_CLK100M_125M_MASK;
- Data = 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
- /* Set PIN_TXDCLK_2X Clock Frequency Selection for outputs 500MHz clock */
- Mask |= HPIPE_MISC_TXDCLK_2X_MASK;
- Data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
- /* Enable 500MHz Clock */
- Mask |= HPIPE_MISC_CLK500_EN_MASK;
- Data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
- if (PcieClk) {
- /* Set reference clock comes from group 1 */
- Mask |= HPIPE_MISC_REFCLK_SEL_MASK;
- Data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
- } else {
- /* Set reference clock comes from group 2 */
- Mask |= HPIPE_MISC_REFCLK_SEL_MASK;
- Data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
- }
- RegSet (HpipeAddr + HPIPE_MISC_REG, Data, Mask);
- if (PcieClk) {
- /* Set reference frequcency select - 0x2 for 25MHz*/
- Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
- Data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
- } else {
- /* Set reference frequcency select - 0x0 for 100MHz*/
- Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
- Data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
- }
- /* Set PHY mode to PCIe */
- Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
- Data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
- /*
- Set the amount of time spent in the LoZ state - set
- for 0x7 only if the PCIe clock is output
- */
- if (PcieClk)
- RegSet (HpipeAddr + HPIPE_GLOBAL_PM_CTRL,
0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
- /* Set Maximal PHY Generation Setting (8Gbps) */
- Mask = HPIPE_INTERFACE_GEN_MAX_MASK;
- Data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
- /* Set Link Train Mode (Tx training control pins are used) */
- Mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
- Data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
- RegSet (HpipeAddr + HPIPE_INTERFACE_REG, Data, Mask);
- /* Set Idle_sync enable */
- Mask = HPIPE_PCIE_IDLE_SYNC_MASK;
- Data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
- /* Select bits for PCIE Gen3(32bit) */
- Mask |= HPIPE_PCIE_SEL_BITS_MASK;
- Data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
- RegSet (HpipeAddr + HPIPE_PCIE_REG0, Data, Mask);
- /* Enable Tx_adapt_g1 */
- Mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
- Data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
- /* Enable Tx_adapt_gn1 */
- Mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
- Data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
- /* Disable Tx_adapt_g0 */
- Mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
- Data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
- RegSet (HpipeAddr + HPIPE_TX_TRAIN_CTRL_REG, Data, Mask);
- /* Set reg_tx_train_chk_init */
- Mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
- Data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
- /* Enable TX_COE_FM_PIN_PCIE3_EN */
- Mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
- Data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
- RegSet (HpipeAddr + HPIPE_TX_TRAIN_REG, Data, Mask);
+}
+STATIC +VOID +ComPhyPciePhyPowerUp (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- /* Release from PIPE soft reset */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- /* Wait 15ms - for ComPhy calibration done */
- MicroSecondDelay (15000);
- MemoryFence ();
+}
+STATIC +EFI_STATUS +ComPhyPcieCheckPll (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Data;
- /* Read Lane status */
- Data = MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG);
- if ((Data & HPIPE_LANE_STATUS0_PCLK_EN_MASK) == 0) {
- DEBUG((DEBUG_INFO, "ComPhy: Read from reg = %p - value = 0x%x\n",
HpipeAddr + HPIPE_LANE_STATUS0_REG, Data));
- DEBUG((DEBUG_INFO, "ComPhy: HPIPE_LANE_STATUS0_PCLK_EN_MASK is 0\n"));
- Status = EFI_D_ERROR;
- }
- return Status;
+}
+STATIC +EFI_STATUS +ComPhyPciePowerUp (
- IN UINT32 Lane,
- IN UINT32 PcieBy4,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
- EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
- ComPhyPcieRFUConfiguration (ComPhyAddr);
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- ComPhyPciePhyConfiguration (ComPhyAddr, HpipeAddr);
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n"));
- ComPhyPciePhyPowerUp (HpipeAddr);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
- Status = ComPhyPcieCheckPll (HpipeAddr);
- return Status;
+}
+STATIC +VOID +ComPhyUsb3RFUConfiguration (
- IN EFI_PHYSICAL_ADDRESS ComPhyAddr
+) +{
- UINT32 Mask, Data;
- /* RFU configurations - hard reset ComPhy */
- Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
- Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
- Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
- Data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
- Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
- Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
- Mask |= COMMON_PHY_PHY_MODE_MASK;
- Data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
- RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
- /* Release from hard reset */
- Mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
- Data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
- Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
- Data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
- RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
- /* Wait 1ms - until band gap and ref clock ready */
- MicroSecondDelay (1000);
- MemoryFence ();
+}
+STATIC +VOID +ComPhyUsb3PhyConfiguration (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- UINT32 Mask, Data;
- /* Set PIPE soft reset */
- Mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
- Data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
- /* Set PHY Datapath width mode for V0 */
- Mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
- Data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
- /* Set Data bus width USB mode for V0 */
- Mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
- Data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
- /* Set CORE_CLK output frequency for 250Mhz */
- Mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
- Data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, Data, Mask);
- /* Set PLL ready delay for 0x2 */
- RegSet (HpipeAddr + HPIPE_CLK_SRC_LO_REG,
- 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
- HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
- /* Set reference clock to come from group 1 - 25Mhz */
- RegSet (HpipeAddr + HPIPE_MISC_REG, 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
- HPIPE_MISC_REFCLK_SEL_MASK);
- /* Set reference frequcency select - 0x2 */
- Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
- Data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
- /* Set PHY mode to USB - 0x5 */
- Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
- Data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
- /* Set the amount of time spent in the LoZ state - set for 0x7 */
- RegSet (HpipeAddr + HPIPE_GLOBAL_PM_CTRL,
- 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
- HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
- /* Set max PHY generation setting - 5Gbps */
- RegSet (HpipeAddr + HPIPE_INTERFACE_REG,
- 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK);
- /* Set select Data width 20Bit (SEL_BITS[2:0]) */
- RegSet (HpipeAddr + HPIPE_LOOPBACK_REG,
- 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
+}
+STATIC +VOID +ComPhyUsb3SetAnalogParameters (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- UINT32 Data, Mask;
- /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
- Mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
- Data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
- /* Set Override PHY DFE control pins for 0x1 */
- Mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
- Data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
- /* Set Spread Spectrum Clock Enable fot 0x1 */
- Mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
- Data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
- RegSet (HpipeAddr + HPIPE_LANE_CFG4_REG, Data, Mask);
+}
+STATIC +UINTN +ComphyUsb3PowerUp (
- UINT32 Lane,
- EFI_PHYSICAL_ADDRESS HpipeBase,
- EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Data;
- EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
- EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
- ComPhyUsb3RFUConfiguration (ComPhyAddr);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "stage: Comphy configuration\n"));
- ComPhyUsb3PhyConfiguration (HpipeAddr);
- /* Start analog paramters from ETP(HW) */
- DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
- ComPhyUsb3SetAnalogParameters (HpipeAddr);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy power up\n"));
- /* Release from PIPE soft reset */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- /* Wait 15ms - for ComPhy calibration done */
- MicroSecondDelay (15000);
- MemoryFence ();
- DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
- /* Read Lane status */
- Data = MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG);
- if ((Data & HPIPE_LANE_STATUS0_PCLK_EN_MASK) == 0) {
- DEBUG((DEBUG_ERROR, "ComPhy: HPIPE_LANE_STATUS0_PCLK_EN_MASK is 0\n"));
- Status = EFI_D_ERROR;
- }
- return Status;
+}
+STATIC +UINT32 +PollingWithTimeout (
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT32 Val,
- IN UINT32 Mask,
- IN UINT64 Usec_timeout
- )
+{
- UINT32 Data;
- do {
- MicroSecondDelay(1);
- Data = MmioRead32(Addr) & Mask;
- } while (Data != Val && --Usec_timeout > 0);
- if (Usec_timeout == 0)
- return Data;
- return 0;
+}
+STATIC +VOID +ComPhySataMacPowerDown (
- IN EFI_PHYSICAL_ADDRESS SataBase
+) +{
- UINT32 Mask, Data;
- /*
- MAC configuration - power down ComPhy
- Use indirect address for vendor specific SATA control register
- */
- RegSet (SataBase + SATA3_VENDOR_ADDRESS,
- SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, SATA3_VENDOR_ADDR_MASK);
- /* SATA 0 power down */
- Mask = SATA3_CTRL_SATA0_PD_MASK;
- Data = 0x1 << SATA3_CTRL_SATA0_PD_OFFSET;
- /* SATA 1 power down */
- Mask |= SATA3_CTRL_SATA1_PD_MASK;
- Data |= 0x1 << SATA3_CTRL_SATA1_PD_OFFSET;
- /* SATA SSU disable */
- Mask |= SATA3_CTRL_SATA1_ENABLE_MASK;
- Data |= 0x0 << SATA3_CTRL_SATA1_ENABLE_OFFSET;
- /* SATA port 1 disable */
- Mask |= SATA3_CTRL_SATA_SSU_MASK;
- Data |= 0x0 << SATA3_CTRL_SATA_SSU_OFFSET;
- RegSet (SataBase + SATA3_VENDOR_DATA, Data, Mask);
+}
+STATIC +VOID +ComPhySataRFUConfiguration (
- IN EFI_PHYSICAL_ADDRESS ComPhyAddr,
- IN EFI_PHYSICAL_ADDRESS SdIpAddr
+) +{
- UINT32 Mask, Data;
- /* RFU configurations - hard reset ComPhy */
- Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
- Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
- Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
- Mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
- Mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
- RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
- /* Set select Data width 40Bit - SATA mode only */
- RegSet (ComPhyAddr + COMMON_PHY_CFG6_REG,
- 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET, COMMON_PHY_CFG6_IF_40_SEL_MASK);
- /* Release from hard reset in SD external */
- Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
- Data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
- Data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
- RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
- /* Wait 1ms - until band gap and ref clock ready */
- MicroSecondDelay (1000);
- MemoryFence ();
+}
+STATIC +VOID +ComPhySataPhyConfiguration (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- UINT32 Mask, Data;
- /* Set reference clock to comes from group 1 - choose 25Mhz */
- RegSet (HpipeAddr + HPIPE_MISC_REG,
- 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET, HPIPE_MISC_REFCLK_SEL_MASK);
- /* Reference frequency select set 1 (for SATA = 25Mhz) */
- Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
- Data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
- /* PHY mode select (set SATA = 0x0 */
- Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
- Data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
- /* Set max PHY generation setting - 6Gbps */
- RegSet (HpipeAddr + HPIPE_INTERFACE_REG,
- 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK);
- /* Set select Data width 40Bit (SEL_BITS[2:0]) */
- RegSet (HpipeAddr + HPIPE_LOOPBACK_REG,
- 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
+}
+STATIC +VOID +ComPhySataSetAnalogParameters (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- /* DFE reset sequence */
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
- /* SW reset for interupt logic */
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK);
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK);
+}
+STATIC +VOID +ComPhySataPhyPowerUp (
- IN EFI_PHYSICAL_ADDRESS SataBase
+) +{
- UINT32 Data, Mask;
- /*
- MAC configuration - power up ComPhy - power up PLL/TX/RX
- Use indirect address for vendor specific SATA control register
- */
- RegSet (SataBase + SATA3_VENDOR_ADDRESS,
- SATA_CONTROL_REG << SATA3_VENDOR_ADDR_OFSSET, SATA3_VENDOR_ADDR_MASK);
- /* SATA 0 power up */
- Mask = SATA3_CTRL_SATA0_PD_MASK;
- Data = 0x0 << SATA3_CTRL_SATA0_PD_OFFSET;
- /* SATA 1 power up */
- Mask |= SATA3_CTRL_SATA1_PD_MASK;
- Data |= 0x0 << SATA3_CTRL_SATA1_PD_OFFSET;
- /* SATA SSU enable */
- Mask |= SATA3_CTRL_SATA1_ENABLE_MASK;
- Data |= 0x1 << SATA3_CTRL_SATA1_ENABLE_OFFSET;
- /* SATA port 1 enable */
- Mask |= SATA3_CTRL_SATA_SSU_MASK;
- Data |= 0x1 << SATA3_CTRL_SATA_SSU_OFFSET;
- RegSet (SataBase + SATA3_VENDOR_DATA, Data, Mask);
- /* MBUS request size and interface select register */
- RegSet (SataBase + SATA3_VENDOR_ADDRESS,
- SATA_MBUS_SIZE_SELECT_REG << SATA3_VENDOR_ADDR_OFSSET,
SATA3_VENDOR_ADDR_MASK);
- /* Mbus regret enable */
- RegSet (SataBase + SATA3_VENDOR_DATA, 0x1 << SATA_MBUS_REGRET_EN_OFFSET,
- SATA_MBUS_REGRET_EN_MASK);
+}
+STATIC +EFI_STATUS +ComPhySataCheckPll (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr,
- IN EFI_PHYSICAL_ADDRESS SdIpAddr
+) +{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Data,Mask;
- IN EFI_PHYSICAL_ADDRESS Addr;
- Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG;
- Data = SD_EXTERNAL_STATUS0_PLL_TX_MASK & SD_EXTERNAL_STATUS0_PLL_RX_MASK;
- Mask = Data;
- Data = PollingWithTimeout (Addr, Data, Mask, 15000);
- if (Data != 0) {
- DEBUG((DEBUG_INFO, "ComPhy: Read from reg = %p - value = 0x%x\n",
HpipeAddr + HPIPE_LANE_STATUS0_REG, Data));
- DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_PLL_TX is %d, SD_EXTERNAL_STATUS0_PLL_RX is %d\n",
(Data & SD_EXTERNAL_STATUS0_PLL_TX_MASK),
(Data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)));
- Status = EFI_D_ERROR;
- }
- return Status;
+}
+STATIC +UINTN +ComPhySataPowerUp (
- IN UINT32 Lane,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
- EFI_PHYSICAL_ADDRESS SdIpAddr = SD_ADDR(HpipeBase, Lane);
- EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
- EFI_PHYSICAL_ADDRESS SataBase;
- SataBase = PcdGet32 (PcdSataBaseAddress);
- if (SataBase == 0) {
- DEBUG((DEBUG_INFO, "ComPhy: SATA address not defined\n"));
- return EFI_D_ERROR;
- }
- DEBUG((DEBUG_INFO, "ComPhySataPowerUp: stage: MAC configuration - power down ComPhy\n"));
- ComPhySataMacPowerDown (SataBase);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
- ComPhySataRFUConfiguration (ComPhyAddr, SdIpAddr);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy configuration\n"));
- ComPhySataPhyConfiguration (HpipeAddr);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
- ComPhySataSetAnalogParameters (HpipeAddr);
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n"));
- ComPhySataPhyPowerUp (SataBase);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
- Status = ComPhySataCheckPll (HpipeAddr, SdIpAddr);
- return Status;
+}
+STATIC +VOID +ComPhySgmiiRFUConfiguration (
- IN EFI_PHYSICAL_ADDRESS ComPhyAddr,
- IN EFI_PHYSICAL_ADDRESS SdIpAddr,
- IN UINT32 SgmiiSpeed
+) +{
- UINT32 Mask, Data;
- Mask = COMMON_PHY_CFG1_PWR_UP_MASK;
- Data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
- Mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
- Data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
- RegSet (ComPhyAddr + COMMON_PHY_CFG1_REG, Data, Mask);
- /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
- Mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
- Data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
- Mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
- if (SgmiiSpeed == PHY_SPEED_1_25G) {
- Data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
- Data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
- } else {
- /* 3.125G */
- Data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
- Data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
- }
- Mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
- Data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
- Data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
- Data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
- RegSet (SdIpAddr + SD_EXTERNAL_CONFIG0_REG, Data, Mask);
- /* Release from hard reset */
- Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
- Data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
- Data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
- Data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
- RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
- /* Release from hard reset */
- Mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
- Data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
- Data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
- RegSet (SdIpAddr+ SD_EXTERNAL_CONFIG1_REG, Data, Mask);
- /* Wait 1ms - until band gap and ref clock ready */
- MicroSecondDelay (1000);
- MemoryFence ();
+}
+STATIC +VOID +ComPhySgmiiPhyConfiguration (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
+) +{
- UINT32 Mask, Data;
- /* Set reference clock */
- Mask = HPIPE_MISC_REFCLK_SEL_MASK;
- Data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
- RegSet (HpipeAddr + HPIPE_MISC_REG, Data, Mask);
- /* Power and PLL Control */
- Mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
- Data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
- Mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
- Data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, Data, Mask);
- /* Loopback register */
- Mask = HPIPE_LOOPBACK_SEL_MASK;
- Data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
- RegSet (HpipeAddr + HPIPE_LOOPBACK_REG, Data, Mask);
- /* Rx control 1 */
- Mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
- Data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
- Mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
- Data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
- RegSet (HpipeAddr + HPIPE_RX_CONTROL_1_REG, Data, Mask);
- /* DTL Control */
- Mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
- Data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
- RegSet (HpipeAddr + HPIPE_PWR_CTR_DTL_REG, Data, Mask);
+}
+STATIC +EFI_STATUS +ComPhySgmiiRFUPowerUp (
- IN EFI_PHYSICAL_ADDRESS SdIpAddr
+) +{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, Data;
- EFI_PHYSICAL_ADDRESS Addr;
- /* SerDes External Configuration */
- Mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
- Data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
- Data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
- Data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
- RegSet (SdIpAddr + SD_EXTERNAL_CONFIG0_REG, Data, Mask);
- /* Check PLL rx & tx ready */
- Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG;
- Data = SD_EXTERNAL_STATUS0_PLL_RX_MASK | SD_EXTERNAL_STATUS0_PLL_TX_MASK;
- Mask = Data;
- Data = PollingWithTimeout (Addr, Data, Mask, 15000);
- if (Data != 0) {
- DEBUG((DEBUG_ERROR, "ComPhy: Read from reg = %p - value = 0x%x\n",
SdIpAddr + SD_EXTERNAL_STATUS0_REG, Data));
- DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_PLL_RX is %d, SD_EXTERNAL_STATUS0_PLL_TX is %d\n",
(Data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
(Data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)));
- Status = EFI_D_ERROR;
- }
- /* RX init */
- Mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
- Data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
- RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
- /* Check that RX init done */
- Addr = SdIpAddr + SD_EXTERNAL_STATUS0_REG;
- Data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
- Mask = Data;
- Data = PollingWithTimeout (Addr, Data, Mask, 100);
- if (Data != 0) {
- DEBUG((DEBUG_ERROR, "ComPhy: Read from reg = %p - value = 0x%x\n",
SdIpAddr + SD_EXTERNAL_STATUS0_REG, Data));
- DEBUG((DEBUG_ERROR, "ComPhy: SD_EXTERNAL_STATUS0_RX_INIT is 0\n"));
- Status = EFI_D_ERROR;
- }
- Mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
- Data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
- Mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
- Data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
- RegSet (SdIpAddr + SD_EXTERNAL_CONFIG1_REG, Data, Mask);
- return Status;
+}
+STATIC +UINTN +ComPhySgmiiPowerUp (
- IN UINT32 Lane,
- IN UINT32 SgmiiSpeed,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- EFI_PHYSICAL_ADDRESS HpipeAddr = HPIPE_ADDR(HpipeBase, Lane);
- EFI_PHYSICAL_ADDRESS SdIpAddr = SD_ADDR(HpipeBase, Lane);
- EFI_PHYSICAL_ADDRESS ComPhyAddr = COMPHY_ADDR(ComPhyBase, Lane);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset ComPhy\n"));
- ComPhySgmiiRFUConfiguration (ComPhyAddr, SdIpAddr, SgmiiSpeed);
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- ComPhySgmiiPhyConfiguration (HpipeAddr);
- /* Set analog paramters from ETP(HW) - for now use the default data */
- DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
- RegSet (HpipeAddr + HPIPE_G1_SET_0_REG,
- 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET, HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - Power Up PLL,Tx,Rx\n"));
- Status = ComPhySgmiiRFUPowerUp (SdIpAddr);
- return Status;
+}
+STATIC +VOID +ComPhyMuxCp110 (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg,
- IN COMPHY_MAP *SerdesMap
- )
+{
- EFI_PHYSICAL_ADDRESS ComPhyBaseAddr;
- COMPHY_MAP ComPhyMapPipeData[MAX_LANE_OPTIONS];
- COMPHY_MAP ComPhyMapPhyData[MAX_LANE_OPTIONS];
- UINT32 Lane, ComPhyMaxCount;
- ComPhyMaxCount = PtrChipCfg->LanesCount;
- ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr;
- /*
- Copy the SerDes map configuration for PIPE map and PHY map.
- The ComPhyMuxInit modifies the Type of the Lane if the Type is not valid.
- Because we have 2 selectors, run the ComPhyMuxInit twice and after
- that, update the original SerdesMap.
- */
- for (Lane = 0; Lane < ComPhyMaxCount; Lane++) {
- ComPhyMapPipeData[Lane].Type = SerdesMap[Lane].Type;
- ComPhyMapPipeData[Lane].Speed = SerdesMap[Lane].Speed;
- ComPhyMapPhyData[Lane].Type = SerdesMap[Lane].Type;
- ComPhyMapPhyData[Lane].Speed = SerdesMap[Lane].Speed;
- }
- PtrChipCfg->MuxData = Cp110ComPhyMuxData;
- ComPhyMuxInit(PtrChipCfg, ComPhyMapPhyData, ComPhyBaseAddr +
- COMMON_SELECTOR_PHY_OFFSET);
- PtrChipCfg->MuxData = Cp110ComPhyPipeMuxData;
- ComPhyMuxInit(PtrChipCfg, ComPhyMapPipeData, ComPhyBaseAddr +
- COMMON_SELECTOR_PIPE_OFFSET);
- /* Fix the Type after check the PHY and PIPE configuration */
- for (Lane = 0; Lane < ComPhyMaxCount; Lane++)
- if ((ComPhyMapPipeData[Lane].Type == PHY_TYPE_UNCONNECTED) &&
(ComPhyMapPhyData[Lane].Type == PHY_TYPE_UNCONNECTED))
SerdesMap[Lane].Type = PHY_TYPE_UNCONNECTED;
+}
+EFI_STATUS +ComPhyCp110Init (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg
- )
+{
- EFI_STATUS Status;
- COMPHY_MAP *PtrComPhyMap, *SerdesMap;
- EFI_PHYSICAL_ADDRESS ComPhyBaseAddr, HpipeBaseAddr;
- UINT32 ComPhyMaxCount, Lane;
- UINT32 PcieBy4 = 1; // Indicating if first 4 lanes set to PCIE
- ComPhyMaxCount = PtrChipCfg->LanesCount;
- ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr;
- HpipeBaseAddr = PtrChipCfg->Hpipe3BaseAddr;
- SerdesMap = PtrChipCfg->MapData;
- /* Config Comphy mux configuration */
- ComPhyMuxCp110(PtrChipCfg, SerdesMap);
- /* Check if the first 4 Lanes configured as By-4 */
- for (Lane = 0, PtrComPhyMap = SerdesMap; Lane < 4; Lane++, PtrComPhyMap++) {
- if (PtrComPhyMap->Type != PHY_TYPE_PCIE0) {
PcieBy4 = 0;
break;
- }
- }
- for (Lane = 0, PtrComPhyMap = SerdesMap; Lane < ComPhyMaxCount;
Lane++, PtrComPhyMap++) {
- DEBUG((DEBUG_INFO, "ComPhy: Initialize serdes number %d\n", Lane));
- DEBUG((DEBUG_INFO, "ComPhy: Serdes Type = 0x%x\n", PtrComPhyMap->Type));
- switch (PtrComPhyMap->Type) {
- case PHY_TYPE_UNCONNECTED:
continue;
break;
- case PHY_TYPE_PCIE0:
- case PHY_TYPE_PCIE1:
- case PHY_TYPE_PCIE2:
- case PHY_TYPE_PCIE3:
Status = ComPhyPciePowerUp(Lane, PcieBy4, HpipeBaseAddr, ComPhyBaseAddr);
break;
- case PHY_TYPE_SATA0:
- case PHY_TYPE_SATA1:
- case PHY_TYPE_SATA2:
- case PHY_TYPE_SATA3:
Status = ComPhySataPowerUp(Lane, HpipeBaseAddr, ComPhyBaseAddr);
break;
- case PHY_TYPE_USB3_HOST0:
- case PHY_TYPE_USB3_HOST1:
Status = ComphyUsb3PowerUp(Lane, HpipeBaseAddr, ComPhyBaseAddr);
break;
- case PHY_TYPE_SGMII0:
- case PHY_TYPE_SGMII1:
- case PHY_TYPE_SGMII2:
- case PHY_TYPE_SGMII3:
Status = ComPhySgmiiPowerUp(Lane, PtrComPhyMap->Speed, HpipeBaseAddr,
ComPhyBaseAddr);
break;
- default:
DEBUG((DEBUG_ERROR, "Unknown SerDes Type, skip initialize SerDes %d\n",
Lane));
break;
- }
- if (EFI_ERROR(Status))
DEBUG((DEBUG_ERROR, "PLL is not locked - Failed to initialize Lane %d\n",
Lane));
- }
- return EFI_SUCCESS;
+} diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c new file mode 100644 index 0000000..1b45bb7 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c @@ -0,0 +1,288 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+* Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#include "ComPhyLib.h"
+CHAR16 * TypeStringTable [] = {L"unconnected", L"PCIE0", L"PCIE1", L"PCIE2",
L"PCIE3", L"SATA0", L"SATA1", L"SATA2", L"SATA3",
L"SGMII0", L"SGMII1", L"SGMII2", L"SGMII3",
L"QSGMII", L"USB3_HOST0", L"USB3_HOST1",
L"USB3_DEVICE", L"XAUI0", L"XAUI1", L"XAUI2",
L"XAUI3", L"RXAUI0", L"RXAUI1", L"KR"};
+CHAR16 * SpeedStringTable [] = {L"-", L"1.25 Gbps", L"1.5 Gbps", L"2.5 Gbps",
L"3.0 Gbps", L"3.125 Gbps", L"5 Gbps",
L"6 Gbps", L"6.25 Gbps", L"10.31 Gbps"};
+CHIP_COMPHY_CONFIG ChipCfgTbl[] = {
- {
- .ChipType = L"Cp110",
- .Init = ComPhyCp110Init
- }
+};
+VOID +RegSet (
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT32 Data,
- IN UINT32 Mask
- )
+{
- DEBUG((DEBUG_INFO, "Write to address = %10x, data = %10x (mask = %10x)"
- "- ", Addr, Data, Mask));
- DEBUG((DEBUG_INFO, "old value = %10x ==> ", MmioRead32 (Addr)));
- RegSetSilent (Addr, Data, Mask);
- DEBUG((DEBUG_INFO, "new value %10x\n", MmioRead32 (Addr)));
+}
+VOID +RegSetSilent (
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT32 Data,
- IN UINT32 Mask
- )
+{
- UINT32 RegData;
- RegData = MmioRead32 (Addr);
- RegData &= ~Mask;
- RegData |= Data;
- MmioWrite32 (Addr, RegData);
+}
+VOID +RegSet16 (
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT16 Data,
- IN UINT16 Mask
- )
+{
- DEBUG((DEBUG_INFO, "Write to address = %#010lx, Data = %#06x (mask = %#06x)"
- "- ", Addr, Data, Mask));
- DEBUG((DEBUG_INFO, "old value = %#06x ==> ", MmioRead16 (Addr)));
- RegSetSilent16 (Addr, Data, Mask);
- DEBUG((DEBUG_INFO, "new value %#06x\n", MmioRead16 (Addr)));
+}
+VOID +RegSetSilent16(
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT16 Data,
- IN UINT16 Mask
- )
+{
- UINT16 RegData;
- RegData = MmioRead16(Addr);
- RegData &= ~Mask;
- RegData |= Data;
- MmioWrite16 (Addr, RegData);
+}
+/* This function returns enum with SerDesType */ +UINT32 +ParseSerdesTypeString (
- CHAR16* String
- )
+{
- UINT32 i;
- if (String == NULL)
- return PHY_TYPE_INVALID;
- for (i = 0; i < PHY_TYPE_MAX; i++) {
- if (StrCmp (String, TypeStringTable[i]) == 0) {
return i;
- }
- }
- /* PCD string doesn't match any supported SerDes Type */
- return PHY_TYPE_INVALID;
+}
+/* This function converts SerDes speed in MHz to enum with SerDesSpeed */ +UINT32 +ParseSerdesSpeed (
- UINT32 Value
- )
+{
- UINT32 i;
- UINT32 ValueTable [] = {0, 1250, 1500, 2500, 3000, 3125,
5000, 6000, 6250, 10310};
- for (i = 0; i < 10; i++) {
- if (Value == ValueTable[i]) {
return i;
- }
- }
- /* PCD SerDes speed value doesn't match any supported SerDes speed */
- return PHY_SPEED_INVALID;
+}
+CHAR16 * +GetTypeString (
- UINT32 Type
- )
+{
- if (Type < 0 || Type > PHY_TYPE_MAX) {
- return L"invalid";
- }
- return TypeStringTable[Type];
+}
+CHAR16 * +GetSpeedString (
- UINT32 Speed
- )
+{
- if (Speed < 0 || Speed > 10) {
- return L"invalid";
- }
- return SpeedStringTable[Speed];
+}
+VOID +ComPhyPrint (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg
- )
+{
- UINT32 Lane;
- CHAR16 *SpeedStr, *TypeStr;
- for (Lane = 0; Lane < PtrChipCfg->LanesCount; Lane++) {
- SpeedStr = GetSpeedString(PtrChipCfg->MapData[Lane].Speed);
- TypeStr = GetTypeString(PtrChipCfg->MapData[Lane].Type);
- DEBUG((DEBUG_ERROR, "Comphy-%d: %-13s %-10s\n", Lane, TypeStr, SpeedStr));
- }
- DEBUG((DEBUG_ERROR, "\n"));
+}
+EFI_STATUS +GetChipComPhyInit (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg
- )
+{
- UINTN i, TblSize;
- TblSize = sizeof(ChipCfgTbl) / sizeof(ChipCfgTbl[0]);
- for (i = 0; i < TblSize ; i++) {
- if (StrCmp (PtrChipCfg->ChipType, ChipCfgTbl[i].ChipType) == 0) {
PtrChipCfg->Init = ChipCfgTbl[i].Init;
return EFI_SUCCESS;
- }
- }
- DEBUG((DEBUG_ERROR, "ComPhy: Empty ChipType string\n"));
- return EFI_D_ERROR;
+}
+STATIC +VOID +InitComPhyConfig (
- IN OUT CHIP_COMPHY_CONFIG *ChipConfig,
- IN OUT PCD_LANE_MAP *LaneData
- )
+{
- /*
- Below macro contains variable name concatenation (used to form PCD's name)
- and that's why invoking it cannot be automated, e.g. using for loop.
- Currently up to 4 ComPhys might be configured.
- */
- GetComPhyPcd(ChipConfig, LaneData, 0);
- GetComPhyPcd(ChipConfig, LaneData, 1);
- GetComPhyPcd(ChipConfig, LaneData, 2);
- GetComPhyPcd(ChipConfig, LaneData, 3);
+}
+EFI_STATUS +MvComPhyInit (
- VOID
- )
+{
- EFI_STATUS Status;
- CHIP_COMPHY_CONFIG ChipConfig[MAX_CHIPS], *PtrChipCfg;
- PCD_LANE_MAP LaneData[MAX_CHIPS];
- UINT32 Lane, ChipCount, i, MaxComphyCount;
- ChipCount = PcdGet32 (PcdComPhyChipCount);
- InitComPhyConfig(ChipConfig, LaneData);
- if (ChipCount <= 0 || ChipCount > MAX_CHIPS)
- return EFI_INVALID_PARAMETER;
- for (i = 0; i < ChipCount ; i++) {
- PtrChipCfg = &ChipConfig[i];
- /* Get the count of the SerDes of the specific chip */
- MaxComphyCount = PtrChipCfg->LanesCount;
- for (Lane = 0; Lane < MaxComphyCount; Lane++) {
/* Parse PCD with string indicating SerDes Type */
PtrChipCfg->MapData[Lane].Type =
ParseSerdesTypeString (LaneData[i].TypeStr[Lane]);
PtrChipCfg->MapData[Lane].Speed =
ParseSerdesSpeed (LaneData[i].SpeedValue[Lane]);
PtrChipCfg->MapData[Lane].Invert = (UINT32) LaneData[i].InvFlag[Lane];
if ((PtrChipCfg->MapData[Lane].Speed == PHY_SPEED_INVALID) ||
(PtrChipCfg->MapData[Lane].Speed == PHY_SPEED_ERROR) ||
(PtrChipCfg->MapData[Lane].Type == PHY_TYPE_INVALID)) {
DEBUG((DEBUG_ERROR, "ComPhy: No valid phy speed or type for lane %d, "
"setting lane as unconnected\n", Lane + 1));
PtrChipCfg->MapData[Lane].Type = PHY_TYPE_UNCONNECTED;
PtrChipCfg->MapData[Lane].Speed = PHY_SPEED_INVALID;
}
- };
- Status = GetChipComPhyInit (PtrChipCfg);
- if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, "ComPhy: Invalid Chip%dType name\n", i));
return Status;
- }
- ComPhyPrint (PtrChipCfg);
- /* PHY power UP sequence */
- PtrChipCfg->Init (PtrChipCfg);
- }
- return EFI_SUCCESS;
+} diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h new file mode 100644 index 0000000..48cafc9 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h @@ -0,0 +1,452 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+* Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#ifndef __COMPHY_H__ +#define __COMPHY_H__
+#include <Library/ArmLib.h> +#include <Library/ArmPlatformLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/TimerLib.h> +#include <Library/ParsePcdLib.h>
+#define MAX_LANE_OPTIONS 10 +#define MAX_CHIPS 4
+/***** Parsing PCD *****/ +#define GET_TYPE_STRING(id) PcdGetPtr(PcdChip##id##Compatible) +#define GET_LANE_TYPE(id) PcdGetPtr(PcdChip##id##ComPhyTypes) +#define GET_LANE_SPEED(id) PcdGetPtr(PcdChip##id##ComPhySpeeds) +#define GET_LANE_INV(id) PcdGetPtr(PcdChip##id##ComPhyInvFlags) +#define GET_COMPHY_BASE_ADDR(id) PcdGet64(PcdChip##id##ComPhyBaseAddress) +#define GET_HPIPE3_BASE_ADDR(id) PcdGet64(PcdChip##id##Hpipe3BaseAddress) +#define GET_MUX_BIT_COUNT(id) PcdGet32(PcdChip##id##ComPhyMuxBitCount) +#define GET_MAX_LANES(id) PcdGet32(PcdChip##id##ComPhyMaxLanes)
+#define FillLaneMap(chip_struct, lane_struct, id) { \
- ParsePcdString((CHAR16 *) GET_LANE_TYPE(id), chip_struct[id].LanesCount, NULL, lane_struct[id].TypeStr); \
- ParsePcdString((CHAR16 *) GET_LANE_SPEED(id), chip_struct[id].LanesCount, lane_struct[id].SpeedValue, NULL); \
- ParsePcdString((CHAR16 *) GET_LANE_INV(id), chip_struct[id].LanesCount, lane_struct[id].InvFlag, NULL); \
+}
+#define GetComPhyPcd(chip_struct, lane_struct, id) { \
- chip_struct[id].ChipType = (CHAR16 *) GET_TYPE_STRING(id); \
- chip_struct[id].ComPhyBaseAddr = GET_COMPHY_BASE_ADDR(id); \
- chip_struct[id].Hpipe3BaseAddr = GET_HPIPE3_BASE_ADDR(id); \
- chip_struct[id].MuxBitCount = GET_MUX_BIT_COUNT(id); \
- chip_struct[id].LanesCount = GET_MAX_LANES(id); \
- FillLaneMap(chip_struct, lane_struct, id); \
+}
+/***** ComPhy *****/ +#define PHY_SPEED_ERROR 0 +#define PHY_SPEED_1_25G 1 +#define PHY_SPEED_1_5G 2 +#define PHY_SPEED_2_5G 3 +#define PHY_SPEED_3G 4 +#define PHY_SPEED_3_125G 5 +#define PHY_SPEED_5G 6 +#define PHY_SPEED_6G 7 +#define PHY_SPEED_6_25G 8 +#define PHY_SPEED_10_3125G 9 +#define PHY_SPEED_MAX 10 +#define PHY_SPEED_INVALID 0xff
+#define PHY_TYPE_UNCONNECTED 0 +#define PHY_TYPE_PCIE0 1 +#define PHY_TYPE_PCIE1 2 +#define PHY_TYPE_PCIE2 3 +#define PHY_TYPE_PCIE3 4 +#define PHY_TYPE_SATA0 5 +#define PHY_TYPE_SATA1 6 +#define PHY_TYPE_SATA2 7 +#define PHY_TYPE_SATA3 8 +#define PHY_TYPE_SGMII0 9 +#define PHY_TYPE_SGMII1 10 +#define PHY_TYPE_SGMII2 11 +#define PHY_TYPE_SGMII3 12 +#define PHY_TYPE_QSGMII 13 +#define PHY_TYPE_USB3_HOST0 14 +#define PHY_TYPE_USB3_HOST1 15 +#define PHY_TYPE_USB3_DEVICE 16 +#define PHY_TYPE_XAUI0 17 +#define PHY_TYPE_XAUI1 18 +#define PHY_TYPE_XAUI2 19 +#define PHY_TYPE_XAUI3 20 +#define PHY_TYPE_RXAUI0 21 +#define PHY_TYPE_RXAUI1 22 +#define PHY_TYPE_KR 23 +#define PHY_TYPE_MAX 24 +#define PHY_TYPE_INVALID 0xff
+#define PHY_POLARITY_NO_INVERT 0 +#define PHY_POLARITY_TXD_INVERT 1 +#define PHY_POLARITY_RXD_INVERT 2 +#define PHY_POLARITY_ALL_INVERT (PHY_POLARITY_TXD_INVERT | PHY_POLARITY_RXD_INVERT)
+/***** SerDes IP registers *****/ +#define SD_EXTERNAL_CONFIG0_REG 0 +#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET 1 +#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK (1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET 3 +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK (0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET 7 +#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK (0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET 11 +#define SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK (1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET) +#define SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET 12 +#define SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK (1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET) +#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET 14 +#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK (1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET)
+#define SD_EXTERNAL_CONFIG1_REG 0x4 +#define SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET 3 +#define SD_EXTERNAL_CONFIG1_RESET_IN_MASK (0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET) +#define SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET 4 +#define SD_EXTERNAL_CONFIG1_RX_INIT_MASK (0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET) +#define SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET 5 +#define SD_EXTERNAL_CONFIG1_RESET_CORE_MASK (0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET) +#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET 6 +#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK (0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET)
+#define SD_EXTERNAL_STATUS0_REG 0x18 +#define SD_EXTERNAL_STATUS0_PLL_TX_OFFSET 2 +#define SD_EXTERNAL_STATUS0_PLL_TX_MASK (0x1 << SD_EXTERNAL_STATUS0_PLL_TX_OFFSET) +#define SD_EXTERNAL_STATUS0_PLL_RX_OFFSET 3 +#define SD_EXTERNAL_STATUS0_PLL_RX_MASK (0x1 << SD_EXTERNAL_STATUS0_PLL_RX_OFFSET) +#define SD_EXTERNAL_STATUS0_RX_INIT_OFFSET 4 +#define SD_EXTERNAL_STATUS0_RX_INIT_MASK (0x1 << SD_EXTERNAL_STATUS0_RX_INIT_OFFSET)
+/***** HPIPE registers *****/ +#define HPIPE_PWR_PLL_REG 0x4 +#define HPIPE_PWR_PLL_REF_FREQ_OFFSET 0 +#define HPIPE_PWR_PLL_REF_FREQ_MASK (0x1f << HPIPE_PWR_PLL_REF_FREQ_OFFSET) +#define HPIPE_PWR_PLL_PHY_MODE_OFFSET 5 +#define HPIPE_PWR_PLL_PHY_MODE_MASK (0x7 << HPIPE_PWR_PLL_PHY_MODE_OFFSET)
+#define HPIPE_KVCO_CALIB_CTRL_REG 0x8 +#define HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET 12 +#define HPIPE_KVCO_CALIB_CTRL_MAX_PLL_MASK (0x1 << HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET)
+#define HPIPE_SQUELCH_FFE_SETTING_REG 0x018
+#define HPIPE_DFE_REG0 0x01C +#define HPIPE_DFE_RES_FORCE_OFFSET 15 +#define HPIPE_DFE_RES_FORCE_MASK (0x1 << HPIPE_DFE_RES_FORCE_OFFSET)
+#define HPIPE_DFE_F3_F5_REG 0x028 +#define HPIPE_DFE_F3_F5_DFE_EN_OFFSET 14 +#define HPIPE_DFE_F3_F5_DFE_EN_MASK (0x1 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET) +#define HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET 15 +#define HPIPE_DFE_F3_F5_DFE_CTRL_MASK (0x1 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET)
+#define HPIPE_G1_SET_0_REG 0x034 +#define HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET 7 +#define HPIPE_G1_SET_0_G1_TX_EMPH1_MASK (0xf << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET)
+#define HPIPE_G1_SET_1_REG 0x038 +#define HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET 0 +#define HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK (0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET) +#define HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET 3 +#define HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK (0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET) +#define HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET 10 +#define HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK (0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET)
+#define HPIPE_G2_SETTINGS_1_REG 0x040
+#define HPIPE_LOOPBACK_REG 0x08c +#define HPIPE_LOOPBACK_SEL_OFFSET 1 +#define HPIPE_LOOPBACK_SEL_MASK (0x7 << HPIPE_LOOPBACK_SEL_OFFSET)
+#define HPIPE_SYNC_PATTERN_REG 0x090
+#define HPIPE_INTERFACE_REG 0x94 +#define HPIPE_INTERFACE_GEN_MAX_OFFSET 10 +#define HPIPE_INTERFACE_GEN_MAX_MASK (0x3 << HPIPE_INTERFACE_GEN_MAX_OFFSET) +#define HPIPE_INTERFACE_LINK_TRAIN_OFFSET 14 +#define HPIPE_INTERFACE_LINK_TRAIN_MASK (0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET)
+#define HPIPE_ISOLATE_MODE_REG 0x98 +#define HPIPE_ISOLATE_MODE_GEN_RX_OFFSET 0 +#define HPIPE_ISOLATE_MODE_GEN_RX_MASK (0xf << HPIPE_ISOLATE_MODE_GEN_RX_OFFSET) +#define HPIPE_ISOLATE_MODE_GEN_TX_OFFSET 4 +#define HPIPE_ISOLATE_MODE_GEN_TX_MASK (0xf << HPIPE_ISOLATE_MODE_GEN_TX_OFFSET)
+#define HPIPE_VTHIMPCAL_CTRL_REG 0x104
+#define HPIPE_PCIE_REG0 0x120 +#define HPIPE_PCIE_IDLE_SYNC_OFFSET 12 +#define HPIPE_PCIE_IDLE_SYNC_MASK (0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET) +#define HPIPE_PCIE_SEL_BITS_OFFSET 13 +#define HPIPE_PCIE_SEL_BITS_MASK (0x3 << HPIPE_PCIE_SEL_BITS_OFFSET)
+#define HPIPE_LANE_ALIGN_REG 0x124 +#define HPIPE_LANE_ALIGN_OFF_OFFSET 12 +#define HPIPE_LANE_ALIGN_OFF_MASK (0x1 << HPIPE_LANE_ALIGN_OFF_OFFSET)
+#define HPIPE_MISC_REG 0x13C +#define HPIPE_MISC_CLK100M_125M_OFFSET 4 +#define HPIPE_MISC_CLK100M_125M_MASK (0x1 << HPIPE_MISC_CLK100M_125M_OFFSET) +#define HPIPE_MISC_TXDCLK_2X_OFFSET 6 +#define HPIPE_MISC_TXDCLK_2X_MASK (0x1 << HPIPE_MISC_TXDCLK_2X_OFFSET) +#define HPIPE_MISC_CLK500_EN_OFFSET 7 +#define HPIPE_MISC_CLK500_EN_MASK (0x1 << HPIPE_MISC_CLK500_EN_OFFSET) +#define HPIPE_MISC_REFCLK_SEL_OFFSET 10 +#define HPIPE_MISC_REFCLK_SEL_MASK (0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET)
+#define HPIPE_RX_CONTROL_1_REG 0x140 +#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET 11 +#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK (0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET) +#define HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET 12 +#define HPIPE_RX_CONTROL_1_CLK8T_EN_MASK (0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET)
+#define HPIPE_PWR_CTR_REG 0x148 +#define HPIPE_PWR_CTR_RST_DFE_OFFSET 0 +#define HPIPE_PWR_CTR_RST_DFE_MASK (0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET) +#define HPIPE_PWR_CTR_SFT_RST_OFFSET 10 +#define HPIPE_PWR_CTR_SFT_RST_MASK (0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET)
+#define HPIPE_PLLINTP_REG1 0x150
+#define HPIPE_PWR_CTR_DTL_REG 0x184 +#define HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET 0x2 +#define HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK (0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET)
+#define HPIPE_RX_REG3 0x188
+#define HPIPE_TX_TRAIN_CTRL_REG 0x26C +#define HPIPE_TX_TRAIN_CTRL_G1_OFFSET 0 +#define HPIPE_TX_TRAIN_CTRL_G1_MASK (0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET) +#define HPIPE_TX_TRAIN_CTRL_GN1_OFFSET 1 +#define HPIPE_TX_TRAIN_CTRL_GN1_MASK (0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET) +#define HPIPE_TX_TRAIN_CTRL_G0_OFFSET 2 +#define HPIPE_TX_TRAIN_CTRL_G0_MASK (0x1 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET)
+#define HPIPE_PCIE_REG1 0x288 +#define HPIPE_PCIE_REG3 0x290
+#define HPIPE_TX_TRAIN_REG 0x31C +#define HPIPE_TX_TRAIN_CHK_INIT_OFFSET 4 +#define HPIPE_TX_TRAIN_CHK_INIT_MASK (0x1 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET) +#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET 7 +#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK (0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET)
+#define HPIPE_G1_SETTINGS_3_REG 0x440 +#define HPIPE_G1_SETTINGS_4_REG 0x444 +#define HPIPE_G2_SETTINGS_3_REG 0x448 +#define HPIPE_G2_SETTINGS_4_REG 0x44C
+#define HPIPE_DFE_CTRL_28_REG 0x49C +#define HPIPE_DFE_CTRL_28_PIPE4_OFFSET 7 +#define HPIPE_DFE_CTRL_28_PIPE4_MASK (0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET)
+#define HPIPE_LANE_CONFIG0_REG 0x604 +#define HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET 9 +#define HPIPE_LANE_CONFIG0_MAX_PLL_MASK (0x1 << HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET) +#define HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET 10 +#define HPIPE_LANE_CONFIG0_GEN2_PLL_MASK (0x1 << HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET)
+#define HPIPE_LANE_STATUS0_REG 0x60C +#define HPIPE_LANE_STATUS0_PCLK_EN_OFFSET 0 +#define HPIPE_LANE_STATUS0_PCLK_EN_MASK (0x1 << HPIPE_LANE_STATUS0_PCLK_EN_OFFSET)
+#define HPIPE_LANE_CFG4_REG 0x620 +#define HPIPE_LANE_CFG4_DFE_CTRL_OFFSET 0 +#define HPIPE_LANE_CFG4_DFE_CTRL_MASK (0x7 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET) +#define HPIPE_LANE_CFG4_DFE_OVER_OFFSET 6 +#define HPIPE_LANE_CFG4_DFE_OVER_MASK (0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET) +#define HPIPE_LANE_CFG4_SSC_CTRL_OFFSET 7 +#define HPIPE_LANE_CFG4_SSC_CTRL_MASK (0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET)
+#define HPIPE_LANE_EQ_CFG1_REG 0x6a0 +#define HPIPE_CFG_UPDATE_POLARITY_OFFSET 12 +#define HPIPE_CFG_UPDATE_POLARITY_MASK (0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET)
+#define HPIPE_RST_CLK_CTRL_REG 0x704 +#define HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET 0 +#define HPIPE_RST_CLK_CTRL_PIPE_RST_MASK (0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET) +#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET 2 +#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK (0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET) +#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET 3 +#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK (0x1 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET) +#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET 9 +#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK (0x1 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET)
+#define HPIPE_CLK_SRC_LO_REG 0x70c +#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET 5 +#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK (0x7 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET)
+#define HPIPE_CLK_SRC_HI_REG 0x710 +#define HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET 0 +#define HPIPE_CLK_SRC_HI_LANE_STRT_MASK (0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET) +#define HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET 1 +#define HPIPE_CLK_SRC_HI_LANE_BREAK_MASK (0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET) +#define HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET 2 +#define HPIPE_CLK_SRC_HI_LANE_MASTER_MASK (0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET) +#define HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET 7 +#define HPIPE_CLK_SRC_HI_MODE_PIPE_MASK (0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET)
+#define HPIPE_GLOBAL_MISC_CTRL 0x718 +#define HPIPE_GLOBAL_PM_CTRL 0x740 +#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET 0 +#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK (0xFF << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET)
+/***** COMPHY registers *****/ +#define COMMON_PHY_CFG1_REG 0x0 +#define COMMON_PHY_CFG1_PWR_UP_OFFSET 1 +#define COMMON_PHY_CFG1_PWR_UP_MASK (0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET) +#define COMMON_PHY_CFG1_PIPE_SELECT_OFFSET 2 +#define COMMON_PHY_CFG1_PIPE_SELECT_MASK (0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET) +#define COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET 13 +#define COMMON_PHY_CFG1_PWR_ON_RESET_MASK (0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET) +#define COMMON_PHY_CFG1_CORE_RSTN_OFFSET 14 +#define COMMON_PHY_CFG1_CORE_RSTN_MASK (0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET) +#define COMMON_PHY_PHY_MODE_OFFSET 15 +#define COMMON_PHY_PHY_MODE_MASK (0x1 << COMMON_PHY_PHY_MODE_OFFSET)
+#define COMMON_PHY_CFG6_REG 0x14 +#define COMMON_PHY_CFG6_IF_40_SEL_OFFSET 18 +#define COMMON_PHY_CFG6_IF_40_SEL_MASK (0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET)
+#define COMMON_SELECTOR_PHY_OFFSET 0x140 +#define COMMON_SELECTOR_PIPE_OFFSET 0x144
+/***** SATA registers *****/ +#define SATA3_VENDOR_ADDRESS 0xA0 +#define SATA3_VENDOR_ADDR_OFSSET 0 +#define SATA3_VENDOR_ADDR_MASK (0xFFFFFFFF << SATA3_VENDOR_ADDR_OFSSET) +#define SATA3_VENDOR_DATA 0xA4
+#define SATA_CONTROL_REG 0x0 +#define SATA3_CTRL_SATA0_PD_OFFSET 6 +#define SATA3_CTRL_SATA0_PD_MASK (1 << SATA3_CTRL_SATA0_PD_OFFSET) +#define SATA3_CTRL_SATA1_PD_OFFSET 14 +#define SATA3_CTRL_SATA1_PD_MASK (1 << SATA3_CTRL_SATA1_PD_OFFSET) +#define SATA3_CTRL_SATA1_ENABLE_OFFSET 22 +#define SATA3_CTRL_SATA1_ENABLE_MASK (1 << SATA3_CTRL_SATA1_ENABLE_OFFSET) +#define SATA3_CTRL_SATA_SSU_OFFSET 23 +#define SATA3_CTRL_SATA_SSU_MASK (1 << SATA3_CTRL_SATA_SSU_OFFSET)
+#define SATA_MBUS_SIZE_SELECT_REG 0x4 +#define SATA_MBUS_REGRET_EN_OFFSET 7 +#define SATA_MBUS_REGRET_EN_MASK (0x1 << SATA_MBUS_REGRET_EN_OFFSET)
+/***************************/
+typedef struct _CHIP_COMPHY_CONFIG CHIP_COMPHY_CONFIG;
+typedef struct {
- UINT32 Type;
- UINT32 MuxValue;
+} COMPHY_MUX_OPTIONS;
+typedef struct {
- UINT32 MaxLaneValues;
- COMPHY_MUX_OPTIONS MuxValues[MAX_LANE_OPTIONS];
+} COMPHY_MUX_DATA;
+typedef struct {
- UINT32 Type;
- UINT32 Speed;
- UINT32 Invert;
+} COMPHY_MAP;
+typedef struct {
- CHAR16 *TypeStr[MAX_LANE_OPTIONS];
- UINTN SpeedValue[MAX_LANE_OPTIONS];
- UINTN InvFlag[MAX_LANE_OPTIONS];
+} PCD_LANE_MAP;
+typedef +EFI_STATUS +(*COMPHY_CHIP_INIT) (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg
- );
+struct _CHIP_COMPHY_CONFIG {
- CHAR16* ChipType;
- COMPHY_MAP MapData[MAX_LANE_OPTIONS];
- COMPHY_MUX_DATA *MuxData;
- EFI_PHYSICAL_ADDRESS ComPhyBaseAddr;
- EFI_PHYSICAL_ADDRESS Hpipe3BaseAddr;
- COMPHY_CHIP_INIT Init;
- UINT32 LanesCount;
- UINT32 MuxBitCount;
+};
+VOID +ComPhyMuxInit (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg,
- IN COMPHY_MAP *ComPhyMapData,
- IN EFI_PHYSICAL_ADDRESS SelectorBase
- );
+EFI_STATUS +ComPhyCp110Init (
- IN CHIP_COMPHY_CONFIG * First
- );
+VOID +RegSet (
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT32 Data,
- IN UINT32 Mask
- );
+VOID +RegSetSilent (
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT32 Data,
- IN UINT32 Mask
- );
+VOID +RegSet16 (
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT16 Data,
- IN UINT16 Mask
- );
+VOID +RegSetSilent16(
- IN EFI_PHYSICAL_ADDRESS Addr,
- IN UINT16 Data,
- IN UINT16 Mask
- );
+#endif // __COMPHY_H__ diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf new file mode 100644 index 0000000..a7ee1f8 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf @@ -0,0 +1,109 @@ +# Copyright (C) 2016 Marvell International Ltd. +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute and/or +# modify this File under the following licensing terms. +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Marvell nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#
+[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = MarvellComPhyLib
- FILE_GUID = 3314541a-9647-4a37-b8c6-24e000900e4e
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = ComPhyLib
+[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ArmPkg/ArmPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
- OpenPlatformPkg/Platforms/Marvell/Marvell.dec
+[LibraryClasses]
- ArmLib
- DebugLib
- MemoryAllocationLib
- PcdLib
- IoLib
- ParsePcdLib
+[Sources.common]
- ComPhyLib.c
- ComPhyCp110.c
- ComPhyMux.c
+[FixedPcd]
- gMarvellTokenSpaceGuid.PcdComPhyChipCount
- #Chip0
- gMarvellTokenSpaceGuid.PcdChip0Compatible
- gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress
- gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes
- gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds
- gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags
- #Chip1
- gMarvellTokenSpaceGuid.PcdChip1Compatible
- gMarvellTokenSpaceGuid.PcdChip1ComPhyBaseAddress
- gMarvellTokenSpaceGuid.PcdChip1Hpipe3BaseAddress
- gMarvellTokenSpaceGuid.PcdChip1ComPhyMuxBitCount
- gMarvellTokenSpaceGuid.PcdChip1ComPhyMaxLanes
- gMarvellTokenSpaceGuid.PcdChip1ComPhyTypes
- gMarvellTokenSpaceGuid.PcdChip1ComPhySpeeds
- gMarvellTokenSpaceGuid.PcdChip1ComPhyInvFlags
- #Chip2
- gMarvellTokenSpaceGuid.PcdChip2Compatible
- gMarvellTokenSpaceGuid.PcdChip2ComPhyBaseAddress
- gMarvellTokenSpaceGuid.PcdChip2Hpipe3BaseAddress
- gMarvellTokenSpaceGuid.PcdChip2ComPhyMuxBitCount
- gMarvellTokenSpaceGuid.PcdChip2ComPhyMaxLanes
- gMarvellTokenSpaceGuid.PcdChip2ComPhyTypes
- gMarvellTokenSpaceGuid.PcdChip2ComPhySpeeds
- gMarvellTokenSpaceGuid.PcdChip2ComPhyInvFlags
- #Chip3
- gMarvellTokenSpaceGuid.PcdChip3Compatible
- gMarvellTokenSpaceGuid.PcdChip3ComPhyBaseAddress
- gMarvellTokenSpaceGuid.PcdChip3Hpipe3BaseAddress
- gMarvellTokenSpaceGuid.PcdChip3ComPhyMuxBitCount
- gMarvellTokenSpaceGuid.PcdChip3ComPhyMaxLanes
- gMarvellTokenSpaceGuid.PcdChip3ComPhyTypes
- gMarvellTokenSpaceGuid.PcdChip3ComPhySpeeds
- gMarvellTokenSpaceGuid.PcdChip3ComPhyInvFlags
- #SATA
- gMarvellTokenSpaceGuid.PcdSataBaseAddress
diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c new file mode 100644 index 0000000..595745b --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c @@ -0,0 +1,132 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
+* Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#include "ComPhyLib.h"
+STATIC +VOID +ComPhyMuxCheckConfig (
- IN COMPHY_MUX_DATA *MuxData,
- IN COMPHY_MAP *ComPhyMapData,
- IN UINTN ComPhyMaxLanes
- )
+{
- COMPHY_MUX_OPTIONS *PtrMuxOpt;
- UINTN Lane, Opt, Valid;
- for (Lane = 0; Lane < ComPhyMaxLanes; Lane++, ComPhyMapData++, MuxData++) {
- PtrMuxOpt = MuxData->MuxValues;
- for (Opt = 0, Valid = 0; Opt < MuxData->MaxLaneValues; Opt++, PtrMuxOpt++) {
if (PtrMuxOpt->Type == ComPhyMapData->Type) {
Valid = 1;
break;
}
- }
- if (Valid == 0) {
DEBUG((DEBUG_INFO, "Lane number %d, had invalid Type %d\n", Lane,
ComPhyMapData->Type));
DEBUG((DEBUG_INFO, "Set Lane %d as Type %d\n", Lane,
PHY_TYPE_UNCONNECTED));
ComPhyMapData->Type = PHY_TYPE_UNCONNECTED;
- } else {
DEBUG((DEBUG_INFO, "Lane number %d, has Type %d\n", Lane,
ComPhyMapData->Type));
- }
- }
+}
+STATIC +UINT32 +ComPhyMuxGetMuxValue (
- IN COMPHY_MUX_DATA *MuxData,
- IN UINT32 Type,
- IN UINTN Lane
- )
+{
- COMPHY_MUX_OPTIONS *PtrMuxOpt;
- UINTN Opt;
- UINT32 Value = 0;
- PtrMuxOpt = MuxData->MuxValues;
- for (Opt = 0 ; Opt < MuxData->MaxLaneValues; Opt++, PtrMuxOpt++)
- if (PtrMuxOpt->Type == Type) {
Value = PtrMuxOpt->MuxValue;
break;
- }
- return Value;
+}
+STATIC +VOID +ComPhyMuxRegWrite (
- IN COMPHY_MUX_DATA *MuxData,
- IN COMPHY_MAP *ComPhyMapData,
- IN UINTN ComPhyMaxLanes,
- IN EFI_PHYSICAL_ADDRESS SelectorBase,
- IN UINT32 BitCount
- )
+{
- UINT32 Lane, Value, Offset, Mask;
- for (Lane = 0; Lane < ComPhyMaxLanes; Lane++, ComPhyMapData++, MuxData++) {
- Offset = Lane * BitCount;
- Mask = (((1 << BitCount) - 1) << Offset);
- Value = (ComPhyMuxGetMuxValue (MuxData, ComPhyMapData->Type, Lane) <<
Offset);
- RegSet (SelectorBase, Value, Mask);
- }
+}
+VOID +ComPhyMuxInit (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg,
- IN COMPHY_MAP *ComPhyMapData,
- IN EFI_PHYSICAL_ADDRESS SelectorBase
- )
+{
- COMPHY_MUX_DATA *MuxData;
- UINT32 MuxBitCount;
- UINT32 ComPhyMaxLanes;
- ComPhyMaxLanes = PtrChipCfg->LanesCount;
- MuxData = PtrChipCfg->MuxData;
- MuxBitCount = PtrChipCfg->MuxBitCount;
- /* Check if the configuration is valid */
- ComPhyMuxCheckConfig (MuxData, ComPhyMapData, ComPhyMaxLanes);
- /* Init COMPHY selectors */
- ComPhyMuxRegWrite (MuxData, ComPhyMapData, ComPhyMaxLanes, SelectorBase,
- MuxBitCount);
+} diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e63add4..70c5cce 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -128,6 +128,56 @@ gMarvellTokenSpaceGuid.PcdSpiFlashPageSize|0|UINT32|0x3000055 gMarvellTokenSpaceGuid.PcdSpiFlashId|0|UINT32|0x3000056 +#ComPhy
- #Chip0
- gMarvellTokenSpaceGuid.PcdComPhyChipCount|0|UINT32|0x30000098
- gMarvellTokenSpaceGuid.PcdChip0Compatible|{ 0 }|VOID*|0x30000064
- gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress|0|UINT64|0x30000065
- gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress|0|UINT64|0x30000066
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount|0|UINT32|0x30000067
- gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes|0|UINT32|0x30001267
- gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|{ 0 }|VOID*|0x30000068
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|{ 0 }|VOID*|0x30000069
- gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags|{ 0 }|VOID*|0x30000070
- #Chip1
- gMarvellTokenSpaceGuid.PcdChip1Compatible|{ 0 }|VOID*|0x30000100
- gMarvellTokenSpaceGuid.PcdChip1ComPhyBaseAddress|0|UINT64|0x30000101
- gMarvellTokenSpaceGuid.PcdChip1Hpipe3BaseAddress|0|UINT64|0x30000102
- gMarvellTokenSpaceGuid.PcdChip1ComPhyMuxBitCount|0|UINT32|0x30000103
- gMarvellTokenSpaceGuid.PcdChip1ComPhyMaxLanes|0|UINT32|0x30001304
- gMarvellTokenSpaceGuid.PcdChip1ComPhyTypes|{ 0 }|VOID*|0x30000105
- gMarvellTokenSpaceGuid.PcdChip1ComPhySpeeds|{ 0 }|VOID*|0x30000106
- gMarvellTokenSpaceGuid.PcdChip1ComPhyInvFlags|{ 0 }|VOID*|0x30000107
- #Chip2
- gMarvellTokenSpaceGuid.PcdChip2Compatible|{ 0 }|VOID*|0x30000135
- gMarvellTokenSpaceGuid.PcdChip2ComPhyBaseAddress|0|UINT64|0x30000136
- gMarvellTokenSpaceGuid.PcdChip2Hpipe3BaseAddress|0|UINT64|0x30000137
- gMarvellTokenSpaceGuid.PcdChip2ComPhyMuxBitCount|0|UINT32|0x30000138
- gMarvellTokenSpaceGuid.PcdChip2ComPhyMaxLanes|0|UINT32|0x30000139
- gMarvellTokenSpaceGuid.PcdChip2ComPhyTypes|{ 0 }|VOID*|0x30000140
- gMarvellTokenSpaceGuid.PcdChip2ComPhySpeeds|{ 0 }|VOID*|0x30000141
- gMarvellTokenSpaceGuid.PcdChip2ComPhyInvFlags|{ 0 }|VOID*|0x30000142
- #Chip3
- gMarvellTokenSpaceGuid.PcdChip3Compatible|{ 0 }|VOID*|0x30000170
- gMarvellTokenSpaceGuid.PcdChip3ComPhyBaseAddress|0|UINT64|0x30000171
- gMarvellTokenSpaceGuid.PcdChip3Hpipe3BaseAddress|0|UINT64|0x30000172
- gMarvellTokenSpaceGuid.PcdChip3ComPhyMuxBitCount|0|UINT32|0x30000173
- gMarvellTokenSpaceGuid.PcdChip3ComPhyMaxLanes|0|UINT32|0x30000174
- gMarvellTokenSpaceGuid.PcdChip3ComPhyTypes|{ 0 }|VOID*|0x30000175
- gMarvellTokenSpaceGuid.PcdChip3ComPhySpeeds|{ 0 }|VOID*|0x30000176
- gMarvellTokenSpaceGuid.PcdChip3ComPhyInvFlags|{ 0 }|VOID*|0x30000177
+#SATA
- gMarvellTokenSpaceGuid.PcdSataBaseAddress|0|UINT32|0x4000052
[Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} -- 1.8.3.1
From: Jan Dąbroś jsd@semihalf.com
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 12 ++++++++++++ .../Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 4 ++-- .../Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 1 + 4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 0e234ef..25e2763 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -31,6 +31,7 @@ # [LibraryClasses.common] ArmPlatformLib|OpenPlatformPkg/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf + ComPhyLib|OpenPlatformPkg/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf MppLib|OpenPlatformPkg/Platforms/Marvell/Library/MppLib/MppLib.inf ParsePcdLib|OpenPlatformPkg/Platforms/Marvell/Library/ParsePcdLib/ParsePcdLib.inf
diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 29ddf7a..347fb71 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -95,3 +95,15 @@ gMarvellTokenSpaceGuid.PcdSpiFlashEraseSize|65536 gMarvellTokenSpaceGuid.PcdSpiFlashPageSize|256 gMarvellTokenSpaceGuid.PcdSpiFlashId|0x20BA18 + + #ComPhy + gMarvellTokenSpaceGuid.PcdComPhyChipCount|1 + + gMarvellTokenSpaceGuid.PcdChip0ComPhyMaxLanes|6 + gMarvellTokenSpaceGuid.PcdChip0ComPhyBaseAddress|0xF2441000 + gMarvellTokenSpaceGuid.PcdChip0Hpipe3BaseAddress|0xF2120000 + gMarvellTokenSpaceGuid.PcdChip0ComPhyMuxBitCount|4 + gMarvellTokenSpaceGuid.PcdChip0Compatible|L"Cp110" + + gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|L"SGMII2;USB3_HOST0;SGMII0;SATA1;USB3_HOST1;PCIE2" + gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|L"3125;5000;1250;5000;5000;5000" diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c index a2b25e1..e9fe92c 100644 --- a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c @@ -16,6 +16,7 @@ #include <Library/ArmLib.h> #include <Library/ArmPlatformLib.h> #include <Library/MppLib.h> +#include <Library/MvComPhyLib.h> #include <Ppi/ArmMpCoreInfo.h>
@@ -92,8 +93,7 @@ ArmPlatformInitialize ( return RETURN_SUCCESS; }
- //TODO: Add basic platfrom initialization - + MvComPhyInit (); MppInitialize (); return RETURN_SUCCESS; } diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf index bd78406..367d1ce 100644 --- a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf +++ b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf @@ -47,6 +47,7 @@
[LibraryClasses] ArmLib + ComPhyLib DebugLib MemoryAllocationLib MppLib
From: Bartosz Szczepanek bsz@semihalf.com
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Armada/Armada.dsc.inc | 17 ++++++++++++++++- Platforms/Marvell/Armada/Armada70x0.fdf | 12 ++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 25e2763..2e16b8f 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -91,8 +91,11 @@ EfiResetSystemLib|EmbeddedPkg/Library/TemplateResetSystemLib/TemplateResetSystemLib.inf RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
- # Networking Requirements for ArmPlatformPkg/Bds + # Network support NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf + IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf + DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf + UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
# These libraries are used by the dynamic EFI Shell commands ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf @@ -389,6 +392,18 @@ OpenPlatformPkg/Drivers/Spi/MvSpiDxe.inf OpenPlatformPkg/Drivers/Spi/Devices/MvSpiFlash.inf
+ # Network support + MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf + MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf + MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf + MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf + MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf + MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf + MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf + MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf + MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf + MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf index 61793dc..955577b 100644 --- a/Platforms/Marvell/Armada/Armada70x0.fdf +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -108,6 +108,18 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c INF OpenPlatformPkg/Drivers/Spi/MvSpiDxe.inf INF OpenPlatformPkg/Drivers/Spi/Devices/MvSpiFlash.inf
+ # Network support + INF MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf + INF MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf + INF MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf + INF MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf + INF MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf + INF MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf + INF MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf + INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf + INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf + INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf + # Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
From: Bartosz Szczepanek bsz@semihalf.com
MDIO protocol allows PHY drivers to access their resources using SMI bus. It consists of MARVELL_MDIO_READ and MARVELL_MDIO_WRITE functions.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Documentation/Marvell/PortingGuide/Mdio.txt | 7 + Drivers/Net/MvMdioDxe/MvMdioDxe.c | 237 ++++++++++++++++++++++++++++ Drivers/Net/MvMdioDxe/MvMdioDxe.h | 57 +++++++ Drivers/Net/MvMdioDxe/MvMdioDxe.inf | 69 ++++++++ Platforms/Marvell/Include/Protocol/Mdio.h | 66 ++++++++ Platforms/Marvell/Marvell.dec | 4 + 6 files changed, 440 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Mdio.txt create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.c create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.h create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.inf create mode 100644 Platforms/Marvell/Include/Protocol/Mdio.h
diff --git a/Documentation/Marvell/PortingGuide/Mdio.txt b/Documentation/Marvell/PortingGuide/Mdio.txt new file mode 100644 index 0000000..c341d9e --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Mdio.txt @@ -0,0 +1,7 @@ +MDIO driver configuration +------------------------- +MDIO driver provides access to network PHYs' registers via MARVELL_MDIO_READ and +MARVELL_MDIO_WRITE functions (MARVELL_MDIO_PROTOCOL). Following PCD is required: + + gMarvellTokenSpaceGuid.PcdMdioBaseAddress + (base address of SMI management register) diff --git a/Drivers/Net/MvMdioDxe/MvMdioDxe.c b/Drivers/Net/MvMdioDxe/MvMdioDxe.c new file mode 100644 index 0000000..ae466d7 --- /dev/null +++ b/Drivers/Net/MvMdioDxe/MvMdioDxe.c @@ -0,0 +1,237 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include <Protocol/DriverBinding.h> +#include <Protocol/Mdio.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include "MvMdioDxe.h" + +UINT64 MdioBase = 0; + +STATIC +EFI_STATUS +MdioCheckParam ( + INTN PhyAddr, + INTN RegOff + ) +{ + if (PhyAddr > MVEBU_PHY_ADDR_MASK) { + DEBUG((DEBUG_ERROR, "Invalid PHY address %d\n", PhyAddr)); + return EFI_INVALID_PARAMETER; + } + + if (RegOff > MVEBU_PHY_REG_MASK) { + DEBUG((DEBUG_ERROR, "Invalid register offset %d\n", RegOff)); + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MdioWaitReady ( + VOID + ) +{ + UINT32 Timeout = MVEBU_SMI_TIMEOUT; + UINT32 MdioReg; + + /* wait till the SMI is not busy */ + do { + /* read smi register */ + MdioReg = MmioRead32(MdioBase); + if (Timeout-- == 0) { + DEBUG((DEBUG_ERROR, "SMI busy Timeout\n")); + return EFI_TIMEOUT; + } + } while (MdioReg & MVEBU_SMI_BUSY); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MdioWaitValid ( + VOID + ) +{ + UINT32 Timeout = MVEBU_SMI_TIMEOUT; + UINT32 MdioReg; + + /* wait till read value is ready */ + do { + /* read smi register */ + MdioReg = MmioRead32 (MdioBase); + if (Timeout-- == 0) { + DEBUG((DEBUG_ERROR, "SMI read ready time-out\n")); + return EFI_TIMEOUT; + } + } while (!(MdioReg & MVEBU_SMI_READ_VALID)); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MdioOperation ( + IN CONST MARVELL_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff, + IN BOOLEAN Write, + IN OUT UINT32 *Data + ) +{ + UINT32 MdioReg; + EFI_STATUS Status; + + Status = MdioCheckParam (PhyAddr, RegOff); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MdioDxe: wrong parameters\n")); + return Status; + } + + /* wait till the SMI is not busy */ + Status = MdioWaitReady (); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n")); + return Status; + } + + /* fill the phy addr and reg offset and write opcode and data */ + MdioReg = (PhyAddr << MVEBU_SMI_DEV_ADDR_OFFS) + | (RegOff << MVEBU_SMI_REG_ADDR_OFFS); + if (Write) { + MdioReg &= ~MVEBU_SMI_OPCODE_READ; + MdioReg |= (*Data << MVEBU_SMI_DATA_OFFS); + } else { + MdioReg |= MVEBU_SMI_OPCODE_READ; + } + + /* write the smi register */ + MdioRegWrite32 (MdioReg, MdioBase); + + /* make sure that the write transaction is over */ + Status = Write ? MdioWaitReady () : MdioWaitValid (); + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n")); + return Status; + } + + if (!Write) { + *Data = MmioRead32 (MdioBase) & MVEBU_SMI_DATA_MASK; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvMdioRead ( + IN CONST MARVELL_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff, + IN UINT32 *Data + ) +{ + EFI_STATUS Status; + + Status = MdioOperation ( + This, + PhyAddr, + RegOff, + FALSE, + Data + ); + + return Status; +} + +EFI_STATUS +MvMdioWrite ( + IN CONST MARVELL_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff, + IN UINT32 Data + ) +{ + return MdioOperation ( + This, + PhyAddr, + RegOff, + TRUE, + &Data + ); +} + +EFI_STATUS +EFIAPI +MvMdioDxeInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + MARVELL_MDIO_PROTOCOL *Mdio; + EFI_STATUS Status; + EFI_HANDLE Handle = NULL; + + Mdio = AllocateZeroPool (sizeof (MARVELL_MDIO_PROTOCOL)); + 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, + NULL + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "Failed to install interfaces\n")); + return Status; + } + + return EFI_SUCCESS; +} diff --git a/Drivers/Net/MvMdioDxe/MvMdioDxe.h b/Drivers/Net/MvMdioDxe/MvMdioDxe.h new file mode 100644 index 0000000..b41a1e6 --- /dev/null +++ b/Drivers/Net/MvMdioDxe/MvMdioDxe.h @@ -0,0 +1,57 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#ifndef __MDIO_DXE_H__ +#define __MDIO_DXE_H__ + +#include <Uefi.h> + +#define MVEBU_SMI_TIMEOUT 10000 + +/* SMI register fields */ +#define MVEBU_SMI_DATA_OFFS 0 /* Data */ +#define MVEBU_SMI_DATA_MASK (0xffff << MVEBU_SMI_DATA_OFFS) +#define MVEBU_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ +#define MVEBU_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr*/ +#define MVEBU_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ +#define MVEBU_SMI_OPCODE_READ (1 << MVEBU_SMI_OPCODE_OFFS) +#define MVEBU_SMI_READ_VALID (1 << 27) /* Read Valid */ +#define MVEBU_SMI_BUSY (1 << 28) /* Busy */ + +#define MVEBU_PHY_REG_MASK 0x1f +#define MVEBU_PHY_ADDR_MASK 0x1f + +#define MdioRegWrite32(x, y) MmioWrite32((y), (x)) + +#endif // __MDIO_DXE_H__ diff --git a/Drivers/Net/MvMdioDxe/MvMdioDxe.inf b/Drivers/Net/MvMdioDxe/MvMdioDxe.inf new file mode 100644 index 0000000..c6dc443 --- /dev/null +++ b/Drivers/Net/MvMdioDxe/MvMdioDxe.inf @@ -0,0 +1,69 @@ +# Copyright (C) 2016 Marvell International Ltd. +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute and/or +# modify this File under the following licensing terms. +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Marvell nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MdioDxe + FILE_GUID = 59fc3843-d8d4-40ba-ae07-38967138509c + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MvMdioDxeInitialise + +[Sources.common] + MvMdioDxe.c + MvMdioDxe.h + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IoLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + +[Protocols] + gMarvellMdioProtocolGuid + +[Pcd] + gMarvellTokenSpaceGuid.PcdMdioBaseAddress + +[Depex] + TRUE diff --git a/Platforms/Marvell/Include/Protocol/Mdio.h b/Platforms/Marvell/Include/Protocol/Mdio.h new file mode 100644 index 0000000..44e4579 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Mdio.h @@ -0,0 +1,66 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#ifndef __MDIO_H__ +#define __MDIO_H__ + +#define MARVELL_MDIO_PROTOCOL_GUID { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} + +typedef struct _MARVELL_MDIO_PROTOCOL MARVELL_MDIO_PROTOCOL; + +typedef +EFI_STATUS +(EFIAPI *MARVELL_MDIO_READ) ( + IN CONST MARVELL_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff, + IN UINT32 *Data + ); + +typedef +EFI_STATUS +(EFIAPI *MARVELL_MDIO_WRITE) ( + IN CONST MARVELL_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff, + IN UINT32 Data + ); + +struct _MARVELL_MDIO_PROTOCOL { + MARVELL_MDIO_READ Read; + MARVELL_MDIO_WRITE Write; +}; + +extern EFI_GUID gMarvellMdioProtocolGuid; +#endif diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index 70c5cce..9744c37 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -178,8 +178,12 @@ #SATA gMarvellTokenSpaceGuid.PcdSataBaseAddress|0|UINT32|0x4000052
+#MDIO + gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0|UINT64|0x3000043 + [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} + gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }}
On Thu, Aug 11, 2016 at 11:51:35AM +0200, Marcin Wojtas wrote:
From: Bartosz Szczepanek bsz@semihalf.com
MDIO protocol allows PHY drivers to access their resources using SMI bus. It consists of MARVELL_MDIO_READ and MARVELL_MDIO_WRITE functions.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Thanks! Reviewed-by: Leif Lindholm leif.lindholm@linaro.org
Documentation/Marvell/PortingGuide/Mdio.txt | 7 + Drivers/Net/MvMdioDxe/MvMdioDxe.c | 237 ++++++++++++++++++++++++++++ Drivers/Net/MvMdioDxe/MvMdioDxe.h | 57 +++++++ Drivers/Net/MvMdioDxe/MvMdioDxe.inf | 69 ++++++++ Platforms/Marvell/Include/Protocol/Mdio.h | 66 ++++++++ Platforms/Marvell/Marvell.dec | 4 + 6 files changed, 440 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Mdio.txt create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.c create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.h create mode 100644 Drivers/Net/MvMdioDxe/MvMdioDxe.inf create mode 100644 Platforms/Marvell/Include/Protocol/Mdio.h
diff --git a/Documentation/Marvell/PortingGuide/Mdio.txt b/Documentation/Marvell/PortingGuide/Mdio.txt new file mode 100644 index 0000000..c341d9e --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Mdio.txt @@ -0,0 +1,7 @@ +MDIO driver configuration +------------------------- +MDIO driver provides access to network PHYs' registers via MARVELL_MDIO_READ and +MARVELL_MDIO_WRITE functions (MARVELL_MDIO_PROTOCOL). Following PCD is required:
- gMarvellTokenSpaceGuid.PcdMdioBaseAddress
- (base address of SMI management register)
diff --git a/Drivers/Net/MvMdioDxe/MvMdioDxe.c b/Drivers/Net/MvMdioDxe/MvMdioDxe.c new file mode 100644 index 0000000..ae466d7 --- /dev/null +++ b/Drivers/Net/MvMdioDxe/MvMdioDxe.c @@ -0,0 +1,237 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#include <Protocol/DriverBinding.h> +#include <Protocol/Mdio.h>
+#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h>
+#include "MvMdioDxe.h"
+UINT64 MdioBase = 0;
+STATIC +EFI_STATUS +MdioCheckParam (
- INTN PhyAddr,
- INTN RegOff
- )
+{
- if (PhyAddr > MVEBU_PHY_ADDR_MASK) {
- DEBUG((DEBUG_ERROR, "Invalid PHY address %d\n", PhyAddr));
- return EFI_INVALID_PARAMETER;
- }
- if (RegOff > MVEBU_PHY_REG_MASK) {
- DEBUG((DEBUG_ERROR, "Invalid register offset %d\n", RegOff));
- return EFI_INVALID_PARAMETER;
- }
- return EFI_SUCCESS;
+}
+STATIC +EFI_STATUS +MdioWaitReady (
- VOID
- )
+{
- UINT32 Timeout = MVEBU_SMI_TIMEOUT;
- UINT32 MdioReg;
- /* wait till the SMI is not busy */
- do {
- /* read smi register */
- MdioReg = MmioRead32(MdioBase);
- if (Timeout-- == 0) {
DEBUG((DEBUG_ERROR, "SMI busy Timeout\n"));
return EFI_TIMEOUT;
- }
- } while (MdioReg & MVEBU_SMI_BUSY);
- return EFI_SUCCESS;
+}
+STATIC +EFI_STATUS +MdioWaitValid (
- VOID
- )
+{
- UINT32 Timeout = MVEBU_SMI_TIMEOUT;
- UINT32 MdioReg;
- /* wait till read value is ready */
- do {
- /* read smi register */
- MdioReg = MmioRead32 (MdioBase);
- if (Timeout-- == 0) {
DEBUG((DEBUG_ERROR, "SMI read ready time-out\n"));
return EFI_TIMEOUT;
- }
- } while (!(MdioReg & MVEBU_SMI_READ_VALID));
- return EFI_SUCCESS;
+}
+STATIC +EFI_STATUS +MdioOperation (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff,
- IN BOOLEAN Write,
- IN OUT UINT32 *Data
- )
+{
- UINT32 MdioReg;
- EFI_STATUS Status;
- Status = MdioCheckParam (PhyAddr, RegOff);
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "MdioDxe: wrong parameters\n"));
- return Status;
- }
- /* wait till the SMI is not busy */
- Status = MdioWaitReady ();
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n"));
- return Status;
- }
- /* fill the phy addr and reg offset and write opcode and data */
- MdioReg = (PhyAddr << MVEBU_SMI_DEV_ADDR_OFFS)
| (RegOff << MVEBU_SMI_REG_ADDR_OFFS);
- if (Write) {
- MdioReg &= ~MVEBU_SMI_OPCODE_READ;
- MdioReg |= (*Data << MVEBU_SMI_DATA_OFFS);
- } else {
- MdioReg |= MVEBU_SMI_OPCODE_READ;
- }
- /* write the smi register */
- MdioRegWrite32 (MdioReg, MdioBase);
- /* make sure that the write transaction is over */
- Status = Write ? MdioWaitReady () : MdioWaitValid ();
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "MdioDxe: MdioWaitReady error\n"));
- return Status;
- }
- if (!Write) {
- *Data = MmioRead32 (MdioBase) & MVEBU_SMI_DATA_MASK;
- }
- return EFI_SUCCESS;
+}
+STATIC +EFI_STATUS +MvMdioRead (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff,
- IN UINT32 *Data
- )
+{
- EFI_STATUS Status;
- Status = MdioOperation (
This,
PhyAddr,
RegOff,
FALSE,
Data
);
- return Status;
+}
+EFI_STATUS +MvMdioWrite (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff,
- IN UINT32 Data
- )
+{
- return MdioOperation (
This,
PhyAddr,
RegOff,
TRUE,
&Data
);
+}
+EFI_STATUS +EFIAPI +MvMdioDxeInitialise (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
+{
- MARVELL_MDIO_PROTOCOL *Mdio;
- EFI_STATUS Status;
- EFI_HANDLE Handle = NULL;
- Mdio = AllocateZeroPool (sizeof (MARVELL_MDIO_PROTOCOL));
- 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,
NULL
);
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "Failed to install interfaces\n"));
- return Status;
- }
- return EFI_SUCCESS;
+} diff --git a/Drivers/Net/MvMdioDxe/MvMdioDxe.h b/Drivers/Net/MvMdioDxe/MvMdioDxe.h new file mode 100644 index 0000000..b41a1e6 --- /dev/null +++ b/Drivers/Net/MvMdioDxe/MvMdioDxe.h @@ -0,0 +1,57 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#ifndef __MDIO_DXE_H__ +#define __MDIO_DXE_H__
+#include <Uefi.h>
+#define MVEBU_SMI_TIMEOUT 10000
+/* SMI register fields */ +#define MVEBU_SMI_DATA_OFFS 0 /* Data */ +#define MVEBU_SMI_DATA_MASK (0xffff << MVEBU_SMI_DATA_OFFS) +#define MVEBU_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ +#define MVEBU_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr*/ +#define MVEBU_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ +#define MVEBU_SMI_OPCODE_READ (1 << MVEBU_SMI_OPCODE_OFFS) +#define MVEBU_SMI_READ_VALID (1 << 27) /* Read Valid */ +#define MVEBU_SMI_BUSY (1 << 28) /* Busy */
+#define MVEBU_PHY_REG_MASK 0x1f +#define MVEBU_PHY_ADDR_MASK 0x1f
+#define MdioRegWrite32(x, y) MmioWrite32((y), (x))
+#endif // __MDIO_DXE_H__ diff --git a/Drivers/Net/MvMdioDxe/MvMdioDxe.inf b/Drivers/Net/MvMdioDxe/MvMdioDxe.inf new file mode 100644 index 0000000..c6dc443 --- /dev/null +++ b/Drivers/Net/MvMdioDxe/MvMdioDxe.inf @@ -0,0 +1,69 @@ +# Copyright (C) 2016 Marvell International Ltd. +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute and/or +# modify this File under the following licensing terms. +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Marvell nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#
+[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = MdioDxe
- FILE_GUID = 59fc3843-d8d4-40ba-ae07-38967138509c
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = MvMdioDxeInitialise
+[Sources.common]
- MvMdioDxe.c
- MvMdioDxe.h
+[Packages]
- ArmPkg/ArmPkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- MdePkg/MdePkg.dec
- OpenPlatformPkg/Platforms/Marvell/Marvell.dec
+[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- IoLib
- PcdLib
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- UefiLib
+[Protocols]
- gMarvellMdioProtocolGuid
+[Pcd]
- gMarvellTokenSpaceGuid.PcdMdioBaseAddress
+[Depex]
- TRUE
diff --git a/Platforms/Marvell/Include/Protocol/Mdio.h b/Platforms/Marvell/Include/Protocol/Mdio.h new file mode 100644 index 0000000..44e4579 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Mdio.h @@ -0,0 +1,66 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#ifndef __MDIO_H__ +#define __MDIO_H__
+#define MARVELL_MDIO_PROTOCOL_GUID { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
+typedef struct _MARVELL_MDIO_PROTOCOL MARVELL_MDIO_PROTOCOL;
+typedef +EFI_STATUS +(EFIAPI *MARVELL_MDIO_READ) (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff,
- IN UINT32 *Data
- );
+typedef +EFI_STATUS +(EFIAPI *MARVELL_MDIO_WRITE) (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff,
- IN UINT32 Data
- );
+struct _MARVELL_MDIO_PROTOCOL {
- MARVELL_MDIO_READ Read;
- MARVELL_MDIO_WRITE Write;
+};
+extern EFI_GUID gMarvellMdioProtocolGuid; +#endif diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index 70c5cce..9744c37 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -178,8 +178,12 @@ #SATA gMarvellTokenSpaceGuid.PcdSataBaseAddress|0|UINT32|0x4000052 +#MDIO
- gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0|UINT64|0x3000043
[Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
- gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }}
1.8.3.1
From: Bartosz Szczepanek bsz@semihalf.com
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 3 +++ Platforms/Marvell/Armada/Armada70x0.fdf | 1 + 3 files changed, 5 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 2e16b8f..0b00826 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -403,6 +403,7 @@ MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf + OpenPlatformPkg/Drivers/Net/MvMdioDxe/MvMdioDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 347fb71..f513b48 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -107,3 +107,6 @@
gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|L"SGMII2;USB3_HOST0;SGMII0;SATA1;USB3_HOST1;PCIE2" gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|L"3125;5000;1250;5000;5000;5000" + + #MDIO + gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0xF212A200 diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf index 955577b..fb5bb6a 100644 --- a/Platforms/Marvell/Armada/Armada70x0.fdf +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -119,6 +119,7 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c INF MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf + INF OpenPlatformPkg/Drivers/Net/MvMdioDxe/MvMdioDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
From: Bartosz Szczepanek bsz@semihalf.com
MARVELL_PHY_PROTOCOL describes API between PHY devices and network controller drivers. It consists of Status (used for periodic link state check) and Init (called once) functions. This is used on Marvell A70x0 platform in conjunction with MvPhy and Pp2Dxe drivers.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Include/Protocol/MvPhy.h | 103 +++++++++++++++++++++++++++++ Platforms/Marvell/Marvell.dec | 1 + 2 files changed, 104 insertions(+) create mode 100644 Platforms/Marvell/Include/Protocol/MvPhy.h
diff --git a/Platforms/Marvell/Include/Protocol/MvPhy.h b/Platforms/Marvell/Include/Protocol/MvPhy.h new file mode 100644 index 0000000..67bbd2d --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/MvPhy.h @@ -0,0 +1,103 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#ifndef __MV_PHY_H__ +#define __MV_PHY_H__ + +#define MARVELL_PHY_PROTOCOL_GUID { 0x0d728a1e, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} + +typedef struct _MARVELL_PHY_PROTOCOL MARVELL_PHY_PROTOCOL; + +typedef enum { + PHY_CONNECTION_RGMII, + PHY_CONNECTION_RGMII_ID, + PHY_CONNECTION_RGMII_TXID, + PHY_CONNECTION_RGMII_RXID, + PHY_CONNECTION_SGMII, + PHY_CONNECTION_RTBI, + PHY_CONNECTION_XAUI, + PHY_CONNECTION_RXAUI +} PHY_CONNECTION; + +typedef enum { + NO_SPEED, + SPEED_10, + SPEED_100, + SPEED_1000, + SPEED_2500, + SPEED_10000 +} PHY_SPEED; + +typedef struct { + UINT32 Addr; + BOOLEAN LinkUp; + BOOLEAN FullDuplex; + BOOLEAN AutoNegotiation; + PHY_SPEED Speed; + PHY_CONNECTION Connection; +} PHY_DEVICE; + +/* + * Before calling MARVELL_PHY_STATUS driver should request PHY_DEVICE structure by + * calling MARVELL_PHY_INIT. Pointer to that needs to be provided as an argument to + * MARVELL_PHY_STATUS. + */ +typedef +EFI_STATUS +(EFIAPI *MARVELL_PHY_STATUS) ( + IN CONST MARVELL_PHY_PROTOCOL *This, + IN OUT PHY_DEVICE *PhyDev + ); + +/* + * MARVELL_PHY_INIT allocates PhyDev and provides driver with pointer via **PhyDev. + * After it becomes unnecessary, PhyDev should be freed by a driver (or it will + * get freed at ExitBootServices). + */ +typedef +EFI_STATUS +(EFIAPI *MARVELL_PHY_INIT) ( + IN CONST MARVELL_PHY_PROTOCOL *This, + IN UINT32 PhyAddr, + IN PHY_CONNECTION PhyConnection, + IN OUT PHY_DEVICE **PhyDev + ); + +struct _MARVELL_PHY_PROTOCOL { + MARVELL_PHY_STATUS Status; + MARVELL_PHY_INIT Init; +}; + +extern EFI_GUID gMarvellPhyProtocolGuid; +#endif diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index 9744c37..9c53b8c 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -184,6 +184,7 @@ [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} + gMarvellPhyProtocolGuid = { 0x0d728a1e, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }}
From: Bartosz Szczepanek bsz@semihalf.com
MvPhyDxe implements support for Marvell 1512 PHYs. MARVELL_PHY_PROTOCOL is produced in order to provide Status and Initialize functions to network controller drivers. This driver requires MARVELL_MDIO_PROTOCOL to communicate with PHY device.
Several PCDs were added to enable PHY ids and connection types configuration. These are described in attached documentation.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Documentation/Marvell/PortingGuide/Phy.txt | 45 +++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c | 432 +++++++++++++++++++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h | 194 +++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf | 71 +++++ Platforms/Marvell/Marvell.dec | 5 + 5 files changed, 747 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Phy.txt create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf
diff --git a/Documentation/Marvell/PortingGuide/Phy.txt b/Documentation/Marvell/PortingGuide/Phy.txt new file mode 100644 index 0000000..69dae02 --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Phy.txt @@ -0,0 +1,45 @@ +PHY driver configuration +------------------------ +MvPhyDxe provides basic initialization and status routines for Marvell PHYs. +Currently only 1512 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) + +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: + + typedef enum { +0 MV_PHY_DEVICE_1512, + } 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: + + gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE + +assuming, that PHY models are 1512: + + gMarvellTokenSpaceGuid.PcdPhyDeviceIds|{ 0x0, 0x0 } diff --git a/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c new file mode 100644 index 0000000..fb96d8b --- /dev/null +++ b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c @@ -0,0 +1,432 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include <Protocol/DriverBinding.h> +#include <Protocol/Mdio.h> +#include <Protocol/MvPhy.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include "MvPhyDxe.h" + +#define TIMEOUT 500 + +STATIC MARVELL_MDIO_PROTOCOL *Mdio; + +STATIC MV_PHY_DEVICE MvPhyDevices[] = { + { MV_PHY_DEVICE_1512, MvPhyInit1512 }, + { 0, NULL } +}; + +EFI_STATUS +MvPhyStatus ( + IN CONST MARVELL_PHY_PROTOCOL *This, + IN PHY_DEVICE *PhyDev + ); + +EFI_STATUS +MvPhyReset ( + IN UINT32 PhyAddr + ) +{ + UINT32 Reg = 0; + INTN timeout = TIMEOUT; + + Mdio->Read(Mdio, PhyAddr, MII_BMCR, &Reg); + Reg |= BMCR_RESET; + Mdio->Write(Mdio, PhyAddr, MII_BMCR, Reg); + + while ((Reg & BMCR_RESET) && timeout--) { + Mdio->Read(Mdio, PhyAddr, MII_BMCR, &Reg); + gBS->Stall(1000); + } + + if (Reg & BMCR_RESET) { + DEBUG((DEBUG_ERROR, "PHY reset timed out\n")); + return EFI_TIMEOUT; + } + + return EFI_SUCCESS; +} + +/* Marvell 88E1111S */ +EFI_STATUS +MvPhyM88e1111sConfig ( + IN PHY_DEVICE *PhyDev + ) +{ + UINT32 Reg; + + if ((PhyDev->Connection == PHY_CONNECTION_RGMII) || + (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); + + if ((PhyDev->Connection == PHY_CONNECTION_RGMII) || + (PhyDev->Connection == PHY_CONNECTION_RGMII_ID)) { + Reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); + } else if (PhyDev->Connection == PHY_CONNECTION_RGMII_RXID) { + Reg &= ~MIIM_88E1111_TX_DELAY; + Reg |= MIIM_88E1111_RX_DELAY; + } else if (PhyDev->Connection == PHY_CONNECTION_RGMII_TXID) { + Reg &= ~MIIM_88E1111_RX_DELAY; + Reg |= MIIM_88E1111_TX_DELAY; + } + + Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_CR, Reg); + + Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, &Reg); + + Reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK); + + if (Reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES) + Reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII; + else + Reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII; + + Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, Reg); + } + + if (PhyDev->Connection == PHY_CONNECTION_SGMII) { + Mdio->Read(Mdio, PhyDev->Addr, 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); + } + + if (PhyDev->Connection == PHY_CONNECTION_RTBI) { + Mdio->Read(Mdio, PhyDev->Addr, 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->Read(Mdio, PhyDev->Addr, 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); + + /* soft reset */ + MvPhyReset(PhyDev->Addr); + + Mdio->Read(Mdio, PhyDev->Addr, 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->Read(Mdio, PhyDev->Addr, MII_BMCR, &Reg); + Reg |= (BMCR_ANENABLE | BMCR_ANRESTART); + Reg &= ~BMCR_ISOLATE; + Mdio->Write(Mdio, PhyDev->Addr, MII_BMCR, Reg); + + /* soft reset */ + MvPhyReset(PhyDev->Addr); + + MvPhyReset(PhyDev->Addr); + + return EFI_SUCCESS; +} + +EFI_STATUS +MvPhyParseStatus ( + IN PHY_DEVICE *PhyDev + ) +{ + UINT32 Data; + UINT32 Speed; + + Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS, &Data); + + if ((Data & MIIM_88E1xxx_PHYSTAT_LINK) && + !(Data & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { + INTN i = 0; + + DEBUG((DEBUG_ERROR,"MvPhyDxe: Waiting for PHY realtime link")); + while (!(Data & MIIM_88E1xxx_PHYSTAT_SPDDONE)) { + if (i > PHY_AUTONEGOTIATE_TIMEOUT) { + DEBUG((DEBUG_ERROR," TIMEOUT !\n")); + PhyDev->LinkUp = FALSE; + break; + } + + if ((i++ % 1000) == 0) + DEBUG((DEBUG_ERROR, ".")); + gBS->Stall(1000); + Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS, &Data); + } + DEBUG((DEBUG_ERROR," done\n")); + gBS->Stall(500000); + } else { + if (Data & MIIM_88E1xxx_PHYSTAT_LINK) { + DEBUG((DEBUG_ERROR, "MvPhyDxe: link up, ")); + PhyDev->LinkUp = TRUE; + } else { + DEBUG((DEBUG_ERROR, "MvPhyDxe: link down, ")); + PhyDev->LinkUp = FALSE; + } + } + + if (Data & MIIM_88E1xxx_PHYSTAT_DUPLEX) { + DEBUG((DEBUG_ERROR, "full duplex, ")); + PhyDev->FullDuplex = TRUE; + } else { + DEBUG((DEBUG_ERROR, "half duplex, ")); + PhyDev->FullDuplex = FALSE; + } + + Speed = Data & MIIM_88E1xxx_PHYSTAT_SPEED; + + switch (Speed) { + case MIIM_88E1xxx_PHYSTAT_GBIT: + DEBUG((DEBUG_ERROR, "speed 1000\n")); + PhyDev->Speed = SPEED_1000; + break; + case MIIM_88E1xxx_PHYSTAT_100: + DEBUG((DEBUG_ERROR, "speed 100\n")); + PhyDev->Speed = SPEED_100; + break; + default: + DEBUG((DEBUG_ERROR, "speed 10\n")); + PhyDev->Speed = SPEED_10; + break; + } + + return EFI_SUCCESS; +} + +STATIC +VOID +MvPhy1512WriteBits ( + IN UINT32 PhyAddr, + IN UINT8 RegNum, + IN UINT16 Offset, + IN UINT16 Len, + IN UINT16 Data) +{ + UINT32 Reg, Mask; + + if ((Len + Offset) >= 16) + Mask = 0 - (1 << Offset); + else + Mask = (1 << (Len + Offset)) - (1 << Offset); + + Mdio->Read(Mdio, PhyAddr, RegNum, &Reg); + + Reg &= ~Mask; + Reg |= Data << Offset; + + Mdio->Write(Mdio, PhyAddr, RegNum, Reg); +} + +STATIC +EFI_STATUS +MvPhyInit1512 ( + IN CONST MARVELL_PHY_PROTOCOL *Snp, + IN UINT32 PhyAddr, + IN OUT PHY_DEVICE *PhyDev + ) +{ + UINT32 Data; + INTN i; + + + /* Phy configuration */ + if (PhyDev->Connection == PHY_CONNECTION_SGMII) { + 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, PhyAddr, 22, 0x0000); + Mdio->Write(Mdio, PhyAddr, 22, 0x0012); + + /* Write HWCFG_MODE = SGMII to Copper */ + MvPhy1512WriteBits(PhyAddr, 20, 0, 3, 1); + + /* Phy reset */ + MvPhy1512WriteBits(PhyAddr, 20, 15, 1, 1); + Mdio->Write(Mdio, PhyAddr, 22, 0); + gBS->Stall(100); + } + + MvPhyM88e1111sConfig (PhyDev); + + /* autonegotiation on startup is not always required */ + if (!PcdGetBool (PcdPhyStartupAutoneg)) + return EFI_SUCCESS; + + Mdio->Read(Mdio, PhyAddr, MII_BMSR, &Data); + + if ((Data & BMSR_ANEGCAPABLE) && !(Data & BMSR_ANEGCOMPLETE)) { + + DEBUG((DEBUG_ERROR, "MvPhyDxe: Waiting for PHY auto negotiation... ")); + for (i = 0; !(Data & BMSR_ANEGCOMPLETE); i++) { + if (i > PHY_ANEG_TIMEOUT) { + DEBUG((DEBUG_ERROR, "timeout\n")); + PhyDev->LinkUp = FALSE; + return EFI_TIMEOUT; + } + + gBS->Stall(1000); /* 1 ms */ + Mdio->Read(Mdio, PhyAddr, MII_BMSR, &Data); + } + PhyDev->LinkUp = TRUE; + DEBUG((DEBUG_INFO, "MvPhyDxe: link up\n")); + } else { + Mdio->Read(Mdio, PhyAddr, MII_BMSR, &Data); + + if (Data & BMSR_LSTATUS) { + PhyDev->LinkUp = TRUE; + DEBUG((DEBUG_INFO, "MvPhyDxe: link up\n")); + } else { + PhyDev->LinkUp = FALSE; + DEBUG((DEBUG_INFO, "MvPhyDxe: link down\n")); + } + } + MvPhyParseStatus (PhyDev); + + return EFI_SUCCESS; +} + +EFI_STATUS +MvPhyInit ( + IN CONST MARVELL_PHY_PROTOCOL *Snp, + IN UINT32 PhyAddr, + IN PHY_CONNECTION PhyConnection, + IN OUT PHY_DEVICE **OutPhyDev + ) +{ + EFI_STATUS Status; + PHY_DEVICE *PhyDev; + UINT8 *DeviceIds; + INTN i; + + Status = gBS->LocateProtocol ( + &gMarvellMdioProtocolGuid, + NULL, + (VOID **) &Mdio + ); + if (EFI_ERROR(Status)) + return Status; + + /* perform setup common for all PHYs */ + PhyDev = AllocateZeroPool (sizeof (PHY_DEVICE)); + PhyDev->Addr = PhyAddr; + PhyDev->Connection = PhyConnection; + DEBUG((DEBUG_INFO, "MvPhyDxe: PhyAddr is %d, connection %d\n", + PhyAddr, PhyConnection)); + *OutPhyDev = PhyDev; + + DeviceIds = PcdGetPtr (PcdPhyDeviceIds); + for (i = 0; i < PcdGetSize (PcdPhyDeviceIds); i++) { + /* find MvPhyDevices fitting entry */ + if (MvPhyDevices[i].DevId == DeviceIds[i]) { + ASSERT (MvPhyDevices[i].DevInit != NULL); + /* proceed with PHY-specific initialization */ + return MvPhyDevices[i].DevInit(Snp, PhyAddr, PhyDev); + } + } + + /* if we are here, no matching DevId was found */ + Status = EFI_INVALID_PARAMETER; + FreePool (PhyDev); + return Status; +} + +EFI_STATUS +MvPhyStatus ( + IN CONST MARVELL_PHY_PROTOCOL *This, + IN PHY_DEVICE *PhyDev + ) +{ + UINT32 Data; + + Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR, &Data); + Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR, &Data); + + if ((Data & BMSR_LSTATUS) == 0) { + PhyDev->LinkUp = FALSE; + } else { + PhyDev->LinkUp = TRUE; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +MvPhyDxeInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + MARVELL_PHY_PROTOCOL *Phy; + EFI_STATUS Status; + EFI_HANDLE Handle = NULL; + + Phy = AllocateZeroPool (sizeof (MARVELL_PHY_PROTOCOL)); + Phy->Status = MvPhyStatus; + Phy->Init = MvPhyInit; + + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gMarvellPhyProtocolGuid, Phy, + NULL + ); + + if (EFI_ERROR(Status)) { + DEBUG((DEBUG_ERROR, "Failed to install interfaces\n")); + return Status; + } + DEBUG((DEBUG_ERROR, "Succesfully installed protocol interfaces\n")); + + return EFI_SUCCESS; +} diff --git a/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h new file mode 100644 index 0000000..6bd06c5 --- /dev/null +++ b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h @@ -0,0 +1,194 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd. + +Marvell BSD License Option + +If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Marvell nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ +#ifndef __MV_PHY_DXE_H__ +#define __MV_PHY_DXE_H__ + +#define MII_BMCR 0x00 /* Basic mode control Register */ +#define MII_BMSR 0x01 /* Basic mode status Register */ +#define MII_PHYSID1 0x02 /* PHYS ID 1 */ +#define MII_PHYSID2 0x03 /* PHYS ID 2 */ +#define MII_ADVERTISE 0x04 /* Advertisement control Reg */ +#define MII_LPA 0x05 /* Link partner ability Reg */ +#define MII_EXPANSION 0x06 /* Expansion Register */ +#define MII_CTRL1000 0x09 /* 1000BASE-T control */ +#define MII_STAT1000 0x0a /* 1000BASE-T status */ +#define MII_ESTATUS 0x0f /* Extended Status */ +#define MII_DCOUNTER 0x12 /* Disconnect counter */ +#define MII_FCSCOUNTER 0x13 /* False carrier counter */ +#define MII_NWAYTEST 0x14 /* N-way auto-neg test Reg */ +#define MII_RERRCOUNTER 0x15 /* Receive error counter */ +#define MII_SREVISION 0x16 /* Silicon revision */ +#define MII_RESV1 0x17 /* Reserved... */ +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */ +#define MII_PHYADDR 0x19 /* PHY address */ +#define MII_RESV2 0x1a /* Reserved... */ +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */ +#define MII_NCONFIG 0x1c /* Network interface config */ + +/* Basic mode control Register. */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ +#define BMCR_CTST 0x0080 /* Collision test */ +#define BMCR_FULLDPLX 0x0100 /* Full duplex */ +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */ +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */ +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */ +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */ +#define BMCR_RESET 0x8000 /* Reset the DP83840 */ + +/* Basic mode status Register. */ +#define BMSR_ERCAP 0x0001 /* Ext-Reg capability */ +#define BMSR_JCD 0x0002 /* Jabber detected */ +#define BMSR_LSTATUS 0x0004 /* Link status */ +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ +#define BMSR_RFAULT 0x0010 /* Remote fault detected */ +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ +#define BMSR_RESV 0x00c0 /* Unused... */ +#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ +#define BMSR_100HALF2 0x0200 /* Can do 100BASE-T2 HDX */ +#define BMSR_100FULL2 0x0400 /* Can do 100BASE-T2 FDX */ +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */ + +#define PHY_ANEG_TIMEOUT 4000 + +#define PHY_INTERFACE_MODE_RGMII 0 +#define PHY_INTERFACE_MODE_RGMII_ID 1 +#define PHY_INTERFACE_MODE_RGMII_RXID 2 +#define PHY_INTERFACE_MODE_RGMII_TXID 3 +#define PHY_INTERFACE_MODE_SGMII 4 +#define PHY_INTERFACE_MODE_RTBI 5 + +#define PHY_AUTONEGOTIATE_TIMEOUT 5000 + +/* 88E1011 PHY Status Register */ +#define MIIM_88E1xxx_PHY_STATUS 0x11 +#define MIIM_88E1xxx_PHYSTAT_SPEED 0xc000 +#define MIIM_88E1xxx_PHYSTAT_GBIT 0x8000 +#define MIIM_88E1xxx_PHYSTAT_100 0x4000 +#define MIIM_88E1xxx_PHYSTAT_DUPLEX 0x2000 +#define MIIM_88E1xxx_PHYSTAT_SPDDONE 0x0800 +#define MIIM_88E1xxx_PHYSTAT_LINK 0x0400 + +#define MIIM_88E1xxx_PHY_SCR 0x10 +#define MIIM_88E1xxx_PHY_MDI_X_AUTO 0x0060 + +/* 88E1111 PHY LED Control Register */ +#define MIIM_88E1111_PHY_LED_CONTROL 24 +#define MIIM_88E1111_PHY_LED_DIRECT 0x4100 +#define MIIM_88E1111_PHY_LED_COMBINE 0x411C + +/* 88E1111 Extended PHY Specific Control Register */ +#define MIIM_88E1111_PHY_EXT_CR 0x14 +#define MIIM_88E1111_RX_DELAY 0x80 +#define MIIM_88E1111_TX_DELAY 0x2 + +/* 88E1111 Extended PHY Specific Status Register */ +#define MIIM_88E1111_PHY_EXT_SR 0x1b +#define MIIM_88E1111_HWCFG_MODE_MASK 0xf +#define MIIM_88E1111_HWCFG_MODE_COPPER_RGMII 0xb +#define MIIM_88E1111_HWCFG_MODE_FIBER_RGMII 0x3 +#define MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK 0x4 +#define MIIM_88E1111_HWCFG_MODE_COPPER_RTBI 0x9 +#define MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO 0x8000 +#define MIIM_88E1111_HWCFG_FIBER_COPPER_RES 0x2000 + +#define MIIM_88E1111_COPPER 0 +#define MIIM_88E1111_FIBER 1 + +/* 88E1118 PHY defines */ +#define MIIM_88E1118_PHY_PAGE 22 +#define MIIM_88E1118_PHY_LED_PAGE 3 + +/* 88E1121 PHY LED Control Register */ +#define MIIM_88E1121_PHY_LED_CTRL 16 +#define MIIM_88E1121_PHY_LED_PAGE 3 +#define MIIM_88E1121_PHY_LED_DEF 0x0030 + +/* 88E1121 PHY IRQ Enable/Status Register */ +#define MIIM_88E1121_PHY_IRQ_EN 18 +#define MIIM_88E1121_PHY_IRQ_STATUS 19 + +#define MIIM_88E1121_PHY_PAGE 22 + +/* 88E1145 Extended PHY Specific Control Register */ +#define MIIM_88E1145_PHY_EXT_CR 20 +#define MIIM_M88E1145_RGMII_RX_DELAY 0x0080 +#define MIIM_M88E1145_RGMII_TX_DELAY 0x0002 + +#define MIIM_88E1145_PHY_LED_CONTROL 24 +#define MIIM_88E1145_PHY_LED_DIRECT 0x4100 + +#define MIIM_88E1145_PHY_PAGE 29 +#define MIIM_88E1145_PHY_CAL_OV 30 + +#define MIIM_88E1149_PHY_PAGE 29 + +/* 88E1310 PHY defines */ +#define MIIM_88E1310_PHY_LED_CTRL 16 +#define MIIM_88E1310_PHY_IRQ_EN 18 +#define MIIM_88E1310_PHY_RGMII_CTRL 21 +#define MIIM_88E1310_PHY_PAGE 22 + +typedef enum { + MV_PHY_DEVICE_1512 +} MV_PHY_DEVICE_ID; + +typedef +EFI_STATUS +(*MV_PHY_DEVICE_INIT) ( + IN CONST MARVELL_PHY_PROTOCOL *Snp, + IN UINT32 PhyAddr, + IN OUT PHY_DEVICE *PhyDev + ); + +typedef struct { + MV_PHY_DEVICE_ID DevId; + MV_PHY_DEVICE_INIT DevInit; +} MV_PHY_DEVICE; + +STATIC +EFI_STATUS +MvPhyInit1512 ( + IN CONST MARVELL_PHY_PROTOCOL *Snp, + IN UINT32 PhyAddr, + IN OUT PHY_DEVICE *PhyDev + ); + +#endif diff --git a/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf new file mode 100644 index 0000000..713eada --- /dev/null +++ b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf @@ -0,0 +1,71 @@ +# Copyright (C) 2016 Marvell International Ltd. +# +# Marvell BSD License Option +# +# If you received this File from Marvell, you may opt to use, redistribute and/or +# modify this File under the following licensing terms. +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Marvell nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MvPhyDxe + FILE_GUID = 5aac3843-d8d4-40ba-ae07-38967138509c + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MvPhyDxeInitialise + +[Sources.common] + MvPhyDxe.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IoLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + +[Protocols] + gMarvellMdioProtocolGuid + gMarvellPhyProtocolGuid + +[Pcd] + gMarvellTokenSpaceGuid.PcdPhyConnectionTypes + gMarvellTokenSpaceGuid.PcdPhyDeviceIds + gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg + +[Depex] + TRUE diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index 9c53b8c..73102ed 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -181,6 +181,11 @@ #MDIO gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0|UINT64|0x3000043
+#PHY + gMarvellTokenSpaceGuid.PcdPhyConnectionTypes|{ 0 }|VOID*|0x3000044 + gMarvellTokenSpaceGuid.PcdPhyDeviceIds|{ 0 }|VOID*|0x3000095 + gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE|BOOLEAN|0x3000070 + [Protocols] gMarvellEepromProtocolGuid = { 0xcd728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
On Thu, Aug 11, 2016 at 11:51:38AM +0200, Marcin Wojtas wrote:
From: Bartosz Szczepanek bsz@semihalf.com
MvPhyDxe implements support for Marvell 1512 PHYs. MARVELL_PHY_PROTOCOL is produced in order to provide Status and Initialize functions to network controller drivers. This driver requires MARVELL_MDIO_PROTOCOL to communicate with PHY device.
Several PCDs were added to enable PHY ids and connection types configuration. These are described in attached documentation.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Documentation/Marvell/PortingGuide/Phy.txt | 45 +++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c | 432 +++++++++++++++++++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h | 194 +++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf | 71 +++++ Platforms/Marvell/Marvell.dec | 5 + 5 files changed, 747 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Phy.txt create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h create mode 100644 Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf
diff --git a/Documentation/Marvell/PortingGuide/Phy.txt b/Documentation/Marvell/PortingGuide/Phy.txt new file mode 100644 index 0000000..69dae02 --- /dev/null +++ b/Documentation/Marvell/PortingGuide/Phy.txt @@ -0,0 +1,45 @@ +PHY driver configuration +------------------------ +MvPhyDxe provides basic initialization and status routines for Marvell PHYs. +Currently only 1512 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)
+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:
- typedef enum {
+0 MV_PHY_DEVICE_1512,
- } 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:
- gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE
+assuming, that PHY models are 1512:
- gMarvellTokenSpaceGuid.PcdPhyDeviceIds|{ 0x0, 0x0 }
diff --git a/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c new file mode 100644 index 0000000..fb96d8b --- /dev/null +++ b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c @@ -0,0 +1,432 @@ +/******************************************************************************** +Copyright (C) 2016 Marvell International Ltd.
+Marvell BSD License Option
+If you received this File from Marvell, you may opt to use, redistribute and/or +modify this File under the following licensing terms. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of Marvell nor the names of its contributors may be
- used to endorse or promote products derived from this software without
- specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+#include <Protocol/DriverBinding.h> +#include <Protocol/Mdio.h> +#include <Protocol/MvPhy.h>
+#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h>
+#include "MvPhyDxe.h"
+#define TIMEOUT 500
+STATIC MARVELL_MDIO_PROTOCOL *Mdio;
+STATIC MV_PHY_DEVICE MvPhyDevices[] = {
- { MV_PHY_DEVICE_1512, MvPhyInit1512 },
- { 0, NULL }
+};
+EFI_STATUS +MvPhyStatus (
- IN CONST MARVELL_PHY_PROTOCOL *This,
- IN PHY_DEVICE *PhyDev
- );
+EFI_STATUS +MvPhyReset (
- IN UINT32 PhyAddr
- )
+{
- UINT32 Reg = 0;
- INTN timeout = TIMEOUT;
- Mdio->Read(Mdio, PhyAddr, MII_BMCR, &Reg);
- Reg |= BMCR_RESET;
- Mdio->Write(Mdio, PhyAddr, MII_BMCR, Reg);
- while ((Reg & BMCR_RESET) && timeout--) {
- Mdio->Read(Mdio, PhyAddr, MII_BMCR, &Reg);
- gBS->Stall(1000);
- }
- if (Reg & BMCR_RESET) {
- DEBUG((DEBUG_ERROR, "PHY reset timed out\n"));
- return EFI_TIMEOUT;
- }
- return EFI_SUCCESS;
+}
+/* Marvell 88E1111S */ +EFI_STATUS +MvPhyM88e1111sConfig (
- IN PHY_DEVICE *PhyDev
- )
+{
- UINT32 Reg;
- if ((PhyDev->Connection == PHY_CONNECTION_RGMII) ||
(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);
- if ((PhyDev->Connection == PHY_CONNECTION_RGMII) ||
(PhyDev->Connection == PHY_CONNECTION_RGMII_ID)) {
Reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
- } else if (PhyDev->Connection == PHY_CONNECTION_RGMII_RXID) {
Reg &= ~MIIM_88E1111_TX_DELAY;
Reg |= MIIM_88E1111_RX_DELAY;
- } else if (PhyDev->Connection == PHY_CONNECTION_RGMII_TXID) {
Reg &= ~MIIM_88E1111_RX_DELAY;
Reg |= MIIM_88E1111_TX_DELAY;
- }
- Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_CR, Reg);
- Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, &Reg);
- Reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
- if (Reg & MIIM_88E1111_HWCFG_FIBER_COPPER_RES)
Reg |= MIIM_88E1111_HWCFG_MODE_FIBER_RGMII;
- else
Reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII;
- Mdio->Write(Mdio, PhyDev->Addr, MIIM_88E1111_PHY_EXT_SR, Reg);
- }
- if (PhyDev->Connection == PHY_CONNECTION_SGMII) {
- Mdio->Read(Mdio, PhyDev->Addr, 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);
- }
- if (PhyDev->Connection == PHY_CONNECTION_RTBI) {
- Mdio->Read(Mdio, PhyDev->Addr, 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->Read(Mdio, PhyDev->Addr, 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);
- /* soft reset */
- MvPhyReset(PhyDev->Addr);
- Mdio->Read(Mdio, PhyDev->Addr, 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->Read(Mdio, PhyDev->Addr, MII_BMCR, &Reg);
- Reg |= (BMCR_ANENABLE | BMCR_ANRESTART);
- Reg &= ~BMCR_ISOLATE;
- Mdio->Write(Mdio, PhyDev->Addr, MII_BMCR, Reg);
- /* soft reset */
- MvPhyReset(PhyDev->Addr);
- MvPhyReset(PhyDev->Addr);
- return EFI_SUCCESS;
+}
+EFI_STATUS +MvPhyParseStatus (
- IN PHY_DEVICE *PhyDev
- )
+{
- UINT32 Data;
- UINT32 Speed;
- Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS, &Data);
- if ((Data & MIIM_88E1xxx_PHYSTAT_LINK) &&
- !(Data & MIIM_88E1xxx_PHYSTAT_SPDDONE)) {
- INTN i = 0;
- DEBUG((DEBUG_ERROR,"MvPhyDxe: Waiting for PHY realtime link"));
- while (!(Data & MIIM_88E1xxx_PHYSTAT_SPDDONE)) {
if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
DEBUG((DEBUG_ERROR," TIMEOUT !\n"));
PhyDev->LinkUp = FALSE;
break;
}
if ((i++ % 1000) == 0)
DEBUG((DEBUG_ERROR, "."));
gBS->Stall(1000);
Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS, &Data);
- }
- DEBUG((DEBUG_ERROR," done\n"));
- gBS->Stall(500000);
- } else {
- if (Data & MIIM_88E1xxx_PHYSTAT_LINK) {
DEBUG((DEBUG_ERROR, "MvPhyDxe: link up, "));
PhyDev->LinkUp = TRUE;
- } else {
DEBUG((DEBUG_ERROR, "MvPhyDxe: link down, "));
PhyDev->LinkUp = FALSE;
- }
- }
- if (Data & MIIM_88E1xxx_PHYSTAT_DUPLEX) {
- DEBUG((DEBUG_ERROR, "full duplex, "));
- PhyDev->FullDuplex = TRUE;
- } else {
- DEBUG((DEBUG_ERROR, "half duplex, "));
- PhyDev->FullDuplex = FALSE;
- }
- Speed = Data & MIIM_88E1xxx_PHYSTAT_SPEED;
- switch (Speed) {
- case MIIM_88E1xxx_PHYSTAT_GBIT:
- DEBUG((DEBUG_ERROR, "speed 1000\n"));
- PhyDev->Speed = SPEED_1000;
- break;
- case MIIM_88E1xxx_PHYSTAT_100:
- DEBUG((DEBUG_ERROR, "speed 100\n"));
- PhyDev->Speed = SPEED_100;
- break;
- default:
- DEBUG((DEBUG_ERROR, "speed 10\n"));
- PhyDev->Speed = SPEED_10;
- break;
- }
- return EFI_SUCCESS;
+}
+STATIC +VOID +MvPhy1512WriteBits (
- IN UINT32 PhyAddr,
- IN UINT8 RegNum,
- IN UINT16 Offset,
- IN UINT16 Len,
- IN UINT16 Data)
+{
- UINT32 Reg, Mask;
- if ((Len + Offset) >= 16)
- Mask = 0 - (1 << Offset);
- else
- Mask = (1 << (Len + Offset)) - (1 << Offset);
- Mdio->Read(Mdio, PhyAddr, RegNum, &Reg);
- Reg &= ~Mask;
- Reg |= Data << Offset;
- Mdio->Write(Mdio, PhyAddr, RegNum, Reg);
+}
+STATIC +EFI_STATUS +MvPhyInit1512 (
- IN CONST MARVELL_PHY_PROTOCOL *Snp,
- IN UINT32 PhyAddr,
- IN OUT PHY_DEVICE *PhyDev
- )
+{
- UINT32 Data;
- INTN i;
Extra blank line inserted.
- /* Phy configuration */
I could really do with some more description than that. Since we only have numeric values of both the registers being written to and the values being written ... this either needs a high-level description of _what_ is being configured in the PHY, or it needs to have symbolic constants defined.
- if (PhyDev->Connection == PHY_CONNECTION_SGMII) {
- 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, PhyAddr, 22, 0x0000);
- Mdio->Write(Mdio, PhyAddr, 22, 0x0012);
- /* Write HWCFG_MODE = SGMII to Copper */
- MvPhy1512WriteBits(PhyAddr, 20, 0, 3, 1);
- /* Phy reset */
- MvPhy1512WriteBits(PhyAddr, 20, 15, 1, 1);
- Mdio->Write(Mdio, PhyAddr, 22, 0);
Make it 0x0000 to match the cases above please.
Best Regards,
Leif
From: Bartosz Szczepanek bsz@semihalf.com
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com Reviewed-by: Leif Lindholm leif.lindholm@linaro.org --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 5 +++++ Platforms/Marvell/Armada/Armada70x0.fdf | 1 + 3 files changed, 7 insertions(+)
diff --git a/Platforms/Marvell/Armada/Armada.dsc.inc b/Platforms/Marvell/Armada/Armada.dsc.inc index 0b00826..195ccc5 100644 --- a/Platforms/Marvell/Armada/Armada.dsc.inc +++ b/Platforms/Marvell/Armada/Armada.dsc.inc @@ -404,6 +404,7 @@ MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf OpenPlatformPkg/Drivers/Net/MvMdioDxe/MvMdioDxe.inf + OpenPlatformPkg/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf
MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf diff --git a/Platforms/Marvell/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index f513b48..3062591 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -110,3 +110,8 @@
#MDIO gMarvellTokenSpaceGuid.PcdMdioBaseAddress|0xF212A200 + + #PHY + gMarvellTokenSpaceGuid.PcdPhyConnectionTypes|{ 0x0, 0x0 } + gMarvellTokenSpaceGuid.PcdPhyDeviceIds|{ 0x0, 0x0 } + gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg|FALSE diff --git a/Platforms/Marvell/Armada/Armada70x0.fdf b/Platforms/Marvell/Armada/Armada70x0.fdf index fb5bb6a..c56d4e3 100644 --- a/Platforms/Marvell/Armada/Armada70x0.fdf +++ b/Platforms/Marvell/Armada/Armada70x0.fdf @@ -120,6 +120,7 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c INF MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf INF MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf INF OpenPlatformPkg/Drivers/Net/MvMdioDxe/MvMdioDxe.inf + INF OpenPlatformPkg/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf