From patchwork Mon Aug 24 09:40:48 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Fernandez X-Patchwork-Id: 52627 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f197.google.com (mail-wi0-f197.google.com [209.85.212.197]) by patches.linaro.org (Postfix) with ESMTPS id 3512F2041A for ; Mon, 24 Aug 2015 09:42:36 +0000 (UTC) Received: by wilj18 with SMTP id j18sf24894700wil.0 for ; Mon, 24 Aug 2015 02:42: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: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=lLSOIJ6noFWr3Va8ZxguSeM5M90eA/z9786BRGuAulU=; b=GBYicvxuZebOMMfZzj71VUPOjBp/SFX3hrQjPJRAliyc+4Gkln48zvnghOJEk5U399 kH695Fs+5Mpn/PzRbyJ7OQrjavUekASjOD8V5Cr5PXbo/lGHRdhBsyRz/5kYQzcI38Fk y8gAlCGptxQqsn9jq/jVd24UqktgkYn7ESxuVZ/ogbVtuXLoPaOv+x+4noKyGpHjLSt2 fXxL3UvpXTx8FLUFxK0Ke8zB+ZCPbES6a4VX7WHrH5CGt7cRNdhtliK7OtH4DSlpIW/v 2/w+OwkZJSZP3g0ekjSNToNBe81rLWj5DZp5kZCZzixqcMa2ATlKRLKDas+X1CkxjVmk O7vQ== X-Gm-Message-State: ALoCoQlM9RuonwMyC6jZsBqzP91gODyEJoCz6k0luUFwy30DJo9hfReLujP0OuNZe3E1SqMfzgZR X-Received: by 10.112.132.105 with SMTP id ot9mr6524996lbb.21.1440409355520; Mon, 24 Aug 2015 02:42:35 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.28.226 with SMTP id e2ls509424lah.14.gmail; Mon, 24 Aug 2015 02:42:35 -0700 (PDT) X-Received: by 10.112.234.165 with SMTP id uf5mr18934331lbc.91.1440409355336; Mon, 24 Aug 2015 02:42:35 -0700 (PDT) Received: from mail-lb0-f179.google.com (mail-lb0-f179.google.com. [209.85.217.179]) by mx.google.com with ESMTPS id qg4si12687930lbb.25.2015.08.24.02.42.35 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Aug 2015 02:42:35 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.179 as permitted sender) client-ip=209.85.217.179; Received: by lbbsx3 with SMTP id sx3so76163897lbb.0 for ; Mon, 24 Aug 2015 02:42:35 -0700 (PDT) X-Received: by 10.152.18.164 with SMTP id x4mr14988014lad.35.1440409355050; Mon, 24 Aug 2015 02:42:35 -0700 (PDT) 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.162.200 with SMTP id yc8csp2346019lbb; Mon, 24 Aug 2015 02:42:33 -0700 (PDT) X-Received: by 10.68.168.161 with SMTP id zx1mr44212553pbb.35.1440409352851; Mon, 24 Aug 2015 02:42:32 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id cq7si16707263pad.104.2015.08.24.02.42.31; Mon, 24 Aug 2015 02:42:32 -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; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933900AbbHXJmO (ORCPT + 28 others); Mon, 24 Aug 2015 05:42:14 -0400 Received: from mail-wi0-f170.google.com ([209.85.212.170]:33618 "EHLO mail-wi0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933344AbbHXJmL (ORCPT ); Mon, 24 Aug 2015 05:42:11 -0400 Received: by wijp15 with SMTP id p15so71821244wij.0 for ; Mon, 24 Aug 2015 02:42:10 -0700 (PDT) X-Received: by 10.180.21.169 with SMTP id w9mr28386564wie.73.1440409330708; Mon, 24 Aug 2015 02:42:10 -0700 (PDT) Received: from lmenx315.st.com. ([80.12.55.183]) by smtp.gmail.com with ESMTPSA id ub19sm15309920wib.8.2015.08.24.02.42.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Aug 2015 02:42:10 -0700 (PDT) From: Gabriel Fernandez To: Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Srinivas Kandagatla , Maxime Coquelin , Patrice Chotard , Russell King , Michael Turquette , Stephen Boyd , Gabriel Fernandez , Peter Griffin , Pankaj Dev , Olivier Bideau , Geert Uytterhoeven , Fabian Frederick Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@stlinux.com, linux-clk@vger.kernel.org Subject: [PATCH v2 1/4] drivers: clk: st: Support for enable/disable in Clockgen PLLs Date: Mon, 24 Aug 2015 11:40:48 +0200 Message-Id: <1440409251-11166-2-git-send-email-gabriel.fernandez@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org> References: <1440409251-11166-1-git-send-email-gabriel.fernandez@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: gabriel.fernandez@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.217.179 as permitted sender) smtp.mailfrom=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: , The patch adds support for enable/disable of the Clockgen PLLs. clkgen_pll_enable/clkgen_pll_disable added as generic function for all PLLs. Signed-off-by: Pankaj Dev Signed-off-by: Gabriel Fernandez --- drivers/clk/st/clkgen-pll.c | 92 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index b2a332c..7ee485d 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "clkgen.h" @@ -43,6 +44,7 @@ static DEFINE_SPINLOCK(clkgena_c32_odf_lock); struct clkgen_pll_data { struct clkgen_field pdn_status; + struct clkgen_field pdn_ctrl; struct clkgen_field locked_status; struct clkgen_field mdiv; struct clkgen_field ndiv; @@ -62,6 +64,7 @@ static const struct clk_ops st_pll1200c32_ops; static const struct clkgen_pll_data st_pll1600c65_ax = { .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), + .pdn_ctrl = CLKGEN_FIELD(0x10, 0x1, 0), .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL1600_MASK, 0), .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), @@ -70,6 +73,7 @@ static const struct clkgen_pll_data st_pll1600c65_ax = { static const struct clkgen_pll_data st_pll800c65_ax = { .pdn_status = CLKGEN_FIELD(0x0, 0x1, 19), + .pdn_ctrl = CLKGEN_FIELD(0xC, 0x1, 1), .locked_status = CLKGEN_FIELD(0x0, 0x1, 31), .mdiv = CLKGEN_FIELD(0x0, C65_MDIV_PLL800_MASK, 0), .ndiv = CLKGEN_FIELD(0x0, C65_NDIV_MASK, 8), @@ -79,6 +83,7 @@ static const struct clkgen_pll_data st_pll800c65_ax = { static const struct clkgen_pll_data st_pll3200c32_a1x_0 = { .pdn_status = CLKGEN_FIELD(0x0, 0x1, 31), + .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 0), .locked_status = CLKGEN_FIELD(0x4, 0x1, 31), .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 0x0), .idf = CLKGEN_FIELD(0x4, C32_IDF_MASK, 0x0), @@ -96,6 +101,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_0 = { static const struct clkgen_pll_data st_pll3200c32_a1x_1 = { .pdn_status = CLKGEN_FIELD(0xC, 0x1, 31), + .pdn_ctrl = CLKGEN_FIELD(0x18, 0x1, 1), .locked_status = CLKGEN_FIELD(0x10, 0x1, 31), .ndiv = CLKGEN_FIELD(0xC, C32_NDIV_MASK, 0x0), .idf = CLKGEN_FIELD(0x10, C32_IDF_MASK, 0x0), @@ -114,6 +120,7 @@ static const struct clkgen_pll_data st_pll3200c32_a1x_1 = { /* 415 specific */ static const struct clkgen_pll_data st_pll3200c32_a9_415 = { .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), + .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), .ndiv = CLKGEN_FIELD(0x0, C32_NDIV_MASK, 9), .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 22), @@ -125,6 +132,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_415 = { static const struct clkgen_pll_data st_pll3200c32_ddr_415 = { .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), + .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), .locked_status = CLKGEN_FIELD(0x100, 0x1, 0), .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), @@ -137,7 +145,8 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_415 = { }; static const struct clkgen_pll_data st_pll1200c32_gpu_415 = { - .pdn_status = CLKGEN_FIELD(0x144, 0x1, 3), + .pdn_status = CLKGEN_FIELD(0x4, 0x1, 0), + .pdn_ctrl = CLKGEN_FIELD(0x4, 0x1, 0), .locked_status = CLKGEN_FIELD(0x168, 0x1, 0), .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), @@ -149,6 +158,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_415 = { /* 416 specific */ static const struct clkgen_pll_data st_pll3200c32_a9_416 = { .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), + .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), .locked_status = CLKGEN_FIELD(0x6C, 0x1, 0), .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), @@ -160,6 +170,7 @@ static const struct clkgen_pll_data st_pll3200c32_a9_416 = { static const struct clkgen_pll_data st_pll3200c32_ddr_416 = { .pdn_status = CLKGEN_FIELD(0x0, 0x1, 0), + .pdn_ctrl = CLKGEN_FIELD(0x0, 0x1, 0), .locked_status = CLKGEN_FIELD(0x10C, 0x1, 0), .ndiv = CLKGEN_FIELD(0x8, C32_NDIV_MASK, 0), .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 25), @@ -173,6 +184,7 @@ static const struct clkgen_pll_data st_pll3200c32_ddr_416 = { static const struct clkgen_pll_data st_pll1200c32_gpu_416 = { .pdn_status = CLKGEN_FIELD(0x8E4, 0x1, 3), + .pdn_ctrl = CLKGEN_FIELD(0x8E4, 0x1, 3), .locked_status = CLKGEN_FIELD(0x90C, 0x1, 0), .ldf = CLKGEN_FIELD(0x0, C32_LDF_MASK, 3), .idf = CLKGEN_FIELD(0x0, C32_IDF_MASK, 0), @@ -184,6 +196,7 @@ static const struct clkgen_pll_data st_pll1200c32_gpu_416 = { static const struct clkgen_pll_data st_pll3200c32_407_a0 = { /* 407 A0 */ .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), + .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8), .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), @@ -196,6 +209,7 @@ static const struct clkgen_pll_data st_pll3200c32_407_a0 = { static const struct clkgen_pll_data st_pll3200c32_cx_0 = { /* 407 C0 PLL0 */ .pdn_status = CLKGEN_FIELD(0x2a0, 0x1, 8), + .pdn_ctrl = CLKGEN_FIELD(0x2a0, 0x1, 8), .locked_status = CLKGEN_FIELD(0x2a0, 0x1, 24), .ndiv = CLKGEN_FIELD(0x2a4, C32_NDIV_MASK, 16), .idf = CLKGEN_FIELD(0x2a4, C32_IDF_MASK, 0x0), @@ -208,6 +222,7 @@ static const struct clkgen_pll_data st_pll3200c32_cx_0 = { static const struct clkgen_pll_data st_pll3200c32_cx_1 = { /* 407 C0 PLL1 */ .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8), + .pdn_ctrl = CLKGEN_FIELD(0x2c8, 0x1, 8), .locked_status = CLKGEN_FIELD(0x2c8, 0x1, 24), .ndiv = CLKGEN_FIELD(0x2cc, C32_NDIV_MASK, 16), .idf = CLKGEN_FIELD(0x2cc, C32_IDF_MASK, 0x0), @@ -220,6 +235,7 @@ static const struct clkgen_pll_data st_pll3200c32_cx_1 = { static const struct clkgen_pll_data st_pll3200c32_407_a9 = { /* 407 A9 */ .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0), + .pdn_ctrl = CLKGEN_FIELD(0x1a8, 0x1, 0), .locked_status = CLKGEN_FIELD(0x87c, 0x1, 0), .ndiv = CLKGEN_FIELD(0x1b0, C32_NDIV_MASK, 0), .idf = CLKGEN_FIELD(0x1a8, C32_IDF_MASK, 25), @@ -271,6 +287,71 @@ static int clkgen_pll_is_enabled(struct clk_hw *hw) return !poweroff; } +static int __clkgen_pll_enable(struct clk_hw *hw) +{ + struct clkgen_pll *pll = to_clkgen_pll(hw); + void __iomem *base = pll->regs_base; + struct clkgen_field *field = &pll->data->locked_status; + int ret = 0; + u32 reg; + + if (clkgen_pll_is_enabled(hw)) + return 0; + + CLKGEN_WRITE(pll, pdn_ctrl, 0); + + ret = readl_relaxed_poll_timeout(base + field->offset, reg, + !!((reg >> field->shift) & field->mask), 0, 10000); + + if (!ret) + pr_debug("%s:%s enabled\n", __clk_get_name(hw->clk), __func__); + + return ret; +} + +static int clkgen_pll_enable(struct clk_hw *hw) +{ + struct clkgen_pll *pll = to_clkgen_pll(hw); + unsigned long flags = 0; + int ret = 0; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + ret = __clkgen_pll_enable(hw); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); + + return ret; +} + +static void __clkgen_pll_disable(struct clk_hw *hw) +{ + struct clkgen_pll *pll = to_clkgen_pll(hw); + + if (!clkgen_pll_is_enabled(hw)) + return; + + CLKGEN_WRITE(pll, pdn_ctrl, 1); + + pr_debug("%s:%s disabled\n", __clk_get_name(hw->clk), __func__); +} + +static void clkgen_pll_disable(struct clk_hw *hw) +{ + struct clkgen_pll *pll = to_clkgen_pll(hw); + unsigned long flags = 0; + + if (pll->lock) + spin_lock_irqsave(pll->lock, flags); + + __clkgen_pll_disable(hw); + + if (pll->lock) + spin_unlock_irqrestore(pll->lock, flags); +} + static unsigned long recalc_stm_pll800c65(struct clk_hw *hw, unsigned long parent_rate) { @@ -372,21 +453,29 @@ static unsigned long recalc_stm_pll1200c32(struct clk_hw *hw, } static const struct clk_ops st_pll1600c65_ops = { + .enable = clkgen_pll_enable, + .disable = clkgen_pll_disable, .is_enabled = clkgen_pll_is_enabled, .recalc_rate = recalc_stm_pll1600c65, }; static const struct clk_ops st_pll800c65_ops = { + .enable = clkgen_pll_enable, + .disable = clkgen_pll_disable, .is_enabled = clkgen_pll_is_enabled, .recalc_rate = recalc_stm_pll800c65, }; static const struct clk_ops stm_pll3200c32_ops = { + .enable = clkgen_pll_enable, + .disable = clkgen_pll_disable, .is_enabled = clkgen_pll_is_enabled, .recalc_rate = recalc_stm_pll3200c32, }; static const struct clk_ops st_pll1200c32_ops = { + .enable = clkgen_pll_enable, + .disable = clkgen_pll_disable, .is_enabled = clkgen_pll_is_enabled, .recalc_rate = recalc_stm_pll1200c32, }; @@ -414,6 +503,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name, pll->data = pll_data; pll->regs_base = reg; pll->hw.init = &init; + pll->lock = lock; clk = clk_register(NULL, &pll->hw); if (IS_ERR(clk)) {