mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
spi: fsl_qspi: Add controller busy check before new spi operation
It is recommended to check either controller is free to take new spi action. The IP_ACC and AHB_ACC bits indicates that the controller is busy in IP or AHB mode respectively. And the BUSY bit indicates that controller is currently busy handling a transaction to an external flash device Signed-off-by: Suresh Gupta <suresh.gupta@nxp.com> Reviewed-by: Jagan Teki <jagan@openedev.com>
This commit is contained in:
parent
994266bdff
commit
1c631da459
2 changed files with 31 additions and 1 deletions
|
@ -14,6 +14,7 @@
|
|||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <watchdog.h>
|
||||
#include <wait_bit.h>
|
||||
#include "fsl_qspi.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
@ -991,7 +992,7 @@ static int fsl_qspi_probe(struct udevice *bus)
|
|||
struct fsl_qspi_platdata *plat = dev_get_platdata(bus);
|
||||
struct fsl_qspi_priv *priv = dev_get_priv(bus);
|
||||
struct dm_spi_bus *dm_spi_bus;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
dm_spi_bus = bus->uclass_priv;
|
||||
|
||||
|
@ -1011,6 +1012,18 @@ static int fsl_qspi_probe(struct udevice *bus)
|
|||
priv->flash_num = plat->flash_num;
|
||||
priv->num_chipselect = plat->num_chipselect;
|
||||
|
||||
/* make sure controller is not busy anywhere */
|
||||
ret = wait_for_bit(__func__, &priv->regs->sr,
|
||||
QSPI_SR_BUSY_MASK |
|
||||
QSPI_SR_AHB_ACC_MASK |
|
||||
QSPI_SR_IP_ACC_MASK,
|
||||
false, 100, false);
|
||||
|
||||
if (ret) {
|
||||
debug("ERROR : The controller is busy\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
mcr_val = qspi_read32(priv->flags, &priv->regs->mcr);
|
||||
qspi_write32(priv->flags, &priv->regs->mcr,
|
||||
QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK |
|
||||
|
@ -1156,10 +1169,23 @@ static int fsl_qspi_claim_bus(struct udevice *dev)
|
|||
struct fsl_qspi_priv *priv;
|
||||
struct udevice *bus;
|
||||
struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
|
||||
int ret;
|
||||
|
||||
bus = dev->parent;
|
||||
priv = dev_get_priv(bus);
|
||||
|
||||
/* make sure controller is not busy anywhere */
|
||||
ret = wait_for_bit(__func__, &priv->regs->sr,
|
||||
QSPI_SR_BUSY_MASK |
|
||||
QSPI_SR_AHB_ACC_MASK |
|
||||
QSPI_SR_IP_ACC_MASK,
|
||||
false, 100, false);
|
||||
|
||||
if (ret) {
|
||||
debug("ERROR : The controller is busy\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv->cur_amba_base = priv->amba_base[slave_plat->cs];
|
||||
|
||||
qspi_module_disable(priv, 0);
|
||||
|
|
|
@ -105,6 +105,10 @@ struct fsl_qspi_regs {
|
|||
#define QSPI_RBCT_RXBRD_SHIFT 8
|
||||
#define QSPI_RBCT_RXBRD_USEIPS (1 << QSPI_RBCT_RXBRD_SHIFT)
|
||||
|
||||
#define QSPI_SR_AHB_ACC_SHIFT 2
|
||||
#define QSPI_SR_AHB_ACC_MASK (1 << QSPI_SR_AHB_ACC_SHIFT)
|
||||
#define QSPI_SR_IP_ACC_SHIFT 1
|
||||
#define QSPI_SR_IP_ACC_MASK (1 << QSPI_SR_IP_ACC_SHIFT)
|
||||
#define QSPI_SR_BUSY_SHIFT 0
|
||||
#define QSPI_SR_BUSY_MASK (1 << QSPI_SR_BUSY_SHIFT)
|
||||
|
||||
|
|
Loading…
Reference in a new issue