// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2017 ATMEL * Copyright 2017 Free Electrons * * Author: Boris Brezillon <boris.brezillon@free-electrons.com> * * Derived from the atmel_nand.c driver which contained the following * copyrights: * * Copyright 2003 Rick Bronson * * Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8) * Copyright 2001 Thomas Gleixner (gleixner@autronix.de) * * Derived from drivers/mtd/spia.c (removed in v3.8) * Copyright 2000 Steven J. Hill (sjhill@cotw.com) * * * Add Hardware ECC support for AT91SAM9260 / AT91SAM9263 * Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright 2007 * * Derived from Das U-Boot source code * (u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c) * Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas * * Add Programmable Multibit ECC support for various AT91 SoC * Copyright 2012 ATMEL, Hong Xu * * Add Nand Flash Controller support for SAMA5 SoC * Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) * * A few words about the naming convention in this file. This convention * applies to structure and function names. * * Prefixes: * * - atmel_nand_: all generic structures/functions * - atmel_smc_nand_: all structures/functions specific to the SMC interface * (at91sam9 and avr32 SoCs) * - atmel_hsmc_nand_: all structures/functions specific to the HSMC interface * (sama5 SoCs and later) * - atmel_nfc_: all structures/functions used to manipulate the NFC sub-block * that is available in the HSMC block * - <soc>_nand_: all SoC specific structures/functions
*/
/* * If the controller supports DMA, the buffer address is DMA-able and * len is long enough to make DMA transfers profitable, let's trigger * a DMA transfer. If it fails, fallback to PIO mode.
*/ if (nc->dmac && virt_addr_valid(buf) &&
len >= MIN_DMA_LEN && !force_8bit &&
!atmel_nand_dma_transfer(nc, buf, nand->activecs->io.dma, len,
DMA_FROM_DEVICE)) return;
if ((nand->base.options & NAND_BUSWIDTH_16) && !force_8bit)
ioread16_rep(nand->activecs->io.virt, buf, len / 2); else
ioread8_rep(nand->activecs->io.virt, buf, len);
}
/* * If the controller supports DMA, the buffer address is DMA-able and * len is long enough to make DMA transfers profitable, let's trigger * a DMA transfer. If it fails, fallback to PIO mode.
*/ if (nc->dmac && virt_addr_valid(buf) &&
len >= MIN_DMA_LEN && !force_8bit &&
!atmel_nand_dma_transfer(nc, (void *)buf, nand->activecs->io.dma,
len, DMA_TO_DEVICE)) return;
if ((nand->base.options & NAND_BUSWIDTH_16) && !force_8bit)
iowrite16_rep(nand->activecs->io.virt, buf, len / 2); else
iowrite8_rep(nand->activecs->io.virt, buf, len);
}
nc = to_nand_controller(nand->base.controller); switch (instr->type) { case NAND_OP_CMD_INSTR:
writeb(instr->ctx.cmd.opcode,
nand->activecs->io.virt + nc->caps->cle_offs); return0; case NAND_OP_ADDR_INSTR: for (i = 0; i < instr->ctx.addr.naddrs; i++)
writeb(instr->ctx.addr.addrs[i],
nand->activecs->io.virt + nc->caps->ale_offs); return0; case NAND_OP_DATA_IN_INSTR:
atmel_nand_data_in(nand, instr->ctx.data.buf.in,
instr->ctx.data.len,
instr->ctx.data.force_8bit); return0; case NAND_OP_DATA_OUT_INSTR:
atmel_nand_data_out(nand, instr->ctx.data.buf.out,
instr->ctx.data.len,
instr->ctx.data.force_8bit); return0; case NAND_OP_WAITRDY_INSTR: return atmel_nand_waitrdy(nand,
instr->ctx.waitrdy.timeout_ms); default: break;
}
return -EINVAL;
}
staticint atmel_smc_nand_exec_op(struct atmel_nand *nand, conststruct nand_operation *op, bool check_only)
{ unsignedint i; int ret = 0;
if (check_only) return0;
atmel_nand_select_target(nand, op->cs);
gpiod_set_value(nand->activecs->csgpio, 0); for (i = 0; i < op->ninstrs; i++) {
ret = atmel_smc_nand_exec_instr(nand, &op->instrs[i]); if (ret) break;
}
gpiod_set_value(nand->activecs->csgpio, 1);
for (i = 0; i < chip->ecc.steps; i++) {
ret = atmel_pmecc_correct_sector(nand->pmecc, i, databuf,
eccbuf); if (ret < 0 && !atmel_pmecc_correct_erased_chunks(nand->pmecc))
ret = nand_check_erased_ecc_chunk(databuf,
chip->ecc.size,
eccbuf,
chip->ecc.bytes,
NULL, 0,
chip->ecc.strength);
ret = atmel_nand_pmecc_enable(chip, NAND_ECC_WRITE, raw); if (ret) return ret;
ret = atmel_nfc_exec_op(nc, false); if (ret) {
atmel_nand_pmecc_disable(chip, raw);
dev_err(nc->base.dev, "Failed to transfer NAND page data (err = %d)\n",
ret); return ret;
}
ret = atmel_nand_pmecc_generate_eccbytes(chip, raw);
/* * Optimized read page accessors only work when the NAND R/B pin is * connected to a native SoC R/B pin. If that's not the case, fallback * to the non-optimized one.
*/ if (nand->activecs->rb.type != ATMEL_NAND_NATIVE_RB) return atmel_nand_pmecc_read_pg(chip, buf, oob_required, page,
raw);
nc->op.cmds[nc->op.ncmds++] = NAND_CMD_READ0;
if (mtd->writesize > 512)
nc->op.cmds[nc->op.ncmds++] = NAND_CMD_READSTART;
staticint atmel_nand_ecc_init(struct nand_chip *chip)
{ struct atmel_nand_controller *nc; int ret;
nc = to_nand_controller(chip->controller);
switch (chip->ecc.engine_type) { case NAND_ECC_ENGINE_TYPE_NONE: case NAND_ECC_ENGINE_TYPE_SOFT: /* * Nothing to do, the core will initialize everything for us.
*/ break;
case NAND_ECC_ENGINE_TYPE_ON_HOST:
ret = atmel_nand_pmecc_init(chip); if (ret) return ret;
/* * Set write pulse timing. This one is easy to extract: * * NWE_PULSE = tWP
*/
ncycles = DIV_ROUND_UP(conf->timings.sdr.tWP_min, mckperiodps);
totalcycles = ncycles;
ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NWE_SHIFT,
ncycles); if (ret) return ret;
/* * The write setup timing depends on the operation done on the NAND. * All operations goes through the same data bus, but the operation * type depends on the address we are writing to (ALE/CLE address * lines). * Since we have no way to differentiate the different operations at * the SMC level, we must consider the worst case (the biggest setup * time among all operation types): * * NWE_SETUP = max(tCLS, tCS, tALS, tDS) - NWE_PULSE
*/
timeps = max3(conf->timings.sdr.tCLS_min, conf->timings.sdr.tCS_min,
conf->timings.sdr.tALS_min);
timeps = max(timeps, conf->timings.sdr.tDS_min);
ncycles = DIV_ROUND_UP(timeps, mckperiodps);
ncycles = ncycles > totalcycles ? ncycles - totalcycles : 0;
totalcycles += ncycles;
ret = atmel_smc_cs_conf_set_setup(smcconf, ATMEL_SMC_NWE_SHIFT,
ncycles); if (ret) return ret;
/* * As for the write setup timing, the write hold timing depends on the * operation done on the NAND: * * NWE_HOLD = max(tCLH, tCH, tALH, tDH, tWH)
*/
timeps = max3(conf->timings.sdr.tCLH_min, conf->timings.sdr.tCH_min,
conf->timings.sdr.tALH_min);
timeps = max3(timeps, conf->timings.sdr.tDH_min,
conf->timings.sdr.tWH_min);
ncycles = DIV_ROUND_UP(timeps, mckperiodps);
totalcycles += ncycles;
/* * The write cycle timing is directly matching tWC, but is also * dependent on the other timings on the setup and hold timings we * calculated earlier, which gives: * * NWE_CYCLE = max(tWC, NWE_SETUP + NWE_PULSE + NWE_HOLD)
*/
ncycles = DIV_ROUND_UP(conf->timings.sdr.tWC_min, mckperiodps);
ncycles = max(totalcycles, ncycles);
ret = atmel_smc_cs_conf_set_cycle(smcconf, ATMEL_SMC_NWE_SHIFT,
ncycles); if (ret) return ret;
/* * We don't want the CS line to be toggled between each byte/word * transfer to the NAND. The only way to guarantee that is to have the * NCS_{WR,RD}_{SETUP,HOLD} timings set to 0, which in turn means: * * NCS_WR_PULSE = NWE_CYCLE
*/
ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NCS_WR_SHIFT,
ncycles); if (ret) return ret;
/* * As for the write setup timing, the read hold timing depends on the * operation done on the NAND: * * NRD_HOLD = max(tREH, tRHOH)
*/
timeps = max(conf->timings.sdr.tREH_min, conf->timings.sdr.tRHOH_min);
ncycles = DIV_ROUND_UP(timeps, mckperiodps);
totalcycles = ncycles;
/* * In ONFI 4.0 specs, tRHZ has been increased to support EDO NANDs and * we might end up with a config that does not fit in the TDF field. * Just take the max value in this case and hope that the NAND is more * tolerant than advertised.
*/ if (ncycles > ATMEL_SMC_MODE_TDF_MAX)
ncycles = ATMEL_SMC_MODE_TDF_MAX; elseif (ncycles < ATMEL_SMC_MODE_TDF_MIN)
ncycles = ATMEL_SMC_MODE_TDF_MIN;
/* * Read setup timing depends on the operation done on the NAND: * * NRD_SETUP = max(tAR, tCLR)
*/
timeps = max(conf->timings.sdr.tAR_min, conf->timings.sdr.tCLR_min);
ncycles = DIV_ROUND_UP(timeps, mckperiodps);
totalcycles += ncycles;
ret = atmel_smc_cs_conf_set_setup(smcconf, ATMEL_SMC_NRD_SHIFT, ncycles); if (ret) return ret;
/* * The read cycle timing is directly matching tRC, but is also * dependent on the setup and hold timings we calculated earlier, * which gives: * * NRD_CYCLE = max(tRC, NRD_SETUP + NRD_PULSE + NRD_HOLD)
*/
ncycles = DIV_ROUND_UP(conf->timings.sdr.tRC_min, mckperiodps);
ncycles = max(totalcycles, ncycles);
ret = atmel_smc_cs_conf_set_cycle(smcconf, ATMEL_SMC_NRD_SHIFT,
ncycles); if (ret) return ret;
/* * We don't want the CS line to be toggled between each byte/word * transfer from the NAND. The only way to guarantee that is to have * the NCS_{WR,RD}_{SETUP,HOLD} timings set to 0, which in turn means: * * NCS_RD_PULSE = NRD_CYCLE
*/
ret = atmel_smc_cs_conf_set_pulse(smcconf, ATMEL_SMC_NCS_RD_SHIFT,
ncycles); if (ret) return ret;
/* Txxx timings are directly matching tXXX ones. */
ncycles = DIV_ROUND_UP(conf->timings.sdr.tCLR_min, mckperiodps);
ret = atmel_smc_cs_conf_set_timing(smcconf,
ATMEL_HSMC_TIMINGS_TCLR_SHIFT,
ncycles); if (ret) return ret;
ncycles = DIV_ROUND_UP(conf->timings.sdr.tADL_min, mckperiodps);
ret = atmel_smc_cs_conf_set_timing(smcconf,
ATMEL_HSMC_TIMINGS_TADL_SHIFT,
ncycles); /* * Version 4 of the ONFI spec mandates that tADL be at least 400 * nanoseconds, but, depending on the master clock rate, 400 ns may not * fit in the tADL field of the SMC reg. We need to relax the check and * accept the -ERANGE return code. * * Note that previous versions of the ONFI spec had a lower tADL_min * (100 or 200 ns). It's not clear why this timing constraint got * increased but it seems most NANDs are fine with values lower than * 400ns, so we should be safe.
*/ if (ret && ret != -ERANGE) return ret;
ncycles = DIV_ROUND_UP(conf->timings.sdr.tAR_min, mckperiodps);
ret = atmel_smc_cs_conf_set_timing(smcconf,
ATMEL_HSMC_TIMINGS_TAR_SHIFT,
ncycles); if (ret) return ret;
ncycles = DIV_ROUND_UP(conf->timings.sdr.tRR_min, mckperiodps);
ret = atmel_smc_cs_conf_set_timing(smcconf,
ATMEL_HSMC_TIMINGS_TRR_SHIFT,
ncycles); if (ret) return ret;
ncycles = DIV_ROUND_UP(conf->timings.sdr.tWB_max, mckperiodps);
ret = atmel_smc_cs_conf_set_timing(smcconf,
ATMEL_HSMC_TIMINGS_TWB_SHIFT,
ncycles); if (ret) return ret;
/* Attach the CS line to the NFC logic. */
smcconf->timings |= ATMEL_HSMC_TIMINGS_NFSEL;
/* Set the appropriate data bus width. */ if (nand->base.options & NAND_BUSWIDTH_16)
smcconf->mode |= ATMEL_SMC_MODE_DBW_16;
smc_nc = to_smc_nand_controller(chip->controller); if (!smc_nc->ebi_csa_regmap) return;
/* Attach the CS to the NAND Flash logic. */ for (i = 0; i < nand->numcs; i++)
regmap_update_bits(smc_nc->ebi_csa_regmap,
smc_nc->ebi_csa->offs,
BIT(nand->cs[i].id), BIT(nand->cs[i].id));
if (smc_nc->ebi_csa->nfd0_on_d16)
regmap_update_bits(smc_nc->ebi_csa_regmap,
smc_nc->ebi_csa->offs,
smc_nc->ebi_csa->nfd0_on_d16,
smc_nc->ebi_csa->nfd0_on_d16);
}
/* No card inserted, skip this NAND. */ if (nand->cdgpio && gpiod_get_value(nand->cdgpio)) {
dev_info(nc->dev, "No SmartMedia card inserted.\n"); return0;
}
nc->caps->ops->nand_init(nc, nand);
ret = nand_scan(chip, nand->numcs); if (ret) {
dev_err(nc->dev, "NAND scan failed: %d\n", ret); return ret;
}
ret = mtd_device_register(mtd, NULL, 0); if (ret) {
dev_err(nc->dev, "Failed to register mtd device: %d\n", ret);
nand_cleanup(chip); return ret;
}
/* * Legacy bindings only allow connecting a single NAND with a unique CS * line to the controller.
*/
nand = devm_kzalloc(nc->dev, sizeof(*nand) + sizeof(*nand->cs),
GFP_KERNEL); if (!nand) return -ENOMEM;
nand->numcs = 1;
nand->cs[0].io.virt = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(nand->cs[0].io.virt)) return PTR_ERR(nand->cs[0].io.virt);
nand->cs[0].io.dma = res->start;
/* * The old driver was hardcoding the CS id to 3 for all sama5 * controllers. Since this id is only meaningful for the sama5 * controller we can safely assign this id to 3 no matter the * controller. * If one wants to connect a NAND to a different CS line, he will * have to use the new bindings.
*/
nand->cs[0].id = 3;
/* R/B GPIO. */
gpio = devm_gpiod_get_index_optional(dev, NULL, 0, GPIOD_IN); if (IS_ERR(gpio)) {
dev_err(dev, "Failed to get R/B gpio (err = %ld)\n",
PTR_ERR(gpio)); return PTR_ERR(gpio);
}
if (gpio) {
nand->cs[0].rb.type = ATMEL_NAND_GPIO_RB;
nand->cs[0].rb.gpio = gpio;
}
/* CS GPIO. */
gpio = devm_gpiod_get_index_optional(dev, NULL, 1, GPIOD_OUT_HIGH); if (IS_ERR(gpio)) {
dev_err(dev, "Failed to get CS gpio (err = %ld)\n",
PTR_ERR(gpio)); return PTR_ERR(gpio);
}
nand->cs[0].csgpio = gpio;
/* Card detect GPIO. */
gpio = devm_gpiod_get_index_optional(nc->dev, NULL, 2, GPIOD_IN); if (IS_ERR(gpio)) {
dev_err(dev, "Failed to get detect gpio (err = %ld)\n",
PTR_ERR(gpio)); return PTR_ERR(gpio);
}
ret = nc->caps->ops->ecc_init(chip); if (ret) return ret;
if (nc->caps->legacy_of_bindings || !nc->dev->of_node) { /* * We keep the MTD name unchanged to avoid breaking platforms * where the MTD cmdline parser is used and the bootloader * has not been updated to use the new naming scheme.
*/
mtd->name = "atmel_nand";
} elseif (!mtd->name) { /* * If the new bindings are used and the bootloader has not been * updated to pass a new mtdparts parameter on the cmdline, you * should define the following property in your nand node: * * label = "atmel_nand"; * * This way, mtd->name will be set by the core when * nand_set_flash_node() is called.
*/
mtd->name = devm_kasprintf(nc->dev, GFP_KERNEL, "%s:nand.%d", dev_name(nc->dev),
nand->cs[0].id); if (!mtd->name) {
dev_err(nc->dev, "Failed to allocate mtd->name\n"); return -ENOMEM;
}
}
/* * The at91sam9263 has 2 EBIs, if the NAND controller is under EBI1 * add 4 to ->ebi_csa->offs.
*/ if (of_device_is_compatible(dev->parent->of_node, "atmel,at91sam9263-ebi1"))
nc->ebi_csa->offs += 4;
staticint
atmel_smc_nand_controller_remove(struct atmel_nand_controller *nc)
{ int ret;
ret = atmel_nand_controller_remove_nands(nc); if (ret) return ret;
atmel_nand_controller_cleanup(nc);
return0;
}
/* * The SMC reg layout of at91rm9200 is completely different which prevents us * from re-using atmel_smc_nand_setup_interface() for the * ->setup_interface() hook. * At this point, there's no support for the at91rm9200 SMC IP, so we leave * ->setup_interface() unassigned.
*/ staticconststruct atmel_nand_controller_ops at91rm9200_nc_ops = {
.probe = atmel_smc_nand_controller_probe,
.remove = atmel_smc_nand_controller_remove,
.ecc_init = atmel_nand_ecc_init,
.nand_init = atmel_smc_nand_init,
.exec_op = atmel_smc_nand_exec_op,
};
if (pdev->id_entry)
caps = (void *)pdev->id_entry->driver_data; else
caps = of_device_get_match_data(&pdev->dev);
if (!caps) {
dev_err(&pdev->dev, "Could not retrieve NFC caps\n"); return -EINVAL;
}
if (caps->legacy_of_bindings) { struct device_node *nfc_node;
u32 ale_offs = 21;
/* * If we are parsing legacy DT props and the DT contains a * valid NFC node, forward the request to the sama5 logic.
*/
nfc_node = of_get_compatible_child(pdev->dev.of_node, "atmel,sama5d3-nfc"); if (nfc_node) {
caps = &atmel_sama5_nand_caps;
of_node_put(nfc_node);
}
/* * Even if the compatible says we are dealing with an * at91rm9200 controller, the atmel,nand-has-dma specify that * this controller supports DMA, which means we are in fact * dealing with an at91sam9g45+ controller.
*/ if (!caps->has_dma &&
of_property_read_bool(pdev->dev.of_node, "atmel,nand-has-dma"))
caps = &atmel_sam9g45_nand_caps;
/* * All SoCs except the at91sam9261 are assigning ALE to A21 and * CLE to A22. If atmel,nand-addr-offset != 21 this means we're * actually dealing with an at91sam9261 controller.
*/
of_property_read_u32(pdev->dev.of_node, "atmel,nand-addr-offset", &ale_offs); if (ale_offs != 21)
caps = &atmel_sam9261_nand_caps;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.