Merge tag 'asoc-fix-v5.18-rc7' of https://git.kernel.org/pub/scm/linux/kernel/git...
[platform/kernel/linux-starfive.git] / drivers / clk / clk-gate_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Kunit test for clk gate basic type
4  */
5 #include <linux/clk.h>
6 #include <linux/clk-provider.h>
7 #include <linux/platform_device.h>
8
9 #include <kunit/test.h>
10
11 static void clk_gate_register_test_dev(struct kunit *test)
12 {
13         struct clk_hw *ret;
14         struct platform_device *pdev;
15
16         pdev = platform_device_register_simple("test_gate_device", -1, NULL, 0);
17         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
18
19         ret = clk_hw_register_gate(&pdev->dev, "test_gate", NULL, 0, NULL,
20                                    0, 0, NULL);
21         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
22         KUNIT_EXPECT_STREQ(test, "test_gate", clk_hw_get_name(ret));
23         KUNIT_EXPECT_EQ(test, 0UL, clk_hw_get_flags(ret));
24
25         clk_hw_unregister_gate(ret);
26         platform_device_put(pdev);
27 }
28
29 static void clk_gate_register_test_parent_names(struct kunit *test)
30 {
31         struct clk_hw *parent;
32         struct clk_hw *ret;
33
34         parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
35                                             1000000);
36         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
37
38         ret = clk_hw_register_gate(NULL, "test_gate", "test_parent", 0, NULL,
39                                    0, 0, NULL);
40         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
41         KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
42
43         clk_hw_unregister_gate(ret);
44         clk_hw_unregister_fixed_rate(parent);
45 }
46
47 static void clk_gate_register_test_parent_data(struct kunit *test)
48 {
49         struct clk_hw *parent;
50         struct clk_hw *ret;
51         struct clk_parent_data pdata = { };
52
53         parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
54                                             1000000);
55         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
56         pdata.hw = parent;
57
58         ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
59                                                NULL, 0, 0, NULL);
60         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
61         KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
62
63         clk_hw_unregister_gate(ret);
64         clk_hw_unregister_fixed_rate(parent);
65 }
66
67 static void clk_gate_register_test_parent_data_legacy(struct kunit *test)
68 {
69         struct clk_hw *parent;
70         struct clk_hw *ret;
71         struct clk_parent_data pdata = { };
72
73         parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
74                                             1000000);
75         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
76         pdata.name = "test_parent";
77
78         ret = clk_hw_register_gate_parent_data(NULL, "test_gate", &pdata, 0,
79                                                NULL, 0, 0, NULL);
80         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
81         KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
82
83         clk_hw_unregister_gate(ret);
84         clk_hw_unregister_fixed_rate(parent);
85 }
86
87 static void clk_gate_register_test_parent_hw(struct kunit *test)
88 {
89         struct clk_hw *parent;
90         struct clk_hw *ret;
91
92         parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
93                                             1000000);
94         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
95
96         ret = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0, NULL,
97                                              0, 0, NULL);
98         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ret);
99         KUNIT_EXPECT_PTR_EQ(test, parent, clk_hw_get_parent(ret));
100
101         clk_hw_unregister_gate(ret);
102         clk_hw_unregister_fixed_rate(parent);
103 }
104
105 static void clk_gate_register_test_hiword_invalid(struct kunit *test)
106 {
107         struct clk_hw *ret;
108
109         ret = clk_hw_register_gate(NULL, "test_gate", NULL, 0, NULL,
110                                    20, CLK_GATE_HIWORD_MASK, NULL);
111
112         KUNIT_EXPECT_TRUE(test, IS_ERR(ret));
113 }
114
115 static struct kunit_case clk_gate_register_test_cases[] = {
116         KUNIT_CASE(clk_gate_register_test_dev),
117         KUNIT_CASE(clk_gate_register_test_parent_names),
118         KUNIT_CASE(clk_gate_register_test_parent_data),
119         KUNIT_CASE(clk_gate_register_test_parent_data_legacy),
120         KUNIT_CASE(clk_gate_register_test_parent_hw),
121         KUNIT_CASE(clk_gate_register_test_hiword_invalid),
122         {}
123 };
124
125 static struct kunit_suite clk_gate_register_test_suite = {
126         .name = "clk-gate-register-test",
127         .test_cases = clk_gate_register_test_cases,
128 };
129
130 struct clk_gate_test_context {
131         void __iomem *fake_mem;
132         struct clk_hw *hw;
133         struct clk_hw *parent;
134         u32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
135 };
136
137 static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
138 {
139         struct clk_gate_test_context *ctx;
140
141         test->priv = ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
142         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
143         ctx->fake_mem = (void __force __iomem *)&ctx->fake_reg;
144
145         return ctx;
146 }
147
148 static void clk_gate_test_parent_rate(struct kunit *test)
149 {
150         struct clk_gate_test_context *ctx = test->priv;
151         struct clk_hw *parent = ctx->parent;
152         struct clk_hw *hw = ctx->hw;
153         unsigned long prate = clk_hw_get_rate(parent);
154         unsigned long rate = clk_hw_get_rate(hw);
155
156         KUNIT_EXPECT_EQ(test, prate, rate);
157 }
158
159 static void clk_gate_test_enable(struct kunit *test)
160 {
161         struct clk_gate_test_context *ctx = test->priv;
162         struct clk_hw *parent = ctx->parent;
163         struct clk_hw *hw = ctx->hw;
164         struct clk *clk = hw->clk;
165         u32 enable_val = BIT(5);
166
167         KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
168
169         KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
170         KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
171         KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
172         KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
173         KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
174 }
175
176 static void clk_gate_test_disable(struct kunit *test)
177 {
178         struct clk_gate_test_context *ctx = test->priv;
179         struct clk_hw *parent = ctx->parent;
180         struct clk_hw *hw = ctx->hw;
181         struct clk *clk = hw->clk;
182         u32 enable_val = BIT(5);
183         u32 disable_val = 0;
184
185         KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
186         KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
187
188         clk_disable_unprepare(clk);
189         KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
190         KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
191         KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
192         KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
193         KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
194 }
195
196 static struct kunit_case clk_gate_test_cases[] = {
197         KUNIT_CASE(clk_gate_test_parent_rate),
198         KUNIT_CASE(clk_gate_test_enable),
199         KUNIT_CASE(clk_gate_test_disable),
200         {}
201 };
202
203 static int clk_gate_test_init(struct kunit *test)
204 {
205         struct clk_hw *parent;
206         struct clk_hw *hw;
207         struct clk_gate_test_context *ctx;
208
209         ctx = clk_gate_test_alloc_ctx(test);
210         parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
211                                             2000000);
212         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
213
214         hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
215                                             ctx->fake_mem, 5, 0, NULL);
216         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
217
218         ctx->hw = hw;
219         ctx->parent = parent;
220
221         return 0;
222 }
223
224 static void clk_gate_test_exit(struct kunit *test)
225 {
226         struct clk_gate_test_context *ctx = test->priv;
227
228         clk_hw_unregister_gate(ctx->hw);
229         clk_hw_unregister_fixed_rate(ctx->parent);
230 }
231
232 static struct kunit_suite clk_gate_test_suite = {
233         .name = "clk-gate-test",
234         .init = clk_gate_test_init,
235         .exit = clk_gate_test_exit,
236         .test_cases = clk_gate_test_cases,
237 };
238
239 static void clk_gate_test_invert_enable(struct kunit *test)
240 {
241         struct clk_gate_test_context *ctx = test->priv;
242         struct clk_hw *parent = ctx->parent;
243         struct clk_hw *hw = ctx->hw;
244         struct clk *clk = hw->clk;
245         u32 enable_val = 0;
246
247         KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
248
249         KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
250         KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
251         KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
252         KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
253         KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
254 }
255
256 static void clk_gate_test_invert_disable(struct kunit *test)
257 {
258         struct clk_gate_test_context *ctx = test->priv;
259         struct clk_hw *parent = ctx->parent;
260         struct clk_hw *hw = ctx->hw;
261         struct clk *clk = hw->clk;
262         u32 enable_val = 0;
263         u32 disable_val = BIT(15);
264
265         KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
266         KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
267
268         clk_disable_unprepare(clk);
269         KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
270         KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
271         KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
272         KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
273         KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
274 }
275
276 static struct kunit_case clk_gate_test_invert_cases[] = {
277         KUNIT_CASE(clk_gate_test_invert_enable),
278         KUNIT_CASE(clk_gate_test_invert_disable),
279         {}
280 };
281
282 static int clk_gate_test_invert_init(struct kunit *test)
283 {
284         struct clk_hw *parent;
285         struct clk_hw *hw;
286         struct clk_gate_test_context *ctx;
287
288         ctx = clk_gate_test_alloc_ctx(test);
289         parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
290                                             2000000);
291         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
292
293         ctx->fake_reg = BIT(15); /* Default to off */
294         hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
295                                             ctx->fake_mem, 15,
296                                             CLK_GATE_SET_TO_DISABLE, NULL);
297         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
298
299         ctx->hw = hw;
300         ctx->parent = parent;
301
302         return 0;
303 }
304
305 static struct kunit_suite clk_gate_test_invert_suite = {
306         .name = "clk-gate-invert-test",
307         .init = clk_gate_test_invert_init,
308         .exit = clk_gate_test_exit,
309         .test_cases = clk_gate_test_invert_cases,
310 };
311
312 static void clk_gate_test_hiword_enable(struct kunit *test)
313 {
314         struct clk_gate_test_context *ctx = test->priv;
315         struct clk_hw *parent = ctx->parent;
316         struct clk_hw *hw = ctx->hw;
317         struct clk *clk = hw->clk;
318         u32 enable_val = BIT(9) | BIT(9 + 16);
319
320         KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
321
322         KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
323         KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
324         KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
325         KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
326         KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(parent));
327 }
328
329 static void clk_gate_test_hiword_disable(struct kunit *test)
330 {
331         struct clk_gate_test_context *ctx = test->priv;
332         struct clk_hw *parent = ctx->parent;
333         struct clk_hw *hw = ctx->hw;
334         struct clk *clk = hw->clk;
335         u32 enable_val = BIT(9) | BIT(9 + 16);
336         u32 disable_val = BIT(9 + 16);
337
338         KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
339         KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
340
341         clk_disable_unprepare(clk);
342         KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
343         KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
344         KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
345         KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
346         KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(parent));
347 }
348
349 static struct kunit_case clk_gate_test_hiword_cases[] = {
350         KUNIT_CASE(clk_gate_test_hiword_enable),
351         KUNIT_CASE(clk_gate_test_hiword_disable),
352         {}
353 };
354
355 static int clk_gate_test_hiword_init(struct kunit *test)
356 {
357         struct clk_hw *parent;
358         struct clk_hw *hw;
359         struct clk_gate_test_context *ctx;
360
361         ctx = clk_gate_test_alloc_ctx(test);
362         parent = clk_hw_register_fixed_rate(NULL, "test_parent", NULL, 0,
363                                             2000000);
364         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
365
366         hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
367                                             ctx->fake_mem, 9,
368                                             CLK_GATE_HIWORD_MASK, NULL);
369         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
370
371         ctx->hw = hw;
372         ctx->parent = parent;
373
374         return 0;
375 }
376
377 static struct kunit_suite clk_gate_test_hiword_suite = {
378         .name = "clk-gate-hiword-test",
379         .init = clk_gate_test_hiword_init,
380         .exit = clk_gate_test_exit,
381         .test_cases = clk_gate_test_hiword_cases,
382 };
383
384 static void clk_gate_test_is_enabled(struct kunit *test)
385 {
386         struct clk_hw *hw;
387         struct clk_gate_test_context *ctx;
388
389         ctx = clk_gate_test_alloc_ctx(test);
390         ctx->fake_reg = BIT(7);
391         hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
392                                   0, NULL);
393         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
394         KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
395
396         clk_hw_unregister_gate(hw);
397 }
398
399 static void clk_gate_test_is_disabled(struct kunit *test)
400 {
401         struct clk_hw *hw;
402         struct clk_gate_test_context *ctx;
403
404         ctx = clk_gate_test_alloc_ctx(test);
405         ctx->fake_reg = BIT(4);
406         hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
407                                   0, NULL);
408         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
409         KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
410
411         clk_hw_unregister_gate(hw);
412 }
413
414 static void clk_gate_test_is_enabled_inverted(struct kunit *test)
415 {
416         struct clk_hw *hw;
417         struct clk_gate_test_context *ctx;
418
419         ctx = clk_gate_test_alloc_ctx(test);
420         ctx->fake_reg = BIT(31);
421         hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 2,
422                                   CLK_GATE_SET_TO_DISABLE, NULL);
423         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
424         KUNIT_ASSERT_TRUE(test, clk_hw_is_enabled(hw));
425
426         clk_hw_unregister_gate(hw);
427 }
428
429 static void clk_gate_test_is_disabled_inverted(struct kunit *test)
430 {
431         struct clk_hw *hw;
432         struct clk_gate_test_context *ctx;
433
434         ctx = clk_gate_test_alloc_ctx(test);
435         ctx->fake_reg = BIT(29);
436         hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 29,
437                                   CLK_GATE_SET_TO_DISABLE, NULL);
438         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
439         KUNIT_ASSERT_FALSE(test, clk_hw_is_enabled(hw));
440
441         clk_hw_unregister_gate(hw);
442 }
443
444 static struct kunit_case clk_gate_test_enabled_cases[] = {
445         KUNIT_CASE(clk_gate_test_is_enabled),
446         KUNIT_CASE(clk_gate_test_is_disabled),
447         KUNIT_CASE(clk_gate_test_is_enabled_inverted),
448         KUNIT_CASE(clk_gate_test_is_disabled_inverted),
449         {}
450 };
451
452 static struct kunit_suite clk_gate_test_enabled_suite = {
453         .name = "clk-gate-is_enabled-test",
454         .test_cases = clk_gate_test_enabled_cases,
455 };
456
457 kunit_test_suites(
458         &clk_gate_register_test_suite,
459         &clk_gate_test_suite,
460         &clk_gate_test_invert_suite,
461         &clk_gate_test_hiword_suite,
462         &clk_gate_test_enabled_suite
463 );
464 MODULE_LICENSE("GPL v2");