diff mbox

[v8,2/2] arm-soc: Add support for arm-based tango4 platforms

Message ID 56377F09.6050805@sigmadesigns.com (mailing list archive)
State New, archived
Headers show

Commit Message

Marc Gonzalez Nov. 2, 2015, 3:19 p.m. UTC
Add support for Sigma Designs ARM-based Tango4 "Secure Media Processor"
platforms (i.e. smp8734, smp8756, smp8758, smp8759) built around the
Cortex-A9 MPCore r3p0 (dual-core SoCs, except the 8756).

Support for older MIPS-based platforms can be found elsewhere:
https://github.com/mansr/linux-tangox

Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
---
 arch/arm/Kconfig              |  2 ++
 arch/arm/Makefile             |  1 +
 arch/arm/mach-tangox/Kconfig  | 12 ++++++++++++
 arch/arm/mach-tangox/Makefile |  2 ++
 arch/arm/mach-tangox/setup.c  | 32 ++++++++++++++++++++++++++++++++
 arch/arm/mach-tangox/smc.S    |  9 +++++++++
 arch/arm/mach-tangox/smc.h    |  5 +++++
 7 files changed, 63 insertions(+)
 create mode 100644 arch/arm/mach-tangox/Kconfig
 create mode 100644 arch/arm/mach-tangox/Makefile
 create mode 100644 arch/arm/mach-tangox/setup.c
 create mode 100644 arch/arm/mach-tangox/smc.S
 create mode 100644 arch/arm/mach-tangox/smc.h

Comments

Måns Rullgård Nov. 2, 2015, 4:22 p.m. UTC | #1
Marc Gonzalez <marc_gonzalez@sigmadesigns.com> writes:

> diff --git a/arch/arm/mach-tangox/setup.c b/arch/arm/mach-tangox/setup.c
> new file mode 100644
> index 000000000000..a90e04140a0e
> --- /dev/null
> +++ b/arch/arm/mach-tangox/setup.c
> @@ -0,0 +1,32 @@
> +#include <linux/smp.h>
> +#include <asm/mach/arch.h>
> +#include <asm/hardware/cache-l2x0.h>
> +#include "smc.h"
> +
> +static int tango4_boot_secondary(unsigned int cpu, struct task_struct *idle)
> +{
> +	tango_set_aux_boot_addr(virt_to_phys(secondary_startup));
> +	tango_start_aux_core();
> +	return 0;
> +}
> +
> +static struct smp_operations tango4_smp_ops __initdata = {
> +	.smp_boot_secondary	= tango4_boot_secondary,
> +};
> +
> +CPU_METHOD_OF_DECLARE(tango4_smp, "sigma,tango4-smp", &tango4_smp_ops);

Unless I'm missing something, you should enable the SCU before starting
secondary CPUs.  It's also a good idea to structure the code with
separate prepare and boot functions even if all the current chips are
only dual-core.

> +static void tango_l2c_write(unsigned long val, unsigned int reg)
> +{
> +	pr_debug("%s: reg=0x%x val=0x%lx\n", __func__, reg, val);
> +	if (reg == L2X0_CTRL)
> +		tango_set_l2_control(val);

What about other registers?  Does the firmware support setting the
prefetch control register?

> +}
> +
> +static const char *tango_dt_compat[] = { "sigma,tango4", NULL };
> +
> +DT_MACHINE_START(TANGO_DT, "Sigma Tango DT")
> +	.dt_compat	= tango_dt_compat,
> +	.l2c_aux_mask	= ~0,
> +	.l2c_write_sec	= tango_l2c_write,
> +MACHINE_END
> diff --git a/arch/arm/mach-tangox/smc.S b/arch/arm/mach-tangox/smc.S
> new file mode 100644
> index 000000000000..35f9623aedb1
> --- /dev/null
> +++ b/arch/arm/mach-tangox/smc.S
> @@ -0,0 +1,9 @@
> +#include <linux/linkage.h>
> +
> +ENTRY(tango_smc)
> +	push	{lr}
> +	mov	ip, r1
> +	dsb

Did you ever get a straight answer on the dsb here?

> +	smc	#0
> +	pop	{pc}
> +ENDPROC(tango_smc)
> diff --git a/arch/arm/mach-tangox/smc.h b/arch/arm/mach-tangox/smc.h
> new file mode 100644
> index 000000000000..4e704dcf8da8
> --- /dev/null
> +++ b/arch/arm/mach-tangox/smc.h
> @@ -0,0 +1,5 @@
> +extern int tango_smc(unsigned int val, unsigned int service);
> +
> +#define tango_set_l2_control(val)	tango_smc(val, 0x102)
> +#define tango_start_aux_core()		tango_smc(666, 0x104)

666?

> +#define tango_set_aux_boot_addr(val)	tango_smc((unsigned int)val, 0x105)
> -- 
> 2.4.5
Marc Gonzalez Nov. 2, 2015, 5:33 p.m. UTC | #2
On 02/11/2015 17:22, Måns Rullgård wrote:

> Unless I'm missing something, you should enable the SCU before starting
> secondary CPUs.  It's also a good idea to structure the code with
> separate prepare and boot functions even if all the current chips are
> only dual-core.

About the SCU: I will check with the firmware author.
About prepare: this is the firmware's responsibility.
(Not all chips are dual-core, the 8756 is single-core.)

> What about other registers?  Does the firmware support setting the
> prefetch control register?

Yes, after masking out some bits.
My port uses the firmware-supplied value.

Regards.
Måns Rullgård Nov. 2, 2015, 6:01 p.m. UTC | #3
Marc Gonzalez <marc_gonzalez@sigmadesigns.com> writes:

> On 02/11/2015 17:22, Måns Rullgård wrote:
>
>> Unless I'm missing something, you should enable the SCU before starting
>> secondary CPUs.  It's also a good idea to structure the code with
>> separate prepare and boot functions even if all the current chips are
>> only dual-core.
>
> About the SCU: I will check with the firmware author.
> About prepare: this is the firmware's responsibility.
> (Not all chips are dual-core, the 8756 is single-core.)

Then the DT should say so.

Rule 0: never trust the firmware.

>> What about other registers?  Does the firmware support setting the
>> prefetch control register?
>
> Yes, after masking out some bits.

Then you should provide the kernel with a means of doing that.  Is the
SMC ID from OMAP4 correct?
Mark Rutland Nov. 2, 2015, 6:26 p.m. UTC | #4
> > +ENTRY(tango_smc)
> > +	push	{lr}
> > +	mov	ip, r1
> > +	dsb
> 
> Did you ever get a straight answer on the dsb here?

We didn't. Having a look just now, the earliest example appears to be
in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
rationale.

Given that the MMU is on (and speculative accesses are permitted) I
can't see what the DSB achieves -- it can't quiesce the memory system.

Santosh, any idea?

Thanks,
Mark.

> > +	smc	#0
> > +	pop	{pc}
> > +ENDPROC(tango_smc)

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2009-December/005815.html
Måns Rullgård Nov. 2, 2015, 6:30 p.m. UTC | #5
Mark Rutland <mark.rutland@arm.com> writes:

>> > +ENTRY(tango_smc)
>> > +	push	{lr}
>> > +	mov	ip, r1
>> > +	dsb
>> 
>> Did you ever get a straight answer on the dsb here?
>
> We didn't. Having a look just now, the earliest example appears to be
> in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
> rationale.

My guess is it was added out of frustration during early OMAP
development and forgotten.  Then it became cargo cult.
Santosh Shilimkar Nov. 2, 2015, 6:37 p.m. UTC | #6
On 11/2/2015 10:26 AM, Mark Rutland wrote:
>>> +ENTRY(tango_smc)
>>> +	push	{lr}
>>> +	mov	ip, r1
>>> +	dsb
>>
>> Did you ever get a straight answer on the dsb here?
>
> We didn't. Having a look just now, the earliest example appears to be
> in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
> rationale.
>
> Given that the MMU is on (and speculative accesses are permitted) I
> can't see what the DSB achieves -- it can't quiesce the memory system.
>
> Santosh, any idea?
>
IIRC, it was requirement from the OMAP ROM code to have a dsb before
we call the SMC routine. I can't recollect more than that now.

Regards,
Santosh
Marc Gonzalez Nov. 3, 2015, 8:34 a.m. UTC | #7
Santosh Shilimkar wrote:

> Mark Rutland wrote:
> 
>> We didn't. Having a look just now, the earliest example appears to be
>> in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
>> rationale.
>> 
>> Given that the MMU is on (and speculative accesses are permitted) I
>> can't see what the DSB achieves -- it can't quiesce the memory system.
>> 
>> Santosh, any idea?
>
> IIRC, it was requirement from the OMAP ROM code to have a dsb before
> we call the SMC routine. I can't recollect more than that now.

In that case, shouldn't dsb have been added to the ROM code,
on the "other side" of the smc, so as to not depend on Linux
code "getting it right"?

Regards.
Måns Rullgård Nov. 3, 2015, 10:12 a.m. UTC | #8
Marc Gonzalez <marc_gonzalez@sigmadesigns.com> writes:

> Santosh Shilimkar wrote:
>
>> Mark Rutland wrote:
>> 
>>> We didn't. Having a look just now, the earliest example appears to be
>>> in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
>>> rationale.
>>> 
>>> Given that the MMU is on (and speculative accesses are permitted) I
>>> can't see what the DSB achieves -- it can't quiesce the memory system.
>>> 
>>> Santosh, any idea?
>>
>> IIRC, it was requirement from the OMAP ROM code to have a dsb before
>> we call the SMC routine. I can't recollect more than that now.
>
> In that case, shouldn't dsb have been added to the ROM code,
> on the "other side" of the smc, so as to not depend on Linux
> code "getting it right"?

You're new to this, aren't you? :)
Santosh Shilimkar Nov. 3, 2015, 4:37 p.m. UTC | #9
On 11/3/2015 2:12 AM, Måns Rullgård wrote:
> Marc Gonzalez <marc_gonzalez@sigmadesigns.com> writes:
>
>> Santosh Shilimkar wrote:
>>
>>> Mark Rutland wrote:
>>>
>>>> We didn't. Having a look just now, the earliest example appears to be
>>>> in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
>>>> rationale.
>>>>
>>>> Given that the MMU is on (and speculative accesses are permitted) I
>>>> can't see what the DSB achieves -- it can't quiesce the memory system.
>>>>
>>>> Santosh, any idea?
>>>
>>> IIRC, it was requirement from the OMAP ROM code to have a dsb before
>>> we call the SMC routine. I can't recollect more than that now.
>>
>> In that case, shouldn't dsb have been added to the ROM code,
>> on the "other side" of the smc, so as to not depend on Linux
>> code "getting it right"?
>
> You're new to this, aren't you? :)
>
:-) Indeed. ROM code is burned into the chip and can't be changed.

Regards,
Santosh
Marc Gonzalez Nov. 3, 2015, 5:04 p.m. UTC | #10
On 03/11/2015 17:37, Santosh Shilimkar wrote:
> On 11/3/2015 2:12 AM, Måns Rullgård wrote:
>> Marc Gonzalez writes:
>>
>>> Santosh Shilimkar wrote:
>>>
>>>> Mark Rutland wrote:
>>>>
>>>>> We didn't. Having a look just now, the earliest example appears to be
>>>>> in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
>>>>> rationale.
>>>>>
>>>>> Given that the MMU is on (and speculative accesses are permitted) I
>>>>> can't see what the DSB achieves -- it can't quiesce the memory system.
>>>>>
>>>>> Santosh, any idea?
>>>>
>>>> IIRC, it was requirement from the OMAP ROM code to have a dsb before
>>>> we call the SMC routine. I can't recollect more than that now.
>>>
>>> In that case, shouldn't dsb have been added to the ROM code,
>>> on the "other side" of the smc, so as to not depend on Linux
>>> code "getting it right"?
>>
>> You're new to this, aren't you? :)
>
> :-) Indeed. ROM code is burned into the chip and can't be changed.

Oh, that kind of ROM... I thought EEPROM.
(Our secure OS is stored in NAND flash.)

If I'm bored, I'll try measuring the run-time difference with
and without dsb.

Regards.
Måns Rullgård Nov. 3, 2015, 6:02 p.m. UTC | #11
Marc Gonzalez <marc_gonzalez@sigmadesigns.com> writes:

> On 03/11/2015 17:37, Santosh Shilimkar wrote:
>> On 11/3/2015 2:12 AM, Måns Rullgård wrote:
>>> Marc Gonzalez writes:
>>>
>>>> Santosh Shilimkar wrote:
>>>>
>>>>> Mark Rutland wrote:
>>>>>
>>>>>> We didn't. Having a look just now, the earliest example appears to be
>>>>>> in OMAP4 L2 support patches back in 2009 [1]. I was not able to find a
>>>>>> rationale.
>>>>>>
>>>>>> Given that the MMU is on (and speculative accesses are permitted) I
>>>>>> can't see what the DSB achieves -- it can't quiesce the memory system.
>>>>>>
>>>>>> Santosh, any idea?
>>>>>
>>>>> IIRC, it was requirement from the OMAP ROM code to have a dsb before
>>>>> we call the SMC routine. I can't recollect more than that now.
>>>>
>>>> In that case, shouldn't dsb have been added to the ROM code,
>>>> on the "other side" of the smc, so as to not depend on Linux
>>>> code "getting it right"?
>>>
>>> You're new to this, aren't you? :)
>>
>> :-) Indeed. ROM code is burned into the chip and can't be changed.
>
> Oh, that kind of ROM... I thought EEPROM.
> (Our secure OS is stored in NAND flash.)
>
> If I'm bored, I'll try measuring the run-time difference with
> and without dsb.

Don't bother.  This is only used during initialisation anyway.  If that
takes a few microseconds longer, you won't be able to tell.
diff mbox

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 774dc59650c5..d8f0c31f521f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -934,6 +934,8 @@  source "arch/arm/mach-sunxi/Kconfig"
 
 source "arch/arm/mach-prima2/Kconfig"
 
+source "arch/arm/mach-tangox/Kconfig"
+
 source "arch/arm/mach-tegra/Kconfig"
 
 source "arch/arm/mach-u300/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7451b447cc2d..7fcb4c63cdf7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -203,6 +203,7 @@  machine-$(CONFIG_ARCH_SOCFPGA)		+= socfpga
 machine-$(CONFIG_ARCH_STI)		+= sti
 machine-$(CONFIG_ARCH_STM32)		+= stm32
 machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
+machine-$(CONFIG_ARCH_TANGOX)		+= tangox
 machine-$(CONFIG_ARCH_TEGRA)		+= tegra
 machine-$(CONFIG_ARCH_U300)		+= u300
 machine-$(CONFIG_ARCH_U8500)		+= ux500
diff --git a/arch/arm/mach-tangox/Kconfig b/arch/arm/mach-tangox/Kconfig
new file mode 100644
index 000000000000..cf814d7336f3
--- /dev/null
+++ b/arch/arm/mach-tangox/Kconfig
@@ -0,0 +1,12 @@ 
+config ARCH_TANGOX
+	bool "Sigma Designs Tango4 (SMP87xx)" if ARCH_MULTI_V7
+	# Cortex-A9 MPCore r3p0, PL310 r3p2
+	select ARCH_HAS_HOLES_MEMORYMODEL
+	select ARM_ERRATA_754322
+	select ARM_ERRATA_764369 if SMP
+	select ARM_ERRATA_775420
+	select ARM_GIC
+	select CLKSRC_TANGO_XTAL
+	select GENERIC_IRQ_CHIP
+	select HAVE_ARM_SCU
+	select HAVE_ARM_TWD
diff --git a/arch/arm/mach-tangox/Makefile b/arch/arm/mach-tangox/Makefile
new file mode 100644
index 000000000000..0d7e2b5976e3
--- /dev/null
+++ b/arch/arm/mach-tangox/Makefile
@@ -0,0 +1,2 @@ 
+asflags-y += -mcpu=cortex-a9
+obj-y += setup.o smc.o
diff --git a/arch/arm/mach-tangox/setup.c b/arch/arm/mach-tangox/setup.c
new file mode 100644
index 000000000000..a90e04140a0e
--- /dev/null
+++ b/arch/arm/mach-tangox/setup.c
@@ -0,0 +1,32 @@ 
+#include <linux/smp.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "smc.h"
+
+static int tango4_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	tango_set_aux_boot_addr(virt_to_phys(secondary_startup));
+	tango_start_aux_core();
+	return 0;
+}
+
+static struct smp_operations tango4_smp_ops __initdata = {
+	.smp_boot_secondary	= tango4_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(tango4_smp, "sigma,tango4-smp", &tango4_smp_ops);
+
+static void tango_l2c_write(unsigned long val, unsigned int reg)
+{
+	pr_debug("%s: reg=0x%x val=0x%lx\n", __func__, reg, val);
+	if (reg == L2X0_CTRL)
+		tango_set_l2_control(val);
+}
+
+static const char *tango_dt_compat[] = { "sigma,tango4", NULL };
+
+DT_MACHINE_START(TANGO_DT, "Sigma Tango DT")
+	.dt_compat	= tango_dt_compat,
+	.l2c_aux_mask	= ~0,
+	.l2c_write_sec	= tango_l2c_write,
+MACHINE_END
diff --git a/arch/arm/mach-tangox/smc.S b/arch/arm/mach-tangox/smc.S
new file mode 100644
index 000000000000..35f9623aedb1
--- /dev/null
+++ b/arch/arm/mach-tangox/smc.S
@@ -0,0 +1,9 @@ 
+#include <linux/linkage.h>
+
+ENTRY(tango_smc)
+	push	{lr}
+	mov	ip, r1
+	dsb
+	smc	#0
+	pop	{pc}
+ENDPROC(tango_smc)
diff --git a/arch/arm/mach-tangox/smc.h b/arch/arm/mach-tangox/smc.h
new file mode 100644
index 000000000000..4e704dcf8da8
--- /dev/null
+++ b/arch/arm/mach-tangox/smc.h
@@ -0,0 +1,5 @@ 
+extern int tango_smc(unsigned int val, unsigned int service);
+
+#define tango_set_l2_control(val)	tango_smc(val, 0x102)
+#define tango_start_aux_core()		tango_smc(666, 0x104)
+#define tango_set_aux_boot_addr(val)	tango_smc((unsigned int)val, 0x105)