Message ID | 20231212-ep93xx-v6-20-c307b8ac9aa8@maquefel.me |
---|---|
State | New |
Headers | show |
Series | ep93xx device tree conversion | expand |
On Tue, Dec 12, 2023 at 11:20:37AM +0300, Nikita Shubin via B4 Relay wrote: > From: Nikita Shubin <nikita.shubin@maquefel.me> > > Technologic Systems has it's own nand controller implementation in CPLD. > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> > --- > drivers/mtd/nand/raw/Kconfig | 7 + > drivers/mtd/nand/raw/Makefile | 1 + > drivers/mtd/nand/raw/technologic-nand-controller.c | 220 +++++++++++++++++++++ > 3 files changed, 228 insertions(+) > > diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig > index cbf8ae85e1ae..3937c10dea1c 100644 > --- a/drivers/mtd/nand/raw/Kconfig > +++ b/drivers/mtd/nand/raw/Kconfig > @@ -449,6 +449,13 @@ config MTD_NAND_RENESAS > Enables support for the NAND controller found on Renesas R-Car > Gen3 and RZ/N1 SoC families. > > +config MTD_NAND_TS72XX > + tristate "ts72xx NAND controller" > + depends on ARCH_EP93XX && HAS_IOMEM > + help > + Enables support for NAND controller on ts72xx SBCs. > + This is a legacy driver based on gen_nand. Why is a new "legacy driver" being written these days? Why not do it properly? thanks, greg k-h
Hello Greg! On Tue, 2023-12-12 at 09:30 +0100, Greg Kroah-Hartman wrote: > On Tue, Dec 12, 2023 at 11:20:37AM +0300, Nikita Shubin via B4 Relay > wrote: > > From: Nikita Shubin <nikita.shubin@maquefel.me> > > > > Technologic Systems has it's own nand controller implementation in > > CPLD. > > > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> > > --- > > drivers/mtd/nand/raw/Kconfig | 7 + > > drivers/mtd/nand/raw/Makefile | 1 + > > drivers/mtd/nand/raw/technologic-nand-controller.c | 220 > > +++++++++++++++++++++ > > 3 files changed, 228 insertions(+) > > > > diff --git a/drivers/mtd/nand/raw/Kconfig > > b/drivers/mtd/nand/raw/Kconfig > > index cbf8ae85e1ae..3937c10dea1c 100644 > > --- a/drivers/mtd/nand/raw/Kconfig > > +++ b/drivers/mtd/nand/raw/Kconfig > > @@ -449,6 +449,13 @@ config MTD_NAND_RENESAS > > Enables support for the NAND controller found on Renesas > > R-Car > > Gen3 and RZ/N1 SoC families. > > > > +config MTD_NAND_TS72XX > > + tristate "ts72xx NAND controller" > > + depends on ARCH_EP93XX && HAS_IOMEM > > + help > > + Enables support for NAND controller on ts72xx SBCs. > > + This is a legacy driver based on gen_nand. > > Why is a new "legacy driver" being written these days? Why not do it > properly? Sorry, my bad, description is a leftover from older description (when i was allowed to submit a legacy one). The driver is mostly new, shiny and approved by Miquel: https://lore.kernel.org/lkml/20231004103911.2aa65354@xps-13/ The KConfig description should be fixed. > > thanks, > > greg k-h
Hello, nikita.shubin@maquefel.me wrote on Tue, 12 Dec 2023 11:35:48 +0300: > Hello Greg! > > On Tue, 2023-12-12 at 09:30 +0100, Greg Kroah-Hartman wrote: > > On Tue, Dec 12, 2023 at 11:20:37AM +0300, Nikita Shubin via B4 Relay > > wrote: > > > From: Nikita Shubin <nikita.shubin@maquefel.me> > > > > > > Technologic Systems has it's own nand controller implementation in > > > CPLD. > > > > > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> > > > --- > > > drivers/mtd/nand/raw/Kconfig | 7 + > > > drivers/mtd/nand/raw/Makefile | 1 + > > > drivers/mtd/nand/raw/technologic-nand-controller.c | 220 > > > +++++++++++++++++++++ > > > 3 files changed, 228 insertions(+) > > > > > > diff --git a/drivers/mtd/nand/raw/Kconfig > > > b/drivers/mtd/nand/raw/Kconfig > > > index cbf8ae85e1ae..3937c10dea1c 100644 > > > --- a/drivers/mtd/nand/raw/Kconfig > > > +++ b/drivers/mtd/nand/raw/Kconfig > > > @@ -449,6 +449,13 @@ config MTD_NAND_RENESAS > > > Enables support for the NAND controller found on Renesas > > > R-Car > > > Gen3 and RZ/N1 SoC families. > > > > > > +config MTD_NAND_TS72XX > > > + tristate "ts72xx NAND controller" > > > + depends on ARCH_EP93XX && HAS_IOMEM > > > + help > > > + Enables support for NAND controller on ts72xx SBCs. > > > + This is a legacy driver based on gen_nand. > > > > Why is a new "legacy driver" being written these days? Why not do it > > properly? > > Sorry, my bad, description is a leftover from older description (when i > was allowed to submit a legacy one). > > The driver is mostly new, shiny and approved by Miquel: > > https://lore.kernel.org/lkml/20231004103911.2aa65354@xps-13/ > > The KConfig description should be fixed. Indeed, later submissions carried a brand new implementation which no longer leverages any legacy hook. The Kconfig description is wrong, good catch. Thanks, Miquèl
Hi Nikita, devnull+nikita.shubin.maquefel.me@kernel.org wrote on Tue, 12 Dec 2023 11:20:37 +0300: > From: Nikita Shubin <nikita.shubin@maquefel.me> > > Technologic Systems has it's own nand controller implementation in CPLD. > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> I'm fine with this version, I could collect patches 19 and 20 through mtd but I saw no clear answer to the cover letter, regarding who should pickup the patches. Let me know what you prefer. Thanks, Miquèl
Hello Miquel and Uwe. On Fri, 2023-12-15 at 11:16 +0100, Miquel Raynal wrote: > Hi Nikita, > > devnull+nikita.shubin.maquefel.me@kernel.org wrote on Tue, 12 Dec > 2023 > 11:20:37 +0300: > > > From: Nikita Shubin <nikita.shubin@maquefel.me> > > > > Technologic Systems has it's own nand controller implementation in > > CPLD. > > > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> > > I'm fine with this version, I could collect patches 19 and 20 through > mtd but I saw no clear answer to the cover letter, regarding who > should > pickup the patches. Let me know what you prefer. This is still planned going via arm-soc branch, as these patches are pretty useless without ep93xx totally converted to device tree. > > Thanks, > Miquèl
Hi Nikita, nikita.shubin@maquefel.me wrote on Fri, 15 Dec 2023 15:11:02 +0300: > Hello Miquel and Uwe. > > On Fri, 2023-12-15 at 11:16 +0100, Miquel Raynal wrote: > > Hi Nikita, > > > > devnull+nikita.shubin.maquefel.me@kernel.org wrote on Tue, 12 Dec > > 2023 > > 11:20:37 +0300: > > > > > From: Nikita Shubin <nikita.shubin@maquefel.me> > > > > > > Technologic Systems has it's own nand controller implementation in > > > CPLD. > > > > > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me> > > > > I'm fine with this version, I could collect patches 19 and 20 through > > mtd but I saw no clear answer to the cover letter, regarding who > > should > > pickup the patches. Let me know what you prefer. > > This is still planned going via arm-soc branch, as these patches are > pretty useless without ep93xx totally converted to device tree. Alright, so I will not take these patches for the next merge window. Acked-by: Miquel Raynal <miquel.raynal@bootlin.com> Thanks, Miquèl
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index cbf8ae85e1ae..3937c10dea1c 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -449,6 +449,13 @@ config MTD_NAND_RENESAS Enables support for the NAND controller found on Renesas R-Car Gen3 and RZ/N1 SoC families. +config MTD_NAND_TS72XX + tristate "ts72xx NAND controller" + depends on ARCH_EP93XX && HAS_IOMEM + help + Enables support for NAND controller on ts72xx SBCs. + This is a legacy driver based on gen_nand. + comment "Misc" config MTD_SM_COMMON diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 25120a4afada..d0b0e6b83568 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_MTD_NAND_MLC_LPC32XX) += lpc32xx_mlc.o obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o +obj-$(CONFIG_MTD_NAND_TS72XX) += technologic-nand-controller.o obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o diff --git a/drivers/mtd/nand/raw/technologic-nand-controller.c b/drivers/mtd/nand/raw/technologic-nand-controller.c new file mode 100644 index 000000000000..63157e7b5572 --- /dev/null +++ b/drivers/mtd/nand/raw/technologic-nand-controller.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Technologic Systems TS72xx NAND controller driver + * + * Copyright (C) 2023 Nikita Shubin <nikita.shubin@maquefel.me> + * + * Derived from: plat_nand.c + * Author: Vitaly Wool <vitalywool@gmail.com> + */ + +#include <linux/bits.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <linux/mtd/mtd.h> +#include <linux/mtd/platnand.h> + +#define TS72XX_NAND_CONTROL_ADDR_LINE BIT(22) /* 0xN0400000 */ +#define TS72XX_NAND_BUSY_ADDR_LINE BIT(23) /* 0xN0800000 */ + +#define TS72XX_NAND_ALE BIT(0) +#define TS72XX_NAND_CLE BIT(1) +#define TS72XX_NAND_NCE BIT(2) + +#define TS72XX_NAND_CTRL_CLE (TS72XX_NAND_NCE | TS72XX_NAND_CLE) +#define TS72XX_NAND_CTRL_ALE (TS72XX_NAND_NCE | TS72XX_NAND_ALE) + +struct ts72xx_nand_data { + struct nand_controller controller; + struct nand_chip chip; + void __iomem *base; + void __iomem *ctrl; + void __iomem *busy; +}; + +static inline struct ts72xx_nand_data *chip_to_ts72xx(struct nand_chip *chip) +{ + return container_of(chip, struct ts72xx_nand_data, chip); +} + +static int ts72xx_nand_attach_chip(struct nand_chip *chip) +{ + switch (chip->ecc.engine_type) { + case NAND_ECC_ENGINE_TYPE_ON_HOST: + return -EINVAL; + case NAND_ECC_ENGINE_TYPE_SOFT: + if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) + chip->ecc.algo = NAND_ECC_ALGO_HAMMING; + chip->ecc.algo = NAND_ECC_ALGO_HAMMING; + fallthrough; + default: + return 0; + } +} + +static void ts72xx_nand_ctrl(struct nand_chip *chip, u8 value) +{ + struct ts72xx_nand_data *data = chip_to_ts72xx(chip); + unsigned char bits = ioread8(data->ctrl) & ~GENMASK(2, 0); + + iowrite8(bits | value, data->ctrl); +} + +static int ts72xx_nand_exec_instr(struct nand_chip *chip, + const struct nand_op_instr *instr) +{ + struct ts72xx_nand_data *data = chip_to_ts72xx(chip); + unsigned int timeout_us; + u32 status; + int ret; + + switch (instr->type) { + case NAND_OP_CMD_INSTR: + ts72xx_nand_ctrl(chip, TS72XX_NAND_CTRL_CLE); + iowrite8(instr->ctx.cmd.opcode, data->base); + ts72xx_nand_ctrl(chip, TS72XX_NAND_NCE); + break; + + case NAND_OP_ADDR_INSTR: + ts72xx_nand_ctrl(chip, TS72XX_NAND_CTRL_ALE); + iowrite8_rep(data->base, instr->ctx.addr.addrs, instr->ctx.addr.naddrs); + ts72xx_nand_ctrl(chip, TS72XX_NAND_NCE); + break; + + case NAND_OP_DATA_IN_INSTR: + ioread8_rep(data->base, instr->ctx.data.buf.in, instr->ctx.data.len); + break; + + case NAND_OP_DATA_OUT_INSTR: + iowrite8_rep(data->base, instr->ctx.data.buf.in, instr->ctx.data.len); + break; + + case NAND_OP_WAITRDY_INSTR: + timeout_us = instr->ctx.waitrdy.timeout_ms * 1000; + ret = readb_poll_timeout(data->busy, status, status & BIT(5), 0, timeout_us); + if (ret) + return ret; + + break; + } + + if (instr->delay_ns) + ndelay(instr->delay_ns); + + return 0; +} + +static int ts72xx_nand_exec_op(struct nand_chip *chip, + const struct nand_operation *op, bool check_only) +{ + unsigned int i; + int ret; + + if (check_only) + return 0; + + for (i = 0; i < op->ninstrs; i++) { + ret = ts72xx_nand_exec_instr(chip, &op->instrs[i]); + if (ret) + return ret; + } + + return 0; +} + +static const struct nand_controller_ops ts72xx_nand_ops = { + .attach_chip = ts72xx_nand_attach_chip, + .exec_op = ts72xx_nand_exec_op, +}; + +static int ts72xx_nand_probe(struct platform_device *pdev) +{ + struct ts72xx_nand_data *data; + struct fwnode_handle *child; + struct mtd_info *mtd; + int err; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + nand_controller_init(&data->controller); + data->controller.ops = &ts72xx_nand_ops; + data->chip.controller = &data->controller; + + data->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(data->base)) + return PTR_ERR(data->base); + data->ctrl = data->base + TS72XX_NAND_CONTROL_ADDR_LINE; + data->busy = data->base + TS72XX_NAND_BUSY_ADDR_LINE; + + child = fwnode_get_next_child_node(dev_fwnode(&pdev->dev), NULL); + if (!child) + return dev_err_probe(&pdev->dev, -ENXIO, + "ts72xx controller node should have exactly one child\n"); + + nand_set_flash_node(&data->chip, to_of_node(child)); + mtd = nand_to_mtd(&data->chip); + mtd->dev.parent = &pdev->dev; + platform_set_drvdata(pdev, data); + + /* + * This driver assumes that the default ECC engine should be TYPE_SOFT. + * Set ->engine_type before registering the NAND devices in order to + * provide a driver specific default value. + */ + data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; + + /* Scan to find existence of the device */ + err = nand_scan(&data->chip, 1); + if (err) + goto err_handle_put; + + err = mtd_device_parse_register(mtd, NULL, NULL, NULL, 0); + if (err) + goto err_clean_nand; + + return 0; + +err_clean_nand: + nand_cleanup(&data->chip); +err_handle_put: + fwnode_handle_put(child); + return err; +} + +static void ts72xx_nand_remove(struct platform_device *pdev) +{ + struct ts72xx_nand_data *data = platform_get_drvdata(pdev); + struct nand_chip *chip = &data->chip; + int ret; + + ret = mtd_device_unregister(nand_to_mtd(chip)); + WARN_ON(ret); + nand_cleanup(chip); +} + +static const struct of_device_id ts72xx_id_table[] = { + { .compatible = "technologic,ts7200-nand" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, ts72xx_id_table); + +static struct platform_driver ts72xx_nand_driver = { + .driver = { + .name = "ts72xx-nand", + .of_match_table = ts72xx_id_table, + }, + .probe = ts72xx_nand_probe, + .remove_new = ts72xx_nand_remove, +}; +module_platform_driver(ts72xx_nand_driver); + +MODULE_AUTHOR("Nikita Shubin <nikita.shubin@maquefel.me>"); +MODULE_DESCRIPTION("Technologic Systems TS72xx NAND controller driver"); +MODULE_LICENSE("GPL");