// SPDX-License-Identifier: GPL-2.0
/*
 * Support for Macronix external hardware ECC engine for NAND devices, also
 * called DPE for Data Processing Engine.
 *
 * Copyright © 2019 Macronix
 * Author: Miquel Raynal <miquel.raynal@bootlin.com>
 */

#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand-ecc-mxic.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

/* DPE Configuration */
#define DP_CONFIG 0x00
#define   ECC_EN BIT(0)
#define   ECC_TYP(idx) (((idx) << 3) & GENMASK(6, 3))
/* DPE Interrupt Status */
#define INTRPT_STS 0x04
#define   TRANS_CMPLT BIT(0)
#define   SDMA_MAIN BIT(1)
#define   SDMA_SPARE BIT(2)
#define   ECC_ERR BIT(3)
#define   TO_SPARE BIT(4)
#define   TO_MAIN BIT(5)
/* DPE Interrupt Status Enable */
#define INTRPT_STS_EN 0x08
/* DPE Interrupt Signal Enable */
#define INTRPT_SIG_EN 0x0C
/* Host Controller Configuration */
#define HC_CONFIG 0x10
#define   DEV2MEM 0 /* TRANS_TYP_DMA in the spec */
#define   MEM2MEM BIT(4) /* TRANS_TYP_IO in the spec */
#define   MAPPING BIT(5) /* TRANS_TYP_MAPPING in the spec */
#define   ECC_PACKED 0 /* LAYOUT_TYP_INTEGRATED in the spec */
#define   ECC_INTERLEAVED BIT(2) /* LAYOUT_TYP_DISTRIBUTED in the spec */
#define   BURST_TYP_FIXED 0
#define   BURST_TYP_INCREASING BIT(0)
/* Host Controller Slave Address */
#define HC_SLV_ADDR 0x14
/* ECC Chunk Size */
#define CHUNK_SIZE 0x20
/* Main Data Size */
#define MAIN_SIZE 0x24
/* Spare Data Size */
#define SPARE_SIZE 0x28
#define   META_SZ(reg) ((reg) & GENMASK(7, 0))
#define   PARITY_SZ(reg) (((reg) & GENMASK(15, 8)) >> 8)
#define   RSV_SZ(reg) (((reg) & GENMASK(23, 16)) >> 16)
#define   SPARE_SZ(reg) ((reg) >> 24)
/* ECC Chunk Count */
#define CHUNK_CNT 0x30
/* SDMA Control */
#define SDMA_CTRL 0x40
#define   WRITE_NAND 0
#define   READ_NAND BIT(1)
#define   CONT_NAND BIT(29)
#define   CONT_SYSM BIT(30) /* Continue System Memory? */
#define   SDMA_STRT BIT(31)
/* SDMA Address of Main Data */
#define SDMA_MAIN_ADDR 0x44
/* SDMA Address of Spare Data */
#define SDMA_SPARE_ADDR 0x48
/* DPE Version Number */
#define DP_VER 0xD0
#define   DP_VER_OFFSET 16

/* Status bytes between each chunk of spare data */
#define STAT_BYTES 4
#define   NO_ERR 0x00
#define   MAX_CORR_ERR 0x28
#define   UNCORR_ERR 0xFE
#define   ERASED_CHUNK 0xFF

struct mxic_ecc_engine {
	struct device *dev;
	void __iomem *regs;
	int irq;
	struct completion complete;
	struct nand_ecc_engine external_engine;
	struct nand_ecc_engine pipelined_engine;
	struct mutex lock;
};

struct mxic_ecc_ctx {
	/* ECC machinery */
	unsigned int data_step_sz;
	unsigned int oob_step_sz;
	unsigned int parity_sz;
	unsigned int meta_sz;
	u8 *status;
	int steps;

	/* DMA boilerplate */
	struct nand_ecc_req_tweak_ctx req_ctx;
	u8 *oobwithstat;
	struct scatterlist sg[2];
	struct nand_page_io_req *req;
	unsigned int pageoffs;
};

static struct mxic_ecc_engine *ext_ecc_eng_to_mxic(struct nand_ecc_engine *eng)
{
	return container_of(eng, struct mxic_ecc_engine, external_engine);
}

static struct mxic_ecc_engine *pip_ecc_eng_to_mxic(struct nand_ecc_engine *eng)
{
	return container_of(eng, struct mxic_ecc_engine, pipelined_engine);
}

static struct mxic_ecc_engine *nand_to_mxic(struct nand_device *nand)
{
	struct nand_ecc_engine *eng = nand->ecc.engine;

	if (eng->integration == NAND_ECC_ENGINE_INTEGRATION_EXTERNAL)
		return ext_ecc_eng_to_mxic(eng);
	else
		return pip_ecc_eng_to_mxic(eng);
}

static int mxic_ecc_ooblayout_ecc(struct mtd_info *mtd, int section,
				  struct mtd_oob_region *oobregion)
{
	struct nand_device *nand = mtd_to_nanddev(mtd);
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);

	if (section < 0 || section >= ctx->steps)
		return -ERANGE;

	oobregion->offset = (section * ctx->oob_step_sz) + ctx->meta_sz;
	oobregion->length = ctx->parity_sz;

	return 0;
}

static int mxic_ecc_ooblayout_free(struct mtd_info *mtd, int section,
				   struct mtd_oob_region *oobregion)
{
	struct nand_device *nand = mtd_to_nanddev(mtd);
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);

	if (section < 0 || section >= ctx->steps)
		return -ERANGE;

	if (!section) {
		oobregion->offset = 2;
		oobregion->length = ctx->meta_sz - 2;
	} else {
		oobregion->offset = section * ctx->oob_step_sz;
		oobregion->length = ctx->meta_sz;
	}

	return 0;
}

static const struct mtd_ooblayout_ops mxic_ecc_ooblayout_ops = {
	.ecc = mxic_ecc_ooblayout_ecc,
	.free = mxic_ecc_ooblayout_free,
};

static void mxic_ecc_disable_engine(struct mxic_ecc_engine *mxic)
{
	u32 reg;

	reg = readl(mxic->regs + DP_CONFIG);
	reg &= ~ECC_EN;
	writel(reg, mxic->regs + DP_CONFIG);
}

static void mxic_ecc_enable_engine(struct mxic_ecc_engine *mxic)
{
	u32 reg;

	reg = readl(mxic->regs + DP_CONFIG);
	reg |= ECC_EN;
	writel(reg, mxic->regs + DP_CONFIG);
}

static void mxic_ecc_disable_int(struct mxic_ecc_engine *mxic)
{
	writel(0, mxic->regs + INTRPT_SIG_EN);
}

static void mxic_ecc_enable_int(struct mxic_ecc_engine *mxic)
{
	writel(TRANS_CMPLT, mxic->regs + INTRPT_SIG_EN);
}

static irqreturn_t mxic_ecc_isr(int irq, void *dev_id)
{
	struct mxic_ecc_engine *mxic = dev_id;
	u32 sts;

	sts = readl(mxic->regs + INTRPT_STS);
	if (!sts)
		return IRQ_NONE;

	if (sts & TRANS_CMPLT)
		complete(&mxic->complete);

	writel(sts, mxic->regs + INTRPT_STS);

	return IRQ_HANDLED;
}

static int mxic_ecc_init_ctx(struct nand_device *nand, struct device *dev)
{
	struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
	struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
	struct nand_ecc_props *reqs = &nand->ecc.requirements;
	struct nand_ecc_props *user = &nand->ecc.user_conf;
	struct mtd_info *mtd = nanddev_to_mtd(nand);
	int step_size = 0, strength = 0, desired_correction = 0, steps, idx;
	static const int possible_strength[] = {4, 8, 40, 48};
	static const int spare_size[] = {32, 32, 96, 96};
	struct mxic_ecc_ctx *ctx;
	u32 spare_reg;
	int ret;

	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	nand->ecc.ctx.priv = ctx;

	/* Only large page NAND chips may use BCH */
	if (mtd->oobsize < 64) {
		pr_err("BCH cannot be used with small page NAND chips\n");
		return -EINVAL;
	}

	mtd_set_ooblayout(mtd, &mxic_ecc_ooblayout_ops);

	/* Enable all status bits */
	writel(TRANS_CMPLT | SDMA_MAIN | SDMA_SPARE | ECC_ERR |
	       TO_SPARE | TO_MAIN, mxic->regs + INTRPT_STS_EN);

	/* Configure the correction depending on the NAND device topology */
	if (user->step_size && user->strength) {
		step_size = user->step_size;
		strength = user->strength;
	} else if (reqs->step_size && reqs->strength) {
		step_size = reqs->step_size;
		strength = reqs->strength;
	}

	if (step_size && strength) {
		steps = mtd->writesize / step_size;
		desired_correction = steps * strength;
	}

	/* Step size is fixed to 1kiB, strength may vary (4 possible values) */
	conf->step_size = SZ_1K;
	steps = mtd->writesize / conf->step_size;

	ctx->status = devm_kzalloc(dev, steps * sizeof(u8), GFP_KERNEL);
	if (!ctx->status)
		return -ENOMEM;

	if (desired_correction) {
		strength = desired_correction / steps;

		for (idx = 0; idx < ARRAY_SIZE(possible_strength); idx++)
			if (possible_strength[idx] >= strength)
				break;

		idx = min_t(unsigned int, idx,
			    ARRAY_SIZE(possible_strength) - 1);
	} else {
		/* Missing data, maximize the correction */
		idx = ARRAY_SIZE(possible_strength) - 1;
	}

	/* Tune the selected strength until it fits in the OOB area */
	for (; idx >= 0; idx--) {
		if (spare_size[idx] * steps <= mtd->oobsize)
			break;
	}

	/* This engine cannot be used with this NAND device */
	if (idx < 0)
		return -EINVAL;

	/* Configure the engine for the desired strength */
	writel(ECC_TYP(idx), mxic->regs + DP_CONFIG);
	conf->strength = possible_strength[idx];
	spare_reg = readl(mxic->regs + SPARE_SIZE);

	ctx->steps = steps;
	ctx->data_step_sz = mtd->writesize / steps;
	ctx->oob_step_sz = mtd->oobsize / steps;
	ctx->parity_sz = PARITY_SZ(spare_reg);
	ctx->meta_sz = META_SZ(spare_reg);

	/* Ensure buffers will contain enough bytes to store the STAT_BYTES */
	ctx->req_ctx.oob_buffer_size = nanddev_per_page_oobsize(nand) +
					(ctx->steps * STAT_BYTES);
	ret = nand_ecc_init_req_tweaking(&ctx->req_ctx, nand);
	if (ret)
		return ret;

	ctx->oobwithstat = kmalloc(mtd->oobsize + (ctx->steps * STAT_BYTES),
				   GFP_KERNEL);
	if (!ctx->oobwithstat) {
		ret = -ENOMEM;
		goto cleanup_req_tweak;
	}

	sg_init_table(ctx->sg, 2);

	/* Configuration dump and sanity checks */
	dev_err(dev, "DPE version number: %d\n",
		readl(mxic->regs + DP_VER) >> DP_VER_OFFSET);
	dev_err(dev, "Chunk size: %d\n", readl(mxic->regs + CHUNK_SIZE));
	dev_err(dev, "Main size: %d\n", readl(mxic->regs + MAIN_SIZE));
	dev_err(dev, "Spare size: %d\n", SPARE_SZ(spare_reg));
	dev_err(dev, "Rsv size: %ld\n", RSV_SZ(spare_reg));
	dev_err(dev, "Parity size: %d\n", ctx->parity_sz);
	dev_err(dev, "Meta size: %d\n", ctx->meta_sz);

	if ((ctx->meta_sz + ctx->parity_sz + RSV_SZ(spare_reg)) !=
	    SPARE_SZ(spare_reg)) {
		dev_err(dev, "Wrong OOB configuration: %d + %d + %ld != %d\n",
			ctx->meta_sz, ctx->parity_sz, RSV_SZ(spare_reg),
			SPARE_SZ(spare_reg));
		ret = -EINVAL;
		goto free_oobwithstat;
	}

	if (ctx->oob_step_sz != SPARE_SZ(spare_reg)) {
		dev_err(dev, "Wrong OOB configuration: %d != %d\n",
			ctx->oob_step_sz, SPARE_SZ(spare_reg));
		ret = -EINVAL;
		goto free_oobwithstat;
	}

	return 0;

free_oobwithstat:
	kfree(ctx->oobwithstat);
cleanup_req_tweak:
	nand_ecc_cleanup_req_tweaking(&ctx->req_ctx);

	return ret;
}

static int mxic_ecc_init_ctx_external(struct nand_device *nand)
{
	struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
	struct device *dev = nand->ecc.engine->dev;
	int ret;

	dev_info(dev, "Macronix ECC engine in external mode\n");

	ret = mxic_ecc_init_ctx(nand, dev);
	if (ret)
		return ret;

	/* Trigger each step manually */
	writel(1, mxic->regs + CHUNK_CNT);
	writel(BURST_TYP_INCREASING | ECC_PACKED | MEM2MEM,
	       mxic->regs + HC_CONFIG);

	return 0;
}

static int mxic_ecc_init_ctx_pipelined(struct nand_device *nand)
{
	struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
	struct mxic_ecc_ctx *ctx;
	struct device *dev;
	int ret;

	dev = nand_ecc_get_engine_dev(nand->ecc.engine->dev);
	if (!dev)
		return -EINVAL;

	dev_info(dev, "Macronix ECC engine in pipelined/mapping mode\n");

	ret = mxic_ecc_init_ctx(nand, dev);
	if (ret)
		return ret;

	ctx = nand_to_ecc_ctx(nand);

	/* All steps should be handled in one go directly by the internal DMA */
	writel(ctx->steps, mxic->regs + CHUNK_CNT);

	/*
	 * Interleaved ECC scheme cannot be used otherwise factory bad block
	 * markers would be lost. A packed layout is mandatory.
	 */
	writel(BURST_TYP_INCREASING | ECC_PACKED | MAPPING,
	       mxic->regs + HC_CONFIG);

	return 0;
}

static void mxic_ecc_cleanup_ctx(struct nand_device *nand)
{
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);

	if (ctx) {
		nand_ecc_cleanup_req_tweaking(&ctx->req_ctx);
		kfree(ctx->oobwithstat);
	}
}

static int mxic_ecc_data_xfer_wait_for_completion(struct mxic_ecc_engine *mxic)
{
	u32 val;
	int ret;

	if (mxic->irq) {
		reinit_completion(&mxic->complete);
		mxic_ecc_enable_int(mxic);
		ret = wait_for_completion_timeout(&mxic->complete,
						  msecs_to_jiffies(1000));
		mxic_ecc_disable_int(mxic);
	} else {
		ret = readl_poll_timeout(mxic->regs + INTRPT_STS, val,
					 val & TRANS_CMPLT, 10, USEC_PER_SEC);
		writel(val, mxic->regs + INTRPT_STS);
	}

	if (ret) {
		dev_err(mxic->dev, "Timeout on data xfer completion\n");
		return -ETIMEDOUT;
	}

	return 0;
}

static int mxic_ecc_process_data(struct mxic_ecc_engine *mxic,
				 unsigned int direction)
{
	unsigned int dir = (direction == NAND_PAGE_READ) ?
			   READ_NAND : WRITE_NAND;
	int ret;

	mxic_ecc_enable_engine(mxic);

	/* Trigger processing */
	writel(SDMA_STRT | dir, mxic->regs + SDMA_CTRL);

	/* Wait for completion */
	ret = mxic_ecc_data_xfer_wait_for_completion(mxic);

	mxic_ecc_disable_engine(mxic);

	return ret;
}

int mxic_ecc_process_data_pipelined(struct nand_ecc_engine *eng,
				    unsigned int direction, dma_addr_t dirmap)
{
	struct mxic_ecc_engine *mxic = pip_ecc_eng_to_mxic(eng);

	if (dirmap)
		writel(dirmap, mxic->regs + HC_SLV_ADDR);

	return mxic_ecc_process_data(mxic, direction);
}
EXPORT_SYMBOL_GPL(mxic_ecc_process_data_pipelined);

static void mxic_ecc_extract_status_bytes(struct mxic_ecc_ctx *ctx)
{
	u8 *buf = ctx->oobwithstat;
	int next_stat_pos;
	int step;

	/* Extract the ECC status */
	for (step = 0; step < ctx->steps; step++) {
		next_stat_pos = ctx->oob_step_sz +
				((STAT_BYTES + ctx->oob_step_sz) * step);

		ctx->status[step] = buf[next_stat_pos];
	}
}

static void mxic_ecc_reconstruct_oobbuf(struct mxic_ecc_ctx *ctx,
					u8 *dst, const u8 *src)
{
	int step;

	/* Reconstruct the OOB buffer linearly (without the ECC status bytes) */
	for (step = 0; step < ctx->steps; step++)
		memcpy(dst + (step * ctx->oob_step_sz),
		       src + (step * (ctx->oob_step_sz + STAT_BYTES)),
		       ctx->oob_step_sz);
}

static void mxic_ecc_add_room_in_oobbuf(struct mxic_ecc_ctx *ctx,
					u8 *dst, const u8 *src)
{
	int step;

	/* Add some space in the OOB buffer for the status bytes */
	for (step = 0; step < ctx->steps; step++)
		memcpy(dst + (step * (ctx->oob_step_sz + STAT_BYTES)),
		       src + (step * ctx->oob_step_sz),
		       ctx->oob_step_sz);
}

static int mxic_ecc_count_biterrs(struct mxic_ecc_engine *mxic,
				  struct nand_device *nand)
{
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);
	struct mtd_info *mtd = nanddev_to_mtd(nand);
	struct device *dev = mxic->dev;
	unsigned int max_bf = 0;
	bool failure = false;
	int step;

	for (step = 0; step < ctx->steps; step++) {
		u8 stat = ctx->status[step];

		if (stat == NO_ERR) {
			dev_dbg(dev, "ECC step %d: no error\n", step);
		} else if (stat == ERASED_CHUNK) {
			dev_dbg(dev, "ECC step %d: erased\n", step);
		} else if (stat == UNCORR_ERR || stat > MAX_CORR_ERR) {
			dev_dbg(dev, "ECC step %d: uncorrectable\n", step);
			mtd->ecc_stats.failed++;
			failure = true;
		} else {
			dev_dbg(dev, "ECC step %d: %d bits corrected\n",
				step, stat);
			max_bf = max_t(unsigned int, max_bf, stat);
			mtd->ecc_stats.corrected += stat;
		}
	}

	return failure ? -EBADMSG : max_bf;
}

/* External ECC engine helpers */
static int mxic_ecc_prepare_io_req_external(struct nand_device *nand,
					    struct nand_page_io_req *req)
{
	struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);
	struct mtd_info *mtd = nanddev_to_mtd(nand);
	int offset, nents, step, ret;

	if (req->mode == MTD_OPS_RAW)
		return 0;

	nand_ecc_tweak_req(&ctx->req_ctx, req);
	ctx->req = req;

	if (req->type == NAND_PAGE_READ)
		return 0;

	mxic_ecc_add_room_in_oobbuf(ctx, ctx->oobwithstat,
				    ctx->req->oobbuf.out);

	sg_set_buf(&ctx->sg[0], req->databuf.out, req->datalen);
	sg_set_buf(&ctx->sg[1], ctx->oobwithstat,
		   req->ooblen + (ctx->steps * STAT_BYTES));

	nents = dma_map_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL);
	if (!nents)
		return -EINVAL;

	mutex_lock(&mxic->lock);

	for (step = 0; step < ctx->steps; step++) {
		writel(sg_dma_address(&ctx->sg[0]) + (step * ctx->data_step_sz),
		       mxic->regs + SDMA_MAIN_ADDR);
		writel(sg_dma_address(&ctx->sg[1]) + (step * (ctx->oob_step_sz + STAT_BYTES)),
		       mxic->regs + SDMA_SPARE_ADDR);
		ret = mxic_ecc_process_data(mxic, ctx->req->type);
		if (ret)
			break;
	}

	mutex_unlock(&mxic->lock);

	dma_unmap_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL);

	if (ret)
		return ret;

	/* Retrieve the calculated ECC bytes */
	for (step = 0; step < ctx->steps; step++) {
		offset = ctx->meta_sz + (step * ctx->oob_step_sz);
		mtd_ooblayout_get_eccbytes(mtd,
					   (u8 *)ctx->req->oobbuf.out + offset,
					   ctx->oobwithstat + (step * STAT_BYTES),
					   step * ctx->parity_sz,
					   ctx->parity_sz);
	}

	return 0;
}

static int mxic_ecc_finish_io_req_external(struct nand_device *nand,
					   struct nand_page_io_req *req)
{
	struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);
	int nents, step, ret;

	if (req->mode == MTD_OPS_RAW)
		return 0;

	if (req->type == NAND_PAGE_WRITE) {
		nand_ecc_restore_req(&ctx->req_ctx, req);
		return 0;
	}

	/* Copy the OOB buffer and add room for the ECC engine status bytes */
	mxic_ecc_add_room_in_oobbuf(ctx, ctx->oobwithstat, ctx->req->oobbuf.in);

	sg_set_buf(&ctx->sg[0], req->databuf.in, req->datalen);
	sg_set_buf(&ctx->sg[1], ctx->oobwithstat,
		   req->ooblen + (ctx->steps * STAT_BYTES));
	nents = dma_map_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL);
	if (!nents)
		return -EINVAL;

	mutex_lock(&mxic->lock);

	for (step = 0; step < ctx->steps; step++) {
		writel(sg_dma_address(&ctx->sg[0]) + (step * ctx->data_step_sz),
		       mxic->regs + SDMA_MAIN_ADDR);
		writel(sg_dma_address(&ctx->sg[1]) + (step * (ctx->oob_step_sz + STAT_BYTES)),
		       mxic->regs + SDMA_SPARE_ADDR);
		ret = mxic_ecc_process_data(mxic, ctx->req->type);
		if (ret)
			break;
	}

	mutex_unlock(&mxic->lock);

	dma_unmap_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL);

	if (ret) {
		nand_ecc_restore_req(&ctx->req_ctx, req);
		return ret;
	}

	/* Extract the status bytes and reconstruct the buffer */
	mxic_ecc_extract_status_bytes(ctx);
	mxic_ecc_reconstruct_oobbuf(ctx, ctx->req->oobbuf.in, ctx->oobwithstat);

	nand_ecc_restore_req(&ctx->req_ctx, req);

	return mxic_ecc_count_biterrs(mxic, nand);
}

/* Pipelined ECC engine helpers */
static int mxic_ecc_prepare_io_req_pipelined(struct nand_device *nand,
					     struct nand_page_io_req *req)
{
	struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);
	int nents;

	if (req->mode == MTD_OPS_RAW)
		return 0;

	nand_ecc_tweak_req(&ctx->req_ctx, req);
	ctx->req = req;

	/* Copy the OOB buffer and add room for the ECC engine status bytes */
	mxic_ecc_add_room_in_oobbuf(ctx, ctx->oobwithstat, ctx->req->oobbuf.in);

	sg_set_buf(&ctx->sg[0], req->databuf.in, req->datalen);
	sg_set_buf(&ctx->sg[1], ctx->oobwithstat,
		   req->ooblen + (ctx->steps * STAT_BYTES));

	nents = dma_map_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL);
	if (!nents)
		return -EINVAL;

	mutex_lock(&mxic->lock);

	writel(sg_dma_address(&ctx->sg[0]), mxic->regs + SDMA_MAIN_ADDR);
	writel(sg_dma_address(&ctx->sg[1]), mxic->regs + SDMA_SPARE_ADDR);

	return 0;
}

static int mxic_ecc_finish_io_req_pipelined(struct nand_device *nand,
					    struct nand_page_io_req *req)
{
	struct mxic_ecc_engine *mxic = nand_to_mxic(nand);
	struct mxic_ecc_ctx *ctx = nand_to_ecc_ctx(nand);
	int ret = 0;

	if (req->mode == MTD_OPS_RAW)
		return 0;

	mutex_unlock(&mxic->lock);

	dma_unmap_sg(mxic->dev, ctx->sg, 2, DMA_BIDIRECTIONAL);

	if (req->type == NAND_PAGE_READ) {
		mxic_ecc_extract_status_bytes(ctx);
		mxic_ecc_reconstruct_oobbuf(ctx, ctx->req->oobbuf.in,
					    ctx->oobwithstat);
		ret = mxic_ecc_count_biterrs(mxic, nand);
	}

	nand_ecc_restore_req(&ctx->req_ctx, req);

	return ret;
}

static struct nand_ecc_engine_ops mxic_ecc_engine_external_ops = {
	.init_ctx = mxic_ecc_init_ctx_external,
	.cleanup_ctx = mxic_ecc_cleanup_ctx,
	.prepare_io_req = mxic_ecc_prepare_io_req_external,
	.finish_io_req = mxic_ecc_finish_io_req_external,
};

static struct nand_ecc_engine_ops mxic_ecc_engine_pipelined_ops = {
	.init_ctx = mxic_ecc_init_ctx_pipelined,
	.cleanup_ctx = mxic_ecc_cleanup_ctx,
	.prepare_io_req = mxic_ecc_prepare_io_req_pipelined,
	.finish_io_req = mxic_ecc_finish_io_req_pipelined,
};

struct nand_ecc_engine_ops *mxic_ecc_get_pipelined_ops(void)
{
	return &mxic_ecc_engine_pipelined_ops;
}
EXPORT_SYMBOL_GPL(mxic_ecc_get_pipelined_ops);

static struct platform_device *
mxic_ecc_get_pdev(struct platform_device *spi_pdev)
{
	struct platform_device *eng_pdev;
	struct device_node *np;

	/* Retrieve the nand-ecc-engine phandle */
	np = of_parse_phandle(spi_pdev->dev.of_node, "nand-ecc-engine", 0);
	if (!np)
		return NULL;

	/* Jump to the engine's device node */
	eng_pdev = of_find_device_by_node(np);
	of_node_put(np);

	return eng_pdev;
}

void mxic_ecc_put_pipelined_engine(struct nand_ecc_engine *eng)
{
	struct mxic_ecc_engine *mxic = pip_ecc_eng_to_mxic(eng);

	platform_device_put(to_platform_device(mxic->dev));
}
EXPORT_SYMBOL_GPL(mxic_ecc_put_pipelined_engine);

struct nand_ecc_engine *
mxic_ecc_get_pipelined_engine(struct platform_device *spi_pdev)
{
	struct platform_device *eng_pdev;
	struct mxic_ecc_engine *mxic;

	eng_pdev = mxic_ecc_get_pdev(spi_pdev);
	if (!eng_pdev)
		return ERR_PTR(-ENODEV);

	mxic = platform_get_drvdata(eng_pdev);
	if (!mxic) {
		platform_device_put(eng_pdev);
		return ERR_PTR(-EPROBE_DEFER);
	}

	return &mxic->pipelined_engine;
}
EXPORT_SYMBOL_GPL(mxic_ecc_get_pipelined_engine);

/*
 * Only the external ECC engine is exported as the pipelined is SoC specific, so
 * it is registered directly by the drivers that wrap it.
 */
static int mxic_ecc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mxic_ecc_engine *mxic;
	int ret;

	mxic = devm_kzalloc(&pdev->dev, sizeof(*mxic), GFP_KERNEL);
	if (!mxic)
		return -ENOMEM;

	mxic->dev = &pdev->dev;

	/*
	 * Both memory regions for the ECC engine itself and the AXI slave
	 * address are mandatory.
	 */
	mxic->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(mxic->regs)) {
		dev_err(&pdev->dev, "Missing memory region\n");
		return PTR_ERR(mxic->regs);
	}

	mxic_ecc_disable_engine(mxic);
	mxic_ecc_disable_int(mxic);

	/* IRQ is optional yet much more efficient */
	mxic->irq = platform_get_irq_byname_optional(pdev, "ecc-engine");
	if (mxic->irq > 0) {
		ret = devm_request_irq(&pdev->dev, mxic->irq, mxic_ecc_isr, 0,
				       "mxic-ecc", mxic);
		if (ret)
			return ret;
	} else {
		dev_info(dev, "Invalid or missing IRQ, fallback to polling\n");
		mxic->irq = 0;
	}

	mutex_init(&mxic->lock);

	/*
	 * In external mode, the device is the ECC engine. In pipelined mode,
	 * the device is the host controller. The device is used to match the
	 * right ECC engine based on the DT properties.
	 */
	mxic->external_engine.dev = &pdev->dev;
	mxic->external_engine.integration = NAND_ECC_ENGINE_INTEGRATION_EXTERNAL;
	mxic->external_engine.ops = &mxic_ecc_engine_external_ops;

	nand_ecc_register_on_host_hw_engine(&mxic->external_engine);

	platform_set_drvdata(pdev, mxic);

	return 0;
}

static int mxic_ecc_remove(struct platform_device *pdev)
{
	struct mxic_ecc_engine *mxic = platform_get_drvdata(pdev);

	nand_ecc_unregister_on_host_hw_engine(&mxic->external_engine);

	return 0;
}

static const struct of_device_id mxic_ecc_of_ids[] = {
	{
		.compatible = "mxicy,nand-ecc-engine-rev3",
	},
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mxic_ecc_of_ids);

static struct platform_driver mxic_ecc_driver = {
	.driver	= {
		.name = "mxic-nand-ecc-engine",
		.of_match_table = mxic_ecc_of_ids,
	},
	.probe = mxic_ecc_probe,
	.remove	= mxic_ecc_remove,
};
module_platform_driver(mxic_ecc_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
MODULE_DESCRIPTION("Macronix NAND hardware ECC controller");
