Received: by 10.192.165.156 with SMTP id m28csp1488929imm; Wed, 11 Apr 2018 21:02:13 -0700 (PDT) X-Google-Smtp-Source: AIpwx49YZ5QfJwrTX1VorZTRastGluGvd3SPdh5lhRODorG/o+sD+jQkeKqZf3y3yhBg042gbJWs X-Received: by 10.99.112.82 with SMTP id a18mr5388302pgn.292.1523505733687; Wed, 11 Apr 2018 21:02:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523505733; cv=none; d=google.com; s=arc-20160816; b=NHBqotpYBDxkrI7CJYY396PAKiN6nU24RQC/WYQekhPL9lfX9MqUlFKXM3E8nLZV2M d/IoFCg11w+LMOqvKwsegKpyklfA0d4EmkM+1JVwCpf3xhGtIDZLYPqIVfwHBE6N2DEU BjROPDrX7ZdYHt3USCb9XxSYE/+F9XrOuH3Te08SLAu8VoDFtyBnxt5sejAEBigxeLei W+ECXK0KMDw/Fc3xt+5N+ryr4sS41NRGoaWxtAgKyd1xRVh9zSlRdYRckoZTnLdJrLe3 LnxXNadGR7M1Nu21QgoiKc7zJ7bDSYq0jYuGfEvsoyGOd8qAANE6A5yA2gC6/CechrIr 4TJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature :arc-authentication-results; bh=PWXNxhpIFuQxJEF8mn5q/fWL3wvyYb7UH+O5KU+9/ws=; b=f8hN6yuOqBwzuwJo8XUpxgydS2VHDPIzXMHIDXSvAcd/Vf4EBImvzrLmIkX1uk9zNi WK5kuxeTUqFUCndP0aJDd7xpyvYf2QRwRokuPz9B+98T8XVMWaO9V8QiKmMKcFYT01+G mf0eD71vtaUM5hIz+K7D2JW0DDwuVMayZ+WCB8bXbTv2WXw349e18p8C8Ej+9kR3oBst MQHdiYVlEI2YpQD2zqpQNPyaEThR6lRSy3jto0x0nMtiCOFhoFah6/QByuy2XmvsbsBn HVSU7ga7RByBqurIZFS4kzChwIw6yTEC5BOe7+RS8/ciYasbwA+vwSuBxJc8+1P+/838 eHjw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=IsF7YZdQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 3-v6si2443584plr.440.2018.04.11.21.01.36; Wed, 11 Apr 2018 21:02:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ti.com header.s=ti-com-17Q1 header.b=IsF7YZdQ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ti.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753193AbeDLD5R (ORCPT + 99 others); Wed, 11 Apr 2018 23:57:17 -0400 Received: from lelnx194.ext.ti.com ([198.47.27.80]:58105 "EHLO lelnx194.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752660AbeDLDzC (ORCPT ); Wed, 11 Apr 2018 23:55:02 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by lelnx194.ext.ti.com (8.15.1/8.15.1) with ESMTP id w3C3sno0026998; Wed, 11 Apr 2018 22:54:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ti.com; s=ti-com-17Q1; t=1523505289; bh=R0FO1t+Q4MNYTbwrk0EgEFeyyiiMdFoNT2jLYUghXAk=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=IsF7YZdQ8b7P8fDNEsh/+rpPT3NJ7GCdJB7n/oPuTECDLXu64biD+aR4/SVkA34ME JqYzNx5g+hBUunxNIZMXT+g+a2myC2rOdgX5k2KiSJsoOItwHPOwT4FmqUVB4Qute5 ZxISfzZf88XBPdQcjZA/4zSieVIGCKR9HSWoO0Wg= Received: from DLEE115.ent.ti.com (dlee115.ent.ti.com [157.170.170.26]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id w3C3snFB007814; Wed, 11 Apr 2018 22:54:49 -0500 Received: from DLEE103.ent.ti.com (157.170.170.33) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1261.35; Wed, 11 Apr 2018 22:54:48 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1261.35 via Frontend Transport; Wed, 11 Apr 2018 22:54:48 -0500 Received: from ula0393675.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id w3C3sQpm010150; Wed, 11 Apr 2018 22:54:45 -0500 From: Keerthy To: , , CC: , , , , , , , , Subject: [PATCH 05/14] ARM: OMAP2: Add functions to save and restore powerdomain context Date: Thu, 12 Apr 2018 09:23:50 +0530 Message-ID: <1523505239-16229-6-git-send-email-j-keerthy@ti.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1523505239-16229-1-git-send-email-j-keerthy@ti.com> References: <1523505239-16229-1-git-send-email-j-keerthy@ti.com> MIME-Version: 1.0 Content-Type: text/plain X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Russ Dill The powerdomain control registers are stored in the WKUP powerdomain on AM33XX/AM43XX, which is lost on RTC-only suspend and also hibernate. This adds context save and restore functions for those registers. Sometimes the powerdomain state does not need to change, perhaps we only need to change memory retention states, so make sure the restored state is different from the current state before we wait for a transition. Signed-off-by: Keerthy Signed-off-by: Dave Gerlach Signed-off-by: Russ Dill --- arch/arm/mach-omap2/powerdomain.c | 60 +++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomain.h | 7 +++++ arch/arm/mach-omap2/prm33xx.c | 31 ++++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 50 ++++++++++++++++++++++++++++++++ 4 files changed, 148 insertions(+) diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 76eb6ec..ee693f6 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -1199,3 +1199,63 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm) return 0; } + +/** + * pwrdm_save_context - save powerdomain registers + * + * Register state is going to be lost due to a suspend or hibernate + * event. Save the powerdomain registers. + */ +static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused) +{ + if (arch_pwrdm && arch_pwrdm->pwrdm_save_context) + arch_pwrdm->pwrdm_save_context(pwrdm); + return 0; +} + +/** + * pwrdm_save_context - restore powerdomain registers + * + * Restore powerdomain control registers after a suspend or resume + * event. + */ +static int pwrdm_restore_context(struct powerdomain *pwrdm, void *unused) +{ + if (arch_pwrdm && arch_pwrdm->pwrdm_restore_context) + arch_pwrdm->pwrdm_restore_context(pwrdm); + return 0; +} + +static int pwrdm_lost_power(struct powerdomain *pwrdm, void *unused) +{ + int state; + + /* + * Power has been lost across all powerdomains, increment the + * counter. + */ + + state = pwrdm_read_pwrst(pwrdm); + if (state != PWRDM_POWER_OFF) { + pwrdm->state_counter[state]++; + pwrdm->state_counter[PWRDM_POWER_OFF]++; + } + pwrdm->state = state; + + return 0; +} + +void pwrdms_save_context(void) +{ + pwrdm_for_each(pwrdm_save_context, NULL); +} + +void pwrdms_restore_context(void) +{ + pwrdm_for_each(pwrdm_restore_context, NULL); +} + +void pwrdms_lost_power(void) +{ + pwrdm_for_each(pwrdm_lost_power, NULL); +} diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 28a796c..9a907fb 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -144,6 +144,7 @@ struct powerdomain { s64 timer; s64 state_timer[PWRDM_MAX_PWRSTS]; #endif + u32 context; }; /** @@ -198,6 +199,8 @@ struct pwrdm_ops { int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm); int (*pwrdm_wait_transition)(struct powerdomain *pwrdm); int (*pwrdm_has_voltdm)(void); + void (*pwrdm_save_context)(struct powerdomain *pwrdm); + void (*pwrdm_restore_context)(struct powerdomain *pwrdm); }; int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs); @@ -273,4 +276,8 @@ u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm, extern void pwrdm_lock(struct powerdomain *pwrdm); extern void pwrdm_unlock(struct powerdomain *pwrdm); +extern void pwrdms_save_context(void); +extern void pwrdms_restore_context(void); + +extern void pwrdms_lost_power(void); #endif diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index ebaf80d..d514166 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c @@ -342,6 +342,35 @@ static void am33xx_prm_global_warm_sw_reset(void) AM33XX_PRM_RSTCTRL_OFFSET); } +static void am33xx_pwrdm_save_context(struct powerdomain *pwrdm) +{ + pwrdm->context = am33xx_prm_read_reg(pwrdm->prcm_offs, + pwrdm->pwrstctrl_offs); + /* + * Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request, + * reading back a 1 indicates a request in progress. + */ + pwrdm->context &= ~AM33XX_LOWPOWERSTATECHANGE_MASK; +} + +static void am33xx_pwrdm_restore_context(struct powerdomain *pwrdm) +{ + int st, ctrl; + + st = am33xx_prm_read_reg(pwrdm->prcm_offs, + pwrdm->pwrstst_offs); + + am33xx_prm_write_reg(pwrdm->context, pwrdm->prcm_offs, + pwrdm->pwrstctrl_offs); + + /* Make sure we only wait for a transition if there is one */ + st &= OMAP_POWERSTATEST_MASK; + ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context; + + if (st != ctrl) + am33xx_pwrdm_wait_transition(pwrdm); +} + struct pwrdm_ops am33xx_pwrdm_operations = { .pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst, .pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst, @@ -357,6 +386,8 @@ struct pwrdm_ops am33xx_pwrdm_operations = { .pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst, .pwrdm_wait_transition = am33xx_pwrdm_wait_transition, .pwrdm_has_voltdm = am33xx_check_vcvp, + .pwrdm_save_context = am33xx_pwrdm_save_context, + .pwrdm_restore_context = am33xx_pwrdm_restore_context, }; static struct prm_ll_data am33xx_prm_ll_data = { diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index acb9593..47b657c 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -667,6 +667,54 @@ static int omap4_check_vcvp(void) return 0; } +/** + * omap4_pwrdm_save_context - Saves the powerdomain state + * @pwrdm: pointer to individual powerdomain + * + * The function saves the powerdomain state control information. + * This is needed in rtc+ddr modes where we lose powerdomain context. + */ +static void omap4_pwrdm_save_context(struct powerdomain *pwrdm) +{ + pwrdm->context = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, + pwrdm->prcm_offs, + pwrdm->pwrstctrl_offs); + + /* + * Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request, + * reading back a 1 indicates a request in progress. + */ + pwrdm->context &= ~OMAP4430_LOWPOWERSTATECHANGE_MASK; +} + +/** + * omap4_pwrdm_restore_context - Restores the powerdomain state + * @pwrdm: pointer to individual powerdomain + * + * The function restores the powerdomain state control information. + * This is needed in rtc+ddr modes where we lose powerdomain context. + */ +static void omap4_pwrdm_restore_context(struct powerdomain *pwrdm) +{ + int st, ctrl; + + st = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, + pwrdm->prcm_offs, + pwrdm->pwrstctrl_offs); + + omap4_prminst_write_inst_reg(pwrdm->context, + pwrdm->prcm_partition, + pwrdm->prcm_offs, + pwrdm->pwrstctrl_offs); + + /* Make sure we only wait for a transition if there is one */ + st &= OMAP_POWERSTATEST_MASK; + ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context; + + if (st != ctrl) + omap4_pwrdm_wait_transition(pwrdm); +} + struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst, @@ -685,6 +733,8 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, .pwrdm_wait_transition = omap4_pwrdm_wait_transition, .pwrdm_has_voltdm = omap4_check_vcvp, + .pwrdm_save_context = omap4_pwrdm_save_context, + .pwrdm_restore_context = omap4_pwrdm_restore_context, }; static int omap44xx_prm_late_init(void); -- 1.9.1