blob: 29df00f0abf647f456b2f225b3285b1163fe01ab [file] [log] [blame]
/*
* Copyright (c) 2025 Google LLC.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/device.h>
#include <zephyr/drivers/reset.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
ZTEST_SUITE(reset_mmio_tests, NULL, NULL, NULL, NULL, NULL);
#define RESET_MAX_NUM 16
void check_status(const struct device *dev, uint32_t base, uint32_t id, bool expected_state,
bool active_low)
{
uint8_t actual_state;
zassert_ok(reset_status(dev, id, &actual_state), "Failed getting reset state");
zassert_equal(actual_state, expected_state,
"reset state %u doesn't match expected state %u", actual_state,
expected_state);
zassert_equal(FIELD_GET(BIT(id), sys_read32(base)), active_low ^ expected_state);
}
/* Tests that the reset driver assert functionality is correct for active
* low devices.
*/
ZTEST(reset_mmio_tests, test_reset_mmio_assert_active_low)
{
const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset1));
uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset1));
bool active_low = true;
uint8_t i;
for (i = 0; i < RESET_MAX_NUM; i++) {
reset_line_deassert(dev, i);
check_status(dev, base, i, false, active_low);
/* Check idempotency */
reset_line_deassert(dev, i);
check_status(dev, base, i, false, active_low);
/* Check ressserting resets */
reset_line_assert(dev, i);
check_status(dev, base, i, true, active_low);
/* Check idempotency */
reset_line_assert(dev, i);
check_status(dev, base, i, true, active_low);
}
}
/* Tests that the reset driver assert functionality is correct for active
* high devices.
*/
ZTEST(reset_mmio_tests, test_reset_mmio_assert_active_high)
{
const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset0));
uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset0));
bool active_low = false;
uint8_t i;
for (i = 0; i < RESET_MAX_NUM; i++) {
reset_line_deassert(dev, i);
check_status(dev, base, i, false, active_low);
/* Check idempotency */
reset_line_deassert(dev, i);
check_status(dev, base, i, false, active_low);
/* Check ressserting resets */
reset_line_assert(dev, i);
check_status(dev, base, i, true, active_low);
/* Check idempotency */
reset_line_assert(dev, i);
check_status(dev, base, i, true, active_low);
}
}
/* Tests that the reset driver toggle functionality is correct for active
* low devices
*/
ZTEST(reset_mmio_tests, test_reset_mmio_toggle_active_low)
{
const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset1));
uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset1));
bool active_low = true;
uint8_t i;
for (i = 0; i < RESET_MAX_NUM; i++) {
/* Begin by making sure the reset is asserted */
reset_line_assert(dev, i);
check_status(dev, base, i, true, active_low);
reset_line_toggle(dev, i);
check_status(dev, base, i, false, active_low);
reset_line_toggle(dev, i);
check_status(dev, base, i, true, active_low);
}
}
/* Tests that the reset driver toggle functionality is correct for active
* high devices
*/
ZTEST(reset_mmio_tests, test_reset_mmio_toggle_active_high)
{
const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset0));
uint32_t base = DT_REG_ADDR(DT_NODELABEL(reset0));
bool active_low = false;
uint8_t i;
for (i = 0; i < RESET_MAX_NUM; i++) {
/* Begin by making sure the reset is asserted */
reset_line_assert(dev, i);
check_status(dev, base, i, true, active_low);
reset_line_toggle(dev, i);
check_status(dev, base, i, false, active_low);
reset_line_toggle(dev, i);
check_status(dev, base, i, true, active_low);
}
}
/* Tests that the reset driver rejects out of bounds bits */
ZTEST(reset_mmio_tests, test_reset_mmio_oob)
{
const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(reset0));
uint8_t i, status;
for (i = RESET_MAX_NUM; i < 32; i++) {
zassert_not_ok(reset_line_assert(dev, i));
zassert_not_ok(reset_line_deassert(dev, i));
zassert_not_ok(reset_status(dev, i, &status));
zassert_not_ok(reset_line_toggle(dev, i));
}
}