Commit 90d6bf48 authored by Boris Brezillon's avatar Boris Brezillon Committed by Miquel Raynal

mtd: rawnand: tango: Convert the driver to exec_op()

Let's convert the driver to exec_op() to have one less driver relying
on the legacy interface.
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20200518170912.328988-1-boris.brezillon@collabora.com
parent 5197360f
...@@ -113,59 +113,80 @@ struct tango_chip { ...@@ -113,59 +113,80 @@ struct tango_chip {
#define TIMING(t0, t1, t2, t3) ((t0) << 24 | (t1) << 16 | (t2) << 8 | (t3)) #define TIMING(t0, t1, t2, t3) ((t0) << 24 | (t1) << 16 | (t2) << 8 | (t3))
static void tango_cmd_ctrl(struct nand_chip *chip, int dat, unsigned int ctrl) static void tango_select_target(struct nand_chip *chip, unsigned int cs)
{ {
struct tango_nfc *nfc = to_tango_nfc(chip->controller);
struct tango_chip *tchip = to_tango_chip(chip); struct tango_chip *tchip = to_tango_chip(chip);
if (ctrl & NAND_CLE) writel_relaxed(tchip->timing1, nfc->reg_base + NFC_TIMING1);
writeb_relaxed(dat, tchip->base + PBUS_CMD); writel_relaxed(tchip->timing2, nfc->reg_base + NFC_TIMING2);
writel_relaxed(tchip->xfer_cfg, nfc->reg_base + NFC_XFER_CFG);
if (ctrl & NAND_ALE) writel_relaxed(tchip->pkt_0_cfg, nfc->reg_base + NFC_PKT_0_CFG);
writeb_relaxed(dat, tchip->base + PBUS_ADDR); writel_relaxed(tchip->pkt_n_cfg, nfc->reg_base + NFC_PKT_N_CFG);
writel_relaxed(tchip->bb_cfg, nfc->reg_base + NFC_BB_CFG);
} }
static int tango_dev_ready(struct nand_chip *chip) static int tango_waitrdy(struct nand_chip *chip, unsigned int timeout_ms)
{ {
struct tango_nfc *nfc = to_tango_nfc(chip->controller); struct tango_nfc *nfc = to_tango_nfc(chip->controller);
u32 status;
return readl_relaxed(nfc->pbus_base + PBUS_CS_CTRL) & PBUS_IORDY; return readl_relaxed_poll_timeout(nfc->pbus_base + PBUS_CS_CTRL,
status, status & PBUS_IORDY, 20,
timeout_ms);
} }
static u8 tango_read_byte(struct nand_chip *chip) static int tango_exec_instr(struct nand_chip *chip,
const struct nand_op_instr *instr)
{ {
struct tango_chip *tchip = to_tango_chip(chip); struct tango_chip *tchip = to_tango_chip(chip);
unsigned int i;
return readb_relaxed(tchip->base + PBUS_DATA); switch (instr->type) {
} case NAND_OP_CMD_INSTR:
writeb_relaxed(instr->ctx.cmd.opcode, tchip->base + PBUS_CMD);
static void tango_read_buf(struct nand_chip *chip, u8 *buf, int len) return 0;
{ case NAND_OP_ADDR_INSTR:
struct tango_chip *tchip = to_tango_chip(chip); for (i = 0; i < instr->ctx.addr.naddrs; i++)
writeb_relaxed(instr->ctx.addr.addrs[i],
tchip->base + PBUS_ADDR);
return 0;
case NAND_OP_DATA_IN_INSTR:
ioread8_rep(tchip->base + PBUS_DATA, instr->ctx.data.buf.in,
instr->ctx.data.len);
return 0;
case NAND_OP_DATA_OUT_INSTR:
iowrite8_rep(tchip->base + PBUS_DATA, instr->ctx.data.buf.out,
instr->ctx.data.len);
return 0;
case NAND_OP_WAITRDY_INSTR:
return tango_waitrdy(chip,
instr->ctx.waitrdy.timeout_ms);
default:
break;
}
ioread8_rep(tchip->base + PBUS_DATA, buf, len); return -EINVAL;
} }
static void tango_write_buf(struct nand_chip *chip, const u8 *buf, int len) static int tango_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{ {
struct tango_chip *tchip = to_tango_chip(chip); unsigned int i;
int ret = 0;
iowrite8_rep(tchip->base + PBUS_DATA, buf, len);
}
static void tango_select_chip(struct nand_chip *chip, int idx) if (check_only)
{ return 0;
struct tango_nfc *nfc = to_tango_nfc(chip->controller);
struct tango_chip *tchip = to_tango_chip(chip);
if (idx < 0) tango_select_target(chip, op->cs);
return; /* No "chip unselect" function */ for (i = 0; i < op->ninstrs; i++) {
ret = tango_exec_instr(chip, &op->instrs[i]);
if (ret)
break;
}
writel_relaxed(tchip->timing1, nfc->reg_base + NFC_TIMING1); return ret;
writel_relaxed(tchip->timing2, nfc->reg_base + NFC_TIMING2);
writel_relaxed(tchip->xfer_cfg, nfc->reg_base + NFC_XFER_CFG);
writel_relaxed(tchip->pkt_0_cfg, nfc->reg_base + NFC_PKT_0_CFG);
writel_relaxed(tchip->pkt_n_cfg, nfc->reg_base + NFC_PKT_N_CFG);
writel_relaxed(tchip->bb_cfg, nfc->reg_base + NFC_BB_CFG);
} }
/* /*
...@@ -279,6 +300,7 @@ static int tango_read_page(struct nand_chip *chip, u8 *buf, ...@@ -279,6 +300,7 @@ static int tango_read_page(struct nand_chip *chip, u8 *buf,
struct tango_nfc *nfc = to_tango_nfc(chip->controller); struct tango_nfc *nfc = to_tango_nfc(chip->controller);
int err, res, len = mtd->writesize; int err, res, len = mtd->writesize;
tango_select_target(chip, chip->cur_cs);
if (oob_required) if (oob_required)
chip->ecc.read_oob(chip, page); chip->ecc.read_oob(chip, page);
...@@ -300,22 +322,30 @@ static int tango_write_page(struct nand_chip *chip, const u8 *buf, ...@@ -300,22 +322,30 @@ static int tango_write_page(struct nand_chip *chip, const u8 *buf,
{ {
struct mtd_info *mtd = nand_to_mtd(chip); struct mtd_info *mtd = nand_to_mtd(chip);
struct tango_nfc *nfc = to_tango_nfc(chip->controller); struct tango_nfc *nfc = to_tango_nfc(chip->controller);
int err, status, len = mtd->writesize; const struct nand_sdr_timings *timings;
int err, len = mtd->writesize;
u8 status;
/* Calling tango_write_oob() would send PAGEPROG twice */ /* Calling tango_write_oob() would send PAGEPROG twice */
if (oob_required) if (oob_required)
return -ENOTSUPP; return -ENOTSUPP;
tango_select_target(chip, chip->cur_cs);
writel_relaxed(0xffffffff, nfc->mem_base + METADATA); writel_relaxed(0xffffffff, nfc->mem_base + METADATA);
err = do_dma(nfc, DMA_TO_DEVICE, NFC_WRITE, buf, len, page); err = do_dma(nfc, DMA_TO_DEVICE, NFC_WRITE, buf, len, page);
if (err) if (err)
return err; return err;
status = chip->legacy.waitfunc(chip); timings = nand_get_sdr_timings(&chip->data_interface);
if (status & NAND_STATUS_FAIL) err = tango_waitrdy(chip, PSEC_TO_MSEC(timings->tR_max));
return -EIO; if (err)
return err;
return 0; err = nand_status_op(chip, &status);
if (err)
return err;
return (status & NAND_STATUS_FAIL) ? -EIO : 0;
} }
static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos) static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos)
...@@ -326,7 +356,9 @@ static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos) ...@@ -326,7 +356,9 @@ static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos)
/* skip over "len" bytes */ /* skip over "len" bytes */
nand_change_read_column_op(chip, *pos, NULL, 0, false); nand_change_read_column_op(chip, *pos, NULL, 0, false);
} else { } else {
tango_read_buf(chip, *buf, len); struct tango_chip *tchip = to_tango_chip(chip);
ioread8_rep(tchip->base + PBUS_DATA, *buf, len);
*buf += len; *buf += len;
} }
} }
...@@ -339,7 +371,9 @@ static void aux_write(struct nand_chip *chip, const u8 **buf, int len, int *pos) ...@@ -339,7 +371,9 @@ static void aux_write(struct nand_chip *chip, const u8 **buf, int len, int *pos)
/* skip over "len" bytes */ /* skip over "len" bytes */
nand_change_write_column_op(chip, *pos, NULL, 0, false); nand_change_write_column_op(chip, *pos, NULL, 0, false);
} else { } else {
tango_write_buf(chip, *buf, len); struct tango_chip *tchip = to_tango_chip(chip);
iowrite8_rep(tchip->base + PBUS_DATA, *buf, len);
*buf += len; *buf += len;
} }
} }
...@@ -420,6 +454,7 @@ static void raw_write(struct nand_chip *chip, const u8 *buf, const u8 *oob) ...@@ -420,6 +454,7 @@ static void raw_write(struct nand_chip *chip, const u8 *buf, const u8 *oob)
static int tango_read_page_raw(struct nand_chip *chip, u8 *buf, static int tango_read_page_raw(struct nand_chip *chip, u8 *buf,
int oob_required, int page) int oob_required, int page)
{ {
tango_select_target(chip, chip->cur_cs);
nand_read_page_op(chip, page, 0, NULL, 0); nand_read_page_op(chip, page, 0, NULL, 0);
raw_read(chip, buf, chip->oob_poi); raw_read(chip, buf, chip->oob_poi);
return 0; return 0;
...@@ -428,6 +463,7 @@ static int tango_read_page_raw(struct nand_chip *chip, u8 *buf, ...@@ -428,6 +463,7 @@ static int tango_read_page_raw(struct nand_chip *chip, u8 *buf,
static int tango_write_page_raw(struct nand_chip *chip, const u8 *buf, static int tango_write_page_raw(struct nand_chip *chip, const u8 *buf,
int oob_required, int page) int oob_required, int page)
{ {
tango_select_target(chip, chip->cur_cs);
nand_prog_page_begin_op(chip, page, 0, NULL, 0); nand_prog_page_begin_op(chip, page, 0, NULL, 0);
raw_write(chip, buf, chip->oob_poi); raw_write(chip, buf, chip->oob_poi);
return nand_prog_page_end_op(chip); return nand_prog_page_end_op(chip);
...@@ -435,6 +471,7 @@ static int tango_write_page_raw(struct nand_chip *chip, const u8 *buf, ...@@ -435,6 +471,7 @@ static int tango_write_page_raw(struct nand_chip *chip, const u8 *buf,
static int tango_read_oob(struct nand_chip *chip, int page) static int tango_read_oob(struct nand_chip *chip, int page)
{ {
tango_select_target(chip, chip->cur_cs);
nand_read_page_op(chip, page, 0, NULL, 0); nand_read_page_op(chip, page, 0, NULL, 0);
raw_read(chip, NULL, chip->oob_poi); raw_read(chip, NULL, chip->oob_poi);
return 0; return 0;
...@@ -442,6 +479,7 @@ static int tango_read_oob(struct nand_chip *chip, int page) ...@@ -442,6 +479,7 @@ static int tango_read_oob(struct nand_chip *chip, int page)
static int tango_write_oob(struct nand_chip *chip, int page) static int tango_write_oob(struct nand_chip *chip, int page)
{ {
tango_select_target(chip, chip->cur_cs);
nand_prog_page_begin_op(chip, page, 0, NULL, 0); nand_prog_page_begin_op(chip, page, 0, NULL, 0);
raw_write(chip, NULL, chip->oob_poi); raw_write(chip, NULL, chip->oob_poi);
return nand_prog_page_end_op(chip); return nand_prog_page_end_op(chip);
...@@ -528,6 +566,7 @@ static int tango_attach_chip(struct nand_chip *chip) ...@@ -528,6 +566,7 @@ static int tango_attach_chip(struct nand_chip *chip)
static const struct nand_controller_ops tango_controller_ops = { static const struct nand_controller_ops tango_controller_ops = {
.attach_chip = tango_attach_chip, .attach_chip = tango_attach_chip,
.setup_data_interface = tango_set_timings, .setup_data_interface = tango_set_timings,
.exec_op = tango_exec_op,
}; };
static int chip_init(struct device *dev, struct device_node *np) static int chip_init(struct device *dev, struct device_node *np)
...@@ -562,12 +601,6 @@ static int chip_init(struct device *dev, struct device_node *np) ...@@ -562,12 +601,6 @@ static int chip_init(struct device *dev, struct device_node *np)
ecc = &chip->ecc; ecc = &chip->ecc;
mtd = nand_to_mtd(chip); mtd = nand_to_mtd(chip);
chip->legacy.read_byte = tango_read_byte;
chip->legacy.write_buf = tango_write_buf;
chip->legacy.read_buf = tango_read_buf;
chip->legacy.select_chip = tango_select_chip;
chip->legacy.cmd_ctrl = tango_cmd_ctrl;
chip->legacy.dev_ready = tango_dev_ready;
chip->options = NAND_USES_DMA | chip->options = NAND_USES_DMA |
NAND_NO_SUBPAGE_WRITE | NAND_NO_SUBPAGE_WRITE |
NAND_WAIT_TCCS; NAND_WAIT_TCCS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment