Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344301
b: refs/heads/master
c: 45f5984
h: refs/heads/master
i:
  344299: 702cff9
v: v3
  • Loading branch information
Gregory CLEMENT committed Nov 21, 2012
1 parent 060a803 commit 1ec7312
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: de4901933f6dfc0180f761790d3f47fc64e6270f
refs/heads/master: 45f5984a8a528f7507f3ec860d297934d4449ad1
3 changes: 3 additions & 0 deletions trunk/arch/arm/configs/mvebu_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ CONFIG_ARCH_MVEBU=y
CONFIG_MACH_ARMADA_370=y
CONFIG_MACH_ARMADA_XP=y
# CONFIG_CACHE_L2X0 is not set
# CONFIG_SWP_EMULATE is not set
CONFIG_SMP=y
# CONFIG_LOCAL_TIMERS is not set
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
# CONFIG_COMPACTION is not set
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/mach-mvebu/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ menu "Marvell SOC with device tree"
config MACH_ARMADA_370_XP
bool
select ARMADA_370_XP_TIMER
select HAVE_SMP
select CPU_PJ4B

config MACH_ARMADA_370
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/arm/mach-mvebu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include \

obj-y += system-controller.o
obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o coherency.o coherency_ll.o pmsu.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
3 changes: 3 additions & 0 deletions trunk/arch/arm/mach-mvebu/armada-370-xp.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <asm/mach/time.h>
#include "armada-370-xp.h"
#include "common.h"
#include "coherency.h"

static struct map_desc armada_370_xp_io_desc[] __initdata = {
{
Expand Down Expand Up @@ -51,6 +52,7 @@ struct sys_timer armada_370_xp_timer = {
static void __init armada_370_xp_dt_init(void)
{
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
coherency_init();
}

static const char * const armada_370_xp_dt_board_dt_compat[] = {
Expand All @@ -60,6 +62,7 @@ static const char * const armada_370_xp_dt_board_dt_compat[] = {
};

DT_MACHINE_START(ARMADA_XP_DT, "Marvell Aramada 370/XP (Device Tree)")
.smp = smp_ops(armada_xp_smp_ops),
.init_machine = armada_370_xp_dt_init,
.map_io = armada_370_xp_map_io,
.init_irq = armada_370_xp_init_irq,
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/arm/mach-mvebu/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ void mvebu_restart(char mode, const char *cmd);
void armada_370_xp_init_irq(void);
void armada_370_xp_handle_irq(struct pt_regs *regs);

void armada_xp_cpu_die(unsigned int cpu);
int armada_370_xp_coherency_init(void);
int armada_370_xp_pmsu_init(void);
void armada_xp_secondary_startup(void);
extern struct smp_operations armada_xp_smp_ops;
#endif
49 changes: 49 additions & 0 deletions trunk/arch/arm/mach-mvebu/headsmp.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* SMP support: Entry point for secondary CPUs
*
* Copyright (C) 2012 Marvell
*
* Yehuda Yitschak <yehuday@marvell.com>
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*
* This file implements the assembly entry point for secondary CPUs in
* an SMP kernel. The only thing we need to do is to add the CPU to
* the coherency fabric by writing to 2 registers. Currently the base
* register addresses are hard coded due to the early initialisation
* problems.
*/

#include <linux/linkage.h>
#include <linux/init.h>

/*
* 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

/*
* Armada XP specific entry point for secondary CPUs.
* We add the CPU to the coherency fabric and then jump to secondary
* startup
*/
ENTRY(armada_xp_secondary_startup)

/* 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)
30 changes: 30 additions & 0 deletions trunk/arch/arm/mach-mvebu/hotplug.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Symmetric Multi Processing (SMP) support for Armada XP
*
* Copyright (C) 2012 Marvell
*
* Lior Amsalem <alior@marvell.com>
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
#include <asm/proc-fns.h>

/*
* platform-specific code to shutdown a CPU
*
* Called with IRQs disabled
*/
void __ref armada_xp_cpu_die(unsigned int cpu)
{
cpu_do_idle();

/* We should never return from idle */
panic("mvebu: cpu %d unexpectedly exit from shutdown\n", cpu);
}
122 changes: 122 additions & 0 deletions trunk/arch/arm/mach-mvebu/platsmp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Symmetric Multi Processing (SMP) support for Armada XP
*
* Copyright (C) 2012 Marvell
*
* Lior Amsalem <alior@marvell.com>
* Yehuda Yitschak <yehuday@marvell.com>
* Gregory CLEMENT <gregory.clement@free-electrons.com>
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*
* The Armada XP SoC has 4 ARMv7 PJ4B CPUs running in full HW coherency
* This file implements the routines for preparing the SMP infrastructure
* and waking up the secondary CPUs
*/

#include <linux/init.h>
#include <linux/smp.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include "common.h"
#include "armada-370-xp.h"
#include "pmsu.h"
#include "coherency.h"

void __init set_secondary_cpus_clock(void)
{
int thiscpu;
unsigned long rate;
struct clk *cpu_clk = NULL;
struct device_node *np = NULL;

thiscpu = smp_processor_id();
for_each_node_by_type(np, "cpu") {
int err;
int cpu;

err = of_property_read_u32(np, "reg", &cpu);
if (WARN_ON(err))
return;

if (cpu == thiscpu) {
cpu_clk = of_clk_get(np, 0);
break;
}
}
if (WARN_ON(IS_ERR(cpu_clk)))
return;
clk_prepare_enable(cpu_clk);
rate = clk_get_rate(cpu_clk);

/* set all the other CPU clk to the same rate than the boot CPU */
for_each_node_by_type(np, "cpu") {
int err;
int cpu;

err = of_property_read_u32(np, "reg", &cpu);
if (WARN_ON(err))
return;

if (cpu != thiscpu) {
cpu_clk = of_clk_get(np, 0);
clk_set_rate(cpu_clk, rate);
}
}
}

static void __cpuinit armada_xp_secondary_init(unsigned int cpu)
{
armada_xp_mpic_smp_cpu_init();
}

static int __cpuinit armada_xp_boot_secondary(unsigned int cpu,
struct task_struct *idle)
{
pr_info("Booting CPU %d\n", cpu);

armada_xp_boot_cpu(cpu, armada_xp_secondary_startup);

return 0;
}

static void __init armada_xp_smp_init_cpus(void)
{
unsigned int i, ncores;
ncores = coherency_get_cpu_count();

/* Limit possible CPUs to defconfig */
if (ncores > nr_cpu_ids) {
pr_warn("SMP: %d CPUs physically present. Only %d configured.",
ncores, nr_cpu_ids);
pr_warn("Clipping CPU count to %d\n", nr_cpu_ids);
ncores = nr_cpu_ids;
}

for (i = 0; i < ncores; i++)
set_cpu_possible(i, true);

set_smp_cross_call(armada_mpic_send_doorbell);
}

void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus)
{
set_secondary_cpus_clock();
flush_cache_all();
set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0);
}

struct smp_operations armada_xp_smp_ops __initdata = {
.smp_init_cpus = armada_xp_smp_init_cpus,
.smp_prepare_cpus = armada_xp_smp_prepare_cpus,
.smp_secondary_init = armada_xp_secondary_init,
.smp_boot_secondary = armada_xp_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = armada_xp_cpu_die,
#endif
};

0 comments on commit 1ec7312

Please sign in to comment.