From patchwork Thu Oct 19 16:42:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Romain Izard X-Patchwork-Id: 10017703 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D255060224 for ; Thu, 19 Oct 2017 16:42:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C517528B64 for ; Thu, 19 Oct 2017 16:42:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B9F0028D7B; Thu, 19 Oct 2017 16:42:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2F69128B64 for ; Thu, 19 Oct 2017 16:42:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753715AbdJSQmh (ORCPT ); Thu, 19 Oct 2017 12:42:37 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:52839 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752682AbdJSQmc (ORCPT ); Thu, 19 Oct 2017 12:42:32 -0400 Received: by mail-wr0-f194.google.com with SMTP id k62so8963820wrc.9; Thu, 19 Oct 2017 09:42:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5v5OQvNstnVmbIx9/rItx5KKfRrxeaMxdASdro2SAIU=; b=pdFuy6ZGWbFljh3ga6+j7X0BgVXEoIckKxmbvpGUT+CIddXyFacowVnP1PKt9Qr0ng suupTWdYbaBWqMPbHPsDA5uFI715k3lhisAHMJ60mPORfY/qyv9NqlmKzBJqHX3Eq52P GKO+AKegWyVA0A1dzhUuqcF9gR7erfkJYeAygDsuEN9KMIEWxVGH5UIBdFLfaRxI9KN5 PnEmMWWsVZCiG/5Smxe60lfvofL0nTCtxyRr8nGzstus+GH5ONbS7oD/KSzDH+f5Zx9R rhPLO4iVrycHV3YR/iUoCTXVHkNDeo4obyY+md9KQxlPEfF5NLjRa/mmhUk2KlKQbmVW fVpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5v5OQvNstnVmbIx9/rItx5KKfRrxeaMxdASdro2SAIU=; b=Gu2A5c1u+PrP2T3jJfTkFAEDMIlnaEVzGr5lCcKa/EliKAP4Dr16UEcIwrCBCC6qIA UNlcakOkeDHig7aWuI00b1hjIcYtnFMOoPfy8c7LeTdbn5fnMrgE5VwB6FAj4xVw4lgZ 68Jd7AgIlrcDwpZEj6ARfdYN75tZi/90HMMK4pJR3akqaJ4h9uCbL2ZDXm54dqsiqaLs hB0dgADv5coEI4zapKPMEXYmLn1ylhA2lTmKMViXsMZdN0GMOGdvYSU4Wu2xNkW3naBN G3jg5CRQn+4VvtH+j+o+yb0biSdzMUGD55gx+wDFrjErGSQDiYs4rH1TT8hXfQF/VY2t 6SKg== X-Gm-Message-State: AMCzsaWIOeksVNrXsaRr4VT8Ycu7nUQoZUJ20f/IBfWNJcGQf5Lw8aYh OqXx4eR3HdOTLja4MaYZvCw= X-Google-Smtp-Source: ABhQp+QeLhke64agUV7bK41VYcu4NMpbXhG4JS7lL5Z8eYb3xljGq+QOHCOIaWTqlk6gCZqmETrDTQ== X-Received: by 10.223.167.154 with SMTP id j26mr2038839wrc.174.1508431351225; Thu, 19 Oct 2017 09:42:31 -0700 (PDT) Received: from localhost.localdomain (146.187.3.109.rev.sfr.net. [109.3.187.146]) by smtp.gmail.com with ESMTPSA id a195sm1458905wme.34.2017.10.19.09.42.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 19 Oct 2017 09:42:30 -0700 (PDT) From: Romain Izard To: Boris Brezillon , Michael Turquette , Stephen Boyd , Alexandre Belloni , Nicolas Ferre , Ludovic Desroches Cc: linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Romain Izard , Romain Izard Subject: [PATCH v5 3/3] clk: at91: pmc: Support backup for programmable clocks Date: Thu, 19 Oct 2017 18:42:07 +0200 Message-Id: <20171019164207.32717-4-romain.izard.pro@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171019164207.32717-1-romain.izard.pro@gmail.com> References: <20171019164207.32717-1-romain.izard.pro@gmail.com> Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Romain Izard When an AT91 programmable clock is declared in the device tree, register it into the Power Management Controller driver. On entering suspend mode, the driver saves and restores the Programmable Clock registers to support the backup mode for these clocks. Signed-off-by: Romain Izard Acked-by: Nicolas Ferre --- Changes in v2: * register PCKs on clock startup Changes in v3: * improve comments on hanling 0 in pmc_register_id and pmc_register_pck * declare local variables earlier for checkpatch drivers/clk/at91/clk-programmable.c | 2 ++ drivers/clk/at91/pmc.c | 35 +++++++++++++++++++++++++++++++++++ drivers/clk/at91/pmc.h | 2 ++ 3 files changed, 39 insertions(+) diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 85a449cf61e3..0e6aab1252fc 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c @@ -204,6 +204,8 @@ at91_clk_register_programmable(struct regmap *regmap, if (ret) { kfree(prog); hw = ERR_PTR(ret); + } else { + pmc_register_pck(id); } return hw; diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 07dc2861ad3f..1fa27f4ea538 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -22,6 +22,7 @@ #include "pmc.h" #define PMC_MAX_IDS 128 +#define PMC_MAX_PCKS 8 int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range) @@ -50,6 +51,7 @@ EXPORT_SYMBOL_GPL(of_at91_get_clk_range); static struct regmap *pmcreg; static u8 registered_ids[PMC_MAX_IDS]; +static u8 registered_pcks[PMC_MAX_PCKS]; static struct { @@ -66,8 +68,13 @@ static struct u32 pcr[PMC_MAX_IDS]; u32 audio_pll0; u32 audio_pll1; + u32 pckr[PMC_MAX_PCKS]; } pmc_cache; +/* + * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored + * without alteration in the table, and 0 is for unused clocks. + */ void pmc_register_id(u8 id) { int i; @@ -82,9 +89,28 @@ void pmc_register_id(u8 id) } } +/* + * As Programmable Clock 0 is valid on AT91 chips, there is an offset + * of 1 between the stored value and the real clock ID. + */ +void pmc_register_pck(u8 pck) +{ + int i; + + for (i = 0; i < PMC_MAX_PCKS; i++) { + if (registered_pcks[i] == 0) { + registered_pcks[i] = pck + 1; + break; + } + if (registered_pcks[i] == (pck + 1)) + break; + } +} + static int pmc_suspend(void) { int i; + u8 num; regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr); regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0); @@ -103,6 +129,10 @@ static int pmc_suspend(void) regmap_read(pmcreg, AT91_PMC_PCR, &pmc_cache.pcr[registered_ids[i]]); } + for (i = 0; registered_pcks[i]; i++) { + num = registered_pcks[i] - 1; + regmap_read(pmcreg, AT91_PMC_PCKR(num), &pmc_cache.pckr[num]); + } return 0; } @@ -119,6 +149,7 @@ static bool pmc_ready(unsigned int mask) static void pmc_resume(void) { int i; + u8 num; u32 tmp; u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA; @@ -143,6 +174,10 @@ static void pmc_resume(void) pmc_cache.pcr[registered_ids[i]] | AT91_PMC_PCR_CMD); } + for (i = 0; registered_pcks[i]; i++) { + num = registered_pcks[i] - 1; + regmap_write(pmcreg, AT91_PMC_PCKR(num), pmc_cache.pckr[num]); + } if (pmc_cache.uckr & AT91_PMC_UPLLEN) mask |= AT91_PMC_LOCKU; diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 858e8ef7e8db..d22b1fa9ecdc 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -31,8 +31,10 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname, #ifdef CONFIG_PM void pmc_register_id(u8 id); +void pmc_register_pck(u8 pck); #else static inline void pmc_register_id(u8 id) {} +static inline void pmc_register_pck(u8 pck) {} #endif #endif /* __PMC_H_ */