mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-26 20:37:16 +00:00
net: xilinx_axi: add PCS/PMA PHY
If we bridge an external PHY to Xilinx's PCS/PMA PHY and would like to get and set the real status of the PHY facing the external world. Then we should phy_connect() to the external PHY instead of the PCS/PMA one. Thus, we add a pcs-handle DT entry, which have been merged in Linux, and leave the configuration of it to the driver itself. Unlike Linux, where the PCS/PMA PHY is managed by phylink, managing the PCS/PMA PHY is only internal to the driver in U-Boot. The PCS/PMA PHY pressents only when the phy-mode is configured as SGMII or 1000Base-X, so it is always 1 Gbps and full-duplex and we may skip passing link information out. Signed-off-by: Andy Chiu <andy.chiu@sifive.com> Reviewed-by: Greentime Hu <greentime.hu@sifive.com> Link: https://lore.kernel.org/r/20221101035800.912644-2-andy.chiu@sifive.com Signed-off-by: Michal Simek <michal.simek@amd.com>
This commit is contained in:
parent
d2c5607edd
commit
e23544cffe
1 changed files with 24 additions and 2 deletions
|
@ -109,6 +109,7 @@ struct axidma_plat {
|
|||
struct eth_pdata eth_pdata;
|
||||
struct axidma_reg *dmatx;
|
||||
struct axidma_reg *dmarx;
|
||||
int pcsaddr;
|
||||
int phyaddr;
|
||||
u8 eth_hasnobuf;
|
||||
int phy_of_handle;
|
||||
|
@ -119,6 +120,7 @@ struct axidma_plat {
|
|||
struct axidma_priv {
|
||||
struct axidma_reg *dmatx;
|
||||
struct axidma_reg *dmarx;
|
||||
int pcsaddr;
|
||||
int phyaddr;
|
||||
struct axi_regs *iobase;
|
||||
phy_interface_t interface;
|
||||
|
@ -301,6 +303,13 @@ static int axiemac_phy_init(struct udevice *dev)
|
|||
if (IS_ENABLED(CONFIG_DM_ETH_PHY))
|
||||
priv->phyaddr = eth_phy_get_addr(dev);
|
||||
|
||||
/*
|
||||
* Set address of PCS/PMA PHY to the one pointed by phy-handle for
|
||||
* backward compatibility.
|
||||
*/
|
||||
if (priv->phyaddr != -1 && priv->pcsaddr == 0)
|
||||
priv->pcsaddr = priv->phyaddr;
|
||||
|
||||
if (priv->phyaddr == -1) {
|
||||
/* Detect the PHY address */
|
||||
for (i = 31; i >= 0; i--) {
|
||||
|
@ -348,12 +357,12 @@ static int setup_phy(struct udevice *dev)
|
|||
* after DMA and ethernet resets and hence
|
||||
* check and clear if set.
|
||||
*/
|
||||
ret = phyread(priv, priv->phyaddr, MII_BMCR, &temp);
|
||||
ret = phyread(priv, priv->pcsaddr, MII_BMCR, &temp);
|
||||
if (ret)
|
||||
return 0;
|
||||
if (temp & BMCR_ISOLATE) {
|
||||
temp &= ~BMCR_ISOLATE;
|
||||
ret = phywrite(priv, priv->phyaddr, MII_BMCR, temp);
|
||||
ret = phywrite(priv, priv->pcsaddr, MII_BMCR, temp);
|
||||
if (ret)
|
||||
return 0;
|
||||
}
|
||||
|
@ -784,6 +793,7 @@ static int axi_emac_probe(struct udevice *dev)
|
|||
|
||||
if (priv->mactype == EMAC_1G) {
|
||||
priv->eth_hasnobuf = plat->eth_hasnobuf;
|
||||
priv->pcsaddr = plat->pcsaddr;
|
||||
priv->phyaddr = plat->phyaddr;
|
||||
priv->phy_of_handle = plat->phy_of_handle;
|
||||
priv->interface = pdata->phy_interface;
|
||||
|
@ -861,6 +871,8 @@ static int axi_emac_of_to_plat(struct udevice *dev)
|
|||
|
||||
if (plat->mactype == EMAC_1G) {
|
||||
plat->phyaddr = -1;
|
||||
/* PHYAD 0 always redirects to the PCS/PMA PHY */
|
||||
plat->pcsaddr = 0;
|
||||
|
||||
offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
|
||||
"phy-handle");
|
||||
|
@ -878,6 +890,16 @@ static int axi_emac_of_to_plat(struct udevice *dev)
|
|||
|
||||
plat->eth_hasnobuf = fdtdec_get_bool(gd->fdt_blob, node,
|
||||
"xlnx,eth-hasnobuf");
|
||||
|
||||
if (pdata->phy_interface == PHY_INTERFACE_MODE_SGMII ||
|
||||
pdata->phy_interface == PHY_INTERFACE_MODE_1000BASEX) {
|
||||
offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
|
||||
"pcs-handle");
|
||||
if (offset > 0) {
|
||||
plat->pcsaddr = fdtdec_get_int(gd->fdt_blob,
|
||||
offset, "reg", -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue