Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 372104
b: refs/heads/master
c: e8db288
h: refs/heads/master
v: v3
  • Loading branch information
Nicolas Pitre committed Apr 24, 2013
1 parent 0b06f16 commit fa9be8b
Show file tree
Hide file tree
Showing 6 changed files with 160 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: 0c91e7e07ebf08092bf8e28d8cd8d420732fc716
refs/heads/master: e8db288e05e588ad3f416b3a24354d60d02f35f2
8 changes: 8 additions & 0 deletions trunk/arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,14 @@ config HAVE_ARM_TWD
help
This options enables support for the ARM timer and watchdog unit

config MCPM
bool "Multi-Cluster Power Management"
depends on CPU_V7 && SMP
help
This option provides the common power management infrastructure
for (multi-)cluster based systems, such as big.LITTLE based
systems.

choice
prompt "Memory split"
default VMSPLIT_3G
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/arm/common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o
obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o
22 changes: 22 additions & 0 deletions trunk/arch/arm/common/mcpm_entry.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* arch/arm/common/mcpm_entry.c -- entry point for multi-cluster PM
*
* Created by: Nicolas Pitre, March 2012
* Copyright: (C) 2012-2013 Linaro Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <asm/mcpm.h>
#include <asm/cacheflush.h>

extern unsigned long mcpm_entry_vectors[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER];

void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr)
{
unsigned long val = ptr ? virt_to_phys(ptr) : 0;
mcpm_entry_vectors[cluster][cpu] = val;
sync_cache_w(&mcpm_entry_vectors[cluster][cpu]);
}
86 changes: 86 additions & 0 deletions trunk/arch/arm/common/mcpm_head.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* arch/arm/common/mcpm_head.S -- kernel entry point for multi-cluster PM
*
* Created by: Nicolas Pitre, March 2012
* Copyright: (C) 2012-2013 Linaro Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/linkage.h>
#include <asm/mcpm.h>

.macro pr_dbg string
#if defined(CONFIG_DEBUG_LL) && defined(DEBUG)
b 1901f
1902: .asciz "CPU"
1903: .asciz " cluster"
1904: .asciz ": \string"
.align
1901: adr r0, 1902b
bl printascii
mov r0, r9
bl printhex8
adr r0, 1903b
bl printascii
mov r0, r10
bl printhex8
adr r0, 1904b
bl printascii
#endif
.endm

.arm
.align

ENTRY(mcpm_entry_point)

THUMB( adr r12, BSYM(1f) )
THUMB( bx r12 )
THUMB( .thumb )
1:
mrc p15, 0, r0, c0, c0, 5 @ MPIDR
ubfx r9, r0, #0, #8 @ r9 = cpu
ubfx r10, r0, #8, #8 @ r10 = cluster
mov r3, #MAX_CPUS_PER_CLUSTER
mla r4, r3, r10, r9 @ r4 = canonical CPU index
cmp r4, #(MAX_CPUS_PER_CLUSTER * MAX_NR_CLUSTERS)
blo 2f

/* We didn't expect this CPU. Try to cheaply make it quiet. */
1: wfi
wfe
b 1b

2: pr_dbg "kernel mcpm_entry_point\n"

/*
* MMU is off so we need to get to mcpm_entry_vectors in a
* position independent way.
*/
adr r5, 3f
ldr r6, [r5]
add r6, r5, r6 @ r6 = mcpm_entry_vectors

mcpm_entry_gated:
ldr r5, [r6, r4, lsl #2] @ r5 = CPU entry vector
cmp r5, #0
wfeeq
beq mcpm_entry_gated
pr_dbg "released\n"
bx r5

.align 2

3: .word mcpm_entry_vectors - .

ENDPROC(mcpm_entry_point)

.bss
.align 5

.type mcpm_entry_vectors, #object
ENTRY(mcpm_entry_vectors)
.space 4 * MAX_NR_CLUSTERS * MAX_CPUS_PER_CLUSTER
42 changes: 42 additions & 0 deletions trunk/arch/arm/include/asm/mcpm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* arch/arm/include/asm/mcpm.h
*
* Created by: Nicolas Pitre, April 2012
* Copyright: (C) 2012-2013 Linaro Limited
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifndef MCPM_H
#define MCPM_H

/*
* Maximum number of possible clusters / CPUs per cluster.
*
* This should be sufficient for quite a while, while keeping the
* (assembly) code simpler. When this starts to grow then we'll have
* to consider dynamic allocation.
*/
#define MAX_CPUS_PER_CLUSTER 4
#define MAX_NR_CLUSTERS 2

#ifndef __ASSEMBLY__

/*
* Platform specific code should use this symbol to set up secondary
* entry location for processors to use when released from reset.
*/
extern void mcpm_entry_point(void);

/*
* This is used to indicate where the given CPU from given cluster should
* branch once it is ready to re-enter the kernel using ptr, or NULL if it
* should be gated. A gated CPU is held in a WFE loop until its vector
* becomes non NULL.
*/
void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr);

#endif /* ! __ASSEMBLY__ */
#endif

0 comments on commit fa9be8b

Please sign in to comment.