atf: add support for dosilicon fmsh gsto spi nand
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -19,8 +19,11 @@
|
||||
|
||||
#define SPI_NAND_MAX_ID_LEN 4U
|
||||
#define DELAY_US_400MS 400000U
|
||||
#define DOSILICON_ID 0xE5U
|
||||
#define ETRON_ID 0xD5U
|
||||
#define FMSH_ID 0xA1U
|
||||
#define GIGADEVICE_ID 0xC8U
|
||||
#define GSTO_ID 0x52U
|
||||
#define MACRONIX_ID 0xC2U
|
||||
#define MICRON_ID 0x2CU
|
||||
#define TOSHIBA_ID 0x98U
|
||||
@@ -48,12 +51,12 @@ static struct spinand_device spinand_dev;
|
||||
.quad_mode = (_quad_mode), .need_qe = (_need_qe)}
|
||||
|
||||
static const struct spi_nand_info spi_nand_flash[] = {
|
||||
/*SPI_NAND_INFO("W25N01GV",
|
||||
SPI_NAND_INFO("W25N01GV",
|
||||
SPI_NAND_ID(true, 3, 0xef, 0xaa, 0x21, 0x00),
|
||||
SPI_NAND_MEMORG_1G_2K_64, true, false),
|
||||
SPI_NAND_INFO("MX35LF1GE4AB",
|
||||
SPI_NAND_ID(true, 2, 0xc2, 0x12, 0x00, 0x00),
|
||||
SPI_NAND_MEMORG_1G_2K_64, true, true)*/
|
||||
SPI_NAND_MEMORG_1G_2K_64, true, true)
|
||||
};
|
||||
|
||||
static int spi_nand_reg(bool read_reg, uint8_t reg, uint8_t *val,
|
||||
@@ -122,7 +125,10 @@ static int spi_nand_quad_enable(uint8_t manufacturer_id)
|
||||
|
||||
if (manufacturer_id != MACRONIX_ID &&
|
||||
manufacturer_id != GIGADEVICE_ID &&
|
||||
manufacturer_id != ETRON_ID) {
|
||||
manufacturer_id != GSTO_ID &&
|
||||
manufacturer_id != DOSILICON_ID &&
|
||||
manufacturer_id != ETRON_ID &&
|
||||
manufacturer_id != FMSH_ID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -356,6 +362,10 @@ static int spi_nand_check_pp(struct parameter_page *pp, uint8_t *sel)
|
||||
INFO("PP COPY %d CRC read: 0x%x, compute: 0x%x\n",
|
||||
i, crc, crc_compute);
|
||||
|
||||
// Integrity CRC (bytes 254-255) on FMSH was reversed
|
||||
if (crc != crc_compute)
|
||||
crc = htobe16(pp->integrity_crc);
|
||||
|
||||
if (crc != crc_compute) {
|
||||
ret = -EBADMSG;
|
||||
continue;
|
||||
@@ -392,8 +402,9 @@ static int spi_nand_check_pp(struct parameter_page *pp, uint8_t *sel)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int spi_nand_read_pp(struct parameter_page *pp, uint8_t *sel)
|
||||
static int spi_nand_read_pp(uint8_t *id, struct parameter_page *pp, uint8_t *sel)
|
||||
{
|
||||
const bool is_dosilicon = (id[1] == DOSILICON_ID);
|
||||
uint8_t status;
|
||||
uint8_t cfg_reg;
|
||||
int ret, op_ret;
|
||||
@@ -405,7 +416,7 @@ static int spi_nand_read_pp(struct parameter_page *pp, uint8_t *sel)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = spi_nand_write_reg(SPI_NAND_REG_CFG, cfg_reg | BIT(6));
|
||||
ret = spi_nand_write_reg(SPI_NAND_REG_CFG, is_dosilicon ? BIT(6) : (cfg_reg | BIT(6)));
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -441,7 +452,7 @@ out:
|
||||
ERROR("Parameter page read failed\n");
|
||||
}
|
||||
|
||||
ret = spi_nand_write_reg(SPI_NAND_REG_CFG, cfg_reg);
|
||||
ret = spi_nand_write_reg(SPI_NAND_REG_CFG, is_dosilicon ? 0x10 : cfg_reg);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -578,12 +589,15 @@ int spi_nand_init(unsigned long long *size, unsigned int *erase_size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = spi_nand_read_pp(pp, &sel);
|
||||
ret = spi_nand_read_id(id);
|
||||
if (ret != 0) {
|
||||
ERROR("SPI_NAND Read ID failed.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = spi_nand_read_pp(id, pp, &sel);
|
||||
if (ret != 0) {
|
||||
ERROR("Parameter page read fail, fallback to read ID.\n");
|
||||
ret = spi_nand_read_id(id);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
spi_nand_set_data_via_id(&spinand_dev, id, &vendor_id);
|
||||
} else {
|
||||
vendor_id = pp[sel].manufactuere_id;
|
||||
|
||||
Reference in New Issue
Block a user