diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-12 17:57:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-12 17:57:52 -0400 |
commit | 4dbf09fea60d158e60a30c419e0cfa1ea138dd57 (patch) | |
tree | 9530efcb3ca37e6664b9df41e8a33ea7286dba50 /drivers/mtd/nand/raw/atmel/nand-controller.c | |
parent | 983dfa4b6ee556563f7963348e4e2f97fc8a15b8 (diff) | |
parent | 3008ba87093852f3756c5d33f584602e5e2a4aa4 (diff) |
Merge tag 'mtd/for-5.2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull MTD updates from Richard Weinberger:
"MTD core changes:
- New AFS partition parser
- Update MAINTAINERS entry
- Use of fall-throughs markers
NAND core changes:
- Support having the bad block markers in either the first, second or
last page of a block. The combination of all three location is now
possible.
- Constification of NAND_OP_PARSER(_PATTERN) elements.
- Generic NAND DT bindings changed to yaml format (can be used to
check the proposed bindings. First platform to be fully supported:
sunxi.
- Stopped using several legacy hooks.
- Preparation to use the generic NAND layer with the addition of
several helpers and the removal of the struct nand_chip from
generic functions.
- Kconfig cleanup to prepare the introduction of external ECC engines
support.
- Fallthrough comments.
- Introduction of the SPI-mem dirmap API for SPI-NAND devices.
Raw NAND controller drivers changes:
- nandsim:
- Switch to ->exec-op().
- meson:
- Misc cleanups and fixes.
- New OOB layout.
- Sunxi:
- A23/A33 NAND DMA support.
- Ingenic:
- Full reorganization and cleanup.
- Clear separation between NAND controller and ECC engine.
- Support JZ4740 an JZ4725B.
- Denali:
- Clear controller/chip separation.
- ->exec_op() migration.
- Various cleanups.
- fsl_elbc:
- Enable software ECC support.
- Atmel:
- Sam9x60 support.
- GPMI:
- Introduce the GPMI_IS_MXS() macro.
- Various trivial/spelling/coding style fixes.
SPI NOR core changes:
- Print all JEDEC ID bytes on error
- Fix comment of spi_nor_find_best_erase_type()
- Add region locking flags for s25fl512s
SPI NOR controller drivers changes:
- intel-spi:
- Avoid crossing 4K address boundary on read/write
- Add support for Intel Comet Lake SPI serial flash"
* tag 'mtd/for-5.2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (120 commits)
mtd: part: fix incorrect format specifier for an unsigned long long
mtd: lpddr_cmds: Mark expected switch fall-through
mtd: phram: Mark expected switch fall-throughs
mtd: cfi_cmdset_0002: Mark expected switch fall-throughs
mtd: cfi_util: mark expected switch fall-throughs
MAINTAINERS: MTD Git repository is hosted on kernel.org
MAINTAINERS: Update jffs2 entry
mtd: afs: add v2 partition parsing
mtd: afs: factor the IIS read into partition parser
mtd: afs: factor footer parsing into the v1 part parsing
mtd: factor out v1 partition parsing
mtd: afs: simplify partition detection
mtd: afs: simplify partition parsing
mtd: partitions: Add OF support to AFS partitions
mtd: partitions: Add AFS partitions DT bindings
mtd: afs: Move AFS partition parser to parsers subdir
mtd: maps: Make uclinux_ram_map static
mtd: maps: Allow MTD_PHYSMAP with MTD_RAM
MAINTAINERS: Add myself as MTD maintainer
MAINTAINERS: Remove my name from the MTD and NAND entries
...
Diffstat (limited to 'drivers/mtd/nand/raw/atmel/nand-controller.c')
-rw-r--r-- | drivers/mtd/nand/raw/atmel/nand-controller.c | 127 |
1 files changed, 96 insertions, 31 deletions
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index 5781fcf6b76c..8d6be90a6fe8 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright 2017 ATMEL * Copyright 2017 Free Electrons @@ -29,10 +30,6 @@ * Add Nand Flash Controller support for SAMA5 SoC * Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * * A few words about the naming convention in this file. This convention * applies to structure and function names. * @@ -65,6 +62,7 @@ #include <linux/iopoll.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <soc/at91/atmel-sfr.h> #include "pmecc.h" @@ -211,6 +209,7 @@ struct atmel_nand_controller_caps { bool legacy_of_bindings; u32 ale_offs; u32 cle_offs; + const char *ebi_csa_regmap_name; const struct atmel_nand_controller_ops *ops; }; @@ -231,10 +230,15 @@ to_nand_controller(struct nand_controller *ctl) return container_of(ctl, struct atmel_nand_controller, base); } +struct atmel_smc_nand_ebi_csa_cfg { + u32 offs; + u32 nfd0_on_d16; +}; + struct atmel_smc_nand_controller { struct atmel_nand_controller base; - struct regmap *matrix; - unsigned int ebi_csa_offs; + struct regmap *ebi_csa_regmap; + struct atmel_smc_nand_ebi_csa_cfg *ebi_csa; }; static inline struct atmel_smc_nand_controller * @@ -1068,15 +1072,15 @@ static int atmel_nand_pmecc_init(struct nand_chip *chip) req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH; else if (chip->ecc.strength) req.ecc.strength = chip->ecc.strength; - else if (chip->ecc_strength_ds) - req.ecc.strength = chip->ecc_strength_ds; + else if (chip->base.eccreq.strength) + req.ecc.strength = chip->base.eccreq.strength; else req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH; if (chip->ecc.size) req.ecc.sectorsize = chip->ecc.size; - else if (chip->ecc_step_ds) - req.ecc.sectorsize = chip->ecc_step_ds; + else if (chip->base.eccreq.step_size) + req.ecc.sectorsize = chip->base.eccreq.step_size; else req.ecc.sectorsize = ATMEL_PMECC_SECTOR_SIZE_AUTO; @@ -1507,13 +1511,20 @@ static void atmel_smc_nand_init(struct atmel_nand_controller *nc, atmel_nand_init(nc, nand); smc_nc = to_smc_nand_controller(chip->controller); - if (!smc_nc->matrix) + 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->matrix, smc_nc->ebi_csa_offs, + 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); } static void atmel_hsmc_nand_init(struct atmel_nand_controller *nc, @@ -1797,7 +1808,7 @@ static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc) ret = of_property_read_u32(np, "#size-cells", &val); if (ret) { - dev_err(dev, "missing #address-cells property\n"); + dev_err(dev, "missing #size-cells property\n"); return ret; } @@ -1833,34 +1844,71 @@ static void atmel_nand_controller_cleanup(struct atmel_nand_controller *nc) clk_put(nc->mck); } -static const struct of_device_id atmel_matrix_of_ids[] = { +static const struct atmel_smc_nand_ebi_csa_cfg at91sam9260_ebi_csa = { + .offs = AT91SAM9260_MATRIX_EBICSA, +}; + +static const struct atmel_smc_nand_ebi_csa_cfg at91sam9261_ebi_csa = { + .offs = AT91SAM9261_MATRIX_EBICSA, +}; + +static const struct atmel_smc_nand_ebi_csa_cfg at91sam9263_ebi_csa = { + .offs = AT91SAM9263_MATRIX_EBI0CSA, +}; + +static const struct atmel_smc_nand_ebi_csa_cfg at91sam9rl_ebi_csa = { + .offs = AT91SAM9RL_MATRIX_EBICSA, +}; + +static const struct atmel_smc_nand_ebi_csa_cfg at91sam9g45_ebi_csa = { + .offs = AT91SAM9G45_MATRIX_EBICSA, +}; + +static const struct atmel_smc_nand_ebi_csa_cfg at91sam9n12_ebi_csa = { + .offs = AT91SAM9N12_MATRIX_EBICSA, +}; + +static const struct atmel_smc_nand_ebi_csa_cfg at91sam9x5_ebi_csa = { + .offs = AT91SAM9X5_MATRIX_EBICSA, +}; + +static const struct atmel_smc_nand_ebi_csa_cfg sam9x60_ebi_csa = { + .offs = AT91_SFR_CCFG_EBICSA, + .nfd0_on_d16 = AT91_SFR_CCFG_NFD0_ON_D16, +}; + +static const struct of_device_id atmel_ebi_csa_regmap_of_ids[] = { { .compatible = "atmel,at91sam9260-matrix", - .data = (void *)AT91SAM9260_MATRIX_EBICSA, + .data = &at91sam9260_ebi_csa, }, { .compatible = "atmel,at91sam9261-matrix", - .data = (void *)AT91SAM9261_MATRIX_EBICSA, + .data = &at91sam9261_ebi_csa, }, { .compatible = "atmel,at91sam9263-matrix", - .data = (void *)AT91SAM9263_MATRIX_EBI0CSA, + .data = &at91sam9263_ebi_csa, }, { .compatible = "atmel,at91sam9rl-matrix", - .data = (void *)AT91SAM9RL_MATRIX_EBICSA, + .data = &at91sam9rl_ebi_csa, }, { .compatible = "atmel,at91sam9g45-matrix", - .data = (void *)AT91SAM9G45_MATRIX_EBICSA, + .data = &at91sam9g45_ebi_csa, }, { .compatible = "atmel,at91sam9n12-matrix", - .data = (void *)AT91SAM9N12_MATRIX_EBICSA, + .data = &at91sam9n12_ebi_csa, }, { .compatible = "atmel,at91sam9x5-matrix", - .data = (void *)AT91SAM9X5_MATRIX_EBICSA, + .data = &at91sam9x5_ebi_csa, + }, + { + .compatible = "microchip,sam9x60-sfr", + .data = &sam9x60_ebi_csa, }, { /* sentinel */ }, }; @@ -1982,37 +2030,38 @@ atmel_smc_nand_controller_init(struct atmel_smc_nand_controller *nc) struct device_node *np; int ret; - /* We do not retrieve the matrix syscon when parsing old DTs. */ + /* We do not retrieve the EBICSA regmap when parsing old DTs. */ if (nc->base.caps->legacy_of_bindings) return 0; - np = of_parse_phandle(dev->parent->of_node, "atmel,matrix", 0); + np = of_parse_phandle(dev->parent->of_node, + nc->base.caps->ebi_csa_regmap_name, 0); if (!np) return 0; - match = of_match_node(atmel_matrix_of_ids, np); + match = of_match_node(atmel_ebi_csa_regmap_of_ids, np); if (!match) { of_node_put(np); return 0; } - nc->matrix = syscon_node_to_regmap(np); + nc->ebi_csa_regmap = syscon_node_to_regmap(np); of_node_put(np); - if (IS_ERR(nc->matrix)) { - ret = PTR_ERR(nc->matrix); - dev_err(dev, "Could not get Matrix regmap (err = %d)\n", ret); + if (IS_ERR(nc->ebi_csa_regmap)) { + ret = PTR_ERR(nc->ebi_csa_regmap); + dev_err(dev, "Could not get EBICSA regmap (err = %d)\n", ret); return ret; } - nc->ebi_csa_offs = (uintptr_t)match->data; + nc->ebi_csa = (struct atmel_smc_nand_ebi_csa_cfg *)match->data; /* * The at91sam9263 has 2 EBIs, if the NAND controller is under EBI1 - * add 4 to ->ebi_csa_offs. + * add 4 to ->ebi_csa->offs. */ if (of_device_is_compatible(dev->parent->of_node, "atmel,at91sam9263-ebi1")) - nc->ebi_csa_offs += 4; + nc->ebi_csa->offs += 4; return 0; } @@ -2341,6 +2390,7 @@ static const struct atmel_nand_controller_ops at91rm9200_nc_ops = { static const struct atmel_nand_controller_caps atmel_rm9200_nc_caps = { .ale_offs = BIT(21), .cle_offs = BIT(22), + .ebi_csa_regmap_name = "atmel,matrix", .ops = &at91rm9200_nc_ops, }; @@ -2355,12 +2405,14 @@ static const struct atmel_nand_controller_ops atmel_smc_nc_ops = { static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps = { .ale_offs = BIT(21), .cle_offs = BIT(22), + .ebi_csa_regmap_name = "atmel,matrix", .ops = &atmel_smc_nc_ops, }; static const struct atmel_nand_controller_caps atmel_sam9261_nc_caps = { .ale_offs = BIT(22), .cle_offs = BIT(21), + .ebi_csa_regmap_name = "atmel,matrix", .ops = &atmel_smc_nc_ops, }; @@ -2368,6 +2420,15 @@ static const struct atmel_nand_controller_caps atmel_sam9g45_nc_caps = { .has_dma = true, .ale_offs = BIT(21), .cle_offs = BIT(22), + .ebi_csa_regmap_name = "atmel,matrix", + .ops = &atmel_smc_nc_ops, +}; + +static const struct atmel_nand_controller_caps microchip_sam9x60_nc_caps = { + .has_dma = true, + .ale_offs = BIT(21), + .cle_offs = BIT(22), + .ebi_csa_regmap_name = "microchip,sfr", .ops = &atmel_smc_nc_ops, }; @@ -2415,6 +2476,10 @@ static const struct of_device_id atmel_nand_controller_of_ids[] = { .compatible = "atmel,sama5d3-nand-controller", .data = &atmel_sama5_nc_caps, }, + { + .compatible = "microchip,sam9x60-nand-controller", + .data = µchip_sam9x60_nc_caps, + }, /* Support for old/deprecated bindings: */ { .compatible = "atmel,at91rm9200-nand", |