1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Kunit test for clock fractional divider |
4 | */ |
5 | #include <linux/clk-provider.h> |
6 | #include <kunit/test.h> |
7 | |
8 | #include "clk-fractional-divider.h" |
9 | |
10 | /* |
11 | * Test the maximum denominator case for fd clock without flags. |
12 | * |
13 | * Expect the highest possible denominator to be used in order to get as close as possible to the |
14 | * requested rate. |
15 | */ |
16 | static void clk_fd_test_approximation_max_denominator(struct kunit *test) |
17 | { |
18 | struct clk_fractional_divider *fd; |
19 | unsigned long rate, parent_rate, parent_rate_before, m, n, max_n; |
20 | |
21 | fd = kunit_kzalloc(test, size: sizeof(*fd), GFP_KERNEL); |
22 | KUNIT_ASSERT_NOT_NULL(test, fd); |
23 | |
24 | fd->mwidth = 3; |
25 | fd->nwidth = 3; |
26 | max_n = 7; |
27 | |
28 | rate = 240000000; |
29 | parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */ |
30 | parent_rate_before = parent_rate; |
31 | |
32 | clk_fractional_divider_general_approximation(hw: &fd->hw, rate, parent_rate: &parent_rate, m: &m, n: &n); |
33 | KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before); |
34 | |
35 | KUNIT_EXPECT_EQ(test, m, 1); |
36 | KUNIT_EXPECT_EQ(test, n, max_n); |
37 | } |
38 | |
39 | /* |
40 | * Test the maximum numerator case for fd clock without flags. |
41 | * |
42 | * Expect the highest possible numerator to be used in order to get as close as possible to the |
43 | * requested rate. |
44 | */ |
45 | static void clk_fd_test_approximation_max_numerator(struct kunit *test) |
46 | { |
47 | struct clk_fractional_divider *fd; |
48 | unsigned long rate, parent_rate, parent_rate_before, m, n, max_m; |
49 | |
50 | fd = kunit_kzalloc(test, size: sizeof(*fd), GFP_KERNEL); |
51 | KUNIT_ASSERT_NOT_NULL(test, fd); |
52 | |
53 | fd->mwidth = 3; |
54 | max_m = 7; |
55 | fd->nwidth = 3; |
56 | |
57 | rate = 240000000; |
58 | parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */ |
59 | parent_rate_before = parent_rate; |
60 | |
61 | clk_fractional_divider_general_approximation(hw: &fd->hw, rate, parent_rate: &parent_rate, m: &m, n: &n); |
62 | KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before); |
63 | |
64 | KUNIT_EXPECT_EQ(test, m, max_m); |
65 | KUNIT_EXPECT_EQ(test, n, 1); |
66 | } |
67 | |
68 | /* |
69 | * Test the maximum denominator case for zero based fd clock. |
70 | * |
71 | * Expect the highest possible denominator to be used in order to get as close as possible to the |
72 | * requested rate. |
73 | */ |
74 | static void clk_fd_test_approximation_max_denominator_zero_based(struct kunit *test) |
75 | { |
76 | struct clk_fractional_divider *fd; |
77 | unsigned long rate, parent_rate, parent_rate_before, m, n, max_n; |
78 | |
79 | fd = kunit_kzalloc(test, size: sizeof(*fd), GFP_KERNEL); |
80 | KUNIT_ASSERT_NOT_NULL(test, fd); |
81 | |
82 | fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED; |
83 | fd->mwidth = 3; |
84 | fd->nwidth = 3; |
85 | max_n = 8; |
86 | |
87 | rate = 240000000; |
88 | parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */ |
89 | parent_rate_before = parent_rate; |
90 | |
91 | clk_fractional_divider_general_approximation(hw: &fd->hw, rate, parent_rate: &parent_rate, m: &m, n: &n); |
92 | KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before); |
93 | |
94 | KUNIT_EXPECT_EQ(test, m, 1); |
95 | KUNIT_EXPECT_EQ(test, n, max_n); |
96 | } |
97 | |
98 | /* |
99 | * Test the maximum numerator case for zero based fd clock. |
100 | * |
101 | * Expect the highest possible numerator to be used in order to get as close as possible to the |
102 | * requested rate. |
103 | */ |
104 | static void clk_fd_test_approximation_max_numerator_zero_based(struct kunit *test) |
105 | { |
106 | struct clk_fractional_divider *fd; |
107 | unsigned long rate, parent_rate, parent_rate_before, m, n, max_m; |
108 | |
109 | fd = kunit_kzalloc(test, size: sizeof(*fd), GFP_KERNEL); |
110 | KUNIT_ASSERT_NOT_NULL(test, fd); |
111 | |
112 | fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED; |
113 | fd->mwidth = 3; |
114 | max_m = 8; |
115 | fd->nwidth = 3; |
116 | |
117 | rate = 240000000; |
118 | parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */ |
119 | parent_rate_before = parent_rate; |
120 | |
121 | clk_fractional_divider_general_approximation(hw: &fd->hw, rate, parent_rate: &parent_rate, m: &m, n: &n); |
122 | KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before); |
123 | |
124 | KUNIT_EXPECT_EQ(test, m, max_m); |
125 | KUNIT_EXPECT_EQ(test, n, 1); |
126 | } |
127 | |
128 | static struct kunit_case clk_fd_approximation_test_cases[] = { |
129 | KUNIT_CASE(clk_fd_test_approximation_max_denominator), |
130 | KUNIT_CASE(clk_fd_test_approximation_max_numerator), |
131 | KUNIT_CASE(clk_fd_test_approximation_max_denominator_zero_based), |
132 | KUNIT_CASE(clk_fd_test_approximation_max_numerator_zero_based), |
133 | {} |
134 | }; |
135 | |
136 | /* |
137 | * Test suite for clk_fractional_divider_general_approximation(). |
138 | */ |
139 | static struct kunit_suite clk_fd_approximation_suite = { |
140 | .name = "clk-fd-approximation" , |
141 | .test_cases = clk_fd_approximation_test_cases, |
142 | }; |
143 | |
144 | kunit_test_suites( |
145 | &clk_fd_approximation_suite |
146 | ); |
147 | MODULE_LICENSE("GPL" ); |
148 | |