diff mbox series

fsi: aspeed: Emit fewer barriers in opb operations

Message ID 20210223041737.171274-1-joel@jms.id.au
State Accepted, archived
Headers show
Series fsi: aspeed: Emit fewer barriers in opb operations | expand

Commit Message

Joel Stanley Feb. 23, 2021, 4:17 a.m. UTC
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>
---
 drivers/fsi/fsi-master-aspeed.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

Comments

Jeremy Kerr Feb. 23, 2021, 6:02 a.m. UTC | #1
Hey Joel,

diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index 90dbe58ca1ed..09fff86b2bac 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -101,11 +101,11 @@ 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);
+       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);

Future-joel is going to be angry at you if you don't add a comment
about the ordering requirements there.

Otherwise,

Acked-by: Jeremy Kerr <jk@ozlabs.org>

Cheers,


Jeremy
Eddie James April 13, 2021, 8:08 p.m. UTC | #2
On Tue, 2021-02-23 at 14:47 +1030, Joel Stanley wrote:
> 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.

Reviewed-by: Eddie James <eajames@linux.ibm.com>

I have also tested this patch on hardware, so

Tested-by: Eddie James <eajames@linux.ibm.com>

> 
> 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>
> ---
>  drivers/fsi/fsi-master-aspeed.c | 18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-
> master-aspeed.c
> index 90dbe58ca1ed..09fff86b2bac 100644
> --- a/drivers/fsi/fsi-master-aspeed.c
> +++ b/drivers/fsi/fsi-master-aspeed.c
> @@ -101,11 +101,11 @@ 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);
> +	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 +149,10 @@ 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);
> +	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,
diff mbox series

Patch

diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index 90dbe58ca1ed..09fff86b2bac 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -101,11 +101,11 @@  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);
+	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 +149,10 @@  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);
+	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,