From patchwork Tue Jul 4 11:59: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: 106958 Delivered-To: patch@linaro.org Received: by 10.140.101.44 with SMTP id t41csp913592qge; Tue, 4 Jul 2017 05:01:46 -0700 (PDT) X-Received: by 10.98.152.25 with SMTP id q25mr14657943pfd.47.1499169706270; Tue, 04 Jul 2017 05:01:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1499169706; cv=none; d=google.com; s=arc-20160816; b=og/aNTL3e7KwvgpEHkucfbLr8s/5sxnwANVKZn1mN3BjdI/zoJlM3+pWw6lNhMcbyC SusI7aOYxqyHIwnXFfZl+JMQ1xBdhLPaAHfx9uiL8IRld+kVFMUvaGYTitWNY/kkyFuc JeMWnvNz3+1cAClxeI1zMpXPQOxtWUTxsdziqvAi5S+b97K9nj5O4Vept/FU0xoGbNvH JDFTvzMQeUnOWH8NrboGmXh2ule1a0ZjyayLb+OUiO+qb4b1HMJg4uHTqMx9kZGgaT+T 7QRiS8Iw6iRG6Z1Z0J1eHaRWVKasOSKfxLyVt8yINrz3H1+Q1XSff/36vw5R8YLQDVbD FwEA== 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=YA51fIanGtGRQtoIS0+LM/27QcuzQEFvA/W7vzyk7H4=; b=IW2eEcMImOCPOHr2mAOR14RrNfov1lsRjG03k6vmt2iluDrLkVhNqEtpcDrqtczGQM EkXtO2kSAupfc47iQeJotURjSdUF2VsRBSum3ACVMfQEETi1GrssOA9E9XOkUffYrFT2 7jkuVpbnoLQY2VGDDWEm/rqP6wbwza8jc4XBcEn6/2Pl4g2DRvP7fvb+5xwXnceCNRs+ aD72ekmzImoT5zQMJnfJD1WkKnqcyGGl2b9RMrCk9iE8Q0UWdWD37zisoOFZss2DzGR+ 8fH8VHUrmE0B6AltmlAqihkExw6+d4nc19wmREZm0iq3ZiFwhFcc7eGd9B/vk4bfJAHJ qXTg== 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 o5si7429934plh.543.2017.07.04.05.01.45; Tue, 04 Jul 2017 05:01:46 -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 S1752409AbdGDMBl (ORCPT + 25 others); Tue, 4 Jul 2017 08:01:41 -0400 Received: from mail.free-electrons.com ([62.4.15.54]:43623 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752194AbdGDL7s (ORCPT ); Tue, 4 Jul 2017 07:59:48 -0400 Received: by mail.free-electrons.com (Postfix, from userid 110) id 5E9BC21FC1; Tue, 4 Jul 2017 13:59:45 +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 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 F026721D40; Tue, 4 Jul 2017 13:59:44 +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 v2 6/9] clk: at91: clk-generated: make gclk determine audio_pll rate Date: Tue, 4 Jul 2017 13:59:24 +0200 Message-Id: <20170704115927.32662-7-quentin.schulz@free-electrons.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170704115927.32662-1-quentin.schulz@free-electrons.com> References: <20170704115927.32662-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 --- v2: - added conditions for audio pll rate setting restriction for SSC and I2S, drivers/clk/at91/clk-generated.c | 48 +++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 6 deletions(-) -- 2.11.0 diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 6530a2e7e84d..87866786a6ab 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; @@ -126,15 +133,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 +156,40 @@ 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->id != GCK_ID_SSC0 && gck->id != GCK_ID_SSC1 && + gck->id != GCK_ID_I2S0 && gck->id != GCK_ID_I2S1 && + gck->id != GCK_ID_CLASSD) + 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 +299,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;