Message ID | 20191220093900.1855751-1-marex@denx.de |
---|---|
State | Changes Requested |
Delegated to: | Miquel Raynal |
Headers | show |
Series | [V2] mtd: rawnand: denali_dt: Add support for configuring SPARE_AREA_SKIP_BYTES | expand |
On Fri, Dec 20, 2019 at 6:39 PM Marek Vasut <marex@denx.de> wrote: > > The SPARE_AREA_SKIP_BYTES register is reset when the controller reset > signal is toggled. Yet, this register must be configured to match the > content of the NAND OOB area. The current default value is always set > to 8 and is programmed into the hardware in case the hardware was not > programmed before (e.g. in a bootloader) with a different value. This > however does not work when the block is reset properly by Linux. > > On Altera SoCFPGA CycloneV, ArriaV and Arria10, which are the SoCFPGA > platforms which support booting from NAND, the SPARE_AREA_SKIP_BYTES > value must be set to 2. On Socionext Uniphier, the value is 8. This > patch adds support for preconfiguring the default value and handles > the special SoCFPGA case by setting the default to 2 on all SoCFPGA > platforms, while retaining the original behavior and default value of > 8 on all the other platforms. > > Signed-off-by: Marek Vasut <marex@denx.de> > Cc: Masahiro Yamada <yamada.masahiro@socionext.com> > Cc: Miquel Raynal <miquel.raynal@bootlin.com> > Cc: Richard Weinberger <richard@nod.at> > Cc: Vignesh Raghavendra <vigneshr@ti.com> > To: linux-mtd@lists.infradead.org > Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com> > --- > V2: Move denali->oob_skip_bytes = data->oob_skip_bytes; right after > of_device_get_match_data() FYI. This patch was rebased to avoid a conflict: http://patchwork.ozlabs.org/patch/1214018/ My Ack is in v3. I solved a merge conflict, and bundled in a series: http://patchwork.ozlabs.org/project/linux-mtd/list/?series=149821 > --- > drivers/mtd/nand/raw/denali.c | 13 ++++++++++--- > drivers/mtd/nand/raw/denali_dt.c | 5 +++++ > 2 files changed, 15 insertions(+), 3 deletions(-) > > diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c > index 3102ddbd8abdb..b6c463d021677 100644 > --- a/drivers/mtd/nand/raw/denali.c > +++ b/drivers/mtd/nand/raw/denali.c > @@ -1302,14 +1302,21 @@ int denali_init(struct denali_controller *denali) > > /* > * Set how many bytes should be skipped before writing data in OOB. > + * If a non-zero value has already been configured, update it in HW. > * If a non-zero value has already been set (by firmware or something), > * just use it. Otherwise, set the driver's default. > */ > - denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES); > - if (!denali->oob_skip_bytes) { > - denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES; > + if (denali->oob_skip_bytes) { > iowrite32(denali->oob_skip_bytes, > denali->reg + SPARE_AREA_SKIP_BYTES); > + } else { > + denali->oob_skip_bytes = > + ioread32(denali->reg + SPARE_AREA_SKIP_BYTES); > + if (!denali->oob_skip_bytes) { > + denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES; > + iowrite32(denali->oob_skip_bytes, > + denali->reg + SPARE_AREA_SKIP_BYTES); > + } > } > > iowrite32(0, denali->reg + TRANSFER_SPARE_REG); > diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c > index 8b779a899dcf4..443f9c1f6854d 100644 > --- a/drivers/mtd/nand/raw/denali_dt.c > +++ b/drivers/mtd/nand/raw/denali_dt.c > @@ -27,6 +27,7 @@ struct denali_dt { > struct denali_dt_data { > unsigned int revision; > unsigned int caps; > + unsigned int oob_skip_bytes; > const struct nand_ecc_caps *ecc_caps; > }; > > @@ -34,6 +35,7 @@ NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes, > 512, 8, 15); > static const struct denali_dt_data denali_socfpga_data = { > .caps = DENALI_CAP_HW_ECC_FIXUP, > + .oob_skip_bytes = 2, > .ecc_caps = &denali_socfpga_ecc_caps, > }; > > @@ -42,6 +44,7 @@ NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes, > static const struct denali_dt_data denali_uniphier_v5a_data = { > .caps = DENALI_CAP_HW_ECC_FIXUP | > DENALI_CAP_DMA_64BIT, > + .oob_skip_bytes = 8, > .ecc_caps = &denali_uniphier_v5a_ecc_caps, > }; > > @@ -51,6 +54,7 @@ static const struct denali_dt_data denali_uniphier_v5b_data = { > .revision = 0x0501, > .caps = DENALI_CAP_HW_ECC_FIXUP | > DENALI_CAP_DMA_64BIT, > + .oob_skip_bytes = 8, > .ecc_caps = &denali_uniphier_v5b_ecc_caps, > }; > > @@ -122,6 +126,7 @@ static int denali_dt_probe(struct platform_device *pdev) > denali->revision = data->revision; > denali->caps = data->caps; > denali->ecc_caps = data->ecc_caps; > + denali->oob_skip_bytes = data->oob_skip_bytes; > } > > denali->dev = dev; > -- > 2.24.1 > > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/
Hi Masahiro, Masahiro Yamada <masahiroy@kernel.org> wrote on Fri, 10 Jan 2020 01:06:20 +0900: > On Fri, Dec 20, 2019 at 6:39 PM Marek Vasut <marex@denx.de> wrote: > > > > The SPARE_AREA_SKIP_BYTES register is reset when the controller reset > > signal is toggled. Yet, this register must be configured to match the > > content of the NAND OOB area. The current default value is always set > > to 8 and is programmed into the hardware in case the hardware was not > > programmed before (e.g. in a bootloader) with a different value. This > > however does not work when the block is reset properly by Linux. > > > > On Altera SoCFPGA CycloneV, ArriaV and Arria10, which are the SoCFPGA > > platforms which support booting from NAND, the SPARE_AREA_SKIP_BYTES > > value must be set to 2. On Socionext Uniphier, the value is 8. This > > patch adds support for preconfiguring the default value and handles > > the special SoCFPGA case by setting the default to 2 on all SoCFPGA > > platforms, while retaining the original behavior and default value of > > 8 on all the other platforms. > > > > Signed-off-by: Marek Vasut <marex@denx.de> > > Cc: Masahiro Yamada <yamada.masahiro@socionext.com> > > Cc: Miquel Raynal <miquel.raynal@bootlin.com> > > Cc: Richard Weinberger <richard@nod.at> > > Cc: Vignesh Raghavendra <vigneshr@ti.com> > > To: linux-mtd@lists.infradead.org > > Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com> > > --- > > V2: Move denali->oob_skip_bytes = data->oob_skip_bytes; right after > > of_device_get_match_data() > > > FYI. > > This patch was rebased to avoid a conflict: > http://patchwork.ozlabs.org/patch/1214018/ > > My Ack is in v3. It is indeed about to be applied :) Cheers, Miquèl
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 3102ddbd8abdb..b6c463d021677 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -1302,14 +1302,21 @@ int denali_init(struct denali_controller *denali) /* * Set how many bytes should be skipped before writing data in OOB. + * If a non-zero value has already been configured, update it in HW. * If a non-zero value has already been set (by firmware or something), * just use it. Otherwise, set the driver's default. */ - denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES); - if (!denali->oob_skip_bytes) { - denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES; + if (denali->oob_skip_bytes) { iowrite32(denali->oob_skip_bytes, denali->reg + SPARE_AREA_SKIP_BYTES); + } else { + denali->oob_skip_bytes = + ioread32(denali->reg + SPARE_AREA_SKIP_BYTES); + if (!denali->oob_skip_bytes) { + denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES; + iowrite32(denali->oob_skip_bytes, + denali->reg + SPARE_AREA_SKIP_BYTES); + } } iowrite32(0, denali->reg + TRANSFER_SPARE_REG); diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 8b779a899dcf4..443f9c1f6854d 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -27,6 +27,7 @@ struct denali_dt { struct denali_dt_data { unsigned int revision; unsigned int caps; + unsigned int oob_skip_bytes; const struct nand_ecc_caps *ecc_caps; }; @@ -34,6 +35,7 @@ NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes, 512, 8, 15); static const struct denali_dt_data denali_socfpga_data = { .caps = DENALI_CAP_HW_ECC_FIXUP, + .oob_skip_bytes = 2, .ecc_caps = &denali_socfpga_ecc_caps, }; @@ -42,6 +44,7 @@ NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes, static const struct denali_dt_data denali_uniphier_v5a_data = { .caps = DENALI_CAP_HW_ECC_FIXUP | DENALI_CAP_DMA_64BIT, + .oob_skip_bytes = 8, .ecc_caps = &denali_uniphier_v5a_ecc_caps, }; @@ -51,6 +54,7 @@ static const struct denali_dt_data denali_uniphier_v5b_data = { .revision = 0x0501, .caps = DENALI_CAP_HW_ECC_FIXUP | DENALI_CAP_DMA_64BIT, + .oob_skip_bytes = 8, .ecc_caps = &denali_uniphier_v5b_ecc_caps, }; @@ -122,6 +126,7 @@ static int denali_dt_probe(struct platform_device *pdev) denali->revision = data->revision; denali->caps = data->caps; denali->ecc_caps = data->ecc_caps; + denali->oob_skip_bytes = data->oob_skip_bytes; } denali->dev = dev;