Skip to content

Commit

Permalink
nand: Support longsys nand flash
Browse files Browse the repository at this point in the history
Summary:
    Support longsys nand flash(64MB).

Signed-off-by: yaqiang.li <[email protected]>
  • Loading branch information
yaqiang.li committed Dec 8, 2022
1 parent cdd89be commit 937b4ca
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 2 deletions.
2 changes: 1 addition & 1 deletion drivers/mtd/nand/spi/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
spinand-objs := core.o macronix.o micron.o winbond.o gigadevice.o esmt.o xtx.o
spinand-objs := core.o macronix.o micron.o winbond.o gigadevice.o esmt.o xtx.o longsys.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
3 changes: 2 additions & 1 deletion drivers/mtd/nand/spi/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,7 @@ static const struct nand_ops spinand_ops = {

static const struct spinand_manufacturer *spinand_manufacturers[] = {
&gigadevice_spinand_manufacturer,
&longsys_spinand_manufacturer,
&macronix_spinand_manufacturer,
#if IS_ENABLED(CONFIG_SPINAND_ESMT)
&esmt_spinand_manufacturer,
Expand Down Expand Up @@ -911,7 +912,7 @@ static int spinand_detect(struct spinand_device *spinand)

spinand->id.len = SPINAND_MAX_ID_LEN;

ret = spinand_manufacturer_detect(spinand);
ret = spinand_manufacturer_detect(spinand);
if (ret) {
dev_err(dev, "unknown raw ID %*phN\n", SPINAND_MAX_ID_LEN,
spinand->id.data);
Expand Down
108 changes: 108 additions & 0 deletions drivers/mtd/nand/spi/longsys.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2019 Horizon Robotics, Inc.
* All rights reserved.
*
* Author:
*› Peng01 Liu<[email protected]>
*/

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/mtd/spinand.h>

#define SPINAND_MFR_LONGSYS 0xCD
#define SPINAND_DID_LONGSYS 0x60

static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_X4_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(true, 0, NULL, 0));

static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD(false, 0, NULL, 0));

static int f35uqa512m_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section > 3)
return -ERANGE;

/* ECC is not user accessible */
region->offset = 0;
region->length = 0;

return 0;
}

static int f35uqa512m_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
if (section > 3)
return -ERANGE;

/*
* No ECC data is stored in the accessible OOB so the full 16 bytes
* of each spare region is available to the user. Apparently also
* covered by the internal ECC.
*/
if (section) {
region->offset = 16 * section;
region->length = 16;
} else {
/* First byte in spare0 area is used for bad block marker */
region->offset = 1;
region->length = 15;
}

return 0;
}

static const struct mtd_ooblayout_ops f35uqa512m_ooblayout = {
.ecc = f35uqa512m_ooblayout_ecc,
.free = f35uqa512m_ooblayout_free,
};

static const struct spinand_info longsys_spinand_table[] = {
SPINAND_INFO("F35UQA512M", 0xCD,
NAND_MEMORG(1, 2048, 64, 64, 512, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&f35uqa512m_ooblayout,
NULL)),

};

static int longsysdevice_spinand_detect(struct spinand_device *spinand)
{
u8 *id = spinand->id.data;
int ret, i = 0;

if (id[1] != SPINAND_MFR_LONGSYS)
return 0;

ret = spinand_match_and_init(spinand, longsys_spinand_table,
ARRAY_SIZE(longsys_spinand_table),
id[1]);
if (ret)
return ret;

return 1;
}

static const struct spinand_manufacturer_ops longsys_spinand_manuf_ops = {
.detect = longsysdevice_spinand_detect,
};

const struct spinand_manufacturer longsys_spinand_manufacturer = {
.id = SPINAND_MFR_LONGSYS,
.name = "Longsys",
.ops = &longsys_spinand_manuf_ops,
};
1 change: 1 addition & 0 deletions include/linux/mtd/spinand.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ extern const struct spinand_manufacturer micron_spinand_manufacturer;
extern const struct spinand_manufacturer winbond_spinand_manufacturer;
extern const struct spinand_manufacturer esmt_spinand_manufacturer;
extern const struct spinand_manufacturer xtx_spinand_manufacturer;
extern const struct spinand_manufacturer longsys_spinand_manufacturer;

/**
* struct spinand_op_variants - SPI NAND operation variants
Expand Down

0 comments on commit 937b4ca

Please sign in to comment.