1b849f8b5STudor Ambarus // SPDX-License-Identifier: GPL-2.0
293db446aSBoris Brezillon /*
393db446aSBoris Brezillon  * Copyright 2017 ATMEL
493db446aSBoris Brezillon  * Copyright 2017 Free Electrons
593db446aSBoris Brezillon  *
693db446aSBoris Brezillon  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
793db446aSBoris Brezillon  *
893db446aSBoris Brezillon  * Derived from the atmel_nand.c driver which contained the following
993db446aSBoris Brezillon  * copyrights:
1093db446aSBoris Brezillon  *
1193db446aSBoris Brezillon  *   Copyright 2003 Rick Bronson
1293db446aSBoris Brezillon  *
1393db446aSBoris Brezillon  *   Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8)
1493db446aSBoris Brezillon  *	Copyright 2001 Thomas Gleixner (gleixner@autronix.de)
1593db446aSBoris Brezillon  *
1693db446aSBoris Brezillon  *   Derived from drivers/mtd/spia.c (removed in v3.8)
1793db446aSBoris Brezillon  *	Copyright 2000 Steven J. Hill (sjhill@cotw.com)
1893db446aSBoris Brezillon  *
1993db446aSBoris Brezillon  *
2093db446aSBoris Brezillon  *   Add Hardware ECC support for AT91SAM9260 / AT91SAM9263
2193db446aSBoris Brezillon  *	Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright 2007
2293db446aSBoris Brezillon  *
2393db446aSBoris Brezillon  *   Derived from Das U-Boot source code
2493db446aSBoris Brezillon  *	(u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c)
2593db446aSBoris Brezillon  *	Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
2693db446aSBoris Brezillon  *
2793db446aSBoris Brezillon  *   Add Programmable Multibit ECC support for various AT91 SoC
2893db446aSBoris Brezillon  *	Copyright 2012 ATMEL, Hong Xu
2993db446aSBoris Brezillon  *
3093db446aSBoris Brezillon  *   Add Nand Flash Controller support for SAMA5 SoC
3193db446aSBoris Brezillon  *	Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com)
3293db446aSBoris Brezillon  *
3393db446aSBoris Brezillon  * A few words about the naming convention in this file. This convention
3493db446aSBoris Brezillon  * applies to structure and function names.
3593db446aSBoris Brezillon  *
3693db446aSBoris Brezillon  * Prefixes:
3793db446aSBoris Brezillon  *
3893db446aSBoris Brezillon  * - atmel_nand_: all generic structures/functions
3993db446aSBoris Brezillon  * - atmel_smc_nand_: all structures/functions specific to the SMC interface
4093db446aSBoris Brezillon  *		      (at91sam9 and avr32 SoCs)
4193db446aSBoris Brezillon  * - atmel_hsmc_nand_: all structures/functions specific to the HSMC interface
4293db446aSBoris Brezillon  *		       (sama5 SoCs and later)
4393db446aSBoris Brezillon  * - atmel_nfc_: all structures/functions used to manipulate the NFC sub-block
4493db446aSBoris Brezillon  *		 that is available in the HSMC block
4593db446aSBoris Brezillon  * - <soc>_nand_: all SoC specific structures/functions
4693db446aSBoris Brezillon  */
4793db446aSBoris Brezillon 
4893db446aSBoris Brezillon #include <linux/clk.h>
4993db446aSBoris Brezillon #include <linux/dma-mapping.h>
5093db446aSBoris Brezillon #include <linux/dmaengine.h>
5193db446aSBoris Brezillon #include <linux/genalloc.h>
5293db446aSBoris Brezillon #include <linux/gpio/consumer.h>
5393db446aSBoris Brezillon #include <linux/interrupt.h>
5493db446aSBoris Brezillon #include <linux/mfd/syscon.h>
5593db446aSBoris Brezillon #include <linux/mfd/syscon/atmel-matrix.h>
5693db446aSBoris Brezillon #include <linux/mfd/syscon/atmel-smc.h>
5793db446aSBoris Brezillon #include <linux/module.h>
5893db446aSBoris Brezillon #include <linux/mtd/rawnand.h>
5993db446aSBoris Brezillon #include <linux/of_address.h>
6093db446aSBoris Brezillon #include <linux/of_irq.h>
6193db446aSBoris Brezillon #include <linux/of_platform.h>
6293db446aSBoris Brezillon #include <linux/iopoll.h>
6393db446aSBoris Brezillon #include <linux/platform_device.h>
6493db446aSBoris Brezillon #include <linux/regmap.h>
65ccf20cccSTudor Ambarus #include <soc/at91/atmel-sfr.h>
6693db446aSBoris Brezillon 
6793db446aSBoris Brezillon #include "pmecc.h"
6893db446aSBoris Brezillon 
6993db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG			0x0
7093db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_SPARESIZE(x)		(((x) / 4) << 24)
7193db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_SPARESIZE_MASK	GENMASK(30, 24)
7293db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_DTO(cyc, mul)	(((cyc) << 16) | ((mul) << 20))
7393db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_DTO_MAX		GENMASK(22, 16)
7493db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_RBEDGE		BIT(13)
7593db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_FALLING_EDGE		BIT(12)
7693db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_RSPARE		BIT(9)
7793db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_WSPARE		BIT(8)
7893db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_PAGESIZE_MASK	GENMASK(2, 0)
7993db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CFG_PAGESIZE(x)		(fls((x) / 512) - 1)
8093db446aSBoris Brezillon 
8193db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CTRL			0x4
8293db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CTRL_EN			BIT(0)
8393db446aSBoris Brezillon #define ATMEL_HSMC_NFC_CTRL_DIS			BIT(1)
8493db446aSBoris Brezillon 
8593db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR			0x8
8693db446aSBoris Brezillon #define ATMEL_HSMC_NFC_IER			0xc
8793db446aSBoris Brezillon #define ATMEL_HSMC_NFC_IDR			0x10
8893db446aSBoris Brezillon #define ATMEL_HSMC_NFC_IMR			0x14
8993db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_ENABLED		BIT(1)
9093db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_RB_RISE		BIT(4)
9193db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_RB_FALL		BIT(5)
9293db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_BUSY			BIT(8)
9393db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_WR			BIT(11)
9493db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_CSID			GENMASK(14, 12)
9593db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_XFRDONE		BIT(16)
9693db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_CMDDONE		BIT(17)
9793db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_DTOE			BIT(20)
9893db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_UNDEF			BIT(21)
9993db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_AWB			BIT(22)
10093db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_NFCASE		BIT(23)
10193db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_ERRORS		(ATMEL_HSMC_NFC_SR_DTOE | \
10293db446aSBoris Brezillon 						 ATMEL_HSMC_NFC_SR_UNDEF | \
10393db446aSBoris Brezillon 						 ATMEL_HSMC_NFC_SR_AWB | \
10493db446aSBoris Brezillon 						 ATMEL_HSMC_NFC_SR_NFCASE)
10593db446aSBoris Brezillon #define ATMEL_HSMC_NFC_SR_RBEDGE(x)		BIT((x) + 24)
10693db446aSBoris Brezillon 
10793db446aSBoris Brezillon #define ATMEL_HSMC_NFC_ADDR			0x18
10893db446aSBoris Brezillon #define ATMEL_HSMC_NFC_BANK			0x1c
10993db446aSBoris Brezillon 
11093db446aSBoris Brezillon #define ATMEL_NFC_MAX_RB_ID			7
11193db446aSBoris Brezillon 
11293db446aSBoris Brezillon #define ATMEL_NFC_SRAM_SIZE			0x2400
11393db446aSBoris Brezillon 
11493db446aSBoris Brezillon #define ATMEL_NFC_CMD(pos, cmd)			((cmd) << (((pos) * 8) + 2))
11593db446aSBoris Brezillon #define ATMEL_NFC_VCMD2				BIT(18)
11693db446aSBoris Brezillon #define ATMEL_NFC_ACYCLE(naddrs)		((naddrs) << 19)
11793db446aSBoris Brezillon #define ATMEL_NFC_CSID(cs)			((cs) << 22)
11893db446aSBoris Brezillon #define ATMEL_NFC_DATAEN			BIT(25)
11993db446aSBoris Brezillon #define ATMEL_NFC_NFCWR				BIT(26)
12093db446aSBoris Brezillon 
12193db446aSBoris Brezillon #define ATMEL_NFC_MAX_ADDR_CYCLES		5
12293db446aSBoris Brezillon 
12393db446aSBoris Brezillon #define ATMEL_NAND_ALE_OFFSET			BIT(21)
12493db446aSBoris Brezillon #define ATMEL_NAND_CLE_OFFSET			BIT(22)
12593db446aSBoris Brezillon 
12693db446aSBoris Brezillon #define DEFAULT_TIMEOUT_MS			1000
12793db446aSBoris Brezillon #define MIN_DMA_LEN				128
12893db446aSBoris Brezillon 
129efc6362cSPeter Rosin static bool atmel_nand_avoid_dma __read_mostly;
130efc6362cSPeter Rosin 
131efc6362cSPeter Rosin MODULE_PARM_DESC(avoiddma, "Avoid using DMA");
132efc6362cSPeter Rosin module_param_named(avoiddma, atmel_nand_avoid_dma, bool, 0400);
133efc6362cSPeter Rosin 
13493db446aSBoris Brezillon enum atmel_nand_rb_type {
13593db446aSBoris Brezillon 	ATMEL_NAND_NO_RB,
13693db446aSBoris Brezillon 	ATMEL_NAND_NATIVE_RB,
13793db446aSBoris Brezillon 	ATMEL_NAND_GPIO_RB,
13893db446aSBoris Brezillon };
13993db446aSBoris Brezillon 
14093db446aSBoris Brezillon struct atmel_nand_rb {
14193db446aSBoris Brezillon 	enum atmel_nand_rb_type type;
14293db446aSBoris Brezillon 	union {
14393db446aSBoris Brezillon 		struct gpio_desc *gpio;
14493db446aSBoris Brezillon 		int id;
14593db446aSBoris Brezillon 	};
14693db446aSBoris Brezillon };
14793db446aSBoris Brezillon 
14893db446aSBoris Brezillon struct atmel_nand_cs {
14993db446aSBoris Brezillon 	int id;
15093db446aSBoris Brezillon 	struct atmel_nand_rb rb;
15193db446aSBoris Brezillon 	struct gpio_desc *csgpio;
15293db446aSBoris Brezillon 	struct {
15393db446aSBoris Brezillon 		void __iomem *virt;
15493db446aSBoris Brezillon 		dma_addr_t dma;
15593db446aSBoris Brezillon 	} io;
15693db446aSBoris Brezillon 
15793db446aSBoris Brezillon 	struct atmel_smc_cs_conf smcconf;
15893db446aSBoris Brezillon };
15993db446aSBoris Brezillon 
16093db446aSBoris Brezillon struct atmel_nand {
16193db446aSBoris Brezillon 	struct list_head node;
16293db446aSBoris Brezillon 	struct device *dev;
16393db446aSBoris Brezillon 	struct nand_chip base;
16493db446aSBoris Brezillon 	struct atmel_nand_cs *activecs;
16593db446aSBoris Brezillon 	struct atmel_pmecc_user *pmecc;
16693db446aSBoris Brezillon 	struct gpio_desc *cdgpio;
16793db446aSBoris Brezillon 	int numcs;
16879c610abSKees Cook 	struct atmel_nand_cs cs[] __counted_by(numcs);
16993db446aSBoris Brezillon };
17093db446aSBoris Brezillon 
to_atmel_nand(struct nand_chip * chip)17193db446aSBoris Brezillon static inline struct atmel_nand *to_atmel_nand(struct nand_chip *chip)
17293db446aSBoris Brezillon {
17393db446aSBoris Brezillon 	return container_of(chip, struct atmel_nand, base);
17493db446aSBoris Brezillon }
17593db446aSBoris Brezillon 
17693db446aSBoris Brezillon enum atmel_nfc_data_xfer {
17793db446aSBoris Brezillon 	ATMEL_NFC_NO_DATA,
17893db446aSBoris Brezillon 	ATMEL_NFC_READ_DATA,
17993db446aSBoris Brezillon 	ATMEL_NFC_WRITE_DATA,
18093db446aSBoris Brezillon };
18193db446aSBoris Brezillon 
18293db446aSBoris Brezillon struct atmel_nfc_op {
18393db446aSBoris Brezillon 	u8 cs;
18493db446aSBoris Brezillon 	u8 ncmds;
18593db446aSBoris Brezillon 	u8 cmds[2];
18693db446aSBoris Brezillon 	u8 naddrs;
18793db446aSBoris Brezillon 	u8 addrs[5];
18893db446aSBoris Brezillon 	enum atmel_nfc_data_xfer data;
18993db446aSBoris Brezillon 	u32 wait;
19093db446aSBoris Brezillon 	u32 errors;
19193db446aSBoris Brezillon };
19293db446aSBoris Brezillon 
19393db446aSBoris Brezillon struct atmel_nand_controller;
19493db446aSBoris Brezillon struct atmel_nand_controller_caps;
19593db446aSBoris Brezillon 
19693db446aSBoris Brezillon struct atmel_nand_controller_ops {
19793db446aSBoris Brezillon 	int (*probe)(struct platform_device *pdev,
19893db446aSBoris Brezillon 		     const struct atmel_nand_controller_caps *caps);
19993db446aSBoris Brezillon 	int (*remove)(struct atmel_nand_controller *nc);
20093db446aSBoris Brezillon 	void (*nand_init)(struct atmel_nand_controller *nc,
20193db446aSBoris Brezillon 			  struct atmel_nand *nand);
202577e010cSMiquel Raynal 	int (*ecc_init)(struct nand_chip *chip);
2034c46667bSMiquel Raynal 	int (*setup_interface)(struct atmel_nand *nand, int csline,
2044c46667bSMiquel Raynal 			       const struct nand_interface_config *conf);
20503b3e0c2SBoris Brezillon 	int (*exec_op)(struct atmel_nand *nand,
20603b3e0c2SBoris Brezillon 		       const struct nand_operation *op, bool check_only);
20793db446aSBoris Brezillon };
20893db446aSBoris Brezillon 
20993db446aSBoris Brezillon struct atmel_nand_controller_caps {
21093db446aSBoris Brezillon 	bool has_dma;
21193db446aSBoris Brezillon 	bool legacy_of_bindings;
21293db446aSBoris Brezillon 	u32 ale_offs;
21393db446aSBoris Brezillon 	u32 cle_offs;
214e2c19c50STudor Ambarus 	const char *ebi_csa_regmap_name;
21593db446aSBoris Brezillon 	const struct atmel_nand_controller_ops *ops;
21693db446aSBoris Brezillon };
21793db446aSBoris Brezillon 
21893db446aSBoris Brezillon struct atmel_nand_controller {
2197da45139SMiquel Raynal 	struct nand_controller base;
22093db446aSBoris Brezillon 	const struct atmel_nand_controller_caps *caps;
22193db446aSBoris Brezillon 	struct device *dev;
22293db446aSBoris Brezillon 	struct regmap *smc;
22393db446aSBoris Brezillon 	struct dma_chan *dmac;
22493db446aSBoris Brezillon 	struct atmel_pmecc *pmecc;
22593db446aSBoris Brezillon 	struct list_head chips;
22693db446aSBoris Brezillon 	struct clk *mck;
22793db446aSBoris Brezillon };
22893db446aSBoris Brezillon 
22993db446aSBoris Brezillon static inline struct atmel_nand_controller *
to_nand_controller(struct nand_controller * ctl)2307da45139SMiquel Raynal to_nand_controller(struct nand_controller *ctl)
23193db446aSBoris Brezillon {
23293db446aSBoris Brezillon 	return container_of(ctl, struct atmel_nand_controller, base);
23393db446aSBoris Brezillon }
23493db446aSBoris Brezillon 
235ccf20cccSTudor Ambarus struct atmel_smc_nand_ebi_csa_cfg {
236ccf20cccSTudor Ambarus 	u32 offs;
237ccf20cccSTudor Ambarus 	u32 nfd0_on_d16;
238ccf20cccSTudor Ambarus };
239ccf20cccSTudor Ambarus 
24093db446aSBoris Brezillon struct atmel_smc_nand_controller {
24193db446aSBoris Brezillon 	struct atmel_nand_controller base;
242e2c19c50STudor Ambarus 	struct regmap *ebi_csa_regmap;
243ccf20cccSTudor Ambarus 	struct atmel_smc_nand_ebi_csa_cfg *ebi_csa;
24493db446aSBoris Brezillon };
24593db446aSBoris Brezillon 
24693db446aSBoris Brezillon static inline struct atmel_smc_nand_controller *
to_smc_nand_controller(struct nand_controller * ctl)2477da45139SMiquel Raynal to_smc_nand_controller(struct nand_controller *ctl)
24893db446aSBoris Brezillon {
24993db446aSBoris Brezillon 	return container_of(to_nand_controller(ctl),
25093db446aSBoris Brezillon 			    struct atmel_smc_nand_controller, base);
25193db446aSBoris Brezillon }
25293db446aSBoris Brezillon 
25393db446aSBoris Brezillon struct atmel_hsmc_nand_controller {
25493db446aSBoris Brezillon 	struct atmel_nand_controller base;
25593db446aSBoris Brezillon 	struct {
25693db446aSBoris Brezillon 		struct gen_pool *pool;
25793db446aSBoris Brezillon 		void __iomem *virt;
25893db446aSBoris Brezillon 		dma_addr_t dma;
25993db446aSBoris Brezillon 	} sram;
26093db446aSBoris Brezillon 	const struct atmel_hsmc_reg_layout *hsmc_layout;
26193db446aSBoris Brezillon 	struct regmap *io;
26293db446aSBoris Brezillon 	struct atmel_nfc_op op;
26393db446aSBoris Brezillon 	struct completion complete;
26403b3e0c2SBoris Brezillon 	u32 cfg;
26593db446aSBoris Brezillon 	int irq;
26693db446aSBoris Brezillon 
26793db446aSBoris Brezillon 	/* Only used when instantiating from legacy DT bindings. */
26893db446aSBoris Brezillon 	struct clk *clk;
26993db446aSBoris Brezillon };
27093db446aSBoris Brezillon 
27193db446aSBoris Brezillon static inline struct atmel_hsmc_nand_controller *
to_hsmc_nand_controller(struct nand_controller * ctl)2727da45139SMiquel Raynal to_hsmc_nand_controller(struct nand_controller *ctl)
27393db446aSBoris Brezillon {
27493db446aSBoris Brezillon 	return container_of(to_nand_controller(ctl),
27593db446aSBoris Brezillon 			    struct atmel_hsmc_nand_controller, base);
27693db446aSBoris Brezillon }
27793db446aSBoris Brezillon 
atmel_nfc_op_done(struct atmel_nfc_op * op,u32 status)27893db446aSBoris Brezillon static bool atmel_nfc_op_done(struct atmel_nfc_op *op, u32 status)
27993db446aSBoris Brezillon {
28093db446aSBoris Brezillon 	op->errors |= status & ATMEL_HSMC_NFC_SR_ERRORS;
28193db446aSBoris Brezillon 	op->wait ^= status & op->wait;
28293db446aSBoris Brezillon 
28393db446aSBoris Brezillon 	return !op->wait || op->errors;
28493db446aSBoris Brezillon }
28593db446aSBoris Brezillon 
atmel_nfc_interrupt(int irq,void * data)28693db446aSBoris Brezillon static irqreturn_t atmel_nfc_interrupt(int irq, void *data)
28793db446aSBoris Brezillon {
28893db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc = data;
28993db446aSBoris Brezillon 	u32 sr, rcvd;
29093db446aSBoris Brezillon 	bool done;
29193db446aSBoris Brezillon 
29293db446aSBoris Brezillon 	regmap_read(nc->base.smc, ATMEL_HSMC_NFC_SR, &sr);
29393db446aSBoris Brezillon 
29493db446aSBoris Brezillon 	rcvd = sr & (nc->op.wait | ATMEL_HSMC_NFC_SR_ERRORS);
29593db446aSBoris Brezillon 	done = atmel_nfc_op_done(&nc->op, sr);
29693db446aSBoris Brezillon 
29793db446aSBoris Brezillon 	if (rcvd)
29893db446aSBoris Brezillon 		regmap_write(nc->base.smc, ATMEL_HSMC_NFC_IDR, rcvd);
29993db446aSBoris Brezillon 
30093db446aSBoris Brezillon 	if (done)
30193db446aSBoris Brezillon 		complete(&nc->complete);
30293db446aSBoris Brezillon 
30393db446aSBoris Brezillon 	return rcvd ? IRQ_HANDLED : IRQ_NONE;
30493db446aSBoris Brezillon }
30593db446aSBoris Brezillon 
atmel_nfc_wait(struct atmel_hsmc_nand_controller * nc,bool poll,unsigned int timeout_ms)30693db446aSBoris Brezillon static int atmel_nfc_wait(struct atmel_hsmc_nand_controller *nc, bool poll,
30793db446aSBoris Brezillon 			  unsigned int timeout_ms)
30893db446aSBoris Brezillon {
30993db446aSBoris Brezillon 	int ret;
31093db446aSBoris Brezillon 
31193db446aSBoris Brezillon 	if (!timeout_ms)
31293db446aSBoris Brezillon 		timeout_ms = DEFAULT_TIMEOUT_MS;
31393db446aSBoris Brezillon 
31493db446aSBoris Brezillon 	if (poll) {
31593db446aSBoris Brezillon 		u32 status;
31693db446aSBoris Brezillon 
31793db446aSBoris Brezillon 		ret = regmap_read_poll_timeout(nc->base.smc,
31893db446aSBoris Brezillon 					       ATMEL_HSMC_NFC_SR, status,
31993db446aSBoris Brezillon 					       atmel_nfc_op_done(&nc->op,
32093db446aSBoris Brezillon 								 status),
32193db446aSBoris Brezillon 					       0, timeout_ms * 1000);
32293db446aSBoris Brezillon 	} else {
32393db446aSBoris Brezillon 		init_completion(&nc->complete);
32493db446aSBoris Brezillon 		regmap_write(nc->base.smc, ATMEL_HSMC_NFC_IER,
32593db446aSBoris Brezillon 			     nc->op.wait | ATMEL_HSMC_NFC_SR_ERRORS);
32693db446aSBoris Brezillon 		ret = wait_for_completion_timeout(&nc->complete,
32793db446aSBoris Brezillon 						msecs_to_jiffies(timeout_ms));
32893db446aSBoris Brezillon 		if (!ret)
32993db446aSBoris Brezillon 			ret = -ETIMEDOUT;
33093db446aSBoris Brezillon 		else
33193db446aSBoris Brezillon 			ret = 0;
33293db446aSBoris Brezillon 
33393db446aSBoris Brezillon 		regmap_write(nc->base.smc, ATMEL_HSMC_NFC_IDR, 0xffffffff);
33493db446aSBoris Brezillon 	}
33593db446aSBoris Brezillon 
33693db446aSBoris Brezillon 	if (nc->op.errors & ATMEL_HSMC_NFC_SR_DTOE) {
33793db446aSBoris Brezillon 		dev_err(nc->base.dev, "Waiting NAND R/B Timeout\n");
33893db446aSBoris Brezillon 		ret = -ETIMEDOUT;
33993db446aSBoris Brezillon 	}
34093db446aSBoris Brezillon 
34193db446aSBoris Brezillon 	if (nc->op.errors & ATMEL_HSMC_NFC_SR_UNDEF) {
34293db446aSBoris Brezillon 		dev_err(nc->base.dev, "Access to an undefined area\n");
34393db446aSBoris Brezillon 		ret = -EIO;
34493db446aSBoris Brezillon 	}
34593db446aSBoris Brezillon 
34693db446aSBoris Brezillon 	if (nc->op.errors & ATMEL_HSMC_NFC_SR_AWB) {
34793db446aSBoris Brezillon 		dev_err(nc->base.dev, "Access while busy\n");
34893db446aSBoris Brezillon 		ret = -EIO;
34993db446aSBoris Brezillon 	}
35093db446aSBoris Brezillon 
35193db446aSBoris Brezillon 	if (nc->op.errors & ATMEL_HSMC_NFC_SR_NFCASE) {
35293db446aSBoris Brezillon 		dev_err(nc->base.dev, "Wrong access size\n");
35393db446aSBoris Brezillon 		ret = -EIO;
35493db446aSBoris Brezillon 	}
35593db446aSBoris Brezillon 
35693db446aSBoris Brezillon 	return ret;
35793db446aSBoris Brezillon }
35893db446aSBoris Brezillon 
atmel_nand_dma_transfer_finished(void * data)35993db446aSBoris Brezillon static void atmel_nand_dma_transfer_finished(void *data)
36093db446aSBoris Brezillon {
36193db446aSBoris Brezillon 	struct completion *finished = data;
36293db446aSBoris Brezillon 
36393db446aSBoris Brezillon 	complete(finished);
36493db446aSBoris Brezillon }
36593db446aSBoris Brezillon 
atmel_nand_dma_transfer(struct atmel_nand_controller * nc,void * buf,dma_addr_t dev_dma,size_t len,enum dma_data_direction dir)36693db446aSBoris Brezillon static int atmel_nand_dma_transfer(struct atmel_nand_controller *nc,
36793db446aSBoris Brezillon 				   void *buf, dma_addr_t dev_dma, size_t len,
36893db446aSBoris Brezillon 				   enum dma_data_direction dir)
36993db446aSBoris Brezillon {
37093db446aSBoris Brezillon 	DECLARE_COMPLETION_ONSTACK(finished);
37193db446aSBoris Brezillon 	dma_addr_t src_dma, dst_dma, buf_dma;
37293db446aSBoris Brezillon 	struct dma_async_tx_descriptor *tx;
37393db446aSBoris Brezillon 	dma_cookie_t cookie;
37493db446aSBoris Brezillon 
37593db446aSBoris Brezillon 	buf_dma = dma_map_single(nc->dev, buf, len, dir);
37693db446aSBoris Brezillon 	if (dma_mapping_error(nc->dev, dev_dma)) {
37793db446aSBoris Brezillon 		dev_err(nc->dev,
37893db446aSBoris Brezillon 			"Failed to prepare a buffer for DMA access\n");
37993db446aSBoris Brezillon 		goto err;
38093db446aSBoris Brezillon 	}
38193db446aSBoris Brezillon 
38293db446aSBoris Brezillon 	if (dir == DMA_FROM_DEVICE) {
38393db446aSBoris Brezillon 		src_dma = dev_dma;
38493db446aSBoris Brezillon 		dst_dma = buf_dma;
38593db446aSBoris Brezillon 	} else {
38693db446aSBoris Brezillon 		src_dma = buf_dma;
38793db446aSBoris Brezillon 		dst_dma = dev_dma;
38893db446aSBoris Brezillon 	}
38993db446aSBoris Brezillon 
39093db446aSBoris Brezillon 	tx = dmaengine_prep_dma_memcpy(nc->dmac, dst_dma, src_dma, len,
39193db446aSBoris Brezillon 				       DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
39293db446aSBoris Brezillon 	if (!tx) {
39393db446aSBoris Brezillon 		dev_err(nc->dev, "Failed to prepare DMA memcpy\n");
39493db446aSBoris Brezillon 		goto err_unmap;
39593db446aSBoris Brezillon 	}
39693db446aSBoris Brezillon 
39793db446aSBoris Brezillon 	tx->callback = atmel_nand_dma_transfer_finished;
39893db446aSBoris Brezillon 	tx->callback_param = &finished;
39993db446aSBoris Brezillon 
40093db446aSBoris Brezillon 	cookie = dmaengine_submit(tx);
40193db446aSBoris Brezillon 	if (dma_submit_error(cookie)) {
40293db446aSBoris Brezillon 		dev_err(nc->dev, "Failed to do DMA tx_submit\n");
40393db446aSBoris Brezillon 		goto err_unmap;
40493db446aSBoris Brezillon 	}
40593db446aSBoris Brezillon 
40693db446aSBoris Brezillon 	dma_async_issue_pending(nc->dmac);
40793db446aSBoris Brezillon 	wait_for_completion(&finished);
4081161703cSTudor Ambarus 	dma_unmap_single(nc->dev, buf_dma, len, dir);
40993db446aSBoris Brezillon 
41093db446aSBoris Brezillon 	return 0;
41193db446aSBoris Brezillon 
41293db446aSBoris Brezillon err_unmap:
41393db446aSBoris Brezillon 	dma_unmap_single(nc->dev, buf_dma, len, dir);
41493db446aSBoris Brezillon 
41593db446aSBoris Brezillon err:
41693db446aSBoris Brezillon 	dev_dbg(nc->dev, "Fall back to CPU I/O\n");
41793db446aSBoris Brezillon 
41893db446aSBoris Brezillon 	return -EIO;
41993db446aSBoris Brezillon }
42093db446aSBoris Brezillon 
atmel_nfc_exec_op(struct atmel_hsmc_nand_controller * nc,bool poll)42193db446aSBoris Brezillon static int atmel_nfc_exec_op(struct atmel_hsmc_nand_controller *nc, bool poll)
42293db446aSBoris Brezillon {
42393db446aSBoris Brezillon 	u8 *addrs = nc->op.addrs;
42493db446aSBoris Brezillon 	unsigned int op = 0;
42593db446aSBoris Brezillon 	u32 addr, val;
42693db446aSBoris Brezillon 	int i, ret;
42793db446aSBoris Brezillon 
42893db446aSBoris Brezillon 	nc->op.wait = ATMEL_HSMC_NFC_SR_CMDDONE;
42993db446aSBoris Brezillon 
43093db446aSBoris Brezillon 	for (i = 0; i < nc->op.ncmds; i++)
43193db446aSBoris Brezillon 		op |= ATMEL_NFC_CMD(i, nc->op.cmds[i]);
43293db446aSBoris Brezillon 
43393db446aSBoris Brezillon 	if (nc->op.naddrs == ATMEL_NFC_MAX_ADDR_CYCLES)
43493db446aSBoris Brezillon 		regmap_write(nc->base.smc, ATMEL_HSMC_NFC_ADDR, *addrs++);
43593db446aSBoris Brezillon 
43693db446aSBoris Brezillon 	op |= ATMEL_NFC_CSID(nc->op.cs) |
43793db446aSBoris Brezillon 	      ATMEL_NFC_ACYCLE(nc->op.naddrs);
43893db446aSBoris Brezillon 
43993db446aSBoris Brezillon 	if (nc->op.ncmds > 1)
44093db446aSBoris Brezillon 		op |= ATMEL_NFC_VCMD2;
44193db446aSBoris Brezillon 
44293db446aSBoris Brezillon 	addr = addrs[0] | (addrs[1] << 8) | (addrs[2] << 16) |
44393db446aSBoris Brezillon 	       (addrs[3] << 24);
44493db446aSBoris Brezillon 
44593db446aSBoris Brezillon 	if (nc->op.data != ATMEL_NFC_NO_DATA) {
44693db446aSBoris Brezillon 		op |= ATMEL_NFC_DATAEN;
44793db446aSBoris Brezillon 		nc->op.wait |= ATMEL_HSMC_NFC_SR_XFRDONE;
44893db446aSBoris Brezillon 
44993db446aSBoris Brezillon 		if (nc->op.data == ATMEL_NFC_WRITE_DATA)
45093db446aSBoris Brezillon 			op |= ATMEL_NFC_NFCWR;
45193db446aSBoris Brezillon 	}
45293db446aSBoris Brezillon 
45393db446aSBoris Brezillon 	/* Clear all flags. */
45493db446aSBoris Brezillon 	regmap_read(nc->base.smc, ATMEL_HSMC_NFC_SR, &val);
45593db446aSBoris Brezillon 
45693db446aSBoris Brezillon 	/* Send the command. */
45793db446aSBoris Brezillon 	regmap_write(nc->io, op, addr);
45893db446aSBoris Brezillon 
45993db446aSBoris Brezillon 	ret = atmel_nfc_wait(nc, poll, 0);
46093db446aSBoris Brezillon 	if (ret)
46193db446aSBoris Brezillon 		dev_err(nc->base.dev,
46293db446aSBoris Brezillon 			"Failed to send NAND command (err = %d)!",
46393db446aSBoris Brezillon 			ret);
46493db446aSBoris Brezillon 
46593db446aSBoris Brezillon 	/* Reset the op state. */
46693db446aSBoris Brezillon 	memset(&nc->op, 0, sizeof(nc->op));
46793db446aSBoris Brezillon 
46893db446aSBoris Brezillon 	return ret;
46993db446aSBoris Brezillon }
47093db446aSBoris Brezillon 
atmel_nand_data_in(struct atmel_nand * nand,void * buf,unsigned int len,bool force_8bit)47103b3e0c2SBoris Brezillon static void atmel_nand_data_in(struct atmel_nand *nand, void *buf,
47203b3e0c2SBoris Brezillon 			       unsigned int len, bool force_8bit)
47303b3e0c2SBoris Brezillon {
47403b3e0c2SBoris Brezillon 	struct atmel_nand_controller *nc;
47503b3e0c2SBoris Brezillon 
47603b3e0c2SBoris Brezillon 	nc = to_nand_controller(nand->base.controller);
47703b3e0c2SBoris Brezillon 
47803b3e0c2SBoris Brezillon 	/*
47903b3e0c2SBoris Brezillon 	 * If the controller supports DMA, the buffer address is DMA-able and
48003b3e0c2SBoris Brezillon 	 * len is long enough to make DMA transfers profitable, let's trigger
48103b3e0c2SBoris Brezillon 	 * a DMA transfer. If it fails, fallback to PIO mode.
48203b3e0c2SBoris Brezillon 	 */
48303b3e0c2SBoris Brezillon 	if (nc->dmac && virt_addr_valid(buf) &&
48403b3e0c2SBoris Brezillon 	    len >= MIN_DMA_LEN && !force_8bit &&
48503b3e0c2SBoris Brezillon 	    !atmel_nand_dma_transfer(nc, buf, nand->activecs->io.dma, len,
48603b3e0c2SBoris Brezillon 				     DMA_FROM_DEVICE))
48703b3e0c2SBoris Brezillon 		return;
48803b3e0c2SBoris Brezillon 
48903b3e0c2SBoris Brezillon 	if ((nand->base.options & NAND_BUSWIDTH_16) && !force_8bit)
49003b3e0c2SBoris Brezillon 		ioread16_rep(nand->activecs->io.virt, buf, len / 2);
49103b3e0c2SBoris Brezillon 	else
49203b3e0c2SBoris Brezillon 		ioread8_rep(nand->activecs->io.virt, buf, len);
49303b3e0c2SBoris Brezillon }
49403b3e0c2SBoris Brezillon 
atmel_nand_data_out(struct atmel_nand * nand,const void * buf,unsigned int len,bool force_8bit)49503b3e0c2SBoris Brezillon static void atmel_nand_data_out(struct atmel_nand *nand, const void *buf,
49603b3e0c2SBoris Brezillon 				unsigned int len, bool force_8bit)
49703b3e0c2SBoris Brezillon {
49803b3e0c2SBoris Brezillon 	struct atmel_nand_controller *nc;
49903b3e0c2SBoris Brezillon 
50003b3e0c2SBoris Brezillon 	nc = to_nand_controller(nand->base.controller);
50103b3e0c2SBoris Brezillon 
50203b3e0c2SBoris Brezillon 	/*
50303b3e0c2SBoris Brezillon 	 * If the controller supports DMA, the buffer address is DMA-able and
50403b3e0c2SBoris Brezillon 	 * len is long enough to make DMA transfers profitable, let's trigger
50503b3e0c2SBoris Brezillon 	 * a DMA transfer. If it fails, fallback to PIO mode.
50603b3e0c2SBoris Brezillon 	 */
50703b3e0c2SBoris Brezillon 	if (nc->dmac && virt_addr_valid(buf) &&
50803b3e0c2SBoris Brezillon 	    len >= MIN_DMA_LEN && !force_8bit &&
50903b3e0c2SBoris Brezillon 	    !atmel_nand_dma_transfer(nc, (void *)buf, nand->activecs->io.dma,
51003b3e0c2SBoris Brezillon 				     len, DMA_TO_DEVICE))
51103b3e0c2SBoris Brezillon 		return;
51203b3e0c2SBoris Brezillon 
51303b3e0c2SBoris Brezillon 	if ((nand->base.options & NAND_BUSWIDTH_16) && !force_8bit)
51403b3e0c2SBoris Brezillon 		iowrite16_rep(nand->activecs->io.virt, buf, len / 2);
51503b3e0c2SBoris Brezillon 	else
51603b3e0c2SBoris Brezillon 		iowrite8_rep(nand->activecs->io.virt, buf, len);
51703b3e0c2SBoris Brezillon }
51803b3e0c2SBoris Brezillon 
atmel_nand_waitrdy(struct atmel_nand * nand,unsigned int timeout_ms)51903b3e0c2SBoris Brezillon static int atmel_nand_waitrdy(struct atmel_nand *nand, unsigned int timeout_ms)
52003b3e0c2SBoris Brezillon {
52103b3e0c2SBoris Brezillon 	if (nand->activecs->rb.type == ATMEL_NAND_NO_RB)
52203b3e0c2SBoris Brezillon 		return nand_soft_waitrdy(&nand->base, timeout_ms);
52303b3e0c2SBoris Brezillon 
52403b3e0c2SBoris Brezillon 	return nand_gpio_waitrdy(&nand->base, nand->activecs->rb.gpio,
52503b3e0c2SBoris Brezillon 				 timeout_ms);
52603b3e0c2SBoris Brezillon }
52703b3e0c2SBoris Brezillon 
atmel_hsmc_nand_waitrdy(struct atmel_nand * nand,unsigned int timeout_ms)52803b3e0c2SBoris Brezillon static int atmel_hsmc_nand_waitrdy(struct atmel_nand *nand,
52903b3e0c2SBoris Brezillon 				   unsigned int timeout_ms)
53003b3e0c2SBoris Brezillon {
53103b3e0c2SBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
53203b3e0c2SBoris Brezillon 	u32 status, mask;
53303b3e0c2SBoris Brezillon 
53403b3e0c2SBoris Brezillon 	if (nand->activecs->rb.type != ATMEL_NAND_NATIVE_RB)
53503b3e0c2SBoris Brezillon 		return atmel_nand_waitrdy(nand, timeout_ms);
53603b3e0c2SBoris Brezillon 
53703b3e0c2SBoris Brezillon 	nc = to_hsmc_nand_controller(nand->base.controller);
53803b3e0c2SBoris Brezillon 	mask = ATMEL_HSMC_NFC_SR_RBEDGE(nand->activecs->rb.id);
53903b3e0c2SBoris Brezillon 	return regmap_read_poll_timeout_atomic(nc->base.smc, ATMEL_HSMC_NFC_SR,
54003b3e0c2SBoris Brezillon 					       status, status & mask,
54103b3e0c2SBoris Brezillon 					       10, timeout_ms * 1000);
54203b3e0c2SBoris Brezillon }
54303b3e0c2SBoris Brezillon 
atmel_nand_select_target(struct atmel_nand * nand,unsigned int cs)54403b3e0c2SBoris Brezillon static void atmel_nand_select_target(struct atmel_nand *nand,
54503b3e0c2SBoris Brezillon 				     unsigned int cs)
54603b3e0c2SBoris Brezillon {
54703b3e0c2SBoris Brezillon 	nand->activecs = &nand->cs[cs];
54803b3e0c2SBoris Brezillon }
54903b3e0c2SBoris Brezillon 
atmel_hsmc_nand_select_target(struct atmel_nand * nand,unsigned int cs)55003b3e0c2SBoris Brezillon static void atmel_hsmc_nand_select_target(struct atmel_nand *nand,
55103b3e0c2SBoris Brezillon 					  unsigned int cs)
55203b3e0c2SBoris Brezillon {
55303b3e0c2SBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(&nand->base);
55403b3e0c2SBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
55503b3e0c2SBoris Brezillon 	u32 cfg = ATMEL_HSMC_NFC_CFG_PAGESIZE(mtd->writesize) |
55603b3e0c2SBoris Brezillon 		  ATMEL_HSMC_NFC_CFG_SPARESIZE(mtd->oobsize) |
55703b3e0c2SBoris Brezillon 		  ATMEL_HSMC_NFC_CFG_RSPARE;
55803b3e0c2SBoris Brezillon 
55903b3e0c2SBoris Brezillon 	nand->activecs = &nand->cs[cs];
56003b3e0c2SBoris Brezillon 	nc = to_hsmc_nand_controller(nand->base.controller);
56103b3e0c2SBoris Brezillon 	if (nc->cfg == cfg)
56203b3e0c2SBoris Brezillon 		return;
56303b3e0c2SBoris Brezillon 
56403b3e0c2SBoris Brezillon 	regmap_update_bits(nc->base.smc, ATMEL_HSMC_NFC_CFG,
56503b3e0c2SBoris Brezillon 			   ATMEL_HSMC_NFC_CFG_PAGESIZE_MASK |
56603b3e0c2SBoris Brezillon 			   ATMEL_HSMC_NFC_CFG_SPARESIZE_MASK |
56703b3e0c2SBoris Brezillon 			   ATMEL_HSMC_NFC_CFG_RSPARE |
56803b3e0c2SBoris Brezillon 			   ATMEL_HSMC_NFC_CFG_WSPARE,
56903b3e0c2SBoris Brezillon 			   cfg);
57003b3e0c2SBoris Brezillon 	nc->cfg = cfg;
57103b3e0c2SBoris Brezillon }
57203b3e0c2SBoris Brezillon 
atmel_smc_nand_exec_instr(struct atmel_nand * nand,const struct nand_op_instr * instr)57303b3e0c2SBoris Brezillon static int atmel_smc_nand_exec_instr(struct atmel_nand *nand,
57403b3e0c2SBoris Brezillon 				     const struct nand_op_instr *instr)
57503b3e0c2SBoris Brezillon {
57603b3e0c2SBoris Brezillon 	struct atmel_nand_controller *nc;
57703b3e0c2SBoris Brezillon 	unsigned int i;
57803b3e0c2SBoris Brezillon 
57903b3e0c2SBoris Brezillon 	nc = to_nand_controller(nand->base.controller);
58003b3e0c2SBoris Brezillon 	switch (instr->type) {
58103b3e0c2SBoris Brezillon 	case NAND_OP_CMD_INSTR:
58203b3e0c2SBoris Brezillon 		writeb(instr->ctx.cmd.opcode,
58303b3e0c2SBoris Brezillon 		       nand->activecs->io.virt + nc->caps->cle_offs);
58403b3e0c2SBoris Brezillon 		return 0;
58503b3e0c2SBoris Brezillon 	case NAND_OP_ADDR_INSTR:
58603b3e0c2SBoris Brezillon 		for (i = 0; i < instr->ctx.addr.naddrs; i++)
58703b3e0c2SBoris Brezillon 			writeb(instr->ctx.addr.addrs[i],
58803b3e0c2SBoris Brezillon 			       nand->activecs->io.virt + nc->caps->ale_offs);
58903b3e0c2SBoris Brezillon 		return 0;
59003b3e0c2SBoris Brezillon 	case NAND_OP_DATA_IN_INSTR:
59103b3e0c2SBoris Brezillon 		atmel_nand_data_in(nand, instr->ctx.data.buf.in,
59203b3e0c2SBoris Brezillon 				   instr->ctx.data.len,
59303b3e0c2SBoris Brezillon 				   instr->ctx.data.force_8bit);
59403b3e0c2SBoris Brezillon 		return 0;
59503b3e0c2SBoris Brezillon 	case NAND_OP_DATA_OUT_INSTR:
59603b3e0c2SBoris Brezillon 		atmel_nand_data_out(nand, instr->ctx.data.buf.out,
59703b3e0c2SBoris Brezillon 				    instr->ctx.data.len,
59803b3e0c2SBoris Brezillon 				    instr->ctx.data.force_8bit);
59903b3e0c2SBoris Brezillon 		return 0;
60003b3e0c2SBoris Brezillon 	case NAND_OP_WAITRDY_INSTR:
60103b3e0c2SBoris Brezillon 		return atmel_nand_waitrdy(nand,
60203b3e0c2SBoris Brezillon 					  instr->ctx.waitrdy.timeout_ms);
60303b3e0c2SBoris Brezillon 	default:
60403b3e0c2SBoris Brezillon 		break;
60503b3e0c2SBoris Brezillon 	}
60603b3e0c2SBoris Brezillon 
60703b3e0c2SBoris Brezillon 	return -EINVAL;
60803b3e0c2SBoris Brezillon }
60903b3e0c2SBoris Brezillon 
atmel_smc_nand_exec_op(struct atmel_nand * nand,const struct nand_operation * op,bool check_only)61003b3e0c2SBoris Brezillon static int atmel_smc_nand_exec_op(struct atmel_nand *nand,
61103b3e0c2SBoris Brezillon 				  const struct nand_operation *op,
61203b3e0c2SBoris Brezillon 				  bool check_only)
61303b3e0c2SBoris Brezillon {
61403b3e0c2SBoris Brezillon 	unsigned int i;
61503b3e0c2SBoris Brezillon 	int ret = 0;
61603b3e0c2SBoris Brezillon 
61703b3e0c2SBoris Brezillon 	if (check_only)
61803b3e0c2SBoris Brezillon 		return 0;
61903b3e0c2SBoris Brezillon 
62003b3e0c2SBoris Brezillon 	atmel_nand_select_target(nand, op->cs);
62103b3e0c2SBoris Brezillon 	gpiod_set_value(nand->activecs->csgpio, 0);
62203b3e0c2SBoris Brezillon 	for (i = 0; i < op->ninstrs; i++) {
62303b3e0c2SBoris Brezillon 		ret = atmel_smc_nand_exec_instr(nand, &op->instrs[i]);
62403b3e0c2SBoris Brezillon 		if (ret)
62503b3e0c2SBoris Brezillon 			break;
62603b3e0c2SBoris Brezillon 	}
62703b3e0c2SBoris Brezillon 	gpiod_set_value(nand->activecs->csgpio, 1);
62803b3e0c2SBoris Brezillon 
62903b3e0c2SBoris Brezillon 	return ret;
63003b3e0c2SBoris Brezillon }
63103b3e0c2SBoris Brezillon 
atmel_hsmc_exec_cmd_addr(struct nand_chip * chip,const struct nand_subop * subop)63203b3e0c2SBoris Brezillon static int atmel_hsmc_exec_cmd_addr(struct nand_chip *chip,
63303b3e0c2SBoris Brezillon 				    const struct nand_subop *subop)
63403b3e0c2SBoris Brezillon {
63503b3e0c2SBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
63603b3e0c2SBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
63703b3e0c2SBoris Brezillon 	unsigned int i, j;
63803b3e0c2SBoris Brezillon 
63903b3e0c2SBoris Brezillon 	nc = to_hsmc_nand_controller(chip->controller);
64003b3e0c2SBoris Brezillon 
64103b3e0c2SBoris Brezillon 	nc->op.cs = nand->activecs->id;
64203b3e0c2SBoris Brezillon 	for (i = 0; i < subop->ninstrs; i++) {
64303b3e0c2SBoris Brezillon 		const struct nand_op_instr *instr = &subop->instrs[i];
64403b3e0c2SBoris Brezillon 
64503b3e0c2SBoris Brezillon 		if (instr->type == NAND_OP_CMD_INSTR) {
64603b3e0c2SBoris Brezillon 			nc->op.cmds[nc->op.ncmds++] = instr->ctx.cmd.opcode;
64703b3e0c2SBoris Brezillon 			continue;
64803b3e0c2SBoris Brezillon 		}
64903b3e0c2SBoris Brezillon 
65003b3e0c2SBoris Brezillon 		for (j = nand_subop_get_addr_start_off(subop, i);
65103b3e0c2SBoris Brezillon 		     j < nand_subop_get_num_addr_cyc(subop, i); j++) {
65203b3e0c2SBoris Brezillon 			nc->op.addrs[nc->op.naddrs] = instr->ctx.addr.addrs[j];
65303b3e0c2SBoris Brezillon 			nc->op.naddrs++;
65403b3e0c2SBoris Brezillon 		}
65503b3e0c2SBoris Brezillon 	}
65603b3e0c2SBoris Brezillon 
65703b3e0c2SBoris Brezillon 	return atmel_nfc_exec_op(nc, true);
65803b3e0c2SBoris Brezillon }
65903b3e0c2SBoris Brezillon 
atmel_hsmc_exec_rw(struct nand_chip * chip,const struct nand_subop * subop)66003b3e0c2SBoris Brezillon static int atmel_hsmc_exec_rw(struct nand_chip *chip,
66103b3e0c2SBoris Brezillon 			      const struct nand_subop *subop)
66203b3e0c2SBoris Brezillon {
66303b3e0c2SBoris Brezillon 	const struct nand_op_instr *instr = subop->instrs;
66403b3e0c2SBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
66503b3e0c2SBoris Brezillon 
66603b3e0c2SBoris Brezillon 	if (instr->type == NAND_OP_DATA_IN_INSTR)
66703b3e0c2SBoris Brezillon 		atmel_nand_data_in(nand, instr->ctx.data.buf.in,
66803b3e0c2SBoris Brezillon 				   instr->ctx.data.len,
66903b3e0c2SBoris Brezillon 				   instr->ctx.data.force_8bit);
67003b3e0c2SBoris Brezillon 	else
67103b3e0c2SBoris Brezillon 		atmel_nand_data_out(nand, instr->ctx.data.buf.out,
67203b3e0c2SBoris Brezillon 				    instr->ctx.data.len,
67303b3e0c2SBoris Brezillon 				    instr->ctx.data.force_8bit);
67403b3e0c2SBoris Brezillon 
67503b3e0c2SBoris Brezillon 	return 0;
67603b3e0c2SBoris Brezillon }
67703b3e0c2SBoris Brezillon 
atmel_hsmc_exec_waitrdy(struct nand_chip * chip,const struct nand_subop * subop)67803b3e0c2SBoris Brezillon static int atmel_hsmc_exec_waitrdy(struct nand_chip *chip,
67903b3e0c2SBoris Brezillon 				   const struct nand_subop *subop)
68003b3e0c2SBoris Brezillon {
68103b3e0c2SBoris Brezillon 	const struct nand_op_instr *instr = subop->instrs;
68203b3e0c2SBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
68303b3e0c2SBoris Brezillon 
68403b3e0c2SBoris Brezillon 	return atmel_hsmc_nand_waitrdy(nand, instr->ctx.waitrdy.timeout_ms);
68503b3e0c2SBoris Brezillon }
68603b3e0c2SBoris Brezillon 
68703b3e0c2SBoris Brezillon static const struct nand_op_parser atmel_hsmc_op_parser = NAND_OP_PARSER(
68803b3e0c2SBoris Brezillon 	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_cmd_addr,
68903b3e0c2SBoris Brezillon 		NAND_OP_PARSER_PAT_CMD_ELEM(true),
69003b3e0c2SBoris Brezillon 		NAND_OP_PARSER_PAT_ADDR_ELEM(true, 5),
69103b3e0c2SBoris Brezillon 		NAND_OP_PARSER_PAT_CMD_ELEM(true)),
69203b3e0c2SBoris Brezillon 	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_rw,
69303b3e0c2SBoris Brezillon 		NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 0)),
69403b3e0c2SBoris Brezillon 	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_rw,
69503b3e0c2SBoris Brezillon 		NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, 0)),
69603b3e0c2SBoris Brezillon 	NAND_OP_PARSER_PATTERN(atmel_hsmc_exec_waitrdy,
69703b3e0c2SBoris Brezillon 		NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
69803b3e0c2SBoris Brezillon );
69903b3e0c2SBoris Brezillon 
atmel_hsmc_nand_exec_op(struct atmel_nand * nand,const struct nand_operation * op,bool check_only)70003b3e0c2SBoris Brezillon static int atmel_hsmc_nand_exec_op(struct atmel_nand *nand,
70103b3e0c2SBoris Brezillon 				   const struct nand_operation *op,
70203b3e0c2SBoris Brezillon 				   bool check_only)
70303b3e0c2SBoris Brezillon {
70403b3e0c2SBoris Brezillon 	int ret;
70503b3e0c2SBoris Brezillon 
70603b3e0c2SBoris Brezillon 	if (check_only)
70703b3e0c2SBoris Brezillon 		return nand_op_parser_exec_op(&nand->base,
70803b3e0c2SBoris Brezillon 					      &atmel_hsmc_op_parser, op, true);
70903b3e0c2SBoris Brezillon 
71003b3e0c2SBoris Brezillon 	atmel_hsmc_nand_select_target(nand, op->cs);
71103b3e0c2SBoris Brezillon 	ret = nand_op_parser_exec_op(&nand->base, &atmel_hsmc_op_parser, op,
71203b3e0c2SBoris Brezillon 				     false);
71303b3e0c2SBoris Brezillon 
71403b3e0c2SBoris Brezillon 	return ret;
71503b3e0c2SBoris Brezillon }
71603b3e0c2SBoris Brezillon 
atmel_nfc_copy_to_sram(struct nand_chip * chip,const u8 * buf,bool oob_required)71793db446aSBoris Brezillon static void atmel_nfc_copy_to_sram(struct nand_chip *chip, const u8 *buf,
71893db446aSBoris Brezillon 				   bool oob_required)
71993db446aSBoris Brezillon {
72093db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
72193db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
72293db446aSBoris Brezillon 	int ret = -EIO;
72393db446aSBoris Brezillon 
72493db446aSBoris Brezillon 	nc = to_hsmc_nand_controller(chip->controller);
72593db446aSBoris Brezillon 
72693db446aSBoris Brezillon 	if (nc->base.dmac)
72793db446aSBoris Brezillon 		ret = atmel_nand_dma_transfer(&nc->base, (void *)buf,
72893db446aSBoris Brezillon 					      nc->sram.dma, mtd->writesize,
72993db446aSBoris Brezillon 					      DMA_TO_DEVICE);
73093db446aSBoris Brezillon 
73193db446aSBoris Brezillon 	/* Falling back to CPU copy. */
73293db446aSBoris Brezillon 	if (ret)
73393db446aSBoris Brezillon 		memcpy_toio(nc->sram.virt, buf, mtd->writesize);
73493db446aSBoris Brezillon 
73593db446aSBoris Brezillon 	if (oob_required)
73693db446aSBoris Brezillon 		memcpy_toio(nc->sram.virt + mtd->writesize, chip->oob_poi,
73793db446aSBoris Brezillon 			    mtd->oobsize);
73893db446aSBoris Brezillon }
73993db446aSBoris Brezillon 
atmel_nfc_copy_from_sram(struct nand_chip * chip,u8 * buf,bool oob_required)74093db446aSBoris Brezillon static void atmel_nfc_copy_from_sram(struct nand_chip *chip, u8 *buf,
74193db446aSBoris Brezillon 				     bool oob_required)
74293db446aSBoris Brezillon {
74393db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
74493db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
74593db446aSBoris Brezillon 	int ret = -EIO;
74693db446aSBoris Brezillon 
74793db446aSBoris Brezillon 	nc = to_hsmc_nand_controller(chip->controller);
74893db446aSBoris Brezillon 
74993db446aSBoris Brezillon 	if (nc->base.dmac)
75093db446aSBoris Brezillon 		ret = atmel_nand_dma_transfer(&nc->base, buf, nc->sram.dma,
75193db446aSBoris Brezillon 					      mtd->writesize, DMA_FROM_DEVICE);
75293db446aSBoris Brezillon 
75393db446aSBoris Brezillon 	/* Falling back to CPU copy. */
75493db446aSBoris Brezillon 	if (ret)
75593db446aSBoris Brezillon 		memcpy_fromio(buf, nc->sram.virt, mtd->writesize);
75693db446aSBoris Brezillon 
75793db446aSBoris Brezillon 	if (oob_required)
75893db446aSBoris Brezillon 		memcpy_fromio(chip->oob_poi, nc->sram.virt + mtd->writesize,
75993db446aSBoris Brezillon 			      mtd->oobsize);
76093db446aSBoris Brezillon }
76193db446aSBoris Brezillon 
atmel_nfc_set_op_addr(struct nand_chip * chip,int page,int column)76293db446aSBoris Brezillon static void atmel_nfc_set_op_addr(struct nand_chip *chip, int page, int column)
76393db446aSBoris Brezillon {
76493db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
76593db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
76693db446aSBoris Brezillon 
76793db446aSBoris Brezillon 	nc = to_hsmc_nand_controller(chip->controller);
76893db446aSBoris Brezillon 
76993db446aSBoris Brezillon 	if (column >= 0) {
77093db446aSBoris Brezillon 		nc->op.addrs[nc->op.naddrs++] = column;
77193db446aSBoris Brezillon 
77293db446aSBoris Brezillon 		/*
77393db446aSBoris Brezillon 		 * 2 address cycles for the column offset on large page NANDs.
77493db446aSBoris Brezillon 		 */
77593db446aSBoris Brezillon 		if (mtd->writesize > 512)
77693db446aSBoris Brezillon 			nc->op.addrs[nc->op.naddrs++] = column >> 8;
77793db446aSBoris Brezillon 	}
77893db446aSBoris Brezillon 
77993db446aSBoris Brezillon 	if (page >= 0) {
78093db446aSBoris Brezillon 		nc->op.addrs[nc->op.naddrs++] = page;
78193db446aSBoris Brezillon 		nc->op.addrs[nc->op.naddrs++] = page >> 8;
78293db446aSBoris Brezillon 
78393db446aSBoris Brezillon 		if (chip->options & NAND_ROW_ADDR_3)
78493db446aSBoris Brezillon 			nc->op.addrs[nc->op.naddrs++] = page >> 16;
78593db446aSBoris Brezillon 	}
78693db446aSBoris Brezillon }
78793db446aSBoris Brezillon 
atmel_nand_pmecc_enable(struct nand_chip * chip,int op,bool raw)78893db446aSBoris Brezillon static int atmel_nand_pmecc_enable(struct nand_chip *chip, int op, bool raw)
78993db446aSBoris Brezillon {
79093db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
79193db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
79293db446aSBoris Brezillon 	int ret;
79393db446aSBoris Brezillon 
79493db446aSBoris Brezillon 	nc = to_nand_controller(chip->controller);
79593db446aSBoris Brezillon 
79693db446aSBoris Brezillon 	if (raw)
79793db446aSBoris Brezillon 		return 0;
79893db446aSBoris Brezillon 
79993db446aSBoris Brezillon 	ret = atmel_pmecc_enable(nand->pmecc, op);
80093db446aSBoris Brezillon 	if (ret)
80193db446aSBoris Brezillon 		dev_err(nc->dev,
80293db446aSBoris Brezillon 			"Failed to enable ECC engine (err = %d)\n", ret);
80393db446aSBoris Brezillon 
80493db446aSBoris Brezillon 	return ret;
80593db446aSBoris Brezillon }
80693db446aSBoris Brezillon 
atmel_nand_pmecc_disable(struct nand_chip * chip,bool raw)80793db446aSBoris Brezillon static void atmel_nand_pmecc_disable(struct nand_chip *chip, bool raw)
80893db446aSBoris Brezillon {
80993db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
81093db446aSBoris Brezillon 
81193db446aSBoris Brezillon 	if (!raw)
81293db446aSBoris Brezillon 		atmel_pmecc_disable(nand->pmecc);
81393db446aSBoris Brezillon }
81493db446aSBoris Brezillon 
atmel_nand_pmecc_generate_eccbytes(struct nand_chip * chip,bool raw)81593db446aSBoris Brezillon static int atmel_nand_pmecc_generate_eccbytes(struct nand_chip *chip, bool raw)
81693db446aSBoris Brezillon {
81793db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
81893db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
81993db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
82093db446aSBoris Brezillon 	struct mtd_oob_region oobregion;
82193db446aSBoris Brezillon 	void *eccbuf;
82293db446aSBoris Brezillon 	int ret, i;
82393db446aSBoris Brezillon 
82493db446aSBoris Brezillon 	nc = to_nand_controller(chip->controller);
82593db446aSBoris Brezillon 
82693db446aSBoris Brezillon 	if (raw)
82793db446aSBoris Brezillon 		return 0;
82893db446aSBoris Brezillon 
82993db446aSBoris Brezillon 	ret = atmel_pmecc_wait_rdy(nand->pmecc);
83093db446aSBoris Brezillon 	if (ret) {
83193db446aSBoris Brezillon 		dev_err(nc->dev,
83293db446aSBoris Brezillon 			"Failed to transfer NAND page data (err = %d)\n",
83393db446aSBoris Brezillon 			ret);
83493db446aSBoris Brezillon 		return ret;
83593db446aSBoris Brezillon 	}
83693db446aSBoris Brezillon 
83793db446aSBoris Brezillon 	mtd_ooblayout_ecc(mtd, 0, &oobregion);
83893db446aSBoris Brezillon 	eccbuf = chip->oob_poi + oobregion.offset;
83993db446aSBoris Brezillon 
84093db446aSBoris Brezillon 	for (i = 0; i < chip->ecc.steps; i++) {
84193db446aSBoris Brezillon 		atmel_pmecc_get_generated_eccbytes(nand->pmecc, i,
84293db446aSBoris Brezillon 						   eccbuf);
84393db446aSBoris Brezillon 		eccbuf += chip->ecc.bytes;
84493db446aSBoris Brezillon 	}
84593db446aSBoris Brezillon 
84693db446aSBoris Brezillon 	return 0;
84793db446aSBoris Brezillon }
84893db446aSBoris Brezillon 
atmel_nand_pmecc_correct_data(struct nand_chip * chip,void * buf,bool raw)84993db446aSBoris Brezillon static int atmel_nand_pmecc_correct_data(struct nand_chip *chip, void *buf,
85093db446aSBoris Brezillon 					 bool raw)
85193db446aSBoris Brezillon {
85293db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
85393db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
85493db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
85593db446aSBoris Brezillon 	struct mtd_oob_region oobregion;
85693db446aSBoris Brezillon 	int ret, i, max_bitflips = 0;
85793db446aSBoris Brezillon 	void *databuf, *eccbuf;
85893db446aSBoris Brezillon 
85993db446aSBoris Brezillon 	nc = to_nand_controller(chip->controller);
86093db446aSBoris Brezillon 
86193db446aSBoris Brezillon 	if (raw)
86293db446aSBoris Brezillon 		return 0;
86393db446aSBoris Brezillon 
86493db446aSBoris Brezillon 	ret = atmel_pmecc_wait_rdy(nand->pmecc);
86593db446aSBoris Brezillon 	if (ret) {
86693db446aSBoris Brezillon 		dev_err(nc->dev,
86793db446aSBoris Brezillon 			"Failed to read NAND page data (err = %d)\n",
86893db446aSBoris Brezillon 			ret);
86993db446aSBoris Brezillon 		return ret;
87093db446aSBoris Brezillon 	}
87193db446aSBoris Brezillon 
87293db446aSBoris Brezillon 	mtd_ooblayout_ecc(mtd, 0, &oobregion);
87393db446aSBoris Brezillon 	eccbuf = chip->oob_poi + oobregion.offset;
87493db446aSBoris Brezillon 	databuf = buf;
87593db446aSBoris Brezillon 
87693db446aSBoris Brezillon 	for (i = 0; i < chip->ecc.steps; i++) {
87793db446aSBoris Brezillon 		ret = atmel_pmecc_correct_sector(nand->pmecc, i, databuf,
87893db446aSBoris Brezillon 						 eccbuf);
87993db446aSBoris Brezillon 		if (ret < 0 && !atmel_pmecc_correct_erased_chunks(nand->pmecc))
88093db446aSBoris Brezillon 			ret = nand_check_erased_ecc_chunk(databuf,
88193db446aSBoris Brezillon 							  chip->ecc.size,
88293db446aSBoris Brezillon 							  eccbuf,
88393db446aSBoris Brezillon 							  chip->ecc.bytes,
88493db446aSBoris Brezillon 							  NULL, 0,
88593db446aSBoris Brezillon 							  chip->ecc.strength);
88693db446aSBoris Brezillon 
88733cebf70SKai Stuhlemmer (ebee Engineering) 		if (ret >= 0) {
88833cebf70SKai Stuhlemmer (ebee Engineering) 			mtd->ecc_stats.corrected += ret;
88993db446aSBoris Brezillon 			max_bitflips = max(ret, max_bitflips);
89033cebf70SKai Stuhlemmer (ebee Engineering) 		} else {
89193db446aSBoris Brezillon 			mtd->ecc_stats.failed++;
89233cebf70SKai Stuhlemmer (ebee Engineering) 		}
89393db446aSBoris Brezillon 
89493db446aSBoris Brezillon 		databuf += chip->ecc.size;
89593db446aSBoris Brezillon 		eccbuf += chip->ecc.bytes;
89693db446aSBoris Brezillon 	}
89793db446aSBoris Brezillon 
89893db446aSBoris Brezillon 	return max_bitflips;
89993db446aSBoris Brezillon }
90093db446aSBoris Brezillon 
atmel_nand_pmecc_write_pg(struct nand_chip * chip,const u8 * buf,bool oob_required,int page,bool raw)90193db446aSBoris Brezillon static int atmel_nand_pmecc_write_pg(struct nand_chip *chip, const u8 *buf,
90293db446aSBoris Brezillon 				     bool oob_required, int page, bool raw)
90393db446aSBoris Brezillon {
90493db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
90593db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
90693db446aSBoris Brezillon 	int ret;
90793db446aSBoris Brezillon 
90893db446aSBoris Brezillon 	nand_prog_page_begin_op(chip, page, 0, NULL, 0);
90993db446aSBoris Brezillon 
91093db446aSBoris Brezillon 	ret = atmel_nand_pmecc_enable(chip, NAND_ECC_WRITE, raw);
91193db446aSBoris Brezillon 	if (ret)
91293db446aSBoris Brezillon 		return ret;
91393db446aSBoris Brezillon 
9145b2baf1fSBoris Brezillon 	nand_write_data_op(chip, buf, mtd->writesize, false);
91593db446aSBoris Brezillon 
91693db446aSBoris Brezillon 	ret = atmel_nand_pmecc_generate_eccbytes(chip, raw);
91793db446aSBoris Brezillon 	if (ret) {
91893db446aSBoris Brezillon 		atmel_pmecc_disable(nand->pmecc);
91993db446aSBoris Brezillon 		return ret;
92093db446aSBoris Brezillon 	}
92193db446aSBoris Brezillon 
92293db446aSBoris Brezillon 	atmel_nand_pmecc_disable(chip, raw);
92393db446aSBoris Brezillon 
9245b2baf1fSBoris Brezillon 	nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
92593db446aSBoris Brezillon 
92693db446aSBoris Brezillon 	return nand_prog_page_end_op(chip);
92793db446aSBoris Brezillon }
92893db446aSBoris Brezillon 
atmel_nand_pmecc_write_page(struct nand_chip * chip,const u8 * buf,int oob_required,int page)929767eb6fbSBoris Brezillon static int atmel_nand_pmecc_write_page(struct nand_chip *chip, const u8 *buf,
93093db446aSBoris Brezillon 				       int oob_required, int page)
93193db446aSBoris Brezillon {
93293db446aSBoris Brezillon 	return atmel_nand_pmecc_write_pg(chip, buf, oob_required, page, false);
93393db446aSBoris Brezillon }
93493db446aSBoris Brezillon 
atmel_nand_pmecc_write_page_raw(struct nand_chip * chip,const u8 * buf,int oob_required,int page)935767eb6fbSBoris Brezillon static int atmel_nand_pmecc_write_page_raw(struct nand_chip *chip,
93693db446aSBoris Brezillon 					   const u8 *buf, int oob_required,
93793db446aSBoris Brezillon 					   int page)
93893db446aSBoris Brezillon {
93993db446aSBoris Brezillon 	return atmel_nand_pmecc_write_pg(chip, buf, oob_required, page, true);
94093db446aSBoris Brezillon }
94193db446aSBoris Brezillon 
atmel_nand_pmecc_read_pg(struct nand_chip * chip,u8 * buf,bool oob_required,int page,bool raw)94293db446aSBoris Brezillon static int atmel_nand_pmecc_read_pg(struct nand_chip *chip, u8 *buf,
94393db446aSBoris Brezillon 				    bool oob_required, int page, bool raw)
94493db446aSBoris Brezillon {
94593db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
94693db446aSBoris Brezillon 	int ret;
94793db446aSBoris Brezillon 
94893db446aSBoris Brezillon 	nand_read_page_op(chip, page, 0, NULL, 0);
94993db446aSBoris Brezillon 
95093db446aSBoris Brezillon 	ret = atmel_nand_pmecc_enable(chip, NAND_ECC_READ, raw);
95193db446aSBoris Brezillon 	if (ret)
95293db446aSBoris Brezillon 		return ret;
95393db446aSBoris Brezillon 
954d27c9859SAlex Dewar 	ret = nand_read_data_op(chip, buf, mtd->writesize, false, false);
955d27c9859SAlex Dewar 	if (ret)
956d27c9859SAlex Dewar 		goto out_disable;
957d27c9859SAlex Dewar 
958d27c9859SAlex Dewar 	ret = nand_read_data_op(chip, chip->oob_poi, mtd->oobsize, false, false);
959d27c9859SAlex Dewar 	if (ret)
960d27c9859SAlex Dewar 		goto out_disable;
96193db446aSBoris Brezillon 
96293db446aSBoris Brezillon 	ret = atmel_nand_pmecc_correct_data(chip, buf, raw);
96393db446aSBoris Brezillon 
964d27c9859SAlex Dewar out_disable:
96593db446aSBoris Brezillon 	atmel_nand_pmecc_disable(chip, raw);
96693db446aSBoris Brezillon 
96793db446aSBoris Brezillon 	return ret;
96893db446aSBoris Brezillon }
96993db446aSBoris Brezillon 
atmel_nand_pmecc_read_page(struct nand_chip * chip,u8 * buf,int oob_required,int page)970b9761687SBoris Brezillon static int atmel_nand_pmecc_read_page(struct nand_chip *chip, u8 *buf,
97193db446aSBoris Brezillon 				      int oob_required, int page)
97293db446aSBoris Brezillon {
97393db446aSBoris Brezillon 	return atmel_nand_pmecc_read_pg(chip, buf, oob_required, page, false);
97493db446aSBoris Brezillon }
97593db446aSBoris Brezillon 
atmel_nand_pmecc_read_page_raw(struct nand_chip * chip,u8 * buf,int oob_required,int page)976b9761687SBoris Brezillon static int atmel_nand_pmecc_read_page_raw(struct nand_chip *chip, u8 *buf,
97793db446aSBoris Brezillon 					  int oob_required, int page)
97893db446aSBoris Brezillon {
97993db446aSBoris Brezillon 	return atmel_nand_pmecc_read_pg(chip, buf, oob_required, page, true);
98093db446aSBoris Brezillon }
98193db446aSBoris Brezillon 
atmel_hsmc_nand_pmecc_write_pg(struct nand_chip * chip,const u8 * buf,bool oob_required,int page,bool raw)98293db446aSBoris Brezillon static int atmel_hsmc_nand_pmecc_write_pg(struct nand_chip *chip,
98393db446aSBoris Brezillon 					  const u8 *buf, bool oob_required,
98493db446aSBoris Brezillon 					  int page, bool raw)
98593db446aSBoris Brezillon {
98693db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
98793db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
98893db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
989060c931cSBoris Brezillon 	int ret;
99093db446aSBoris Brezillon 
99103b3e0c2SBoris Brezillon 	atmel_hsmc_nand_select_target(nand, chip->cur_cs);
99293db446aSBoris Brezillon 	nc = to_hsmc_nand_controller(chip->controller);
99393db446aSBoris Brezillon 
99493db446aSBoris Brezillon 	atmel_nfc_copy_to_sram(chip, buf, false);
99593db446aSBoris Brezillon 
99693db446aSBoris Brezillon 	nc->op.cmds[0] = NAND_CMD_SEQIN;
99793db446aSBoris Brezillon 	nc->op.ncmds = 1;
99893db446aSBoris Brezillon 	atmel_nfc_set_op_addr(chip, page, 0x0);
99993db446aSBoris Brezillon 	nc->op.cs = nand->activecs->id;
100093db446aSBoris Brezillon 	nc->op.data = ATMEL_NFC_WRITE_DATA;
100193db446aSBoris Brezillon 
100293db446aSBoris Brezillon 	ret = atmel_nand_pmecc_enable(chip, NAND_ECC_WRITE, raw);
100393db446aSBoris Brezillon 	if (ret)
100493db446aSBoris Brezillon 		return ret;
100593db446aSBoris Brezillon 
100693db446aSBoris Brezillon 	ret = atmel_nfc_exec_op(nc, false);
100793db446aSBoris Brezillon 	if (ret) {
100893db446aSBoris Brezillon 		atmel_nand_pmecc_disable(chip, raw);
100993db446aSBoris Brezillon 		dev_err(nc->base.dev,
101093db446aSBoris Brezillon 			"Failed to transfer NAND page data (err = %d)\n",
101193db446aSBoris Brezillon 			ret);
101293db446aSBoris Brezillon 		return ret;
101393db446aSBoris Brezillon 	}
101493db446aSBoris Brezillon 
101593db446aSBoris Brezillon 	ret = atmel_nand_pmecc_generate_eccbytes(chip, raw);
101693db446aSBoris Brezillon 
101793db446aSBoris Brezillon 	atmel_nand_pmecc_disable(chip, raw);
101893db446aSBoris Brezillon 
101993db446aSBoris Brezillon 	if (ret)
102093db446aSBoris Brezillon 		return ret;
102193db446aSBoris Brezillon 
10225b2baf1fSBoris Brezillon 	nand_write_data_op(chip, chip->oob_poi, mtd->oobsize, false);
102393db446aSBoris Brezillon 
1024060c931cSBoris Brezillon 	return nand_prog_page_end_op(chip);
102593db446aSBoris Brezillon }
102693db446aSBoris Brezillon 
atmel_hsmc_nand_pmecc_write_page(struct nand_chip * chip,const u8 * buf,int oob_required,int page)1027767eb6fbSBoris Brezillon static int atmel_hsmc_nand_pmecc_write_page(struct nand_chip *chip,
102893db446aSBoris Brezillon 					    const u8 *buf, int oob_required,
102993db446aSBoris Brezillon 					    int page)
103093db446aSBoris Brezillon {
103193db446aSBoris Brezillon 	return atmel_hsmc_nand_pmecc_write_pg(chip, buf, oob_required, page,
103293db446aSBoris Brezillon 					      false);
103393db446aSBoris Brezillon }
103493db446aSBoris Brezillon 
atmel_hsmc_nand_pmecc_write_page_raw(struct nand_chip * chip,const u8 * buf,int oob_required,int page)1035767eb6fbSBoris Brezillon static int atmel_hsmc_nand_pmecc_write_page_raw(struct nand_chip *chip,
103693db446aSBoris Brezillon 						const u8 *buf,
103793db446aSBoris Brezillon 						int oob_required, int page)
103893db446aSBoris Brezillon {
103993db446aSBoris Brezillon 	return atmel_hsmc_nand_pmecc_write_pg(chip, buf, oob_required, page,
104093db446aSBoris Brezillon 					      true);
104193db446aSBoris Brezillon }
104293db446aSBoris Brezillon 
atmel_hsmc_nand_pmecc_read_pg(struct nand_chip * chip,u8 * buf,bool oob_required,int page,bool raw)104393db446aSBoris Brezillon static int atmel_hsmc_nand_pmecc_read_pg(struct nand_chip *chip, u8 *buf,
104493db446aSBoris Brezillon 					 bool oob_required, int page,
104593db446aSBoris Brezillon 					 bool raw)
104693db446aSBoris Brezillon {
104793db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
104893db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
104993db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
105093db446aSBoris Brezillon 	int ret;
105193db446aSBoris Brezillon 
105203b3e0c2SBoris Brezillon 	atmel_hsmc_nand_select_target(nand, chip->cur_cs);
105393db446aSBoris Brezillon 	nc = to_hsmc_nand_controller(chip->controller);
105493db446aSBoris Brezillon 
105593db446aSBoris Brezillon 	/*
105693db446aSBoris Brezillon 	 * Optimized read page accessors only work when the NAND R/B pin is
105793db446aSBoris Brezillon 	 * connected to a native SoC R/B pin. If that's not the case, fallback
105893db446aSBoris Brezillon 	 * to the non-optimized one.
105993db446aSBoris Brezillon 	 */
1060dca3c3ceSBoris Brezillon 	if (nand->activecs->rb.type != ATMEL_NAND_NATIVE_RB)
106193db446aSBoris Brezillon 		return atmel_nand_pmecc_read_pg(chip, buf, oob_required, page,
106293db446aSBoris Brezillon 						raw);
106393db446aSBoris Brezillon 
106493db446aSBoris Brezillon 	nc->op.cmds[nc->op.ncmds++] = NAND_CMD_READ0;
106593db446aSBoris Brezillon 
106693db446aSBoris Brezillon 	if (mtd->writesize > 512)
106793db446aSBoris Brezillon 		nc->op.cmds[nc->op.ncmds++] = NAND_CMD_READSTART;
106893db446aSBoris Brezillon 
106993db446aSBoris Brezillon 	atmel_nfc_set_op_addr(chip, page, 0x0);
107093db446aSBoris Brezillon 	nc->op.cs = nand->activecs->id;
107193db446aSBoris Brezillon 	nc->op.data = ATMEL_NFC_READ_DATA;
107293db446aSBoris Brezillon 
107393db446aSBoris Brezillon 	ret = atmel_nand_pmecc_enable(chip, NAND_ECC_READ, raw);
107493db446aSBoris Brezillon 	if (ret)
107593db446aSBoris Brezillon 		return ret;
107693db446aSBoris Brezillon 
107793db446aSBoris Brezillon 	ret = atmel_nfc_exec_op(nc, false);
107893db446aSBoris Brezillon 	if (ret) {
107993db446aSBoris Brezillon 		atmel_nand_pmecc_disable(chip, raw);
108093db446aSBoris Brezillon 		dev_err(nc->base.dev,
108193db446aSBoris Brezillon 			"Failed to load NAND page data (err = %d)\n",
108293db446aSBoris Brezillon 			ret);
108393db446aSBoris Brezillon 		return ret;
108493db446aSBoris Brezillon 	}
108593db446aSBoris Brezillon 
108693db446aSBoris Brezillon 	atmel_nfc_copy_from_sram(chip, buf, true);
108793db446aSBoris Brezillon 
108893db446aSBoris Brezillon 	ret = atmel_nand_pmecc_correct_data(chip, buf, raw);
108993db446aSBoris Brezillon 
109093db446aSBoris Brezillon 	atmel_nand_pmecc_disable(chip, raw);
109193db446aSBoris Brezillon 
109293db446aSBoris Brezillon 	return ret;
109393db446aSBoris Brezillon }
109493db446aSBoris Brezillon 
atmel_hsmc_nand_pmecc_read_page(struct nand_chip * chip,u8 * buf,int oob_required,int page)1095b9761687SBoris Brezillon static int atmel_hsmc_nand_pmecc_read_page(struct nand_chip *chip, u8 *buf,
109693db446aSBoris Brezillon 					   int oob_required, int page)
109793db446aSBoris Brezillon {
109893db446aSBoris Brezillon 	return atmel_hsmc_nand_pmecc_read_pg(chip, buf, oob_required, page,
109993db446aSBoris Brezillon 					     false);
110093db446aSBoris Brezillon }
110193db446aSBoris Brezillon 
atmel_hsmc_nand_pmecc_read_page_raw(struct nand_chip * chip,u8 * buf,int oob_required,int page)1102b9761687SBoris Brezillon static int atmel_hsmc_nand_pmecc_read_page_raw(struct nand_chip *chip,
110393db446aSBoris Brezillon 					       u8 *buf, int oob_required,
110493db446aSBoris Brezillon 					       int page)
110593db446aSBoris Brezillon {
110693db446aSBoris Brezillon 	return atmel_hsmc_nand_pmecc_read_pg(chip, buf, oob_required, page,
110793db446aSBoris Brezillon 					     true);
110893db446aSBoris Brezillon }
110993db446aSBoris Brezillon 
atmel_nand_pmecc_init(struct nand_chip * chip)111093db446aSBoris Brezillon static int atmel_nand_pmecc_init(struct nand_chip *chip)
111193db446aSBoris Brezillon {
111253576c7bSMiquel Raynal 	const struct nand_ecc_props *requirements =
111353576c7bSMiquel Raynal 		nanddev_get_ecc_requirements(&chip->base);
111493db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
1115b5156335SMiquel Raynal 	struct nand_device *nanddev = mtd_to_nanddev(mtd);
111693db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
111793db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
111893db446aSBoris Brezillon 	struct atmel_pmecc_user_req req;
111993db446aSBoris Brezillon 
112093db446aSBoris Brezillon 	nc = to_nand_controller(chip->controller);
112193db446aSBoris Brezillon 
112293db446aSBoris Brezillon 	if (!nc->pmecc) {
112393db446aSBoris Brezillon 		dev_err(nc->dev, "HW ECC not supported\n");
112493db446aSBoris Brezillon 		return -ENOTSUPP;
112593db446aSBoris Brezillon 	}
112693db446aSBoris Brezillon 
112793db446aSBoris Brezillon 	if (nc->caps->legacy_of_bindings) {
112893db446aSBoris Brezillon 		u32 val;
112993db446aSBoris Brezillon 
113093db446aSBoris Brezillon 		if (!of_property_read_u32(nc->dev->of_node, "atmel,pmecc-cap",
113193db446aSBoris Brezillon 					  &val))
113293db446aSBoris Brezillon 			chip->ecc.strength = val;
113393db446aSBoris Brezillon 
113493db446aSBoris Brezillon 		if (!of_property_read_u32(nc->dev->of_node,
113593db446aSBoris Brezillon 					  "atmel,pmecc-sector-size",
113693db446aSBoris Brezillon 					  &val))
113793db446aSBoris Brezillon 			chip->ecc.size = val;
113893db446aSBoris Brezillon 	}
113993db446aSBoris Brezillon 
1140b5156335SMiquel Raynal 	if (nanddev->ecc.user_conf.flags & NAND_ECC_MAXIMIZE_STRENGTH)
114193db446aSBoris Brezillon 		req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH;
114293db446aSBoris Brezillon 	else if (chip->ecc.strength)
114393db446aSBoris Brezillon 		req.ecc.strength = chip->ecc.strength;
114453576c7bSMiquel Raynal 	else if (requirements->strength)
114553576c7bSMiquel Raynal 		req.ecc.strength = requirements->strength;
114693db446aSBoris Brezillon 	else
114793db446aSBoris Brezillon 		req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH;
114893db446aSBoris Brezillon 
114993db446aSBoris Brezillon 	if (chip->ecc.size)
115093db446aSBoris Brezillon 		req.ecc.sectorsize = chip->ecc.size;
115153576c7bSMiquel Raynal 	else if (requirements->step_size)
115253576c7bSMiquel Raynal 		req.ecc.sectorsize = requirements->step_size;
115393db446aSBoris Brezillon 	else
115493db446aSBoris Brezillon 		req.ecc.sectorsize = ATMEL_PMECC_SECTOR_SIZE_AUTO;
115593db446aSBoris Brezillon 
115693db446aSBoris Brezillon 	req.pagesize = mtd->writesize;
115793db446aSBoris Brezillon 	req.oobsize = mtd->oobsize;
115893db446aSBoris Brezillon 
115993db446aSBoris Brezillon 	if (mtd->writesize <= 512) {
116093db446aSBoris Brezillon 		req.ecc.bytes = 4;
116193db446aSBoris Brezillon 		req.ecc.ooboffset = 0;
116293db446aSBoris Brezillon 	} else {
116393db446aSBoris Brezillon 		req.ecc.bytes = mtd->oobsize - 2;
116493db446aSBoris Brezillon 		req.ecc.ooboffset = ATMEL_PMECC_OOBOFFSET_AUTO;
116593db446aSBoris Brezillon 	}
116693db446aSBoris Brezillon 
116793db446aSBoris Brezillon 	nand->pmecc = atmel_pmecc_create_user(nc->pmecc, &req);
116893db446aSBoris Brezillon 	if (IS_ERR(nand->pmecc))
116993db446aSBoris Brezillon 		return PTR_ERR(nand->pmecc);
117093db446aSBoris Brezillon 
1171e0a564aeSMiquel Raynal 	chip->ecc.algo = NAND_ECC_ALGO_BCH;
117293db446aSBoris Brezillon 	chip->ecc.size = req.ecc.sectorsize;
117393db446aSBoris Brezillon 	chip->ecc.bytes = req.ecc.bytes / req.ecc.nsectors;
117493db446aSBoris Brezillon 	chip->ecc.strength = req.ecc.strength;
117593db446aSBoris Brezillon 
117693db446aSBoris Brezillon 	chip->options |= NAND_NO_SUBPAGE_WRITE;
117793db446aSBoris Brezillon 
11781e3b37aaSMiquel Raynal 	mtd_set_ooblayout(mtd, nand_get_large_page_ooblayout());
117993db446aSBoris Brezillon 
118093db446aSBoris Brezillon 	return 0;
118193db446aSBoris Brezillon }
118293db446aSBoris Brezillon 
atmel_nand_ecc_init(struct nand_chip * chip)1183577e010cSMiquel Raynal static int atmel_nand_ecc_init(struct nand_chip *chip)
118493db446aSBoris Brezillon {
118593db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
118693db446aSBoris Brezillon 	int ret;
118793db446aSBoris Brezillon 
118893db446aSBoris Brezillon 	nc = to_nand_controller(chip->controller);
118993db446aSBoris Brezillon 
1190bace41f8SMiquel Raynal 	switch (chip->ecc.engine_type) {
1191bace41f8SMiquel Raynal 	case NAND_ECC_ENGINE_TYPE_NONE:
1192bace41f8SMiquel Raynal 	case NAND_ECC_ENGINE_TYPE_SOFT:
119393db446aSBoris Brezillon 		/*
119493db446aSBoris Brezillon 		 * Nothing to do, the core will initialize everything for us.
119593db446aSBoris Brezillon 		 */
119693db446aSBoris Brezillon 		break;
119793db446aSBoris Brezillon 
1198bace41f8SMiquel Raynal 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
119993db446aSBoris Brezillon 		ret = atmel_nand_pmecc_init(chip);
120093db446aSBoris Brezillon 		if (ret)
120193db446aSBoris Brezillon 			return ret;
120293db446aSBoris Brezillon 
120393db446aSBoris Brezillon 		chip->ecc.read_page = atmel_nand_pmecc_read_page;
120493db446aSBoris Brezillon 		chip->ecc.write_page = atmel_nand_pmecc_write_page;
120593db446aSBoris Brezillon 		chip->ecc.read_page_raw = atmel_nand_pmecc_read_page_raw;
120693db446aSBoris Brezillon 		chip->ecc.write_page_raw = atmel_nand_pmecc_write_page_raw;
120793db446aSBoris Brezillon 		break;
120893db446aSBoris Brezillon 
120993db446aSBoris Brezillon 	default:
121093db446aSBoris Brezillon 		/* Other modes are not supported. */
121193db446aSBoris Brezillon 		dev_err(nc->dev, "Unsupported ECC mode: %d\n",
1212bace41f8SMiquel Raynal 			chip->ecc.engine_type);
121393db446aSBoris Brezillon 		return -ENOTSUPP;
121493db446aSBoris Brezillon 	}
121593db446aSBoris Brezillon 
121693db446aSBoris Brezillon 	return 0;
121793db446aSBoris Brezillon }
121893db446aSBoris Brezillon 
atmel_hsmc_nand_ecc_init(struct nand_chip * chip)1219577e010cSMiquel Raynal static int atmel_hsmc_nand_ecc_init(struct nand_chip *chip)
122093db446aSBoris Brezillon {
122193db446aSBoris Brezillon 	int ret;
122293db446aSBoris Brezillon 
1223577e010cSMiquel Raynal 	ret = atmel_nand_ecc_init(chip);
122493db446aSBoris Brezillon 	if (ret)
122593db446aSBoris Brezillon 		return ret;
122693db446aSBoris Brezillon 
1227bace41f8SMiquel Raynal 	if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
122893db446aSBoris Brezillon 		return 0;
122993db446aSBoris Brezillon 
123093db446aSBoris Brezillon 	/* Adjust the ECC operations for the HSMC IP. */
123193db446aSBoris Brezillon 	chip->ecc.read_page = atmel_hsmc_nand_pmecc_read_page;
123293db446aSBoris Brezillon 	chip->ecc.write_page = atmel_hsmc_nand_pmecc_write_page;
123393db446aSBoris Brezillon 	chip->ecc.read_page_raw = atmel_hsmc_nand_pmecc_read_page_raw;
123493db446aSBoris Brezillon 	chip->ecc.write_page_raw = atmel_hsmc_nand_pmecc_write_page_raw;
123593db446aSBoris Brezillon 
123693db446aSBoris Brezillon 	return 0;
123793db446aSBoris Brezillon }
123893db446aSBoris Brezillon 
atmel_smc_nand_prepare_smcconf(struct atmel_nand * nand,const struct nand_interface_config * conf,struct atmel_smc_cs_conf * smcconf)123993db446aSBoris Brezillon static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
12404c46667bSMiquel Raynal 					const struct nand_interface_config *conf,
124193db446aSBoris Brezillon 					struct atmel_smc_cs_conf *smcconf)
124293db446aSBoris Brezillon {
124393db446aSBoris Brezillon 	u32 ncycles, totalcycles, timeps, mckperiodps;
124493db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
124593db446aSBoris Brezillon 	int ret;
124693db446aSBoris Brezillon 
124793db446aSBoris Brezillon 	nc = to_nand_controller(nand->base.controller);
124893db446aSBoris Brezillon 
124993db446aSBoris Brezillon 	/* DDR interface not supported. */
1250961965c4SMiquel Raynal 	if (!nand_interface_is_sdr(conf))
125193db446aSBoris Brezillon 		return -ENOTSUPP;
125293db446aSBoris Brezillon 
125393db446aSBoris Brezillon 	/*
125493db446aSBoris Brezillon 	 * tRC < 30ns implies EDO mode. This controller does not support this
125593db446aSBoris Brezillon 	 * mode.
125693db446aSBoris Brezillon 	 */
125793db446aSBoris Brezillon 	if (conf->timings.sdr.tRC_min < 30000)
125893db446aSBoris Brezillon 		return -ENOTSUPP;
125993db446aSBoris Brezillon 
126093db446aSBoris Brezillon 	atmel_smc_cs_conf_init(smcconf);
126193db446aSBoris Brezillon 
126293db446aSBoris Brezillon 	mckperiodps = NSEC_PER_SEC / clk_get_rate(nc->mck);
126393db446aSBoris Brezillon 	mckperiodps *= 1000;
126493db446aSBoris Brezillon 
126593db446aSBoris Brezillon 	/*
126693db446aSBoris Brezillon 	 * Set write pulse timing. This one is easy to extract:
126793db446aSBoris Brezillon 	 *
126893db446aSBoris Brezillon 	 * NWE_PULSE = tWP
126993db446aSBoris Brezillon 	 */
127093db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tWP_min, mckperiodps);
127193db446aSBoris Brezillon 	totalcycles = ncycles;
127293db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NWE_SHIFT,
127393db446aSBoris Brezillon 					  ncycles);
127493db446aSBoris Brezillon 	if (ret)
127593db446aSBoris Brezillon 		return ret;
127693db446aSBoris Brezillon 
127793db446aSBoris Brezillon 	/*
127893db446aSBoris Brezillon 	 * The write setup timing depends on the operation done on the NAND.
127993db446aSBoris Brezillon 	 * All operations goes through the same data bus, but the operation
128093db446aSBoris Brezillon 	 * type depends on the address we are writing to (ALE/CLE address
128193db446aSBoris Brezillon 	 * lines).
128293db446aSBoris Brezillon 	 * Since we have no way to differentiate the different operations at
128393db446aSBoris Brezillon 	 * the SMC level, we must consider the worst case (the biggest setup
128493db446aSBoris Brezillon 	 * time among all operation types):
128593db446aSBoris Brezillon 	 *
128693db446aSBoris Brezillon 	 * NWE_SETUP = max(tCLS, tCS, tALS, tDS) - NWE_PULSE
128793db446aSBoris Brezillon 	 */
128893db446aSBoris Brezillon 	timeps = max3(conf->timings.sdr.tCLS_min, conf->timings.sdr.tCS_min,
128993db446aSBoris Brezillon 		      conf->timings.sdr.tALS_min);
129093db446aSBoris Brezillon 	timeps = max(timeps, conf->timings.sdr.tDS_min);
129193db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(timeps, mckperiodps);
129293db446aSBoris Brezillon 	ncycles = ncycles > totalcycles ? ncycles - totalcycles : 0;
129393db446aSBoris Brezillon 	totalcycles += ncycles;
129493db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_setup(smcconf, ATMEL_SMC_NWE_SHIFT,
129593db446aSBoris Brezillon 					  ncycles);
129693db446aSBoris Brezillon 	if (ret)
129793db446aSBoris Brezillon 		return ret;
129893db446aSBoris Brezillon 
129993db446aSBoris Brezillon 	/*
130093db446aSBoris Brezillon 	 * As for the write setup timing, the write hold timing depends on the
130193db446aSBoris Brezillon 	 * operation done on the NAND:
130293db446aSBoris Brezillon 	 *
130393db446aSBoris Brezillon 	 * NWE_HOLD = max(tCLH, tCH, tALH, tDH, tWH)
130493db446aSBoris Brezillon 	 */
130593db446aSBoris Brezillon 	timeps = max3(conf->timings.sdr.tCLH_min, conf->timings.sdr.tCH_min,
130693db446aSBoris Brezillon 		      conf->timings.sdr.tALH_min);
130793db446aSBoris Brezillon 	timeps = max3(timeps, conf->timings.sdr.tDH_min,
130893db446aSBoris Brezillon 		      conf->timings.sdr.tWH_min);
130993db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(timeps, mckperiodps);
131093db446aSBoris Brezillon 	totalcycles += ncycles;
131193db446aSBoris Brezillon 
131293db446aSBoris Brezillon 	/*
131393db446aSBoris Brezillon 	 * The write cycle timing is directly matching tWC, but is also
131493db446aSBoris Brezillon 	 * dependent on the other timings on the setup and hold timings we
131593db446aSBoris Brezillon 	 * calculated earlier, which gives:
131693db446aSBoris Brezillon 	 *
131793db446aSBoris Brezillon 	 * NWE_CYCLE = max(tWC, NWE_SETUP + NWE_PULSE + NWE_HOLD)
131893db446aSBoris Brezillon 	 */
131993db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tWC_min, mckperiodps);
132093db446aSBoris Brezillon 	ncycles = max(totalcycles, ncycles);
132193db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_cycle(smcconf, ATMEL_SMC_NWE_SHIFT,
132293db446aSBoris Brezillon 					  ncycles);
132393db446aSBoris Brezillon 	if (ret)
132493db446aSBoris Brezillon 		return ret;
132593db446aSBoris Brezillon 
132693db446aSBoris Brezillon 	/*
132793db446aSBoris Brezillon 	 * We don't want the CS line to be toggled between each byte/word
132893db446aSBoris Brezillon 	 * transfer to the NAND. The only way to guarantee that is to have the
132993db446aSBoris Brezillon 	 * NCS_{WR,RD}_{SETUP,HOLD} timings set to 0, which in turn means:
133093db446aSBoris Brezillon 	 *
133193db446aSBoris Brezillon 	 * NCS_WR_PULSE = NWE_CYCLE
133293db446aSBoris Brezillon 	 */
133393db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NCS_WR_SHIFT,
133493db446aSBoris Brezillon 					  ncycles);
133593db446aSBoris Brezillon 	if (ret)
133693db446aSBoris Brezillon 		return ret;
133793db446aSBoris Brezillon 
133893db446aSBoris Brezillon 	/*
133993db446aSBoris Brezillon 	 * As for the write setup timing, the read hold timing depends on the
134093db446aSBoris Brezillon 	 * operation done on the NAND:
134193db446aSBoris Brezillon 	 *
134293db446aSBoris Brezillon 	 * NRD_HOLD = max(tREH, tRHOH)
134393db446aSBoris Brezillon 	 */
134493db446aSBoris Brezillon 	timeps = max(conf->timings.sdr.tREH_min, conf->timings.sdr.tRHOH_min);
134593db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(timeps, mckperiodps);
134693db446aSBoris Brezillon 	totalcycles = ncycles;
134793db446aSBoris Brezillon 
134893db446aSBoris Brezillon 	/*
134993db446aSBoris Brezillon 	 * TDF = tRHZ - NRD_HOLD
135093db446aSBoris Brezillon 	 */
135193db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tRHZ_max, mckperiodps);
135293db446aSBoris Brezillon 	ncycles -= totalcycles;
135393db446aSBoris Brezillon 
135493db446aSBoris Brezillon 	/*
135593db446aSBoris Brezillon 	 * In ONFI 4.0 specs, tRHZ has been increased to support EDO NANDs and
135693db446aSBoris Brezillon 	 * we might end up with a config that does not fit in the TDF field.
135793db446aSBoris Brezillon 	 * Just take the max value in this case and hope that the NAND is more
135893db446aSBoris Brezillon 	 * tolerant than advertised.
135993db446aSBoris Brezillon 	 */
136093db446aSBoris Brezillon 	if (ncycles > ATMEL_SMC_MODE_TDF_MAX)
136193db446aSBoris Brezillon 		ncycles = ATMEL_SMC_MODE_TDF_MAX;
136293db446aSBoris Brezillon 	else if (ncycles < ATMEL_SMC_MODE_TDF_MIN)
136393db446aSBoris Brezillon 		ncycles = ATMEL_SMC_MODE_TDF_MIN;
136493db446aSBoris Brezillon 
136593db446aSBoris Brezillon 	smcconf->mode |= ATMEL_SMC_MODE_TDF(ncycles) |
136693db446aSBoris Brezillon 			 ATMEL_SMC_MODE_TDFMODE_OPTIMIZED;
136793db446aSBoris Brezillon 
136893db446aSBoris Brezillon 	/*
136993db446aSBoris Brezillon 	 * Read pulse timing directly matches tRP:
137093db446aSBoris Brezillon 	 *
137193db446aSBoris Brezillon 	 * NRD_PULSE = tRP
137293db446aSBoris Brezillon 	 */
137393db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tRP_min, mckperiodps);
137493db446aSBoris Brezillon 	totalcycles += ncycles;
137593db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NRD_SHIFT,
137693db446aSBoris Brezillon 					  ncycles);
137793db446aSBoris Brezillon 	if (ret)
137893db446aSBoris Brezillon 		return ret;
137993db446aSBoris Brezillon 
138093db446aSBoris Brezillon 	/*
1381*1c60e027SAlexander Dahl 	 * The read cycle timing is directly matching tRC, but is also
138293db446aSBoris Brezillon 	 * dependent on the setup and hold timings we calculated earlier,
138393db446aSBoris Brezillon 	 * which gives:
138493db446aSBoris Brezillon 	 *
138593db446aSBoris Brezillon 	 * NRD_CYCLE = max(tRC, NRD_PULSE + NRD_HOLD)
138693db446aSBoris Brezillon 	 *
138793db446aSBoris Brezillon 	 * NRD_SETUP is always 0.
138893db446aSBoris Brezillon 	 */
138993db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tRC_min, mckperiodps);
139093db446aSBoris Brezillon 	ncycles = max(totalcycles, ncycles);
139193db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_cycle(smcconf, ATMEL_SMC_NRD_SHIFT,
139293db446aSBoris Brezillon 					  ncycles);
139393db446aSBoris Brezillon 	if (ret)
139493db446aSBoris Brezillon 		return ret;
139593db446aSBoris Brezillon 
139693db446aSBoris Brezillon 	/*
139793db446aSBoris Brezillon 	 * We don't want the CS line to be toggled between each byte/word
139893db446aSBoris Brezillon 	 * transfer from the NAND. The only way to guarantee that is to have
139993db446aSBoris Brezillon 	 * the NCS_{WR,RD}_{SETUP,HOLD} timings set to 0, which in turn means:
140093db446aSBoris Brezillon 	 *
140193db446aSBoris Brezillon 	 * NCS_RD_PULSE = NRD_CYCLE
140293db446aSBoris Brezillon 	 */
140393db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NCS_RD_SHIFT,
140493db446aSBoris Brezillon 					  ncycles);
140593db446aSBoris Brezillon 	if (ret)
140693db446aSBoris Brezillon 		return ret;
140793db446aSBoris Brezillon 
140893db446aSBoris Brezillon 	/* Txxx timings are directly matching tXXX ones. */
140993db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tCLR_min, mckperiodps);
141093db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_timing(smcconf,
141193db446aSBoris Brezillon 					   ATMEL_HSMC_TIMINGS_TCLR_SHIFT,
141293db446aSBoris Brezillon 					   ncycles);
141393db446aSBoris Brezillon 	if (ret)
141493db446aSBoris Brezillon 		return ret;
141593db446aSBoris Brezillon 
141693db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tADL_min, mckperiodps);
141793db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_timing(smcconf,
141893db446aSBoris Brezillon 					   ATMEL_HSMC_TIMINGS_TADL_SHIFT,
141993db446aSBoris Brezillon 					   ncycles);
142093db446aSBoris Brezillon 	/*
142193db446aSBoris Brezillon 	 * Version 4 of the ONFI spec mandates that tADL be at least 400
142293db446aSBoris Brezillon 	 * nanoseconds, but, depending on the master clock rate, 400 ns may not
142393db446aSBoris Brezillon 	 * fit in the tADL field of the SMC reg. We need to relax the check and
142493db446aSBoris Brezillon 	 * accept the -ERANGE return code.
142593db446aSBoris Brezillon 	 *
142693db446aSBoris Brezillon 	 * Note that previous versions of the ONFI spec had a lower tADL_min
142793db446aSBoris Brezillon 	 * (100 or 200 ns). It's not clear why this timing constraint got
142893db446aSBoris Brezillon 	 * increased but it seems most NANDs are fine with values lower than
142993db446aSBoris Brezillon 	 * 400ns, so we should be safe.
143093db446aSBoris Brezillon 	 */
143193db446aSBoris Brezillon 	if (ret && ret != -ERANGE)
143293db446aSBoris Brezillon 		return ret;
143393db446aSBoris Brezillon 
143493db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tAR_min, mckperiodps);
143593db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_timing(smcconf,
143693db446aSBoris Brezillon 					   ATMEL_HSMC_TIMINGS_TAR_SHIFT,
143793db446aSBoris Brezillon 					   ncycles);
143893db446aSBoris Brezillon 	if (ret)
143993db446aSBoris Brezillon 		return ret;
144093db446aSBoris Brezillon 
144193db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tRR_min, mckperiodps);
144293db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_timing(smcconf,
144393db446aSBoris Brezillon 					   ATMEL_HSMC_TIMINGS_TRR_SHIFT,
144493db446aSBoris Brezillon 					   ncycles);
144593db446aSBoris Brezillon 	if (ret)
144693db446aSBoris Brezillon 		return ret;
144793db446aSBoris Brezillon 
144893db446aSBoris Brezillon 	ncycles = DIV_ROUND_UP(conf->timings.sdr.tWB_max, mckperiodps);
144993db446aSBoris Brezillon 	ret = atmel_smc_cs_conf_set_timing(smcconf,
145093db446aSBoris Brezillon 					   ATMEL_HSMC_TIMINGS_TWB_SHIFT,
145193db446aSBoris Brezillon 					   ncycles);
145293db446aSBoris Brezillon 	if (ret)
145393db446aSBoris Brezillon 		return ret;
145493db446aSBoris Brezillon 
145593db446aSBoris Brezillon 	/* Attach the CS line to the NFC logic. */
145693db446aSBoris Brezillon 	smcconf->timings |= ATMEL_HSMC_TIMINGS_NFSEL;
145793db446aSBoris Brezillon 
145893db446aSBoris Brezillon 	/* Set the appropriate data bus width. */
145993db446aSBoris Brezillon 	if (nand->base.options & NAND_BUSWIDTH_16)
146093db446aSBoris Brezillon 		smcconf->mode |= ATMEL_SMC_MODE_DBW_16;
146193db446aSBoris Brezillon 
146293db446aSBoris Brezillon 	/* Operate in NRD/NWE READ/WRITEMODE. */
146393db446aSBoris Brezillon 	smcconf->mode |= ATMEL_SMC_MODE_READMODE_NRD |
146493db446aSBoris Brezillon 			 ATMEL_SMC_MODE_WRITEMODE_NWE;
146593db446aSBoris Brezillon 
146693db446aSBoris Brezillon 	return 0;
146793db446aSBoris Brezillon }
146893db446aSBoris Brezillon 
atmel_smc_nand_setup_interface(struct atmel_nand * nand,int csline,const struct nand_interface_config * conf)14694c46667bSMiquel Raynal static int atmel_smc_nand_setup_interface(struct atmel_nand *nand,
147093db446aSBoris Brezillon 					int csline,
14714c46667bSMiquel Raynal 					const struct nand_interface_config *conf)
147293db446aSBoris Brezillon {
147393db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
147493db446aSBoris Brezillon 	struct atmel_smc_cs_conf smcconf;
147593db446aSBoris Brezillon 	struct atmel_nand_cs *cs;
147693db446aSBoris Brezillon 	int ret;
147793db446aSBoris Brezillon 
147893db446aSBoris Brezillon 	nc = to_nand_controller(nand->base.controller);
147993db446aSBoris Brezillon 
148093db446aSBoris Brezillon 	ret = atmel_smc_nand_prepare_smcconf(nand, conf, &smcconf);
148193db446aSBoris Brezillon 	if (ret)
148293db446aSBoris Brezillon 		return ret;
148393db446aSBoris Brezillon 
148493db446aSBoris Brezillon 	if (csline == NAND_DATA_IFACE_CHECK_ONLY)
148593db446aSBoris Brezillon 		return 0;
148693db446aSBoris Brezillon 
148793db446aSBoris Brezillon 	cs = &nand->cs[csline];
148893db446aSBoris Brezillon 	cs->smcconf = smcconf;
148993db446aSBoris Brezillon 	atmel_smc_cs_conf_apply(nc->smc, cs->id, &cs->smcconf);
149093db446aSBoris Brezillon 
149193db446aSBoris Brezillon 	return 0;
149293db446aSBoris Brezillon }
149393db446aSBoris Brezillon 
atmel_hsmc_nand_setup_interface(struct atmel_nand * nand,int csline,const struct nand_interface_config * conf)14944c46667bSMiquel Raynal static int atmel_hsmc_nand_setup_interface(struct atmel_nand *nand,
149593db446aSBoris Brezillon 					int csline,
14964c46667bSMiquel Raynal 					const struct nand_interface_config *conf)
149793db446aSBoris Brezillon {
149893db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
149993db446aSBoris Brezillon 	struct atmel_smc_cs_conf smcconf;
150093db446aSBoris Brezillon 	struct atmel_nand_cs *cs;
150193db446aSBoris Brezillon 	int ret;
150293db446aSBoris Brezillon 
150393db446aSBoris Brezillon 	nc = to_hsmc_nand_controller(nand->base.controller);
150493db446aSBoris Brezillon 
150593db446aSBoris Brezillon 	ret = atmel_smc_nand_prepare_smcconf(nand, conf, &smcconf);
150693db446aSBoris Brezillon 	if (ret)
150793db446aSBoris Brezillon 		return ret;
150893db446aSBoris Brezillon 
150993db446aSBoris Brezillon 	if (csline == NAND_DATA_IFACE_CHECK_ONLY)
151093db446aSBoris Brezillon 		return 0;
151193db446aSBoris Brezillon 
151293db446aSBoris Brezillon 	cs = &nand->cs[csline];
151393db446aSBoris Brezillon 	cs->smcconf = smcconf;
151493db446aSBoris Brezillon 
151593db446aSBoris Brezillon 	if (cs->rb.type == ATMEL_NAND_NATIVE_RB)
151693db446aSBoris Brezillon 		cs->smcconf.timings |= ATMEL_HSMC_TIMINGS_RBNSEL(cs->rb.id);
151793db446aSBoris Brezillon 
151893db446aSBoris Brezillon 	atmel_hsmc_cs_conf_apply(nc->base.smc, nc->hsmc_layout, cs->id,
151993db446aSBoris Brezillon 				 &cs->smcconf);
152093db446aSBoris Brezillon 
152193db446aSBoris Brezillon 	return 0;
152293db446aSBoris Brezillon }
152393db446aSBoris Brezillon 
atmel_nand_setup_interface(struct nand_chip * chip,int csline,const struct nand_interface_config * conf)15244c46667bSMiquel Raynal static int atmel_nand_setup_interface(struct nand_chip *chip, int csline,
15254c46667bSMiquel Raynal 				      const struct nand_interface_config *conf)
152693db446aSBoris Brezillon {
152793db446aSBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
1528ed2a4910SMiquel Raynal 	const struct nand_sdr_timings *sdr;
152993db446aSBoris Brezillon 	struct atmel_nand_controller *nc;
153093db446aSBoris Brezillon 
1531ed2a4910SMiquel Raynal 	sdr = nand_get_sdr_timings(conf);
1532ed2a4910SMiquel Raynal 	if (IS_ERR(sdr))
1533ed2a4910SMiquel Raynal 		return PTR_ERR(sdr);
1534ed2a4910SMiquel Raynal 
153593db446aSBoris Brezillon 	nc = to_nand_controller(nand->base.controller);
153693db446aSBoris Brezillon 
153793db446aSBoris Brezillon 	if (csline >= nand->numcs ||
153893db446aSBoris Brezillon 	    (csline < 0 && csline != NAND_DATA_IFACE_CHECK_ONLY))
153993db446aSBoris Brezillon 		return -EINVAL;
154093db446aSBoris Brezillon 
15414c46667bSMiquel Raynal 	return nc->caps->ops->setup_interface(nand, csline, conf);
154293db446aSBoris Brezillon }
154393db446aSBoris Brezillon 
atmel_nand_exec_op(struct nand_chip * chip,const struct nand_operation * op,bool check_only)154403b3e0c2SBoris Brezillon static int atmel_nand_exec_op(struct nand_chip *chip,
154503b3e0c2SBoris Brezillon 			      const struct nand_operation *op,
154603b3e0c2SBoris Brezillon 			      bool check_only)
154703b3e0c2SBoris Brezillon {
154803b3e0c2SBoris Brezillon 	struct atmel_nand *nand = to_atmel_nand(chip);
154903b3e0c2SBoris Brezillon 	struct atmel_nand_controller *nc;
155003b3e0c2SBoris Brezillon 
155103b3e0c2SBoris Brezillon 	nc = to_nand_controller(nand->base.controller);
155203b3e0c2SBoris Brezillon 
155303b3e0c2SBoris Brezillon 	return nc->caps->ops->exec_op(nand, op, check_only);
155403b3e0c2SBoris Brezillon }
155503b3e0c2SBoris Brezillon 
atmel_nand_init(struct atmel_nand_controller * nc,struct atmel_nand * nand)155693db446aSBoris Brezillon static void atmel_nand_init(struct atmel_nand_controller *nc,
155793db446aSBoris Brezillon 			    struct atmel_nand *nand)
155893db446aSBoris Brezillon {
155993db446aSBoris Brezillon 	struct nand_chip *chip = &nand->base;
156093db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
156193db446aSBoris Brezillon 
156293db446aSBoris Brezillon 	mtd->dev.parent = nc->dev;
156393db446aSBoris Brezillon 	nand->base.controller = &nc->base;
156493db446aSBoris Brezillon 
15654c46667bSMiquel Raynal 	if (!nc->mck || !nc->caps->ops->setup_interface)
15667a08dbaeSBoris Brezillon 		chip->options |= NAND_KEEP_TIMINGS;
156793db446aSBoris Brezillon 
156893db446aSBoris Brezillon 	/*
156993db446aSBoris Brezillon 	 * Use a bounce buffer when the buffer passed by the MTD user is not
157093db446aSBoris Brezillon 	 * suitable for DMA.
157193db446aSBoris Brezillon 	 */
157293db446aSBoris Brezillon 	if (nc->dmac)
1573ce8148d7SMiquel Raynal 		chip->options |= NAND_USES_DMA;
157493db446aSBoris Brezillon 
157593db446aSBoris Brezillon 	/* Default to HW ECC if pmecc is available. */
157693db446aSBoris Brezillon 	if (nc->pmecc)
1577bace41f8SMiquel Raynal 		chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
157893db446aSBoris Brezillon }
157993db446aSBoris Brezillon 
atmel_smc_nand_init(struct atmel_nand_controller * nc,struct atmel_nand * nand)158093db446aSBoris Brezillon static void atmel_smc_nand_init(struct atmel_nand_controller *nc,
158193db446aSBoris Brezillon 				struct atmel_nand *nand)
158293db446aSBoris Brezillon {
158393db446aSBoris Brezillon 	struct nand_chip *chip = &nand->base;
158493db446aSBoris Brezillon 	struct atmel_smc_nand_controller *smc_nc;
158593db446aSBoris Brezillon 	int i;
158693db446aSBoris Brezillon 
158793db446aSBoris Brezillon 	atmel_nand_init(nc, nand);
158893db446aSBoris Brezillon 
158993db446aSBoris Brezillon 	smc_nc = to_smc_nand_controller(chip->controller);
1590e2c19c50STudor Ambarus 	if (!smc_nc->ebi_csa_regmap)
159193db446aSBoris Brezillon 		return;
159293db446aSBoris Brezillon 
159393db446aSBoris Brezillon 	/* Attach the CS to the NAND Flash logic. */
159493db446aSBoris Brezillon 	for (i = 0; i < nand->numcs; i++)
1595ccf20cccSTudor Ambarus 		regmap_update_bits(smc_nc->ebi_csa_regmap,
1596ccf20cccSTudor Ambarus 				   smc_nc->ebi_csa->offs,
159793db446aSBoris Brezillon 				   BIT(nand->cs[i].id), BIT(nand->cs[i].id));
1598ccf20cccSTudor Ambarus 
1599ccf20cccSTudor Ambarus 	if (smc_nc->ebi_csa->nfd0_on_d16)
1600ccf20cccSTudor Ambarus 		regmap_update_bits(smc_nc->ebi_csa_regmap,
1601ccf20cccSTudor Ambarus 				   smc_nc->ebi_csa->offs,
1602ccf20cccSTudor Ambarus 				   smc_nc->ebi_csa->nfd0_on_d16,
1603ccf20cccSTudor Ambarus 				   smc_nc->ebi_csa->nfd0_on_d16);
160493db446aSBoris Brezillon }
160593db446aSBoris Brezillon 
atmel_nand_controller_remove_nand(struct atmel_nand * nand)16067928225fSMiquel Raynal static int atmel_nand_controller_remove_nand(struct atmel_nand *nand)
160793db446aSBoris Brezillon {
160893db446aSBoris Brezillon 	struct nand_chip *chip = &nand->base;
160993db446aSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
161093db446aSBoris Brezillon 	int ret;
161193db446aSBoris Brezillon 
161293db446aSBoris Brezillon 	ret = mtd_device_unregister(mtd);
161393db446aSBoris Brezillon 	if (ret)
161493db446aSBoris Brezillon 		return ret;
161593db446aSBoris Brezillon 
161693db446aSBoris Brezillon 	nand_cleanup(chip);
161793db446aSBoris Brezillon 	list_del(&nand->node);
161893db446aSBoris Brezillon 
161993db446aSBoris Brezillon 	return 0;
162093db446aSBoris Brezillon }
162193db446aSBoris Brezillon 
atmel_nand_create(struct atmel_nand_controller * nc,struct device_node * np,int reg_cells)162293db446aSBoris Brezillon static struct atmel_nand *atmel_nand_create(struct atmel_nand_controller *nc,
162393db446aSBoris Brezillon 					    struct device_node *np,
162493db446aSBoris Brezillon 					    int reg_cells)
162593db446aSBoris Brezillon {
162693db446aSBoris Brezillon 	struct atmel_nand *nand;
162793db446aSBoris Brezillon 	struct gpio_desc *gpio;
162893db446aSBoris Brezillon 	int numcs, ret, i;
162993db446aSBoris Brezillon 
163093db446aSBoris Brezillon 	numcs = of_property_count_elems_of_size(np, "reg",
163193db446aSBoris Brezillon 						reg_cells * sizeof(u32));
163293db446aSBoris Brezillon 	if (numcs < 1) {
163393db446aSBoris Brezillon 		dev_err(nc->dev, "Missing or invalid reg property\n");
163493db446aSBoris Brezillon 		return ERR_PTR(-EINVAL);
163593db446aSBoris Brezillon 	}
163693db446aSBoris Brezillon 
16372f91eb69SGustavo A. R. Silva 	nand = devm_kzalloc(nc->dev, struct_size(nand, cs, numcs), GFP_KERNEL);
163818567523SZhen Lei 	if (!nand)
163993db446aSBoris Brezillon 		return ERR_PTR(-ENOMEM);
164093db446aSBoris Brezillon 
164193db446aSBoris Brezillon 	nand->numcs = numcs;
164293db446aSBoris Brezillon 
16437a95a72eSDmitry Torokhov 	gpio = devm_fwnode_gpiod_get(nc->dev, of_fwnode_handle(np),
16447a95a72eSDmitry Torokhov 				     "det", GPIOD_IN, "nand-det");
164593db446aSBoris Brezillon 	if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {
164693db446aSBoris Brezillon 		dev_err(nc->dev,
164793db446aSBoris Brezillon 			"Failed to get detect gpio (err = %ld)\n",
164893db446aSBoris Brezillon 			PTR_ERR(gpio));
164993db446aSBoris Brezillon 		return ERR_CAST(gpio);
165093db446aSBoris Brezillon 	}
165193db446aSBoris Brezillon 
165293db446aSBoris Brezillon 	if (!IS_ERR(gpio))
165393db446aSBoris Brezillon 		nand->cdgpio = gpio;
165493db446aSBoris Brezillon 
165593db446aSBoris Brezillon 	for (i = 0; i < numcs; i++) {
165693db446aSBoris Brezillon 		struct resource res;
165793db446aSBoris Brezillon 		u32 val;
165893db446aSBoris Brezillon 
165993db446aSBoris Brezillon 		ret = of_address_to_resource(np, 0, &res);
166093db446aSBoris Brezillon 		if (ret) {
166193db446aSBoris Brezillon 			dev_err(nc->dev, "Invalid reg property (err = %d)\n",
166293db446aSBoris Brezillon 				ret);
166393db446aSBoris Brezillon 			return ERR_PTR(ret);
166493db446aSBoris Brezillon 		}
166593db446aSBoris Brezillon 
166693db446aSBoris Brezillon 		ret = of_property_read_u32_index(np, "reg", i * reg_cells,
166793db446aSBoris Brezillon 						 &val);
166893db446aSBoris Brezillon 		if (ret) {
166993db446aSBoris Brezillon 			dev_err(nc->dev, "Invalid reg property (err = %d)\n",
167093db446aSBoris Brezillon 				ret);
167193db446aSBoris Brezillon 			return ERR_PTR(ret);
167293db446aSBoris Brezillon 		}
167393db446aSBoris Brezillon 
167493db446aSBoris Brezillon 		nand->cs[i].id = val;
167593db446aSBoris Brezillon 
167693db446aSBoris Brezillon 		nand->cs[i].io.dma = res.start;
167793db446aSBoris Brezillon 		nand->cs[i].io.virt = devm_ioremap_resource(nc->dev, &res);
167893db446aSBoris Brezillon 		if (IS_ERR(nand->cs[i].io.virt))
167993db446aSBoris Brezillon 			return ERR_CAST(nand->cs[i].io.virt);
168093db446aSBoris Brezillon 
168193db446aSBoris Brezillon 		if (!of_property_read_u32(np, "atmel,rb", &val)) {
168293db446aSBoris Brezillon 			if (val > ATMEL_NFC_MAX_RB_ID)
168393db446aSBoris Brezillon 				return ERR_PTR(-EINVAL);
168493db446aSBoris Brezillon 
168593db446aSBoris Brezillon 			nand->cs[i].rb.type = ATMEL_NAND_NATIVE_RB;
168693db446aSBoris Brezillon 			nand->cs[i].rb.id = val;
168793db446aSBoris Brezillon 		} else {
16887a95a72eSDmitry Torokhov 			gpio = devm_fwnode_gpiod_get_index(nc->dev,
16897a95a72eSDmitry Torokhov 							   of_fwnode_handle(np),
16907a95a72eSDmitry Torokhov 							   "rb", i, GPIOD_IN,
16917a95a72eSDmitry Torokhov 							   "nand-rb");
169293db446aSBoris Brezillon 			if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {
169393db446aSBoris Brezillon 				dev_err(nc->dev,
169493db446aSBoris Brezillon 					"Failed to get R/B gpio (err = %ld)\n",
169593db446aSBoris Brezillon 					PTR_ERR(gpio));
169693db446aSBoris Brezillon 				return ERR_CAST(gpio);
169793db446aSBoris Brezillon 			}
169893db446aSBoris Brezillon 
169993db446aSBoris Brezillon 			if (!IS_ERR(gpio)) {
170093db446aSBoris Brezillon 				nand->cs[i].rb.type = ATMEL_NAND_GPIO_RB;
170193db446aSBoris Brezillon 				nand->cs[i].rb.gpio = gpio;
170293db446aSBoris Brezillon 			}
170393db446aSBoris Brezillon 		}
170493db446aSBoris Brezillon 
17057a95a72eSDmitry Torokhov 		gpio = devm_fwnode_gpiod_get_index(nc->dev,
17067a95a72eSDmitry Torokhov 						   of_fwnode_handle(np),
17077a95a72eSDmitry Torokhov 						   "cs", i, GPIOD_OUT_HIGH,
170893db446aSBoris Brezillon 						   "nand-cs");
170993db446aSBoris Brezillon 		if (IS_ERR(gpio) && PTR_ERR(gpio) != -ENOENT) {
171093db446aSBoris Brezillon 			dev_err(nc->dev,
171193db446aSBoris Brezillon 				"Failed to get CS gpio (err = %ld)\n",
171293db446aSBoris Brezillon 				PTR_ERR(gpio));
171393db446aSBoris Brezillon 			return ERR_CAST(gpio);
171493db446aSBoris Brezillon 		}
171593db446aSBoris Brezillon 
171693db446aSBoris Brezillon 		if (!IS_ERR(gpio))
171793db446aSBoris Brezillon 			nand->cs[i].csgpio = gpio;
171893db446aSBoris Brezillon 	}
171993db446aSBoris Brezillon 
172093db446aSBoris Brezillon 	nand_set_flash_node(&nand->base, np);
172193db446aSBoris Brezillon 
172293db446aSBoris Brezillon 	return nand;
172393db446aSBoris Brezillon }
172493db446aSBoris Brezillon 
172593db446aSBoris Brezillon static int
atmel_nand_controller_add_nand(struct atmel_nand_controller * nc,struct atmel_nand * nand)172693db446aSBoris Brezillon atmel_nand_controller_add_nand(struct atmel_nand_controller *nc,
172793db446aSBoris Brezillon 			       struct atmel_nand *nand)
172893db446aSBoris Brezillon {
1729577e010cSMiquel Raynal 	struct nand_chip *chip = &nand->base;
1730577e010cSMiquel Raynal 	struct mtd_info *mtd = nand_to_mtd(chip);
173193db446aSBoris Brezillon 	int ret;
173293db446aSBoris Brezillon 
173393db446aSBoris Brezillon 	/* No card inserted, skip this NAND. */
173493db446aSBoris Brezillon 	if (nand->cdgpio && gpiod_get_value(nand->cdgpio)) {
173593db446aSBoris Brezillon 		dev_info(nc->dev, "No SmartMedia card inserted.\n");
173693db446aSBoris Brezillon 		return 0;
173793db446aSBoris Brezillon 	}
173893db446aSBoris Brezillon 
173993db446aSBoris Brezillon 	nc->caps->ops->nand_init(nc, nand);
174093db446aSBoris Brezillon 
174100ad378fSBoris Brezillon 	ret = nand_scan(chip, nand->numcs);
17427928225fSMiquel Raynal 	if (ret) {
1743577e010cSMiquel Raynal 		dev_err(nc->dev, "NAND scan failed: %d\n", ret);
17447928225fSMiquel Raynal 		return ret;
17457928225fSMiquel Raynal 	}
17467928225fSMiquel Raynal 
17477928225fSMiquel Raynal 	ret = mtd_device_register(mtd, NULL, 0);
17487928225fSMiquel Raynal 	if (ret) {
17497928225fSMiquel Raynal 		dev_err(nc->dev, "Failed to register mtd device: %d\n", ret);
17507928225fSMiquel Raynal 		nand_cleanup(chip);
17517928225fSMiquel Raynal 		return ret;
17527928225fSMiquel Raynal 	}
17537928225fSMiquel Raynal 
17547928225fSMiquel Raynal 	list_add_tail(&nand->node, &nc->chips);
17557928225fSMiquel Raynal 
17567928225fSMiquel Raynal 	return 0;
175793db446aSBoris Brezillon }
175893db446aSBoris Brezillon 
175993db446aSBoris Brezillon static int
atmel_nand_controller_remove_nands(struct atmel_nand_controller * nc)176093db446aSBoris Brezillon atmel_nand_controller_remove_nands(struct atmel_nand_controller *nc)
176193db446aSBoris Brezillon {
176293db446aSBoris Brezillon 	struct atmel_nand *nand, *tmp;
176393db446aSBoris Brezillon 	int ret;
176493db446aSBoris Brezillon 
176593db446aSBoris Brezillon 	list_for_each_entry_safe(nand, tmp, &nc->chips, node) {
17667928225fSMiquel Raynal 		ret = atmel_nand_controller_remove_nand(nand);
176793db446aSBoris Brezillon 		if (ret)
176893db446aSBoris Brezillon 			return ret;
176993db446aSBoris Brezillon 	}
177093db446aSBoris Brezillon 
177193db446aSBoris Brezillon 	return 0;
177293db446aSBoris Brezillon }
177393db446aSBoris Brezillon 
177493db446aSBoris Brezillon static int
atmel_nand_controller_legacy_add_nands(struct atmel_nand_controller * nc)177593db446aSBoris Brezillon atmel_nand_controller_legacy_add_nands(struct atmel_nand_controller *nc)
177693db446aSBoris Brezillon {
177793db446aSBoris Brezillon 	struct device *dev = nc->dev;
177893db446aSBoris Brezillon 	struct platform_device *pdev = to_platform_device(dev);
177993db446aSBoris Brezillon 	struct atmel_nand *nand;
178093db446aSBoris Brezillon 	struct gpio_desc *gpio;
178193db446aSBoris Brezillon 	struct resource *res;
178293db446aSBoris Brezillon 
178393db446aSBoris Brezillon 	/*
178493db446aSBoris Brezillon 	 * Legacy bindings only allow connecting a single NAND with a unique CS
178593db446aSBoris Brezillon 	 * line to the controller.
178693db446aSBoris Brezillon 	 */
178793db446aSBoris Brezillon 	nand = devm_kzalloc(nc->dev, sizeof(*nand) + sizeof(*nand->cs),
178893db446aSBoris Brezillon 			    GFP_KERNEL);
178993db446aSBoris Brezillon 	if (!nand)
179093db446aSBoris Brezillon 		return -ENOMEM;
179193db446aSBoris Brezillon 
179293db446aSBoris Brezillon 	nand->numcs = 1;
179393db446aSBoris Brezillon 
179409ea085fSYangtao Li 	nand->cs[0].io.virt = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
179593db446aSBoris Brezillon 	if (IS_ERR(nand->cs[0].io.virt))
179693db446aSBoris Brezillon 		return PTR_ERR(nand->cs[0].io.virt);
179793db446aSBoris Brezillon 
179893db446aSBoris Brezillon 	nand->cs[0].io.dma = res->start;
179993db446aSBoris Brezillon 
180093db446aSBoris Brezillon 	/*
180193db446aSBoris Brezillon 	 * The old driver was hardcoding the CS id to 3 for all sama5
180293db446aSBoris Brezillon 	 * controllers. Since this id is only meaningful for the sama5
180393db446aSBoris Brezillon 	 * controller we can safely assign this id to 3 no matter the
180493db446aSBoris Brezillon 	 * controller.
180593db446aSBoris Brezillon 	 * If one wants to connect a NAND to a different CS line, he will
180693db446aSBoris Brezillon 	 * have to use the new bindings.
180793db446aSBoris Brezillon 	 */
180893db446aSBoris Brezillon 	nand->cs[0].id = 3;
180993db446aSBoris Brezillon 
181093db446aSBoris Brezillon 	/* R/B GPIO. */
181193db446aSBoris Brezillon 	gpio = devm_gpiod_get_index_optional(dev, NULL, 0,  GPIOD_IN);
181293db446aSBoris Brezillon 	if (IS_ERR(gpio)) {
181393db446aSBoris Brezillon 		dev_err(dev, "Failed to get R/B gpio (err = %ld)\n",
181493db446aSBoris Brezillon 			PTR_ERR(gpio));
181593db446aSBoris Brezillon 		return PTR_ERR(gpio);
181693db446aSBoris Brezillon 	}
181793db446aSBoris Brezillon 
181893db446aSBoris Brezillon 	if (gpio) {
181993db446aSBoris Brezillon 		nand->cs[0].rb.type = ATMEL_NAND_GPIO_RB;
182093db446aSBoris Brezillon 		nand->cs[0].rb.gpio = gpio;
182193db446aSBoris Brezillon 	}
182293db446aSBoris Brezillon 
182393db446aSBoris Brezillon 	/* CS GPIO. */
182493db446aSBoris Brezillon 	gpio = devm_gpiod_get_index_optional(dev, NULL, 1, GPIOD_OUT_HIGH);
182593db446aSBoris Brezillon 	if (IS_ERR(gpio)) {
182693db446aSBoris Brezillon 		dev_err(dev, "Failed to get CS gpio (err = %ld)\n",
182793db446aSBoris Brezillon 			PTR_ERR(gpio));
182893db446aSBoris Brezillon 		return PTR_ERR(gpio);
182993db446aSBoris Brezillon 	}
183093db446aSBoris Brezillon 
183193db446aSBoris Brezillon 	nand->cs[0].csgpio = gpio;
183293db446aSBoris Brezillon 
183393db446aSBoris Brezillon 	/* Card detect GPIO. */
183493db446aSBoris Brezillon 	gpio = devm_gpiod_get_index_optional(nc->dev, NULL, 2, GPIOD_IN);
183593db446aSBoris Brezillon 	if (IS_ERR(gpio)) {
183693db446aSBoris Brezillon 		dev_err(dev,
183793db446aSBoris Brezillon 			"Failed to get detect gpio (err = %ld)\n",
183893db446aSBoris Brezillon 			PTR_ERR(gpio));
183993db446aSBoris Brezillon 		return PTR_ERR(gpio);
184093db446aSBoris Brezillon 	}
184193db446aSBoris Brezillon 
184293db446aSBoris Brezillon 	nand->cdgpio = gpio;
184393db446aSBoris Brezillon 
184493db446aSBoris Brezillon 	nand_set_flash_node(&nand->base, nc->dev->of_node);
184593db446aSBoris Brezillon 
184693db446aSBoris Brezillon 	return atmel_nand_controller_add_nand(nc, nand);
184793db446aSBoris Brezillon }
184893db446aSBoris Brezillon 
atmel_nand_controller_add_nands(struct atmel_nand_controller * nc)184993db446aSBoris Brezillon static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc)
185093db446aSBoris Brezillon {
185193db446aSBoris Brezillon 	struct device_node *np, *nand_np;
185293db446aSBoris Brezillon 	struct device *dev = nc->dev;
185393db446aSBoris Brezillon 	int ret, reg_cells;
185493db446aSBoris Brezillon 	u32 val;
185593db446aSBoris Brezillon 
185693db446aSBoris Brezillon 	/* We do not retrieve the SMC syscon when parsing old DTs. */
185793db446aSBoris Brezillon 	if (nc->caps->legacy_of_bindings)
185893db446aSBoris Brezillon 		return atmel_nand_controller_legacy_add_nands(nc);
185993db446aSBoris Brezillon 
186093db446aSBoris Brezillon 	np = dev->of_node;
186193db446aSBoris Brezillon 
186293db446aSBoris Brezillon 	ret = of_property_read_u32(np, "#address-cells", &val);
186393db446aSBoris Brezillon 	if (ret) {
186493db446aSBoris Brezillon 		dev_err(dev, "missing #address-cells property\n");
186593db446aSBoris Brezillon 		return ret;
186693db446aSBoris Brezillon 	}
186793db446aSBoris Brezillon 
186893db446aSBoris Brezillon 	reg_cells = val;
186993db446aSBoris Brezillon 
187093db446aSBoris Brezillon 	ret = of_property_read_u32(np, "#size-cells", &val);
187193db446aSBoris Brezillon 	if (ret) {
1872e39bb786SMiquel Raynal 		dev_err(dev, "missing #size-cells property\n");
187393db446aSBoris Brezillon 		return ret;
187493db446aSBoris Brezillon 	}
187593db446aSBoris Brezillon 
187693db446aSBoris Brezillon 	reg_cells += val;
187793db446aSBoris Brezillon 
187893db446aSBoris Brezillon 	for_each_child_of_node(np, nand_np) {
187993db446aSBoris Brezillon 		struct atmel_nand *nand;
188093db446aSBoris Brezillon 
188193db446aSBoris Brezillon 		nand = atmel_nand_create(nc, nand_np, reg_cells);
188293db446aSBoris Brezillon 		if (IS_ERR(nand)) {
188393db446aSBoris Brezillon 			ret = PTR_ERR(nand);
188493db446aSBoris Brezillon 			goto err;
188593db446aSBoris Brezillon 		}
188693db446aSBoris Brezillon 
188793db446aSBoris Brezillon 		ret = atmel_nand_controller_add_nand(nc, nand);
188893db446aSBoris Brezillon 		if (ret)
188993db446aSBoris Brezillon 			goto err;
189093db446aSBoris Brezillon 	}
189193db446aSBoris Brezillon 
189293db446aSBoris Brezillon 	return 0;
189393db446aSBoris Brezillon 
189493db446aSBoris Brezillon err:
189593db446aSBoris Brezillon 	atmel_nand_controller_remove_nands(nc);
189693db446aSBoris Brezillon 
189793db446aSBoris Brezillon 	return ret;
189893db446aSBoris Brezillon }
189993db446aSBoris Brezillon 
atmel_nand_controller_cleanup(struct atmel_nand_controller * nc)190093db446aSBoris Brezillon static void atmel_nand_controller_cleanup(struct atmel_nand_controller *nc)
190193db446aSBoris Brezillon {
190293db446aSBoris Brezillon 	if (nc->dmac)
190393db446aSBoris Brezillon 		dma_release_channel(nc->dmac);
190493db446aSBoris Brezillon 
190593db446aSBoris Brezillon 	clk_put(nc->mck);
190693db446aSBoris Brezillon }
190793db446aSBoris Brezillon 
1908ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg at91sam9260_ebi_csa = {
1909ccf20cccSTudor Ambarus 	.offs = AT91SAM9260_MATRIX_EBICSA,
1910ccf20cccSTudor Ambarus };
1911ccf20cccSTudor Ambarus 
1912ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg at91sam9261_ebi_csa = {
1913ccf20cccSTudor Ambarus 	.offs = AT91SAM9261_MATRIX_EBICSA,
1914ccf20cccSTudor Ambarus };
1915ccf20cccSTudor Ambarus 
1916ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg at91sam9263_ebi_csa = {
1917ccf20cccSTudor Ambarus 	.offs = AT91SAM9263_MATRIX_EBI0CSA,
1918ccf20cccSTudor Ambarus };
1919ccf20cccSTudor Ambarus 
1920ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg at91sam9rl_ebi_csa = {
1921ccf20cccSTudor Ambarus 	.offs = AT91SAM9RL_MATRIX_EBICSA,
1922ccf20cccSTudor Ambarus };
1923ccf20cccSTudor Ambarus 
1924ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg at91sam9g45_ebi_csa = {
1925ccf20cccSTudor Ambarus 	.offs = AT91SAM9G45_MATRIX_EBICSA,
1926ccf20cccSTudor Ambarus };
1927ccf20cccSTudor Ambarus 
1928ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg at91sam9n12_ebi_csa = {
1929ccf20cccSTudor Ambarus 	.offs = AT91SAM9N12_MATRIX_EBICSA,
1930ccf20cccSTudor Ambarus };
1931ccf20cccSTudor Ambarus 
1932ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg at91sam9x5_ebi_csa = {
1933ccf20cccSTudor Ambarus 	.offs = AT91SAM9X5_MATRIX_EBICSA,
1934ccf20cccSTudor Ambarus };
1935ccf20cccSTudor Ambarus 
1936ccf20cccSTudor Ambarus static const struct atmel_smc_nand_ebi_csa_cfg sam9x60_ebi_csa = {
1937ccf20cccSTudor Ambarus 	.offs = AT91_SFR_CCFG_EBICSA,
1938ccf20cccSTudor Ambarus 	.nfd0_on_d16 = AT91_SFR_CCFG_NFD0_ON_D16,
1939ccf20cccSTudor Ambarus };
1940ccf20cccSTudor Ambarus 
1941e02dacd3SMiquel Raynal static const struct of_device_id __maybe_unused atmel_ebi_csa_regmap_of_ids[] = {
194293db446aSBoris Brezillon 	{
194393db446aSBoris Brezillon 		.compatible = "atmel,at91sam9260-matrix",
1944ccf20cccSTudor Ambarus 		.data = &at91sam9260_ebi_csa,
194593db446aSBoris Brezillon 	},
194693db446aSBoris Brezillon 	{
194793db446aSBoris Brezillon 		.compatible = "atmel,at91sam9261-matrix",
1948ccf20cccSTudor Ambarus 		.data = &at91sam9261_ebi_csa,
194993db446aSBoris Brezillon 	},
195093db446aSBoris Brezillon 	{
195193db446aSBoris Brezillon 		.compatible = "atmel,at91sam9263-matrix",
1952ccf20cccSTudor Ambarus 		.data = &at91sam9263_ebi_csa,
195393db446aSBoris Brezillon 	},
195493db446aSBoris Brezillon 	{
195593db446aSBoris Brezillon 		.compatible = "atmel,at91sam9rl-matrix",
1956ccf20cccSTudor Ambarus 		.data = &at91sam9rl_ebi_csa,
195793db446aSBoris Brezillon 	},
195893db446aSBoris Brezillon 	{
195993db446aSBoris Brezillon 		.compatible = "atmel,at91sam9g45-matrix",
1960ccf20cccSTudor Ambarus 		.data = &at91sam9g45_ebi_csa,
196193db446aSBoris Brezillon 	},
196293db446aSBoris Brezillon 	{
196393db446aSBoris Brezillon 		.compatible = "atmel,at91sam9n12-matrix",
1964ccf20cccSTudor Ambarus 		.data = &at91sam9n12_ebi_csa,
196593db446aSBoris Brezillon 	},
196693db446aSBoris Brezillon 	{
196793db446aSBoris Brezillon 		.compatible = "atmel,at91sam9x5-matrix",
1968ccf20cccSTudor Ambarus 		.data = &at91sam9x5_ebi_csa,
1969ccf20cccSTudor Ambarus 	},
1970ccf20cccSTudor Ambarus 	{
1971ccf20cccSTudor Ambarus 		.compatible = "microchip,sam9x60-sfr",
1972ccf20cccSTudor Ambarus 		.data = &sam9x60_ebi_csa,
197393db446aSBoris Brezillon 	},
197493db446aSBoris Brezillon 	{ /* sentinel */ },
197593db446aSBoris Brezillon };
197693db446aSBoris Brezillon 
atmel_nand_attach_chip(struct nand_chip * chip)1977577e010cSMiquel Raynal static int atmel_nand_attach_chip(struct nand_chip *chip)
1978577e010cSMiquel Raynal {
1979577e010cSMiquel Raynal 	struct atmel_nand_controller *nc = to_nand_controller(chip->controller);
1980577e010cSMiquel Raynal 	struct atmel_nand *nand = to_atmel_nand(chip);
1981577e010cSMiquel Raynal 	struct mtd_info *mtd = nand_to_mtd(chip);
1982577e010cSMiquel Raynal 	int ret;
1983577e010cSMiquel Raynal 
1984577e010cSMiquel Raynal 	ret = nc->caps->ops->ecc_init(chip);
1985577e010cSMiquel Raynal 	if (ret)
1986577e010cSMiquel Raynal 		return ret;
1987577e010cSMiquel Raynal 
1988577e010cSMiquel Raynal 	if (nc->caps->legacy_of_bindings || !nc->dev->of_node) {
1989577e010cSMiquel Raynal 		/*
1990577e010cSMiquel Raynal 		 * We keep the MTD name unchanged to avoid breaking platforms
1991577e010cSMiquel Raynal 		 * where the MTD cmdline parser is used and the bootloader
1992577e010cSMiquel Raynal 		 * has not been updated to use the new naming scheme.
1993577e010cSMiquel Raynal 		 */
1994577e010cSMiquel Raynal 		mtd->name = "atmel_nand";
1995577e010cSMiquel Raynal 	} else if (!mtd->name) {
1996577e010cSMiquel Raynal 		/*
1997577e010cSMiquel Raynal 		 * If the new bindings are used and the bootloader has not been
1998577e010cSMiquel Raynal 		 * updated to pass a new mtdparts parameter on the cmdline, you
1999577e010cSMiquel Raynal 		 * should define the following property in your nand node:
2000577e010cSMiquel Raynal 		 *
2001577e010cSMiquel Raynal 		 *	label = "atmel_nand";
2002577e010cSMiquel Raynal 		 *
2003577e010cSMiquel Raynal 		 * This way, mtd->name will be set by the core when
2004577e010cSMiquel Raynal 		 * nand_set_flash_node() is called.
2005577e010cSMiquel Raynal 		 */
2006577e010cSMiquel Raynal 		mtd->name = devm_kasprintf(nc->dev, GFP_KERNEL,
2007577e010cSMiquel Raynal 					   "%s:nand.%d", dev_name(nc->dev),
2008577e010cSMiquel Raynal 					   nand->cs[0].id);
2009577e010cSMiquel Raynal 		if (!mtd->name) {
2010577e010cSMiquel Raynal 			dev_err(nc->dev, "Failed to allocate mtd->name\n");
2011577e010cSMiquel Raynal 			return -ENOMEM;
2012577e010cSMiquel Raynal 		}
2013577e010cSMiquel Raynal 	}
2014577e010cSMiquel Raynal 
2015577e010cSMiquel Raynal 	return 0;
2016577e010cSMiquel Raynal }
2017577e010cSMiquel Raynal 
2018577e010cSMiquel Raynal static const struct nand_controller_ops atmel_nand_controller_ops = {
2019577e010cSMiquel Raynal 	.attach_chip = atmel_nand_attach_chip,
20204c46667bSMiquel Raynal 	.setup_interface = atmel_nand_setup_interface,
202103b3e0c2SBoris Brezillon 	.exec_op = atmel_nand_exec_op,
2022577e010cSMiquel Raynal };
2023577e010cSMiquel Raynal 
atmel_nand_controller_init(struct atmel_nand_controller * nc,struct platform_device * pdev,const struct atmel_nand_controller_caps * caps)202493db446aSBoris Brezillon static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
202593db446aSBoris Brezillon 				struct platform_device *pdev,
202693db446aSBoris Brezillon 				const struct atmel_nand_controller_caps *caps)
202793db446aSBoris Brezillon {
202893db446aSBoris Brezillon 	struct device *dev = &pdev->dev;
202993db446aSBoris Brezillon 	struct device_node *np = dev->of_node;
203093db446aSBoris Brezillon 	int ret;
203193db446aSBoris Brezillon 
20327da45139SMiquel Raynal 	nand_controller_init(&nc->base);
2033577e010cSMiquel Raynal 	nc->base.ops = &atmel_nand_controller_ops;
203493db446aSBoris Brezillon 	INIT_LIST_HEAD(&nc->chips);
203593db446aSBoris Brezillon 	nc->dev = dev;
203693db446aSBoris Brezillon 	nc->caps = caps;
203793db446aSBoris Brezillon 
203893db446aSBoris Brezillon 	platform_set_drvdata(pdev, nc);
203993db446aSBoris Brezillon 
204093db446aSBoris Brezillon 	nc->pmecc = devm_atmel_pmecc_get(dev);
20411caa7522SKrzysztof Kozlowski 	if (IS_ERR(nc->pmecc))
20421caa7522SKrzysztof Kozlowski 		return dev_err_probe(dev, PTR_ERR(nc->pmecc),
20431caa7522SKrzysztof Kozlowski 				     "Could not get PMECC object\n");
204493db446aSBoris Brezillon 
2045efc6362cSPeter Rosin 	if (nc->caps->has_dma && !atmel_nand_avoid_dma) {
204693db446aSBoris Brezillon 		dma_cap_mask_t mask;
204793db446aSBoris Brezillon 
204893db446aSBoris Brezillon 		dma_cap_zero(mask);
204993db446aSBoris Brezillon 		dma_cap_set(DMA_MEMCPY, mask);
205093db446aSBoris Brezillon 
205193db446aSBoris Brezillon 		nc->dmac = dma_request_channel(mask, NULL, NULL);
205293db446aSBoris Brezillon 		if (!nc->dmac)
205393db446aSBoris Brezillon 			dev_err(nc->dev, "Failed to request DMA channel\n");
205493db446aSBoris Brezillon 	}
205593db446aSBoris Brezillon 
205693db446aSBoris Brezillon 	/* We do not retrieve the SMC syscon when parsing old DTs. */
205793db446aSBoris Brezillon 	if (nc->caps->legacy_of_bindings)
205893db446aSBoris Brezillon 		return 0;
205993db446aSBoris Brezillon 
206093db446aSBoris Brezillon 	nc->mck = of_clk_get(dev->parent->of_node, 0);
206193db446aSBoris Brezillon 	if (IS_ERR(nc->mck)) {
206293db446aSBoris Brezillon 		dev_err(dev, "Failed to retrieve MCK clk\n");
2063fecbd4a3SXin Xiong 		ret = PTR_ERR(nc->mck);
2064fecbd4a3SXin Xiong 		goto out_release_dma;
206593db446aSBoris Brezillon 	}
206693db446aSBoris Brezillon 
206793db446aSBoris Brezillon 	np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0);
206893db446aSBoris Brezillon 	if (!np) {
206993db446aSBoris Brezillon 		dev_err(dev, "Missing or invalid atmel,smc property\n");
2070fecbd4a3SXin Xiong 		ret = -EINVAL;
2071fecbd4a3SXin Xiong 		goto out_release_dma;
207293db446aSBoris Brezillon 	}
207393db446aSBoris Brezillon 
207493db446aSBoris Brezillon 	nc->smc = syscon_node_to_regmap(np);
207593db446aSBoris Brezillon 	of_node_put(np);
207693db446aSBoris Brezillon 	if (IS_ERR(nc->smc)) {
207793db446aSBoris Brezillon 		ret = PTR_ERR(nc->smc);
207893db446aSBoris Brezillon 		dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret);
2079fecbd4a3SXin Xiong 		goto out_release_dma;
208093db446aSBoris Brezillon 	}
208193db446aSBoris Brezillon 
208293db446aSBoris Brezillon 	return 0;
2083fecbd4a3SXin Xiong 
2084fecbd4a3SXin Xiong out_release_dma:
2085fecbd4a3SXin Xiong 	if (nc->dmac)
2086fecbd4a3SXin Xiong 		dma_release_channel(nc->dmac);
2087fecbd4a3SXin Xiong 
2088fecbd4a3SXin Xiong 	return ret;
208993db446aSBoris Brezillon }
209093db446aSBoris Brezillon 
209193db446aSBoris Brezillon static int
atmel_smc_nand_controller_init(struct atmel_smc_nand_controller * nc)209293db446aSBoris Brezillon atmel_smc_nand_controller_init(struct atmel_smc_nand_controller *nc)
209393db446aSBoris Brezillon {
209493db446aSBoris Brezillon 	struct device *dev = nc->base.dev;
209593db446aSBoris Brezillon 	const struct of_device_id *match;
209693db446aSBoris Brezillon 	struct device_node *np;
209793db446aSBoris Brezillon 	int ret;
209893db446aSBoris Brezillon 
2099e2c19c50STudor Ambarus 	/* We do not retrieve the EBICSA regmap when parsing old DTs. */
210093db446aSBoris Brezillon 	if (nc->base.caps->legacy_of_bindings)
210193db446aSBoris Brezillon 		return 0;
210293db446aSBoris Brezillon 
2103e2c19c50STudor Ambarus 	np = of_parse_phandle(dev->parent->of_node,
2104e2c19c50STudor Ambarus 			      nc->base.caps->ebi_csa_regmap_name, 0);
210593db446aSBoris Brezillon 	if (!np)
210693db446aSBoris Brezillon 		return 0;
210793db446aSBoris Brezillon 
2108e2c19c50STudor Ambarus 	match = of_match_node(atmel_ebi_csa_regmap_of_ids, np);
210993db446aSBoris Brezillon 	if (!match) {
211093db446aSBoris Brezillon 		of_node_put(np);
211193db446aSBoris Brezillon 		return 0;
211293db446aSBoris Brezillon 	}
211393db446aSBoris Brezillon 
2114e2c19c50STudor Ambarus 	nc->ebi_csa_regmap = syscon_node_to_regmap(np);
211593db446aSBoris Brezillon 	of_node_put(np);
2116e2c19c50STudor Ambarus 	if (IS_ERR(nc->ebi_csa_regmap)) {
2117e2c19c50STudor Ambarus 		ret = PTR_ERR(nc->ebi_csa_regmap);
2118e2c19c50STudor Ambarus 		dev_err(dev, "Could not get EBICSA regmap (err = %d)\n", ret);
211993db446aSBoris Brezillon 		return ret;
212093db446aSBoris Brezillon 	}
212193db446aSBoris Brezillon 
2122ccf20cccSTudor Ambarus 	nc->ebi_csa = (struct atmel_smc_nand_ebi_csa_cfg *)match->data;
212393db446aSBoris Brezillon 
212493db446aSBoris Brezillon 	/*
212593db446aSBoris Brezillon 	 * The at91sam9263 has 2 EBIs, if the NAND controller is under EBI1
2126ccf20cccSTudor Ambarus 	 * add 4 to ->ebi_csa->offs.
212793db446aSBoris Brezillon 	 */
212893db446aSBoris Brezillon 	if (of_device_is_compatible(dev->parent->of_node,
212993db446aSBoris Brezillon 				    "atmel,at91sam9263-ebi1"))
2130ccf20cccSTudor Ambarus 		nc->ebi_csa->offs += 4;
213193db446aSBoris Brezillon 
213293db446aSBoris Brezillon 	return 0;
213393db446aSBoris Brezillon }
213493db446aSBoris Brezillon 
213593db446aSBoris Brezillon static int
atmel_hsmc_nand_controller_legacy_init(struct atmel_hsmc_nand_controller * nc)213693db446aSBoris Brezillon atmel_hsmc_nand_controller_legacy_init(struct atmel_hsmc_nand_controller *nc)
213793db446aSBoris Brezillon {
213893db446aSBoris Brezillon 	struct regmap_config regmap_conf = {
213993db446aSBoris Brezillon 		.reg_bits = 32,
214093db446aSBoris Brezillon 		.val_bits = 32,
214193db446aSBoris Brezillon 		.reg_stride = 4,
214293db446aSBoris Brezillon 	};
214393db446aSBoris Brezillon 
214493db446aSBoris Brezillon 	struct device *dev = nc->base.dev;
214593db446aSBoris Brezillon 	struct device_node *nand_np, *nfc_np;
214693db446aSBoris Brezillon 	void __iomem *iomem;
214793db446aSBoris Brezillon 	struct resource res;
214893db446aSBoris Brezillon 	int ret;
214993db446aSBoris Brezillon 
215093db446aSBoris Brezillon 	nand_np = dev->of_node;
21515d1e9c22SJohan Hovold 	nfc_np = of_get_compatible_child(dev->of_node, "atmel,sama5d3-nfc");
2152fbed2028SGustavo A. R. Silva 	if (!nfc_np) {
2153fbed2028SGustavo A. R. Silva 		dev_err(dev, "Could not find device node for sama5d3-nfc\n");
2154fbed2028SGustavo A. R. Silva 		return -ENODEV;
2155fbed2028SGustavo A. R. Silva 	}
215693db446aSBoris Brezillon 
215793db446aSBoris Brezillon 	nc->clk = of_clk_get(nfc_np, 0);
215893db446aSBoris Brezillon 	if (IS_ERR(nc->clk)) {
215993db446aSBoris Brezillon 		ret = PTR_ERR(nc->clk);
216093db446aSBoris Brezillon 		dev_err(dev, "Failed to retrieve HSMC clock (err = %d)\n",
216193db446aSBoris Brezillon 			ret);
216293db446aSBoris Brezillon 		goto out;
216393db446aSBoris Brezillon 	}
216493db446aSBoris Brezillon 
216593db446aSBoris Brezillon 	ret = clk_prepare_enable(nc->clk);
216693db446aSBoris Brezillon 	if (ret) {
216793db446aSBoris Brezillon 		dev_err(dev, "Failed to enable the HSMC clock (err = %d)\n",
216893db446aSBoris Brezillon 			ret);
216993db446aSBoris Brezillon 		goto out;
217093db446aSBoris Brezillon 	}
217193db446aSBoris Brezillon 
217293db446aSBoris Brezillon 	nc->irq = of_irq_get(nand_np, 0);
217393db446aSBoris Brezillon 	if (nc->irq <= 0) {
217493db446aSBoris Brezillon 		ret = nc->irq ?: -ENXIO;
217593db446aSBoris Brezillon 		if (ret != -EPROBE_DEFER)
217693db446aSBoris Brezillon 			dev_err(dev, "Failed to get IRQ number (err = %d)\n",
217793db446aSBoris Brezillon 				ret);
217893db446aSBoris Brezillon 		goto out;
217993db446aSBoris Brezillon 	}
218093db446aSBoris Brezillon 
218193db446aSBoris Brezillon 	ret = of_address_to_resource(nfc_np, 0, &res);
218293db446aSBoris Brezillon 	if (ret) {
218393db446aSBoris Brezillon 		dev_err(dev, "Invalid or missing NFC IO resource (err = %d)\n",
218493db446aSBoris Brezillon 			ret);
218593db446aSBoris Brezillon 		goto out;
218693db446aSBoris Brezillon 	}
218793db446aSBoris Brezillon 
218893db446aSBoris Brezillon 	iomem = devm_ioremap_resource(dev, &res);
218993db446aSBoris Brezillon 	if (IS_ERR(iomem)) {
219093db446aSBoris Brezillon 		ret = PTR_ERR(iomem);
219193db446aSBoris Brezillon 		goto out;
219293db446aSBoris Brezillon 	}
219393db446aSBoris Brezillon 
219493db446aSBoris Brezillon 	regmap_conf.name = "nfc-io";
219593db446aSBoris Brezillon 	regmap_conf.max_register = resource_size(&res) - 4;
219693db446aSBoris Brezillon 	nc->io = devm_regmap_init_mmio(dev, iomem, &regmap_conf);
219793db446aSBoris Brezillon 	if (IS_ERR(nc->io)) {
219893db446aSBoris Brezillon 		ret = PTR_ERR(nc->io);
219993db446aSBoris Brezillon 		dev_err(dev, "Could not create NFC IO regmap (err = %d)\n",
220093db446aSBoris Brezillon 			ret);
220193db446aSBoris Brezillon 		goto out;
220293db446aSBoris Brezillon 	}
220393db446aSBoris Brezillon 
220493db446aSBoris Brezillon 	ret = of_address_to_resource(nfc_np, 1, &res);
220593db446aSBoris Brezillon 	if (ret) {
220693db446aSBoris Brezillon 		dev_err(dev, "Invalid or missing HSMC resource (err = %d)\n",
220793db446aSBoris Brezillon 			ret);
220893db446aSBoris Brezillon 		goto out;
220993db446aSBoris Brezillon 	}
221093db446aSBoris Brezillon 
221193db446aSBoris Brezillon 	iomem = devm_ioremap_resource(dev, &res);
221293db446aSBoris Brezillon 	if (IS_ERR(iomem)) {
221393db446aSBoris Brezillon 		ret = PTR_ERR(iomem);
221493db446aSBoris Brezillon 		goto out;
221593db446aSBoris Brezillon 	}
221693db446aSBoris Brezillon 
221793db446aSBoris Brezillon 	regmap_conf.name = "smc";
221893db446aSBoris Brezillon 	regmap_conf.max_register = resource_size(&res) - 4;
221993db446aSBoris Brezillon 	nc->base.smc = devm_regmap_init_mmio(dev, iomem, &regmap_conf);
222093db446aSBoris Brezillon 	if (IS_ERR(nc->base.smc)) {
222193db446aSBoris Brezillon 		ret = PTR_ERR(nc->base.smc);
222293db446aSBoris Brezillon 		dev_err(dev, "Could not create NFC IO regmap (err = %d)\n",
222393db446aSBoris Brezillon 			ret);
222493db446aSBoris Brezillon 		goto out;
222593db446aSBoris Brezillon 	}
222693db446aSBoris Brezillon 
222793db446aSBoris Brezillon 	ret = of_address_to_resource(nfc_np, 2, &res);
222893db446aSBoris Brezillon 	if (ret) {
222993db446aSBoris Brezillon 		dev_err(dev, "Invalid or missing SRAM resource (err = %d)\n",
223093db446aSBoris Brezillon 			ret);
223193db446aSBoris Brezillon 		goto out;
223293db446aSBoris Brezillon 	}
223393db446aSBoris Brezillon 
223493db446aSBoris Brezillon 	nc->sram.virt = devm_ioremap_resource(dev, &res);
223593db446aSBoris Brezillon 	if (IS_ERR(nc->sram.virt)) {
223693db446aSBoris Brezillon 		ret = PTR_ERR(nc->sram.virt);
223793db446aSBoris Brezillon 		goto out;
223893db446aSBoris Brezillon 	}
223993db446aSBoris Brezillon 
224093db446aSBoris Brezillon 	nc->sram.dma = res.start;
224193db446aSBoris Brezillon 
224293db446aSBoris Brezillon out:
224393db446aSBoris Brezillon 	of_node_put(nfc_np);
224493db446aSBoris Brezillon 
224593db446aSBoris Brezillon 	return ret;
224693db446aSBoris Brezillon }
224793db446aSBoris Brezillon 
224893db446aSBoris Brezillon static int
atmel_hsmc_nand_controller_init(struct atmel_hsmc_nand_controller * nc)224993db446aSBoris Brezillon atmel_hsmc_nand_controller_init(struct atmel_hsmc_nand_controller *nc)
225093db446aSBoris Brezillon {
225193db446aSBoris Brezillon 	struct device *dev = nc->base.dev;
225293db446aSBoris Brezillon 	struct device_node *np;
225393db446aSBoris Brezillon 	int ret;
225493db446aSBoris Brezillon 
225593db446aSBoris Brezillon 	np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0);
225693db446aSBoris Brezillon 	if (!np) {
225793db446aSBoris Brezillon 		dev_err(dev, "Missing or invalid atmel,smc property\n");
225893db446aSBoris Brezillon 		return -EINVAL;
225993db446aSBoris Brezillon 	}
226093db446aSBoris Brezillon 
226193db446aSBoris Brezillon 	nc->hsmc_layout = atmel_hsmc_get_reg_layout(np);
226293db446aSBoris Brezillon 
226393db446aSBoris Brezillon 	nc->irq = of_irq_get(np, 0);
226493db446aSBoris Brezillon 	of_node_put(np);
226593db446aSBoris Brezillon 	if (nc->irq <= 0) {
226693db446aSBoris Brezillon 		ret = nc->irq ?: -ENXIO;
226793db446aSBoris Brezillon 		if (ret != -EPROBE_DEFER)
226893db446aSBoris Brezillon 			dev_err(dev, "Failed to get IRQ number (err = %d)\n",
226993db446aSBoris Brezillon 				ret);
227093db446aSBoris Brezillon 		return ret;
227193db446aSBoris Brezillon 	}
227293db446aSBoris Brezillon 
227393db446aSBoris Brezillon 	np = of_parse_phandle(dev->of_node, "atmel,nfc-io", 0);
227493db446aSBoris Brezillon 	if (!np) {
227593db446aSBoris Brezillon 		dev_err(dev, "Missing or invalid atmel,nfc-io property\n");
227693db446aSBoris Brezillon 		return -EINVAL;
227793db446aSBoris Brezillon 	}
227893db446aSBoris Brezillon 
227993db446aSBoris Brezillon 	nc->io = syscon_node_to_regmap(np);
228093db446aSBoris Brezillon 	of_node_put(np);
228193db446aSBoris Brezillon 	if (IS_ERR(nc->io)) {
228293db446aSBoris Brezillon 		ret = PTR_ERR(nc->io);
228393db446aSBoris Brezillon 		dev_err(dev, "Could not get NFC IO regmap (err = %d)\n", ret);
228493db446aSBoris Brezillon 		return ret;
228593db446aSBoris Brezillon 	}
228693db446aSBoris Brezillon 
228793db446aSBoris Brezillon 	nc->sram.pool = of_gen_pool_get(nc->base.dev->of_node,
228893db446aSBoris Brezillon 					 "atmel,nfc-sram", 0);
228993db446aSBoris Brezillon 	if (!nc->sram.pool) {
229093db446aSBoris Brezillon 		dev_err(nc->base.dev, "Missing SRAM\n");
229193db446aSBoris Brezillon 		return -ENOMEM;
229293db446aSBoris Brezillon 	}
229393db446aSBoris Brezillon 
2294d28395c9SBoris Brezillon 	nc->sram.virt = (void __iomem *)gen_pool_dma_alloc(nc->sram.pool,
229593db446aSBoris Brezillon 							   ATMEL_NFC_SRAM_SIZE,
229693db446aSBoris Brezillon 							   &nc->sram.dma);
229793db446aSBoris Brezillon 	if (!nc->sram.virt) {
229893db446aSBoris Brezillon 		dev_err(nc->base.dev,
229993db446aSBoris Brezillon 			"Could not allocate memory from the NFC SRAM pool\n");
230093db446aSBoris Brezillon 		return -ENOMEM;
230193db446aSBoris Brezillon 	}
230293db446aSBoris Brezillon 
230393db446aSBoris Brezillon 	return 0;
230493db446aSBoris Brezillon }
230593db446aSBoris Brezillon 
230693db446aSBoris Brezillon static int
atmel_hsmc_nand_controller_remove(struct atmel_nand_controller * nc)230793db446aSBoris Brezillon atmel_hsmc_nand_controller_remove(struct atmel_nand_controller *nc)
230893db446aSBoris Brezillon {
230993db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *hsmc_nc;
231093db446aSBoris Brezillon 	int ret;
231193db446aSBoris Brezillon 
231293db446aSBoris Brezillon 	ret = atmel_nand_controller_remove_nands(nc);
231393db446aSBoris Brezillon 	if (ret)
231493db446aSBoris Brezillon 		return ret;
231593db446aSBoris Brezillon 
231693db446aSBoris Brezillon 	hsmc_nc = container_of(nc, struct atmel_hsmc_nand_controller, base);
2317b0155dadSBoris Brezillon 	regmap_write(hsmc_nc->base.smc, ATMEL_HSMC_NFC_CTRL,
2318b0155dadSBoris Brezillon 		     ATMEL_HSMC_NFC_CTRL_DIS);
2319b0155dadSBoris Brezillon 
232093db446aSBoris Brezillon 	if (hsmc_nc->sram.pool)
232193db446aSBoris Brezillon 		gen_pool_free(hsmc_nc->sram.pool,
232293db446aSBoris Brezillon 			      (unsigned long)hsmc_nc->sram.virt,
232393db446aSBoris Brezillon 			      ATMEL_NFC_SRAM_SIZE);
232493db446aSBoris Brezillon 
232593db446aSBoris Brezillon 	if (hsmc_nc->clk) {
232693db446aSBoris Brezillon 		clk_disable_unprepare(hsmc_nc->clk);
232793db446aSBoris Brezillon 		clk_put(hsmc_nc->clk);
232893db446aSBoris Brezillon 	}
232993db446aSBoris Brezillon 
233093db446aSBoris Brezillon 	atmel_nand_controller_cleanup(nc);
233193db446aSBoris Brezillon 
233293db446aSBoris Brezillon 	return 0;
233393db446aSBoris Brezillon }
233493db446aSBoris Brezillon 
atmel_hsmc_nand_controller_probe(struct platform_device * pdev,const struct atmel_nand_controller_caps * caps)233593db446aSBoris Brezillon static int atmel_hsmc_nand_controller_probe(struct platform_device *pdev,
233693db446aSBoris Brezillon 				const struct atmel_nand_controller_caps *caps)
233793db446aSBoris Brezillon {
233893db446aSBoris Brezillon 	struct device *dev = &pdev->dev;
233993db446aSBoris Brezillon 	struct atmel_hsmc_nand_controller *nc;
234093db446aSBoris Brezillon 	int ret;
234193db446aSBoris Brezillon 
234293db446aSBoris Brezillon 	nc = devm_kzalloc(dev, sizeof(*nc), GFP_KERNEL);
234393db446aSBoris Brezillon 	if (!nc)
234493db446aSBoris Brezillon 		return -ENOMEM;
234593db446aSBoris Brezillon 
234693db446aSBoris Brezillon 	ret = atmel_nand_controller_init(&nc->base, pdev, caps);
234793db446aSBoris Brezillon 	if (ret)
234893db446aSBoris Brezillon 		return ret;
234993db446aSBoris Brezillon 
235093db446aSBoris Brezillon 	if (caps->legacy_of_bindings)
235193db446aSBoris Brezillon 		ret = atmel_hsmc_nand_controller_legacy_init(nc);
235293db446aSBoris Brezillon 	else
235393db446aSBoris Brezillon 		ret = atmel_hsmc_nand_controller_init(nc);
235493db446aSBoris Brezillon 
235593db446aSBoris Brezillon 	if (ret)
235693db446aSBoris Brezillon 		return ret;
235793db446aSBoris Brezillon 
235893db446aSBoris Brezillon 	/* Make sure all irqs are masked before registering our IRQ handler. */
235993db446aSBoris Brezillon 	regmap_write(nc->base.smc, ATMEL_HSMC_NFC_IDR, 0xffffffff);
236093db446aSBoris Brezillon 	ret = devm_request_irq(dev, nc->irq, atmel_nfc_interrupt,
236193db446aSBoris Brezillon 			       IRQF_SHARED, "nfc", nc);
236293db446aSBoris Brezillon 	if (ret) {
236393db446aSBoris Brezillon 		dev_err(dev,
236493db446aSBoris Brezillon 			"Could not get register NFC interrupt handler (err = %d)\n",
236593db446aSBoris Brezillon 			ret);
236693db446aSBoris Brezillon 		goto err;
236793db446aSBoris Brezillon 	}
236893db446aSBoris Brezillon 
236993db446aSBoris Brezillon 	/* Initial NFC configuration. */
237093db446aSBoris Brezillon 	regmap_write(nc->base.smc, ATMEL_HSMC_NFC_CFG,
237193db446aSBoris Brezillon 		     ATMEL_HSMC_NFC_CFG_DTO_MAX);
2372b0155dadSBoris Brezillon 	regmap_write(nc->base.smc, ATMEL_HSMC_NFC_CTRL,
2373b0155dadSBoris Brezillon 		     ATMEL_HSMC_NFC_CTRL_EN);
237493db446aSBoris Brezillon 
237593db446aSBoris Brezillon 	ret = atmel_nand_controller_add_nands(&nc->base);
237693db446aSBoris Brezillon 	if (ret)
237793db446aSBoris Brezillon 		goto err;
237893db446aSBoris Brezillon 
237993db446aSBoris Brezillon 	return 0;
238093db446aSBoris Brezillon 
238193db446aSBoris Brezillon err:
238293db446aSBoris Brezillon 	atmel_hsmc_nand_controller_remove(&nc->base);
238393db446aSBoris Brezillon 
238493db446aSBoris Brezillon 	return ret;
238593db446aSBoris Brezillon }
238693db446aSBoris Brezillon 
238793db446aSBoris Brezillon static const struct atmel_nand_controller_ops atmel_hsmc_nc_ops = {
238893db446aSBoris Brezillon 	.probe = atmel_hsmc_nand_controller_probe,
238993db446aSBoris Brezillon 	.remove = atmel_hsmc_nand_controller_remove,
239093db446aSBoris Brezillon 	.ecc_init = atmel_hsmc_nand_ecc_init,
23914bc02243SBoris Brezillon 	.nand_init = atmel_nand_init,
23924c46667bSMiquel Raynal 	.setup_interface = atmel_hsmc_nand_setup_interface,
239303b3e0c2SBoris Brezillon 	.exec_op = atmel_hsmc_nand_exec_op,
239493db446aSBoris Brezillon };
239593db446aSBoris Brezillon 
239693db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_sama5_nc_caps = {
239793db446aSBoris Brezillon 	.has_dma = true,
239893db446aSBoris Brezillon 	.ale_offs = BIT(21),
239993db446aSBoris Brezillon 	.cle_offs = BIT(22),
240093db446aSBoris Brezillon 	.ops = &atmel_hsmc_nc_ops,
240193db446aSBoris Brezillon };
240293db446aSBoris Brezillon 
240393db446aSBoris Brezillon /* Only used to parse old bindings. */
240493db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_sama5_nand_caps = {
240593db446aSBoris Brezillon 	.has_dma = true,
240693db446aSBoris Brezillon 	.ale_offs = BIT(21),
240793db446aSBoris Brezillon 	.cle_offs = BIT(22),
240893db446aSBoris Brezillon 	.ops = &atmel_hsmc_nc_ops,
240993db446aSBoris Brezillon 	.legacy_of_bindings = true,
241093db446aSBoris Brezillon };
241193db446aSBoris Brezillon 
atmel_smc_nand_controller_probe(struct platform_device * pdev,const struct atmel_nand_controller_caps * caps)241293db446aSBoris Brezillon static int atmel_smc_nand_controller_probe(struct platform_device *pdev,
241393db446aSBoris Brezillon 				const struct atmel_nand_controller_caps *caps)
241493db446aSBoris Brezillon {
241593db446aSBoris Brezillon 	struct device *dev = &pdev->dev;
241693db446aSBoris Brezillon 	struct atmel_smc_nand_controller *nc;
241793db446aSBoris Brezillon 	int ret;
241893db446aSBoris Brezillon 
241993db446aSBoris Brezillon 	nc = devm_kzalloc(dev, sizeof(*nc), GFP_KERNEL);
242093db446aSBoris Brezillon 	if (!nc)
242193db446aSBoris Brezillon 		return -ENOMEM;
242293db446aSBoris Brezillon 
242393db446aSBoris Brezillon 	ret = atmel_nand_controller_init(&nc->base, pdev, caps);
242493db446aSBoris Brezillon 	if (ret)
242593db446aSBoris Brezillon 		return ret;
242693db446aSBoris Brezillon 
242793db446aSBoris Brezillon 	ret = atmel_smc_nand_controller_init(nc);
242893db446aSBoris Brezillon 	if (ret)
242993db446aSBoris Brezillon 		return ret;
243093db446aSBoris Brezillon 
243193db446aSBoris Brezillon 	return atmel_nand_controller_add_nands(&nc->base);
243293db446aSBoris Brezillon }
243393db446aSBoris Brezillon 
243493db446aSBoris Brezillon static int
atmel_smc_nand_controller_remove(struct atmel_nand_controller * nc)243593db446aSBoris Brezillon atmel_smc_nand_controller_remove(struct atmel_nand_controller *nc)
243693db446aSBoris Brezillon {
243793db446aSBoris Brezillon 	int ret;
243893db446aSBoris Brezillon 
243993db446aSBoris Brezillon 	ret = atmel_nand_controller_remove_nands(nc);
244093db446aSBoris Brezillon 	if (ret)
244193db446aSBoris Brezillon 		return ret;
244293db446aSBoris Brezillon 
244393db446aSBoris Brezillon 	atmel_nand_controller_cleanup(nc);
244493db446aSBoris Brezillon 
244593db446aSBoris Brezillon 	return 0;
244693db446aSBoris Brezillon }
244793db446aSBoris Brezillon 
244893db446aSBoris Brezillon /*
244993db446aSBoris Brezillon  * The SMC reg layout of at91rm9200 is completely different which prevents us
24504c46667bSMiquel Raynal  * from re-using atmel_smc_nand_setup_interface() for the
24514c46667bSMiquel Raynal  * ->setup_interface() hook.
245293db446aSBoris Brezillon  * At this point, there's no support for the at91rm9200 SMC IP, so we leave
24534c46667bSMiquel Raynal  * ->setup_interface() unassigned.
245493db446aSBoris Brezillon  */
245593db446aSBoris Brezillon static const struct atmel_nand_controller_ops at91rm9200_nc_ops = {
245693db446aSBoris Brezillon 	.probe = atmel_smc_nand_controller_probe,
245793db446aSBoris Brezillon 	.remove = atmel_smc_nand_controller_remove,
245893db446aSBoris Brezillon 	.ecc_init = atmel_nand_ecc_init,
245993db446aSBoris Brezillon 	.nand_init = atmel_smc_nand_init,
246003b3e0c2SBoris Brezillon 	.exec_op = atmel_smc_nand_exec_op,
246193db446aSBoris Brezillon };
246293db446aSBoris Brezillon 
246393db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_rm9200_nc_caps = {
246493db446aSBoris Brezillon 	.ale_offs = BIT(21),
246593db446aSBoris Brezillon 	.cle_offs = BIT(22),
2466e2c19c50STudor Ambarus 	.ebi_csa_regmap_name = "atmel,matrix",
246793db446aSBoris Brezillon 	.ops = &at91rm9200_nc_ops,
246893db446aSBoris Brezillon };
246993db446aSBoris Brezillon 
247093db446aSBoris Brezillon static const struct atmel_nand_controller_ops atmel_smc_nc_ops = {
247193db446aSBoris Brezillon 	.probe = atmel_smc_nand_controller_probe,
247293db446aSBoris Brezillon 	.remove = atmel_smc_nand_controller_remove,
247393db446aSBoris Brezillon 	.ecc_init = atmel_nand_ecc_init,
247493db446aSBoris Brezillon 	.nand_init = atmel_smc_nand_init,
24754c46667bSMiquel Raynal 	.setup_interface = atmel_smc_nand_setup_interface,
247603b3e0c2SBoris Brezillon 	.exec_op = atmel_smc_nand_exec_op,
247793db446aSBoris Brezillon };
247893db446aSBoris Brezillon 
247993db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps = {
248093db446aSBoris Brezillon 	.ale_offs = BIT(21),
248193db446aSBoris Brezillon 	.cle_offs = BIT(22),
2482e2c19c50STudor Ambarus 	.ebi_csa_regmap_name = "atmel,matrix",
248393db446aSBoris Brezillon 	.ops = &atmel_smc_nc_ops,
248493db446aSBoris Brezillon };
248593db446aSBoris Brezillon 
248693db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_sam9261_nc_caps = {
248793db446aSBoris Brezillon 	.ale_offs = BIT(22),
248893db446aSBoris Brezillon 	.cle_offs = BIT(21),
2489e2c19c50STudor Ambarus 	.ebi_csa_regmap_name = "atmel,matrix",
249093db446aSBoris Brezillon 	.ops = &atmel_smc_nc_ops,
249193db446aSBoris Brezillon };
249293db446aSBoris Brezillon 
249393db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_sam9g45_nc_caps = {
249493db446aSBoris Brezillon 	.has_dma = true,
249593db446aSBoris Brezillon 	.ale_offs = BIT(21),
249693db446aSBoris Brezillon 	.cle_offs = BIT(22),
2497e2c19c50STudor Ambarus 	.ebi_csa_regmap_name = "atmel,matrix",
249893db446aSBoris Brezillon 	.ops = &atmel_smc_nc_ops,
249993db446aSBoris Brezillon };
250093db446aSBoris Brezillon 
2501ccf20cccSTudor Ambarus static const struct atmel_nand_controller_caps microchip_sam9x60_nc_caps = {
2502ccf20cccSTudor Ambarus 	.has_dma = true,
2503ccf20cccSTudor Ambarus 	.ale_offs = BIT(21),
2504ccf20cccSTudor Ambarus 	.cle_offs = BIT(22),
2505ccf20cccSTudor Ambarus 	.ebi_csa_regmap_name = "microchip,sfr",
2506ccf20cccSTudor Ambarus 	.ops = &atmel_smc_nc_ops,
2507ccf20cccSTudor Ambarus };
2508ccf20cccSTudor Ambarus 
250993db446aSBoris Brezillon /* Only used to parse old bindings. */
251093db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_rm9200_nand_caps = {
251193db446aSBoris Brezillon 	.ale_offs = BIT(21),
251293db446aSBoris Brezillon 	.cle_offs = BIT(22),
251393db446aSBoris Brezillon 	.ops = &atmel_smc_nc_ops,
251493db446aSBoris Brezillon 	.legacy_of_bindings = true,
251593db446aSBoris Brezillon };
251693db446aSBoris Brezillon 
251793db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_sam9261_nand_caps = {
251893db446aSBoris Brezillon 	.ale_offs = BIT(22),
251993db446aSBoris Brezillon 	.cle_offs = BIT(21),
252093db446aSBoris Brezillon 	.ops = &atmel_smc_nc_ops,
252193db446aSBoris Brezillon 	.legacy_of_bindings = true,
252293db446aSBoris Brezillon };
252393db446aSBoris Brezillon 
252493db446aSBoris Brezillon static const struct atmel_nand_controller_caps atmel_sam9g45_nand_caps = {
252593db446aSBoris Brezillon 	.has_dma = true,
252693db446aSBoris Brezillon 	.ale_offs = BIT(21),
252793db446aSBoris Brezillon 	.cle_offs = BIT(22),
252893db446aSBoris Brezillon 	.ops = &atmel_smc_nc_ops,
252993db446aSBoris Brezillon 	.legacy_of_bindings = true,
253093db446aSBoris Brezillon };
253193db446aSBoris Brezillon 
253293db446aSBoris Brezillon static const struct of_device_id atmel_nand_controller_of_ids[] = {
253393db446aSBoris Brezillon 	{
253493db446aSBoris Brezillon 		.compatible = "atmel,at91rm9200-nand-controller",
253593db446aSBoris Brezillon 		.data = &atmel_rm9200_nc_caps,
253693db446aSBoris Brezillon 	},
253793db446aSBoris Brezillon 	{
253893db446aSBoris Brezillon 		.compatible = "atmel,at91sam9260-nand-controller",
253993db446aSBoris Brezillon 		.data = &atmel_sam9260_nc_caps,
254093db446aSBoris Brezillon 	},
254193db446aSBoris Brezillon 	{
254293db446aSBoris Brezillon 		.compatible = "atmel,at91sam9261-nand-controller",
254393db446aSBoris Brezillon 		.data = &atmel_sam9261_nc_caps,
254493db446aSBoris Brezillon 	},
254593db446aSBoris Brezillon 	{
254693db446aSBoris Brezillon 		.compatible = "atmel,at91sam9g45-nand-controller",
254793db446aSBoris Brezillon 		.data = &atmel_sam9g45_nc_caps,
254893db446aSBoris Brezillon 	},
254993db446aSBoris Brezillon 	{
255093db446aSBoris Brezillon 		.compatible = "atmel,sama5d3-nand-controller",
255193db446aSBoris Brezillon 		.data = &atmel_sama5_nc_caps,
255293db446aSBoris Brezillon 	},
2553ccf20cccSTudor Ambarus 	{
2554ccf20cccSTudor Ambarus 		.compatible = "microchip,sam9x60-nand-controller",
2555ccf20cccSTudor Ambarus 		.data = &microchip_sam9x60_nc_caps,
2556ccf20cccSTudor Ambarus 	},
255793db446aSBoris Brezillon 	/* Support for old/deprecated bindings: */
255893db446aSBoris Brezillon 	{
255993db446aSBoris Brezillon 		.compatible = "atmel,at91rm9200-nand",
256093db446aSBoris Brezillon 		.data = &atmel_rm9200_nand_caps,
256193db446aSBoris Brezillon 	},
256293db446aSBoris Brezillon 	{
256393db446aSBoris Brezillon 		.compatible = "atmel,sama5d4-nand",
256493db446aSBoris Brezillon 		.data = &atmel_rm9200_nand_caps,
256593db446aSBoris Brezillon 	},
256693db446aSBoris Brezillon 	{
256793db446aSBoris Brezillon 		.compatible = "atmel,sama5d2-nand",
256893db446aSBoris Brezillon 		.data = &atmel_rm9200_nand_caps,
256993db446aSBoris Brezillon 	},
257093db446aSBoris Brezillon 	{ /* sentinel */ },
257193db446aSBoris Brezillon };
257293db446aSBoris Brezillon MODULE_DEVICE_TABLE(of, atmel_nand_controller_of_ids);
257393db446aSBoris Brezillon 
atmel_nand_controller_probe(struct platform_device * pdev)257493db446aSBoris Brezillon static int atmel_nand_controller_probe(struct platform_device *pdev)
257593db446aSBoris Brezillon {
257693db446aSBoris Brezillon 	const struct atmel_nand_controller_caps *caps;
257793db446aSBoris Brezillon 
257893db446aSBoris Brezillon 	if (pdev->id_entry)
257993db446aSBoris Brezillon 		caps = (void *)pdev->id_entry->driver_data;
258093db446aSBoris Brezillon 	else
258193db446aSBoris Brezillon 		caps = of_device_get_match_data(&pdev->dev);
258293db446aSBoris Brezillon 
258393db446aSBoris Brezillon 	if (!caps) {
258493db446aSBoris Brezillon 		dev_err(&pdev->dev, "Could not retrieve NFC caps\n");
258593db446aSBoris Brezillon 		return -EINVAL;
258693db446aSBoris Brezillon 	}
258793db446aSBoris Brezillon 
258893db446aSBoris Brezillon 	if (caps->legacy_of_bindings) {
25895d1e9c22SJohan Hovold 		struct device_node *nfc_node;
259093db446aSBoris Brezillon 		u32 ale_offs = 21;
259193db446aSBoris Brezillon 
259293db446aSBoris Brezillon 		/*
259393db446aSBoris Brezillon 		 * If we are parsing legacy DT props and the DT contains a
259493db446aSBoris Brezillon 		 * valid NFC node, forward the request to the sama5 logic.
259593db446aSBoris Brezillon 		 */
25965d1e9c22SJohan Hovold 		nfc_node = of_get_compatible_child(pdev->dev.of_node,
25975d1e9c22SJohan Hovold 						   "atmel,sama5d3-nfc");
25985d1e9c22SJohan Hovold 		if (nfc_node) {
259993db446aSBoris Brezillon 			caps = &atmel_sama5_nand_caps;
26005d1e9c22SJohan Hovold 			of_node_put(nfc_node);
26015d1e9c22SJohan Hovold 		}
260293db446aSBoris Brezillon 
260393db446aSBoris Brezillon 		/*
260493db446aSBoris Brezillon 		 * Even if the compatible says we are dealing with an
260593db446aSBoris Brezillon 		 * at91rm9200 controller, the atmel,nand-has-dma specify that
260693db446aSBoris Brezillon 		 * this controller supports DMA, which means we are in fact
260793db446aSBoris Brezillon 		 * dealing with an at91sam9g45+ controller.
260893db446aSBoris Brezillon 		 */
260993db446aSBoris Brezillon 		if (!caps->has_dma &&
261093db446aSBoris Brezillon 		    of_property_read_bool(pdev->dev.of_node,
261193db446aSBoris Brezillon 					  "atmel,nand-has-dma"))
261293db446aSBoris Brezillon 			caps = &atmel_sam9g45_nand_caps;
261393db446aSBoris Brezillon 
261493db446aSBoris Brezillon 		/*
261593db446aSBoris Brezillon 		 * All SoCs except the at91sam9261 are assigning ALE to A21 and
261693db446aSBoris Brezillon 		 * CLE to A22. If atmel,nand-addr-offset != 21 this means we're
261793db446aSBoris Brezillon 		 * actually dealing with an at91sam9261 controller.
261893db446aSBoris Brezillon 		 */
261993db446aSBoris Brezillon 		of_property_read_u32(pdev->dev.of_node,
262093db446aSBoris Brezillon 				     "atmel,nand-addr-offset", &ale_offs);
262193db446aSBoris Brezillon 		if (ale_offs != 21)
262293db446aSBoris Brezillon 			caps = &atmel_sam9261_nand_caps;
262393db446aSBoris Brezillon 	}
262493db446aSBoris Brezillon 
262593db446aSBoris Brezillon 	return caps->ops->probe(pdev, caps);
262693db446aSBoris Brezillon }
262793db446aSBoris Brezillon 
atmel_nand_controller_remove(struct platform_device * pdev)2628ec185b18SUwe Kleine-König static void atmel_nand_controller_remove(struct platform_device *pdev)
262993db446aSBoris Brezillon {
263093db446aSBoris Brezillon 	struct atmel_nand_controller *nc = platform_get_drvdata(pdev);
263193db446aSBoris Brezillon 
26321cc82e09SUwe Kleine-König 	WARN_ON(nc->caps->ops->remove(nc));
263393db446aSBoris Brezillon }
263493db446aSBoris Brezillon 
atmel_nand_controller_resume(struct device * dev)263593db446aSBoris Brezillon static __maybe_unused int atmel_nand_controller_resume(struct device *dev)
263693db446aSBoris Brezillon {
263793db446aSBoris Brezillon 	struct atmel_nand_controller *nc = dev_get_drvdata(dev);
263893db446aSBoris Brezillon 	struct atmel_nand *nand;
263993db446aSBoris Brezillon 
264093db446aSBoris Brezillon 	if (nc->pmecc)
264193db446aSBoris Brezillon 		atmel_pmecc_reset(nc->pmecc);
264293db446aSBoris Brezillon 
264393db446aSBoris Brezillon 	list_for_each_entry(nand, &nc->chips, node) {
264493db446aSBoris Brezillon 		int i;
264593db446aSBoris Brezillon 
264693db446aSBoris Brezillon 		for (i = 0; i < nand->numcs; i++)
264793db446aSBoris Brezillon 			nand_reset(&nand->base, i);
264893db446aSBoris Brezillon 	}
264993db446aSBoris Brezillon 
265093db446aSBoris Brezillon 	return 0;
265193db446aSBoris Brezillon }
265293db446aSBoris Brezillon 
265393db446aSBoris Brezillon static SIMPLE_DEV_PM_OPS(atmel_nand_controller_pm_ops, NULL,
265493db446aSBoris Brezillon 			 atmel_nand_controller_resume);
265593db446aSBoris Brezillon 
265693db446aSBoris Brezillon static struct platform_driver atmel_nand_controller_driver = {
265793db446aSBoris Brezillon 	.driver = {
265893db446aSBoris Brezillon 		.name = "atmel-nand-controller",
26593f26d1bfSMiquel Raynal 		.of_match_table = atmel_nand_controller_of_ids,
266093db446aSBoris Brezillon 		.pm = &atmel_nand_controller_pm_ops,
266193db446aSBoris Brezillon 	},
266293db446aSBoris Brezillon 	.probe = atmel_nand_controller_probe,
2663ec185b18SUwe Kleine-König 	.remove_new = atmel_nand_controller_remove,
266493db446aSBoris Brezillon };
266593db446aSBoris Brezillon module_platform_driver(atmel_nand_controller_driver);
266693db446aSBoris Brezillon 
266793db446aSBoris Brezillon MODULE_LICENSE("GPL");
266893db446aSBoris Brezillon MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>");
266993db446aSBoris Brezillon MODULE_DESCRIPTION("NAND Flash Controller driver for Atmel SoCs");
267093db446aSBoris Brezillon MODULE_ALIAS("platform:atmel-nand-controller");
2671