spi_flash: Make a deep copy of spi_slave structure
Commit 36b81af
(spi: Pass pointer to spi_slave structure in
spi_setup_slave) changes the way spi_setup_slave handles the spi_slave
structure. Instead of expecting spi controller drivers to maintain
spi_slave structure in CAR_GLOBAL/data section, caller is expected to
manage the spi_slave structure. This requires that spi_flash drivers
maintain spi_slave structure and flash probe function needs to make a
copy of the passed in spi_slave structure.
This change fixes the regression on Lenovo X230 and other mainboards.
Change-Id: I0ad971eecaf3bfe301e9f95badc043193cc27cab
Signed-off-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: https://review.coreboot.org/17728
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Iru Cai <mytbk920423@gmail.com>
This commit is contained in:
parent
d3d1f13599
commit
810e2cde30
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
|
||||||
|
@ -108,13 +109,13 @@ static int adesto_write(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_AT25DF_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_AT25DF_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: adesto Page Program failed\n");
|
printk(BIOS_WARNING, "SF: adesto Page Program failed\n");
|
||||||
|
@ -165,7 +166,7 @@ struct spi_flash *spi_flash_probe_adesto(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
stm->params = params;
|
stm->params = params;
|
||||||
stm->flash.spi = spi;
|
memcpy(&stm->flash.spi, spi, sizeof(*spi));
|
||||||
stm->flash.name = params->name;
|
stm->flash.name = params->name;
|
||||||
|
|
||||||
/* Assuming power-of-two page size initially. */
|
/* Assuming power-of-two page size initially. */
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -90,13 +91,13 @@ static int amic_write(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_A25_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_A25_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: AMIC Page Program failed\n");
|
printk(BIOS_WARNING, "SF: AMIC Page Program failed\n");
|
||||||
|
@ -147,7 +148,7 @@ struct spi_flash *spi_flash_probe_amic(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
amic->params = params;
|
amic->params = params;
|
||||||
amic->flash.spi = spi;
|
memcpy(&amic->flash.spi, spi, sizeof(*spi));
|
||||||
amic->flash.name = params->name;
|
amic->flash.name = params->name;
|
||||||
|
|
||||||
/* Assuming power-of-two page size initially. */
|
/* Assuming power-of-two page size initially. */
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
/* M25Pxx-specific commands */
|
/* M25Pxx-specific commands */
|
||||||
|
@ -135,13 +137,13 @@ static int atmel_write(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_AT25_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_AT25_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Atmel Page Program failed\n");
|
printk(BIOS_WARNING, "SF: Atmel Page Program failed\n");
|
||||||
|
@ -192,7 +194,7 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
stm->params = params;
|
stm->params = params;
|
||||||
stm->flash.spi = spi;
|
memcpy(&stm->flash.spi, spi, sizeof(*spi));
|
||||||
stm->flash.name = params->name;
|
stm->flash.name = params->name;
|
||||||
|
|
||||||
/* Assuming power-of-two page size initially. */
|
/* Assuming power-of-two page size initially. */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ static int eon_write(const struct spi_flash *flash,
|
||||||
chunk_len = min(len - actual, page_size - byte_addr);
|
chunk_len = min(len - actual, page_size - byte_addr);
|
||||||
chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
|
chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_EN25_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_EN25_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -113,7 +114,7 @@ static int eon_write(const struct spi_flash *flash,
|
||||||
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: EON Page Program failed\n");
|
printk(BIOS_WARNING, "SF: EON Page Program failed\n");
|
||||||
|
@ -164,7 +165,7 @@ struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
eon->params = params;
|
eon->params = params;
|
||||||
eon->flash.spi = spi;
|
memcpy(&eon->flash.spi, spi, sizeof(*spi));
|
||||||
eon->flash.name = params->name;
|
eon->flash.name = params->name;
|
||||||
|
|
||||||
eon->flash.internal_write = eon_write;
|
eon->flash.internal_write = eon_write;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ static int gigadevice_write(const struct spi_flash *flash, u32 offset,
|
||||||
chunk_len = min(len - actual, page_size - byte_addr);
|
chunk_len = min(len - actual, page_size - byte_addr);
|
||||||
chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
|
chunk_len = spi_crop_chunk(sizeof(cmd), chunk_len);
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_GD25_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_GD25_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING,
|
printk(BIOS_WARNING,
|
||||||
"SF gigadevice.c: Enabling Write failed\n");
|
"SF gigadevice.c: Enabling Write failed\n");
|
||||||
|
@ -155,7 +156,7 @@ static int gigadevice_write(const struct spi_flash *flash, u32 offset,
|
||||||
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING,
|
printk(BIOS_WARNING,
|
||||||
|
@ -205,7 +206,7 @@ struct spi_flash *spi_flash_probe_gigadevice(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
stm.params = params;
|
stm.params = params;
|
||||||
stm.flash.spi = spi;
|
memcpy(&stm.flash.spi, spi, sizeof(*spi));
|
||||||
stm.flash.name = params->name;
|
stm.flash.name = params->name;
|
||||||
|
|
||||||
/* Assuming power-of-two page size initially. */
|
/* Assuming power-of-two page size initially. */
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -175,13 +176,13 @@ static int macronix_write(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_MX25XX_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Macronix Page Program failed\n");
|
printk(BIOS_WARNING, "SF: Macronix Page Program failed\n");
|
||||||
|
@ -224,7 +225,7 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
mcx.params = params;
|
mcx.params = params;
|
||||||
mcx.flash.spi = spi;
|
memcpy(&mcx.flash.spi, spi, sizeof(*spi));
|
||||||
mcx.flash.name = params->name;
|
mcx.flash.name = params->name;
|
||||||
|
|
||||||
mcx.flash.internal_write = macronix_write;
|
mcx.flash.internal_write = macronix_write;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -230,13 +231,13 @@ static int spansion_write(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_S25FLXX_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_S25FLXX_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, 4,
|
ret = spi_flash_cmd_write(&flash->spi, cmd, 4,
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: SPANSION Page Program failed\n");
|
printk(BIOS_WARNING, "SF: SPANSION Page Program failed\n");
|
||||||
|
@ -283,7 +284,7 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
|
||||||
spsn = &spsn_flash;
|
spsn = &spsn_flash;
|
||||||
|
|
||||||
spsn->params = params;
|
spsn->params = params;
|
||||||
spsn->flash.spi = spi;
|
memcpy(&spsn->flash.spi, spi, sizeof(*spi));
|
||||||
spsn->flash.name = params->name;
|
spsn->flash.name = params->name;
|
||||||
|
|
||||||
spsn->flash.internal_write = spansion_write;
|
spsn->flash.internal_write = spansion_write;
|
||||||
|
|
|
@ -77,7 +77,7 @@ done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len)
|
int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len)
|
||||||
{
|
{
|
||||||
int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len);
|
int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -86,7 +86,7 @@ int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
|
static int spi_flash_cmd_read(const struct spi_slave *spi, const u8 *cmd,
|
||||||
size_t cmd_len, void *data, size_t data_len)
|
size_t cmd_len, void *data, size_t data_len)
|
||||||
{
|
{
|
||||||
int ret = do_spi_flash_cmd(spi, cmd, cmd_len, data, data_len);
|
int ret = do_spi_flash_cmd(spi, cmd, cmd_len, data, data_len);
|
||||||
|
@ -101,8 +101,8 @@ static int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd,
|
||||||
/* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */
|
/* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wstack-usage="
|
#pragma GCC diagnostic ignored "-Wstack-usage="
|
||||||
int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
|
int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd,
|
||||||
const void *data, size_t data_len)
|
size_t cmd_len, const void *data, size_t data_len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u8 buff[cmd_len + data_len];
|
u8 buff[cmd_len + data_len];
|
||||||
|
@ -119,7 +119,7 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
static int spi_flash_cmd_read_array(struct spi_slave *spi, u8 *cmd,
|
static int spi_flash_cmd_read_array(const struct spi_slave *spi, u8 *cmd,
|
||||||
size_t cmd_len, u32 offset,
|
size_t cmd_len, u32 offset,
|
||||||
size_t len, void *data)
|
size_t len, void *data)
|
||||||
{
|
{
|
||||||
|
@ -135,7 +135,7 @@ int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
|
||||||
cmd[0] = CMD_READ_ARRAY_FAST;
|
cmd[0] = CMD_READ_ARRAY_FAST;
|
||||||
cmd[4] = 0x00;
|
cmd[4] = 0x00;
|
||||||
|
|
||||||
return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd),
|
return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd),
|
||||||
offset, len, data);
|
offset, len, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,14 +145,14 @@ int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset,
|
||||||
u8 cmd[4];
|
u8 cmd[4];
|
||||||
|
|
||||||
cmd[0] = CMD_READ_ARRAY_SLOW;
|
cmd[0] = CMD_READ_ARRAY_SLOW;
|
||||||
return spi_flash_cmd_read_array(flash->spi, cmd, sizeof(cmd),
|
return spi_flash_cmd_read_array(&flash->spi, cmd, sizeof(cmd),
|
||||||
offset, len, data);
|
offset, len, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout,
|
int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout,
|
||||||
u8 cmd, u8 poll_bit)
|
u8 cmd, u8 poll_bit)
|
||||||
{
|
{
|
||||||
struct spi_slave *spi = flash->spi;
|
const struct spi_slave *spi = &flash->spi;
|
||||||
int ret;
|
int ret;
|
||||||
u8 status;
|
u8 status;
|
||||||
struct mono_time current, end;
|
struct mono_time current, end;
|
||||||
|
@ -205,11 +205,11 @@ int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len)
|
||||||
printk(BIOS_SPEW, "SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
|
printk(BIOS_SPEW, "SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
|
||||||
cmd[2], cmd[3], offset);
|
cmd[2], cmd[3], offset);
|
||||||
#endif
|
#endif
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), NULL, 0);
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ out:
|
||||||
|
|
||||||
int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg)
|
int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg)
|
||||||
{
|
{
|
||||||
return spi_flash_cmd(flash->spi, flash->status_cmd, reg, sizeof(*reg));
|
return spi_flash_cmd(&flash->spi, flash->status_cmd, reg, sizeof(*reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#define STATUS_WIP 0x01
|
#define STATUS_WIP 0x01
|
||||||
|
|
||||||
/* Send a single-byte command to the device and read the response */
|
/* Send a single-byte command to the device and read the response */
|
||||||
int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len);
|
int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len);
|
||||||
|
|
||||||
int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
|
int spi_flash_cmd_read_fast(const struct spi_flash *flash, u32 offset,
|
||||||
size_t len, void *data);
|
size_t len, void *data);
|
||||||
|
@ -44,8 +44,8 @@ int spi_flash_cmd_read_slow(const struct spi_flash *flash, u32 offset,
|
||||||
* Send a multi-byte command to the device followed by (optional)
|
* Send a multi-byte command to the device followed by (optional)
|
||||||
* data. Used for programming the flash array, etc.
|
* data. Used for programming the flash array, etc.
|
||||||
*/
|
*/
|
||||||
int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len,
|
int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd,
|
||||||
const void *data, size_t data_len);
|
size_t cmd_len, const void *data, size_t data_len);
|
||||||
|
|
||||||
/* Send a command to the device and wait for some bit to clear itself. */
|
/* Send a command to the device and wait for some bit to clear itself. */
|
||||||
int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout,
|
int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout,
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ static const struct sst_spi_flash_params sst_spi_flash_table[] = {
|
||||||
static int
|
static int
|
||||||
sst_enable_writing(const struct spi_flash *flash)
|
sst_enable_writing(const struct spi_flash *flash)
|
||||||
{
|
{
|
||||||
int ret = spi_flash_cmd(flash->spi, CMD_SST_WREN, NULL, 0);
|
int ret = spi_flash_cmd(&flash->spi, CMD_SST_WREN, NULL, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -118,7 +119,7 @@ sst_enable_writing(const struct spi_flash *flash)
|
||||||
static int
|
static int
|
||||||
sst_enable_writing_status(const struct spi_flash *flash)
|
sst_enable_writing_status(const struct spi_flash *flash)
|
||||||
{
|
{
|
||||||
int ret = spi_flash_cmd(flash->spi, CMD_SST_EWSR, NULL, 0);
|
int ret = spi_flash_cmd(&flash->spi, CMD_SST_EWSR, NULL, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write Status failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write Status failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -127,7 +128,7 @@ sst_enable_writing_status(const struct spi_flash *flash)
|
||||||
static int
|
static int
|
||||||
sst_disable_writing(const struct spi_flash *flash)
|
sst_disable_writing(const struct spi_flash *flash)
|
||||||
{
|
{
|
||||||
int ret = spi_flash_cmd(flash->spi, CMD_SST_WRDI, NULL, 0);
|
int ret = spi_flash_cmd(&flash->spi, CMD_SST_WRDI, NULL, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
printk(BIOS_WARNING, "SF: Disabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Disabling Write failed\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -146,14 +147,14 @@ sst_byte_write(const struct spi_flash *flash, u32 offset, const void *buf)
|
||||||
|
|
||||||
#if CONFIG_DEBUG_SPI_FLASH
|
#if CONFIG_DEBUG_SPI_FLASH
|
||||||
printk(BIOS_SPEW, "BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
|
printk(BIOS_SPEW, "BP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
|
||||||
spi_w8r8(flash->spi, CMD_SST_RDSR), buf, cmd[0], offset);
|
spi_w8r8(&flash->spi, CMD_SST_RDSR), buf, cmd[0], offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = sst_enable_writing(flash);
|
ret = sst_enable_writing(flash);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd), buf, 1);
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -205,13 +206,13 @@ static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_SST_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_SST_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: SST Page Program failed\n");
|
printk(BIOS_WARNING, "SF: SST Page Program failed\n");
|
||||||
|
@ -263,11 +264,11 @@ static int sst_write_ai(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
for (; actual < len - 1; actual += 2) {
|
for (; actual < len - 1; actual += 2) {
|
||||||
#if CONFIG_DEBUG_SPI_FLASH
|
#if CONFIG_DEBUG_SPI_FLASH
|
||||||
printk(BIOS_SPEW, "WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
|
printk(BIOS_SPEW, "WP[%02x]: 0x%p => cmd = { 0x%02x 0x%06x }\n",
|
||||||
spi_w8r8(flash->spi, CMD_SST_RDSR), buf + actual, cmd[0],
|
spi_w8r8(&flash->spi, CMD_SST_RDSR), buf + actual, cmd[0],
|
||||||
offset);
|
offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, cmd_len,
|
ret = spi_flash_cmd_write(&flash->spi, cmd, cmd_len,
|
||||||
buf + actual, 2);
|
buf + actual, 2);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(BIOS_WARNING, "SF: SST word program failed\n");
|
printk(BIOS_WARNING, "SF: SST word program failed\n");
|
||||||
|
@ -310,11 +311,11 @@ sst_unlock(const struct spi_flash *flash)
|
||||||
|
|
||||||
cmd = CMD_SST_WRSR;
|
cmd = CMD_SST_WRSR;
|
||||||
status = 0;
|
status = 0;
|
||||||
ret = spi_flash_cmd_write(flash->spi, &cmd, 1, &status, 1);
|
ret = spi_flash_cmd_write(&flash->spi, &cmd, 1, &status, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
printk(BIOS_WARNING, "SF: Unable to set status byte\n");
|
printk(BIOS_WARNING, "SF: Unable to set status byte\n");
|
||||||
|
|
||||||
printk(BIOS_INFO, "SF: SST: status = %x\n", spi_w8r8(flash->spi, CMD_SST_RDSR));
|
printk(BIOS_INFO, "SF: SST: status = %x\n", spi_w8r8(&flash->spi, CMD_SST_RDSR));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +345,7 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
stm->params = params;
|
stm->params = params;
|
||||||
stm->flash.spi = spi;
|
memcpy(&stm->flash.spi, spi, sizeof(*spi));
|
||||||
stm->flash.name = params->name;
|
stm->flash.name = params->name;
|
||||||
|
|
||||||
stm->flash.internal_write = params->write;
|
stm->flash.internal_write = params->write;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -204,13 +205,13 @@ static int stmicro_write(const struct spi_flash *flash,
|
||||||
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_M25PXX_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_M25PXX_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: STMicro Page Program failed\n");
|
printk(BIOS_WARNING, "SF: STMicro Page Program failed\n");
|
||||||
|
@ -268,7 +269,7 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
stm.params = params;
|
stm.params = params;
|
||||||
stm.flash.spi = spi;
|
memcpy(&stm.flash.spi, spi, sizeof(*spi));
|
||||||
stm.flash.name = params->name;
|
stm.flash.name = params->name;
|
||||||
|
|
||||||
stm.flash.internal_write = stmicro_write;
|
stm.flash.internal_write = stmicro_write;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <spi_flash.h>
|
#include <spi_flash.h>
|
||||||
#include <spi-generic.h>
|
#include <spi-generic.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "spi_flash_internal.h"
|
#include "spi_flash_internal.h"
|
||||||
|
|
||||||
|
@ -166,13 +167,13 @@ static int winbond_write(const struct spi_flash *flash, u32 offset, size_t len,
|
||||||
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = spi_flash_cmd(flash->spi, CMD_W25_WREN, NULL, 0);
|
ret = spi_flash_cmd(&flash->spi, CMD_W25_WREN, NULL, 0);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
printk(BIOS_WARNING, "SF: Enabling Write failed\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd_write(flash->spi, cmd, sizeof(cmd),
|
ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd),
|
||||||
buf + actual, chunk_len);
|
buf + actual, chunk_len);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printk(BIOS_WARNING, "SF: Winbond Page Program failed\n");
|
printk(BIOS_WARNING, "SF: Winbond Page Program failed\n");
|
||||||
|
@ -218,7 +219,7 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
stm.params = params;
|
stm.params = params;
|
||||||
stm.flash.spi = spi;
|
memcpy(&stm.flash.spi, spi, sizeof(*spi));
|
||||||
stm.flash.name = params->name;
|
stm.flash.name = params->name;
|
||||||
|
|
||||||
/* Assuming power-of-two page size initially. */
|
/* Assuming power-of-two page size initially. */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <spi-generic.h>
|
||||||
#include <boot/coreboot_tables.h>
|
#include <boot/coreboot_tables.h>
|
||||||
|
|
||||||
/* SPI Flash opcodes */
|
/* SPI Flash opcodes */
|
||||||
|
@ -24,7 +25,7 @@
|
||||||
#define SPI_OPCODE_FAST_READ 0x0b
|
#define SPI_OPCODE_FAST_READ 0x0b
|
||||||
|
|
||||||
struct spi_flash {
|
struct spi_flash {
|
||||||
struct spi_slave *spi;
|
struct spi_slave spi;
|
||||||
const char *name;
|
const char *name;
|
||||||
u32 size;
|
u32 size;
|
||||||
u32 sector_size;
|
u32 sector_size;
|
||||||
|
|
|
@ -352,7 +352,8 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
|
||||||
flash_bits = read_spi_sfdp_param(ctx, 0x04);
|
flash_bits = read_spi_sfdp_param(ctx, 0x04);
|
||||||
flash->size = (flash_bits >> 3) + 1;
|
flash->size = (flash_bits >> 3) + 1;
|
||||||
|
|
||||||
flash->spi = spi;
|
memcpy(&flash->spi, spi, sizeof(*spi));
|
||||||
|
|
||||||
flash->name = "Apollolake hardware sequencer";
|
flash->name = "Apollolake hardware sequencer";
|
||||||
|
|
||||||
/* Can erase both 4 KiB and 64 KiB chunks. Declare the smaller size. */
|
/* Can erase both 4 KiB and 64 KiB chunks. Declare the smaller size. */
|
||||||
|
|
|
@ -191,7 +191,7 @@ int pch_hwseq_erase(const struct spi_flash *flash, u32 offset, size_t len)
|
||||||
len, start);
|
len, start);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spi_release_bus(flash->spi);
|
spi_release_bus(&flash->spi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
|
||||||
/* Ensure writes can take place to the flash. */
|
/* Ensure writes can take place to the flash. */
|
||||||
spi_init();
|
spi_init();
|
||||||
|
|
||||||
flash->spi = spi;
|
memcpy(&flash->spi, spi, sizeof(*spi));
|
||||||
flash->name = "Opaque HW-sequencing";
|
flash->name = "Opaque HW-sequencing";
|
||||||
|
|
||||||
flash->internal_write = pch_hwseq_write;
|
flash->internal_write = pch_hwseq_write;
|
||||||
|
|
|
@ -236,12 +236,13 @@ static int nor_erase(const struct spi_flash *flash, u32 offset, size_t len)
|
||||||
struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
|
struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
|
||||||
{
|
{
|
||||||
static struct spi_flash flash = {0};
|
static struct spi_flash flash = {0};
|
||||||
|
static int done = 0;
|
||||||
|
|
||||||
if (flash.spi)
|
if (done)
|
||||||
return &flash;
|
return &flash;
|
||||||
|
|
||||||
write32(&mt8173_nor->wrprot, SFLASH_COMMAND_ENABLE);
|
write32(&mt8173_nor->wrprot, SFLASH_COMMAND_ENABLE);
|
||||||
flash.spi = spi;
|
memcpy(&flash.spi, spi, sizeof(*spi));
|
||||||
flash.name = "mt8173 flash controller";
|
flash.name = "mt8173 flash controller";
|
||||||
flash.internal_write = nor_write;
|
flash.internal_write = nor_write;
|
||||||
flash.internal_erase = nor_erase;
|
flash.internal_erase = nor_erase;
|
||||||
|
@ -250,5 +251,6 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
|
||||||
flash.sector_size = 0x1000;
|
flash.sector_size = 0x1000;
|
||||||
flash.erase_cmd = SECTOR_ERASE_CMD;
|
flash.erase_cmd = SECTOR_ERASE_CMD;
|
||||||
flash.size = CONFIG_ROM_SIZE;
|
flash.size = CONFIG_ROM_SIZE;
|
||||||
|
done = 1;
|
||||||
return &flash;
|
return &flash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -733,7 +733,7 @@ static int ich_hwseq_erase(const struct spi_flash *flash, u32 offset,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_claim_bus(flash->spi);
|
ret = spi_claim_bus(&flash->spi);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printk(BIOS_ERR, "SF: Unable to claim SPI bus\n");
|
printk(BIOS_ERR, "SF: Unable to claim SPI bus\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -766,7 +766,7 @@ static int ich_hwseq_erase(const struct spi_flash *flash, u32 offset,
|
||||||
printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start);
|
printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spi_release_bus(flash->spi);
|
spi_release_bus(&flash->spi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,7 +921,7 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
flash->spi = spi;
|
memcpy(&flash->spi, spi, sizeof(*spi));
|
||||||
flash->name = "Opaque HW-sequencing";
|
flash->name = "Opaque HW-sequencing";
|
||||||
|
|
||||||
flash->internal_write = ich_hwseq_write;
|
flash->internal_write = ich_hwseq_write;
|
||||||
|
|
Loading…
Reference in New Issue