summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2022-12-05 16:33:19 +0300
committerTom Rini <trini@konsulko.com>2022-12-05 16:33:19 +0300
commita50622d78c5c6babd1853ae913f339df54fe532c (patch)
treed9983965f00679f68b5a12cbc2dbc5dd64aafc4d /drivers
parentbdaf047f51eda655f3d6bc9d076696f7733a57d8 (diff)
parent7ad3c09e7911e71c9a16a30aa052093a8f9b7e7c (diff)
downloadu-boot-a50622d78c5c6babd1853ae913f339df54fe532c.tar.xz
Merge tag 'xilinx-for-v2023.01-rc3-v2' of https://source.denx.de/u-boot/custodians/u-boot-microblaze
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.c2
-rw-r--r--drivers/net/xilinx_axi_emac.c70
-rw-r--r--drivers/spi/cadence_qspi_apb.c6
-rw-r--r--drivers/spi/zynqmp_gqspi.c8
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 78de3c5281..1ea8363d9f 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 5f5bc650be..3e9919993d 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 cfae5dcbda..d1f89138ef 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 48eff777df..335b458cb9 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;