Lines Matching +full:nand +full:- +full:ecc +full:- +full:algo

1 // SPDX-License-Identifier: GPL-2.0-only
15 #include <asm/mach-au1x00/au1000.h>
16 #include <asm/mach-au1x00/au1550nd.h>
33 * au_write_buf - write buffer to chip
34 * @this: NAND chip object
48 writeb(p[i], ctx->base + MEM_STNAND_DATA); in au_write_buf()
54 * au_read_buf - read chip data into buffer
55 * @this: NAND chip object
69 p[i] = readb(ctx->base + MEM_STNAND_DATA); in au_read_buf()
75 * au_write_buf16 - write buffer to chip
76 * @this: NAND chip object
91 writew(p[i], ctx->base + MEM_STNAND_DATA); in au_write_buf16()
97 * au_read_buf16 - read chip data into buffer
98 * @this: NAND chip object
112 p[i] = readw(ctx->base + MEM_STNAND_DATA); in au_read_buf16()
130 end = (start | (start - 1)) & ~(start ^ mask); in find_nand_cs()
135 return -ENODEV; in find_nand_cs()
150 return -ETIMEDOUT; in au1550nd_waitrdy()
160 switch (instr->type) { in au1550nd_exec_instr()
162 writeb(instr->ctx.cmd.opcode, in au1550nd_exec_instr()
163 ctx->base + MEM_STNAND_CMD); in au1550nd_exec_instr()
169 for (i = 0; i < instr->ctx.addr.naddrs; i++) { in au1550nd_exec_instr()
170 writeb(instr->ctx.addr.addrs[i], in au1550nd_exec_instr()
171 ctx->base + MEM_STNAND_ADDR); in au1550nd_exec_instr()
178 if ((this->options & NAND_BUSWIDTH_16) && in au1550nd_exec_instr()
179 !instr->ctx.data.force_8bit) in au1550nd_exec_instr()
180 au_read_buf16(this, instr->ctx.data.buf.in, in au1550nd_exec_instr()
181 instr->ctx.data.len); in au1550nd_exec_instr()
183 au_read_buf(this, instr->ctx.data.buf.in, in au1550nd_exec_instr()
184 instr->ctx.data.len); in au1550nd_exec_instr()
188 if ((this->options & NAND_BUSWIDTH_16) && in au1550nd_exec_instr()
189 !instr->ctx.data.force_8bit) in au1550nd_exec_instr()
190 au_write_buf16(this, instr->ctx.data.buf.out, in au1550nd_exec_instr()
191 instr->ctx.data.len); in au1550nd_exec_instr()
193 au_write_buf(this, instr->ctx.data.buf.out, in au1550nd_exec_instr()
194 instr->ctx.data.len); in au1550nd_exec_instr()
198 ret = au1550nd_waitrdy(this, instr->ctx.waitrdy.timeout_ms); in au1550nd_exec_instr()
201 return -EINVAL; in au1550nd_exec_instr()
204 if (instr->delay_ns) in au1550nd_exec_instr()
205 ndelay(instr->delay_ns); in au1550nd_exec_instr()
222 alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL); in au1550nd_exec_op()
226 for (i = 0; i < op->ninstrs; i++) { in au1550nd_exec_op()
227 ret = au1550nd_exec_instr(this, &op->instrs[i]); in au1550nd_exec_op()
242 if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && in au1550nd_attach_chip()
243 chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN) in au1550nd_attach_chip()
244 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in au1550nd_attach_chip()
263 pd = dev_get_platdata(&pdev->dev); in au1550nd_probe()
265 dev_err(&pdev->dev, "missing platform data\n"); in au1550nd_probe()
266 return -ENODEV; in au1550nd_probe()
271 return -ENOMEM; in au1550nd_probe()
275 dev_err(&pdev->dev, "no NAND memory resource\n"); in au1550nd_probe()
276 ret = -ENODEV; in au1550nd_probe()
279 if (request_mem_region(r->start, resource_size(r), "au1550-nand")) { in au1550nd_probe()
280 dev_err(&pdev->dev, "cannot claim NAND memory area\n"); in au1550nd_probe()
281 ret = -ENOMEM; in au1550nd_probe()
285 ctx->base = ioremap(r->start, 0x1000); in au1550nd_probe()
286 if (!ctx->base) { in au1550nd_probe()
287 dev_err(&pdev->dev, "cannot remap NAND memory area\n"); in au1550nd_probe()
288 ret = -ENODEV; in au1550nd_probe()
292 this = &ctx->chip; in au1550nd_probe()
294 mtd->dev.parent = &pdev->dev; in au1550nd_probe()
296 /* figure out which CS# r->start belongs to */ in au1550nd_probe()
297 cs = find_nand_cs(r->start); in au1550nd_probe()
299 dev_err(&pdev->dev, "cannot detect NAND chipselect\n"); in au1550nd_probe()
300 ret = -ENODEV; in au1550nd_probe()
303 ctx->cs = cs; in au1550nd_probe()
305 nand_controller_init(&ctx->controller); in au1550nd_probe()
306 ctx->controller.ops = &au1550nd_ops; in au1550nd_probe()
307 this->controller = &ctx->controller; in au1550nd_probe()
309 if (pd->devwidth) in au1550nd_probe()
310 this->options |= NAND_BUSWIDTH_16; in au1550nd_probe()
313 * This driver assumes that the default ECC engine should be TYPE_SOFT. in au1550nd_probe()
314 * Set ->engine_type before registering the NAND devices in order to in au1550nd_probe()
317 this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; in au1550nd_probe()
321 dev_err(&pdev->dev, "NAND scan failed with %d\n", ret); in au1550nd_probe()
325 mtd_device_register(mtd, pd->parts, pd->num_parts); in au1550nd_probe()
332 iounmap(ctx->base); in au1550nd_probe()
334 release_mem_region(r->start, resource_size(r)); in au1550nd_probe()
344 struct nand_chip *chip = &ctx->chip; in au1550nd_remove()
350 iounmap(ctx->base); in au1550nd_remove()
351 release_mem_region(r->start, 0x1000); in au1550nd_remove()
358 .name = "au1550-nand",
368 MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on Pb1550 board");