Mario Scheithauer has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/58847 )
Change subject: mb/siemens/mc_ehl: Invert PHY to MAC Interrupt Polarity for TSN GbE ......................................................................
mb/siemens/mc_ehl: Invert PHY to MAC Interrupt Polarity for TSN GbE
Invert PHY to MAC Interrupt Polarity for enabled TSN GbE controller.
Change-Id: I440ed5b61b2704af36ee7b1e7dd59435720763c0 Signed-off-by: Mario Scheithauer mario.scheithauer@siemens.com --- M src/mainboard/siemens/mc_ehl/mainboard.c 1 file changed, 115 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/47/58847/1
diff --git a/src/mainboard/siemens/mc_ehl/mainboard.c b/src/mainboard/siemens/mc_ehl/mainboard.c index 8641428..242b5d6 100644 --- a/src/mainboard/siemens/mc_ehl/mainboard.c +++ b/src/mainboard/siemens/mc_ehl/mainboard.c @@ -3,6 +3,7 @@ #include <baseboard/variants.h> #include <bootstate.h> #include <console/console.h> +#include <delay.h> #include <device/device.h> #include <device/pci_def.h> #include <device/pci_ops.h> @@ -17,6 +18,26 @@ #define MAX_PATH_DEPTH 12 #define MAX_NUM_MAPPINGS 10
+#define B_TSN_MEM_MAC_MDIO_ADDRESS_MASK 0x03FF7F0E +#define R_TSN_MEM_MAC_MDIO_ADDRESS 0x200 +#define R_TSN_MEM_MAC_MDIO_DATA 0x204 +#define N_TSN_MEM_MAC_MDIO_REGAD 0x10 +#define V_TSN_MEM_MAC_MDIO_GCR 0x0 +#define N_TSN_MEM_MAC_MDIO_PHYAD 0x15 +#define V_TSN_MEM_MAC_MDIO_ADHOC_GCR_ADD 0x15 +#define N_TSN_MEM_MAC_MDIO_CLK_TRAIL 0xC +#define V_TSN_MEM_MAC_MDIO_CLK_TRAIL 0x4 +#define N_TSN_MEM_MAC_MDIO_CLK_CSR 0x8 +#define V_TSN_MEM_MAC_MDIO_CLK_CSR_DIV_10 0xB +#define V_TSN_MEM_MAC_MDIO_GMII_22_PHY_READ 0x0C +#define V_TSN_MEM_MAC_MDIO_GMII_22_PHY_WRITE 0x04 +#define B_TSN_MEM_MAC_MDIO_GMII_BUSY (1 << 0) + +#define B_TSN_MEM_MAC_ADHOC_PHY2MAC_INTR_POL (1 << 6) + +#define TSN_MAX_LOOP_TIME 4000 +#define TSN_GMII_DELAY 50 + /** \brief This function can decide if a given MAC address is valid or not. * Currently, addresses filled with 0xff or 0x00 are not valid. * @param mac Buffer to the MAC address to check @@ -114,6 +135,67 @@ return CB_SUCCESS; }
+static int32_t PhyGmiiBusyStatus(uint32_t TsnBar0) +{ + uint32_t Count; + + for (Count = 0; Count < TSN_MAX_LOOP_TIME; ++Count) { + if (read32((void *)(TsnBar0 + R_TSN_MEM_MAC_MDIO_ADDRESS)) & + B_TSN_MEM_MAC_MDIO_GMII_BUSY) + udelay(TSN_GMII_DELAY); + else + return CB_SUCCESS; + } + printk(BIOS_INFO, "PhyGMIIBusyStatus Timeout in %d micro seconds\n", + TSN_MAX_LOOP_TIME * TSN_GMII_DELAY); + return CB_ERR; +} + +static uint16_t TsnMdioRead(uint32_t TsnBar0, uint8_t PhyAdd, uint8_t RegAdd) +{ + uint32_t MacMdioAddressValue; + uint16_t Data16; + enum cb_err Status; + + Data16 = 0; + MacMdioAddressValue = read32((void *)(TsnBar0 + R_TSN_MEM_MAC_MDIO_ADDRESS)); + MacMdioAddressValue &= (uint32_t)~(B_TSN_MEM_MAC_MDIO_ADDRESS_MASK); + MacMdioAddressValue |= (PhyAdd << N_TSN_MEM_MAC_MDIO_PHYAD) + | (RegAdd << N_TSN_MEM_MAC_MDIO_REGAD) + | (V_TSN_MEM_MAC_MDIO_CLK_TRAIL << N_TSN_MEM_MAC_MDIO_CLK_TRAIL) + | (V_TSN_MEM_MAC_MDIO_CLK_CSR_DIV_10 << N_TSN_MEM_MAC_MDIO_CLK_CSR) + | V_TSN_MEM_MAC_MDIO_GMII_22_PHY_READ | B_TSN_MEM_MAC_MDIO_GMII_BUSY; + write32((void *)(TsnBar0 + R_TSN_MEM_MAC_MDIO_ADDRESS), MacMdioAddressValue); + + // Wait for MDIO frame transfer complete before reading MDIO DATA register + Status = PhyGmiiBusyStatus(TsnBar0); + if (Status == CB_ERR) + printk(BIOS_INFO, "TSN GMII Busy. MIDO PhyAdd: 0x%x, Register 0x%x read " + "invalid\n", PhyAdd, RegAdd); + Data16 = read16((void *)(TsnBar0 + R_TSN_MEM_MAC_MDIO_DATA)); + printk(BIOS_INFO, "TSN MDIO Read PhyAdd: 0x%x, RegAdd: 0x%x , Value: 0x%x, " + "Raw: 0x%x\n", PhyAdd, RegAdd, Data16, MacMdioAddressValue); + return Data16; +} + +static void TsnMdioWrite(uint32_t TsnBar0, uint8_t PhyAdd, uint8_t RegAdd, + uint16_t DataValue) +{ + uint32_t MacMdioAddressValue; + + write16((void *)(TsnBar0 + R_TSN_MEM_MAC_MDIO_DATA), DataValue); + MacMdioAddressValue = read32((void *)(TsnBar0 + R_TSN_MEM_MAC_MDIO_ADDRESS)); + MacMdioAddressValue &= (uint32_t)~(B_TSN_MEM_MAC_MDIO_ADDRESS_MASK); + MacMdioAddressValue |= (PhyAdd << N_TSN_MEM_MAC_MDIO_PHYAD) + | (RegAdd << N_TSN_MEM_MAC_MDIO_REGAD) + | (V_TSN_MEM_MAC_MDIO_CLK_TRAIL << N_TSN_MEM_MAC_MDIO_CLK_TRAIL) + | (V_TSN_MEM_MAC_MDIO_CLK_CSR_DIV_10 << N_TSN_MEM_MAC_MDIO_CLK_CSR) + | V_TSN_MEM_MAC_MDIO_GMII_22_PHY_WRITE | B_TSN_MEM_MAC_MDIO_GMII_BUSY; + write32((void *)(TsnBar0 + R_TSN_MEM_MAC_MDIO_ADDRESS), MacMdioAddressValue); + printk(BIOS_INFO, "TSN MDIO Write PhyAdd: 0x%x, RegAdd: 0x%x, Value : 0x%x, " + "Raw: 0x%x\n", PhyAdd, RegAdd, DataValue, MacMdioAddressValue); +} + static void wait_for_legacy_dev(void *unused) { uint32_t legacy_delay, us_since_boot; @@ -174,6 +256,17 @@ if (!status) printk(BIOS_INFO, "TSN (1e.4 - SGMII - X127): Update MAC " "address successful\n"); + uint32_t bar = (pci_read_config32(dev, PCI_BASE_ADDRESS_0) & 0xFFFFF000); + if (bar) { + uint16_t GcrValue; + + // Reading Tsn Adhoc Register GCR mgbe_mdio + GcrValue = TsnMdioRead(bar, V_TSN_MEM_MAC_MDIO_ADHOC_GCR_ADD, + V_TSN_MEM_MAC_MDIO_GCR); + GcrValue |= B_TSN_MEM_MAC_ADHOC_PHY2MAC_INTR_POL; + TsnMdioWrite(bar, V_TSN_MEM_MAC_MDIO_ADHOC_GCR_ADD, + V_TSN_MEM_MAC_MDIO_GCR, GcrValue); + } } // set mac address for 1d.1 tsn dev = dev_find_device(PCI_VENDOR_ID_INTEL, 0x4ba0, 0); @@ -183,6 +276,17 @@ if (!status) printk(BIOS_INFO, "TSN (1d.1 - RGMII P0 - X120/X170): " "Update MAC address successful\n"); + uint32_t bar = (pci_read_config32(dev, PCI_BASE_ADDRESS_0) & 0xFFFFF000); + if (bar) { + uint16_t GcrValue; + + // Reading Tsn Adhoc Register GCR mgbe_mdio + GcrValue = TsnMdioRead(bar, V_TSN_MEM_MAC_MDIO_ADHOC_GCR_ADD, + V_TSN_MEM_MAC_MDIO_GCR); + GcrValue |= B_TSN_MEM_MAC_ADHOC_PHY2MAC_INTR_POL; + TsnMdioWrite(bar, V_TSN_MEM_MAC_MDIO_ADHOC_GCR_ADD, + V_TSN_MEM_MAC_MDIO_GCR, GcrValue); + } } // set mac address for 1d.2 tsn dev = dev_find_device(PCI_VENDOR_ID_INTEL, 0x4bb0, 0); @@ -192,6 +296,17 @@ if (!status) printk(BIOS_INFO, "TSN (1d.2 - RGMII P1 - X130/X160): " "Update MAC address successful\n"); + uint32_t bar = (pci_read_config32(dev, PCI_BASE_ADDRESS_0) & 0xFFFFF000); + if (bar) { + uint16_t GcrValue; + + // Reading Tsn Adhoc Register GCR mgbe_mdio + GcrValue = TsnMdioRead(bar, V_TSN_MEM_MAC_MDIO_ADHOC_GCR_ADD, + V_TSN_MEM_MAC_MDIO_GCR); + GcrValue |= B_TSN_MEM_MAC_ADHOC_PHY2MAC_INTR_POL; + TsnMdioWrite(bar, V_TSN_MEM_MAC_MDIO_ADHOC_GCR_ADD, + V_TSN_MEM_MAC_MDIO_GCR, GcrValue); + } } }