Commit 86322f5982206f431ee4678a74182859c249aac4
Committed by
Simon Glass
1 parent
72e5016f87
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
dm: test: Add tests for the generic PHY uclass
Those tests check: - the ability for a phy-user to get a phy based on its name or its index - the ability of a phy device (provider) to manage multiple ports - the ability to perform operations on the phy (init,deinit,on,off) - the behavior of the uclass when optional operations are not implemented Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Showing 9 changed files with 253 additions and 0 deletions Side-by-side Diff
arch/sandbox/dts/test.dts
... | ... | @@ -59,6 +59,23 @@ |
59 | 59 | ping-add = <3>; |
60 | 60 | }; |
61 | 61 | |
62 | + phy_provider0: gen_phy@0 { | |
63 | + compatible = "sandbox,phy"; | |
64 | + #phy-cells = <1>; | |
65 | + }; | |
66 | + | |
67 | + phy_provider1: gen_phy@1 { | |
68 | + compatible = "sandbox,phy"; | |
69 | + #phy-cells = <0>; | |
70 | + broken; | |
71 | + }; | |
72 | + | |
73 | + gen_phy_user: gen_phy_user { | |
74 | + compatible = "simple-bus"; | |
75 | + phys = <&phy_provider0 0>, <&phy_provider0 1>, <&phy_provider1>; | |
76 | + phy-names = "phy1", "phy2", "phy3"; | |
77 | + }; | |
78 | + | |
62 | 79 | some-bus { |
63 | 80 | #address-cells = <1>; |
64 | 81 | #size-cells = <0>; |
configs/sandbox_defconfig
configs/sandbox_noblk_defconfig
configs/sandbox_spl_defconfig
drivers/phy/Kconfig
... | ... | @@ -33,5 +33,13 @@ |
33 | 33 | compatible as possible with the equivalent framework found in the |
34 | 34 | linux kernel. |
35 | 35 | |
36 | +config PHY_SANDBOX | |
37 | + bool "Sandbox PHY support" | |
38 | + depends on SANDBOX | |
39 | + depends on PHY | |
40 | + help | |
41 | + This select a dummy sandbox PHY driver. It used only to implement | |
42 | + the unit tests for the phy framework | |
43 | + | |
36 | 44 | endmenu |
drivers/phy/Makefile
drivers/phy/sandbox-phy.c
1 | +/* | |
2 | + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ | |
3 | + * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#include <common.h> | |
9 | +#include <dm.h> | |
10 | +#include <generic-phy.h> | |
11 | + | |
12 | +DECLARE_GLOBAL_DATA_PTR; | |
13 | + | |
14 | +struct sandbox_phy_priv { | |
15 | + bool initialized; | |
16 | + bool on; | |
17 | + bool broken; | |
18 | +}; | |
19 | + | |
20 | +static int sandbox_phy_power_on(struct phy *phy) | |
21 | +{ | |
22 | + struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); | |
23 | + | |
24 | + if (!priv->initialized) | |
25 | + return -EIO; | |
26 | + | |
27 | + if (priv->broken) | |
28 | + return -EIO; | |
29 | + | |
30 | + priv->on = true; | |
31 | + | |
32 | + return 0; | |
33 | +} | |
34 | + | |
35 | +static int sandbox_phy_power_off(struct phy *phy) | |
36 | +{ | |
37 | + struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); | |
38 | + | |
39 | + if (!priv->initialized) | |
40 | + return -EIO; | |
41 | + | |
42 | + if (priv->broken) | |
43 | + return -EIO; | |
44 | + | |
45 | + /* | |
46 | + * for validation purpose, let's says that power off | |
47 | + * works only for PHY 0 | |
48 | + */ | |
49 | + if (phy->id) | |
50 | + return -EIO; | |
51 | + | |
52 | + priv->on = false; | |
53 | + | |
54 | + return 0; | |
55 | +} | |
56 | + | |
57 | +static int sandbox_phy_init(struct phy *phy) | |
58 | +{ | |
59 | + struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); | |
60 | + | |
61 | + priv->initialized = true; | |
62 | + priv->on = true; | |
63 | + | |
64 | + return 0; | |
65 | +} | |
66 | + | |
67 | +static int sandbox_phy_exit(struct phy *phy) | |
68 | +{ | |
69 | + struct sandbox_phy_priv *priv = dev_get_priv(phy->dev); | |
70 | + | |
71 | + priv->initialized = false; | |
72 | + priv->on = false; | |
73 | + | |
74 | + return 0; | |
75 | +} | |
76 | + | |
77 | +static int sandbox_phy_probe(struct udevice *dev) | |
78 | +{ | |
79 | + struct sandbox_phy_priv *priv = dev_get_priv(dev); | |
80 | + | |
81 | + priv->initialized = false; | |
82 | + priv->on = false; | |
83 | + priv->broken = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), | |
84 | + "broken"); | |
85 | + | |
86 | + return 0; | |
87 | +} | |
88 | + | |
89 | +static struct phy_ops sandbox_phy_ops = { | |
90 | + .power_on = sandbox_phy_power_on, | |
91 | + .power_off = sandbox_phy_power_off, | |
92 | + .init = sandbox_phy_init, | |
93 | + .exit = sandbox_phy_exit, | |
94 | +}; | |
95 | + | |
96 | +static const struct udevice_id sandbox_phy_ids[] = { | |
97 | + { .compatible = "sandbox,phy" }, | |
98 | + { } | |
99 | +}; | |
100 | + | |
101 | +U_BOOT_DRIVER(phy_sandbox) = { | |
102 | + .name = "phy_sandbox", | |
103 | + .id = UCLASS_PHY, | |
104 | + .of_match = sandbox_phy_ids, | |
105 | + .ops = &sandbox_phy_ops, | |
106 | + .probe = sandbox_phy_probe, | |
107 | + .priv_auto_alloc_size = sizeof(struct sandbox_phy_priv), | |
108 | +}; |
test/dm/Makefile
test/dm/phy.c
1 | +/* | |
2 | + * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ | |
3 | + * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> | |
4 | + * | |
5 | + * SPDX-License-Identifier: GPL-2.0+ | |
6 | + */ | |
7 | + | |
8 | +#include <common.h> | |
9 | +#include <dm.h> | |
10 | +#include <generic-phy.h> | |
11 | +#include <dm/test.h> | |
12 | +#include <test/ut.h> | |
13 | + | |
14 | +DECLARE_GLOBAL_DATA_PTR; | |
15 | + | |
16 | +/* Base test of the phy uclass */ | |
17 | +static int dm_test_phy_base(struct unit_test_state *uts) | |
18 | +{ | |
19 | + struct udevice *dev; | |
20 | + struct phy phy1_method1; | |
21 | + struct phy phy1_method2; | |
22 | + struct phy phy2; | |
23 | + struct phy phy3; | |
24 | + struct udevice *parent; | |
25 | + | |
26 | + /* Get the device using the phy device*/ | |
27 | + ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS, | |
28 | + "gen_phy_user", &parent)); | |
29 | + /* | |
30 | + * Get the same phy port in 2 different ways and compare. | |
31 | + */ | |
32 | + ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1)) | |
33 | + ut_assertok(generic_phy_get_by_index(parent, 0, &phy1_method2)) | |
34 | + ut_asserteq(phy1_method1.id, phy1_method2.id); | |
35 | + | |
36 | + /* | |
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 | |
39 | + */ | |
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); | |
43 | + | |
44 | + /* | |
45 | + * Get the third phy port. Check that the phy provider is different | |
46 | + */ | |
47 | + ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3)) | |
48 | + ut_assert(phy2.dev != phy3.dev); | |
49 | + | |
50 | + /* Try to get a non-existing phy */ | |
51 | + ut_asserteq(-ENODEV, uclass_get_device(UCLASS_PHY, 3, &dev)); | |
52 | + ut_assert(generic_phy_get_by_name(parent, "phy_not_existing", | |
53 | + &phy1_method1) < 0) | |
54 | + | |
55 | + return 0; | |
56 | +} | |
57 | +DM_TEST(dm_test_phy_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); | |
58 | + | |
59 | +/* Test of the phy uclass using the sandbox phy driver operations */ | |
60 | +static int dm_test_phy_ops(struct unit_test_state *uts) | |
61 | +{ | |
62 | + struct phy phy1; | |
63 | + struct phy phy2; | |
64 | + struct phy phy3; | |
65 | + struct udevice *parent; | |
66 | + | |
67 | + ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS, | |
68 | + "gen_phy_user", &parent)); | |
69 | + | |
70 | + ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1)); | |
71 | + ut_assertok(generic_phy_get_by_name(parent, "phy2", &phy2)); | |
72 | + ut_assertok(generic_phy_get_by_name(parent, "phy3", &phy3)); | |
73 | + | |
74 | + /* test normal operations */ | |
75 | + ut_assertok(generic_phy_init(&phy1)); | |
76 | + ut_assertok(generic_phy_power_on(&phy1)); | |
77 | + ut_assertok(generic_phy_power_off(&phy1)); | |
78 | + | |
79 | + /* | |
80 | + * test operations after exit(). | |
81 | + * The sandbox phy driver does not allow it. | |
82 | + */ | |
83 | + ut_assertok(generic_phy_exit(&phy1)); | |
84 | + ut_assert(generic_phy_power_on(&phy1) != 0); | |
85 | + ut_assert(generic_phy_power_off(&phy1) != 0); | |
86 | + | |
87 | + /* | |
88 | + * test normal operations again (after re-init) | |
89 | + */ | |
90 | + ut_assertok(generic_phy_init(&phy1)); | |
91 | + ut_assertok(generic_phy_power_on(&phy1)); | |
92 | + ut_assertok(generic_phy_power_off(&phy1)); | |
93 | + | |
94 | + /* | |
95 | + * test calling unimplemented feature. | |
96 | + * The call is expected to succeed | |
97 | + */ | |
98 | + ut_assertok(generic_phy_reset(&phy1)); | |
99 | + | |
100 | + /* PHY2 has a known problem with power off */ | |
101 | + ut_assertok(generic_phy_init(&phy2)); | |
102 | + ut_assertok(generic_phy_power_on(&phy2)); | |
103 | + ut_assert(generic_phy_power_off(&phy2) == -EIO); | |
104 | + | |
105 | + /* PHY3 has a known problem with power off and power on*/ | |
106 | + ut_assertok(generic_phy_init(&phy3)); | |
107 | + ut_assert(generic_phy_power_off(&phy3) == -EIO); | |
108 | + ut_assert(generic_phy_power_off(&phy3) == -EIO); | |
109 | + | |
110 | + return 0; | |
111 | +} | |
112 | +DM_TEST(dm_test_phy_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); |