From patchwork Mon Oct 12 17:41:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Axel Haslam X-Patchwork-Id: 7378141 X-Patchwork-Delegate: horms@verge.net.au Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6C72C9F1D5 for ; Mon, 12 Oct 2015 17:41:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5BDBC206F6 for ; Mon, 12 Oct 2015 17:41:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2A3CE20674 for ; Mon, 12 Oct 2015 17:41:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751580AbbJLRlh (ORCPT ); Mon, 12 Oct 2015 13:41:37 -0400 Received: from mail-wi0-f170.google.com ([209.85.212.170]:35843 "EHLO mail-wi0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751555AbbJLRlh (ORCPT ); Mon, 12 Oct 2015 13:41:37 -0400 Received: by wicgb1 with SMTP id gb1so158180472wic.1 for ; Mon, 12 Oct 2015 10:41:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5WBZpwv+cx0myBNY9cy8h8o+YAlgXcdQJDegu1od5mM=; b=CMYXa8Cn+O3khq9ngi5/NnM0l/uzbakLJ+lypEM7kQ4n0cWvpVd80KBe+BzibWG6Ln xWd7Om2SX4lCrx7BzEM7Q5vDxcamtIqutqeV8XmqtK4HI6CPDuGhSxD//iNRIE3uKUm6 r9kBDTuRnmXQfS9pmE+loaFGj5W8R4iExsVxit+x3yWgtdajWJx756fKkKuIhYNz8s0S gin4SONMLEvxGCGP74NWGImygF/C4yqWvZ7CJmIxVtJ1xTxU9GHgXmLmyRa/mAg2tXU/ Ml9dSgY/BL4UfqH2WKZUJVmAeRCF/ZLrjK/iMpQ3JJx5MnZLDPTpXiHwDbnfxz+y1ZLh DKgQ== X-Gm-Message-State: ALoCoQngmbIEqYb6+SK6GbB4eyyLZCmiX3teS8SUdCx3O+rMojE3LFYvCJEWf4is2Jy11p4cZf3Z X-Received: by 10.194.158.68 with SMTP id ws4mr35362056wjb.25.1444671695703; Mon, 12 Oct 2015 10:41:35 -0700 (PDT) Received: from localhost.localdomain (LPoitiers-656-1-62-228.w90-63.abo.wanadoo.fr. [90.63.143.228]) by smtp.gmail.com with ESMTPSA id gw8sm50686wib.15.2015.10.12.10.41.33 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 12 Oct 2015 10:41:35 -0700 (PDT) From: ahaslam@baylibre.com To: magnus.damm@gmail.com, horms@verge.net.au, geert@glider.be Cc: bcousson@baylibre.com, linux-sh@vger.kernel.org, Axel Haslam Subject: [RFC/RFT 4/6] ARM: shmobile: Add MCPM back end functions Date: Mon, 12 Oct 2015 19:41:12 +0200 Message-Id: <1444671674-19275-5-git-send-email-ahaslam@baylibre.com> X-Mailer: git-send-email 2.4.5 In-Reply-To: <1444671674-19275-1-git-send-email-ahaslam@baylibre.com> References: <1444671674-19275-1-git-send-email-ahaslam@baylibre.com> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Axel Haslam Add machine-dependent MCPM call-backs for shmobile. (inspired form arch/arm/mach-vexpress/tc2_pm.c) Signed-off-by: Axel Haslam --- arch/arm/mach-shmobile/Kconfig | 9 ++ arch/arm/mach-shmobile/Makefile | 1 + arch/arm/mach-shmobile/common.h | 6 ++ arch/arm/mach-shmobile/mcpm-shmobile.c | 155 +++++++++++++++++++++++++++++++++ arch/arm/mach-shmobile/platsmp-apmu.c | 2 +- 5 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-shmobile/mcpm-shmobile.c diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 926e336..e73628d 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -75,6 +75,7 @@ config ARCH_R8A7779 config ARCH_R8A7790 bool "R-Car H2 (R8A77900)" select ARCH_RCAR_GEN2 + select SHMOBILE_MCPM if MCPM select I2C config ARCH_R8A7791 @@ -96,6 +97,14 @@ config ARCH_SH73A0 select ARCH_RMOBILE select RENESAS_INTC_IRQPIN +config SHMOBILE_MCPM + bool "Shmobile Multi-Cluster PM support" + default n + depends on MCPM + select ARM_CCI400_PORT_CTRL + help + This is needed to provide CPU and cluster power management. + comment "Renesas ARM SoCs System Configuration" endif diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 476de30..8793a83 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_PM_RCAR) += pm-rcar.o obj-$(CONFIG_PM_RMOBILE) += pm-rmobile.o obj-$(CONFIG_ARCH_RCAR_GEN2) += pm-rcar-gen2.o +obj-$(CONFIG_SHMOBILE_MCPM) += mcpm-shmobile.o # Board objects ifndef CONFIG_ARCH_SHMOBILE_MULTI diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 8d27ec5..13a4efd 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -22,6 +22,12 @@ struct clk; extern int shmobile_clk_init(void); extern struct platform_suspend_ops shmobile_suspend_ops; +#if defined(CONFIG_SHMOBILE_MCPM) +extern bool sh_mcpm_probed(void); +#else +static inline bool sh_mcpm_probed(void) { return false; } +#endif + #ifdef CONFIG_SUSPEND int shmobile_suspend_init(void); void shmobile_smp_apmu_suspend_init(void); diff --git a/arch/arm/mach-shmobile/mcpm-shmobile.c b/arch/arm/mach-shmobile/mcpm-shmobile.c new file mode 100644 index 0000000..cc7fe5f --- /dev/null +++ b/arch/arm/mach-shmobile/mcpm-shmobile.c @@ -0,0 +1,155 @@ +/* + * SMP support for SoCs with APMU + * + * Copyright (C) 2015 Renesas Electronics Corporation + * + * 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 +#include +#include +#include + +#include +#include + +#include "common.h" +#include "platsmp-apmu.h" + +static bool sh_mcpm_probe_ok; + +static inline unsigned int pcpu_to_cpu(unsigned int pcpu, unsigned int pcluster) +{ + unsigned int mpidr = 0; + + mpidr = pcpu | (pcluster << MPIDR_LEVEL_BITS); + + return get_logical_index(mpidr); +} + +bool sh_mcpm_probed(void) +{ + return sh_mcpm_probe_ok; +} + +static void __naked sh_mcpm_power_up_setup(unsigned int affinity_level) +{ + asm volatile ("\n" + "cmp r0, #1\n" + "bxne lr\n" + "b cci_enable_port_for_self "); +} + +static int sh_mcpm_cpu_powerup(unsigned int pcpu, unsigned int pcluster) +{ + int cpu = pcpu_to_cpu(pcpu, pcluster); + + apmu_power_on(cpu); + + return 0; +} + +static int sh_mcpm_cluster_powerup(unsigned int cluster) +{ + return 0; +} + +static void sh_mcpm_cpu_powerdown_prepare(unsigned int pcpu, + unsigned int pcluster) +{ + int cpu = pcpu_to_cpu(pcpu, pcluster); + + apmu_power_off(cpu); +} + +static void sh_mcpm_cluster_powerdown_prepare(unsigned int pcluster) +{ +} + +static void sh_mcpm_cpu_cache_disable(void) +{ + v7_exit_coherency_flush(louis); +} + +static void sh_mcpm_cluster_cache_disable(void) +{ + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) { + /* disable L2 prefetching on the Cortex-A15 */ + asm volatile( + "mcr p15, 1, %0, c15, c0, 3\n\t" + "isb\n\t" + "dsb" + : : "r" (0x400)); + } + + v7_exit_coherency_flush(all); + cci_disable_port_by_cpu(read_cpuid_mpidr()); +} + +static void sh_mcpm_cpu_is_up(unsigned int pcpu, unsigned int pcluster) +{ +} + +static int sh_mcpm_wait_for_powerdown(unsigned int pcpu, unsigned int pcluster) +{ + int cpu = pcpu_to_cpu(pcpu, pcluster); + + apmu_power_off_poll(cpu); + + return 0; +} + +static const struct mcpm_platform_ops sh_mcpm_power_ops = { + .cpu_powerup = sh_mcpm_cpu_powerup, + .cluster_powerup = sh_mcpm_cluster_powerup, + .cpu_powerdown_prepare = sh_mcpm_cpu_powerdown_prepare, + .cluster_powerdown_prepare = sh_mcpm_cluster_powerdown_prepare, + .cpu_cache_disable = sh_mcpm_cpu_cache_disable, + .cluster_cache_disable = sh_mcpm_cluster_cache_disable, + .wait_for_powerdown = sh_mcpm_wait_for_powerdown, + .cpu_is_up = sh_mcpm_cpu_is_up, +}; + +static int __init sh_mcpm_init(void) +{ + struct device_node *node; + int ret = 0; + int i; + + sh_mcpm_probe_ok = false; + + /* Register boot function as boot cpu did not call power up + * but will call power down on idle. + */ + + node = of_find_compatible_node(NULL, NULL, "arm,cci-400"); + if (!node && !of_device_is_available(node)) { + pr_err("cci-400 node not found!"); + return -ENODEV; + } + + if (!cci_probed()) + return -ENODEV; + + ret = mcpm_platform_register(&sh_mcpm_power_ops); + if (!ret) + ret = mcpm_sync_init(sh_mcpm_power_up_setup); + if (!ret) + ret = mcpm_loopback(sh_mcpm_cluster_cache_disable); /* CCI on */ + if (ret) { + pr_err("mcpm could not be stared. %d\n", ret); + return ret; + } + + for (i = 0; i < num_possible_cpus(); i++) + shmobile_smp_hook(i, + virt_to_phys(mcpm_entry_point), 0); + + mcpm_smp_set_ops(); + sh_mcpm_probe_ok = true; + + return 0; +} +early_initcall(sh_mcpm_init); diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index b88d97c..e9988b7 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -46,7 +46,7 @@ int __maybe_unused apmu_power_on(unsigned int cpu) if (!p) return -EINVAL; - if (pcluster != boot_pcluster) { + if (!sh_mcpm_probed() && (pcluster != boot_pcluster)) { pr_err("Requested to boot cpu %d on non-boot cluster!\n", cpu); return -EINVAL; }