summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 79d24a5)
raw | patch | inline | side by side (parent: 79d24a5)
author | Sourav Poddar <sourav.poddar@ti.com> | |
Wed, 7 Aug 2013 12:38:33 +0000 (18:08 +0530) | ||
committer | Somnath Mukherjee <somnath@ti.com> | |
Thu, 8 Aug 2013 13:02:39 +0000 (18:32 +0530) |
Qspi controller has a memory mapped port which can be used for
data transfers. First controller need to be configured through
configuration port, then for data read switch the controller
to memory mapped and read from the predefined location.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
data transfers. First controller need to be configured through
configuration port, then for data read switch the controller
to memory mapped and read from the predefined location.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
index afb25c4f6ce63860bc8a652a39eec59d32606c03..2c1c7f68fb5c0d7dce8dba020370f2d13735d72a 100644 (file)
flash->page_size = 256;
flash->sector_size = 256 * params->pages_per_sector;
flash->size = flash->sector_size * params->nr_sectors;
+ flash->memory_map = spi->memory_map;
return flash;
}
index 76ac1fecfa593a1a983ee07d7f2de2c530b87781..e9c6a1847e2c023c1e49eeb336ebe3186896f32f 100644 (file)
spi->quad_enable = 1;
/* Handle memory-mapped SPI */
- if (flash->memory_map)
+ if (flash->memory_map) {
+ spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MEM_MAP);
memcpy(data, flash->memory_map + offset, len);
+ spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MEM_MAP_END);
+ return 0;
+ }
page_size = flash->page_size;
page_addr = offset / page_size;
int ret = -1;
/* Handle memory-mapped SPI */
- if (flash->memory_map)
+ if (flash->memory_map) {
+ spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MEM_MAP);
memcpy(data, flash->memory_map + offset, len);
+ spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_MEM_MAP_END);
+ return 0;
+ }
cmd[0] = CMD_READ_ARRAY_FAST;
cmd[4] = 0x00;
diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c
index 12bba11629036807a30f9c1a1a9e54087dc1bb94..d314b6e3b5aae71345e6c54311dc1d22227951d5 100644 (file)
--- a/drivers/spi/ti_qspi.c
+++ b/drivers/spi/ti_qspi.c
struct qspi_slave {
struct spi_slave slave;
unsigned int mode;
- u32 cmd;
- u32 dc;
+ u32 cmd;
+ u32 dc;
};
#define to_qspi_slave(s) container_of(s, struct qspi_slave, slave)
#define QSPI_WC_BUSY (QSPI_WC | QSPI_BUSY)
#define QSPI_XFER_DONE QSPI_WC
+#define MM_SWITCH 0x01
+#define MEM_CS 0x100
+#define MEM_CS_UNSELECT 0xfffff0ff
+#define MMAP_START_ADDR 0x5c000000
+#define CORE_CTRL_IO 0x4a002558
+
+#define QSPI_CMD_READ (0x3 << 0)
+#define QSPI_CMD_READ_QUAD (0x6b << 0)
+#define QSPI_CMD_READ_FAST (0x0b << 0)
+
+#define QSPI_SETUP0_NUM_A_BYTES (0x2 << 8)
+#define QSPI_SETUP0_NUM_D_BYTES_NO_BITS (0x0 << 10)
+#define QSPI_SETUP0_NUM_D_BYTES_8_BITS (0x1 << 10)
+#define QSPI_SETUP0_READ_NORMAL (0x0 << 12)
+#define QSPI_SETUP0_READ_QUAD (0x3 << 12)
+#define QSPI_CMD_WRITE (0x2 << 16)
+#define QSPI_NUM_DUMMY_BITS (0x0 << 24)
+
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
return 1;
/* nothing to do */
}
+void spi_set_up_spi_register(struct spi_slave *slave)
+{
+ u32 memval = 0;
+
+ slave->memory_map = (void *)MMAP_START_ADDR;
+
+#ifdef CONFIG_SF_QUAD_RD
+ memval |= (QSPI_CMD_READ_QUAD | QSPI_SETUP0_NUM_A_BYTES |
+ QSPI_SETUP0_NUM_D_BYTES_8_BITS | QSPI_SETUP0_READ_QUAD |
+ QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS);
+#else
+ memval |= (QSPI_CMD_READ | QSPI_SETUP0_NUM_A_BYTES |
+ QSPI_SETUP0_NUM_D_BYTES_NO_BITS | QSPI_SETUP0_READ_NORMAL |
+ QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS);
+#endif
+ writel(memval, &qspi->spi_setup0);
+}
+
void spi_set_speed(struct spi_slave *slave, uint hz)
{
uint clk_div;
spi_set_speed(&qslave->slave, max_hz);
qslave->mode = mode;
+
+#ifdef CONFIG_MMAP
+ spi_set_up_spi_register(&qslave->slave);
+#endif
+
debug("%s: bus:%i cs:%i mode:%i\n", __func__, bus, cs, mode);
return &qslave->slave;
const uchar *txp = dout;
uchar *rxp = din;
uint status;
- int timeout;
+ int timeout, val;
debug("%s: bus:%i cs:%i bitlen:%i words:%i flags:%lx\n", __func__,
slave->bus, slave->cs, bitlen, words, flags);
- if (bitlen == 0)
- return -1;
+
+ qslave->dc = 0;
+ if (qslave->mode & SPI_CPHA)
+ qslave->dc |= QSPI_CKPHA(slave->cs);
+ if (qslave->mode & SPI_CPOL)
+ qslave->dc |= QSPI_CKPOL(slave->cs);
+ if (qslave->mode & SPI_CS_HIGH)
+ qslave->dc |= QSPI_CSPOL(slave->cs);
+
+ writel(qslave->dc, &qspi->spi_dc);
+
+ if (flags == SPI_XFER_MEM_MAP) {
+ writel(MM_SWITCH, &qspi->spi_switch);
+ val = readl(CORE_CTRL_IO);
+ val |= MEM_CS;
+ writel(val, CORE_CTRL_IO);
+ return 0;
+ } else if (flags == SPI_XFER_MEM_MAP_END) {
+ writel(~MM_SWITCH, &qspi->spi_switch);
+ val = readl(CORE_CTRL_IO);
+ val &= MEM_CS_UNSELECT;
+ writel(val, CORE_CTRL_IO);
+ return 0;
+ }
+
+ if (bitlen == 0)
+ return -1;
if (bitlen % 8) {
flags |= SPI_XFER_END;
qslave->cmd |= QSPI_3_PIN;
qslave->cmd |= 0xfff;
- /* setup device control reg */
- qslave->dc = 0;
- if (qslave->mode & SPI_CPHA)
- qslave->dc |= QSPI_CKPHA(slave->cs);
- if (qslave->mode & SPI_CPOL)
- qslave->dc |= QSPI_CKPOL(slave->cs);
- if (qslave->mode & SPI_CS_HIGH)
- qslave->dc |= QSPI_CSPOL(slave->cs);
-
while (words--) {
if (txp) {
debug("tx cmd %08x dc %08x data %02x\n",
index d5cd451fdb75677307dd163fa4caeb45a77d3f59..ab5228a8892d91e0c7f828ebc26214b8bd976d36 100644 (file)
#define CONFIG_CMD_SF
#define CONFIG_CMD_SPI
#define CONFIG_SF_QUAD_RD
-#define CONFIG_SF_DEFAULT_SPEED 12000000
+#define CONFIG_MMAP
+#define CONFIG_SF_DEFAULT_SPEED 48000000
#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3
/* SPI SPL */
diff --git a/include/spi.h b/include/spi.h
index c9277bf4d97358169bcb4ef119f621a43a391b10..087aee346a4cc9b449d16d5375fa29e5be53f2e8 100644 (file)
--- a/include/spi.h
+++ b/include/spi.h
#define SPI_XFER_BEGIN 0x01 /* Assert CS before transfer */
#define SPI_XFER_END 0x02 /* Deassert CS after transfer */
+/* Header byte that marks the start of the message */
+#define SPI_PREAMBLE_END_BYTE 0xec
+
+#define SPI_XFER_MEM_MAP 0x05
+#define SPI_XFER_MEM_MAP_END 0x06
/*-----------------------------------------------------------------------
* Representation of a SPI slave, i.e. what we're communicating with.
*
unsigned int cs;
unsigned int max_write_size;
bool quad_enable;
+ void *memory_map;
};
/*-----------------------------------------------------------------------