From patchwork Mon Mar 2 20:30:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 45315 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id BEC49214B5 for ; Mon, 2 Mar 2015 20:30:37 +0000 (UTC) Received: by wivr20 with SMTP id r20sf11620685wiv.3 for ; Mon, 02 Mar 2015 12:30:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=/EYbktKF8IxoUyRPY1NmkSpSHLnOPoGN0+S4x4FACPU=; b=M077O8IFe0mgrXIjtZ2kf7T3WF8u6yHs5o1672Ljj3Sv4/MW7sC3oIV8p9Ta5QDxcc c3vcwIAQVRuDs3yvtfBZYJKIRlwWh5Yw7TrmDGXF6MnaXEIvFq70pqmrdihP5YgxbkiZ XfVZHPtoe94nT7n+IkVfjcbCu8YVr5kCaVUKH5qcq7SAP2+DteIgSYttBLTmVLcXFHTZ LUNerVV7x9Cgt/ufPZB+q7F1MKmhLWfoyge3gk2yPhcUp9G9ibptlbLozKQdKGPwzghA kCNePupdO0B53p+ZKvlmTvyFWKrkrOTUgCZssMTgUJ/iHMNc29jFwStk+4Q5K1ASNVKC dwdg== X-Gm-Message-State: ALoCoQm2M4wyds1qlXHrnBZ2rddbzhhJDSNeSz8u1oZAgtG4MeouxFXs+5tlMHkYwXNyrODFQJIM X-Received: by 10.194.221.65 with SMTP id qc1mr4067024wjc.7.1425328237098; Mon, 02 Mar 2015 12:30:37 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.164.193 with SMTP id ys1ls506764lab.39.gmail; Mon, 02 Mar 2015 12:30:36 -0800 (PST) X-Received: by 10.152.243.4 with SMTP id wu4mr26203573lac.33.1425328236832; Mon, 02 Mar 2015 12:30:36 -0800 (PST) Received: from mail-la0-f43.google.com (mail-la0-f43.google.com. [209.85.215.43]) by mx.google.com with ESMTPS id c5si9703035laf.16.2015.03.02.12.30.36 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Mar 2015 12:30:36 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) client-ip=209.85.215.43; Received: by labgm9 with SMTP id gm9so33013354lab.2 for ; Mon, 02 Mar 2015 12:30:36 -0800 (PST) X-Received: by 10.152.116.18 with SMTP id js18mr26160545lab.106.1425328236691; Mon, 02 Mar 2015 12:30:36 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp140690lbj; Mon, 2 Mar 2015 12:30:35 -0800 (PST) X-Received: by 10.68.237.2 with SMTP id uy2mr49853243pbc.72.1425328226803; Mon, 02 Mar 2015 12:30:26 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h7si8247492pdn.131.2015.03.02.12.30.25; Mon, 02 Mar 2015 12:30:26 -0800 (PST) Received-SPF: none (google.com: linux-pm-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754775AbbCBUaY (ORCPT + 11 others); Mon, 2 Mar 2015 15:30:24 -0500 Received: from mail-pd0-f171.google.com ([209.85.192.171]:36423 "EHLO mail-pd0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754554AbbCBUaW (ORCPT ); Mon, 2 Mar 2015 15:30:22 -0500 Received: by pdbnh10 with SMTP id nh10so18658262pdb.3 for ; Mon, 02 Mar 2015 12:30:22 -0800 (PST) X-Received: by 10.66.66.105 with SMTP id e9mr49807260pat.17.1425328222079; Mon, 02 Mar 2015 12:30:22 -0800 (PST) Received: from ubuntu.localdomain (i-global254.qualcomm.com. [199.106.103.254]) by mx.google.com with ESMTPSA id bs2sm12730008pbd.74.2015.03.02.12.30.20 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 02 Mar 2015 12:30:21 -0800 (PST) From: Lina Iyer To: sboyd@codeaurora.org, galak@codeaurora.org, linux-arm-msm@vger.kernel.org, agross@codeaurora.org Cc: linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, khilman@linaro.org, Lina Iyer , Stephen Boyd Subject: [PATCH v3 3/3] firmware: qcom: scm: Support cpu power down through SCM Date: Mon, 2 Mar 2015 13:30:07 -0700 Message-Id: <1425328207-58415-4-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1425328207-58415-1-git-send-email-lina.iyer@linaro.org> References: <1425328207-58415-1-git-send-email-lina.iyer@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lina.iyer@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Support powering down the calling cpu, by trapping into SCM. This termination function triggers the ARM cpu to execute WFI instruction, causing the power controller to safely power the cpu down. Caches may be flushed before powering down the cpu. If cache controller is set to turn off when the cpu is powered down, then the flags argument indicates to the secure mode to flush its cache lines before executing WFI.The warm boot reset address for the cpu should be set before the calling into this function for the cpu to resume. The original code for the qcom_scm_call_atomic1() comes from a patch by Stephen Boyd [1]. The function scm_call_atomic1() has been cherry picked and renamed to match the convention used in this file. Since there are no users of scm_call_atomic2(), the function is not included. [1]. https://lkml.org/lkml/2014/8/4/765 Signed-off-by: Stephen Boyd Signed-off-by: Lina Iyer --- drivers/firmware/qcom_scm.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/qcom_scm.h | 6 ++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 4d8ede4..994b50f 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -311,6 +311,45 @@ out: return ret; } +#define SCM_CLASS_REGISTER (0x2 << 8) +#define SCM_MASK_IRQS BIT(5) +#define SCM_ATOMIC(svc, cmd, n) (((((svc) << 10)|((cmd) & 0x3ff)) << 12) | \ + SCM_CLASS_REGISTER | \ + SCM_MASK_IRQS | \ + (n & 0xf)) + +/** + * qcom_scm_call_atomic1() - Send an atomic SCM command with one argument + * @svc_id: service identifier + * @cmd_id: command identifier + * @arg1: first argument + * + * This shall only be used with commands that are guaranteed to be + * uninterruptable, atomic and SMP safe. + */ +static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1) +{ + int context_id; + + register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1); + register u32 r1 asm("r1") = (u32)&context_id; + register u32 r2 asm("r2") = arg1; + + asm volatile( + __asmeq("%0", "r0") + __asmeq("%1", "r0") + __asmeq("%2", "r1") + __asmeq("%3", "r2") +#ifdef REQUIRES_SEC + ".arch_extension sec\n" +#endif + "smc #0 @ switch to secure world\n" + : "=r" (r0) + : "r" (r0), "r" (r1), "r" (r2) + : "r3"); + return r0; +} + u32 qcom_scm_get_version(void) { int context_id; @@ -435,3 +474,21 @@ int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus) return ret; } EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); + +#define QCOM_SCM_CMD_TERMINATE_PC 0x2 +#define QCOM_SCM_FLUSH_FLAG_MASK 0x3 + +/** + * qcom_scm_cpu_power_down() - Power down the cpu + * @flags - Flags to flush cache + * + * This is an end point to power down cpu. If there was a pending interrupt, + * the control would return from this function, otherwise, the cpu jumps to the + * warm boot entry point set for this cpu upon reset. + */ +void qcom_scm_cpu_power_down(u32 flags) +{ + qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC, + flags & QCOM_SCM_FLUSH_FLAG_MASK); +} +EXPORT_SYMBOL(qcom_scm_cpu_power_down); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 95ef72a..0f26f44 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Code Aurora Forum. All rights reserved. +/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. * * This program is free software; you can redistribute it and/or modify @@ -13,8 +13,12 @@ #ifndef __QCOM_SCM_H #define __QCOM_SCM_H +#define QCOM_SCM_L2_ON 0x0 +#define QCOM_SCM_L2_OFF 0x1 + extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); +extern void qcom_scm_cpu_power_down(u32 flags); #define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))