@@ -26,6 +26,7 @@
#include <asm/cacheflush.h>
#include <asm/dbell.h>
#include <asm/fsl_guts.h>
+#include <asm/cputhreads.h>
#include <sysdev/fsl_soc.h>
#include <sysdev/mpic.h>
@@ -45,6 +46,7 @@ static u64 timebase;
static int tb_req;
static int tb_valid;
static u32 cur_booting_core;
+static bool rcpmv2;
#ifdef CONFIG_PPC_E500MC
/* get a physical mask of online cores and booting core */
@@ -53,26 +55,40 @@ static inline u32 get_phy_cpu_mask(void)
u32 mask;
int cpu;
- mask = 1 << cur_booting_core;
- for_each_online_cpu(cpu)
- mask |= 1 << get_hard_smp_processor_id(cpu);
+ if (smt_capable()) {
+ /* two threads in one core share one time base */
+ mask = 1 << cpu_core_index_of_thread(cur_booting_core);
+ for_each_online_cpu(cpu)
+ mask |= 1 << cpu_core_index_of_thread(
+ get_hard_smp_processor_id(cpu));
+ } else {
+ mask = 1 << cur_booting_core;
+ for_each_online_cpu(cpu)
+ mask |= 1 << get_hard_smp_processor_id(cpu);
+ }
return mask;
}
static void mpc85xx_timebase_freeze(int freeze)
{
- struct ccsr_rcpm __iomem *rcpm = guts_regs;
+ u32 *addr;
u32 mask = get_phy_cpu_mask();
+ if (rcpmv2)
+ addr = &((struct ccsr_rcpm_v2 *)guts_regs)->pctbenr;
+ else
+ addr = &((struct ccsr_rcpm *)guts_regs)->ctbenr;
+
if (freeze)
- clrbits32(&rcpm->ctbenr, mask);
+ clrbits32(addr, mask);
else
- setbits32(&rcpm->ctbenr, mask);
+ setbits32(addr, mask);
- /* read back to push the previos write */
- in_be32(&rcpm->ctbenr);
+ /* read back to push the previous write */
+ in_be32(addr);
}
+
#else
static void mpc85xx_timebase_freeze(int freeze)
{
@@ -98,6 +114,16 @@ static void mpc85xx_give_timebase(void)
if (system_state == SYSTEM_BOOTING)
return;
+#ifdef CONFIG_PPC_E500MC
+ /*
+ * If the booting thread is not the first thread of the core,
+ * skip time base sync.
+ */
+ if (smt_capable() &&
+ cur_booting_core != cpu_first_thread_sibling(cur_booting_core))
+ return;
+#endif
+
local_irq_save(flags);
while (!tb_req)
@@ -125,6 +151,12 @@ static void mpc85xx_take_timebase(void)
if (system_state == SYSTEM_BOOTING)
return;
+#ifdef CONFIG_PPC_E500MC
+ if (smt_capable() &&
+ cur_booting_core != cpu_first_thread_sibling(cur_booting_core))
+ return;
+#endif
+
local_irq_save(flags);
tb_req = 1;
@@ -465,6 +497,7 @@ static const struct of_device_id mpc85xx_smp_guts_ids[] = {
{ .compatible = "fsl,p1023-guts", },
{ .compatible = "fsl,p2020-guts", },
{ .compatible = "fsl,qoriq-rcpm-1.0", },
+ { .compatible = "fsl,qoriq-rcpm-2", },
{},
};
@@ -491,6 +524,9 @@ void __init mpc85xx_smp_init(void)
np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids);
if (np) {
+ if (of_device_is_compatible(np, "fsl,qoriq-rcpm-2"))
+ rcpmv2 = true;
+
guts_regs = of_iomap(np, 0);
of_node_put(np);
if (!guts_regs) {