 c06fb25d1f
			
		
	
	c06fb25d1f
	
	
		
			
	
		
	
	
		
			Some checks failed
		
		
	
	Build Kernel / Build all affected Kernels (push) Has been cancelled
				
			Build all core packages / Build all core packages for selected target (push) Has been cancelled
				
			Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
				
			Build Toolchains / Build Toolchains for each target (push) Has been cancelled
				
			Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
				
			Coverity scan build / Coverity x86/64 build (push) Has been cancelled
				
			
		
			
				
	
	
		
			171 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From f32085fc0b87049491b07e198d924d738a1a2834 Mon Sep 17 00:00:00 2001
 | |
| From: Daniel Danzberger <daniel@dd-wrt.com>
 | |
| Date: Wed, 3 Aug 2022 17:31:03 +0200
 | |
| Subject: [PATCH] mtd: spinand: Add support for Etron EM73D044VCx
 | |
| 
 | |
| Airoha is a new ARM platform based on Cortex-A53 which has recently been
 | |
| merged into linux-next.
 | |
| 
 | |
| Due to BootROM limitations on this platform, the Cortex-A53 can't run in
 | |
| Aarch64 mode and code must be compiled for 32-Bit ARM.
 | |
| 
 | |
| This support is based mostly on those linux-next commits backported
 | |
| for kernel 5.15.
 | |
| 
 | |
| Patches:
 | |
| 1 - platform support = linux-next
 | |
| 2 - clock driver = linux-next
 | |
| 3 - gpio driver = linux-next
 | |
| 4 - linux,usable-memory-range dts support = linux-next
 | |
| 5 - mtd spinand driver
 | |
| 6 - spi driver
 | |
| 7 - pci driver (kconfig only, uses mediatek PCI) = linux-next
 | |
| 
 | |
| Still missing:
 | |
| - Ethernet driver
 | |
| - Sysupgrade support
 | |
| 
 | |
| A.t.m there exists one subtarget EN7523 with only one evaluation
 | |
| board.
 | |
| 
 | |
| The initramfs can be run with the following commands from u-boot:
 | |
| -
 | |
| u-boot> setenv bootfile \
 | |
| 	openwrt-airoha-airoha_en7523-evb-initramfs-kernel.bin
 | |
| u-boot> tftpboot
 | |
| u-boot> bootm 0x81800000
 | |
| -
 | |
| 
 | |
| Submitted-by: Daniel Danzberger <daniel@dd-wrt.com>
 | |
| 
 | |
| --- a/drivers/mtd/nand/spi/Makefile
 | |
| +++ b/drivers/mtd/nand/spi/Makefile
 | |
| @@ -1,4 +1,4 @@
 | |
|  # SPDX-License-Identifier: GPL-2.0
 | |
| -spinand-objs := core.o alliancememory.o ato.o esmt.o foresee.o gigadevice.o macronix.o
 | |
| -spinand-objs += micron.o paragon.o toshiba.o winbond.o xtx.o
 | |
| +spinand-objs := core.o alliancememory.o ato.o esmt.o etron.o foresee.o gigadevice.o
 | |
| +spinand-objs += macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
 | |
|  obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
 | |
| --- a/drivers/mtd/nand/spi/core.c
 | |
| +++ b/drivers/mtd/nand/spi/core.c
 | |
| @@ -940,6 +940,7 @@ static const struct spinand_manufacturer
 | |
|  	&alliancememory_spinand_manufacturer,
 | |
|  	&ato_spinand_manufacturer,
 | |
|  	&esmt_c8_spinand_manufacturer,
 | |
| +	&etron_spinand_manufacturer,
 | |
|  	&foresee_spinand_manufacturer,
 | |
|  	&gigadevice_spinand_manufacturer,
 | |
|  	¯onix_spinand_manufacturer,
 | |
| --- /dev/null
 | |
| +++ b/drivers/mtd/nand/spi/etron.c
 | |
| @@ -0,0 +1,98 @@
 | |
| +// SPDX-License-Identifier: GPL-2.0
 | |
| +
 | |
| +#include <linux/device.h>
 | |
| +#include <linux/kernel.h>
 | |
| +#include <linux/mtd/spinand.h>
 | |
| +
 | |
| +#define SPINAND_MFR_ETRON			0xd5
 | |
| +
 | |
| +
 | |
| +static SPINAND_OP_VARIANTS(read_cache_variants,
 | |
| +		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
 | |
| +		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
 | |
| +		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
 | |
| +		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
 | |
| +		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
 | |
| +		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
 | |
| +
 | |
| +static SPINAND_OP_VARIANTS(write_cache_variants,
 | |
| +		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
 | |
| +		SPINAND_PROG_LOAD(true, 0, NULL, 0));
 | |
| +
 | |
| +static SPINAND_OP_VARIANTS(update_cache_variants,
 | |
| +		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
 | |
| +		SPINAND_PROG_LOAD(false, 0, NULL, 0));
 | |
| +
 | |
| +static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
 | |
| +					struct mtd_oob_region *oobregion)
 | |
| +{
 | |
| +	if (section)
 | |
| +		return -ERANGE;
 | |
| +
 | |
| +	oobregion->offset = 72;
 | |
| +	oobregion->length = 56;
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static int etron_ooblayout_free(struct mtd_info *mtd, int section,
 | |
| +			   struct mtd_oob_region *oobregion)
 | |
| +{
 | |
| +	if (section)
 | |
| +		return -ERANGE;
 | |
| +
 | |
| +	oobregion->offset = 1;
 | |
| +	oobregion->length = 71;
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
 | |
| +{
 | |
| +	switch (status & STATUS_ECC_MASK) {
 | |
| +	case STATUS_ECC_NO_BITFLIPS:
 | |
| +		return 0;
 | |
| +
 | |
| +	case STATUS_ECC_HAS_BITFLIPS:
 | |
| +		/* Between 1-7 bitflips were corrected */
 | |
| +		return 7;
 | |
| +
 | |
| +	case STATUS_ECC_MASK:
 | |
| +		/* Maximum bitflips were corrected */
 | |
| +		return 8;
 | |
| +
 | |
| +	case STATUS_ECC_UNCOR_ERROR:
 | |
| +		return -EBADMSG;
 | |
| +	}
 | |
| +
 | |
| +	return -EINVAL;
 | |
| +}
 | |
| +
 | |
| +static const struct mtd_ooblayout_ops etron_ooblayout = {
 | |
| +	.ecc = etron_ooblayout_ecc,
 | |
| +	.free = etron_ooblayout_free,
 | |
| +};
 | |
| +
 | |
| +static const struct spinand_info etron_spinand_table[] = {
 | |
| +	SPINAND_INFO("EM73D044VCx",
 | |
| +		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f),
 | |
| +		     // bpc, pagesize, oobsize, pagesperblock, bperlun, maxbadplun, ppl, lpt, #t
 | |
| +		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
 | |
| +		     NAND_ECCREQ(8, 512),
 | |
| +		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
 | |
| +					      &write_cache_variants,
 | |
| +					      &update_cache_variants),
 | |
| +		     SPINAND_HAS_QE_BIT,
 | |
| +		     SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
 | |
| +};
 | |
| +
 | |
| +static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
 | |
| +};
 | |
| +
 | |
| +const struct spinand_manufacturer etron_spinand_manufacturer = {
 | |
| +	.id = SPINAND_MFR_ETRON,
 | |
| +	.name = "Etron",
 | |
| +	.chips = etron_spinand_table,
 | |
| +	.nchips = ARRAY_SIZE(etron_spinand_table),
 | |
| +	.ops = &etron_spinand_manuf_ops,
 | |
| +};
 | |
| --- a/include/linux/mtd/spinand.h
 | |
| +++ b/include/linux/mtd/spinand.h
 | |
| @@ -263,6 +263,7 @@ struct spinand_manufacturer {
 | |
|  extern const struct spinand_manufacturer alliancememory_spinand_manufacturer;
 | |
|  extern const struct spinand_manufacturer ato_spinand_manufacturer;
 | |
|  extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
 | |
| +extern const struct spinand_manufacturer etron_spinand_manufacturer;
 | |
|  extern const struct spinand_manufacturer foresee_spinand_manufacturer;
 | |
|  extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
 | |
|  extern const struct spinand_manufacturer macronix_spinand_manufacturer;
 |