diff options
author | Tom Rini <trini@konsulko.com> | 2022-12-05 08:33:19 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-12-05 08:33:19 -0500 |
commit | a50622d78c5c6babd1853ae913f339df54fe532c (patch) | |
tree | d9983965f00679f68b5a12cbc2dbc5dd64aafc4d /drivers | |
parent | bdaf047f51eda655f3d6bc9d076696f7733a57d8 (diff) | |
parent | 7ad3c09e7911e71c9a16a30aa052093a8f9b7e7c (diff) | |
download | u-boot-a50622d78c5c6babd1853ae913f339df54fe532c.tar.gz |
Merge tag 'xilinx-for-v2023.01-rc3-v2' of https://source.denx.de/u-boot/custodians/u-boot-microblazeWIP/05Dec2022
Xilinx changes for v2023.01-rc3-v2
xilinx:
- Fix MAC address selection for System Controller from FRU
- Cleanup Kconfig (ZYNQ_MAC_IN_EEPROM symbol)
versal:
- Create u-boot.elf for mini spi configurations
versal-net:
- Enable MT35XU flash
zynq:
- Add missing timer to DT for mini configurations
zynqmp:
- Do not include psu_init to U-Boot by default
- Do not enable IPI by default to mini U-Boot
- Update Luca's fragment
- Fix SPL_FS_LOAD_PAYLOAD_NAME usage
spi:
- gqspi: Fix tapdelay values
- gqspi: Fix 64bit address support
- cadence: Remove condition for calling enable linear mode
- nor-core: Invert logic to reflect sst26 flash unlocked
net:
- Add PCS/PMA phy support
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/spi/spi-nor-core.c | 2 | ||||
-rw-r--r-- | drivers/net/xilinx_axi_emac.c | 70 | ||||
-rw-r--r-- | drivers/spi/cadence_qspi_apb.c | 6 | ||||
-rw-r--r-- | drivers/spi/zynqmp_gqspi.c | 8 |
4 files changed, 75 insertions, 11 deletions
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 78de3c52816..1ea8363d9f8 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -1600,7 +1600,7 @@ static int sst26_is_unlocked(struct spi_nor *nor, loff_t ofs, uint64_t len) ofs -= ofs & (SZ_64K - 1); len = len & (SZ_64K - 1) ? (len & ~(SZ_64K - 1)) + SZ_64K : len; - return sst26_lock_ctl(nor, ofs, len, SST26_CTL_CHECK); + return !sst26_lock_ctl(nor, ofs, len, SST26_CTL_CHECK); } static int sst_write_byteprogram(struct spi_nor *nor, loff_t to, size_t len, diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 5f5bc650bef..3e9919993d0 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -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--) { @@ -333,6 +342,45 @@ static int axiemac_phy_init(struct udevice *dev) return 0; } +static int pcs_pma_startup(struct axidma_priv *priv) +{ + u32 rc, retry_cnt = 0; + u16 mii_reg; + + rc = phyread(priv, priv->pcsaddr, MII_BMCR, &mii_reg); + if (rc) + goto failed_mdio; + + if (!(mii_reg & BMCR_ANENABLE)) { + mii_reg |= BMCR_ANENABLE; + if (phywrite(priv, priv->pcsaddr, MII_BMCR, mii_reg)) + goto failed_mdio; + } + + /* + * Check the internal PHY status and warn user if the link between it + * and the external PHY is not obtained. + */ + debug("axiemac: waiting for link status of the PCS/PMA PHY"); + while (retry_cnt * 10 < PHY_ANEG_TIMEOUT) { + rc = phyread(priv, priv->pcsaddr, MII_BMSR, &mii_reg); + if ((mii_reg & BMSR_LSTATUS) && mii_reg != 0xffff && !rc) { + debug(".Done\n"); + return 0; + } + if ((retry_cnt++ % 10) == 0) + debug("."); + mdelay(10); + } + debug("\n"); + printf("axiemac: Warning, PCS/PMA PHY@%d is not ready, link is down\n", + priv->pcsaddr); + return 1; +failed_mdio: + printf("axiemac: MDIO to the PCS/PMA PHY has failed\n"); + return 1; +} + /* Setting axi emac and phy to proper setting */ static int setup_phy(struct udevice *dev) { @@ -348,12 +396,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; } @@ -364,6 +412,11 @@ static int setup_phy(struct udevice *dev) phydev->dev->name); return 0; } + if (priv->interface == PHY_INTERFACE_MODE_SGMII || + priv->interface == PHY_INTERFACE_MODE_1000BASEX) { + if (pcs_pma_startup(priv)) + return 0; + } if (!phydev->link) { printf("%s: No link.\n", phydev->dev->name); return 0; @@ -784,6 +837,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 +915,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 +934,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; diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index cfae5dcbda0..d1f89138ef1 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -735,8 +735,7 @@ int cadence_qspi_apb_read_execute(struct cadence_spi_priv *priv, void *buf = op->data.buf.in; size_t len = op->data.nbytes; - if (CONFIG_IS_ENABLED(ARCH_VERSAL)) - cadence_qspi_apb_enable_linear_mode(true); + cadence_qspi_apb_enable_linear_mode(true); if (priv->use_dac_mode && (from + len < priv->ahbsize)) { if (len < 256 || @@ -905,9 +904,6 @@ int cadence_qspi_apb_write_execute(struct cadence_spi_priv *priv, const void *buf = op->data.buf.out; size_t len = op->data.nbytes; - if (CONFIG_IS_ENABLED(ARCH_VERSAL)) - cadence_qspi_apb_enable_linear_mode(true); - /* * Some flashes like the Cypress Semper flash expect a dummy 4-byte * address (all 0s) with the read status register command in DTR mode. diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index 48eff777dfb..335b458cb90 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -94,7 +94,7 @@ #define GQSPI_BAUD_DIV_SHIFT 2 #define GQSPI_LPBK_DLY_ADJ_LPBK_SHIFT 5 -#define GQSPI_LPBK_DLY_ADJ_DLY_1 0x2 +#define GQSPI_LPBK_DLY_ADJ_DLY_1 0x1 #define GQSPI_LPBK_DLY_ADJ_DLY_1_SHIFT 3 #define GQSPI_LPBK_DLY_ADJ_DLY_0 0x3 #define GQSPI_USE_DATA_DLY 0x1 @@ -662,7 +662,7 @@ static int zynqmp_qspi_start_io(struct zynqmp_qspi_priv *priv, static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, u32 gen_fifo_cmd, u32 *buf) { - u32 addr; + unsigned long addr; u32 size; u32 actuallen = priv->len; u32 totallen = priv->len; @@ -678,7 +678,9 @@ static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, totallen -= priv->len; /* Save remaining bytes length to read */ actuallen = priv->len; /* Actual number of bytes reading */ - writel((unsigned long)buf, &dma_regs->dmadst); + writel(lower_32_bits((unsigned long)buf), &dma_regs->dmadst); + writel(upper_32_bits((unsigned long)buf) & GENMASK(11, 0), + &dma_regs->dmadstmsb); writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize); writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); addr = (unsigned long)buf; |