X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmtd%2Fspi%2Fsf_probe.c;h=e84ab1363bd3a7aacee59d2bdcac694716e49d97;hb=cc56f13392197d6195ec6df2569bec1ce4d7b9ce;hp=d95c8b9ae30b1dce91c9956a26f7122155489fd7;hpb=33adfb5f9b06ac1a386dddc222cc50e24a9909e2;p=u-boot diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index d95c8b9ae3..e84ab1363b 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -25,11 +25,60 @@ static u8 spi_read_cmds_array[] = { CMD_READ_DUAL_OUTPUT_FAST, CMD_READ_DUAL_IO_FAST, CMD_READ_QUAD_OUTPUT_FAST, + CMD_READ_QUAD_IO_FAST, }; +#ifdef CONFIG_SPI_FLASH_MACRONIX +static int spi_flash_set_qeb_mxic(struct spi_flash *flash) +{ + u8 qeb_status; + int ret; + + ret = spi_flash_cmd_read_status(flash, &qeb_status); + if (ret < 0) + return ret; + + if (qeb_status & STATUS_QEB_MXIC) { + debug("SF: mxic: QEB is already set\n"); + } else { + ret = spi_flash_cmd_write_status(flash, STATUS_QEB_MXIC); + if (ret < 0) + return ret; + } + + return ret; +} +#endif + +#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) +static int spi_flash_set_qeb_winspan(struct spi_flash *flash) +{ + u8 qeb_status; + int ret; + + ret = spi_flash_cmd_read_config(flash, &qeb_status); + if (ret < 0) + return ret; + + if (qeb_status & STATUS_QEB_WINSPAN) { + debug("SF: winspan: QEB is already set\n"); + } else { + ret = spi_flash_cmd_write_config(flash, STATUS_QEB_WINSPAN); + if (ret < 0) + return ret; + } + + return ret; +} +#endif + static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) { switch (idcode0) { +#ifdef CONFIG_SPI_FLASH_MACRONIX + case SPI_FLASH_CFI_MFR_MACRONIX: + return spi_flash_set_qeb_mxic(flash); +#endif #if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) case SPI_FLASH_CFI_MFR_SPANSION: case SPI_FLASH_CFI_MFR_WINBOND: @@ -74,17 +123,17 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi, return NULL; } - flash = malloc(sizeof(*flash)); + flash = calloc(1, sizeof(*flash)); if (!flash) { debug("SF: Failed to allocate spi_flash\n"); return NULL; } - memset(flash, '\0', sizeof(*flash)); /* Assign spi data */ flash->spi = spi; flash->name = params->name; flash->memory_map = spi->memory_map; + flash->dual_flash = flash->spi->option; /* Assign spi_flash ops */ flash->write = spi_flash_cmd_write_ops; @@ -96,17 +145,22 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi, flash->read = spi_flash_cmd_read_ops; /* Compute the flash size */ - flash->page_size = (ext_jedec == 0x4d00) ? 512 : 256; - flash->sector_size = params->sector_size; - flash->size = flash->sector_size * params->nr_sectors; + flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0; + flash->page_size = ((ext_jedec == 0x4d00) ? 512 : 256) << flash->shift; + flash->sector_size = params->sector_size << flash->shift; + flash->size = flash->sector_size * params->nr_sectors << flash->shift; +#ifdef CONFIG_SF_DUAL_FLASH + if (flash->dual_flash & SF_DUAL_STACKED_FLASH) + flash->size <<= 1; +#endif /* Compute erase sector and command */ if (params->flags & SECT_4K) { flash->erase_cmd = CMD_ERASE_4K; - flash->erase_size = 4096; + flash->erase_size = 4096 << flash->shift; } else if (params->flags & SECT_32K) { flash->erase_cmd = CMD_ERASE_32K; - flash->erase_size = 32768; + flash->erase_size = 32768 << flash->shift; } else { flash->erase_cmd = CMD_ERASE_64K; flash->erase_size = flash->sector_size; @@ -118,7 +172,7 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi, cmd = spi_read_cmds_array[cmd - 1]; flash->read_cmd = cmd; } else { - /* Go for for default supported read cmd */ + /* Go for default supported read cmd */ flash->read_cmd = CMD_READ_ARRAY_FAST; } @@ -131,6 +185,7 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi, /* Set the quad enable bit - only for quad commands */ if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || + (flash->read_cmd == CMD_READ_QUAD_IO_FAST) || (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { if (spi_flash_set_qeb(flash, idcode[0])) { debug("SF: Fail to set QEB for %02x\n", idcode[0]); @@ -138,7 +193,26 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi, } } - /* Poll cmd seclection */ + /* Read dummy_byte: dummy byte is determined based on the + * dummy cycles of a particular command. + * Fast commands - dummy_byte = dummy_cycles/8 + * I/O commands- dummy_byte = (dummy_cycles * no.of lines)/8 + * For I/O commands except cmd[0] everything goes on no.of lines + * based on particular command but incase of fast commands except + * data all go on single line irrespective of command. + */ + switch (flash->read_cmd) { + case CMD_READ_QUAD_IO_FAST: + flash->dummy_byte = 2; + break; + case CMD_READ_ARRAY_SLOW: + flash->dummy_byte = 0; + break; + default: + flash->dummy_byte = 1; + } + + /* Poll cmd selection */ flash->poll_cmd = CMD_READ_STATUS; #ifdef CONFIG_SPI_FLASH_STMICRO if (params->flags & E_FSR) @@ -255,7 +329,10 @@ static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi) puts("\n"); #endif #ifndef CONFIG_SPI_FLASH_BAR - if (flash->size > SPI_FLASH_16MB_BOUN) { + if (((flash->dual_flash == SF_SINGLE_FLASH) && + (flash->size > SPI_FLASH_16MB_BOUN)) || + ((flash->dual_flash > SF_SINGLE_FLASH) && + (flash->size > SPI_FLASH_16MB_BOUN << 1))) { puts("SF: Warning - Only lower 16MiB accessible,"); puts(" Full access #define CONFIG_SPI_FLASH_BAR\n"); }