1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
5 #include <device/mdio.h>
6 #include <device/pci.h>
7 #include <device/pci_ids.h>
8 #include <device/pci_ops.h>
9 #include <intelblocks/lpss.h>
10 #include <soc/soc_chip.h>
11 #include <soc/tsn_gbe.h>
14 static void program_mac_address(struct device
*dev
, void *base
)
17 uint8_t mac
[MAC_ADDR_LEN
];
19 /* Check first whether there is a valid MAC address available */
20 status
= mainboard_get_mac_address(dev
, mac
);
21 if (status
!= CB_SUCCESS
) {
22 printk(BIOS_INFO
, "TSN GbE: No valid MAC address found\n");
26 printk(BIOS_DEBUG
, "TSN GbE: Programming MAC Address...\n");
28 /* Write the upper 16 bits of the first 6-byte MAC address */
29 clrsetbits32(base
+ TSN_MAC_ADD0_HIGH
, 0xffff, ((mac
[5] << 8) | mac
[4]));
30 /* Write the lower 32 bits of the first 6-byte MAC address */
31 clrsetbits32(base
+ TSN_MAC_ADD0_LOW
, 0xffffffff,
32 (mac
[3] << 24) | (mac
[2] << 16) | (mac
[1] << 8) | mac
[0]);
36 static void tsn_set_phy2mac_irq_polarity(struct device
*dev
, enum tsn_phy_irq_polarity pol
)
39 const struct mdio_bus_operations
*mdio_ops
;
41 mdio_ops
= dev_get_mdio_ops(dev
);
45 if (pol
== RISING_EDGE
) {
46 /* Read TSN adhoc PHY sublayer register - global configuration register */
47 gcr_reg
= mdio_ops
->read(dev
, TSN_MAC_MDIO_ADHOC_ADR
, TSN_MAC_MDIO_GCR
);
48 gcr_reg
|= TSN_MAC_PHY2MAC_INTR_POL
;
49 mdio_ops
->write(dev
, TSN_MAC_MDIO_ADHOC_ADR
, TSN_MAC_MDIO_GCR
, gcr_reg
);
53 static void gbe_tsn_enable(struct device
*dev
)
55 /* Ensure controller is in D0 state. */
56 lpss_set_power_state(PCI_DEV(0, PCI_SLOT(dev
->path
.pci
.devfn
),
57 PCI_FUNC(dev
->path
.pci
.devfn
)), STATE_D0
);
60 static void gbe_tsn_init(struct device
*dev
)
62 /* Get the base address of the I/O registers in memory space */
63 struct resource
*gbe_tsn_res
= find_resource(dev
, PCI_BASE_ADDRESS_0
);
64 void *io_mem_base
= (void *)(uintptr_t)gbe_tsn_res
->base
;
65 config_t
*config
= config_of(dev
);
67 /* Program MAC address */
68 program_mac_address(dev
, io_mem_base
);
70 /* Set PHY-to-MAC IRQ polarity according to devicetree */
71 switch (dev
->path
.pci
.devfn
) {
73 tsn_set_phy2mac_irq_polarity(dev
, config
->pch_tsn_phy_irq_edge
);
75 case PCH_DEVFN_PSEGBE0
:
76 tsn_set_phy2mac_irq_polarity(dev
, config
->pse_tsn_phy_irq_edge
[0]);
78 case PCH_DEVFN_PSEGBE1
:
79 tsn_set_phy2mac_irq_polarity(dev
, config
->pse_tsn_phy_irq_edge
[1]);
84 static enum cb_err
phy_gmii_ready(void *base
)
88 stopwatch_init_msecs_expire(&sw
, GMII_TIMEOUT_MS
);
90 if (!(read32((base
+ MAC_MDIO_ADR
)) & MAC_GMII_BUSY
))
93 } while (!stopwatch_expired(&sw
));
95 printk(BIOS_ERR
, "%s Timeout after %lld msec\n", __func__
,
96 stopwatch_duration_msecs(&sw
));
100 static uint16_t tsn_mdio_read(struct device
*dev
, uint8_t phy_adr
, uint8_t reg_adr
)
103 struct resource
*gbe_tsn_res
= find_resource(dev
, PCI_BASE_ADDRESS_0
);
104 void *mmio_base
= res2mmio(gbe_tsn_res
, 0, 0);
109 clrsetbits32(mmio_base
+ MAC_MDIO_ADR
, MAC_MDIO_ADR_MASK
,
110 MAC_PHYAD(phy_adr
) | MAC_REGAD(reg_adr
)
111 | MAC_CLK_TRAIL_4
| MAC_CSR_CLK_DIV_102
112 | MAC_OP_CMD_READ
| MAC_GMII_BUSY
);
114 /* Wait for MDIO frame transfer to complete before reading MDIO DATA register. */
115 if (phy_gmii_ready(mmio_base
) != CB_SUCCESS
) {
116 printk(BIOS_ERR
, "%s TSN GMII busy. PHY Adr: 0x%x, Reg 0x%x\n",
117 __func__
, phy_adr
, reg_adr
);
119 data
= read16(mmio_base
+ MAC_MDIO_DATA
);
120 printk(BIOS_SPEW
, "%s PHY Adr: 0x%x, Reg: 0x%x , Data: 0x%x\n",
121 __func__
, phy_adr
, reg_adr
, data
);
126 static void tsn_mdio_write(struct device
*dev
, uint8_t phy_adr
, uint8_t reg_adr
, uint16_t data
)
128 struct resource
*gbe_tsn_res
= find_resource(dev
, PCI_BASE_ADDRESS_0
);
129 void *mmio_base
= res2mmio(gbe_tsn_res
, 0, 0);
134 write16(mmio_base
+ MAC_MDIO_DATA
, data
);
135 clrsetbits32(mmio_base
+ MAC_MDIO_ADR
, MAC_MDIO_ADR_MASK
,
136 MAC_PHYAD(phy_adr
) | MAC_REGAD(reg_adr
)
137 | MAC_CLK_TRAIL_4
| MAC_CSR_CLK_DIV_102
138 | MAC_OP_CMD_WRITE
| MAC_GMII_BUSY
);
140 /* Wait for MDIO frame transfer to complete before exit. */
141 if (phy_gmii_ready(mmio_base
) != CB_SUCCESS
)
142 printk(BIOS_ERR
, "%s TSN GMII busy. PHY Adr: 0x%x, Reg 0x%x\n",
143 __func__
, phy_adr
, reg_adr
);
145 printk(BIOS_SPEW
, "%s PHY Adr: 0x%x, Reg: 0x%x , Data: 0x%x\n",
146 __func__
, phy_adr
, reg_adr
, data
);
149 static struct mdio_bus_operations mdio_ops
= {
150 .read
= tsn_mdio_read
,
151 .write
= tsn_mdio_write
,
154 static struct device_operations gbe_tsn_ops
= {
155 .read_resources
= pci_dev_read_resources
,
156 .set_resources
= pci_dev_set_resources
,
157 .enable_resources
= pci_dev_enable_resources
,
158 .scan_bus
= scan_generic_bus
,
159 .enable
= gbe_tsn_enable
,
160 .init
= gbe_tsn_init
,
161 .ops_mdio
= &mdio_ops
,
164 static const unsigned short gbe_tsn_device_ids
[] = {
165 PCI_DID_INTEL_EHL_GBE_HOST
,
166 PCI_DID_INTEL_EHL_GBE_PSE_0
,
167 PCI_DID_INTEL_EHL_GBE_PSE_1
,
171 static const struct pci_driver gbe_tsn_driver __pci_driver
= {
173 .vendor
= PCI_VID_INTEL
,
174 .devices
= gbe_tsn_device_ids
,