From patchwork Sat Jun 17 13:10:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Oltmanns X-Patchwork-Id: 109488 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1981261vqr; Sat, 17 Jun 2023 06:37:24 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6Eptio10qdb3enVALFgafTkF19YQmGk6qI7kHZ82WqRcKa3FfbgK8XzRtEhaUm303idNJZ X-Received: by 2002:a17:903:41c4:b0:1a6:a405:f714 with SMTP id u4-20020a17090341c400b001a6a405f714mr6534249ple.63.1687009043880; Sat, 17 Jun 2023 06:37:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687009043; cv=none; d=google.com; s=arc-20160816; b=HKmDtMh8aAIb+rM0x1dXFPHwMeBNrC6SWLIiY0klezqhmKLAn1x+PQ5WeU7gfcbt0R yqyqYvZ7APbObuRO1J1KHIKrCH+2WEAiM5ildsuzjF4DQhH/WUSFZ3/jg1n8g1AlHIQN MT23U7gKRH6Hb3Qpx1dm6g0djvP+PrHrb9ikHAYxSiW1e3BED5DIh2PSPPZWYG5XrJKX BMIs0NMnmoMbUuEz5JICwQcduMbwVfILbzujyQMLVh3Qku1NRv97ORwYc17AYYjqDjdG /dVBxDovsNenLZgVCMxwodDyYJnZ4MrO8oC4nLuHT844tWKt3KfZt/NiFIdf9ZbM9S9s sAYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=piM6ASDgch6PVWDiOGs21ydWS2z+iDsSfAmRcYpzIiU=; b=N62hQgX5sd/zniJEpMQt1Iz7DTwHYs2B/THS9YStjnG+3qfPcfN1jdTTIgJ4QvBPtk Gxdl1KJbt1JxI/GoDH3motre8XO3Nnz0mzKWgpzws4rV5qn3k8vbjUsEDjcybp5PzoiT NRd6mWQDSNHT41Ki+fAAYyQ+a34SHOpryAzkBLfpER2CW/gz/bEkA16ClWTMpLDssU0c KFru/c9bARhpAb3qPNBXjZAbCIJtyTASJ+/vLnpkkg29rdJxgdBqgWWPR4NF/iVLrX9+ Pmj7ifZz+QBjEHyiLLnjUFs4cUzFxoSobp0xcmDzWbeR2uh9DT3ch3TN1LJe2U3GGaz+ KUdA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oltmanns.dev header.s=MBO0001 header.b=KSPOsr5c; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oltmanns.dev Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id la12-20020a170902fa0c00b001b3cf7eb499si10943841plb.633.2023.06.17.06.37.10; Sat, 17 Jun 2023 06:37:23 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@oltmanns.dev header.s=MBO0001 header.b=KSPOsr5c; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oltmanns.dev Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346292AbjFQNLI (ORCPT + 99 others); Sat, 17 Jun 2023 09:11:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34354 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234822AbjFQNLD (ORCPT ); Sat, 17 Jun 2023 09:11:03 -0400 Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [80.241.56.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D228F10C8; Sat, 17 Jun 2023 06:11:01 -0700 (PDT) Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4QjxH62X24z9sQ8; Sat, 17 Jun 2023 15:10:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oltmanns.dev; s=MBO0001; t=1687007458; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=piM6ASDgch6PVWDiOGs21ydWS2z+iDsSfAmRcYpzIiU=; b=KSPOsr5cxsmsYEao8mRDaSqgRmo3HE5aSDD/ijiaVKToPEMnJUPFKjlvEHLfF5v6ZWxbw5 QamkTttPpyTuSmiMzRV+dK03cJGei4NOtQSyonmD+DzLvJaSBDZXGEW7zmujCn8sVaTWx7 gtJdJK5rdAzcX4cpP5R9+IpKhdwlwf49QMV3lAjzeMXcMy5fn/Mm5BfAYEe8IWCufgwssS t0zyh4vvIO3WsYnTXm7z9Rr1z4vh7CPBgSEGpr4sT9PWlvuCJ/ILGuL23mLxGwibA3y/ig W34kAsAkHNPHDQEfW6lZeQlEGWekmwBqu2+hV65R1tZeMgVlgtUlrM/MhlZoMQ== From: Frank Oltmanns To: Michael Turquette , Stephen Boyd Cc: Frank Oltmanns , "A . s . Dong" , Abel Vesa , Fabio Estevam , linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, NXP Linux Team , Peng Fan , Pengutronix Kernel Team , Sascha Hauer , Shawn Guo , Elaine Zhang Subject: [PATCH v5 1/2] clk: fractional-divider: Improve approximation when zero based and export Date: Sat, 17 Jun 2023 15:10:40 +0200 Message-ID: <20230617131041.18313-2-frank@oltmanns.dev> In-Reply-To: <20230617131041.18313-1-frank@oltmanns.dev> References: <20230617131041.18313-1-frank@oltmanns.dev> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4QjxH62X24z9sQ8 X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1768945668763524249?= X-GMAIL-MSGID: =?utf-8?q?1768957195140120258?= Consider the CLK_FRAC_DIVIDER_ZERO_BASED flag when finding the best approximation for m and n. By doing so, increase the range of valid values for the numerator and denominator by 1. Furthermore, export the approximation function so that users of this function can be compiled as modules. Cc: A.s. Dong Signed-off-by: Frank Oltmanns --- drivers/clk/clk-fractional-divider.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index 479297763e70..5067e067e906 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -123,6 +123,7 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw, unsigned long *m, unsigned long *n) { struct clk_fractional_divider *fd = to_clk_fd(hw); + unsigned long max_m, max_n; /* * Get rate closer to *parent_rate to guarantee there is no overflow @@ -138,10 +139,17 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw, rate <<= scale - fd->nwidth; } - rational_best_approximation(rate, *parent_rate, - GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), - m, n); + if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) { + max_m = 1 << fd->mwidth; + max_n = 1 << fd->nwidth; + } else { + max_m = GENMASK(fd->mwidth - 1, 0); + max_n = GENMASK(fd->nwidth - 1, 0); + } + + rational_best_approximation(rate, *parent_rate, max_m, max_n, m, n); } +EXPORT_SYMBOL_GPL(clk_fractional_divider_general_approximation); static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) @@ -169,13 +177,18 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_fractional_divider *fd = to_clk_fd(hw); unsigned long flags = 0; - unsigned long m, n; + unsigned long m, n, max_m, max_n; u32 mmask, nmask; u32 val; - rational_best_approximation(rate, parent_rate, - GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), - &m, &n); + if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) { + max_m = 1 << fd->mwidth; + max_n = 1 << fd->nwidth; + } else { + max_m = GENMASK(fd->mwidth - 1, 0); + max_n = GENMASK(fd->nwidth - 1, 0); + } + rational_best_approximation(rate, parent_rate, max_m, max_n, &m, &n); if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) { m--; From patchwork Sat Jun 17 13:10:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Oltmanns X-Patchwork-Id: 109489 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1981269vqr; Sat, 17 Jun 2023 06:37:25 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5cCbIwpYgDoVr0zJwjCJWX2CD/A2TjyhnpK+JM/CDGl8BRqn6nnMHLsJvxkItyBPzs6EAC X-Received: by 2002:a05:6870:d18a:b0:19e:8deb:389b with SMTP id a10-20020a056870d18a00b0019e8deb389bmr2985743oac.41.1687009045053; Sat, 17 Jun 2023 06:37:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687009045; cv=none; d=google.com; s=arc-20160816; b=eqmZ7CDh4N/O57jXNg1hfZ8Av79GmYZ4jR1UTITSxBg7c6IY2IZiAUHgl4bhcTP6ew VtOY81UkC64B3Ugb5y6dclQXzGGhVP84G5B43c2+JE5dJH7DN6Ho1QBpZR5gWF4aOxxW exUi87zPK/qNwqvaXe8ILRP0SzbIwqiiE8lK4aQ/l/gt2yiqJTW0SP38qJpwHwUuFbVF Y0ZPBe0HtkL13T74Gh2JnM1GEozbgw7t0TM9VAb2I3nF54+qLuWHdXKFqOoRwqnlRaos kHuAK/vtoJEVuEELrYSRn2OxV2GpzpuKj2wTjuH5JMHHsVQoA2/hipzm1h5a7kTgT4SG S+uQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=p5tjwuOtHg+H68IXOztHB24QdLm2Kp3Ta/skyoV/pfU=; b=I8MDkWrqukGn0MnbaTgLQ8Ky8dCTa7asVdcmCKEX6gyq1f/xNl/HbytTIjrRUAKXxU 8nLV1lkJFyyEBGjAzVwFYnTJrijV4Hgr0fILFjt9+bSPFOO7A71weOXuULQ1WFPWuL+O drnI4UwLvlBl3R3dr5TDs7JT37j3owFugjW9Cnr7FwPPjhPWU2/Hl/TPAUkQ+HrhglhZ 1IoTx+/upJAjrK+9GsZn0wAeJFrI5clTye0JALXx4+TPE+YidjYtKl1vfbEpPOz6HBhw 5bNJAwPV+moMy05AuU96ywaW6qvH9pftkSboJNZe/LCyFgLVggNCcS+u7oeELo4pWW3u DKOw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oltmanns.dev header.s=MBO0001 header.b=yEkl9cQj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oltmanns.dev Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id q197-20020a632ace000000b0054fdb18c877si7301082pgq.607.2023.06.17.06.37.12; Sat, 17 Jun 2023 06:37:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@oltmanns.dev header.s=MBO0001 header.b=yEkl9cQj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=oltmanns.dev Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346317AbjFQNLN (ORCPT + 99 others); Sat, 17 Jun 2023 09:11:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346273AbjFQNLF (ORCPT ); Sat, 17 Jun 2023 09:11:05 -0400 Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [80.241.56.171]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 543D4F3; Sat, 17 Jun 2023 06:11:04 -0700 (PDT) Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4QjxH90KwZz9sjK; Sat, 17 Jun 2023 15:11:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oltmanns.dev; s=MBO0001; t=1687007461; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=p5tjwuOtHg+H68IXOztHB24QdLm2Kp3Ta/skyoV/pfU=; b=yEkl9cQjLR/gPQ0xIZ84snzggl/ppBru2aqpg9C5TCZglUjAlt1Nqy5RHDsZ47VR970fOc SN+DmrhcsCSA6tOITVxZWkO2uXAlMsFj1DxlR8GrcUjDVhZAvx75PkfoSoCKUwVMNyiNlC oEALHCehHAsToDym8//EfNcu+5/zXYJhgwqeHcF9hqANruw1MvnX7OrNn9CP2o6DAAPuYs TS661RmS/nTr7RtOoQW/zfAi8TdE2+1bXdHh69+i4mMSZ64ok7EvgP8+iAHNDRLJHxVei9 H2bwR7whv/ojRXMqylO2+8hN2OGna4XdW6Q4vmR+rXtddd83n+iKt4L7onCtcA== From: Frank Oltmanns To: Michael Turquette , Stephen Boyd Cc: Frank Oltmanns , "A.s. Dong" , Abel Vesa , Fabio Estevam , linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, NXP Linux Team , Peng Fan , Pengutronix Kernel Team , Sascha Hauer , Shawn Guo , Elaine Zhang Subject: [PATCH v5 2/2] clk: fractional-divider: tests: Add test suite for edge cases Date: Sat, 17 Jun 2023 15:10:41 +0200 Message-ID: <20230617131041.18313-3-frank@oltmanns.dev> In-Reply-To: <20230617131041.18313-1-frank@oltmanns.dev> References: <20230617131041.18313-1-frank@oltmanns.dev> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4QjxH90KwZz9sjK X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1768957196458572776?= X-GMAIL-MSGID: =?utf-8?q?1768957196458572776?= In light of the recent discovery that the fractional divisor approximation does not utilize the full available range for clocks that are flagged CLK_FRAC_DIVIDER_ZERO_BASED [1], implement tests for the edge cases of this clock type. Signed-off-by: Frank Oltmanns Link: https://lore.kernel.org/lkml/20230529133433.56215-1-frank@oltmanns.dev [1] --- Please note: I get two checkpatch warnings for this patch: - Concerning the help text in Kconfig. - Regarding the file being added, asking if MAINTAINERS needs updating. Both the help text as well as the MAINTAINERS file seem fine to me. As expected, when the tests are run *without* PATCH 1, the two "zero based" test cases fail: ================= clk-fd-test (4 subtests) ================= [PASSED] clk_fd_test_approximation_max_denominator [PASSED] clk_fd_test_approximation_max_numerator # clk_fd_test_approximation_max_denominator_zero_based: EXPECTATION FAILED at drivers/clk/clk-fractional-divider_test.c:104 Expected n == max_n, but n == 7 (0x7) max_n == 8 (0x8) [FAILED] clk_fd_test_approximation_max_denominator_zero_based # clk_fd_test_approximation_max_numerator_zero_based: EXPECTATION FAILED at drivers/clk/clk-fractional-divider_test.c:134 Expected m == max_m, but m == 7 (0x7) max_m == 8 (0x8) [FAILED] clk_fd_test_approximation_max_numerator_zero_based # clk-fd-test: pass:2 fail:2 skip:0 total:4 # Totals: pass:2 fail:2 skip:0 total:4 =================== [FAILED] clk-fd-test =================== Best regards, Frank drivers/clk/.kunitconfig | 1 + drivers/clk/Kconfig | 7 + drivers/clk/Makefile | 1 + drivers/clk/clk-fractional-divider_test.c | 157 ++++++++++++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 drivers/clk/clk-fractional-divider_test.c diff --git a/drivers/clk/.kunitconfig b/drivers/clk/.kunitconfig index 2fbeb71316f8..efa12ac2b3f2 100644 --- a/drivers/clk/.kunitconfig +++ b/drivers/clk/.kunitconfig @@ -2,4 +2,5 @@ CONFIG_KUNIT=y CONFIG_COMMON_CLK=y CONFIG_CLK_KUNIT_TEST=y CONFIG_CLK_GATE_KUNIT_TEST=y +CONFIG_CLK_FD_KUNIT_TEST=y CONFIG_UML_PCI_OVER_VIRTIO=n diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 016814e15536..3fbb40cb5551 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -513,4 +513,11 @@ config CLK_GATE_KUNIT_TEST help Kunit test for the basic clk gate type. +config CLK_FD_KUNIT_TEST + tristate "Basic fractional divider type Kunit test" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + Kunit test for the clk-fractional-divider type. + endif diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 0aebef17edc6..9d2337c12dd1 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-multiplier.o obj-$(CONFIG_COMMON_CLK) += clk-mux.o obj-$(CONFIG_COMMON_CLK) += clk-composite.o obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o +obj-$(CONFIG_CLK_FD_KUNIT_TEST) += clk-fractional-divider_test.o obj-$(CONFIG_COMMON_CLK) += clk-gpio.o ifeq ($(CONFIG_OF), y) obj-$(CONFIG_COMMON_CLK) += clk-conf.o diff --git a/drivers/clk/clk-fractional-divider_test.c b/drivers/clk/clk-fractional-divider_test.c new file mode 100644 index 000000000000..7b8105496cbb --- /dev/null +++ b/drivers/clk/clk-fractional-divider_test.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Kunit test for clock fractional divider + */ +#include +#include + +/* Needed for clk_hw_get_clk() */ +#include "clk.h" + +/* Needed for clk_fractional_divider_general_approximation */ +#include "clk-fractional-divider.h" + +#include + +/* + * Test the maximum denominator case for fd clock without flags. + * + * Expect the highest possible denominator to be used in order to get as close as possible to the + * requested rate. + */ +static void clk_fd_test_approximation_max_denominator(struct kunit *test) +{ + struct clk_fractional_divider *fd; + struct clk_hw *hw; + unsigned long rate, parent_rate, m, n, max_n; + + fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, fd); + + fd->mwidth = 3; + fd->nwidth = 3; + max_n = 7; + + hw = &fd->hw; + + rate = 240000000; + parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */ + + clk_fractional_divider_general_approximation(hw, rate, &parent_rate, &m, &n); + KUNIT_EXPECT_EQ(test, parent_rate, (max_n + 1) * rate); /* parent remains unchanged */ + KUNIT_EXPECT_EQ(test, m, 1); + KUNIT_EXPECT_EQ(test, n, max_n); +} + +/* + * Test the maximum numerator case for fd clock without flags. + * + * Expect the highest possible numerator to be used in order to get as close as possible to the + * requested rate. + */ +static void clk_fd_test_approximation_max_numerator(struct kunit *test) +{ + struct clk_fractional_divider *fd; + struct clk_hw *hw; + unsigned long rate, parent_rate, m, n, max_m; + + fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, fd); + + fd->mwidth = 3; + max_m = 7; + fd->nwidth = 3; + + hw = &fd->hw; + + rate = 240000000; + parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */ + + clk_fractional_divider_general_approximation(hw, rate, &parent_rate, &m, &n); + KUNIT_EXPECT_EQ(test, parent_rate, rate / (max_m + 1)); /* parent remains unchanged */ + KUNIT_EXPECT_EQ(test, m, max_m); + KUNIT_EXPECT_EQ(test, n, 1); +} + +/* + * Test the maximum denominator case for zero based fd clock. + * + * Expect the highest possible denominator to be used in order to get as close as possible to the + * requested rate. + */ +static void clk_fd_test_approximation_max_denominator_zero_based(struct kunit *test) +{ + struct clk_fractional_divider *fd; + struct clk_hw *hw; + unsigned long rate, parent_rate, m, n, max_n; + + fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, fd); + + fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED; + fd->mwidth = 3; + fd->nwidth = 3; + max_n = 8; + + hw = &fd->hw; + + rate = 240000000; + parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */ + + clk_fractional_divider_general_approximation(hw, rate, &parent_rate, &m, &n); + KUNIT_EXPECT_EQ(test, parent_rate, (max_n + 1) * rate); /* parent remains unchanged */ + KUNIT_EXPECT_EQ(test, m, 1); + KUNIT_EXPECT_EQ(test, n, max_n); +} + +/* + * Test the maximum numerator case for zero based fd clock. + * + * Expect the highest possible numerator to be used in order to get as close as possible to the + * requested rate. + */ +static void clk_fd_test_approximation_max_numerator_zero_based(struct kunit *test) +{ + struct clk_fractional_divider *fd; + struct clk_hw *hw; + unsigned long rate, parent_rate, m, n, max_m; + + fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, fd); + + fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED; + fd->mwidth = 3; + max_m = 8; + fd->nwidth = 3; + + hw = &fd->hw; + + rate = 240000000; + parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */ + + clk_fractional_divider_general_approximation(hw, rate, &parent_rate, &m, &n); + KUNIT_EXPECT_EQ(test, parent_rate, rate / (max_m + 1)); /* parent remains unchanged */ + KUNIT_EXPECT_EQ(test, m, max_m); + KUNIT_EXPECT_EQ(test, n, 1); +} + +static struct kunit_case clk_fd_test_cases[] = { + KUNIT_CASE(clk_fd_test_approximation_max_denominator), + KUNIT_CASE(clk_fd_test_approximation_max_numerator), + KUNIT_CASE(clk_fd_test_approximation_max_denominator_zero_based), + KUNIT_CASE(clk_fd_test_approximation_max_numerator_zero_based), + {} +}; + +/* + * Test suite for a fractional divider clock. + */ +static struct kunit_suite clk_fd_test_suite = { + .name = "clk-fd-test", + .test_cases = clk_fd_test_cases, +}; + +kunit_test_suites( + &clk_fd_test_suite +); +MODULE_LICENSE("GPL");