* [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux
@ 2024-09-16 9:58 Linus Walleij
2024-09-16 9:58 ` [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller Linus Walleij
` (6 more replies)
0 siblings, 7 replies; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij, Florian Fainelli, Miquel Raynal, Kamal Dasu,
David Regan
These are a number of assorted upstream Linux fixes to the
BRCMNAND driver that I have backported in an attempt to get
BRCMBCA working with U-Boot (still not there).
This patch set lowers the hamming distance between the Linux
and U-Boot drivers a bit as well, while we deviate quite
a bit it is still possible to bring fixes over thanks to
exercises like this.
On top of this I have a BCMBCA driver which works fine
albeit with some complaints about ONFI:
NAND: Could not find valid ONFI parameter page; aborting
256 MiB
(...)
=> nand info
Device 0: nand0, sector size 128 KiB
Page size 2048 b
OOB size 64 b
Erase size 131072 b
ecc strength 4 bits
ecc step size 512 b
subpagesize 2048 b
options 0x00104200
bbt options 0x00060000
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Changes in v2:
- Augment the write protect handling to also support the bool
"write-protect" property in legacy DTS files.
- Fix a mistake in the use_strap DTS property parsing.
- Tested successfully with BCMBCA driver (will be submitted
once this is merged).
- Link to v1: https://patchwork.ozlabs.org/project/uboot/list/?series=423357
---
Linus Walleij (1):
mtd: rawnand: brcmnand: Add read data bus interface
William Zhang (6):
mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller
mtd: rawnand: brcmnand: Fix potential false time out warning
mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write
mtd: rawnand: brcmnand: Fix mtd oobsize
mtd: rawnand: brcmnand: Support write protection setting from dts
mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 209 ++++++++++++++++++++++++-------
drivers/mtd/nand/raw/brcmnand/brcmnand.h | 2 +
2 files changed, 166 insertions(+), 45 deletions(-)
---
base-commit: a7b83ade98e0f567c82d168022e12d3ebef1f318
change-id: 20240911-brcmnand-fixes-dabd75230a63
Best regards,
--
Linus Walleij <linus.walleij@linaro.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
@ 2024-09-16 9:58 ` Linus Walleij
2024-09-17 0:21 ` William Zhang
2024-09-29 17:19 ` Michael Nazzareno Trimarchi
2024-09-16 9:58 ` [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time out warning Linus Walleij
` (5 subsequent siblings)
6 siblings, 2 replies; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij, Florian Fainelli, Miquel Raynal
From: William Zhang <william.zhang@broadcom.com>
Backport from the Linux kernel
commit 2ec2839a9062db8a592525a3fdabd42dcd9a3a9b
"mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller"
v7.2 controller has different ECC level field size and shift in the acc
control register than its predecessor and successor controller. It needs
to be set specifically.
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-2-william.zhang@broadcom.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 74 ++++++++++++++++++--------------
1 file changed, 41 insertions(+), 33 deletions(-)
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index b1af3f717d43..700d1122639f 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -218,6 +218,7 @@ struct brcmnand_controller {
const unsigned int *page_sizes;
unsigned int page_size_shift;
unsigned int max_oob;
+ u32 ecc_level_shift;
u32 features;
/* for low-power standby/resume only */
@@ -544,6 +545,34 @@ enum {
INTFC_CTLR_READY = BIT(31),
};
+/***********************************************************************
+ * NAND ACC CONTROL bitfield
+ *
+ * Some bits have remained constant throughout hardware revision, while
+ * others have shifted around.
+ ***********************************************************************/
+
+/* Constant for all versions (where supported) */
+enum {
+ /* See BRCMNAND_HAS_CACHE_MODE */
+ ACC_CONTROL_CACHE_MODE = BIT(22),
+
+ /* See BRCMNAND_HAS_PREFETCH */
+ ACC_CONTROL_PREFETCH = BIT(23),
+
+ ACC_CONTROL_PAGE_HIT = BIT(24),
+ ACC_CONTROL_WR_PREEMPT = BIT(25),
+ ACC_CONTROL_PARTIAL_PAGE = BIT(26),
+ ACC_CONTROL_RD_ERASED = BIT(27),
+ ACC_CONTROL_FAST_PGM_RDIN = BIT(28),
+ ACC_CONTROL_WR_ECC = BIT(30),
+ ACC_CONTROL_RD_ECC = BIT(31),
+};
+
+#define ACC_CONTROL_ECC_SHIFT 16
+/* Only for v7.2 */
+#define ACC_CONTROL_ECC_EXT_SHIFT 13
+
static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)
{
return brcmnand_readl(ctrl->nand_base + offs);
@@ -675,6 +704,12 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
#endif /* __UBOOT__ */
ctrl->features |= BRCMNAND_HAS_WP;
+ /* v7.2 has different ecc level shift in the acc register */
+ if (ctrl->nand_version == 0x0702)
+ ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT;
+ else
+ ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT;
+
return 0;
}
@@ -844,30 +879,6 @@ static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl)
return 0;
}
-/***********************************************************************
- * NAND ACC CONTROL bitfield
- *
- * Some bits have remained constant throughout hardware revision, while
- * others have shifted around.
- ***********************************************************************/
-
-/* Constant for all versions (where supported) */
-enum {
- /* See BRCMNAND_HAS_CACHE_MODE */
- ACC_CONTROL_CACHE_MODE = BIT(22),
-
- /* See BRCMNAND_HAS_PREFETCH */
- ACC_CONTROL_PREFETCH = BIT(23),
-
- ACC_CONTROL_PAGE_HIT = BIT(24),
- ACC_CONTROL_WR_PREEMPT = BIT(25),
- ACC_CONTROL_PARTIAL_PAGE = BIT(26),
- ACC_CONTROL_RD_ERASED = BIT(27),
- ACC_CONTROL_FAST_PGM_RDIN = BIT(28),
- ACC_CONTROL_WR_ECC = BIT(30),
- ACC_CONTROL_RD_ECC = BIT(31),
-};
-
static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
{
if (ctrl->nand_version == 0x0702)
@@ -880,18 +891,15 @@ static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
return GENMASK(4, 0);
}
-#define NAND_ACC_CONTROL_ECC_SHIFT 16
-#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13
-
static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl)
{
u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f;
- mask <<= NAND_ACC_CONTROL_ECC_SHIFT;
+ mask <<= ACC_CONTROL_ECC_SHIFT;
/* v7.2 includes additional ECC levels */
- if (ctrl->nand_version >= 0x0702)
- mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT;
+ if (ctrl->nand_version == 0x0702)
+ mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT;
return mask;
}
@@ -905,8 +913,8 @@ static void brcmnand_set_ecc_enabled(struct brcmnand_host *host, int en)
if (en) {
acc_control |= ecc_flags; /* enable RD/WR ECC */
- acc_control |= host->hwcfg.ecc_level
- << NAND_ACC_CONTROL_ECC_SHIFT;
+ acc_control &= ~brcmnand_ecc_level_mask(ctrl);
+ acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift;
} else {
acc_control &= ~ecc_flags; /* disable RD/WR ECC */
acc_control &= ~brcmnand_ecc_level_mask(ctrl);
@@ -2225,7 +2233,7 @@ static int brcmnand_set_cfg(struct brcmnand_host *host,
tmp &= ~brcmnand_ecc_level_mask(ctrl);
tmp &= ~brcmnand_spare_area_mask(ctrl);
if (ctrl->nand_version >= 0x0302) {
- tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT;
+ tmp |= cfg->ecc_level << ctrl->ecc_level_shift;
tmp |= cfg->spare_area_size;
}
nand_writereg(ctrl, acc_control_offs, tmp);
--
2.46.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time out warning
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
2024-09-16 9:58 ` [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller Linus Walleij
@ 2024-09-16 9:58 ` Linus Walleij
2024-09-17 0:20 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 3/7] mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write Linus Walleij
` (4 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij, Florian Fainelli, Miquel Raynal
From: William Zhang <william.zhang@broadcom.com>
Backport from the Linux kernel:
commit 9cc0a598b944816f2968baf2631757f22721b996
"mtd: rawnand: brcmnand: Fix potential false time out warning"
If system is busy during the command status polling function, the driver
may not get the chance to poll the status register till the end of time
out and return the premature status. Do a final check after time out
happens to ensure reading the correct status.
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-3-william.zhang@broadcom.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 700d1122639f..46a4107a83a9 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1011,6 +1011,14 @@ static int bcmnand_ctrl_poll_status(struct brcmnand_controller *ctrl,
} while (get_timer(base) < limit);
#endif /* __UBOOT__ */
+ /*
+ * do a final check after time out in case the CPU was busy and the driver
+ * did not get enough time to perform the polling to avoid false alarms
+ */
+ val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
+ if ((val & mask) == expected_val)
+ return 0;
+
dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
expected_val, val & mask);
--
2.46.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 3/7] mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
2024-09-16 9:58 ` [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller Linus Walleij
2024-09-16 9:58 ` [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time out warning Linus Walleij
@ 2024-09-16 9:58 ` Linus Walleij
2024-09-17 0:22 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 4/7] mtd: rawnand: brcmnand: Fix mtd oobsize Linus Walleij
` (3 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij, Florian Fainelli, Miquel Raynal
From: William Zhang <william.zhang@broadcom.com>
Backport of upstream Linux
commit 5d53244186c9ac58cb88d76a0958ca55b83a15cd
"mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write"
When the oob buffer length is not in multiple of words, the oob write
function does out-of-bounds read on the oob source buffer at the last
iteration. Fix that by always checking length limit on the oob buffer
read and fill with 0xff when reaching the end of the buffer to the oob
registers.
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-5-william.zhang@broadcom.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 46a4107a83a9..60d34bd21f53 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1334,19 +1334,33 @@ static int write_oob_to_regs(struct brcmnand_controller *ctrl, int i,
const u8 *oob, int sas, int sector_1k)
{
int tbytes = sas << sector_1k;
- int j;
+ int j, k = 0;
+ u32 last = 0xffffffff;
+ u8 *plast = (u8 *)&last;
/* Adjust OOB values for 1K sector size */
if (sector_1k && (i & 0x01))
tbytes = max(0, tbytes - (int)ctrl->max_oob);
tbytes = min_t(int, tbytes, ctrl->max_oob);
- for (j = 0; j < tbytes; j += 4)
+ /*
+ * tbytes may not be multiple of words. Make sure we don't read out of
+ * the boundary and stop at last word.
+ */
+ for (j = 0; (j + 3) < tbytes; j += 4)
oob_reg_write(ctrl, j,
(oob[j + 0] << 24) |
(oob[j + 1] << 16) |
(oob[j + 2] << 8) |
(oob[j + 3] << 0));
+
+ /* handle the remaing bytes */
+ while (j < tbytes)
+ plast[k++] = oob[j++];
+
+ if (tbytes & 0x3)
+ oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last));
+
return tbytes;
}
--
2.46.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 4/7] mtd: rawnand: brcmnand: Fix mtd oobsize
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
` (2 preceding siblings ...)
2024-09-16 9:58 ` [PATCH v2 3/7] mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write Linus Walleij
@ 2024-09-16 9:58 ` Linus Walleij
2024-09-17 0:22 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 5/7] mtd: rawnand: brcmnand: Add read data bus interface Linus Walleij
` (2 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij, Miquel Raynal
From: William Zhang <william.zhang@broadcom.com>
Backport from upstream Linux
commit 60177390fa061c62d156f4a546e3efd90df3c183
"mtd: rawnand: brcmnand: Fix mtd oobsize"
brcmnand controller can only access the flash spare area up to certain
bytes based on the ECC level. It can be less than the actual flash spare
area size. For example, for many NAND chip supporting ECC BCH-8, it has
226 bytes spare area. But controller can only uses 218 bytes. So brcmand
driver overrides the mtd oobsize with the controller's accessible spare
area size. When the nand base driver utilizes the nand_device object, it
resets the oobsize back to the actual flash spare aprea size from
nand_memory_organization structure and controller may not able to access
all the oob area as mtd advises.
This change fixes the issue by overriding the oobsize in the
nand_memory_organization structure to the controller's accessible spare
area size.
Fixes: a7ab085d7c16 ("mtd: rawnand: Initialize the nand_device object")
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-6-william.zhang@broadcom.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 60d34bd21f53..552b239b95ae 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -25,6 +25,7 @@
#include <linux/completion.h>
#include <linux/errno.h>
#include <linux/log2.h>
+#include <linux/mtd/nand.h>
#include <linux/mtd/rawnand.h>
#include <asm/processor.h>
#include <dm.h>
@@ -2304,6 +2305,8 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
{
struct mtd_info *mtd = nand_to_mtd(&host->chip);
struct nand_chip *chip = &host->chip;
+ struct nand_device *nanddev = mtd_to_nanddev(mtd);
+ struct nand_memory_organization *memorg = nanddev_get_memorg(nanddev);
struct brcmnand_controller *ctrl = host->ctrl;
struct brcmnand_cfg *cfg = &host->hwcfg;
char msg[128];
@@ -2331,10 +2334,11 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
if (cfg->spare_area_size > ctrl->max_oob)
cfg->spare_area_size = ctrl->max_oob;
/*
- * Set oobsize to be consistent with controller's spare_area_size, as
- * the rest is inaccessible.
+ * Set mtd and memorg oobsize to be consistent with controller's
+ * spare_area_size, as the rest is inaccessible.
*/
mtd->oobsize = cfg->spare_area_size * (mtd->writesize >> FC_SHIFT);
+ memorg->oobsize = mtd->oobsize;
cfg->device_size = mtd->size;
cfg->block_size = mtd->erasesize;
--
2.46.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 5/7] mtd: rawnand: brcmnand: Add read data bus interface
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
` (3 preceding siblings ...)
2024-09-16 9:58 ` [PATCH v2 4/7] mtd: rawnand: brcmnand: Fix mtd oobsize Linus Walleij
@ 2024-09-16 9:58 ` Linus Walleij
2024-09-17 0:22 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 6/7] mtd: rawnand: brcmnand: Support write protection setting from dts Linus Walleij
2024-09-16 9:58 ` [PATCH v2 7/7] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap Linus Walleij
6 siblings, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij
This is a port of the read data bus interface from the Linux
brcmnand driver, commit 546e425991205f59281e160a0d0daed47b7ca9b3
"mtd: rawnand: brcmnand: Add BCMBCA read data bus interface"
This is needed for the BCMBCA RAW NAND driver.
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++++++++---
drivers/mtd/nand/raw/brcmnand/brcmnand.h | 2 ++
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 552b239b95ae..2f786584a1ae 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -769,6 +769,20 @@ static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl,
__raw_writel(val, ctrl->nand_fc + word * 4);
}
+static inline void brcmnand_read_data_bus(struct brcmnand_controller *ctrl,
+ void __iomem *flash_cache, u32 *buffer, int fc_words)
+{
+ struct brcmnand_soc *soc = ctrl->soc;
+ int i;
+
+ if (soc && soc->read_data_bus) {
+ soc->read_data_bus(soc, flash_cache, buffer, fc_words);
+ } else {
+ for (i = 0; i < fc_words; i++)
+ buffer[i] = brcmnand_read_fc(ctrl, i);
+ }
+}
+
static void brcmnand_clear_ecc_addr(struct brcmnand_controller *ctrl)
{
@@ -1812,7 +1826,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
{
struct brcmnand_host *host = nand_get_controller_data(chip);
struct brcmnand_controller *ctrl = host->ctrl;
- int i, j, ret = 0;
+ int i, ret = 0;
brcmnand_clear_ecc_addr(ctrl);
@@ -1825,8 +1839,8 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip,
if (likely(buf)) {
brcmnand_soc_data_bus_prepare(ctrl->soc, false);
- for (j = 0; j < FC_WORDS; j++, buf++)
- *buf = brcmnand_read_fc(ctrl, j);
+ brcmnand_read_data_bus(ctrl, ctrl->nand_fc, buf, FC_WORDS);
+ buf += FC_WORDS;
brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
}
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
index 6946a62b0679..3a1d60471361 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -11,6 +11,8 @@ struct brcmnand_soc {
void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
bool is_param);
+ void (*read_data_bus)(struct brcmnand_soc *soc, void __iomem *flash_cache,
+ u32 *buffer, int fc_words);
void *ctrl;
};
--
2.46.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 6/7] mtd: rawnand: brcmnand: Support write protection setting from dts
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
` (4 preceding siblings ...)
2024-09-16 9:58 ` [PATCH v2 5/7] mtd: rawnand: brcmnand: Add read data bus interface Linus Walleij
@ 2024-09-16 9:58 ` Linus Walleij
2024-09-17 0:26 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 7/7] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap Linus Walleij
6 siblings, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij, Florian Fainelli, Kamal Dasu, David Regan,
Miquel Raynal
From: William Zhang <william.zhang@broadcom.com>
Backport of upstream Linux
commit 8e7daa85641c9559c113f6b217bdc923397de77c
"mtd: rawnand: brcmnand: Support write protection setting from dts"
Augmented to also support the "write-protect" boolean property.
The write protection feature is controlled by the module parameter wp_on
with default set to enabled. But not all the board use this feature
especially in BCMBCA broadband board. And module parameter is not
sufficient as different board can have different option. Add a device
tree property and allow this feature to be configured through the board
dts on per board basis.
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Kamal Dasu <kamal.dasu@broadcom.com>
Reviewed-by: David Regan <dregan@broadcom.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-william.zhang@broadcom.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 2f786584a1ae..071b33951648 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2844,8 +2844,17 @@ int brcmnand_probe(struct udevice *dev, struct brcmnand_soc *soc)
/* Disable XOR addressing */
brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
+ /* Check if the board connects the WP pin */
+#ifndef __UBOOT__
+ if (of_property_read_bool(dn, "brcm,wp-not-connected"))
+#else
+ if (dev_read_bool(ctrl->dev, "brcm,wp-not-connected"))
+#endif /* __UBOOT__ */
+ wp_on = 0;
+
/* Read the write-protect configuration in the device tree */
- wp_on = dev_read_u32_default(dev, "write-protect", wp_on);
+ if (dev_read_bool(ctrl->dev, "write-protect"))
+ wp_on = dev_read_u32_default(dev, "write-protect", wp_on);
if (ctrl->features & BRCMNAND_HAS_WP) {
/* Permanently disable write protection */
--
2.46.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 7/7] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
` (5 preceding siblings ...)
2024-09-16 9:58 ` [PATCH v2 6/7] mtd: rawnand: brcmnand: Support write protection setting from dts Linus Walleij
@ 2024-09-16 9:58 ` Linus Walleij
2024-09-17 0:31 ` William Zhang
6 siblings, 1 reply; 17+ messages in thread
From: Linus Walleij @ 2024-09-16 9:58 UTC (permalink / raw)
To: u-boot, Dario Binacchi, Michael Trimarchi, Anand Gore,
William Zhang, Kursad Oney, Philippe Reynes
Cc: Linus Walleij, David Regan, Miquel Raynal
From: William Zhang <william.zhang@broadcom.com>
Backport from the upstream Linux kernel
commit c2cf7e25eb2a3c915a420fb8ceed8912add7f36c
"mtd: rawnand: brcmnand: Add support for getting ecc setting from strap"
Note: the upstream kernel introduces a new
bool brcmnand_get_sector_size_1k() function because the int
version in U-Boot has been removed in Linux. I kept the old
int-returning version that is already in U-Boot as we depend
on that in other code.
BCMBCA broadband SoC based board design does not specify ecc setting in
dts but rather use the SoC NAND strap info to obtain the ecc strength
and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
this purpose and update driver to support this option. However these two
options can not be used at the same time.
Signed-off-by: William Zhang <william.zhang@broadcom.com>
Reviewed-by: David Regan <dregan@broadcom.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/linux-mtd/20240301173308.226004-1-william.zhang@broadcom.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
drivers/mtd/nand/raw/brcmnand/brcmnand.c | 70 ++++++++++++++++++++++++++++++--
1 file changed, 66 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 071b33951648..749553c9df90 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -980,6 +980,43 @@ static void brcmnand_set_sector_size_1k(struct brcmnand_host *host, int val)
nand_writereg(ctrl, acc_control_offs, tmp);
}
+static int brcmnand_get_spare_size(struct brcmnand_host *host)
+{
+ struct brcmnand_controller *ctrl = host->ctrl;
+ u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+ BRCMNAND_CS_ACC_CONTROL);
+ u32 acc = nand_readreg(ctrl, acc_control_offs);
+
+ return (acc & brcmnand_spare_area_mask(ctrl));
+}
+
+static void brcmnand_get_ecc_settings(struct brcmnand_host *host, struct nand_chip *chip)
+{
+ struct brcmnand_controller *ctrl = host->ctrl;
+ u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
+ BRCMNAND_CS_ACC_CONTROL);
+ bool sector_size_1k = brcmnand_get_sector_size_1k(host);
+ int spare_area_size, ecc_level;
+ u32 acc;
+
+ spare_area_size = brcmnand_get_spare_size(host);
+ acc = nand_readreg(ctrl, acc_control_offs);
+ ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl->ecc_level_shift;
+ if (sector_size_1k)
+ chip->ecc.strength = ecc_level * 2;
+ else if (spare_area_size == 16 && ecc_level == 15)
+ chip->ecc.strength = 1; /* hamming */
+ else
+ chip->ecc.strength = ecc_level;
+
+ if (chip->ecc.size == 0) {
+ if (sector_size_1k)
+ chip->ecc.size = 1024;
+ else
+ chip->ecc.size = 512;
+ }
+}
+
/***********************************************************************
* CS_NAND_SELECT
***********************************************************************/
@@ -2323,12 +2360,33 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
struct nand_memory_organization *memorg = nanddev_get_memorg(nanddev);
struct brcmnand_controller *ctrl = host->ctrl;
struct brcmnand_cfg *cfg = &host->hwcfg;
- char msg[128];
u32 offs, tmp, oob_sector;
+ bool use_strap = false;
+ char msg[128];
int ret;
memset(cfg, 0, sizeof(*cfg));
+#ifndef __UBOOT__
+ use_strap = of_property_read_bool(nand_get_flash_node(chip),
+ "brcm,nand-ecc-use-strap"):
+#else
+ use_strap = ofnode_read_bool(nand_get_flash_node(chip),
+ "brcm,nand-ecc-use-strap");
+#endif /* __UBOOT__ */
+ /*
+ * Either nand-ecc-xxx or brcm,nand-ecc-use-strap can be set. Error out
+ * if both exist.
+ */
+ if (chip->ecc.strength && use_strap) {
+ dev_err(ctrl->dev,
+ "ECC strap and DT ECC configuration properties are mutually exclusive\n");
+ return -EINVAL;
+ }
+
+ if (use_strap)
+ brcmnand_get_ecc_settings(host, chip);
+
#ifndef __UBOOT__
ret = of_property_read_u32(nand_get_flash_node(chip),
"brcm,nand-oob-sector-size",
@@ -2338,10 +2396,14 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
"brcm,nand-oob-sector-size",
&oob_sector);
#endif /* __UBOOT__ */
+
if (ret) {
- /* Use detected size */
- cfg->spare_area_size = mtd->oobsize /
- (mtd->writesize >> FC_SHIFT);
+ if (use_strap)
+ cfg->spare_area_size = brcmnand_get_spare_size(host);
+ else
+ /* Use detected size */
+ cfg->spare_area_size = mtd->oobsize /
+ (mtd->writesize >> FC_SHIFT);
} else {
cfg->spare_area_size = oob_sector;
}
--
2.46.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* RE: [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time out warning
2024-09-16 9:58 ` [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time out warning Linus Walleij
@ 2024-09-17 0:20 ` William Zhang
2024-09-29 17:20 ` Michael Nazzareno Trimarchi
0 siblings, 1 reply; 17+ messages in thread
From: William Zhang @ 2024-09-17 0:20 UTC (permalink / raw)
To: Linus Walleij, u-boot, Dario Binacchi, Michael Trimarchi,
Anand Gore, Kursad Oney, Philippe Reynes
Cc: Florian Fainelli, Miquel Raynal
[-- Attachment #1: Type: text/plain, Size: 2457 bytes --]
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, September 16, 2024 2:59 AM
> To: u-boot@lists.denx.de; Dario Binacchi
> <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> <michael@amarulasolutions.com>; Anand Gore
> <anand.gore@broadcom.com>; William Zhang
> <william.zhang@broadcom.com>; Kursad Oney
> <kursad.oney@broadcom.com>; Philippe Reynes
> <philippe.reynes@softathome.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; Florian Fainelli
> <florian.fainelli@broadcom.com>; Miquel Raynal
> <miquel.raynal@bootlin.com>
> Subject: [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time
> out warning
>
> From: William Zhang <william.zhang@broadcom.com>
>
> Backport from the Linux kernel:
> commit 9cc0a598b944816f2968baf2631757f22721b996
> "mtd: rawnand: brcmnand: Fix potential false time out warning"
>
> If system is busy during the command status polling function, the driver
> may not get the chance to poll the status register till the end of time
> out and return the premature status. Do a final check after time out
> happens to ensure reading the correct status.
>
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-3-
> william.zhang@broadcom.com
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 700d1122639f..46a4107a83a9 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -1011,6 +1011,14 @@ static int bcmnand_ctrl_poll_status(struct
> brcmnand_controller *ctrl,
> } while (get_timer(base) < limit);
> #endif /* __UBOOT__ */
>
> + /*
> + * do a final check after time out in case the CPU was busy and the
> driver
> + * did not get enough time to perform the polling to avoid false
> alarms
> + */
> + val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
> + if ((val & mask) == expected_val)
> + return 0;
> +
> dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
> expected_val, val & mask);
>
>
> --
> 2.46.0
Reviewed-by: William Zhang <william.zhang@broadcom.com>
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4212 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller
2024-09-16 9:58 ` [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller Linus Walleij
@ 2024-09-17 0:21 ` William Zhang
2024-09-29 17:19 ` Michael Nazzareno Trimarchi
1 sibling, 0 replies; 17+ messages in thread
From: William Zhang @ 2024-09-17 0:21 UTC (permalink / raw)
To: Linus Walleij, u-boot, Dario Binacchi, Michael Trimarchi,
Anand Gore, Kursad Oney, Philippe Reynes
Cc: Florian Fainelli, Miquel Raynal
[-- Attachment #1: Type: text/plain, Size: 6328 bytes --]
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, September 16, 2024 2:59 AM
> To: u-boot@lists.denx.de; Dario Binacchi
> <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> <michael@amarulasolutions.com>; Anand Gore
> <anand.gore@broadcom.com>; William Zhang
> <william.zhang@broadcom.com>; Kursad Oney
> <kursad.oney@broadcom.com>; Philippe Reynes
> <philippe.reynes@softathome.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; Florian Fainelli
> <florian.fainelli@broadcom.com>; Miquel Raynal
> <miquel.raynal@bootlin.com>
> Subject: [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field
> setting for v7.2 controller
>
> From: William Zhang <william.zhang@broadcom.com>
>
> Backport from the Linux kernel
> commit 2ec2839a9062db8a592525a3fdabd42dcd9a3a9b
> "mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller"
>
> v7.2 controller has different ECC level field size and shift in the acc
> control register than its predecessor and successor controller. It needs
> to be set specifically.
>
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-2-
> william.zhang@broadcom.com
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 74
> ++++++++++++++++++--------------
> 1 file changed, 41 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index b1af3f717d43..700d1122639f 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -218,6 +218,7 @@ struct brcmnand_controller {
> const unsigned int *page_sizes;
> unsigned int page_size_shift;
> unsigned int max_oob;
> + u32 ecc_level_shift;
> u32 features;
>
> /* for low-power standby/resume only */
> @@ -544,6 +545,34 @@ enum {
> INTFC_CTLR_READY = BIT(31),
> };
>
> +/*********************************************************
> **************
> + * NAND ACC CONTROL bitfield
> + *
> + * Some bits have remained constant throughout hardware revision, while
> + * others have shifted around.
> +
> **********************************************************
> *************/
> +
> +/* Constant for all versions (where supported) */
> +enum {
> + /* See BRCMNAND_HAS_CACHE_MODE */
> + ACC_CONTROL_CACHE_MODE = BIT(22),
> +
> + /* See BRCMNAND_HAS_PREFETCH */
> + ACC_CONTROL_PREFETCH = BIT(23),
> +
> + ACC_CONTROL_PAGE_HIT = BIT(24),
> + ACC_CONTROL_WR_PREEMPT = BIT(25),
> + ACC_CONTROL_PARTIAL_PAGE = BIT(26),
> + ACC_CONTROL_RD_ERASED = BIT(27),
> + ACC_CONTROL_FAST_PGM_RDIN = BIT(28),
> + ACC_CONTROL_WR_ECC = BIT(30),
> + ACC_CONTROL_RD_ECC = BIT(31),
> +};
> +
> +#define ACC_CONTROL_ECC_SHIFT 16
> +/* Only for v7.2 */
> +#define ACC_CONTROL_ECC_EXT_SHIFT 13
> +
> static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32
> offs)
> {
> return brcmnand_readl(ctrl->nand_base + offs);
> @@ -675,6 +704,12 @@ static int brcmnand_revision_init(struct
> brcmnand_controller *ctrl)
> #endif /* __UBOOT__ */
> ctrl->features |= BRCMNAND_HAS_WP;
>
> + /* v7.2 has different ecc level shift in the acc register */
> + if (ctrl->nand_version == 0x0702)
> + ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT;
> + else
> + ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT;
> +
> return 0;
> }
>
> @@ -844,30 +879,6 @@ static inline int brcmnand_cmd_shift(struct
> brcmnand_controller *ctrl)
> return 0;
> }
>
> -
> /**********************************************************
> *************
> - * NAND ACC CONTROL bitfield
> - *
> - * Some bits have remained constant throughout hardware revision, while
> - * others have shifted around.
> -
> **********************************************************
> *************/
> -
> -/* Constant for all versions (where supported) */
> -enum {
> - /* See BRCMNAND_HAS_CACHE_MODE */
> - ACC_CONTROL_CACHE_MODE = BIT(22),
> -
> - /* See BRCMNAND_HAS_PREFETCH */
> - ACC_CONTROL_PREFETCH = BIT(23),
> -
> - ACC_CONTROL_PAGE_HIT = BIT(24),
> - ACC_CONTROL_WR_PREEMPT = BIT(25),
> - ACC_CONTROL_PARTIAL_PAGE = BIT(26),
> - ACC_CONTROL_RD_ERASED = BIT(27),
> - ACC_CONTROL_FAST_PGM_RDIN = BIT(28),
> - ACC_CONTROL_WR_ECC = BIT(30),
> - ACC_CONTROL_RD_ECC = BIT(31),
> -};
> -
> static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller
> *ctrl)
> {
> if (ctrl->nand_version == 0x0702)
> @@ -880,18 +891,15 @@ static inline u32
> brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
> return GENMASK(4, 0);
> }
>
> -#define NAND_ACC_CONTROL_ECC_SHIFT 16
> -#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13
> -
> static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller
> *ctrl)
> {
> u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f;
>
> - mask <<= NAND_ACC_CONTROL_ECC_SHIFT;
> + mask <<= ACC_CONTROL_ECC_SHIFT;
>
> /* v7.2 includes additional ECC levels */
> - if (ctrl->nand_version >= 0x0702)
> - mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT;
> + if (ctrl->nand_version == 0x0702)
> + mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT;
>
> return mask;
> }
> @@ -905,8 +913,8 @@ static void brcmnand_set_ecc_enabled(struct
> brcmnand_host *host, int en)
>
> if (en) {
> acc_control |= ecc_flags; /* enable RD/WR ECC */
> - acc_control |= host->hwcfg.ecc_level
> - << NAND_ACC_CONTROL_ECC_SHIFT;
> + acc_control &= ~brcmnand_ecc_level_mask(ctrl);
> + acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift;
> } else {
> acc_control &= ~ecc_flags; /* disable RD/WR ECC */
> acc_control &= ~brcmnand_ecc_level_mask(ctrl);
> @@ -2225,7 +2233,7 @@ static int brcmnand_set_cfg(struct
> brcmnand_host *host,
> tmp &= ~brcmnand_ecc_level_mask(ctrl);
> tmp &= ~brcmnand_spare_area_mask(ctrl);
> if (ctrl->nand_version >= 0x0302) {
> - tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT;
> + tmp |= cfg->ecc_level << ctrl->ecc_level_shift;
> tmp |= cfg->spare_area_size;
> }
> nand_writereg(ctrl, acc_control_offs, tmp);
>
> --
> 2.46.0
Reviewed-by: William Zhang <william.zhang@broadcom.com>
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4212 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH v2 3/7] mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write
2024-09-16 9:58 ` [PATCH v2 3/7] mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write Linus Walleij
@ 2024-09-17 0:22 ` William Zhang
0 siblings, 0 replies; 17+ messages in thread
From: William Zhang @ 2024-09-17 0:22 UTC (permalink / raw)
To: Linus Walleij, u-boot, Dario Binacchi, Michael Trimarchi,
Anand Gore, Kursad Oney, Philippe Reynes
Cc: Florian Fainelli, Miquel Raynal
[-- Attachment #1: Type: text/plain, Size: 3007 bytes --]
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, September 16, 2024 2:59 AM
> To: u-boot@lists.denx.de; Dario Binacchi
> <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> <michael@amarulasolutions.com>; Anand Gore
> <anand.gore@broadcom.com>; William Zhang
> <william.zhang@broadcom.com>; Kursad Oney
> <kursad.oney@broadcom.com>; Philippe Reynes
> <philippe.reynes@softathome.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; Florian Fainelli
> <florian.fainelli@broadcom.com>; Miquel Raynal
> <miquel.raynal@bootlin.com>
> Subject: [PATCH v2 3/7] mtd: rawnand: brcmnand: Fix potential out-of-
> bounds access in oob write
>
> From: William Zhang <william.zhang@broadcom.com>
>
> Backport of upstream Linux
> commit 5d53244186c9ac58cb88d76a0958ca55b83a15cd
> "mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write"
>
> When the oob buffer length is not in multiple of words, the oob write
> function does out-of-bounds read on the oob source buffer at the last
> iteration. Fix that by always checking length limit on the oob buffer
> read and fill with 0xff when reaching the end of the buffer to the oob
> registers.
>
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-5-
> william.zhang@broadcom.com
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 18 ++++++++++++++++--
> 1 file changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 46a4107a83a9..60d34bd21f53 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -1334,19 +1334,33 @@ static int write_oob_to_regs(struct
> brcmnand_controller *ctrl, int i,
> const u8 *oob, int sas, int sector_1k)
> {
> int tbytes = sas << sector_1k;
> - int j;
> + int j, k = 0;
> + u32 last = 0xffffffff;
> + u8 *plast = (u8 *)&last;
>
> /* Adjust OOB values for 1K sector size */
> if (sector_1k && (i & 0x01))
> tbytes = max(0, tbytes - (int)ctrl->max_oob);
> tbytes = min_t(int, tbytes, ctrl->max_oob);
>
> - for (j = 0; j < tbytes; j += 4)
> + /*
> + * tbytes may not be multiple of words. Make sure we don't read
> out of
> + * the boundary and stop at last word.
> + */
> + for (j = 0; (j + 3) < tbytes; j += 4)
> oob_reg_write(ctrl, j,
> (oob[j + 0] << 24) |
> (oob[j + 1] << 16) |
> (oob[j + 2] << 8) |
> (oob[j + 3] << 0));
> +
> + /* handle the remaing bytes */
> + while (j < tbytes)
> + plast[k++] = oob[j++];
> +
> + if (tbytes & 0x3)
> + oob_reg_write(ctrl, (tbytes & ~0x3), (__force
> u32)cpu_to_be32(last));
> +
> return tbytes;
> }
>
>
> --
> 2.46.0
Reviewed-by: William Zhang <william.zhang@broadcom.com>
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4212 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH v2 4/7] mtd: rawnand: brcmnand: Fix mtd oobsize
2024-09-16 9:58 ` [PATCH v2 4/7] mtd: rawnand: brcmnand: Fix mtd oobsize Linus Walleij
@ 2024-09-17 0:22 ` William Zhang
0 siblings, 0 replies; 17+ messages in thread
From: William Zhang @ 2024-09-17 0:22 UTC (permalink / raw)
To: Linus Walleij, u-boot, Dario Binacchi, Michael Trimarchi,
Anand Gore, Kursad Oney, Philippe Reynes
Cc: Miquel Raynal
[-- Attachment #1: Type: text/plain, Size: 3588 bytes --]
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, September 16, 2024 2:59 AM
> To: u-boot@lists.denx.de; Dario Binacchi
> <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> <michael@amarulasolutions.com>; Anand Gore
> <anand.gore@broadcom.com>; William Zhang
> <william.zhang@broadcom.com>; Kursad Oney
> <kursad.oney@broadcom.com>; Philippe Reynes
> <philippe.reynes@softathome.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; Miquel Raynal
> <miquel.raynal@bootlin.com>
> Subject: [PATCH v2 4/7] mtd: rawnand: brcmnand: Fix mtd oobsize
>
> From: William Zhang <william.zhang@broadcom.com>
>
> Backport from upstream Linux
> commit 60177390fa061c62d156f4a546e3efd90df3c183
> "mtd: rawnand: brcmnand: Fix mtd oobsize"
>
> brcmnand controller can only access the flash spare area up to certain
> bytes based on the ECC level. It can be less than the actual flash spare
> area size. For example, for many NAND chip supporting ECC BCH-8, it has
> 226 bytes spare area. But controller can only uses 218 bytes. So brcmand
> driver overrides the mtd oobsize with the controller's accessible spare
> area size. When the nand base driver utilizes the nand_device object, it
> resets the oobsize back to the actual flash spare aprea size from
> nand_memory_organization structure and controller may not able to
> access
> all the oob area as mtd advises.
>
> This change fixes the issue by overriding the oobsize in the
> nand_memory_organization structure to the controller's accessible spare
> area size.
>
> Fixes: a7ab085d7c16 ("mtd: rawnand: Initialize the nand_device object")
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-6-
> william.zhang@broadcom.com
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 60d34bd21f53..552b239b95ae 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -25,6 +25,7 @@
> #include <linux/completion.h>
> #include <linux/errno.h>
> #include <linux/log2.h>
> +#include <linux/mtd/nand.h>
> #include <linux/mtd/rawnand.h>
> #include <asm/processor.h>
> #include <dm.h>
> @@ -2304,6 +2305,8 @@ static int brcmnand_setup_dev(struct
> brcmnand_host *host)
> {
> struct mtd_info *mtd = nand_to_mtd(&host->chip);
> struct nand_chip *chip = &host->chip;
> + struct nand_device *nanddev = mtd_to_nanddev(mtd);
> + struct nand_memory_organization *memorg =
> nanddev_get_memorg(nanddev);
> struct brcmnand_controller *ctrl = host->ctrl;
> struct brcmnand_cfg *cfg = &host->hwcfg;
> char msg[128];
> @@ -2331,10 +2334,11 @@ static int brcmnand_setup_dev(struct
> brcmnand_host *host)
> if (cfg->spare_area_size > ctrl->max_oob)
> cfg->spare_area_size = ctrl->max_oob;
> /*
> - * Set oobsize to be consistent with controller's spare_area_size, as
> - * the rest is inaccessible.
> + * Set mtd and memorg oobsize to be consistent with controller's
> + * spare_area_size, as the rest is inaccessible.
> */
> mtd->oobsize = cfg->spare_area_size * (mtd->writesize >>
> FC_SHIFT);
> + memorg->oobsize = mtd->oobsize;
>
> cfg->device_size = mtd->size;
> cfg->block_size = mtd->erasesize;
>
> --
> 2.46.0
Reviewed-by: William Zhang <william.zhang@broadcom.com>
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4212 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH v2 5/7] mtd: rawnand: brcmnand: Add read data bus interface
2024-09-16 9:58 ` [PATCH v2 5/7] mtd: rawnand: brcmnand: Add read data bus interface Linus Walleij
@ 2024-09-17 0:22 ` William Zhang
0 siblings, 0 replies; 17+ messages in thread
From: William Zhang @ 2024-09-17 0:22 UTC (permalink / raw)
To: Linus Walleij, u-boot, Dario Binacchi, Michael Trimarchi,
Anand Gore, Kursad Oney, Philippe Reynes
[-- Attachment #1: Type: text/plain, Size: 3401 bytes --]
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, September 16, 2024 2:59 AM
> To: u-boot@lists.denx.de; Dario Binacchi
> <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> <michael@amarulasolutions.com>; Anand Gore
> <anand.gore@broadcom.com>; William Zhang
> <william.zhang@broadcom.com>; Kursad Oney
> <kursad.oney@broadcom.com>; Philippe Reynes
> <philippe.reynes@softathome.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>
> Subject: [PATCH v2 5/7] mtd: rawnand: brcmnand: Add read data bus
> interface
>
> This is a port of the read data bus interface from the Linux
> brcmnand driver, commit
> 546e425991205f59281e160a0d0daed47b7ca9b3
> "mtd: rawnand: brcmnand: Add BCMBCA read data bus interface"
>
> This is needed for the BCMBCA RAW NAND driver.
>
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++++++++-
> --
> drivers/mtd/nand/raw/brcmnand/brcmnand.h | 2 ++
> 2 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 552b239b95ae..2f786584a1ae 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -769,6 +769,20 @@ static inline void brcmnand_write_fc(struct
> brcmnand_controller *ctrl,
> __raw_writel(val, ctrl->nand_fc + word * 4);
> }
>
> +static inline void brcmnand_read_data_bus(struct brcmnand_controller
> *ctrl,
> + void __iomem *flash_cache, u32
> *buffer, int fc_words)
> +{
> + struct brcmnand_soc *soc = ctrl->soc;
> + int i;
> +
> + if (soc && soc->read_data_bus) {
> + soc->read_data_bus(soc, flash_cache, buffer, fc_words);
> + } else {
> + for (i = 0; i < fc_words; i++)
> + buffer[i] = brcmnand_read_fc(ctrl, i);
> + }
> +}
> +
> static void brcmnand_clear_ecc_addr(struct brcmnand_controller *ctrl)
> {
>
> @@ -1812,7 +1826,7 @@ static int brcmnand_read_by_pio(struct
> mtd_info *mtd, struct nand_chip *chip,
> {
> struct brcmnand_host *host = nand_get_controller_data(chip);
> struct brcmnand_controller *ctrl = host->ctrl;
> - int i, j, ret = 0;
> + int i, ret = 0;
>
> brcmnand_clear_ecc_addr(ctrl);
>
> @@ -1825,8 +1839,8 @@ static int brcmnand_read_by_pio(struct
> mtd_info *mtd, struct nand_chip *chip,
> if (likely(buf)) {
> brcmnand_soc_data_bus_prepare(ctrl->soc, false);
>
> - for (j = 0; j < FC_WORDS; j++, buf++)
> - *buf = brcmnand_read_fc(ctrl, j);
> + brcmnand_read_data_bus(ctrl, ctrl->nand_fc, buf,
> FC_WORDS);
> + buf += FC_WORDS;
>
> brcmnand_soc_data_bus_unprepare(ctrl->soc, false);
> }
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
> index 6946a62b0679..3a1d60471361 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
> @@ -11,6 +11,8 @@ struct brcmnand_soc {
> void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
> void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
> bool is_param);
> + void (*read_data_bus)(struct brcmnand_soc *soc, void __iomem
> *flash_cache,
> + u32 *buffer, int fc_words);
> void *ctrl;
> };
>
>
> --
> 2.46.0
Reviewed-by: William Zhang <william.zhang@broadcom.com>
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4212 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH v2 6/7] mtd: rawnand: brcmnand: Support write protection setting from dts
2024-09-16 9:58 ` [PATCH v2 6/7] mtd: rawnand: brcmnand: Support write protection setting from dts Linus Walleij
@ 2024-09-17 0:26 ` William Zhang
0 siblings, 0 replies; 17+ messages in thread
From: William Zhang @ 2024-09-17 0:26 UTC (permalink / raw)
To: Linus Walleij, u-boot, Dario Binacchi, Michael Trimarchi,
Anand Gore, Kursad Oney, Philippe Reynes
Cc: Florian Fainelli, Kamal Dasu, David Regan, Miquel Raynal
[-- Attachment #1: Type: text/plain, Size: 3167 bytes --]
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, September 16, 2024 2:59 AM
> To: u-boot@lists.denx.de; Dario Binacchi
> <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> <michael@amarulasolutions.com>; Anand Gore
> <anand.gore@broadcom.com>; William Zhang
> <william.zhang@broadcom.com>; Kursad Oney
> <kursad.oney@broadcom.com>; Philippe Reynes
> <philippe.reynes@softathome.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; Florian Fainelli
> <florian.fainelli@broadcom.com>; Kamal Dasu
> <kamal.dasu@broadcom.com>; David Regan <dregan@broadcom.com>;
> Miquel Raynal <miquel.raynal@bootlin.com>
> Subject: [PATCH v2 6/7] mtd: rawnand: brcmnand: Support write
> protection setting from dts
>
> From: William Zhang <william.zhang@broadcom.com>
>
> Backport of upstream Linux
> commit 8e7daa85641c9559c113f6b217bdc923397de77c
> "mtd: rawnand: brcmnand: Support write protection setting from dts"
>
> Augmented to also support the "write-protect" boolean property.
>
> The write protection feature is controlled by the module parameter wp_on
> with default set to enabled. But not all the board use this feature
> especially in BCMBCA broadband board. And module parameter is not
> sufficient as different board can have different option. Add a device
> tree property and allow this feature to be configured through the board
> dts on per board basis.
>
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> Reviewed-by: Kamal Dasu <kamal.dasu@broadcom.com>
> Reviewed-by: David Regan <dregan@broadcom.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Link: https://lore.kernel.org/linux-mtd/20240223034758.13753-14-
> william.zhang@broadcom.com
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 2f786584a1ae..071b33951648 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -2844,8 +2844,17 @@ int brcmnand_probe(struct udevice *dev,
> struct brcmnand_soc *soc)
> /* Disable XOR addressing */
> brcmnand_rmw_reg(ctrl, BRCMNAND_CS_XOR, 0xff, 0, 0);
>
> + /* Check if the board connects the WP pin */
> +#ifndef __UBOOT__
> + if (of_property_read_bool(dn, "brcm,wp-not-connected"))
> +#else
> + if (dev_read_bool(ctrl->dev, "brcm,wp-not-connected"))
> +#endif /* __UBOOT__ */
> + wp_on = 0;
> +
> /* Read the write-protect configuration in the device tree */
> - wp_on = dev_read_u32_default(dev, "write-protect", wp_on);
> + if (dev_read_bool(ctrl->dev, "write-protect"))
write-protect is a u32 property. Should use dev_read_u32 and check return
code to see if the property exist or not.
> + wp_on = dev_read_u32_default(dev, "write-protect", wp_on);
>
> if (ctrl->features & BRCMNAND_HAS_WP) {
> /* Permanently disable write protection */
>
> --
> 2.46.0
Reviewed-by: William Zhang <william.zhang@broadcom.com>
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4212 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* RE: [PATCH v2 7/7] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap
2024-09-16 9:58 ` [PATCH v2 7/7] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap Linus Walleij
@ 2024-09-17 0:31 ` William Zhang
0 siblings, 0 replies; 17+ messages in thread
From: William Zhang @ 2024-09-17 0:31 UTC (permalink / raw)
To: Linus Walleij, u-boot, Dario Binacchi, Michael Trimarchi,
Anand Gore, Kursad Oney, Philippe Reynes
Cc: David Regan, Miquel Raynal
[-- Attachment #1: Type: text/plain, Size: 5604 bytes --]
> -----Original Message-----
> From: Linus Walleij <linus.walleij@linaro.org>
> Sent: Monday, September 16, 2024 2:59 AM
> To: u-boot@lists.denx.de; Dario Binacchi
> <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> <michael@amarulasolutions.com>; Anand Gore
> <anand.gore@broadcom.com>; William Zhang
> <william.zhang@broadcom.com>; Kursad Oney
> <kursad.oney@broadcom.com>; Philippe Reynes
> <philippe.reynes@softathome.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>; David Regan
> <dregan@broadcom.com>; Miquel Raynal <miquel.raynal@bootlin.com>
> Subject: [PATCH v2 7/7] mtd: rawnand: brcmnand: Add support for getting
> ecc setting from strap
>
> From: William Zhang <william.zhang@broadcom.com>
>
> Backport from the upstream Linux kernel
> commit c2cf7e25eb2a3c915a420fb8ceed8912add7f36c
> "mtd: rawnand: brcmnand: Add support for getting ecc setting from strap"
>
> Note: the upstream kernel introduces a new
> bool brcmnand_get_sector_size_1k() function because the int
> version in U-Boot has been removed in Linux. I kept the old
> int-returning version that is already in U-Boot as we depend
> on that in other code.
>
> BCMBCA broadband SoC based board design does not specify ecc setting in
> dts but rather use the SoC NAND strap info to obtain the ecc strength
> and spare area size setting. Add brcm,nand-ecc-use-strap dts propety for
> this purpose and update driver to support this option. However these two
> options can not be used at the same time.
>
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Reviewed-by: David Regan <dregan@broadcom.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Link: https://lore.kernel.org/linux-mtd/20240301173308.226004-1-
> william.zhang@broadcom.com
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 70
> ++++++++++++++++++++++++++++++--
> 1 file changed, 66 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 071b33951648..749553c9df90 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -980,6 +980,43 @@ static void brcmnand_set_sector_size_1k(struct
> brcmnand_host *host, int val)
> nand_writereg(ctrl, acc_control_offs, tmp);
> }
>
> +static int brcmnand_get_spare_size(struct brcmnand_host *host)
> +{
> + struct brcmnand_controller *ctrl = host->ctrl;
> + u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +
> BRCMNAND_CS_ACC_CONTROL);
> + u32 acc = nand_readreg(ctrl, acc_control_offs);
> +
> + return (acc & brcmnand_spare_area_mask(ctrl));
> +}
> +
> +static void brcmnand_get_ecc_settings(struct brcmnand_host *host,
> struct nand_chip *chip)
> +{
> + struct brcmnand_controller *ctrl = host->ctrl;
> + u16 acc_control_offs = brcmnand_cs_offset(ctrl, host->cs,
> +
> BRCMNAND_CS_ACC_CONTROL);
> + bool sector_size_1k = brcmnand_get_sector_size_1k(host);
> + int spare_area_size, ecc_level;
> + u32 acc;
> +
> + spare_area_size = brcmnand_get_spare_size(host);
> + acc = nand_readreg(ctrl, acc_control_offs);
> + ecc_level = (acc & brcmnand_ecc_level_mask(ctrl)) >> ctrl-
> >ecc_level_shift;
> + if (sector_size_1k)
> + chip->ecc.strength = ecc_level * 2;
> + else if (spare_area_size == 16 && ecc_level == 15)
> + chip->ecc.strength = 1; /* hamming */
> + else
> + chip->ecc.strength = ecc_level;
> +
> + if (chip->ecc.size == 0) {
> + if (sector_size_1k)
> + chip->ecc.size = 1024;
> + else
> + chip->ecc.size = 512;
> + }
> +}
> +
>
> /**********************************************************
> *************
> * CS_NAND_SELECT
>
> **********************************************************
> *************/
> @@ -2323,12 +2360,33 @@ static int brcmnand_setup_dev(struct
> brcmnand_host *host)
> struct nand_memory_organization *memorg =
> nanddev_get_memorg(nanddev);
> struct brcmnand_controller *ctrl = host->ctrl;
> struct brcmnand_cfg *cfg = &host->hwcfg;
> - char msg[128];
> u32 offs, tmp, oob_sector;
> + bool use_strap = false;
> + char msg[128];
> int ret;
>
> memset(cfg, 0, sizeof(*cfg));
>
> +#ifndef __UBOOT__
> + use_strap = of_property_read_bool(nand_get_flash_node(chip),
> + "brcm,nand-ecc-use-strap"):
> +#else
> + use_strap = ofnode_read_bool(nand_get_flash_node(chip),
> + "brcm,nand-ecc-use-strap");
> +#endif /* __UBOOT__ */
> + /*
> + * Either nand-ecc-xxx or brcm,nand-ecc-use-strap can be set. Error
> out
> + * if both exist.
> + */
> + if (chip->ecc.strength && use_strap) {
> + dev_err(ctrl->dev,
> + "ECC strap and DT ECC configuration properties are
> mutually exclusive\n");
> + return -EINVAL;
> + }
> +
> + if (use_strap)
> + brcmnand_get_ecc_settings(host, chip);
> +
> #ifndef __UBOOT__
> ret = of_property_read_u32(nand_get_flash_node(chip),
> "brcm,nand-oob-sector-size",
> @@ -2338,10 +2396,14 @@ static int brcmnand_setup_dev(struct
> brcmnand_host *host)
> "brcm,nand-oob-sector-size",
> &oob_sector);
> #endif /* __UBOOT__ */
> +
> if (ret) {
> - /* Use detected size */
> - cfg->spare_area_size = mtd->oobsize /
> - (mtd->writesize >> FC_SHIFT);
> + if (use_strap)
> + cfg->spare_area_size =
> brcmnand_get_spare_size(host);
> + else
> + /* Use detected size */
> + cfg->spare_area_size = mtd->oobsize /
> + (mtd->writesize >> FC_SHIFT);
> } else {
> cfg->spare_area_size = oob_sector;
> }
>
> --
> 2.46.0
Reviewed-by: William Zhang <william.zhang@broadcom.com>
Tested-by: William Zhang <william.zhang@broadcom.com>
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4212 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller
2024-09-16 9:58 ` [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller Linus Walleij
2024-09-17 0:21 ` William Zhang
@ 2024-09-29 17:19 ` Michael Nazzareno Trimarchi
1 sibling, 0 replies; 17+ messages in thread
From: Michael Nazzareno Trimarchi @ 2024-09-29 17:19 UTC (permalink / raw)
To: Linus Walleij
Cc: u-boot, Dario Binacchi, Anand Gore, William Zhang, Kursad Oney,
Philippe Reynes, Florian Fainelli, Miquel Raynal
On Mon, Sep 16, 2024 at 11:58 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> From: William Zhang <william.zhang@broadcom.com>
>
> Backport from the Linux kernel
> commit 2ec2839a9062db8a592525a3fdabd42dcd9a3a9b
> "mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller"
>
> v7.2 controller has different ECC level field size and shift in the acc
> control register than its predecessor and successor controller. It needs
> to be set specifically.
>
> Signed-off-by: William Zhang <william.zhang@broadcom.com>
> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-2-william.zhang@broadcom.com
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> drivers/mtd/nand/raw/brcmnand/brcmnand.c | 74 ++++++++++++++++++--------------
> 1 file changed, 41 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index b1af3f717d43..700d1122639f 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -218,6 +218,7 @@ struct brcmnand_controller {
> const unsigned int *page_sizes;
> unsigned int page_size_shift;
> unsigned int max_oob;
> + u32 ecc_level_shift;
> u32 features;
>
> /* for low-power standby/resume only */
> @@ -544,6 +545,34 @@ enum {
> INTFC_CTLR_READY = BIT(31),
> };
>
> +/***********************************************************************
> + * NAND ACC CONTROL bitfield
> + *
> + * Some bits have remained constant throughout hardware revision, while
> + * others have shifted around.
> + ***********************************************************************/
> +
> +/* Constant for all versions (where supported) */
> +enum {
> + /* See BRCMNAND_HAS_CACHE_MODE */
> + ACC_CONTROL_CACHE_MODE = BIT(22),
> +
> + /* See BRCMNAND_HAS_PREFETCH */
> + ACC_CONTROL_PREFETCH = BIT(23),
> +
> + ACC_CONTROL_PAGE_HIT = BIT(24),
> + ACC_CONTROL_WR_PREEMPT = BIT(25),
> + ACC_CONTROL_PARTIAL_PAGE = BIT(26),
> + ACC_CONTROL_RD_ERASED = BIT(27),
> + ACC_CONTROL_FAST_PGM_RDIN = BIT(28),
> + ACC_CONTROL_WR_ECC = BIT(30),
> + ACC_CONTROL_RD_ECC = BIT(31),
> +};
> +
> +#define ACC_CONTROL_ECC_SHIFT 16
> +/* Only for v7.2 */
> +#define ACC_CONTROL_ECC_EXT_SHIFT 13
> +
> static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)
> {
> return brcmnand_readl(ctrl->nand_base + offs);
> @@ -675,6 +704,12 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
> #endif /* __UBOOT__ */
> ctrl->features |= BRCMNAND_HAS_WP;
>
> + /* v7.2 has different ecc level shift in the acc register */
> + if (ctrl->nand_version == 0x0702)
> + ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT;
> + else
> + ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT;
> +
> return 0;
> }
>
> @@ -844,30 +879,6 @@ static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl)
> return 0;
> }
>
> -/***********************************************************************
> - * NAND ACC CONTROL bitfield
> - *
> - * Some bits have remained constant throughout hardware revision, while
> - * others have shifted around.
> - ***********************************************************************/
> -
> -/* Constant for all versions (where supported) */
> -enum {
> - /* See BRCMNAND_HAS_CACHE_MODE */
> - ACC_CONTROL_CACHE_MODE = BIT(22),
> -
> - /* See BRCMNAND_HAS_PREFETCH */
> - ACC_CONTROL_PREFETCH = BIT(23),
> -
> - ACC_CONTROL_PAGE_HIT = BIT(24),
> - ACC_CONTROL_WR_PREEMPT = BIT(25),
> - ACC_CONTROL_PARTIAL_PAGE = BIT(26),
> - ACC_CONTROL_RD_ERASED = BIT(27),
> - ACC_CONTROL_FAST_PGM_RDIN = BIT(28),
> - ACC_CONTROL_WR_ECC = BIT(30),
> - ACC_CONTROL_RD_ECC = BIT(31),
> -};
> -
> static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
> {
> if (ctrl->nand_version == 0x0702)
> @@ -880,18 +891,15 @@ static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
> return GENMASK(4, 0);
> }
>
> -#define NAND_ACC_CONTROL_ECC_SHIFT 16
> -#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13
> -
> static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl)
> {
> u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f;
>
> - mask <<= NAND_ACC_CONTROL_ECC_SHIFT;
> + mask <<= ACC_CONTROL_ECC_SHIFT;
>
> /* v7.2 includes additional ECC levels */
> - if (ctrl->nand_version >= 0x0702)
> - mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT;
> + if (ctrl->nand_version == 0x0702)
> + mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT;
>
> return mask;
> }
> @@ -905,8 +913,8 @@ static void brcmnand_set_ecc_enabled(struct brcmnand_host *host, int en)
>
> if (en) {
> acc_control |= ecc_flags; /* enable RD/WR ECC */
> - acc_control |= host->hwcfg.ecc_level
> - << NAND_ACC_CONTROL_ECC_SHIFT;
> + acc_control &= ~brcmnand_ecc_level_mask(ctrl);
> + acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift;
> } else {
> acc_control &= ~ecc_flags; /* disable RD/WR ECC */
> acc_control &= ~brcmnand_ecc_level_mask(ctrl);
> @@ -2225,7 +2233,7 @@ static int brcmnand_set_cfg(struct brcmnand_host *host,
> tmp &= ~brcmnand_ecc_level_mask(ctrl);
> tmp &= ~brcmnand_spare_area_mask(ctrl);
> if (ctrl->nand_version >= 0x0302) {
> - tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT;
> + tmp |= cfg->ecc_level << ctrl->ecc_level_shift;
> tmp |= cfg->spare_area_size;
> }
> nand_writereg(ctrl, acc_control_offs, tmp);
>
> --
> 2.46.0
>
Acked-by; Michael Trimarchi <michael@amarulasolutions.com>
--
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
michael@amarulasolutions.com
__________________________________
Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
info@amarulasolutions.com
www.amarulasolutions.com
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time out warning
2024-09-17 0:20 ` William Zhang
@ 2024-09-29 17:20 ` Michael Nazzareno Trimarchi
0 siblings, 0 replies; 17+ messages in thread
From: Michael Nazzareno Trimarchi @ 2024-09-29 17:20 UTC (permalink / raw)
To: William Zhang
Cc: Linus Walleij, u-boot, Dario Binacchi, Anand Gore, Kursad Oney,
Philippe Reynes, Florian Fainelli, Miquel Raynal
All, Dario
On Tue, Sep 17, 2024 at 2:20 AM William Zhang
<william.zhang@broadcom.com> wrote:
>
> > -----Original Message-----
> > From: Linus Walleij <linus.walleij@linaro.org>
> > Sent: Monday, September 16, 2024 2:59 AM
> > To: u-boot@lists.denx.de; Dario Binacchi
> > <dario.binacchi@amarulasolutions.com>; Michael Trimarchi
> > <michael@amarulasolutions.com>; Anand Gore
> > <anand.gore@broadcom.com>; William Zhang
> > <william.zhang@broadcom.com>; Kursad Oney
> > <kursad.oney@broadcom.com>; Philippe Reynes
> > <philippe.reynes@softathome.com>
> > Cc: Linus Walleij <linus.walleij@linaro.org>; Florian Fainelli
> > <florian.fainelli@broadcom.com>; Miquel Raynal
> > <miquel.raynal@bootlin.com>
> > Subject: [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time
> > out warning
> >
> > From: William Zhang <william.zhang@broadcom.com>
> >
> > Backport from the Linux kernel:
> > commit 9cc0a598b944816f2968baf2631757f22721b996
> > "mtd: rawnand: brcmnand: Fix potential false time out warning"
> >
> > If system is busy during the command status polling function, the driver
> > may not get the chance to poll the status register till the end of time
> > out and return the premature status. Do a final check after time out
> > happens to ensure reading the correct status.
> >
> > Signed-off-by: William Zhang <william.zhang@broadcom.com>
> > Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> > Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
> > Link: https://lore.kernel.org/linux-mtd/20230706182909.79151-3-
> > william.zhang@broadcom.com
> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> > ---
> > drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++++++
> > 1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> > b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> > index 700d1122639f..46a4107a83a9 100644
> > --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> > +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> > @@ -1011,6 +1011,14 @@ static int bcmnand_ctrl_poll_status(struct
> > brcmnand_controller *ctrl,
> > } while (get_timer(base) < limit);
> > #endif /* __UBOOT__ */
> >
> > + /*
> > + * do a final check after time out in case the CPU was busy and the
> > driver
> > + * did not get enough time to perform the polling to avoid false
> > alarms
> > + */
> > + val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS);
> > + if ((val & mask) == expected_val)
> > + return 0;
> > +
> > dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n",
> > expected_val, val & mask);
> >
> >
> > --
> > 2.46.0
>
> Reviewed-by: William Zhang <william.zhang@broadcom.com>
Acked-by; Michael Trimarchi <michael@amarulasolutions.com>
--
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
michael@amarulasolutions.com
__________________________________
Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
info@amarulasolutions.com
www.amarulasolutions.com
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2024-09-29 17:20 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-16 9:58 [PATCH v2 0/7] mtd: nand: brcmnand: Backported fixes from Linux Linus Walleij
2024-09-16 9:58 ` [PATCH v2 1/7] mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller Linus Walleij
2024-09-17 0:21 ` William Zhang
2024-09-29 17:19 ` Michael Nazzareno Trimarchi
2024-09-16 9:58 ` [PATCH v2 2/7] mtd: rawnand: brcmnand: Fix potential false time out warning Linus Walleij
2024-09-17 0:20 ` William Zhang
2024-09-29 17:20 ` Michael Nazzareno Trimarchi
2024-09-16 9:58 ` [PATCH v2 3/7] mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write Linus Walleij
2024-09-17 0:22 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 4/7] mtd: rawnand: brcmnand: Fix mtd oobsize Linus Walleij
2024-09-17 0:22 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 5/7] mtd: rawnand: brcmnand: Add read data bus interface Linus Walleij
2024-09-17 0:22 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 6/7] mtd: rawnand: brcmnand: Support write protection setting from dts Linus Walleij
2024-09-17 0:26 ` William Zhang
2024-09-16 9:58 ` [PATCH v2 7/7] mtd: rawnand: brcmnand: Add support for getting ecc setting from strap Linus Walleij
2024-09-17 0:31 ` William Zhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox