From patchwork Mon Oct 12 18:13:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Anderson X-Patchwork-Id: 1381072 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=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com 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=BHC+on0P; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (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 4C96LJ5VK2z9sT6 for ; Tue, 13 Oct 2020 05:15:52 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7947782542; Mon, 12 Oct 2020 20:15:17 +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="BHC+on0P"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A1939824D5; Mon, 12 Oct 2020 20:15:14 +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-qk1-x742.google.com (mail-qk1-x742.google.com [IPv6:2607:f8b0:4864:20::742]) (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 AAA42824D5 for ; Mon, 12 Oct 2020 20:15:11 +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-x742.google.com with SMTP id 140so16790171qko.2 for ; Mon, 12 Oct 2020 11:15:11 -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=xq7sArLTYPY6gszkuMwDDkFWa28PAbMFz36kqxd3jtM=; b=BHC+on0P+eUahfgXybfQwOb+PV8ZYeFZtEBbd6TO9ttCySnTKQd13LtqPsDn+obW6c km6rdQLOGQakVQ/8N/gcy4QZTCtF+Qr/9nPix95EciDEiKX1vy2zMbU+Xv1DQORJRtSs lAxKhtpsG3UNIc/9D7GNZYujT6KAbZgzZpJZC3t9aWQPwTRDoG0m3wtEq7UBi9G516HE GenJ/ckZP9Tqs7iR/yfH9foNXwB+G9R3r+Zl8MXGif+MMKUyPFxWsLnAzVmeqJHKatQK WQxoK34VnLUXvwPi6mETLp1Osk1xGXqXHRepxHI5P2biLvx6We4PCKWdYIr0E43G9ob1 KPHw== 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=xq7sArLTYPY6gszkuMwDDkFWa28PAbMFz36kqxd3jtM=; b=uScGj57T3bMPo9AvDiO79NNC0t7LOud0hB2nEhYRfxPtMim6PVaLFL5PRfJTuWdPX1 aBHicN0QLw08KxyrzGWoLXts0bBiPESHdWvzML9lYnJs+jPWpOEeEJTGVlHrv4RuhAPH k8gDgzVWVU8zt7AWZ+GBhXOHZ2jR46StEDNhDkn6SSXurxVDUxAqGlVyOD9gOSZ58RI6 pKc1hGsTx6BQYxBKFXP8mXkPK6hllhjVL9VUQMFOhmcSWaPRqof/3xoEyje+SzCw9+mK yGHDEhVK/BkBhExPUGszH7klnbxTVHGksIRJ7aAsNbsIIEvlJkbbU+AuF0P9xm/e5+a7 cMUg== X-Gm-Message-State: AOAM53225mXjQuZzQYHDwWGHfO6JxB6zJHTjphnnUobgunxIMDFff2pY KfPmQi+xHwcoioV6uwXMd86IQ1VPRAPHeA== X-Google-Smtp-Source: ABdhPJz5jMcy6RIe3nKex/gMVkAVrybtbPo0j6KS9paK98L5Ovu8wy4zlig63u4GFcz5fUWnFjOlqQ== X-Received: by 2002:ae9:f444:: with SMTP id z4mr10755180qkl.338.1602526510199; Mon, 12 Oct 2020 11:15:10 -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 t3sm12968651qtq.24.2020.10.12.11.15.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Oct 2020 11:15:09 -0700 (PDT) From: Sean Anderson To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Rick Chen , Bin Meng , Sean Anderson , Lukasz Majewski Subject: [PATCH v2 03/16] clk: k210: Remove bypass clock Date: Mon, 12 Oct 2020 14:13:32 -0400 Message-Id: <20201012181345.338661-4-seanga2@gmail.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201012181345.338661-1-seanga2@gmail.com> References: <20201012181345.338661-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.3 at phobos.denx.de X-Virus-Status: Clean Now that the PLLs get properly enabled, the bypass clock is no longer necessary. Signed-off-by: Sean Anderson --- Changes in v2: - New drivers/clk/kendryte/Makefile | 2 +- drivers/clk/kendryte/bypass.c | 273 ---------------------------------- drivers/clk/kendryte/clk.c | 43 ++---- include/kendryte/bypass.h | 31 ---- 4 files changed, 15 insertions(+), 334 deletions(-) delete mode 100644 drivers/clk/kendryte/bypass.c delete mode 100644 include/kendryte/bypass.h diff --git a/drivers/clk/kendryte/Makefile b/drivers/clk/kendryte/Makefile index 6fb68253ae..d26bce954f 100644 --- a/drivers/clk/kendryte/Makefile +++ b/drivers/clk/kendryte/Makefile @@ -1 +1 @@ -obj-y += bypass.o clk.o pll.o +obj-y += clk.o pll.o diff --git a/drivers/clk/kendryte/bypass.c b/drivers/clk/kendryte/bypass.c deleted file mode 100644 index 5f1986f2cb..0000000000 --- a/drivers/clk/kendryte/bypass.c +++ /dev/null @@ -1,273 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2020 Sean Anderson - */ - -#define LOG_CATEGORY UCLASS_CLK - -#include -#include -#include -#include -#include -#include -#include -#include - -#define CLK_K210_BYPASS "k210_clk_bypass" - -/* - * This is a small driver to do a software bypass of a clock if hardware bypass - * is not working. I have tried to write this in a generic fashion, so that it - * could be potentially broken out of the kendryte code at some future date. - * - * Say you have the following clock configuration - * - * +---+ +---+ - * |osc| |pll| - * +---+ +---+ - * ^ - * /| - * / | - * / | - * / | - * / | - * +---+ +---+ - * |clk| |clk| - * +---+ +---+ - * - * But the pll does not have a bypass, so when you configure the pll, the - * configuration needs to change to look like - * - * +---+ +---+ - * |osc| |pll| - * +---+ +---+ - * ^ - * |\ - * | \ - * | \ - * | \ - * | \ - * +---+ +---+ - * |clk| |clk| - * +---+ +---+ - * - * To set this up, create a bypass clock with bypassee=pll and alt=osc. When - * creating the child clocks, set their parent to the bypass clock. After - * creating all the children, call k210_bypass_setchildren(). - */ - -static int k210_bypass_dobypass(struct k210_bypass *bypass) -{ - int ret, i; - - /* - * If we already have saved parents, then the children are already - * bypassed - */ - if (bypass->child_count && bypass->saved_parents[0]) - return 0; - - for (i = 0; i < bypass->child_count; i++) { - struct clk *child = bypass->children[i]; - struct clk *parent = clk_get_parent(child); - - if (IS_ERR(parent)) { - for (; i; i--) - bypass->saved_parents[i] = NULL; - return PTR_ERR(parent); - } - bypass->saved_parents[i] = parent; - } - - for (i = 0; i < bypass->child_count; i++) { - struct clk *child = bypass->children[i]; - - ret = clk_set_parent(child, bypass->alt); - if (ret) { - for (; i; i--) - clk_set_parent(bypass->children[i], - bypass->saved_parents[i]); - for (i = 0; i < bypass->child_count; i++) - bypass->saved_parents[i] = NULL; - return ret; - } - } - - return 0; -} - -static int k210_bypass_unbypass(struct k210_bypass *bypass) -{ - int err, ret, i; - - if (!bypass->child_count && !bypass->saved_parents[0]) { - log_warning("Cannot unbypass children; dobypass not called first\n"); - return 0; - } - - ret = 0; - for (i = 0; i < bypass->child_count; i++) { - err = clk_set_parent(bypass->children[i], - bypass->saved_parents[i]); - if (err) - ret = err; - bypass->saved_parents[i] = NULL; - } - return ret; -} - -static ulong k210_bypass_get_rate(struct clk *clk) -{ - struct k210_bypass *bypass = to_k210_bypass(clk); - const struct clk_ops *ops = bypass->bypassee_ops; - - if (ops->get_rate) - return ops->get_rate(bypass->bypassee); - else - return clk_get_parent_rate(bypass->bypassee); -} - -static ulong k210_bypass_set_rate(struct clk *clk, unsigned long rate) -{ - int ret; - struct k210_bypass *bypass = to_k210_bypass(clk); - const struct clk_ops *ops = bypass->bypassee_ops; - - /* Don't bother bypassing if we aren't going to set the rate */ - if (!ops->set_rate) - return k210_bypass_get_rate(clk); - - ret = k210_bypass_dobypass(bypass); - if (ret) - return ret; - - ret = ops->set_rate(bypass->bypassee, rate); - if (ret < 0) - return ret; - - return k210_bypass_unbypass(bypass); -} - -static int k210_bypass_set_parent(struct clk *clk, struct clk *parent) -{ - struct k210_bypass *bypass = to_k210_bypass(clk); - const struct clk_ops *ops = bypass->bypassee_ops; - - if (ops->set_parent) - return ops->set_parent(bypass->bypassee, parent); - else - return -ENOTSUPP; -} - -/* - * For these next two functions, do the bypassing even if there is no - * en-/-disable function, since the bypassing itself can be observed in between - * calls. - */ -static int k210_bypass_enable(struct clk *clk) -{ - int ret; - struct k210_bypass *bypass = to_k210_bypass(clk); - const struct clk_ops *ops = bypass->bypassee_ops; - - ret = k210_bypass_dobypass(bypass); - if (ret) - return ret; - - if (ops->enable) - ret = ops->enable(bypass->bypassee); - else - ret = 0; - if (ret) - return ret; - - return k210_bypass_unbypass(bypass); -} - -static int k210_bypass_disable(struct clk *clk) -{ - int ret; - struct k210_bypass *bypass = to_k210_bypass(clk); - const struct clk_ops *ops = bypass->bypassee_ops; - - ret = k210_bypass_dobypass(bypass); - if (ret) - return ret; - - if (ops->disable) - return ops->disable(bypass->bypassee); - else - return 0; -} - -static const struct clk_ops k210_bypass_ops = { - .get_rate = k210_bypass_get_rate, - .set_rate = k210_bypass_set_rate, - .set_parent = k210_bypass_set_parent, - .enable = k210_bypass_enable, - .disable = k210_bypass_disable, -}; - -int k210_bypass_set_children(struct clk *clk, struct clk **children, - size_t child_count) -{ - struct k210_bypass *bypass = to_k210_bypass(clk); - - kfree(bypass->saved_parents); - if (child_count) { - bypass->saved_parents = - kcalloc(child_count, sizeof(struct clk *), GFP_KERNEL); - if (!bypass->saved_parents) - return -ENOMEM; - } - bypass->child_count = child_count; - bypass->children = children; - - return 0; -} - -struct clk *k210_register_bypass_struct(const char *name, - const char *parent_name, - struct k210_bypass *bypass) -{ - int ret; - struct clk *clk; - - clk = &bypass->clk; - - ret = clk_register(clk, CLK_K210_BYPASS, name, parent_name); - if (ret) - return ERR_PTR(ret); - - bypass->bypassee->dev = clk->dev; - return clk; -} - -struct clk *k210_register_bypass(const char *name, const char *parent_name, - struct clk *bypassee, - const struct clk_ops *bypassee_ops, - struct clk *alt) -{ - struct clk *clk; - struct k210_bypass *bypass; - - bypass = kzalloc(sizeof(*bypass), GFP_KERNEL); - if (!bypass) - return ERR_PTR(-ENOMEM); - - bypass->bypassee = bypassee; - bypass->bypassee_ops = bypassee_ops; - bypass->alt = alt; - - clk = k210_register_bypass_struct(name, parent_name, bypass); - if (IS_ERR(clk)) - kfree(bypass); - return clk; -} - -U_BOOT_DRIVER(k210_bypass) = { - .name = CLK_K210_BYPASS, - .id = UCLASS_CLK, - .ops = &k210_bypass_ops, -}; diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c index bb196961af..e657efc572 100644 --- a/drivers/clk/kendryte/clk.c +++ b/drivers/clk/kendryte/clk.c @@ -11,7 +11,6 @@ #include #include -#include #include /* All methods are delegated to CCF clocks */ @@ -347,10 +346,6 @@ static const struct k210_comp_params k210_comps[] = { #undef COMP_NOMUX_ID #undef COMP_LIST -static struct clk *k210_bypass_children = { - NULL, -}; - /* Helper functions to create sub-clocks */ static struct clk_mux *k210_create_mux(const struct k210_mux_params *params, void *base) @@ -482,7 +477,7 @@ static int k210_clk_probe(struct udevice *dev) { int ret; const char *in0; - struct clk *in0_clk, *bypass; + struct clk *in0_clk; struct clk_mux *mux; struct clk_divider *div; struct k210_pll *pll; @@ -516,17 +511,13 @@ static int k210_clk_probe(struct udevice *dev) aclk_sels[0] = in0; pll2_sels[0] = in0; - /* - * All PLLs have a broken bypass, but pll0 has the CPU downstream, so we - * need to manually reparent it whenever we configure pll0 - */ - pll = k210_create_pll(&k210_plls[0], base); - if (pll) { - bypass = k210_register_bypass("pll0", in0, &pll->clk, - &k210_pll_ops, in0_clk); - clk_dm(K210_CLK_PLL0, bypass); - } else { - return -ENOMEM; + { + const struct k210_pll_params *params = &k210_plls[0]; + + clk_dm(K210_CLK_PLL0, + k210_register_pll("pll0", in0, base + params->off, + base + params->lock_off, params->shift, + params->width)); } { @@ -565,18 +556,12 @@ static int k210_clk_probe(struct udevice *dev) free(mux); free(div); } else { - struct clk *aclk = - clk_register_composite(NULL, "aclk", aclk_sels, - ARRAY_SIZE(aclk_sels), - &mux->clk, &clk_mux_ops, - &div->clk, &clk_divider_ops, - NULL, NULL, 0); - clk_dm(K210_CLK_ACLK, aclk); - if (!IS_ERR(aclk)) { - k210_bypass_children = aclk; - k210_bypass_set_children(bypass, - &k210_bypass_children, 1); - } + clk_dm(K210_CLK_ACLK, + clk_register_composite(NULL, "aclk", aclk_sels, + ARRAY_SIZE(aclk_sels), + &mux->clk, &clk_mux_ops, + &div->clk, &clk_divider_ops, + NULL, NULL, 0)); } #define REGISTER_COMP(id, name) \ diff --git a/include/kendryte/bypass.h b/include/kendryte/bypass.h deleted file mode 100644 index ab85bbcbfc..0000000000 --- a/include/kendryte/bypass.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2020 Sean Anderson - */ -#ifndef K210_BYPASS_H -#define K210_BYPASS_H - -struct clk; - -struct k210_bypass { - struct clk clk; - struct clk **children; /* Clocks to reparent */ - struct clk **saved_parents; /* Parents saved over en-/dis-able */ - struct clk *bypassee; /* Clock to bypass */ - const struct clk_ops *bypassee_ops; /* Ops of the bypass clock */ - struct clk *alt; /* Clock to set children to when bypassing */ - size_t child_count; -}; - -#define to_k210_bypass(_clk) container_of(_clk, struct k210_bypass, clk) - -int k210_bypass_set_children(struct clk *clk, struct clk **children, - size_t child_count); -struct clk *k210_register_bypass_struct(const char *name, - const char *parent_name, - struct k210_bypass *bypass); -struct clk *k210_register_bypass(const char *name, const char *parent_name, - struct clk *bypassee, - const struct clk_ops *bypassee_ops, - struct clk *alt); -#endif /* K210_BYPASS_H */