gpio.c (9989B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Updated, and converted to generic GPIO based driver by Russell King. 4 * 5 * Written by Ben Dooks <ben@simtec.co.uk> 6 * Based on 2.4 version by Mark Whittaker 7 * 8 * © 2004 Simtec Electronics 9 * 10 * Device driver for NAND flash that uses a memory mapped interface to 11 * read/write the NAND commands and data, and GPIO pins for control signals 12 * (the DT binding refers to this as "GPIO assisted NAND flash") 13 */ 14 15#include <linux/kernel.h> 16#include <linux/err.h> 17#include <linux/slab.h> 18#include <linux/module.h> 19#include <linux/platform_device.h> 20#include <linux/gpio/consumer.h> 21#include <linux/io.h> 22#include <linux/mtd/mtd.h> 23#include <linux/mtd/rawnand.h> 24#include <linux/mtd/partitions.h> 25#include <linux/mtd/nand-gpio.h> 26#include <linux/of.h> 27#include <linux/of_address.h> 28#include <linux/delay.h> 29 30struct gpiomtd { 31 struct nand_controller base; 32 void __iomem *io; 33 void __iomem *io_sync; 34 struct nand_chip nand_chip; 35 struct gpio_nand_platdata plat; 36 struct gpio_desc *nce; /* Optional chip enable */ 37 struct gpio_desc *cle; 38 struct gpio_desc *ale; 39 struct gpio_desc *rdy; 40 struct gpio_desc *nwp; /* Optional write protection */ 41}; 42 43static inline struct gpiomtd *gpio_nand_getpriv(struct mtd_info *mtd) 44{ 45 return container_of(mtd_to_nand(mtd), struct gpiomtd, nand_chip); 46} 47 48 49#ifdef CONFIG_ARM 50/* gpio_nand_dosync() 51 * 52 * Make sure the GPIO state changes occur in-order with writes to NAND 53 * memory region. 54 * Needed on PXA due to bus-reordering within the SoC itself (see section on 55 * I/O ordering in PXA manual (section 2.3, p35) 56 */ 57static void gpio_nand_dosync(struct gpiomtd *gpiomtd) 58{ 59 unsigned long tmp; 60 61 if (gpiomtd->io_sync) { 62 /* 63 * Linux memory barriers don't cater for what's required here. 64 * What's required is what's here - a read from a separate 65 * region with a dependency on that read. 66 */ 67 tmp = readl(gpiomtd->io_sync); 68 asm volatile("mov %1, %0\n" : "=r" (tmp) : "r" (tmp)); 69 } 70} 71#else 72static inline void gpio_nand_dosync(struct gpiomtd *gpiomtd) {} 73#endif 74 75static int gpio_nand_exec_instr(struct nand_chip *chip, 76 const struct nand_op_instr *instr) 77{ 78 struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip)); 79 unsigned int i; 80 81 switch (instr->type) { 82 case NAND_OP_CMD_INSTR: 83 gpio_nand_dosync(gpiomtd); 84 gpiod_set_value(gpiomtd->cle, 1); 85 gpio_nand_dosync(gpiomtd); 86 writeb(instr->ctx.cmd.opcode, gpiomtd->io); 87 gpio_nand_dosync(gpiomtd); 88 gpiod_set_value(gpiomtd->cle, 0); 89 return 0; 90 91 case NAND_OP_ADDR_INSTR: 92 gpio_nand_dosync(gpiomtd); 93 gpiod_set_value(gpiomtd->ale, 1); 94 gpio_nand_dosync(gpiomtd); 95 for (i = 0; i < instr->ctx.addr.naddrs; i++) 96 writeb(instr->ctx.addr.addrs[i], gpiomtd->io); 97 gpio_nand_dosync(gpiomtd); 98 gpiod_set_value(gpiomtd->ale, 0); 99 return 0; 100 101 case NAND_OP_DATA_IN_INSTR: 102 gpio_nand_dosync(gpiomtd); 103 if ((chip->options & NAND_BUSWIDTH_16) && 104 !instr->ctx.data.force_8bit) 105 ioread16_rep(gpiomtd->io, instr->ctx.data.buf.in, 106 instr->ctx.data.len / 2); 107 else 108 ioread8_rep(gpiomtd->io, instr->ctx.data.buf.in, 109 instr->ctx.data.len); 110 return 0; 111 112 case NAND_OP_DATA_OUT_INSTR: 113 gpio_nand_dosync(gpiomtd); 114 if ((chip->options & NAND_BUSWIDTH_16) && 115 !instr->ctx.data.force_8bit) 116 iowrite16_rep(gpiomtd->io, instr->ctx.data.buf.out, 117 instr->ctx.data.len / 2); 118 else 119 iowrite8_rep(gpiomtd->io, instr->ctx.data.buf.out, 120 instr->ctx.data.len); 121 return 0; 122 123 case NAND_OP_WAITRDY_INSTR: 124 if (!gpiomtd->rdy) 125 return nand_soft_waitrdy(chip, instr->ctx.waitrdy.timeout_ms); 126 127 return nand_gpio_waitrdy(chip, gpiomtd->rdy, 128 instr->ctx.waitrdy.timeout_ms); 129 130 default: 131 return -EINVAL; 132 } 133 134 return 0; 135} 136 137static int gpio_nand_exec_op(struct nand_chip *chip, 138 const struct nand_operation *op, 139 bool check_only) 140{ 141 struct gpiomtd *gpiomtd = gpio_nand_getpriv(nand_to_mtd(chip)); 142 unsigned int i; 143 int ret = 0; 144 145 if (check_only) 146 return 0; 147 148 gpio_nand_dosync(gpiomtd); 149 gpiod_set_value(gpiomtd->nce, 0); 150 for (i = 0; i < op->ninstrs; i++) { 151 ret = gpio_nand_exec_instr(chip, &op->instrs[i]); 152 if (ret) 153 break; 154 155 if (op->instrs[i].delay_ns) 156 ndelay(op->instrs[i].delay_ns); 157 } 158 gpio_nand_dosync(gpiomtd); 159 gpiod_set_value(gpiomtd->nce, 1); 160 161 return ret; 162} 163 164static int gpio_nand_attach_chip(struct nand_chip *chip) 165{ 166 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && 167 chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) 168 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; 169 170 return 0; 171} 172 173static const struct nand_controller_ops gpio_nand_ops = { 174 .exec_op = gpio_nand_exec_op, 175 .attach_chip = gpio_nand_attach_chip, 176}; 177 178#ifdef CONFIG_OF 179static const struct of_device_id gpio_nand_id_table[] = { 180 { .compatible = "gpio-control-nand" }, 181 {} 182}; 183MODULE_DEVICE_TABLE(of, gpio_nand_id_table); 184 185static int gpio_nand_get_config_of(const struct device *dev, 186 struct gpio_nand_platdata *plat) 187{ 188 u32 val; 189 190 if (!dev->of_node) 191 return -ENODEV; 192 193 if (!of_property_read_u32(dev->of_node, "bank-width", &val)) { 194 if (val == 2) { 195 plat->options |= NAND_BUSWIDTH_16; 196 } else if (val != 1) { 197 dev_err(dev, "invalid bank-width %u\n", val); 198 return -EINVAL; 199 } 200 } 201 202 if (!of_property_read_u32(dev->of_node, "chip-delay", &val)) 203 plat->chip_delay = val; 204 205 return 0; 206} 207 208static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev) 209{ 210 struct resource *r; 211 u64 addr; 212 213 if (of_property_read_u64(pdev->dev.of_node, 214 "gpio-control-nand,io-sync-reg", &addr)) 215 return NULL; 216 217 r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL); 218 if (!r) 219 return NULL; 220 221 r->start = addr; 222 r->end = r->start + 0x3; 223 r->flags = IORESOURCE_MEM; 224 225 return r; 226} 227#else /* CONFIG_OF */ 228static inline int gpio_nand_get_config_of(const struct device *dev, 229 struct gpio_nand_platdata *plat) 230{ 231 return -ENOSYS; 232} 233 234static inline struct resource * 235gpio_nand_get_io_sync_of(struct platform_device *pdev) 236{ 237 return NULL; 238} 239#endif /* CONFIG_OF */ 240 241static inline int gpio_nand_get_config(const struct device *dev, 242 struct gpio_nand_platdata *plat) 243{ 244 int ret = gpio_nand_get_config_of(dev, plat); 245 246 if (!ret) 247 return ret; 248 249 if (dev_get_platdata(dev)) { 250 memcpy(plat, dev_get_platdata(dev), sizeof(*plat)); 251 return 0; 252 } 253 254 return -EINVAL; 255} 256 257static inline struct resource * 258gpio_nand_get_io_sync(struct platform_device *pdev) 259{ 260 struct resource *r = gpio_nand_get_io_sync_of(pdev); 261 262 if (r) 263 return r; 264 265 return platform_get_resource(pdev, IORESOURCE_MEM, 1); 266} 267 268static int gpio_nand_remove(struct platform_device *pdev) 269{ 270 struct gpiomtd *gpiomtd = platform_get_drvdata(pdev); 271 struct nand_chip *chip = &gpiomtd->nand_chip; 272 int ret; 273 274 ret = mtd_device_unregister(nand_to_mtd(chip)); 275 WARN_ON(ret); 276 nand_cleanup(chip); 277 278 /* Enable write protection and disable the chip */ 279 if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp)) 280 gpiod_set_value(gpiomtd->nwp, 0); 281 if (gpiomtd->nce && !IS_ERR(gpiomtd->nce)) 282 gpiod_set_value(gpiomtd->nce, 0); 283 284 return 0; 285} 286 287static int gpio_nand_probe(struct platform_device *pdev) 288{ 289 struct gpiomtd *gpiomtd; 290 struct nand_chip *chip; 291 struct mtd_info *mtd; 292 struct resource *res; 293 struct device *dev = &pdev->dev; 294 int ret = 0; 295 296 if (!dev->of_node && !dev_get_platdata(dev)) 297 return -EINVAL; 298 299 gpiomtd = devm_kzalloc(dev, sizeof(*gpiomtd), GFP_KERNEL); 300 if (!gpiomtd) 301 return -ENOMEM; 302 303 chip = &gpiomtd->nand_chip; 304 305 gpiomtd->io = devm_platform_ioremap_resource(pdev, 0); 306 if (IS_ERR(gpiomtd->io)) 307 return PTR_ERR(gpiomtd->io); 308 309 res = gpio_nand_get_io_sync(pdev); 310 if (res) { 311 gpiomtd->io_sync = devm_ioremap_resource(dev, res); 312 if (IS_ERR(gpiomtd->io_sync)) 313 return PTR_ERR(gpiomtd->io_sync); 314 } 315 316 ret = gpio_nand_get_config(dev, &gpiomtd->plat); 317 if (ret) 318 return ret; 319 320 /* Just enable the chip */ 321 gpiomtd->nce = devm_gpiod_get_optional(dev, "nce", GPIOD_OUT_HIGH); 322 if (IS_ERR(gpiomtd->nce)) 323 return PTR_ERR(gpiomtd->nce); 324 325 /* We disable write protection once we know probe() will succeed */ 326 gpiomtd->nwp = devm_gpiod_get_optional(dev, "nwp", GPIOD_OUT_LOW); 327 if (IS_ERR(gpiomtd->nwp)) { 328 ret = PTR_ERR(gpiomtd->nwp); 329 goto out_ce; 330 } 331 332 gpiomtd->ale = devm_gpiod_get(dev, "ale", GPIOD_OUT_LOW); 333 if (IS_ERR(gpiomtd->ale)) { 334 ret = PTR_ERR(gpiomtd->ale); 335 goto out_ce; 336 } 337 338 gpiomtd->cle = devm_gpiod_get(dev, "cle", GPIOD_OUT_LOW); 339 if (IS_ERR(gpiomtd->cle)) { 340 ret = PTR_ERR(gpiomtd->cle); 341 goto out_ce; 342 } 343 344 gpiomtd->rdy = devm_gpiod_get_optional(dev, "rdy", GPIOD_IN); 345 if (IS_ERR(gpiomtd->rdy)) { 346 ret = PTR_ERR(gpiomtd->rdy); 347 goto out_ce; 348 } 349 350 nand_controller_init(&gpiomtd->base); 351 gpiomtd->base.ops = &gpio_nand_ops; 352 353 nand_set_flash_node(chip, pdev->dev.of_node); 354 chip->options = gpiomtd->plat.options; 355 chip->controller = &gpiomtd->base; 356 357 mtd = nand_to_mtd(chip); 358 mtd->dev.parent = dev; 359 360 platform_set_drvdata(pdev, gpiomtd); 361 362 /* Disable write protection, if wired up */ 363 if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp)) 364 gpiod_direction_output(gpiomtd->nwp, 1); 365 366 /* 367 * This driver assumes that the default ECC engine should be TYPE_SOFT. 368 * Set ->engine_type before registering the NAND devices in order to 369 * provide a driver specific default value. 370 */ 371 chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; 372 373 ret = nand_scan(chip, 1); 374 if (ret) 375 goto err_wp; 376 377 if (gpiomtd->plat.adjust_parts) 378 gpiomtd->plat.adjust_parts(&gpiomtd->plat, mtd->size); 379 380 ret = mtd_device_register(mtd, gpiomtd->plat.parts, 381 gpiomtd->plat.num_parts); 382 if (!ret) 383 return 0; 384 385err_wp: 386 if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp)) 387 gpiod_set_value(gpiomtd->nwp, 0); 388out_ce: 389 if (gpiomtd->nce && !IS_ERR(gpiomtd->nce)) 390 gpiod_set_value(gpiomtd->nce, 0); 391 392 return ret; 393} 394 395static struct platform_driver gpio_nand_driver = { 396 .probe = gpio_nand_probe, 397 .remove = gpio_nand_remove, 398 .driver = { 399 .name = "gpio-nand", 400 .of_match_table = of_match_ptr(gpio_nand_id_table), 401 }, 402}; 403 404module_platform_driver(gpio_nand_driver); 405 406MODULE_LICENSE("GPL"); 407MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 408MODULE_DESCRIPTION("GPIO NAND Driver");