diff --git a/package/kernel/bcm63xx-cfe/Makefile b/package/kernel/bcm63xx-cfe/Makefile index 32f031ff558..f97e07579cc 100644 --- a/package/kernel/bcm63xx-cfe/Makefile +++ b/package/kernel/bcm63xx-cfe/Makefile @@ -2,11 +2,11 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=bcm63xx-cfe -PKG_VERSION:=2020-05-18 PKG_RELEASE:=1 PKG_SOURCE_URL:=https://github.com/openwrt/bcm63xx-cfe.git PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2020-05-18 PKG_SOURCE_VERSION:=efe3b81121a84c0b8ba6a7d0d47cd5eeeb23808d PKG_MIRROR_HASH:=299dcf6ef1ad034df26daee6446b574abcd7526a2fe90fb8115890e71bc0d58b diff --git a/target/linux/bcm63xx/dts/bcm63268.dtsi b/target/linux/bcm63xx/dts/bcm63268.dtsi index 1b4b3e61787..0c08aead202 100644 --- a/target/linux/bcm63xx/dts/bcm63268.dtsi +++ b/target/linux/bcm63xx/dts/bcm63268.dtsi @@ -4,6 +4,7 @@ compatible = "brcm,bcm63268"; aliases { + nflash = &nflash; pinctrl = &pinctrl; serial0 = &uart0; serial1 = &uart1; @@ -239,6 +240,30 @@ /* clocks = <&clkctl 16>; */ }; + nflash: nand@10000200 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,nand-bcm6368", + "brcm,brcmnand-v4.0", + "brcm,brcmnand"; + reg = <0x10000200 0x180>, + <0x10000600 0x200>, + <0x100000b0 0x10>; + reg-names = "nand", + "nand-cache", + "nand-int-base"; + + interrupt-parent = <&periph_intc>; + interrupts = <50>; + + /* clocks = <&clkctl 20>; */ + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + + status = "disabled"; + }; + leds: led-controller@10001900 { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/bcm63xx/dts/bcm6328.dtsi b/target/linux/bcm63xx/dts/bcm6328.dtsi index d08b6bab7a7..f62fad783e5 100644 --- a/target/linux/bcm63xx/dts/bcm6328.dtsi +++ b/target/linux/bcm63xx/dts/bcm6328.dtsi @@ -4,6 +4,7 @@ compatible = "brcm,bcm6328"; aliases { + nflash = &nflash; pinctrl = &pinctrl; serial0 = &uart0; serial1 = &uart1; @@ -179,6 +180,25 @@ status = "disabled"; }; + nflash: nand@10000200 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,nand-bcm6368", + "brcm,brcmnand-v2.2", + "brcm,brcmnand"; + reg = <0x10000200 0x180>, + <0x10000400 0x200>, + <0x10000070 0x10>; + reg-names = "nand", + "nand-cache", + "nand-int-base"; + + interrupt-parent = <&periph_intc>; + interrupts = <0>; + + status = "disabled"; + }; + leds: led-controller@10000800 { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/bcm63xx/dts/bcm6362.dtsi b/target/linux/bcm63xx/dts/bcm6362.dtsi index 2ff5c52ad7e..e639fc88375 100644 --- a/target/linux/bcm63xx/dts/bcm6362.dtsi +++ b/target/linux/bcm63xx/dts/bcm6362.dtsi @@ -4,6 +4,7 @@ compatible = "brcm,bcm6362"; aliases { + nflash = &nflash; pinctrl = &pinctrl; serial0 = &uart0; serial1 = &uart1; @@ -283,6 +284,30 @@ /* clocks = <&clkctl 16>; */ }; + nflash: nand@10000200 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,nand-bcm6368", + "brcm,brcmnand-v2.2", + "brcm,brcmnand"; + reg = <0x10000200 0x180>, + <0x10000600 0x200>, + <0x10000070 0x10>; + reg-names = "nand", + "nand-cache", + "nand-int-base"; + + interrupt-parent = <&periph_intc>; + interrupts = <12>; + + /* clocks = <&clkctl 20>; */ + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + + status = "disabled"; + }; + leds: led-controller@10001900 { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/bcm63xx/dts/bcm6368.dtsi b/target/linux/bcm63xx/dts/bcm6368.dtsi index b834f9ef0f8..b539020c213 100644 --- a/target/linux/bcm63xx/dts/bcm6368.dtsi +++ b/target/linux/bcm63xx/dts/bcm6368.dtsi @@ -4,6 +4,7 @@ compatible = "brcm,bcm6368"; aliases { + nflash = &nflash; pflash = &pflash; pinctrl = &pinctrl; serial0 = &uart0; @@ -298,6 +299,27 @@ status = "disabled"; }; + nflash: nand@10000200 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,nand-bcm6368", + "brcm,brcmnand-v2.1", + "brcm,brcmnand"; + reg = <0x10000200 0x180>, + <0x10000600 0x200>, + <0x10000070 0x10>; + reg-names = "nand", + "nand-cache", + "nand-int-base"; + + interrupt-parent = <&periph_intc>; + interrupts = <10>; + + /* clocks = <&clkctl 17>; */ + + status = "disabled"; + }; + lsspi: spi@10000800 { #address-cells = <1>; #size-cells = <0>; diff --git a/target/linux/bcm63xx/image/Makefile b/target/linux/bcm63xx/image/Makefile index 321aec93a1e..e392d99f2c5 100644 --- a/target/linux/bcm63xx/image/Makefile +++ b/target/linux/bcm63xx/image/Makefile @@ -105,6 +105,79 @@ define Build/cfe-bin $(CFE_EXTRAS) $(1) endef +define Build/cfe-jffs2 + $(STAGING_DIR_HOST)/bin/mkfs.jffs2 \ + --big-endian \ + --pad \ + --no-cleanmarkers \ + --eraseblock=$(patsubst %k,%KiB,$(BLOCKSIZE)) \ + --root=$(1) \ + --output=$@ \ + --compression-mode=none + + $(call Build/pad-to,$(BLOCKSIZE)) +endef + +define Build/cfe-jffs2-cferam + mv $@ $@.kernel + + rm -rf $@-cferam + mkdir -p $@-cferam + + # CFE ROM checks JFFS2 dirent version of cferam. + # If version is not > 0 it will ignore the fs entry. + # JFFS2 sets version 0 to the first fs entry and increments + # it on the following ones, so let's create a dummy file that + # will have version 0 and let cferam be the second (version 1). + touch $@-cferam/1-openwrt + # Add cferam as the last file in the JFFS2 partition + cp $(KDIR)/bcm63xx-cfe/$(CFE_RAM_FILE) $@-cferam/$(CFE_RAM_JFFS2_NAME) + + # The JFFS2 partition creation should result in the following + # layout: + # 1) 1-openwrt (version 0, ino 2) + # 2) cferam.000 (version 1, ino 3) + $(call Build/cfe-jffs2,$@-cferam) + + # Some devices need padding between CFE RAM and kernel + $(if $(CFE_RAM_JFFS2_PAD),$(call Build/pad-to,$(CFE_RAM_JFFS2_PAD))) + + # Append kernel + dd if=$@.kernel >> $@ + rm -f $@.kernel +endef + +define Build/cfe-jffs2-kernel + rm -rf $@-kernel + mkdir -p $@-kernel + + # CFE RAM checks JFFS2 dirent version of vmlinux. + # If version is not > 0 it will ignore the fs entry. + # JFFS2 sets version 0 to the first fs entry and increments + # it on the following ones, so let's create a dummy file that + # will have version 0 and let cferam be the second (version 1). + touch $@-kernel/1-openwrt + # vmlinux is located on a different JFFS2 partition, but CFE RAM + # ignores it, so let's create another dummy file that will match + # the JFFS2 ino of cferam entry on the first JFFS2 partition. + # CFE RAM won't be able to find vmlinux if cferam has the same + # ino as vmlinux. + touch $@-kernel/2-openwrt + # Add vmlinux as the last file in the JFFS2 partition + $(TOPDIR)/scripts/cfe-bin-header.py \ + --input-file $@ \ + --output-file $@-kernel/vmlinux.lz \ + --load-addr $(LOADER_ENTRY) \ + --entry-addr $(LOADER_ENTRY) + + # The JFFS2 partition creation should result in the following + # layout: + # 1) 1-openwrt (version 0, ino 2) + # 2) 2-openwrt (version 1, ino 3) + # 3) vmlinux.lz (version 2, ino 4) + $(call Build/cfe-jffs2,$@-kernel) +endef + define Build/cfe-old-bin $(TOPDIR)/scripts/brcmImage.pl -t -p \ -o $@ -b $(CFE_BOARD_ID) -c $(CFE_CHIP_ID) \ @@ -121,6 +194,17 @@ define Build/cfe-spw303v-bin $(CFE_EXTRAS) $(1) endef +define Build/cfe-wfi-tag + $(TOPDIR)/scripts/cfe-wfi-tag.py \ + --input-file $@ \ + --output-file $@.new \ + --version $(if $(1),$(1),$(CFE_WFI_VERSION)) \ + --chip-id $(CFE_WFI_CHIP_ID) \ + --flash-type $(CFE_WFI_FLASH_TYPE) \ + $(if $(CFE_WFI_FLAGS),--flags $(CFE_WFI_FLAGS)) + mv $@.new $@ +endef + define Build/spw303v-bin $(STAGING_DIR_HOST)/bin/spw303v -i $@ -o $@.spw303v mv $@.spw303v $@ @@ -170,4 +254,8 @@ USB2_PACKAGES := kmod-usb2 kmod-usb-ohci kmod-usb-ledtrig-usbport include bcm63xx.mk +ifeq ($(SUBTARGET),smp) +include bcm63xx_nand.mk +endif + $(eval $(call BuildImage)) diff --git a/target/linux/bcm63xx/image/bcm63xx_nand.mk b/target/linux/bcm63xx/image/bcm63xx_nand.mk new file mode 100644 index 00000000000..8e733f2b23c --- /dev/null +++ b/target/linux/bcm63xx/image/bcm63xx_nand.mk @@ -0,0 +1,35 @@ +# +# BCM63XX NAND Profiles +# + +DEVICE_VARS += CFE_RAM_FILE +DEVICE_VARS += CFE_RAM_JFFS2_NAME CFE_RAM_JFFS2_PAD +DEVICE_VARS += CFE_WFI_CHIP_ID CFE_WFI_FLASH_TYPE +DEVICE_VARS += CFE_WFI_FLAGS CFE_WFI_VERSION + +# CFE expects a single JFFS2 partition with cferam and kernel. However, +# it's possible to fool CFE into properly loading both cferam and kernel +# from two different JFFS2 partitions by adding dummy files (see +# cfe-jffs2-cferam and cfe-jffs2-kernel). +# Separate JFFS2 partitions allow upgrading openwrt without reflashing cferam +# JFFS2 partition, which is much safer in case anything goes wrong. +define Device/bcm63xx-nand + FILESYSTEMS := squashfs ubifs + KERNEL := kernel-bin | append-dtb | relocate-kernel | lzma | cfe-jffs2-kernel + KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-lzma elf + IMAGES := cfe.bin sysupgrade.bin + IMAGE/cfe.bin := append-kernel | pad-to $$$$(KERNEL_SIZE) | cfe-jffs2-cferam | append-ubi | cfe-wfi-tag + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata + KERNEL_SIZE := 5120k + CFE_CHIP_ID := + CFE_RAM_FILE := + CFE_RAM_JFFS2_NAME := + CFE_RAM_JFFS2_PAD := + CFE_WFI_VERSION := 0x5731 + CFE_WFI_CHIP_ID = 0x$$(CFE_CHIP_ID) + CFE_WFI_FLASH_TYPE := + CFE_WFI_FLAGS := + UBINIZE_OPTS := -E 5 + DEVICE_PACKAGES += nand-utils + SUPPORTED_DEVICES := $(subst _,$(comma),$(1)) +endef diff --git a/target/linux/bcm63xx/patches-5.4/430-MIPS-BCM63XX-add-nand-clocks.patch b/target/linux/bcm63xx/patches-5.4/430-MIPS-BCM63XX-add-nand-clocks.patch new file mode 100644 index 00000000000..883f76fe76b --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/430-MIPS-BCM63XX-add-nand-clocks.patch @@ -0,0 +1,50 @@ +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -430,6 +430,23 @@ static struct clk clk_pcie = { + }; + + /* ++ * NAND clock ++ */ ++static void nand_set(struct clk *clk, int enable) ++{ ++ if (BCMCPU_IS_6362()) ++ bcm_hwclock_set(CKCTL_6362_NAND_EN, enable); ++ else if (BCMCPU_IS_6368()) ++ bcm_hwclock_set(CKCTL_6368_NAND_EN, enable); ++ else if (BCMCPU_IS_63268()) ++ bcm_hwclock_set(CKCTL_63268_NAND_EN, enable); ++} ++ ++static struct clk clk_nand = { ++ .set = nand_set, ++}; ++ ++/* + * Internal peripheral clock + */ + static struct clk clk_periph = { +@@ -612,6 +629,7 @@ static struct clk_lookup bcm6362_clks[] + CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll), + CLKDEV_INIT("10001000.spi", "pll", &clk_hsspi_pll), + /* gated clocks */ ++ CLKDEV_INIT(NULL, "nand", &clk_nand), + CLKDEV_INIT(NULL, "enetsw", &clk_enetsw), + CLKDEV_INIT(NULL, "usbh", &clk_usbh), + CLKDEV_INIT(NULL, "usbd", &clk_usbd), +@@ -629,6 +647,7 @@ static struct clk_lookup bcm6368_clks[] + CLKDEV_INIT("10000100.serial", "refclk", &clk_periph), + CLKDEV_INIT("10000120.serial", "refclk", &clk_periph), + /* gated clocks */ ++ CLKDEV_INIT(NULL, "nand", &clk_nand), + CLKDEV_INIT(NULL, "enetsw", &clk_enetsw), + CLKDEV_INIT(NULL, "usbh", &clk_usbh), + CLKDEV_INIT(NULL, "usbd", &clk_usbd), +@@ -647,6 +666,7 @@ static struct clk_lookup bcm63268_clks[] + CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll), + CLKDEV_INIT("10001000.spi", "pll", &clk_hsspi_pll), + /* gated clocks */ ++ CLKDEV_INIT(NULL, "nand", &clk_nand), + CLKDEV_INIT(NULL, "enetsw", &clk_enetsw), + CLKDEV_INIT(NULL, "usbh", &clk_usbh), + CLKDEV_INIT(NULL, "usbd", &clk_usbd), diff --git a/target/linux/bcm63xx/patches-5.4/431-MIPS-BCM63XX-add-nand-rset.patch b/target/linux/bcm63xx/patches-5.4/431-MIPS-BCM63XX-add-nand-rset.patch new file mode 100644 index 00000000000..1172b231973 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/431-MIPS-BCM63XX-add-nand-rset.patch @@ -0,0 +1,145 @@ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -181,7 +181,8 @@ enum bcm63xx_regs_set { + RSET_PCMDMAC, + RSET_PCMDMAS, + RSET_RNG, +- RSET_MISC ++ RSET_MISC, ++ RSET_NAND + }; + + #define RSET_DSL_LMEM_SIZE (64 * 1024 * 4) +@@ -259,6 +260,7 @@ enum bcm63xx_regs_set { + #define BCM_3368_PCMDMAS_BASE (0xdeadbeef) + #define BCM_3368_RNG_BASE (0xdeadbeef) + #define BCM_3368_MISC_BASE (0xdeadbeef) ++#define BCM_3368_NAND_BASE (0xdeadbeef) + + /* + * 6318 register sets base address +@@ -306,6 +308,7 @@ enum bcm63xx_regs_set { + #define BCM_6318_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6318_RNG_BASE (0xdeadbeef) + #define BCM_6318_MISC_BASE (0xb0000280) ++#define BCM_6318_NAND_BASE (0xdeadbeef) + #define BCM_6318_OTP_BASE (0xdeadbeef) + + #define BCM_6318_STRAP_BASE (0xb0000900) +@@ -356,6 +359,7 @@ enum bcm63xx_regs_set { + #define BCM_6328_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6328_RNG_BASE (0xdeadbeef) + #define BCM_6328_MISC_BASE (0xb0001800) ++#define BCM_6328_NAND_BASE (0xb0000200) + #define BCM_6328_OTP_BASE (0xb0000600) + + /* +@@ -405,6 +409,7 @@ enum bcm63xx_regs_set { + #define BCM_6338_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6338_RNG_BASE (0xdeadbeef) + #define BCM_6338_MISC_BASE (0xdeadbeef) ++#define BCM_6338_NAND_BASE (0xdeadbeef) + + /* + * 6345 register sets base address +@@ -453,6 +458,7 @@ enum bcm63xx_regs_set { + #define BCM_6345_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6345_RNG_BASE (0xdeadbeef) + #define BCM_6345_MISC_BASE (0xdeadbeef) ++#define BCM_6345_NAND_BASE (0xdeadbeef) + + /* + * 6348 register sets base address +@@ -499,6 +505,7 @@ enum bcm63xx_regs_set { + #define BCM_6348_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6348_RNG_BASE (0xdeadbeef) + #define BCM_6348_MISC_BASE (0xdeadbeef) ++#define BCM_6348_NAND_BASE (0xdeadbeef) + + /* + * 6358 register sets base address +@@ -545,7 +552,7 @@ enum bcm63xx_regs_set { + #define BCM_6358_PCMDMAS_BASE (0xfffe1a00) + #define BCM_6358_RNG_BASE (0xdeadbeef) + #define BCM_6358_MISC_BASE (0xdeadbeef) +- ++#define BCM_6358_NAND_BASE (0xdeadbeef) + + /* + * 6362 register sets base address +@@ -593,6 +600,7 @@ enum bcm63xx_regs_set { + #define BCM_6362_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6362_RNG_BASE (0xdeadbeef) + #define BCM_6362_MISC_BASE (0xb0001800) ++#define BCM_6362_NAND_BASE (0xb0000200) + + #define BCM_6362_NAND_REG_BASE (0xb0000200) + #define BCM_6362_NAND_CACHE_BASE (0xb0000600) +@@ -648,6 +656,7 @@ enum bcm63xx_regs_set { + #define BCM_6368_PCMDMAS_BASE (0xb0005c00) + #define BCM_6368_RNG_BASE (0xb0004180) + #define BCM_6368_MISC_BASE (0xdeadbeef) ++#define BCM_6368_NAND_BASE (0xb0000200) + + /* + * 63268 register sets base address +@@ -695,6 +704,7 @@ enum bcm63xx_regs_set { + #define BCM_63268_PCMDMAS_BASE (0xdeadbeef) + #define BCM_63268_RNG_BASE (0xdeadbeef) + #define BCM_63268_MISC_BASE (0xb0001800) ++#define BCM_63268_NAND_BASE (0xb0000200) + + extern const unsigned long *bcm63xx_regs_base; + +@@ -740,6 +750,7 @@ extern const unsigned long *bcm63xx_regs + [RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \ + [RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \ + [RSET_MISC] = BCM_## __cpu ##_MISC_BASE, \ ++ [RSET_NAND] = BCM_## __cpu ##_NAND_BASE, \ + + + static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h +@@ -111,5 +111,7 @@ + #define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o)) + #define bcm_misc_readl(o) bcm_rset_readl(RSET_MISC, (o)) + #define bcm_misc_writel(v, o) bcm_rset_writel(RSET_MISC, (v), (o)) ++#define bcm_nand_readl(o) bcm_rset_readl(RSET_NAND, (o)) ++#define bcm_nand_writel(v, o) bcm_rset_writel(RSET_NAND, (v), (o)) + + #endif /* ! BCM63XX_IO_H_ */ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -1688,4 +1688,31 @@ + #define OTP_USER_BITS_6328_REG(i) (0x20 + (i) * 4) + #define OTP_6328_REG3_TP1_DISABLED BIT(9) + ++/************************************************************************* ++ * _REG relative to RSET_NAND ++ *************************************************************************/ ++ ++#define NAND_CS_SEL_REG 0x14 ++#define NAND_CS_SEL_EBC_CS0_SEL (1 << 0) ++#define NAND_CS_SEL_EBC_CS1_SEL (1 << 1) ++#define NAND_CS_SEL_EBC_CS2_SEL (1 << 2) ++#define NAND_CS_SEL_EBC_CS3_SEL (1 << 3) ++#define NAND_CS_SEL_EBC_CS4_SEL (1 << 4) ++#define NAND_CS_SEL_EBC_CS5_SEL (1 << 5) ++#define NAND_CS_SEL_EBC_CS6_SEL (1 << 6) ++#define NAND_CS_SEL_EBC_CS7_SEL (1 << 7) ++#define NAND_CS_SEL_EBI_CS0_USES_NAND (1 << 8) ++#define NAND_CS_SEL_EBI_CS1_USES_NAND (1 << 9) ++#define NAND_CS_SEL_EBI_CS2_USES_NAND (1 << 10) ++#define NAND_CS_SEL_EBI_CS3_USES_NAND (1 << 11) ++#define NAND_CS_SEL_EBI_CS4_USES_NAND (1 << 12) ++#define NAND_CS_SEL_EBI_CS5_USES_NAND (1 << 13) ++#define NAND_CS_SEL_EBI_CS6_USES_NAND (1 << 14) ++#define NAND_CS_SEL_EBI_CS7_USES_NAND (1 << 15) ++#define NAND_CS_SEL_WR_PROT_BLK0 (1 << 28) ++#define NAND_CS_SEL_AUTO_DEV_ID (1 << 30) ++#define NAND_CS_SEL_CS_LOCK (1 << 31) ++ ++#define NAND_CS_XOR_REG 0x18 ++ + #endif /* BCM63XX_REGS_H_ */ diff --git a/target/linux/bcm63xx/patches-5.4/432-MIPS-BCM63XX-detect-nand-nvram.patch b/target/linux/bcm63xx/patches-5.4/432-MIPS-BCM63XX-detect-nand-nvram.patch new file mode 100644 index 00000000000..5a2a5f2489a --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/432-MIPS-BCM63XX-detect-nand-nvram.patch @@ -0,0 +1,17 @@ +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -229,6 +229,14 @@ void __init bcm63xx_flash_detect(void) + } + + bcm_rset_writel(RSET_HSSPI, val, HSSPI_FLASH_CTRL_REG); ++ } else if (flash_type == BCM63XX_FLASH_TYPE_NAND && ++ (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368() || ++ BCMCPU_IS_63268())) { ++ bcm_nand_writel(NAND_CS_SEL_AUTO_DEV_ID ++ | NAND_CS_SEL_EBI_CS0_USES_NAND ++ | NAND_CS_SEL_EBC_CS0_SEL, ++ NAND_CS_SEL_REG); ++ bcm_nand_writel(1, NAND_CS_XOR_REG); + } + } + diff --git a/target/linux/bcm63xx/patches-5.4/433-MIPS-BCM63XX-enable-nand-support.patch b/target/linux/bcm63xx/patches-5.4/433-MIPS-BCM63XX-enable-nand-support.patch new file mode 100644 index 00000000000..7d63ee79830 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/433-MIPS-BCM63XX-enable-nand-support.patch @@ -0,0 +1,17 @@ +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -271,8 +271,12 @@ int __init bcm63xx_flash_register(void) + return -ENODEV; + } + case BCM63XX_FLASH_TYPE_NAND: +- pr_warn("unsupported NAND flash detected\n"); +- return -ENODEV; ++ if (board_of_device_present("nflash")) { ++ return 0; ++ } else { ++ pr_warn("unsupported NAND flash detected\n"); ++ return -ENODEV; ++ } + default: + pr_err("flash detection failed for BCM%x: %d\n", + bcm63xx_get_cpu_id(), flash_type); diff --git a/target/linux/bcm63xx/patches-5.4/434-nand-raw-use-write_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch b/target/linux/bcm63xx/patches-5.4/434-nand-raw-use-write_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch new file mode 100644 index 00000000000..cf4322f29fb --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/434-nand-raw-use-write_oob_raw-for-MTD_OPS_AUTO_OOB-mode.patch @@ -0,0 +1,11 @@ +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -488,7 +488,7 @@ static int nand_do_write_oob(struct nand + + nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops); + +- if (ops->mode == MTD_OPS_RAW) ++ if (ops->mode == MTD_OPS_AUTO_OOB || ops->mode == MTD_OPS_RAW) + status = chip->ecc.write_oob_raw(chip, page & chip->pagemask); + else + status = chip->ecc.write_oob(chip, page & chip->pagemask); diff --git a/target/linux/bcm63xx/patches-5.4/435-mtd-rawnand-brcmnand-correctly-verify-erased-pages.patch b/target/linux/bcm63xx/patches-5.4/435-mtd-rawnand-brcmnand-correctly-verify-erased-pages.patch new file mode 100644 index 00000000000..cbd9e9e1478 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/435-mtd-rawnand-brcmnand-correctly-verify-erased-pages.patch @@ -0,0 +1,42 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -1787,28 +1787,31 @@ static int brcmnand_read_by_pio(struct m + static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, + struct nand_chip *chip, void *buf, u64 addr) + { +- int i, sas; +- void *oob = chip->oob_poi; ++ struct mtd_oob_region ecc; ++ int i; + int bitflips = 0; + int page = addr >> chip->page_shift; + int ret; ++ void *ecc_bytes; + void *ecc_chunk; + + if (!buf) + buf = nand_get_data_buf(chip); + +- sas = mtd->oobsize / chip->ecc.steps; +- + /* read without ecc for verification */ + ret = chip->ecc.read_page_raw(chip, buf, true, page); + if (ret) + return ret; + +- for (i = 0; i < chip->ecc.steps; i++, oob += sas) { ++ for (i = 0; i < chip->ecc.steps; i++) { + ecc_chunk = buf + chip->ecc.size * i; +- ret = nand_check_erased_ecc_chunk(ecc_chunk, +- chip->ecc.size, +- oob, sas, NULL, 0, ++ ++ mtd_ooblayout_ecc(mtd, i, &ecc); ++ ecc_bytes = chip->oob_poi + ecc.offset; ++ ++ ret = nand_check_erased_ecc_chunk(ecc_chunk, chip->ecc.size, ++ ecc_bytes, ecc.length, ++ NULL, 0, + chip->ecc.strength); + if (ret < 0) + return ret; diff --git a/target/linux/bcm63xx/patches-5.4/436-mtd-rawnand-brcmnand-fix-hamming-oob-layout.patch b/target/linux/bcm63xx/patches-5.4/436-mtd-rawnand-brcmnand-fix-hamming-oob-layout.patch new file mode 100644 index 00000000000..40536c282f8 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/436-mtd-rawnand-brcmnand-fix-hamming-oob-layout.patch @@ -0,0 +1,21 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -1019,11 +1019,14 @@ static int brcmnand_hamming_ooblayout_fr + if (!section) { + /* + * Small-page NAND use byte 6 for BBI while large-page +- * NAND use byte 0. ++ * NAND use bytes 0 and 1. + */ +- if (cfg->page_size > 512) +- oobregion->offset++; +- oobregion->length--; ++ if (cfg->page_size > 512) { ++ oobregion->offset += 2; ++ oobregion->length -= 2; ++ } else { ++ oobregion->length--; ++ } + } + } + diff --git a/target/linux/bcm63xx/patches-5.4/437-mtd-rawnand-brcmnand-improve-hamming-oob-layout.patch b/target/linux/bcm63xx/patches-5.4/437-mtd-rawnand-brcmnand-improve-hamming-oob-layout.patch new file mode 100644 index 00000000000..68bbc7ad193 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/437-mtd-rawnand-brcmnand-improve-hamming-oob-layout.patch @@ -0,0 +1,52 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -1003,33 +1003,30 @@ static int brcmnand_hamming_ooblayout_fr + struct brcmnand_cfg *cfg = &host->hwcfg; + int sas = cfg->spare_area_size << cfg->sector_size_1k; + int sectors = cfg->page_size / (512 << cfg->sector_size_1k); ++ u32 next; + +- if (section >= sectors * 2) ++ if (section > sectors) + return -ERANGE; + +- oobregion->offset = (section / 2) * sas; ++ next = (section * sas); ++ if (section < sectors) ++ next += 6; + +- if (section & 1) { +- oobregion->offset += 9; +- oobregion->length = 7; ++ if (section) { ++ oobregion->offset = ((section - 1) * sas) + 9; + } else { +- oobregion->length = 6; +- +- /* First sector of each page may have BBI */ +- if (!section) { +- /* +- * Small-page NAND use byte 6 for BBI while large-page +- * NAND use bytes 0 and 1. +- */ +- if (cfg->page_size > 512) { +- oobregion->offset += 2; +- oobregion->length -= 2; +- } else { +- oobregion->length--; +- } ++ if (cfg->page_size > 512) { ++ /* Large page NAND uses first 2 bytes for BBI */ ++ oobregion->offset = 2; ++ } else { ++ /* Small page NAND uses last byte before ECC for BBI */ ++ oobregion->offset = 0; ++ next--; + } + } + ++ oobregion->length = next - oobregion->offset; ++ + return 0; + } + diff --git a/target/linux/bcm63xx/patches-5.4/438-mtd-rawnand-brcmnand-rename-v4-registers.patch b/target/linux/bcm63xx/patches-5.4/438-mtd-rawnand-brcmnand-rename-v4-registers.patch new file mode 100644 index 00000000000..091f63f6631 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/438-mtd-rawnand-brcmnand-rename-v4-registers.patch @@ -0,0 +1,24 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -269,8 +269,8 @@ enum brcmnand_reg { + BRCMNAND_FC_BASE, + }; + +-/* BRCMNAND v4.0 */ +-static const u16 brcmnand_regs_v40[] = { ++/* BRCMNAND v3.3-v4.0 */ ++static const u16 brcmnand_regs_v33[] = { + [BRCMNAND_CMD_START] = 0x04, + [BRCMNAND_CMD_EXT_ADDRESS] = 0x08, + [BRCMNAND_CMD_ADDRESS] = 0x0c, +@@ -522,8 +522,8 @@ static int brcmnand_revision_init(struct + ctrl->reg_offsets = brcmnand_regs_v60; + else if (ctrl->nand_version >= 0x0500) + ctrl->reg_offsets = brcmnand_regs_v50; +- else if (ctrl->nand_version >= 0x0400) +- ctrl->reg_offsets = brcmnand_regs_v40; ++ else if (ctrl->nand_version >= 0x0303) ++ ctrl->reg_offsets = brcmnand_regs_v33; + + /* Chip-select stride */ + if (ctrl->nand_version >= 0x0701) diff --git a/target/linux/bcm63xx/patches-5.4/439-mtd-rawnand-brcmnand-fix-CS0-layout.patch b/target/linux/bcm63xx/patches-5.4/439-mtd-rawnand-brcmnand-fix-CS0-layout.patch new file mode 100644 index 00000000000..fdeff8734d9 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/439-mtd-rawnand-brcmnand-fix-CS0-layout.patch @@ -0,0 +1,14 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -537,8 +537,9 @@ static int brcmnand_revision_init(struct + } else { + ctrl->cs_offsets = brcmnand_cs_offsets; + +- /* v5.0 and earlier has a different CS0 offset layout */ +- if (ctrl->nand_version <= 0x0500) ++ /* v3.3-5.0 have a different CS0 offset layout */ ++ if (ctrl->nand_version >= 0x0303 && ++ ctrl->nand_version <= 0x0500) + ctrl->cs0_offsets = brcmnand_cs_offsets_cs0; + } + diff --git a/target/linux/bcm63xx/patches-5.4/440-mtd-rawnand-brcmnand-rename-page-sizes.patch b/target/linux/bcm63xx/patches-5.4/440-mtd-rawnand-brcmnand-rename-page-sizes.patch new file mode 100644 index 00000000000..cdf8d3d4d60 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/440-mtd-rawnand-brcmnand-rename-page-sizes.patch @@ -0,0 +1,20 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -502,7 +502,7 @@ static int brcmnand_revision_init(struct + { + static const unsigned int block_sizes_v6[] = { 8, 16, 128, 256, 512, 1024, 2048, 0 }; + static const unsigned int block_sizes_v4[] = { 16, 128, 8, 512, 256, 1024, 2048, 0 }; +- static const unsigned int page_sizes[] = { 512, 2048, 4096, 8192, 0 }; ++ static const unsigned int page_sizes_v3_4[] = { 512, 2048, 4096, 8192, 0 }; + + ctrl->nand_version = nand_readreg(ctrl, 0) & 0xffff; + +@@ -549,7 +549,7 @@ static int brcmnand_revision_init(struct + ctrl->max_page_size = 16 * 1024; + ctrl->max_block_size = 2 * 1024 * 1024; + } else { +- ctrl->page_sizes = page_sizes; ++ ctrl->page_sizes = page_sizes_v3_4; + if (ctrl->nand_version >= 0x0600) + ctrl->block_sizes = block_sizes_v6; + else diff --git a/target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch b/target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch new file mode 100644 index 00000000000..a212a5bda93 --- /dev/null +++ b/target/linux/bcm63xx/patches-5.4/441-mtd-rawnand-brcmnand-support-v2.1-v2.2-controllers.patch @@ -0,0 +1,143 @@ +--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c ++++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c +@@ -269,6 +269,36 @@ enum brcmnand_reg { + BRCMNAND_FC_BASE, + }; + ++/* BRCMNAND v2.1-v2.2 */ ++static const u16 brcmnand_regs_v21[] = { ++ [BRCMNAND_CMD_START] = 0x04, ++ [BRCMNAND_CMD_EXT_ADDRESS] = 0x08, ++ [BRCMNAND_CMD_ADDRESS] = 0x0c, ++ [BRCMNAND_INTFC_STATUS] = 0x5c, ++ [BRCMNAND_CS_SELECT] = 0x14, ++ [BRCMNAND_CS_XOR] = 0x18, ++ [BRCMNAND_LL_OP] = 0, ++ [BRCMNAND_CS0_BASE] = 0x40, ++ [BRCMNAND_CS1_BASE] = 0, ++ [BRCMNAND_CORR_THRESHOLD] = 0, ++ [BRCMNAND_CORR_THRESHOLD_EXT] = 0, ++ [BRCMNAND_UNCORR_COUNT] = 0, ++ [BRCMNAND_CORR_COUNT] = 0, ++ [BRCMNAND_CORR_EXT_ADDR] = 0x60, ++ [BRCMNAND_CORR_ADDR] = 0x64, ++ [BRCMNAND_UNCORR_EXT_ADDR] = 0x68, ++ [BRCMNAND_UNCORR_ADDR] = 0x6c, ++ [BRCMNAND_SEMAPHORE] = 0x50, ++ [BRCMNAND_ID] = 0x54, ++ [BRCMNAND_ID_EXT] = 0, ++ [BRCMNAND_LL_RDATA] = 0, ++ [BRCMNAND_OOB_READ_BASE] = 0x20, ++ [BRCMNAND_OOB_READ_10_BASE] = 0, ++ [BRCMNAND_OOB_WRITE_BASE] = 0x30, ++ [BRCMNAND_OOB_WRITE_10_BASE] = 0, ++ [BRCMNAND_FC_BASE] = 0x200, ++}; ++ + /* BRCMNAND v3.3-v4.0 */ + static const u16 brcmnand_regs_v33[] = { + [BRCMNAND_CMD_START] = 0x04, +@@ -502,12 +532,16 @@ static int brcmnand_revision_init(struct + { + static const unsigned int block_sizes_v6[] = { 8, 16, 128, 256, 512, 1024, 2048, 0 }; + static const unsigned int block_sizes_v4[] = { 16, 128, 8, 512, 256, 1024, 2048, 0 }; ++ static const unsigned int block_sizes_v2_2[] = { 16, 128, 8, 512, 256, 0 }; ++ static const unsigned int block_sizes_v2_1[] = { 16, 128, 8, 512, 0 }; + static const unsigned int page_sizes_v3_4[] = { 512, 2048, 4096, 8192, 0 }; ++ static const unsigned int page_sizes_v2_2[] = { 512, 2048, 4096, 0 }; ++ static const unsigned int page_sizes_v2_1[] = { 512, 2048, 0 }; + + ctrl->nand_version = nand_readreg(ctrl, 0) & 0xffff; + +- /* Only support v4.0+? */ +- if (ctrl->nand_version < 0x0400) { ++ /* Only support v2.1+ */ ++ if (ctrl->nand_version < 0x0201) { + dev_err(ctrl->dev, "version %#x not supported\n", + ctrl->nand_version); + return -ENODEV; +@@ -524,6 +558,8 @@ static int brcmnand_revision_init(struct + ctrl->reg_offsets = brcmnand_regs_v50; + else if (ctrl->nand_version >= 0x0303) + ctrl->reg_offsets = brcmnand_regs_v33; ++ else if (ctrl->nand_version >= 0x0201) ++ ctrl->reg_offsets = brcmnand_regs_v21; + + /* Chip-select stride */ + if (ctrl->nand_version >= 0x0701) +@@ -549,14 +585,27 @@ static int brcmnand_revision_init(struct + ctrl->max_page_size = 16 * 1024; + ctrl->max_block_size = 2 * 1024 * 1024; + } else { +- ctrl->page_sizes = page_sizes_v3_4; ++ if (ctrl->nand_version >= 0x0304) ++ ctrl->page_sizes = page_sizes_v3_4; ++ else if (ctrl->nand_version >= 0x0202) ++ ctrl->page_sizes = page_sizes_v2_2; ++ else ++ ctrl->page_sizes = page_sizes_v2_1; ++ + if (ctrl->nand_version >= 0x0600) + ctrl->block_sizes = block_sizes_v6; +- else ++ else if (ctrl->nand_version >= 0x0400) + ctrl->block_sizes = block_sizes_v4; ++ else if (ctrl->nand_version >= 0x0202) ++ ctrl->block_sizes = block_sizes_v2_2; ++ else ++ ctrl->block_sizes = block_sizes_v2_1; + + if (ctrl->nand_version < 0x0400) { +- ctrl->max_page_size = 4096; ++ if (ctrl->nand_version < 0x0202) ++ ctrl->max_page_size = 2048; ++ else ++ ctrl->max_page_size = 4096; + ctrl->max_block_size = 512 * 1024; + } + } +@@ -724,6 +773,9 @@ static void brcmnand_wr_corr_thresh(stru + enum brcmnand_reg reg = BRCMNAND_CORR_THRESHOLD; + int cs = host->cs; + ++ if (!ctrl->reg_offsets[reg]) ++ return; ++ + if (ctrl->nand_version == 0x0702) + bits = 7; + else if (ctrl->nand_version >= 0x0600) +@@ -782,8 +834,10 @@ static inline u32 brcmnand_spare_area_ma + return GENMASK(7, 0); + else if (ctrl->nand_version >= 0x0600) + return GENMASK(6, 0); +- else ++ else if (ctrl->nand_version >= 0x0303) + return GENMASK(5, 0); ++ else ++ return GENMASK(4, 0); + } + + #define NAND_ACC_CONTROL_ECC_SHIFT 16 +@@ -2158,9 +2212,11 @@ static int brcmnand_set_cfg(struct brcmn + + tmp = nand_readreg(ctrl, acc_control_offs); + tmp &= ~brcmnand_ecc_level_mask(ctrl); +- tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; + tmp &= ~brcmnand_spare_area_mask(ctrl); +- tmp |= cfg->spare_area_size; ++ if (ctrl->nand_version >= 0x0302) { ++ tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; ++ tmp |= cfg->spare_area_size; ++ } + nand_writereg(ctrl, acc_control_offs, tmp); + + brcmnand_set_sector_size_1k(host, cfg->sector_size_1k); +@@ -2524,6 +2580,8 @@ const struct dev_pm_ops brcmnand_pm_ops + EXPORT_SYMBOL_GPL(brcmnand_pm_ops); + + static const struct of_device_id brcmnand_of_match[] = { ++ { .compatible = "brcm,brcmnand-v2.1" }, ++ { .compatible = "brcm,brcmnand-v2.2" }, + { .compatible = "brcm,brcmnand-v4.0" }, + { .compatible = "brcm,brcmnand-v5.0" }, + { .compatible = "brcm,brcmnand-v6.0" }, diff --git a/target/linux/bcm63xx/patches-5.4/511-board_V2500V.patch b/target/linux/bcm63xx/patches-5.4/511-board_V2500V.patch index e2a10846e0f..47590af6e3d 100644 --- a/target/linux/bcm63xx/patches-5.4/511-board_V2500V.patch +++ b/target/linux/bcm63xx/patches-5.4/511-board_V2500V.patch @@ -76,7 +76,7 @@ #include #include #include -@@ -248,6 +249,13 @@ int __init bcm63xx_flash_register(void) +@@ -256,6 +257,13 @@ int __init bcm63xx_flash_register(void) val = bcm_mpi_readl(MPI_CSBASE_REG(0)); val &= MPI_CSBASE_BASE_MASK; diff --git a/target/linux/bcm63xx/smp/config-default b/target/linux/bcm63xx/smp/config-default index 935e97f91a7..cc43bb20239 100644 --- a/target/linux/bcm63xx/smp/config-default +++ b/target/linux/bcm63xx/smp/config-default @@ -1,17 +1,48 @@ CONFIG_CPU_RMAP=y +CONFIG_CRC16=y +CONFIG_CRYPTO_ACOMP2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_LZO=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_NULL2=y +CONFIG_CRYPTO_ZSTD=y +CONFIG_JFFS2_FS_NAND=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MTD_NAND_BRCMNAND=y +CONFIG_MTD_NAND_CORE=y +CONFIG_MTD_NAND_ECC_SW_HAMMING=y +CONFIG_MTD_RAW_NAND=y +CONFIG_MTD_SPLIT_BCM_WFI_FW=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_LIMIT=20 +CONFIG_MTD_UBI_BLOCK=y +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 CONFIG_NET_FLOW_LIMIT=y CONFIG_NR_CPUS=2 CONFIG_PADATA=y CONFIG_RCU_STALL_COMMON=y CONFIG_RFS_ACCEL=y CONFIG_RPS=y +CONFIG_SGL_ALLOC=y CONFIG_SMP=y CONFIG_SMP_UP=y CONFIG_TREE_RCU=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UBIFS_FS_ZSTD=y CONFIG_XPS=y +CONFIG_XXHASH=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZSTD_COMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y diff --git a/target/linux/bcm63xx/smp/target.mk b/target/linux/bcm63xx/smp/target.mk index b0ccf97498d..36bc2becdc0 100644 --- a/target/linux/bcm63xx/smp/target.mk +++ b/target/linux/bcm63xx/smp/target.mk @@ -1,8 +1,17 @@ BOARDNAME:=smp +FEATURES+=nand define Target/Description - Build firmware images for BCM63XX boards with SMP support. - Currently only BCM6362 and BCM6368 supported. + Build firmware images for BCM63XX boards with SMP and NAND support. + SoCs with 2 cores: + - BCM6328 (some boards only have 1 core) + - BCM6358 (SMP unsupported due to shared TLB) + - BCM6362 + - BCM6368 + - BCM63268 + SoCs with NAND controller: + - BCM6328 (v2.2) + - BCM6362 (v2.2) + - BCM6368 (v2.1) + - BCM63268 (v4.0) endef - -