Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp3858445rwd; Sat, 17 Jun 2023 03:34:17 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4XphDfr2sMLRNQaUuO59wFHnILYKUgTA237CHx4K/SVPJEkty2Afm4xD/WapdYB2uC+1iD X-Received: by 2002:a05:6359:a12:b0:130:5951:b268 with SMTP id el18-20020a0563590a1200b001305951b268mr1452184rwb.31.1686998056970; Sat, 17 Jun 2023 03:34:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686998056; cv=none; d=google.com; s=arc-20160816; b=k2bWvtVoMQZB/eMVJCCFntwc8IGvLQvRoGclWzVHthvkTGEwQ7FAJPsrKRunm8K3k2 U7/udvIoduNE6jlo5pakoPgdAxF53Msh6tgOwcNqVke0H/5/22XINjcMGS09mRsaeWum jBOQYN4fdZ2mmfWS57Wd4Blrr5Cd1xUeoF26GwIZxIHutOMqsdn0Trcgwt7z7DiPMIEY gPuFsyhF0jJO3I2AT2I5TE8FJYvzPG5k7EoKLSZ9QJI4oDMBnUzT68Ez0Xl5ww5hbUtC pA8hwuIl4UBp4oBCJp+8uN87jGMr7XAUT4G0y6gYdIMJaS0sfXG5cZqiu+dgBYVOS0CV 1jNQ== 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=VgAbYyJh48hxAs8I72LsWS5J2+rDqhQyILPVFj8OEQc=; b=Ms1VMsW2RO4SaH0b+o6TR1TTUHJd6y5yTF1mTH3loQhivA1lLyOR6MPEWT5a/6qUfD wBG2yr7o6CLtYY3iUToPP/GkD/tvZe3+JZYsxRN8aLvt7W2Q1YawvVpRvTzDhfZFi8js 7vPU7H7XpAB7l+Blp1aSrFtdyYHqM7Sy9s7WjBzb+51A8fwON42SUbZAlB8iSHDjj989 YUUVyrpiDiAaS4NAMFQ9j4XjpBvN86rm7vExWl3Cnafjt6Wv8U7h5scAjzr/M/XlgMyj 0KotyiMrdxmNJbrID/7lbuCsy9moRgAwR2GHdwAbXwZCik7xkR000nPQPck4oKIDUpuo iDDw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@oltmanns.dev header.s=MBO0001 header.b=bWmrmWi+; 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u11-20020a6540cb000000b0053b8f80c63dsi5868764pgp.734.2023.06.17.03.34.00; Sat, 17 Jun 2023 03:34:16 -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=bWmrmWi+; 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 S235928AbjFQK37 (ORCPT + 99 others); Sat, 17 Jun 2023 06:29:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346138AbjFQK3q (ORCPT ); Sat, 17 Jun 2023 06:29:46 -0400 Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [80.241.56.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA7DA1FFE; Sat, 17 Jun 2023 03:29:43 -0700 (PDT) Received: from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202]) (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-202.mailbox.org (Postfix) with ESMTPS id 4Qjshz24ctz9sb9; Sat, 17 Jun 2023 12:29:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oltmanns.dev; s=MBO0001; t=1686997779; 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=VgAbYyJh48hxAs8I72LsWS5J2+rDqhQyILPVFj8OEQc=; b=bWmrmWi+8prioSC+1LbWqb/zTPzY+DRXxzPU418SST2mY10H2OwdEvxZoBg8ZI4QzLDxyK xwnHMtHoz31528+39tafNGCiF0uq89qXfX7KvXR2EjSPYwmmwvi45JJQ5BAXE3GVXc7uxZ 8mGHcJ77iUjWC+dtcE3g/xJKc9pwbAhdi2eqMm95OuiC0t/JceSvtGTycZJiPEto7nLmlE SM5/Wk4ejB3hyzFvqe1xzRcYTPBgMo1o8YFTV1JHZBJ6mKgqPD969+dXyMUdifXf1Qg8sS PX0NFw1GQVNm2jLsm+dEoHAjAbiePItJvupsvRveV5ttyO0JmDih8XkMA1VARA== 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 v4 2/2] clk: fractional-divider: tests: Add test suite for edge cases Date: Sat, 17 Jun 2023 12:29:19 +0200 Message-ID: <20230617102919.27564-3-frank@oltmanns.dev> In-Reply-To: <20230617102919.27564-1-frank@oltmanns.dev> References: <20230617102919.27564-1-frank@oltmanns.dev> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 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:107 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:138 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 | 161 ++++++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 drivers/clk/clk-fractional-divider_test.c 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..30a776cf33c0 --- /dev/null +++ b/drivers/clk/clk-fractional-divider_test.c @@ -0,0 +1,161 @@ +// 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_m, max_n; + + fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, fd); + + fd->mwidth = 3; + max_m = 7; + 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, max_n; + + fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, fd); + + fd->mwidth = 3; + max_m = 7; + fd->nwidth = 3; + max_n = 7; + + 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_n + 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_m, 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; + max_m = 8; + 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, 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; + max_m = 8; + fd->nwidth = 3; + max_n = 8; + + 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_n + 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"); -- 2.41.0