* [PATCH 2/3 v3] mtd: spi-nor: fsl-quadspi: Enable support big endian registers
@ 2015-06-18 8:59 Haikun Wang
2015-07-06 22:43 ` Brian Norris
0 siblings, 1 reply; 3+ messages in thread
From: Haikun Wang @ 2015-06-18 8:59 UTC (permalink / raw)
To: dwmw2, computersforpeace, linux-mtd, han.xu; +Cc: Haikun Wang
QSPI registers are big endian on LS1021A.
This patch check endianness before accessing register and
swap the data if QSPI register is big endian.
Signed-off-by: Haikun Wang <haikun.wang@freescale.com>
---
Changes in v3:
- Rebase with l2-mtd.git
Changes in v2:
- Fix compile issue
drivers/mtd/spi-nor/fsl-quadspi.c | 139 ++++++++++++++++++++++----------------
1 file changed, 81 insertions(+), 58 deletions(-)
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
index 6cd14e4..dc157f9 100644
--- a/drivers/mtd/spi-nor/fsl-quadspi.c
+++ b/drivers/mtd/spi-nor/fsl-quadspi.c
@@ -191,6 +191,8 @@
#define SEQID_EN4B 10
#define SEQID_BRWR 11
+#define FSL_QSPI_FLAG_REGMAP_BE (1 << 0)
+
enum fsl_qspi_devtype {
FSL_QUADSPI_VYBRID,
FSL_QUADSPI_IMX6SX,
@@ -202,6 +204,7 @@ struct fsl_qspi_devtype_data {
int rxfifo;
int txfifo;
int ahb_buf_size;
+ u32 flags;
};
static struct fsl_qspi_devtype_data vybrid_data = {
@@ -222,7 +225,8 @@ static struct fsl_qspi_devtype_data ls1_data = {
.devtype = FSL_QUADSPI_LS1,
.rxfifo = 128,
.txfifo = 64,
- .ahb_buf_size = 1024
+ .ahb_buf_size = 1024,
+ .flags = FSL_QSPI_FLAG_REGMAP_BE
};
#define FSL_QSPI_MAX_CHIP 4
@@ -253,6 +257,18 @@ static inline int is_imx6sx_qspi(struct fsl_qspi *q)
return q->devtype_data->devtype == FSL_QUADSPI_IMX6SX;
}
+static void qspi_writel(struct fsl_qspi *q, u32 val, void __iomem *addr)
+{
+ q->devtype_data->flags & FSL_QSPI_FLAG_REGMAP_BE ?
+ writel(cpu_to_be32(val), addr) : writel(val, addr);
+}
+
+static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr)
+{
+ return q->devtype_data->flags & FSL_QSPI_FLAG_REGMAP_BE ?
+ cpu_to_be32(readl(addr)) : readl(addr);
+}
+
/*
* An IC bug makes us to re-arrange the 32-bit data.
* The following chips, such as IMX6SLX, have fixed this bug.
@@ -264,14 +280,14 @@ static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a)
static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
{
- writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
- writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
+ qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
+ qspi_writel(q, QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
}
static inline void fsl_qspi_lock_lut(struct fsl_qspi *q)
{
- writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
- writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
+ qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
+ qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
}
static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
@@ -280,8 +296,8 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
u32 reg;
/* clear interrupt */
- reg = readl(q->iobase + QUADSPI_FR);
- writel(reg, q->iobase + QUADSPI_FR);
+ reg = qspi_readl(q, q->iobase + QUADSPI_FR);
+ qspi_writel(q, reg, q->iobase + QUADSPI_FR);
if (reg & QUADSPI_FR_TFF_MASK)
complete(&q->c);
@@ -302,7 +318,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
/* Clear all the LUT table */
for (i = 0; i < QUADSPI_LUT_NUM; i++)
- writel(0, base + QUADSPI_LUT_BASE + i * 4);
+ qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
/* Quad Read */
lut_base = SEQID_QUAD_READ * 4;
@@ -318,14 +334,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
dummy = 8;
}
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
- writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
+ qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
base + QUADSPI_LUT(lut_base + 1));
/* Write enable */
lut_base = SEQID_WREN * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
+ base + QUADSPI_LUT(lut_base));
/* Page Program */
lut_base = SEQID_PP * 4;
@@ -339,13 +356,13 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
addrlen = ADDR32BIT;
}
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
- writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
+ qspi_writel(q, LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
/* Read Status */
lut_base = SEQID_RDSR * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
base + QUADSPI_LUT(lut_base));
/* Erase a sector */
@@ -360,40 +377,43 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
addrlen = ADDR32BIT;
}
- writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
+ qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
base + QUADSPI_LUT(lut_base));
/* Erase the whole chip */
lut_base = SEQID_CHIP_ERASE * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
base + QUADSPI_LUT(lut_base));
/* READ ID */
lut_base = SEQID_RDID * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
base + QUADSPI_LUT(lut_base));
/* Write Register */
lut_base = SEQID_WRSR * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
base + QUADSPI_LUT(lut_base));
/* Read Configuration Register */
lut_base = SEQID_RDCR * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
base + QUADSPI_LUT(lut_base));
/* Write disable */
lut_base = SEQID_WRDI * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
+ base + QUADSPI_LUT(lut_base));
/* Enter 4 Byte Mode (Micron) */
lut_base = SEQID_EN4B * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
+ base + QUADSPI_LUT(lut_base));
/* Enter 4 Byte Mode (Spansion) */
lut_base = SEQID_BRWR * 4;
- writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base));
+ qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
+ base + QUADSPI_LUT(lut_base));
fsl_qspi_lock_lut(q);
}
@@ -446,15 +466,16 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
q->chip_base_addr, addr, len, cmd);
/* save the reg */
- reg = readl(base + QUADSPI_MCR);
+ reg = qspi_readl(q, base + QUADSPI_MCR);
- writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR);
- writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
+ qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
+ base + QUADSPI_SFAR);
+ qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
base + QUADSPI_RBCT);
- writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
+ qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
do {
- reg2 = readl(base + QUADSPI_SR);
+ reg2 = qspi_readl(q, base + QUADSPI_SR);
if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
udelay(1);
dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2);
@@ -465,21 +486,22 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
/* trigger the LUT now */
seqid = fsl_qspi_get_seqid(q, cmd);
- writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR);
+ qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
+ base + QUADSPI_IPCR);
/* Wait for the interrupt. */
if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) {
dev_err(q->dev,
"cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n",
- cmd, addr, readl(base + QUADSPI_FR),
- readl(base + QUADSPI_SR));
+ cmd, addr, qspi_readl(q, base + QUADSPI_FR),
+ qspi_readl(q, base + QUADSPI_SR));
err = -ETIMEDOUT;
} else {
err = 0;
}
/* restore the MCR */
- writel(reg, base + QUADSPI_MCR);
+ qspi_writel(q, reg, base + QUADSPI_MCR);
return err;
}
@@ -491,7 +513,7 @@ static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf)
int i = 0;
while (len > 0) {
- tmp = readl(q->iobase + QUADSPI_RBDR + i * 4);
+ tmp = qspi_readl(q, q->iobase + QUADSPI_RBDR + i * 4);
tmp = fsl_qspi_endian_xchg(q, tmp);
dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n",
q->chip_base_addr, tmp);
@@ -519,9 +541,9 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
{
u32 reg;
- reg = readl(q->iobase + QUADSPI_MCR);
+ reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK;
- writel(reg, q->iobase + QUADSPI_MCR);
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
/*
* The minimum delay : 1 AHB + 2 SFCK clocks.
@@ -530,7 +552,7 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
udelay(1);
reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK);
- writel(reg, q->iobase + QUADSPI_MCR);
+ qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
}
static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
@@ -544,13 +566,13 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
q->chip_base_addr, to, count);
/* clear the TX FIFO. */
- tmp = readl(q->iobase + QUADSPI_MCR);
- writel(tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
+ tmp = qspi_readl(q, q->iobase + QUADSPI_MCR);
+ qspi_writel(q, tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
/* fill the TX data to the FIFO */
for (j = 0, i = ((count + 3) / 4); j < i; j++) {
tmp = fsl_qspi_endian_xchg(q, *txbuf);
- writel(tmp, q->iobase + QUADSPI_TBDR);
+ qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
txbuf++;
}
@@ -568,10 +590,10 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
int nor_size = q->nor_size;
void __iomem *base = q->iobase;
- writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
- writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
- writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
- writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
+ qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
+ qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
+ qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
+ qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
}
/*
@@ -593,24 +615,25 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
int seqid;
/* AHB configuration for access buffer 0/1/2 .*/
- writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
- writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
- writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
+ qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
+ qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
+ qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
/*
* Set ADATSZ with the maximum AHB buffer size to improve the
* read performance.
*/
- writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8)
- << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
+ qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
+ ((q->devtype_data->ahb_buf_size / 8)
+ << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
/* We only use the buffer3 */
- writel(0, base + QUADSPI_BUF0IND);
- writel(0, base + QUADSPI_BUF1IND);
- writel(0, base + QUADSPI_BUF2IND);
+ qspi_writel(q, 0, base + QUADSPI_BUF0IND);
+ qspi_writel(q, 0, base + QUADSPI_BUF1IND);
+ qspi_writel(q, 0, base + QUADSPI_BUF2IND);
/* Set the default lut sequence for AHB Read. */
seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
- writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
+ qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
q->iobase + QUADSPI_BFGENCR);
}
@@ -630,21 +653,21 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
fsl_qspi_init_lut(q);
/* Disable the module */
- writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
+ qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
base + QUADSPI_MCR);
- reg = readl(base + QUADSPI_SMPR);
- writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK
+ reg = qspi_readl(q, base + QUADSPI_SMPR);
+ qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
| QUADSPI_SMPR_FSPHS_MASK
| QUADSPI_SMPR_HSENA_MASK
| QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
/* Enable the module */
- writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
+ qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
base + QUADSPI_MCR);
/* enable the interrupt */
- writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
+ qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
return 0;
}
@@ -979,8 +1002,8 @@ static int fsl_qspi_remove(struct platform_device *pdev)
}
/* disable the hardware */
- writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
- writel(0x0, q->iobase + QUADSPI_RSER);
+ qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
+ qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
clk_unprepare(q->clk);
clk_unprepare(q->clk_en);
--
2.1.0.27.g96db324
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH 2/3 v3] mtd: spi-nor: fsl-quadspi: Enable support big endian registers
2015-06-18 8:59 [PATCH 2/3 v3] mtd: spi-nor: fsl-quadspi: Enable support big endian registers Haikun Wang
@ 2015-07-06 22:43 ` Brian Norris
2015-07-07 3:04 ` Wang Haikun
0 siblings, 1 reply; 3+ messages in thread
From: Brian Norris @ 2015-07-06 22:43 UTC (permalink / raw)
To: Haikun Wang; +Cc: dwmw2, linux-mtd, han.xu
Hi Haikun,
On Thu, Jun 18, 2015 at 04:59:08PM +0800, Haikun Wang wrote:
> QSPI registers are big endian on LS1021A.
> This patch check endianness before accessing register and
> swap the data if QSPI register is big endian.
>
> Signed-off-by: Haikun Wang <haikun.wang@freescale.com>
> ---
> Changes in v3:
> - Rebase with l2-mtd.git
Unfortunately, this still doesn't apply. One of Han Xu's patches
conflicts.
> Changes in v2:
> - Fix compile issue
>
> drivers/mtd/spi-nor/fsl-quadspi.c | 139 ++++++++++++++++++++++----------------
> 1 file changed, 81 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
> index 6cd14e4..dc157f9 100644
> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
> @@ -191,6 +191,8 @@
> #define SEQID_EN4B 10
> #define SEQID_BRWR 11
>
> +#define FSL_QSPI_FLAG_REGMAP_BE (1 << 0)
> +
> enum fsl_qspi_devtype {
> FSL_QUADSPI_VYBRID,
> FSL_QUADSPI_IMX6SX,
> @@ -202,6 +204,7 @@ struct fsl_qspi_devtype_data {
> int rxfifo;
> int txfifo;
> int ahb_buf_size;
> + u32 flags;
> };
>
> static struct fsl_qspi_devtype_data vybrid_data = {
> @@ -222,7 +225,8 @@ static struct fsl_qspi_devtype_data ls1_data = {
> .devtype = FSL_QUADSPI_LS1,
> .rxfifo = 128,
> .txfifo = 64,
> - .ahb_buf_size = 1024
> + .ahb_buf_size = 1024,
> + .flags = FSL_QSPI_FLAG_REGMAP_BE
> };
>
> #define FSL_QSPI_MAX_CHIP 4
> @@ -253,6 +257,18 @@ static inline int is_imx6sx_qspi(struct fsl_qspi *q)
> return q->devtype_data->devtype == FSL_QUADSPI_IMX6SX;
> }
>
> +static void qspi_writel(struct fsl_qspi *q, u32 val, void __iomem *addr)
> +{
> + q->devtype_data->flags & FSL_QSPI_FLAG_REGMAP_BE ?
> + writel(cpu_to_be32(val), addr) : writel(val, addr);
> +}
> +
> +static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr)
> +{
> + return q->devtype_data->flags & FSL_QSPI_FLAG_REGMAP_BE ?
> + cpu_to_be32(readl(addr)) : readl(addr);
> +}
> +
> /*
> * An IC bug makes us to re-arrange the 32-bit data.
> * The following chips, such as IMX6SLX, have fixed this bug.
> @@ -264,14 +280,14 @@ static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a)
>
> static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
> {
> - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
> - writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
> + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
> + qspi_writel(q, QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
> }
>
> static inline void fsl_qspi_lock_lut(struct fsl_qspi *q)
> {
> - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
> - writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
> + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
> + qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
> }
>
> static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
> @@ -280,8 +296,8 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
> u32 reg;
>
> /* clear interrupt */
> - reg = readl(q->iobase + QUADSPI_FR);
> - writel(reg, q->iobase + QUADSPI_FR);
> + reg = qspi_readl(q, q->iobase + QUADSPI_FR);
> + qspi_writel(q, reg, q->iobase + QUADSPI_FR);
>
> if (reg & QUADSPI_FR_TFF_MASK)
> complete(&q->c);
> @@ -302,7 +318,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
>
> /* Clear all the LUT table */
> for (i = 0; i < QUADSPI_LUT_NUM; i++)
> - writel(0, base + QUADSPI_LUT_BASE + i * 4);
> + qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
>
> /* Quad Read */
> lut_base = SEQID_QUAD_READ * 4;
> @@ -318,14 +334,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
> dummy = 8;
> }
>
> - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
> + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
> base + QUADSPI_LUT(lut_base));
> - writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
> + qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
> base + QUADSPI_LUT(lut_base + 1));
>
> /* Write enable */
> lut_base = SEQID_WREN * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
> + base + QUADSPI_LUT(lut_base));
>
> /* Page Program */
> lut_base = SEQID_PP * 4;
> @@ -339,13 +356,13 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
> addrlen = ADDR32BIT;
> }
>
> - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
> + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
> base + QUADSPI_LUT(lut_base));
> - writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
> + qspi_writel(q, LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
>
> /* Read Status */
> lut_base = SEQID_RDSR * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
> base + QUADSPI_LUT(lut_base));
>
> /* Erase a sector */
> @@ -360,40 +377,43 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
> addrlen = ADDR32BIT;
> }
>
> - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
> + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
> base + QUADSPI_LUT(lut_base));
>
> /* Erase the whole chip */
> lut_base = SEQID_CHIP_ERASE * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
> base + QUADSPI_LUT(lut_base));
>
> /* READ ID */
> lut_base = SEQID_RDID * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
> base + QUADSPI_LUT(lut_base));
>
> /* Write Register */
> lut_base = SEQID_WRSR * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
> base + QUADSPI_LUT(lut_base));
>
> /* Read Configuration Register */
> lut_base = SEQID_RDCR * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
> base + QUADSPI_LUT(lut_base));
>
> /* Write disable */
> lut_base = SEQID_WRDI * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base));
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
> + base + QUADSPI_LUT(lut_base));
>
> /* Enter 4 Byte Mode (Micron) */
> lut_base = SEQID_EN4B * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base));
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
> + base + QUADSPI_LUT(lut_base));
>
> /* Enter 4 Byte Mode (Spansion) */
> lut_base = SEQID_BRWR * 4;
> - writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base));
> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
> + base + QUADSPI_LUT(lut_base));
>
> fsl_qspi_lock_lut(q);
> }
> @@ -446,15 +466,16 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
> q->chip_base_addr, addr, len, cmd);
>
> /* save the reg */
> - reg = readl(base + QUADSPI_MCR);
> + reg = qspi_readl(q, base + QUADSPI_MCR);
>
> - writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR);
> - writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
> + qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
> + base + QUADSPI_SFAR);
> + qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
> base + QUADSPI_RBCT);
> - writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
> + qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
>
> do {
> - reg2 = readl(base + QUADSPI_SR);
> + reg2 = qspi_readl(q, base + QUADSPI_SR);
> if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
> udelay(1);
> dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2);
> @@ -465,21 +486,22 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
>
> /* trigger the LUT now */
> seqid = fsl_qspi_get_seqid(q, cmd);
> - writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR);
> + qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
> + base + QUADSPI_IPCR);
>
> /* Wait for the interrupt. */
> if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) {
> dev_err(q->dev,
> "cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n",
> - cmd, addr, readl(base + QUADSPI_FR),
> - readl(base + QUADSPI_SR));
> + cmd, addr, qspi_readl(q, base + QUADSPI_FR),
> + qspi_readl(q, base + QUADSPI_SR));
> err = -ETIMEDOUT;
> } else {
> err = 0;
> }
>
> /* restore the MCR */
> - writel(reg, base + QUADSPI_MCR);
> + qspi_writel(q, reg, base + QUADSPI_MCR);
>
> return err;
> }
> @@ -491,7 +513,7 @@ static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf)
> int i = 0;
>
> while (len > 0) {
> - tmp = readl(q->iobase + QUADSPI_RBDR + i * 4);
> + tmp = qspi_readl(q, q->iobase + QUADSPI_RBDR + i * 4);
> tmp = fsl_qspi_endian_xchg(q, tmp);
> dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n",
> q->chip_base_addr, tmp);
> @@ -519,9 +541,9 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
> {
> u32 reg;
>
> - reg = readl(q->iobase + QUADSPI_MCR);
> + reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
> reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK;
> - writel(reg, q->iobase + QUADSPI_MCR);
> + qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
>
> /*
> * The minimum delay : 1 AHB + 2 SFCK clocks.
> @@ -530,7 +552,7 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
> udelay(1);
>
> reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK);
> - writel(reg, q->iobase + QUADSPI_MCR);
> + qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
> }
>
> static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
> @@ -544,13 +566,13 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
> q->chip_base_addr, to, count);
>
> /* clear the TX FIFO. */
> - tmp = readl(q->iobase + QUADSPI_MCR);
> - writel(tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
> + tmp = qspi_readl(q, q->iobase + QUADSPI_MCR);
> + qspi_writel(q, tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
>
> /* fill the TX data to the FIFO */
> for (j = 0, i = ((count + 3) / 4); j < i; j++) {
> tmp = fsl_qspi_endian_xchg(q, *txbuf);
> - writel(tmp, q->iobase + QUADSPI_TBDR);
> + qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
> txbuf++;
> }
>
> @@ -568,10 +590,10 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
> int nor_size = q->nor_size;
> void __iomem *base = q->iobase;
>
> - writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
> - writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
> - writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
> - writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
> + qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
> + qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
> + qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
> + qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
> }
>
> /*
> @@ -593,24 +615,25 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
> int seqid;
>
> /* AHB configuration for access buffer 0/1/2 .*/
> - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
> - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
> - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
> + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
> + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
> + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
> /*
> * Set ADATSZ with the maximum AHB buffer size to improve the
> * read performance.
> */
> - writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8)
> - << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
> + qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
> + ((q->devtype_data->ahb_buf_size / 8)
> + << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
>
> /* We only use the buffer3 */
> - writel(0, base + QUADSPI_BUF0IND);
> - writel(0, base + QUADSPI_BUF1IND);
> - writel(0, base + QUADSPI_BUF2IND);
> + qspi_writel(q, 0, base + QUADSPI_BUF0IND);
> + qspi_writel(q, 0, base + QUADSPI_BUF1IND);
> + qspi_writel(q, 0, base + QUADSPI_BUF2IND);
>
> /* Set the default lut sequence for AHB Read. */
> seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
> - writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
> + qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
> q->iobase + QUADSPI_BFGENCR);
> }
>
> @@ -630,21 +653,21 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
> fsl_qspi_init_lut(q);
>
> /* Disable the module */
> - writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
> + qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
> base + QUADSPI_MCR);
>
> - reg = readl(base + QUADSPI_SMPR);
> - writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK
> + reg = qspi_readl(q, base + QUADSPI_SMPR);
> + qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
> | QUADSPI_SMPR_FSPHS_MASK
> | QUADSPI_SMPR_HSENA_MASK
> | QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
>
> /* Enable the module */
> - writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
> + qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
> base + QUADSPI_MCR);
>
> /* enable the interrupt */
> - writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
> + qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
>
> return 0;
> }
> @@ -979,8 +1002,8 @@ static int fsl_qspi_remove(struct platform_device *pdev)
> }
>
> /* disable the hardware */
> - writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
> - writel(0x0, q->iobase + QUADSPI_RSER);
> + qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
> + qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
>
> clk_unprepare(q->clk);
> clk_unprepare(q->clk_en);
^^ I think the problem is somewhere in here.
Brian
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH 2/3 v3] mtd: spi-nor: fsl-quadspi: Enable support big endian registers
2015-07-06 22:43 ` Brian Norris
@ 2015-07-07 3:04 ` Wang Haikun
0 siblings, 0 replies; 3+ messages in thread
From: Wang Haikun @ 2015-07-07 3:04 UTC (permalink / raw)
To: Brian Norris; +Cc: dwmw2@infradead.org, linux-mtd@lists.infradead.org, Xu Han
On 7/7/2015 6:43 AM, Brian Norris wrote:
> Hi Haikun,
>
> On Thu, Jun 18, 2015 at 04:59:08PM +0800, Haikun Wang wrote:
>> QSPI registers are big endian on LS1021A.
>> This patch check endianness before accessing register and
>> swap the data if QSPI register is big endian.
>>
>> Signed-off-by: Haikun Wang <haikun.wang@freescale.com>
>> ---
>> Changes in v3:
>> - Rebase with l2-mtd.git
>
> Unfortunately, this still doesn't apply. One of Han Xu's patches
> conflicts.
OK, I will re-submit all of my patches.
>
>> Changes in v2:
>> - Fix compile issue
>>
>> drivers/mtd/spi-nor/fsl-quadspi.c | 139 ++++++++++++++++++++++----------------
>> 1 file changed, 81 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c
>> index 6cd14e4..dc157f9 100644
>> --- a/drivers/mtd/spi-nor/fsl-quadspi.c
>> +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
>> @@ -191,6 +191,8 @@
>> #define SEQID_EN4B 10
>> #define SEQID_BRWR 11
>>
>> +#define FSL_QSPI_FLAG_REGMAP_BE (1 << 0)
>> +
>> enum fsl_qspi_devtype {
>> FSL_QUADSPI_VYBRID,
>> FSL_QUADSPI_IMX6SX,
>> @@ -202,6 +204,7 @@ struct fsl_qspi_devtype_data {
>> int rxfifo;
>> int txfifo;
>> int ahb_buf_size;
>> + u32 flags;
>> };
>>
>> static struct fsl_qspi_devtype_data vybrid_data = {
>> @@ -222,7 +225,8 @@ static struct fsl_qspi_devtype_data ls1_data = {
>> .devtype = FSL_QUADSPI_LS1,
>> .rxfifo = 128,
>> .txfifo = 64,
>> - .ahb_buf_size = 1024
>> + .ahb_buf_size = 1024,
>> + .flags = FSL_QSPI_FLAG_REGMAP_BE
>> };
>>
>> #define FSL_QSPI_MAX_CHIP 4
>> @@ -253,6 +257,18 @@ static inline int is_imx6sx_qspi(struct fsl_qspi *q)
>> return q->devtype_data->devtype == FSL_QUADSPI_IMX6SX;
>> }
>>
>> +static void qspi_writel(struct fsl_qspi *q, u32 val, void __iomem *addr)
>> +{
>> + q->devtype_data->flags & FSL_QSPI_FLAG_REGMAP_BE ?
>> + writel(cpu_to_be32(val), addr) : writel(val, addr);
>> +}
>> +
>> +static u32 qspi_readl(struct fsl_qspi *q, void __iomem *addr)
>> +{
>> + return q->devtype_data->flags & FSL_QSPI_FLAG_REGMAP_BE ?
>> + cpu_to_be32(readl(addr)) : readl(addr);
>> +}
>> +
>> /*
>> * An IC bug makes us to re-arrange the 32-bit data.
>> * The following chips, such as IMX6SLX, have fixed this bug.
>> @@ -264,14 +280,14 @@ static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a)
>>
>> static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q)
>> {
>> - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
>> - writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
>> + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
>> + qspi_writel(q, QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR);
>> }
>>
>> static inline void fsl_qspi_lock_lut(struct fsl_qspi *q)
>> {
>> - writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
>> - writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
>> + qspi_writel(q, QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY);
>> + qspi_writel(q, QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR);
>> }
>>
>> static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
>> @@ -280,8 +296,8 @@ static irqreturn_t fsl_qspi_irq_handler(int irq, void *dev_id)
>> u32 reg;
>>
>> /* clear interrupt */
>> - reg = readl(q->iobase + QUADSPI_FR);
>> - writel(reg, q->iobase + QUADSPI_FR);
>> + reg = qspi_readl(q, q->iobase + QUADSPI_FR);
>> + qspi_writel(q, reg, q->iobase + QUADSPI_FR);
>>
>> if (reg & QUADSPI_FR_TFF_MASK)
>> complete(&q->c);
>> @@ -302,7 +318,7 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
>>
>> /* Clear all the LUT table */
>> for (i = 0; i < QUADSPI_LUT_NUM; i++)
>> - writel(0, base + QUADSPI_LUT_BASE + i * 4);
>> + qspi_writel(q, 0, base + QUADSPI_LUT_BASE + i * 4);
>>
>> /* Quad Read */
>> lut_base = SEQID_QUAD_READ * 4;
>> @@ -318,14 +334,15 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
>> dummy = 8;
>> }
>>
>> - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
>> + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
>> base + QUADSPI_LUT(lut_base));
>> - writel(LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
>> + qspi_writel(q, LUT0(DUMMY, PAD1, dummy) | LUT1(READ, PAD4, rxfifo),
>> base + QUADSPI_LUT(lut_base + 1));
>>
>> /* Write enable */
>> lut_base = SEQID_WREN * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_WREN), base + QUADSPI_LUT(lut_base));
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WREN),
>> + base + QUADSPI_LUT(lut_base));
>>
>> /* Page Program */
>> lut_base = SEQID_PP * 4;
>> @@ -339,13 +356,13 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
>> addrlen = ADDR32BIT;
>> }
>>
>> - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
>> + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
>> base + QUADSPI_LUT(lut_base));
>> - writel(LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
>> + qspi_writel(q, LUT0(WRITE, PAD1, 0), base + QUADSPI_LUT(lut_base + 1));
>>
>> /* Read Status */
>> lut_base = SEQID_RDSR * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDSR) | LUT1(READ, PAD1, 0x1),
>> base + QUADSPI_LUT(lut_base));
>>
>> /* Erase a sector */
>> @@ -360,40 +377,43 @@ static void fsl_qspi_init_lut(struct fsl_qspi *q)
>> addrlen = ADDR32BIT;
>> }
>>
>> - writel(LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
>> + qspi_writel(q, LUT0(CMD, PAD1, cmd) | LUT1(ADDR, PAD1, addrlen),
>> base + QUADSPI_LUT(lut_base));
>>
>> /* Erase the whole chip */
>> lut_base = SEQID_CHIP_ERASE * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_CHIP_ERASE),
>> base + QUADSPI_LUT(lut_base));
>>
>> /* READ ID */
>> lut_base = SEQID_RDID * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDID) | LUT1(READ, PAD1, 0x8),
>> base + QUADSPI_LUT(lut_base));
>>
>> /* Write Register */
>> lut_base = SEQID_WRSR * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRSR) | LUT1(WRITE, PAD1, 0x2),
>> base + QUADSPI_LUT(lut_base));
>>
>> /* Read Configuration Register */
>> lut_base = SEQID_RDCR * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_RDCR) | LUT1(READ, PAD1, 0x1),
>> base + QUADSPI_LUT(lut_base));
>>
>> /* Write disable */
>> lut_base = SEQID_WRDI * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_WRDI), base + QUADSPI_LUT(lut_base));
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_WRDI),
>> + base + QUADSPI_LUT(lut_base));
>>
>> /* Enter 4 Byte Mode (Micron) */
>> lut_base = SEQID_EN4B * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_EN4B), base + QUADSPI_LUT(lut_base));
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_EN4B),
>> + base + QUADSPI_LUT(lut_base));
>>
>> /* Enter 4 Byte Mode (Spansion) */
>> lut_base = SEQID_BRWR * 4;
>> - writel(LUT0(CMD, PAD1, SPINOR_OP_BRWR), base + QUADSPI_LUT(lut_base));
>> + qspi_writel(q, LUT0(CMD, PAD1, SPINOR_OP_BRWR),
>> + base + QUADSPI_LUT(lut_base));
>>
>> fsl_qspi_lock_lut(q);
>> }
>> @@ -446,15 +466,16 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
>> q->chip_base_addr, addr, len, cmd);
>>
>> /* save the reg */
>> - reg = readl(base + QUADSPI_MCR);
>> + reg = qspi_readl(q, base + QUADSPI_MCR);
>>
>> - writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR);
>> - writel(QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
>> + qspi_writel(q, q->memmap_phy + q->chip_base_addr + addr,
>> + base + QUADSPI_SFAR);
>> + qspi_writel(q, QUADSPI_RBCT_WMRK_MASK | QUADSPI_RBCT_RXBRD_USEIPS,
>> base + QUADSPI_RBCT);
>> - writel(reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
>> + qspi_writel(q, reg | QUADSPI_MCR_CLR_RXF_MASK, base + QUADSPI_MCR);
>>
>> do {
>> - reg2 = readl(base + QUADSPI_SR);
>> + reg2 = qspi_readl(q, base + QUADSPI_SR);
>> if (reg2 & (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK)) {
>> udelay(1);
>> dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2);
>> @@ -465,21 +486,22 @@ fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len)
>>
>> /* trigger the LUT now */
>> seqid = fsl_qspi_get_seqid(q, cmd);
>> - writel((seqid << QUADSPI_IPCR_SEQID_SHIFT) | len, base + QUADSPI_IPCR);
>> + qspi_writel(q, (seqid << QUADSPI_IPCR_SEQID_SHIFT) | len,
>> + base + QUADSPI_IPCR);
>>
>> /* Wait for the interrupt. */
>> if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) {
>> dev_err(q->dev,
>> "cmd 0x%.2x timeout, addr@%.8x, FR:0x%.8x, SR:0x%.8x\n",
>> - cmd, addr, readl(base + QUADSPI_FR),
>> - readl(base + QUADSPI_SR));
>> + cmd, addr, qspi_readl(q, base + QUADSPI_FR),
>> + qspi_readl(q, base + QUADSPI_SR));
>> err = -ETIMEDOUT;
>> } else {
>> err = 0;
>> }
>>
>> /* restore the MCR */
>> - writel(reg, base + QUADSPI_MCR);
>> + qspi_writel(q, reg, base + QUADSPI_MCR);
>>
>> return err;
>> }
>> @@ -491,7 +513,7 @@ static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf)
>> int i = 0;
>>
>> while (len > 0) {
>> - tmp = readl(q->iobase + QUADSPI_RBDR + i * 4);
>> + tmp = qspi_readl(q, q->iobase + QUADSPI_RBDR + i * 4);
>> tmp = fsl_qspi_endian_xchg(q, tmp);
>> dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n",
>> q->chip_base_addr, tmp);
>> @@ -519,9 +541,9 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
>> {
>> u32 reg;
>>
>> - reg = readl(q->iobase + QUADSPI_MCR);
>> + reg = qspi_readl(q, q->iobase + QUADSPI_MCR);
>> reg |= QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK;
>> - writel(reg, q->iobase + QUADSPI_MCR);
>> + qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
>>
>> /*
>> * The minimum delay : 1 AHB + 2 SFCK clocks.
>> @@ -530,7 +552,7 @@ static inline void fsl_qspi_invalid(struct fsl_qspi *q)
>> udelay(1);
>>
>> reg &= ~(QUADSPI_MCR_SWRSTHD_MASK | QUADSPI_MCR_SWRSTSD_MASK);
>> - writel(reg, q->iobase + QUADSPI_MCR);
>> + qspi_writel(q, reg, q->iobase + QUADSPI_MCR);
>> }
>>
>> static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
>> @@ -544,13 +566,13 @@ static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor,
>> q->chip_base_addr, to, count);
>>
>> /* clear the TX FIFO. */
>> - tmp = readl(q->iobase + QUADSPI_MCR);
>> - writel(tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
>> + tmp = qspi_readl(q, q->iobase + QUADSPI_MCR);
>> + qspi_writel(q, tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR);
>>
>> /* fill the TX data to the FIFO */
>> for (j = 0, i = ((count + 3) / 4); j < i; j++) {
>> tmp = fsl_qspi_endian_xchg(q, *txbuf);
>> - writel(tmp, q->iobase + QUADSPI_TBDR);
>> + qspi_writel(q, tmp, q->iobase + QUADSPI_TBDR);
>> txbuf++;
>> }
>>
>> @@ -568,10 +590,10 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q)
>> int nor_size = q->nor_size;
>> void __iomem *base = q->iobase;
>>
>> - writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
>> - writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
>> - writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
>> - writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
>> + qspi_writel(q, nor_size + q->memmap_phy, base + QUADSPI_SFA1AD);
>> + qspi_writel(q, nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD);
>> + qspi_writel(q, nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD);
>> + qspi_writel(q, nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD);
>> }
>>
>> /*
>> @@ -593,24 +615,25 @@ static void fsl_qspi_init_abh_read(struct fsl_qspi *q)
>> int seqid;
>>
>> /* AHB configuration for access buffer 0/1/2 .*/
>> - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
>> - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
>> - writel(QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
>> + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF0CR);
>> + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF1CR);
>> + qspi_writel(q, QUADSPI_BUFXCR_INVALID_MSTRID, base + QUADSPI_BUF2CR);
>> /*
>> * Set ADATSZ with the maximum AHB buffer size to improve the
>> * read performance.
>> */
>> - writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8)
>> - << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
>> + qspi_writel(q, QUADSPI_BUF3CR_ALLMST_MASK |
>> + ((q->devtype_data->ahb_buf_size / 8)
>> + << QUADSPI_BUF3CR_ADATSZ_SHIFT), base + QUADSPI_BUF3CR);
>>
>> /* We only use the buffer3 */
>> - writel(0, base + QUADSPI_BUF0IND);
>> - writel(0, base + QUADSPI_BUF1IND);
>> - writel(0, base + QUADSPI_BUF2IND);
>> + qspi_writel(q, 0, base + QUADSPI_BUF0IND);
>> + qspi_writel(q, 0, base + QUADSPI_BUF1IND);
>> + qspi_writel(q, 0, base + QUADSPI_BUF2IND);
>>
>> /* Set the default lut sequence for AHB Read. */
>> seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode);
>> - writel(seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
>> + qspi_writel(q, seqid << QUADSPI_BFGENCR_SEQID_SHIFT,
>> q->iobase + QUADSPI_BFGENCR);
>> }
>>
>> @@ -630,21 +653,21 @@ static int fsl_qspi_nor_setup(struct fsl_qspi *q)
>> fsl_qspi_init_lut(q);
>>
>> /* Disable the module */
>> - writel(QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
>> + qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
>> base + QUADSPI_MCR);
>>
>> - reg = readl(base + QUADSPI_SMPR);
>> - writel(reg & ~(QUADSPI_SMPR_FSDLY_MASK
>> + reg = qspi_readl(q, base + QUADSPI_SMPR);
>> + qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
>> | QUADSPI_SMPR_FSPHS_MASK
>> | QUADSPI_SMPR_HSENA_MASK
>> | QUADSPI_SMPR_DDRSMP_MASK), base + QUADSPI_SMPR);
>>
>> /* Enable the module */
>> - writel(QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
>> + qspi_writel(q, QUADSPI_MCR_RESERVED_MASK | QUADSPI_MCR_END_CFG_MASK,
>> base + QUADSPI_MCR);
>>
>> /* enable the interrupt */
>> - writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
>> + qspi_writel(q, QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER);
>>
>> return 0;
>> }
>> @@ -979,8 +1002,8 @@ static int fsl_qspi_remove(struct platform_device *pdev)
>> }
>>
>> /* disable the hardware */
>> - writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
>> - writel(0x0, q->iobase + QUADSPI_RSER);
>> + qspi_writel(q, QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR);
>> + qspi_writel(q, 0x0, q->iobase + QUADSPI_RSER);
>>
>> clk_unprepare(q->clk);
>> clk_unprepare(q->clk_en);
>
> ^^ I think the problem is somewhere in here.
>
> Brian
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-07-07 3:04 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-18 8:59 [PATCH 2/3 v3] mtd: spi-nor: fsl-quadspi: Enable support big endian registers Haikun Wang
2015-07-06 22:43 ` Brian Norris
2015-07-07 3:04 ` Wang Haikun
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox