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