mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-24 13:40:24 +09:00
- new GigaDevice flash ids - fixes for imx, nxp_spi drivers
This commit is contained in:
commit
b839fc9d47
29
cmd/sf.c
29
cmd/sf.c
@ -344,8 +344,11 @@ static int do_spi_flash_erase(int argc, char *const argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_erase(flash, offset, size);
|
ret = spi_flash_erase(flash, offset, size);
|
||||||
printf("SF: %zu bytes @ %#x Erased: %s\n", (size_t)size, (u32)offset,
|
printf("SF: %zu bytes @ %#x Erased: ", (size_t)size, (u32)offset);
|
||||||
ret ? "ERROR" : "OK");
|
if (ret)
|
||||||
|
printf("ERROR %d\n", ret);
|
||||||
|
else
|
||||||
|
printf("OK\n");
|
||||||
|
|
||||||
return ret == 0 ? 0 : 1;
|
return ret == 0 ? 0 : 1;
|
||||||
}
|
}
|
||||||
@ -442,20 +445,22 @@ static int spi_flash_test(struct spi_flash *flash, uint8_t *buf, ulong len,
|
|||||||
ulong offset, uint8_t *vbuf)
|
ulong offset, uint8_t *vbuf)
|
||||||
{
|
{
|
||||||
struct test_info test;
|
struct test_info test;
|
||||||
int i;
|
int err, i;
|
||||||
|
|
||||||
printf("SPI flash test:\n");
|
printf("SPI flash test:\n");
|
||||||
memset(&test, '\0', sizeof(test));
|
memset(&test, '\0', sizeof(test));
|
||||||
test.base_ms = get_timer(0);
|
test.base_ms = get_timer(0);
|
||||||
test.bytes = len;
|
test.bytes = len;
|
||||||
if (spi_flash_erase(flash, offset, len)) {
|
err = spi_flash_erase(flash, offset, len);
|
||||||
printf("Erase failed\n");
|
if (err) {
|
||||||
|
printf("Erase failed (err = %d)\n", err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
spi_test_next_stage(&test);
|
spi_test_next_stage(&test);
|
||||||
|
|
||||||
if (spi_flash_read(flash, offset, len, vbuf)) {
|
err = spi_flash_read(flash, offset, len, vbuf);
|
||||||
printf("Check read failed\n");
|
if (err) {
|
||||||
|
printf("Check read failed (err = %d)\n", err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
@ -468,15 +473,17 @@ static int spi_flash_test(struct spi_flash *flash, uint8_t *buf, ulong len,
|
|||||||
}
|
}
|
||||||
spi_test_next_stage(&test);
|
spi_test_next_stage(&test);
|
||||||
|
|
||||||
if (spi_flash_write(flash, offset, len, buf)) {
|
err = spi_flash_write(flash, offset, len, buf);
|
||||||
printf("Write failed\n");
|
if (err) {
|
||||||
|
printf("Write failed (err = %d)\n", err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memset(vbuf, '\0', len);
|
memset(vbuf, '\0', len);
|
||||||
spi_test_next_stage(&test);
|
spi_test_next_stage(&test);
|
||||||
|
|
||||||
if (spi_flash_read(flash, offset, len, vbuf)) {
|
err = spi_flash_read(flash, offset, len, vbuf);
|
||||||
printf("Read failed\n");
|
if (err) {
|
||||||
|
printf("Read failed (ret = %d)\n", err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
spi_test_next_stage(&test);
|
spi_test_next_stage(&test);
|
||||||
|
@ -17,9 +17,22 @@
|
|||||||
#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
|
#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
|
||||||
#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
|
#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
|
||||||
|
|
||||||
#define GD5FXGQ4XEXXG_REG_STATUS2 0xf0
|
#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4)
|
||||||
|
#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4)
|
||||||
|
|
||||||
static SPINAND_OP_VARIANTS(read_cache_variants,
|
#define GD5FXGQXXEXXG_REG_STATUS2 0xf0
|
||||||
|
|
||||||
|
/* Q4 devices, QUADIO: Dummy bytes valid for 1 and 2 GBit variants */
|
||||||
|
static SPINAND_OP_VARIANTS(gd5fxgq4_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));
|
||||||
|
|
||||||
|
/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */
|
||||||
|
static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
|
||||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
||||||
SPINAND_PAGE_READ_FROM_CACHE_X4_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_DUALIO_OP(0, 1, NULL, 0),
|
||||||
@ -35,7 +48,7 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
|
|||||||
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||||
|
|
||||||
static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
|
static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||||
struct mtd_oob_region *region)
|
struct mtd_oob_region *region)
|
||||||
{
|
{
|
||||||
if (section)
|
if (section)
|
||||||
@ -47,7 +60,7 @@ static int gd5fxgq4xexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gd5fxgq4xexxg_ooblayout_free(struct mtd_info *mtd, int section,
|
static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section,
|
||||||
struct mtd_oob_region *region)
|
struct mtd_oob_region *region)
|
||||||
{
|
{
|
||||||
if (section)
|
if (section)
|
||||||
@ -64,7 +77,7 @@ static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
|
|||||||
u8 status)
|
u8 status)
|
||||||
{
|
{
|
||||||
u8 status2;
|
u8 status2;
|
||||||
struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4XEXXG_REG_STATUS2,
|
struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
|
||||||
&status2);
|
&status2);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -102,21 +115,67 @@ static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct mtd_ooblayout_ops gd5fxgq4xexxg_ooblayout = {
|
static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
|
||||||
.ecc = gd5fxgq4xexxg_ooblayout_ecc,
|
u8 status)
|
||||||
.rfree = gd5fxgq4xexxg_ooblayout_free,
|
{
|
||||||
|
u8 status2;
|
||||||
|
struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
|
||||||
|
&status2);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (status & STATUS_ECC_MASK) {
|
||||||
|
case STATUS_ECC_NO_BITFLIPS:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
|
||||||
|
/*
|
||||||
|
* Read status2 register to determine a more fine grained
|
||||||
|
* bit error status
|
||||||
|
*/
|
||||||
|
ret = spi_mem_exec_op(spinand->slave, &op);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1 ... 4 bits are flipped (and corrected)
|
||||||
|
*/
|
||||||
|
/* bits sorted this way (1...0): ECCSE1, ECCSE0 */
|
||||||
|
return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
|
||||||
|
|
||||||
|
case STATUS_ECC_UNCOR_ERROR:
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct mtd_ooblayout_ops gd5fxgqxxexxg_ooblayout = {
|
||||||
|
.ecc = gd5fxgqxxexxg_ooblayout_ecc,
|
||||||
|
.rfree = gd5fxgqxxexxg_ooblayout_free,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct spinand_info gigadevice_spinand_table[] = {
|
static const struct spinand_info gigadevice_spinand_table[] = {
|
||||||
SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
|
SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
|
||||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||||
NAND_ECCREQ(8, 512),
|
NAND_ECCREQ(8, 512),
|
||||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants,
|
||||||
&write_cache_variants,
|
&write_cache_variants,
|
||||||
&update_cache_variants),
|
&update_cache_variants),
|
||||||
0,
|
0,
|
||||||
SPINAND_ECCINFO(&gd5fxgq4xexxg_ooblayout,
|
SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
|
||||||
gd5fxgq4xexxg_ecc_get_status)),
|
gd5fxgq4xexxg_ecc_get_status)),
|
||||||
|
SPINAND_INFO("GD5F1GQ5UExxG", 0x51,
|
||||||
|
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||||
|
NAND_ECCREQ(4, 512),
|
||||||
|
SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
|
||||||
|
&write_cache_variants,
|
||||||
|
&update_cache_variants),
|
||||||
|
0,
|
||||||
|
SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
|
||||||
|
gd5fxgq5xexxg_ecc_get_status)),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int gigadevice_spinand_detect(struct spinand_device *spinand)
|
static int gigadevice_spinand_detect(struct spinand_device *spinand)
|
||||||
|
@ -107,6 +107,11 @@ const struct flash_info spi_nor_ids[] = {
|
|||||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
||||||
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
|
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
INFO("gd25lq64c", 0xc86017, 0, 64 * 1024, 128,
|
||||||
|
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
||||||
|
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
INFO("gd25q128", 0xc84018, 0, 64 * 1024, 256,
|
INFO("gd25q128", 0xc84018, 0, 64 * 1024, 256,
|
||||||
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
||||||
@ -319,7 +324,10 @@ const struct flash_info spi_nor_ids[] = {
|
|||||||
{ INFO("w25q80bl", 0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
{ INFO("w25q80bl", 0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||||
{ INFO("w25q16cl", 0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
{ INFO("w25q16cl", 0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||||
{ INFO("w25q64cv", 0xef4017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
{ INFO("w25q64cv", 0xef4017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||||
{ INFO("w25q128", 0xef4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
{ INFO("w25q128", 0xef4018, 0, 64 * 1024, 256,
|
||||||
|
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
|
||||||
|
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
|
||||||
|
},
|
||||||
{ INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
{ INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||||
{ INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
{ INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||||
{ INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
{ INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
||||||
|
@ -662,7 +662,10 @@ static int mxc_spi_release_bus(struct udevice *dev)
|
|||||||
|
|
||||||
static int mxc_spi_set_speed(struct udevice *bus, uint speed)
|
static int mxc_spi_set_speed(struct udevice *bus, uint speed)
|
||||||
{
|
{
|
||||||
/* Nothing to do */
|
struct mxc_spi_slave *mxcs = dev_get_plat(bus);
|
||||||
|
|
||||||
|
mxcs->max_hz = speed;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,7 +823,7 @@ static int nxp_fspi_default_setup(struct nxp_fspi *f)
|
|||||||
|
|
||||||
/* the default frequency, we will change it later if necessary. */
|
/* the default frequency, we will change it later if necessary. */
|
||||||
ret = clk_set_rate(&f->clk, 20000000);
|
ret = clk_set_rate(&f->clk, 20000000);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = nxp_fspi_clk_prep_enable(f);
|
ret = nxp_fspi_clk_prep_enable(f);
|
||||||
@ -914,7 +914,7 @@ static int nxp_fspi_set_speed(struct udevice *bus, uint speed)
|
|||||||
nxp_fspi_clk_disable_unprep(f);
|
nxp_fspi_clk_disable_unprep(f);
|
||||||
|
|
||||||
ret = clk_set_rate(&f->clk, speed);
|
ret = clk_set_rate(&f->clk, speed);
|
||||||
if (ret)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = nxp_fspi_clk_prep_enable(f);
|
ret = nxp_fspi_clk_prep_enable(f);
|
||||||
|
@ -302,8 +302,8 @@ struct spi_flash {
|
|||||||
* @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR
|
* @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR
|
||||||
* @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR
|
* @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR
|
||||||
* @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is
|
* @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is
|
||||||
* @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode
|
|
||||||
* completely locked
|
* completely locked
|
||||||
|
* @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode
|
||||||
* @priv: the private data
|
* @priv: the private data
|
||||||
*/
|
*/
|
||||||
struct spi_nor {
|
struct spi_nor {
|
||||||
|
Loading…
Reference in New Issue
Block a user