1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020, Linaro Limited
4  *
5  * Tests scmi_agent uclass and the SCMI drivers implemented in other
6  * uclass devices probe when a SCMI server exposes resources.
7  *
8  * Note in test.dts the protocol@10 node in agent 1. Protocol 0x10 is not
9  * implemented in U-Boot SCMI components but the implementation is exepected
10  * to not complain on unknown protocol IDs, as long as it is not used. Note
11  * in test.dts tests that SCMI drivers probing does not fail for such an
12  * unknown SCMI protocol ID.
13  */
14 
15 #include <common.h>
16 #include <clk.h>
17 #include <dm.h>
18 #include <reset.h>
19 #include <asm/scmi_test.h>
20 #include <dm/device-internal.h>
21 #include <dm/test.h>
22 #include <linux/kconfig.h>
23 #include <test/ut.h>
24 
ut_assert_scmi_state_preprobe(struct unit_test_state * uts)25 static int ut_assert_scmi_state_preprobe(struct unit_test_state *uts)
26 {
27 	struct sandbox_scmi_service *scmi_ctx = sandbox_scmi_service_ctx();
28 
29 	ut_assertnonnull(scmi_ctx);
30 	if (scmi_ctx->agent_count)
31 		ut_asserteq(2, scmi_ctx->agent_count);
32 
33 	return 0;
34 }
35 
ut_assert_scmi_state_postprobe(struct unit_test_state * uts,struct udevice * dev)36 static int ut_assert_scmi_state_postprobe(struct unit_test_state *uts,
37 					  struct udevice *dev)
38 {
39 	struct sandbox_scmi_devices *scmi_devices;
40 	struct sandbox_scmi_service *scmi_ctx;
41 
42 	/* Device references to check context against test sequence */
43 	scmi_devices = sandbox_scmi_devices_ctx(dev);
44 
45 	ut_assertnonnull(scmi_devices);
46 	if (IS_ENABLED(CONFIG_CLK_SCMI))
47 		ut_asserteq(3, scmi_devices->clk_count);
48 	if (IS_ENABLED(CONFIG_RESET_SCMI))
49 		ut_asserteq(1, scmi_devices->reset_count);
50 
51 	/* State of the simulated SCMI server exposed */
52 	scmi_ctx = sandbox_scmi_service_ctx();
53 
54 	ut_asserteq(2, scmi_ctx->agent_count);
55 
56 	ut_assertnonnull(scmi_ctx->agent[0]);
57 	ut_asserteq(2, scmi_ctx->agent[0]->clk_count);
58 	ut_assertnonnull(scmi_ctx->agent[0]->clk);
59 	ut_asserteq(1, scmi_ctx->agent[0]->reset_count);
60 	ut_assertnonnull(scmi_ctx->agent[0]->reset);
61 
62 	ut_assertnonnull(scmi_ctx->agent[1]);
63 	ut_assertnonnull(scmi_ctx->agent[1]->clk);
64 	ut_asserteq(1, scmi_ctx->agent[1]->clk_count);
65 
66 	return 0;
67 }
68 
load_sandbox_scmi_test_devices(struct unit_test_state * uts,struct udevice ** dev)69 static int load_sandbox_scmi_test_devices(struct unit_test_state *uts,
70 					  struct udevice **dev)
71 {
72 	int ret;
73 
74 	ret = ut_assert_scmi_state_preprobe(uts);
75 	if (ret)
76 		return ret;
77 
78 	ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "sandbox_scmi",
79 					      dev));
80 	ut_assertnonnull(*dev);
81 
82 	return ut_assert_scmi_state_postprobe(uts, *dev);
83 }
84 
release_sandbox_scmi_test_devices(struct unit_test_state * uts,struct udevice * dev)85 static int release_sandbox_scmi_test_devices(struct unit_test_state *uts,
86 					     struct udevice *dev)
87 {
88 	ut_assertok(device_remove(dev, DM_REMOVE_NORMAL));
89 
90 	/* Not sure test devices are fully removed, agent may not be visible */
91 	return 0;
92 }
93 
94 /*
95  * Test SCMI states when loading and releasing resources
96  * related to SCMI drivers.
97  */
dm_test_scmi_sandbox_agent(struct unit_test_state * uts)98 static int dm_test_scmi_sandbox_agent(struct unit_test_state *uts)
99 {
100 	struct udevice *dev = NULL;
101 	int ret;
102 
103 	ret = load_sandbox_scmi_test_devices(uts, &dev);
104 	if (!ret)
105 		ret = release_sandbox_scmi_test_devices(uts, dev);
106 
107 	return ret;
108 }
109 
110 DM_TEST(dm_test_scmi_sandbox_agent, UT_TESTF_SCAN_FDT);
111 
dm_test_scmi_clocks(struct unit_test_state * uts)112 static int dm_test_scmi_clocks(struct unit_test_state *uts)
113 {
114 	struct sandbox_scmi_devices *scmi_devices;
115 	struct sandbox_scmi_service *scmi_ctx;
116 	struct udevice *dev = NULL;
117 	int ret_dev;
118 	int ret;
119 
120 	if (!IS_ENABLED(CONFIG_CLK_SCMI))
121 		return 0;
122 
123 	ret = load_sandbox_scmi_test_devices(uts, &dev);
124 	if (ret)
125 		return ret;
126 
127 	scmi_devices = sandbox_scmi_devices_ctx(dev);
128 	scmi_ctx = sandbox_scmi_service_ctx();
129 
130 	/* Test SCMI clocks rate manipulation */
131 	ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
132 	ut_asserteq(333, clk_get_rate(&scmi_devices->clk[1]));
133 	ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2]));
134 
135 	ret_dev = clk_set_rate(&scmi_devices->clk[1], 1088);
136 	ut_assert(!ret_dev || ret_dev == 1088);
137 
138 	ut_asserteq(1000, scmi_ctx->agent[0]->clk[0].rate);
139 	ut_asserteq(1088, scmi_ctx->agent[0]->clk[1].rate);
140 	ut_asserteq(44, scmi_ctx->agent[1]->clk[0].rate);
141 
142 	ut_asserteq(1000, clk_get_rate(&scmi_devices->clk[0]));
143 	ut_asserteq(1088, clk_get_rate(&scmi_devices->clk[1]));
144 	ut_asserteq(44, clk_get_rate(&scmi_devices->clk[2]));
145 
146 	/* restore original rate for further tests */
147 	ret_dev = clk_set_rate(&scmi_devices->clk[1], 333);
148 	ut_assert(!ret_dev || ret_dev == 333);
149 
150 	/* Test SCMI clocks gating manipulation */
151 	ut_assert(!scmi_ctx->agent[0]->clk[0].enabled);
152 	ut_assert(!scmi_ctx->agent[0]->clk[1].enabled);
153 	ut_assert(!scmi_ctx->agent[1]->clk[0].enabled);
154 
155 	ut_asserteq(0, clk_enable(&scmi_devices->clk[1]));
156 	ut_asserteq(0, clk_enable(&scmi_devices->clk[2]));
157 
158 	ut_assert(!scmi_ctx->agent[0]->clk[0].enabled);
159 	ut_assert(scmi_ctx->agent[0]->clk[1].enabled);
160 	ut_assert(scmi_ctx->agent[1]->clk[0].enabled);
161 
162 	ut_assertok(clk_disable(&scmi_devices->clk[1]));
163 	ut_assertok(clk_disable(&scmi_devices->clk[2]));
164 
165 	ut_assert(!scmi_ctx->agent[0]->clk[0].enabled);
166 	ut_assert(!scmi_ctx->agent[0]->clk[1].enabled);
167 	ut_assert(!scmi_ctx->agent[1]->clk[0].enabled);
168 
169 	return release_sandbox_scmi_test_devices(uts, dev);
170 }
171 
172 DM_TEST(dm_test_scmi_clocks, UT_TESTF_SCAN_FDT);
173 
dm_test_scmi_resets(struct unit_test_state * uts)174 static int dm_test_scmi_resets(struct unit_test_state *uts)
175 {
176 	struct sandbox_scmi_devices *scmi_devices;
177 	struct sandbox_scmi_service *scmi_ctx;
178 	struct udevice *dev = NULL;
179 	int ret;
180 
181 	if (!IS_ENABLED(CONFIG_RESET_SCMI))
182 		return 0;
183 
184 	ret = load_sandbox_scmi_test_devices(uts, &dev);
185 	if (ret)
186 		return ret;
187 
188 	scmi_devices = sandbox_scmi_devices_ctx(dev);
189 	scmi_ctx = sandbox_scmi_service_ctx();
190 
191 	/* Test SCMI resect controller manipulation */
192 	ut_assert(!scmi_ctx->agent[0]->reset[0].asserted)
193 
194 	ut_assertok(reset_assert(&scmi_devices->reset[0]));
195 	ut_assert(scmi_ctx->agent[0]->reset[0].asserted)
196 
197 	ut_assertok(reset_deassert(&scmi_devices->reset[0]));
198 	ut_assert(!scmi_ctx->agent[0]->reset[0].asserted);
199 
200 	return release_sandbox_scmi_test_devices(uts, dev);
201 }
202 
203 DM_TEST(dm_test_scmi_resets, UT_TESTF_SCAN_FDT);
204