Skip to content

Commit

Permalink
Merge tag 'nand/for-5.9' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/mtd/linux into mtd/next

Core changes:
* Drop useless 'depends on' in Kconfig
* Add an extra level in the Kconfig hierarchy
* Trivial spellings
* Dynamic allocation of the interface configurations
* Dropping the default ONFI timing mode
* Various cleanup (types, structures, naming, comments)
* Hide the chip->data_interface indirection
* Add the generic rb-gpios property
* Add the ->choose_interface_config() hook
* Introduce nand_choose_best_sdr_timings()
* Use default values for tPROG_max and tBERS_max
* Avoid redefining tR_max and tCCS_min
* Add a helper to find the closest ONFI mode
* bcm63xx MTD parsers: simplify CFE detection

Raw NAND controller drivers changes:
* fsl-upm: Deprecation of specific DT properties
* fsl_upm: Driver rework and cleanup in favor of ->exec_op()
* Ingenic: Cleanup ARRAY_SIZE() vs sizeof() use
* brcmnand: ECC error handling on EDU transfers
* brcmnand: Don't default to EDU transfers
* qcom: Set BAM mode only if not set already
* qcom: Avoid write to unavailable register
* gpio: Driver rework in favor of ->exec_op()
* tango: ->exec_op() conversion
* mtk: ->exec_op() conversion

Raw NAND chip drivers changes:
* toshiba: Implement ->choose_interface_config() for TH58NVG2S3HBAI4
* toshiba: Implement ->choose_interface_config() for TC58NVG0S3E
* toshiba: Implement ->choose_interface_config() for TC58TEG5DCLTA00
* hynix: Implement ->choose_interface_config() for H27UCG8T2ATR-BC
  • Loading branch information
Richard Weinberger committed Aug 7, 2020
2 parents 0c84b7f + da151e3 commit 6a13802
Show file tree
Hide file tree
Showing 41 changed files with 1,018 additions and 747 deletions.
10 changes: 5 additions & 5 deletions Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ Required properties:
- fsl,upm-cmd-offset : UPM pattern offset for the command latch.

Optional properties:
- fsl,upm-wait-flags : add chip-dependent short delays after running the
UPM pattern (0x1), after writing a data byte (0x2) or after
writing out a buffer (0x4).
- fsl,upm-addr-line-cs-offsets : address offsets for multi-chip support.
The corresponding address lines are used to select the chip.
- gpios : may specify optional GPIOs connected to the Ready-Not-Busy pins
(R/B#). For multi-chip devices, "n" GPIO definitions are required
according to the number of chips.

Deprecated properties:
- fsl,upm-wait-flags : add chip-dependent short delays after running the
UPM pattern (0x1), after writing a data byte (0x2) or after
writing out a buffer (0x4).
- chip-delay : chip dependent delay for transferring data from array to
read registers (tR). Required if property "gpios" is not used
(R/B# pins not connected).
Expand Down Expand Up @@ -52,8 +54,6 @@ upm@3,0 {
fsl,upm-cmd-offset = <0x08>;
/* Multi-chip NAND device */
fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
fsl,upm-wait-flags = <0x5>;
chip-delay = <25>; // in micro-seconds

nand@0 {
#address-cells = <1>;
Expand Down
7 changes: 7 additions & 0 deletions Documentation/devicetree/bindings/mtd/nand-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ patternProperties:
description:
Contains the native Ready/Busy IDs.

rb-gpios:
description:
Contains one or more GPIO descriptor (the numper of descriptor
depends on the number of R/B pins exposed by the flash) for the
Ready/Busy pins. Active state refers to the NAND ready state and
should be set to GPIOD_ACTIVE_HIGH unless the signal is inverted.

required:
- reg

Expand Down
5 changes: 5 additions & 0 deletions drivers/mtd/nand/Kconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only

menu "NAND"

config MTD_NAND_CORE
tristate

source "drivers/mtd/nand/onenand/Kconfig"
source "drivers/mtd/nand/raw/Kconfig"
source "drivers/mtd/nand/spi/Kconfig"

endmenu
1 change: 0 additions & 1 deletion drivers/mtd/nand/onenand/Kconfig
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig MTD_ONENAND
tristate "OneNAND Device Support"
depends on MTD
depends on HAS_IOMEM
help
This enables support for accessing all type of OneNAND flash
Expand Down
1 change: 0 additions & 1 deletion drivers/mtd/nand/raw/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ config MTD_NAND_ECC_SW_HAMMING_SMC

menuconfig MTD_RAW_NAND
tristate "Raw/Parallel NAND Device Support"
depends on MTD
select MTD_NAND_CORE
select MTD_NAND_ECC_SW_HAMMING
help
Expand Down
6 changes: 3 additions & 3 deletions drivers/mtd/nand/raw/ams-delta.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ static int gpio_nand_exec_op(struct nand_chip *this,
return ret;
}

static int gpio_nand_setup_data_interface(struct nand_chip *this, int csline,
const struct nand_data_interface *cf)
static int gpio_nand_setup_interface(struct nand_chip *this, int csline,
const struct nand_interface_config *cf)
{
struct gpio_nand *priv = nand_get_controller_data(this);
const struct nand_sdr_timings *sdr = nand_get_sdr_timings(cf);
Expand All @@ -217,7 +217,7 @@ static int gpio_nand_setup_data_interface(struct nand_chip *this, int csline,

static const struct nand_controller_ops gpio_nand_ops = {
.exec_op = gpio_nand_exec_op,
.setup_data_interface = gpio_nand_setup_data_interface,
.setup_interface = gpio_nand_setup_interface,
};

/*
Expand Down
6 changes: 3 additions & 3 deletions drivers/mtd/nand/raw/arasan-nand-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,8 +854,8 @@ static int anfc_exec_op(struct nand_chip *chip,
return nand_op_parser_exec_op(chip, &anfc_op_parser, op, check_only);
}

static int anfc_setup_data_interface(struct nand_chip *chip, int target,
const struct nand_data_interface *conf)
static int anfc_setup_interface(struct nand_chip *chip, int target,
const struct nand_interface_config *conf)
{
struct anand *anand = to_anand(chip);
struct arasan_nfc *nfc = to_anfc(chip->controller);
Expand Down Expand Up @@ -1083,7 +1083,7 @@ static void anfc_detach_chip(struct nand_chip *chip)

static const struct nand_controller_ops anfc_ops = {
.exec_op = anfc_exec_op,
.setup_data_interface = anfc_setup_data_interface,
.setup_interface = anfc_setup_interface,
.attach_chip = anfc_attach_chip,
.detach_chip = anfc_detach_chip,
};
Expand Down
34 changes: 17 additions & 17 deletions drivers/mtd/nand/raw/atmel/nand-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ struct atmel_nand_controller_ops {
void (*nand_init)(struct atmel_nand_controller *nc,
struct atmel_nand *nand);
int (*ecc_init)(struct nand_chip *chip);
int (*setup_data_interface)(struct atmel_nand *nand, int csline,
const struct nand_data_interface *conf);
int (*setup_interface)(struct atmel_nand *nand, int csline,
const struct nand_interface_config *conf);
};

struct atmel_nand_controller_caps {
Expand Down Expand Up @@ -1168,7 +1168,7 @@ static int atmel_hsmc_nand_ecc_init(struct nand_chip *chip)
}

static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
const struct nand_data_interface *conf,
const struct nand_interface_config *conf,
struct atmel_smc_cs_conf *smcconf)
{
u32 ncycles, totalcycles, timeps, mckperiodps;
Expand Down Expand Up @@ -1397,9 +1397,9 @@ static int atmel_smc_nand_prepare_smcconf(struct atmel_nand *nand,
return 0;
}

static int atmel_smc_nand_setup_data_interface(struct atmel_nand *nand,
static int atmel_smc_nand_setup_interface(struct atmel_nand *nand,
int csline,
const struct nand_data_interface *conf)
const struct nand_interface_config *conf)
{
struct atmel_nand_controller *nc;
struct atmel_smc_cs_conf smcconf;
Expand All @@ -1422,9 +1422,9 @@ static int atmel_smc_nand_setup_data_interface(struct atmel_nand *nand,
return 0;
}

static int atmel_hsmc_nand_setup_data_interface(struct atmel_nand *nand,
static int atmel_hsmc_nand_setup_interface(struct atmel_nand *nand,
int csline,
const struct nand_data_interface *conf)
const struct nand_interface_config *conf)
{
struct atmel_hsmc_nand_controller *nc;
struct atmel_smc_cs_conf smcconf;
Expand Down Expand Up @@ -1452,8 +1452,8 @@ static int atmel_hsmc_nand_setup_data_interface(struct atmel_nand *nand,
return 0;
}

static int atmel_nand_setup_data_interface(struct nand_chip *chip, int csline,
const struct nand_data_interface *conf)
static int atmel_nand_setup_interface(struct nand_chip *chip, int csline,
const struct nand_interface_config *conf)
{
struct atmel_nand *nand = to_atmel_nand(chip);
struct atmel_nand_controller *nc;
Expand All @@ -1464,7 +1464,7 @@ static int atmel_nand_setup_data_interface(struct nand_chip *chip, int csline,
(csline < 0 && csline != NAND_DATA_IFACE_CHECK_ONLY))
return -EINVAL;

return nc->caps->ops->setup_data_interface(nand, csline, conf);
return nc->caps->ops->setup_interface(nand, csline, conf);
}

static void atmel_nand_init(struct atmel_nand_controller *nc,
Expand All @@ -1483,7 +1483,7 @@ static void atmel_nand_init(struct atmel_nand_controller *nc,
chip->legacy.write_buf = atmel_nand_write_buf;
chip->legacy.select_chip = atmel_nand_select_chip;

if (!nc->mck || !nc->caps->ops->setup_data_interface)
if (!nc->mck || !nc->caps->ops->setup_interface)
chip->options |= NAND_KEEP_TIMINGS;

/* Some NANDs require a longer delay than the default one (20us). */
Expand Down Expand Up @@ -1956,7 +1956,7 @@ static int atmel_nand_attach_chip(struct nand_chip *chip)

static const struct nand_controller_ops atmel_nand_controller_ops = {
.attach_chip = atmel_nand_attach_chip,
.setup_data_interface = atmel_nand_setup_data_interface,
.setup_interface = atmel_nand_setup_interface,
};

static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
Expand Down Expand Up @@ -2318,7 +2318,7 @@ static const struct atmel_nand_controller_ops atmel_hsmc_nc_ops = {
.remove = atmel_hsmc_nand_controller_remove,
.ecc_init = atmel_hsmc_nand_ecc_init,
.nand_init = atmel_hsmc_nand_init,
.setup_data_interface = atmel_hsmc_nand_setup_data_interface,
.setup_interface = atmel_hsmc_nand_setup_interface,
};

static const struct atmel_nand_controller_caps atmel_sama5_nc_caps = {
Expand Down Expand Up @@ -2375,10 +2375,10 @@ atmel_smc_nand_controller_remove(struct atmel_nand_controller *nc)

/*
* The SMC reg layout of at91rm9200 is completely different which prevents us
* from re-using atmel_smc_nand_setup_data_interface() for the
* ->setup_data_interface() hook.
* 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_data_interface() unassigned.
* ->setup_interface() unassigned.
*/
static const struct atmel_nand_controller_ops at91rm9200_nc_ops = {
.probe = atmel_smc_nand_controller_probe,
Expand All @@ -2399,7 +2399,7 @@ static const struct atmel_nand_controller_ops atmel_smc_nc_ops = {
.remove = atmel_smc_nand_controller_remove,
.ecc_init = atmel_nand_ecc_init,
.nand_init = atmel_smc_nand_init,
.setup_data_interface = atmel_smc_nand_setup_data_interface,
.setup_interface = atmel_smc_nand_setup_interface,
};

static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps = {
Expand Down
31 changes: 29 additions & 2 deletions drivers/mtd/nand/raw/brcmnand/brcmnand.c
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,22 @@ static int brcmnand_edu_trans(struct brcmnand_host *host, u64 addr, u32 *buf,
edu_writel(ctrl, EDU_STOP, 0); /* force stop */
edu_readl(ctrl, EDU_STOP);

if (!ret && edu_cmd == EDU_CMD_READ) {
u64 err_addr = 0;

/*
* check for ECC errors here, subpage ECC errors are
* retained in ECC error address register
*/
err_addr = brcmnand_get_uncorrecc_addr(ctrl);
if (!err_addr) {
err_addr = brcmnand_get_correcc_addr(ctrl);
if (err_addr)
ret = -EUCLEAN;
} else
ret = -EBADMSG;
}

return ret;
}

Expand Down Expand Up @@ -2124,6 +2140,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
u64 err_addr = 0;
int err;
bool retry = true;
bool edu_err = false;

dev_dbg(ctrl->dev, "read %llx -> %p\n", (unsigned long long)addr, buf);

Expand All @@ -2141,6 +2158,10 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
else
return -EIO;
}

if (has_edu(ctrl) && err_addr)
edu_err = true;

} else {
if (oob)
memset(oob, 0x99, mtd->oobsize);
Expand Down Expand Up @@ -2188,6 +2209,11 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip,
if (mtd_is_bitflip(err)) {
unsigned int corrected = brcmnand_count_corrected(ctrl);

/* in case of EDU correctable error we read again using PIO */
if (edu_err)
err = brcmnand_read_by_pio(mtd, chip, addr, trans, buf,
oob, &err_addr);

dev_dbg(ctrl->dev, "corrected error at 0x%llx\n",
(unsigned long long)err_addr);
mtd->ecc_stats.corrected += corrected;
Expand Down Expand Up @@ -3023,8 +3049,9 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
if (ret < 0)
goto err;

/* set edu transfer function to call */
ctrl->dma_trans = brcmnand_edu_trans;
if (has_edu(ctrl))
/* set edu transfer function to call */
ctrl->dma_trans = brcmnand_edu_trans;
}

/* Disable automatic device ID config, direct addressing */
Expand Down
6 changes: 3 additions & 3 deletions drivers/mtd/nand/raw/cadence-nand-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -2303,8 +2303,8 @@ static inline u32 calc_tdvw(u32 trp_cnt, u32 clk_period, u32 trhoh_min,
}

static int
cadence_nand_setup_data_interface(struct nand_chip *chip, int chipnr,
const struct nand_data_interface *conf)
cadence_nand_setup_interface(struct nand_chip *chip, int chipnr,
const struct nand_interface_config *conf)
{
const struct nand_sdr_timings *sdr;
struct cdns_nand_ctrl *cdns_ctrl = to_cdns_nand_ctrl(chip->controller);
Expand Down Expand Up @@ -2690,7 +2690,7 @@ static int cadence_nand_attach_chip(struct nand_chip *chip)
static const struct nand_controller_ops cadence_nand_controller_ops = {
.attach_chip = cadence_nand_attach_chip,
.exec_op = cadence_nand_exec_op,
.setup_data_interface = cadence_nand_setup_data_interface,
.setup_interface = cadence_nand_setup_interface,
};

static int cadence_nand_chip_init(struct cdns_nand_ctrl *cdns_ctrl,
Expand Down
8 changes: 4 additions & 4 deletions drivers/mtd/nand/raw/denali.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,8 +761,8 @@ static int denali_write_page(struct nand_chip *chip, const u8 *buf,
return denali_page_xfer(chip, (void *)buf, mtd->writesize, page, true);
}

static int denali_setup_data_interface(struct nand_chip *chip, int chipnr,
const struct nand_data_interface *conf)
static int denali_setup_interface(struct nand_chip *chip, int chipnr,
const struct nand_interface_config *conf)
{
static const unsigned int data_setup_on_host = 10000;
struct denali_controller *denali = to_denali_controller(chip);
Expand Down Expand Up @@ -1173,7 +1173,7 @@ static int denali_exec_op(struct nand_chip *chip,
static const struct nand_controller_ops denali_controller_ops = {
.attach_chip = denali_attach_chip,
.exec_op = denali_exec_op,
.setup_data_interface = denali_setup_data_interface,
.setup_interface = denali_setup_interface,
};

int denali_chip_init(struct denali_controller *denali,
Expand Down Expand Up @@ -1230,7 +1230,7 @@ int denali_chip_init(struct denali_controller *denali,
chip->buf_align = 16;
}

/* clk rate info is needed for setup_data_interface */
/* clk rate info is needed for setup_interface */
if (!denali->clk_rate || !denali->clk_x_rate)
chip->options |= NAND_KEEP_TIMINGS;

Expand Down
Loading

0 comments on commit 6a13802

Please sign in to comment.