1 /*
2 * Copyright (c) 2025 Google LLC.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/reset.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/ztest.h>
11
12 ZTEST_SUITE(reset_mmio_tests, NULL, NULL, NULL, NULL, NULL);
13
14 #define RESET_MAX_NUM 16
15
check_status(const struct device * dev,uint32_t base,uint32_t id,bool expected_state,bool active_low)16 void check_status(const struct device *dev, uint32_t base, uint32_t id, bool expected_state,
17 bool active_low)
18 {
19 uint8_t actual_state;
20
21 zassert_ok(reset_status(dev, id, &actual_state), "Failed getting reset state");
22 zassert_equal(actual_state, expected_state,
23 "reset state %u doesn't match expected state %u", actual_state,
24 expected_state);
25 zassert_equal(FIELD_GET(BIT(id), sys_read32(base)), active_low ^ expected_state);
26 }
27
28 /* Tests that the reset driver assert functionality is correct for active
29 * low devices.
30 */
ZTEST(reset_mmio_tests,test_reset_mmio_assert_active_low)31 ZTEST(reset_mmio_tests, test_reset_mmio_assert_active_low)
32 {
33 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset1));
34 uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset1));
35 bool active_low = true;
36 uint8_t i;
37
38 for (i = 0; i < RESET_MAX_NUM; i++) {
39 reset_line_deassert(dev, i);
40 check_status(dev, base, i, false, active_low);
41 /* Check idempotency */
42 reset_line_deassert(dev, i);
43 check_status(dev, base, i, false, active_low);
44
45 /* Check ressserting resets */
46 reset_line_assert(dev, i);
47 check_status(dev, base, i, true, active_low);
48 /* Check idempotency */
49 reset_line_assert(dev, i);
50 check_status(dev, base, i, true, active_low);
51 }
52 }
53
54 /* Tests that the reset driver assert functionality is correct for active
55 * high devices.
56 */
ZTEST(reset_mmio_tests,test_reset_mmio_assert_active_high)57 ZTEST(reset_mmio_tests, test_reset_mmio_assert_active_high)
58 {
59 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset0));
60 uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset0));
61 bool active_low = false;
62 uint8_t i;
63
64 for (i = 0; i < RESET_MAX_NUM; i++) {
65 reset_line_deassert(dev, i);
66 check_status(dev, base, i, false, active_low);
67 /* Check idempotency */
68 reset_line_deassert(dev, i);
69 check_status(dev, base, i, false, active_low);
70
71 /* Check ressserting resets */
72 reset_line_assert(dev, i);
73 check_status(dev, base, i, true, active_low);
74 /* Check idempotency */
75 reset_line_assert(dev, i);
76 check_status(dev, base, i, true, active_low);
77 }
78 }
79
80 /* Tests that the reset driver toggle functionality is correct for active
81 * low devices
82 */
ZTEST(reset_mmio_tests,test_reset_mmio_toggle_active_low)83 ZTEST(reset_mmio_tests, test_reset_mmio_toggle_active_low)
84 {
85 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset1));
86 uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset1));
87 bool active_low = true;
88 uint8_t i;
89
90 for (i = 0; i < RESET_MAX_NUM; i++) {
91 /* Begin by making sure the reset is asserted */
92 reset_line_assert(dev, i);
93 check_status(dev, base, i, true, active_low);
94 reset_line_toggle(dev, i);
95 check_status(dev, base, i, false, active_low);
96 reset_line_toggle(dev, i);
97 check_status(dev, base, i, true, active_low);
98 }
99 }
100
101 /* Tests that the reset driver toggle functionality is correct for active
102 * high devices
103 */
ZTEST(reset_mmio_tests,test_reset_mmio_toggle_active_high)104 ZTEST(reset_mmio_tests, test_reset_mmio_toggle_active_high)
105 {
106 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset0));
107 uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset0));
108 bool active_low = false;
109 uint8_t i;
110
111 for (i = 0; i < RESET_MAX_NUM; i++) {
112 /* Begin by making sure the reset is asserted */
113 reset_line_assert(dev, i);
114 check_status(dev, base, i, true, active_low);
115 reset_line_toggle(dev, i);
116 check_status(dev, base, i, false, active_low);
117 reset_line_toggle(dev, i);
118 check_status(dev, base, i, true, active_low);
119 }
120 }
121
122 /* Tests that the reset driver rejects out of bounds bits */
ZTEST(reset_mmio_tests,test_reset_mmio_oob)123 ZTEST(reset_mmio_tests, test_reset_mmio_oob)
124 {
125 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset0));
126 uint8_t i, status;
127
128 for (i = RESET_MAX_NUM; i < 32; i++) {
129 zassert_not_ok(reset_line_assert(dev, i));
130 zassert_not_ok(reset_line_deassert(dev, i));
131 zassert_not_ok(reset_status(dev, i, &status));
132 zassert_not_ok(reset_line_toggle(dev, i));
133 }
134 }
135