From patchwork Thu Jul 13 07:49:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quentin Schulz X-Patchwork-Id: 107566 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp1884340qge; Thu, 13 Jul 2017 00:51:41 -0700 (PDT) X-Received: by 10.84.224.133 with SMTP id s5mr8365115plj.93.1499932301119; Thu, 13 Jul 2017 00:51:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499932301; cv=none; d=google.com; s=arc-20160816; b=oUbDb3RsTNUQZcL8izorDhWUqUxbNs90cdFsoxl/pFYYm1iGu0UtDSU6vIYo+64GCo 2Ckfj1tjtF5SPXNY9kPcPBz6mzJ38wswZLSFNnTxllijyWsUS1JvExxRUvAMmTg4wBUm dmXQP3VlsvTe5mOyOgfVc6YySgGaB788gWoX1SfNZ3dQXRS/yDh3PQHK6YfEdAVwsMUw t0SszWjtQJ2QGl/geFWa9I17c/UBCpySFXSt38lnVrA0V/Ik+XoCqUGnt/2vMyU16Z0g x8LOjiXfHf7upw8CbLNqKcYZF+HWMoxr5IA0Fk9tG4X+t8vHTRI/ajqSrZTdQyuBhItZ 08oQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=5q1VUiGZfLIKcWn3+cmabo+k6qbS89M3EJW6bqgGrDk=; b=AiFhHVg6zJv3xuuiRv2waq3B0gh9KLty7iw+tD1TnHjyXfy00LqU3bB5mmJV4uLMiD KJfGe2ZzGmjwQQjTflbTNhJgbDkMBlsg2yGQy802UAD30WmQ/I92o1YInWBJILyVrO+b s+K+Tl7LJmikglm5wizSzRLFYVtr/bL0m4f6iijEeXW0FnluZ0NXMXaKH4C5pjrZ8MI9 zDquJip3DIYpT3IlOumM+ce2b8n4TkiTewRFhamgjxzw+Oce1UsLNBBS3EglP24etEjz rnpcwAZzbJQU44g4qojRnGgZE3SOodkaJ7yXd1peLT6nW8+dodb76K9uEOycmvWBhJn5 0Ezw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 92si3898192plw.105.2017.07.13.00.51.40; Thu, 13 Jul 2017 00:51:41 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751882AbdGMHvX (ORCPT + 25 others); Thu, 13 Jul 2017 03:51:23 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:48064 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751238AbdGMHto (ORCPT ); Thu, 13 Jul 2017 03:49:44 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id DC84621FE2; Thu, 13 Jul 2017 09:49:40 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 7DD6D21FC7; Thu, 13 Jul 2017 09:49:40 +0200 (CEST) From: Quentin Schulz To: mturquette@baylibre.com, sboyd@codeaurora.org, robh+dt@kernel.org, mark.rutland@arm.com, lgirdwood@gmail.com, broonie@kernel.org, nicolas.ferre@microchip.com, alexandre.belloni@free-electrons.com, linux@armlinux.org.uk, boris.brezillon@free-electrons.com, perex@perex.cz, tiwai@suse.com Cc: Quentin Schulz , cyrille.pitchen@wedev4u.fr, thomas.petazzoni@free-electrons.com, linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v3 6/9] clk: at91: clk-generated: make gclk determine audio_pll rate Date: Thu, 13 Jul 2017 09:49:24 +0200 Message-Id: <20170713074927.10882-7-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170713074927.10882-1-quentin.schulz@free-electrons.com> References: <20170713074927.10882-1-quentin.schulz@free-electrons.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This allows gclk to determine audio_pll rate and set the parent rate accordingly. However, there are multiple children clocks that could technically change the rate of audio_pll (via gck). With the rate locking, the first consumer to enable the clock will be the one definitely setting the rate of the clock. Since audio IPs are most likely to request the same rate, we enforce that the only clks able to modify gck rate are those of audio IPs. To remain consistent, we deny other clocks to be children of audio_pll. Signed-off-by: Quentin Schulz Acked-by: Boris Brezillon --- v3: - added a flag per generated clock to know which one is allowed to modify audio_pll rate, - set the flag in setup function depending on the compatible and the clock ID, v2: - added conditions for audio pll rate setting restriction for SSC and I2S, drivers/clk/at91/clk-generated.c | 63 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) -- 2.11.0 diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 7260e498e059..33481368740e 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -26,6 +26,13 @@ #define GENERATED_SOURCE_MAX 6 #define GENERATED_MAX_DIV 255 +#define GCK_ID_SSC0 43 +#define GCK_ID_SSC1 44 +#define GCK_ID_I2S0 54 +#define GCK_ID_I2S1 55 +#define GCK_ID_CLASSD 59 +#define GCK_INDEX_DT_AUDIO_PLL 5 + struct clk_generated { struct clk_hw hw; struct regmap *regmap; @@ -34,6 +41,7 @@ struct clk_generated { u32 id; u32 gckdiv; u8 parent_id; + bool audio_pll_allowed; }; #define to_clk_generated(hw) \ @@ -126,15 +134,14 @@ static int clk_generated_determine_rate(struct clk_hw *hw, { struct clk_generated *gck = to_clk_generated(hw); struct clk_hw *parent = NULL; + struct clk_rate_request req_parent = *req; long best_rate = -EINVAL; - unsigned long min_rate; + unsigned long min_rate, parent_rate; int best_diff = -1; int i; + u32 div; - for (i = 0; i < clk_hw_get_num_parents(hw); i++) { - u32 div; - unsigned long parent_rate; - + for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) { parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; @@ -150,11 +157,38 @@ static int clk_generated_determine_rate(struct clk_hw *hw, clk_generated_best_diff(req, parent, parent_rate, div, &best_diff, &best_rate); + if (!best_diff) + break; + } + + /* + * The audio_pll rate can be modified, unlike the five others clocks + * that should never be altered. + * The audio_pll can technically be used by multiple consumers. However, + * with the rate locking, the first consumer to enable to clock will be + * the one definitely setting the rate of the clock. + * Since audio IPs are most likely to request the same rate, we enforce + * that the only clks able to modify gck rate are those of audio IPs. + */ + + if (!gck->audio_pll_allowed) + goto end; + + parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL); + if (!parent) + goto end; + + for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { + req_parent.rate = req->rate * div; + __clk_determine_rate(parent, &req_parent); + clk_generated_best_diff(req, parent, req_parent.rate, div, + &best_diff, &best_rate); if (!best_diff) break; } +end: pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", __func__, best_rate, __clk_get_name((req->best_parent_hw)->clk), @@ -264,7 +298,8 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, init.ops = &generated_ops; init.parent_names = parent_names; init.num_parents = num_parents; - init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT; gck->id = id; gck->hw.init = &init; @@ -296,6 +331,7 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) struct device_node *gcknp; struct clk_range range = CLK_RANGE(0, 0); struct regmap *regmap; + struct clk_generated *gck; num_parents = of_clk_get_parent_count(np); if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) @@ -327,6 +363,21 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, parent_names, num_parents, id, &range); + + gck = to_clk_generated(hw); + + if (of_device_is_compatible(np, + "atmel,sama5d2-clk-generated")) { + if (gck->id == GCK_ID_SSC0 || gck->id == GCK_ID_SSC1 || + gck->id == GCK_ID_I2S0 || gck->id == GCK_ID_I2S1 || + gck->id == GCK_ID_CLASSD) + gck->audio_pll_allowed = true; + else + gck->audio_pll_allowed = false; + } else { + gck->audio_pll_allowed = false; + } + if (IS_ERR(hw)) continue;