From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 46429C47083 for ; Fri, 4 Jun 2021 03:59:48 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9860D61400 for ; Fri, 4 Jun 2021 03:59:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9860D61400 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8974782FF5; Fri, 4 Jun 2021 05:59:16 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="maJ1Pb+t"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2BB7182FEA; Fri, 4 Jun 2021 05:58:58 +0200 (CEST) Received: from mail-qk1-x729.google.com (mail-qk1-x729.google.com [IPv6:2607:f8b0:4864:20::729]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 7DA0382FE8 for ; Fri, 4 Jun 2021 05:58:44 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=seanga2@gmail.com Received: by mail-qk1-x729.google.com with SMTP id h20so8109255qko.11 for ; Thu, 03 Jun 2021 20:58:44 -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 :mime-version:content-transfer-encoding; bh=s293aaS2AO4poDdk6c40sBZ1lGNCXDEsaXrzYME9y6o=; b=maJ1Pb+toi9NcmlN/2yxWkYoI9BvOVeF2SaqQP8hwH4LJsuhG4w+89LEwFfUSfnV6Q tCnlR755xpMDpTh9QRLwOVPM3t+gCKEUsdqmktvH5HSMMQWnXBcn5vN9gN0vzBG5BX9w 4DfB1bzua5s3CWBX4yztElWpg+GBja+FIIRodFKP6v5Tij4Ekz7HfxYHQcbumK/mIUYc M3zCb3UbKdJ7RxGj+UoAfp3puSOyffgTfh58HcNGQAU7gxNkEXacBJGFyc2Te/2kLub7 LT+tKZclHQtpfcg4x8O0MbZzf9y8FAKvByLbuPaZkFT5ZvK4SkzISVR/4p4VolZF+5Jm vCrg== 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:mime-version:content-transfer-encoding; bh=s293aaS2AO4poDdk6c40sBZ1lGNCXDEsaXrzYME9y6o=; b=Vkrvk8uRLXx+8XgO41LF8lq7qQVWUk5t6Git1uFNatWKYQvaxrXM3tpkRrS0Ab6VeK gTgfU0ut76D0z/ehlovyuUE7do/iZ6NMDsKzSmm9Rnu98qjlaZ+edf72HO5VXb0ifxKo 68C28aV7k75Md1KVwp3P/lTOQ8Tga7lzoXAm0LLSQHYHWa76SEIK3JX0y5Qsi3DJqwue 8BhSYjH4Dr1BKguZwemzg5t57mpgsVKYMJmRXSgxrNO5a7Z3/0h8qbdiPTs+OGmlhiNc RXZ2AOgGDlfnIetT+7+By2oJFCw/W++Et7CCTR9q34MlFSGA1JTBwr64Z3s/pbBbXI6R 9oaQ== X-Gm-Message-State: AOAM531qyMrcz70ezk0HaWT+h/7zCfoC1RYz4uIE5YJ73JRpaiUFyMtg tY8cw2ThpYTP8E2YIjW7NGIcgNSAkas= X-Google-Smtp-Source: ABdhPJzjTrfYsDiE1g0TgdTdbbOLqNb11g8R0OHt83xqY9LOlvCoukUvqP3JgczqcFnUMTWfKtSysA== X-Received: by 2002:a37:d58:: with SMTP id 85mr103611qkn.414.1622779123087; Thu, 03 Jun 2021 20:58:43 -0700 (PDT) Received: from godwin.fios-router.home (pool-74-96-87-9.washdc.fios.verizon.net. [74.96.87.9]) by smtp.gmail.com with ESMTPSA id s10sm3120612qkj.77.2021.06.03.20.58.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Jun 2021 20:58:42 -0700 (PDT) From: Sean Anderson To: u-boot@lists.denx.de Cc: Lukasz Majewski , Leo Liang , Damien Le Moal , Sean Anderson Subject: [PATCH v2 05/11] clk: k210: Re-add support for setting rate Date: Thu, 3 Jun 2021 23:58:28 -0400 Message-Id: <20210604035834.625772-6-seanga2@gmail.com> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20210604035834.625772-1-seanga2@gmail.com> References: <20210604035834.625772-1-seanga2@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.4 at phobos.denx.de X-Virus-Status: Clean This adds support for setting clock rates, which was left out of the initial CCF expunging. There are several tricky bits here, mostly related to the PLLS: * The PLL's bypass is broken. If the PLL is reconfigured, any child clocks will be stopped. * PLL0 is the parent of ACLK which is the CPU and SRAM's clock. To prevent stopping the CPU while we configure PLL0's rate, ACLK is reparented to IN0 while PLL0 is disabled. * PLL1 is the parent of the AISRAM clock. This clock cannot be reparented, so we instead just disallow changing PLL1's rate after relocation (when we are using the AISRAM). Signed-off-by: Sean Anderson --- Changes in v2: - Only force probe clocks pre-reloc drivers/clk/kendryte/clk.c | 89 +++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c index 203d5f741c..a1742eb856 100644 --- a/drivers/clk/kendryte/clk.c +++ b/drivers/clk/kendryte/clk.c @@ -17,6 +17,8 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + /** * struct k210_clk_priv - K210 clock driver private data * @base: The base address of the sysctl device @@ -1059,11 +1061,6 @@ static ulong k210_clk_get_rate(struct clk *clk) return do_k210_clk_get_rate(dev_get_priv(clk->dev), clk->id); } -static ulong k210_clk_set_rate(struct clk *clk, unsigned long rate) -{ - return -ENOSYS; -} - static int do_k210_clk_set_parent(struct k210_clk_priv *priv, int id, int new) { int i; @@ -1089,6 +1086,81 @@ static int k210_clk_set_parent(struct clk *clk, struct clk *parent) parent->id); } +static ulong k210_clk_set_rate(struct clk *clk, unsigned long rate) +{ + int parent, ret, err; + ulong rate_in, val; + const struct k210_div_params *div; + struct k210_clk_priv *priv = dev_get_priv(clk->dev); + + if (clk->id == K210_CLK_IN0) + return clk_set_rate(&priv->in0, rate); + + parent = k210_clk_get_parent(priv, clk->id); + rate_in = do_k210_clk_get_rate(priv, parent); + + log_debug("id=%ld rate=%lu rate_in=%lu\n", clk->id, rate, rate_in); + + if (clk->id == K210_CLK_PLL0) { + /* Bypass ACLK so the CPU keeps going */ + ret = do_k210_clk_set_parent(priv, K210_CLK_ACLK, K210_CLK_IN0); + if (ret) + return ret; + } else if (clk->id == K210_CLK_PLL1 && gd->flags & GD_FLG_RELOC) { + /* + * We can't bypass the AI clock like we can ACLK, and after + * relocation we are using the AI ram. + */ + return -EPERM; + } + + if (k210_clks[clk->id].flags & K210_CLKF_PLL) { + ret = k210_pll_set_rate(priv, k210_clks[clk->id].pll, rate, + rate_in); + if (!IS_ERR_VALUE(ret) && clk->id == K210_CLK_PLL0) { + /* + * This may have the side effect of reparenting ACLK, + * but I don't really want to keep track of what the old + * parent was. + */ + err = do_k210_clk_set_parent(priv, K210_CLK_ACLK, + K210_CLK_PLL0); + if (err) + return err; + } + return ret; + } + + if (k210_clks[clk->id].div == K210_CLK_DIV_NONE) + return -ENOSYS; + div = &k210_divs[k210_clks[clk->id].div]; + + switch (div->type) { + case K210_DIV_ONE: + val = DIV_ROUND_CLOSEST_ULL((u64)rate_in, rate); + val = val ? val - 1 : 0; + break; + case K210_DIV_EVEN: + val = DIV_ROUND_CLOSEST_ULL((u64)rate_in, 2 * rate); + break; + case K210_DIV_POWER: + /* This is ACLK, which has no divider on IN0 */ + if (parent == K210_CLK_IN0) + return -ENOSYS; + + DIV_ROUND_CLOSEST_ULL((u64)rate_in, rate); + val = __ffs(val); + break; + default: + assert(false); + return -EINVAL; + }; + + val = val ? val - 1 : 0; + k210_clk_writel(priv, div->off, div->shift, div->width, val); + return do_k210_clk_get_rate(priv, clk->id); +} + static int k210_clk_endisable(struct k210_clk_priv *priv, int id, bool enable) { int parent = k210_clk_get_parent(priv, id); @@ -1163,6 +1235,13 @@ static int k210_clk_probe(struct udevice *dev) if (ret) return ret; + /* + * Force setting defaults, even before relocation. This is so we can + * set the clock rate for PLL1 before we relocate into aisram. + */ + if (gd->flags & GD_FLG_RELOC) + clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); + return 0; } -- 2.31.0