[U-Boot] [PATCH v2 0/14] sunxi: Add support for the CHIP Pro

The CHIP Pro is a SoM made by NextThing Co, and that embeds a GR8 SIP, an AXP209 PMIC, a WiFi BT chip and a 512MB SLC NAND.
Since the first Allwinner device coming whit an SLC NAND that doesn't have the shortcomings (and breakages) the MLC NAND has, we can finally enable the NAND support on a board by default.
This is the occasion to introduce a bunch of additions needed imo to be able to come up with a sane NAND support for our users.
The biggest pain point is that the BROM uses a different ECC and randomizer configuration than for the rest of the NAND. In order to lessen the number of bitflips, you also need to pad with random data the SPL image.
Since it's quite tedious to do right (and most users won't be able to figure it out) and since if it is not done right, it will eventually turn into an unusable system (which is bad UX), we think that the best solution is to generate an SPL image that already embeds all this. We'll possible have to do the same thing for the U-Boot image (at least for the random padding) on MLC NANDs.
The only drawback from that is that you need to flash it raw, instead of using the usual nand write, but it's just a different command, nothing major anyway.
In order to flash it, from a device switched in FEL, on your host: sunxi-fel spl spl/sunxi-spl.bin sunxi-fel write 0x4a000000 u-boot-dtb.bin sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin sunxi-fel exe 0x4a000000
And on the board, once u-boot is running (assuming the NAND is already erased):
nand write.raw.noverify 0x43000000 0 40 nand write.raw.noverify 0x43000000 0x400000 40
nand write 0x4a000000 0x800000 0xc0000
I also encountered some weird bug in the private libgcc that prevents U-Boot from loading. Disabling CONFIG_USE_PRIVATE_LIBGCC fixes that.
Let me know what you think, Maxime
Changes from v1: - Allowed to build lib/bch.c for the host, and used that in the image builder - Fixed a bug in the NAND driver - Wrote a documentation on how to flash a NAND image on an Allwinner board - Fixed a few compilation breakages and issues - Moved U-boot offset out of the config header and into Kconfig - Moved the environment into UBI - Moved the environment selection to Kconfig - Moved the CMD_MTDPARTS options to Kconfig - Provide MTDIDS_DEFAULT and MTDPARTS_DEFAULT options through Kconfig - Added the tags from everyone
Boris Brezillon (1): mtd: nand: add support for the TC58NVG2S0H chip
Hans de Goede (1): sunxi: Enable UBI and NAND support
Maxime Ripard (12): nand: sunxi: Fix modulo by zero error bch: Allow to build for the host tools: sunxi: Add spl image builder common: Move environment choice to Kconfig cmd: Add Kconfig option for CMD_MTDPARTS and related options mtd: sunxi: Select the U-Boot location config option mtd: sunxi: Change U-Boot offset sunxi: Add the default mtdids and mtdparts to our env nand: sunxi: Add options for the SPL NAND configuration scripts: sunxi: Build an raw SPL image sunxi: Sync GR8 DTS and AXP209 with the kernel sunxi: Add support for the CHIP Pro
Makefile | 3 +- arch/arm/dts/Makefile | 1 +- arch/arm/dts/axp209.dtsi | 6 +- arch/arm/dts/ntc-gr8-chip-pro.dts | 266 +++++++- arch/arm/dts/ntc-gr8.dtsi | 1132 ++++++++++++++++++++++++++++++- board/sunxi/Kconfig | 8 +- board/sunxi/README.nand | 54 +- cmd/Kconfig | 19 +- cmd/mtdparts.c | 8 +- common/Kconfig | 65 ++- configs/CHIP_pro_defconfig | 32 +- drivers/mtd/nand/Kconfig | 19 +- drivers/mtd/nand/nand_ids.c | 3 +- drivers/mtd/nand/sunxi_nand_spl.c | 7 +- include/configs/sunxi-common.h | 44 +- include/environment.h | 2 +- lib/bch.c | 48 +- scripts/Makefile.spl | 15 +- tools/.gitignore | 1 +- tools/Makefile | 2 +- tools/sunxi-spl-image-builder.c | 484 +++++++++++++- 21 files changed, 2204 insertions(+), 15 deletions(-) create mode 100644 arch/arm/dts/ntc-gr8-chip-pro.dts create mode 100644 arch/arm/dts/ntc-gr8.dtsi create mode 100644 board/sunxi/README.nand create mode 100644 configs/CHIP_pro_defconfig create mode 100644 tools/sunxi-spl-image-builder.c
base-commit: d8bdfc80da39211d95f10d24e79f2e867305f71b

When trying to autodetect the ECC and randomization configurations, the driver starts with a randomization disabled and no seeds.
In this case, the number of seeds is obviously 0, and the randomize boolean is set to false.
However, the logic that retrieves the seed for a given page offset will blindly use the number of seeds, without testing if the randomization is enabled, basically doing a modulo by 0.
As it turns out, the libgcc in the common toolchain returns 0 here, which was our expected value in such a case, and why we would not detect it. However, U-Boot's libgcc will for some reason return from the function instead, resulting in an error to load the U-Boot binary in the SPL.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- drivers/mtd/nand/sunxi_nand_spl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 1ef7366d4c42..eed4472bdc34 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -245,7 +245,7 @@ static int nand_read_page(const struct nfc_config *conf, u32 offs, { dma_addr_t dst = (dma_addr_t)dest; int nsectors = len / conf->ecc_size; - u16 rand_seed; + u16 rand_seed = 0; u32 val; int page;
@@ -258,8 +258,9 @@ static int nand_read_page(const struct nfc_config *conf, u32 offs, /* clear ecc status */ writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
- /* Choose correct seed */ - rand_seed = random_seed[page % conf->nseeds]; + /* Choose correct seed if randomized */ + if (conf->randomize) + rand_seed = random_seed[page % conf->nseeds];
writel((rand_seed << 16) | (conf->ecc_strength << 12) | (conf->randomize ? NFC_ECC_RANDOM_EN : 0) |

On Tue, 22 Nov 2016 13:38:31 +0100 Maxime Ripard maxime.ripard@free-electrons.com wrote:
When trying to autodetect the ECC and randomization configurations, the driver starts with a randomization disabled and no seeds.
In this case, the number of seeds is obviously 0, and the randomize boolean is set to false.
However, the logic that retrieves the seed for a given page offset will blindly use the number of seeds, without testing if the randomization is enabled, basically doing a modulo by 0.
As it turns out, the libgcc in the common toolchain returns 0 here, which was our expected value in such a case, and why we would not detect it. However, U-Boot's libgcc will for some reason return from the function instead, resulting in an error to load the U-Boot binary in the SPL.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
Acked-by: Boris Brezillon boris.brezillon@free-electrons.com
drivers/mtd/nand/sunxi_nand_spl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 1ef7366d4c42..eed4472bdc34 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -245,7 +245,7 @@ static int nand_read_page(const struct nfc_config *conf, u32 offs, { dma_addr_t dst = (dma_addr_t)dest; int nsectors = len / conf->ecc_size;
- u16 rand_seed;
- u16 rand_seed = 0; u32 val; int page;
@@ -258,8 +258,9 @@ static int nand_read_page(const struct nfc_config *conf, u32 offs, /* clear ecc status */ writel(0, SUNXI_NFC_BASE + NFC_ECC_ST);
- /* Choose correct seed */
- rand_seed = random_seed[page % conf->nseeds];
/* Choose correct seed if randomized */
if (conf->randomize)
rand_seed = random_seed[page % conf->nseeds];
writel((rand_seed << 16) | (conf->ecc_strength << 12) | (conf->randomize ? NFC_ECC_RANDOM_EN : 0) |

On Tue, 2016-11-22 at 13:38 +0100, Maxime Ripard wrote:
When trying to autodetect the ECC and randomization configurations, the driver starts with a randomization disabled and no seeds.
In this case, the number of seeds is obviously 0, and the randomize boolean is set to false.
However, the logic that retrieves the seed for a given page offset will blindly use the number of seeds, without testing if the randomization is enabled, basically doing a modulo by 0.
As it turns out, the libgcc in the common toolchain returns 0 here, which was our expected value in such a case, and why we would not detect it. However, U-Boot's libgcc will for some reason return from the function instead, resulting in an error to load the U-Boot binary in the SPL.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
drivers/mtd/nand/sunxi_nand_spl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
Acked-by: Scott Wood oss@buserror.net
-Scott

From: Boris Brezillon boris.brezillon@free-electrons.com
Add the description of the Toshiba TC58NVG2S0H SLC nand to the nand_ids table so we can use the NAND ECC infos and the ONFI timings.
Signed-off-by: Boris Brezillon boris.brezillon@free-electrons.com Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Reviewed-by: Hans de Goede hdegoede@redhat.com Acked-by: Scott Wood oss@buserror.net --- drivers/mtd/nand/nand_ids.c | 3 +++ 1 file changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index ce0a14e28abb..d36f9006c99d 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -46,6 +46,9 @@ struct nand_flash_dev nand_flash_ids[] = { {"TC58NVG2S0F 4G 3.3V 8-bit", { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) }, + {"TC58NVG2S0H 4G 3.3V 8-bit", + { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00} }, + SZ_4K, SZ_512, SZ_256K, 0, 8, 256, NAND_ECC_INFO(8, SZ_512) }, {"TC58NVG3S0F 8G 3.3V 8-bit", { .id = {0x98, 0xd3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08} }, SZ_4K, SZ_1K, SZ_256K, 0, 8, 232, NAND_ECC_INFO(4, SZ_512) },

We will need the bch functions in the tool to generate the SPL images for the Allwinner SoCs.
Do the needed adjustments so that we can use it on the host.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- lib/bch.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+), 0 deletions(-)
diff --git a/lib/bch.c b/lib/bch.c index 147715afd06a..ec53483774b5 100644 --- a/lib/bch.c +++ b/lib/bch.c @@ -54,10 +54,27 @@ * finite fields GF(2^q). In Rapport de recherche INRIA no 2829, 1996. */
+#ifndef USE_HOSTCC #include <common.h> #include <ubi_uboot.h>
#include <linux/bitops.h> +#else +#include <errno.h> +#include <endian.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#undef cpu_to_be32 +#define cpu_to_be32 htobe32 +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define kmalloc(size, flags) malloc(size) +#define kzalloc(size, flags) calloc(1, size) +#define kfree free +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + #include <asm/byteorder.h> #include <linux/bch.h>
@@ -95,6 +112,37 @@ struct gf_poly_deg1 { unsigned int c[2]; };
+#ifdef USE_HOSTCC +static int fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} +#endif + /* * same as encode_bch(), but process input data one byte at a time */

On Tue, Nov 22, 2016 at 01:38:33PM +0100, Maxime Ripard wrote:
We will need the bch functions in the tool to generate the SPL images for the Allwinner SoCs.
Do the needed adjustments so that we can use it on the host.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
Reviewed-by: Tom Rini trini@konsulko.com

On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
We will need the bch functions in the tool to generate the SPL images for the Allwinner SoCs.
Do the needed adjustments so that we can use it on the host.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
lib/bch.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+), 0 deletions(-)
diff --git a/lib/bch.c b/lib/bch.c index 147715afd06a..ec53483774b5 100644 --- a/lib/bch.c +++ b/lib/bch.c @@ -54,10 +54,27 @@
- finite fields GF(2^q). In Rapport de recherche INRIA no 2829, 1996.
*/
+#ifndef USE_HOSTCC #include <common.h> #include <ubi_uboot.h>
#include <linux/bitops.h> +#else +#include <errno.h> +#include <endian.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h>
+#undef cpu_to_be32 +#define cpu_to_be32 htobe32 +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define kmalloc(size, flags) malloc(size) +#define kzalloc(size, flags) calloc(1, size) +#define kfree free +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif
#include <asm/byteorder.h> #include <linux/bch.h>
@@ -95,6 +112,37 @@ struct gf_poly_deg1 { unsigned int c[2]; };
+#ifdef USE_HOSTCC +static int fls(int x) +{
This look redundant definition to me, can't we use this from include/linux/bitops.h ?
thanks!

On Fri, Nov 25, 2016 at 10:35:15PM +0530, Jagan Teki wrote:
On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
We will need the bch functions in the tool to generate the SPL images for the Allwinner SoCs.
Do the needed adjustments so that we can use it on the host.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
lib/bch.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+), 0 deletions(-)
diff --git a/lib/bch.c b/lib/bch.c index 147715afd06a..ec53483774b5 100644 --- a/lib/bch.c +++ b/lib/bch.c @@ -54,10 +54,27 @@
- finite fields GF(2^q). In Rapport de recherche INRIA no 2829, 1996.
*/
+#ifndef USE_HOSTCC #include <common.h> #include <ubi_uboot.h>
#include <linux/bitops.h> +#else +#include <errno.h> +#include <endian.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h>
+#undef cpu_to_be32 +#define cpu_to_be32 htobe32 +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#define kmalloc(size, flags) malloc(size) +#define kzalloc(size, flags) calloc(1, size) +#define kfree free +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif
#include <asm/byteorder.h> #include <linux/bch.h>
@@ -95,6 +112,37 @@ struct gf_poly_deg1 { unsigned int c[2]; };
+#ifdef USE_HOSTCC +static int fls(int x) +{
This look redundant definition to me, can't we use this from include/linux/bitops.h ?
This is compiled to run in userspace, linux/bitops.h isn't available there.
Maxime

This program generates raw SPL images that can be flashed on the NAND with the ECC and randomizer properly set up.
This has been copied (and tweaked to find the right headers) from the sunxi-tools (https://github.com/linux-sunxi/sunxi-tools) upstream repository, commit 1c3a6ca5.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Acked-by: Boris Brezillon boris.brezillon@free-electrons.com Reviewed-by: Hans de Goede hdegoede@redhat.com --- tools/.gitignore | 1 +- tools/Makefile | 2 +- tools/sunxi-spl-image-builder.c | 484 +++++++++++++++++++++++++++++++++- 3 files changed, 487 insertions(+), 0 deletions(-) create mode 100644 tools/sunxi-spl-image-builder.c
diff --git a/tools/.gitignore b/tools/.gitignore index cb1e722d4575..16574467544c 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -15,6 +15,7 @@ /mkexynosspl /mxsboot /mksunxiboot +/sunxi-spl-image-builder /ncb /proftool /relocate-rela diff --git a/tools/Makefile b/tools/Makefile index 400588cf0f5c..f37d3262e1f1 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -171,6 +171,8 @@ hostprogs-$(CONFIG_MX28) += mxsboot HOSTCFLAGS_mxsboot.o := -pedantic
hostprogs-$(CONFIG_ARCH_SUNXI) += mksunxiboot +hostprogs-$(CONFIG_ARCH_SUNXI) += sunxi-spl-image-builder +sunxi-spl-image-builder-objs := sunxi-spl-image-builder.o lib/bch.o
hostprogs-$(CONFIG_NETCONSOLE) += ncb hostprogs-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1 diff --git a/tools/sunxi-spl-image-builder.c b/tools/sunxi-spl-image-builder.c new file mode 100644 index 000000000000..d538a3881319 --- /dev/null +++ b/tools/sunxi-spl-image-builder.c @@ -0,0 +1,484 @@ +/* + * Allwinner NAND randomizer and image builder implementation: + * + * Copyright © 2016 NextThing Co. + * Copyright © 2016 Free Electrons + * + * Author: Boris Brezillon boris.brezillon@free-electrons.com + * + */ + +#include <linux/bch.h> + +#include <getopt.h> +#include <version.h> + +#define BCH_PRIMITIVE_POLY 0x5803 + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) + +struct image_info { + int ecc_strength; + int ecc_step_size; + int page_size; + int oob_size; + int usable_page_size; + int eraseblock_size; + int scramble; + int boot0; + off_t offset; + const char *source; + const char *dest; +}; + +static void swap_bits(uint8_t *buf, int len) +{ + int i, j; + + for (j = 0; j < len; j++) { + uint8_t byte = buf[j]; + + buf[j] = 0; + for (i = 0; i < 8; i++) { + if (byte & (1 << i)) + buf[j] |= (1 << (7 - i)); + } + } +} + +static uint16_t lfsr_step(uint16_t state, int count) +{ + state &= 0x7fff; + while (count--) + state = ((state >> 1) | + ((((state >> 0) ^ (state >> 1)) & 1) << 14)) & 0x7fff; + + return state; +} + +static uint16_t default_scrambler_seeds[] = { + 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72, + 0x0d67, 0x67f9, 0x1be7, 0x077d, 0x032f, 0x0dac, 0x2716, 0x2436, + 0x7922, 0x1510, 0x3860, 0x5287, 0x480f, 0x4252, 0x1789, 0x5a2d, + 0x2a49, 0x5e10, 0x437f, 0x4b4e, 0x2f45, 0x216e, 0x5cb7, 0x7130, + 0x2a3f, 0x60e4, 0x4dc9, 0x0ef0, 0x0f52, 0x1bb9, 0x6211, 0x7a56, + 0x226d, 0x4ea7, 0x6f36, 0x3692, 0x38bf, 0x0c62, 0x05eb, 0x4c55, + 0x60f4, 0x728c, 0x3b6f, 0x2037, 0x7f69, 0x0936, 0x651a, 0x4ceb, + 0x6218, 0x79f3, 0x383f, 0x18d9, 0x4f05, 0x5c82, 0x2912, 0x6f17, + 0x6856, 0x5938, 0x1007, 0x61ab, 0x3e7f, 0x57c2, 0x542f, 0x4f62, + 0x7454, 0x2eac, 0x7739, 0x42d4, 0x2f90, 0x435a, 0x2e52, 0x2064, + 0x637c, 0x66ad, 0x2c90, 0x0bad, 0x759c, 0x0029, 0x0986, 0x7126, + 0x1ca7, 0x1605, 0x386a, 0x27f5, 0x1380, 0x6d75, 0x24c3, 0x0f8e, + 0x2b7a, 0x1418, 0x1fd1, 0x7dc1, 0x2d8e, 0x43af, 0x2267, 0x7da3, + 0x4e3d, 0x1338, 0x50db, 0x454d, 0x764d, 0x40a3, 0x42e6, 0x262b, + 0x2d2e, 0x1aea, 0x2e17, 0x173d, 0x3a6e, 0x71bf, 0x25f9, 0x0a5d, + 0x7c57, 0x0fbe, 0x46ce, 0x4939, 0x6b17, 0x37bb, 0x3e91, 0x76db, +}; + +static uint16_t brom_scrambler_seeds[] = { 0x4a80 }; + +static void scramble(const struct image_info *info, + int page, uint8_t *data, int datalen) +{ + uint16_t state; + int i; + + /* Boot0 is always scrambled no matter the command line option. */ + if (info->boot0) { + state = brom_scrambler_seeds[0]; + } else { + unsigned seedmod = info->eraseblock_size / info->page_size; + + /* Bail out earlier if the user didn't ask for scrambling. */ + if (!info->scramble) + return; + + if (seedmod > ARRAY_SIZE(default_scrambler_seeds)) + seedmod = ARRAY_SIZE(default_scrambler_seeds); + + state = default_scrambler_seeds[page % seedmod]; + } + + /* Prepare the initial state... */ + state = lfsr_step(state, 15); + + /* and start scrambling data. */ + for (i = 0; i < datalen; i++) { + data[i] ^= state; + state = lfsr_step(state, 8); + } +} + +static int write_page(const struct image_info *info, uint8_t *buffer, + FILE *src, FILE *rnd, FILE *dst, + struct bch_control *bch, int page) +{ + int steps = info->usable_page_size / info->ecc_step_size; + int eccbytes = DIV_ROUND_UP(info->ecc_strength * 14, 8); + off_t pos = ftell(dst); + size_t pad, cnt; + int i; + + if (eccbytes % 2) + eccbytes++; + + memset(buffer, 0xff, info->page_size + info->oob_size); + cnt = fread(buffer, 1, info->usable_page_size, src); + if (!cnt) { + if (!feof(src)) { + fprintf(stderr, + "Failed to read data from the source\n"); + return -1; + } else { + return 0; + } + } + + fwrite(buffer, info->page_size + info->oob_size, 1, dst); + + for (i = 0; i < info->usable_page_size; i++) { + if (buffer[i] != 0xff) + break; + } + + /* We leave empty pages at 0xff. */ + if (i == info->usable_page_size) + return 0; + + /* Restore the source pointer to read it again. */ + fseek(src, -cnt, SEEK_CUR); + + /* Randomize unused space if scrambling is required. */ + if (info->scramble) { + int offs; + + if (info->boot0) { + size_t ret; + + offs = steps * (info->ecc_step_size + eccbytes + 4); + cnt = info->page_size + info->oob_size - offs; + ret = fread(buffer + offs, 1, cnt, rnd); + if (!ret && !feof(rnd)) { + fprintf(stderr, + "Failed to read random data\n"); + return -1; + } + } else { + offs = info->page_size + (steps * (eccbytes + 4)); + cnt = info->page_size + info->oob_size - offs; + memset(buffer + offs, 0xff, cnt); + scramble(info, page, buffer + offs, cnt); + } + fseek(dst, pos + offs, SEEK_SET); + fwrite(buffer + offs, cnt, 1, dst); + } + + for (i = 0; i < steps; i++) { + int ecc_offs, data_offs; + uint8_t *ecc; + + memset(buffer, 0xff, info->ecc_step_size + eccbytes + 4); + ecc = buffer + info->ecc_step_size + 4; + if (info->boot0) { + data_offs = i * (info->ecc_step_size + eccbytes + 4); + ecc_offs = data_offs + info->ecc_step_size + 4; + } else { + data_offs = i * info->ecc_step_size; + ecc_offs = info->page_size + 4 + (i * (eccbytes + 4)); + } + + cnt = fread(buffer, 1, info->ecc_step_size, src); + if (!cnt && !feof(src)) { + fprintf(stderr, + "Failed to read data from the source\n"); + return -1; + } + + pad = info->ecc_step_size - cnt; + if (pad) { + if (info->scramble && info->boot0) { + size_t ret; + + ret = fread(buffer + cnt, 1, pad, rnd); + if (!ret && !feof(rnd)) { + fprintf(stderr, + "Failed to read random data\n"); + return -1; + } + } else { + memset(buffer + cnt, 0xff, pad); + } + } + + memset(ecc, 0, eccbytes); + swap_bits(buffer, info->ecc_step_size + 4); + encode_bch(bch, buffer, info->ecc_step_size + 4, ecc); + swap_bits(buffer, info->ecc_step_size + 4); + swap_bits(ecc, eccbytes); + scramble(info, page, buffer, info->ecc_step_size + 4 + eccbytes); + + fseek(dst, pos + data_offs, SEEK_SET); + fwrite(buffer, info->ecc_step_size, 1, dst); + fseek(dst, pos + ecc_offs - 4, SEEK_SET); + fwrite(ecc - 4, eccbytes + 4, 1, dst); + } + + /* Fix BBM. */ + fseek(dst, pos + info->page_size, SEEK_SET); + memset(buffer, 0xff, 2); + fwrite(buffer, 2, 1, dst); + + /* Make dst pointer point to the next page. */ + fseek(dst, pos + info->page_size + info->oob_size, SEEK_SET); + + return 0; +} + +static int create_image(const struct image_info *info) +{ + off_t page = info->offset / info->page_size; + struct bch_control *bch; + FILE *src, *dst, *rnd; + uint8_t *buffer; + + bch = init_bch(14, info->ecc_strength, BCH_PRIMITIVE_POLY); + if (!bch) { + fprintf(stderr, "Failed to init the BCH engine\n"); + return -1; + } + + buffer = malloc(info->page_size + info->oob_size); + if (!buffer) { + fprintf(stderr, "Failed to allocate the NAND page buffer\n"); + return -1; + } + + memset(buffer, 0xff, info->page_size + info->oob_size); + + src = fopen(info->source, "r"); + if (!src) { + fprintf(stderr, "Failed to open source file (%s)\n", + info->source); + return -1; + } + + dst = fopen(info->dest, "w"); + if (!dst) { + fprintf(stderr, "Failed to open dest file (%s)\n", info->dest); + return -1; + } + + rnd = fopen("/dev/urandom", "r"); + if (!rnd) { + fprintf(stderr, "Failed to open /dev/urandom\n"); + return -1; + } + + while (!feof(src)) { + int ret; + + ret = write_page(info, buffer, src, rnd, dst, bch, page++); + if (ret) + return ret; + } + + return 0; +} + +static void display_help(int status) +{ + fprintf(status == EXIT_SUCCESS ? stdout : stderr, + "sunxi-nand-image-builder %s\n" + "\n" + "Usage: sunxi-nand-image-builder [OPTIONS] source-image output-image\n" + "\n" + "Creates a raw NAND image that can be read by the sunxi NAND controller.\n" + "\n" + "-h --help Display this help and exit\n" + "-c <str>/<step> --ecc=<str>/<step> ECC config (strength/step-size)\n" + "-p <size> --page=<size> Page size\n" + "-o <size> --oob=<size> OOB size\n" + "-u <size> --usable=<size> Usable page size\n" + "-e <size> --eraseblock=<size> Erase block size\n" + "-b --boot0 Build a boot0 image.\n" + "-s --scramble Scramble data\n" + "-a <offset> --address=<offset> Where the image will be programmed.\n" + "\n" + "Notes:\n" + "All the information you need to pass to this tool should be part of\n" + "the NAND datasheet.\n" + "\n" + "The NAND controller only supports the following ECC configs\n" + " Valid ECC strengths: 16, 24, 28, 32, 40, 48, 56, 60 and 64\n" + " Valid ECC step size: 512 and 1024\n" + "\n" + "If you are building a boot0 image, you'll have specify extra options.\n" + "These options should be chosen based on the layouts described here:\n" + " http://linux-sunxi.org/NAND#More_information_on_BROM_NAND%5Cn" + "\n" + " --usable should be assigned the 'Hardware page' value\n" + " --ecc should be assigned the 'ECC capacity'/'ECC page' values\n" + " --usable should be smaller than --page\n" + "\n" + "The --address option is only required for non-boot0 images that are \n" + "meant to be programmed at a non eraseblock aligned offset.\n" + "\n" + "Examples:\n" + " The H27UCG8T2BTR-BC NAND exposes\n" + " * 16k pages\n" + " * 1280 OOB bytes per page\n" + " * 4M eraseblocks\n" + " * requires data scrambling\n" + " * expects a minimum ECC of 40bits/1024bytes\n" + "\n" + " A normal image can be generated with\n" + " sunxi-nand-image-builder -p 16384 -o 1280 -e 0x400000 -s -c 40/1024\n" + " A boot0 image can be generated with\n" + " sunxi-nand-image-builder -p 16384 -o 1280 -e 0x400000 -s -b -u 4096 -c 64/1024\n", + PLAIN_VERSION); + exit(status); +} + +static int check_image_info(struct image_info *info) +{ + static int valid_ecc_strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; + int eccbytes, eccsteps; + unsigned i; + + if (!info->page_size) { + fprintf(stderr, "--page is missing\n"); + return -EINVAL; + } + + if (!info->page_size) { + fprintf(stderr, "--oob is missing\n"); + return -EINVAL; + } + + if (!info->eraseblock_size) { + fprintf(stderr, "--eraseblock is missing\n"); + return -EINVAL; + } + + if (info->ecc_step_size != 512 && info->ecc_step_size != 1024) { + fprintf(stderr, "Invalid ECC step argument: %d\n", + info->ecc_step_size); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(valid_ecc_strengths); i++) { + if (valid_ecc_strengths[i] == info->ecc_strength) + break; + } + + if (i == ARRAY_SIZE(valid_ecc_strengths)) { + fprintf(stderr, "Invalid ECC strength argument: %d\n", + info->ecc_strength); + return -EINVAL; + } + + eccbytes = DIV_ROUND_UP(info->ecc_strength * 14, 8); + if (eccbytes % 2) + eccbytes++; + eccbytes += 4; + + eccsteps = info->usable_page_size / info->ecc_step_size; + + if (info->page_size + info->oob_size < + info->usable_page_size + (eccsteps * eccbytes)) { + fprintf(stderr, + "ECC bytes do not fit in the NAND page, choose a weaker ECC\n"); + return -EINVAL; + } + + return 0; +} + +int main(int argc, char **argv) +{ + struct image_info info; + + memset(&info, 0, sizeof(info)); + /* + * Process user arguments + */ + for (;;) { + int option_index = 0; + char *endptr = NULL; + static const struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"ecc", required_argument, 0, 'c'}, + {"page", required_argument, 0, 'p'}, + {"oob", required_argument, 0, 'o'}, + {"usable", required_argument, 0, 'u'}, + {"eraseblock", required_argument, 0, 'e'}, + {"boot0", no_argument, 0, 'b'}, + {"scramble", no_argument, 0, 's'}, + {"address", required_argument, 0, 'a'}, + {0, 0, 0, 0}, + }; + + int c = getopt_long(argc, argv, "c:p:o:u:e:ba:sh", + long_options, &option_index); + if (c == EOF) + break; + + switch (c) { + case 'h': + display_help(0); + break; + case 's': + info.scramble = 1; + break; + case 'c': + info.ecc_strength = strtol(optarg, &endptr, 0); + if (endptr || *endptr == '/') + info.ecc_step_size = strtol(endptr + 1, NULL, 0); + break; + case 'p': + info.page_size = strtol(optarg, NULL, 0); + break; + case 'o': + info.oob_size = strtol(optarg, NULL, 0); + break; + case 'u': + info.usable_page_size = strtol(optarg, NULL, 0); + break; + case 'e': + info.eraseblock_size = strtol(optarg, NULL, 0); + break; + case 'b': + info.boot0 = 1; + break; + case 'a': + info.offset = strtoull(optarg, NULL, 0); + break; + case '?': + display_help(-1); + break; + } + } + + if ((argc - optind) != 2) + display_help(-1); + + info.source = argv[optind]; + info.dest = argv[optind + 1]; + + if (!info.boot0) { + info.usable_page_size = info.page_size; + } else if (!info.usable_page_size) { + if (info.page_size > 8192) + info.usable_page_size = 8192; + else if (info.page_size > 4096) + info.usable_page_size = 4096; + else + info.usable_page_size = 1024; + } + + if (check_image_info(&info)) + display_help(-1); + + return create_image(&info); +}

The environment location is something that might change per board (depending on what storage options are availaible there) or depending on the user choice (when we have several options).
Instead of hardcoding it in our configuration header, create a Kconfig choice with the options we use for now, and the symbols that depend on it.
Once done, also remove the irrelevant sunxi defines.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- common/Kconfig | 65 +++++++++++++++++++++++++++++++++++- include/configs/sunxi-common.h | 14 +------- include/environment.h | 2 +- 3 files changed, 70 insertions(+), 11 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig index 913d21a9ec58..3aa63db98314 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -158,6 +158,71 @@ config SPI_BOOT
endmenu
+menu "Environment" + +choice + prompt "Environment Device" + default ENV_IS_IN_MMC if ARCH_SUNXI + +config ENV_IS_IN_MMC + bool "Environment in an MMC device" + depends on CMD_MMC + help + Define this if you have an MMC device which you want to use for the + environment. + +config ENV_IS_IN_NAND + bool "Environment in a NAND device" + depends on CMD_NAND + help + Define this if you have a NAND device which you want to use for the + environment. + +config ENV_IS_IN_UBI + bool "Environment in a UBI volume" + depends on CMD_UBI + depends on CMD_MTDPARTS + help + Define this if you have a UBI volume which you want to use for the + environment. + +config ENV_IS_NOWHERE + bool "Environment is not stored" + help + Define this if you don't want to or can't have an environment stored + on a storage medium + +endchoice + +config ENV_OFFSET + hex "Environment Offset" + depends on !ENV_IS_IN_UBI + depends on !ENV_IS_NOWHERE + default 0x88000 if ARCH_SUNXI + help + Offset from the start of the device (or partition) + +config ENV_SIZE + hex "Environment Size" + depends on !ENV_IS_NOWHERE + default 0x20000 if ARCH_SUNXI + help + Size of the environment storage area + +config ENV_UBI_PART + string "UBI partition name" + depends on ENV_IS_IN_UBI + help + MTD partition containing the UBI device + +config ENV_UBI_VOLUME + string "UBI volume name" + depends on ENV_IS_IN_UBI + help + Name of the volume that you want to store the environment in. + +endmenu + config BOOTDELAY int "delay in seconds before automatically booting" default 2 diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 8363414828fa..fd2677ba14a4 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -143,7 +143,9 @@ #define CONFIG_GENERIC_MMC #define CONFIG_MMC_SUNXI #define CONFIG_MMC_SUNXI_SLOT 0 -#define CONFIG_ENV_IS_IN_MMC +#endif + +#if defined(CONFIG_ENV_IS_IN_MMC) #define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ #endif
@@ -175,9 +177,6 @@
#define CONFIG_SYS_MONITOR_LEN (768 << 10) /* 768 KiB */
-#define CONFIG_ENV_OFFSET (544 << 10) /* (8 + 24 + 512) KiB */ -#define CONFIG_ENV_SIZE (128 << 10) /* 128 KiB */ - #define CONFIG_FAT_WRITE /* enable write access */
#define CONFIG_SPL_FRAMEWORK @@ -349,13 +348,6 @@ extern int soft_i2c_gpio_scl; #define CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE #endif
-#if !defined CONFIG_ENV_IS_IN_MMC && \ - !defined CONFIG_ENV_IS_IN_NAND && \ - !defined CONFIG_ENV_IS_IN_FAT && \ - !defined CONFIG_ENV_IS_IN_SPI_FLASH -#define CONFIG_ENV_IS_NOWHERE -#endif - #define CONFIG_MISC_INIT_R
#ifndef CONFIG_SPL_BUILD diff --git a/include/environment.h b/include/environment.h index b602e8ac46b6..6f94986c6b3e 100644 --- a/include/environment.h +++ b/include/environment.h @@ -8,6 +8,8 @@ #ifndef _ENVIRONMENT_H_ #define _ENVIRONMENT_H_
+#include <linux/kconfig.h> + /************************************************************************** * * The "environment" is stored as a list of '\0' terminated

On Tue, Nov 22, 2016 at 01:38:35PM +0100, Maxime Ripard wrote:
The environment location is something that might change per board (depending on what storage options are availaible there) or depending on the user choice (when we have several options).
Instead of hardcoding it in our configuration header, create a Kconfig choice with the options we use for now, and the symbols that depend on it.
Once done, also remove the irrelevant sunxi defines.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
Reviewed-by: Tom Rini trini@konsulko.com

CMD_MTDPARTS is something the user might or might not want to select, and might depends on (or be selected by) other options too.
This is even truer for the MTDIDS_DEFAULT and MTDPARTS_DEFAULT options that might change from one board to another, or from one user to the other, depending on what it expects and what storage devices are available.
In order to ease that configuration, add those options to Kconfig.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- cmd/Kconfig | 19 +++++++++++++++++++ cmd/mtdparts.c | 8 ++++++++ 2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/cmd/Kconfig b/cmd/Kconfig index e339d8638aa5..cd98e2a2bd00 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -717,6 +717,25 @@ config CMD_FS_GENERIC help Enables filesystem commands (e.g. load, ls) that work for multiple fs types. + +config CMD_MTDPARTS + bool "MTD partition support" + help + MTD partition support + +config MTDIDS_DEFAULT + string "Default MTD IDs" + depends on CMD_MTDPARTS + help + Defines a default MTD ID + +config MTDPARTS_DEFAULT + string "Default MTD partition scheme" + depends on CMD_MTDPARTS + help + Defines a default MTD partitioning scheme in the Linux MTD command + line partitions format + endmenu
config CMD_UBI diff --git a/cmd/mtdparts.c b/cmd/mtdparts.c index b9b160dc1e2f..112bf1f3e3cd 100644 --- a/cmd/mtdparts.c +++ b/cmd/mtdparts.c @@ -110,11 +110,19 @@ DECLARE_GLOBAL_DATA_PTR;
/* default values for mtdids and mtdparts variables */ #if !defined(MTDIDS_DEFAULT) +#ifdef CONFIG_MTDIDS_DEFAULT +#define MTDIDS_DEFAULT CONFIG_MTDIDS_DEFAULT +#else #define MTDIDS_DEFAULT NULL #endif +#endif #if !defined(MTDPARTS_DEFAULT) +#ifdef CONFIG_MTDPARTS_DEFAULT +#define MTDPARTS_DEFAULT CONFIG_MTDPARTS_DEFAULT +#else #define MTDPARTS_DEFAULT NULL #endif +#endif #if defined(CONFIG_SYS_MTDPARTS_RUNTIME) extern void board_mtdparts_default(const char **mtdids, const char **mtdparts); #endif

On Tue, Nov 22, 2016 at 01:38:36PM +0100, Maxime Ripard wrote:
CMD_MTDPARTS is something the user might or might not want to select, and might depends on (or be selected by) other options too.
This is even truer for the MTDIDS_DEFAULT and MTDPARTS_DEFAULT options that might change from one board to another, or from one user to the other, depending on what it expects and what storage devices are available.
In order to ease that configuration, add those options to Kconfig.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
Reviewed-by: Tom Rini trini@konsulko.com

Hi Maxime,
On Tue, 22 Nov 2016 13:38:36 +0100 Maxime Ripard maxime.ripard@free-electrons.com wrote:
CMD_MTDPARTS is something the user might or might not want to select, and might depends on (or be selected by) other options too.
This is even truer for the MTDIDS_DEFAULT and MTDPARTS_DEFAULT options that might change from one board to another, or from one user to the other, depending on what it expects and what storage devices are available.
In order to ease that configuration, add those options to Kconfig.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
cmd/Kconfig | 19 +++++++++++++++++++ cmd/mtdparts.c | 8 ++++++++ 2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/cmd/Kconfig b/cmd/Kconfig index e339d8638aa5..cd98e2a2bd00 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -717,6 +717,25 @@ config CMD_FS_GENERIC help Enables filesystem commands (e.g. load, ls) that work for multiple fs types.
+config CMD_MTDPARTS
- bool "MTD partition support"
depends on MTD
Also, it seems that MTD_DEVICE and MTD_PARTITIONS still have to be defined in the board/soc config header, which is kind of disturbing.
I modified the patch (see below) to add hidden MTD_DEVICE and MTD_PARTITIONS options and select them from MTDPARTS. This way you can get rid of all MTD related definitions in sunxi-common.h.
I also have 3 more patches [1][2][3] to expose UBIFS and NAND suboptions through Kconfig in order to get rid of the extra definitions you add in sunxi-common.h (patch 9). Let me know if you want me to send them separately, otherwise, you can include them in your series.
Regards,
Boris
[1]http://code.bulix.org/l9ca0i-107843 [2]http://code.bulix.org/29dzqe-107844 [3]http://code.bulix.org/hp7y46-107845
--->8--- From 55ff74860374b32df1e4073227d2a9aa39873459 Mon Sep 17 00:00:00 2001 From: Maxime Ripard maxime.ripard@free-electrons.com Date: Tue, 22 Nov 2016 13:38:36 +0100 Subject: [PATCH] cmd: Add Kconfig option for CMD_MTDPARTS and related options
CMD_MTDPARTS is something the user might or might not want to select, and might depends on (or be selected by) other options too. Add the hidden MTD_DEVICE and MTD_PARTITIONS options and select them from CMD_MTDPARTS since they are required to properly expose MTD devices and partitions to various users, including mtdparts.
This is even truer for the MTDIDS_DEFAULT and MTDPARTS_DEFAULT options that might change from one board to another, or from one user to the other, depending on what it expects and what storage devices are available.
In order to ease that configuration, add those options to Kconfig.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- cmd/Kconfig | 22 ++++++++++++++++++++++ cmd/mtdparts.c | 8 ++++++++ drivers/mtd/Kconfig | 8 ++++++++ 3 files changed, 38 insertions(+)
diff --git a/cmd/Kconfig b/cmd/Kconfig index 91bd3fb0b58e..05afc2864744 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -763,6 +763,28 @@ config CMD_FS_GENERIC help Enables filesystem commands (e.g. load, ls) that work for multiple fs types. + +config CMD_MTDPARTS + bool "MTD partition support" + depends on MTD + select MTD_DEVICE + select MTD_PARTITIONS + help + MTD partition support + +config MTDIDS_DEFAULT + string "Default MTD IDs" + depends on CMD_MTDPARTS + help + Defines a default MTD ID + +config MTDPARTS_DEFAULT + string "Default MTD partition scheme" + depends on CMD_MTDPARTS + help + Defines a default MTD partitioning scheme in the Linux MTD command + line partitions format + endmenu
config CMD_UBI diff --git a/cmd/mtdparts.c b/cmd/mtdparts.c index b9b160dc1e2f..112bf1f3e3cd 100644 --- a/cmd/mtdparts.c +++ b/cmd/mtdparts.c @@ -110,11 +110,19 @@ DECLARE_GLOBAL_DATA_PTR;
/* default values for mtdids and mtdparts variables */ #if !defined(MTDIDS_DEFAULT) +#ifdef CONFIG_MTDIDS_DEFAULT +#define MTDIDS_DEFAULT CONFIG_MTDIDS_DEFAULT +#else #define MTDIDS_DEFAULT NULL #endif +#endif #if !defined(MTDPARTS_DEFAULT) +#ifdef CONFIG_MTDPARTS_DEFAULT +#define MTDPARTS_DEFAULT CONFIG_MTDPARTS_DEFAULT +#else #define MTDPARTS_DEFAULT NULL #endif +#endif #if defined(CONFIG_SYS_MTDPARTS_RUNTIME) extern void board_mtdparts_default(const char **mtdids, const char **mtdparts); #endif diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 3a9705c41bdf..bebb2f78533e 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -35,6 +35,14 @@ config FLASH_PIC32 This enables access to Microchip PIC32 internal non-CFI flash chips through PIC32 Non-Volatile-Memory Controller.
+config MTD_DEVICE + bool + depends on MTD + +config MTD_PARTITIONS + bool + depends on MTD + endmenu
source "drivers/mtd/nand/Kconfig"

Hi Boris,
On Wed, Jan 04, 2017 at 10:10:56AM +0100, Boris Brezillon wrote:
Hi Maxime,
On Tue, 22 Nov 2016 13:38:36 +0100 Maxime Ripard maxime.ripard@free-electrons.com wrote:
CMD_MTDPARTS is something the user might or might not want to select, and might depends on (or be selected by) other options too.
This is even truer for the MTDIDS_DEFAULT and MTDPARTS_DEFAULT options that might change from one board to another, or from one user to the other, depending on what it expects and what storage devices are available.
In order to ease that configuration, add those options to Kconfig.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
cmd/Kconfig | 19 +++++++++++++++++++ cmd/mtdparts.c | 8 ++++++++ 2 files changed, 27 insertions(+), 0 deletions(-)
diff --git a/cmd/Kconfig b/cmd/Kconfig index e339d8638aa5..cd98e2a2bd00 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -717,6 +717,25 @@ config CMD_FS_GENERIC help Enables filesystem commands (e.g. load, ls) that work for multiple fs types.
+config CMD_MTDPARTS
- bool "MTD partition support"
depends on MTD
Also, it seems that MTD_DEVICE and MTD_PARTITIONS still have to be defined in the board/soc config header, which is kind of disturbing.
Indeed
I modified the patch (see below) to add hidden MTD_DEVICE and MTD_PARTITIONS options and select them from MTDPARTS. This way you can get rid of all MTD related definitions in sunxi-common.h.
I also have 3 more patches [1][2][3] to expose UBIFS and NAND suboptions through Kconfig in order to get rid of the extra definitions you add in sunxi-common.h (patch 9). Let me know if you want me to send them separately, otherwise, you can include them in your series.
Looks good. I won't have time to send them before a while, so feel free to send them separately.
Thanks! Maxime

We'll need that symbol so that the default offset are defined
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- drivers/mtd/nand/Kconfig | 1 + 1 file changed, 1 insertion(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index df154bfd32b9..2cc9e513d2e9 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -67,6 +67,7 @@ config NAND_SUNXI bool "Support for NAND on Allwinner SoCs" depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I select SYS_NAND_SELF_INIT + select SYS_NAND_U_BOOT_LOCATIONS ---help--- Enable support for NAND. This option enables the standard and SPL drivers.

The default U-Boot offset for the Allwinner SoCs was set to 32kB.
This was probably to try to maintain some compatibility with the current image that we build for the MMC where the U-Boot binary is also located at a 32kB offset.
However, this causes a number of issues. The first one is that it prevents us from using a backup SPL entirely, which is troublesome in case where the first would be corrupt (especially on MLC which have a higher number of bitflips).
We also cannot use the original MMC image on the NAND, because we need to prepare the SPL image to include the ECCs and randomizer settings, which reduces the interest of setting it at that particular offset.
It also prevents us from upgrading and flashing the U-Boot and SPLs independantly, since it's very likely that it will fall in the same erase block.
Since that default wasn't used by any board, change it for 8MB, which will be in an erase block of its own, all the erase blocks being multiple of two. The highest erase block size we encountered is 4MB, which means that in this particular setup, the first and second erase blocks will be for the SPL and its backup, and the third for U-Boot.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- drivers/mtd/nand/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 2cc9e513d2e9..505102440609 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -121,7 +121,7 @@ config SYS_NAND_U_BOOT_LOCATIONS
config SYS_NAND_U_BOOT_OFFS hex "Location in NAND to read U-Boot from" - default 0x8000 if NAND_SUNXI + default 0x800000 if NAND_SUNXI depends on SYS_NAND_U_BOOT_LOCATIONS help Set the offset from the start of the nand where u-boot should be

On Tue, Nov 22, 2016 at 01:38:38PM +0100, Maxime Ripard wrote:
The default U-Boot offset for the Allwinner SoCs was set to 32kB.
This was probably to try to maintain some compatibility with the current image that we build for the MMC where the U-Boot binary is also located at a 32kB offset.
However, this causes a number of issues. The first one is that it prevents us from using a backup SPL entirely, which is troublesome in case where the first would be corrupt (especially on MLC which have a higher number of bitflips).
We also cannot use the original MMC image on the NAND, because we need to prepare the SPL image to include the ECCs and randomizer settings, which reduces the interest of setting it at that particular offset.
It also prevents us from upgrading and flashing the U-Boot and SPLs independantly, since it's very likely that it will fall in the same erase block.
Since that default wasn't used by any board, change it for 8MB, which will be in an erase block of its own, all the erase blocks being multiple of two. The highest erase block size we encountered is 4MB, which means that in this particular setup, the first and second erase blocks will be for the SPL and its backup, and the third for U-Boot.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
Reviewed-by: Tom Rini trini@konsulko.com

From: Hans de Goede hdegoede@redhat.com
Enable the NAND and UBI support in the configuration header so that we can (finally) use it.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- board/sunxi/Kconfig | 8 ++++++++ include/configs/sunxi-common.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index e1d4ab148f08..c6a620a20167 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -460,6 +460,14 @@ config AXP_GPIO ---help--- Say Y here to enable support for the gpio pins of the axp PMIC ICs.
+if NAND_SUNXI +config CMD_NAND + default y + +config CMD_UBI + default y +endif + config VIDEO bool "Enable graphical uboot console on HDMI, LCD or VGA" depends on !MACH_SUN8I_A83T && !MACH_SUN8I_H3 && !MACH_SUN9I && !MACH_SUN50I diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index fd2677ba14a4..feedd9f8811b 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -132,6 +132,20 @@ #define CONFIG_SYS_NAND_MAX_ECCPOS 1664 #define CONFIG_SYS_NAND_ONFI_DETECTION #define CONFIG_SYS_MAX_NAND_DEVICE 8 + +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#endif + +#ifdef CONFIG_CMD_NAND +#define CONFIG_CMD_NAND_TRIMFFS +#endif + +#ifdef CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS + +#define CONFIG_RBTREE +#define CONFIG_LZO #endif
#ifdef CONFIG_SPL_SPI_SUNXI

On Tue, 22 Nov 2016 13:38:39 +0100 Maxime Ripard maxime.ripard@free-electrons.com wrote:
From: Hans de Goede hdegoede@redhat.com
Enable the NAND and UBI support in the configuration header so that we can (finally) use it.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
board/sunxi/Kconfig | 8 ++++++++ include/configs/sunxi-common.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index e1d4ab148f08..c6a620a20167 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -460,6 +460,14 @@ config AXP_GPIO ---help--- Say Y here to enable support for the gpio pins of the axp PMIC ICs.
+if NAND_SUNXI +config CMD_NAND
- default y
+config CMD_UBI
- default y
+endif
config VIDEO bool "Enable graphical uboot console on HDMI, LCD or VGA" depends on !MACH_SUN8I_A83T && !MACH_SUN8I_H3 && !MACH_SUN9I && !MACH_SUN50I diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index fd2677ba14a4..feedd9f8811b 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -132,6 +132,20 @@ #define CONFIG_SYS_NAND_MAX_ECCPOS 1664 #define CONFIG_SYS_NAND_ONFI_DETECTION #define CONFIG_SYS_MAX_NAND_DEVICE 8
+#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#endif
+#ifdef CONFIG_CMD_NAND +#define CONFIG_CMD_NAND_TRIMFFS +#endif
+#ifdef CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS
+#define CONFIG_RBTREE +#define CONFIG_LZO #endif
#ifdef CONFIG_SPL_SPI_SUNXI
Shouldn't we add all these MTD/NAND/UBI/UBIFS related options in Kconfig too?

On Tue, Nov 22, 2016 at 01:38:39PM +0100, Maxime Ripard wrote:
From: Hans de Goede hdegoede@redhat.com
Enable the NAND and UBI support in the configuration header so that we can (finally) use it.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
board/sunxi/Kconfig | 8 ++++++++ include/configs/sunxi-common.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index e1d4ab148f08..c6a620a20167 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -460,6 +460,14 @@ config AXP_GPIO ---help--- Say Y here to enable support for the gpio pins of the axp PMIC ICs.
+if NAND_SUNXI +config CMD_NAND
- default y
+config CMD_UBI
- default y
+endif
We want to move away from adding 'default y' to board/*/Kconfig and instead have 'default y if ...' where the option is declared. In this particular case we have a TODO of adding a NAND option that would be used to hide things like CMD_NAND and other sub-sections rather than using CMD_NAND for everything.
That said, we've just got 2 sunxi boards with NAND today right? Maybe we shouldn't make this default for all sunxi boards yet, yes? Thanks!

On Tue, Nov 22, 2016 at 3:24 PM, Tom Rini trini@konsulko.com wrote:
On Tue, Nov 22, 2016 at 01:38:39PM +0100, Maxime Ripard wrote:
From: Hans de Goede hdegoede@redhat.com
Enable the NAND and UBI support in the configuration header so that we can (finally) use it.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
board/sunxi/Kconfig | 8 ++++++++ include/configs/sunxi-common.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index e1d4ab148f08..c6a620a20167 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -460,6 +460,14 @@ config AXP_GPIO ---help--- Say Y here to enable support for the gpio pins of the axp PMIC ICs.
+if NAND_SUNXI +config CMD_NAND
default y
+config CMD_UBI
default y
+endif
We want to move away from adding 'default y' to board/*/Kconfig and instead have 'default y if ...' where the option is declared. In this particular case we have a TODO of adding a NAND option that would be used to hide things like CMD_NAND and other sub-sections rather than using CMD_NAND for everything.
That said, we've just got 2 sunxi boards with NAND today right? Maybe we shouldn't make this default for all sunxi boards yet, yes? Thanks!
There might be a few more (I think CubieTruck has onboard nand for example) but at least in Fedora we don't support any of the devices running nand because of the support in generally isn't great yet.
Peter

Hi Tom,
On Tue, Nov 22, 2016 at 10:24:27AM -0500, Tom Rini wrote:
On Tue, Nov 22, 2016 at 01:38:39PM +0100, Maxime Ripard wrote:
From: Hans de Goede hdegoede@redhat.com
Enable the NAND and UBI support in the configuration header so that we can (finally) use it.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
board/sunxi/Kconfig | 8 ++++++++ include/configs/sunxi-common.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index e1d4ab148f08..c6a620a20167 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -460,6 +460,14 @@ config AXP_GPIO ---help--- Say Y here to enable support for the gpio pins of the axp PMIC ICs.
+if NAND_SUNXI +config CMD_NAND
- default y
+config CMD_UBI
- default y
+endif
We want to move away from adding 'default y' to board/*/Kconfig and instead have 'default y if ...' where the option is declared.
Yeah, I wasn't really sure about this. You can find the two constructs in there. But ok, that's noted :)
In this particular case we have a TODO of adding a NAND option that would be used to hide things like CMD_NAND and other sub-sections rather than using CMD_NAND for everything.
Ok.
That said, we've just got 2 sunxi boards with NAND today right? Maybe we shouldn't make this default for all sunxi boards yet, yes? Thanks!
Not really. The huge majority of the rather old boards (basically everything older than a year or so) is using NAND. However, they're all using MLC NANDs, which are not supported into UBI right now.
The CHIP Pro is the only board with an Allwinner SoC and an SLC NAND, hence why we can enable the NAND support.
However, in both cases (MLC and SLC), we'll need UBI. In the former because other filesystems will not be reliable, in the latter because the NAND is quite huge and the other filesystems would take an insane amount of time to be accessed.
Maxime

On Tue, Nov 22, 2016 at 04:54:53PM +0100, Maxime Ripard wrote:
Hi Tom,
On Tue, Nov 22, 2016 at 10:24:27AM -0500, Tom Rini wrote:
On Tue, Nov 22, 2016 at 01:38:39PM +0100, Maxime Ripard wrote:
From: Hans de Goede hdegoede@redhat.com
Enable the NAND and UBI support in the configuration header so that we can (finally) use it.
Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
board/sunxi/Kconfig | 8 ++++++++ include/configs/sunxi-common.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index e1d4ab148f08..c6a620a20167 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -460,6 +460,14 @@ config AXP_GPIO ---help--- Say Y here to enable support for the gpio pins of the axp PMIC ICs.
+if NAND_SUNXI +config CMD_NAND
- default y
+config CMD_UBI
- default y
+endif
We want to move away from adding 'default y' to board/*/Kconfig and instead have 'default y if ...' where the option is declared.
Yeah, I wasn't really sure about this. You can find the two constructs in there. But ok, that's noted :)
In this particular case we have a TODO of adding a NAND option that would be used to hide things like CMD_NAND and other sub-sections rather than using CMD_NAND for everything.
Ok.
That said, we've just got 2 sunxi boards with NAND today right? Maybe we shouldn't make this default for all sunxi boards yet, yes? Thanks!
Not really. The huge majority of the rather old boards (basically everything older than a year or so) is using NAND. However, they're all using MLC NANDs, which are not supported into UBI right now.
Ah, good to know, OK. So v2, default y if ARCH_SUNXI on cmd/Kconfig :)

In order for the user to be able to see and modify them, add those variables to the default environment.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com --- include/configs/sunxi-common.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+), 0 deletions(-)
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index feedd9f8811b..93411bebd9f5 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -491,6 +491,20 @@ extern int soft_i2c_gpio_scl; "stderr=serial\0" #endif
+#ifdef CONFIG_MTDIDS_DEFAULT +#define SUNXI_MTDIDS_DEFAULT \ + "mtdids=" CONFIG_MTDIDS_DEFAULT "\0" +#else +#define SUNXI_MTDIDS_DEFAULT +#endif + +#ifdef CONFIG_MTDPARTS_DEFAULT +#define SUNXI_MTDPARTS_DEFAULT \ + "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" +#else +#define SUNXI_MTDPARTS_DEFAULT +#endif + #define CONSOLE_ENV_SETTINGS \ CONSOLE_STDIN_SETTINGS \ CONSOLE_STDOUT_SETTINGS @@ -501,6 +515,8 @@ extern int soft_i2c_gpio_scl; DFU_ALT_INFO_RAM \ "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ "console=ttyS0,115200\0" \ + SUNXI_MTDIDS_DEFAULT \ + SUNXI_MTDPARTS_DEFAULT \ BOOTCMD_SUNXI_COMPAT \ BOOTENV

On Tue, Nov 22, 2016 at 01:38:40PM +0100, Maxime Ripard wrote:
In order for the user to be able to see and modify them, add those variables to the default environment.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com
Reviewed-by: Tom Rini trini@konsulko.com

The SPL image needs to be built with a different ECC configuration than the U-Boot binary.
Add Kconfig options with defaults to provide a value that should work for anyone, but is still configurable if needs be.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Acked-by: Boris Brezillon boris.brezillon@free-electrons.com Reviewed-by: Hans de Goede hdegoede@redhat.com Acked-by: Scott Wood oss@buserror.net --- drivers/mtd/nand/Kconfig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 505102440609..9b98e11babf2 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -74,6 +74,22 @@ config NAND_SUNXI The SPL driver only supports reading from the NAND using DMA transfers.
+if NAND_SUNXI + +config NAND_SUNXI_SPL_ECC_STRENGTH + int "Allwinner NAND SPL ECC Strength" + default 64 + +config NAND_SUNXI_SPL_ECC_SIZE + int "Allwinner NAND SPL ECC Step Size" + default 1024 + +config NAND_SUNXI_SPL_USABLE_PAGE_SIZE + int "Allwinner NAND SPL Usable Page Size" + default 1024 + +endif + config NAND_ARASAN bool "Configure Arasan Nand" help

Introduce a new sunxi-spl-with-ecc.bin image with already the right header, ECC, randomizer and padding for the BROM to be able to read it.
It needs to be flashed using a raw access to the NAND so that the controller doesn't change a thing to it, since we already have all the right parameters.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Acked-by: Boris Brezillon boris.brezillon@free-electrons.com --- Makefile | 3 ++- board/sunxi/README.nand | 54 ++++++++++++++++++++++++++++++++++++++++++- scripts/Makefile.spl | 15 ++++++++++++- 3 files changed, 72 insertions(+), 0 deletions(-) create mode 100644 board/sunxi/README.nand
diff --git a/Makefile b/Makefile index 37cbcb28f75e..12a248e297b5 100644 --- a/Makefile +++ b/Makefile @@ -1345,6 +1345,9 @@ spl/u-boot-spl: tools prepare \ spl/sunxi-spl.bin: spl/u-boot-spl @:
+spl/sunxi-spl-with-ecc.bin: spl/sunxi-spl.bin + @: + spl/u-boot-spl.sfp: spl/u-boot-spl @:
diff --git a/board/sunxi/README.nand b/board/sunxi/README.nand new file mode 100644 index 000000000000..a5d4ff0e90a3 --- /dev/null +++ b/board/sunxi/README.nand @@ -0,0 +1,54 @@ +Allwinner NAND flashing +======================= + +A lot of Allwinner devices, especially the older ones (pre-H3 era), +comes with a NAND. NANDs storages are a pretty weak choice when it +comes to the reliability, and it comes with a number of flaws like +read and write disturbs, data retention issues, bloks becoming +unusable, etc. + +In order to mitigate that, various strategies have been found to be +able to recover from those issues like ECC, hardware randomization, +and of course, redundancy for the critical parts. + +This is obviously something that we will take into account when +creating our images. However, the BROM will use a quite weird pattern +when accessing the NAND, and will access only at most 4kB per page, +which means that we also have to split that binary accross several +pages. + +In order to accomodate that, we create a tool that will generate an +SPL image that is ready to be programmed directly embedding the ECCs, +randomized, and with the necessary bits needed to reduce the number of +bitflips. The U-Boot build system, when configured for the NAND will +also generate the image sunxi-spl-with-ecc.bin that will have been +generated by that tool. + +In order to flash your U-Boot image onto a board, assuming that the +board is in FEL mode, you'll need the sunxi-tools that you can find at +this repository: https://github.com/linux-sunxi/sunxi-tools + +Then, you'll need to first load an SPL to initialise the RAM: +sunxi-fel spl spl/sunxi-spl.bin + +Load the binaries we'll flash into RAM: +sunxi-fel write 0x4a000000 u-boot-dtb.bin +sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin + +And execute U-Boot +sunxi-fel exe 0x4a000000 + +On your board, you'll now have all the needed binaries into RAM, so +you only need to erase the NAND... + +nand erase.chip + +Then write the SPL and its backup: + +nand write.raw.noverify 0x43000000 0 40 +nand write.raw.noverify 0x43000000 0x400000 40 + +And finally write the U-Boot binary: +nand write 0x4a000000 0x800000 0xc0000 + +You can now reboot and enjoy your NAND. \ No newline at end of file diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index e0b0117dc9b6..6a381f26d21a 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -168,6 +168,10 @@ endif
ifdef CONFIG_ARCH_SUNXI ALL-y += $(obj)/sunxi-spl.bin + +ifdef CONFIG_NAND_SUNXI +ALL-y += $(obj)/sunxi-spl-with-ecc.bin +endif endif
ifeq ($(CONFIG_SYS_SOC),"at91") @@ -276,6 +280,17 @@ cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@ $(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE $(call if_changed,mksunxiboot)
+quiet_cmd_sunxi_spl_image_builder = SUNXI_SPL_IMAGE_BUILDER $@ +cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \ + -c $(CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH)/$(CONFIG_NAND_SUNXI_SPL_ECC_SIZE) \ + -p $(CONFIG_SYS_NAND_PAGE_SIZE) \ + -o $(CONFIG_SYS_NAND_OOBSIZE) \ + -u $(CONFIG_NAND_SUNXI_SPL_USABLE_PAGE_SIZE) \ + -e $(CONFIG_SYS_NAND_BLOCK_SIZE) \ + -s -b $< $@ +$(obj)/sunxi-spl-with-ecc.bin: $(obj)/sunxi-spl.bin + $(call if_changed,sunxi_spl_image_builder) + # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk quiet_cmd_u-boot-spl ?= LD $@

On Tue, 22 Nov 2016 13:38:42 +0100 Maxime Ripard maxime.ripard@free-electrons.com wrote:
Introduce a new sunxi-spl-with-ecc.bin image with already the right header, ECC, randomizer and padding for the BROM to be able to read it.
It needs to be flashed using a raw access to the NAND so that the controller doesn't change a thing to it, since we already have all the right parameters.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Acked-by: Boris Brezillon boris.brezillon@free-electrons.com
Makefile | 3 ++- board/sunxi/README.nand | 54 ++++++++++++++++++++++++++++++++++++++++++- scripts/Makefile.spl | 15 ++++++++++++- 3 files changed, 72 insertions(+), 0 deletions(-) create mode 100644 board/sunxi/README.nand
diff --git a/Makefile b/Makefile index 37cbcb28f75e..12a248e297b5 100644 --- a/Makefile +++ b/Makefile @@ -1345,6 +1345,9 @@ spl/u-boot-spl: tools prepare \ spl/sunxi-spl.bin: spl/u-boot-spl @:
+spl/sunxi-spl-with-ecc.bin: spl/sunxi-spl.bin
- @:
spl/u-boot-spl.sfp: spl/u-boot-spl @:
diff --git a/board/sunxi/README.nand b/board/sunxi/README.nand new file mode 100644 index 000000000000..a5d4ff0e90a3 --- /dev/null +++ b/board/sunxi/README.nand @@ -0,0 +1,54 @@ +Allwinner NAND flashing +=======================
+A lot of Allwinner devices, especially the older ones (pre-H3 era), +comes with a NAND. NANDs storages are a pretty weak choice when it +comes to the reliability, and it comes with a number of flaws like +read and write disturbs, data retention issues, bloks becoming +unusable, etc.
+In order to mitigate that, various strategies have been found to be +able to recover from those issues like ECC, hardware randomization, +and of course, redundancy for the critical parts.
+This is obviously something that we will take into account when +creating our images. However, the BROM will use a quite weird pattern +when accessing the NAND, and will access only at most 4kB per page, +which means that we also have to split that binary accross several +pages.
+In order to accomodate that, we create a tool that will generate an +SPL image that is ready to be programmed directly embedding the ECCs, +randomized, and with the necessary bits needed to reduce the number of +bitflips. The U-Boot build system, when configured for the NAND will +also generate the image sunxi-spl-with-ecc.bin that will have been +generated by that tool.
+In order to flash your U-Boot image onto a board, assuming that the +board is in FEL mode, you'll need the sunxi-tools that you can find at +this repository: https://github.com/linux-sunxi/sunxi-tools
+Then, you'll need to first load an SPL to initialise the RAM: +sunxi-fel spl spl/sunxi-spl.bin
+Load the binaries we'll flash into RAM: +sunxi-fel write 0x4a000000 u-boot-dtb.bin +sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin
+And execute U-Boot +sunxi-fel exe 0x4a000000
+On your board, you'll now have all the needed binaries into RAM, so +you only need to erase the NAND...
+nand erase.chip
+Then write the SPL and its backup:
+nand write.raw.noverify 0x43000000 0 40 +nand write.raw.noverify 0x43000000 0x400000 40
+And finally write the U-Boot binary: +nand write 0x4a000000 0x800000 0xc0000
+You can now reboot and enjoy your NAND. \ No newline at end of file diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index e0b0117dc9b6..6a381f26d21a 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -168,6 +168,10 @@ endif
ifdef CONFIG_ARCH_SUNXI ALL-y += $(obj)/sunxi-spl.bin
+ifdef CONFIG_NAND_SUNXI +ALL-y += $(obj)/sunxi-spl-with-ecc.bin +endif endif
ifeq ($(CONFIG_SYS_SOC),"at91") @@ -276,6 +280,17 @@ cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@ $(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE $(call if_changed,mksunxiboot)
+quiet_cmd_sunxi_spl_image_builder = SUNXI_SPL_IMAGE_BUILDER $@ +cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \
-c $(CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH)/$(CONFIG_NAND_SUNXI_SPL_ECC_SIZE) \
-p $(CONFIG_SYS_NAND_PAGE_SIZE) \
-o $(CONFIG_SYS_NAND_OOBSIZE) \
-u $(CONFIG_NAND_SUNXI_SPL_USABLE_PAGE_SIZE) \
-e $(CONFIG_SYS_NAND_BLOCK_SIZE) \
-s -b $< $@
Maybe you should define default values for SYS_NAND_PAGE_SIZE, SYS_NAND_OOBSIZE and SYS_NAND_BLOCK_SIZE in case the SYS_EXTRA_OPTIONS option does not contain these definitions in order to avoid build failures.
+$(obj)/sunxi-spl-with-ecc.bin: $(obj)/sunxi-spl.bin
- $(call if_changed,sunxi_spl_image_builder)
# Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk quiet_cmd_u-boot-spl ?= LD $@

Hello Maxime,
Am 22.11.2016 um 13:38 schrieb Maxime Ripard:
Introduce a new sunxi-spl-with-ecc.bin image with already the right header, ECC, randomizer and padding for the BROM to be able to read it.
It needs to be flashed using a raw access to the NAND so that the controller doesn't change a thing to it, since we already have all the right parameters.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Acked-by: Boris Brezillon boris.brezillon@free-electrons.com
Makefile | 3 ++- board/sunxi/README.nand | 54 ++++++++++++++++++++++++++++++++++++++++++- scripts/Makefile.spl | 15 ++++++++++++- 3 files changed, 72 insertions(+), 0 deletions(-) create mode 100644 board/sunxi/README.nand
Thanks for adding a README.
Reviewed-by: Heiko Schocher hs@denx.de
bye, Heiko
diff --git a/Makefile b/Makefile index 37cbcb28f75e..12a248e297b5 100644 --- a/Makefile +++ b/Makefile @@ -1345,6 +1345,9 @@ spl/u-boot-spl: tools prepare \ spl/sunxi-spl.bin: spl/u-boot-spl @:
+spl/sunxi-spl-with-ecc.bin: spl/sunxi-spl.bin
- @:
- spl/u-boot-spl.sfp: spl/u-boot-spl @:
diff --git a/board/sunxi/README.nand b/board/sunxi/README.nand new file mode 100644 index 000000000000..a5d4ff0e90a3 --- /dev/null +++ b/board/sunxi/README.nand @@ -0,0 +1,54 @@ +Allwinner NAND flashing +=======================
+A lot of Allwinner devices, especially the older ones (pre-H3 era), +comes with a NAND. NANDs storages are a pretty weak choice when it +comes to the reliability, and it comes with a number of flaws like +read and write disturbs, data retention issues, bloks becoming +unusable, etc.
+In order to mitigate that, various strategies have been found to be +able to recover from those issues like ECC, hardware randomization, +and of course, redundancy for the critical parts.
+This is obviously something that we will take into account when +creating our images. However, the BROM will use a quite weird pattern +when accessing the NAND, and will access only at most 4kB per page, +which means that we also have to split that binary accross several +pages.
+In order to accomodate that, we create a tool that will generate an +SPL image that is ready to be programmed directly embedding the ECCs, +randomized, and with the necessary bits needed to reduce the number of +bitflips. The U-Boot build system, when configured for the NAND will +also generate the image sunxi-spl-with-ecc.bin that will have been +generated by that tool.
+In order to flash your U-Boot image onto a board, assuming that the +board is in FEL mode, you'll need the sunxi-tools that you can find at +this repository: https://github.com/linux-sunxi/sunxi-tools
+Then, you'll need to first load an SPL to initialise the RAM: +sunxi-fel spl spl/sunxi-spl.bin
+Load the binaries we'll flash into RAM: +sunxi-fel write 0x4a000000 u-boot-dtb.bin +sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin
+And execute U-Boot +sunxi-fel exe 0x4a000000
+On your board, you'll now have all the needed binaries into RAM, so +you only need to erase the NAND...
+nand erase.chip
+Then write the SPL and its backup:
+nand write.raw.noverify 0x43000000 0 40 +nand write.raw.noverify 0x43000000 0x400000 40
+And finally write the U-Boot binary: +nand write 0x4a000000 0x800000 0xc0000
+You can now reboot and enjoy your NAND. \ No newline at end of file diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index e0b0117dc9b6..6a381f26d21a 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -168,6 +168,10 @@ endif
ifdef CONFIG_ARCH_SUNXI ALL-y += $(obj)/sunxi-spl.bin
+ifdef CONFIG_NAND_SUNXI +ALL-y += $(obj)/sunxi-spl-with-ecc.bin +endif endif
ifeq ($(CONFIG_SYS_SOC),"at91") @@ -276,6 +280,17 @@ cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@ $(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin FORCE $(call if_changed,mksunxiboot)
+quiet_cmd_sunxi_spl_image_builder = SUNXI_SPL_IMAGE_BUILDER $@ +cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \
-c $(CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH)/$(CONFIG_NAND_SUNXI_SPL_ECC_SIZE) \
-p $(CONFIG_SYS_NAND_PAGE_SIZE) \
-o $(CONFIG_SYS_NAND_OOBSIZE) \
-u $(CONFIG_NAND_SUNXI_SPL_USABLE_PAGE_SIZE) \
-e $(CONFIG_SYS_NAND_BLOCK_SIZE) \
-s -b $< $@
+$(obj)/sunxi-spl-with-ecc.bin: $(obj)/sunxi-spl.bin
- $(call if_changed,sunxi_spl_image_builder)
- # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk quiet_cmd_u-boot-spl ?= LD $@

Those DT will be part of 4.10, sync them so we can have our own config.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Reviewed-by: Hans de Goede hdegoede@redhat.com --- arch/arm/dts/Makefile | 1 +- arch/arm/dts/axp209.dtsi | 6 +- arch/arm/dts/ntc-gr8-chip-pro.dts | 266 +++++++- arch/arm/dts/ntc-gr8.dtsi | 1132 ++++++++++++++++++++++++++++++- 4 files changed, 1405 insertions(+), 0 deletions(-) create mode 100644 arch/arm/dts/ntc-gr8-chip-pro.dts create mode 100644 arch/arm/dts/ntc-gr8.dtsi
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 836a8c4d1ee2..932dbe07cf14 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -180,6 +180,7 @@ dtb-$(CONFIG_MACH_SUN4I) += \ sun4i-a10-pcduino2.dtb \ sun4i-a10-pov-protab2-ips9.dtb dtb-$(CONFIG_MACH_SUN5I) += \ + ntc-gr8-chip-pro.dtb \ sun5i-a10s-auxtek-t003.dtb \ sun5i-a10s-auxtek-t004.dtb \ sun5i-a10s-mk802.dtb \ diff --git a/arch/arm/dts/axp209.dtsi b/arch/arm/dts/axp209.dtsi index afbe89c01df5..675bb0f30825 100644 --- a/arch/arm/dts/axp209.dtsi +++ b/arch/arm/dts/axp209.dtsi @@ -53,6 +53,12 @@ interrupt-controller; #interrupt-cells = <1>;
+ axp_gpio: gpio { + compatible = "x-powers,axp209-gpio"; + gpio-controller; + #gpio-cells = <2>; + }; + regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <1500>; diff --git a/arch/arm/dts/ntc-gr8-chip-pro.dts b/arch/arm/dts/ntc-gr8-chip-pro.dts new file mode 100644 index 000000000000..c4be912df481 --- /dev/null +++ b/arch/arm/dts/ntc-gr8-chip-pro.dts @@ -0,0 +1,266 @@ +/* + * Copyright 2016 Free Electrons + * Copyright 2016 NextThing Co + * + * Maxime Ripard maxime.ripard@free-electrons.com + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "ntc-gr8.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + model = "NextThing C.H.I.P. Pro"; + compatible = "nextthing,chip-pro", "nextthing,gr8"; + + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + status { + label = "chip-pro:white:status"; + gpios = <&axp_gpio 2 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + mmc0_pwrseq: mmc0_pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_reg_on_pin_chip_pro>; + reset-gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; /* PB10 */ + }; +}; + +&codec { + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + + /* + * The interrupt is routed through the "External Fast + * Interrupt Request" pin (ball G13 of the module) + * directly to the main interrupt controller, without + * any other controller interfering. + */ + interrupts = <0>; + }; +}; + +#include "axp209.dtsi" + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "disabled"; +}; + +&i2s0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_mclk_pins_a>, <&i2s0_data_pins_a>; + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>; + vmmc-supply = <®_vcc3v3>; + mmc-pwrseq = <&mmc0_pwrseq>; + bus-width = <4>; + non-removable; + status = "okay"; +}; + +&nfc { + pinctrl-names = "default"; + pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>; + status = "okay"; + + nand@0 { + #address-cells = <2>; + #size-cells = <2>; + reg = <0>; + allwinner,rb = <0>; + nand-ecc-mode = "hw"; + }; +}; + +&ohci0 { + status = "okay"; +}; + +&otg_sram { + status = "okay"; +}; + +&pio { + usb0_id_pin_chip_pro: usb0-id-pin@0 { + allwinner,pins = "PG2"; + allwinner,function = "gpio_in"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + wifi_reg_on_pin_chip_pro: wifi-reg-on-pin@0 { + allwinner,pins = "PB10"; + allwinner,function = "gpio_out"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins>; + status = "disabled"; +}; + +®_dcdc2 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; + regulator-always-on; +}; + +®_dcdc3 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1300000>; + regulator-name = "vdd-sys"; + regulator-always-on; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3300000>; + regulator-name = "avcc"; + regulator-always-on; +}; + +/* + * Both LDO3 and LDO4 are used in parallel to power up the + * WiFi/BT chip. + */ +®_ldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-1"; + regulator-always-on; +}; + +®_ldo4 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi-2"; + regulator-always-on; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins_a>, <&uart2_cts_rts_pins_a>; + status = "disabled"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins_a>, <&uart3_cts_rts_pins_a>; + status = "okay"; +}; + +&usb_otg { + /* + * The CHIP Pro doesn't have a controllable VBUS, nor does it + * have any 5v rail on the board itself. + * + * If one wants to use it as a true OTG port, it should be + * done in the baseboard, and its DT / overlay will add it. + */ + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_pin_chip_pro>; + usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */ + usb0_vbus_power-supply = <&usb_power_supply>; + usb1_vbus-supply = <®_vcc5v0>; + status = "okay"; +}; diff --git a/arch/arm/dts/ntc-gr8.dtsi b/arch/arm/dts/ntc-gr8.dtsi new file mode 100644 index 000000000000..ea86d4d58db6 --- /dev/null +++ b/arch/arm/dts/ntc-gr8.dtsi @@ -0,0 +1,1132 @@ +/* + * Copyright 2016 Mylène Josserand + * + * Mylène Josserand mylene.josserand@free-electrons.com + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <dt-bindings/clock/sun4i-a10-pll2.h> +#include <dt-bindings/dma/sun4i-a10.h> +#include <dt-bindings/pinctrl/sun4i-a10.h> + +/ { + interrupt-parent = <&intc>; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a8"; + reg = <0x0>; + clocks = <&cpu>; + }; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* + * This is a dummy clock, to be used as placeholder on + * other mux clocks when a specific parent clock is not + * yet implemented. It should be dropped when the driver + * is complete. + */ + dummy: dummy { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + osc24M: clk@01c20050 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-osc-clk"; + reg = <0x01c20050 0x4>; + clock-frequency = <24000000>; + clock-output-names = "osc24M"; + }; + + osc3M: osc3M-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clocks = <&osc24M>; + clock-output-names = "osc3M"; + }; + + osc32k: clk@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "osc32k"; + }; + + pll1: clk@01c20000 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-pll1-clk"; + reg = <0x01c20000 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll1"; + }; + + pll2: clk@01c20008 { + #clock-cells = <1>; + compatible = "allwinner,sun5i-a13-pll2-clk"; + reg = <0x01c20008 0x8>; + clocks = <&osc24M>; + clock-output-names = "pll2-1x", "pll2-2x", + "pll2-4x", "pll2-8x"; + }; + + pll3: clk@01c20010 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-pll3-clk"; + reg = <0x01c20010 0x4>; + clocks = <&osc3M>; + clock-output-names = "pll3"; + }; + + pll3x2: pll3x2-clk { + compatible = "allwinner,sun4i-a10-pll3-2x-clk"; + #clock-cells = <0>; + clock-div = <1>; + clock-mult = <2>; + clocks = <&pll3>; + clock-output-names = "pll3-2x"; + }; + + pll4: clk@01c20018 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-pll1-clk"; + reg = <0x01c20018 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll4"; + }; + + pll5: clk@01c20020 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-pll5-clk"; + reg = <0x01c20020 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll5_ddr", "pll5_other"; + }; + + pll6: clk@01c20028 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-pll6-clk"; + reg = <0x01c20028 0x4>; + clocks = <&osc24M>; + clock-output-names = "pll6_sata", "pll6_other", "pll6"; + }; + + pll7: clk@01c20030 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-pll3-clk"; + reg = <0x01c20030 0x4>; + clocks = <&osc3M>; + clock-output-names = "pll7"; + }; + + pll7x2: pll7x2-clk { + compatible = "allwinner,sun4i-a10-pll3-2x-clk"; + #clock-cells = <0>; + clock-div = <1>; + clock-mult = <2>; + clocks = <&pll7>; + clock-output-names = "pll7-2x"; + }; + + /* dummy is 200M */ + cpu: cpu@01c20054 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-cpu-clk"; + reg = <0x01c20054 0x4>; + clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>; + clock-output-names = "cpu"; + }; + + axi: axi@01c20054 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-axi-clk"; + reg = <0x01c20054 0x4>; + clocks = <&cpu>; + clock-output-names = "axi"; + }; + + ahb: ahb@01c20054 { + #clock-cells = <0>; + compatible = "allwinner,sun5i-a13-ahb-clk"; + reg = <0x01c20054 0x4>; + clocks = <&axi>, <&cpu>, <&pll6 1>; + clock-output-names = "ahb"; + /* + * Use PLL6 as parent, instead of CPU/AXI + * which has rate changes due to cpufreq + */ + assigned-clocks = <&ahb>; + assigned-clock-parents = <&pll6 1>; + }; + + apb0: apb0@01c20054 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-apb0-clk"; + reg = <0x01c20054 0x4>; + clocks = <&ahb>; + clock-output-names = "apb0"; + }; + + apb1: clk@01c20058 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-apb1-clk"; + reg = <0x01c20058 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&osc32k>; + clock-output-names = "apb1"; + }; + + axi_gates: clk@01c2005c { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-gates-clk"; + reg = <0x01c2005c 0x4>; + clocks = <&axi>; + clock-indices = <0>; + clock-output-names = "axi_dram"; + }; + + ahb_gates: clk@01c20060 { + #clock-cells = <1>; + compatible = "allwinner,sun5i-a13-ahb-gates-clk"; + reg = <0x01c20060 0x8>; + clocks = <&ahb>; + clock-indices = <0>, <1>, + <2>, <5>, <6>, + <7>, <8>, <9>, + <10>, <13>, + <14>, <17>, <20>, + <21>, <22>, + <28>, <32>, <34>, + <36>, <40>, <44>, + <46>, <51>, + <52>; + clock-output-names = "ahb_usbotg", "ahb_ehci", + "ahb_ohci", "ahb_ss", "ahb_dma", + "ahb_bist", "ahb_mmc0", "ahb_mmc1", + "ahb_mmc2", "ahb_nand", + "ahb_sdram", "ahb_emac", "ahb_spi0", + "ahb_spi1", "ahb_spi2", + "ahb_hstimer", "ahb_ve", "ahb_tve", + "ahb_lcd", "ahb_csi", "ahb_de_be", + "ahb_de_fe", "ahb_iep", + "ahb_mali400"; + }; + + apb0_gates: clk@01c20068 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-gates-clk"; + reg = <0x01c20068 0x4>; + clocks = <&apb0>; + clock-indices = <0>, <3>, + <5>, <6>; + clock-output-names = "apb0_codec", "apb0_i2s0", + "apb0_pio", "apb0_ir"; + }; + + apb1_gates: clk@01c2006c { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-gates-clk"; + reg = <0x01c2006c 0x4>; + clocks = <&apb1>; + clock-indices = <0>, <1>, + <2>, <17>, + <18>, <19>; + clock-output-names = "apb1_i2c0", "apb1_i2c1", + "apb1_i2c2", "apb1_uart1", + "apb1_uart2", "apb1_uart3"; + }; + + nand_clk: clk@01c20080 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c20080 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "nand"; + }; + + ms_clk: clk@01c20084 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c20084 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ms"; + }; + + mmc0_clk: clk@01c20088 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-mmc-clk"; + reg = <0x01c20088 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc0", + "mmc0_output", + "mmc0_sample"; + }; + + mmc1_clk: clk@01c2008c { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-mmc-clk"; + reg = <0x01c2008c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc1", + "mmc1_output", + "mmc1_sample"; + }; + + mmc2_clk: clk@01c20090 { + #clock-cells = <1>; + compatible = "allwinner,sun4i-a10-mmc-clk"; + reg = <0x01c20090 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mmc2", + "mmc2_output", + "mmc2_sample"; + }; + + ts_clk: clk@01c20098 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c20098 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ts"; + }; + + ss_clk: clk@01c2009c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c2009c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ss"; + }; + + spi0_clk: clk@01c200a0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c200a0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi0"; + }; + + spi1_clk: clk@01c200a4 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c200a4 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi1"; + }; + + spi2_clk: clk@01c200a8 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c200a8 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "spi2"; + }; + + ir0_clk: clk@01c200b0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c200b0 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "ir0"; + }; + + i2s0_clk: clk@01c200b8 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod1-clk"; + reg = <0x01c200b8 0x4>; + clocks = <&pll2 SUN4I_A10_PLL2_8X>, + <&pll2 SUN4I_A10_PLL2_4X>, + <&pll2 SUN4I_A10_PLL2_2X>, + <&pll2 SUN4I_A10_PLL2_1X>; + clock-output-names = "i2s0"; + }; + + spdif_clk: clk@01c200c0 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod1-clk"; + reg = <0x01c200c0 0x4>; + clocks = <&pll2 SUN4I_A10_PLL2_8X>, + <&pll2 SUN4I_A10_PLL2_4X>, + <&pll2 SUN4I_A10_PLL2_2X>, + <&pll2 SUN4I_A10_PLL2_1X>; + clock-output-names = "spdif"; + }; + + usb_clk: clk@01c200cc { + #clock-cells = <1>; + #reset-cells = <1>; + compatible = "allwinner,sun5i-a13-usb-clk"; + reg = <0x01c200cc 0x4>; + clocks = <&pll6 1>; + clock-output-names = "usb_ohci0", "usb_phy"; + }; + + dram_gates: clk@01c20100 { + #clock-cells = <1>; + compatible = "nextthing,gr8-dram-gates-clk", + "allwinner,sun4i-a10-gates-clk"; + reg = <0x01c20100 0x4>; + clocks = <&pll5 0>; + clock-indices = <0>, + <1>, + <25>, + <26>, + <29>, + <31>; + clock-output-names = "dram_ve", + "dram_csi", + "dram_de_fe", + "dram_de_be", + "dram_ace", + "dram_iep"; + }; + + de_be_clk: clk@01c20104 { + #clock-cells = <0>; + #reset-cells = <0>; + compatible = "allwinner,sun4i-a10-display-clk"; + reg = <0x01c20104 0x4>; + clocks = <&pll3>, <&pll7>, <&pll5 1>; + clock-output-names = "de-be"; + }; + + de_fe_clk: clk@01c2010c { + #clock-cells = <0>; + #reset-cells = <0>; + compatible = "allwinner,sun4i-a10-display-clk"; + reg = <0x01c2010c 0x4>; + clocks = <&pll3>, <&pll7>, <&pll5 1>; + clock-output-names = "de-fe"; + }; + + tcon_ch0_clk: clk@01c20118 { + #clock-cells = <0>; + #reset-cells = <1>; + compatible = "allwinner,sun4i-a10-tcon-ch0-clk"; + reg = <0x01c20118 0x4>; + clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>; + clock-output-names = "tcon-ch0-sclk"; + }; + + tcon_ch1_clk: clk@01c2012c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-tcon-ch1-clk"; + reg = <0x01c2012c 0x4>; + clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>; + clock-output-names = "tcon-ch1-sclk"; + }; + + codec_clk: clk@01c20140 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-codec-clk"; + reg = <0x01c20140 0x4>; + clocks = <&pll2 SUN4I_A10_PLL2_1X>; + clock-output-names = "codec"; + }; + + mbus_clk: clk@01c2015c { + #clock-cells = <0>; + compatible = "allwinner,sun5i-a13-mbus-clk"; + reg = <0x01c2015c 0x4>; + clocks = <&osc24M>, <&pll6 1>, <&pll5 1>; + clock-output-names = "mbus"; + }; + }; + + display-engine { + compatible = "allwinner,sun5i-a13-display-engine"; + allwinner,pipelines = <&fe0>; + }; + + soc@01c00000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram-controller@01c00000 { + compatible = "allwinner,sun4i-a10-sram-controller"; + reg = <0x01c00000 0x30>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + sram_a: sram@00000000 { + compatible = "mmio-sram"; + reg = <0x00000000 0xc000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00000000 0xc000>; + }; + + sram_d: sram@00010000 { + compatible = "mmio-sram"; + reg = <0x00010000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00010000 0x1000>; + + otg_sram: sram-section@0000 { + compatible = "allwinner,sun4i-a10-sram-d"; + reg = <0x0000 0x1000>; + status = "disabled"; + }; + }; + }; + + dma: dma-controller@01c02000 { + compatible = "allwinner,sun4i-a10-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <27>; + clocks = <&ahb_gates 6>; + #dma-cells = <2>; + }; + + nfc: nand@01c03000 { + compatible = "allwinner,sun4i-a10-nand"; + reg = <0x01c03000 0x1000>; + interrupts = <37>; + clocks = <&ahb_gates 13>, <&nand_clk>; + clock-names = "ahb", "mod"; + dmas = <&dma SUN4I_DMA_DEDICATED 3>; + dma-names = "rxtx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi0: spi@01c05000 { + compatible = "allwinner,sun4i-a10-spi"; + reg = <0x01c05000 0x1000>; + interrupts = <10>; + clocks = <&ahb_gates 20>, <&spi0_clk>; + clock-names = "ahb", "mod"; + dmas = <&dma SUN4I_DMA_DEDICATED 27>, + <&dma SUN4I_DMA_DEDICATED 26>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@01c06000 { + compatible = "allwinner,sun4i-a10-spi"; + reg = <0x01c06000 0x1000>; + interrupts = <11>; + clocks = <&ahb_gates 21>, <&spi1_clk>; + clock-names = "ahb", "mod"; + dmas = <&dma SUN4I_DMA_DEDICATED 9>, + <&dma SUN4I_DMA_DEDICATED 8>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + tve0: tv-encoder@01c0a000 { + compatible = "allwinner,sun4i-a10-tv-encoder"; + reg = <0x01c0a000 0x1000>; + clocks = <&ahb_gates 34>; + resets = <&tcon_ch0_clk 0>; + status = "disabled"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + tve0_in_tcon0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon0_out_tve0>; + }; + }; + }; + + tcon0: lcd-controller@01c0c000 { + compatible = "allwinner,sun5i-a13-tcon"; + reg = <0x01c0c000 0x1000>; + interrupts = <44>; + resets = <&tcon_ch0_clk 1>; + reset-names = "lcd"; + clocks = <&ahb_gates 36>, + <&tcon_ch0_clk>, + <&tcon_ch1_clk>; + clock-names = "ahb", + "tcon-ch0", + "tcon-ch1"; + clock-output-names = "tcon-pixel-clock"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + tcon0_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + tcon0_in_be0: endpoint@0 { + reg = <0>; + remote-endpoint = <&be0_out_tcon0>; + }; + }; + + tcon0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + tcon0_out_tve0: endpoint@1 { + reg = <1>; + remote-endpoint = <&tve0_in_tcon0>; + }; + }; + }; + }; + + mmc0: mmc@01c0f000 { + compatible = "allwinner,sun5i-a13-mmc"; + reg = <0x01c0f000 0x1000>; + clocks = <&ahb_gates 8>, + <&mmc0_clk 0>, + <&mmc0_clk 1>, + <&mmc0_clk 2>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + interrupts = <32>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc1: mmc@01c10000 { + compatible = "allwinner,sun5i-a13-mmc"; + reg = <0x01c10000 0x1000>; + clocks = <&ahb_gates 9>, + <&mmc1_clk 0>, + <&mmc1_clk 1>, + <&mmc1_clk 2>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + interrupts = <33>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc2: mmc@01c11000 { + compatible = "allwinner,sun5i-a13-mmc"; + reg = <0x01c11000 0x1000>; + clocks = <&ahb_gates 10>, + <&mmc2_clk 0>, + <&mmc2_clk 1>, + <&mmc2_clk 2>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + interrupts = <34>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + usb_otg: usb@01c13000 { + compatible = "allwinner,sun4i-a10-musb"; + reg = <0x01c13000 0x0400>; + clocks = <&ahb_gates 0>; + interrupts = <38>; + interrupt-names = "mc"; + phys = <&usbphy 0>; + phy-names = "usb"; + extcon = <&usbphy 0>; + allwinner,sram = <&otg_sram 1>; + status = "disabled"; + + dr_mode = "otg"; + }; + + usbphy: phy@01c13400 { + #phy-cells = <1>; + compatible = "allwinner,sun5i-a13-usb-phy"; + reg = <0x01c13400 0x10 0x01c14800 0x4>; + reg-names = "phy_ctrl", "pmu1"; + clocks = <&usb_clk 8>; + clock-names = "usb_phy"; + resets = <&usb_clk 0>, <&usb_clk 1>; + reset-names = "usb0_reset", "usb1_reset"; + status = "disabled"; + }; + + ehci0: usb@01c14000 { + compatible = "allwinner,sun5i-a13-ehci", "generic-ehci"; + reg = <0x01c14000 0x100>; + interrupts = <39>; + clocks = <&ahb_gates 1>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci0: usb@01c14400 { + compatible = "allwinner,sun5i-a13-ohci", "generic-ohci"; + reg = <0x01c14400 0x100>; + interrupts = <40>; + clocks = <&usb_clk 6>, <&ahb_gates 2>; + phys = <&usbphy 1>; + phy-names = "usb"; + status = "disabled"; + }; + + spi2: spi@01c17000 { + compatible = "allwinner,sun4i-a10-spi"; + reg = <0x01c17000 0x1000>; + interrupts = <12>; + clocks = <&ahb_gates 22>, <&spi2_clk>; + clock-names = "ahb", "mod"; + dmas = <&dma SUN4I_DMA_DEDICATED 29>, + <&dma SUN4I_DMA_DEDICATED 28>; + dma-names = "rx", "tx"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + intc: interrupt-controller@01c20400 { + compatible = "allwinner,sun4i-a10-ic"; + reg = <0x01c20400 0x400>; + interrupt-controller; + #interrupt-cells = <1>; + }; + + pio: pinctrl@01c20800 { + compatible = "nextthing,gr8-pinctrl"; + reg = <0x01c20800 0x400>; + interrupts = <28>; + clocks = <&apb0_gates 5>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <3>; + #gpio-cells = <3>; + + i2c0_pins_a: i2c0@0 { + allwinner,pins = "PB0", "PB1"; + allwinner,function = "i2c0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + i2c1_pins_a: i2c1@0 { + allwinner,pins = "PB15", "PB16"; + allwinner,function = "i2c1"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + i2c2_pins_a: i2c2@0 { + allwinner,pins = "PB17", "PB18"; + allwinner,function = "i2c2"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + i2s0_data_pins_a: i2s0-data@0 { + allwinner,pins = "PB6", "PB7", "PB8", "PB9"; + allwinner,function = "i2s0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + i2s0_mclk_pins_a: i2s0-mclk@0 { + allwinner,pins = "PB5"; + allwinner,function = "i2s0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + ir0_rx_pins_a: ir0@0 { + allwinner,pins = "PB4"; + allwinner,function = "ir0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + lcd_rgb666_pins: lcd-rgb666@0 { + allwinner,pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", + "PD10", "PD11", "PD12", "PD13", "PD14", "PD15", + "PD18", "PD19", "PD20", "PD21", "PD22", "PD23", + "PD24", "PD25", "PD26", "PD27"; + allwinner,function = "lcd0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + mmc0_pins_a: mmc0@0 { + allwinner,pins = "PF0", "PF1", "PF2", "PF3", + "PF4", "PF5"; + allwinner,function = "mmc0"; + allwinner,drive = <SUN4I_PINCTRL_30_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + nand_pins_a: nand-base0@0 { + allwinner,pins = "PC0", "PC1", "PC2", + "PC5", "PC8", "PC9", "PC10", + "PC11", "PC12", "PC13", "PC14", + "PC15"; + allwinner,function = "nand0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + nand_cs0_pins_a: nand-cs@0 { + allwinner,pins = "PC4"; + allwinner,function = "nand0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + nand_rb0_pins_a: nand-rb@0 { + allwinner,pins = "PC6"; + allwinner,function = "nand0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + pwm0_pins_a: pwm0@0 { + allwinner,pins = "PB2"; + allwinner,function = "pwm0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + pwm1_pins: pwm1 { + allwinner,pins = "PG13"; + allwinner,function = "pwm1"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + spdif_tx_pins_a: spdif@0 { + allwinner,pins = "PB10"; + allwinner,function = "spdif"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_PULL_UP>; + }; + + uart1_pins_a: uart1@1 { + allwinner,pins = "PG3", "PG4"; + allwinner,function = "uart1"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + uart1_cts_rts_pins_a: uart1-cts-rts@0 { + allwinner,pins = "PG5", "PG6"; + allwinner,function = "uart1"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + uart2_pins_a: uart2@1 { + allwinner,pins = "PD2", "PD3"; + allwinner,function = "uart2"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + uart2_cts_rts_pins_a: uart2-cts-rts@0 { + allwinner,pins = "PD4", "PD5"; + allwinner,function = "uart2"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + uart3_pins_a: uart3@1 { + allwinner,pins = "PG9", "PG10"; + allwinner,function = "uart3"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + + uart3_cts_rts_pins_a: uart3-cts-rts@0 { + allwinner,pins = "PG11", "PG12"; + allwinner,function = "uart3"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + }; + + pwm: pwm@01c20e00 { + compatible = "allwinner,sun5i-a10s-pwm"; + reg = <0x01c20e00 0xc>; + clocks = <&osc24M>; + #pwm-cells = <3>; + status = "disabled"; + }; + + timer@01c20c00 { + compatible = "allwinner,sun4i-a10-timer"; + reg = <0x01c20c00 0x90>; + interrupts = <22>; + clocks = <&osc24M>; + }; + + wdt: watchdog@01c20c90 { + compatible = "allwinner,sun4i-a10-wdt"; + reg = <0x01c20c90 0x10>; + }; + + spdif: spdif@01c21000 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun4i-a10-spdif"; + reg = <0x01c21000 0x400>; + interrupts = <13>; + clocks = <&apb0_gates 1>, <&spdif_clk>; + clock-names = "apb", "spdif"; + dmas = <&dma SUN4I_DMA_NORMAL 2>, + <&dma SUN4I_DMA_NORMAL 2>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + ir0: ir@01c21800 { + compatible = "allwinner,sun4i-a10-ir"; + clocks = <&apb0_gates 6>, <&ir0_clk>; + clock-names = "apb", "ir"; + interrupts = <5>; + reg = <0x01c21800 0x40>; + status = "disabled"; + }; + + i2s0: i2s@01c22400 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun4i-a10-i2s"; + reg = <0x01c22400 0x400>; + interrupts = <16>; + clocks = <&apb0_gates 3>, <&i2s0_clk>; + clock-names = "apb", "mod"; + dmas = <&dma SUN4I_DMA_NORMAL 3>, + <&dma SUN4I_DMA_NORMAL 3>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + lradc: lradc@01c22800 { + compatible = "allwinner,sun4i-a10-lradc-keys"; + reg = <0x01c22800 0x100>; + interrupts = <31>; + status = "disabled"; + }; + + codec: codec@01c22c00 { + #sound-dai-cells = <0>; + compatible = "allwinner,sun4i-a10-codec"; + reg = <0x01c22c00 0x40>; + interrupts = <30>; + clocks = <&apb0_gates 0>, <&codec_clk>; + clock-names = "apb", "codec"; + dmas = <&dma SUN4I_DMA_NORMAL 19>, + <&dma SUN4I_DMA_NORMAL 19>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + rtp: rtp@01c25000 { + compatible = "allwinner,sun5i-a13-ts"; + reg = <0x01c25000 0x100>; + interrupts = <29>; + #thermal-sensor-cells = <0>; + }; + + uart1: serial@01c28400 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28400 0x400>; + interrupts = <2>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&apb1_gates 17>; + status = "disabled"; + }; + + uart2: serial@01c28800 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28800 0x400>; + interrupts = <3>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&apb1_gates 18>; + status = "disabled"; + }; + + uart3: serial@01c28c00 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28c00 0x400>; + interrupts = <4>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&apb1_gates 19>; + status = "disabled"; + }; + + i2c0: i2c@01c2ac00 { + compatible = "allwinner,sun4i-a10-i2c"; + reg = <0x01c2ac00 0x400>; + interrupts = <7>; + clocks = <&apb1_gates 0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@01c2b000 { + compatible = "allwinner,sun4i-a10-i2c"; + reg = <0x01c2b000 0x400>; + interrupts = <8>; + clocks = <&apb1_gates 1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@01c2b400 { + compatible = "allwinner,sun4i-a10-i2c"; + reg = <0x01c2b400 0x400>; + interrupts = <9>; + clocks = <&apb1_gates 2>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + timer@01c60000 { + compatible = "allwinner,sun5i-a13-hstimer"; + reg = <0x01c60000 0x1000>; + interrupts = <82>, <83>; + clocks = <&ahb_gates 28>; + }; + + fe0: display-frontend@01e00000 { + compatible = "allwinner,sun5i-a13-display-frontend"; + reg = <0x01e00000 0x20000>; + interrupts = <47>; + clocks = <&ahb_gates 46>, <&de_fe_clk>, + <&dram_gates 25>; + clock-names = "ahb", "mod", + "ram"; + resets = <&de_fe_clk>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + fe0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + fe0_out_be0: endpoint@0 { + reg = <0>; + remote-endpoint = <&be0_in_fe0>; + }; + }; + }; + }; + + be0: display-backend@01e60000 { + compatible = "allwinner,sun5i-a13-display-backend"; + reg = <0x01e60000 0x10000>; + clocks = <&ahb_gates 44>, <&de_be_clk>, + <&dram_gates 26>; + clock-names = "ahb", "mod", + "ram"; + resets = <&de_be_clk>; + status = "disabled"; + + assigned-clocks = <&de_be_clk>; + assigned-clock-rates = <300000000>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + be0_in: port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + be0_in_fe0: endpoint@0 { + reg = <0>; + remote-endpoint = <&fe0_out_be0>; + }; + }; + + be0_out: port@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + be0_out_tcon0: endpoint@0 { + reg = <0>; + remote-endpoint = <&tcon0_in_be0>; + }; + }; + }; + }; + }; +};

On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
Those DT will be part of 4.10, sync them so we can have our own config.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Reviewed-by: Hans de Goede hdegoede@redhat.com
arch/arm/dts/Makefile | 1 +- arch/arm/dts/axp209.dtsi | 6 +- arch/arm/dts/ntc-gr8-chip-pro.dts | 266 +++++++- arch/arm/dts/ntc-gr8.dtsi | 1132 ++++++++++++++++++++++++++++++- 4 files changed, 1405 insertions(+), 0 deletions(-) create mode 100644 arch/arm/dts/ntc-gr8-chip-pro.dts create mode 100644 arch/arm/dts/ntc-gr8.dtsi
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 836a8c4d1ee2..932dbe07cf14 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -180,6 +180,7 @@ dtb-$(CONFIG_MACH_SUN4I) += \ sun4i-a10-pcduino2.dtb \ sun4i-a10-pov-protab2-ips9.dtb dtb-$(CONFIG_MACH_SUN5I) += \
ntc-gr8-chip-pro.dtb \
sun5i- prefix is better, isn't it?
sun5i-a10s-auxtek-t003.dtb \ sun5i-a10s-auxtek-t004.dtb \ sun5i-a10s-mk802.dtb \
diff --git a/arch/arm/dts/axp209.dtsi b/arch/arm/dts/axp209.dtsi index afbe89c01df5..675bb0f30825 100644 --- a/arch/arm/dts/axp209.dtsi +++ b/arch/arm/dts/axp209.dtsi @@ -53,6 +53,12 @@ interrupt-controller; #interrupt-cells = <1>;
axp_gpio: gpio {
compatible = "x-powers,axp209-gpio";
gpio-controller;
#gpio-cells = <2>;
};
regulators { /* Default work frequency for buck regulators */ x-powers,dcdc-freq = <1500>;
diff --git a/arch/arm/dts/ntc-gr8-chip-pro.dts b/arch/arm/dts/ntc-gr8-chip-pro.dts new file mode 100644 index 000000000000..c4be912df481 --- /dev/null +++ b/arch/arm/dts/ntc-gr8-chip-pro.dts @@ -0,0 +1,266 @@ +/*
- Copyright 2016 Free Electrons
- Copyright 2016 NextThing Co
- Maxime Ripard maxime.ripard@free-electrons.com
- This file is dual-licensed: you can use it either under the terms
- of the GPL or the X11 license, at your option. Note that this dual
- licensing only applies to this file, and not this project as a
- whole.
- a) This file is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- Or, alternatively,
- b) Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
- */
+/dts-v1/; +#include "ntc-gr8.dtsi" +#include "sunxi-common-regulators.dtsi"
+#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h>
+/ {
model = "NextThing C.H.I.P. Pro";
compatible = "nextthing,chip-pro", "nextthing,gr8";
aliases {
i2c0 = &i2c0;
i2c1 = &i2c1;
serial0 = &uart1;
serial1 = &uart2;
serial2 = &uart3;
};
chosen {
stdout-path = "serial0:115200n8";
};
leds {
compatible = "gpio-leds";
status {
label = "chip-pro:white:status";
gpios = <&axp_gpio 2 GPIO_ACTIVE_HIGH>;
default-state = "on";
};
};
mmc0_pwrseq: mmc0_pwrseq {
compatible = "mmc-pwrseq-simple";
pinctrl-names = "default";
pinctrl-0 = <&wifi_reg_on_pin_chip_pro>;
reset-gpios = <&pio 1 10 GPIO_ACTIVE_LOW>; /* PB10 */
};
+};
+&codec {
status = "okay";
+};
+&ehci0 {
status = "okay";
+};
+&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_a>;
status = "okay";
axp209: pmic@34 {
reg = <0x34>;
/*
* The interrupt is routed through the "External Fast
* Interrupt Request" pin (ball G13 of the module)
* directly to the main interrupt controller, without
* any other controller interfering.
*/
interrupts = <0>;
};
+};
+#include "axp209.dtsi"
+&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
status = "disabled";
+};
+&i2s0 {
pinctrl-names = "default";
pinctrl-0 = <&i2s0_mclk_pins_a>, <&i2s0_data_pins_a>;
status = "disabled";
+};
+&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_a>;
vmmc-supply = <®_vcc3v3>;
mmc-pwrseq = <&mmc0_pwrseq>;
bus-width = <4>;
non-removable;
status = "okay";
+};
+&nfc {
pinctrl-names = "default";
pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>;
status = "okay";
nand@0 {
#address-cells = <2>;
#size-cells = <2>;
reg = <0>;
allwinner,rb = <0>;
nand-ecc-mode = "hw";
};
+};
+&ohci0 {
status = "okay";
+};
+&otg_sram {
status = "okay";
+};
+&pio {
usb0_id_pin_chip_pro: usb0-id-pin@0 {
allwinner,pins = "PG2";
allwinner,function = "gpio_in";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
wifi_reg_on_pin_chip_pro: wifi-reg-on-pin@0 {
allwinner,pins = "PB10";
allwinner,function = "gpio_out";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
+};
+&pwm {
pinctrl-names = "default";
pinctrl-0 = <&pwm0_pins_a>, <&pwm1_pins>;
status = "disabled";
+};
+®_dcdc2 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1400000>;
regulator-name = "vdd-cpu";
regulator-always-on;
+};
+®_dcdc3 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1300000>;
regulator-name = "vdd-sys";
regulator-always-on;
+};
+®_ldo1 {
regulator-name = "vdd-rtc";
+};
+®_ldo2 {
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3300000>;
regulator-name = "avcc";
regulator-always-on;
+};
+/*
- Both LDO3 and LDO4 are used in parallel to power up the
- WiFi/BT chip.
- */
+®_ldo3 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-wifi-1";
regulator-always-on;
+};
+®_ldo4 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-wifi-2";
regulator-always-on;
+};
+&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&uart1_pins_a>, <&uart1_cts_rts_pins_a>;
status = "okay";
+};
+&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins_a>, <&uart2_cts_rts_pins_a>;
status = "disabled";
+};
+&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&uart3_pins_a>, <&uart3_cts_rts_pins_a>;
status = "okay";
+};
+&usb_otg {
/*
* The CHIP Pro doesn't have a controllable VBUS, nor does it
* have any 5v rail on the board itself.
*
* If one wants to use it as a true OTG port, it should be
* done in the baseboard, and its DT / overlay will add it.
*/
dr_mode = "otg";
status = "okay";
+};
+&usb_power_supply {
status = "okay";
+};
+&usbphy {
pinctrl-names = "default";
pinctrl-0 = <&usb0_id_pin_chip_pro>;
usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */
usb0_vbus_power-supply = <&usb_power_supply>;
usb1_vbus-supply = <®_vcc5v0>;
status = "okay";
+}; diff --git a/arch/arm/dts/ntc-gr8.dtsi b/arch/arm/dts/ntc-gr8.dtsi new file mode 100644 index 000000000000..ea86d4d58db6 --- /dev/null +++ b/arch/arm/dts/ntc-gr8.dtsi @@ -0,0 +1,1132 @@ +/*
- Copyright 2016 Mylène Josserand
- Mylène Josserand mylene.josserand@free-electrons.com
- This file is dual-licensed: you can use it either under the terms
- of the GPL or the X11 license, at your option. Note that this dual
- licensing only applies to this file, and not this project as a
- whole.
- a) This library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- Or, alternatively,
- b) Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
- */
+#include <dt-bindings/clock/sun4i-a10-pll2.h> +#include <dt-bindings/dma/sun4i-a10.h> +#include <dt-bindings/pinctrl/sun4i-a10.h>
+/ {
interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a8";
reg = <0x0>;
clocks = <&cpu>;
};
};
clocks {
#address-cells = <1>;
#size-cells = <1>;
ranges;
/*
* This is a dummy clock, to be used as placeholder on
* other mux clocks when a specific parent clock is not
* yet implemented. It should be dropped when the driver
* is complete.
*/
dummy: dummy {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <0>;
};
osc24M: clk@01c20050 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-osc-clk";
reg = <0x01c20050 0x4>;
clock-frequency = <24000000>;
clock-output-names = "osc24M";
};
osc3M: osc3M-clk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
clock-div = <8>;
clock-mult = <1>;
clocks = <&osc24M>;
clock-output-names = "osc3M";
};
osc32k: clk@0 {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <32768>;
clock-output-names = "osc32k";
};
pll1: clk@01c20000 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20000 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll1";
};
pll2: clk@01c20008 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-pll2-clk";
reg = <0x01c20008 0x8>;
clocks = <&osc24M>;
clock-output-names = "pll2-1x", "pll2-2x",
"pll2-4x", "pll2-8x";
};
pll3: clk@01c20010 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll3-clk";
reg = <0x01c20010 0x4>;
clocks = <&osc3M>;
clock-output-names = "pll3";
};
pll3x2: pll3x2-clk {
compatible = "allwinner,sun4i-a10-pll3-2x-clk";
#clock-cells = <0>;
clock-div = <1>;
clock-mult = <2>;
clocks = <&pll3>;
clock-output-names = "pll3-2x";
};
pll4: clk@01c20018 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll1-clk";
reg = <0x01c20018 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll4";
};
pll5: clk@01c20020 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-pll5-clk";
reg = <0x01c20020 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll5_ddr", "pll5_other";
};
pll6: clk@01c20028 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-pll6-clk";
reg = <0x01c20028 0x4>;
clocks = <&osc24M>;
clock-output-names = "pll6_sata", "pll6_other", "pll6";
};
pll7: clk@01c20030 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-pll3-clk";
reg = <0x01c20030 0x4>;
clocks = <&osc3M>;
clock-output-names = "pll7";
};
pll7x2: pll7x2-clk {
compatible = "allwinner,sun4i-a10-pll3-2x-clk";
#clock-cells = <0>;
clock-div = <1>;
clock-mult = <2>;
clocks = <&pll7>;
clock-output-names = "pll7-2x";
};
/* dummy is 200M */
cpu: cpu@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-cpu-clk";
reg = <0x01c20054 0x4>;
clocks = <&osc32k>, <&osc24M>, <&pll1>, <&dummy>;
clock-output-names = "cpu";
};
axi: axi@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-axi-clk";
reg = <0x01c20054 0x4>;
clocks = <&cpu>;
clock-output-names = "axi";
};
ahb: ahb@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-ahb-clk";
reg = <0x01c20054 0x4>;
clocks = <&axi>, <&cpu>, <&pll6 1>;
clock-output-names = "ahb";
/*
* Use PLL6 as parent, instead of CPU/AXI
* which has rate changes due to cpufreq
*/
assigned-clocks = <&ahb>;
assigned-clock-parents = <&pll6 1>;
};
apb0: apb0@01c20054 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-apb0-clk";
reg = <0x01c20054 0x4>;
clocks = <&ahb>;
clock-output-names = "apb0";
};
apb1: clk@01c20058 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-apb1-clk";
reg = <0x01c20058 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&osc32k>;
clock-output-names = "apb1";
};
axi_gates: clk@01c2005c {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-gates-clk";
reg = <0x01c2005c 0x4>;
clocks = <&axi>;
clock-indices = <0>;
clock-output-names = "axi_dram";
};
ahb_gates: clk@01c20060 {
#clock-cells = <1>;
compatible = "allwinner,sun5i-a13-ahb-gates-clk";
reg = <0x01c20060 0x8>;
clocks = <&ahb>;
clock-indices = <0>, <1>,
<2>, <5>, <6>,
<7>, <8>, <9>,
<10>, <13>,
<14>, <17>, <20>,
<21>, <22>,
<28>, <32>, <34>,
<36>, <40>, <44>,
<46>, <51>,
<52>;
clock-output-names = "ahb_usbotg", "ahb_ehci",
"ahb_ohci", "ahb_ss", "ahb_dma",
"ahb_bist", "ahb_mmc0", "ahb_mmc1",
"ahb_mmc2", "ahb_nand",
"ahb_sdram", "ahb_emac", "ahb_spi0",
"ahb_spi1", "ahb_spi2",
"ahb_hstimer", "ahb_ve", "ahb_tve",
"ahb_lcd", "ahb_csi", "ahb_de_be",
"ahb_de_fe", "ahb_iep",
"ahb_mali400";
};
apb0_gates: clk@01c20068 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-gates-clk";
reg = <0x01c20068 0x4>;
clocks = <&apb0>;
clock-indices = <0>, <3>,
<5>, <6>;
clock-output-names = "apb0_codec", "apb0_i2s0",
"apb0_pio", "apb0_ir";
};
apb1_gates: clk@01c2006c {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-gates-clk";
reg = <0x01c2006c 0x4>;
clocks = <&apb1>;
clock-indices = <0>, <1>,
<2>, <17>,
<18>, <19>;
clock-output-names = "apb1_i2c0", "apb1_i2c1",
"apb1_i2c2", "apb1_uart1",
"apb1_uart2", "apb1_uart3";
};
nand_clk: clk@01c20080 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20080 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "nand";
};
ms_clk: clk@01c20084 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20084 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ms";
};
mmc0_clk: clk@01c20088 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20088 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc0",
"mmc0_output",
"mmc0_sample";
};
mmc1_clk: clk@01c2008c {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c2008c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc1",
"mmc1_output",
"mmc1_sample";
};
mmc2_clk: clk@01c20090 {
#clock-cells = <1>;
compatible = "allwinner,sun4i-a10-mmc-clk";
reg = <0x01c20090 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mmc2",
"mmc2_output",
"mmc2_sample";
};
ts_clk: clk@01c20098 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c20098 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ts";
};
ss_clk: clk@01c2009c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c2009c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ss";
};
spi0_clk: clk@01c200a0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a0 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi0";
};
spi1_clk: clk@01c200a4 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a4 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi1";
};
spi2_clk: clk@01c200a8 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200a8 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "spi2";
};
ir0_clk: clk@01c200b0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod0-clk";
reg = <0x01c200b0 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "ir0";
};
i2s0_clk: clk@01c200b8 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod1-clk";
reg = <0x01c200b8 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_8X>,
<&pll2 SUN4I_A10_PLL2_4X>,
<&pll2 SUN4I_A10_PLL2_2X>,
<&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "i2s0";
};
spdif_clk: clk@01c200c0 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-mod1-clk";
reg = <0x01c200c0 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_8X>,
<&pll2 SUN4I_A10_PLL2_4X>,
<&pll2 SUN4I_A10_PLL2_2X>,
<&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "spdif";
};
usb_clk: clk@01c200cc {
#clock-cells = <1>;
#reset-cells = <1>;
compatible = "allwinner,sun5i-a13-usb-clk";
reg = <0x01c200cc 0x4>;
clocks = <&pll6 1>;
clock-output-names = "usb_ohci0", "usb_phy";
};
dram_gates: clk@01c20100 {
#clock-cells = <1>;
compatible = "nextthing,gr8-dram-gates-clk",
"allwinner,sun4i-a10-gates-clk";
reg = <0x01c20100 0x4>;
clocks = <&pll5 0>;
clock-indices = <0>,
<1>,
<25>,
<26>,
<29>,
<31>;
clock-output-names = "dram_ve",
"dram_csi",
"dram_de_fe",
"dram_de_be",
"dram_ace",
"dram_iep";
};
de_be_clk: clk@01c20104 {
#clock-cells = <0>;
#reset-cells = <0>;
compatible = "allwinner,sun4i-a10-display-clk";
reg = <0x01c20104 0x4>;
clocks = <&pll3>, <&pll7>, <&pll5 1>;
clock-output-names = "de-be";
};
de_fe_clk: clk@01c2010c {
#clock-cells = <0>;
#reset-cells = <0>;
compatible = "allwinner,sun4i-a10-display-clk";
reg = <0x01c2010c 0x4>;
clocks = <&pll3>, <&pll7>, <&pll5 1>;
clock-output-names = "de-fe";
};
tcon_ch0_clk: clk@01c20118 {
#clock-cells = <0>;
#reset-cells = <1>;
compatible = "allwinner,sun4i-a10-tcon-ch0-clk";
reg = <0x01c20118 0x4>;
clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
clock-output-names = "tcon-ch0-sclk";
};
tcon_ch1_clk: clk@01c2012c {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-tcon-ch1-clk";
reg = <0x01c2012c 0x4>;
clocks = <&pll3>, <&pll7>, <&pll3x2>, <&pll7x2>;
clock-output-names = "tcon-ch1-sclk";
};
codec_clk: clk@01c20140 {
#clock-cells = <0>;
compatible = "allwinner,sun4i-a10-codec-clk";
reg = <0x01c20140 0x4>;
clocks = <&pll2 SUN4I_A10_PLL2_1X>;
clock-output-names = "codec";
};
mbus_clk: clk@01c2015c {
#clock-cells = <0>;
compatible = "allwinner,sun5i-a13-mbus-clk";
reg = <0x01c2015c 0x4>;
clocks = <&osc24M>, <&pll6 1>, <&pll5 1>;
clock-output-names = "mbus";
};
};
display-engine {
compatible = "allwinner,sun5i-a13-display-engine";
allwinner,pipelines = <&fe0>;
};
soc@01c00000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
sram-controller@01c00000 {
compatible = "allwinner,sun4i-a10-sram-controller";
reg = <0x01c00000 0x30>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
sram_a: sram@00000000 {
compatible = "mmio-sram";
reg = <0x00000000 0xc000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x00000000 0xc000>;
};
sram_d: sram@00010000 {
compatible = "mmio-sram";
reg = <0x00010000 0x1000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x00010000 0x1000>;
otg_sram: sram-section@0000 {
compatible = "allwinner,sun4i-a10-sram-d";
reg = <0x0000 0x1000>;
status = "disabled";
};
};
};
dma: dma-controller@01c02000 {
compatible = "allwinner,sun4i-a10-dma";
reg = <0x01c02000 0x1000>;
interrupts = <27>;
clocks = <&ahb_gates 6>;
#dma-cells = <2>;
};
nfc: nand@01c03000 {
compatible = "allwinner,sun4i-a10-nand";
reg = <0x01c03000 0x1000>;
interrupts = <37>;
clocks = <&ahb_gates 13>, <&nand_clk>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 3>;
dma-names = "rxtx";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
spi0: spi@01c05000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c05000 0x1000>;
interrupts = <10>;
clocks = <&ahb_gates 20>, <&spi0_clk>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 27>,
<&dma SUN4I_DMA_DEDICATED 26>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
spi1: spi@01c06000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c06000 0x1000>;
interrupts = <11>;
clocks = <&ahb_gates 21>, <&spi1_clk>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 9>,
<&dma SUN4I_DMA_DEDICATED 8>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
tve0: tv-encoder@01c0a000 {
compatible = "allwinner,sun4i-a10-tv-encoder";
reg = <0x01c0a000 0x1000>;
clocks = <&ahb_gates 34>;
resets = <&tcon_ch0_clk 0>;
status = "disabled";
port {
#address-cells = <1>;
#size-cells = <0>;
tve0_in_tcon0: endpoint@0 {
reg = <0>;
remote-endpoint = <&tcon0_out_tve0>;
};
};
};
tcon0: lcd-controller@01c0c000 {
compatible = "allwinner,sun5i-a13-tcon";
reg = <0x01c0c000 0x1000>;
interrupts = <44>;
resets = <&tcon_ch0_clk 1>;
reset-names = "lcd";
clocks = <&ahb_gates 36>,
<&tcon_ch0_clk>,
<&tcon_ch1_clk>;
clock-names = "ahb",
"tcon-ch0",
"tcon-ch1";
clock-output-names = "tcon-pixel-clock";
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
tcon0_in: port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
tcon0_in_be0: endpoint@0 {
reg = <0>;
remote-endpoint = <&be0_out_tcon0>;
};
};
tcon0_out: port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
tcon0_out_tve0: endpoint@1 {
reg = <1>;
remote-endpoint = <&tve0_in_tcon0>;
};
};
};
};
mmc0: mmc@01c0f000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c0f000 0x1000>;
clocks = <&ahb_gates 8>,
<&mmc0_clk 0>,
<&mmc0_clk 1>,
<&mmc0_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <32>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
mmc1: mmc@01c10000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c10000 0x1000>;
clocks = <&ahb_gates 9>,
<&mmc1_clk 0>,
<&mmc1_clk 1>,
<&mmc1_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <33>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
mmc2: mmc@01c11000 {
compatible = "allwinner,sun5i-a13-mmc";
reg = <0x01c11000 0x1000>;
clocks = <&ahb_gates 10>,
<&mmc2_clk 0>,
<&mmc2_clk 1>,
<&mmc2_clk 2>;
clock-names = "ahb",
"mmc",
"output",
"sample";
interrupts = <34>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
usb_otg: usb@01c13000 {
compatible = "allwinner,sun4i-a10-musb";
reg = <0x01c13000 0x0400>;
clocks = <&ahb_gates 0>;
interrupts = <38>;
interrupt-names = "mc";
phys = <&usbphy 0>;
phy-names = "usb";
extcon = <&usbphy 0>;
allwinner,sram = <&otg_sram 1>;
status = "disabled";
dr_mode = "otg";
};
usbphy: phy@01c13400 {
#phy-cells = <1>;
compatible = "allwinner,sun5i-a13-usb-phy";
reg = <0x01c13400 0x10 0x01c14800 0x4>;
reg-names = "phy_ctrl", "pmu1";
clocks = <&usb_clk 8>;
clock-names = "usb_phy";
resets = <&usb_clk 0>, <&usb_clk 1>;
reset-names = "usb0_reset", "usb1_reset";
status = "disabled";
};
ehci0: usb@01c14000 {
compatible = "allwinner,sun5i-a13-ehci", "generic-ehci";
reg = <0x01c14000 0x100>;
interrupts = <39>;
clocks = <&ahb_gates 1>;
phys = <&usbphy 1>;
phy-names = "usb";
status = "disabled";
};
ohci0: usb@01c14400 {
compatible = "allwinner,sun5i-a13-ohci", "generic-ohci";
reg = <0x01c14400 0x100>;
interrupts = <40>;
clocks = <&usb_clk 6>, <&ahb_gates 2>;
phys = <&usbphy 1>;
phy-names = "usb";
status = "disabled";
};
spi2: spi@01c17000 {
compatible = "allwinner,sun4i-a10-spi";
reg = <0x01c17000 0x1000>;
interrupts = <12>;
clocks = <&ahb_gates 22>, <&spi2_clk>;
clock-names = "ahb", "mod";
dmas = <&dma SUN4I_DMA_DEDICATED 29>,
<&dma SUN4I_DMA_DEDICATED 28>;
dma-names = "rx", "tx";
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
intc: interrupt-controller@01c20400 {
compatible = "allwinner,sun4i-a10-ic";
reg = <0x01c20400 0x400>;
interrupt-controller;
#interrupt-cells = <1>;
};
pio: pinctrl@01c20800 {
compatible = "nextthing,gr8-pinctrl";
reg = <0x01c20800 0x400>;
interrupts = <28>;
clocks = <&apb0_gates 5>;
gpio-controller;
interrupt-controller;
#interrupt-cells = <3>;
#gpio-cells = <3>;
i2c0_pins_a: i2c0@0 {
allwinner,pins = "PB0", "PB1";
allwinner,function = "i2c0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c1_pins_a: i2c1@0 {
allwinner,pins = "PB15", "PB16";
allwinner,function = "i2c1";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2c2_pins_a: i2c2@0 {
allwinner,pins = "PB17", "PB18";
allwinner,function = "i2c2";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2s0_data_pins_a: i2s0-data@0 {
allwinner,pins = "PB6", "PB7", "PB8", "PB9";
allwinner,function = "i2s0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
i2s0_mclk_pins_a: i2s0-mclk@0 {
allwinner,pins = "PB5";
allwinner,function = "i2s0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
ir0_rx_pins_a: ir0@0 {
allwinner,pins = "PB4";
allwinner,function = "ir0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
lcd_rgb666_pins: lcd-rgb666@0 {
allwinner,pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
"PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
"PD18", "PD19", "PD20", "PD21", "PD22", "PD23",
"PD24", "PD25", "PD26", "PD27";
allwinner,function = "lcd0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
mmc0_pins_a: mmc0@0 {
allwinner,pins = "PF0", "PF1", "PF2", "PF3",
"PF4", "PF5";
allwinner,function = "mmc0";
allwinner,drive = <SUN4I_PINCTRL_30_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
nand_pins_a: nand-base0@0 {
allwinner,pins = "PC0", "PC1", "PC2",
"PC5", "PC8", "PC9", "PC10",
"PC11", "PC12", "PC13", "PC14",
"PC15";
allwinner,function = "nand0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
nand_cs0_pins_a: nand-cs@0 {
allwinner,pins = "PC4";
allwinner,function = "nand0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
nand_rb0_pins_a: nand-rb@0 {
allwinner,pins = "PC6";
allwinner,function = "nand0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
pwm0_pins_a: pwm0@0 {
allwinner,pins = "PB2";
allwinner,function = "pwm0";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
pwm1_pins: pwm1 {
allwinner,pins = "PG13";
allwinner,function = "pwm1";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
spdif_tx_pins_a: spdif@0 {
allwinner,pins = "PB10";
allwinner,function = "spdif";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
uart1_pins_a: uart1@1 {
allwinner,pins = "PG3", "PG4";
allwinner,function = "uart1";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart1_cts_rts_pins_a: uart1-cts-rts@0 {
allwinner,pins = "PG5", "PG6";
allwinner,function = "uart1";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart2_pins_a: uart2@1 {
allwinner,pins = "PD2", "PD3";
allwinner,function = "uart2";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart2_cts_rts_pins_a: uart2-cts-rts@0 {
allwinner,pins = "PD4", "PD5";
allwinner,function = "uart2";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart3_pins_a: uart3@1 {
allwinner,pins = "PG9", "PG10";
allwinner,function = "uart3";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
uart3_cts_rts_pins_a: uart3-cts-rts@0 {
allwinner,pins = "PG11", "PG12";
allwinner,function = "uart3";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
pwm: pwm@01c20e00 {
compatible = "allwinner,sun5i-a10s-pwm";
reg = <0x01c20e00 0xc>;
clocks = <&osc24M>;
#pwm-cells = <3>;
status = "disabled";
};
timer@01c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0x90>;
interrupts = <22>;
clocks = <&osc24M>;
};
wdt: watchdog@01c20c90 {
compatible = "allwinner,sun4i-a10-wdt";
reg = <0x01c20c90 0x10>;
};
spdif: spdif@01c21000 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun4i-a10-spdif";
reg = <0x01c21000 0x400>;
interrupts = <13>;
clocks = <&apb0_gates 1>, <&spdif_clk>;
clock-names = "apb", "spdif";
dmas = <&dma SUN4I_DMA_NORMAL 2>,
<&dma SUN4I_DMA_NORMAL 2>;
dma-names = "rx", "tx";
status = "disabled";
};
ir0: ir@01c21800 {
compatible = "allwinner,sun4i-a10-ir";
clocks = <&apb0_gates 6>, <&ir0_clk>;
clock-names = "apb", "ir";
interrupts = <5>;
reg = <0x01c21800 0x40>;
status = "disabled";
};
i2s0: i2s@01c22400 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun4i-a10-i2s";
reg = <0x01c22400 0x400>;
interrupts = <16>;
clocks = <&apb0_gates 3>, <&i2s0_clk>;
clock-names = "apb", "mod";
dmas = <&dma SUN4I_DMA_NORMAL 3>,
<&dma SUN4I_DMA_NORMAL 3>;
dma-names = "rx", "tx";
status = "disabled";
};
lradc: lradc@01c22800 {
compatible = "allwinner,sun4i-a10-lradc-keys";
reg = <0x01c22800 0x100>;
interrupts = <31>;
status = "disabled";
};
codec: codec@01c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun4i-a10-codec";
reg = <0x01c22c00 0x40>;
interrupts = <30>;
clocks = <&apb0_gates 0>, <&codec_clk>;
clock-names = "apb", "codec";
dmas = <&dma SUN4I_DMA_NORMAL 19>,
<&dma SUN4I_DMA_NORMAL 19>;
dma-names = "rx", "tx";
status = "disabled";
};
rtp: rtp@01c25000 {
compatible = "allwinner,sun5i-a13-ts";
reg = <0x01c25000 0x100>;
interrupts = <29>;
#thermal-sensor-cells = <0>;
};
uart1: serial@01c28400 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28400 0x400>;
interrupts = <2>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 17>;
status = "disabled";
};
uart2: serial@01c28800 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28800 0x400>;
interrupts = <3>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 18>;
status = "disabled";
};
uart3: serial@01c28c00 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28c00 0x400>;
interrupts = <4>;
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&apb1_gates 19>;
status = "disabled";
};
i2c0: i2c@01c2ac00 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2ac00 0x400>;
interrupts = <7>;
clocks = <&apb1_gates 0>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
i2c1: i2c@01c2b000 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2b000 0x400>;
interrupts = <8>;
clocks = <&apb1_gates 1>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
i2c2: i2c@01c2b400 {
compatible = "allwinner,sun4i-a10-i2c";
reg = <0x01c2b400 0x400>;
interrupts = <9>;
clocks = <&apb1_gates 2>;
status = "disabled";
#address-cells = <1>;
#size-cells = <0>;
};
timer@01c60000 {
compatible = "allwinner,sun5i-a13-hstimer";
reg = <0x01c60000 0x1000>;
interrupts = <82>, <83>;
clocks = <&ahb_gates 28>;
};
fe0: display-frontend@01e00000 {
compatible = "allwinner,sun5i-a13-display-frontend";
reg = <0x01e00000 0x20000>;
interrupts = <47>;
clocks = <&ahb_gates 46>, <&de_fe_clk>,
<&dram_gates 25>;
clock-names = "ahb", "mod",
"ram";
resets = <&de_fe_clk>;
status = "disabled";
ports {
#address-cells = <1>;
#size-cells = <0>;
fe0_out: port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
fe0_out_be0: endpoint@0 {
reg = <0>;
remote-endpoint = <&be0_in_fe0>;
};
};
};
};
be0: display-backend@01e60000 {
compatible = "allwinner,sun5i-a13-display-backend";
reg = <0x01e60000 0x10000>;
clocks = <&ahb_gates 44>, <&de_be_clk>,
<&dram_gates 26>;
clock-names = "ahb", "mod",
"ram";
resets = <&de_be_clk>;
status = "disabled";
assigned-clocks = <&de_be_clk>;
assigned-clock-rates = <300000000>;
ports {
#address-cells = <1>;
#size-cells = <0>;
be0_in: port@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
be0_in_fe0: endpoint@0 {
reg = <0>;
remote-endpoint = <&fe0_out_be0>;
};
};
be0_out: port@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
be0_out_tcon0: endpoint@0 {
reg = <0>;
remote-endpoint = <&tcon0_in_be0>;
};
};
};
};
};
+};
git-series 0.8.11
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On Sat, Dec 03, 2016 at 07:19:23PM +0530, Jagan Teki wrote:
On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
Those DT will be part of 4.10, sync them so we can have our own config.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Reviewed-by: Hans de Goede hdegoede@redhat.com
arch/arm/dts/Makefile | 1 +- arch/arm/dts/axp209.dtsi | 6 +- arch/arm/dts/ntc-gr8-chip-pro.dts | 266 +++++++- arch/arm/dts/ntc-gr8.dtsi | 1132 ++++++++++++++++++++++++++++++- 4 files changed, 1405 insertions(+), 0 deletions(-) create mode 100644 arch/arm/dts/ntc-gr8-chip-pro.dts create mode 100644 arch/arm/dts/ntc-gr8.dtsi
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 836a8c4d1ee2..932dbe07cf14 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -180,6 +180,7 @@ dtb-$(CONFIG_MACH_SUN4I) += \ sun4i-a10-pcduino2.dtb \ sun4i-a10-pov-protab2-ips9.dtb dtb-$(CONFIG_MACH_SUN5I) += \
ntc-gr8-chip-pro.dtb \
sun5i- prefix is better, isn't it?
This has been changed in upstream linux, and will be changed accordingly in the next version.
Thanks! Maxime

The CHIP Pro is a SoM that features the GR8 SIP, an AXP209, a BT/WiFi chip and a 512MiB SLC NAND.
This it's an SLC NAND, it doesn't suffer the same drawbacks than found on the MLC NANDs, and we can enable it right away.
Signed-off-by: Maxime Ripard maxime.ripard@free-electrons.com Reviewed-by: Hans de Goede hdegoede@redhat.com --- configs/CHIP_pro_defconfig | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+), 0 deletions(-) create mode 100644 configs/CHIP_pro_defconfig
diff --git a/configs/CHIP_pro_defconfig b/configs/CHIP_pro_defconfig new file mode 100644 index 000000000000..77acd075d288 --- /dev/null +++ b/configs/CHIP_pro_defconfig @@ -0,0 +1,32 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_SPL_I2C_SUPPORT=y +# CONFIG_SPL_MMC_SUPPORT is not set +CONFIG_SPL_NAND_SUPPORT=y +CONFIG_MACH_SUN5I=y +CONFIG_DRAM_TIMINGS_DDR3_800E_1066G_1333J=y +# CONFIG_MMC is not set +CONFIG_USB0_VBUS_PIN="PB10" +CONFIG_DEFAULT_DEVICE_TREE="ntc-gr8-chip-pro" +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,SYS_NAND_BLOCK_SIZE=0x40000,SYS_NAND_PAGE_SIZE=4096,SYS_NAND_OOBSIZE=256" +CONFIG_ENV_IS_IN_UBI=y +CONFIG_ENV_UBI_PART="UBI" +CONFIG_ENV_UBI_VOLUME="uboot-env" +CONFIG_SPL=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_DFU=y +CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_MTDPARTS=y +CONFIG_MTDIDS_DEFAULT="nand0=sunxi-nand.0" +CONFIG_MTDPARTS_DEFAULT="mtdparts=sunxi-nand.0:256k(spl),256k(spl-backup),2m(uboot),2m(uboot-backup),-(UBI)" +CONFIG_DFU_RAM=y +CONFIG_NAND_SUNXI=y +CONFIG_AXP_ALDO3_VOLT=3300 +CONFIG_AXP_ALDO4_VOLT=3300 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_MUSB_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_G_DNL_MANUFACTURER="Allwinner Technology" +CONFIG_G_DNL_VENDOR_NUM=0x1f3a +CONFIG_G_DNL_PRODUCT_NUM=0x1010

On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
The CHIP Pro is a SoM made by NextThing Co, and that embeds a GR8 SIP, an AXP209 PMIC, a WiFi BT chip and a 512MB SLC NAND.
Since the first Allwinner device coming whit an SLC NAND that doesn't have the shortcomings (and breakages) the MLC NAND has, we can finally enable the NAND support on a board by default.
This is the occasion to introduce a bunch of additions needed imo to be able to come up with a sane NAND support for our users.
The biggest pain point is that the BROM uses a different ECC and randomizer configuration than for the rest of the NAND. In order to lessen the number of bitflips, you also need to pad with random data the SPL image.
Since it's quite tedious to do right (and most users won't be able to figure it out) and since if it is not done right, it will eventually turn into an unusable system (which is bad UX), we think that the best solution is to generate an SPL image that already embeds all this. We'll possible have to do the same thing for the U-Boot image (at least for the random padding) on MLC NANDs.
The only drawback from that is that you need to flash it raw, instead of using the usual nand write, but it's just a different command, nothing major anyway.
In order to flash it, from a device switched in FEL, on your host: sunxi-fel spl spl/sunxi-spl.bin sunxi-fel write 0x4a000000 u-boot-dtb.bin sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin sunxi-fel exe 0x4a000000
And on the board, once u-boot is running (assuming the NAND is already erased):
nand write.raw.noverify 0x43000000 0 40 nand write.raw.noverify 0x43000000 0x400000 40
nand write 0x4a000000 0x800000 0xc0000
I also encountered some weird bug in the private libgcc that prevents U-Boot from loading. Disabling CONFIG_USE_PRIVATE_LIBGCC fixes that.
Let me know what you think, Maxime
Changes from v1:
- Allowed to build lib/bch.c for the host, and used that in the image builder
- Fixed a bug in the NAND driver
- Wrote a documentation on how to flash a NAND image on an Allwinner board
- Fixed a few compilation breakages and issues
- Moved U-boot offset out of the config header and into Kconfig
- Moved the environment into UBI
- Moved the environment selection to Kconfig
- Moved the CMD_MTDPARTS options to Kconfig
- Provide MTDIDS_DEFAULT and MTDPARTS_DEFAULT options through Kconfig
- Added the tags from everyone
Boris Brezillon (1): mtd: nand: add support for the TC58NVG2S0H chip
Will skip this, already in tree.
Hans de Goede (1): sunxi: Enable UBI and NAND support
Maxime Ripard (12): nand: sunxi: Fix modulo by zero error bch: Allow to build for the host tools: sunxi: Add spl image builder common: Move environment choice to Kconfig cmd: Add Kconfig option for CMD_MTDPARTS and related options mtd: sunxi: Select the U-Boot location config option mtd: sunxi: Change U-Boot offset sunxi: Add the default mtdids and mtdparts to our env nand: sunxi: Add options for the SPL NAND configuration scripts: sunxi: Build an raw SPL image
Reviewed-by: Jagan Teki jagan@openedev.com
sunxi: Sync GR8 DTS and AXP209 with the kerne
Sent the review comments about this.
sunxi: Add support for the CHIP Pro
thanks!

Hi Maxime,
On Sun, Dec 4, 2016 at 8:19 AM, Jagan Teki jagan@openedev.com wrote:
On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
The CHIP Pro is a SoM made by NextThing Co, and that embeds a GR8 SIP, an AXP209 PMIC, a WiFi BT chip and a 512MB SLC NAND.
Since the first Allwinner device coming whit an SLC NAND that doesn't have the shortcomings (and breakages) the MLC NAND has, we can finally enable the NAND support on a board by default.
This is the occasion to introduce a bunch of additions needed imo to be able to come up with a sane NAND support for our users.
The biggest pain point is that the BROM uses a different ECC and randomizer configuration than for the rest of the NAND. In order to lessen the number of bitflips, you also need to pad with random data the SPL image.
Since it's quite tedious to do right (and most users won't be able to figure it out) and since if it is not done right, it will eventually turn into an unusable system (which is bad UX), we think that the best solution is to generate an SPL image that already embeds all this. We'll possible have to do the same thing for the U-Boot image (at least for the random padding) on MLC NANDs.
The only drawback from that is that you need to flash it raw, instead of using the usual nand write, but it's just a different command, nothing major anyway.
In order to flash it, from a device switched in FEL, on your host: sunxi-fel spl spl/sunxi-spl.bin sunxi-fel write 0x4a000000 u-boot-dtb.bin sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin sunxi-fel exe 0x4a000000
And on the board, once u-boot is running (assuming the NAND is already erased):
nand write.raw.noverify 0x43000000 0 40 nand write.raw.noverify 0x43000000 0x400000 40
nand write 0x4a000000 0x800000 0xc0000
I also encountered some weird bug in the private libgcc that prevents U-Boot from loading. Disabling CONFIG_USE_PRIVATE_LIBGCC fixes that.
Let me know what you think, Maxime
Changes from v1:
- Allowed to build lib/bch.c for the host, and used that in the image builder
- Fixed a bug in the NAND driver
- Wrote a documentation on how to flash a NAND image on an Allwinner board
- Fixed a few compilation breakages and issues
- Moved U-boot offset out of the config header and into Kconfig
- Moved the environment into UBI
- Moved the environment selection to Kconfig
- Moved the CMD_MTDPARTS options to Kconfig
- Provide MTDIDS_DEFAULT and MTDPARTS_DEFAULT options through Kconfig
- Added the tags from everyone
Boris Brezillon (1): mtd: nand: add support for the TC58NVG2S0H chip
Will skip this, already in tree.
Hans de Goede (1): sunxi: Enable UBI and NAND support
Maxime Ripard (12): nand: sunxi: Fix modulo by zero error bch: Allow to build for the host tools: sunxi: Add spl image builder common: Move environment choice to Kconfig cmd: Add Kconfig option for CMD_MTDPARTS and related options mtd: sunxi: Select the U-Boot location config option mtd: sunxi: Change U-Boot offset sunxi: Add the default mtdids and mtdparts to our env nand: sunxi: Add options for the SPL NAND configuration scripts: sunxi: Build an raw SPL image
Reviewed-by: Jagan Teki jagan@openedev.com
sunxi: Sync GR8 DTS and AXP209 with the kerne
Sent the review comments about this.
sunxi: Add support for the CHIP Pro
Found many buildman issue with this series[1], please refer to master-next and let me know for if I miss any or fixes from you.
[1] https://paste.ubuntu.com/23585255/
thanks!

Hi Maxime,
On Mon, Dec 5, 2016 at 10:33 PM, Jagan Teki jagan@openedev.com wrote:
Hi Maxime,
On Sun, Dec 4, 2016 at 8:19 AM, Jagan Teki jagan@openedev.com wrote:
On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
The CHIP Pro is a SoM made by NextThing Co, and that embeds a GR8 SIP, an AXP209 PMIC, a WiFi BT chip and a 512MB SLC NAND.
Since the first Allwinner device coming whit an SLC NAND that doesn't have the shortcomings (and breakages) the MLC NAND has, we can finally enable the NAND support on a board by default.
This is the occasion to introduce a bunch of additions needed imo to be able to come up with a sane NAND support for our users.
The biggest pain point is that the BROM uses a different ECC and randomizer configuration than for the rest of the NAND. In order to lessen the number of bitflips, you also need to pad with random data the SPL image.
Since it's quite tedious to do right (and most users won't be able to figure it out) and since if it is not done right, it will eventually turn into an unusable system (which is bad UX), we think that the best solution is to generate an SPL image that already embeds all this. We'll possible have to do the same thing for the U-Boot image (at least for the random padding) on MLC NANDs.
The only drawback from that is that you need to flash it raw, instead of using the usual nand write, but it's just a different command, nothing major anyway.
In order to flash it, from a device switched in FEL, on your host: sunxi-fel spl spl/sunxi-spl.bin sunxi-fel write 0x4a000000 u-boot-dtb.bin sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin sunxi-fel exe 0x4a000000
And on the board, once u-boot is running (assuming the NAND is already erased):
nand write.raw.noverify 0x43000000 0 40 nand write.raw.noverify 0x43000000 0x400000 40
nand write 0x4a000000 0x800000 0xc0000
I also encountered some weird bug in the private libgcc that prevents U-Boot from loading. Disabling CONFIG_USE_PRIVATE_LIBGCC fixes that.
Let me know what you think, Maxime
Changes from v1:
- Allowed to build lib/bch.c for the host, and used that in the image builder
- Fixed a bug in the NAND driver
- Wrote a documentation on how to flash a NAND image on an Allwinner board
- Fixed a few compilation breakages and issues
- Moved U-boot offset out of the config header and into Kconfig
- Moved the environment into UBI
- Moved the environment selection to Kconfig
- Moved the CMD_MTDPARTS options to Kconfig
- Provide MTDIDS_DEFAULT and MTDPARTS_DEFAULT options through Kconfig
- Added the tags from everyone
Boris Brezillon (1): mtd: nand: add support for the TC58NVG2S0H chip
Will skip this, already in tree.
Hans de Goede (1): sunxi: Enable UBI and NAND support
Maxime Ripard (12): nand: sunxi: Fix modulo by zero error bch: Allow to build for the host tools: sunxi: Add spl image builder common: Move environment choice to Kconfig cmd: Add Kconfig option for CMD_MTDPARTS and related options mtd: sunxi: Select the U-Boot location config option mtd: sunxi: Change U-Boot offset sunxi: Add the default mtdids and mtdparts to our env nand: sunxi: Add options for the SPL NAND configuration scripts: sunxi: Build an raw SPL image
Reviewed-by: Jagan Teki jagan@openedev.com
sunxi: Sync GR8 DTS and AXP209 with the kerne
Sent the review comments about this.
sunxi: Add support for the CHIP Pro
Found many buildman issue with this series[1], please refer to master-next and let me know for if I miss any or fixes from you.
Did you able to reproduce?
thanks!

On Mon, Dec 05, 2016 at 10:33:35PM +0100, Jagan Teki wrote:
Hi Maxime,
On Sun, Dec 4, 2016 at 8:19 AM, Jagan Teki jagan@openedev.com wrote:
On Tue, Nov 22, 2016 at 6:08 PM, Maxime Ripard maxime.ripard@free-electrons.com wrote:
The CHIP Pro is a SoM made by NextThing Co, and that embeds a GR8 SIP, an AXP209 PMIC, a WiFi BT chip and a 512MB SLC NAND.
Since the first Allwinner device coming whit an SLC NAND that doesn't have the shortcomings (and breakages) the MLC NAND has, we can finally enable the NAND support on a board by default.
This is the occasion to introduce a bunch of additions needed imo to be able to come up with a sane NAND support for our users.
The biggest pain point is that the BROM uses a different ECC and randomizer configuration than for the rest of the NAND. In order to lessen the number of bitflips, you also need to pad with random data the SPL image.
Since it's quite tedious to do right (and most users won't be able to figure it out) and since if it is not done right, it will eventually turn into an unusable system (which is bad UX), we think that the best solution is to generate an SPL image that already embeds all this. We'll possible have to do the same thing for the U-Boot image (at least for the random padding) on MLC NANDs.
The only drawback from that is that you need to flash it raw, instead of using the usual nand write, but it's just a different command, nothing major anyway.
In order to flash it, from a device switched in FEL, on your host: sunxi-fel spl spl/sunxi-spl.bin sunxi-fel write 0x4a000000 u-boot-dtb.bin sunxi-fel write 0x43000000 spl/sunxi-spl-with-ecc.bin sunxi-fel exe 0x4a000000
And on the board, once u-boot is running (assuming the NAND is already erased):
nand write.raw.noverify 0x43000000 0 40 nand write.raw.noverify 0x43000000 0x400000 40
nand write 0x4a000000 0x800000 0xc0000
I also encountered some weird bug in the private libgcc that prevents U-Boot from loading. Disabling CONFIG_USE_PRIVATE_LIBGCC fixes that.
Let me know what you think, Maxime
Changes from v1:
- Allowed to build lib/bch.c for the host, and used that in the image builder
- Fixed a bug in the NAND driver
- Wrote a documentation on how to flash a NAND image on an Allwinner board
- Fixed a few compilation breakages and issues
- Moved U-boot offset out of the config header and into Kconfig
- Moved the environment into UBI
- Moved the environment selection to Kconfig
- Moved the CMD_MTDPARTS options to Kconfig
- Provide MTDIDS_DEFAULT and MTDPARTS_DEFAULT options through Kconfig
- Added the tags from everyone
Boris Brezillon (1): mtd: nand: add support for the TC58NVG2S0H chip
Will skip this, already in tree.
Hans de Goede (1): sunxi: Enable UBI and NAND support
Maxime Ripard (12): nand: sunxi: Fix modulo by zero error bch: Allow to build for the host tools: sunxi: Add spl image builder common: Move environment choice to Kconfig cmd: Add Kconfig option for CMD_MTDPARTS and related options mtd: sunxi: Select the U-Boot location config option mtd: sunxi: Change U-Boot offset sunxi: Add the default mtdids and mtdparts to our env nand: sunxi: Add options for the SPL NAND configuration scripts: sunxi: Build an raw SPL image
Reviewed-by: Jagan Teki jagan@openedev.com
sunxi: Sync GR8 DTS and AXP209 with the kerne
Sent the review comments about this.
sunxi: Add support for the CHIP Pro
Found many buildman issue with this series[1], please refer to master-next and let me know for if I miss any or fixes from you.
Sorry, I haven't been able to work on this lately. Please ignore that version for now, I will resubmit a v3 with this fixed.
Thanks! Maxime
participants (7)
-
Boris Brezillon
-
Heiko Schocher
-
Jagan Teki
-
Maxime Ripard
-
Peter Robinson
-
Scott Wood
-
Tom Rini