summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2021-02-23 14:47:37 +1030
committerJoel Stanley <joel@jms.id.au>2021-06-04 14:18:17 +0930
commit4134cb9165786761b28eef4c6b945f13bf54d623 (patch)
tree876f378776976d4da1e0d4b26df6098eb22ccffe
parent910810945707fe9877ca86a0dca4e585fd05e37b (diff)
fsi: aspeed: Emit fewer barriers in opb operations
When setting up a read or write to the OPB memory space, we must perform five or six AHB writes. The ordering of these up until the trigger write does not matter, so use writel_relaxed. The generated code goes from (Debian GCC 10.2.1-6): mov r8, r3 mcr 15, 0, sl, cr7, cr10, {4} str sl, [r6, #20] mcr 15, 0, sl, cr7, cr10, {4} str r3, [r6, #24] mcr 15, 0, sl, cr7, cr10, {4} str r1, [r6, #28] mcr 15, 0, sl, cr7, cr10, {4} str r2, [r6, #32] mcr 15, 0, sl, cr7, cr10, {4} mov r1, #1 str r1, [r6, #64] ; 0x40 mcr 15, 0, sl, cr7, cr10, {4} str r1, [r6, #4] to this: str r3, [r7, #20] str r2, [r7, #24] str r1, [r7, #28] str r3, [r7, #64] mov r8, #0 mcr 15, 0, r8, cr7, cr10, {4} str r3, [r7, #4] Signed-off-by: Joel Stanley <joel@jms.id.au> Acked-by: Jeremy Kerr <jk@ozlabs.org> Reviewed-by: Eddie James <eajames@linux.ibm.com> Tested-by: Eddie James <eajames@linux.ibm.com> Link: https://lore.kernel.org/r/20210223041737.171274-1-joel@jms.id.au Signed-off-by: Joel Stanley <joel@jms.id.au>
-rw-r--r--drivers/fsi/fsi-master-aspeed.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index dbad73162c83..1b6dd2f6aae0 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -101,11 +101,15 @@ static int __opb_write(struct fsi_master_aspeed *aspeed, u32 addr,
u32 reg, status;
int ret;
- writel(CMD_WRITE, base + OPB0_RW);
- writel(transfer_size, base + OPB0_XFER_SIZE);
- writel(addr, base + OPB0_FSI_ADDR);
- writel(val, base + OPB0_FSI_DATA_W);
- writel(0x1, base + OPB_IRQ_CLEAR);
+ /*
+ * The ordering of these writes up until the trigger
+ * write does not matter, so use writel_relaxed.
+ */
+ writel_relaxed(CMD_WRITE, base + OPB0_RW);
+ writel_relaxed(transfer_size, base + OPB0_XFER_SIZE);
+ writel_relaxed(addr, base + OPB0_FSI_ADDR);
+ writel_relaxed(val, base + OPB0_FSI_DATA_W);
+ writel_relaxed(0x1, base + OPB_IRQ_CLEAR);
writel(0x1, base + OPB_TRIGGER);
ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg,
@@ -149,10 +153,14 @@ static int __opb_read(struct fsi_master_aspeed *aspeed, uint32_t addr,
u32 result, reg;
int status, ret;
- writel(CMD_READ, base + OPB0_RW);
- writel(transfer_size, base + OPB0_XFER_SIZE);
- writel(addr, base + OPB0_FSI_ADDR);
- writel(0x1, base + OPB_IRQ_CLEAR);
+ /*
+ * The ordering of these writes up until the trigger
+ * write does not matter, so use writel_relaxed.
+ */
+ writel_relaxed(CMD_READ, base + OPB0_RW);
+ writel_relaxed(transfer_size, base + OPB0_XFER_SIZE);
+ writel_relaxed(addr, base + OPB0_FSI_ADDR);
+ writel_relaxed(0x1, base + OPB_IRQ_CLEAR);
writel(0x1, base + OPB_TRIGGER);
ret = readl_poll_timeout(base + OPB_IRQ_STATUS, reg,