diff mbox

[2/2] ARM: cci: driver need big endian fixes in asm code

Message ID 1381207040-1623-3-git-send-email-victor.kamensky@linaro.org
State New
Headers show

Commit Message

vkamensky Oct. 8, 2013, 4:37 a.m. UTC
cci_enable_port_for_self written in asm and it works with h/w
registers that are in little endian format. When run in big
endian mode it needs byte swap before/after it writes/reads
to/from such registers

Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
---
 drivers/bus/arm-cci.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Dave Martin Oct. 8, 2013, 5:51 p.m. UTC | #1
On Mon, Oct 07, 2013 at 09:37:20PM -0700, Victor Kamensky wrote:
> cci_enable_port_for_self written in asm and it works with h/w
> registers that are in little endian format. When run in big
> endian mode it needs byte swap before/after it writes/reads
> to/from such registers

Lorenzo should comment on this if he's not already seen it.

> 
> Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
> ---
>  drivers/bus/arm-cci.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
> index 2009266..6db173e 100644
> --- a/drivers/bus/arm-cci.c
> +++ b/drivers/bus/arm-cci.c
> @@ -281,6 +281,9 @@ asmlinkage void __naked cci_enable_port_for_self(void)
>  	/* Enable the CCI port */
>  "	ldr	r0, [r0, %[offsetof_port_phys]] \n"
>  "	mov	r3, #"__stringify(CCI_ENABLE_REQ)" \n"
> +#ifdef __ARMEB__
> +"	rev	r3, r3 \n"
> +#endif /* __ARMEB__ */

Hmmm, this is a bit ugly, but we can't easily use ARM_BE8() here.

That would be more easily solved if this was a separate .S file...

Maybe it's not worth it.

Cheers
---Dave

>  "	str	r3, [r0, #"__stringify(CCI_PORT_CTRL)"] \n"
>  
>  	/* poll the status reg for completion */
> @@ -288,6 +291,9 @@ asmlinkage void __naked cci_enable_port_for_self(void)
>  "	ldr	r0, [r1] \n"
>  "	ldr	r0, [r0, r1]		@ cci_ctrl_base \n"
>  "4:	ldr	r1, [r0, #"__stringify(CCI_CTRL_STATUS)"] \n"
> +#ifdef __ARMEB__
> +"	rev	r1, r1 \n"
> +#endif /* __ARMEB__ */
>  "	tst	r1, #1 \n"
>  "	bne	4b \n"
>  
> -- 
> 1.8.1.4
> 
> 
> _______________________________________________
> linaro-kernel mailing list
> linaro-kernel@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-kernel
Nicolas Pitre Oct. 8, 2013, 5:57 p.m. UTC | #2
On Tue, 8 Oct 2013, Dave Martin wrote:

> On Mon, Oct 07, 2013 at 09:37:20PM -0700, Victor Kamensky wrote:
> > cci_enable_port_for_self written in asm and it works with h/w
> > registers that are in little endian format. When run in big
> > endian mode it needs byte swap before/after it writes/reads
> > to/from such registers
> 
> Lorenzo should comment on this if he's not already seen it.
> 
> > 
> > Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
> > ---
> >  drivers/bus/arm-cci.c | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
> > index 2009266..6db173e 100644
> > --- a/drivers/bus/arm-cci.c
> > +++ b/drivers/bus/arm-cci.c
> > @@ -281,6 +281,9 @@ asmlinkage void __naked cci_enable_port_for_self(void)
> >  	/* Enable the CCI port */
> >  "	ldr	r0, [r0, %[offsetof_port_phys]] \n"
> >  "	mov	r3, #"__stringify(CCI_ENABLE_REQ)" \n"
> > +#ifdef __ARMEB__
> > +"	rev	r3, r3 \n"
> > +#endif /* __ARMEB__ */
> 
> Hmmm, this is a bit ugly, but we can't easily use ARM_BE8() here.

In any case, it would be more efficient to swap the CCI_ENABLE_REQ 
constant at compile time rather than doing it at run time with an extra 
instruction.


Nicolas
vkamensky Oct. 8, 2013, 6:14 p.m. UTC | #3
Hi Nicolas,

On 8 October 2013 10:57, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> On Tue, 8 Oct 2013, Dave Martin wrote:
>
>> On Mon, Oct 07, 2013 at 09:37:20PM -0700, Victor Kamensky wrote:
>> > cci_enable_port_for_self written in asm and it works with h/w
>> > registers that are in little endian format. When run in big
>> > endian mode it needs byte swap before/after it writes/reads
>> > to/from such registers
>>
>> Lorenzo should comment on this if he's not already seen it.
>>
>> >
>> > Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
>> > ---
>> >  drivers/bus/arm-cci.c | 6 ++++++
>> >  1 file changed, 6 insertions(+)
>> >
>> > diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
>> > index 2009266..6db173e 100644
>> > --- a/drivers/bus/arm-cci.c
>> > +++ b/drivers/bus/arm-cci.c
>> > @@ -281,6 +281,9 @@ asmlinkage void __naked cci_enable_port_for_self(void)
>> >     /* Enable the CCI port */
>> >  "  ldr     r0, [r0, %[offsetof_port_phys]] \n"
>> >  "  mov     r3, #"__stringify(CCI_ENABLE_REQ)" \n"
>> > +#ifdef __ARMEB__
>> > +"  rev     r3, r3 \n"
>> > +#endif /* __ARMEB__ */
>>
>> Hmmm, this is a bit ugly, but we can't easily use ARM_BE8() here.
>
> In any case, it would be more efficient to swap the CCI_ENABLE_REQ
> constant at compile time rather than doing it at run time with an extra
> instruction.

I could try to do this but it would require introducing another constant,
because CCI_ENABLE_REQ is used in another place in writel_relaxed
call which will do byteswap inside. Is such run-time optimization really
worth it compared to code readability. Please let me know.
I am OK either way. Personally I thought that run-time byteswap would
be more readable.

Also I am concerned how can I compile time byteswap CCI_ENABLE_REQ
in context of its being used with __stringify ...  Wondering it should be
stringfied into real number not long expression

Thanks,
Victor

>
> Nicolas
Nicolas Pitre Oct. 8, 2013, 6:26 p.m. UTC | #4
On Tue, 8 Oct 2013, Victor Kamensky wrote:

> Hi Nicolas,
> 
> On 8 October 2013 10:57, Nicolas Pitre <nicolas.pitre@linaro.org> wrote:
> > On Tue, 8 Oct 2013, Dave Martin wrote:
> >
> >> On Mon, Oct 07, 2013 at 09:37:20PM -0700, Victor Kamensky wrote:
> >> > cci_enable_port_for_self written in asm and it works with h/w
> >> > registers that are in little endian format. When run in big
> >> > endian mode it needs byte swap before/after it writes/reads
> >> > to/from such registers
> >>
> >> Lorenzo should comment on this if he's not already seen it.
> >>
> >> >
> >> > Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org>
> >> > ---
> >> >  drivers/bus/arm-cci.c | 6 ++++++
> >> >  1 file changed, 6 insertions(+)
> >> >
> >> > diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
> >> > index 2009266..6db173e 100644
> >> > --- a/drivers/bus/arm-cci.c
> >> > +++ b/drivers/bus/arm-cci.c
> >> > @@ -281,6 +281,9 @@ asmlinkage void __naked cci_enable_port_for_self(void)
> >> >     /* Enable the CCI port */
> >> >  "  ldr     r0, [r0, %[offsetof_port_phys]] \n"
> >> >  "  mov     r3, #"__stringify(CCI_ENABLE_REQ)" \n"
> >> > +#ifdef __ARMEB__
> >> > +"  rev     r3, r3 \n"
> >> > +#endif /* __ARMEB__ */
> >>
> >> Hmmm, this is a bit ugly, but we can't easily use ARM_BE8() here.
> >
> > In any case, it would be more efficient to swap the CCI_ENABLE_REQ
> > constant at compile time rather than doing it at run time with an extra
> > instruction.
> 
> I could try to do this but it would require introducing another constant,
> because CCI_ENABLE_REQ is used in another place in writel_relaxed
> call which will do byteswap inside. Is such run-time optimization really
> worth it compared to code readability. Please let me know.
> I am OK either way. Personally I thought that run-time byteswap would
> be more readable.

You're probably right.

> Also I am concerned how can I compile time byteswap CCI_ENABLE_REQ
> in context of its being used with __stringify ...  Wondering it should be
> stringfied into real number not long expression

The assembler can accept a subset of the simple C operands so it is 
possible that this could just work.  Otherwise it is best to go with a 
runtime swap.


Nicolas
diff mbox

Patch

diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 2009266..6db173e 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -281,6 +281,9 @@  asmlinkage void __naked cci_enable_port_for_self(void)
 	/* Enable the CCI port */
 "	ldr	r0, [r0, %[offsetof_port_phys]] \n"
 "	mov	r3, #"__stringify(CCI_ENABLE_REQ)" \n"
+#ifdef __ARMEB__
+"	rev	r3, r3 \n"
+#endif /* __ARMEB__ */
 "	str	r3, [r0, #"__stringify(CCI_PORT_CTRL)"] \n"
 
 	/* poll the status reg for completion */
@@ -288,6 +291,9 @@  asmlinkage void __naked cci_enable_port_for_self(void)
 "	ldr	r0, [r1] \n"
 "	ldr	r0, [r0, r1]		@ cci_ctrl_base \n"
 "4:	ldr	r1, [r0, #"__stringify(CCI_CTRL_STATUS)"] \n"
+#ifdef __ARMEB__
+"	rev	r1, r1 \n"
+#endif /* __ARMEB__ */
 "	tst	r1, #1 \n"
 "	bne	4b \n"