1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * TXx9 NAND flash memory controller driver
4 * Based on RBTX49xx patch from CELF patch archive.
5 *
6 * (C) Copyright TOSHIBA CORPORATION 2004-2007
7 * All Rights Reserved.
8 */
9#include <linux/err.h>
10#include <linux/init.h>
11#include <linux/slab.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/delay.h>
15#include <linux/mtd/mtd.h>
16#include <linux/mtd/rawnand.h>
17#include <linux/mtd/partitions.h>
18#include <linux/io.h>
19#include <linux/platform_data/txx9/ndfmc.h>
20
21/* TXX9 NDFMC Registers */
22#define TXX9_NDFDTR	0x00
23#define TXX9_NDFMCR	0x04
24#define TXX9_NDFSR	0x08
25#define TXX9_NDFISR	0x0c
26#define TXX9_NDFIMR	0x10
27#define TXX9_NDFSPR	0x14
28#define TXX9_NDFRSTR	0x18	/* not TX4939 */
29
30/* NDFMCR : NDFMC Mode Control */
31#define TXX9_NDFMCR_WE	0x80
32#define TXX9_NDFMCR_ECC_ALL	0x60
33#define TXX9_NDFMCR_ECC_RESET	0x60
34#define TXX9_NDFMCR_ECC_READ	0x40
35#define TXX9_NDFMCR_ECC_ON	0x20
36#define TXX9_NDFMCR_ECC_OFF	0x00
37#define TXX9_NDFMCR_CE	0x10
38#define TXX9_NDFMCR_BSPRT	0x04	/* TX4925/TX4926 only */
39#define TXX9_NDFMCR_ALE	0x02
40#define TXX9_NDFMCR_CLE	0x01
41/* TX4939 only */
42#define TXX9_NDFMCR_X16	0x0400
43#define TXX9_NDFMCR_DMAREQ_MASK	0x0300
44#define TXX9_NDFMCR_DMAREQ_NODMA	0x0000
45#define TXX9_NDFMCR_DMAREQ_128	0x0100
46#define TXX9_NDFMCR_DMAREQ_256	0x0200
47#define TXX9_NDFMCR_DMAREQ_512	0x0300
48#define TXX9_NDFMCR_CS_MASK	0x0c
49#define TXX9_NDFMCR_CS(ch)	((ch) << 2)
50
51/* NDFMCR : NDFMC Status */
52#define TXX9_NDFSR_BUSY	0x80
53/* TX4939 only */
54#define TXX9_NDFSR_DMARUN	0x40
55
56/* NDFMCR : NDFMC Reset */
57#define TXX9_NDFRSTR_RST	0x01
58
59struct txx9ndfmc_priv {
60	struct platform_device *dev;
61	struct nand_chip chip;
62	int cs;
63	const char *mtdname;
64};
65
66#define MAX_TXX9NDFMC_DEV	4
67struct txx9ndfmc_drvdata {
68	struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];
69	void __iomem *base;
70	unsigned char hold;	/* in gbusclock */
71	unsigned char spw;	/* in gbusclock */
72	struct nand_controller controller;
73};
74
75static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
76{
77	struct nand_chip *chip = mtd_to_nand(mtd);
78	struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip);
79	return txx9_priv->dev;
80}
81
82static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)
83{
84	struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
85	struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
86
87	return drvdata->base + (reg << plat->shift);
88}
89
90static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)
91{
92	return __raw_readl(ndregaddr(dev, reg));
93}
94
95static void txx9ndfmc_write(struct platform_device *dev,
96			    u32 val, unsigned int reg)
97{
98	__raw_writel(val, ndregaddr(dev, reg));
99}
100
101static uint8_t txx9ndfmc_read_byte(struct nand_chip *chip)
102{
103	struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
104
105	return txx9ndfmc_read(dev, TXX9_NDFDTR);
106}
107
108static void txx9ndfmc_write_buf(struct nand_chip *chip, const uint8_t *buf,
109				int len)
110{
111	struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
112	void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
113	u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
114
115	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);
116	while (len--)
117		__raw_writel(*buf++, ndfdtr);
118	txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
119}
120
121static void txx9ndfmc_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
122{
123	struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
124	void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
125
126	while (len--)
127		*buf++ = __raw_readl(ndfdtr);
128}
129
130static void txx9ndfmc_cmd_ctrl(struct nand_chip *chip, int cmd,
131			       unsigned int ctrl)
132{
133	struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip);
134	struct platform_device *dev = txx9_priv->dev;
135	struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
136
137	if (ctrl & NAND_CTRL_CHANGE) {
138		u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
139
140		mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);
141		mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;
142		mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;
143		/* TXX9_NDFMCR_CE bit is 0:high 1:low */
144		mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;
145		if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {
146			mcr &= ~TXX9_NDFMCR_CS_MASK;
147			mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);
148		}
149		txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
150	}
151	if (cmd != NAND_CMD_NONE)
152		txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);
153	if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {
154		/* dummy write to update external latch */
155		if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)
156			txx9ndfmc_write(dev, 0, TXX9_NDFDTR);
157	}
158}
159
160static int txx9ndfmc_dev_ready(struct nand_chip *chip)
161{
162	struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
163
164	return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);
165}
166
167static int txx9ndfmc_calculate_ecc(struct nand_chip *chip, const uint8_t *dat,
168				   uint8_t *ecc_code)
169{
170	struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
171	int eccbytes;
172	u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
173
174	mcr &= ~TXX9_NDFMCR_ECC_ALL;
175	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
176	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);
177	for (eccbytes = chip->ecc.bytes; eccbytes > 0; eccbytes -= 3) {
178		ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);
179		ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);
180		ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);
181		ecc_code += 3;
182	}
183	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
184	return 0;
185}
186
187static int txx9ndfmc_correct_data(struct nand_chip *chip, unsigned char *buf,
188				  unsigned char *read_ecc,
189				  unsigned char *calc_ecc)
190{
191	int eccsize;
192	int corrected = 0;
193	int stat;
194
195	for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) {
196		stat = rawnand_sw_hamming_correct(chip, buf, read_ecc,
197						  calc_ecc);
198		if (stat < 0)
199			return stat;
200		corrected += stat;
201		buf += 256;
202		read_ecc += 3;
203		calc_ecc += 3;
204	}
205	return corrected;
206}
207
208static void txx9ndfmc_enable_hwecc(struct nand_chip *chip, int mode)
209{
210	struct platform_device *dev = mtd_to_platdev(nand_to_mtd(chip));
211	u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
212
213	mcr &= ~TXX9_NDFMCR_ECC_ALL;
214	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);
215	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
216	txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);
217}
218
219static void txx9ndfmc_initialize(struct platform_device *dev)
220{
221	struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
222	struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
223	int tmout = 100;
224
225	if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)
226		; /* no NDFRSTR.  Write to NDFSPR resets the NDFMC. */
227	else {
228		/* reset NDFMC */
229		txx9ndfmc_write(dev,
230				txx9ndfmc_read(dev, TXX9_NDFRSTR) |
231				TXX9_NDFRSTR_RST,
232				TXX9_NDFRSTR);
233		while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {
234			if (--tmout == 0) {
235				dev_err(&dev->dev, "reset failed.\n");
236				break;
237			}
238			udelay(1);
239		}
240	}
241	/* setup Hold Time, Strobe Pulse Width */
242	txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);
243	txx9ndfmc_write(dev,
244			(plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?
245			TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);
246}
247
248#define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \
249	DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)
250
251static int txx9ndfmc_attach_chip(struct nand_chip *chip)
252{
253	struct mtd_info *mtd = nand_to_mtd(chip);
254
255	if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
256		return 0;
257
258	chip->ecc.strength = 1;
259
260	if (mtd->writesize >= 512) {
261		chip->ecc.size = 512;
262		chip->ecc.bytes = 6;
263	} else {
264		chip->ecc.size = 256;
265		chip->ecc.bytes = 3;
266	}
267
268	chip->ecc.calculate = txx9ndfmc_calculate_ecc;
269	chip->ecc.correct = txx9ndfmc_correct_data;
270	chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
271
272	return 0;
273}
274
275static const struct nand_controller_ops txx9ndfmc_controller_ops = {
276	.attach_chip = txx9ndfmc_attach_chip,
277};
278
279static int txx9ndfmc_probe(struct platform_device *dev)
280{
281	struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev);
282	int hold, spw;
283	int i;
284	struct txx9ndfmc_drvdata *drvdata;
285	unsigned long gbusclk = plat->gbus_clock;
286
287	drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
288	if (!drvdata)
289		return -ENOMEM;
290	drvdata->base = devm_platform_ioremap_resource(dev, 0);
291	if (IS_ERR(drvdata->base))
292		return PTR_ERR(drvdata->base);
293
294	hold = plat->hold ?: 20; /* tDH */
295	spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */
296
297	hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
298	spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
299	if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
300		hold -= 2;	/* actual hold time : (HOLD + 2) BUSCLK */
301	spw -= 1;	/* actual wait time : (SPW + 1) BUSCLK */
302	hold = clamp(hold, 1, 15);
303	drvdata->hold = hold;
304	spw = clamp(spw, 1, 15);
305	drvdata->spw = spw;
306	dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
307		 (gbusclk + 500000) / 1000000, hold, spw);
308
309	nand_controller_init(&drvdata->controller);
310	drvdata->controller.ops = &txx9ndfmc_controller_ops;
311
312	platform_set_drvdata(dev, drvdata);
313	txx9ndfmc_initialize(dev);
314
315	for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
316		struct txx9ndfmc_priv *txx9_priv;
317		struct nand_chip *chip;
318		struct mtd_info *mtd;
319
320		if (!(plat->ch_mask & (1 << i)))
321			continue;
322		txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
323				    GFP_KERNEL);
324		if (!txx9_priv)
325			continue;
326		chip = &txx9_priv->chip;
327		mtd = nand_to_mtd(chip);
328		mtd->dev.parent = &dev->dev;
329
330		chip->legacy.read_byte = txx9ndfmc_read_byte;
331		chip->legacy.read_buf = txx9ndfmc_read_buf;
332		chip->legacy.write_buf = txx9ndfmc_write_buf;
333		chip->legacy.cmd_ctrl = txx9ndfmc_cmd_ctrl;
334		chip->legacy.dev_ready = txx9ndfmc_dev_ready;
335		chip->legacy.chip_delay = 100;
336		chip->controller = &drvdata->controller;
337
338		nand_set_controller_data(chip, txx9_priv);
339		txx9_priv->dev = dev;
340
341		if (plat->ch_mask != 1) {
342			txx9_priv->cs = i;
343			txx9_priv->mtdname = kasprintf(GFP_KERNEL, "%s.%u",
344						       dev_name(&dev->dev), i);
345		} else {
346			txx9_priv->cs = -1;
347			txx9_priv->mtdname = kstrdup(dev_name(&dev->dev),
348						     GFP_KERNEL);
349		}
350		if (!txx9_priv->mtdname) {
351			kfree(txx9_priv);
352			dev_err(&dev->dev, "Unable to allocate MTD name.\n");
353			continue;
354		}
355		if (plat->wide_mask & (1 << i))
356			chip->options |= NAND_BUSWIDTH_16;
357
358		if (nand_scan(chip, 1)) {
359			kfree(txx9_priv->mtdname);
360			kfree(txx9_priv);
361			continue;
362		}
363		mtd->name = txx9_priv->mtdname;
364
365		mtd_device_register(mtd, NULL, 0);
366		drvdata->mtds[i] = mtd;
367	}
368
369	return 0;
370}
371
372static void txx9ndfmc_remove(struct platform_device *dev)
373{
374	struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
375	int ret, i;
376
377	for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
378		struct mtd_info *mtd = drvdata->mtds[i];
379		struct nand_chip *chip;
380		struct txx9ndfmc_priv *txx9_priv;
381
382		if (!mtd)
383			continue;
384		chip = mtd_to_nand(mtd);
385		txx9_priv = nand_get_controller_data(chip);
386
387		ret = mtd_device_unregister(nand_to_mtd(chip));
388		WARN_ON(ret);
389		nand_cleanup(chip);
390		kfree(txx9_priv->mtdname);
391		kfree(txx9_priv);
392	}
393}
394
395#ifdef CONFIG_PM
396static int txx9ndfmc_resume(struct platform_device *dev)
397{
398	if (platform_get_drvdata(dev))
399		txx9ndfmc_initialize(dev);
400	return 0;
401}
402#else
403#define txx9ndfmc_resume NULL
404#endif
405
406static struct platform_driver txx9ndfmc_driver = {
407	.probe		= txx9ndfmc_probe,
408	.remove_new	= txx9ndfmc_remove,
409	.resume		= txx9ndfmc_resume,
410	.driver		= {
411		.name	= "txx9ndfmc",
412	},
413};
414module_platform_driver(txx9ndfmc_driver);
415
416MODULE_LICENSE("GPL");
417MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
418MODULE_ALIAS("platform:txx9ndfmc");
419