From patchwork Thu Apr 25 10:29:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090671 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYQH4yTVz9s3q for ; Thu, 25 Apr 2019 20:31:51 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 4612AC21DD4; Thu, 25 Apr 2019 10:30:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 4FDD1C21E1B; Thu, 25 Apr 2019 10:30:39 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id F2035C21DFA; Thu, 25 Apr 2019 10:30:30 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.10]) by lists.denx.de (Postfix) with ESMTPS id 9B322C21DF3 for ; Thu, 25 Apr 2019 10:30:26 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNd0p6qz1rbM3; Thu, 25 Apr 2019 12:30:22 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNZ4Gtyz1qyC7; Thu, 25 Apr 2019 12:30:22 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id KA5rzI6mnSRl; Thu, 25 Apr 2019 12:30:21 +0200 (CEST) X-Auth-Info: Xgzjr1XCBm31qKycQDzBOIRN+ZW/TpJ15lt7PGL8Ets= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:21 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:43 +0200 Message-Id: <20190425102953.5348-2-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 01/11] dm: Fix documentation entry as there is no UCLASS_CLOCK uclass X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" There is no UCLASS_CLOCK uclass defined. Instead we do use the UCLASS_CLK. Signed-off-by: Lukasz Majewski Reviewed-by: Simon Glass Reviewed-by: Peng Fan --- Changes in v3: None include/clk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/clk.h b/include/clk.h index 8e366163f9..f6fbcc6634 100644 --- a/include/clk.h +++ b/include/clk.h @@ -19,7 +19,7 @@ * clock provider. This API provides a standard means for drivers to enable and * disable clocks, and to set the rate at which they oscillate. * - * A driver that implements UCLASS_CLOCK is a clock provider. A provider will + * A driver that implements UCLASS_CLK is a clock provider. A provider will * often implement multiple separate clocks, since the hardware it manages * often has this capability. clk-uclass.h describes the interface which * clock providers must implement. From patchwork Thu Apr 25 10:29:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090670 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYP330y6z9s3q for ; Thu, 25 Apr 2019 20:30:47 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 071A0C21E39; Thu, 25 Apr 2019 10:30:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id B5A7DC21DFD; Thu, 25 Apr 2019 10:30:38 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id EC1F7C21DD3; Thu, 25 Apr 2019 10:30:30 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.10]) by lists.denx.de (Postfix) with ESMTPS id 10204C21D8E for ; Thu, 25 Apr 2019 10:30:27 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNf5QvHz1rbMK; Thu, 25 Apr 2019 12:30:24 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNc2J4Fz1qyC8; Thu, 25 Apr 2019 12:30:24 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id 0dg3MMw82UI2; Thu, 25 Apr 2019 12:30:22 +0200 (CEST) X-Auth-Info: WD99Oc0y32TeWkl8G7Sx5InP1Xy+O/Hl8am6R2gZHxQ= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:22 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:44 +0200 Message-Id: <20190425102953.5348-3-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 02/11] cmd: Do not show frequency for clocks which .get_rate() return error X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" It may happen that some UCLASS_CLK clocks drivers work as a "managers", to call other, proper clocks. This situation is present in the iMX{6|8} clocks when supporting CONFIG_CLK (and CCF). To avoid bogus output of "clk dump" we omit clocks which return error value - allowing reusing default implementation of this command. Signed-off-by: Lukasz Majewski Reviewed-by: Simon Glass Reviewed-by: Peng Fan --- Changes in v3: None cmd/clk.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/clk.c b/cmd/clk.c index fd4231589c..2ea82176aa 100644 --- a/cmd/clk.c +++ b/cmd/clk.c @@ -16,6 +16,7 @@ int __weak soc_clk_dump(void) struct udevice *dev; struct uclass *uc; struct clk clk; + ulong rate; int ret; /* Device addresses start at 1 */ @@ -37,7 +38,9 @@ int __weak soc_clk_dump(void) continue; } - printf("%-30.30s : %lu Hz\n", dev->name, clk_get_rate(&clk)); + rate = clk_get_rate(&clk); + if (!IS_ERR_VALUE(rate)) + printf("%-30.30s : %lu Hz\n", dev->name, rate); clk_free(&clk); } From patchwork Thu Apr 25 10:29:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090676 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYTK1d2Qz9s3Z for ; Thu, 25 Apr 2019 20:34:29 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id E23C8C21DE8; Thu, 25 Apr 2019 10:31:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 5BA24C21E30; Thu, 25 Apr 2019 10:30:44 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 38E98C21E2F; Thu, 25 Apr 2019 10:30:30 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.10]) by lists.denx.de (Postfix) with ESMTPS id 7248AC21DDC for ; Thu, 25 Apr 2019 10:30:26 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNf1LHrz1rbMP; Thu, 25 Apr 2019 12:30:26 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNf0BZnz1qyCC; Thu, 25 Apr 2019 12:30:26 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id Ww_BUV0caIfl; Thu, 25 Apr 2019 12:30:24 +0200 (CEST) X-Auth-Info: IeKIooBUg8b94OcJFRHlu+aSCuP5Jw7kULD3NwQcqmY= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:24 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:45 +0200 Message-Id: <20190425102953.5348-4-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 03/11] clk: Remove clock ID check in .get_rate() of clk_fixed_* X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This check requires the struct clk passed to .get_rate() to be always cleared out as any clock with valid ID causes -EINVAL return value. The return code of fixed clocks shall always be returned. Signed-off-by: Lukasz Majewski Reviewed-by: Peng Fan --- Changes in v3: None drivers/clk/clk_fixed_factor.c | 3 --- drivers/clk/clk_fixed_rate.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/clk/clk_fixed_factor.c b/drivers/clk/clk_fixed_factor.c index 5fa20a84db..dcdb6ddf5c 100644 --- a/drivers/clk/clk_fixed_factor.c +++ b/drivers/clk/clk_fixed_factor.c @@ -24,9 +24,6 @@ static ulong clk_fixed_factor_get_rate(struct clk *clk) uint64_t rate; struct clk_fixed_factor *ff = to_clk_fixed_factor(clk->dev); - if (clk->id != 0) - return -EINVAL; - rate = clk_get_rate(&ff->parent); if (IS_ERR_VALUE(rate)) return rate; diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c index d8d9f86c86..50dbb13655 100644 --- a/drivers/clk/clk_fixed_rate.c +++ b/drivers/clk/clk_fixed_rate.c @@ -15,9 +15,6 @@ struct clk_fixed_rate { static ulong clk_fixed_rate_get_rate(struct clk *clk) { - if (clk->id != 0) - return -EINVAL; - return to_clk_fixed_rate(clk->dev)->fixed_rate; } From patchwork Thu Apr 25 10:29:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090677 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYTW393vz9s3Z for ; Thu, 25 Apr 2019 20:34:39 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id E15EDC21DDC; Thu, 25 Apr 2019 10:31:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id D7797C21E15; Thu, 25 Apr 2019 10:30:43 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 7B120C21DA6; Thu, 25 Apr 2019 10:30:32 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id 454F2C21DD3 for ; Thu, 25 Apr 2019 10:30:28 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNh0Zhzz1rJh7; Thu, 25 Apr 2019 12:30:28 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNg6RVBz1qyC6; Thu, 25 Apr 2019 12:30:27 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id DsBsEKvewiH7; Thu, 25 Apr 2019 12:30:26 +0200 (CEST) X-Auth-Info: DDjMMi2C6yd9gwrHv6jrGnS50gKrW3SEGIhCZD9kr0k= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:26 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:46 +0200 Message-Id: <20190425102953.5348-5-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 04/11] clk: Extend struct clk to provide information regarding clock rate X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit extends the struct clk to provide information regarding the clock rate. As a result the clock tree traversal is performed at most once, and further reads are using the cached value. Signed-off-by: Lukasz Majewski Reviewed-by: Peng Fan --- Changes in v3: None include/clk.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/clk.h b/include/clk.h index f6fbcc6634..f29ba02da1 100644 --- a/include/clk.h +++ b/include/clk.h @@ -39,6 +39,7 @@ struct udevice; * other clock APIs to identify which clock signal to operate upon. * * @dev: The device which implements the clock signal. + * @rate: The clock rate (in HZ). * @id: The clock signal ID within the provider. * @data: An optional data field for scenarios where a single integer ID is not * sufficient. If used, it can be populated through an .of_xlate op and @@ -54,6 +55,7 @@ struct udevice; */ struct clk { struct udevice *dev; + unsigned long rate; /* in HZ */ /* * Written by of_xlate. In the future, we might add more fields here. */ From patchwork Thu Apr 25 10:29:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090672 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYRj58d4z9s3q for ; Thu, 25 Apr 2019 20:33:05 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 46B46C21D4A; Thu, 25 Apr 2019 10:32:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 30BCAC21D65; Thu, 25 Apr 2019 10:31:04 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 2A3F3C21DFB; Thu, 25 Apr 2019 10:30:33 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id C0BF1C21DD4 for ; Thu, 25 Apr 2019 10:30:29 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNj4G3zz1rJgl; Thu, 25 Apr 2019 12:30:29 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNj40CDz1qyC6; Thu, 25 Apr 2019 12:30:29 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id 0VTlssoWMiSF; Thu, 25 Apr 2019 12:30:28 +0200 (CEST) X-Auth-Info: lmUHfIg5r5D7TA+dOBNkjbVmUbnyam5Ax/6S6pOujVI= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:28 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:47 +0200 Message-Id: <20190425102953.5348-6-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 05/11] clk: Provide struct clk for fixed rate clock (clk_fixed_rate.c) X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Up till now the fixed rate clock ('osc') has been added to UCLASS_CLK without declaring struct clk. As a result it was only accessible by iterating the udevice's uclass list. This is a problem for clock code, which operates on pointers to struct clk (like clk_get_rate()), not udevices. After this change struct clk is accessible from udevice and udevice from struct clk. Signed-off-by: Lukasz Majewski Reviewed-by: Peng Fan --- Changes in v3: None drivers/clk/clk_fixed_rate.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c index 50dbb13655..089f060a23 100644 --- a/drivers/clk/clk_fixed_rate.c +++ b/drivers/clk/clk_fixed_rate.c @@ -8,6 +8,7 @@ #include struct clk_fixed_rate { + struct clk clk; unsigned long fixed_rate; }; @@ -24,10 +25,14 @@ const struct clk_ops clk_fixed_rate_ops = { static int clk_fixed_rate_ofdata_to_platdata(struct udevice *dev) { + struct clk *clk = &to_clk_fixed_rate(dev)->clk; #if !CONFIG_IS_ENABLED(OF_PLATDATA) to_clk_fixed_rate(dev)->fixed_rate = dev_read_u32_default(dev, "clock-frequency", 0); #endif + /* Make fixed rate clock accessible from higher level struct clk */ + dev->driver_data = (ulong)clk; + clk->dev = dev; return 0; } From patchwork Thu Apr 25 10:29:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090673 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYSV1CBlz9s3q for ; Thu, 25 Apr 2019 20:33:45 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 6B7BAC21C2C; Thu, 25 Apr 2019 10:32:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id F3B3FC21E2F; Thu, 25 Apr 2019 10:31:07 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 0ACE2C21E1E; Thu, 25 Apr 2019 10:30:35 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id DF81AC21DF3 for ; Thu, 25 Apr 2019 10:30:31 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNl4zJrz1rJgl; Thu, 25 Apr 2019 12:30:31 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNl3Ykxz1qyC6; Thu, 25 Apr 2019 12:30:31 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id OoPbq3BUwkEq; Thu, 25 Apr 2019 12:30:29 +0200 (CEST) X-Auth-Info: MnlJEwqBCjeZ42K4HXkargjOKh30LCO4Zl3Utkz2j+c= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:29 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:48 +0200 Message-Id: <20190425102953.5348-7-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 06/11] dm: clk: Define clk_get_parent() for clk operations X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit adds the clk_get_parent() function, which is responsible for getting the parent's struct clock pointer. U-boot's DM support for getting parent is different (the parent relationship is in udevice) than the one in common clock framework (CCF) in Linux. To obtain the pointer to struct clk of parent the pdev->driver_data field is read. Signed-off-by: Lukasz Majewski Reviewed-by: Peng Fan --- Changes in v3: - New patch drivers/clk/clk-uclass.c | 15 +++++++++++++++ include/clk.h | 9 +++++++++ 2 files changed, 24 insertions(+) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 844b87cc33..7ebe4e79fe 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -340,6 +340,21 @@ ulong clk_get_rate(struct clk *clk) return ops->get_rate(clk); } +struct clk *clk_get_parent(struct clk *clk) +{ + struct udevice *pdev; + struct clk *pclk; + + debug("%s(clk=%p)\n", __func__, clk); + + pdev = dev_get_parent(clk->dev); + pclk = (struct clk *)dev_get_driver_data(pdev); + if (!pclk) + return ERR_PTR(-ENODEV); + + return pclk; +} + ulong clk_set_rate(struct clk *clk, ulong rate) { const struct clk_ops *ops = clk_dev_ops(clk->dev); diff --git a/include/clk.h b/include/clk.h index f29ba02da1..b44ee3b158 100644 --- a/include/clk.h +++ b/include/clk.h @@ -240,6 +240,15 @@ int clk_free(struct clk *clk); ulong clk_get_rate(struct clk *clk); /** + * clk_get_parent() - Get current clock's parent. + * + * @clk: A clock struct that was previously successfully requested by + * clk_request/get_by_*(). + * @return pointer to parent's struct clk, or error code passed as pointer + */ +struct clk *clk_get_parent(struct clk *clk); + +/** * clk_set_rate() - Set current clock rate. * * @clk: A clock struct that was previously successfully requested by From patchwork Thu Apr 25 10:29:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090679 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYW667FJz9s3Z for ; Thu, 25 Apr 2019 20:36:02 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 533DCC21DA2; Thu, 25 Apr 2019 10:31:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 7E9BBC21E12; Thu, 25 Apr 2019 10:31:01 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 607EAC21DD4; Thu, 25 Apr 2019 10:30:38 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.10]) by lists.denx.de (Postfix) with ESMTPS id 85F93C21C57 for ; Thu, 25 Apr 2019 10:30:34 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNn6gwRz1rbM0; Thu, 25 Apr 2019 12:30:33 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNn59Wqz1qyC7; Thu, 25 Apr 2019 12:30:33 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id Cf21SgOQHnLe; Thu, 25 Apr 2019 12:30:31 +0200 (CEST) X-Auth-Info: aodX9IdwH23CI3NstqGi17EHkQFbAa6MXDYXnI96ziM= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:31 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:49 +0200 Message-Id: <20190425102953.5348-8-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 07/11] dm: clk: Define clk_get_parent_rate() for clk operations X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit adds the clk_get_parent_rate() function, which is responsible for getting the rate of parent clock. Unfortunately, u-boot's DM support for getting parent is different (the parent relationship is in udevice) than the one in common clock framework (CCF) in Linux. To alleviate this problem - the clk_get_parent_rate() function has been introduced to clk-uclass.c. Signed-off-by: Lukasz Majewski --- Changes in v3: - The rate information is now cached into struct clk field - The clk_get_parent() is used to get pointer to the parent struct clk drivers/clk/clk-uclass.c | 22 ++++++++++++++++++++++ include/clk.h | 9 +++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 7ebe4e79fe..da6624d4f2 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -355,6 +355,28 @@ struct clk *clk_get_parent(struct clk *clk) return pclk; } +ulong clk_get_parent_rate(struct clk *clk) +{ + const struct clk_ops *ops; + struct clk *pclk; + + debug("%s(clk=%p)\n", __func__, clk); + + pclk = clk_get_parent(clk); + if (IS_ERR(pclk)) + return -ENODEV; + + ops = clk_dev_ops(pclk->dev); + if (!ops->get_rate) + return -ENOSYS; + + /* Read the 'rate' if not already set */ + if (!pclk->rate) + pclk->rate = clk_get_rate(pclk); + + return pclk->rate; +} + ulong clk_set_rate(struct clk *clk, ulong rate) { const struct clk_ops *ops = clk_dev_ops(clk->dev); diff --git a/include/clk.h b/include/clk.h index b44ee3b158..98c3e12fb4 100644 --- a/include/clk.h +++ b/include/clk.h @@ -249,6 +249,15 @@ ulong clk_get_rate(struct clk *clk); struct clk *clk_get_parent(struct clk *clk); /** + * clk_get_parent_rate() - Get parent of current clock rate. + * + * @clk: A clock struct that was previously successfully requested by + * clk_request/get_by_*(). + * @return clock rate in Hz, or -ve error code. + */ +ulong clk_get_parent_rate(struct clk *clk); + +/** * clk_set_rate() - Set current clock rate. * * @clk: A clock struct that was previously successfully requested by From patchwork Thu Apr 25 10:29:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090678 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYTd4F7lz9s3Z for ; Thu, 25 Apr 2019 20:34:45 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 45613C21DD7; Thu, 25 Apr 2019 10:31:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id DC4A2C21D74; Thu, 25 Apr 2019 10:30:53 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 17654C21CB1; Thu, 25 Apr 2019 10:30:39 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id 22FFCC21CB1 for ; Thu, 25 Apr 2019 10:30:36 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNq6fYCz1rJh7; Thu, 25 Apr 2019 12:30:35 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNq5N5qz1qyC6; Thu, 25 Apr 2019 12:30:35 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id Kk-0N37fjxMe; Thu, 25 Apr 2019 12:30:34 +0200 (CEST) X-Auth-Info: 7T3lKrQWgYgiS7VxpvynFdYCx94FqA/9Zsq1pAQ2xEs= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:34 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:50 +0200 Message-Id: <20190425102953.5348-9-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 08/11] dm: clk: Define clk_get_by_id() for clk operations X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit adds the clk_get_by_id() function, which is responsible for getting the udevice with matching clk->id. Such approach allows re-usage of inherit DM list relationship for the same class (UCLASS_CLK). As a result - we don't need any other external list - it is just enough to look for UCLASS_CLK related udevices. Signed-off-by: Lukasz Majewski Reviewed-by: Peng Fan --- Changes in v3: - Replace -ENODEV with -ENOENT - Use **clkp instead of **c drivers/clk/clk-uclass.c | 22 ++++++++++++++++++++++ include/clk.h | 11 +++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index da6624d4f2..85dae5321a 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -451,6 +451,28 @@ int clk_disable_bulk(struct clk_bulk *bulk) return 0; } +int clk_get_by_id(ulong id, struct clk **clkp) +{ + struct udevice *dev; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_CLK, &uc); + if (ret) + return ret; + + uclass_foreach_dev(dev, uc) { + struct clk *clk = (struct clk *)dev_get_driver_data(dev); + + if (clk && clk->id == id) { + *clkp = clk; + return 0; + } + } + + return -ENOENT; +} + UCLASS_DRIVER(clk) = { .id = UCLASS_CLK, .name = "clk", diff --git a/include/clk.h b/include/clk.h index 98c3e12fb4..a4ecca9fbc 100644 --- a/include/clk.h +++ b/include/clk.h @@ -326,4 +326,15 @@ static inline bool clk_valid(struct clk *clk) { return !!clk->dev; } + +/** + * clk_get_by_id() - Get the clock by its ID + * + * @id: The clock ID to search for + * + * @clkp: A pointer to clock struct that has been found among added clocks + * to UCLASS_CLK + * @return zero on success, or -ENOENT on error + */ +int clk_get_by_id(ulong id, struct clk **clkp); #endif From patchwork Thu Apr 25 10:29:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090674 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYSX5smDz9s3q for ; Thu, 25 Apr 2019 20:33:48 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 7998DC21E0D; Thu, 25 Apr 2019 10:32:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C3FC0C21E18; Thu, 25 Apr 2019 10:31:08 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 27F89C21C50; Thu, 25 Apr 2019 10:30:39 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id 085ECC21E15 for ; Thu, 25 Apr 2019 10:30:38 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNs5yCWz1rJh3; Thu, 25 Apr 2019 12:30:37 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNs4NzMz1qyC7; Thu, 25 Apr 2019 12:30:37 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id jP0ddnZf801L; Thu, 25 Apr 2019 12:30:36 +0200 (CEST) X-Auth-Info: e9p6QbnXKfSiXKNGkvtPgy8bvAH5cq4mYUqQXp0g+fE= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:36 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:51 +0200 Message-Id: <20190425102953.5348-10-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 09/11] clk: test: Provide unit test for clk_get_by_id() method X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit provides sandbox unit test for clk_get_by_id() method. To test it default test clocks setup had to be adjusted to emulate structure similar to clocks in the Common Clock Framework [CCF] (for iMX devices). The clk_get_by_id() relies on dev->driver_data having the pointer to struct clk. Signed-off-by: Lukasz Majewski --- Changes in v3: - New patch arch/sandbox/include/asm/clk.h | 8 ++++++++ drivers/clk/clk_sandbox_test.c | 23 +++++++++++++++++++++++ test/dm/clk.c | 3 ++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h index 2b1c49f783..90f925109f 100644 --- a/arch/sandbox/include/asm/clk.h +++ b/arch/sandbox/include/asm/clk.h @@ -63,6 +63,14 @@ int sandbox_clk_query_enable(struct udevice *dev, int id); */ int sandbox_clk_test_get(struct udevice *dev); /** + * sandbox_clk_test_get_by_id - Ask the sandbox clock test device to request its + * clocks by using clock id. + * + * @dev: The sandbox clock test (client) devivce. + * @return: 0 if OK, or a negative error code. + */ +int sandbox_clk_test_get_by_id(struct udevice *dev); +/** * sandbox_clk_test_get_bulk - Ask the sandbox clock test device to request its * clocks with the bulk clk API. * diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c index e8465dbfad..4d276f55b9 100644 --- a/drivers/clk/clk_sandbox_test.c +++ b/drivers/clk/clk_sandbox_test.c @@ -34,6 +34,29 @@ int sandbox_clk_test_get(struct udevice *dev) return 0; } +int sandbox_clk_test_get_by_id(struct udevice *dev) +{ + struct sandbox_clk_test *sbct = dev_get_priv(dev); + struct clk *clkp, *i2c_clk; + ulong driver_data_bkp; + const int id = 24; + int ret, id_bkp; + + i2c_clk = &sbct->clks[SANDBOX_CLK_TEST_ID_I2C]; + + id_bkp = i2c_clk->id; + i2c_clk->id = id; + driver_data_bkp = i2c_clk->dev->driver_data; + i2c_clk->dev->driver_data = (ulong)i2c_clk; + + ret = clk_get_by_id(id, &clkp); + + i2c_clk->id = id_bkp; + i2c_clk->dev->driver_data = driver_data_bkp; + + return ret; +} + int sandbox_clk_test_get_bulk(struct udevice *dev) { struct sandbox_clk_test *sbct = dev_get_priv(dev); diff --git a/test/dm/clk.c b/test/dm/clk.c index 112d5cbbc9..8b858cee01 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -99,8 +99,9 @@ static int dm_test_clk(struct unit_test_state *uts) ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_SPI)); ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C)); - ut_assertok(sandbox_clk_test_free(dev_test)); + ut_asserteq(0, sandbox_clk_test_get_by_id(dev_test)); + ut_assertok(sandbox_clk_test_free(dev_test)); return 0; } DM_TEST(dm_test_clk, DM_TESTF_SCAN_FDT); From patchwork Thu Apr 25 10:29:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090675 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYT60kK0z9s3q for ; Thu, 25 Apr 2019 20:34:17 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 8E9C1C21D56; Thu, 25 Apr 2019 10:32:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 79EBDC21E08; Thu, 25 Apr 2019 10:31:31 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 6D927C21DA6; Thu, 25 Apr 2019 10:30:43 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id 04164C21E0F for ; Thu, 25 Apr 2019 10:30:40 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYNv5sMQz1rJhN; Thu, 25 Apr 2019 12:30:39 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYNv4HDtz1qyC6; Thu, 25 Apr 2019 12:30:39 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id TGz9lYae7Neh; Thu, 25 Apr 2019 12:30:38 +0200 (CEST) X-Auth-Info: Q4BoK9xJfpiomQKoSHyhB+pIEfeFKSt5d7grN1/iGFI= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:37 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:52 +0200 Message-Id: <20190425102953.5348-11-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Subject: [U-Boot] [PATCH v3 10/11] clk: test: Provide unit test for clk_get_parent_rate() method X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit provides sandbox unit test for clk_get_parent_rate() method. For testing the default test clocks setup had to be adjusted to emulate structure similar to clocks in the Common Clock Framework [CCF] (for iMX devices). The clk_get_parent_rate() relies on dev->driver_data having the pointer to proper struct clk. It uses internally clk_get_parent() method also tested by this test. Signed-off-by: Lukasz Majewski --- Changes in v3: - New patch arch/sandbox/include/asm/clk.h | 8 ++++++++ drivers/clk/clk_sandbox_test.c | 26 ++++++++++++++++++++++++++ test/dm/clk.c | 1 + 3 files changed, 35 insertions(+) diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h index 90f925109f..1df9534236 100644 --- a/arch/sandbox/include/asm/clk.h +++ b/arch/sandbox/include/asm/clk.h @@ -79,6 +79,14 @@ int sandbox_clk_test_get_by_id(struct udevice *dev); */ int sandbox_clk_test_get_bulk(struct udevice *dev); /** + * sandbox_clk_test_get_parent_rate - Ask the sandbox clock test device to + * query a passed clock's parent rate. + * + * @dev: The sandbox clock test (client) devivce. + * @return: The rate of the clock + */ +ulong sandbox_clk_test_get_parent_rate(struct udevice *dev); +/** * sandbox_clk_test_get_rate - Ask the sandbox clock test device to query a * clock's rate. * diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c index 4d276f55b9..8ea15614c1 100644 --- a/drivers/clk/clk_sandbox_test.c +++ b/drivers/clk/clk_sandbox_test.c @@ -64,6 +64,32 @@ int sandbox_clk_test_get_bulk(struct udevice *dev) return clk_get_bulk(dev, &sbct->bulk); } +ulong sandbox_clk_test_get_parent_rate(struct udevice *dev) +{ + struct sandbox_clk_test *sbct = dev_get_priv(dev); + struct clk *i2c_clk, *parent_clk; + struct udevice *parent_bkp; + ulong rate; + + parent_clk = &sbct->clks[SANDBOX_CLK_TEST_ID_FIXED]; + i2c_clk = &sbct->clks[SANDBOX_CLK_TEST_ID_I2C]; + + parent_clk->dev->driver_data = (ulong)parent_clk; + parent_bkp = i2c_clk->dev->parent; + i2c_clk->dev->parent = parent_clk->dev; + + rate = clk_get_parent_rate(i2c_clk); + + i2c_clk->dev->parent = parent_bkp; + parent_clk->dev->driver_data = 0; + + /* Check if cache'd value is correct */ + if (parent_clk->rate != 1234) + return 0; + + return rate; +} + ulong sandbox_clk_test_get_rate(struct udevice *dev, int id) { struct sandbox_clk_test *sbct = dev_get_priv(dev); diff --git a/test/dm/clk.c b/test/dm/clk.c index 8b858cee01..94f475bd8e 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -100,6 +100,7 @@ static int dm_test_clk(struct unit_test_state *uts) ut_asserteq(0, sandbox_clk_query_enable(dev_clk, SANDBOX_CLK_ID_I2C)); ut_asserteq(0, sandbox_clk_test_get_by_id(dev_test)); + ut_asserteq(1234, sandbox_clk_test_get_parent_rate(dev_test)); ut_assertok(sandbox_clk_test_free(dev_test)); return 0; From patchwork Thu Apr 25 10:29:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 1090680 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=denx.de Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44qYWY6Tgyz9s3Z for ; Thu, 25 Apr 2019 20:36:25 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 7F286C21CB1; Thu, 25 Apr 2019 10:32:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 12333C21DFA; Thu, 25 Apr 2019 10:31:49 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id D328DC21DFA; Thu, 25 Apr 2019 10:30:48 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id 8B1C2C21E12 for ; Thu, 25 Apr 2019 10:30:44 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 44qYP02V8zz1rJtC; Thu, 25 Apr 2019 12:30:44 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 44qYP00wKRz1qyC6; Thu, 25 Apr 2019 12:30:44 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id sLGJd5Mhrk5G; Thu, 25 Apr 2019 12:30:40 +0200 (CEST) X-Auth-Info: 9599jpe3624AeTaDpxTVh31SPDYECuUJcYuvqPdjZAA= Received: from localhost.localdomain (85-222-111-42.dynamic.chello.pl [85.222.111.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Thu, 25 Apr 2019 12:30:39 +0200 (CEST) From: Lukasz Majewski To: Stefano Babic , Fabio Estevam , Marek Vasut , Simon Glass , Tom Rini , u-boot@lists.denx.de, Jagan Teki , Peng Fan , Marcel Ziswiler , Adam Ford Date: Thu, 25 Apr 2019 12:29:53 +0200 Message-Id: <20190425102953.5348-12-lukma@denx.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190425102953.5348-1-lukma@denx.de> References: <20190425102953.5348-1-lukma@denx.de> Cc: Manivannan Sadhasivam , Stefan Roese Subject: [U-Boot] [PATCH v3 11/11] clk: Port Linux common clock framework [CCF] for imx6q to U-boot (tag: 5.0-rc3) X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This commit brings the files from Linux kernel to provide clocks support as it is used on the Linux kernel with common clock framework [CCF] setup. The directory structure has been preserved. The ported code only supports reading information from PLL, MUX, Divider, etc and enabling/disabling the clocks USDHCx/ECSPIx depending on used bus. Moreover, it is agnostic to the alias numbering as the information about the clock is read from device tree. One needs to pay attention to the comments indicating necessary for U-boot's DM changes. If needed the code can be extended to support the "set" part of the clock management. Signed-off-by: Lukasz Majewski --- Changes in v3: None drivers/clk/Kconfig | 14 ++++ drivers/clk/Makefile | 2 + drivers/clk/clk-divider.c | 148 ++++++++++++++++++++++++++++++++++ drivers/clk/clk-fixed-factor.c | 87 ++++++++++++++++++++ drivers/clk/clk-mux.c | 164 +++++++++++++++++++++++++++++++++++++ drivers/clk/clk.c | 56 +++++++++++++ drivers/clk/imx/Kconfig | 9 +++ drivers/clk/imx/Makefile | 2 + drivers/clk/imx/clk-gate2.c | 113 ++++++++++++++++++++++++++ drivers/clk/imx/clk-imx6q.c | 179 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk-pfd.c | 91 +++++++++++++++++++++ drivers/clk/imx/clk-pllv3.c | 83 +++++++++++++++++++ drivers/clk/imx/clk.h | 75 +++++++++++++++++ include/linux/clk-provider.h | 94 ++++++++++++++++++++++ 14 files changed, 1117 insertions(+) create mode 100644 drivers/clk/clk-divider.c create mode 100644 drivers/clk/clk-fixed-factor.c create mode 100644 drivers/clk/clk-mux.c create mode 100644 drivers/clk/clk.c create mode 100644 drivers/clk/imx/clk-gate2.c create mode 100644 drivers/clk/imx/clk-imx6q.c create mode 100644 drivers/clk/imx/clk-pfd.c create mode 100644 drivers/clk/imx/clk-pllv3.c create mode 100644 drivers/clk/imx/clk.h create mode 100644 include/linux/clk-provider.h diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index ff60fc5c45..9df3bc731a 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -46,6 +46,20 @@ config CLK_BOSTON help Enable this to support the clocks +config SPL_CLK_CCF + bool "SPL Common Clock Framework [CCF] support " + depends on SPL_CLK + help + Enable this option if you want to (re-)use the Linux kernel's Common + Clock Framework [CCF] code in U-Boot's SPL. + +config CLK_CCF + bool "Common Clock Framework [CCF] support " + depends on CLK + help + Enable this option if you want to (re-)use the Linux kernel's Common + Clock Framework [CCF] code in U-Boot's clock driver. + config CLK_STM32F bool "Enable clock driver support for STM32F family" depends on CLK && (STM32F7 || STM32F4) diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 1d9d725cae..9fcc75e0ea 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -7,6 +7,8 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_rate.o obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_factor.o +obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk.o clk-divider.o clk-mux.o +obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk-fixed-factor.o obj-y += imx/ obj-y += tegra/ diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c new file mode 100644 index 0000000000..3841d8bfbb --- /dev/null +++ b/drivers/clk/clk-divider.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2011 Richard Zhao, Linaro + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define UBOOT_DM_CLK_CCF_DIVIDER "ccf_clk_divider" + +static unsigned int _get_table_div(const struct clk_div_table *table, + unsigned int val) +{ + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; clkt++) + if (clkt->val == val) + return clkt->div; + return 0; +} + +static unsigned int _get_div(const struct clk_div_table *table, + unsigned int val, unsigned long flags, u8 width) +{ + if (flags & CLK_DIVIDER_ONE_BASED) + return val; + if (flags & CLK_DIVIDER_POWER_OF_TWO) + return 1 << val; + if (flags & CLK_DIVIDER_MAX_AT_ZERO) + return val ? val : clk_div_mask(width) + 1; + if (table) + return _get_table_div(table, val); + return val + 1; +} + +unsigned long divider_recalc_rate(struct clk *hw, unsigned long parent_rate, + unsigned int val, + const struct clk_div_table *table, + unsigned long flags, unsigned long width) +{ + unsigned int div; + + div = _get_div(table, val, flags, width); + if (!div) { + WARN(!(flags & CLK_DIVIDER_ALLOW_ZERO), + "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n", + clk_hw_get_name(hw)); + return parent_rate; + } + + return DIV_ROUND_UP_ULL((u64)parent_rate, div); +} + +static ulong clk_divider_recalc_rate(struct clk *clk) +{ + struct clk_divider *divider = + (struct clk_divider *)dev_get_driver_data(clk->dev); + unsigned long parent_rate = clk_get_parent_rate(clk); + unsigned int val; + + val = readl(divider->reg) >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_recalc_rate(clk, parent_rate, val, divider->table, + divider->flags, divider->width); +} + +const struct clk_ops clk_divider_ops = { + .get_rate = clk_divider_recalc_rate, +}; + +static struct clk *_register_divider(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_divider_flags, const struct clk_div_table *table) +{ + struct clk_divider *div; + struct clk *clk; + int ret; + + if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { + if (width + shift > 16) { + pr_warn("divider value exceeds LOWORD field\n"); + return ERR_PTR(-EINVAL); + } + } + + /* allocate the divider */ + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + /* struct clk_divider assignments */ + div->reg = reg; + div->shift = shift; + div->width = width; + div->flags = clk_divider_flags; + div->table = table; + + /* register the clock */ + clk = &div->clk; + + ret = clk_register(clk, UBOOT_DM_CLK_CCF_DIVIDER, (ulong)clk, + name, parent_name); + if (ret) { + kfree(div); + return ERR_PTR(ret); + } + + return clk; +} + +struct clk *clk_register_divider(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_divider_flags) +{ + struct clk *clk; + + clk = _register_divider(dev, name, parent_name, flags, reg, shift, + width, clk_divider_flags, NULL); + if (IS_ERR(clk)) + return ERR_CAST(clk); + return clk; +} + +U_BOOT_DRIVER(ccf_clk_divider) = { + .name = UBOOT_DM_CLK_CCF_DIVIDER, + .id = UCLASS_CLK, + .ops = &clk_divider_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c new file mode 100644 index 0000000000..acbc0909b4 --- /dev/null +++ b/drivers/clk/clk-fixed-factor.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + */ +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor" + +static ulong clk_factor_recalc_rate(struct clk *clk) +{ + struct clk_fixed_factor *fix = + (struct clk_fixed_factor *)dev_get_driver_data(clk->dev); + unsigned long parent_rate = clk_get_parent_rate(clk); + unsigned long long int rate; + + rate = (unsigned long long int)parent_rate * fix->mult; + do_div(rate, fix->div); + return (ulong)rate; +} + +const struct clk_ops ccf_clk_fixed_factor_ops = { + .get_rate = clk_factor_recalc_rate, +}; + +struct clk *clk_hw_register_fixed_factor(struct device *dev, + const char *name, const char *parent_name, unsigned long flags, + unsigned int mult, unsigned int div) +{ + struct clk_fixed_factor *fix; + struct clk *clk; + int ret; + + fix = kmalloc(sizeof(*fix), GFP_KERNEL); + if (!fix) + return ERR_PTR(-ENOMEM); + + /* struct clk_fixed_factor assignments */ + fix->mult = mult; + fix->div = div; + clk = &fix->clk; + + /* + * We pass the struct clk *clk pointer (which is the same as + * clk_fixed_factor *fix - by the struct elements alignment) to DM as a + * driver_data, so it can be easily accessible from the udevice level. + * Moreover, the struct clk is only a wrapper on udevice which + * corresponds to the "real" clock device. + */ + ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, (ulong)clk, + name, parent_name); + if (ret) { + kfree(fix); + return ERR_PTR(ret); + } + + return clk; +} + +struct clk *clk_register_fixed_factor(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + unsigned int mult, unsigned int div) +{ + struct clk *clk; + + clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult, + div); + if (IS_ERR(clk)) + return ERR_CAST(clk); + return clk; +} + +U_BOOT_DRIVER(imx_clk_fixed_factor) = { + .name = UBOOT_DM_CLK_IMX_FIXED_FACTOR, + .id = UCLASS_CLK, + .ops = &ccf_clk_fixed_factor_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c new file mode 100644 index 0000000000..2c85f2052c --- /dev/null +++ b/drivers/clk/clk-mux.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2011 Richard Zhao, Linaro + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * Simple multiplexer clock implementation + */ + +/* + * U-Boot CCF porting node: + * + * The Linux kernel - as of tag: 5.0-rc3 is using also the imx_clk_fixup_mux() + * version of CCF mux. It is used on e.g. imx6q to provide fixes (like + * imx_cscmr1_fixup) for broken HW. + * + * At least for IMX6Q (but NOT IMX6QP) it is important when we set the parent + * clock. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define UBOOT_DM_CLK_CCF_MUX "ccf_clk_mux" + +int clk_mux_val_to_index(struct clk *clk, u32 *table, unsigned int flags, + unsigned int val) +{ + struct clk_mux *mux = to_clk_mux(clk); + int num_parents = mux->num_parents; + + if (table) { + int i; + + for (i = 0; i < num_parents; i++) + if (table[i] == val) + return i; + return -EINVAL; + } + + if (val && (flags & CLK_MUX_INDEX_BIT)) + val = ffs(val) - 1; + + if (val && (flags & CLK_MUX_INDEX_ONE)) + val--; + + if (val >= num_parents) + return -EINVAL; + + return val; +} + +static u8 clk_mux_get_parent(struct clk *clk) +{ + struct clk_mux *mux = to_clk_mux(clk); + u32 val; + + val = readl(mux->reg) >> mux->shift; + val &= mux->mask; + + return clk_mux_val_to_index(clk, mux->table, mux->flags, val); +} + +const struct clk_ops clk_mux_ops = { + .get_rate = clk_generic_get_rate, +}; + +struct clk *clk_hw_register_mux_table(struct device *dev, const char *name, + const char * const *parent_names, u8 num_parents, + unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, + u8 clk_mux_flags, u32 *table) +{ + struct clk_mux *mux; + struct clk *clk; + u8 width = 0; + int ret; + + if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { + width = fls(mask) - ffs(mask) + 1; + if (width + shift > 16) { + pr_err("mux value exceeds LOWORD field\n"); + return ERR_PTR(-EINVAL); + } + } + + /* allocate the mux */ + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + /* U-boot specific assignments */ + mux->parent_names = parent_names; + mux->num_parents = num_parents; + + /* struct clk_mux assignments */ + mux->reg = reg; + mux->shift = shift; + mux->mask = mask; + mux->flags = clk_mux_flags; + mux->table = table; + + clk = &mux->clk; + + /* + * Read the current mux setup - so we assign correct parent. + * + * Changing parent would require changing internals of udevice struct + * for the corresponding clock (to do that define .set_parent() method. + */ + ret = clk_register(clk, UBOOT_DM_CLK_CCF_MUX, (ulong)clk, name, + parent_names[clk_mux_get_parent(clk)]); + if (ret) { + kfree(mux); + return ERR_PTR(ret); + } + + return clk; +} + +struct clk *clk_register_mux_table(struct device *dev, const char *name, + const char * const *parent_names, u8 num_parents, + unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, + u8 clk_mux_flags, u32 *table) +{ + struct clk *clk; + + clk = clk_hw_register_mux_table(dev, name, parent_names, num_parents, + flags, reg, shift, mask, clk_mux_flags, + table); + if (IS_ERR(clk)) + return ERR_CAST(clk); + return clk; +} + +struct clk *clk_register_mux(struct device *dev, const char *name, + const char * const *parent_names, u8 num_parents, + unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_mux_flags) +{ + u32 mask = BIT(width) - 1; + + return clk_register_mux_table(dev, name, parent_names, num_parents, + flags, reg, shift, mask, clk_mux_flags, + NULL); +} + +U_BOOT_DRIVER(ccf_clk_mux) = { + .name = UBOOT_DM_CLK_CCF_MUX, + .id = UCLASS_CLK, + .ops = &clk_mux_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c new file mode 100644 index 0000000000..0a0fffb50b --- /dev/null +++ b/drivers/clk/clk.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include +#include +#include +#include +#include +#include +#include + +int clk_register(struct clk *clk, const char *drv_name, + ulong drv_data, const char *name, + const char *parent_name) +{ + struct udevice *parent; + struct driver *drv; + int ret; + + ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent); + if (ret) + printf("%s: UCLASS parent: 0x%p\n", __func__, parent); + + debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, parent->name, + parent); + + drv = lists_driver_lookup_name(drv_name); + if (!drv) { + printf("%s: %s is not a valid driver name\n", + __func__, drv_name); + return -ENOENT; + } + + ret = device_bind_with_driver_data(parent, drv, name, drv_data, + ofnode_null(), &clk->dev); + if (ret) { + printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name, + ret); + return ret; + } + + return 0; +} + +ulong clk_generic_get_rate(struct clk *clk) +{ + return clk_get_parent_rate(clk); +} + +const char *clk_hw_get_name(const struct clk *hw) +{ + return hw->dev->name; +} diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index a6fb58d6cf..469768b5c3 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -1,3 +1,12 @@ +config CLK_IMX6Q + bool "Clock support for i.MX6Q" + depends on ARCH_MX6 + select CLK + select CLK_CCF + select SPL_CLK_CCF + help + This enables DM/DTS support for clock driver in i.MX6Q platforms. + config CLK_IMX8 bool "Clock support for i.MX8" depends on ARCH_IMX8 diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 5505ae52e2..beba3bff39 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -2,4 +2,6 @@ # # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk-gate2.o clk-pllv3.o clk-pfd.o +obj-$(CONFIG_CLK_IMX6Q) += clk-imx6q.o obj-$(CONFIG_CLK_IMX8) += clk-imx8.o diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c new file mode 100644 index 0000000000..1e53e4f9db --- /dev/null +++ b/drivers/clk/imx/clk-gate2.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright (C) 2010-2011 Canonical Ltd + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Gated clock implementation + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define UBOOT_DM_CLK_IMX_GATE2 "imx_clk_gate2" + +struct clk_gate2 { + struct clk clk; + void __iomem *reg; + u8 bit_idx; + u8 cgr_val; + u8 flags; +}; + +#define to_clk_gate2(_clk) container_of(_clk, struct clk_gate2, clk) + +static int clk_gate2_enable(struct clk *clk) +{ + struct clk_gate2 *gate = + (struct clk_gate2 *)dev_get_driver_data(clk->dev); + u32 reg; + + reg = readl(gate->reg); + reg &= ~(3 << gate->bit_idx); + reg |= gate->cgr_val << gate->bit_idx; + writel(reg, gate->reg); + + return 0; +} + +static int clk_gate2_disable(struct clk *clk) +{ + struct clk_gate2 *gate = + (struct clk_gate2 *)dev_get_driver_data(clk->dev); + u32 reg; + + reg = readl(gate->reg); + reg &= ~(3 << gate->bit_idx); + writel(reg, gate->reg); + + return 0; +} + +static const struct clk_ops clk_gate2_ops = { + .enable = clk_gate2_enable, + .disable = clk_gate2_disable, + .get_rate = clk_generic_get_rate, +}; + +struct clk *clk_register_gate2(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, u8 cgr_val, + u8 clk_gate2_flags) +{ + struct clk_gate2 *gate; + struct clk *clk; + int ret; + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + /* struct clk_gate2 assignments */ + gate->reg = reg; + gate->bit_idx = bit_idx; + gate->cgr_val = cgr_val; + gate->flags = clk_gate2_flags; + + /* + * U-boot DM adjustments: + * + * clk and gate reslove to the same address - lets pass clock + * for better readability. + */ + clk = &gate->clk; + + ret = clk_register(clk, UBOOT_DM_CLK_IMX_GATE2, (ulong)clk, + name, parent_name); + if (ret) { + kfree(gate); + return ERR_PTR(ret); + } + + return clk; +} + +U_BOOT_DRIVER(clk_gate2) = { + .name = UBOOT_DM_CLK_IMX_GATE2, + .id = UCLASS_CLK, + .ops = &clk_gate2_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c new file mode 100644 index 0000000000..92e9337d44 --- /dev/null +++ b/drivers/clk/imx/clk-imx6q.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +static int imx6q_check_id(ulong id) +{ + if (id < IMX6QDL_CLK_DUMMY || id >= IMX6QDL_CLK_END) { + printf("%s: Invalid clk ID #%lu\n", __func__, id); + return -EINVAL; + } + + return 0; +} + +static ulong imx6q_clk_get_rate(struct clk *clk) +{ + struct clk *c; + int ret; + + debug("%s(#%lu)\n", __func__, clk->id); + + ret = imx6q_check_id(clk->id); + if (ret) + return ret; + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + return clk_get_rate(c); +} + +static ulong imx6q_clk_set_rate(struct clk *clk, unsigned long rate) +{ + debug("%s(#%lu), rate: %lu\n", __func__, clk->id, rate); + + return rate; +} + +static int __imx6q_clk_enable(struct clk *clk, bool enable) +{ + struct clk *c; + int ret = 0; + + debug("%s(#%lu) en: %d\n", __func__, clk->id, enable); + + ret = imx6q_check_id(clk->id); + if (ret) + return ret; + + ret = clk_get_by_id(clk->id, &c); + if (ret) + return ret; + + if (enable) + ret = clk_enable(c); + else + ret = clk_disable(c); + + return ret; +} + +static int imx6q_clk_disable(struct clk *clk) +{ + return __imx6q_clk_enable(clk, 0); +} + +static int imx6q_clk_enable(struct clk *clk) +{ + return __imx6q_clk_enable(clk, 1); +} + +static struct clk_ops imx6q_clk_ops = { + .set_rate = imx6q_clk_set_rate, + .get_rate = imx6q_clk_get_rate, + .enable = imx6q_clk_enable, + .disable = imx6q_clk_disable, +}; + +static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; + +static int imx6q_clk_probe(struct udevice *dev) +{ + void *base; + + /* Anatop clocks */ + base = (void *)ANATOP_BASE_ADDR; + + clk_dm(IMX6QDL_CLK_PLL2, + imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", + base + 0x30, 0x1)); + clk_dm(IMX6QDL_CLK_PLL3_USB_OTG, + imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", + base + 0x10, 0x3)); + clk_dm(IMX6QDL_CLK_PLL3_60M, + imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8)); + clk_dm(IMX6QDL_CLK_PLL2_PFD0_352M, + imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0)); + clk_dm(IMX6QDL_CLK_PLL2_PFD2_396M, + imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2)); + + /* CCM clocks */ + base = dev_read_addr_ptr(dev); + if (base == (void *)FDT_ADDR_T_NONE) + return -EINVAL; + + clk_dm(IMX6QDL_CLK_USDHC1_SEL, + imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, + usdhc_sels, ARRAY_SIZE(usdhc_sels))); + clk_dm(IMX6QDL_CLK_USDHC2_SEL, + imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, + usdhc_sels, ARRAY_SIZE(usdhc_sels))); + clk_dm(IMX6QDL_CLK_USDHC3_SEL, + imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, + usdhc_sels, ARRAY_SIZE(usdhc_sels))); + clk_dm(IMX6QDL_CLK_USDHC4_SEL, + imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, + usdhc_sels, ARRAY_SIZE(usdhc_sels))); + + clk_dm(IMX6QDL_CLK_USDHC1_PODF, + imx_clk_divider("usdhc1_podf", "usdhc1_sel", + base + 0x24, 11, 3)); + clk_dm(IMX6QDL_CLK_USDHC2_PODF, + imx_clk_divider("usdhc2_podf", "usdhc2_sel", + base + 0x24, 16, 3)); + clk_dm(IMX6QDL_CLK_USDHC3_PODF, + imx_clk_divider("usdhc3_podf", "usdhc3_sel", + base + 0x24, 19, 3)); + clk_dm(IMX6QDL_CLK_USDHC4_PODF, + imx_clk_divider("usdhc4_podf", "usdhc4_sel", + base + 0x24, 22, 3)); + + clk_dm(IMX6QDL_CLK_ECSPI_ROOT, + imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6)); + + clk_dm(IMX6QDL_CLK_ECSPI1, + imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0)); + clk_dm(IMX6QDL_CLK_ECSPI2, + imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2)); + clk_dm(IMX6QDL_CLK_ECSPI3, + imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4)); + clk_dm(IMX6QDL_CLK_ECSPI4, + imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6)); + clk_dm(IMX6QDL_CLK_USDHC1, + imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2)); + clk_dm(IMX6QDL_CLK_USDHC2, + imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4)); + clk_dm(IMX6QDL_CLK_USDHC3, + imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6)); + clk_dm(IMX6QDL_CLK_USDHC4, + imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8)); + + return 0; +} + +static const struct udevice_id imx6q_clk_ids[] = { + { .compatible = "fsl,imx6q-ccm" }, + { }, +}; + +U_BOOT_DRIVER(imx6q_clk) = { + .name = "clk_imx6q", + .id = UCLASS_CLK, + .of_match = imx6q_clk_ids, + .ops = &imx6q_clk_ops, + .probe = imx6q_clk_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c new file mode 100644 index 0000000000..2293d481d4 --- /dev/null +++ b/drivers/clk/imx/clk-pfd.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define UBOOT_DM_CLK_IMX_PFD "imx_clk_pfd" + +struct clk_pfd { + struct clk clk; + void __iomem *reg; + u8 idx; +}; + +#define to_clk_pfd(_clk) container_of(_clk, struct clk_pfd, clk) + +#define SET 0x4 +#define CLR 0x8 +#define OTG 0xc + +static unsigned long clk_pfd_recalc_rate(struct clk *clk) +{ + struct clk_pfd *pfd = + (struct clk_pfd *)dev_get_driver_data(clk->dev); + unsigned long parent_rate = clk_get_parent_rate(clk); + u64 tmp = parent_rate; + u8 frac = (readl(pfd->reg) >> (pfd->idx * 8)) & 0x3f; + + tmp *= 18; + do_div(tmp, frac); + + return tmp; +} + +static const struct clk_ops clk_pfd_ops = { + .get_rate = clk_pfd_recalc_rate, +}; + +struct clk *imx_clk_pfd(const char *name, const char *parent_name, + void __iomem *reg, u8 idx) +{ + struct clk_pfd *pfd; + struct clk *clk; + int ret; + + pfd = kzalloc(sizeof(*pfd), GFP_KERNEL); + if (!pfd) + return ERR_PTR(-ENOMEM); + + pfd->reg = reg; + pfd->idx = idx; + + /* register the clock */ + clk = &pfd->clk; + + ret = clk_register(clk, UBOOT_DM_CLK_IMX_PFD, (ulong)clk, + name, parent_name); + if (ret) { + kfree(pfd); + return ERR_PTR(ret); + } + + return clk; +} + +U_BOOT_DRIVER(clk_pfd) = { + .name = UBOOT_DM_CLK_IMX_PFD, + .id = UCLASS_CLK, + .ops = &clk_pfd_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c new file mode 100644 index 0000000000..3fe9b7c03d --- /dev/null +++ b/drivers/clk/imx/clk-pllv3.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ + +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define UBOOT_DM_CLK_IMX_PLLV3 "imx_clk_pllv3" + +struct clk_pllv3 { + struct clk clk; + void __iomem *base; + u32 div_mask; + u32 div_shift; +}; + +#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk) + +static ulong clk_pllv3_get_rate(struct clk *clk) +{ + struct clk_pllv3 *pll = + (struct clk_pllv3 *)dev_get_driver_data(clk->dev); + unsigned long parent_rate = clk_get_parent_rate(clk); + + u32 div = (readl(pll->base) >> pll->div_shift) & pll->div_mask; + + return (div == 1) ? parent_rate * 22 : parent_rate * 20; +} + +static const struct clk_ops clk_pllv3_generic_ops = { + .get_rate = clk_pllv3_get_rate, +}; + +struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, + const char *parent_name, void __iomem *base, + u32 div_mask) +{ + struct clk_pllv3 *pll; + struct clk *clk; + char *drv_name; + int ret; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + switch (type) { + case IMX_PLLV3_GENERIC: + case IMX_PLLV3_USB: + drv_name = UBOOT_DM_CLK_IMX_PLLV3; + break; + default: + kfree(pll); + return ERR_PTR(-ENOTSUPP); + } + + pll->base = base; + pll->div_mask = div_mask; + clk = &pll->clk; + + ret = clk_register(clk, drv_name, (ulong)clk, name, parent_name); + if (ret) { + kfree(pll); + return ERR_PTR(ret); + } + + return clk; +} + +U_BOOT_DRIVER(clk_pllv3_generic) = { + .name = UBOOT_DM_CLK_IMX_PLLV3, + .id = UCLASS_CLK, + .ops = &clk_pllv3_generic_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h new file mode 100644 index 0000000000..864a215a22 --- /dev/null +++ b/drivers/clk/imx/clk.h @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + */ +#ifndef __MACH_IMX_CLK_H +#define __MACH_IMX_CLK_H + +#include + +static inline void clk_dm(ulong id, struct clk *clk) +{ + if (!IS_ERR(clk)) + clk->id = id; +} + +enum imx_pllv3_type { + IMX_PLLV3_GENERIC, + IMX_PLLV3_SYS, + IMX_PLLV3_USB, + IMX_PLLV3_USB_VF610, + IMX_PLLV3_AV, + IMX_PLLV3_ENET, + IMX_PLLV3_ENET_IMX7, + IMX_PLLV3_SYS_VF610, + IMX_PLLV3_DDR_IMX7, +}; + +struct clk *clk_register_gate2(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, u8 cgr_val, + u8 clk_gate_flags); + +struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, + const char *parent_name, void __iomem *base, + u32 div_mask); + +static inline struct clk *imx_clk_gate2(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0x3, 0); +} + +static inline struct clk *imx_clk_fixed_factor(const char *name, + const char *parent, unsigned int mult, unsigned int div) +{ + return clk_register_fixed_factor(NULL, name, parent, + CLK_SET_RATE_PARENT, mult, div); +} + +static inline struct clk *imx_clk_divider(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 width) +{ + return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, + reg, shift, width, 0); +} + +struct clk *imx_clk_pfd(const char *name, const char *parent_name, + void __iomem *reg, u8 idx); + +struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, + u8 shift, u8 width, const char * const *parents, + int num_parents, void (*fixup)(u32 *val)); + +static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, + u8 shift, u8 width, const char * const *parents, + int num_parents) +{ + return clk_register_mux(NULL, name, parents, num_parents, + CLK_SET_RATE_NO_REPARENT, reg, shift, + width, 0); +} + +#endif /* __MACH_IMX_CLK_H */ diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h new file mode 100644 index 0000000000..eac045c5f8 --- /dev/null +++ b/include/linux/clk-provider.h @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 DENX Software Engineering + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * Copyright (c) 2010-2011 Jeremy Kerr + * Copyright (C) 2011-2012 Linaro Ltd + */ +#ifndef __LINUX_CLK_PROVIDER_H +#define __LINUX_CLK_PROVIDER_H + +#define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ +#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ + +#define CLK_MUX_INDEX_ONE BIT(0) +#define CLK_MUX_INDEX_BIT BIT(1) +#define CLK_MUX_HIWORD_MASK BIT(2) +#define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */ +#define CLK_MUX_ROUND_CLOSEST BIT(4) + +struct clk_mux { + struct clk clk; + void __iomem *reg; + u32 *table; + u32 mask; + u8 shift; + u8 flags; + + /* + * Fields from struct clk_init_data - this struct has been + * omitted to avoid too deep level of CCF for bootloader + */ + const char * const *parent_names; + u8 num_parents; +}; + +#define to_clk_mux(_clk) container_of(_clk, struct clk_mux, clk) + +struct clk_div_table { + unsigned int val; + unsigned int div; +}; + +struct clk_divider { + struct clk clk; + void __iomem *reg; + u8 shift; + u8 width; + u8 flags; + const struct clk_div_table *table; +}; + +#define clk_div_mask(width) ((1 << (width)) - 1) +#define to_clk_divider(_clk) container_of(_clk, struct clk_divider, clk) + +#define CLK_DIVIDER_ONE_BASED BIT(0) +#define CLK_DIVIDER_POWER_OF_TWO BIT(1) +#define CLK_DIVIDER_ALLOW_ZERO BIT(2) +#define CLK_DIVIDER_HIWORD_MASK BIT(3) +#define CLK_DIVIDER_ROUND_CLOSEST BIT(4) +#define CLK_DIVIDER_READ_ONLY BIT(5) +#define CLK_DIVIDER_MAX_AT_ZERO BIT(6) + +struct clk_fixed_factor { + struct clk clk; + unsigned int mult; + unsigned int div; +}; + +#define to_clk_fixed_factor(_clk) container_of(_clk, struct clk_fixed_factor,\ + clk) + +int clk_register(struct clk *clk, const char *drv_name, + ulong drv_data, const char *name, + const char *parent_name); + +struct clk *clk_register_fixed_factor(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + unsigned int mult, unsigned int div); + +struct clk *clk_register_divider(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_divider_flags); + +struct clk *clk_register_mux(struct device *dev, const char *name, + const char * const *parent_names, u8 num_parents, + unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_mux_flags); + +const char *clk_hw_get_name(const struct clk *hw); +ulong clk_generic_get_rate(struct clk *clk); +#endif /* __LINUX_CLK_PROVIDER_H */