From patchwork Mon Dec 11 16:55:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Romain Izard X-Patchwork-Id: 10105537 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 E1D1F60360 for ; Mon, 11 Dec 2017 16:56:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE707297C2 for ; Mon, 11 Dec 2017 16:56:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C3026297C6; Mon, 11 Dec 2017 16:56:31 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham 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 2F1802976F for ; Mon, 11 Dec 2017 16:56:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752833AbdLKQ4a (ORCPT ); Mon, 11 Dec 2017 11:56:30 -0500 Received: from mail-wr0-f195.google.com ([209.85.128.195]:39903 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752598AbdLKQ4I (ORCPT ); Mon, 11 Dec 2017 11:56:08 -0500 Received: by mail-wr0-f195.google.com with SMTP id a41so18315444wra.6; Mon, 11 Dec 2017 08:56:07 -0800 (PST) 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=zVDV0D9/3sfFVSWtSL3Ld78j0fnpbPXXikLHTd/8MGU=; b=ib9EVGh53MhDzMwyqrttUZZqdZfYyGlrrHH0jAOBoB2h87Sg8NcXVRikO7IU5YbNX/ LMRseiEJKdSsBeB8sVxVzW6elDMmL9rCzU0mHEDBz3RWrklKy4/W/poPOvAIniTxyMGx z0wojkcxMhnJ014/9wbDxT89rUL9GahTm04omfYM8vylhZ0EqLGO3xz8GhhAGWahLpve uh94lhBv/gKbWVL17O80YAykoWsx2a8F3bsbP8GtlpTwGtGbPvoccgYSA2bPmI663atM Upm8eHNKMBaJ7yp5Tl7IIcbbUIz6KWGWny/oejDYAF4B80bGgZm6Dn0RUCTqW1/VVb44 42Iw== 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=zVDV0D9/3sfFVSWtSL3Ld78j0fnpbPXXikLHTd/8MGU=; b=IWVBxfEkpijTCvmsJBBKGg2ZLPj6eKjuuZNmCaRkX+AqpRwtKmrl8SpxtkfIUUEPao 8BKplRfcwohf+DZf/+z7AL+gOlkxeI4hhzqequnXiQ5PMvkJzVy/Al/2trSI8aoytLmm UCOFulkj2+7s7UgRx8nIVJyK/tuVP0+xQ70m/d1AxH+n+ge6WIXjePMgnfJOhDM78fGB GUCLpjzRsUPVOA9B2HhZaZMukvyPhswbUhaeED0wpUjOq2TqR5u9H857aagcmiMGMU/k w1afx8noB/d6/VUEzP2pmndZCL/mjl1fr18lb3RuVstLlQX4dBbKP9XGyEsu8xampZ9G POwg== X-Gm-Message-State: AKGB3mIc6fnPSCgO9+If8/oFK+zgOl6/H72yicoscEuXSoYHUojbebTv Ev7h/NVwM1UseTQA77xk2Qk= X-Google-Smtp-Source: ACJfBovueX8xw1K9p/3zidZYiZ7ZdAOWzn+/BvrDaXmDR6nB0x10oFrQH3M8IL474AaY8MJzDEKw2A== X-Received: by 10.223.138.246 with SMTP id z51mr1036453wrz.152.1513011366935; Mon, 11 Dec 2017 08:56:06 -0800 (PST) Received: from localhost.localdomain (146.187.3.109.rev.sfr.net. [109.3.187.146]) by smtp.gmail.com with ESMTPSA id j77sm12699597wmf.36.2017.12.11.08.56.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Dec 2017 08:56:06 -0800 (PST) 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 Subject: [PATCH v6 3/3] clk: at91: pmc: Support backup for programmable clocks Date: Mon, 11 Dec 2017 17:55:35 +0100 Message-Id: <20171211165535.5126-4-romain.izard.pro@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171211165535.5126-1-romain.izard.pro@gmail.com> References: <20171211165535.5126-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 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 Acked-by: Alexandre Belloni --- 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 Changes in v6: * Use the correct author email address 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_ */