From mboxrd@z Thu Jan 1 00:00:00 1970 From: nico@fluxnic.net (Nicolas Pitre) Date: Thu, 06 Jun 2013 12:49:52 -0400 (EDT) Subject: [PATCH v2] arm: mvebu: don't hardcode a physical address in headsmp.S In-Reply-To: <1370514268-9159-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1370415901-4721-6-git-send-email-thomas.petazzoni@free-electrons.com> <1370514268-9159-1-git-send-email-thomas.petazzoni@free-electrons.com> Message-ID: To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Thu, 6 Jun 2013, Thomas Petazzoni wrote: > Now that the coherency_init() function is called a bit earlier, we can > actually read the physical address of the coherency unit registers > from the Device Tree, and communicate that to the headsmp.S code, > which avoids hardcoding a physical address. > > Signed-off-by: Thomas Petazzoni Acked-by: Nicolas Pitre > --- > Changes from v1 to v2: > > * Simplified the code in headsmp.S to compute the physical address of > the coherency unit base address. Suggested by Nicolas Pitre. > > * Added a sync_cache_w() call to ensure the physical address of the > coherency unit stored in the coherency_phys_base is visible by the > other CPUs. The other CPUs are reading this before they join the > coherency fabric, so we need to make some manual cache coherency > here. Noticed by Will Deacon. > > arch/arm/mach-mvebu/coherency.c | 12 ++++++++++++ > arch/arm/mach-mvebu/headsmp.S | 16 ++++++++-------- > 2 files changed, 20 insertions(+), 8 deletions(-) > > diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c > index d74794a..32fcf69 100644 > --- a/arch/arm/mach-mvebu/coherency.c > +++ b/arch/arm/mach-mvebu/coherency.c > @@ -25,8 +25,10 @@ > #include > #include > #include > +#include > #include "armada-370-xp.h" > > +unsigned long __cpuinitdata coherency_phys_base; > static void __iomem *coherency_base; > static void __iomem *coherency_cpu_base; > > @@ -124,7 +126,17 @@ int __init coherency_init(void) > > np = of_find_matching_node(NULL, of_coherency_table); > if (np) { > + struct resource res; > pr_info("Initializing Coherency fabric\n"); > + of_address_to_resource(np, 0, &res); > + coherency_phys_base = res.start; > + /* > + * Ensure secondary CPUs will see the updated value, > + * which they read before they join the coherency > + * fabric, and therefore before they are coherent with > + * the boot CPU cache. > + */ > + sync_cache_w(&coherency_phys_base); > coherency_base = of_iomap(np, 0); > coherency_cpu_base = of_iomap(np, 1); > set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); > diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S > index a06e0ed..7147300 100644 > --- a/arch/arm/mach-mvebu/headsmp.S > +++ b/arch/arm/mach-mvebu/headsmp.S > @@ -21,12 +21,6 @@ > #include > #include > > -/* > - * At this stage the secondary CPUs don't have acces yet to the MMU, so > - * we have to provide physical addresses > - */ > -#define ARMADA_XP_CFB_BASE 0xD0020200 > - > __CPUINIT > > /* > @@ -35,15 +29,21 @@ > * startup > */ > ENTRY(armada_xp_secondary_startup) > + /* Get coherency fabric base physical address */ > + adr r0, 1f > + ldr r1, [r0] > + ldr r0, [r0, r1] > > /* Read CPU id */ > mrc p15, 0, r1, c0, c0, 5 > and r1, r1, #0xF > > /* Add CPU to coherency fabric */ > - ldr r0, =ARMADA_XP_CFB_BASE > - > bl ll_set_cpu_coherent > b secondary_startup > > ENDPROC(armada_xp_secondary_startup) > + > + .align 2 > +1: > + .long coherency_phys_base - . > -- > 1.8.1.2 >