mail.coreboot.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
List overview
Download
coreboot-gerrit
December 2016
----- 2024 -----
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
coreboot-gerrit@coreboot.org
1 participants
1140 discussions
Start a n
N
ew thread
New patch to review for coreboot: cbfstool: Fix off-by-one error in checking hash_type
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17698
-gerrit commit 2c80f80b985a465f80023bd5f14a8e206ef6610c Author: Furquan Shaikh <furquan(a)chromium.org> Date: Fri Dec 2 09:24:50 2016 -0800 cbfstool: Fix off-by-one error in checking hash_type Change-Id: Iaf208705d0cd450288af721d53053b2d3407a336 Found-by: Coverity Scan #1325836 Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- util/cbfstool/cbfs_image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c index 6dc47c7..e1a0e8c 100644 --- a/util/cbfstool/cbfs_image.c +++ b/util/cbfstool/cbfs_image.c @@ -1399,7 +1399,7 @@ int cbfs_print_entry_info(struct cbfs_image *image, struct cbfs_file *entry, struct cbfs_file_attr_hash *hash = NULL; while ((hash = cbfs_file_get_next_hash(entry, hash)) != NULL) { unsigned int hash_type = ntohl(hash->hash_type); - if (hash_type > CBFS_NUM_SUPPORTED_HASHES) { + if (hash_type >= CBFS_NUM_SUPPORTED_HASHES) { fprintf(fp, "invalid hash type %d\n", hash_type); break; }
1
0
0
0
Patch set updated for coreboot: spi: Get rid of SPI_ATOMIC_SEQUENCING
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17681
-gerrit commit 6721d0df513084bd8d2a03429c95dd56aba6e697 Author: Furquan Shaikh <furquan(a)chromium.org> Date: Tue Nov 29 22:07:42 2016 -0800 spi: Get rid of SPI_ATOMIC_SEQUENCING SPI_ATOMIC_SEQUENCING was added to accomodate spi flash controllers with the ability to perform tx and rx of flash command and response at the same time. Instead of introducing this notion at SPI flash driver layer, clean up the interface to SPI used by flash. Flash uses a command-response kind of communication. Thus, even though SPI is duplex, flash command needs to be sent out on SPI bus and then flash response should be received on the bus. Some specialized x86 flash controllers are capable of handling command and response in a single transaction. In order to support all the varied cases: 1. Add spi_xfer_vector that takes as input a vector of SPI operations and calls back into SPI controller driver to process these operations. 2. In order to accomodate flash command-response model, use two vectors while calling into spi_xfer_vector -- one with dout set to non-NULL(command) and other with din set to non-NULL(response). 3. For specialized SPI flash controllers combine two successive vectors if the transactions look like a command-response pair. BUG=chrome-os-partner:59832 BRANCH=None TEST=Compiles successfully Change-Id: I4c9e78c585ad95c40c0d5af078ff8251da286236 Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- src/drivers/spi/Kconfig | 10 ------ src/drivers/spi/spi-generic.c | 19 ++++++++--- src/drivers/spi/spi_flash.c | 47 +++++++++------------------ src/include/spi-generic.h | 34 ++++++++++++++++++-- src/mainboard/google/purin/Kconfig | 1 - src/soc/broadcom/cygnus/spi.c | 48 +++++++++++++++++++++++++++- src/soc/imgtec/pistachio/Kconfig | 1 - src/soc/imgtec/pistachio/spi.c | 54 ++++++++++++++++++++++++++++---- src/soc/intel/baytrail/spi.c | 48 +++++++++++++++++++++++++++- src/soc/intel/braswell/spi.c | 48 +++++++++++++++++++++++++++- src/soc/intel/broadwell/spi.c | 48 +++++++++++++++++++++++++++- src/soc/intel/fsp_baytrail/spi.c | 48 +++++++++++++++++++++++++++- src/soc/intel/fsp_broadwell_de/spi.c | 48 +++++++++++++++++++++++++++- src/soc/marvell/armada38x/spi.c | 33 +++++++++++++------ src/soc/mediatek/mt8173/Kconfig | 1 - src/soc/mediatek/mt8173/spi.c | 48 +++++++++++++++++++++++++++- src/soc/nvidia/tegra124/spi.c | 22 +++++++++++-- src/soc/nvidia/tegra210/spi.c | 22 +++++++++++-- src/soc/qualcomm/ipq40xx/Kconfig | 1 - src/soc/qualcomm/ipq40xx/spi.c | 48 +++++++++++++++++++++++++++- src/soc/qualcomm/ipq806x/Kconfig | 1 - src/soc/qualcomm/ipq806x/spi.c | 48 +++++++++++++++++++++++++++- src/soc/rockchip/common/spi.c | 22 +++++++++++-- src/soc/samsung/exynos5420/spi.c | 20 ++++++++++-- src/southbridge/amd/agesa/hudson/spi.c | 48 +++++++++++++++++++++++++++- src/southbridge/amd/cimx/sb800/spi.c | 48 +++++++++++++++++++++++++++- src/southbridge/amd/sb700/spi.c | 48 +++++++++++++++++++++++++++- src/southbridge/intel/common/spi.c | 48 +++++++++++++++++++++++++++- src/southbridge/intel/fsp_rangeley/spi.c | 48 +++++++++++++++++++++++++++- 29 files changed, 866 insertions(+), 94 deletions(-) diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig index b55de58..c8d86ff 100644 --- a/src/drivers/spi/Kconfig +++ b/src/drivers/spi/Kconfig @@ -61,16 +61,6 @@ config SPI_FLASH_INCLUDE_ALL_DRIVERS default n if COMMON_CBFS_SPI_WRAPPER default y -config SPI_ATOMIC_SEQUENCING - bool - default y if ARCH_X86 - default n if !ARCH_X86 - help - Select this option if the SPI controller uses "atomic sequencing." - Atomic sequencing is when the sequence of commands is pre-programmed - in the SPI controller. Hardware manages the transaction instead of - software. This is common on x86 platforms. - config SPI_FLASH_SMM bool "SPI flash driver support in SMM" default n diff --git a/src/drivers/spi/spi-generic.c b/src/drivers/spi/spi-generic.c index 4fcd04c..0e8c1b4 100644 --- a/src/drivers/spi/spi-generic.c +++ b/src/drivers/spi/spi-generic.c @@ -32,16 +32,27 @@ void spi_release_bus(const struct spi_slave *slave) ctrlr->release_bus(slave); } -int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, - void *din, size_t bytesin) +int spi_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) { const struct spi_ctrlr *ctrlr = slave->ctrlr; - if (ctrlr && ctrlr->xfer) - return ctrlr->xfer(slave, dout, bytesout, din, bytesin); + if (ctrlr && ctrlr->xfer_vector) + return ctrlr->xfer_vector(slave, vectors, count); return -1; } +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, + void *din, size_t bytesin) +{ + struct spi_op vectors[] = { + { .dout = dout, .bytesout = bytesout, + .din = din, .bytesin = bytesin, + }, + }; + return spi_xfer_vector(slave, vectors, ARRAY_SIZE(vectors)); +} + void __attribute__((weak)) spi_init(void) { /* Default weak implementation - do nothing. */ diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index b51a1e5..7ebea68 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -32,47 +32,30 @@ static void spi_flash_addr(u32 addr, u8 *cmd) cmd[3] = addr >> 0; } -/* - * If atomic sequencing is used, the cycle type is known to the SPI - * controller so that it can perform consecutive transfers and arbitrate - * automatically. Otherwise the SPI controller transfers whatever the - * user requests immediately, without regard to sequence. Atomic - * sequencing is commonly used on x86 platforms. - * - * SPI flash commands are simple two-step sequences. The command byte is - * always written first and may be followed by an address. Then data is - * either read or written. For atomic sequencing we'll pass everything into - * spi_xfer() at once and let the controller handle the details. Otherwise - * we will write all output bytes first and then read if necessary. - * - * FIXME: This really should be abstracted better, but that will - * require overhauling the entire SPI infrastructure. - */ static int do_spi_flash_cmd(const struct spi_slave *spi, const void *dout, size_t bytes_out, void *din, size_t bytes_in) { int ret = 1; + /* + * SPI flash requires command-response kind of behavior. Thus, two + * separate SPI vectors are required -- first to transmit dout and other + * to receive in din. If some specialized SPI flash controllers + * (e.g. x86) can perform both command and response together, it should + * be handled at SPI flash controller driver level. + */ + struct spi_op vectors[] = { + [0] = { .dout = dout, .bytesout = bytes_out, + .din = NULL, .bytesin = 0, }, + [1] = { .dout = NULL, .bytesout = 0, + .din = din, .bytesin = bytes_in }, + }; if (spi_claim_bus(spi)) return ret; -#if CONFIG_SPI_ATOMIC_SEQUENCING == 1 - if (spi_xfer(spi, dout, bytes_out, din, bytes_in) < 0) - goto done; -#else - if (dout && bytes_out) { - if (spi_xfer(spi, dout, bytes_out, NULL, 0) < 0) - goto done; - } - - if (din && bytes_in) { - if (spi_xfer(spi, NULL, 0, din, bytes_in) < 0) - goto done; - } -#endif + if (spi_xfer_vector(spi, vectors, ARRAY_SIZE(vectors)) == 0) + ret = 0; - ret = 0; -done: spi_release_bus(spi); return ret; } diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index d28fefd..b813bab 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -36,20 +36,35 @@ struct spi_slave { const struct spi_ctrlr *ctrlr; }; +/* + * Representation of a SPI operation. + * + * dout: Pointer to data to send. + * bytesout: Count of data in bytes to send. + * din: Pointer to store received data. + * bytesin: Count of data in bytes to receive. + */ +struct spi_op { + const void *dout; + size_t bytesout; + void *din; + size_t bytesin; +}; + /*----------------------------------------------------------------------- * Representation of a SPI contoller. * * claim_bus: Claim SPI bus and prepare for communication. * release_bus: Release SPI bus. - * xfer: SPI transfer * setup: Setup given SPI device bus. + * xfer_vector: Vector of SPI transfer operations. */ struct spi_ctrlr { int (*claim_bus)(const struct spi_slave *slave); void (*release_bus)(const struct spi_slave *slave); - int (*xfer)(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin); int (*setup)(const struct spi_slave *slave); + int (*xfer_vector)(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count); }; /*----------------------------------------------------------------------- @@ -134,6 +149,19 @@ void spi_release_bus(const struct spi_slave *slave); int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin); +/*----------------------------------------------------------------------- + * Vector of SPI transfer operations + * + * spi_xfer_vector() interface: + * slave: The SPI slave which will be sending/receiving the data. + * vectors: Array of SPI op structures. + * count: Number of SPI op vectors. + * + * Returns: 0 on success, not 0 on failure + */ +int spi_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count); + unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len); /*----------------------------------------------------------------------- diff --git a/src/mainboard/google/purin/Kconfig b/src/mainboard/google/purin/Kconfig index eabab2b..ca0909b 100644 --- a/src/mainboard/google/purin/Kconfig +++ b/src/mainboard/google/purin/Kconfig @@ -26,7 +26,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy select SPI_FLASH select SPI_FLASH_SPANSION select SPI_FLASH_STMICRO # required for the reference board BCM958305K - select SPI_ATOMIC_SEQUENCING config CHROMEOS select VBOOT_VBNV_FLASH diff --git a/src/soc/broadcom/cygnus/spi.c b/src/soc/broadcom/cygnus/spi.c index e597efc..c33c489 100644 --- a/src/soc/broadcom/cygnus/spi.c +++ b/src/soc/broadcom/cygnus/spi.c @@ -275,10 +275,56 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/imgtec/pistachio/Kconfig b/src/soc/imgtec/pistachio/Kconfig index da33cc5..1ce488c 100644 --- a/src/soc/imgtec/pistachio/Kconfig +++ b/src/soc/imgtec/pistachio/Kconfig @@ -22,7 +22,6 @@ config CPU_IMGTEC_PISTACHIO select GENERIC_UDELAY select HAVE_MONOTONIC_TIMER select HAVE_UART_SPECIAL - select SPI_ATOMIC_SEQUENCING select GENERIC_GPIO_LIB select HAVE_HARD_RESET select UART_OVERRIDE_REFCLK diff --git a/src/soc/imgtec/pistachio/spi.c b/src/soc/imgtec/pistachio/spi.c index e956e46..c9d2591 100644 --- a/src/soc/imgtec/pistachio/spi.c +++ b/src/soc/imgtec/pistachio/spi.c @@ -22,10 +22,6 @@ #include <string.h> #include <timer.h> -#if !CONFIG_SPI_ATOMIC_SEQUENCING -#error "Unsupported SPI driver API" -#endif - /* Imgtec controller uses 16 bit packet length. */ #define IMGTEC_SPI_MAX_TRANSFER_SIZE ((1 << 16) - 1) @@ -496,7 +492,7 @@ static int do_spi_xfer(const struct spi_slave *slave, const void *dout, } static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) + size_t bytesout, void *din, size_t bytesin) { unsigned int in_sz, out_sz; int ret; @@ -537,10 +533,56 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return SPIM_OK; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; /* Set up communications parameters for a SPI slave. */ diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index 0f7b0c6..633e7b9 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -610,8 +610,54 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index 2a0ddf8..a1454c2 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -594,8 +594,54 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index d2ae943..3d690d9 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -644,8 +644,54 @@ int spi_flash_protect(u32 start, u32 size) return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index 997bd13..124395c 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -590,8 +590,54 @@ spi_xfer_exit: return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/intel/fsp_broadwell_de/spi.c b/src/soc/intel/fsp_broadwell_de/spi.c index 5848966..ddbab88 100644 --- a/src/soc/intel/fsp_broadwell_de/spi.c +++ b/src/soc/intel/fsp_broadwell_de/spi.c @@ -607,8 +607,54 @@ spi_xfer_exit: return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/marvell/armada38x/spi.c b/src/soc/marvell/armada38x/spi.c index 25480e4..5ae0ace 100644 --- a/src/soc/marvell/armada38x/spi.c +++ b/src/soc/marvell/armada38x/spi.c @@ -465,21 +465,36 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, void *din, size_t in_bytes) { - int ret = -1; - - if (out_bytes) - ret = mrvl_spi_xfer(slave, out_bytes * 8, dout, din); - else if (in_bytes) - ret = mrvl_spi_xfer(slave, in_bytes * 8, dout, din); - else - die("Unexpected condition in spi_xfer\n"); + int ret = 0; + + if (dout && out_bytes) + ret = mrvl_spi_xfer(slave, out_bytes * 8, dout, NULL); + if (!ret && din && in_bytes) + ret = mrvl_spi_xfer(slave, in_bytes * 8, NULL, din); return ret; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i; + int ret = 0; + + for (i = 0; i < count; i++) { + ret = spi_ctrlr_xfer(slave, vectors[i].dout, + vectors[i].bytesout, vectors[i].din, + vectors[i].bytesin); + + if (ret) + return ret; + } + return 0; +} + static const spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/mediatek/mt8173/Kconfig b/src/soc/mediatek/mt8173/Kconfig index ec3481e..7a6ad87 100644 --- a/src/soc/mediatek/mt8173/Kconfig +++ b/src/soc/mediatek/mt8173/Kconfig @@ -9,7 +9,6 @@ config SOC_MEDIATEK_MT8173 select ARM64_USE_ARM_TRUSTED_FIRMWARE select BOOTBLOCK_CONSOLE select HAVE_UART_SPECIAL - select SPI_ATOMIC_SEQUENCING if SPI_FLASH select HAVE_MONOTONIC_TIMER select GENERIC_UDELAY select GENERIC_GPIO_LIB diff --git a/src/soc/mediatek/mt8173/spi.c b/src/soc/mediatek/mt8173/spi.c index 53d5b8c..a010993 100644 --- a/src/soc/mediatek/mt8173/spi.c +++ b/src/soc/mediatek/mt8173/spi.c @@ -279,6 +279,52 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave); @@ -292,7 +338,7 @@ static void spi_ctrlr_release_bus(const struct spi_slave *slave) static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index 5d8084f..d9d321b 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -719,8 +719,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, - size_t out_bytes, void *din, size_t in_bytes) +static int __spi_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct tegra_spi_channel *spi = to_tegra_spi(slave->bus); u8 *out_buf = (u8 *)dout; @@ -798,10 +798,26 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return ret; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + int ret; + size_t i; + + for (i = 0; i < count; i++) { + ret = __spi_xfer(slave, vectors[i].dout, vectors[i].bytesout, + vectors[i].din, vectors[i].bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/nvidia/tegra210/spi.c b/src/soc/nvidia/tegra210/spi.c index 2921355..c697a59 100644 --- a/src/soc/nvidia/tegra210/spi.c +++ b/src/soc/nvidia/tegra210/spi.c @@ -755,8 +755,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, - size_t out_bytes, void *din, size_t in_bytes) +static int __spi_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct tegra_spi_channel *spi = to_tegra_spi(slave->bus); u8 *out_buf = (u8 *)dout; @@ -834,10 +834,26 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return ret; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + int ret; + size_t i; + + for (i = 0; i < count; i++) { + ret = __spi_xfer(slave, vectors[i].dout, vectors[i].bytesout, + vectors[i].din, vectors[i].bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/qualcomm/ipq40xx/Kconfig b/src/soc/qualcomm/ipq40xx/Kconfig index f738622..05f29e4 100644 --- a/src/soc/qualcomm/ipq40xx/Kconfig +++ b/src/soc/qualcomm/ipq40xx/Kconfig @@ -7,7 +7,6 @@ config SOC_QC_IPQ40XX select ARCH_RAMSTAGE_ARMV7 select BOOTBLOCK_CONSOLE select HAVE_UART_SPECIAL - select SPI_ATOMIC_SEQUENCING select GENERIC_GPIO_LIB select HAVE_MONOTONIC_TIMER diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c index 6d044b3..72e573b 100644 --- a/src/soc/qualcomm/ipq40xx/spi.c +++ b/src/soc/qualcomm/ipq40xx/spi.c @@ -652,10 +652,56 @@ out: return ret; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/qualcomm/ipq806x/Kconfig b/src/soc/qualcomm/ipq806x/Kconfig index 7ba5df5..32b61bc 100644 --- a/src/soc/qualcomm/ipq806x/Kconfig +++ b/src/soc/qualcomm/ipq806x/Kconfig @@ -7,7 +7,6 @@ config SOC_QC_IPQ806X select ARCH_RAMSTAGE_ARMV7 select BOOTBLOCK_CONSOLE select HAVE_UART_SPECIAL - select SPI_ATOMIC_SEQUENCING select GENERIC_GPIO_LIB if SOC_QC_IPQ806X diff --git a/src/soc/qualcomm/ipq806x/spi.c b/src/soc/qualcomm/ipq806x/spi.c index e907729..eb8277e 100644 --- a/src/soc/qualcomm/ipq806x/spi.c +++ b/src/soc/qualcomm/ipq806x/spi.c @@ -757,10 +757,56 @@ out: return ret; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 16143b5..e457324 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -256,8 +256,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(65535, buf_len); } -static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, - size_t bytes_out, void *din, size_t bytes_in) +static int __spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytes_out, void *din, size_t bytes_in) { struct rockchip_spi *regs = to_rockchip_spi(slave)->regs; int ret = 0; @@ -328,10 +328,26 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return ret < 0 ? ret : 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + int ret; + size_t i; + + for (i = 0; i < count; i++) { + ret = __spi_xfer(slave, vectors[i].dout, vectors[i].bytesout, + vectors[i].din, vectors[i].bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c index f17566e..48f2767 100644 --- a/src/soc/samsung/exynos5420/spi.c +++ b/src/soc/samsung/exynos5420/spi.c @@ -177,7 +177,7 @@ static void spi_transfer(struct exynos_spi *regs, void *in, const void *out, } } -static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, +static int __spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, void *din, size_t bytes_in) { struct exynos_spi *regs = to_exynos_spi(slave)->regs; @@ -208,10 +208,26 @@ static void spi_ctrlr_release_bus(const struct spi_slave *slave) setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + int ret; + size_t i; + + for (i = 0; i < count; i++) { + ret = __spi_xfer(slave, vectors[i].dout, vectors[i].bytesout, + vectors[i].din, vectors[i].bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c index 8a4adfb..ebf5a70 100644 --- a/src/southbridge/amd/agesa/hudson/spi.c +++ b/src/southbridge/amd/agesa/hudson/spi.c @@ -165,8 +165,54 @@ int chipset_volatile_group_end(const struct spi_flash *flash) return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c index edf192a..5ce6adb 100644 --- a/src/southbridge/amd/cimx/sb800/spi.c +++ b/src/southbridge/amd/cimx/sb800/spi.c @@ -156,8 +156,54 @@ int chipset_volatile_group_end(const struct spi_flash *flash) return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/southbridge/amd/sb700/spi.c b/src/southbridge/amd/sb700/spi.c index 2e16ca8..ad2d813 100644 --- a/src/southbridge/amd/sb700/spi.c +++ b/src/southbridge/amd/sb700/spi.c @@ -118,8 +118,54 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 42a2a74..3745045 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -657,8 +657,54 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) diff --git a/src/southbridge/intel/fsp_rangeley/spi.c b/src/southbridge/intel/fsp_rangeley/spi.c index acdb072..2ea91e6 100644 --- a/src/southbridge/intel/fsp_rangeley/spi.c +++ b/src/southbridge/intel/fsp_rangeley/spi.c @@ -722,8 +722,54 @@ spi_xfer_exit: return 0; } +static int spi_ctrlr_xfer_vector(const struct spi_slave *slave, + const struct spi_op vectors[], size_t count) +{ + size_t i = 0; + int ret; + const void *dout; + void *din; + size_t bytesout, bytesin; + + while (i < count) { + /* + * Data to be sent will always be taken from the current + * vector. + */ + dout = vectors[i].dout; + bytesout = vectors[i].bytesout; + + /* + * Combine two concurrent vectors into one SPI xfer if: + * 1. There are atleast two vectors available. + * 2. Current vector has only dout non-NULL. + * 3. Next vector has only din non-NULL. + * + * If all the above conditions are satisfied, then the SPI flash + * controller can handle both command and response transactions + * concurrently. So, use din from next vector. + */ + if (((i + 1) < count) && + vectors[i].dout && !vectors[i].din && + vectors[i+1].din && !vectors[i].dout) { + i++; + } + + din = vectors[i].din; + bytesin = vectors[i].bytesin; + + i++; + + ret = spi_ctrlr_xfer(slave, dout, bytesout, din, bytesin); + if (ret) + return ret; + } + + return 0; +} + static const struct spi_ctrlr spi_ctrlr = { - .xfer = spi_ctrlr_xfer, + .xfer_vector = spi_ctrlr_xfer_vector, }; int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
1
0
0
0
Patch set updated for coreboot: soc/intel/apollolake: Use the new SPI driver interface
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17562
-gerrit commit a9075aea2f77362bcabb141e1c0e6e54b139642d Author: Furquan Shaikh <furquan(a)chromium.org> Date: Mon Nov 21 12:41:20 2016 -0800 soc/intel/apollolake: Use the new SPI driver interface 1. Define controller for fast SPI. 2. Separate out functions that are specific to SPI and flash controller in different files. BUG=chrome-os-partner:59832 BRANCH=None TEST=Compiles successfully for reef. Change-Id: If07db9d27bbf4f4eb6024175cb7753c6cf4fb793 Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- src/soc/intel/apollolake/Makefile.inc | 6 + src/soc/intel/apollolake/bootblock/bootblock.c | 3 +- src/soc/intel/apollolake/chip.c | 15 +- src/soc/intel/apollolake/flash_ctrlr.c | 390 ++++++++++++++++++++ src/soc/intel/apollolake/include/soc/flash_ctrlr.h | 93 +++++ src/soc/intel/apollolake/include/soc/spi.h | 91 ----- src/soc/intel/apollolake/mmap_boot.c | 4 +- src/soc/intel/apollolake/romstage.c | 10 +- src/soc/intel/apollolake/spi.c | 404 +-------------------- 9 files changed, 525 insertions(+), 491 deletions(-) diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc index 24b5035..d058ddb 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -12,6 +12,7 @@ bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/cache_as_ram.S bootblock-y += bootblock/bootblock.c bootblock-y += car.c +bootblock-y += flash_ctrlr.c bootblock-y += gpio.c bootblock-y += heci.c bootblock-y += itss.c @@ -24,6 +25,7 @@ bootblock-$(CONFIG_SOC_UART_DEBUG) += uart_early.c romstage-y += car.c romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += romstage.c +romstage-y += flash_ctrlr.c romstage-y += gpio.c romstage-y += heci.c romstage-y += i2c_early.c @@ -38,6 +40,7 @@ romstage-y += pmutil.c romstage-y += reset.c romstage-y += spi.c +smm-y += flash_ctrlr.c smm-y += mmap_boot.c smm-y += pmutil.c smm-y += gpio.c @@ -50,6 +53,7 @@ ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c ramstage-y += cpu.c ramstage-y += chip.c ramstage-y += elog.c +ramstage-y += flash_ctrlr.c ramstage-y += dsp.c ramstage-y += gpio.c ramstage-y += graphics.c @@ -76,6 +80,7 @@ ramstage-y += spi.c ramstage-y += xhci.c postcar-y += exit_car.S +postcar-y += flash_ctrlr.c postcar-y += memmap.c postcar-y += mmap_boot.c postcar-y += spi.c @@ -83,6 +88,7 @@ postcar-$(CONFIG_SOC_UART_DEBUG) += uart_early.c postcar-y += tsc_freq.c verstage-y += car.c +verstage-y += flash_ctrlr.c verstage-y += i2c_early.c verstage-y += heci.c verstage-y += memmap.c diff --git a/src/soc/intel/apollolake/bootblock/bootblock.c b/src/soc/intel/apollolake/bootblock/bootblock.c index be10a22..1f5055d 100644 --- a/src/soc/intel/apollolake/bootblock/bootblock.c +++ b/src/soc/intel/apollolake/bootblock/bootblock.c @@ -21,6 +21,7 @@ #include <lib.h> #include <soc/iomap.h> #include <soc/cpu.h> +#include <soc/flash_ctrlr.h> #include <soc/gpio.h> #include <soc/iosf.h> #include <soc/mmap_boot.h> @@ -129,7 +130,7 @@ static void enable_spibar(void) pci_write_config8(dev, PCI_COMMAND, val); /* Initialize SPI to allow BIOS to write/erase on flash. */ - spi_init(); + spi_flash_init(); } static void enable_pmcbar(void) diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index 32d68cc..d481f3e 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -28,6 +28,7 @@ #include <romstage_handoff.h> #include <soc/iomap.h> #include <soc/cpu.h> +#include <soc/flash_ctrlr.h> #include <soc/intel/common/vbt.h> #include <soc/itss.h> #include <soc/nvs.h> @@ -497,14 +498,14 @@ void platform_fsp_notify_status(enum fsp_notify_phase phase) } /* - * spi_init() needs to run unconditionally on every boot (including resume) to - * allow write protect to be disabled for eventlog and nvram updates. This needs - * to be done as early as possible in ramstage. Thus, add a callback for entry - * into BS_PRE_DEVICE. + * spi_flash init() needs to run unconditionally on every boot (including + * resume) to allow write protect to be disabled for eventlog and nvram + * updates. This needs to be done as early as possible in ramstage. Thus, add a + * callback for entry into BS_PRE_DEVICE. */ -static void spi_init_cb(void *unused) +static void spi_flash_init_cb(void *unused) { - spi_init(); + spi_flash_init(); } -BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_init_cb, NULL); +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_flash_init_cb, NULL); diff --git a/src/soc/intel/apollolake/flash_ctrlr.c b/src/soc/intel/apollolake/flash_ctrlr.c new file mode 100644 index 0000000..3374928 --- /dev/null +++ b/src/soc/intel/apollolake/flash_ctrlr.c @@ -0,0 +1,390 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Intel Corp. + * (Written by Alexandru Gagniuc <alexandrux.gagniuc(a)intel.com> for Intel Corp.) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define __SIMPLE_DEVICE__ + +#include <arch/early_variables.h> +#include <arch/io.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <soc/flash_ctrlr.h> +#include <soc/intel/common/spi_flash.h> +#include <soc/pci_devs.h> +#include <spi_flash.h> +#include <spi-generic.h> +#include <stdlib.h> +#include <string.h> + +/* Helper to create a SPI context on API entry. */ +#define BOILERPLATE_CREATE_CTX(ctx) \ + struct spi_flash_ctx real_ctx; \ + struct spi_flash_ctx *ctx = &real_ctx; \ + _get_spi_flash_ctx(ctx) + +/* + * Anything that's not success is <0. Provided solely for readability, as these + * constants are not used outside this file. + */ +enum errors { + SUCCESS = 0, + E_NOT_IMPLEMENTED = -1, + E_TIMEOUT = -2, + E_HW_ERROR = -3, + E_ARGUMENT = -4, +}; + +/* Reduce data-passing burden by grouping transaction data in a context. */ +struct spi_flash_ctx { + uintptr_t mmio_base; + device_t pci_dev; + uint32_t hsfsts_on_last_error; +}; + +static void _get_spi_flash_ctx(struct spi_flash_ctx *ctx) +{ + uint32_t bar; + + /* FIXME: use device definition */ + ctx->pci_dev = SPI_DEV; + + bar = pci_read_config32(ctx->pci_dev, PCI_BASE_ADDRESS_0); + ctx->mmio_base = bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK; + ctx->hsfsts_on_last_error = 0; +} + +/* Read register from the SPI flash controller. 'reg' is the register offset. */ +static uint32_t _spi_flash_ctrlr_reg_read(struct spi_flash_ctx *ctx, uint16_t reg) +{ + uintptr_t addr = ALIGN_DOWN(ctx->mmio_base + reg, 4); + return read32((void *)addr); +} + +uint32_t spi_flash_ctrlr_reg_read(uint16_t reg) +{ + BOILERPLATE_CREATE_CTX(ctx); + return _spi_flash_ctrlr_reg_read(ctx, reg); +} + +/* Write to register in SPI flash controller. 'reg' is the register offset. */ +static void _spi_flash_ctrlr_reg_write(struct spi_flash_ctx *ctx, uint16_t reg, + uint32_t val) +{ + uintptr_t addr = ALIGN_DOWN(ctx->mmio_base + reg, 4); + write32((void *)addr, val); + +} + +/* + * The hardware datasheet is not clear on what HORD values actually do. It + * seems that HORD_SFDP provides access to the first 8 bytes of the SFDP, which + * is the signature and revision fields. HORD_JEDEC provides access to the + * actual flash parameters, and is most likely what you want to use when + * probing the flash from software. + * It's okay to rely on SFPD, since the SPI flash controller requires an SFDP + * 1.5 or newer compliant SPI flash chip. + * NOTE: Due to the register layout of the hardware, all accesses will be + * aligned to a 4 byte boundary. + */ +static uint32_t read_spi_flash_sfdp_param(struct spi_flash_ctx *ctx, + uint16_t sfdp_reg) +{ + uint32_t ptinx_index = sfdp_reg & SPIBAR_PTINX_IDX_MASK; + _spi_flash_ctrlr_reg_write(ctx, SPIBAR_PTINX, + ptinx_index | SPIBAR_PTINX_HORD_JEDEC); + return _spi_flash_ctrlr_reg_read(ctx, SPIBAR_PTDATA); +} + +/* Fill FDATAn FIFO in preparation for a write transaction. */ +static void fill_xfer_fifo(struct spi_flash_ctx *ctx, const void *data, + size_t len) +{ + len = min(len, SPIBAR_FDATA_FIFO_SIZE); + + /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */ + memcpy((void*)(ctx->mmio_base + SPIBAR_FDATA(0)), data, len); +} + +/* Drain FDATAn FIFO after a read transaction populates data. */ +static void drain_xfer_fifo(struct spi_flash_ctx *ctx, void *dest, size_t len) +{ + len = min(len, SPIBAR_FDATA_FIFO_SIZE); + + /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */ + memcpy(dest, (void*)(ctx->mmio_base + SPIBAR_FDATA(0)), len); +} + +/* Fire up a transfer using the hardware sequencer. */ +static void start_hwseq_xfer(struct spi_flash_ctx *ctx, uint32_t hsfsts_cycle, + uint32_t flash_addr, size_t len) +{ + /* Make sure all W1C status bits get cleared. */ + uint32_t hsfsts = SPIBAR_HSFSTS_W1C_BITS; + /* Set up transaction parameters. */ + hsfsts |= hsfsts_cycle & SPIBAR_HSFSTS_FCYCLE_MASK; + hsfsts |= SPIBAR_HSFSTS_FBDC(len - 1); + + _spi_flash_ctrlr_reg_write(ctx, SPIBAR_FADDR, flash_addr); + _spi_flash_ctrlr_reg_write(ctx, SPIBAR_HSFSTS_CTL, + hsfsts | SPIBAR_HSFSTS_FGO); +} + +static void print_xfer_error(struct spi_flash_ctx *ctx, + const char *failure_reason, uint32_t flash_addr) +{ + printk(BIOS_ERR, "SPI Transaction %s at flash offset %x.\n" + "\tHSFSTS = 0x%08x\n", + failure_reason, flash_addr, ctx->hsfsts_on_last_error); +} + +static int wait_for_hwseq_xfer(struct spi_flash_ctx *ctx) +{ + uint32_t hsfsts; + do { + hsfsts = _spi_flash_ctrlr_reg_read(ctx, SPIBAR_HSFSTS_CTL); + + if (hsfsts & SPIBAR_HSFSTS_FCERR) { + ctx->hsfsts_on_last_error = hsfsts; + return E_HW_ERROR; + } + /* TODO: set up timer and abort on timeout */ + } while (!(hsfsts & SPIBAR_HSFSTS_FDONE)); + + return SUCCESS; +} + +/* Execute SPI flash transfer. This is a blocking call. */ +static int exec_sync_hwseq_xfer(struct spi_flash_ctx *ctx, + uint32_t hsfsts_cycle, uint32_t flash_addr, + size_t len) +{ + int ret; + start_hwseq_xfer(ctx, hsfsts_cycle, flash_addr, len); + ret = wait_for_hwseq_xfer(ctx); + if (ret != SUCCESS) { + const char *reason = (ret == E_TIMEOUT) ? "timeout" : "error"; + print_xfer_error(ctx, reason, flash_addr); + } + return ret; +} + +unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) +{ + return MIN(buf_len, SPIBAR_FDATA_FIFO_SIZE); +} + +/* + * Write-protection status for BIOS region (BIOS_CONTROL register): + * EISS/WPD bits 00 01 10 11 + * -- -- -- -- + * normal mode RO RW RO RO + * SMM mode RO RW RO RW + */ +void spi_flash_init(void) +{ + uint32_t bios_ctl; + + BOILERPLATE_CREATE_CTX(ctx); + + bios_ctl = pci_read_config32(ctx->pci_dev, SPIBAR_BIOS_CONTROL); + bios_ctl |= SPIBAR_BIOS_CONTROL_WPD; + bios_ctl &= ~SPIBAR_BIOS_CONTROL_EISS; + + /* Enable Prefetching and caching. */ + bios_ctl |= SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE; + bios_ctl &= ~SPIBAR_BIOS_CONTROL_CACHE_DISABLE; + + pci_write_config32(ctx->pci_dev, SPIBAR_BIOS_CONTROL, bios_ctl); +} + +/* Flash device operations. */ +static struct spi_flash boot_flash CAR_GLOBAL; + +static int nuclear_spi_flash_erase(const struct spi_flash *flash, + uint32_t offset, size_t len) +{ + int ret; + size_t erase_size; + uint32_t erase_cycle; + + BOILERPLATE_CREATE_CTX(ctx); + + if (!IS_ALIGNED(offset, 4 * KiB) || !IS_ALIGNED(len, 4 * KiB)) { + printk(BIOS_ERR, "BUG! SPI erase region not sector aligned.\n"); + return E_ARGUMENT; + } + + while (len) { + if (IS_ALIGNED(offset, 64 * KiB) && (len >= 64 * KiB)) { + erase_size = 64 * KiB; + erase_cycle = SPIBAR_HSFSTS_CYCLE_64K_ERASE; + } else { + erase_size = 4 * KiB; + erase_cycle = SPIBAR_HSFSTS_CYCLE_4K_ERASE; + } + printk(BIOS_SPEW, "Erasing flash addr %x + %zu KiB\n", + offset, erase_size / KiB); + + ret = exec_sync_hwseq_xfer(ctx, erase_cycle, offset, 0); + if (ret != SUCCESS) + return ret; + + offset += erase_size; + len -= erase_size; + } + + return SUCCESS; +} + +/* + * Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and + * that the operation does not cross 256-byte boundary. + */ +static size_t get_xfer_len(uint32_t addr, size_t len) +{ + size_t xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE); + size_t bytes_left = ALIGN_UP(addr, 256) - addr; + + if (bytes_left) + xfer_len = min(xfer_len, bytes_left); + + return xfer_len; +} + +static int nuclear_spi_flash_read(const struct spi_flash *flash, uint32_t addr, + size_t len, void *buf) +{ + int ret; + size_t xfer_len; + uint8_t *data = buf; + + BOILERPLATE_CREATE_CTX(ctx); + + while (len) { + xfer_len = get_xfer_len(addr, len); + + ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_READ, + addr, xfer_len); + if (ret != SUCCESS) + return ret; + + drain_xfer_fifo(ctx, data, xfer_len); + + addr += xfer_len; + data += xfer_len; + len -= xfer_len; + } + + return SUCCESS; +} + +static int nuclear_spi_flash_write(const struct spi_flash *flash, uint32_t addr, + size_t len, const void *buf) +{ + int ret; + size_t xfer_len; + const uint8_t *data = buf; + + BOILERPLATE_CREATE_CTX(ctx); + + while (len) { + xfer_len = get_xfer_len(addr, len); + fill_xfer_fifo(ctx, data, xfer_len); + + ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_WRITE, + addr, xfer_len); + if (ret != SUCCESS) + return ret; + + addr += xfer_len; + data += xfer_len; + len -= xfer_len; + } + + return SUCCESS; +} + +static int nuclear_spi_flash_status(const struct spi_flash *flash, uint8_t *reg) +{ + int ret; + BOILERPLATE_CREATE_CTX(ctx); + + ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_RD_STATUS, 0, + sizeof(*reg)); + if (ret != SUCCESS) + return ret; + + drain_xfer_fifo(ctx, reg, sizeof(*reg)); + return ret; +} + +/* + * We can't use FDOC and FDOD to read FLCOMP, as previous platforms did. + * For details see: + * Ch 31, SPI: p. 194 + * The size of the flash component is always taken from density field in the + * SFDP table. FLCOMP.C0DEN is no longer used by the Flash Controller. + */ +struct spi_flash *spi_flash_programmer_probe(struct spi_slave *dev, int force) +{ + BOILERPLATE_CREATE_CTX(ctx); + struct spi_flash *flash; + uint32_t flash_bits; + + flash = car_get_var_ptr(&boot_flash); + + /* + * bytes = (bits + 1) / 8; + * But we need to do the addition in a way which doesn't overflow for + * 4 Gbit devices (flash_bits == 0xffffffff). + */ + /* FIXME: Don't hardcode 0x04 ? */ + flash_bits = read_spi_flash_sfdp_param(ctx, 0x04); + flash->size = (flash_bits >> 3) + 1; + + flash->spi = dev; + flash->name = "Apollolake hardware sequencer"; + + /* Can erase both 4 KiB and 64 KiB chunks. Declare the smaller size. */ + flash->sector_size = 4 * KiB; + /* + * FIXME: Get erase+cmd, and status_cmd from SFDP. + * + * flash->erase_cmd = ??? + * flash->status_cmd = ??? + */ + + flash->internal_write = nuclear_spi_flash_write; + flash->internal_erase = nuclear_spi_flash_erase; + flash->internal_read = nuclear_spi_flash_read; + flash->internal_status = nuclear_spi_flash_status; + + return flash; +} + +int spi_flash_get_fpr_info(struct fpr_info *info) +{ + BOILERPLATE_CREATE_CTX(ctx); + + if (!ctx->mmio_base) + return -1; + + info->base = ctx->mmio_base + SPIBAR_FPR_BASE; + info->max = SPIBAR_FPR_MAX; + + return 0; +} diff --git a/src/soc/intel/apollolake/include/soc/flash_ctrlr.h b/src/soc/intel/apollolake/include/soc/flash_ctrlr.h new file mode 100644 index 0000000..5b9c622 --- /dev/null +++ b/src/soc/intel/apollolake/include/soc/flash_ctrlr.h @@ -0,0 +1,93 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_APOLLOLAKE_SPI_H_ +#define _SOC_APOLLOLAKE_SPI_H_ + +/* PCI configuration registers */ +#define SPIBAR_BIOS_CONTROL 0xdc +/* Bit definitions for BIOS_CONTROL */ +#define SPIBAR_BIOS_CONTROL_WPD (1 << 0) +#define SPIBAR_BIOS_CONTROL_CACHE_DISABLE (1 << 2) +#define SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE (1 << 3) +#define SPIBAR_BIOS_CONTROL_EISS (1 << 5) + +/* Maximum bytes of data that can fit in FDATAn registers */ +#define SPIBAR_FDATA_FIFO_SIZE 0x40 + +/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +#define SPIBAR_BIOS_BFPREG 0x00 +#define SPIBAR_HSFSTS_CTL 0x04 +#define SPIBAR_FADDR 0x08 +#define SPIBAR_FDATA(n) (0x10 + ((n) & 0xf) * 4) +#define SPIBAR_FPR_BASE 0x84 +#define SPIBAR_PTINX 0xcc +#define SPIBAR_PTDATA 0xd0 + +#define SPIBAR_FPR_MAX 5 + +/* Bit definitions and masks for BIOS_BFPREG register. */ +#define SPIBAR_BFPREG_PRB_MASK (0x7fff) +#define SPIBAR_BFPREG_PRL_SHIFT (16) +#define SPIBAR_BFPREG_PRL_MASK (0x7fff << SPIBAR_BFPREG_PRL_SHIFT) +#define SPIBAR_BFPREG_SBRS (1 << 31) + +/* Bit definitions for HSFSTS_CTL register */ +#define SPIBAR_HSFSTS_FBDC_MASK (0x3f << 24) +#define SPIBAR_HSFSTS_FBDC(n) (((n) << 24) & SPIBAR_HSFSTS_FBDC_MASK) +#define SPIBAR_HSFSTS_WET (1 << 21) +#define SPIBAR_HSFSTS_FCYCLE_MASK (0xf << 17) +#define SPIBAR_HSFSTS_FCYCLE(cyc) (((cyc) << 17) & SPIBAR_HSFSTS_FCYCLE_MASK) +#define SPIBAR_HSFSTS_FGO (1 << 16) +#define SPIBAR_HSFSTS_FLOCKDN (1 << 15) +#define SPIBAR_HSFSTS_FDV (1 << 14) +#define SPIBAR_HSFSTS_FDOPSS (1 << 13) +#define SPIBAR_HSFSTS_SAF_CE (1 << 8) +#define SPIBAR_HSFSTS_SAF_ACTIVE (1 << 7) +#define SPIBAR_HSFSTS_SAF_LE (1 << 6) +#define SPIBAR_HSFSTS_SCIP (1 << 5) +#define SPIBAR_HSFSTS_SAF_DLE (1 << 4) +#define SPIBAR_HSFSTS_SAF_ERROR (1 << 3) +#define SPIBAR_HSFSTS_AEL (1 << 2) +#define SPIBAR_HSFSTS_FCERR (1 << 1) +#define SPIBAR_HSFSTS_FDONE (1 << 0) +#define SPIBAR_HSFSTS_W1C_BITS (0xff) +/* Supported flash cycle types */ +#define SPIBAR_HSFSTS_CYCLE_READ SPIBAR_HSFSTS_FCYCLE(0) +#define SPIBAR_HSFSTS_CYCLE_WRITE SPIBAR_HSFSTS_FCYCLE(2) +#define SPIBAR_HSFSTS_CYCLE_4K_ERASE SPIBAR_HSFSTS_FCYCLE(3) +#define SPIBAR_HSFSTS_CYCLE_64K_ERASE SPIBAR_HSFSTS_FCYCLE(4) +#define SPIBAR_HSFSTS_CYCLE_RD_STATUS SPIBAR_HSFSTS_FCYCLE(8) + +/* Bit definitions for PTINX register */ +#define SPIBAR_PTINX_COMP_0 (0 << 14) +#define SPIBAR_PTINX_COMP_1 (1 << 14) +#define SPIBAR_PTINX_HORD_SFDP (0 << 12) +#define SPIBAR_PTINX_HORD_PARAM (1 << 12) +#define SPIBAR_PTINX_HORD_JEDEC (2 << 12) +#define SPIBAR_PTINX_IDX_MASK 0xffc + +/* + * Reads status register. On success returns 0 and status contains the value + * read from the status register. On error returns -1. + */ +int spi_flash_read_status(uint8_t *status); + +/* Read SPI controller register. */ +uint32_t spi_flash_ctrlr_reg_read(uint16_t reg); + +void spi_flash_init(void); +#endif diff --git a/src/soc/intel/apollolake/include/soc/spi.h b/src/soc/intel/apollolake/include/soc/spi.h deleted file mode 100644 index 4f16a85..0000000 --- a/src/soc/intel/apollolake/include/soc/spi.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2016 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _SOC_APOLLOLAKE_SPI_H_ -#define _SOC_APOLLOLAKE_SPI_H_ - -/* PCI configuration registers */ -#define SPIBAR_BIOS_CONTROL 0xdc -/* Bit definitions for BIOS_CONTROL */ -#define SPIBAR_BIOS_CONTROL_WPD (1 << 0) -#define SPIBAR_BIOS_CONTROL_CACHE_DISABLE (1 << 2) -#define SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE (1 << 3) -#define SPIBAR_BIOS_CONTROL_EISS (1 << 5) - -/* Maximum bytes of data that can fit in FDATAn registers */ -#define SPIBAR_FDATA_FIFO_SIZE 0x40 - -/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ -#define SPIBAR_BIOS_BFPREG 0x00 -#define SPIBAR_HSFSTS_CTL 0x04 -#define SPIBAR_FADDR 0x08 -#define SPIBAR_FDATA(n) (0x10 + ((n) & 0xf) * 4) -#define SPIBAR_FPR_BASE 0x84 -#define SPIBAR_PTINX 0xcc -#define SPIBAR_PTDATA 0xd0 - -#define SPIBAR_FPR_MAX 5 - -/* Bit definitions and masks for BIOS_BFPREG register. */ -#define SPIBAR_BFPREG_PRB_MASK (0x7fff) -#define SPIBAR_BFPREG_PRL_SHIFT (16) -#define SPIBAR_BFPREG_PRL_MASK (0x7fff << SPIBAR_BFPREG_PRL_SHIFT) -#define SPIBAR_BFPREG_SBRS (1 << 31) - -/* Bit definitions for HSFSTS_CTL register */ -#define SPIBAR_HSFSTS_FBDC_MASK (0x3f << 24) -#define SPIBAR_HSFSTS_FBDC(n) (((n) << 24) & SPIBAR_HSFSTS_FBDC_MASK) -#define SPIBAR_HSFSTS_WET (1 << 21) -#define SPIBAR_HSFSTS_FCYCLE_MASK (0xf << 17) -#define SPIBAR_HSFSTS_FCYCLE(cyc) (((cyc) << 17) & SPIBAR_HSFSTS_FCYCLE_MASK) -#define SPIBAR_HSFSTS_FGO (1 << 16) -#define SPIBAR_HSFSTS_FLOCKDN (1 << 15) -#define SPIBAR_HSFSTS_FDV (1 << 14) -#define SPIBAR_HSFSTS_FDOPSS (1 << 13) -#define SPIBAR_HSFSTS_SAF_CE (1 << 8) -#define SPIBAR_HSFSTS_SAF_ACTIVE (1 << 7) -#define SPIBAR_HSFSTS_SAF_LE (1 << 6) -#define SPIBAR_HSFSTS_SCIP (1 << 5) -#define SPIBAR_HSFSTS_SAF_DLE (1 << 4) -#define SPIBAR_HSFSTS_SAF_ERROR (1 << 3) -#define SPIBAR_HSFSTS_AEL (1 << 2) -#define SPIBAR_HSFSTS_FCERR (1 << 1) -#define SPIBAR_HSFSTS_FDONE (1 << 0) -#define SPIBAR_HSFSTS_W1C_BITS (0xff) -/* Supported flash cycle types */ -#define SPIBAR_HSFSTS_CYCLE_READ SPIBAR_HSFSTS_FCYCLE(0) -#define SPIBAR_HSFSTS_CYCLE_WRITE SPIBAR_HSFSTS_FCYCLE(2) -#define SPIBAR_HSFSTS_CYCLE_4K_ERASE SPIBAR_HSFSTS_FCYCLE(3) -#define SPIBAR_HSFSTS_CYCLE_64K_ERASE SPIBAR_HSFSTS_FCYCLE(4) -#define SPIBAR_HSFSTS_CYCLE_RD_STATUS SPIBAR_HSFSTS_FCYCLE(8) - -/* Bit definitions for PTINX register */ -#define SPIBAR_PTINX_COMP_0 (0 << 14) -#define SPIBAR_PTINX_COMP_1 (1 << 14) -#define SPIBAR_PTINX_HORD_SFDP (0 << 12) -#define SPIBAR_PTINX_HORD_PARAM (1 << 12) -#define SPIBAR_PTINX_HORD_JEDEC (2 << 12) -#define SPIBAR_PTINX_IDX_MASK 0xffc - -/* - * Reads status register. On success returns 0 and status contains the value - * read from the status register. On error returns -1. - */ -int spi_read_status(uint8_t *status); - -/* Read SPI controller register. */ -uint32_t spi_ctrlr_reg_read(uint16_t reg); -#endif diff --git a/src/soc/intel/apollolake/mmap_boot.c b/src/soc/intel/apollolake/mmap_boot.c index bf2e5b9..7159c24 100644 --- a/src/soc/intel/apollolake/mmap_boot.c +++ b/src/soc/intel/apollolake/mmap_boot.c @@ -22,9 +22,9 @@ #include <commonlib/region.h> #include <console/console.h> #include <fmap.h> +#include <soc/flash_ctrlr.h> #include <soc/intel/common/nvm.h> #include <soc/mmap_boot.h> -#include <soc/spi.h> /* * BIOS region on the flash is mapped right below 4GiB in the address @@ -81,7 +81,7 @@ static void bios_mmap_init(void) * Base and Limit. * Base and Limit fields are in units of 4KiB. */ - uint32_t val = spi_ctrlr_reg_read(SPIBAR_BIOS_BFPREG); + uint32_t val = spi_flash_ctrlr_reg_read(SPIBAR_BIOS_BFPREG); start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB; bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >> diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c index 039b586..77562c4 100644 --- a/src/soc/intel/apollolake/romstage.c +++ b/src/soc/intel/apollolake/romstage.c @@ -32,14 +32,15 @@ #include <fsp/memmap.h> #include <fsp/util.h> #include <soc/cpu.h> +#include <soc/flash_ctrlr.h> #include <soc/intel/common/mrc_cache.h> #include <soc/iomap.h> #include <soc/northbridge.h> #include <soc/pci_devs.h> #include <soc/pm.h> #include <soc/romstage.h> -#include <soc/spi.h> #include <soc/uart.h> +#include <spi_flash.h> #include <string.h> #include <timestamp.h> #include <timer.h> @@ -316,7 +317,12 @@ void mainboard_save_dimm_info(void) int get_sw_write_protect_state(void) { uint8_t status; + struct spi_flash *flash; + + flash = spi_flash_probe(CONFIG_BOOT_DEVICE_SPI_FLASH_BUS, 0); + if (!flash) + return 0; /* Return unprotected status if status read fails. */ - return spi_read_status(&status) ? 0 : !!(status & 0x80); + return spi_flash_status(flash, &status) ? 0 : !!(status & 0x80); } diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c index 8992fa5..87d4d01 100644 --- a/src/soc/intel/apollolake/spi.c +++ b/src/soc/intel/apollolake/spi.c @@ -1,8 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2016 Intel Corp. - * (Written by Alexandru Gagniuc <alexandrux.gagniuc(a)intel.com> for Intel Corp.) + * Copyright 2016 Google Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,400 +14,29 @@ * GNU General Public License for more details. */ -#define __SIMPLE_DEVICE__ - -#include <arch/early_variables.h> -#include <arch/io.h> #include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <soc/intel/common/spi_flash.h> -#include <soc/pci_devs.h> -#include <soc/spi.h> -#include <spi_flash.h> #include <spi-generic.h> -#include <stdlib.h> -#include <string.h> - -/* Helper to create a SPI context on API entry. */ -#define BOILERPLATE_CREATE_CTX(ctx) \ - struct spi_ctx real_ctx; \ - struct spi_ctx *ctx = &real_ctx; \ - _spi_get_ctx(ctx) - -/* - * Anything that's not success is <0. Provided solely for readability, as these - * constants are not used outside this file. - */ -enum errors { - SUCCESS = 0, - E_NOT_IMPLEMENTED = -1, - E_TIMEOUT = -2, - E_HW_ERROR = -3, - E_ARGUMENT = -4, -}; - -/* Reduce data-passing burden by grouping transaction data in a context. */ -struct spi_ctx { - uintptr_t mmio_base; - device_t pci_dev; - uint32_t hsfsts_on_last_error; -}; - -static void _spi_get_ctx(struct spi_ctx *ctx) -{ - uint32_t bar; - - /* FIXME: use device definition */ - ctx->pci_dev = SPI_DEV; - - bar = pci_read_config32(ctx->pci_dev, PCI_BASE_ADDRESS_0); - ctx->mmio_base = bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK; - ctx->hsfsts_on_last_error = 0; -} - -/* Read register from the SPI controller. 'reg' is the register offset. */ -static uint32_t _spi_ctrlr_reg_read(struct spi_ctx *ctx, uint16_t reg) -{ - uintptr_t addr = ALIGN_DOWN(ctx->mmio_base + reg, 4); - return read32((void *)addr); -} - -uint32_t spi_ctrlr_reg_read(uint16_t reg) -{ - BOILERPLATE_CREATE_CTX(ctx); - return _spi_ctrlr_reg_read(ctx, reg); -} - -/* Write to register in the SPI controller. 'reg' is the register offset. */ -static void _spi_ctrlr_reg_write(struct spi_ctx *ctx, uint16_t reg, - uint32_t val) -{ - uintptr_t addr = ALIGN_DOWN(ctx->mmio_base + reg, 4); - write32((void *)addr, val); - -} - -/* - * The hardware datasheet is not clear on what HORD values actually do. It - * seems that HORD_SFDP provides access to the first 8 bytes of the SFDP, which - * is the signature and revision fields. HORD_JEDEC provides access to the - * actual flash parameters, and is most likely what you want to use when - * probing the flash from software. - * It's okay to rely on SFPD, since the SPI controller requires an SFDP 1.5 or - * newer compliant SPI chip. - * NOTE: Due to the register layout of the hardware, all accesses will be - * aligned to a 4 byte boundary. - */ -static uint32_t read_spi_sfdp_param(struct spi_ctx *ctx, uint16_t sfdp_reg) -{ - uint32_t ptinx_index = sfdp_reg & SPIBAR_PTINX_IDX_MASK; - _spi_ctrlr_reg_write(ctx, SPIBAR_PTINX, - ptinx_index | SPIBAR_PTINX_HORD_JEDEC); - return _spi_ctrlr_reg_read(ctx, SPIBAR_PTDATA); -} - -/* Fill FDATAn FIFO in preparation for a write transaction. */ -static void fill_xfer_fifo(struct spi_ctx *ctx, const void *data, size_t len) -{ - len = min(len, SPIBAR_FDATA_FIFO_SIZE); - - /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */ - memcpy((void*)(ctx->mmio_base + SPIBAR_FDATA(0)), data, len); -} - -/* Drain FDATAn FIFO after a read transaction populates data. */ -static void drain_xfer_fifo(struct spi_ctx *ctx, void *dest, size_t len) -{ - len = min(len, SPIBAR_FDATA_FIFO_SIZE); - - /* YES! memcpy() works. FDATAn does not require 32-bit accesses. */ - memcpy(dest, (void*)(ctx->mmio_base + SPIBAR_FDATA(0)), len); -} - -/* Fire up a transfer using the hardware sequencer. */ -static void start_hwseq_xfer(struct spi_ctx *ctx, uint32_t hsfsts_cycle, - uint32_t flash_addr, size_t len) -{ - /* Make sure all W1C status bits get cleared. */ - uint32_t hsfsts = SPIBAR_HSFSTS_W1C_BITS; - /* Set up transaction parameters. */ - hsfsts |= hsfsts_cycle & SPIBAR_HSFSTS_FCYCLE_MASK; - hsfsts |= SPIBAR_HSFSTS_FBDC(len - 1); - - _spi_ctrlr_reg_write(ctx, SPIBAR_FADDR, flash_addr); - _spi_ctrlr_reg_write(ctx, SPIBAR_HSFSTS_CTL, - hsfsts | SPIBAR_HSFSTS_FGO); -} - -static void print_xfer_error(struct spi_ctx *ctx, const char *failure_reason, - uint32_t flash_addr) -{ - printk(BIOS_ERR, "SPI Transaction %s at flash offset %x.\n" - "\tHSFSTS = 0x%08x\n", - failure_reason, flash_addr, ctx->hsfsts_on_last_error); -} - -static int wait_for_hwseq_xfer(struct spi_ctx *ctx) -{ - uint32_t hsfsts; - do { - hsfsts = _spi_ctrlr_reg_read(ctx, SPIBAR_HSFSTS_CTL); - - if (hsfsts & SPIBAR_HSFSTS_FCERR) { - ctx->hsfsts_on_last_error = hsfsts; - return E_HW_ERROR; - } - /* TODO: set up timer and abort on timeout */ - } while (!(hsfsts & SPIBAR_HSFSTS_FDONE)); - - return SUCCESS; -} - -/* Execute SPI transfer. This is a blocking call. */ -static int exec_sync_hwseq_xfer(struct spi_ctx *ctx, uint32_t hsfsts_cycle, - uint32_t flash_addr, size_t len) -{ - int ret; - start_hwseq_xfer(ctx, hsfsts_cycle, flash_addr, len); - ret = wait_for_hwseq_xfer(ctx); - if (ret != SUCCESS) { - const char *reason = (ret == E_TIMEOUT) ? "timeout" : "error"; - print_xfer_error(ctx, reason, flash_addr); - } - return ret; -} - -unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) -{ - return MIN(buf_len, SPIBAR_FDATA_FIFO_SIZE); -} - -/* - * Write-protection status for BIOS region (BIOS_CONTROL register): - * EISS/WPD bits 00 01 10 11 - * -- -- -- -- - * normal mode RO RW RO RO - * SMM mode RO RW RO RW - */ -void spi_init(void) -{ - uint32_t bios_ctl; - - BOILERPLATE_CREATE_CTX(ctx); - - bios_ctl = pci_read_config32(ctx->pci_dev, SPIBAR_BIOS_CONTROL); - bios_ctl |= SPIBAR_BIOS_CONTROL_WPD; - bios_ctl &= ~SPIBAR_BIOS_CONTROL_EISS; - - /* Enable Prefetching and caching. */ - bios_ctl |= SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE; - bios_ctl &= ~SPIBAR_BIOS_CONTROL_CACHE_DISABLE; - - pci_write_config32(ctx->pci_dev, SPIBAR_BIOS_CONTROL, bios_ctl); -} - -static int nuclear_spi_erase(const struct spi_flash *flash, uint32_t offset, - size_t len) -{ - int ret; - size_t erase_size; - uint32_t erase_cycle; - - BOILERPLATE_CREATE_CTX(ctx); - - if (!IS_ALIGNED(offset, 4 * KiB) || !IS_ALIGNED(len, 4 * KiB)) { - printk(BIOS_ERR, "BUG! SPI erase region not sector aligned.\n"); - return E_ARGUMENT; - } - - while (len) { - if (IS_ALIGNED(offset, 64 * KiB) && (len >= 64 * KiB)) { - erase_size = 64 * KiB; - erase_cycle = SPIBAR_HSFSTS_CYCLE_64K_ERASE; - } else { - erase_size = 4 * KiB; - erase_cycle = SPIBAR_HSFSTS_CYCLE_4K_ERASE; - } - printk(BIOS_SPEW, "Erasing flash addr %x + %zu KiB\n", - offset, erase_size / KiB); - - ret = exec_sync_hwseq_xfer(ctx, erase_cycle, offset, 0); - if (ret != SUCCESS) - return ret; - - offset += erase_size; - len -= erase_size; - } - - return SUCCESS; -} - -/* - * Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and - * that the operation does not cross 256-byte boundary. - */ -static size_t get_xfer_len(uint32_t addr, size_t len) -{ - size_t xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE); - size_t bytes_left = ALIGN_UP(addr, 256) - addr; - - if (bytes_left) - xfer_len = min(xfer_len, bytes_left); - - return xfer_len; -} - -static int nuclear_spi_read(const struct spi_flash *flash, uint32_t addr, - size_t len, void *buf) -{ - int ret; - size_t xfer_len; - uint8_t *data = buf; - - BOILERPLATE_CREATE_CTX(ctx); - - while (len) { - xfer_len = get_xfer_len(addr, len); - - ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_READ, - addr, xfer_len); - if (ret != SUCCESS) - return ret; - - drain_xfer_fifo(ctx, data, xfer_len); - - addr += xfer_len; - data += xfer_len; - len -= xfer_len; - } - - return SUCCESS; -} - -static int nuclear_spi_write(const struct spi_flash *flash, uint32_t addr, - size_t len, const void *buf) -{ - int ret; - size_t xfer_len; - const uint8_t *data = buf; - - BOILERPLATE_CREATE_CTX(ctx); - - while (len) { - xfer_len = get_xfer_len(addr, len); - fill_xfer_fifo(ctx, data, xfer_len); - - ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_WRITE, - addr, xfer_len); - if (ret != SUCCESS) - return ret; - - addr += xfer_len; - data += xfer_len; - len -= xfer_len; - } - - return SUCCESS; -} - -static int nuclear_spi_status(const struct spi_flash *flash, uint8_t *reg) -{ - int ret; - BOILERPLATE_CREATE_CTX(ctx); - - ret = exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_RD_STATUS, 0, - sizeof(*reg)); - if (ret != SUCCESS) - return ret; - - drain_xfer_fifo(ctx, reg, sizeof(*reg)); - return ret; -} - -static struct spi_flash boot_flash CAR_GLOBAL; - -/* - * We can't use FDOC and FDOD to read FLCOMP, as previous platforms did. - * For details see: - * Ch 31, SPI: p. 194 - * The size of the flash component is always taken from density field in the - * SFDP table. FLCOMP.C0DEN is no longer used by the Flash Controller. - */ -struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) -{ - BOILERPLATE_CREATE_CTX(ctx); - struct spi_flash *flash; - uint32_t flash_bits; - - flash = car_get_var_ptr(&boot_flash); - - /* - * bytes = (bits + 1) / 8; - * But we need to do the addition in a way which doesn't overflow for - * 4 Gbit devices (flash_bits == 0xffffffff). - */ - /* FIXME: Don't hardcode 0x04 ? */ - flash_bits = read_spi_sfdp_param(ctx, 0x04); - flash->size = (flash_bits >> 3) + 1; - - flash->spi = spi; - flash->name = "Apollolake hardware sequencer"; - - /* Can erase both 4 KiB and 64 KiB chunks. Declare the smaller size. */ - flash->sector_size = 4 * KiB; - /* - * FIXME: Get erase+cmd, and status_cmd from SFDP. - * - * flash->erase_cmd = ??? - * flash->status_cmd = ??? - */ - - flash->internal_write = nuclear_spi_write; - flash->internal_erase = nuclear_spi_erase; - flash->internal_read = nuclear_spi_read; - flash->internal_status = nuclear_spi_status; - - return flash; -} - -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - BOILERPLATE_CREATE_CTX(ctx); - - /* This is special hardware. We expect bus 0 and CS line 0 here. */ - if ((bus != 0) || (cs != 0)) - return -1; - slave->bus = bus; - slave->cs = cs; - slave->ctrlr = NULL; - - return 0; -} - -int spi_read_status(uint8_t *status) +/* SPI controller managing the fast SPI. */ +static int fast_spi_ctrlr_setup(const struct spi_slave *dev) { - BOILERPLATE_CREATE_CTX(ctx); - - if (exec_sync_hwseq_xfer(ctx, SPIBAR_HSFSTS_CYCLE_RD_STATUS, 0, - sizeof(*status)) != SUCCESS) + if ((dev->bus != 0) && (dev->cs != 0)) { + printk(BIOS_ERR, "%s: Unsupported device " + "bus=0x%x,cs=0x%x!\n", __func__, dev->bus, dev->cs); return -1; + } - drain_xfer_fifo(ctx, status, sizeof(*status)); - + printk(BIOS_INFO, "%s: Found controller for device " + "(bus=0x%x,cs=0x%x)!!\n", __func__, dev->bus, dev->cs); return 0; } -int spi_flash_get_fpr_info(struct fpr_info *info) -{ - BOILERPLATE_CREATE_CTX(ctx); - - if (!ctx->mmio_base) - return -1; +static const struct spi_ctrlr fast_spi_ctrlr = { + .setup = fast_spi_ctrlr_setup, +}; - info->base = ctx->mmio_base + SPIBAR_FPR_BASE; - info->max = SPIBAR_FPR_MAX; +const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { + { .ctrlr = &fast_spi_ctrlr, .bus_start = 0, .bus_end = 0 }, +}; - return 0; -} +const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);
1
0
0
0
Patch set updated for coreboot: spi: Clean up SPI driver interface
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17561
-gerrit commit bf7307458382c06bf5e01e4c416a7effe3f3d39b Author: Furquan Shaikh <furquan(a)chromium.org> Date: Thu Dec 1 07:25:31 2016 -0800 spi: Clean up SPI driver interface 1. Add new structure spi_ctrlr_buses that allows platform to define a mapping from SPI controller to buses managed by the controller. 2. Provide weak implementations of spi_init and spi_setup_slave that will be used by platforms using the new interface. BUG=chrome-os-partner:59832 BRANCH=None TEST=Compiles successfully Change-Id: Ia6f47941b786299f4d823895898ffb1b36e02f73 Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- src/drivers/spi/spi-generic.c | 35 +++++++++++++++++++++++++++++++++++ src/include/spi-generic.h | 19 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/drivers/spi/spi-generic.c b/src/drivers/spi/spi-generic.c index 7398ee9..4fcd04c 100644 --- a/src/drivers/spi/spi-generic.c +++ b/src/drivers/spi/spi-generic.c @@ -41,3 +41,38 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, return -1; } + +void __attribute__((weak)) spi_init(void) +{ + /* Default weak implementation - do nothing. */ +} + +const struct spi_ctrlr_buses spi_ctrlr_bus_map[0] __attribute__((weak)); +const size_t spi_ctrlr_bus_map_count __attribute__((weak)); + +int __attribute__((weak)) spi_setup_slave(unsigned int bus, unsigned int cs, + struct spi_slave *slave) +{ + size_t i; + + memset(slave, 0, sizeof(*slave)); + + for (i = 0; i < spi_ctrlr_bus_map_count; i++) { + if ((spi_ctrlr_bus_map[i].bus_start <= bus) && + (spi_ctrlr_bus_map[i].bus_end >= bus)) { + slave->ctrlr = spi_ctrlr_bus_map[i].ctrlr; + break; + } + } + + if (slave->ctrlr == NULL) + return -1; + + slave->bus = bus; + slave->cs = cs; + + if (slave->ctrlr->setup) + return slave->ctrlr->setup(slave); + + return 0; +} diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index b4a10af..d28fefd 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -42,15 +42,34 @@ struct spi_slave { * claim_bus: Claim SPI bus and prepare for communication. * release_bus: Release SPI bus. * xfer: SPI transfer + * setup: Setup given SPI device bus. */ struct spi_ctrlr { int (*claim_bus)(const struct spi_slave *slave); void (*release_bus)(const struct spi_slave *slave); int (*xfer)(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin); + int (*setup)(const struct spi_slave *slave); }; /*----------------------------------------------------------------------- + * Structure defining mapping of SPI buses to controller. + * + * ctrlr: Pointer to controller structure managing the given SPI buses. + * bus_start: Start bus number managed by the controller. + * bus_end: End bus number manager by the controller. + */ +struct spi_ctrlr_buses { + const struct spi_ctrlr *ctrlr; + unsigned int bus_start; + unsigned int bus_end; +}; + +/* Mapping of SPI buses to controllers - should be defined by platform. */ +extern const struct spi_ctrlr_buses spi_ctrlr_bus_map[]; +extern const size_t spi_ctrlr_bus_map_count; + +/*----------------------------------------------------------------------- * Initialization, must be called once on start up. * */
1
0
0
0
Patch set updated for coreboot: spi: Define and use spi_ctrlr structure
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17684
-gerrit commit 846ad8aa17bc740863a8c01b4f0d70f73d759db9 Author: Furquan Shaikh <furquan(a)chromium.org> Date: Thu Dec 1 07:12:32 2016 -0800 spi: Define and use spi_ctrlr structure 1. Define a new structure spi_ctrlr that allows platforms to define callbacks for spi operations (claim bus, release bus, transfer). 2. Add a new member (pointer to spi_ctrlr structure) in spi_slave structure which will be initialized by call to spi_setup_slave. 3. Define spi_claim_bus, spi_release_bus and spi_xfer in spi-generic.c which will make appropriate calls to ctrlr functions. BUG=chrome-os-partner:59832 BRANCH=None TEST=Compiles successfully Change-Id: Icb2326e3aab1e8f4bef53f553f82b3836358c55e Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- src/drivers/spi/Makefile.inc | 5 ++ src/drivers/spi/spi-generic.c | 43 +++++++++++++ src/include/spi-generic.h | 18 ++++++ src/soc/broadcom/cygnus/spi.c | 87 +++++++++++++------------ src/soc/imgtec/pistachio/spi.c | 105 ++++++++++++++++--------------- src/soc/intel/apollolake/spi.c | 19 +----- src/soc/intel/baytrail/spi.c | 34 +++++----- src/soc/intel/braswell/spi.c | 34 +++++----- src/soc/intel/broadwell/spi.c | 34 +++++----- src/soc/intel/fsp_baytrail/spi.c | 34 +++++----- src/soc/intel/fsp_broadwell_de/spi.c | 34 +++++----- src/soc/intel/skylake/flash_controller.c | 19 +----- src/soc/marvell/armada38x/spi.c | 37 ++++++----- src/soc/marvell/bg4cd/spi.c | 15 ----- src/soc/mediatek/mt8173/spi.c | 60 ++++++++++-------- src/soc/nvidia/tegra124/spi.c | 15 +++-- src/soc/nvidia/tegra210/spi.c | 15 +++-- src/soc/qualcomm/ipq40xx/spi.c | 93 ++++++++++++++------------- src/soc/qualcomm/ipq806x/spi.c | 101 +++++++++++++++-------------- src/soc/rockchip/common/spi.c | 35 ++++++----- src/soc/samsung/exynos5420/spi.c | 45 +++++++------ src/southbridge/amd/agesa/hudson/spi.c | 18 ++---- src/southbridge/amd/cimx/sb800/spi.c | 19 ++---- src/southbridge/amd/sb700/spi.c | 32 ++++------ src/southbridge/intel/common/spi.c | 32 ++++------ src/southbridge/intel/fsp_rangeley/spi.c | 32 ++++------ 26 files changed, 521 insertions(+), 494 deletions(-) diff --git a/src/drivers/spi/Makefile.inc b/src/drivers/spi/Makefile.inc index 92baf62..c1bf307 100644 --- a/src/drivers/spi/Makefile.inc +++ b/src/drivers/spi/Makefile.inc @@ -7,6 +7,7 @@ ramstage-y += spiconsole.c smm-$(CONFIG_DEBUG_SMI) += spiconsole.c endif +bootblock-y += spi-generic.c bootblock-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c bootblock-$(CONFIG_SPI_FLASH) += spi_flash.c bootblock-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY) += boot_device_rw_nommap.c @@ -22,6 +23,7 @@ bootblock-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c bootblock-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c bootblock-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c +romstage-y += spi-generic.c romstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c romstage-$(CONFIG_SPI_FLASH) += spi_flash.c romstage-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY) += boot_device_rw_nommap.c @@ -37,6 +39,7 @@ romstage-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c romstage-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c romstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c +verstage-y += spi-generic.c verstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c verstage-$(CONFIG_SPI_FLASH) += spi_flash.c verstage-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY) += boot_device_rw_nommap.c @@ -52,6 +55,7 @@ verstage-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c verstage-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c verstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c +ramstage-y += spi-generic.c ramstage-$(CONFIG_COMMON_CBFS_SPI_WRAPPER) += cbfs_spi.c ramstage-$(CONFIG_SPI_FLASH) += spi_flash.c ramstage-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP) += boot_device_rw_nommap.c @@ -68,6 +72,7 @@ ramstage-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c ramstage-$(CONFIG_SPI_FRAM_RAMTRON) += ramtron.c ifeq ($(CONFIG_SPI_FLASH_SMM),y) +smm-y += spi-generic.c # SPI flash driver interface smm-$(CONFIG_SPI_FLASH) += spi_flash.c smm-$(CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP) += boot_device_rw_nommap.c diff --git a/src/drivers/spi/spi-generic.c b/src/drivers/spi/spi-generic.c new file mode 100644 index 0000000..7398ee9 --- /dev/null +++ b/src/drivers/spi/spi-generic.c @@ -0,0 +1,43 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <spi-generic.h> +#include <string.h> + +int spi_claim_bus(const struct spi_slave *slave) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + if (ctrlr && ctrlr->claim_bus) + return ctrlr->claim_bus(slave); + return 0; +} + +void spi_release_bus(const struct spi_slave *slave) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + if (ctrlr && ctrlr->release_bus) + ctrlr->release_bus(slave); +} + +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, + void *din, size_t bytesin) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + if (ctrlr && ctrlr->xfer) + return ctrlr->xfer(slave, dout, bytesout, din, bytesin); + + return -1; +} diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index c8b209d..b4a10af 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -21,15 +21,33 @@ /* Controller-specific definitions: */ +struct spi_ctrlr; + /*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * * bus: ID of the bus that the slave is attached to. * cs: ID of the chip select connected to the slave. + * ctrlr: Pointer to SPI controller structure. */ struct spi_slave { unsigned int bus; unsigned int cs; + const struct spi_ctrlr *ctrlr; +}; + +/*----------------------------------------------------------------------- + * Representation of a SPI contoller. + * + * claim_bus: Claim SPI bus and prepare for communication. + * release_bus: Release SPI bus. + * xfer: SPI transfer + */ +struct spi_ctrlr { + int (*claim_bus)(const struct spi_slave *slave); + void (*release_bus)(const struct spi_slave *slave); + int (*xfer)(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin); }; /*----------------------------------------------------------------------- diff --git a/src/soc/broadcom/cygnus/spi.c b/src/soc/broadcom/cygnus/spi.c index 810f2c2..e597efc 100644 --- a/src/soc/broadcom/cygnus/spi.c +++ b/src/soc/broadcom/cygnus/spi.c @@ -96,42 +96,6 @@ static struct qspi_priv *to_qspi_slave(const struct spi_slave *slave) return &qspi_slave; } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - struct qspi_priv *priv = &qspi_slave; - unsigned int spbr; - - slave->bus = bus; - slave->cs = cs; - - priv->max_hz = QSPI_MAX_HZ; - priv->spi_mode = QSPI_MODE; - priv->reg = (void *)(IPROC_QSPI_BASE); - priv->mspi_enabled = 0; - priv->bus_claimed = 0; - - /* MSPI: Basic hardware initialization */ - REG_WR(priv->reg + MSPI_SPCR1_LSB_REG, 0); - REG_WR(priv->reg + MSPI_SPCR1_MSB_REG, 0); - REG_WR(priv->reg + MSPI_NEWQP_REG, 0); - REG_WR(priv->reg + MSPI_ENDQP_REG, 0); - REG_WR(priv->reg + MSPI_SPCR2_REG, 0); - - /* MSPI: SCK configuration */ - spbr = (IPROC_QSPI_CLK - 1) / (2 * priv->max_hz) + 1; - REG_WR(priv->reg + MSPI_SPCR0_LSB_REG, - MAX(MIN(spbr, SPBR_MAX), SPBR_MIN)); - - /* MSPI: Mode configuration (8 bits by default) */ - priv->mspi_16bit = 0; - REG_WR(priv->reg + MSPI_SPCR0_MSB_REG, - 0x80 | /* Master */ - (8 << 2) | /* 8 bits per word */ - (priv->spi_mode & 3)); /* mode: CPOL / CPHA */ - - return 0; -} - static int mspi_enable(struct qspi_priv *priv) { struct stopwatch sw; @@ -156,7 +120,7 @@ static int mspi_enable(struct qspi_priv *priv) return 0; } -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { struct qspi_priv *priv = to_qspi_slave(slave); @@ -175,7 +139,7 @@ int spi_claim_bus(const struct spi_slave *slave) return 0; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct qspi_priv *priv = to_qspi_slave(slave); @@ -189,8 +153,8 @@ void spi_release_bus(const struct spi_slave *slave) #define RXRAM_8B(p, i) (REG_RD((p)->reg + MSPI_RXRAM_REG + \ ((((i) << 1) + 1) << 2)) & 0xff) -int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, - void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { struct qspi_priv *priv = to_qspi_slave(slave); const u8 *tx = (const u8 *)dout; @@ -311,6 +275,49 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, return 0; } +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + struct qspi_priv *priv = &qspi_slave; + unsigned int spbr; + + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + + priv->max_hz = QSPI_MAX_HZ; + priv->spi_mode = QSPI_MODE; + priv->reg = (void *)(IPROC_QSPI_BASE); + priv->mspi_enabled = 0; + priv->bus_claimed = 0; + + /* MSPI: Basic hardware initialization */ + REG_WR(priv->reg + MSPI_SPCR1_LSB_REG, 0); + REG_WR(priv->reg + MSPI_SPCR1_MSB_REG, 0); + REG_WR(priv->reg + MSPI_NEWQP_REG, 0); + REG_WR(priv->reg + MSPI_ENDQP_REG, 0); + REG_WR(priv->reg + MSPI_SPCR2_REG, 0); + + /* MSPI: SCK configuration */ + spbr = (IPROC_QSPI_CLK - 1) / (2 * priv->max_hz) + 1; + REG_WR(priv->reg + MSPI_SPCR0_LSB_REG, + MAX(MIN(spbr, SPBR_MAX), SPBR_MIN)); + + /* MSPI: Mode configuration (8 bits by default) */ + priv->mspi_16bit = 0; + REG_WR(priv->reg + MSPI_SPCR0_MSB_REG, + 0x80 | /* Master */ + (8 << 2) | /* 8 bits per word */ + (priv->spi_mode & 3)); /* mode: CPOL / CPHA */ + + return 0; +} + unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) { return min(65535, buf_len); diff --git a/src/soc/imgtec/pistachio/spi.c b/src/soc/imgtec/pistachio/spi.c index 86c452a..e956e46 100644 --- a/src/soc/imgtec/pistachio/spi.c +++ b/src/soc/imgtec/pistachio/spi.c @@ -421,53 +421,8 @@ void spi_init(void) memset(img_spi_slaves, 0, sizeof(img_spi_slaves)); } -/* Set up communications parameters for a SPI slave. */ -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - struct img_spi_slave *img_slave = NULL; - struct spim_device_parameters *device_parameters; - u32 base; - - switch (bus) { - case 0: - base = IMG_SPIM0_BASE_ADDRESS; - break; - case 1: - base = IMG_SPIM1_BASE_ADDRESS; - break; - default: - printk(BIOS_ERR, "%s: Error: unsupported bus.\n", - __func__); - return -1; - } - if (cs > SPIM_DEVICE4) { - printk(BIOS_ERR, "%s: Error: unsupported chipselect.\n", - __func__); - return -1; - } - - slave->bus = bus; - slave->cs = cs; - - img_slave = get_img_slave(slave); - device_parameters = &(img_slave->device_parameters); - - img_slave->base = base; - - device_parameters->bitrate = 64; - device_parameters->cs_setup = 0; - device_parameters->cs_hold = 0; - device_parameters->cs_delay = 0; - device_parameters->spi_mode = SPIM_MODE_0; - device_parameters->cs_idle_level = 1; - device_parameters->data_idle_level = 0; - img_slave->initialised = IMG_FALSE; - - return 0; -} - /* Claim the bus and prepare it for communication */ -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { int ret; struct img_spi_slave *img_slave; @@ -498,7 +453,7 @@ int spi_claim_bus(const struct spi_slave *slave) } /* Release the SPI bus */ -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct img_spi_slave *img_slave; @@ -540,8 +495,8 @@ static int do_spi_xfer(const struct spi_slave *slave, const void *dout, return spim_io(slave, &buff_0, (dout && din) ? &buff_1 : NULL); } -int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, - void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { unsigned int in_sz, out_sz; int ret; @@ -582,6 +537,58 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, return SPIM_OK; } +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +/* Set up communications parameters for a SPI slave. */ +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + struct img_spi_slave *img_slave = NULL; + struct spim_device_parameters *device_parameters; + u32 base; + + switch (bus) { + case 0: + base = IMG_SPIM0_BASE_ADDRESS; + break; + case 1: + base = IMG_SPIM1_BASE_ADDRESS; + break; + default: + printk(BIOS_ERR, "%s: Error: unsupported bus.\n", + __func__); + return -1; + } + if (cs > SPIM_DEVICE4) { + printk(BIOS_ERR, "%s: Error: unsupported chipselect.\n", + __func__); + return -1; + } + + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + + img_slave = get_img_slave(slave); + device_parameters = &(img_slave->device_parameters); + + img_slave->base = base; + + device_parameters->bitrate = 64; + device_parameters->cs_setup = 0; + device_parameters->cs_hold = 0; + device_parameters->cs_delay = 0; + device_parameters->spi_mode = SPIM_MODE_0; + device_parameters->cs_idle_level = 1; + device_parameters->data_idle_level = 0; + img_slave->initialised = IMG_FALSE; + + return 0; +} + unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) { return min(IMGTEC_SPI_MAX_TRANSFER_SIZE, buf_len); diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c index ca56702..8992fa5 100644 --- a/src/soc/intel/apollolake/spi.c +++ b/src/soc/intel/apollolake/spi.c @@ -184,13 +184,6 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return MIN(buf_len, SPIBAR_FDATA_FIFO_SIZE); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) -{ - printk(BIOS_DEBUG, "NOT IMPLEMENTED: %s() !!!\n", __func__); - return E_NOT_IMPLEMENTED; -} - /* * Write-protection status for BIOS region (BIOS_CONTROL register): * EISS/WPD bits 00 01 10 11 @@ -215,17 +208,6 @@ void spi_init(void) pci_write_config32(ctx->pci_dev, SPIBAR_BIOS_CONTROL, bios_ctl); } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* There's nothing we need to to here. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* No magic needed here. */ -} - static int nuclear_spi_erase(const struct spi_flash *flash, uint32_t offset, size_t len) { @@ -400,6 +382,7 @@ int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) slave->bus = bus; slave->cs = cs; + slave->ctrlr = NULL; return 0; } diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index b4f95aa..0f7b0c6 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -260,13 +260,6 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - static ich9_spi_regs *spi_regs(void) { device_t dev; @@ -308,17 +301,6 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - typedef struct spi_transaction { const uint8_t *out; uint32_t bytesout; @@ -480,8 +462,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; @@ -627,3 +609,15 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +} diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index 4236e6f..2a0ddf8 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -229,13 +229,6 @@ static void read_reg(void *src, void *value, uint32_t size) } } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - static ich9_spi_regs *spi_regs(void) { device_t dev; @@ -287,17 +280,6 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - typedef struct spi_transaction { const uint8_t *out; uint32_t bytesout; @@ -461,8 +443,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; @@ -611,3 +593,15 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +} diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index 5220970..d2ae943 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -259,13 +259,6 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - void spi_init(void) { uint8_t *rcrb; /* Root Complex Register Block */ @@ -304,17 +297,6 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - typedef struct spi_transaction { const uint8_t *out; uint32_t bytesout; @@ -476,8 +458,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; @@ -661,3 +643,15 @@ int spi_flash_protect(u32 start, u32 size) __func__, prr, start, end); return 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +} diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index 06b160c..997bd13 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -249,13 +249,6 @@ static void read_reg(const void *src, void *value, uint32_t size) } } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - static ich9_spi_regs *spi_regs(void) { device_t dev; @@ -288,17 +281,6 @@ void spi_init(void) cntlr.preop = &ich9_spi->preop; } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - typedef struct spi_transaction { const uint8_t *out; uint32_t bytesout; @@ -460,8 +442,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; @@ -607,3 +589,15 @@ spi_xfer_exit: return 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +} diff --git a/src/soc/intel/fsp_broadwell_de/spi.c b/src/soc/intel/fsp_broadwell_de/spi.c index 8af5686..5848966 100644 --- a/src/soc/intel/fsp_broadwell_de/spi.c +++ b/src/soc/intel/fsp_broadwell_de/spi.c @@ -259,13 +259,6 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave * slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - void spi_init(void) { uint8_t *rcrb; /* Root Complex Register Block */ @@ -303,17 +296,6 @@ void spi_init(void) pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - typedef struct spi_transaction { const uint8_t *out; uint32_t bytesout; @@ -475,8 +457,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; @@ -624,3 +606,15 @@ spi_xfer_exit: return 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +} diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c index 734d9d3..e0ac93d 100644 --- a/src/soc/intel/skylake/flash_controller.c +++ b/src/soc/intel/skylake/flash_controller.c @@ -151,13 +151,6 @@ static size_t spi_get_flash_size(pch_spi_regs *spi_bar) return size; } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) -{ - /* TODO: Define xfer for hardware sequencing. */ - return -1; -} - void spi_init(void) { uint8_t bios_cntl; @@ -170,17 +163,6 @@ void spi_init(void) pci_write_config_byte(dev, SPIBAR_BIOS_CNTL, bios_cntl); } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by PCH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by PCH automatically. */ -} - int pch_hwseq_erase(const struct spi_flash *flash, u32 offset, size_t len) { u32 start, end, erase_size; @@ -377,6 +359,7 @@ int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) slave->bus = bus; slave->cs = cs; + slave->ctrlr = NULL; return 0; } diff --git a/src/soc/marvell/armada38x/spi.c b/src/soc/marvell/armada38x/spi.c index 8f96867..25480e4 100644 --- a/src/soc/marvell/armada38x/spi.c +++ b/src/soc/marvell/armada38x/spi.c @@ -442,22 +442,14 @@ static int mrvl_spi_xfer(const struct spi_slave *slave, return 0; } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - mv_spi_sys_init(bus, cs, CONFIG_SF_DEFAULT_SPEED); - return 0; -} - -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { mv_spi_cs_set(slave->bus, slave->cs); mv_spi_cs_assert(slave->bus); return 0; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { mv_spi_cs_deassert(slave->bus); } @@ -467,11 +459,11 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -int spi_xfer(const struct spi_slave *slave, - const void *dout, - size_t out_bytes, - void *din, - size_t in_bytes) +static int spi_ctrlr_xfer(const struct spi_slave *slave, + const void *dout, + size_t out_bytes, + void *din, + size_t in_bytes) { int ret = -1; @@ -483,3 +475,18 @@ int spi_xfer(const struct spi_slave *slave, die("Unexpected condition in spi_xfer\n"); return ret; } + +static const spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + mv_spi_sys_init(bus, cs, CONFIG_SF_DEFAULT_SPEED); + return 0; +} diff --git a/src/soc/marvell/bg4cd/spi.c b/src/soc/marvell/bg4cd/spi.c index 54161bc..188a6bd 100644 --- a/src/soc/marvell/bg4cd/spi.c +++ b/src/soc/marvell/bg4cd/spi.c @@ -19,18 +19,3 @@ int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { return -1; } - -int spi_claim_bus(const struct spi_slave *slave) -{ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ -} - -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t out_bytes, void *din, size_t in_bytes) -{ - return 0; -} diff --git a/src/soc/mediatek/mt8173/spi.c b/src/soc/mediatek/mt8173/spi.c index d6bcc0b..53d5b8c 100644 --- a/src/soc/mediatek/mt8173/spi.c +++ b/src/soc/mediatek/mt8173/spi.c @@ -160,29 +160,7 @@ static void mtk_spi_dump_data(const char *name, const uint8_t *data, #endif } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - struct mtk_spi_bus *eslave; - - switch (bus) { - case CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS: - slave->bus = bus; - slave->cs = cs; - eslave = to_mtk_spi(slave); - assert(read32(&eslave->regs->spi_cfg0_reg) != 0); - spi_sw_reset(eslave->regs); - return 0; - case CONFIG_BOOT_DEVICE_SPI_FLASH_BUS: - slave->bus = bus; - slave->cs = cs; - return 0; - default: - die ("wrong bus number.\n"); - }; - return -1; -} - -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave); struct mtk_spi_regs *regs = mtk_slave->regs; @@ -269,8 +247,8 @@ error: return -1; } -int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, - void *din, size_t bytes_in) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytes_out, void *din, size_t bytes_in) { size_t min_size = 0; int ret; @@ -301,7 +279,7 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, return 0; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave); struct mtk_spi_regs *regs = mtk_slave->regs; @@ -310,3 +288,33 @@ void spi_release_bus(const struct spi_slave *slave) spi_sw_reset(regs); mtk_slave->state = MTK_SPI_IDLE; } + +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + struct mtk_spi_bus *eslave; + + slave->ctrlr = &spi_ctrlr; + + switch (bus) { + case CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS: + slave->bus = bus; + slave->cs = cs; + eslave = to_mtk_spi(slave); + assert(read32(&eslave->regs->spi_cfg0_reg) != 0); + spi_sw_reset(eslave->regs); + return 0; + case CONFIG_BOOT_DEVICE_SPI_FLASH_BUS: + slave->bus = bus; + slave->cs = cs; + return 0; + default: + die ("wrong bus number.\n"); + }; + return -1; +} diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index 0cb4865..5d8084f 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -209,7 +209,7 @@ static unsigned int tegra_spi_speed(unsigned int bus) return 50000000; } -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -232,7 +232,7 @@ int spi_claim_bus(const struct spi_slave *slave) return 0; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -719,8 +719,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t out_bytes, void *din, size_t in_bytes) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct tegra_spi_channel *spi = to_tegra_spi(slave->bus); u8 *out_buf = (u8 *)dout; @@ -798,6 +798,12 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return ret; } +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct tegra_spi_channel *channel = to_tegra_spi(bus); @@ -806,6 +812,7 @@ int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) slave->bus = channel->slave.bus; slave->cs = channel->slave.cs; + slave->ctrlr = &spi_ctrlr; return 0; } diff --git a/src/soc/nvidia/tegra210/spi.c b/src/soc/nvidia/tegra210/spi.c index 3a2dd17..2921355 100644 --- a/src/soc/nvidia/tegra210/spi.c +++ b/src/soc/nvidia/tegra210/spi.c @@ -208,7 +208,7 @@ static struct tegra_spi_channel * const to_tegra_spi(int bus) { return &tegra_spi_channels[bus - 1]; } -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -231,7 +231,7 @@ int spi_claim_bus(const struct spi_slave *slave) return 0; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -755,8 +755,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t out_bytes, void *din, size_t in_bytes) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct tegra_spi_channel *spi = to_tegra_spi(slave->bus); u8 *out_buf = (u8 *)dout; @@ -834,6 +834,12 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return ret; } +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct tegra_spi_channel *channel = to_tegra_spi(bus); @@ -842,6 +848,7 @@ int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) slave->cs = channel->slave.cs; slave->bus = channel->slave.bus; + slave->ctrlr = &spi_ctrlr; return 0; } diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c index cda3bea..6d044b3 100644 --- a/src/soc/qualcomm/ipq40xx/spi.c +++ b/src/soc/qualcomm/ipq40xx/spi.c @@ -226,45 +226,6 @@ static struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) return NULL; } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - struct ipq_spi_slave *ds = NULL; - int i; - - if ((bus < BLSP0_SPI) || (bus > BLSP1_SPI) - || ((bus == BLSP0_SPI) && (cs > 2)) - || ((bus == BLSP1_SPI) && (cs > 0))) { - printk(BIOS_ERR, - "SPI error: unsupported bus %d (Supported busses 0, 1 and 2) " - "or chipselect\n", bus); - return -1; - } - - for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { - if (spi_slave_pool[i].allocated) - continue; - ds = spi_slave_pool + i; - - ds->slave.bus = slave->bus = bus; - ds->slave.cs = slave->cs = cs; - ds->regs = &spi_reg[bus]; - - /* - * TODO(vbendeb): - * hardcoded frequency and mode - we might need to find a way - * to configure this - */ - ds->freq = 10000000; - ds->mode = SPI_MODE3; - ds->allocated = 1; - - return 0; - } - - printk(BIOS_ERR, "SPI error: all %d pools busy\n", i); - return -1; -} - /* * BLSP QUPn SPI Hardware Initialisation */ @@ -340,7 +301,7 @@ static int spi_hw_init(struct ipq_spi_slave *ds) return SUCCESS; } -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); unsigned int ret; @@ -352,7 +313,7 @@ int spi_claim_bus(const struct spi_slave *slave) return SUCCESS; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); @@ -653,8 +614,8 @@ static int blsp_spi_write(struct ipq_spi_slave *ds, u8 *cmd_buffer, * This function is invoked with either tx_buf or rx_buf. * Calling this function with both null does a chip select change. */ -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t out_bytes, void *din, size_t in_bytes) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct ipq_spi_slave *ds = to_ipq_spi(slave); u8 *txp = (u8 *)dout; @@ -690,3 +651,49 @@ out: return ret; } + +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + struct ipq_spi_slave *ds = NULL; + int i; + + if ((bus < BLSP0_SPI) || (bus > BLSP1_SPI) + || ((bus == BLSP0_SPI) && (cs > 2)) + || ((bus == BLSP1_SPI) && (cs > 0))) { + printk(BIOS_ERR, + "SPI error: unsupported bus %d (Supported busses 0, 1 and 2) " + "or chipselect\n", bus); + return -1; + } + + for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { + if (spi_slave_pool[i].allocated) + continue; + ds = spi_slave_pool + i; + + ds->slave.bus = slave->bus = bus; + ds->slave.cs = slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + ds->regs = &spi_reg[bus]; + + /* + * TODO(vbendeb): + * hardcoded frequency and mode - we might need to find a way + * to configure this + */ + ds->freq = 10000000; + ds->mode = SPI_MODE3; + ds->allocated = 1; + + return 0; + } + + printk(BIOS_ERR, "SPI error: all %d pools busy\n", i); + return -1; +} diff --git a/src/soc/qualcomm/ipq806x/spi.c b/src/soc/qualcomm/ipq806x/spi.c index 81dc508..e907729 100644 --- a/src/soc/qualcomm/ipq806x/spi.c +++ b/src/soc/qualcomm/ipq806x/spi.c @@ -518,49 +518,6 @@ static struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) return NULL; } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - struct ipq_spi_slave *ds = NULL; - int i; - - /* - * IPQ GSBI (Generic Serial Bus Interface) supports SPI Flash - * on different GSBI5, GSBI6 and GSBI7 - * with different number of chip selects (CS, channels): - */ - if ((bus < GSBI5_SPI) || (bus > GSBI7_SPI) - || ((bus == GSBI5_SPI) && (cs > 3)) - || ((bus == GSBI6_SPI) && (cs > 0)) - || ((bus == GSBI7_SPI) && (cs > 0))) { - printk(BIOS_ERR, "SPI error: unsupported bus %d " - "(Supported busses 0,1 and 2) or chipselect\n", bus); - } - - for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { - if (spi_slave_pool[i].allocated) - continue; - ds = spi_slave_pool + i; - - ds->slave.bus = slave->bus = bus; - ds->slave.cs = slave->cs = cs; - ds->regs = &spi_reg[bus]; - - /* - * TODO(vbendeb): - * hardcoded frequency and mode - we might need to find a way - * to configure this - */ - ds->freq = 10000000; - ds->mode = GSBI_SPI_MODE_0; - ds->allocated = 1; - - return 0; - } - - printk(BIOS_ERR, "SPI error: all %d pools busy\n", i); - return -1; -} - /* * GSBIn SPI Hardware Initialisation */ @@ -638,7 +595,7 @@ static int spi_hw_init(struct ipq_spi_slave *ds) return SUCCESS; } -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); unsigned int ret; @@ -661,7 +618,7 @@ int spi_claim_bus(const struct spi_slave *slave) return SUCCESS; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); @@ -731,8 +688,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(MAX_PACKET_COUNT, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t out_bytes, void *din, size_t in_bytes) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { int ret; struct ipq_spi_slave *ds = to_ipq_spi(slave); @@ -799,3 +756,53 @@ out: return ret; } + +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + struct ipq_spi_slave *ds = NULL; + int i; + + /* + * IPQ GSBI (Generic Serial Bus Interface) supports SPI Flash + * on different GSBI5, GSBI6 and GSBI7 + * with different number of chip selects (CS, channels): + */ + if ((bus < GSBI5_SPI) || (bus > GSBI7_SPI) + || ((bus == GSBI5_SPI) && (cs > 3)) + || ((bus == GSBI6_SPI) && (cs > 0)) + || ((bus == GSBI7_SPI) && (cs > 0))) { + printk(BIOS_ERR, "SPI error: unsupported bus %d " + "(Supported busses 0,1 and 2) or chipselect\n", bus); + } + + for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { + if (spi_slave_pool[i].allocated) + continue; + ds = spi_slave_pool + i; + + ds->slave.bus = slave->bus = bus; + ds->slave.cs = slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + ds->regs = &spi_reg[bus]; + + /* + * TODO(vbendeb): + * hardcoded frequency and mode - we might need to find a way + * to configure this + */ + ds->freq = 10000000; + ds->mode = GSBI_SPI_MODE_0; + ds->allocated = 1; + + return 0; + } + + printk(BIOS_ERR, "SPI error: all %d pools busy\n", i); + return -1; +} diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 85597f2..16143b5 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -67,16 +67,6 @@ static struct rockchip_spi_slave *to_rockchip_spi(const struct spi_slave *slave) return &rockchip_spi_slaves[slave->bus]; } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - assert(bus < ARRAY_SIZE(rockchip_spi_slaves)); - - slave->bus = bus; - slave->cs = cs; - - return 0; -} - static void spi_cs_activate(const struct spi_slave *slave) { struct rockchip_spi *regs = to_rockchip_spi(slave)->regs; @@ -155,13 +145,13 @@ void rockchip_spi_set_sample_delay(unsigned int bus, unsigned int delay_ns) rsd << SPI_RXDSD_OFFSET); } -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { spi_cs_activate(slave); return 0; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { spi_cs_deactivate(slave); } @@ -266,8 +256,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(65535, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, - size_t bytes_out, void *din, size_t bytes_in) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytes_out, void *din, size_t bytes_in) { struct rockchip_spi *regs = to_rockchip_spi(slave)->regs; int ret = 0; @@ -337,3 +327,20 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, rockchip_spi_enable_chip(regs, 0); return ret < 0 ? ret : 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + assert(bus < ARRAY_SIZE(rockchip_spi_slaves)); + + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + + return 0; +} diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c index 5dbe024..f17566e 100644 --- a/src/soc/samsung/exynos5420/spi.c +++ b/src/soc/samsung/exynos5420/spi.c @@ -117,23 +117,7 @@ static void exynos_spi_init(struct exynos_spi *regs) spi_sw_reset(regs, 1); } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - ASSERT(bus >= 0 && bus < 3); - struct exynos_spi_slave *eslave; - - slave->bus = bus; - slave->cs = cs; - - eslave = to_exynos_spi(slave); - if (!eslave->initialized) { - exynos_spi_init(eslave->regs); - eslave->initialized = 1; - } - return 0; -} - -int spi_claim_bus(const struct spi_slave *slave) +static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { struct exynos_spi *regs = to_exynos_spi(slave)->regs; // TODO(hungte) Add some delay if too many transactions happen at once. @@ -193,7 +177,7 @@ static void spi_transfer(struct exynos_spi *regs, void *in, const void *out, } } -int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, void *din, size_t bytes_in) { struct exynos_spi *regs = to_exynos_spi(slave)->regs; @@ -218,12 +202,35 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, return 0; } -void spi_release_bus(const struct spi_slave *slave) +static void spi_ctrlr_release_bus(const struct spi_slave *slave) { struct exynos_spi *regs = to_exynos_spi(slave)->regs; setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); } +static const struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_ctrlr_claim_bus, + .release_bus = spi_ctrlr_release_bus, + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + ASSERT(bus >= 0 && bus < 3); + struct exynos_spi_slave *eslave; + + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + + eslave = to_exynos_spi(slave); + if (!eslave->initialized) { + exynos_spi_init(eslave->regs); + eslave->initialized = 1; + } + return 0; +} + static int exynos_spi_read(struct spi_slave *slave, void *dest, uint32_t len, uint32_t off) { diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c index a8b3b2a..8a4adfb 100644 --- a/src/southbridge/amd/agesa/hudson/spi.c +++ b/src/southbridge/amd/agesa/hudson/spi.c @@ -90,7 +90,7 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin) { /* First byte is cmd which can not being sent through FIFO. */ @@ -147,17 +147,6 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return 0; } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Nothing is required. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Nothing is required. */ -} - int chipset_volatile_group_begin(const struct spi_flash *flash) { if (!IS_ENABLED (CONFIG_HUDSON_IMC_FWM)) @@ -176,9 +165,14 @@ int chipset_volatile_group_end(const struct spi_flash *flash) return 0; } +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { slave->bus = bus; slave->cs = cs; + slave->ctrlr = &spi_ctrlr; return 0; } diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c index d331060..edf192a 100644 --- a/src/southbridge/amd/cimx/sb800/spi.c +++ b/src/southbridge/amd/cimx/sb800/spi.c @@ -59,7 +59,7 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin) { /* First byte is cmd which can not being sent through FIFO. */ @@ -138,18 +138,6 @@ static void ImcWakeup(void) WaitForEcLDN9MailboxCmdAck(); } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Nothing is required. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Nothing is required. */ - return; -} - int chipset_volatile_group_begin(const struct spi_flash *flash) { if (!IS_ENABLED(CONFIG_SB800_IMC_FWM)) @@ -168,9 +156,14 @@ int chipset_volatile_group_end(const struct spi_flash *flash) return 0; } +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { slave->bus = bus; slave->cs = cs; + slave->ctrlr = &spi_ctrlr; return 0; } diff --git a/src/southbridge/amd/sb700/spi.c b/src/southbridge/amd/sb700/spi.c index fca401c..2e16ca8 100644 --- a/src/southbridge/amd/sb700/spi.c +++ b/src/southbridge/amd/sb700/spi.c @@ -65,25 +65,7 @@ static void execute_command(void) (read8((void *)(spibar+3)) & 0x80)); } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled internally by the SB700 */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled internally by the SB700 */ -} - -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - -int spi_xfer(const struct spi_slave *slave, const void *dout, +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin) { /* First byte is cmd which cannot be sent through the FIFO. */ @@ -135,3 +117,15 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +} diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 7e0cc20..42a2a74 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -285,13 +285,6 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - void spi_init(void) { uint8_t *rcrb; /* Root Complex Register Block */ @@ -348,17 +341,6 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - typedef struct spi_transaction { const uint8_t *out; uint32_t bytesout; @@ -527,7 +509,7 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin) { uint16_t control; @@ -675,6 +657,18 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return 0; } +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +} + /* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ static void ich_hwseq_set_addr(uint32_t addr) { diff --git a/src/southbridge/intel/fsp_rangeley/spi.c b/src/southbridge/intel/fsp_rangeley/spi.c index de676a9..acdb072 100644 --- a/src/southbridge/intel/fsp_rangeley/spi.c +++ b/src/southbridge/intel/fsp_rangeley/spi.c @@ -322,13 +322,6 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) -{ - slave->bus = bus; - slave->cs = cs; - return 0; -} - /* * Check if this device ID matches one of supported Intel SOC devices. * @@ -420,17 +413,6 @@ void spi_init(void) } } -int spi_claim_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(const struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - typedef struct spi_transaction { const uint8_t *out; uint32_t bytesout; @@ -592,7 +574,7 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(const struct spi_slave *slave, const void *dout, +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin) { uint16_t control; @@ -739,3 +721,15 @@ spi_xfer_exit: return 0; } + +static const struct spi_ctrlr spi_ctrlr = { + .xfer = spi_ctrlr_xfer, +}; + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + slave->bus = bus; + slave->cs = cs; + slave->ctrlr = &spi_ctrlr; + return 0; +}
1
0
0
0
Patch set updated for coreboot: spi: Pass pointer to spi_slave structure in spi_setup_slave
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17683
-gerrit commit 11b3f2a611787ae34abc23e9ae91b9e2e8e1ea60 Author: Furquan Shaikh <furquan(a)chromium.org> Date: Thu Dec 1 01:02:44 2016 -0800 spi: Pass pointer to spi_slave structure in spi_setup_slave For spi_setup_slave, instead of making the platform driver return a pointer to spi_slave structure, pass in a structure pointer that can be filled in by the driver as required. This removes the need for platform drivers to maintain a slave structure in data/CAR section. BUG=chrome-os-partner:59832 BRANCH=None TEST=Compiles successfully Change-Id: Ia15a4f88ef4dcfdf616bb1c22261e7cb642a7573 Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- src/drivers/spi/spi_flash.c | 11 ++++--- src/drivers/spi/tpm/tis.c | 10 +++++-- src/drivers/spi/tpm/tpm.c | 18 ++++++------ src/ec/google/chromeec/ec_spi.c | 14 +++++---- src/include/spi-generic.h | 7 +++-- src/soc/broadcom/cygnus/spi.c | 18 ++++++------ src/soc/imgtec/pistachio/spi.c | 46 ++++++++++++++++++------------ src/soc/intel/apollolake/spi.c | 9 ++---- src/soc/intel/baytrail/spi.c | 13 ++------- src/soc/intel/braswell/spi.c | 13 ++------- src/soc/intel/broadwell/spi.c | 13 ++------- src/soc/intel/fsp_baytrail/spi.c | 13 ++------- src/soc/intel/fsp_broadwell_de/spi.c | 13 ++------- src/soc/intel/skylake/flash_controller.c | 9 ++---- src/soc/marvell/armada38x/spi.c | 8 ++---- src/soc/marvell/bg4cd/spi.c | 4 +-- src/soc/mediatek/mt8173/spi.c | 22 +++++++------- src/soc/nvidia/tegra124/spi.c | 9 ++++-- src/soc/nvidia/tegra210/spi.c | 9 ++++-- src/soc/qualcomm/ipq40xx/include/soc/spi.h | 5 ---- src/soc/qualcomm/ipq40xx/spi.c | 34 +++++++++++++++++----- src/soc/qualcomm/ipq806x/include/soc/spi.h | 5 ---- src/soc/qualcomm/ipq806x/spi.c | 32 +++++++++++++++++---- src/soc/rockchip/common/spi.c | 20 ++++++------- src/soc/samsung/exynos5420/spi.c | 13 ++++++--- src/southbridge/amd/agesa/hudson/spi.c | 14 +++------ src/southbridge/amd/cimx/sb800/spi.c | 14 +++------ src/southbridge/amd/sb700/spi.c | 14 +++------ src/southbridge/intel/common/spi.c | 13 ++------- src/southbridge/intel/fsp_rangeley/spi.c | 13 ++------- 30 files changed, 201 insertions(+), 235 deletions(-) diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index b6d535a..b51a1e5 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -343,25 +343,24 @@ static struct spi_flash *__spi_flash_probe(struct spi_slave *spi) struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs) { - struct spi_slave *spi; + struct spi_slave spi; struct spi_flash *flash; - spi = spi_setup_slave(bus, cs); - if (!spi) { + if (spi_setup_slave(bus, cs, &spi)) { printk(BIOS_WARNING, "SF: Failed to set up slave\n"); return NULL; } /* Try special programmer probe if any (without force). */ - flash = spi_flash_programmer_probe(spi, 0); + flash = spi_flash_programmer_probe(&spi, 0); /* If flash is not found, try generic spi flash probe. */ if (!flash) - flash = __spi_flash_probe(spi); + flash = __spi_flash_probe(&spi); /* If flash is not yet found, force special programmer probe if any. */ if (!flash) - flash = spi_flash_programmer_probe(spi, 1); + flash = spi_flash_programmer_probe(&spi, 1); /* Give up -- nothing more to try if flash is not found. */ if (!flash) { diff --git a/src/drivers/spi/tpm/tis.c b/src/drivers/spi/tpm/tis.c index 055525b..d3c727c 100644 --- a/src/drivers/spi/tpm/tis.c +++ b/src/drivers/spi/tpm/tis.c @@ -58,10 +58,16 @@ int tis_close(void) int tis_init(void) { + struct spi_slave spi; struct tpm2_info info; - if (tpm2_init(spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS, - CONFIG_DRIVER_TPM_SPI_CHIP))) { + if (spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS, + CONFIG_DRIVER_TPM_SPI_CHIP, &spi)) { + printk(BIOS_ERR, "Failed to setup TPM SPI slave\n"); + return -1; + } + + if (tpm2_init(&spi)) { printk(BIOS_ERR, "Failed to initialize TPM SPI interface\n"); return -1; } diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c index d364cb9..5abfc45 100644 --- a/src/drivers/spi/tpm/tpm.c +++ b/src/drivers/spi/tpm/tpm.c @@ -36,7 +36,7 @@ /* SPI Interface descriptor used by the driver. */ struct tpm_spi_if { - struct spi_slave *slave; + struct spi_slave slave; int (*cs_assert)(const struct spi_slave *slave); void (*cs_deassert)(const struct spi_slave *slave); int (*xfer)(const struct spi_slave *slave, const void *dout, @@ -130,7 +130,7 @@ static void start_transaction(int read_write, size_t bytes, unsigned addr) header.body[i + 1] = (addr >> (8 * (2 - i))) & 0xff; /* CS assert wakes up the slave. */ - tpm_if.cs_assert(tpm_if.slave); + tpm_if.cs_assert(&tpm_if.slave); /* * The TCG TPM over SPI specification introduces the notion of SPI @@ -157,11 +157,11 @@ static void start_transaction(int read_write, size_t bytes, unsigned addr) * to require to stall the master, this would present an issue. *
crosbug.com/p/52132
has been opened to track this. */ - tpm_if.xfer(tpm_if.slave, header.body, sizeof(header.body), NULL, 0); + tpm_if.xfer(&tpm_if.slave, header.body, sizeof(header.body), NULL, 0); /* Now poll the bus until TPM removes the stall bit. */ do { - tpm_if.xfer(tpm_if.slave, NULL, 0, &byte, 1); + tpm_if.xfer(&tpm_if.slave, NULL, 0, &byte, 1); } while (!(byte & 1)); } @@ -227,7 +227,7 @@ static void trace_dump(const char *prefix, uint32_t reg, */ static void write_bytes(const void *buffer, size_t bytes) { - tpm_if.xfer(tpm_if.slave, buffer, bytes, NULL, 0); + tpm_if.xfer(&tpm_if.slave, buffer, bytes, NULL, 0); } /* @@ -236,7 +236,7 @@ static void write_bytes(const void *buffer, size_t bytes) */ static void read_bytes(void *buffer, size_t bytes) { - tpm_if.xfer(tpm_if.slave, NULL, 0, buffer, bytes); + tpm_if.xfer(&tpm_if.slave, NULL, 0, buffer, bytes); } /* @@ -251,7 +251,7 @@ static int tpm2_write_reg(unsigned reg_number, const void *buffer, size_t bytes) trace_dump("W", reg_number, bytes, buffer, 0); start_transaction(false, bytes, reg_number); write_bytes(buffer, bytes); - tpm_if.cs_deassert(tpm_if.slave); + tpm_if.cs_deassert(&tpm_if.slave); return 1; } @@ -266,7 +266,7 @@ static int tpm2_read_reg(unsigned reg_number, void *buffer, size_t bytes) { start_transaction(true, bytes, reg_number); read_bytes(buffer, bytes); - tpm_if.cs_deassert(tpm_if.slave); + tpm_if.cs_deassert(&tpm_if.slave); trace_dump("R", reg_number, bytes, buffer, 0); return 1; } @@ -303,7 +303,7 @@ int tpm2_init(struct spi_slave *spi_if) uint32_t did_vid, status; uint8_t cmd; - tpm_if.slave = spi_if; + memcpy(&tpm_if.slave, spi_if, sizeof(*spi_if)); tpm2_read_reg(TPM_DID_VID_REG, &did_vid, sizeof(did_vid)); diff --git a/src/ec/google/chromeec/ec_spi.c b/src/ec/google/chromeec/ec_spi.c index a0049c6..810979e 100644 --- a/src/ec/google/chromeec/ec_spi.c +++ b/src/ec/google/chromeec/ec_spi.c @@ -101,13 +101,17 @@ out: int google_chromeec_command(struct chromeec_command *cec_command) { - static struct spi_slave *slave = NULL; - if (!slave) { - slave = spi_setup_slave(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, - CONFIG_EC_GOOGLE_CHROMEEC_SPI_CHIP); + static int done = 0; + static struct spi_slave slave; + + if (!done) { + if (spi_setup_slave(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, + CONFIG_EC_GOOGLE_CHROMEEC_SPI_CHIP, &slave)) + return -1; stopwatch_init(&cs_cooldown_sw); + done = 1; } - return crosec_command_proto(cec_command, crosec_spi_io, slave); + return crosec_command_proto(cec_command, crosec_spi_io, &slave); } #ifndef __PRE_RAM__ diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index 7c53611..c8b209d 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -48,11 +48,12 @@ void spi_init(void); * * bus: Bus ID of the slave chip. * cs: Chip select ID of the slave chip on the specified bus. + * slave: Pointer to slave structure that needs to be initialized. * - * Returns: A spi_slave reference that can be used in subsequent SPI - * calls, or NULL if one or more of the parameters are not supported. + * Returns: + * 0 on success, -1 on error */ -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs); +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave); /*----------------------------------------------------------------------- * Claim the bus and prepare it for communication with a given slave. diff --git a/src/soc/broadcom/cygnus/spi.c b/src/soc/broadcom/cygnus/spi.c index 13b6976..810f2c2 100644 --- a/src/soc/broadcom/cygnus/spi.c +++ b/src/soc/broadcom/cygnus/spi.c @@ -76,9 +76,6 @@ /* QSPI private data */ struct qspi_priv { - /* Slave entry */ - struct spi_slave slave; - /* Specified SPI parameters */ unsigned int max_hz; unsigned int spi_mode; @@ -94,16 +91,19 @@ struct qspi_priv { static struct qspi_priv qspi_slave; -/* Macro to get the private data */ -#define to_qspi_slave(s) container_of(s, struct qspi_priv, slave) +static struct qspi_priv *to_qspi_slave(const struct spi_slave *slave) +{ + return &qspi_slave; +} -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct qspi_priv *priv = &qspi_slave; unsigned int spbr; - priv->slave.bus = bus; - priv->slave.cs = cs; + slave->bus = bus; + slave->cs = cs; + priv->max_hz = QSPI_MAX_HZ; priv->spi_mode = QSPI_MODE; priv->reg = (void *)(IPROC_QSPI_BASE); @@ -129,7 +129,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) (8 << 2) | /* 8 bits per word */ (priv->spi_mode & 3)); /* mode: CPOL / CPHA */ - return &priv->slave; + return 0; } static int mspi_enable(struct qspi_priv *priv) diff --git a/src/soc/imgtec/pistachio/spi.c b/src/soc/imgtec/pistachio/spi.c index 307aec9..86c452a 100644 --- a/src/soc/imgtec/pistachio/spi.c +++ b/src/soc/imgtec/pistachio/spi.c @@ -30,7 +30,6 @@ #define IMGTEC_SPI_MAX_TRANSFER_SIZE ((1 << 16) - 1) struct img_spi_slave { - struct spi_slave slave; /* SPIM instance device parameters */ struct spim_device_parameters device_parameters; /* SPIM instance base address */ @@ -59,13 +58,20 @@ static int wait_status(u32 reg, u32 shift) return SPIM_OK; } +static struct img_spi_slave *get_img_slave(const struct spi_slave *slave) +{ + return img_spi_slaves + slave->bus * SPIM_NUM_PORTS_PER_BLOCK + + slave->cs; +} + /* Transmitter function. Fills TX FIFO with data before enabling SPIM */ static int transmitdata(const struct spi_slave *slave, u8 *buffer, u32 size) { u32 blocksize, base, write_data; int ret; + struct img_spi_slave *img_slave = get_img_slave(slave); - base = container_of(slave, struct img_spi_slave, slave)->base; + base = img_slave->base; while (size) { /* Wait until FIFO empty */ write32(base + SPFI_INT_CLEAR_REG_OFFSET, SPFI_SDE_MASK); @@ -101,8 +107,9 @@ static int receivedata(const struct spi_slave *slave, u8 *buffer, u32 size) { u32 read_data, base; int ret; + struct img_spi_slave *img_slave = get_img_slave(slave); - base = container_of(slave, struct img_spi_slave, slave)->base; + base = img_slave->base; /* * Do 32bit reads first. Clear status GDEX32BIT here so that the first * status reg. read gets the actual bit state @@ -145,10 +152,10 @@ static void setparams(const struct spi_slave *slave, u32 port, struct spim_device_parameters *params) { u32 spim_parameters, port_state, base; + struct img_spi_slave *img_slave = get_img_slave(slave); + base = img_slave->base; spim_parameters = 0; - - base = container_of(slave, struct img_spi_slave, slave)->base; port_state = read32(base + SPFI_PORT_STATE_REG_OFFSET); port_state &= ~((SPIM_PORT0_MASK>>port)|SPFI_PORT_SELECT_MASK); port_state |= params->cs_idle_level<<(SPIM_CS0_IDLE_SHIFT-port); @@ -250,7 +257,9 @@ static u32 control_reg_setup(struct spim_buffer *first, static int check_buffers(const struct spi_slave *slave, struct spim_buffer *first, struct spim_buffer *second){ - if (!(container_of(slave, struct img_spi_slave, slave)->initialised)) + struct img_spi_slave *img_slave = get_img_slave(slave); + + if (!(img_slave->initialised)) return -SPIM_API_NOT_INITIALISED; /* * First operation must always be defined @@ -331,8 +340,9 @@ static int spim_io(const struct spi_slave *slave, struct spim_buffer *first, u32 reg, base; int i, trans_count, ret; struct spim_buffer *transaction[2]; + struct img_spi_slave *img_slave = get_img_slave(slave); - base = container_of(slave, struct img_spi_slave, slave)->base; + base = img_slave->base; ret = check_buffers(slave, first, second); if (ret) @@ -412,11 +422,9 @@ void spi_init(void) } /* Set up communications parameters for a SPI slave. */ -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - struct img_spi_slave *img_slave = NULL; - struct spi_slave *slave; struct spim_device_parameters *device_parameters; u32 base; @@ -430,21 +438,21 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) default: printk(BIOS_ERR, "%s: Error: unsupported bus.\n", __func__); - return NULL; + return -1; } if (cs > SPIM_DEVICE4) { printk(BIOS_ERR, "%s: Error: unsupported chipselect.\n", __func__); - return NULL; + return -1; } - img_slave = img_spi_slaves + bus * SPIM_NUM_PORTS_PER_BLOCK + cs; - slave = &(img_slave->slave); + slave->bus = bus; + slave->cs = cs; + + img_slave = get_img_slave(slave); device_parameters = &(img_slave->device_parameters); img_slave->base = base; - slave->bus = bus; - slave->cs = cs; device_parameters->bitrate = 64; device_parameters->cs_setup = 0; @@ -455,7 +463,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) device_parameters->data_idle_level = 0; img_slave->initialised = IMG_FALSE; - return slave; + return 0; } /* Claim the bus and prepare it for communication */ @@ -469,7 +477,7 @@ int spi_claim_bus(const struct spi_slave *slave) __func__); return -SPIM_API_NOT_INITIALISED; } - img_slave = container_of(slave, struct img_spi_slave, slave); + img_slave = get_img_slave(slave); if (img_slave->initialised) return SPIM_OK; /* Check device parameters */ @@ -499,7 +507,7 @@ void spi_release_bus(const struct spi_slave *slave) __func__); return; } - img_slave = container_of(slave, struct img_spi_slave, slave); + img_slave = get_img_slave(slave); img_slave->initialised = IMG_FALSE; /* Soft reset peripheral internals */ write32(img_slave->base + SPFI_CONTROL_REG_OFFSET, diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c index 6e873f4..ca56702 100644 --- a/src/soc/intel/apollolake/spi.c +++ b/src/soc/intel/apollolake/spi.c @@ -344,7 +344,6 @@ static int nuclear_spi_status(const struct spi_flash *flash, uint8_t *reg) return ret; } -static struct spi_slave boot_spi CAR_GLOBAL; static struct spi_flash boot_flash CAR_GLOBAL; /* @@ -391,20 +390,18 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) return flash; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { BOILERPLATE_CREATE_CTX(ctx); /* This is special hardware. We expect bus 0 and CS line 0 here. */ if ((bus != 0) || (cs != 0)) - return NULL; - - struct spi_slave *slave = car_get_var_ptr(&boot_spi); + return -1; slave->bus = bus; slave->cs = cs; - return slave; + return 0; } int spi_read_status(uint8_t *status) diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index 13f8806..b4f95aa 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -260,20 +260,11 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - slave->bus = bus; slave->cs = cs; - return slave; + return 0; } static ich9_spi_regs *spi_regs(void) diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index 34e031b..4236e6f 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -229,20 +229,11 @@ static void read_reg(void *src, void *value, uint32_t size) } } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_ERR, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - slave->bus = bus; slave->cs = cs; - return slave; + return 0; } static ich9_spi_regs *spi_regs(void) diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index 6aa7dd3..5220970 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -259,20 +259,11 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - slave->bus = bus; slave->cs = cs; - return slave; + return 0; } void spi_init(void) diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index 232366c..06b160c 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -249,20 +249,11 @@ static void read_reg(const void *src, void *value, uint32_t size) } } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - slave->bus = bus; slave->cs = cs; - return slave; + return 0; } static ich9_spi_regs *spi_regs(void) diff --git a/src/soc/intel/fsp_broadwell_de/spi.c b/src/soc/intel/fsp_broadwell_de/spi.c index c38fbce..8af5686 100644 --- a/src/soc/intel/fsp_broadwell_de/spi.c +++ b/src/soc/intel/fsp_broadwell_de/spi.c @@ -259,20 +259,11 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave * slave) { - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - slave->bus = bus; slave->cs = cs; - return slave; + return 0; } void spi_init(void) diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c index 8aee796..734d9d3 100644 --- a/src/soc/intel/skylake/flash_controller.c +++ b/src/soc/intel/skylake/flash_controller.c @@ -342,7 +342,6 @@ int pch_hwseq_read_status(const struct spi_flash *flash, u8 *reg) return 0; } -static struct spi_slave boot_spi CAR_GLOBAL; static struct spi_flash boot_flash CAR_GLOBAL; struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) @@ -370,18 +369,16 @@ struct spi_flash *spi_flash_programmer_probe(struct spi_slave *spi, int force) return flash; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { /* This is special hardware. We expect bus 0 and CS line 0 here. */ if ((bus != 0) || (cs != 0)) - return NULL; - - struct spi_slave *slave = car_get_var_ptr(&boot_spi); + return -1; slave->bus = bus; slave->cs = cs; - return slave; + return 0; } int spi_flash_get_fpr_info(struct fpr_info *info) diff --git a/src/soc/marvell/armada38x/spi.c b/src/soc/marvell/armada38x/spi.c index af0a279..8f96867 100644 --- a/src/soc/marvell/armada38x/spi.c +++ b/src/soc/marvell/armada38x/spi.c @@ -153,8 +153,6 @@ static MV_SPI_TYPE_INFO spi_types[] = { {.en16_bit = MV_TRUE, param define end *******************************************************************************/ -static struct spi_slave s_spi; - static int mv_spi_baud_rate_set(unsigned char spi_id, unsigned int serial_baud_rate); static void mv_spi_cs_deassert(unsigned char spi_id); @@ -444,14 +442,12 @@ static int mrvl_spi_xfer(const struct spi_slave *slave, return 0; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - struct spi_slave *slave = &s_spi; - slave->bus = bus; slave->cs = cs; mv_spi_sys_init(bus, cs, CONFIG_SF_DEFAULT_SPEED); - return slave; + return 0; } int spi_claim_bus(const struct spi_slave *slave) diff --git a/src/soc/marvell/bg4cd/spi.c b/src/soc/marvell/bg4cd/spi.c index 9a999b0..54161bc 100644 --- a/src/soc/marvell/bg4cd/spi.c +++ b/src/soc/marvell/bg4cd/spi.c @@ -15,9 +15,9 @@ #include <stddef.h> #include <spi-generic.h> -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - return NULL; + return -1; } int spi_claim_bus(const struct spi_slave *slave) diff --git a/src/soc/mediatek/mt8173/spi.c b/src/soc/mediatek/mt8173/spi.c index f60de6c..d6bcc0b 100644 --- a/src/soc/mediatek/mt8173/spi.c +++ b/src/soc/mediatek/mt8173/spi.c @@ -47,9 +47,6 @@ enum { static struct mtk_spi_bus spi_bus[1] = { { - .slave = { - .bus = 0, - }, .regs = (void *)SPI_BASE, .state = MTK_SPI_IDLE, } @@ -57,7 +54,8 @@ static struct mtk_spi_bus spi_bus[1] = { static inline struct mtk_spi_bus *to_mtk_spi(const struct spi_slave *slave) { - return container_of(slave, struct mtk_spi_bus, slave); + assert(slave->bus < ARRAY_SIZE(spi_bus)); + return &spi_bus[slave->bus]; } static void spi_sw_reset(struct mtk_spi_regs *regs) @@ -162,24 +160,26 @@ static void mtk_spi_dump_data(const char *name, const uint8_t *data, #endif } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct mtk_spi_bus *eslave; - static struct spi_slave slave; switch (bus) { case CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS: - eslave = &spi_bus[bus]; + slave->bus = bus; + slave->cs = cs; + eslave = to_mtk_spi(slave); assert(read32(&eslave->regs->spi_cfg0_reg) != 0); spi_sw_reset(eslave->regs); - return &eslave->slave; + return 0; case CONFIG_BOOT_DEVICE_SPI_FLASH_BUS: - slave.bus = bus; - slave.cs = cs; - return &slave; + slave->bus = bus; + slave->cs = cs; + return 0; default: die ("wrong bus number.\n"); }; + return -1; } int spi_claim_bus(const struct spi_slave *slave) diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index 2ad4aa1..0cb4865 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -798,11 +798,14 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return ret; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct tegra_spi_channel *channel = to_tegra_spi(bus); if (!channel) - return NULL; + return -1; - return &channel->slave; + slave->bus = channel->slave.bus; + slave->cs = channel->slave.cs; + + return 0; } diff --git a/src/soc/nvidia/tegra210/spi.c b/src/soc/nvidia/tegra210/spi.c index 7efefc4..3a2dd17 100644 --- a/src/soc/nvidia/tegra210/spi.c +++ b/src/soc/nvidia/tegra210/spi.c @@ -834,11 +834,14 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, return ret; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct tegra_spi_channel *channel = to_tegra_spi(bus); if (!channel) - return NULL; + return -1; - return &channel->slave; + slave->cs = channel->slave.cs; + slave->bus = channel->slave.bus; + + return 0; } diff --git a/src/soc/qualcomm/ipq40xx/include/soc/spi.h b/src/soc/qualcomm/ipq40xx/include/soc/spi.h index 8ef1fbf..b91e6ca 100644 --- a/src/soc/qualcomm/ipq40xx/include/soc/spi.h +++ b/src/soc/qualcomm/ipq40xx/include/soc/spi.h @@ -186,9 +186,4 @@ struct ipq_spi_slave { int allocated; }; -static inline struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) -{ - return container_of(slave, struct ipq_spi_slave, slave); -} - #endif /* _IPQ40XX_SPI_H_ */ diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c index 871f24b..cda3bea 100644 --- a/src/soc/qualcomm/ipq40xx/spi.c +++ b/src/soc/qualcomm/ipq40xx/spi.c @@ -207,7 +207,26 @@ void spi_init(void) memset(spi_slave_pool, 0, sizeof(spi_slave_pool)); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +static struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) +{ + struct ipq_spi_slave *ds; + size_t i; + + for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { + ds = spi_slave_pool + i; + + if (!ds->allocated) + continue; + + if ((ds->slave.bus == slave->bus) && + (ds->slave.cs == slave->cs)) + return ds; + } + + return NULL; +} + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct ipq_spi_slave *ds = NULL; int i; @@ -218,16 +237,17 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) printk(BIOS_ERR, "SPI error: unsupported bus %d (Supported busses 0, 1 and 2) " "or chipselect\n", bus); - return NULL; + return -1; } for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { if (spi_slave_pool[i].allocated) continue; ds = spi_slave_pool + i; - ds->slave.bus = bus; - ds->slave.cs = cs; - ds->regs = &spi_reg[bus]; + + ds->slave.bus = slave->bus = bus; + ds->slave.cs = slave->cs = cs; + ds->regs = &spi_reg[bus]; /* * TODO(vbendeb): @@ -238,11 +258,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) ds->mode = SPI_MODE3; ds->allocated = 1; - return &ds->slave; + return 0; } printk(BIOS_ERR, "SPI error: all %d pools busy\n", i); - return NULL; + return -1; } /* diff --git a/src/soc/qualcomm/ipq806x/include/soc/spi.h b/src/soc/qualcomm/ipq806x/include/soc/spi.h index 5dedcda..98a15b8 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/spi.h +++ b/src/soc/qualcomm/ipq806x/include/soc/spi.h @@ -271,9 +271,4 @@ struct ipq_spi_slave { int allocated; }; -static inline struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) -{ - return container_of(slave, struct ipq_spi_slave, slave); -} - #endif /* _IPQ806X_SPI_H_ */ diff --git a/src/soc/qualcomm/ipq806x/spi.c b/src/soc/qualcomm/ipq806x/spi.c index d1af720..81dc508 100644 --- a/src/soc/qualcomm/ipq806x/spi.c +++ b/src/soc/qualcomm/ipq806x/spi.c @@ -499,7 +499,26 @@ void spi_init() memset(spi_slave_pool, 0, sizeof(spi_slave_pool)); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +static struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) +{ + struct ipq_spi_slave *ds; + size_t i; + + for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { + ds = spi_slave_pool + i; + + if (!ds->allocated) + continue; + + if ((ds->slave.bus == slave->bus) && + (ds->slave.cs == slave->cs)) + return ds; + } + + return NULL; +} + +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { struct ipq_spi_slave *ds = NULL; int i; @@ -521,9 +540,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) if (spi_slave_pool[i].allocated) continue; ds = spi_slave_pool + i; - ds->slave.bus = bus; - ds->slave.cs = cs; - ds->regs = &spi_reg[bus]; + + ds->slave.bus = slave->bus = bus; + ds->slave.cs = slave->cs = cs; + ds->regs = &spi_reg[bus]; /* * TODO(vbendeb): @@ -534,11 +554,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) ds->mode = GSBI_SPI_MODE_0; ds->allocated = 1; - return &ds->slave; + return 0; } printk(BIOS_ERR, "SPI error: all %d pools busy\n", i); - return NULL; + return -1; } /* diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 8f45679..85597f2 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -27,7 +27,6 @@ #include <timer.h> struct rockchip_spi_slave { - struct spi_slave slave; struct rockchip_spi *regs; }; @@ -37,30 +36,24 @@ struct rockchip_spi_slave { static struct rockchip_spi_slave rockchip_spi_slaves[] = { { - .slave = { .bus = 0, }, .regs = (void *)SPI0_BASE, }, { - .slave = { .bus = 1, }, .regs = (void *)SPI1_BASE, }, { - .slave = { .bus = 2, }, .regs = (void *)SPI2_BASE, }, #ifdef SPI3_BASE { - .slave = { .bus = 3, }, .regs = (void *)SPI3_BASE, }, #ifdef SPI4_BASE { - .slave = { .bus = 4, }, .regs = (void *)SPI4_BASE, }, #ifdef SPI5_BASE { - .slave = { .bus = 5, }, .regs = (void *)SPI5_BASE, }, #endif @@ -70,13 +63,18 @@ static struct rockchip_spi_slave rockchip_spi_slaves[] = { static struct rockchip_spi_slave *to_rockchip_spi(const struct spi_slave *slave) { - return container_of(slave, struct rockchip_spi_slave, slave); + assert(slave->bus < ARRAY_SIZE(rockchip_spi_slaves)); + return &rockchip_spi_slaves[slave->bus]; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - assert(bus >= 0 && bus < ARRAY_SIZE(rockchip_spi_slaves)); - return &(rockchip_spi_slaves[bus].slave); + assert(bus < ARRAY_SIZE(rockchip_spi_slaves)); + + slave->bus = bus; + slave->cs = cs; + + return 0; } static void spi_cs_activate(const struct spi_slave *slave) diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c index c2faeb5..5dbe024 100644 --- a/src/soc/samsung/exynos5420/spi.c +++ b/src/soc/samsung/exynos5420/spi.c @@ -60,7 +60,7 @@ static struct exynos_spi_slave exynos_spi_slaves[3] = { static inline struct exynos_spi_slave *to_exynos_spi(const struct spi_slave *slave) { - return container_of(slave, struct exynos_spi_slave, slave); + return &exynos_spi_slaves[slave->bus]; } static void spi_sw_reset(struct exynos_spi *regs, int word) @@ -117,15 +117,20 @@ static void exynos_spi_init(struct exynos_spi *regs) spi_sw_reset(regs, 1); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { ASSERT(bus >= 0 && bus < 3); - struct exynos_spi_slave *eslave = &exynos_spi_slaves[bus]; + struct exynos_spi_slave *eslave; + + slave->bus = bus; + slave->cs = cs; + + eslave = to_exynos_spi(slave); if (!eslave->initialized) { exynos_spi_init(eslave->regs); eslave->initialized = 1; } - return &eslave->slave; + return 0; } int spi_claim_bus(const struct spi_slave *slave) diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c index 7bb0e3f..a8b3b2a 100644 --- a/src/southbridge/amd/agesa/hudson/spi.c +++ b/src/southbridge/amd/agesa/hudson/spi.c @@ -176,15 +176,9 @@ int chipset_volatile_group_end(const struct spi_flash *flash) return 0; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - struct spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - return slave; + slave->bus = bus; + slave->cs = cs; + return 0; } diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c index 2522c2e..d331060 100644 --- a/src/southbridge/amd/cimx/sb800/spi.c +++ b/src/southbridge/amd/cimx/sb800/spi.c @@ -168,15 +168,9 @@ int chipset_volatile_group_end(const struct spi_flash *flash) return 0; } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - struct spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - return slave; + slave->bus = bus; + slave->cs = cs; + return 0; } diff --git a/src/southbridge/amd/sb700/spi.c b/src/southbridge/amd/sb700/spi.c index 2b1ae2d..fca401c 100644 --- a/src/southbridge/amd/sb700/spi.c +++ b/src/southbridge/amd/sb700/spi.c @@ -76,17 +76,11 @@ void spi_release_bus(const struct spi_slave *slave) /* Handled internally by the SB700 */ } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - struct spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - return slave; + slave->bus = bus; + slave->cs = cs; + return 0; } int spi_xfer(const struct spi_slave *slave, const void *dout, diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 2d36d38..7e0cc20 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -285,20 +285,11 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - slave->bus = bus; slave->cs = cs; - return slave; + return 0; } void spi_init(void) diff --git a/src/southbridge/intel/fsp_rangeley/spi.c b/src/southbridge/intel/fsp_rangeley/spi.c index 8a0fac2..de676a9 100644 --- a/src/southbridge/intel/fsp_rangeley/spi.c +++ b/src/southbridge/intel/fsp_rangeley/spi.c @@ -322,20 +322,11 @@ static void ich_set_bbar(uint32_t minaddr) writel_(ichspi_bbar, cntlr.bbar); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - slave->bus = bus; slave->cs = cs; - return slave; + return 0; } /*
1
0
0
0
Patch set updated for coreboot: spi: Fix parameter types for spi functions
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17682
-gerrit commit 27d44e5ba5618970acd83dd9f65871c59036a1f6 Author: Furquan Shaikh <furquan(a)chromium.org> Date: Wed Nov 30 04:34:22 2016 -0800 spi: Fix parameter types for spi functions 1. Use size_t instead of unsigned int for bytes_out and bytes_in. 2. Use const attribute for spi_slave structure passed into xfer, claim bus and release bus functions. BUG=chrome-os-partner:59832 BRANCH=None TEST=Compiles successfully Change-Id: Ie70b3520b51c42d750f907892545510c6058f85a Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- src/drivers/spi/spi_flash.c | 4 ++-- src/drivers/spi/tpm/tpm.c | 10 +++++----- src/include/spi-generic.h | 13 ++++++------- src/soc/broadcom/cygnus/spi.c | 8 ++++---- src/soc/imgtec/pistachio/spi.c | 22 +++++++++++----------- src/soc/intel/apollolake/spi.c | 8 ++++---- src/soc/intel/baytrail/spi.c | 8 ++++---- src/soc/intel/braswell/spi.c | 8 ++++---- src/soc/intel/broadwell/spi.c | 8 ++++---- src/soc/intel/fsp_baytrail/spi.c | 8 ++++---- src/soc/intel/fsp_broadwell_de/spi.c | 8 ++++---- src/soc/intel/skylake/flash_controller.c | 8 ++++---- src/soc/marvell/armada38x/spi.c | 14 +++++++------- src/soc/marvell/bg4cd/spi.c | 8 ++++---- src/soc/mediatek/mt8173/spi.c | 16 ++++++++-------- src/soc/nvidia/tegra124/spi.c | 10 +++++----- src/soc/nvidia/tegra210/spi.c | 14 +++++++------- src/soc/qualcomm/ipq40xx/include/soc/spi.h | 2 +- src/soc/qualcomm/ipq40xx/spi.c | 10 +++++----- src/soc/qualcomm/ipq806x/include/soc/spi.h | 2 +- src/soc/qualcomm/ipq806x/spi.c | 8 ++++---- src/soc/rockchip/common/spi.c | 30 +++++++++++++++--------------- src/soc/samsung/exynos5420/spi.c | 20 ++++++++++---------- src/southbridge/amd/agesa/hudson/spi.c | 10 +++++----- src/southbridge/amd/cimx/sb800/spi.c | 10 +++++----- src/southbridge/amd/sb700/spi.c | 10 +++++----- src/southbridge/amd/sb700/spi.h | 4 ++-- src/southbridge/intel/common/spi.c | 8 ++++---- src/southbridge/intel/fsp_rangeley/spi.c | 8 ++++---- 29 files changed, 148 insertions(+), 149 deletions(-) diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index b2fdab9..b6d535a 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -48,8 +48,8 @@ static void spi_flash_addr(u32 addr, u8 *cmd) * FIXME: This really should be abstracted better, but that will * require overhauling the entire SPI infrastructure. */ -static int do_spi_flash_cmd(struct spi_slave *spi, const void *dout, - unsigned int bytes_out, void *din, unsigned int bytes_in) +static int do_spi_flash_cmd(const struct spi_slave *spi, const void *dout, + size_t bytes_out, void *din, size_t bytes_in) { int ret = 1; diff --git a/src/drivers/spi/tpm/tpm.c b/src/drivers/spi/tpm/tpm.c index 9651ea8..d364cb9 100644 --- a/src/drivers/spi/tpm/tpm.c +++ b/src/drivers/spi/tpm/tpm.c @@ -37,11 +37,11 @@ /* SPI Interface descriptor used by the driver. */ struct tpm_spi_if { struct spi_slave *slave; - int (*cs_assert)(struct spi_slave *slave); - void (*cs_deassert)(struct spi_slave *slave); - int (*xfer)(struct spi_slave *slave, const void *dout, - unsigned bytesout, void *din, - unsigned bytesin); + int (*cs_assert)(const struct spi_slave *slave); + void (*cs_deassert)(const struct spi_slave *slave); + int (*xfer)(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, + size_t bytesin); }; /* Use the common SPI driver wrapper as the interface callbacks. */ diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index 347ec3c..7c53611 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -17,6 +17,7 @@ #define _SPI_GENERIC_H_ #include <stdint.h> +#include <stddef.h> /* Controller-specific definitions: */ @@ -67,7 +68,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs); * Returns: 0 if the bus was claimed successfully, or a negative value * if it wasn't. */ -int spi_claim_bus(struct spi_slave *slave); +int spi_claim_bus(const struct spi_slave *slave); /*----------------------------------------------------------------------- * Release the SPI bus @@ -78,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave); * * slave: The SPI slave */ -void spi_release_bus(struct spi_slave *slave); +void spi_release_bus(const struct spi_slave *slave); /*----------------------------------------------------------------------- * SPI transfer @@ -92,10 +93,8 @@ void spi_release_bus(struct spi_slave *slave); * * Returns: 0 on success, not 0 on failure */ -int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout, - void *din, unsigned int bytesin); - - +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, + void *din, size_t bytesin); unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len); @@ -108,7 +107,7 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len); * * TODO: This function probably shouldn't be inlined. */ -static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte) +static inline int spi_w8r8(const struct spi_slave *slave, unsigned char byte) { unsigned char dout[2]; unsigned char din[2]; diff --git a/src/soc/broadcom/cygnus/spi.c b/src/soc/broadcom/cygnus/spi.c index d7c0a8d..13b6976 100644 --- a/src/soc/broadcom/cygnus/spi.c +++ b/src/soc/broadcom/cygnus/spi.c @@ -156,7 +156,7 @@ static int mspi_enable(struct qspi_priv *priv) return 0; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { struct qspi_priv *priv = to_qspi_slave(slave); @@ -175,7 +175,7 @@ int spi_claim_bus(struct spi_slave *slave) return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct qspi_priv *priv = to_qspi_slave(slave); @@ -189,8 +189,8 @@ void spi_release_bus(struct spi_slave *slave) #define RXRAM_8B(p, i) (REG_RD((p)->reg + MSPI_RXRAM_REG + \ ((((i) << 1) + 1) << 2)) & 0xff) -int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout, - void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, + void *din, size_t bytesin) { struct qspi_priv *priv = to_qspi_slave(slave); const u8 *tx = (const u8 *)dout; diff --git a/src/soc/imgtec/pistachio/spi.c b/src/soc/imgtec/pistachio/spi.c index 2b4b01c..307aec9 100644 --- a/src/soc/imgtec/pistachio/spi.c +++ b/src/soc/imgtec/pistachio/spi.c @@ -60,7 +60,7 @@ static int wait_status(u32 reg, u32 shift) } /* Transmitter function. Fills TX FIFO with data before enabling SPIM */ -static int transmitdata(struct spi_slave *slave, u8 *buffer, u32 size) +static int transmitdata(const struct spi_slave *slave, u8 *buffer, u32 size) { u32 blocksize, base, write_data; int ret; @@ -97,7 +97,7 @@ static int transmitdata(struct spi_slave *slave, u8 *buffer, u32 size) } /* Receiver function */ -static int receivedata(struct spi_slave *slave, u8 *buffer, u32 size) +static int receivedata(const struct spi_slave *slave, u8 *buffer, u32 size) { u32 read_data, base; int ret; @@ -141,7 +141,7 @@ static int receivedata(struct spi_slave *slave, u8 *buffer, u32 size) } /* Sets port parameters in port state register. */ -static void setparams(struct spi_slave *slave, u32 port, +static void setparams(const struct spi_slave *slave, u32 port, struct spim_device_parameters *params) { u32 spim_parameters, port_state, base; @@ -247,7 +247,7 @@ static u32 control_reg_setup(struct spim_buffer *first, } /* Checks the given buffer information */ -static int check_buffers(struct spi_slave *slave, struct spim_buffer *first, +static int check_buffers(const struct spi_slave *slave, struct spim_buffer *first, struct spim_buffer *second){ if (!(container_of(slave, struct img_spi_slave, slave)->initialised)) @@ -325,7 +325,7 @@ static int check_device_params(struct spim_device_parameters *pdev_param) } /* Function that carries out read/write operations */ -static int spim_io(struct spi_slave *slave, struct spim_buffer *first, +static int spim_io(const struct spi_slave *slave, struct spim_buffer *first, struct spim_buffer *second) { u32 reg, base; @@ -459,7 +459,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) } /* Claim the bus and prepare it for communication */ -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { int ret; struct img_spi_slave *img_slave; @@ -490,7 +490,7 @@ int spi_claim_bus(struct spi_slave *slave) } /* Release the SPI bus */ -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct img_spi_slave *img_slave; @@ -508,8 +508,8 @@ void spi_release_bus(struct spi_slave *slave) } /* SPI transfer */ -static int do_spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +static int do_spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { struct spim_buffer buff_0; struct spim_buffer buff_1; @@ -532,8 +532,8 @@ static int do_spi_xfer(struct spi_slave *slave, const void *dout, return spim_io(slave, &buff_0, (dout && din) ? &buff_1 : NULL); } -int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytesout, - void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, + void *din, size_t bytesin) { unsigned int in_sz, out_sz; int ret; diff --git a/src/soc/intel/apollolake/spi.c b/src/soc/intel/apollolake/spi.c index eab3a12..6e873f4 100644 --- a/src/soc/intel/apollolake/spi.c +++ b/src/soc/intel/apollolake/spi.c @@ -184,8 +184,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return MIN(buf_len, SPIBAR_FDATA_FIFO_SIZE); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { printk(BIOS_DEBUG, "NOT IMPLEMENTED: %s() !!!\n", __func__); return E_NOT_IMPLEMENTED; @@ -215,13 +215,13 @@ void spi_init(void) pci_write_config32(ctx->pci_dev, SPIBAR_BIOS_CONTROL, bios_ctl); } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* There's nothing we need to to here. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* No magic needed here. */ } diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index 1f2b285..13f8806 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -317,13 +317,13 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ } @@ -489,8 +489,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index 01f2150..34e031b 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -296,13 +296,13 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ } @@ -470,8 +470,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index c7ac09c..6aa7dd3 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -313,13 +313,13 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ } @@ -485,8 +485,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index 1ab73f3..232366c 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -297,13 +297,13 @@ void spi_init(void) cntlr.preop = &ich9_spi->preop; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ } @@ -469,8 +469,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; diff --git a/src/soc/intel/fsp_broadwell_de/spi.c b/src/soc/intel/fsp_broadwell_de/spi.c index 116001f..c38fbce 100644 --- a/src/soc/intel/fsp_broadwell_de/spi.c +++ b/src/soc/intel/fsp_broadwell_de/spi.c @@ -312,13 +312,13 @@ void spi_init(void) pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ } @@ -484,8 +484,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; diff --git a/src/soc/intel/skylake/flash_controller.c b/src/soc/intel/skylake/flash_controller.c index cc6c20a..8aee796 100644 --- a/src/soc/intel/skylake/flash_controller.c +++ b/src/soc/intel/skylake/flash_controller.c @@ -151,8 +151,8 @@ static size_t spi_get_flash_size(pch_spi_regs *spi_bar) return size; } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { /* TODO: Define xfer for hardware sequencing. */ return -1; @@ -170,13 +170,13 @@ void spi_init(void) pci_write_config_byte(dev, SPIBAR_BIOS_CNTL, bios_cntl); } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by PCH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by PCH automatically. */ } diff --git a/src/soc/marvell/armada38x/spi.c b/src/soc/marvell/armada38x/spi.c index 6a0e062..af0a279 100644 --- a/src/soc/marvell/armada38x/spi.c +++ b/src/soc/marvell/armada38x/spi.c @@ -409,8 +409,8 @@ int mv_spi_8bit_data_tx_rx(unsigned char spi_id, return MV_OK; } -static int mrvl_spi_xfer(struct spi_slave *slave, - unsigned int bitlen, +static int mrvl_spi_xfer(const struct spi_slave *slave, + size_t bitlen, const void *dout, void *din) { @@ -454,14 +454,14 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) return slave; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { mv_spi_cs_set(slave->bus, slave->cs); mv_spi_cs_assert(slave->bus); return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { mv_spi_cs_deassert(slave->bus); } @@ -471,11 +471,11 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -int spi_xfer(struct spi_slave *slave, +int spi_xfer(const struct spi_slave *slave, const void *dout, - unsigned out_bytes, + size_t out_bytes, void *din, - unsigned in_bytes) + size_t in_bytes) { int ret = -1; diff --git a/src/soc/marvell/bg4cd/spi.c b/src/soc/marvell/bg4cd/spi.c index 53f46c7..9a999b0 100644 --- a/src/soc/marvell/bg4cd/spi.c +++ b/src/soc/marvell/bg4cd/spi.c @@ -20,17 +20,17 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) return NULL; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned out_bytes, void *din, unsigned in_bytes) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { return 0; } diff --git a/src/soc/mediatek/mt8173/spi.c b/src/soc/mediatek/mt8173/spi.c index 9d56b63..f60de6c 100644 --- a/src/soc/mediatek/mt8173/spi.c +++ b/src/soc/mediatek/mt8173/spi.c @@ -55,7 +55,7 @@ static struct mtk_spi_bus spi_bus[1] = { } }; -static inline struct mtk_spi_bus *to_mtk_spi(struct spi_slave *slave) +static inline struct mtk_spi_bus *to_mtk_spi(const struct spi_slave *slave) { return container_of(slave, struct mtk_spi_bus, slave); } @@ -182,7 +182,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) }; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave); struct mtk_spi_regs *regs = mtk_slave->regs; @@ -193,8 +193,8 @@ int spi_claim_bus(struct spi_slave *slave) return 0; } -static int mtk_spi_fifo_transfer(struct spi_slave *slave, void *in, - const void *out, u32 size) +static int mtk_spi_fifo_transfer(const struct spi_slave *slave, void *in, + const void *out, size_t size) { struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave); struct mtk_spi_regs *regs = mtk_slave->regs; @@ -269,10 +269,10 @@ error: return -1; } -int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytes_out, - void *din, unsigned int bytes_in) +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, + void *din, size_t bytes_in) { - uint32_t min_size = 0; + size_t min_size = 0; int ret; while (bytes_out || bytes_in) { @@ -301,7 +301,7 @@ int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytes_out, return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct mtk_spi_bus *mtk_slave = to_mtk_spi(slave); struct mtk_spi_regs *regs = mtk_slave->regs; diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index d5be4a6..2ad4aa1 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -209,7 +209,7 @@ static unsigned int tegra_spi_speed(unsigned int bus) return 50000000; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -232,7 +232,7 @@ int spi_claim_bus(struct spi_slave *slave) return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -719,13 +719,13 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int out_bytes, void *din, unsigned int in_bytes) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct tegra_spi_channel *spi = to_tegra_spi(slave->bus); u8 *out_buf = (u8 *)dout; u8 *in_buf = (u8 *)din; - unsigned int todo; + size_t todo; int ret = 0; /* tegra bus numbers start at 1 */ diff --git a/src/soc/nvidia/tegra210/spi.c b/src/soc/nvidia/tegra210/spi.c index b01289c..7efefc4 100644 --- a/src/soc/nvidia/tegra210/spi.c +++ b/src/soc/nvidia/tegra210/spi.c @@ -208,7 +208,7 @@ static struct tegra_spi_channel * const to_tegra_spi(int bus) { return &tegra_spi_channels[bus - 1]; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -231,7 +231,7 @@ int spi_claim_bus(struct spi_slave *slave) return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct tegra_spi_regs *regs = to_tegra_spi(slave->bus)->regs; u32 val; @@ -755,13 +755,13 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return buf_len; } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int out_bytes, void *din, unsigned int in_bytes) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct tegra_spi_channel *spi = to_tegra_spi(slave->bus); u8 *out_buf = (u8 *)dout; u8 *in_buf = (u8 *)din; - unsigned int todo; + size_t todo; int ret = 0; /* tegra bus numbers start at 1 */ @@ -827,8 +827,8 @@ int spi_xfer(struct spi_slave *slave, const void *dout, if (ret < 0) { printk(BIOS_ERR, "%s: Error detected\n", __func__); - printk(BIOS_ERR, "Transaction size: %u, bytes remaining: " - "%u out / %u in\n", todo, out_bytes, in_bytes); + printk(BIOS_ERR, "Transaction size: %zu, bytes remaining: " + "%zu out / %zu in\n", todo, out_bytes, in_bytes); clear_fifo_status(spi); } return ret; diff --git a/src/soc/qualcomm/ipq40xx/include/soc/spi.h b/src/soc/qualcomm/ipq40xx/include/soc/spi.h index 1fd6a57..8ef1fbf 100644 --- a/src/soc/qualcomm/ipq40xx/include/soc/spi.h +++ b/src/soc/qualcomm/ipq40xx/include/soc/spi.h @@ -186,7 +186,7 @@ struct ipq_spi_slave { int allocated; }; -static inline struct ipq_spi_slave *to_ipq_spi(struct spi_slave *slave) +static inline struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) { return container_of(slave, struct ipq_spi_slave, slave); } diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c index dcd00c0..871f24b 100644 --- a/src/soc/qualcomm/ipq40xx/spi.c +++ b/src/soc/qualcomm/ipq40xx/spi.c @@ -320,7 +320,7 @@ static int spi_hw_init(struct ipq_spi_slave *ds) return SUCCESS; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); unsigned int ret; @@ -332,7 +332,7 @@ int spi_claim_bus(struct spi_slave *slave) return SUCCESS; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); @@ -341,7 +341,7 @@ void spi_release_bus(struct spi_slave *slave) ds->initialized = 0; } -static void write_force_cs(struct spi_slave *slave, int assert) +static void write_force_cs(const struct spi_slave *slave, int assert) { struct ipq_spi_slave *ds = to_ipq_spi(slave); @@ -633,8 +633,8 @@ static int blsp_spi_write(struct ipq_spi_slave *ds, u8 *cmd_buffer, * This function is invoked with either tx_buf or rx_buf. * Calling this function with both null does a chip select change. */ -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned out_bytes, void *din, unsigned in_bytes) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { struct ipq_spi_slave *ds = to_ipq_spi(slave); u8 *txp = (u8 *)dout; diff --git a/src/soc/qualcomm/ipq806x/include/soc/spi.h b/src/soc/qualcomm/ipq806x/include/soc/spi.h index 4f6f055..5dedcda 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/spi.h +++ b/src/soc/qualcomm/ipq806x/include/soc/spi.h @@ -271,7 +271,7 @@ struct ipq_spi_slave { int allocated; }; -static inline struct ipq_spi_slave *to_ipq_spi(struct spi_slave *slave) +static inline struct ipq_spi_slave *to_ipq_spi(const struct spi_slave *slave) { return container_of(slave, struct ipq_spi_slave, slave); } diff --git a/src/soc/qualcomm/ipq806x/spi.c b/src/soc/qualcomm/ipq806x/spi.c index 71a8c29..d1af720 100644 --- a/src/soc/qualcomm/ipq806x/spi.c +++ b/src/soc/qualcomm/ipq806x/spi.c @@ -618,7 +618,7 @@ static int spi_hw_init(struct ipq_spi_slave *ds) return SUCCESS; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); unsigned int ret; @@ -641,7 +641,7 @@ int spi_claim_bus(struct spi_slave *slave) return SUCCESS; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct ipq_spi_slave *ds = to_ipq_spi(slave); @@ -711,8 +711,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(MAX_PACKET_COUNT, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned out_bytes, void *din, unsigned in_bytes) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) { int ret; struct ipq_spi_slave *ds = to_ipq_spi(slave); diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 3666de3..8f45679 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -68,7 +68,7 @@ static struct rockchip_spi_slave rockchip_spi_slaves[] = { #endif }; -static struct rockchip_spi_slave *to_rockchip_spi(struct spi_slave *slave) +static struct rockchip_spi_slave *to_rockchip_spi(const struct spi_slave *slave) { return container_of(slave, struct rockchip_spi_slave, slave); } @@ -79,13 +79,13 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) return &(rockchip_spi_slaves[bus].slave); } -static void spi_cs_activate(struct spi_slave *slave) +static void spi_cs_activate(const struct spi_slave *slave) { struct rockchip_spi *regs = to_rockchip_spi(slave)->regs; setbits_le32(®s->ser, 1); } -static void spi_cs_deactivate(struct spi_slave *slave) +static void spi_cs_deactivate(const struct spi_slave *slave) { struct rockchip_spi *regs = to_rockchip_spi(slave)->regs; clrbits_le32(®s->ser, 1); @@ -157,13 +157,13 @@ void rockchip_spi_set_sample_delay(unsigned int bus, unsigned int delay_ns) rsd << SPI_RXDSD_OFFSET); } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { spi_cs_activate(slave); return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { spi_cs_deactivate(slave); } @@ -203,11 +203,11 @@ static void set_transfer_mode(struct rockchip_spi *regs, /* returns 0 to indicate success, <0 otherwise */ static int do_xfer(struct rockchip_spi *regs, bool use_16bit, const void *dout, - unsigned int *bytes_out, void *din, unsigned int *bytes_in) + size_t *bytes_out, void *din, size_t *bytes_in) { uint8_t *in_buf = din; uint8_t *out_buf = (uint8_t *)dout; - unsigned int min_xfer; + size_t min_xfer; if (*bytes_out == 0) min_xfer = *bytes_in; @@ -268,8 +268,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(65535, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytes_out, void *din, unsigned int bytes_in) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytes_out, void *din, size_t bytes_in) { struct rockchip_spi *regs = to_rockchip_spi(slave)->regs; int ret = 0; @@ -283,10 +283,10 @@ int spi_xfer(struct spi_slave *slave, const void *dout, * seems to work fine. */ while (bytes_out || bytes_in) { - unsigned int in_now = MIN(bytes_in, 0xfffe); - unsigned int out_now = MIN(bytes_out, 0xfffe); - unsigned int in_rem, out_rem; - unsigned int mask; + size_t in_now = MIN(bytes_in, 0xfffe); + size_t out_now = MIN(bytes_out, 0xfffe); + size_t in_rem, out_rem; + size_t mask; bool use_16bit; rockchip_spi_enable_chip(regs, 0); @@ -324,13 +324,13 @@ int spi_xfer(struct spi_slave *slave, const void *dout, break; if (bytes_out) { - unsigned int sent = out_now - out_rem; + size_t sent = out_now - out_rem; bytes_out -= sent; dout += sent; } if (bytes_in) { - unsigned int received = in_now - in_rem; + size_t received = in_now - in_rem; bytes_in -= received; din += received; } diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c index fd31a2f..c2faeb5 100644 --- a/src/soc/samsung/exynos5420/spi.c +++ b/src/soc/samsung/exynos5420/spi.c @@ -58,7 +58,7 @@ static struct exynos_spi_slave exynos_spi_slaves[3] = { }, }; -static inline struct exynos_spi_slave *to_exynos_spi(struct spi_slave *slave) +static inline struct exynos_spi_slave *to_exynos_spi(const struct spi_slave *slave) { return container_of(slave, struct exynos_spi_slave, slave); } @@ -128,7 +128,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) return &eslave->slave; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { struct exynos_spi *regs = to_exynos_spi(slave)->regs; // TODO(hungte) Add some delay if too many transactions happen at once. @@ -137,19 +137,19 @@ int spi_claim_bus(struct spi_slave *slave) } static void spi_transfer(struct exynos_spi *regs, void *in, const void *out, - u32 size) + size_t size) { u8 *inb = in; const u8 *outb = out; - int width = (size % 4) ? 1 : 4; + size_t width = (size % 4) ? 1 : 4; while (size) { - int packets = size / width; + size_t packets = size / width; // The packet count field is 16 bits wide. packets = MIN(packets, (1 << 16) - 1); - int out_bytes, in_bytes; + size_t out_bytes, in_bytes; out_bytes = in_bytes = packets * width; spi_sw_reset(regs, width == 4); @@ -188,13 +188,13 @@ static void spi_transfer(struct exynos_spi *regs, void *in, const void *out, } } -int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytes_out, - void *din, unsigned int bytes_in) +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytes_out, + void *din, size_t bytes_in) { struct exynos_spi *regs = to_exynos_spi(slave)->regs; if (bytes_out && bytes_in) { - u32 min_size = MIN(bytes_out, bytes_in); + size_t min_size = MIN(bytes_out, bytes_in); spi_transfer(regs, din, dout, min_size); @@ -213,7 +213,7 @@ int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bytes_out, return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { struct exynos_spi *regs = to_exynos_spi(slave)->regs; setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); diff --git a/src/southbridge/amd/agesa/hudson/spi.c b/src/southbridge/amd/agesa/hudson/spi.c index f1a82e9..7bb0e3f 100644 --- a/src/southbridge/amd/agesa/hudson/spi.c +++ b/src/southbridge/amd/agesa/hudson/spi.c @@ -90,13 +90,13 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { /* First byte is cmd which can not being sent through FIFO. */ u8 cmd = *(u8 *)dout++; u8 readoffby1; - u8 count; + size_t count; bytesout--; @@ -147,13 +147,13 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return 0; } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Nothing is required. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Nothing is required. */ } diff --git a/src/southbridge/amd/cimx/sb800/spi.c b/src/southbridge/amd/cimx/sb800/spi.c index 726d8e0..2522c2e 100644 --- a/src/southbridge/amd/cimx/sb800/spi.c +++ b/src/southbridge/amd/cimx/sb800/spi.c @@ -59,14 +59,14 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(AMD_SB_SPI_TX_LEN - cmd_len, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { /* First byte is cmd which can not being sent through FIFO. */ u8 cmd = *(u8 *)dout++; u8 readoffby1; u8 readwrite; - u8 count; + size_t count; bytesout--; @@ -138,13 +138,13 @@ static void ImcWakeup(void) WaitForEcLDN9MailboxCmdAck(); } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Nothing is required. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Nothing is required. */ return; diff --git a/src/southbridge/amd/sb700/spi.c b/src/southbridge/amd/sb700/spi.c index fa316f1..2b1ae2d 100644 --- a/src/southbridge/amd/sb700/spi.c +++ b/src/southbridge/amd/sb700/spi.c @@ -65,13 +65,13 @@ static void execute_command(void) (read8((void *)(spibar+3)) & 0x80)); } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled internally by the SB700 */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled internally by the SB700 */ } @@ -89,14 +89,14 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) return slave; } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { /* First byte is cmd which cannot be sent through the FIFO. */ u8 cmd = *(u8 *)dout++; u8 readoffby1; u8 readwrite; - u8 count; + size_t count; uint32_t spibar = get_spi_bar(); diff --git a/src/southbridge/amd/sb700/spi.h b/src/southbridge/amd/sb700/spi.h index ed5b858..605f3ee 100644 --- a/src/southbridge/amd/sb700/spi.h +++ b/src/southbridge/amd/sb700/spi.h @@ -13,5 +13,5 @@ * GNU General Public License for more details. */ -int spi_claim_bus(struct spi_slave *slave); -void spi_release_bus(struct spi_slave *slave); +int spi_claim_bus(const struct spi_slave *slave); +void spi_release_bus(const struct spi_slave *slave); diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 36102c2..2d36d38 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -357,13 +357,13 @@ static void spi_init_cb(void *unused) BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ } @@ -536,8 +536,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index; diff --git a/src/southbridge/intel/fsp_rangeley/spi.c b/src/southbridge/intel/fsp_rangeley/spi.c index 8b0c3c1..8a0fac2 100644 --- a/src/southbridge/intel/fsp_rangeley/spi.c +++ b/src/southbridge/intel/fsp_rangeley/spi.c @@ -429,13 +429,13 @@ void spi_init(void) } } -int spi_claim_bus(struct spi_slave *slave) +int spi_claim_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ return 0; } -void spi_release_bus(struct spi_slave *slave) +void spi_release_bus(const struct spi_slave *slave) { /* Handled by ICH automatically. */ } @@ -601,8 +601,8 @@ unsigned int spi_crop_chunk(unsigned int cmd_len, unsigned int buf_len) return min(cntlr.databytes, buf_len); } -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bytesout, void *din, unsigned int bytesin) +int spi_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) { uint16_t control; int16_t opcode_index;
1
0
0
0
Patch set updated for coreboot: spi_flash: Move spi flash opcodes to spi_flash.h
by Furquan Shaikh
02 Dec '16
02 Dec '16
Furquan Shaikh (furquan(a)google.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17680
-gerrit commit 18f4578318170e2cd5f6f8f08bbe632d7a1d1d26 Author: Furquan Shaikh <furquan(a)chromium.org> Date: Tue Nov 22 11:43:58 2016 -0800 spi_flash: Move spi flash opcodes to spi_flash.h BUG=chrome-os-partner:59832 BRANCH=None TEST=Compiles successfully Change-Id: I3b6656923bb312de470da43a23f66f350e1cebc7 Signed-off-by: Furquan Shaikh <furquan(a)chromium.org> --- src/include/spi-generic.h | 4 ---- src/include/spi_flash.h | 4 ++++ src/soc/intel/baytrail/spi.c | 1 + src/soc/intel/braswell/spi.c | 1 + src/soc/intel/broadwell/spi.c | 1 + src/soc/intel/fsp_baytrail/spi.c | 1 + src/southbridge/intel/fsp_rangeley/spi.c | 1 + 7 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/include/spi-generic.h b/src/include/spi-generic.h index e57f56d..347ec3c 100644 --- a/src/include/spi-generic.h +++ b/src/include/spi-generic.h @@ -20,10 +20,6 @@ /* Controller-specific definitions: */ -/* SPI opcodes */ -#define SPI_OPCODE_WREN 0x06 -#define SPI_OPCODE_FAST_READ 0x0b - /*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h index 70eef8e..8fec484 100644 --- a/src/include/spi_flash.h +++ b/src/include/spi_flash.h @@ -19,6 +19,10 @@ #include <stddef.h> #include <boot/coreboot_tables.h> +/* SPI Flash opcodes */ +#define SPI_OPCODE_WREN 0x06 +#define SPI_OPCODE_FAST_READ 0x0b + struct spi_flash { struct spi_slave *spi; const char *name; diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index d651350..1f2b285 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -21,6 +21,7 @@ #include <arch/io.h> #include <console/console.h> #include <device/pci_ids.h> +#include <spi_flash.h> #include <spi-generic.h> #include <soc/lpc.h> diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index 97ca2e5..01f2150 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -22,6 +22,7 @@ #include <rules.h> #include <soc/lpc.h> #include <soc/pci_devs.h> +#include <spi_flash.h> #include <spi-generic.h> #include <stdint.h> #include <stdlib.h> diff --git a/src/soc/intel/broadwell/spi.c b/src/soc/intel/broadwell/spi.c index e07b425..c7ac09c 100644 --- a/src/soc/intel/broadwell/spi.c +++ b/src/soc/intel/broadwell/spi.c @@ -20,6 +20,7 @@ #include <arch/io.h> #include <console/console.h> #include <device/pci_ids.h> +#include <spi_flash.h> #include <spi-generic.h> #include <soc/pci_devs.h> #include <soc/rcba.h> diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index b021175..1ab73f3 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -22,6 +22,7 @@ #include <arch/io.h> #include <console/console.h> #include <device/pci_ids.h> +#include <spi_flash.h> #include <spi-generic.h> #include <soc/lpc.h> diff --git a/src/southbridge/intel/fsp_rangeley/spi.c b/src/southbridge/intel/fsp_rangeley/spi.c index 007c612..8b0c3c1 100644 --- a/src/southbridge/intel/fsp_rangeley/spi.c +++ b/src/southbridge/intel/fsp_rangeley/spi.c @@ -22,6 +22,7 @@ #include <console/console.h> #include <device/pci_ids.h> +#include <spi_flash.h> #include <spi-generic.h> static int ich_status_poll(u16 bitmask, int wait_til_set);
1
0
0
0
New patch to review for coreboot: AMD fam10 binaryPI: Remove invalid PCI ops on CPU domain
by Kyösti Mälkki
02 Dec '16
02 Dec '16
Kyösti Mälkki (kyosti.malkki(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17697
-gerrit commit 50e816c8453b598bade5f4f760deedd4017726cf Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com> Date: Fri Dec 2 16:02:30 2016 +0200 AMD fam10 binaryPI: Remove invalid PCI ops on CPU domain Device is of type CPU_CLUSTER, while pci_dev_set_resources() expects PCI_DOMAIN. Change-Id: Ib1add47d71071abb6e9c28e3a85dd0b671741b71 Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com> --- src/northbridge/amd/agesa/family10/northbridge.c | 13 ++----------- src/northbridge/amd/agesa/family12/northbridge.c | 20 ++------------------ src/northbridge/amd/amdfam10/northbridge.c | 7 +------ src/northbridge/amd/pi/00660F01/northbridge.c | 13 ++----------- src/northbridge/amd/pi/00670F00/northbridge.c | 13 ++----------- src/northbridge/amd/pi/00730F01/northbridge.c | 13 ++----------- 6 files changed, 11 insertions(+), 68 deletions(-) diff --git a/src/northbridge/amd/agesa/family10/northbridge.c b/src/northbridge/amd/agesa/family10/northbridge.c index fb4914d..dd19e08 100644 --- a/src/northbridge/amd/agesa/family10/northbridge.c +++ b/src/northbridge/amd/agesa/family10/northbridge.c @@ -1101,18 +1101,9 @@ static void cpu_bus_init(device_t dev) initialize_cpus(dev->link_list); } -static void cpu_bus_read_resources(device_t dev) -{ -} - -static void cpu_bus_set_resources(device_t dev) -{ - pci_dev_set_resources(dev); -} - static struct device_operations cpu_bus_ops = { - .read_resources = cpu_bus_read_resources, - .set_resources = cpu_bus_set_resources, + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, .init = cpu_bus_init, .scan_bus = cpu_bus_scan, diff --git a/src/northbridge/amd/agesa/family12/northbridge.c b/src/northbridge/amd/agesa/family12/northbridge.c index f0fe4e8..2f70572 100644 --- a/src/northbridge/amd/agesa/family12/northbridge.c +++ b/src/northbridge/amd/agesa/family12/northbridge.c @@ -652,22 +652,6 @@ static void domain_enable_resources(device_t dev) /* Bus related code */ - -static void cpu_bus_read_resources(device_t dev) -{ - printk(BIOS_DEBUG, "\nFam12h - northbridge.c - %s - Start.\n",__func__); - - printk(BIOS_DEBUG, "Fam12h - northbridge.c - %s - End.\n",__func__); -} - -static void cpu_bus_set_resources(device_t dev) -{ - printk(BIOS_DEBUG, "\nFam12h - northbridge.c - %s - Start.\n",__func__); - pci_dev_set_resources(dev); - - printk(BIOS_DEBUG, "Fam12h - northbridge.c - %s - End.\n",__func__); -} - static void cpu_bus_init(device_t dev) { printk(BIOS_DEBUG, "\nFam12h - northbridge.c - %s - Start.\n",__func__); @@ -813,8 +797,8 @@ static struct device_operations pci_domain_ops = { static struct device_operations cpu_bus_ops = { - .read_resources = cpu_bus_read_resources, - .set_resources = cpu_bus_set_resources, + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, .init = cpu_bus_init, .scan_bus = 0, diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index d82e1df..cd7a486 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -1955,14 +1955,9 @@ static void cpu_bus_init(device_t dev) #endif } -static void cpu_bus_set_resources(struct device *dev) -{ - pci_dev_set_resources(dev); -} - static struct device_operations cpu_bus_ops = { .read_resources = DEVICE_NOOP, - .set_resources = cpu_bus_set_resources, + .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, .init = cpu_bus_init, .scan_bus = cpu_bus_scan, diff --git a/src/northbridge/amd/pi/00660F01/northbridge.c b/src/northbridge/amd/pi/00660F01/northbridge.c index 97c8179..0cdf4e5 100644 --- a/src/northbridge/amd/pi/00660F01/northbridge.c +++ b/src/northbridge/amd/pi/00660F01/northbridge.c @@ -1088,18 +1088,9 @@ static void cpu_bus_init(device_t dev) initialize_cpus(dev->link_list); } -static void cpu_bus_read_resources(device_t dev) -{ -} - -static void cpu_bus_set_resources(device_t dev) -{ - pci_dev_set_resources(dev); -} - static struct device_operations cpu_bus_ops = { - .read_resources = cpu_bus_read_resources, - .set_resources = cpu_bus_set_resources, + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, .init = cpu_bus_init, .scan_bus = cpu_bus_scan, diff --git a/src/northbridge/amd/pi/00670F00/northbridge.c b/src/northbridge/amd/pi/00670F00/northbridge.c index 5eae902..f042b36 100644 --- a/src/northbridge/amd/pi/00670F00/northbridge.c +++ b/src/northbridge/amd/pi/00670F00/northbridge.c @@ -1089,18 +1089,9 @@ static void cpu_bus_init(device_t dev) initialize_cpus(dev->link_list); } -static void cpu_bus_read_resources(device_t dev) -{ -} - -static void cpu_bus_set_resources(device_t dev) -{ - pci_dev_set_resources(dev); -} - static struct device_operations cpu_bus_ops = { - .read_resources = cpu_bus_read_resources, - .set_resources = cpu_bus_set_resources, + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, .init = cpu_bus_init, .scan_bus = cpu_bus_scan, diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index 1654b8a..45361e7 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -1108,18 +1108,9 @@ static void cpu_bus_init(device_t dev) initialize_cpus(dev->link_list); } -static void cpu_bus_read_resources(device_t dev) -{ -} - -static void cpu_bus_set_resources(device_t dev) -{ - pci_dev_set_resources(dev); -} - static struct device_operations cpu_bus_ops = { - .read_resources = cpu_bus_read_resources, - .set_resources = cpu_bus_set_resources, + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, .init = cpu_bus_init, .scan_bus = cpu_bus_scan,
1
0
0
0
New patch to review for coreboot: MMCONF_SUPPORT_DEFAULT: Drop redundant logging
by Kyösti Mälkki
02 Dec '16
02 Dec '16
Kyösti Mälkki (kyosti.malkki(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
https://review.coreboot.org/17696
-gerrit commit 0ce9b27e0d1bedb2bca2c40df10f473570bd3924 Author: Kyösti Mälkki <kyosti.malkki(a)gmail.com> Date: Fri Dec 2 14:38:13 2016 +0200 MMCONF_SUPPORT_DEFAULT: Drop redundant logging Resource is actually stored even before read_resources, but that's where we currently log this resource. For Intel, use PCI config register offset as the resource index, while AMD side uses MSR address. Change-Id: I6eeef1883c5d1ee5bbcebd1731c0e356af3fd781 Signed-off-by: Kyösti Mälkki <kyosti.malkki(a)gmail.com> --- src/northbridge/amd/agesa/family10/northbridge.c | 5 ----- src/northbridge/amd/agesa/family12/northbridge.c | 6 +----- src/northbridge/amd/agesa/family14/northbridge.c | 6 ------ src/northbridge/amd/agesa/family15/northbridge.c | 6 ------ src/northbridge/amd/agesa/family15rl/northbridge.c | 6 ------ src/northbridge/amd/agesa/family15tn/northbridge.c | 6 ------ src/northbridge/amd/agesa/family16kb/northbridge.c | 6 ------ src/northbridge/amd/amdfam10/northbridge.c | 4 ---- src/northbridge/amd/pi/00630F01/northbridge.c | 6 ------ src/northbridge/amd/pi/00660F01/northbridge.c | 4 ---- src/northbridge/amd/pi/00670F00/northbridge.c | 4 ---- src/northbridge/amd/pi/00730F01/northbridge.c | 4 ---- src/northbridge/intel/fsp_sandybridge/northbridge.c | 19 ++----------------- src/northbridge/intel/i3100/northbridge.c | 15 ++------------- src/northbridge/intel/i945/northbridge.c | 19 ++----------------- src/northbridge/intel/sandybridge/northbridge.c | 19 ++----------------- src/soc/intel/sch/northbridge.c | 15 +-------------- 17 files changed, 10 insertions(+), 140 deletions(-) diff --git a/src/northbridge/amd/agesa/family10/northbridge.c b/src/northbridge/amd/agesa/family10/northbridge.c index 7408e50..fb4914d 100644 --- a/src/northbridge/amd/agesa/family10/northbridge.c +++ b/src/northbridge/amd/agesa/family10/northbridge.c @@ -537,11 +537,6 @@ static void amdfam10_set_resources(device_t dev) assign_resources(bus); } } - - res = find_resource(dev, 0xc0010058); - if (res) { - report_resource_stored(dev, res, " <mmconfig>"); - } } static void mcf0_control_init(struct device *dev) diff --git a/src/northbridge/amd/agesa/family12/northbridge.c b/src/northbridge/amd/agesa/family12/northbridge.c index 5ef7a90..f0fe4e8 100644 --- a/src/northbridge/amd/agesa/family12/northbridge.c +++ b/src/northbridge/amd/agesa/family12/northbridge.c @@ -662,13 +662,9 @@ static void cpu_bus_read_resources(device_t dev) static void cpu_bus_set_resources(device_t dev) { - struct resource *resource = find_resource(dev, 0xc0010058); - printk(BIOS_DEBUG, "\nFam12h - northbridge.c - %s - Start.\n",__func__); - if (resource) { - report_resource_stored(dev, resource, " <mmconfig>"); - } pci_dev_set_resources(dev); + printk(BIOS_DEBUG, "Fam12h - northbridge.c - %s - End.\n",__func__); } diff --git a/src/northbridge/amd/agesa/family14/northbridge.c b/src/northbridge/amd/agesa/family14/northbridge.c index 08d1c49..c41f68a 100644 --- a/src/northbridge/amd/agesa/family14/northbridge.c +++ b/src/northbridge/amd/agesa/family14/northbridge.c @@ -412,12 +412,6 @@ static void nb_set_resources(device_t dev) assign_resources(bus); } } - - /* Print the MMCONF region if it has been reserved. */ - res = find_resource(dev, 0xc0010058); - if (res) { - report_resource_stored(dev, res, " <mmconfig>"); - } } /* Domain/Root Complex related code */ diff --git a/src/northbridge/amd/agesa/family15/northbridge.c b/src/northbridge/amd/agesa/family15/northbridge.c index c5e2921..e7f47f4 100644 --- a/src/northbridge/amd/agesa/family15/northbridge.c +++ b/src/northbridge/amd/agesa/family15/northbridge.c @@ -429,12 +429,6 @@ static void nb_set_resources(device_t dev) assign_resources(bus); } } - - /* Print the MMCONF region if it has been reserved. */ - res = find_resource(dev, 0xc0010058); - if (res) { - report_resource_stored(dev, res, " <mmconfig>"); - } } static void scan_chains(device_t dev) diff --git a/src/northbridge/amd/agesa/family15rl/northbridge.c b/src/northbridge/amd/agesa/family15rl/northbridge.c index 2417933..506d7c8 100644 --- a/src/northbridge/amd/agesa/family15rl/northbridge.c +++ b/src/northbridge/amd/agesa/family15rl/northbridge.c @@ -429,12 +429,6 @@ static void set_resources(struct device *dev) assign_resources(bus); } } - - /* Print the MMCONF region if it has been reserved. */ - res = find_resource(dev, 0xc0010058); - if (res) { - report_resource_stored(dev, res, " <mmconfig>"); - } } static unsigned long acpi_fill_hest(acpi_hest_t *hest) diff --git a/src/northbridge/amd/agesa/family15tn/northbridge.c b/src/northbridge/amd/agesa/family15tn/northbridge.c index 7862e60..38c92e8 100644 --- a/src/northbridge/amd/agesa/family15tn/northbridge.c +++ b/src/northbridge/amd/agesa/family15tn/northbridge.c @@ -428,12 +428,6 @@ static void nb_set_resources(device_t dev) assign_resources(bus); } } - - /* Print the MMCONF region if it has been reserved. */ - res = find_resource(dev, 0xc0010058); - if (res) { - report_resource_stored(dev, res, " <mmconfig>"); - } } diff --git a/src/northbridge/amd/agesa/family16kb/northbridge.c b/src/northbridge/amd/agesa/family16kb/northbridge.c index 23057a9..b9de2e3 100644 --- a/src/northbridge/amd/agesa/family16kb/northbridge.c +++ b/src/northbridge/amd/agesa/family16kb/northbridge.c @@ -428,12 +428,6 @@ static void set_resources(device_t dev) assign_resources(bus); } } - - /* Print the MMCONF region if it has been reserved. */ - res = find_resource(dev, 0xc0010058); - if (res) { - report_resource_stored(dev, res, " <mmconfig>"); - } } diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index 4284e1e..d82e1df 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -1957,10 +1957,6 @@ static void cpu_bus_init(device_t dev) static void cpu_bus_set_resources(struct device *dev) { - struct resource *resource = find_resource(dev, 0xc0010058); - if (resource) { - report_resource_stored(dev, resource, " <mmconfig>"); - } pci_dev_set_resources(dev); } diff --git a/src/northbridge/amd/pi/00630F01/northbridge.c b/src/northbridge/amd/pi/00630F01/northbridge.c index 1695808..d8ad807 100644 --- a/src/northbridge/amd/pi/00630F01/northbridge.c +++ b/src/northbridge/amd/pi/00630F01/northbridge.c @@ -431,12 +431,6 @@ static void set_resources(device_t dev) assign_resources(bus); } } - - /* Print the MMCONF region if it has been reserved. */ - res = find_resource(dev, 0xc0010058); - if (res) { - report_resource_stored(dev, res, " <mmconfig>"); - } } static unsigned long acpi_fill_hest(acpi_hest_t *hest) diff --git a/src/northbridge/amd/pi/00660F01/northbridge.c b/src/northbridge/amd/pi/00660F01/northbridge.c index 9f6ae1f..97c8179 100644 --- a/src/northbridge/amd/pi/00660F01/northbridge.c +++ b/src/northbridge/amd/pi/00660F01/northbridge.c @@ -1094,10 +1094,6 @@ static void cpu_bus_read_resources(device_t dev) static void cpu_bus_set_resources(device_t dev) { - struct resource *resource = find_resource(dev, 0xc0010058); - if (resource) { - report_resource_stored(dev, resource, " <mmconfig>"); - } pci_dev_set_resources(dev); } diff --git a/src/northbridge/amd/pi/00670F00/northbridge.c b/src/northbridge/amd/pi/00670F00/northbridge.c index 521a32c..5eae902 100644 --- a/src/northbridge/amd/pi/00670F00/northbridge.c +++ b/src/northbridge/amd/pi/00670F00/northbridge.c @@ -1095,10 +1095,6 @@ static void cpu_bus_read_resources(device_t dev) static void cpu_bus_set_resources(device_t dev) { - struct resource *resource = find_resource(dev, 0xc0010058); - if (resource) { - report_resource_stored(dev, resource, " <mmconfig>"); - } pci_dev_set_resources(dev); } diff --git a/src/northbridge/amd/pi/00730F01/northbridge.c b/src/northbridge/amd/pi/00730F01/northbridge.c index d97d875..1654b8a 100644 --- a/src/northbridge/amd/pi/00730F01/northbridge.c +++ b/src/northbridge/amd/pi/00730F01/northbridge.c @@ -1114,10 +1114,6 @@ static void cpu_bus_read_resources(device_t dev) static void cpu_bus_set_resources(device_t dev) { - struct resource *resource = find_resource(dev, 0xc0010058); - if (resource) { - report_resource_stored(dev, resource, " <mmconfig>"); - } pci_dev_set_resources(dev); } diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.c b/src/northbridge/intel/fsp_sandybridge/northbridge.c index 877d85f..8c146f1 100644 --- a/src/northbridge/intel/fsp_sandybridge/northbridge.c +++ b/src/northbridge/intel/fsp_sandybridge/northbridge.c @@ -245,28 +245,13 @@ static void mc_read_resources(device_t dev) pci_dev_read_resources(dev); - /* We use 0xcf as an unused index for our PCIe bar so that we find it again */ buses = get_pcie_bar(&pcie_config_base); if (buses) { - struct resource *resource = new_resource(dev, 0xcf); + struct resource *resource = new_resource(dev, PCIEXBAR); mmconf_resource_init(resource, 0, pcie_config_base, buses); } } -static void mc_set_resources(device_t dev) -{ - struct resource *resource; - - /* Report the PCIe BAR */ - resource = find_resource(dev, 0xcf); - if (resource) { - report_resource_stored(dev, resource, "<mmconfig>"); - } - - /* And call the normal set_resources */ - pci_dev_set_resources(dev); -} - static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) { if (!vendor || !device) { @@ -320,7 +305,7 @@ static struct pci_operations intel_pci_ops = { static struct device_operations mc_ops = { .read_resources = mc_read_resources, - .set_resources = mc_set_resources, + .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .init = northbridge_init, .scan_bus = 0, diff --git a/src/northbridge/intel/i3100/northbridge.c b/src/northbridge/intel/i3100/northbridge.c index 65107de..42064ab 100644 --- a/src/northbridge/intel/i3100/northbridge.c +++ b/src/northbridge/intel/i3100/northbridge.c @@ -138,18 +138,7 @@ static void mc_read_resources(device_t dev) { pci_dev_read_resources(dev); - mmconf_resource32(dev, 0xcf); -} - -static void mc_set_resources(device_t dev) -{ - struct resource *resource; - - resource = find_resource(dev, 0xcf); - if (resource) { - report_resource_stored(dev, resource, "<mmconfig>"); - } - pci_dev_set_resources(dev); + mmconf_resource32(dev, EXPECBASE); } static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) @@ -188,7 +177,7 @@ static struct pci_operations intel_pci_ops = { static struct device_operations mc_ops = { .read_resources = mc_read_resources, - .set_resources = mc_set_resources, + .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .init = 0, .scan_bus = 0, diff --git a/src/northbridge/intel/i945/northbridge.c b/src/northbridge/intel/i945/northbridge.c index 26d89d0..118df7d 100644 --- a/src/northbridge/intel/i945/northbridge.c +++ b/src/northbridge/intel/i945/northbridge.c @@ -160,22 +160,7 @@ static void mc_read_resources(device_t dev) pci_dev_read_resources(dev); - /* We use 0xcf as an unused index for our PCIe bar so that we find it again */ - mmconf_resource32(dev, 0xcf); -} - -static void mc_set_resources(device_t dev) -{ - struct resource *resource; - - /* Report the PCIe BAR */ - resource = find_resource(dev, 0xcf); - if (resource) { - report_resource_stored(dev, resource, "<mmconfig>"); - } - - /* And call the normal set_resources */ - pci_dev_set_resources(dev); + mmconf_resource32(dev, PCIEXBAR); } static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) @@ -215,7 +200,7 @@ static struct pci_operations intel_pci_ops = { static struct device_operations mc_ops = { .read_resources = mc_read_resources, - .set_resources = mc_set_resources, + .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .acpi_fill_ssdt_generator = generate_cpu_entries, #if CONFIG_HAVE_ACPI_RESUME diff --git a/src/northbridge/intel/sandybridge/northbridge.c b/src/northbridge/intel/sandybridge/northbridge.c index a86672b..e34628a 100644 --- a/src/northbridge/intel/sandybridge/northbridge.c +++ b/src/northbridge/intel/sandybridge/northbridge.c @@ -265,28 +265,13 @@ static void mc_read_resources(device_t dev) pci_dev_read_resources(dev); - /* We use 0xcf as an unused index for our PCIe bar so that we find it again */ buses = get_pcie_bar(&pcie_config_base); if (buses) { - struct resource *resource = new_resource(dev, 0xcf); + struct resource *resource = new_resource(dev, PCIEXBAR); mmconf_resource_init(resource, 0, pcie_config_base, buses); } } -static void mc_set_resources(device_t dev) -{ - struct resource *resource; - - /* Report the PCIe BAR */ - resource = find_resource(dev, 0xcf); - if (resource) { - report_resource_stored(dev, resource, "<mmconfig>"); - } - - /* And call the normal set_resources */ - pci_dev_set_resources(dev); -} - static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) { if (!vendor || !device) { @@ -475,7 +460,7 @@ static struct pci_operations intel_pci_ops = { static struct device_operations mc_ops = { .read_resources = mc_read_resources, - .set_resources = mc_set_resources, + .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .init = northbridge_init, .scan_bus = 0, diff --git a/src/soc/intel/sch/northbridge.c b/src/soc/intel/sch/northbridge.c index 07b17c0..e4d77f8 100644 --- a/src/soc/intel/sch/northbridge.c +++ b/src/soc/intel/sch/northbridge.c @@ -201,19 +201,6 @@ static void mc_read_resources(device_t dev) } } -static void mc_set_resources(device_t dev) -{ - struct resource *resource; - - /* Report the PCIe BAR. */ - resource = find_resource(dev, 0xcf); - if (resource) - report_resource_stored(dev, resource, "<mmconfig>"); - - /* And call the normal set_resources. */ - pci_dev_set_resources(dev); -} - static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device) { if (!vendor || !device) { @@ -231,7 +218,7 @@ static struct pci_operations intel_pci_ops = { static struct device_operations mc_ops = { .read_resources = mc_read_resources, - .set_resources = mc_set_resources, + .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .acpi_fill_ssdt_generator = generate_cpu_entries, .scan_bus = 0,
1
0
0
0
← Newer
1
...
100
101
102
103
104
105
106
...
114
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
Results per page:
10
25
50
100
200