1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019
4 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
5 */
6
7#include <clk.h>
8#include <dm.h>
9#include <asm/clk.h>
10#include <dm/test.h>
11#include <dm/uclass.h>
12#include <linux/err.h>
13#include <test/test.h>
14#include <test/ut.h>
15#include <sandbox-clk.h>
16
17/* Tests for Common Clock Framework driver */
18static int dm_test_clk_ccf(struct unit_test_state *uts)
19{
20	struct clk *clk, *pclk;
21	struct udevice *dev, *test_dev;
22	long long rate;
23	int ret;
24#if CONFIG_IS_ENABLED(CLK_CCF)
25	struct clk clk_ccf;
26	const char *clkname;
27	int clkid, i;
28#endif
29
30	/* Get the device using the clk device */
31	ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", &dev));
32	ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "clk-test", &test_dev));
33
34	/* Test for clk_get_by_id() */
35	ret = clk_get_by_id(SANDBOX_CLK_ECSPI_ROOT, &clk);
36	ut_assertok(ret);
37	ut_asserteq_str("ecspi_root", clk->dev->name);
38	ut_asserteq(CLK_SET_RATE_PARENT, clk->flags);
39
40	/* Test for clk_get_parent_rate() */
41	ret = clk_get_by_id(SANDBOX_CLK_ECSPI1, &clk);
42	ut_assertok(ret);
43	ut_asserteq_str("ecspi1", clk->dev->name);
44	ut_asserteq(CLK_SET_RATE_PARENT, clk->flags);
45
46	rate = clk_get_parent_rate(clk);
47	ut_asserteq(rate, 20000000);
48
49	/* test the gate of CCF */
50	ret = clk_get_by_id(SANDBOX_CLK_ECSPI0, &clk);
51	ut_assertok(ret);
52	ut_asserteq_str("ecspi0", clk->dev->name);
53	ut_asserteq(CLK_SET_RATE_PARENT, clk->flags);
54
55	rate = clk_get_parent_rate(clk);
56	ut_asserteq(rate, 20000000);
57
58	/* Test the mux of CCF */
59	ret = clk_get_by_id(SANDBOX_CLK_USDHC1_SEL, &clk);
60	ut_assertok(ret);
61	ut_asserteq_str("usdhc1_sel", clk->dev->name);
62	ut_asserteq(CLK_SET_RATE_NO_REPARENT, clk->flags);
63
64	rate = clk_get_parent_rate(clk);
65	ut_asserteq(rate, 60000000);
66
67	rate = clk_set_rate(clk, 60000000);
68	ut_asserteq(rate, -ENOSYS);
69
70	rate = clk_get_rate(clk);
71	ut_asserteq(rate, 60000000);
72
73	ret = clk_get_by_id(SANDBOX_CLK_PLL3_80M, &pclk);
74	ut_assertok(ret);
75
76	ret = clk_set_parent(clk, pclk);
77	ut_assertok(ret);
78
79	rate = clk_get_rate(clk);
80	ut_asserteq(rate, 80000000);
81
82	ret = clk_get_by_id(SANDBOX_CLK_USDHC2_SEL, &clk);
83	ut_assertok(ret);
84	ut_asserteq_str("usdhc2_sel", clk->dev->name);
85	ut_asserteq(CLK_SET_RATE_NO_REPARENT, clk->flags);
86
87	rate = clk_get_parent_rate(clk);
88	ut_asserteq(rate, 80000000);
89
90	pclk = clk_get_parent(clk);
91	ut_asserteq_str("pll3_80m", pclk->dev->name);
92	ut_asserteq(CLK_SET_RATE_PARENT, pclk->flags);
93
94	rate = clk_set_rate(clk, 80000000);
95	ut_asserteq(rate, -ENOSYS);
96
97	rate = clk_get_rate(clk);
98	ut_asserteq(rate, 80000000);
99
100	ret = clk_get_by_id(SANDBOX_CLK_PLL3_60M, &pclk);
101	ut_assertok(ret);
102
103	ret = clk_set_parent(clk, pclk);
104	ut_assertok(ret);
105
106	rate = clk_get_rate(clk);
107	ut_asserteq(rate, 60000000);
108
109	/* Test the composite of CCF */
110	ret = clk_get_by_id(SANDBOX_CLK_I2C, &clk);
111	ut_assertok(ret);
112	ut_asserteq_str("i2c", clk->dev->name);
113	ut_asserteq(CLK_SET_RATE_UNGATE, clk->flags);
114
115	rate = clk_get_rate(clk);
116	ut_asserteq(rate, 60000000);
117
118	rate = clk_set_rate(clk, 60000000);
119	ut_asserteq(rate, 60000000);
120
121#if CONFIG_IS_ENABLED(CLK_CCF)
122	/* Test clk tree enable/disable */
123
124	ret = clk_get_by_index(test_dev, SANDBOX_CLK_TEST_ID_I2C_ROOT, &clk_ccf);
125	ut_assertok(ret);
126	ut_asserteq_str("clk-ccf", clk_ccf.dev->name);
127	ut_asserteq(clk_ccf.id, SANDBOX_CLK_I2C_ROOT);
128
129	ret = clk_get_by_id(SANDBOX_CLK_I2C_ROOT, &clk);
130	ut_assertok(ret);
131	ut_asserteq_str("i2c_root", clk->dev->name);
132	ut_asserteq(clk->id, SANDBOX_CLK_I2C_ROOT);
133
134	ret = clk_enable(&clk_ccf);
135	ut_assertok(ret);
136
137	ret = sandbox_clk_enable_count(clk);
138	ut_asserteq(ret, 1);
139
140	ret = clk_get_by_id(SANDBOX_CLK_I2C, &pclk);
141	ut_assertok(ret);
142
143	ret = sandbox_clk_enable_count(pclk);
144	ut_asserteq(ret, 1);
145
146	ret = clk_disable(clk);
147	ut_assertok(ret);
148
149	ret = sandbox_clk_enable_count(clk);
150	ut_asserteq(ret, 0);
151
152	ret = sandbox_clk_enable_count(pclk);
153	ut_asserteq(ret, 0);
154
155	/* Test clock re-parenting. */
156	ret = clk_get_by_id(SANDBOX_CLK_USDHC1_SEL, &clk);
157	ut_assertok(ret);
158	ut_asserteq_str("usdhc1_sel", clk->dev->name);
159
160	pclk = clk_get_parent(clk);
161	ut_assertok_ptr(pclk);
162	if (!strcmp(pclk->dev->name, "pll3_60m")) {
163		clkname = "pll3_80m";
164		clkid = SANDBOX_CLK_PLL3_80M;
165	} else {
166		clkname = "pll3_60m";
167		clkid = SANDBOX_CLK_PLL3_60M;
168	}
169
170	ret = clk_get_by_id(clkid, &pclk);
171	ut_assertok(ret);
172	ret = clk_set_parent(clk, pclk);
173	ut_assertok(ret);
174	pclk = clk_get_parent(clk);
175	ut_assertok_ptr(pclk);
176	ut_asserteq_str(clkname, pclk->dev->name);
177
178	/* Test disabling critical clock. */
179	ret = clk_get_by_id(SANDBOX_CLK_I2C_ROOT, &clk);
180	ut_assertok(ret);
181	ut_asserteq_str("i2c_root", clk->dev->name);
182
183	/* Disable it, if any. */
184	ret = sandbox_clk_enable_count(clk);
185	for (i = 0; i < ret; i++) {
186		ret = clk_disable(clk);
187		ut_assertok(ret);
188	}
189
190	ret = sandbox_clk_enable_count(clk);
191	ut_asserteq(ret, 0);
192
193	clk->flags = CLK_IS_CRITICAL;
194	ret = clk_enable(clk);
195	ut_assertok(ret);
196
197	ret = clk_disable(clk);
198	ut_assertok(ret);
199	ret = sandbox_clk_enable_count(clk);
200	ut_asserteq(ret, 1);
201	clk->flags &= ~CLK_IS_CRITICAL;
202
203	ret = clk_disable(clk);
204	ut_assertok(ret);
205	ret = sandbox_clk_enable_count(clk);
206	ut_asserteq(ret, 0);
207#endif
208
209	return 1;
210}
211
212DM_TEST(dm_test_clk_ccf, UT_TESTF_SCAN_FDT);
213