Hi,
Since basic support of Armada 7040 has been integrated to the tree, here is another part of the platform. Below commits comprise three parts: * ComPhy library - SerDes configuration and multiplexing * MDIO library * PHY library Altogether they are needed for enabling network on Armada 7040 (driver not included in this patchset).
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.
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 | 82 +++ Documentation/Marvell/PortingGuide/Mdio.txt | 7 + Documentation/Marvell/PortingGuide/Phy.txt | 45 ++ Drivers/Net/MdioDxe/MdioDxe.c | 235 ++++++ Drivers/Net/MdioDxe/MdioDxe.h | 57 ++ Drivers/Net/MdioDxe/MdioDxe.inf | 68 ++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c | 439 +++++++++++ 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 | 21 + Platforms/Marvell/Armada/Armada70x0.fdf | 14 + .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 2 + .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 1 + Platforms/Marvell/Include/Library/ComPhyLib.h | 43 ++ Platforms/Marvell/Include/Protocol/Mdio.h | 65 ++ Platforms/Marvell/Include/Protocol/Phy.h | 103 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c | 290 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 812 +++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 277 +++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 457 ++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 111 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 ++++ Platforms/Marvell/Marvell.dec | 61 ++ 24 files changed, 3606 insertions(+), 1 deletion(-) 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/MdioDxe/MdioDxe.c create mode 100644 Drivers/Net/MdioDxe/MdioDxe.h create mode 100644 Drivers/Net/MdioDxe/MdioDxe.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/ComPhyLib.h create mode 100644 Platforms/Marvell/Include/Protocol/Mdio.h create mode 100644 Platforms/Marvell/Include/Protocol/Phy.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c 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 | 82 +++ Platforms/Marvell/Armada/Armada70x0.dsc | 1 + Platforms/Marvell/Include/Library/ComPhyLib.h | 43 ++ Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c | 290 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 812 ++++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 277 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 457 ++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 111 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 ++++ Platforms/Marvell/Marvell.dec | 51 ++ 10 files changed, 2256 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/ComPhy.txt create mode 100644 Platforms/Marvell/Include/Library/ComPhyLib.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c 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..152671c --- /dev/null +++ b/Documentation/Marvell/PortingGuide/ComPhy.txt @@ -0,0 +1,82 @@ +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. + + gMarvellTokenSpaceGuid.PcdIsZVersionChip + +Indicates if Z1 chip version is used. + +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 are +{ L"Ap806", 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. 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" } + + gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds + +Indicates PHY speeds in MHz. Currently supported are: + +{ 1250, 1500, 2500, 3000, 3125, 5000, 6000, 6250, 1031 } + + gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags + +Indicates lane polarity invert. + +Example +------- + #ComPhy + gMarvellTokenSpaceGuid.PcdComPhyChipCount|1 + gMarvellTokenSpaceGuid.PcdIsZVersionChip|FALSE + + 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/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 29ddf7a..866c165 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -55,6 +55,7 @@ [PcdsFixedAtBuild.common] #MPP gMarvellTokenSpaceGuid.PcdMppChipCount|2 + gMarvellTokenSpaceGuid.PcdIsZVersionChip|FALSE
# APN806-A0 MPP SET gMarvellTokenSpaceGuid.PcdChip0MppReverseFlag|FALSE diff --git a/Platforms/Marvell/Include/Library/ComPhyLib.h b/Platforms/Marvell/Include/Library/ComPhyLib.h new file mode 100644 index 0000000..d63a19d --- /dev/null +++ b/Platforms/Marvell/Include/Library/ComPhyLib.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 __COMPHYLIB_H__ +#define __COMPHYLIB_H__ + +EFI_STATUS +ComPhyInit ( + VOID + ); + +#endif diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c new file mode 100644 index 0000000..d0fad1e --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c @@ -0,0 +1,290 @@ +/******************************************************************************** +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 HPIPE_ADDR(base, lane) (base + 0x800 * lane) +#define COMPHY_RESET_REG 0x120 + +#define COMPHY_RESET_SW_OFFSET 14 +#define COMPHY_RESET_SW_MASK (1 << COMPHY_RESET_SW_OFFSET) +#define COMPHY_RESET_CORE_OFFSET 13 +#define COMPHY_RESET_CORE_MASK (1 << COMPHY_RESET_CORE_OFFSET) + +#define COMPHY_PCI_MAC_CTRL 0x200 + +#define COMPHY_PCI_EN_OFFSET 0 +#define COMPHY_PCI_EN_MASK (0x1 << COMPHY_PCI_EN_OFFSET) +#define COMPHY_PCI_AXI_CACHE_OFFSET 8 +#define COMPHY_PCI_AXI_CACHE_MASK (0xF << COMPHY_PCI_AXI_CACHE_OFFSET) +#define COMPHY_PCI_COHERENT 0x7 +#define COMPHY_PCI_X1_EN_OFFSET 14 +#define COMPHY_PCI_X1_EN_MASK (0x1 << COMPHY_PCI_X1_EN_OFFSET) + +STATIC +VOID +ComPhyPcieReleaseSoftReset ( + IN EFI_PHYSICAL_ADDRESS HpipeAddr + ) +{ + /* Set MAX PLL Calibration */ + RegSet (HpipeAddr + HPIPE_KVCO_CALIB_CTRL_REG, + 0x1 << HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET, + HPIPE_KVCO_CALIB_CTRL_MAX_PLL_MASK); + RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG, + 0x1 << HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET, + HPIPE_LANE_CONFIG0_MAX_PLL_MASK); + RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG, + 0x1 << HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET, + HPIPE_LANE_CONFIG0_GEN2_PLL_MASK); + + /* DFE reset sequence */ + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK); + MicroSecondDelay (10); + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK); + + /* SW reset for interrupt logic */ + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK); + MicroSecondDelay (10); + RegSet (HpipeAddr + HPIPE_PWR_CTR_REG, + 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK); +} + +STATIC +EFI_STATUS +ComPhyPciePowerUp ( + IN UINT32 Lane, + IN UINT32 PcieBy4, + IN EFI_PHYSICAL_ADDRESS HpipeAddr + ) +{ + UINT32 StartVal, BreakVal, MasterVal; + + /* Enable CLK 500 */ + RegSet (HpipeAddr + HPIPE_MISC_REG, 0x1 << HPIPE_MISC_CLK500_EN_OFFSET, + HPIPE_MISC_CLK500_EN_MASK); + /* Clear lane align off */ + if (PcieBy4) + RegSet (HpipeAddr + HPIPE_LANE_ALIGN_REG, + 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET, HPIPE_LANE_ALIGN_OFF_MASK); + /* Reference Frequency Select set 0 (for PCIe 0 = 100Mhz) */ + RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET, + HPIPE_PWR_PLL_REF_FREQ_MASK); + /* PHY Mode Select (set PCIe = 0x3) */ + RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET, + HPIPE_PWR_PLL_PHY_MODE_MASK); + /* Set PIPE RESET - SW reset for the PIPE */ + RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, + 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, + HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); + /* Set PCIe fixed mode to 8 bit @ 250 Mhz */ + RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, + 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET, + HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK); + /* Set 5Gbps for RX and TX */ + RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG, + 0x1 << HPIPE_ISOLATE_MODE_GEN_RX_OFFSET, HPIPE_ISOLATE_MODE_GEN_RX_MASK); + RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG, + 0x1 << HPIPE_ISOLATE_MODE_GEN_TX_OFFSET, HPIPE_ISOLATE_MODE_GEN_TX_MASK); + /* Set Max PHY generation setting - 5GBps */ + RegSet (HpipeAddr + HPIPE_INTERFACE_REG, + 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK); + /* + * Set Lane Break/Start/Master: + * master - Provide RefClock to MAC + * start - Start of providing RefClock + * break - Stop passing the RefClock + */ + if (PcieBy4) { + /* + * If By4 Lane 0 - is master and start PHY + * Lane 1-2 - pass refclock to next phy + * Lane 3 - stop passing refclock + */ + if (Lane == 0) { + StartVal = 0x1; + BreakVal = 0x0; + MasterVal = 0x1; + } else if (Lane == 3) { + StartVal = 0x0; + BreakVal = 0x1; + MasterVal = 0x0; + } else { + StartVal = 0x0; + BreakVal = 0x0; + MasterVal = 0x0; + } + } else { + StartVal = 0x1; + BreakVal = 0x1; + MasterVal = 0x1; + } + RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG, + StartVal << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET, + HPIPE_CLK_SRC_HI_LANE_STRT_MASK); + RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG, + BreakVal << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET, + HPIPE_CLK_SRC_HI_LANE_BREAK_MASK); + RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG, + MasterVal << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET, + HPIPE_CLK_SRC_HI_LANE_MASTER_MASK); + + /* For PCIe by4 need to reset after configure all 4 Lanes */ + if (PcieBy4) { + return EFI_SUCCESS; + } + + ComPhyPcieReleaseSoftReset(HpipeAddr); + /* Release PIPE RESET - release PHY from reset */ + RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG, + 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, + HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); + + MicroSecondDelay (20000); + + /* Return the status of the PLL */ + return (EFI_STATUS) (MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG) & + HPIPE_LANE_STATUS0_PCLK_EN_MASK); +} + +EFI_STATUS +ComPhyAp806Init ( + IN CHIP_COMPHY_CONFIG *PtrChipCfg + ) +{ + EFI_STATUS Status; + COMPHY_MAP *PtrComPhyMap, *SerdesMap; + EFI_PHYSICAL_ADDRESS ComPhyBaseAddr, HpipeBaseAddr; + UINT32 ComPhyMaxCount, Lane; + UINT32 PcieBy4 = 1; + + ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr; + ComPhyMaxCount = PtrChipCfg->LanesCount; + HpipeBaseAddr = PtrChipCfg->Hpipe3BaseAddr; + SerdesMap = PtrChipCfg->MapData; + + /* Set PHY to Normal mode */ + RegSet (ComPhyBaseAddr + COMPHY_RESET_REG, 1 << COMPHY_RESET_SW_OFFSET, + COMPHY_RESET_SW_MASK); + RegSet (ComPhyBaseAddr + COMPHY_RESET_REG, 1 << COMPHY_RESET_CORE_OFFSET, + COMPHY_RESET_CORE_MASK); + + /* 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, HPIPE_ADDR(HpipeBaseAddr, + Lane)); + MicroSecondDelay (20); + break; + default: + DEBUG((DEBUG_INFO, "ComPhy: Unknown SerDes Type, skip initialize " + "SerDes %d\n", Lane)); + break; + } + if (EFI_ERROR(Status)) + DEBUG((DEBUG_ERROR, "ComPhy: PLL is not locked - Failed to initialize " + "Lane %d\n", Lane)); + } + + /* SW reset for PCIe for all Lanes after power up */ + if (PcieBy4) { + for (Lane = 0; Lane < 4; Lane++) { + ComPhyPcieReleaseSoftReset (HPIPE_ADDR(HpipeBaseAddr, Lane)); + } + + /* + * Release PIPE RESET - release PHY from reset + * need to release the Lanes without delay between them + */ + DEBUG((DEBUG_INFO, "ComPhy: Release PIPE reset for PCIe-By4, write to " + "Reset Clock control register\n")); + for (Lane = 0; Lane < 4; Lane++) { + RegSetSilent(HPIPE_ADDR(HpipeBaseAddr, Lane) + HPIPE_RST_CLK_CTRL_REG, + 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET, + HPIPE_RST_CLK_CTRL_PIPE_RST_MASK); + } + + MicroSecondDelay (20000); + for (Lane = 0; Lane < 4; Lane++) { + Status = (EFI_STATUS) MmioRead32 (HPIPE_ADDR(HpipeBaseAddr, Lane) + + HPIPE_LANE_STATUS0_REG) & HPIPE_LANE_STATUS0_PCLK_EN_MASK; + if (EFI_ERROR(Status)) + DEBUG((DEBUG_ERROR, "ComPhy: PLL is not locked - Failed to initialize " + "Lane %d\n", Lane)); + } + } + + /* + * Set PCIe transactions towards A2 as: + * - read allocate + * - write non alocate + * - outer sharable + */ + RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, COMPHY_PCI_COHERENT << + COMPHY_PCI_AXI_CACHE_OFFSET, COMPHY_PCI_AXI_CACHE_MASK); + + /* Set the Port x1 */ + if (PcieBy4) + RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, 0 << COMPHY_PCI_X1_EN_OFFSET, + COMPHY_PCI_X1_EN_MASK); + else + RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, 1 << COMPHY_PCI_X1_EN_OFFSET, + COMPHY_PCI_X1_EN_MASK); + + /* Enable PCIe unit */ + RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, 1 << COMPHY_PCI_EN_OFFSET, + COMPHY_PCI_EN_MASK); + + return EFI_SUCCESS; +} diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c new file mode 100755 index 0000000..e087d69 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c @@ -0,0 +1,812 @@ +/******************************************************************************** +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_ADDR(base, Lane) (base + 0x1000 * Lane) +#define HPIPE_ADDR(base, Lane) (SD_ADDR(base, Lane) + 0x800) +#define COMPHY_ADDR(base, Lane) (base + 0x28 * 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 +EFI_STATUS +ComPhyPciePowerUp ( + IN UINT32 Lane, + IN UINT32 PcieBy4, + IN EFI_PHYSICAL_ADDRESS HpipeBase, + IN EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Mask, Data, PcieClk = 0; + 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")); + /* 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); + + /* Start ComPhy Configuration */ + DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n")); + /* 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); + + 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); + + 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_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 +UINTN +ComphyUsb3PowerUp ( + UINT32 Lane, + EFI_PHYSICAL_ADDRESS HpipeBase, + EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Mask, 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")); + /* 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); + + /* Start ComPhy Configuration */ + DEBUG((DEBUG_INFO, "stage: Comphy configuration\n")); + /* 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); + + /* Start analog paramters from ETP(HW) */ + DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n")); + /* 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); + /* End of analog parameters */ + + 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); + + 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 +UINTN +ComPhySataPowerUp ( + IN UINT32 Lane, + IN EFI_PHYSICAL_ADDRESS HpipeBase, + IN EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status; + UINT32 Mask, Data; + 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, Addr; + + SataBase = PcdGet32 (PcdSataBaseAddress); + if (SataBase == 0) { + DEBUG((DEBUG_INFO, "ComPhy: SATA address not defined\n")); + return EFI_D_ERROR; + } + + DEBUG((DEBUG_INFO, "ComPhy: stage: MAC configuration - power down " + "ComPhy\n")); + /* + * 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); + + DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset " + "ComPhy\n")); + /* 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); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy configuration\n")); + /* Start ComPhy Configuration */ + /* 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); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n")); + + /* 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); + + DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n")); + /* + * 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); + + if (PcdGetBool(PcdIsZVersionChip)) { + /* + * Reduce read & write burst size to 64 byte due to bug in + * AP-806-Z Aurora 2 that prohibits writes larger than 64 byte + */ + MmioWrite32(SataBase + SATA3_VENDOR_ADDRESS, 0x4); + Mask = 0x77; + Data = 0x44; /* 4 = 64 bytes burst */ + 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); + + DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n")); + 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 +ComPhySgmiiPowerUp ( + IN UINT32 Lane, + IN UINT32 SgmiiSpeed, + IN EFI_PHYSICAL_ADDRESS HpipeBase, + IN EFI_PHYSICAL_ADDRESS ComPhyBase + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT32 Mask, Data; + 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 Addr; + + DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset " + "ComPhy\n")); + /* 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; + 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); + + /* Start ComPhy Configuration */ + DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n")); + /* 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); + + /* 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")); + /* 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 +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; + + 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..12b7d73 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c @@ -0,0 +1,277 @@ +/******************************************************************************** +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"Ap806", + .Init = ComPhyAp806Init + }, + { + .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, 1031}; + + 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; +} + +EFI_STATUS +ComPhyInit ( + 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); + + GetComPhyPcd(0); + GetComPhyPcd(1); + GetComPhyPcd(2); + GetComPhyPcd(3); + + if (ChipCount <= 0) + 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..51a3e42 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h @@ -0,0 +1,457 @@ +/******************************************************************************** +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) _PCD_GET_MODE_PTR_PcdChip##id##Compatible +#define GET_LANE_TYPE(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyTypes +#define GET_LANE_SPEED(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhySpeeds +#define GET_LANE_INV(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyInvFlags +#define GET_COMPHY_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##ComPhyBaseAddress +#define GET_HPIPE3_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##Hpipe3BaseAddress +#define GET_MUX_BIT_COUNT(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMuxBitCount +#define GET_MAX_LANES(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMaxLanes + +#define FillLaneMap(id) { \ + ParsePcdString((CHAR16 *) GET_LANE_TYPE(id), ChipConfig[id].LanesCount, NULL, LaneData[id].TypeStr); \ + ParsePcdString((CHAR16 *) GET_LANE_SPEED(id), ChipConfig[id].LanesCount, LaneData[id].SpeedValue, NULL); \ + ParsePcdString((CHAR16 *) GET_LANE_INV(id), ChipConfig[id].LanesCount, LaneData[id].InvFlag, NULL); \ +} + +#define GetComPhyPcd(id) { \ + ChipConfig[id].ChipType = (CHAR16 *) GET_TYPE_STRING(id); \ + ChipConfig[id].ComPhyBaseAddr = GET_COMPHY_BASE_ADDR(id); \ + ChipConfig[id].Hpipe3BaseAddr = GET_HPIPE3_BASE_ADDR(id); \ + ChipConfig[id].MuxBitCount = GET_MUX_BIT_COUNT(id); \ + ChipConfig[id].LanesCount = GET_MAX_LANES(id); \ + FillLaneMap(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 +ComPhyAp806Init ( + IN CHIP_COMPHY_CONFIG * First + ); + +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..0fda235 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf @@ -0,0 +1,111 @@ +# 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 + ComPhyAp806.c + ComPhyMux.c + +[FixedPcd] + gMarvellTokenSpaceGuid.PcdComPhyChipCount + gMarvellTokenSpaceGuid.PcdIsZVersionChip + + #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..b508c36 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -128,6 +128,57 @@ gMarvellTokenSpaceGuid.PcdSpiFlashPageSize|0|UINT32|0x3000055 gMarvellTokenSpaceGuid.PcdSpiFlashId|0|UINT32|0x3000056
+#ComPhy + #Chip0 + gMarvellTokenSpaceGuid.PcdComPhyChipCount|0|UINT32|0x30000098 + gMarvellTokenSpaceGuid.PcdIsZVersionChip|FALSE|BOOLEAN|0x30000099 + + 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 Tue, Jul 12, 2016 at 09:44:36PM +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
Documentation/Marvell/PortingGuide/ComPhy.txt | 82 +++ Platforms/Marvell/Armada/Armada70x0.dsc | 1 + Platforms/Marvell/Include/Library/ComPhyLib.h | 43 ++
Two files added called ComPhyLib.h - should this exported one be called something like MvComPhyLib.h?
Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c | 290 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 812 ++++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 277 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 457 ++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 111 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 ++++ Platforms/Marvell/Marvell.dec | 51 ++ 10 files changed, 2256 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/ComPhy.txt create mode 100644 Platforms/Marvell/Include/Library/ComPhyLib.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c 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..152671c --- /dev/null +++ b/Documentation/Marvell/PortingGuide/ComPhy.txt @@ -0,0 +1,82 @@ +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.
- gMarvellTokenSpaceGuid.PcdIsZVersionChip
+Indicates if Z1 chip version is used.
Does Z1 refer to a pre-release part, something for a different market segment, or...? If it's pre-production, you may want to consider just calling it PcdIsPreProductionChip or something? Not a hard requirement, just a suggestion, but the doc could do with a clarification.
+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 are +{ L"Ap806", 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. 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" }
Are these well understood industry standard terms? If not, could the name of the document where these names come from be pointed out (even if the doc itself is available under NDA only)?
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds
+Indicates PHY speeds in MHz. Currently supported are:
+{ 1250, 1500, 2500, 3000, 3125, 5000, 6000, 6250, 1031 }
Is that last 1031 a typo? (not numerical order, and looks a bit arbitrary)
- gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags
+Indicates lane polarity invert.
+Example +-------
- #ComPhy
- gMarvellTokenSpaceGuid.PcdComPhyChipCount|1
- gMarvellTokenSpaceGuid.PcdIsZVersionChip|FALSE
- 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/Armada/Armada70x0.dsc b/Platforms/Marvell/Armada/Armada70x0.dsc index 29ddf7a..866c165 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -55,6 +55,7 @@ [PcdsFixedAtBuild.common] #MPP gMarvellTokenSpaceGuid.PcdMppChipCount|2
- gMarvellTokenSpaceGuid.PcdIsZVersionChip|FALSE
# APN806-A0 MPP SET gMarvellTokenSpaceGuid.PcdChip0MppReverseFlag|FALSE diff --git a/Platforms/Marvell/Include/Library/ComPhyLib.h b/Platforms/Marvell/Include/Library/ComPhyLib.h new file mode 100644 index 0000000..d63a19d --- /dev/null +++ b/Platforms/Marvell/Include/Library/ComPhyLib.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 __COMPHYLIB_H__ +#define __COMPHYLIB_H__
__MVCOMPHYLIB_H__ ?
+EFI_STATUS +ComPhyInit (
MvComPhyInit or MarvellComPhyInit?
- VOID
- );
+#endif diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c new file mode 100644 index 0000000..d0fad1e --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c @@ -0,0 +1,290 @@ +/******************************************************************************** +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 HPIPE_ADDR(base, lane) (base + 0x800 * lane)
Could we get a #define for that 0x800 as well?
+#define COMPHY_RESET_REG 0x120
+#define COMPHY_RESET_SW_OFFSET 14 +#define COMPHY_RESET_SW_MASK (1 << COMPHY_RESET_SW_OFFSET) +#define COMPHY_RESET_CORE_OFFSET 13 +#define COMPHY_RESET_CORE_MASK (1 << COMPHY_RESET_CORE_OFFSET)
+#define COMPHY_PCI_MAC_CTRL 0x200
+#define COMPHY_PCI_EN_OFFSET 0 +#define COMPHY_PCI_EN_MASK (0x1 << COMPHY_PCI_EN_OFFSET) +#define COMPHY_PCI_AXI_CACHE_OFFSET 8 +#define COMPHY_PCI_AXI_CACHE_MASK (0xF << COMPHY_PCI_AXI_CACHE_OFFSET) +#define COMPHY_PCI_COHERENT 0x7 +#define COMPHY_PCI_X1_EN_OFFSET 14 +#define COMPHY_PCI_X1_EN_MASK (0x1 << COMPHY_PCI_X1_EN_OFFSET)
Should any/all of the above defines be made explicitly UL/ULL in order to avoid signed type promotion issues?
+STATIC +VOID +ComPhyPcieReleaseSoftReset (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
- )
+{
- /* Set MAX PLL Calibration */
- RegSet (HpipeAddr + HPIPE_KVCO_CALIB_CTRL_REG,
- 0x1 << HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET,
- HPIPE_KVCO_CALIB_CTRL_MAX_PLL_MASK);
- RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG,
- 0x1 << HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET,
- HPIPE_LANE_CONFIG0_MAX_PLL_MASK);
- RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG,
- 0x1 << HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET,
- HPIPE_LANE_CONFIG0_GEN2_PLL_MASK);
- /* DFE reset sequence */
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
- MicroSecondDelay (10);
Global comment: can we have some comment on all explicit delays as to why that particular delay value was chosen? Even if it's "seems to work", that will help pinpoint potential problem areas when debugging in future. If it's "X cycles at Y HZ", that will give credibility to it not just being "seems to work".
Also, for each one - are we sure there is no memory barrier requirement? The MmioWrite32 call itself guarantees no automatic ordering semantics.
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
- /* SW reset for interrupt logic */
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK);
- MicroSecondDelay (10);
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET, HPIPE_PWR_CTR_SFT_RST_MASK);
+}
+STATIC +EFI_STATUS +ComPhyPciePowerUp (
- IN UINT32 Lane,
- IN UINT32 PcieBy4,
Lane looks straightforward enough, but what is the meaning of PcieBy4?
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
- )
+{
- UINT32 StartVal, BreakVal, MasterVal;
- /* Enable CLK 500 */
- RegSet (HpipeAddr + HPIPE_MISC_REG, 0x1 << HPIPE_MISC_CLK500_EN_OFFSET,
- HPIPE_MISC_CLK500_EN_MASK);
- /* Clear lane align off */
off or offset?
- if (PcieBy4)
- RegSet (HpipeAddr + HPIPE_LANE_ALIGN_REG,
0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET, HPIPE_LANE_ALIGN_OFF_MASK);
- /* Reference Frequency Select set 0 (for PCIe 0 = 100Mhz) */
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET,
- HPIPE_PWR_PLL_REF_FREQ_MASK);
- /* PHY Mode Select (set PCIe = 0x3) */
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET,
- HPIPE_PWR_PLL_PHY_MODE_MASK);
- /* Set PIPE RESET - SW reset for the PIPE */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- /* Set PCIe fixed mode to 8 bit @ 250 Mhz */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET,
- HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK);
- /* Set 5Gbps for RX and TX */
- RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG,
- 0x1 << HPIPE_ISOLATE_MODE_GEN_RX_OFFSET, HPIPE_ISOLATE_MODE_GEN_RX_MASK);
- RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG,
- 0x1 << HPIPE_ISOLATE_MODE_GEN_TX_OFFSET, HPIPE_ISOLATE_MODE_GEN_TX_MASK);
- /* Set Max PHY generation setting - 5GBps */
- RegSet (HpipeAddr + HPIPE_INTERFACE_REG,
- 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK);
- /*
- Set Lane Break/Start/Master:
- master - Provide RefClock to MAC
- start - Start of providing RefClock
- break - Stop passing the RefClock
- */
- if (PcieBy4) {
- /*
* If By4 Lane 0 - is master and start PHY
* Lane 1-2 - pass refclock to next phy
* Lane 3 - stop passing refclock
*/
- if (Lane == 0) {
StartVal = 0x1;
BreakVal = 0x0;
MasterVal = 0x1;
- } else if (Lane == 3) {
StartVal = 0x0;
BreakVal = 0x1;
MasterVal = 0x0;
- } else {
StartVal = 0x0;
BreakVal = 0x0;
MasterVal = 0x0;
- }
- } else {
- StartVal = 0x1;
- BreakVal = 0x1;
- MasterVal = 0x1;
- }
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- StartVal << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_STRT_MASK);
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- BreakVal << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_BREAK_MASK);
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- MasterVal << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_MASTER_MASK);
- /* For PCIe by4 need to reset after configure all 4 Lanes */
- if (PcieBy4) {
- return EFI_SUCCESS;
- }
- ComPhyPcieReleaseSoftReset(HpipeAddr);
- /* Release PIPE RESET - release PHY from reset */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- MicroSecondDelay (20000);
- /* Return the status of the PLL */
- return (EFI_STATUS) (MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG) &
- HPIPE_LANE_STATUS0_PCLK_EN_MASK);
+}
The above function is very dense, and quite long. (I certainly can't follow what is actually going on.) Would it be possible to either break out parts into STATIC helper functions or: - Break it up a bit with empty lines. - Add a few more detailed multi-line comment blocks. ?
+EFI_STATUS +ComPhyAp806Init (
- IN CHIP_COMPHY_CONFIG *PtrChipCfg
- )
+{
- EFI_STATUS Status;
- COMPHY_MAP *PtrComPhyMap, *SerdesMap;
- EFI_PHYSICAL_ADDRESS ComPhyBaseAddr, HpipeBaseAddr;
- UINT32 ComPhyMaxCount, Lane;
- UINT32 PcieBy4 = 1;
- ComPhyBaseAddr = PtrChipCfg->ComPhyBaseAddr;
- ComPhyMaxCount = PtrChipCfg->LanesCount;
- HpipeBaseAddr = PtrChipCfg->Hpipe3BaseAddr;
- SerdesMap = PtrChipCfg->MapData;
- /* Set PHY to Normal mode */
- RegSet (ComPhyBaseAddr + COMPHY_RESET_REG, 1 << COMPHY_RESET_SW_OFFSET,
- COMPHY_RESET_SW_MASK);
- RegSet (ComPhyBaseAddr + COMPHY_RESET_REG, 1 << COMPHY_RESET_CORE_OFFSET,
- COMPHY_RESET_CORE_MASK);
- /* 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, HPIPE_ADDR(HpipeBaseAddr,
Lane));
MicroSecondDelay (20);
break;
- default:
DEBUG((DEBUG_INFO, "ComPhy: Unknown SerDes Type, skip initialize "
"SerDes %d\n", Lane));
break;
- }
- if (EFI_ERROR(Status))
DEBUG((DEBUG_ERROR, "ComPhy: PLL is not locked - Failed to initialize "
"Lane %d\n", Lane));
- }
- /* SW reset for PCIe for all Lanes after power up */
- if (PcieBy4) {
- for (Lane = 0; Lane < 4; Lane++) {
ComPhyPcieReleaseSoftReset (HPIPE_ADDR(HpipeBaseAddr, Lane));
- }
- /*
* Release PIPE RESET - release PHY from reset
* need to release the Lanes without delay between them
*/
- DEBUG((DEBUG_INFO, "ComPhy: Release PIPE reset for PCIe-By4, write to "
"Reset Clock control register\n"));
- for (Lane = 0; Lane < 4; Lane++) {
RegSetSilent(HPIPE_ADDR(HpipeBaseAddr, Lane) + HPIPE_RST_CLK_CTRL_REG,
0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- }
- MicroSecondDelay (20000);
- for (Lane = 0; Lane < 4; Lane++) {
Status = (EFI_STATUS) MmioRead32 (HPIPE_ADDR(HpipeBaseAddr, Lane) +
HPIPE_LANE_STATUS0_REG) & HPIPE_LANE_STATUS0_PCLK_EN_MASK;
if (EFI_ERROR(Status))
DEBUG((DEBUG_ERROR, "ComPhy: PLL is not locked - Failed to initialize "
"Lane %d\n", Lane));
- }
- }
- /*
- Set PCIe transactions towards A2 as:
- read allocate
- write non alocate
- outer sharable
- */
- RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, COMPHY_PCI_COHERENT <<
- COMPHY_PCI_AXI_CACHE_OFFSET, COMPHY_PCI_AXI_CACHE_MASK);
- /* Set the Port x1 */
- if (PcieBy4)
- RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, 0 << COMPHY_PCI_X1_EN_OFFSET,
COMPHY_PCI_X1_EN_MASK);
- else
- RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, 1 << COMPHY_PCI_X1_EN_OFFSET,
COMPHY_PCI_X1_EN_MASK);
- /* Enable PCIe unit */
- RegSet (ComPhyBaseAddr + COMPHY_PCI_MAC_CTRL, 1 << COMPHY_PCI_EN_OFFSET,
- COMPHY_PCI_EN_MASK);
- return EFI_SUCCESS;
+} diff --git a/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c new file mode 100755 index 0000000..e087d69 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c @@ -0,0 +1,812 @@ +/******************************************************************************** +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_ADDR(base, Lane) (base + 0x1000 * Lane) +#define HPIPE_ADDR(base, Lane) (SD_ADDR(base, Lane) + 0x800) +#define COMPHY_ADDR(base, Lane) (base + 0x28 * Lane)
Some defines for the magic values?
+/*
- 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 +EFI_STATUS +ComPhyPciePowerUp (
- IN UINT32 Lane,
- IN UINT32 PcieBy4,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, Data, PcieClk = 0;
- 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"));
- /* 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 */
Exemplary! :) (But consider whether you need a barrier here.)
- MicroSecondDelay (1000);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- /* 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);
- 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);
- 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_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;
+}
Similar to earlier comment - could this be broken down into some smaller STATIC helper functions or have some multi-line comments inserted to explain the purpose of larger blocks of operations?
+STATIC +UINTN +ComphyUsb3PowerUp (
- UINT32 Lane,
- EFI_PHYSICAL_ADDRESS HpipeBase,
- EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, 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"));
- /* 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);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "stage: Comphy configuration\n"));
- /* 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);
- /* Start analog paramters from ETP(HW) */
- DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
- /* 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);
- /* End of analog parameters */
- 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);
- 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 +UINTN +ComPhySataPowerUp (
- IN UINT32 Lane,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status;
- UINT32 Mask, Data;
- 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, Addr;
- SataBase = PcdGet32 (PcdSataBaseAddress);
- if (SataBase == 0) {
- DEBUG((DEBUG_INFO, "ComPhy: SATA address not defined\n"));
- return EFI_D_ERROR;
- }
- DEBUG((DEBUG_INFO, "ComPhy: stage: MAC configuration - power down "
- "ComPhy\n"));
While I'm sure the comment is correct, could we have the function name printed or something so it's obvious it's the "power up" function that is printing "power down"?
- /*
- 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset "
- "ComPhy\n"));
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy configuration\n"));
- /* Start ComPhy Configuration */
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n"));
- /*
- 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);
- if (PcdGetBool(PcdIsZVersionChip)) {
- /*
* Reduce read & write burst size to 64 byte due to bug in
* AP-806-Z Aurora 2 that prohibits writes larger than 64 byte
*/
- MmioWrite32(SataBase + SATA3_VENDOR_ADDRESS, 0x4);
- Mask = 0x77;
- Data = 0x44; /* 4 = 64 bytes burst */
- 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
- 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;
+}
Also a very long function - although more readable than the others I pointed out.
+STATIC +UINTN +ComPhySgmiiPowerUp (
- IN UINT32 Lane,
- IN UINT32 SgmiiSpeed,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, Data;
- 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 Addr;
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset "
- "ComPhy\n"));
- /* 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;
- 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);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- /* 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);
- /* 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"));
- /* 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;
+}
Long function. STATIC helper functions?
+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;
- 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..12b7d73 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c @@ -0,0 +1,277 @@ +/******************************************************************************** +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"Ap806",
- .Init = ComPhyAp806Init
- },
- {
- .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, 1031};
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;
+}
+EFI_STATUS +ComPhyInit (
- 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);
- GetComPhyPcd(0);
- GetComPhyPcd(1);
- GetComPhyPcd(2);
- GetComPhyPcd(3);
This macro makes it unclear which structure is actually being operated on. Can it add another input parameter so it becomes (ChipConfig, 0) and so on?
- if (ChipCount <= 0)
- 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..51a3e42 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h @@ -0,0 +1,457 @@ +/******************************************************************************** +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) _PCD_GET_MODE_PTR_PcdChip##id##Compatible +#define GET_LANE_TYPE(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyTypes +#define GET_LANE_SPEED(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhySpeeds +#define GET_LANE_INV(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyInvFlags +#define GET_COMPHY_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##ComPhyBaseAddress +#define GET_HPIPE3_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##Hpipe3BaseAddress +#define GET_MUX_BIT_COUNT(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMuxBitCount +#define GET_MAX_LANES(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMaxLanes
Similarly to what happened in Platforms/Marvell/Library/MppLib/MppLib.c, could these be changed to use PcdGet* instead?
+#define FillLaneMap(id) { \
- ParsePcdString((CHAR16 *) GET_LANE_TYPE(id), ChipConfig[id].LanesCount, NULL, LaneData[id].TypeStr); \
- ParsePcdString((CHAR16 *) GET_LANE_SPEED(id), ChipConfig[id].LanesCount, LaneData[id].SpeedValue, NULL); \
- ParsePcdString((CHAR16 *) GET_LANE_INV(id), ChipConfig[id].LanesCount, LaneData[id].InvFlag, NULL); \
+}
This macro hides LaneData also - so can that be added as well, turning the below into a 3-input macro? If the above is _never_ called externally, the above macro can stay as is, but if so I would like it #undef'd below GetComPhyPcd.
+#define GetComPhyPcd(id) { \
- ChipConfig[id].ChipType = (CHAR16 *) GET_TYPE_STRING(id); \
- ChipConfig[id].ComPhyBaseAddr = GET_COMPHY_BASE_ADDR(id); \
- ChipConfig[id].Hpipe3BaseAddr = GET_HPIPE3_BASE_ADDR(id); \
- ChipConfig[id].MuxBitCount = GET_MUX_BIT_COUNT(id); \
- ChipConfig[id].LanesCount = GET_MAX_LANES(id); \
- FillLaneMap(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
Whitespace issue?
+#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 +ComPhyAp806Init (
- IN CHIP_COMPHY_CONFIG * First
- );
+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..0fda235 --- /dev/null +++ b/Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf @@ -0,0 +1,111 @@ +# 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
- ComPhyAp806.c
- ComPhyMux.c
+[FixedPcd]
- gMarvellTokenSpaceGuid.PcdComPhyChipCount
- gMarvellTokenSpaceGuid.PcdIsZVersionChip
- #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..b508c36 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -128,6 +128,57 @@ gMarvellTokenSpaceGuid.PcdSpiFlashPageSize|0|UINT32|0x3000055 gMarvellTokenSpaceGuid.PcdSpiFlashId|0|UINT32|0x3000056 +#ComPhy
- #Chip0
- gMarvellTokenSpaceGuid.PcdComPhyChipCount|0|UINT32|0x30000098
- gMarvellTokenSpaceGuid.PcdIsZVersionChip|FALSE|BOOLEAN|0x30000099
- 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
Hi Leif,
Thanks for your comments. Please find my responses to your remarks inline. Thanks for answering questions in advance.
Regarding CheckPatch issue - it will be fixed in v2.
Best Regards, Jan
+Indicates how many different chips are placed on board. So far, up to 4 chips +are supported.
- gMarvellTokenSpaceGuid.PcdIsZVersionChip
+Indicates if Z1 chip version is used.
Does Z1 refer to a pre-release part, something for a different market segment, or...? If it's pre-production, you may want to consider just calling it PcdIsPreProductionChip or something? Not a hard requirement, just a suggestion, but the doc could do with a clarification.
It is a left-over from support for old chip revision. It will be removed in v2.
+{ 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" }
Are these well understood industry standard terms? If not, could the name of the document where these names come from be pointed out (even if the doc itself is available under NDA only)?
Ok, we will point to proper document or add description in our documentation regarding ComPhy.
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds
+Indicates PHY speeds in MHz. Currently supported are:
+{ 1250, 1500, 2500, 3000, 3125, 5000, 6000, 6250, 1031 }
Is that last 1031 a typo? (not numerical order, and looks a bit arbitrary)
It stands for 10 312 500 Hz. Renaming it to 10310 will be ok?
+#ifndef __COMPHYLIB_H__ +#define __COMPHYLIB_H__
__MVCOMPHYLIB_H__ ?
+EFI_STATUS +ComPhyInit (
MvComPhyInit or MarvellComPhyInit?
It should be MvComPhyInit.
+#include "ComPhyLib.h"
+#define HPIPE_ADDR(base, lane) (base + 0x800 * lane)
Could we get a #define for that 0x800 as well?
Ok.
+#define COMPHY_RESET_REG 0x120
+#define COMPHY_RESET_SW_OFFSET 14 +#define COMPHY_RESET_SW_MASK (1 << COMPHY_RESET_SW_OFFSET) +#define COMPHY_RESET_CORE_OFFSET 13 +#define COMPHY_RESET_CORE_MASK (1 << COMPHY_RESET_CORE_OFFSET)
+#define COMPHY_PCI_MAC_CTRL 0x200
+#define COMPHY_PCI_EN_OFFSET 0 +#define COMPHY_PCI_EN_MASK (0x1 << COMPHY_PCI_EN_OFFSET) +#define COMPHY_PCI_AXI_CACHE_OFFSET 8 +#define COMPHY_PCI_AXI_CACHE_MASK (0xF << COMPHY_PCI_AXI_CACHE_OFFSET) +#define COMPHY_PCI_COHERENT 0x7 +#define COMPHY_PCI_X1_EN_OFFSET 14 +#define COMPHY_PCI_X1_EN_MASK (0x1 << COMPHY_PCI_X1_EN_OFFSET)
Should any/all of the above defines be made explicitly UL/ULL in order to avoid signed type promotion issues?
Proper prefixes will be added where necessary.
+STATIC +VOID +ComPhyPcieReleaseSoftReset (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
- )
+{
- /* Set MAX PLL Calibration */
- RegSet (HpipeAddr + HPIPE_KVCO_CALIB_CTRL_REG,
- 0x1 << HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET,
- HPIPE_KVCO_CALIB_CTRL_MAX_PLL_MASK);
- RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG,
- 0x1 << HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET,
- HPIPE_LANE_CONFIG0_MAX_PLL_MASK);
- RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG,
- 0x1 << HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET,
- HPIPE_LANE_CONFIG0_GEN2_PLL_MASK);
- /* DFE reset sequence */
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
- MicroSecondDelay (10);
Global comment: can we have some comment on all explicit delays as to why that particular delay value was chosen? Even if it's "seems to work", that will help pinpoint potential problem areas when debugging in future. If it's "X cycles at Y HZ", that will give credibility to it not just being "seems to work".
Ok.
Also, for each one - are we sure there is no memory barrier requirement? The MmioWrite32 call itself guarantees no automatic ordering semantics.
Thanks, we definitely should consider this. Could you point me to example code in edk2, where such barrier is used?
+STATIC +EFI_STATUS +ComPhyPciePowerUp (
- IN UINT32 Lane,
- IN UINT32 PcieBy4,
Lane looks straightforward enough, but what is the meaning of PcieBy4?
This is flag indicating if first 4 lanes are set to PCIe type. I think one-line comment will be nice here.
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
- )
+{
- UINT32 StartVal, BreakVal, MasterVal;
- /* Enable CLK 500 */
- RegSet (HpipeAddr + HPIPE_MISC_REG, 0x1 << HPIPE_MISC_CLK500_EN_OFFSET,
- HPIPE_MISC_CLK500_EN_MASK);
- /* Clear lane align off */
off or offset?
Off.
- if (PcieBy4)
- RegSet (HpipeAddr + HPIPE_LANE_ALIGN_REG,
0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET, HPIPE_LANE_ALIGN_OFF_MASK);
- /* Reference Frequency Select set 0 (for PCIe 0 = 100Mhz) */
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET,
- HPIPE_PWR_PLL_REF_FREQ_MASK);
- /* PHY Mode Select (set PCIe = 0x3) */
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET,
- HPIPE_PWR_PLL_PHY_MODE_MASK);
- /* Set PIPE RESET - SW reset for the PIPE */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- /* Set PCIe fixed mode to 8 bit @ 250 Mhz */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET,
- HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK);
- /* Set 5Gbps for RX and TX */
- RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG,
- 0x1 << HPIPE_ISOLATE_MODE_GEN_RX_OFFSET, HPIPE_ISOLATE_MODE_GEN_RX_MASK);
- RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG,
- 0x1 << HPIPE_ISOLATE_MODE_GEN_TX_OFFSET, HPIPE_ISOLATE_MODE_GEN_TX_MASK);
- /* Set Max PHY generation setting - 5GBps */
- RegSet (HpipeAddr + HPIPE_INTERFACE_REG,
- 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK);
- /*
- Set Lane Break/Start/Master:
- master - Provide RefClock to MAC
- start - Start of providing RefClock
- break - Stop passing the RefClock
- */
- if (PcieBy4) {
- /*
* If By4 Lane 0 - is master and start PHY
* Lane 1-2 - pass refclock to next phy
* Lane 3 - stop passing refclock
*/
- if (Lane == 0) {
StartVal = 0x1;
BreakVal = 0x0;
MasterVal = 0x1;
- } else if (Lane == 3) {
StartVal = 0x0;
BreakVal = 0x1;
MasterVal = 0x0;
- } else {
StartVal = 0x0;
BreakVal = 0x0;
MasterVal = 0x0;
- }
- } else {
- StartVal = 0x1;
- BreakVal = 0x1;
- MasterVal = 0x1;
- }
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- StartVal << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_STRT_MASK);
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- BreakVal << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_BREAK_MASK);
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- MasterVal << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_MASTER_MASK);
- /* For PCIe by4 need to reset after configure all 4 Lanes */
- if (PcieBy4) {
- return EFI_SUCCESS;
- }
- ComPhyPcieReleaseSoftReset(HpipeAddr);
- /* Release PIPE RESET - release PHY from reset */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- MicroSecondDelay (20000);
- /* Return the status of the PLL */
- return (EFI_STATUS) (MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG) &
- HPIPE_LANE_STATUS0_PCLK_EN_MASK);
+}
The above function is very dense, and quite long. (I certainly can't follow what is actually going on.) Would it be possible to either break out parts into STATIC helper functions or:
- Break it up a bit with empty lines.
- Add a few more detailed multi-line comment blocks.
?
Ok.
+#define SD_ADDR(base, Lane) (base + 0x1000 * Lane) +#define HPIPE_ADDR(base, Lane) (SD_ADDR(base, Lane) + 0x800) +#define COMPHY_ADDR(base, Lane) (base + 0x28 * Lane)
Some defines for the magic values?
Ok.
+/*
- 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 +EFI_STATUS +ComPhyPciePowerUp (
- IN UINT32 Lane,
- IN UINT32 PcieBy4,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, Data, PcieClk = 0;
- 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"));
- /* 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 */
Exemplary! :) (But consider whether you need a barrier here.)
- MicroSecondDelay (1000);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- /* 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);
- 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);
- 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_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;
+}
Similar to earlier comment - could this be broken down into some smaller STATIC helper functions or have some multi-line comments inserted to explain the purpose of larger blocks of operations?
Ok.
+STATIC +UINTN +ComPhySataPowerUp (
- IN UINT32 Lane,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status;
- UINT32 Mask, Data;
- 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, Addr;
- SataBase = PcdGet32 (PcdSataBaseAddress);
- if (SataBase == 0) {
- DEBUG((DEBUG_INFO, "ComPhy: SATA address not defined\n"));
- return EFI_D_ERROR;
- }
- DEBUG((DEBUG_INFO, "ComPhy: stage: MAC configuration - power down "
- "ComPhy\n"));
While I'm sure the comment is correct, could we have the function name printed or something so it's obvious it's the "power up" function that is printing "power down"?
Ok.
- /*
- 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset "
- "ComPhy\n"));
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy configuration\n"));
- /* Start ComPhy Configuration */
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n"));
- /*
- 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);
- if (PcdGetBool(PcdIsZVersionChip)) {
- /*
* Reduce read & write burst size to 64 byte due to bug in
* AP-806-Z Aurora 2 that prohibits writes larger than 64 byte
*/
- MmioWrite32(SataBase + SATA3_VENDOR_ADDRESS, 0x4);
- Mask = 0x77;
- Data = 0x44; /* 4 = 64 bytes burst */
- 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
- 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;
+}
Also a very long function - although more readable than the others I pointed out.
Ok.
+STATIC +UINTN +ComPhySgmiiPowerUp (
- IN UINT32 Lane,
- IN UINT32 SgmiiSpeed,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, Data;
- 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 Addr;
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset "
- "ComPhy\n"));
- /* 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;
- 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);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- /* 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);
- /* 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"));
- /* 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;
+}
Long function. STATIC helper functions?
Ok.
+UINT32 +ParseSerdesSpeed (
- UINT32 Value
- )
+{
- UINT32 i;
- UINT32 ValueTable [] = {0, 1250, 1500, 2500, 3000, 3125,
5000, 6000, 6250, 1031};
10310?
As above, I will change to 10310.
- ChipCount = PcdGet32 (PcdComPhyChipCount);
- GetComPhyPcd(0);
- GetComPhyPcd(1);
- GetComPhyPcd(2);
- GetComPhyPcd(3);
This macro makes it unclear which structure is actually being operated on. Can it add another input parameter so it becomes (ChipConfig, 0) and so on?
Ok, additional parameter will be added.
+/***** Parsing PCD *****/ +#define GET_TYPE_STRING(id) _PCD_GET_MODE_PTR_PcdChip##id##Compatible +#define GET_LANE_TYPE(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyTypes +#define GET_LANE_SPEED(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhySpeeds +#define GET_LANE_INV(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyInvFlags +#define GET_COMPHY_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##ComPhyBaseAddress +#define GET_HPIPE3_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##Hpipe3BaseAddress +#define GET_MUX_BIT_COUNT(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMuxBitCount +#define GET_MAX_LANES(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMaxLanes
Similarly to what happened in Platforms/Marvell/Library/MppLib/MppLib.c, could these be changed to use PcdGet* instead?
Ok.
+#define FillLaneMap(id) { \
- ParsePcdString((CHAR16 *) GET_LANE_TYPE(id), ChipConfig[id].LanesCount, NULL, LaneData[id].TypeStr); \
- ParsePcdString((CHAR16 *) GET_LANE_SPEED(id), ChipConfig[id].LanesCount, LaneData[id].SpeedValue, NULL); \
- ParsePcdString((CHAR16 *) GET_LANE_INV(id), ChipConfig[id].LanesCount, LaneData[id].InvFlag, NULL); \
+}
This macro hides LaneData also - so can that be added as well, turning the below into a 3-input macro? If the above is _never_ called externally, the above macro can stay as is, but if so I would like it #undef'd below GetComPhyPcd.
Ok.
On Fri, Jul 15, 2016 at 08:35:10AM +0200, Jan Dąbroś wrote:
Hi Leif,
Thanks for your comments. Please find my responses to your remarks inline. Thanks for answering questions in advance.
Regarding CheckPatch issue - it will be fixed in v2.
Best Regards, Jan
+Indicates how many different chips are placed on board. So far, up to 4 chips +are supported.
- gMarvellTokenSpaceGuid.PcdIsZVersionChip
+Indicates if Z1 chip version is used.
Does Z1 refer to a pre-release part, something for a different market segment, or...? If it's pre-production, you may want to consider just calling it PcdIsPreProductionChip or something? Not a hard requirement, just a suggestion, but the doc could do with a clarification.
It is a left-over from support for old chip revision. It will be removed in v2.
+{ 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" }
Are these well understood industry standard terms? If not, could the name of the document where these names come from be pointed out (even if the doc itself is available under NDA only)?
Ok, we will point to proper document or add description in our documentation regarding ComPhy.
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds
+Indicates PHY speeds in MHz. Currently supported are:
+{ 1250, 1500, 2500, 3000, 3125, 5000, 6000, 6250, 1031 }
Is that last 1031 a typo? (not numerical order, and looks a bit arbitrary)
It stands for 10 312 500 Hz. Renaming it to 10310 will be ok?
Well, whatever makes sense really. If it's a higher frequency than the preceding ones, it should be a higher number, and added in numerical order. 10310 sounds reasonable to me, but then I don't know what the others mean :)
+#ifndef __COMPHYLIB_H__ +#define __COMPHYLIB_H__
__MVCOMPHYLIB_H__ ?
+EFI_STATUS +ComPhyInit (
MvComPhyInit or MarvellComPhyInit?
It should be MvComPhyInit.
+#include "ComPhyLib.h"
+#define HPIPE_ADDR(base, lane) (base + 0x800 * lane)
Could we get a #define for that 0x800 as well?
Ok.
+#define COMPHY_RESET_REG 0x120
+#define COMPHY_RESET_SW_OFFSET 14 +#define COMPHY_RESET_SW_MASK (1 << COMPHY_RESET_SW_OFFSET) +#define COMPHY_RESET_CORE_OFFSET 13 +#define COMPHY_RESET_CORE_MASK (1 << COMPHY_RESET_CORE_OFFSET)
+#define COMPHY_PCI_MAC_CTRL 0x200
+#define COMPHY_PCI_EN_OFFSET 0 +#define COMPHY_PCI_EN_MASK (0x1 << COMPHY_PCI_EN_OFFSET) +#define COMPHY_PCI_AXI_CACHE_OFFSET 8 +#define COMPHY_PCI_AXI_CACHE_MASK (0xF << COMPHY_PCI_AXI_CACHE_OFFSET) +#define COMPHY_PCI_COHERENT 0x7 +#define COMPHY_PCI_X1_EN_OFFSET 14 +#define COMPHY_PCI_X1_EN_MASK (0x1 << COMPHY_PCI_X1_EN_OFFSET)
Should any/all of the above defines be made explicitly UL/ULL in order to avoid signed type promotion issues?
Proper prefixes will be added where necessary.
+STATIC +VOID +ComPhyPcieReleaseSoftReset (
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
- )
+{
- /* Set MAX PLL Calibration */
- RegSet (HpipeAddr + HPIPE_KVCO_CALIB_CTRL_REG,
- 0x1 << HPIPE_KVCO_CALIB_CTRL_MAX_PLL_OFFSET,
- HPIPE_KVCO_CALIB_CTRL_MAX_PLL_MASK);
- RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG,
- 0x1 << HPIPE_LANE_CONFIG0_MAX_PLL_OFFSET,
- HPIPE_LANE_CONFIG0_MAX_PLL_MASK);
- RegSet (HpipeAddr + HPIPE_LANE_CONFIG0_REG,
- 0x1 << HPIPE_LANE_CONFIG0_GEN2_PLL_OFFSET,
- HPIPE_LANE_CONFIG0_GEN2_PLL_MASK);
- /* DFE reset sequence */
- RegSet (HpipeAddr + HPIPE_PWR_CTR_REG,
- 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET, HPIPE_PWR_CTR_RST_DFE_MASK);
- MicroSecondDelay (10);
Global comment: can we have some comment on all explicit delays as to why that particular delay value was chosen? Even if it's "seems to work", that will help pinpoint potential problem areas when debugging in future. If it's "X cycles at Y HZ", that will give credibility to it not just being "seems to work".
Ok.
Also, for each one - are we sure there is no memory barrier requirement? The MmioWrite32 call itself guarantees no automatic ordering semantics.
Thanks, we definitely should consider this. Could you point me to example code in edk2, where such barrier is used?
Well ... for drivers, I would prefer the use of MemoryFence(). There are plenty of examples in edk2, and one in OpenPlatformPkg.
+STATIC +EFI_STATUS +ComPhyPciePowerUp (
- IN UINT32 Lane,
- IN UINT32 PcieBy4,
Lane looks straightforward enough, but what is the meaning of PcieBy4?
This is flag indicating if first 4 lanes are set to PCIe type. I think one-line comment will be nice here.
- IN EFI_PHYSICAL_ADDRESS HpipeAddr
- )
+{
- UINT32 StartVal, BreakVal, MasterVal;
- /* Enable CLK 500 */
- RegSet (HpipeAddr + HPIPE_MISC_REG, 0x1 << HPIPE_MISC_CLK500_EN_OFFSET,
- HPIPE_MISC_CLK500_EN_MASK);
- /* Clear lane align off */
off or offset?
Off.
Could it be reworded as "disable clear lane align" or somesuch?
Regards,
Leif
- if (PcieBy4)
- RegSet (HpipeAddr + HPIPE_LANE_ALIGN_REG,
0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET, HPIPE_LANE_ALIGN_OFF_MASK);
- /* Reference Frequency Select set 0 (for PCIe 0 = 100Mhz) */
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET,
- HPIPE_PWR_PLL_REF_FREQ_MASK);
- /* PHY Mode Select (set PCIe = 0x3) */
- RegSet (HpipeAddr + HPIPE_PWR_PLL_REG, 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET,
- HPIPE_PWR_PLL_PHY_MODE_MASK);
- /* Set PIPE RESET - SW reset for the PIPE */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- /* Set PCIe fixed mode to 8 bit @ 250 Mhz */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET,
- HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK);
- /* Set 5Gbps for RX and TX */
- RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG,
- 0x1 << HPIPE_ISOLATE_MODE_GEN_RX_OFFSET, HPIPE_ISOLATE_MODE_GEN_RX_MASK);
- RegSet (HpipeAddr + HPIPE_ISOLATE_MODE_REG,
- 0x1 << HPIPE_ISOLATE_MODE_GEN_TX_OFFSET, HPIPE_ISOLATE_MODE_GEN_TX_MASK);
- /* Set Max PHY generation setting - 5GBps */
- RegSet (HpipeAddr + HPIPE_INTERFACE_REG,
- 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET, HPIPE_INTERFACE_GEN_MAX_MASK);
- /*
- Set Lane Break/Start/Master:
- master - Provide RefClock to MAC
- start - Start of providing RefClock
- break - Stop passing the RefClock
- */
- if (PcieBy4) {
- /*
* If By4 Lane 0 - is master and start PHY
* Lane 1-2 - pass refclock to next phy
* Lane 3 - stop passing refclock
*/
- if (Lane == 0) {
StartVal = 0x1;
BreakVal = 0x0;
MasterVal = 0x1;
- } else if (Lane == 3) {
StartVal = 0x0;
BreakVal = 0x1;
MasterVal = 0x0;
- } else {
StartVal = 0x0;
BreakVal = 0x0;
MasterVal = 0x0;
- }
- } else {
- StartVal = 0x1;
- BreakVal = 0x1;
- MasterVal = 0x1;
- }
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- StartVal << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_STRT_MASK);
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- BreakVal << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_BREAK_MASK);
- RegSet (HpipeAddr + HPIPE_CLK_SRC_HI_REG,
- MasterVal << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET,
- HPIPE_CLK_SRC_HI_LANE_MASTER_MASK);
- /* For PCIe by4 need to reset after configure all 4 Lanes */
- if (PcieBy4) {
- return EFI_SUCCESS;
- }
- ComPhyPcieReleaseSoftReset(HpipeAddr);
- /* Release PIPE RESET - release PHY from reset */
- RegSet (HpipeAddr + HPIPE_RST_CLK_CTRL_REG,
- 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
- HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
- MicroSecondDelay (20000);
- /* Return the status of the PLL */
- return (EFI_STATUS) (MmioRead32 (HpipeAddr + HPIPE_LANE_STATUS0_REG) &
- HPIPE_LANE_STATUS0_PCLK_EN_MASK);
+}
The above function is very dense, and quite long. (I certainly can't follow what is actually going on.) Would it be possible to either break out parts into STATIC helper functions or:
- Break it up a bit with empty lines.
- Add a few more detailed multi-line comment blocks.
?
Ok.
+#define SD_ADDR(base, Lane) (base + 0x1000 * Lane) +#define HPIPE_ADDR(base, Lane) (SD_ADDR(base, Lane) + 0x800) +#define COMPHY_ADDR(base, Lane) (base + 0x28 * Lane)
Some defines for the magic values?
Ok.
+/*
- 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 +EFI_STATUS +ComPhyPciePowerUp (
- IN UINT32 Lane,
- IN UINT32 PcieBy4,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, Data, PcieClk = 0;
- 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"));
- /* 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 */
Exemplary! :) (But consider whether you need a barrier here.)
- MicroSecondDelay (1000);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- /* 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);
- 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);
- 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_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;
+}
Similar to earlier comment - could this be broken down into some smaller STATIC helper functions or have some multi-line comments inserted to explain the purpose of larger blocks of operations?
Ok.
+STATIC +UINTN +ComPhySataPowerUp (
- IN UINT32 Lane,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status;
- UINT32 Mask, Data;
- 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, Addr;
- SataBase = PcdGet32 (PcdSataBaseAddress);
- if (SataBase == 0) {
- DEBUG((DEBUG_INFO, "ComPhy: SATA address not defined\n"));
- return EFI_D_ERROR;
- }
- DEBUG((DEBUG_INFO, "ComPhy: stage: MAC configuration - power down "
- "ComPhy\n"));
While I'm sure the comment is correct, could we have the function name printed or something so it's obvious it's the "power up" function that is printing "power down"?
Ok.
- /*
- 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset "
- "ComPhy\n"));
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Comphy configuration\n"));
- /* Start ComPhy Configuration */
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Analog paramters from ETP(HW)\n"));
- /* 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy power up\n"));
- /*
- 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);
- if (PcdGetBool(PcdIsZVersionChip)) {
- /*
* Reduce read & write burst size to 64 byte due to bug in
* AP-806-Z Aurora 2 that prohibits writes larger than 64 byte
*/
- MmioWrite32(SataBase + SATA3_VENDOR_ADDRESS, 0x4);
- Mask = 0x77;
- Data = 0x44; /* 4 = 64 bytes burst */
- 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);
- DEBUG((DEBUG_INFO, "ComPhy: stage: Check PLL\n"));
- 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;
+}
Also a very long function - although more readable than the others I pointed out.
Ok.
+STATIC +UINTN +ComPhySgmiiPowerUp (
- IN UINT32 Lane,
- IN UINT32 SgmiiSpeed,
- IN EFI_PHYSICAL_ADDRESS HpipeBase,
- IN EFI_PHYSICAL_ADDRESS ComPhyBase
- )
+{
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 Mask, Data;
- 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 Addr;
- DEBUG((DEBUG_INFO, "ComPhy: stage: RFU configurations - hard reset "
- "ComPhy\n"));
- /* 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;
- 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);
- /* Start ComPhy Configuration */
- DEBUG((DEBUG_INFO, "ComPhy: stage: ComPhy configuration\n"));
- /* 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);
- /* 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"));
- /* 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;
+}
Long function. STATIC helper functions?
Ok.
+UINT32 +ParseSerdesSpeed (
- UINT32 Value
- )
+{
- UINT32 i;
- UINT32 ValueTable [] = {0, 1250, 1500, 2500, 3000, 3125,
5000, 6000, 6250, 1031};
10310?
As above, I will change to 10310.
- ChipCount = PcdGet32 (PcdComPhyChipCount);
- GetComPhyPcd(0);
- GetComPhyPcd(1);
- GetComPhyPcd(2);
- GetComPhyPcd(3);
This macro makes it unclear which structure is actually being operated on. Can it add another input parameter so it becomes (ChipConfig, 0) and so on?
Ok, additional parameter will be added.
+/***** Parsing PCD *****/ +#define GET_TYPE_STRING(id) _PCD_GET_MODE_PTR_PcdChip##id##Compatible +#define GET_LANE_TYPE(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyTypes +#define GET_LANE_SPEED(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhySpeeds +#define GET_LANE_INV(id) _PCD_GET_MODE_PTR_PcdChip##id##ComPhyInvFlags +#define GET_COMPHY_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##ComPhyBaseAddress +#define GET_HPIPE3_BASE_ADDR(id) _PCD_GET_MODE_64_PcdChip##id##Hpipe3BaseAddress +#define GET_MUX_BIT_COUNT(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMuxBitCount +#define GET_MAX_LANES(id) _PCD_GET_MODE_32_PcdChip##id##ComPhyMaxLanes
Similarly to what happened in Platforms/Marvell/Library/MppLib/MppLib.c, could these be changed to use PcdGet* instead?
Ok.
+#define FillLaneMap(id) { \
- ParsePcdString((CHAR16 *) GET_LANE_TYPE(id), ChipConfig[id].LanesCount, NULL, LaneData[id].TypeStr); \
- ParsePcdString((CHAR16 *) GET_LANE_SPEED(id), ChipConfig[id].LanesCount, LaneData[id].SpeedValue, NULL); \
- ParsePcdString((CHAR16 *) GET_LANE_INV(id), ChipConfig[id].LanesCount, LaneData[id].InvFlag, NULL); \
+}
This macro hides LaneData also - so can that be added as well, turning the below into a 3-input macro? If the above is _never_ called externally, the above macro can stay as is, but if so I would like it #undef'd below GetComPhyPcd.
Ok.
PatchCheck.py also discovered an issue (on the opp-r20160712-upstream branch):
On Tue, Jul 12, 2016 at 09:44:36PM +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
Documentation/Marvell/PortingGuide/ComPhy.txt | 82 +++ Platforms/Marvell/Armada/Armada70x0.dsc | 1 + Platforms/Marvell/Include/Library/ComPhyLib.h | 43 ++ Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c | 290 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 812 ++++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 277 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 457 ++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 111 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 ++++ Platforms/Marvell/Marvell.dec | 51 ++ 10 files changed, 2256 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/ComPhy.txt create mode 100644 Platforms/Marvell/Include/Library/ComPhyLib.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c 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..152671c --- /dev/null +++ b/Documentation/Marvell/PortingGuide/ComPhy.txt @@ -0,0 +1,82 @@ +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.
- gMarvellTokenSpaceGuid.PcdIsZVersionChip
+Indicates if Z1 chip version is used.
+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 are +{ L"Ap806", 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. 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" }
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds
+Indicates PHY speeds in MHz. Currently supported are:
+{ 1250, 1500, 2500, 3000, 3125, 5000, 6000, 6250, 1031 }
- gMarvellTokenSpaceGuid.PcdChip0ComPhyInvFlags
+Indicates lane polarity invert.
+Example +-------
From here
- #ComPhy
- gMarvellTokenSpaceGuid.PcdComPhyChipCount|1
- gMarvellTokenSpaceGuid.PcdIsZVersionChip|FALSE
- 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"
to here - double CR line endings.
/ Leif
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 --- Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 12 ++++++++++++ .../Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 2 ++ .../Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 1 + 4 files changed, 16 insertions(+)
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 866c165..9945c30 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -96,3 +96,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..9694e0f 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/ComPhyLib.h> #include <Ppi/ArmMpCoreInfo.h>
@@ -94,6 +95,7 @@ ArmPlatformInitialize (
//TODO: Add basic platfrom initialization
+ ComPhyInit (); 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
On Tue, Jul 12, 2016 at 09:44:37PM +0200, Marcin Wojtas wrote:
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
Platforms/Marvell/Armada/Armada.dsc.inc | 1 + Platforms/Marvell/Armada/Armada70x0.dsc | 12 ++++++++++++ .../Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 2 ++ .../Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 1 + 4 files changed, 16 insertions(+)
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 866c165..9945c30 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -96,3 +96,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"
Hmm, the above two lines suggest to me that what we're actually dealing with here is a flattened structure of specific outputs from "Chip0"? If correct, this could be more clearly described in Documentation/Marvell/PortingGuide/ComPhy.txt (so actually a comment for 1/8).
diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c index a2b25e1..9694e0f 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/ComPhyLib.h>
Move up one line to keep alphabetical sort order?
#include <Ppi/ArmMpCoreInfo.h> @@ -94,6 +95,7 @@ ArmPlatformInitialize ( //TODO: Add basic platfrom initialization
Does this comment still belong here?
- ComPhyInit (); 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
-- 1.8.3.1
Hi Leif,
Please find inline comments.
Best Regards, Jan
- gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|L"SGMII2;USB3_HOST0;SGMII0;SATA1;USB3_HOST1;PCIE2"
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|L"3125;5000;1250;5000;5000;5000"
Hmm, the above two lines suggest to me that what we're actually dealing with here is a flattened structure of specific outputs from "Chip0"? If correct, this could be more clearly described in Documentation/Marvell/PortingGuide/ComPhy.txt (so actually a comment for 1/8).
Yes, we are describing configurations of outputs from simple chip. It is a bit like MPP (more complex). I will try to describe these PCDs more clearly.
diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c index a2b25e1..9694e0f 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/ComPhyLib.h>
Move up one line to keep alphabetical sort order?
Ok.
#include <Ppi/ArmMpCoreInfo.h>
@@ -94,6 +95,7 @@ ArmPlatformInitialize (
//TODO: Add basic platfrom initialization
Does this comment still belong here?
Later on (in the one of the next patchsets) there will be Utmi library init call added here, that's why it wasn't removed. But all in all (and noting typo in this comment :)) I think it may be removed in this patch.
On Fri, Jul 15, 2016 at 08:47:28AM +0200, Jan Dąbroś wrote:
Hi Leif,
Please find inline comments.
Best Regards, Jan
- gMarvellTokenSpaceGuid.PcdChip0ComPhyTypes|L"SGMII2;USB3_HOST0;SGMII0;SATA1;USB3_HOST1;PCIE2"
- gMarvellTokenSpaceGuid.PcdChip0ComPhySpeeds|L"3125;5000;1250;5000;5000;5000"
Hmm, the above two lines suggest to me that what we're actually dealing with here is a flattened structure of specific outputs from "Chip0"? If correct, this could be more clearly described in Documentation/Marvell/PortingGuide/ComPhy.txt (so actually a comment for 1/8).
Yes, we are describing configurations of outputs from simple chip. It is a bit like MPP (more complex). I will try to describe these PCDs more clearly.
diff --git a/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c b/Platforms/Marvell/Armada/Library/Armada70x0Lib/Armada70x0Lib.c index a2b25e1..9694e0f 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/ComPhyLib.h>
Move up one line to keep alphabetical sort order?
Ok.
#include <Ppi/ArmMpCoreInfo.h>
@@ -94,6 +95,7 @@ ArmPlatformInitialize (
//TODO: Add basic platfrom initialization
Does this comment still belong here?
Later on (in the one of the next patchsets) there will be Utmi library init call added here, that's why it wasn't removed. But all in all (and noting typo in this comment :)) I think it may be removed in this patch.
Either is fine with me. Thanks!
/ 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 --- 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
On Tue, Jul 12, 2016 at 09:44:38PM +0200, Marcin Wojtas wrote:
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
-- 1.8.3.1
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/MdioDxe/MdioDxe.c | 235 ++++++++++++++++++++++++++++ Drivers/Net/MdioDxe/MdioDxe.h | 57 +++++++ Drivers/Net/MdioDxe/MdioDxe.inf | 68 ++++++++ Platforms/Marvell/Include/Protocol/Mdio.h | 65 ++++++++ Platforms/Marvell/Marvell.dec | 4 + 6 files changed, 436 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Mdio.txt create mode 100644 Drivers/Net/MdioDxe/MdioDxe.c create mode 100644 Drivers/Net/MdioDxe/MdioDxe.h create mode 100644 Drivers/Net/MdioDxe/MdioDxe.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/MdioDxe/MdioDxe.c b/Drivers/Net/MdioDxe/MdioDxe.c new file mode 100644 index 0000000..11f1e24 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.c @@ -0,0 +1,235 @@ +/******************************************************************************** +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/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include "MdioDxe.h" + +UINT64 MdioBase = 0; + +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; +} + +UINT32 +MdioRead ( + IN CONST MARVELL_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff + ) +{ + EFI_STATUS Status; + UINT32 Data; + + Status = MdioOperation ( + This, + PhyAddr, + RegOff, + FALSE, + &Data + ); + + return EFI_ERROR(Status) ? 0 : Data; +} + +EFI_STATUS +MdioWrite ( + 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 +MdioDxeInitialise ( + 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 = MdioRead; + Mdio->Write = MdioWrite; + 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/MdioDxe/MdioDxe.h b/Drivers/Net/MdioDxe/MdioDxe.h new file mode 100644 index 0000000..b41a1e6 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.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/MdioDxe/MdioDxe.inf b/Drivers/Net/MdioDxe/MdioDxe.inf new file mode 100644 index 0000000..57b87f1 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.inf @@ -0,0 +1,68 @@ +# 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 = MdioDxeInitialise + +[Sources.common] + MdioDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + IoLib + PcdLib + BaseLib + BaseMemoryLib + DebugLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + +[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..cc719c8 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Mdio.h @@ -0,0 +1,65 @@ +/******************************************************************************** +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 +UINT32 +(EFIAPI *MARVELL_MDIO_READ) ( + IN CONST MARVELL_MDIO_PROTOCOL *This, + IN UINT32 PhyAddr, + IN UINT32 RegOff + ); + +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 b508c36..321c674 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -178,9 +178,13 @@
#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 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }} + gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
On Tue, Jul 12, 2016 at 09:44:39PM +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
Documentation/Marvell/PortingGuide/Mdio.txt | 7 + Drivers/Net/MdioDxe/MdioDxe.c | 235 ++++++++++++++++++++++++++++ Drivers/Net/MdioDxe/MdioDxe.h | 57 +++++++ Drivers/Net/MdioDxe/MdioDxe.inf | 68 ++++++++ Platforms/Marvell/Include/Protocol/Mdio.h | 65 ++++++++ Platforms/Marvell/Marvell.dec | 4 + 6 files changed, 436 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Mdio.txt create mode 100644 Drivers/Net/MdioDxe/MdioDxe.c create mode 100644 Drivers/Net/MdioDxe/MdioDxe.h create mode 100644 Drivers/Net/MdioDxe/MdioDxe.inf
Should this be MvMdioDxe?
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)
SMI?
diff --git a/Drivers/Net/MdioDxe/MdioDxe.c b/Drivers/Net/MdioDxe/MdioDxe.c new file mode 100644 index 0000000..11f1e24 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.c @@ -0,0 +1,235 @@ +/******************************************************************************** +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/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h>
Alphabetical sorting of the above?
+#include "MdioDxe.h"
+UINT64 MdioBase = 0;
+EFI_STATUS +MdioCheckParam (
MvMdioCheckParam? Or STATIC?
- 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;
+}
+UINT32 +MdioRead (
Mv...? Or STATIC?
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff
- )
+{
- EFI_STATUS Status;
- UINT32 Data;
- Status = MdioOperation (
This,
PhyAddr,
RegOff,
FALSE,
&Data
);
- return EFI_ERROR(Status) ? 0 : Data;
+}
+EFI_STATUS +MdioWrite (
Mv...? Or STATIC?
- 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 +MdioDxeInitialise (
Mv...?
- 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 = MdioRead;
- Mdio->Write = MdioWrite;
- 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/MdioDxe/MdioDxe.h b/Drivers/Net/MdioDxe/MdioDxe.h new file mode 100644 index 0000000..b41a1e6 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.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/MdioDxe/MdioDxe.inf b/Drivers/Net/MdioDxe/MdioDxe.inf new file mode 100644 index 0000000..57b87f1 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.inf @@ -0,0 +1,68 @@ +# 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 = MdioDxeInitialise
+[Sources.common]
- MdioDxe.c
+[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
- ArmPkg/ArmPkg.dec
- OpenPlatformPkg/Platforms/Marvell/Marvell.dec
Sorted?
+[LibraryClasses]
- IoLib
- PcdLib
- BaseLib
- BaseMemoryLib
- DebugLib
- UefiLib
- UefiDriverEntryPoint
- UefiBootServicesTableLib
Sorted?
+[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..cc719c8 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Mdio.h @@ -0,0 +1,65 @@ +/******************************************************************************** +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 +UINT32 +(EFIAPI *MARVELL_MDIO_READ) (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff
- );
+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 b508c36..321c674 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -178,9 +178,13 @@ #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 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }}
- gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
Not vital, but ... sorted?
Regards,
Leif
1.8.3.1
Hi Leif,
+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)
SMI?
It's Serial Management Interface (synonym for MDIO).
Best Regards, Jan
在 7/13/2016 3:44 AM, Marcin Wojtas 写道:
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/MdioDxe/MdioDxe.c | 235 ++++++++++++++++++++++++++++ Drivers/Net/MdioDxe/MdioDxe.h | 57 +++++++ Drivers/Net/MdioDxe/MdioDxe.inf | 68 ++++++++ Platforms/Marvell/Include/Protocol/Mdio.h | 65 ++++++++ Platforms/Marvell/Marvell.dec | 4 + 6 files changed, 436 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Mdio.txt create mode 100644 Drivers/Net/MdioDxe/MdioDxe.c create mode 100644 Drivers/Net/MdioDxe/MdioDxe.h create mode 100644 Drivers/Net/MdioDxe/MdioDxe.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/MdioDxe/MdioDxe.c b/Drivers/Net/MdioDxe/MdioDxe.c new file mode 100644 index 0000000..11f1e24 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.c @@ -0,0 +1,235 @@ +/******************************************************************************** +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/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h>
+#include "MdioDxe.h"
+UINT64 MdioBase = 0;
+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;
+}
+UINT32 +MdioRead (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff
- )
+{
- EFI_STATUS Status;
- UINT32 Data;
- Status = MdioOperation (
This,
PhyAddr,
RegOff,
FALSE,
&Data
);
- return EFI_ERROR(Status) ? 0 : Data;
+}
Can we really identify error status by return value of 0? In other words, is it impossible for the device to have some registers whose value is 0?
I think it is better to use similar form of MdioOperation, i.e. using dedicated Status and a buffer to hold the read value.
Heyi
+EFI_STATUS +MdioWrite (
- 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 +MdioDxeInitialise (
- 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 = MdioRead;
- Mdio->Write = MdioWrite;
- 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/MdioDxe/MdioDxe.h b/Drivers/Net/MdioDxe/MdioDxe.h new file mode 100644 index 0000000..b41a1e6 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.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/MdioDxe/MdioDxe.inf b/Drivers/Net/MdioDxe/MdioDxe.inf new file mode 100644 index 0000000..57b87f1 --- /dev/null +++ b/Drivers/Net/MdioDxe/MdioDxe.inf @@ -0,0 +1,68 @@ +# 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 = MdioDxeInitialise
+[Sources.common]
- MdioDxe.c
+[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
- ArmPkg/ArmPkg.dec
- OpenPlatformPkg/Platforms/Marvell/Marvell.dec
+[LibraryClasses]
- IoLib
- PcdLib
- BaseLib
- BaseMemoryLib
- DebugLib
- UefiLib
- UefiDriverEntryPoint
- UefiBootServicesTableLib
+[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..cc719c8 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Mdio.h @@ -0,0 +1,65 @@ +/******************************************************************************** +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 +UINT32 +(EFIAPI *MARVELL_MDIO_READ) (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff
- );
+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 b508c36..321c674 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -178,9 +178,13 @@ #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 }} gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }}
- gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
Hi Heyi,
+UINT32 +MdioRead (
- IN CONST MARVELL_MDIO_PROTOCOL *This,
- IN UINT32 PhyAddr,
- IN UINT32 RegOff
- )
+{
- EFI_STATUS Status;
- UINT32 Data;
- Status = MdioOperation (
This,
PhyAddr,
RegOff,
FALSE,
&Data
);
- return EFI_ERROR(Status) ? 0 : Data;
+}
Can we really identify error status by return value of 0? In other words, is it impossible for the device to have some registers whose value is 0?
I think it is better to use similar form of MdioOperation, i.e. using dedicated Status and a buffer to hold the read value.
Indeed. Error handling and using data buffer by reference is implented in v2, I'm about to send now.
Best regards, Marcin
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 --- 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..4b69e0c 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/MdioDxe/MdioDxe.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 9945c30..fcf3805 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -108,3 +108,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..3c66ef5 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/MdioDxe/MdioDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
On Tue, Jul 12, 2016 at 09:44:40PM +0200, Marcin Wojtas wrote:
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..4b69e0c 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/MdioDxe/MdioDxe.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 9945c30..fcf3805 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -108,3 +108,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..3c66ef5 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/MdioDxe/MdioDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf -- 1.8.3.1
From: Bartosz Szczepanek bsz@semihalf.com
PHY protocol consists of MARVELL_PHY_STATUS and MARVELL_PHY_INIT functions.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com --- Platforms/Marvell/Include/Protocol/Phy.h | 103 +++++++++++++++++++++++++++++++ Platforms/Marvell/Marvell.dec | 1 + 2 files changed, 104 insertions(+) create mode 100644 Platforms/Marvell/Include/Protocol/Phy.h
diff --git a/Platforms/Marvell/Include/Protocol/Phy.h b/Platforms/Marvell/Include/Protocol/Phy.h new file mode 100644 index 0000000..1bb7229 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Phy.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 __PHY_H__ +#define __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 321c674..e342660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -187,4 +187,5 @@ gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }} gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }} + gMarvellPhyProtocolGuid = { 0x0d728a1e, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
On Tue, Jul 12, 2016 at 09:44:41PM +0200, Marcin Wojtas wrote:
From: Bartosz Szczepanek bsz@semihalf.com
PHY protocol consists of MARVELL_PHY_STATUS and MARVELL_PHY_INIT functions.
A full commit subject body, please :) Who uses it and why?
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Bartosz Szczepanek bsz@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
Platforms/Marvell/Include/Protocol/Phy.h | 103 +++++++++++++++++++++++++++++++ Platforms/Marvell/Marvell.dec | 1 + 2 files changed, 104 insertions(+) create mode 100644 Platforms/Marvell/Include/Protocol/Phy.h
Could do with some namespace tightening. MvPhy.h?
diff --git a/Platforms/Marvell/Include/Protocol/Phy.h b/Platforms/Marvell/Include/Protocol/Phy.h new file mode 100644 index 0000000..1bb7229 --- /dev/null +++ b/Platforms/Marvell/Include/Protocol/Phy.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 __PHY_H__ +#define __PHY_H__
Could do with some namespace tightening.
+#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 321c674..e342660 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -187,4 +187,5 @@ gMarvellSpiMasterProtocolGuid = { 0x23de66a3, 0xf666, 0x4b3e, { 0xaa, 0xa2, 0x68, 0x9b, 0x18, 0xae, 0x2e, 0x19 }} gMarvellSpiFlashProtocolGuid = { 0x9accb423, 0x5bd2, 0x4fca, { 0x9b, 0x4c, 0x2e, 0x65, 0xfc, 0x25, 0xdf, 0x21 }} gMarvellMdioProtocolGuid = { 0x0d728a1f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
- gMarvellPhyProtocolGuid = { 0x0d728a1e, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
Again, not vital but would be handy to get alphabetically sorted.
Regards,
Leif
1.8.3.1
From: Bartosz Szczepanek bsz@semihalf.com
PHY driver produces MARVELL_PHY_PROTOCOL. It supports Marvell 1512 PHYs.
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 | 439 +++++++++++++++++++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h | 194 +++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf | 71 +++++ Platforms/Marvell/Marvell.dec | 5 + 5 files changed, 754 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..5f02d82 --- /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 1518 series PHYs are supported. Following PCDs are required: + + gMarvellTokenSpaceGuid.PcdPhyConnectionTypes + (list of values corresponding to PHY_CONNECTION enum) + gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg + (boolean - if true, driver waits for autonegotiation on startup) + gMarvellTokenSpaceGuid.PcdPhyDeviceIds + (list of values corresponding to MV_PHY_DEVICE_ID enum) + +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..4529f7e --- /dev/null +++ b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c @@ -0,0 +1,439 @@ +/******************************************************************************** +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/Phy.h> +#include <Protocol/Mdio.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include "MvPhyDxe.h" + +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 = 500; + + Reg = Mdio->Read(Mdio, PhyAddr, MII_BMCR); + Reg |= BMCR_RESET; + Mdio->Write(Mdio, PhyAddr, MII_BMCR, Reg); + + while ((Reg & BMCR_RESET) && timeout--) { + Reg = Mdio->Read(Mdio, PhyAddr, MII_BMCR); + 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)) { + Reg = Mdio->Read(Mdio, PhyDev->Addr, + MIIM_88E1111_PHY_EXT_CR); + 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); + + Reg = Mdio->Read(Mdio, PhyDev->Addr, + MIIM_88E1111_PHY_EXT_SR); + + 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) { + Reg = Mdio->Read(Mdio, PhyDev->Addr, + MIIM_88E1111_PHY_EXT_SR); + + 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) { + Reg = Mdio->Read(Mdio, PhyDev->Addr, + MIIM_88E1111_PHY_EXT_CR); + Reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY); + Mdio->Write(Mdio, PhyDev->Addr, + MIIM_88E1111_PHY_EXT_CR, Reg); + + Reg = Mdio->Read(Mdio, PhyDev->Addr, + MIIM_88E1111_PHY_EXT_SR); + 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); + + Reg = Mdio->Read(Mdio, PhyDev->Addr, + MIIM_88E1111_PHY_EXT_SR); + 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); + } + + Reg = Mdio->Read(Mdio, PhyDev->Addr, MII_BMCR); + 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; + + Data = Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS); + + 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); + Data = Mdio->Read(Mdio, PhyDev->Addr, + MIIM_88E1xxx_PHY_STATUS); + } + 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 +MvPhy1518WriteBits ( + IN UINT32 PhyAddr, + IN UINT8 RegNum, + IN UINT16 Offset, + IN UINT16 Len, + IN UINT16 Data) +{ + UINT16 Reg, Mask; + + if ((Len + Offset) >= 16) + Mask = 0 - (1 << Offset); + else + Mask = (1 << (Len + Offset)) - (1 << Offset); + + Reg = Mdio->Read(Mdio, PhyAddr, RegNum); + + 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; + + if (PhyDev->Connection == PHY_CONNECTION_SGMII) { + Mdio->Write(Mdio, PhyAddr, 22, 0x00ff); /* page 0xff */ + 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); /* reg page 0 */ + Mdio->Write(Mdio, PhyAddr, 22, 18); /* reg page 18 */ + /* Write HWCFG_MODE = SGMII to Copper */ + MvPhy1518WriteBits(PhyAddr, 20, 0, 3, 1); + + /* Phy reset */ + MvPhy1518WriteBits(PhyAddr, 20, 15, 1, 1); + Mdio->Write(Mdio, PhyAddr, 22, 0); /* reg page 18 */ + gBS->Stall(100); + } + + MvPhyM88e1111sConfig (PhyDev); + + /* autonegotiation on startup is not always required */ + if (!PcdGetBool (PcdPhyStartupAutoneg)) + return EFI_SUCCESS; + + Data = Mdio->Read(Mdio, PhyAddr, MII_BMSR); + + 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 */ + Data = Mdio->Read(Mdio, PhyAddr, MII_BMSR); + } + PhyDev->LinkUp = TRUE; + DEBUG((DEBUG_INFO, "MvPhyDxe: link up\n")); + } else { + Data = Mdio->Read(Mdio, PhyAddr, MII_BMSR); + + 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; + + Data = Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR); + Data = Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR); + + 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..9b75180 --- /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] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPkg/ArmPkg.dec + OpenPlatformPkg/Platforms/Marvell/Marvell.dec + +[LibraryClasses] + IoLib + PcdLib + BaseLib + BaseMemoryLib + DebugLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + +[Protocols] + gMarvellPhyProtocolGuid + gMarvellMdioProtocolGuid + +[Pcd] + gMarvellTokenSpaceGuid.PcdPhyConnectionTypes + gMarvellTokenSpaceGuid.PcdPhyDeviceIds + gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg + +[Depex] + TRUE diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e342660..a206363 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 }}
On Tue, Jul 12, 2016 at 09:44:42PM +0200, Marcin Wojtas wrote:
From: Bartosz Szczepanek bsz@semihalf.com
PHY driver produces MARVELL_PHY_PROTOCOL. It supports Marvell 1512 PHYs.
Who uses it?
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 | 439 +++++++++++++++++++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.h | 194 +++++++++++++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf | 71 +++++ Platforms/Marvell/Marvell.dec | 5 + 5 files changed, 754 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/Phy.txt
Under Marvell directory, and .txt not exported anywhere, so keep this name if you wish, or rename MvPhy.txt to match other changes if you prefer.
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..5f02d82 --- /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 1518 series PHYs are supported. Following PCDs are required:
Commit message says 1512.
- 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..4529f7e --- /dev/null +++ b/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c @@ -0,0 +1,439 @@ +/******************************************************************************** +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/Phy.h> +#include <Protocol/Mdio.h>
Consider sorting.
+#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h>
Consider sorting.
+#include "MvPhyDxe.h"
+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 = 500;
Could the timeout be set from a #define?
- Reg = Mdio->Read(Mdio, PhyAddr, MII_BMCR);
- Reg |= BMCR_RESET;
- Mdio->Write(Mdio, PhyAddr, MII_BMCR, Reg);
- while ((Reg & BMCR_RESET) && timeout--) {
- Reg = Mdio->Read(Mdio, PhyAddr, MII_BMCR);
- 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)) {
- Reg = Mdio->Read(Mdio, PhyDev->Addr,
MIIM_88E1111_PHY_EXT_CR);
- 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);
- Reg = Mdio->Read(Mdio, PhyDev->Addr,
MIIM_88E1111_PHY_EXT_SR);
I like short lines, but both the above two statements should fit on a single 72-character line? Seen elsewhere in file as well.
- 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) {
- Reg = Mdio->Read(Mdio, PhyDev->Addr,
MIIM_88E1111_PHY_EXT_SR);
- 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) {
- Reg = Mdio->Read(Mdio, PhyDev->Addr,
MIIM_88E1111_PHY_EXT_CR);
- Reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
- Mdio->Write(Mdio, PhyDev->Addr,
MIIM_88E1111_PHY_EXT_CR, Reg);
- Reg = Mdio->Read(Mdio, PhyDev->Addr,
MIIM_88E1111_PHY_EXT_SR);
- 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);
- Reg = Mdio->Read(Mdio, PhyDev->Addr,
MIIM_88E1111_PHY_EXT_SR);
- 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);
- }
- Reg = Mdio->Read(Mdio, PhyDev->Addr, MII_BMCR);
- 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;
- Data = Mdio->Read(Mdio, PhyDev->Addr, MIIM_88E1xxx_PHY_STATUS);
- 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);
Data = Mdio->Read(Mdio, PhyDev->Addr,
MIIM_88E1xxx_PHY_STATUS);
- }
- 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 +MvPhy1518WriteBits (
1518 or 1512?
- IN UINT32 PhyAddr,
- IN UINT8 RegNum,
- IN UINT16 Offset,
- IN UINT16 Len,
- IN UINT16 Data)
+{
- UINT16 Reg, Mask;
- if ((Len + Offset) >= 16)
- Mask = 0 - (1 << Offset);
- else
- Mask = (1 << (Len + Offset)) - (1 << Offset);
- Reg = Mdio->Read(Mdio, PhyAddr, RegNum);
- 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;
- if (PhyDev->Connection == PHY_CONNECTION_SGMII) {
- Mdio->Write(Mdio, PhyAddr, 22, 0x00ff); /* page 0xff */
- 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); /* reg page 0 */
- Mdio->Write(Mdio, PhyAddr, 22, 18); /* reg page 18 */
- /* Write HWCFG_MODE = SGMII to Copper */
- MvPhy1518WriteBits(PhyAddr, 20, 0, 3, 1);
- /* Phy reset */
- MvPhy1518WriteBits(PhyAddr, 20, 15, 1, 1);
- Mdio->Write(Mdio, PhyAddr, 22, 0); /* reg page 18 */
- gBS->Stall(100);
- }
- MvPhyM88e1111sConfig (PhyDev);
- /* autonegotiation on startup is not always required */
- if (!PcdGetBool (PcdPhyStartupAutoneg))
- return EFI_SUCCESS;
- Data = Mdio->Read(Mdio, PhyAddr, MII_BMSR);
- 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 */
Data = Mdio->Read(Mdio, PhyAddr, MII_BMSR);
- }
- PhyDev->LinkUp = TRUE;
- DEBUG((DEBUG_INFO, "MvPhyDxe: link up\n"));
- } else {
- Data = Mdio->Read(Mdio, PhyAddr, MII_BMSR);
- 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;
- Data = Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR);
- Data = Mdio->Read(Mdio, PhyDev->Addr, MII_BMSR);
- 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..9b75180 --- /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]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- ArmPlatformPkg/ArmPlatformPkg.dec
- ArmPkg/ArmPkg.dec
- OpenPlatformPkg/Platforms/Marvell/Marvell.dec
Sort?
+[LibraryClasses]
- IoLib
- PcdLib
- BaseLib
- BaseMemoryLib
- DebugLib
- UefiLib
- UefiDriverEntryPoint
- UefiBootServicesTableLib
Sort?
+[Protocols]
- gMarvellPhyProtocolGuid
- gMarvellMdioProtocolGuid
Sort?
Regards,
Leif
+[Pcd]
- gMarvellTokenSpaceGuid.PcdPhyConnectionTypes
- gMarvellTokenSpaceGuid.PcdPhyDeviceIds
- gMarvellTokenSpaceGuid.PcdPhyStartupAutoneg
+[Depex]
- TRUE
diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index e342660..a206363 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 }} -- 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 --- 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 4b69e0c..af8ecc5 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/MdioDxe/MdioDxe.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 fcf3805..8e7ae79 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -111,3 +111,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 3c66ef5..60463d9 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/MdioDxe/MdioDxe.inf + INF OpenPlatformPkg/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
On Tue, Jul 12, 2016 at 09:44:43PM +0200, Marcin Wojtas wrote:
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 4b69e0c..af8ecc5 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/MdioDxe/MdioDxe.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 fcf3805..8e7ae79 100644 --- a/Platforms/Marvell/Armada/Armada70x0.dsc +++ b/Platforms/Marvell/Armada/Armada70x0.dsc @@ -111,3 +111,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 3c66ef5..60463d9 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/MdioDxe/MdioDxe.inf
- INF OpenPlatformPkg/Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.inf
# Multiple Console IO support INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf -- 1.8.3.1
Hi Leif,
Thank you for such prompt and thorough review!
Best regards, Marcin
2016-07-12 21:44 GMT+02:00 Marcin Wojtas mw@semihalf.com:
Hi,
Since basic support of Armada 7040 has been integrated to the tree, here is another part of the platform. Below commits comprise three parts:
- ComPhy library - SerDes configuration and multiplexing
- MDIO library
- PHY library
Altogether they are needed for enabling network on Armada 7040 (driver not included in this patchset).
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.
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 | 82 +++ Documentation/Marvell/PortingGuide/Mdio.txt | 7 + Documentation/Marvell/PortingGuide/Phy.txt | 45 ++ Drivers/Net/MdioDxe/MdioDxe.c | 235 ++++++ Drivers/Net/MdioDxe/MdioDxe.h | 57 ++ Drivers/Net/MdioDxe/MdioDxe.inf | 68 ++ Drivers/Net/Phy/MvPhyDxe/MvPhyDxe.c | 439 +++++++++++ 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 | 21 + Platforms/Marvell/Armada/Armada70x0.fdf | 14 + .../Armada/Library/Armada70x0Lib/Armada70x0Lib.c | 2 + .../Armada/Library/Armada70x0Lib/Armada70x0Lib.inf | 1 + Platforms/Marvell/Include/Library/ComPhyLib.h | 43 ++ Platforms/Marvell/Include/Protocol/Mdio.h | 65 ++ Platforms/Marvell/Include/Protocol/Phy.h | 103 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c | 290 ++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyCp110.c | 812 +++++++++++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.c | 277 +++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.h | 457 ++++++++++++ Platforms/Marvell/Library/ComPhyLib/ComPhyLib.inf | 111 +++ Platforms/Marvell/Library/ComPhyLib/ComPhyMux.c | 132 ++++ Platforms/Marvell/Marvell.dec | 61 ++ 24 files changed, 3606 insertions(+), 1 deletion(-) 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/MdioDxe/MdioDxe.c create mode 100644 Drivers/Net/MdioDxe/MdioDxe.h create mode 100644 Drivers/Net/MdioDxe/MdioDxe.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/ComPhyLib.h create mode 100644 Platforms/Marvell/Include/Protocol/Mdio.h create mode 100644 Platforms/Marvell/Include/Protocol/Phy.h create mode 100644 Platforms/Marvell/Library/ComPhyLib/ComPhyAp806.c 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
-- 1.8.3.1