Skip to content

Commit d97735d

Browse files
RajuRangojubroonie
authored andcommitted
spi: spi_amd: Optimize IO operations
Read and write the maximum number of data bytes at once, rather than byte by byte. This improves AMD SPI controller driver performance by reducing the time required to access FIFO registers. For example, with the new changes, 64 bytes of data from the FIFO queue can be read in 8 read calls (8 bytes per call) instead of 64 read calls(1 byte per call). Co-developed-by: Krishnamoorthi M <krishnamoorthi.m@amd.com> Signed-off-by: Krishnamoorthi M <krishnamoorthi.m@amd.com> Co-developed-by: Akshata MukundShetty <akshata.mukundshetty@amd.com> Signed-off-by: Akshata MukundShetty <akshata.mukundshetty@amd.com> Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com> Link: https://patch.msgid.link/20240925133644.2922359-6-Raju.Rangoju@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 8cd9141 commit d97735d

1 file changed

Lines changed: 41 additions & 12 deletions

File tree

drivers/spi/spi-amd.c

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/acpi.h>
1010
#include <linux/delay.h>
1111
#include <linux/init.h>
12+
#include <linux/io-64-nonatomic-lo-hi.h>
1213
#include <linux/iopoll.h>
1314
#include <linux/module.h>
1415
#include <linux/platform_device.h>
@@ -140,6 +141,16 @@ static inline void amd_spi_writereg32(struct amd_spi *amd_spi, int idx, u32 val)
140141
writel(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx));
141142
}
142143

144+
static inline u64 amd_spi_readreg64(struct amd_spi *amd_spi, int idx)
145+
{
146+
return readq((u8 __iomem *)amd_spi->io_remap_addr + idx);
147+
}
148+
149+
static inline void amd_spi_writereg64(struct amd_spi *amd_spi, int idx, u64 val)
150+
{
151+
writeq(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx));
152+
}
153+
143154
static inline void amd_spi_setclear_reg32(struct amd_spi *amd_spi, int idx, u32 set, u32 clear)
144155
{
145156
u32 tmp = amd_spi_readreg32(amd_spi, idx);
@@ -448,15 +459,23 @@ static void amd_spi_mem_data_out(struct amd_spi *amd_spi,
448459
const struct spi_mem_op *op)
449460
{
450461
int base_addr = AMD_SPI_FIFO_BASE + op->addr.nbytes;
451-
u8 *buf = (u8 *)op->data.buf.out;
462+
u64 *buf_64 = (u64 *)op->data.buf.out;
452463
u32 nbytes = op->data.nbytes;
464+
u32 left_data = nbytes;
465+
u8 *buf;
453466
int i;
454467

455468
amd_spi_set_opcode(amd_spi, op->cmd.opcode);
456469
amd_spi_set_addr(amd_spi, op);
457470

458-
for (i = 0; i < nbytes; i++)
459-
amd_spi_writereg8(amd_spi, (base_addr + i), buf[i]);
471+
for (i = 0; left_data >= 8; i++, left_data -= 8)
472+
amd_spi_writereg64(amd_spi, base_addr + op->dummy.nbytes + (i * 8), *buf_64++);
473+
474+
buf = (u8 *)buf_64;
475+
for (i = 0; i < left_data; i++) {
476+
amd_spi_writereg8(amd_spi, base_addr + op->dummy.nbytes + nbytes + i - left_data,
477+
buf[i]);
478+
}
460479

461480
amd_spi_set_tx_count(amd_spi, op->addr.nbytes + op->data.nbytes);
462481
amd_spi_set_rx_count(amd_spi, 0);
@@ -467,23 +486,33 @@ static void amd_spi_mem_data_out(struct amd_spi *amd_spi,
467486
static void amd_spi_mem_data_in(struct amd_spi *amd_spi,
468487
const struct spi_mem_op *op)
469488
{
470-
int offset = (op->addr.nbytes == 0) ? 0 : 1;
471-
u8 *buf = (u8 *)op->data.buf.in;
489+
int base_addr = AMD_SPI_FIFO_BASE + op->addr.nbytes;
490+
u64 *buf_64 = (u64 *)op->data.buf.in;
472491
u32 nbytes = op->data.nbytes;
473-
int base_addr, i;
474-
475-
base_addr = AMD_SPI_FIFO_BASE + op->addr.nbytes + offset;
492+
u32 left_data = nbytes;
493+
u8 *buf;
494+
int i;
476495

477496
amd_spi_set_opcode(amd_spi, op->cmd.opcode);
478497
amd_spi_set_addr(amd_spi, op);
479-
amd_spi_set_tx_count(amd_spi, op->addr.nbytes);
480-
amd_spi_set_rx_count(amd_spi, op->data.nbytes + 1);
498+
amd_spi_set_tx_count(amd_spi, op->addr.nbytes + op->dummy.nbytes);
499+
500+
for (i = 0; i < op->dummy.nbytes; i++)
501+
amd_spi_writereg8(amd_spi, (base_addr + i), 0xff);
502+
503+
amd_spi_set_rx_count(amd_spi, op->data.nbytes);
481504
amd_spi_clear_fifo_ptr(amd_spi);
482505
amd_spi_execute_opcode(amd_spi);
483506
amd_spi_busy_wait(amd_spi);
484507

485-
for (i = 0; i < nbytes; i++)
486-
buf[i] = amd_spi_readreg8(amd_spi, base_addr + i);
508+
for (i = 0; left_data >= 8; i++, left_data -= 8)
509+
*buf_64++ = amd_spi_readreg64(amd_spi, base_addr + op->dummy.nbytes +
510+
(i * 8));
511+
512+
buf = (u8 *)buf_64;
513+
for (i = 0; i < left_data; i++)
514+
buf[i] = amd_spi_readreg8(amd_spi, base_addr + op->dummy.nbytes +
515+
nbytes + i - left_data);
487516
}
488517

489518
static int amd_spi_exec_mem_op(struct spi_mem *mem,

0 commit comments

Comments
 (0)