From patchwork Fri Jul 20 12:42:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenhui zhao X-Patchwork-Id: 172243 X-Patchwork-Delegate: galak@kernel.crashing.org Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id E80572C0ABC for ; Fri, 20 Jul 2012 22:43:01 +1000 (EST) Received: from tx2outboundpool.messaging.microsoft.com (tx2ehsobe002.messaging.microsoft.com [65.55.88.12]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (Client CN "mail.global.frontbridge.com", Issuer "Microsoft Secure Server Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 8763C2C04AF for ; Fri, 20 Jul 2012 22:41:20 +1000 (EST) Received: from mail96-tx2-R.bigfish.com (10.9.14.248) by TX2EHSOBE006.bigfish.com (10.9.40.26) with Microsoft SMTP Server id 14.1.225.23; Fri, 20 Jul 2012 12:41:16 +0000 Received: from mail96-tx2 (localhost [127.0.0.1]) by mail96-tx2-R.bigfish.com (Postfix) with ESMTP id C2C57400A8; Fri, 20 Jul 2012 12:41:15 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1202hzz8275bhz2dh2a8h668h839hd24he5bhf0ah107ah) Received: from mail96-tx2 (localhost.localdomain [127.0.0.1]) by mail96-tx2 (MessageSwitch) id 1342788074163748_6382; Fri, 20 Jul 2012 12:41:14 +0000 (UTC) Received: from TX2EHSMHS044.bigfish.com (unknown [10.9.14.247]) by mail96-tx2.bigfish.com (Postfix) with ESMTP id 24549260046; Fri, 20 Jul 2012 12:41:14 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by TX2EHSMHS044.bigfish.com (10.9.99.144) with Microsoft SMTP Server (TLS) id 14.1.225.23; Fri, 20 Jul 2012 12:41:14 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server (TLS) id 14.2.298.5; Fri, 20 Jul 2012 07:41:13 -0500 Received: from localhost.localdomain ([10.193.20.166]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id q6KCevoA006731; Fri, 20 Jul 2012 05:41:10 -0700 From: Zhao Chenhui To: , , Subject: [PATCH v8 3/7] powerpc/85xx: implement hardware timebase sync Date: Fri, 20 Jul 2012 20:42:35 +0800 Message-ID: <1342788159-27529-4-git-send-email-chenhui.zhao@freescale.com> X-Mailer: git-send-email 1.6.4.1 In-Reply-To: <1342788159-27529-1-git-send-email-chenhui.zhao@freescale.com> References: <1342788159-27529-1-git-send-email-chenhui.zhao@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com Cc: linux-kernel@vger.kernel.org X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Do hardware timebase sync. Firstly, stop all timebases, and transfer the timebase value of the boot core to the other core. Finally, start all timebases. Only apply to dual-core chips, such as MPC8572, P2020, etc. Signed-off-by: Zhao Chenhui Signed-off-by: Li Yang --- arch/powerpc/include/asm/fsl_guts.h | 2 + arch/powerpc/platforms/85xx/smp.c | 82 +++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/fsl_guts.h b/arch/powerpc/include/asm/fsl_guts.h index aa4c488..dd5ba2c 100644 --- a/arch/powerpc/include/asm/fsl_guts.h +++ b/arch/powerpc/include/asm/fsl_guts.h @@ -48,6 +48,8 @@ struct ccsr_guts { __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */ u8 res06c[0x70 - 0x6c]; __be32 devdisr; /* 0x.0070 - Device Disable Control */ +#define CCSR_GUTS_DEVDISR_TB1 0x00001000 +#define CCSR_GUTS_DEVDISR_TB0 0x00004000 __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ u8 res078[0x7c - 0x78]; __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 4827709..7ed52a6 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,64 @@ struct epapr_spin_table { u32 pir; }; +static struct ccsr_guts __iomem *guts; +static u64 timebase; +static int tb_req; +static int tb_valid; + +static void mpc85xx_timebase_freeze(int freeze) +{ + uint32_t mask; + + mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; + if (freeze) + setbits32(&guts->devdisr, mask); + else + clrbits32(&guts->devdisr, mask); + + in_be32(&guts->devdisr); +} + +static void mpc85xx_give_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + while (!tb_req) + barrier(); + tb_req = 0; + + mpc85xx_timebase_freeze(1); + timebase = get_tb(); + mb(); + tb_valid = 1; + + while (tb_valid) + barrier(); + + mpc85xx_timebase_freeze(0); + + local_irq_restore(flags); +} + +static void mpc85xx_take_timebase(void) +{ + unsigned long flags; + + local_irq_save(flags); + + tb_req = 1; + while (!tb_valid) + barrier(); + + set_tb(timebase >> 32, timebase & 0xffffffff); + isync(); + tb_valid = 0; + + local_irq_restore(flags); +} + static int __init smp_85xx_kick_cpu(int nr) { @@ -228,6 +287,16 @@ smp_85xx_setup_cpu(int cpu_nr) doorbell_setup_this_cpu(); } +static const struct of_device_id mpc85xx_smp_guts_ids[] = { + { .compatible = "fsl,mpc8572-guts", }, + { .compatible = "fsl,p1020-guts", }, + { .compatible = "fsl,p1021-guts", }, + { .compatible = "fsl,p1022-guts", }, + { .compatible = "fsl,p1023-guts", }, + { .compatible = "fsl,p2020-guts", }, + {}, +}; + void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -249,6 +318,19 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } + np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); + if (np) { + guts = of_iomap(np, 0); + of_node_put(np); + if (!guts) { + pr_err("%s: Could not map guts node address\n", + __func__); + return; + } + smp_85xx_ops.give_timebase = mpc85xx_give_timebase; + smp_85xx_ops.take_timebase = mpc85xx_take_timebase; + } + smp_ops = &smp_85xx_ops; #ifdef CONFIG_KEXEC