diff options
author | Tom Rini <trini@konsulko.com> | 2021-02-23 10:45:55 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-02-23 10:45:55 -0500 |
commit | cbe607b920bc0827d8fe379ed4f5ae4e2058513e (patch) | |
tree | b8cdbb8856766675f37bb92f27ab9c662fa647f9 | |
parent | 8f7a16aac36c2a38956bd04b53cb7b94b7a70180 (diff) | |
parent | d9aa19efa8a6c20d51b7884de0a7f8dae3f835d2 (diff) | |
download | u-boot-cbe607b920bc0827d8fe379ed4f5ae4e2058513e.tar.gz u-boot-cbe607b920bc0827d8fe379ed4f5ae4e2058513e.tar.xz u-boot-cbe607b920bc0827d8fe379ed4f5ae4e2058513e.zip |
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
-rw-r--r-- | arch/arm/mach-zynqmp/include/mach/hardware.h | 4 | ||||
-rw-r--r-- | board/xilinx/common/board.c | 2 | ||||
-rw-r--r-- | board/xilinx/zynq/board.c | 3 | ||||
l--------- | board/xilinx/zynqmp/zynqmp-zcu1275-revA (renamed from board/xilinx/zynqmp/zynqmp-zc1275-revA) | 0 | ||||
-rw-r--r-- | board/xilinx/zynqmp/zynqmp-zcu1275-revB/psu_init_gpl.c (renamed from board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c) | 0 | ||||
-rw-r--r-- | board/xilinx/zynqmp/zynqmp.c | 7 | ||||
-rw-r--r-- | drivers/clk/clk_versal.c | 11 | ||||
-rw-r--r-- | drivers/clk/clk_zynq.c | 10 | ||||
-rw-r--r-- | drivers/clk/clk_zynqmp.c | 49 | ||||
-rw-r--r-- | drivers/fpga/zynqpl.c | 2 | ||||
-rw-r--r-- | drivers/i2c/i2c-cdns.c | 7 | ||||
-rw-r--r-- | drivers/mmc/zynq_sdhci.c | 2 | ||||
-rw-r--r-- | drivers/net/zynq_gem.c | 47 | ||||
-rw-r--r-- | drivers/serial/serial_zynq.c | 2 | ||||
-rw-r--r-- | drivers/spi/zynq_qspi.c | 2 | ||||
-rw-r--r-- | drivers/spi/zynq_spi.c | 2 | ||||
-rw-r--r-- | drivers/spi/zynqmp_gqspi.c | 189 | ||||
-rw-r--r-- | drivers/watchdog/xilinx_wwdt.c | 3 |
18 files changed, 208 insertions, 134 deletions
diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h index b328837c69..3d3c48e247 100644 --- a/arch/arm/mach-zynqmp/include/mach/hardware.h +++ b/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]; diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 4a83d93a85..475628b925 100644 --- a/board/xilinx/common/board.c +++ b/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) diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 49ff3f0dc0..7533dddb9b 100644 --- a/board/xilinx/zynq/board.c +++ b/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; } diff --git a/board/xilinx/zynqmp/zynqmp-zc1275-revA b/board/xilinx/zynqmp/zynqmp-zcu1275-revA index 7abf1dc462..7abf1dc462 120000 --- a/board/xilinx/zynqmp/zynqmp-zc1275-revA +++ b/board/xilinx/zynqmp/zynqmp-zcu1275-revA diff --git a/board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c b/board/xilinx/zynqmp/zynqmp-zcu1275-revB/psu_init_gpl.c index d3eb713e9e..d3eb713e9e 100644 --- a/board/xilinx/zynqmp/zynqmp-zc1275-revB/psu_init_gpl.c +++ b/board/xilinx/zynqmp/zynqmp-zcu1275-revB/psu_init_gpl.c diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 43e322f715..4466717ad4 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/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) diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index 908bc7519c..62523d2909 100644 --- a/drivers/clk/clk_versal.c +++ b/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[] = { diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index 3e3320900d..18915c3e04 100644 --- a/drivers/clk/clk_zynq.c +++ b/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) diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index e8acca0066..609d8e3b2f 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/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[] = { diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index a11e485525..2de40109a8 100644 --- a/drivers/fpga/zynqpl.c +++ b/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); diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index db3c04fa6e..a650dd69b8 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/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; } diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index d9ad0ff199..b79c4021b6 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/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; } diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 5cb02bb3a7..baf06a2ad8 100644 --- a/drivers/net/zynq_gem.c +++ b/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(®s->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" }, diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index 2883e2466f..799d524047 100644 --- a/drivers/serial/serial_zynq.c +++ b/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; } diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 3d829bcb73..cf6da5340a 100644 --- a/drivers/spi/zynq_qspi.c +++ b/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; } diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c index 52b8fbc874..b3e0858eb9 100644 --- a/drivers/spi/zynq_spi.c +++ b/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; } diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index f669974af1..f8d13d193e 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/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(®s->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, ®s->confr); - zynqmp_qspi_set_tapdelay(bus, baud_rate_val); - debug("regs=%p, speed=%d\n", priv->regs, plat->speed_hz); + confr = readl(®s->confr); + confr &= ~GQSPI_BAUD_DIV_MASK; + confr |= (baud_rate_val << 3); + writel(confr, ®s->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[] = { diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c index 9137d87697..11b30ae85d 100644 --- a/drivers/watchdog/xilinx_wwdt.c +++ b/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; } |