[POWERPC] pasemi: SMP timebase sync
authorOlof Johansson <olof@lixom.net>
Sun, 4 Feb 2007 22:36:53 +0000 (16:36 -0600)
committerPaul Mackerras <paulus@samba.org>
Wed, 7 Feb 2007 03:03:22 +0000 (14:03 +1100)
Timebase update is simple on PA6T, since global updates can be done from
one core by writing to an SPR.

Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/platforms/pasemi/setup.c
include/asm-powerpc/reg.h

index cabf7017c05eca080ff3c7845f4139c92364916f..2d9652b6acb352b3e744e1af9b8e37905436c784 100644 (file)
@@ -48,13 +48,36 @@ static void pas_restart(char *cmd)
 }
 
 #ifdef CONFIG_SMP
+static DEFINE_SPINLOCK(timebase_lock);
+
+static void __devinit pas_give_timebase(void)
+{
+       unsigned long tb;
+
+       spin_lock(&timebase_lock);
+       mtspr(SPRN_TBCTL, TBCTL_FREEZE);
+       tb = mftb();
+       mtspr(SPRN_TBCTL, TBCTL_UPDATE_LOWER | (tb & 0xffffffff));
+       mtspr(SPRN_TBCTL, TBCTL_UPDATE_UPPER | (tb >> 32));
+       mtspr(SPRN_TBCTL, TBCTL_RESTART);
+       spin_unlock(&timebase_lock);
+       pr_debug("pas_give_timebase: cpu %d gave tb %lx\n",
+                smp_processor_id(), tb);
+}
+
+static void __devinit pas_take_timebase(void)
+{
+       pr_debug("pas_take_timebase: cpu %d has tb %lx\n",
+                smp_processor_id(), mftb());
+}
+
 struct smp_ops_t pas_smp_ops = {
        .probe          = smp_mpic_probe,
        .message_pass   = smp_mpic_message_pass,
        .kick_cpu       = smp_generic_kick_cpu,
        .setup_cpu      = smp_mpic_setup_cpu,
-       .give_timebase  = smp_generic_give_timebase,
-       .take_timebase  = smp_generic_take_timebase,
+       .give_timebase  = pas_give_timebase,
+       .take_timebase  = pas_take_timebase,
 };
 #endif /* CONFIG_SMP */
 
index 923df6ceaa5c418b40251d2b3f083ca29a42bd5e..0d7f0164ed814ee85cd26b3a2e4f22bbf87ed517 100644 (file)
 #define SPRN_HSRR0     0x13A   /* Save/Restore Register 0 */
 #define SPRN_HSRR1     0x13B   /* Save/Restore Register 1 */
 
+#define SPRN_TBCTL     0x35f   /* PA6T Timebase control register */
+#define   TBCTL_FREEZE         0x0000000000000000ull /* Freeze all tbs */
+#define   TBCTL_RESTART                0x0000000100000000ull /* Restart all tbs */
+#define   TBCTL_UPDATE_UPPER   0x0000000200000000ull /* Set upper 32 bits */
+#define   TBCTL_UPDATE_LOWER   0x0000000300000000ull /* Set lower 32 bits */
+
 #ifndef SPRN_SVR
 #define SPRN_SVR       0x11E   /* System Version Register */
 #endif