1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
8 #include <generic-phy.h>
11 #include <test/test.h>
14 /* Base test of the phy uclass */
15 static int dm_test_phy_base(struct unit_test_state *uts)
18 struct phy phy1_method1;
19 struct phy phy1_method2;
22 struct udevice *parent;
24 /* Get the device using the phy device*/
25 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
26 "gen_phy_user", &parent));
28 * Get the same phy port in 2 different ways and compare.
30 ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1));
31 ut_assert(generic_phy_valid(&phy1_method1));
32 ut_assertok(generic_phy_get_by_index(parent, 0, &phy1_method2));
33 ut_assert(generic_phy_valid(&phy1_method2));
34 ut_asserteq(phy1_method1.id, phy1_method2.id);
37 * Get the second phy port. Check that the same phy provider (device)
38 * provides this 2nd phy port, but that the IDs are different
40 ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2));
41 ut_asserteq_ptr(phy1_method2.dev, phy2.dev);
42 ut_assert(phy1_method1.id != phy2.id);
45 * Get the third phy port. Check that the phy provider is different
47 ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3));
48 ut_assert(phy2.dev != phy3.dev);
50 /* Try to get a non-existing phy */
51 ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PHY, 5, &dev));
52 ut_asserteq(-ENODATA, generic_phy_get_by_name(parent,
53 "phy_not_existing", &phy1_method1));
54 ut_assert(!generic_phy_valid(&phy1_method1));
55 ut_asserteq(-ENOENT, generic_phy_get_by_index(parent, 3,
57 ut_assert(!generic_phy_valid(&phy1_method2));
59 /* Try to get a phy where of_xlate fail */
60 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
61 "gen_phy_user2", &parent));
62 ut_asserteq(-EINVAL, generic_phy_get_by_name(parent, "phy1",
64 ut_assert(!generic_phy_valid(&phy1_method1));
65 ut_asserteq(-EINVAL, generic_phy_get_by_index(parent, 0,
67 ut_assert(!generic_phy_valid(&phy1_method2));
71 DM_TEST(dm_test_phy_base, UTF_SCAN_PDATA | UTF_SCAN_FDT);
73 /* Test of the phy uclass using the sandbox phy driver operations */
74 static int dm_test_phy_ops(struct unit_test_state *uts)
79 struct udevice *parent;
81 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
82 "gen_phy_user", &parent));
84 ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1));
85 ut_asserteq(0, phy1.id);
86 ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2));
87 ut_asserteq(1, phy2.id);
88 ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3));
89 ut_asserteq(0, phy3.id);
91 /* test normal operations */
92 ut_assertok(generic_phy_init(&phy1));
93 ut_assertok(generic_phy_power_on(&phy1));
94 ut_assertok(generic_phy_power_off(&phy1));
97 * Test power_on() failure after exit().
98 * The sandbox phy driver does not allow power-on/off after
99 * exit, but the uclass counts power-on/init calls and skips
100 * calling the driver's ops when e.g. powering off an already
103 ut_assertok(generic_phy_exit(&phy1));
104 ut_assert(generic_phy_power_on(&phy1) != 0);
105 ut_assertok(generic_phy_power_off(&phy1));
108 * test normal operations again (after re-init)
110 ut_assertok(generic_phy_init(&phy1));
111 ut_assertok(generic_phy_power_on(&phy1));
112 ut_assertok(generic_phy_power_off(&phy1));
115 * test calling unimplemented feature.
116 * The call is expected to succeed
118 ut_assertok(generic_phy_reset(&phy1));
121 * Test power_off() failure after exit().
122 * For this we need to call exit() while the phy is powered-on,
123 * so that the uclass actually calls the driver's power-off()
124 * and reports the resulting failure.
126 ut_assertok(generic_phy_power_on(&phy1));
127 ut_assertok(generic_phy_exit(&phy1));
128 ut_assert(generic_phy_power_off(&phy1) != 0);
129 ut_assertok(generic_phy_power_on(&phy1));
131 /* PHY2 has a known problem with power off */
132 ut_assertok(generic_phy_init(&phy2));
133 ut_assertok(generic_phy_power_on(&phy2));
134 ut_asserteq(-EIO, generic_phy_power_off(&phy2));
136 /* PHY3 has a known problem with power off and power on */
137 ut_assertok(generic_phy_init(&phy3));
138 ut_asserteq(-EIO, generic_phy_power_on(&phy3));
139 ut_assertok(generic_phy_power_off(&phy3));
143 DM_TEST(dm_test_phy_ops, UTF_SCAN_PDATA | UTF_SCAN_FDT);
145 static int dm_test_phy_bulk(struct unit_test_state *uts)
147 struct phy_bulk phys;
148 struct udevice *parent;
150 /* test normal operations */
151 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
152 "gen_phy_user1", &parent));
154 ut_assertok(generic_phy_get_bulk(parent, &phys));
155 ut_asserteq(2, phys.count);
157 ut_asserteq(0, generic_phy_init_bulk(&phys));
158 ut_asserteq(0, generic_phy_power_on_bulk(&phys));
159 ut_asserteq(0, generic_phy_power_off_bulk(&phys));
160 ut_asserteq(0, generic_phy_exit_bulk(&phys));
162 /* has a known problem phy */
163 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
164 "gen_phy_user", &parent));
166 ut_assertok(generic_phy_get_bulk(parent, &phys));
167 ut_asserteq(3, phys.count);
169 ut_asserteq(0, generic_phy_init_bulk(&phys));
170 ut_asserteq(-EIO, generic_phy_power_on_bulk(&phys));
171 ut_asserteq(-EIO, generic_phy_power_off_bulk(&phys));
172 ut_asserteq(0, generic_phy_exit_bulk(&phys));
176 DM_TEST(dm_test_phy_bulk, UTF_SCAN_PDATA | UTF_SCAN_FDT);
178 static int dm_test_phy_multi_exit(struct unit_test_state *uts)
180 struct phy phy1_method1;
181 struct phy phy1_method2;
182 struct phy phy1_method3;
183 struct udevice *parent;
185 /* Get the same phy instance in 3 different ways. */
186 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
187 "gen_phy_user", &parent));
188 ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1));
189 ut_asserteq(0, phy1_method1.id);
190 ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method2));
191 ut_asserteq(0, phy1_method2.id);
192 ut_asserteq_ptr(phy1_method1.dev, phy1_method1.dev);
194 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
195 "gen_phy_user1", &parent));
196 ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method3));
197 ut_asserteq(0, phy1_method3.id);
198 ut_asserteq_ptr(phy1_method1.dev, phy1_method3.dev);
201 * Test using the same PHY from different handles.
202 * In non-test code these could be in different drivers.
206 * These must only call the driver's ops at the first init()
209 ut_assertok(generic_phy_init(&phy1_method1));
210 ut_assertok(generic_phy_init(&phy1_method2));
211 ut_assertok(generic_phy_power_on(&phy1_method1));
212 ut_assertok(generic_phy_power_on(&phy1_method2));
213 ut_assertok(generic_phy_init(&phy1_method3));
214 ut_assertok(generic_phy_power_on(&phy1_method3));
217 * These must not call the driver's ops as other handles still
218 * want the PHY powered-on and initialized.
220 ut_assertok(generic_phy_power_off(&phy1_method3));
221 ut_assertok(generic_phy_exit(&phy1_method3));
224 * We would get an error here if the generic_phy_exit() above
225 * actually called the driver's exit(), as the sandbox driver
226 * doesn't allow power-off() after exit().
228 ut_assertok(generic_phy_power_off(&phy1_method1));
229 ut_assertok(generic_phy_power_off(&phy1_method2));
230 ut_assertok(generic_phy_exit(&phy1_method1));
231 ut_assertok(generic_phy_exit(&phy1_method2));
235 DM_TEST(dm_test_phy_multi_exit, UTF_SCAN_PDATA | UTF_SCAN_FDT);
237 static int dm_test_phy_setup(struct unit_test_state *uts)
240 struct udevice *parent;
242 ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS,
243 "gen_phy_user", &parent));
246 ut_assertok(generic_setup_phy(parent, &phy, 0, PHY_MODE_USB_HOST, 0));
247 ut_assertok(generic_shutdown_phy(&phy));
249 /* set_mode as USB Host passes, anything else is not supported */
250 ut_assertok(generic_setup_phy(parent, &phy, 0, PHY_MODE_USB_HOST, 0));
251 ut_assertok(generic_phy_set_mode(&phy, PHY_MODE_USB_HOST, 0));
252 ut_asserteq(-EOPNOTSUPP, generic_phy_set_mode(&phy, PHY_MODE_USB_HOST, 1));
253 ut_asserteq(-EINVAL, generic_phy_set_mode(&phy, PHY_MODE_USB_DEVICE, 0));
254 ut_assertok(generic_shutdown_phy(&phy));
256 /* power_off fail with -EIO */
257 ut_assertok(generic_setup_phy(parent, &phy, 1, PHY_MODE_USB_HOST, 0));
258 ut_asserteq(-EIO, generic_shutdown_phy(&phy));
260 /* power_on fail with -EIO */
261 ut_asserteq(-EIO, generic_setup_phy(parent, &phy, 2, PHY_MODE_USB_HOST, 0));
262 ut_assertok(generic_shutdown_phy(&phy));
264 /* generic_phy_get_by_index fail with -ENOENT */
265 ut_asserteq(-ENOENT, generic_phy_get_by_index(parent, 3, &phy));
266 ut_assertok(generic_setup_phy(parent, &phy, 3, PHY_MODE_USB_HOST, 0));
267 ut_assertok(generic_shutdown_phy(&phy));
271 DM_TEST(dm_test_phy_setup, UTF_SCAN_PDATA | UTF_SCAN_FDT);