From patchwork Mon Apr 12 03:58:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 1464978 X-Patchwork-Delegate: uboot@andestech.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=G8tCjf5o; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FJZjb3xWlz9sVt for ; Mon, 12 Apr 2021 13:58:59 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D5C7181782; Mon, 12 Apr 2021 05:58:30 +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="G8tCjf5o"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1AA1581607; Mon, 12 Apr 2021 05:58:23 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) (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 9330980C69 for ; Mon, 12 Apr 2021 05:58: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=seanga2@gmail.com Received: by mail-qv1-xf35.google.com with SMTP id iu14so5646033qvb.4 for ; Sun, 11 Apr 2021 20:58:16 -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=vfgolT1W5MVDkxwE1f0zUoRwoBGTGTjGETPTSu9DIBs=; b=G8tCjf5o5pMjUimaya1G87OsnV5/DD6x7YdXgr6CoCvUxOndWnQSdeMPd6aNElkhbE RukN4WIq4h+kyzTMphZXfDNa9iw1EaZCyOzb4Ogok3ZxfGEoRm5LQJIfUvsIlHaeQL93 3qjPY6DXJTsBKbqS9AFH9de/A2zOm0vp2c1gUAlcN9sVU10rCxDhSNW2bbegOV1xONmd sjWIsSWqhrf/LYdYe3BJro9Ft07bQZRk2VBaNgAddVWJuiC/fzGZccqErtkOVhmNZo/f vOFuKvJCTEWevZOe93m4DkI2HQMWpO5rNTnMHkrgEeLlRSPpBytvhcaACPtqXEutRv5S QtkA== 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=vfgolT1W5MVDkxwE1f0zUoRwoBGTGTjGETPTSu9DIBs=; b=F0zuA5Uc+w+GMuyG48mHOs1JDe2KG/L/BwFW9PRY44XS9SnPS1i1Bjnd1GI0A3oSj0 PO7v6Z32nYYZrT3ynxyXinzKI0Un95Q/TzBvpk2WhaJBEzjKU0BGBGnP9LVa42NWcKNJ +VIFPw0qP+jsBOd7ZM7BQ11cuQbZIBEQkNUOC8uQjAQqM9N4bewAnyYlC7PvOcbUXf3u rdMMthTy1RQe+yYQmmFtfHu0GZNKFy4Jf6TBXFv4e1rVrtb+O8PuBWWyXNGKskZaGYsv qADL0xCdUcNMsh+w3HgAP+KfE1KMWtIrxsPbFu2Owz3Va9xRm4e0NyUycPn9tO8k8NxM 10oA== X-Gm-Message-State: AOAM533QMk4qCyiMR62wUaR8FgnSUi7hK6yXAUi76esc2KL86EJP1GVN IvTP2Qh9XKH4biaMHPZhGRHbTBHeeOM= X-Google-Smtp-Source: ABdhPJwcAnEZndST0MD6RL0MAuR/tY0c6/N4a6xpDqfXNeHHSHpHojz9Lm6AUwye9+maQGutS73WVQ== X-Received: by 2002:a05:6214:20ad:: with SMTP id 13mr25095968qvd.35.1618199895276; Sun, 11 Apr 2021 20:58:15 -0700 (PDT) Received: from godwin.fios-router.home (pool-108-51-35-162.washdc.fios.verizon.net. [108.51.35.162]) by smtp.gmail.com with ESMTPSA id 14sm7117402qkf.119.2021.04.11.20.58.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 11 Apr 2021 20:58:14 -0700 (PDT) From: Sean Anderson To: u-boot@lists.denx.de, Lukasz Majewski Cc: Damien Le Moal , Sean Anderson , Heinrich Schuchardt , Simon Glass , Stefan Roese Subject: [PATCH 05/11] clk: k210: Re-add support for setting rate Date: Sun, 11 Apr 2021 23:58:01 -0400 Message-Id: <20210412035807.708621-6-seanga2@gmail.com> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20210412035807.708621-1-seanga2@gmail.com> References: <20210412035807.708621-1-seanga2@gmail.com> MIME-Version: 1.0 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 --- drivers/clk/kendryte/clk.c | 88 +++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c index 203d5f741c..cdea3d6f2b 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,12 @@ 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. + */ + clk_set_defaults(dev, 2); + return 0; }