Skip to content

Commit

Permalink
tests: drivers: clock_mgmt: add clock management hardware test
Browse files Browse the repository at this point in the history
Add clock management hardware test. This test applies a series of clock
states for a given consumer, and verifies that each state produces the
expected rate. This test is intended to verify that each clock node
driver within an SOC implementation works as expected.

Boards should define their test overlays for this test to exercise as
much of the clock tree as possible, and ensure some clock states do not
define an explicit clocks property, to test their `clock_set_rate` and
`clock_round_rate` implementations.

Initial support is added for the `lpcxpresso55s69/lpc55s69/cpu0` target,
as this is the only hardware supporting clock management.

Signed-off-by: Daniel DeGrasse <[email protected]>
  • Loading branch information
danieldegrasse committed Oct 3, 2024
1 parent 23d2305 commit a942501
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 0 deletions.
9 changes: 9 additions & 0 deletions tests/drivers/clock_mgmt/clock_mgmt_hw/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(clock_mgmt_hw)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
32 changes: 32 additions & 0 deletions tests/drivers/clock_mgmt/clock_mgmt_hw/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Clock Management Hardware Test
##############################

This test is designed to verify the functionality of hardware clock trees
implementing the clock management API. It defines one dummy devices, which
will be a clock consumer.

The test will apply five clock states for the dummy device, and verify the
frequency matches an expected value for each state. The states are as
follows:

* clock-state-0: CLOCK_MGMT_STATE_DEFAULT, frequency set by "default-freq"
property of consumer node

* clock-state-1: CLOCK_MGMT_STATE_SLEEP, frequency set by "sleep-freq"
property of consumer node

* clock-state-2: CLOCK_MGMT_STATE_TEST1, frequency set by "test1-freq"
property of consumer node

* clock-state-3: CLOCK_MGMT_STATE_TEST2, frequency set by "test2-freq"
property of consumer node

* clock-state-4: CLOCK_MGMT_STATE_TEST3, frequency set by "test3-freq"
property of consumer node

Devices should define these states to exercise as many clock node drivers as
possible. One example might be clocking from a PLL in the default state, a
high speed internal oscillator in the sleep state, and a low speed external
oscillator in the test state. Some states should avoid defining explicit
configuration settings, to verify that runtime clock set_rate APIs work as
expected.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Clock CPU from FROHF, since we will use the PLLs within our testcases */
&system_clock {
sys_clk_96mhz: sys-clk-96mhz {
compatible = "clock-state";
clocks = <&ahbclkdiv 1 &fro_hf 1 &mainclksela 3 &mainclkselb 0>;
clock-frequency = <DT_FREQ_M(96)>;
locking-state;
};
};

&cpu0 {
clock-state-0 = <&sys_clk_96mhz>;
};

/* Define clock states for clockout clock */
&clkout_clock {
clkout_default: clkout-default {
compatible = "clock-state";
/* Enable PLL1 and switch clkout to use it */
clocks = <&xtal32m 1 &clk_in_en 1 &pll1clksel 1 &pll1_pdec 2
&pll1_directo 0 &pll1 300000000 4 75 0 39 19
&pll1_bypass 0 &clkoutsel 5 &clkoutdiv 2>;
clock-frequency = <75000000>;
};
clkout_sleep: clkout-sleep {
compatible = "clock-state";
clocks = <&fro_hf 1 &clkoutsel 3 &clkoutdiv 1>;
clock-frequency = <96000000>;
};
clkout_test1: clkout-test1 {
/* Should use runtime frequency requests */
compatible = "clock-state";
clock-frequency = <73000000>;
};
clkout_test2: clkout-test2 {
/* Should use runtime frequency requests */
compatible = "clock-state";
clock-frequency = <147640000>;
};
clkout_test3: clkout-test3 {
/* Should use runtime frequency requests */
compatible = "clock-state";
clock-frequency = <1000000>;
};
};

/ {
emul_dev: emul-dev {
compatible = "vnd,emul-clock-consumer";
clock-outputs = <&clkout_clock>;
clock-output-names = "default";
clock-state-0 = <&clkout_default>;
default-freq = <75000000>;
clock-state-1 = <&clkout_sleep>;
sleep-freq = <96000000>;
clock-state-2 = <&clkout_test1>;
test1-freq = <73000000>;
clock-state-3 = <&clkout_test2>;
test2-freq = <147640000>;
clock-state-4 = <&clkout_test3>;
test3-freq = <1000000>;
clock-state-names= "default", "sleep", "test1",
"test2", "test3";
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2024 NXP
#
# SPDX-License-Identifier: Apache-2.0

description: |
Binding for emulated clock consumer device. This device is used in testing
to verify that clock states are applied as expected.
compatible: "vnd,emul-clock-consumer"

include: [clock-device.yaml]

properties:
default-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying default clock
management state
sleep-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying sleep clock
management state
test1-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying test1 clock
management state
test2-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying test2 clock
management state
test3-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying test3 clock
management state
5 changes: 5 additions & 0 deletions tests/drivers/clock_mgmt/clock_mgmt_hw/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CONFIG_ZTEST=y
CONFIG_CLOCK_MGMT=y
CONFIG_CLOCK_MGMT_RUNTIME=y
CONFIG_CLOCK_MGMT_SET_RATE=y
CONFIG_ZTEST_STACK_SIZE=2048
62 changes: 62 additions & 0 deletions tests/drivers/clock_mgmt/clock_mgmt_hw/src/test_clock_mgmt_hw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/drivers/clock_mgmt.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(test);

#define CONSUMER_NODE DT_NODELABEL(emul_dev)

CLOCK_MGMT_DT_DEFINE_OUTPUT_BY_NAME(CONSUMER_NODE, default);

/* Get references to each clock management state and output */
static const struct clock_output *dev_out =
CLOCK_MGMT_DT_GET_OUTPUT_BY_NAME(CONSUMER_NODE, default);
static clock_mgmt_state_t dev_default =
CLOCK_MGMT_DT_GET_STATE(CONSUMER_NODE, default, default);
static clock_mgmt_state_t dev_sleep =
CLOCK_MGMT_DT_GET_STATE(CONSUMER_NODE, default, sleep);
static clock_mgmt_state_t dev_test1 =
CLOCK_MGMT_DT_GET_STATE(CONSUMER_NODE, default, test1);
static clock_mgmt_state_t dev_test2 =
CLOCK_MGMT_DT_GET_STATE(CONSUMER_NODE, default, test2);
static clock_mgmt_state_t dev_test3 =
CLOCK_MGMT_DT_GET_STATE(CONSUMER_NODE, default, test3);

void apply_clock_state(clock_mgmt_state_t state, const char *state_name,
int expected_rate)
{
int ret;

/* Apply clock state, verify frequencies */
TC_PRINT("Try to apply %s clock state\n", state_name);

ret = clock_mgmt_apply_state(dev_out, state);
zassert_equal(ret, expected_rate,
"Failed to apply %s clock management state", state_name);

/* Check rate */
ret = clock_mgmt_get_rate(dev_out);
TC_PRINT("Consumer %s clock rate: %d\n", state_name, ret);
zassert_equal(ret, expected_rate,
"Consumer has invalid %s clock rate", state_name);
}

ZTEST(clock_mgmt_hw, test_apply_states)
{
apply_clock_state(dev_default, "default",
DT_PROP(CONSUMER_NODE, default_freq));
apply_clock_state(dev_sleep, "sleep",
DT_PROP(CONSUMER_NODE, sleep_freq));
apply_clock_state(dev_test1, "test1",
DT_PROP(CONSUMER_NODE, test1_freq));
apply_clock_state(dev_test2, "test2",
DT_PROP(CONSUMER_NODE, test2_freq));
apply_clock_state(dev_test3, "test3",
DT_PROP(CONSUMER_NODE, test3_freq));
}

ZTEST_SUITE(clock_mgmt_hw, NULL, NULL, NULL, NULL, NULL);
8 changes: 8 additions & 0 deletions tests/drivers/clock_mgmt/clock_mgmt_hw/testcase.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
tests:
drivers.clock_mgmt.hw:
tags:
- drivers
- clock_mgmt
integration_platforms:
- lpcxpresso55s69/lpc55s69/cpu0
filter: dt_compat_enabled("vnd,emul-clock-consumer")

0 comments on commit a942501

Please sign in to comment.