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 -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCYDUezQAKCRDKSWXLKUoM IbtgAJ9jZ+BOtwFaHR19TENC2DsHTINnnwCfSDn3fU0OFJRI0HD7pRxXr4xrb3M= =Kr8x -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
cbe607b920
@ -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];
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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[] = {
|
||||
|
@ -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)
|
||||
|
@ -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[] = {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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" },
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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[] = {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user