瀏覽代碼

Merge tag 'xilinx-for-v2021.04-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze

Xilinx changes for v2021.04-rc3

qspi:
- Support for dual/quad mode
- Fix speed handling

clk:
- Add clock enable function for zynq/zynqmp/versal

gem:
- Enable clock for Versal
- Fix error path
- Fix mdio deregistration path

fpga:
- Fix buffer alignment for ZynqMP

xilinx:
- Fix reset reason clearing in ZynqMP
- Show silicon version in SPL for Zynq/ZynqMP
- Fix DTB selection for ZynqMP
- Rename zc1275 to zcu1275 to match DT name
Tom Rini 3 年之前
父節點
當前提交
cbe607b920

+ 2 - 2
arch/arm/mach-zynqmp/include/mach/hardware.h

@@ -128,8 +128,8 @@ struct apu_regs {
 
 #define ZYNQMP_CSU_VERSION_EMPTY_SHIFT		20
 
-#define ZYNQMP_SILICON_VER_MASK		0xF000
-#define ZYNQMP_SILICON_VER_SHIFT	12
+#define ZYNQMP_SILICON_VER_MASK		0xF
+#define ZYNQMP_SILICON_VER_SHIFT	0
 
 struct csu_regs {
 	u32 reserved0[4];

+ 1 - 1
board/xilinx/common/board.c

@@ -327,7 +327,7 @@ void *board_fdt_blob_setup(void)
 
 	if (!IS_ENABLED(CONFIG_SPL_BUILD) &&
 	    !IS_ENABLED(CONFIG_VERSAL_NO_DDR) &&
-	    !IS_ENABLED(CONFIG_VERSAL_NO_DDR)) {
+	    !IS_ENABLED(CONFIG_ZYNQMP_NO_DDR)) {
 		fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR;
 
 		if (fdt_magic(fdt_blob) == FDT_MAGIC)

+ 3 - 0
board/xilinx/zynq/board.c

@@ -25,6 +25,9 @@ DECLARE_GLOBAL_DATA_PTR;
 
 int board_init(void)
 {
+	if (IS_ENABLED(CONFIG_SPL_BUILD))
+		printf("Silicon version:\t%d\n", zynq_get_silicon_version());
+
 	return 0;
 }
 

+ 0 - 0
board/xilinx/zynqmp/zynqmp-zc1275-revA → board/xilinx/zynqmp/zynqmp-zcu1275-revA


+ 0 - 0
board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c → board/xilinx/zynqmp/zynqmp-zcu1275-revB/psu_init_gpl.c


+ 2 - 5
board/xilinx/zynqmp/zynqmp.c

@@ -329,6 +329,7 @@ int board_init(void)
 	if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1)
 		zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj,
 						zynqmp_pm_cfg_obj_size);
+	printf("Silicon version:\t%d\n", zynqmp_get_silicon_version());
 #else
 	if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM))
 		xilinx_read_eeprom();
@@ -496,11 +497,7 @@ static int reset_reason(void)
 
 	env_set("reset_reason", reason);
 
-	ret = zynqmp_mmio_write((ulong)&crlapb_base->reset_reason, ~0, ~0);
-	if (ret)
-		return -EINVAL;
-
-	return ret;
+	return 0;
 }
 
 static int set_fdtfile(void)

+ 11 - 0
drivers/clk/clk_versal.c

@@ -718,9 +718,20 @@ static ulong versal_clk_set_rate(struct clk *clk, ulong rate)
 	return clk_rate;
 }
 
+static int versal_clk_enable(struct clk *clk)
+{
+	struct versal_clk_priv *priv = dev_get_priv(clk->dev);
+	u32 clk_id;
+
+	clk_id = priv->clk[clk->id].clk_id;
+
+	return xilinx_pm_request(PM_CLOCK_ENABLE, clk_id, 0, 0, 0, NULL);
+}
+
 static struct clk_ops versal_clk_ops = {
 	.set_rate = versal_clk_set_rate,
 	.get_rate = versal_clk_get_rate,
+	.enable = versal_clk_enable,
 };
 
 static const struct udevice_id versal_clk_ids[] = {

+ 10 - 0
drivers/clk/clk_zynq.c

@@ -445,11 +445,21 @@ static ulong zynq_clk_get_rate(struct clk *clk)
 }
 #endif
 
+static int dummy_enable(struct clk *clk)
+{
+	/*
+	 * Add implementation but by default all clocks are enabled
+	 * after power up which is only one supported case now.
+	 */
+	return 0;
+}
+
 static struct clk_ops zynq_clk_ops = {
 	.get_rate = zynq_clk_get_rate,
 #ifndef CONFIG_SPL_BUILD
 	.set_rate = zynq_clk_set_rate,
 #endif
+	.enable = dummy_enable,
 };
 
 static int zynq_clk_probe(struct udevice *dev)

+ 49 - 0
drivers/clk/clk_zynqmp.c

@@ -199,6 +199,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
 		return CRF_APB_DDR_CTRL;
 	case qspi_ref:
 		return CRL_APB_QSPI_REF_CTRL;
+	case usb3_dual_ref:
+		return CRL_APB_USB3_DUAL_REF_CTRL;
 	case gem0_ref:
 		return CRL_APB_GEM0_REF_CTRL;
 	case gem1_ref:
@@ -207,6 +209,10 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
 		return CRL_APB_GEM2_REF_CTRL;
 	case gem3_ref:
 		return CRL_APB_GEM3_REF_CTRL;
+	case usb0_bus_ref:
+		return CRL_APB_USB0_BUS_REF_CTRL;
+	case usb1_bus_ref:
+		return CRL_APB_USB1_BUS_REF_CTRL;
 	case uart0_ref:
 		return CRL_APB_UART0_REF_CTRL;
 	case uart1_ref:
@@ -699,9 +705,52 @@ static int zynqmp_clk_probe(struct udevice *dev)
 	return 0;
 }
 
+static int zynqmp_clk_enable(struct clk *clk)
+{
+	enum zynqmp_clk id = clk->id;
+	u32 reg, clk_ctrl, clkact_shift, mask;
+	int ret;
+
+	reg = zynqmp_clk_get_register(id);
+	debug("%s, clk_id:%x, clk_base:0x%x\n", __func__, id, reg);
+
+	switch (id) {
+	case usb0_bus_ref ... usb1:
+		clkact_shift = 25;
+		mask = 0x1;
+		break;
+	case gem0_ref ... gem3_ref:
+		clkact_shift = 25;
+		mask = 0x3;
+		break;
+	case qspi_ref ... can1_ref:
+		clkact_shift = 24;
+		mask = 0x1;
+		break;
+	default:
+		return -ENXIO;
+	}
+
+	ret = zynqmp_mmio_read(reg, &clk_ctrl);
+	if (ret) {
+		printf("%s mio read fail\n", __func__);
+		return -EIO;
+	}
+
+	clk_ctrl |= (mask << clkact_shift);
+	ret = zynqmp_mmio_write(reg, mask << clkact_shift, clk_ctrl);
+	if (ret) {
+		printf("%s mio write fail\n", __func__);
+		return -EIO;
+	}
+
+	return ret;
+}
+
 static struct clk_ops zynqmp_clk_ops = {
 	.set_rate = zynqmp_clk_set_rate,
 	.get_rate = zynqmp_clk_get_rate,
+	.enable = zynqmp_clk_enable,
 };
 
 static const struct udevice_id zynqmp_clk_ids[] = {

+ 1 - 1
drivers/fpga/zynqpl.c

@@ -315,7 +315,7 @@ static u32 *zynq_align_dma_buffer(u32 *buf, u32 len, u32 swap)
 		if (new_buf > buf) {
 			debug("%s: Aligned buffer is after buffer start\n",
 			      __func__);
-			new_buf -= ARCH_DMA_MINALIGN;
+			new_buf = (u32 *)((u32)new_buf - ARCH_DMA_MINALIGN);
 		}
 		printf("%s: Align buffer at %x to %x(swap %d)\n", __func__,
 		       (u32)buf, (u32)new_buf, swap);

+ 7 - 0
drivers/i2c/i2c-cdns.c

@@ -15,6 +15,7 @@
 #include <linux/types.h>
 #include <linux/io.h>
 #include <linux/errno.h>
+#include <dm/device_compat.h>
 #include <dm/root.h>
 #include <i2c.h>
 #include <fdtdec.h>
@@ -481,6 +482,12 @@ static int cdns_i2c_of_to_plat(struct udevice *dev)
 
 	i2c_bus->input_freq = clk_get_rate(&clk);
 
+	ret = clk_enable(&clk);
+	if (ret) {
+		dev_err(dev, "failed to enable clock\n");
+		return ret;
+	}
+
 	return 0;
 }
 

+ 1 - 1
drivers/mmc/zynq_sdhci.c

@@ -577,7 +577,7 @@ static int arasan_sdhci_probe(struct udevice *dev)
 	debug("%s: CLK %ld\n", __func__, clock);
 
 	ret = clk_enable(&clk);
-	if (ret && ret != -ENOSYS) {
+	if (ret) {
 		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}

+ 35 - 12
drivers/net/zynq_gem.c

@@ -129,6 +129,8 @@
 #define ZYNQ_GEM_FREQUENCY_100	25000000UL
 #define ZYNQ_GEM_FREQUENCY_1000	125000000UL
 
+#define RXCLK_EN		BIT(0)
+
 /* Device registers */
 struct zynq_gem_regs {
 	u32 nwctrl; /* 0x0 - Network Control reg */
@@ -205,10 +207,12 @@ struct zynq_gem_priv {
 	struct phy_device *phydev;
 	ofnode phy_of_node;
 	struct mii_dev *bus;
-	struct clk clk;
+	struct clk rx_clk;
+	struct clk tx_clk;
 	u32 max_speed;
 	bool int_pcs;
 	bool dma_64bit;
+	u32 clk_en_info;
 };
 
 static int phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
@@ -476,18 +480,25 @@ static int zynq_gem_init(struct udevice *dev)
 		break;
 	}
 
-	ret = clk_set_rate(&priv->clk, clk_rate);
-	if (IS_ERR_VALUE(ret) && ret != (unsigned long)-ENOSYS) {
+	ret = clk_set_rate(&priv->tx_clk, clk_rate);
+	if (IS_ERR_VALUE(ret)) {
 		dev_err(dev, "failed to set tx clock rate\n");
 		return ret;
 	}
 
-	ret = clk_enable(&priv->clk);
-	if (ret && ret != -ENOSYS) {
+	ret = clk_enable(&priv->tx_clk);
+	if (ret) {
 		dev_err(dev, "failed to enable tx clock\n");
 		return ret;
 	}
 
+	if (priv->clk_en_info & RXCLK_EN) {
+		ret = clk_enable(&priv->rx_clk);
+		if (ret) {
+			dev_err(dev, "failed to enable rx clock\n");
+			return ret;
+		}
+	}
 	setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK |
 					ZYNQ_GEM_NWCTRL_TXEN_MASK);
 
@@ -694,10 +705,18 @@ static int zynq_gem_probe(struct udevice *dev)
 	priv->tx_bd = (struct emac_bd *)bd_space;
 	priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE);
 
-	ret = clk_get_by_name(dev, "tx_clk", &priv->clk);
+	ret = clk_get_by_name(dev, "tx_clk", &priv->tx_clk);
 	if (ret < 0) {
-		dev_err(dev, "failed to get clock\n");
-		goto err1;
+		dev_err(dev, "failed to get tx_clock\n");
+		goto err2;
+	}
+
+	if (priv->clk_en_info & RXCLK_EN) {
+		ret = clk_get_by_name(dev, "rx_clk", &priv->rx_clk);
+		if (ret < 0) {
+			dev_err(dev, "failed to get rx_clock\n");
+			goto err2;
+		}
 	}
 
 	priv->bus = mdio_alloc();
@@ -711,14 +730,16 @@ static int zynq_gem_probe(struct udevice *dev)
 
 	ret = zynq_phy_init(dev);
 	if (ret)
-		goto err2;
+		goto err3;
 
 	return ret;
 
+err3:
+	mdio_unregister(priv->bus);
 err2:
-	free(priv->rxbuffers);
-err1:
 	free(priv->tx_bd);
+err1:
+	free(priv->rxbuffers);
 	return ret;
 }
 
@@ -792,11 +813,13 @@ static int zynq_gem_of_to_plat(struct udevice *dev)
 	       (ulong)priv->iobase, (ulong)priv->mdiobase, priv->phyaddr,
 	       phy_string_for_interface(priv->interface));
 
+	priv->clk_en_info = dev_get_driver_data(dev);
+
 	return 0;
 }
 
 static const struct udevice_id zynq_gem_ids[] = {
-	{ .compatible = "cdns,versal-gem" },
+	{ .compatible = "cdns,versal-gem", .data = RXCLK_EN },
 	{ .compatible = "cdns,zynqmp-gem" },
 	{ .compatible = "cdns,zynq-gem" },
 	{ .compatible = "cdns,gem" },

+ 1 - 1
drivers/serial/serial_zynq.c

@@ -127,7 +127,7 @@ static int zynq_serial_setbrg(struct udevice *dev, int baudrate)
 	debug("%s: CLK %ld\n", __func__, clock);
 
 	ret = clk_enable(&clk);
-	if (ret && ret != -ENOSYS) {
+	if (ret) {
 		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}

+ 1 - 1
drivers/spi/zynq_qspi.c

@@ -194,7 +194,7 @@ static int zynq_qspi_probe(struct udevice *bus)
 	}
 
 	ret = clk_enable(&clk);
-	if (ret && ret != -ENOSYS) {
+	if (ret) {
 		dev_err(bus, "failed to enable clock\n");
 		return ret;
 	}

+ 1 - 1
drivers/spi/zynq_spi.c

@@ -144,7 +144,7 @@ static int zynq_spi_probe(struct udevice *bus)
 	}
 
 	ret = clk_enable(&clk);
-	if (ret && ret != -ENOSYS) {
+	if (ret) {
 		dev_err(bus, "failed to enable clock\n");
 		return ret;
 	}

+ 82 - 107
drivers/spi/zynqmp_gqspi.c

@@ -17,6 +17,7 @@
 #include <malloc.h>
 #include <memalign.h>
 #include <spi.h>
+#include <spi-mem.h>
 #include <ubi_uboot.h>
 #include <wait_bit.h>
 #include <dm/device_compat.h>
@@ -172,8 +173,7 @@ struct zynqmp_qspi_priv {
 	unsigned int len;
 	int bytes_to_transfer;
 	int bytes_to_receive;
-	unsigned int is_inst;
-	unsigned int cs_change:1;
+	const struct spi_mem_op *op;
 };
 
 static int zynqmp_qspi_of_to_plat(struct udevice *bus)
@@ -222,6 +222,21 @@ static u32 zynqmp_qspi_bus_select(struct zynqmp_qspi_priv *priv)
 	return gqspi_fifo_reg;
 }
 
+static u32 zynqmp_qspi_genfifo_mode(u8 buswidth)
+{
+	switch (buswidth) {
+	case 1:
+		return GQSPI_SPI_MODE_SPI;
+	case 2:
+		return GQSPI_SPI_MODE_DUAL_SPI;
+	case 4:
+		return GQSPI_SPI_MODE_QSPI;
+	default:
+		debug("Unsupported bus width %u\n", buswidth);
+		return GQSPI_SPI_MODE_SPI;
+	}
+}
+
 static void zynqmp_qspi_fill_gen_fifo(struct zynqmp_qspi_priv *priv,
 				      u32 gqspi_fifo_reg)
 {
@@ -306,12 +321,9 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, uint speed)
 	if (speed > plat->frequency)
 		speed = plat->frequency;
 
-	/* Set the clock frequency */
-	confr = readl(&regs->confr);
-	if (speed == 0) {
-		/* Set baudrate x8, if the freq is 0 */
-		baud_rate_val = GQSPI_DFLT_BAUD_RATE_VAL;
-	} else if (plat->speed_hz != speed) {
+	if (plat->speed_hz != speed) {
+		/* Set the clock frequency */
+		/* If speed == 0, default to lowest speed */
 		while ((baud_rate_val < 8) &&
 		       ((plat->frequency /
 		       (2 << baud_rate_val)) > speed))
@@ -321,13 +333,15 @@ static int zynqmp_qspi_set_speed(struct udevice *bus, uint speed)
 			baud_rate_val = GQSPI_DFLT_BAUD_RATE_VAL;
 
 		plat->speed_hz = plat->frequency / (2 << baud_rate_val);
-	}
-	confr &= ~GQSPI_BAUD_DIV_MASK;
-	confr |= (baud_rate_val << 3);
-	writel(confr, &regs->confr);
 
-	zynqmp_qspi_set_tapdelay(bus, baud_rate_val);
-	debug("regs=%p, speed=%d\n", priv->regs, plat->speed_hz);
+		confr = readl(&regs->confr);
+		confr &= ~GQSPI_BAUD_DIV_MASK;
+		confr |= (baud_rate_val << 3);
+		writel(confr, &regs->confr);
+		zynqmp_qspi_set_tapdelay(bus, baud_rate_val);
+
+		debug("regs=%p, speed=%d\n", priv->regs, plat->speed_hz);
+	}
 
 	return 0;
 }
@@ -359,7 +373,7 @@ static int zynqmp_qspi_probe(struct udevice *bus)
 	debug("%s: CLK %ld\n", __func__, clock);
 
 	ret = clk_enable(&clk);
-	if (ret && ret != -ENOSYS) {
+	if (ret) {
 		dev_err(bus, "failed to enable clock\n");
 		return ret;
 	}
@@ -446,21 +460,42 @@ static int zynqmp_qspi_fill_tx_fifo(struct zynqmp_qspi_priv *priv, u32 size)
 
 static void zynqmp_qspi_genfifo_cmd(struct zynqmp_qspi_priv *priv)
 {
+	const struct spi_mem_op *op = priv->op;
 	u32 gen_fifo_cmd;
-	u32 bytecount = 0;
+	u8 i, dummy_cycles, addr;
+
+	/* Send opcode */
+	gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+	gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(op->cmd.buswidth);
+	gen_fifo_cmd |= GQSPI_GFIFO_TX;
+	gen_fifo_cmd |= op->cmd.opcode;
+	zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
+
+	/* Send address */
+	for (i = 0; i < op->addr.nbytes; i++) {
+		addr = op->addr.val >> (8 * (op->addr.nbytes - i - 1));
 
-	while (priv->len) {
 		gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
-		gen_fifo_cmd |= GQSPI_GFIFO_TX | GQSPI_SPI_MODE_SPI;
-		gen_fifo_cmd |= *(u8 *)priv->tx_buf;
-		bytecount++;
-		priv->len--;
-		priv->tx_buf = (u8 *)priv->tx_buf + 1;
+		gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(op->addr.buswidth);
+		gen_fifo_cmd |= GQSPI_GFIFO_TX;
+		gen_fifo_cmd |= addr;
 
 		debug("GFIFO_CMD_Cmd = 0x%x\n", gen_fifo_cmd);
 
 		zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
 	}
+
+	/* Send dummy */
+	if (op->dummy.nbytes) {
+		dummy_cycles = op->dummy.nbytes * 8 / op->dummy.buswidth;
+
+		gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+		gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(op->dummy.buswidth);
+		gen_fifo_cmd &= ~(GQSPI_GFIFO_TX | GQSPI_GFIFO_RX);
+		gen_fifo_cmd |= GQSPI_GFIFO_DATA_XFR_MASK;
+		gen_fifo_cmd |= dummy_cycles;
+		zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
+	}
 }
 
 static u32 zynqmp_qspi_calc_exp(struct zynqmp_qspi_priv *priv,
@@ -497,11 +532,10 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv)
 	int ret = 0;
 
 	gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+	gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
 	gen_fifo_cmd |= GQSPI_GFIFO_TX |
 			GQSPI_GFIFO_DATA_XFR_MASK;
 
-	gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;
-
 	while (priv->len) {
 		len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd);
 		zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd);
@@ -575,11 +609,10 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv)
 	u32 actuallen = priv->len;
 
 	gen_fifo_cmd = zynqmp_qspi_bus_select(priv);
+	gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth);
 	gen_fifo_cmd |= GQSPI_GFIFO_RX |
 			GQSPI_GFIFO_DATA_XFR_MASK;
 
-	gen_fifo_cmd |= GQSPI_SPI_MODE_SPI;
-
 	/*
 	 * Check if receive buffer is aligned to 4 byte and length
 	 * is multiples of four byte as we are using dma to receive.
@@ -596,62 +629,6 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv)
 	return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf);
 }
 
-static int zynqmp_qspi_start_transfer(struct zynqmp_qspi_priv *priv)
-{
-	int ret = 0;
-
-	if (priv->is_inst) {
-		if (priv->tx_buf)
-			zynqmp_qspi_genfifo_cmd(priv);
-		else
-			return -EINVAL;
-	} else {
-		if (priv->tx_buf)
-			ret = zynqmp_qspi_genfifo_fill_tx(priv);
-		else if (priv->rx_buf)
-			ret = zynqmp_qspi_genfifo_fill_rx(priv);
-		else
-			return -EINVAL;
-	}
-	return ret;
-}
-
-static int zynqmp_qspi_transfer(struct zynqmp_qspi_priv *priv)
-{
-	static unsigned int cs_change = 1;
-	int status = 0;
-
-	debug("%s\n", __func__);
-
-	while (1) {
-		/* Select the chip if required */
-		if (cs_change)
-			zynqmp_qspi_chipselect(priv, 1);
-
-		cs_change = priv->cs_change;
-
-		if (!priv->tx_buf && !priv->rx_buf && priv->len) {
-			status = -EINVAL;
-			break;
-		}
-
-		/* Request the transfer */
-		if (priv->len) {
-			status = zynqmp_qspi_start_transfer(priv);
-			priv->is_inst = 0;
-			if (status < 0)
-				break;
-		}
-
-		if (cs_change)
-			/* Deselect the chip */
-			zynqmp_qspi_chipselect(priv, 0);
-		break;
-	}
-
-	return status;
-}
-
 static int zynqmp_qspi_claim_bus(struct udevice *dev)
 {
 	struct udevice *bus = dev->parent;
@@ -674,45 +651,43 @@ static int zynqmp_qspi_release_bus(struct udevice *dev)
 	return 0;
 }
 
-int zynqmp_qspi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout,
-		     void *din, unsigned long flags)
+static int zynqmp_qspi_exec_op(struct spi_slave *slave,
+			       const struct spi_mem_op *op)
 {
-	struct udevice *bus = dev->parent;
-	struct zynqmp_qspi_priv *priv = dev_get_priv(bus);
+	struct zynqmp_qspi_priv *priv = dev_get_priv(slave->dev->parent);
+	int ret = 0;
 
-	debug("%s: priv: 0x%08lx bitlen: %d dout: 0x%08lx ", __func__,
-	      (unsigned long)priv, bitlen, (unsigned long)dout);
-	debug("din: 0x%08lx flags: 0x%lx\n", (unsigned long)din, flags);
+	priv->op = op;
+	priv->tx_buf = op->data.buf.out;
+	priv->rx_buf = op->data.buf.in;
+	priv->len = op->data.nbytes;
 
-	priv->tx_buf = dout;
-	priv->rx_buf = din;
-	priv->len = bitlen / 8;
+	zynqmp_qspi_chipselect(priv, 1);
 
-	/*
-	 * Assume that the beginning of a transfer with bits to
-	 * transmit must contain a device command.
-	 */
-	if (dout && flags & SPI_XFER_BEGIN)
-		priv->is_inst = 1;
-	else
-		priv->is_inst = 0;
+	/* Send opcode, addr, dummy */
+	zynqmp_qspi_genfifo_cmd(priv);
 
-	if (flags & SPI_XFER_END)
-		priv->cs_change = 1;
-	else
-		priv->cs_change = 0;
+	/* Request the transfer */
+	if (op->data.dir == SPI_MEM_DATA_IN)
+		ret = zynqmp_qspi_genfifo_fill_rx(priv);
+	else if (op->data.dir == SPI_MEM_DATA_OUT)
+		ret = zynqmp_qspi_genfifo_fill_tx(priv);
 
-	zynqmp_qspi_transfer(priv);
+	zynqmp_qspi_chipselect(priv, 0);
 
-	return 0;
+	return ret;
 }
 
+static const struct spi_controller_mem_ops zynqmp_qspi_mem_ops = {
+	.exec_op = zynqmp_qspi_exec_op,
+};
+
 static const struct dm_spi_ops zynqmp_qspi_ops = {
 	.claim_bus      = zynqmp_qspi_claim_bus,
 	.release_bus    = zynqmp_qspi_release_bus,
-	.xfer           = zynqmp_qspi_xfer,
 	.set_speed      = zynqmp_qspi_set_speed,
 	.set_mode       = zynqmp_qspi_set_mode,
+	.mem_ops        = &zynqmp_qspi_mem_ops,
 };
 
 static const struct udevice_id zynqmp_qspi_ids[] = {

+ 1 - 2
drivers/watchdog/xilinx_wwdt.c

@@ -90,9 +90,8 @@ static int xlnx_wwdt_start(struct udevice *dev, u64 timeout, ulong flags)
 	/* Calculate timeout count */
 	count = timeout * clock_f;
 
-	/* clk_enable will return -ENOSYS when it is not implemented */
 	ret = clk_enable(&wdt->clk);
-	if (ret && ret != -ENOSYS) {
+	if (ret) {
 		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}