1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * MikroTik RB91x NAND flash driver
5 * Main part is copied from original driver written by Gabor Juhos.
7 * Copyright (C) 2013-2014 Gabor Juhos <juhosg@openwrt.org>
11 * WARNING: to speed up NAND reading/writing we are working with SoC GPIO
12 * controller registers directly -- not through standard GPIO API.
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/mtd/rawnand.h>
18 #include <linux/mtd/mtd.h>
19 #include <linux/mtd/partitions.h>
20 #include <linux/platform_device.h>
21 #include <linux/gpio/consumer.h>
22 #include <linux/version.h>
23 #include <linux/of_platform.h>
25 #include <asm/mach-ath79/ar71xx_regs.h>
27 /* Bit masks for NAND data lines in ath79 gpio 32-bit register */
28 #define RB91X_NAND_NRW_BIT BIT(12)
29 #define RB91X_NAND_DATA_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) \
30 | BIT(13) | BIT(14) | BIT(15))
31 #define RB91X_NAND_LOW_DATA_MASK 0x1f
32 #define RB91X_NAND_HIGH_DATA_MASK 0xe0
33 #define RB91X_NAND_HIGH_DATA_SHIFT 8
35 enum rb91x_nand_gpios
{
36 RB91X_NAND_READ
,/* Read */
37 RB91X_NAND_RDY
, /* NAND Ready */
38 RB91X_NAND_NCE
, /* Chip Enable. Active low */
39 RB91X_NAND_CLE
, /* Command Latch Enable */
40 RB91X_NAND_ALE
, /* Address Latch Enable */
41 RB91X_NAND_NRW
, /* Read/Write. Active low */
42 RB91X_NAND_NLE
, /* Latch Enable. Active low */
47 struct rb91x_nand_drvdata
{
48 struct nand_chip chip
;
50 struct gpio_desc
**gpio
;
51 void __iomem
*ath79_gpio_base
;
54 static inline void rb91x_nand_latch_lock(struct rb91x_nand_drvdata
*drvdata
,
57 gpiod_set_value_cansleep(drvdata
->gpio
[RB91X_NAND_NLE
], lock
);
60 static int rb91x_ooblayout_ecc(struct mtd_info
*mtd
, int section
,
61 struct mtd_oob_region
*oobregion
)
65 oobregion
->offset
= 8;
66 oobregion
->length
= 3;
69 oobregion
->offset
= 13;
70 oobregion
->length
= 3;
77 static int rb91x_ooblayout_free(struct mtd_info
*mtd
, int section
,
78 struct mtd_oob_region
*oobregion
)
82 oobregion
->offset
= 0;
83 oobregion
->length
= 4;
86 oobregion
->offset
= 4;
87 oobregion
->length
= 1;
90 oobregion
->offset
= 6;
91 oobregion
->length
= 2;
94 oobregion
->offset
= 11;
95 oobregion
->length
= 2;
102 static const struct mtd_ooblayout_ops rb91x_nand_ecclayout_ops
= {
103 .ecc
= rb91x_ooblayout_ecc
,
104 .free
= rb91x_ooblayout_free
,
107 static void rb91x_nand_write(struct rb91x_nand_drvdata
*drvdata
,
111 void __iomem
*base
= drvdata
->ath79_gpio_base
;
117 rb91x_nand_latch_lock(drvdata
, 1);
119 oe_reg
= __raw_readl(base
+ AR71XX_GPIO_REG_OE
);
120 out_reg
= __raw_readl(base
+ AR71XX_GPIO_REG_OUT
);
122 /* Set data lines to output mode */
123 __raw_writel(oe_reg
& ~(RB91X_NAND_DATA_BITS
| RB91X_NAND_NRW_BIT
),
124 base
+ AR71XX_GPIO_REG_OE
);
126 out
= out_reg
& ~(RB91X_NAND_DATA_BITS
| RB91X_NAND_NRW_BIT
);
127 for (i
= 0; i
!= len
; i
++) {
130 data
= (buf
[i
] & RB91X_NAND_HIGH_DATA_MASK
) <<
131 RB91X_NAND_HIGH_DATA_SHIFT
;
132 data
|= buf
[i
] & RB91X_NAND_LOW_DATA_MASK
;
134 __raw_writel(data
, base
+ AR71XX_GPIO_REG_OUT
);
136 /* Deactivate WE line */
137 data
|= RB91X_NAND_NRW_BIT
;
138 __raw_writel(data
, base
+ AR71XX_GPIO_REG_OUT
);
140 __raw_readl(base
+ AR71XX_GPIO_REG_OUT
);
143 /* Restore registers */
144 __raw_writel(out_reg
, base
+ AR71XX_GPIO_REG_OUT
);
145 __raw_writel(oe_reg
, base
+ AR71XX_GPIO_REG_OE
);
147 __raw_readl(base
+ AR71XX_GPIO_REG_OUT
);
149 rb91x_nand_latch_lock(drvdata
, 0);
152 static void rb91x_nand_read(struct rb91x_nand_drvdata
*drvdata
,
156 void __iomem
*base
= drvdata
->ath79_gpio_base
;
161 /* Enable read mode */
162 gpiod_set_value_cansleep(drvdata
->gpio
[RB91X_NAND_READ
], 1);
164 rb91x_nand_latch_lock(drvdata
, 1);
167 oe_reg
= __raw_readl(base
+ AR71XX_GPIO_REG_OE
);
168 out_reg
= __raw_readl(base
+ AR71XX_GPIO_REG_OUT
);
170 /* Set data lines to input mode */
171 __raw_writel(oe_reg
| RB91X_NAND_DATA_BITS
,
172 base
+ AR71XX_GPIO_REG_OE
);
174 for (i
= 0; i
< len
; i
++) {
178 /* Activate RE line */
179 __raw_writel(RB91X_NAND_NRW_BIT
, base
+ AR71XX_GPIO_REG_CLEAR
);
181 __raw_readl(base
+ AR71XX_GPIO_REG_CLEAR
);
183 /* Read input lines */
184 in
= __raw_readl(base
+ AR71XX_GPIO_REG_IN
);
186 /* Deactivate RE line */
187 __raw_writel(RB91X_NAND_NRW_BIT
, base
+ AR71XX_GPIO_REG_SET
);
189 data
= (in
& RB91X_NAND_LOW_DATA_MASK
);
190 data
|= (in
>> RB91X_NAND_HIGH_DATA_SHIFT
) &
191 RB91X_NAND_HIGH_DATA_MASK
;
196 /* Restore registers */
197 __raw_writel(out_reg
, base
+ AR71XX_GPIO_REG_OUT
);
198 __raw_writel(oe_reg
, base
+ AR71XX_GPIO_REG_OE
);
200 __raw_readl(base
+ AR71XX_GPIO_REG_OUT
);
202 rb91x_nand_latch_lock(drvdata
, 0);
204 /* Disable read mode */
205 gpiod_set_value_cansleep(drvdata
->gpio
[RB91X_NAND_READ
], 0);
208 static int rb91x_nand_dev_ready(struct nand_chip
*chip
)
210 struct rb91x_nand_drvdata
*drvdata
= (struct rb91x_nand_drvdata
*)(chip
->priv
);
212 return gpiod_get_value_cansleep(drvdata
->gpio
[RB91X_NAND_RDY
]);
215 static void rb91x_nand_cmd_ctrl(struct nand_chip
*chip
, int cmd
,
218 struct rb91x_nand_drvdata
*drvdata
= chip
->priv
;
220 if (ctrl
& NAND_CTRL_CHANGE
) {
221 gpiod_set_value_cansleep(drvdata
->gpio
[RB91X_NAND_CLE
],
222 (ctrl
& NAND_CLE
) ? 1 : 0);
223 gpiod_set_value_cansleep(drvdata
->gpio
[RB91X_NAND_ALE
],
224 (ctrl
& NAND_ALE
) ? 1 : 0);
225 gpiod_set_value_cansleep(drvdata
->gpio
[RB91X_NAND_NCE
],
226 (ctrl
& NAND_NCE
) ? 1 : 0);
229 if (cmd
!= NAND_CMD_NONE
) {
232 rb91x_nand_write(drvdata
, &t
, 1);
236 static u8
rb91x_nand_read_byte(struct nand_chip
*chip
)
240 rb91x_nand_read(chip
->priv
, &data
, 1);
245 static void rb91x_nand_read_buf(struct nand_chip
*chip
, u8
*buf
, int len
)
247 rb91x_nand_read(chip
->priv
, buf
, len
);
250 static void rb91x_nand_write_buf(struct nand_chip
*chip
, const u8
*buf
, int len
)
252 rb91x_nand_write(chip
->priv
, buf
, len
);
255 static void rb91x_nand_release(struct rb91x_nand_drvdata
*drvdata
)
257 mtd_device_unregister(nand_to_mtd(&drvdata
->chip
));
258 nand_cleanup(&drvdata
->chip
);
261 static int rb91x_nand_probe(struct platform_device
*pdev
)
263 struct rb91x_nand_drvdata
*drvdata
;
264 struct mtd_info
*mtd
;
266 struct device
*dev
= &pdev
->dev
;
267 struct gpio_descs
*gpios
;
269 drvdata
= devm_kzalloc(dev
, sizeof(*drvdata
), GFP_KERNEL
);
273 platform_set_drvdata(pdev
, drvdata
);
275 gpios
= gpiod_get_array(dev
, NULL
, GPIOD_OUT_LOW
);
277 dev_err(dev
, "failed to get gpios: %d\n", (int)gpios
);
281 if (gpios
->ndescs
!= RB91X_NAND_GPIOS
) {
282 dev_err(dev
, "expected %d gpios\n", RB91X_NAND_GPIOS
);
286 drvdata
->gpio
= gpios
->desc
;
288 gpiod_direction_input(drvdata
->gpio
[RB91X_NAND_RDY
]);
290 drvdata
->ath79_gpio_base
= ioremap(AR71XX_GPIO_BASE
, AR71XX_GPIO_SIZE
);
294 drvdata
->chip
.priv
= drvdata
;
296 drvdata
->chip
.legacy
.cmd_ctrl
= rb91x_nand_cmd_ctrl
;
297 drvdata
->chip
.legacy
.dev_ready
= rb91x_nand_dev_ready
;
298 drvdata
->chip
.legacy
.read_byte
= rb91x_nand_read_byte
;
299 drvdata
->chip
.legacy
.write_buf
= rb91x_nand_write_buf
;
300 drvdata
->chip
.legacy
.read_buf
= rb91x_nand_read_buf
;
302 drvdata
->chip
.legacy
.chip_delay
= 25;
303 drvdata
->chip
.ecc
.engine_type
= NAND_ECC_ENGINE_TYPE_SOFT
;
304 drvdata
->chip
.ecc
.algo
= NAND_ECC_ALGO_HAMMING
;
305 drvdata
->chip
.options
= NAND_NO_SUBPAGE_WRITE
;
307 r
= nand_scan(&drvdata
->chip
, 1);
309 dev_err(dev
, "nand_scan() failed: %d\n", r
);
313 mtd
= nand_to_mtd(&drvdata
->chip
);
314 mtd
->dev
.parent
= dev
;
315 mtd_set_of_node(mtd
, dev
->of_node
);
316 mtd
->owner
= THIS_MODULE
;
317 if (mtd
->writesize
== 512)
318 mtd_set_ooblayout(mtd
, &rb91x_nand_ecclayout_ops
);
320 r
= mtd_device_register(mtd
, NULL
, 0);
322 dev_err(dev
, "mtd_device_register() failed: %d\n",
324 goto err_release_nand
;
330 rb91x_nand_release(drvdata
);
334 static int rb91x_nand_remove(struct platform_device
*pdev
)
336 struct rb91x_nand_drvdata
*drvdata
= platform_get_drvdata(pdev
);
338 rb91x_nand_release(drvdata
);
343 static const struct of_device_id rb91x_nand_match
[] = {
344 { .compatible
= "mikrotik,rb91x-nand" },
348 MODULE_DEVICE_TABLE(of
, rb91x_nand_match
);
350 static struct platform_driver rb91x_nand_driver
= {
351 .probe
= rb91x_nand_probe
,
352 .remove
= rb91x_nand_remove
,
354 .name
= "rb91x-nand",
355 .owner
= THIS_MODULE
,
356 .of_match_table
= rb91x_nand_match
,
360 module_platform_driver(rb91x_nand_driver
);
362 MODULE_DESCRIPTION("MikrotTik RB91x NAND flash driver");
363 MODULE_VERSION(DRV_VERSION
);
364 MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
365 MODULE_AUTHOR("Denis Kalashnikov <denis281089@gmail.com>");
366 MODULE_LICENSE("GPL v2");