Gabe Black (gabeblack@chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3710
-gerrit
commit 7486e1a729c0cf3307a3959614eb740a37dea903 Author: Hung-Te Lin hungte@chromium.org Date: Wed Jun 26 20:16:13 2013 +0800
armv7/exynos5420: Change SPI module to standard <spi-generic> interface.
The SPI module in Exynos 5420 didn't follow Coreboot's SPI API standard (spi-generic.h) and will be a problem when we want to share SPI drivers.
This commit replaces exynos_spi_* by spi_* functions.
Note, exynos_spi_read is kept and changed to a static function because its usage is different from the standard API "spi_xfer".
Change-Id: I6de301bc6b46a09f87b0336c60247fedbe844ca3 Signed-off-by: Hung-Te Lin hungte@chromium.org Signed-off-by: Gabe Black gabeblack@chromium.org --- src/cpu/samsung/exynos5420/spi.c | 89 ++++++++++++++++++++++++++++++++++------ src/cpu/samsung/exynos5420/spi.h | 5 --- 2 files changed, 76 insertions(+), 18 deletions(-)
diff --git a/src/cpu/samsung/exynos5420/spi.c b/src/cpu/samsung/exynos5420/spi.c index 35fccb2..e3029b8 100644 --- a/src/cpu/samsung/exynos5420/spi.c +++ b/src/cpu/samsung/exynos5420/spi.c @@ -22,17 +22,61 @@ #include <arch/io.h> #include <stdlib.h> #include <assert.h> +#include <spi_flash.h>
+#include "cpu.h" #include "spi.h"
-#define EXYNOS_BASE_SPI1 ((void *)0x12d30000) - #if defined(CONFIG_DEBUG_SPI) && CONFIG_DEBUG_SPI # define DEBUG_SPI(x,...) printk(BIOS_DEBUG, "EXYNOS_SPI: " x) #else # define DEBUG_SPI(x,...) #endif
+struct exynos_spi_slave { + struct spi_slave slave; + struct exynos_spi *regs; + unsigned int fifo_size; + uint8_t half_duplex; + uint8_t frame_header; /* header byte to detect in half-duplex mode. */ +}; + +static inline struct exynos_spi_slave *to_exynos_spi(struct spi_slave *slave) +{ + return container_of(slave, struct exynos_spi_slave, slave); +} + +void spi_init(void) +{ + printk(BIOS_INFO, "Exynos SPI driver initiated.\n"); +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + // TODO(hungte) Provide Exynos SPI device setup. + return NULL; +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + // TODO(hungte) Detect and check if BUS/CS is valid. + return 0; +} + +void spi_cs_activate(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. + clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + struct exynos_spi *regs = to_exynos_spi(slave)->regs; + setbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); +} + static void exynos_spi_rx_tx(struct exynos_spi *regs, int todo, void *dinp, void const *doutp, int i) { @@ -75,8 +119,11 @@ static void exynos_spi_rx_tx(struct exynos_spi *regs, int todo, }
/* set up SPI channel */ -int exynos_spi_open(struct exynos_spi *regs) +int spi_claim_bus(struct spi_slave *slave) { + struct exynos_spi_slave *espi = to_exynos_spi(slave); + struct exynos_spi *regs = espi->regs; + /* set the spi1 GPIO */
/* set pktcnt and enable it */ @@ -103,8 +150,17 @@ int exynos_spi_open(struct exynos_spi *regs) return 0; }
-int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off) +int spi_xfer(struct spi_slave *slave, const void *dout, unsigned int bitsout, + void *din, unsigned int bitsin) +{ + // TODO(hungte) Invoke exynos_spi_rx_tx to transfer data. + return -1; +} + +static int exynos_spi_read(struct spi_slave *slave, void *dest, uint32_t len, + uint32_t off) { + struct exynos_spi *regs = to_exynos_spi(slave)->regs; int upto, todo; int i; clrbits_le32(®s->cs_reg, SPI_SLAVE_SIG_INACT); /* CS low */ @@ -125,8 +181,9 @@ int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off) return len; }
-int exynos_spi_close(struct exynos_spi *regs) +void spi_release_bus(struct spi_slave *slave) { + struct exynos_spi *regs = to_exynos_spi(slave)->regs; /* * Let put controller mode to BYTE as * SPI driver does not support WORD mode yet @@ -142,25 +199,25 @@ int exynos_spi_close(struct exynos_spi *regs) clrsetbits_le32(®s->ch_cfg, SPI_CH_HS_EN, SPI_CH_RST); clrbits_le32(®s->ch_cfg, SPI_CH_RST); clrbits_le32(®s->ch_cfg, SPI_TX_CH_ON | SPI_RX_CH_ON); - return 0; }
// SPI as CBFS media. struct exynos_spi_media { - struct exynos_spi *regs; + struct spi_slave *slave; struct cbfs_simple_buffer buffer; };
static int exynos_spi_cbfs_open(struct cbfs_media *media) { struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; DEBUG_SPI("exynos_spi_cbfs_open\n"); - return exynos_spi_open(spi->regs); + return spi_claim_bus(spi->slave); }
static int exynos_spi_cbfs_close(struct cbfs_media *media) { struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; DEBUG_SPI("exynos_spi_cbfs_close\n"); - return exynos_spi_close(spi->regs); + spi_release_bus(spi->slave); + return 0; }
static size_t exynos_spi_cbfs_read(struct cbfs_media *media, void *dest, @@ -168,10 +225,10 @@ static size_t exynos_spi_cbfs_read(struct cbfs_media *media, void *dest, struct exynos_spi_media *spi = (struct exynos_spi_media*)media->context; int bytes; DEBUG_SPI("exynos_spi_cbfs_read(%u)\n", count); - bytes = exynos_spi_read(spi->regs, dest, count, offset); + bytes = exynos_spi_read(spi->slave, dest, count, offset); // Flush and re-open the device. - exynos_spi_close(spi->regs); - exynos_spi_open(spi->regs); + spi_release_bus(spi->slave); + spi_claim_bus(spi->slave); return bytes; }
@@ -197,9 +254,15 @@ int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, size_t buffer_size) { // TODO Replace static variable to support multiple streams. static struct exynos_spi_media context; + static struct exynos_spi_slave eslave = { + .slave = { .bus = 1, .rw = SPI_READ_FLAG, }, + .regs = samsung_get_base_spi1(), + .fifo_size = 64, + .half_duplex = 0, + }; DEBUG_SPI("initialize_exynos_spi_cbfs_media\n");
- context.regs = EXYNOS_BASE_SPI1; + context.slave = &eslave.slave; context.buffer.allocated = context.buffer.last_allocate = 0; context.buffer.buffer = buffer_address; context.buffer.size = buffer_size; diff --git a/src/cpu/samsung/exynos5420/spi.h b/src/cpu/samsung/exynos5420/spi.h index faf82b0..94b4fda 100644 --- a/src/cpu/samsung/exynos5420/spi.h +++ b/src/cpu/samsung/exynos5420/spi.h @@ -86,11 +86,6 @@ struct exynos_spi { #define SPI_RX_BYTE_SWAP (1 << 6) #define SPI_RX_HWORD_SWAP (1 << 7)
-/* API */ -int exynos_spi_open(struct exynos_spi *regs); -int exynos_spi_read(struct exynos_spi *regs, void *dest, u32 len, u32 off); -int exynos_spi_close(struct exynos_spi *regs); - /* Serve as CBFS media source */ int initialize_exynos_spi_cbfs_media(struct cbfs_media *media, void *buffer_address,