2019-05-19 15:51:34 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2012-12-20 19:37:32 +08:00
/*
* plat smp support for CSR Marco dual - core SMP SoCs
*
* Copyright ( c ) 2012 Cambridge Silicon Radio Limited , a CSR plc group company .
*/
# include <linux/init.h>
# include <linux/smp.h>
# include <linux/delay.h>
# include <linux/of.h>
# include <linux/of_address.h>
# include <asm/page.h>
# include <asm/mach/map.h>
# include <asm/smp_plat.h>
# include <asm/smp_scu.h>
# include <asm/cacheflush.h>
# include <asm/cputype.h>
# include "common.h"
2014-12-25 16:34:20 +08:00
static void __iomem * clk_base ;
2012-12-20 19:37:32 +08:00
static DEFINE_SPINLOCK ( boot_lock ) ;
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
/* XXX prima2_pen_release is cargo culted code - DO NOT COPY XXX */
volatile int prima2_pen_release = - 1 ;
2013-06-17 15:43:14 -04:00
static void sirfsoc_secondary_init ( unsigned int cpu )
2012-12-20 19:37:32 +08:00
{
/*
* let the primary processor know we ' re out of the
* pen , then head off into the C entry point
*/
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
prima2_pen_release = - 1 ;
2012-12-20 19:37:32 +08:00
smp_wmb ( ) ;
/*
* Synchronise with the boot thread .
*/
spin_lock ( & boot_lock ) ;
spin_unlock ( & boot_lock ) ;
}
2015-02-18 21:19:56 +01:00
static const struct of_device_id clk_ids [ ] = {
2014-12-25 16:34:20 +08:00
{ . compatible = " sirf,atlas7-clkc " } ,
2012-12-20 19:37:32 +08:00
{ } ,
} ;
2013-06-17 15:43:14 -04:00
static int sirfsoc_boot_secondary ( unsigned int cpu , struct task_struct * idle )
2012-12-20 19:37:32 +08:00
{
unsigned long timeout ;
struct device_node * np ;
2014-12-25 16:34:20 +08:00
np = of_find_matching_node ( NULL , clk_ids ) ;
2012-12-20 19:37:32 +08:00
if ( ! np )
return - ENODEV ;
2014-12-25 16:34:20 +08:00
clk_base = of_iomap ( np , 0 ) ;
if ( ! clk_base )
2012-12-20 19:37:32 +08:00
return - ENOMEM ;
/*
2014-12-25 16:34:20 +08:00
* write the address of secondary startup into the clkc register
* at offset 0x2bC , then write the magic number 0x3CAF5D62 to the
* clkc register at offset 0x2b8 , which is what boot rom code is
2012-12-20 19:37:32 +08:00
* waiting for . This would wake up the secondary core from WFE
*/
2014-12-25 16:34:20 +08:00
# define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2bc
2017-01-15 03:59:29 +01:00
__raw_writel ( __pa_symbol ( sirfsoc_secondary_startup ) ,
2014-12-25 16:34:20 +08:00
clk_base + SIRFSOC_CPU1_JUMPADDR_OFFSET ) ;
2012-12-20 19:37:32 +08:00
2014-12-25 16:34:20 +08:00
# define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x2b8
2012-12-20 19:37:32 +08:00
__raw_writel ( 0x3CAF5D62 ,
2014-12-25 16:34:20 +08:00
clk_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET ) ;
2012-12-20 19:37:32 +08:00
/* make sure write buffer is drained */
mb ( ) ;
spin_lock ( & boot_lock ) ;
/*
* The secondary processor is waiting to be released from
* the holding pen - release it , then wait for it to flag
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
* that it has been released by resetting prima2_pen_release .
2012-12-20 19:37:32 +08:00
*
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
* Note that " prima2_pen_release " is the hardware CPU ID , whereas
2012-12-20 19:37:32 +08:00
* " cpu " is Linux ' s internal ID .
*/
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
prima2_pen_release = cpu_logical_map ( cpu ) ;
sync_cache_w ( & prima2_pen_release ) ;
2012-12-20 19:37:32 +08:00
/*
* Send the secondary CPU SEV , thereby causing the boot monitor to read
* the JUMPADDR and WAKEMAGIC , and branch to the address found there .
*/
dsb_sev ( ) ;
timeout = jiffies + ( 1 * HZ ) ;
while ( time_before ( jiffies , timeout ) ) {
smp_rmb ( ) ;
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
if ( prima2_pen_release = = - 1 )
2012-12-20 19:37:32 +08:00
break ;
udelay ( 10 ) ;
}
/*
* now the secondary core is starting up let it run its
* calibrations , then wait for it to finish
*/
spin_unlock ( & boot_lock ) ;
ARM: smp: remove arch-provided "pen_release"
Consolidating the "pen_release" stuff amongst the various SoC
implementations gives credence to having a CPU holding pen for
secondary CPUs. However, this is far from the truth.
Many SoC implementations cargo-cult copied various bits of the pen
release implementation from the initial Realview/Versatile Express
implementation without understanding what it was or why it existed.
The reason it existed is because these are _development_ platforms,
and some board firmware is unable to individually control the
startup of secondary CPUs. Moreover, they do not have a way to
power down or reset secondary CPUs for hot-unplug. Hence, the
pen_release implementation was designed for ARM Ltd's development
platforms to provide a working implementation, even though it is
very far from what is required.
It was decided a while back to reduce the duplication by consolidating
the "pen_release" variable, but this only made the situation worse -
we have ended up with several implementations that read this variable
but do not write it - again, showing the cargo-cult mentality at work,
lack of proper review of new code, and in some cases a lack of testing.
While it would be preferable to remove pen_release entirely from the
kernel, this is not possible without help from the SoC maintainers,
which seems to be lacking. However, I want to remove pen_release from
arch code to remove the credence that having it gives.
This patch removes pen_release from the arch code entirely, adding
private per-SoC definitions for it instead, and explicitly stating
that write_pen_release() is cargo-cult copied and should not be
copied any further. Rename write_pen_release() in a similar fashion
as well.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
2018-12-13 14:02:48 +00:00
return prima2_pen_release ! = - 1 ? - ENOSYS : 0 ;
2012-12-20 19:37:32 +08:00
}
2015-11-15 10:39:53 +09:00
const struct smp_operations sirfsoc_smp_ops __initconst = {
2014-02-18 14:46:28 +08:00
. smp_secondary_init = sirfsoc_secondary_init ,
. smp_boot_secondary = sirfsoc_boot_secondary ,
2012-12-20 19:37:32 +08:00
# ifdef CONFIG_HOTPLUG_CPU
. cpu_die = sirfsoc_cpu_die ,
# endif
} ;