2024-05-07 23:59:19

by Arseniy Krasnov

[permalink] [raw]
Subject: [PATCH v6 0/3] Meson: R/W support for pages used by boot ROM

Amlogic's boot ROM code needs that some pages on NAND must be written
in special "short" ECC mode with scrambling enabled. Such pages:
1) Contain some metadata about hardware.
2) Located with some interval starting from 0 offset, until some
specified offset. Interval and second offset are set in the
device tree.

This patchset adds R/W support for such pages. To enable it we can setup
it in dts:

nand-is-boot-medium;
amlogic,boot-pages = <1024>;
amlogic,boot-page-step = <128>;

It means that each 128th page in range 0 to 1024 pages will be accessed
in special mode ("short" ECC + scrambling). In practice this feature is
needed when we want to update first block of NAND - driver will enable
required mode by itself using value from device tree.

Changelog:
v1 -> v2:
* Rename 'meson,boot-page-XXX' -> 'amlogic,boot-page-XXX'.
* Add words that 'amlogic,boot-page-step' is measured in pages.
* Remove words that 'amlogic,boot-page-XXX' depends on 'nand-is-boot-medium'.
* Make both 'amlogic,boot-page-XXX' depend on each other also, in
addition to 'nand-is-boot-medium' dependency.
v2 -> v3:
* Add quotes to 0001 in dependencies. This fixes 'make dt_binding_check'
warning.
v3 -> v4:
* Rename 'amlogic,boot-page-last' to 'amlogic,boot-pages'.
v4 -> v5:
* Update 'description' fields in bindings.
v5 -> v6:
* Split patch for meson_nand.c to 2 patches: first is refactoring of
scrambling mode handling, another is support for special pages for
boot ROM.
* Update description and commit message in the bindings patch.

Arseniy Krasnov (3):
dt-bindings: mtd: amlogic,meson-nand: support fields for boot ROM code
mtd: rawnand: meson: refactor use of 'meson_nfc_cmd_access()'
mtd: rawnand: meson: read/write access for boot ROM pages

.../bindings/mtd/amlogic,meson-nand.yaml | 18 ++++
drivers/mtd/nand/raw/meson_nand.c | 86 +++++++++++++------
2 files changed, 77 insertions(+), 27 deletions(-)

--
2.35.0



2024-05-07 23:59:36

by Arseniy Krasnov

[permalink] [raw]
Subject: [PATCH v6 2/3] mtd: rawnand: meson: refactor use of 'meson_nfc_cmd_access()'

Move call 'meson_nfc_cmd_seed()' and check for 'NAND_NEED_SCRAMBLING'
to 'meson_nfc_cmd_access()', thus removing code duplication.

Signed-off-by: Arseniy Krasnov <[email protected]>
---
drivers/mtd/nand/raw/meson_nand.c | 30 ++++++++++++------------------
1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index 00ce0e5bb970..39f50cbd4ab9 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -298,14 +298,19 @@ static void meson_nfc_cmd_seed(struct meson_nfc *nfc, u32 seed)
nfc->reg_base + NFC_REG_CMD);
}

-static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
- int scrambler)
+static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir, int page)
{
struct mtd_info *mtd = nand_to_mtd(nand);
struct meson_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
u32 bch = meson_chip->bch_mode, cmd;
int len = mtd->writesize, pagesize, pages;
+ int scrambler;
+
+ if (nand->options & NAND_NEED_SCRAMBLING)
+ scrambler = NFC_CMD_SCRAMBLER_ENABLE;
+ else
+ scrambler = NFC_CMD_SCRAMBLER_DISABLE;

pagesize = nand->ecc.size;

@@ -321,6 +326,9 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
cmd = CMDRWGEN(DMA_DIR(dir), scrambler, bch,
NFC_CMD_SHORTMODE_DISABLE, pagesize, pages);

+ if (scrambler == NFC_CMD_SCRAMBLER_ENABLE)
+ meson_nfc_cmd_seed(nfc, page);
+
writel(cmd, nfc->reg_base + NFC_REG_CMD);
}

@@ -743,14 +751,7 @@ static int meson_nfc_write_page_sub(struct nand_chip *nand,
if (ret)
return ret;

- if (nand->options & NAND_NEED_SCRAMBLING) {
- meson_nfc_cmd_seed(nfc, page);
- meson_nfc_cmd_access(nand, raw, DIRWRITE,
- NFC_CMD_SCRAMBLER_ENABLE);
- } else {
- meson_nfc_cmd_access(nand, raw, DIRWRITE,
- NFC_CMD_SCRAMBLER_DISABLE);
- }
+ meson_nfc_cmd_access(nand, raw, DIRWRITE, page);

cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG;
writel(cmd, nfc->reg_base + NFC_REG_CMD);
@@ -829,14 +830,7 @@ static int meson_nfc_read_page_sub(struct nand_chip *nand,
if (ret)
return ret;

- if (nand->options & NAND_NEED_SCRAMBLING) {
- meson_nfc_cmd_seed(nfc, page);
- meson_nfc_cmd_access(nand, raw, DIRREAD,
- NFC_CMD_SCRAMBLER_ENABLE);
- } else {
- meson_nfc_cmd_access(nand, raw, DIRREAD,
- NFC_CMD_SCRAMBLER_DISABLE);
- }
+ meson_nfc_cmd_access(nand, raw, DIRREAD, page);

ret = meson_nfc_wait_dma_finish(nfc);
meson_nfc_check_ecc_pages_valid(nfc, nand, raw);
--
2.35.0


2024-05-07 23:59:54

by Arseniy Krasnov

[permalink] [raw]
Subject: [PATCH v6 1/3] dt-bindings: mtd: amlogic,meson-nand: support fields for boot ROM code

Boot ROM code on Meson requires that some pages on NAND must be written
in special mode: "short" ECC mode where each block is 384 bytes and
scrambling mode is on. Such pages are located on the chip in the
following way (for example):

[ p0 ][ p1 ][ p2 ][ p3 ][ p4 ][ p5 ][ p6 ][ p7 ] ... [ pN ]
^ ^ ^ ^

pX is page number "X". "^" means "special" page used by boot ROM - e.g.
every 2nd page in the range of [0, 7]. Step (2 in example is set by
'amlogic,boot-page-step' field. Last page in range (7 in example) is
set by 'amlogic,boot-pages' field.

Signed-off-by: Arseniy Krasnov <[email protected]>
---
.../bindings/mtd/amlogic,meson-nand.yaml | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
index 57b6957c8415..284f0f882c32 100644
--- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
@@ -64,11 +64,29 @@ patternProperties:
items:
maximum: 0

+ amlogic,boot-pages:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Number of pages starting from offset 0, where a special ECC
+ configuration must be used because it is accessed by the ROM
+ code. This ECC configuration uses 384 bytes data blocks.
+ Also scrambling mode is enabled for such pages.
+
+ amlogic,boot-page-step:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Interval between pages, accessed by the ROM code. For example
+ we have 8 pages [0, 7]. Pages 0,2,4,6 are accessed by the
+ ROM code, so this field will be 2 (e.g. every 2nd page). Rest
+ of pages - 1,3,5,7 are read/written without this mode.
+
unevaluatedProperties: false

dependencies:
nand-ecc-strength: [nand-ecc-step-size]
nand-ecc-step-size: [nand-ecc-strength]
+ amlogic,boot-pages: [nand-is-boot-medium, "amlogic,boot-page-step"]
+ amlogic,boot-page-step: [nand-is-boot-medium, "amlogic,boot-pages"]


required:
--
2.35.0


2024-05-08 00:00:24

by Arseniy Krasnov

[permalink] [raw]
Subject: [PATCH v6 3/3] mtd: rawnand: meson: read/write access for boot ROM pages

Boot ROM on Meson needs some pages to be read/written in a special mode:
384 byte ECC mode (so called "short" by Amlogic) and with scrambling
enabled. Such pages are located on the chip in the following way (for
example):

[ p0 ][ p1 ][ p2 ][ p3 ][ p4 ][ p5 ][ p6 ][ p7 ] ... [ pN ]
^ ^ ^ ^

pX is page number "X". "^" means "special" page used by boot ROM - e.g.
every 2nd page in the range of [0, 7]. Step (2 here) and last page in
range is read from the device tree.

Signed-off-by: Arseniy Krasnov <[email protected]>
---
drivers/mtd/nand/raw/meson_nand.c | 58 +++++++++++++++++++++++++------
1 file changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index 39f50cbd4ab9..c1bc04dc503e 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -35,6 +35,7 @@
#define NFC_CMD_RB BIT(20)
#define NFC_CMD_SCRAMBLER_ENABLE BIT(19)
#define NFC_CMD_SCRAMBLER_DISABLE 0
+#define NFC_CMD_SHORTMODE_ENABLE 1
#define NFC_CMD_SHORTMODE_DISABLE 0
#define NFC_CMD_RB_INT BIT(14)
#define NFC_CMD_RB_INT_NO_PIN ((0xb << 10) | BIT(18) | BIT(16))
@@ -78,6 +79,8 @@
#define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N)
#define DMA_ADDR_ALIGN 8

+#define NFC_SHORT_MODE_ECC_SZ 384
+
#define ECC_CHECK_RETURN_FF (-1)

#define NAND_CE0 (0xe << 10)
@@ -125,6 +128,8 @@ struct meson_nfc_nand_chip {
u32 twb;
u32 tadl;
u32 tbers_max;
+ u32 boot_pages;
+ u32 boot_page_step;

u32 bch_mode;
u8 *data_buf;
@@ -298,33 +303,46 @@ static void meson_nfc_cmd_seed(struct meson_nfc *nfc, u32 seed)
nfc->reg_base + NFC_REG_CMD);
}

+static int meson_nfc_is_boot_page(struct nand_chip *nand, int page)
+{
+ const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+
+ return (nand->options & NAND_IS_BOOT_MEDIUM) &&
+ !(page % meson_chip->boot_page_step) &&
+ (page < meson_chip->boot_pages);
+}
+
static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir, int page)
{
+ const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
struct mtd_info *mtd = nand_to_mtd(nand);
struct meson_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
- struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
- u32 bch = meson_chip->bch_mode, cmd;
int len = mtd->writesize, pagesize, pages;
int scrambler;
+ u32 cmd;

if (nand->options & NAND_NEED_SCRAMBLING)
scrambler = NFC_CMD_SCRAMBLER_ENABLE;
else
scrambler = NFC_CMD_SCRAMBLER_DISABLE;

- pagesize = nand->ecc.size;
-
if (raw) {
len = mtd->writesize + mtd->oobsize;
cmd = len | scrambler | DMA_DIR(dir);
- writel(cmd, nfc->reg_base + NFC_REG_CMD);
- return;
- }
+ } else if (meson_nfc_is_boot_page(nand, page)) {
+ pagesize = NFC_SHORT_MODE_ECC_SZ >> 3;
+ pages = mtd->writesize / 512;

- pages = len / nand->ecc.size;
+ scrambler = NFC_CMD_SCRAMBLER_ENABLE;
+ cmd = CMDRWGEN(DMA_DIR(dir), scrambler, NFC_ECC_BCH8_1K,
+ NFC_CMD_SHORTMODE_ENABLE, pagesize, pages);
+ } else {
+ pagesize = nand->ecc.size >> 3;
+ pages = len / nand->ecc.size;

- cmd = CMDRWGEN(DMA_DIR(dir), scrambler, bch,
- NFC_CMD_SHORTMODE_DISABLE, pagesize, pages);
+ cmd = CMDRWGEN(DMA_DIR(dir), scrambler, meson_chip->bch_mode,
+ NFC_CMD_SHORTMODE_DISABLE, pagesize, pages);
+ }

if (scrambler == NFC_CMD_SCRAMBLER_ENABLE)
meson_nfc_cmd_seed(nfc, page);
@@ -1430,6 +1448,26 @@ meson_nfc_nand_chip_init(struct device *dev,
if (ret)
return ret;

+ if (nand->options & NAND_IS_BOOT_MEDIUM) {
+ ret = of_property_read_u32(np, "amlogic,boot-pages",
+ &meson_chip->boot_pages);
+ if (ret) {
+ dev_err(dev, "could not retrieve 'amlogic,boot-pages' property: %d",
+ ret);
+ nand_cleanup(nand);
+ return ret;
+ }
+
+ ret = of_property_read_u32(np, "amlogic,boot-page-step",
+ &meson_chip->boot_page_step);
+ if (ret) {
+ dev_err(dev, "could not retrieve 'amlogic,boot-page-step' property: %d",
+ ret);
+ nand_cleanup(nand);
+ return ret;
+ }
+ }
+
ret = mtd_device_register(mtd, NULL, 0);
if (ret) {
dev_err(dev, "failed to register MTD device: %d\n", ret);
--
2.35.0


2024-05-08 14:09:22

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v6 1/3] dt-bindings: mtd: amlogic,meson-nand: support fields for boot ROM code


On Wed, 08 May 2024 02:09:01 +0300, Arseniy Krasnov wrote:
> Boot ROM code on Meson requires that some pages on NAND must be written
> in special mode: "short" ECC mode where each block is 384 bytes and
> scrambling mode is on. Such pages are located on the chip in the
> following way (for example):
>
> [ p0 ][ p1 ][ p2 ][ p3 ][ p4 ][ p5 ][ p6 ][ p7 ] ... [ pN ]
> ^ ^ ^ ^
>
> pX is page number "X". "^" means "special" page used by boot ROM - e.g.
> every 2nd page in the range of [0, 7]. Step (2 in example is set by
> 'amlogic,boot-page-step' field. Last page in range (7 in example) is
> set by 'amlogic,boot-pages' field.
>
> Signed-off-by: Arseniy Krasnov <[email protected]>
> ---
> .../bindings/mtd/amlogic,meson-nand.yaml | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.

Missing tags:

Reviewed-by: Rob Herring (Arm) <[email protected]>




2024-05-12 17:38:04

by Arseniy Krasnov

[permalink] [raw]
Subject: Re: [PATCH v6 1/3] dt-bindings: mtd: amlogic,meson-nand: support fields for boot ROM code

Sorry, sending from proper mail client again (not sure it was delivered sent from gmail client on 08.05) :)

R-b was removed, because this patch was updated

Thanks, Arseniy

On 08.05.2024 20:07, Krasnov Arseniy wrote:
> Hi! I removed Your R-b because patch was changed in this version, after
> comments from Miquel Raynal
>
> Thanks
>
> ср, 8 мая 2024 г., 17:09 Rob Herring (Arm) <[email protected]>:
>
>>
>> On Wed, 08 May 2024 02:09:01 +0300, Arseniy Krasnov wrote:
>>> Boot ROM code on Meson requires that some pages on NAND must be written
>>> in special mode: "short" ECC mode where each block is 384 bytes and
>>> scrambling mode is on. Such pages are located on the chip in the
>>> following way (for example):
>>>
>>> [ p0 ][ p1 ][ p2 ][ p3 ][ p4 ][ p5 ][ p6 ][ p7 ] ... [ pN ]
>>> ^ ^ ^ ^
>>>
>>> pX is page number "X". "^" means "special" page used by boot ROM - e.g.
>>> every 2nd page in the range of [0, 7]. Step (2 in example is set by
>>> 'amlogic,boot-page-step' field. Last page in range (7 in example) is
>>> set by 'amlogic,boot-pages' field.
>>>
>>> Signed-off-by: Arseniy Krasnov <[email protected]>
>>> ---
>>> .../bindings/mtd/amlogic,meson-nand.yaml | 18 ++++++++++++++++++
>>> 1 file changed, 18 insertions(+)
>>>
>>
>>
>> Please add Acked-by/Reviewed-by tags when posting new versions. However,
>> there's no need to repost patches *only* to add the tags. The upstream
>> maintainer will do that for acks received on the version they apply.
>>
>> If a tag was not added on purpose, please state why and what changed.
>>
>> Missing tags:
>>
>> Reviewed-by: Rob Herring (Arm) <[email protected]>
>>
>>
>>
>>
>

2024-05-13 09:10:44

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v6 1/3] dt-bindings: mtd: amlogic,meson-nand: support fields for boot ROM code

On 12/05/2024 19:26, Arseniy Krasnov wrote:
> Sorry, sending from proper mail client again (not sure it was delivered sent from gmail client on 08.05) :)
>
> R-b was removed, because this patch was updated

Then, as Rob requested, explain what changed and why the tag was
removed. There was nothing in this patch's changelog.


Best regards,
Krzysztof


2024-05-13 10:21:43

by Arseniy Krasnov

[permalink] [raw]
Subject: Re: [PATCH v6 1/3] dt-bindings: mtd: amlogic,meson-nand: support fields for boot ROM code

Changelog:

v5 -> v6:

* Update description in 'yaml' and commit message by adding more details
about such special Meson mode. R-b was removed so.

Thanks, Arseniy

On 08.05.2024 02:09, Arseniy Krasnov wrote:
> Boot ROM code on Meson requires that some pages on NAND must be written
> in special mode: "short" ECC mode where each block is 384 bytes and
> scrambling mode is on. Such pages are located on the chip in the
> following way (for example):
>
> [ p0 ][ p1 ][ p2 ][ p3 ][ p4 ][ p5 ][ p6 ][ p7 ] ... [ pN ]
> ^ ^ ^ ^
>
> pX is page number "X". "^" means "special" page used by boot ROM - e.g.
> every 2nd page in the range of [0, 7]. Step (2 in example is set by
> 'amlogic,boot-page-step' field. Last page in range (7 in example) is
> set by 'amlogic,boot-pages' field.
>
> Signed-off-by: Arseniy Krasnov <[email protected]>
> ---
> .../bindings/mtd/amlogic,meson-nand.yaml | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
> index 57b6957c8415..284f0f882c32 100644
> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
> @@ -64,11 +64,29 @@ patternProperties:
> items:
> maximum: 0
>
> + amlogic,boot-pages:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + Number of pages starting from offset 0, where a special ECC
> + configuration must be used because it is accessed by the ROM
> + code. This ECC configuration uses 384 bytes data blocks.
> + Also scrambling mode is enabled for such pages.
> +
> + amlogic,boot-page-step:
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description:
> + Interval between pages, accessed by the ROM code. For example
> + we have 8 pages [0, 7]. Pages 0,2,4,6 are accessed by the
> + ROM code, so this field will be 2 (e.g. every 2nd page). Rest
> + of pages - 1,3,5,7 are read/written without this mode.
> +
> unevaluatedProperties: false
>
> dependencies:
> nand-ecc-strength: [nand-ecc-step-size]
> nand-ecc-step-size: [nand-ecc-strength]
> + amlogic,boot-pages: [nand-is-boot-medium, "amlogic,boot-page-step"]
> + amlogic,boot-page-step: [nand-is-boot-medium, "amlogic,boot-pages"]
>
>
> required:

2024-05-27 12:20:39

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH v6 2/3] mtd: rawnand: meson: refactor use of 'meson_nfc_cmd_access()'

On Tue, 2024-05-07 at 23:09:02 UTC, Arseniy Krasnov wrote:
> Move call 'meson_nfc_cmd_seed()' and check for 'NAND_NEED_SCRAMBLING'
> to 'meson_nfc_cmd_access()', thus removing code duplication.
>
> Signed-off-by: Arseniy Krasnov <[email protected]>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel

2024-05-27 12:20:56

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH v6 3/3] mtd: rawnand: meson: read/write access for boot ROM pages

On Tue, 2024-05-07 at 23:09:03 UTC, Arseniy Krasnov wrote:
> Boot ROM on Meson needs some pages to be read/written in a special mode:
> 384 byte ECC mode (so called "short" by Amlogic) and with scrambling
> enabled. Such pages are located on the chip in the following way (for
> example):
>
> [ p0 ][ p1 ][ p2 ][ p3 ][ p4 ][ p5 ][ p6 ][ p7 ] ... [ pN ]
> ^ ^ ^ ^
>
> pX is page number "X". "^" means "special" page used by boot ROM - e.g.
> every 2nd page in the range of [0, 7]. Step (2 here) and last page in
> range is read from the device tree.
>
> Signed-off-by: Arseniy Krasnov <[email protected]>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel

2024-05-27 12:23:15

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH v6 1/3] dt-bindings: mtd: amlogic,meson-nand: support fields for boot ROM code

On Tue, 2024-05-07 at 23:09:01 UTC, Arseniy Krasnov wrote:
> Boot ROM code on Meson requires that some pages on NAND must be written
> in special mode: "short" ECC mode where each block is 384 bytes and
> scrambling mode is on. Such pages are located on the chip in the
> following way (for example):
>
> [ p0 ][ p1 ][ p2 ][ p3 ][ p4 ][ p5 ][ p6 ][ p7 ] ... [ pN ]
> ^ ^ ^ ^
>
> pX is page number "X". "^" means "special" page used by boot ROM - e.g.
> every 2nd page in the range of [0, 7]. Step (2 in example is set by
> 'amlogic,boot-page-step' field. Last page in range (7 in example) is
> set by 'amlogic,boot-pages' field.
>
> Signed-off-by: Arseniy Krasnov <[email protected]>
> Reviewed-by: Rob Herring (Arm) <[email protected]>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel