Skip to content

Commit

Permalink
tests: drivers: clock_management: add clock_management_minimal test
Browse files Browse the repository at this point in the history
Add clock_management_minimal test. This test is intended to verify that
clock management functions correctly when runtime notifications and rate
setting are disabled. It also verifies that support for multiple clock
outputs on a device works as expected.

The test has the following phases:
- apply default clock state for both clock outputs of the emulated
  consumer. Verify that the resulting clock frequencies match what is
  expected.
- apply sleep clock state for both clock outputs of the emulated
  consumer. Verify that the resulting clock frequencies match what is
  expected.
- Request a clock frequency from each clock output, which should match
  the frequency of one of the defined states exactly. Verify that the
  expected state is applied.

The test is supported on the `native_sim` target using emulated clock
drivers for testing purposes in CI, and on the
`lpcxpresso55s69/lpc55s69/cpu0` target to verify the clock management
API on real hardware.

Signed-off-by: Daniel DeGrasse <[email protected]>
  • Loading branch information
danieldegrasse committed Dec 10, 2024
1 parent 64fb7bb commit 91a3f42
Show file tree
Hide file tree
Showing 8 changed files with 487 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

# Add "common" directory to get DTS bindings for emulated clock drivers
list(APPEND DTS_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../common)

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

FILE(GLOB app_sources src/*.c)
FILE(GLOB clock_sources ../common/emul_clock_drivers/*.c)
target_sources(app PRIVATE ${app_sources} ${clock_sources})

# Add custom clock drivers to clock management header list
add_clock_management_header("../common/emul_clock_drivers/emul_clock_drivers.h")
31 changes: 31 additions & 0 deletions tests/drivers/clock_management/clock_management_minimal/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Clock Management Minimal Test
#############################

This test is designed to verify that the clock management API can function
correctly without runtime callbacks or rate setting enabled. It defines one
dummy clock consumer. In addition, it defines several dummy clock nodes to
verify API functionality. Boards should configure these dummy devices with
clock states as described within the tests below.

Boards may also use the dummy clock nodes as needed if they do not have a
hardware clock output they can safely reconfigure as part of this testcase.

The following tests will run, using the output clock with name "default":

* Verify that the consumer can apply the clock state named "default" for
both the "slow" and "fast" clock output, and that the queried rates of
the "slow" and "fast" clocks match the properties "slow-default-freq"
and "fast-default-freq", respectively.

* Verify that the consumer can apply the clock state named "sleep" for
both the "slow" and "fast" clock output, and that the queried rates of
the "slow" and "fast" clocks match the properties "slow-sleep-freq"
and "fast-sleep-freq", respectively.

* Verify that requesting the frequency given by "slow-request-freq" from
the "slow" clock output reconfigures that clock output to *exactly* the
frequency given by the "slow-request-freq" property.

* Verify that requesting the frequency given by "fast-request-freq" from
the "fast" clock output reconfigures that clock output to *exactly* the
frequency given by the "fast-request-freq" property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2024 Tenstorrent AI ULC
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <freq.h>

/* 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>;
};

/* Disable the SD controller- we are using its clock for this test */
&sdif {
status = "disabled";
};

/* Define clock states for clockout clock */
&clkout_clock {
clkout_16mhz: clkout-16mhz {
compatible = "clock-state";
/* Expect a clock frequency of 16 MHz */
clocks = <&xtal32m 1 &clk_in_en 1 &pll0clksel 1
&pll0_pdec 4 &pll0_directo 0
&pll0 512000000 8 256 0 31 31 0 0 0
&pll1_bypass 0 &clkoutsel 1
&clkoutdiv 8>;
clock-frequency = <DT_FREQ_M(16)>;
};

clkout_1mhz: clkout-1mhz {
compatible = "clock-state";
/* Expect a clock frequency of 1MHz */
clocks = <&fro_1m 1 &clkoutsel 4>;
clock-frequency = <DT_FREQ_M(1)>;
};

clkout_500mhz: clkout-500mhz {
compatible = "clock-state";
/* Expect a clock frequency of 500 KHz */
clocks = <&xtal32m 1 &clk_in_en 1 &pll0clksel 1
&pll0_pdec 4 &pll0_directo 0
&pll0 512000000 8 256 0 31 31 0 0 0
&pll1_bypass 0 &clkoutsel 1
&clkoutdiv 256>;
clock-frequency = <DT_FREQ_K(500)>;
};
};

/* Define clock states for SDIO clock */
&sdio_clock {
sdioclk_48mhz: sdioclk-48mhz {
compatible = "clock-state";
/* Expect a clock frequency of 48 MHz */
clocks = <&fro_12m 1 &pll1clksel 0
&pll1_pdec 4 &pll1_directo 0
&pll1 384000000 4 128 0 62 31
&pll1_bypass 0 &sdioclksel 5
&sdioclkdiv 2>;
clock-frequency = <DT_FREQ_M(48)>;
};

sdioclk_24mhz: sdioclk-24mhz {
compatible = "clock-state";
/* Expect a clock frequency of 24 MHz */
clocks = <&fro_12m 1 &pll1clksel 0
&pll1_pdec 4 &pll1_directo 0
&pll1 384000000 4 128 0 62 31
&pll1_bypass 0 &sdioclksel 5
&sdioclkdiv 4>;
clock-frequency = <DT_FREQ_M(24)>;
};

sdioclk_12mhz: sdioclk-12mhz {
compatible = "clock-state";
/* Expect a clock frequency of 12 MHz */
clocks = <&fro_hf 1 &sdioclksel 3
&sdioclkdiv 8>;
clock-frequency = <DT_FREQ_M(12)>;
};
};

/ {
/* Emulated device clock consumer */
emul_device {
emul_dev1: emul-dev1 {
compatible = "vnd,emul-clock-consumer";
clock-outputs = <&clkout_clock &sdio_clock>;
clock-output-names = "slow", "fast";
clock-state-0 = <&clkout_16mhz &sdioclk_48mhz>;
slow-default-freq = <DT_FREQ_M(16)>;
fast-default-freq = <DT_FREQ_M(48)>;
slow-sleep-freq = <DT_FREQ_M(1)>;
fast-sleep-freq = <DT_FREQ_M(12)>;
clock-state-1 = <&clkout_1mhz &sdioclk_12mhz>;
slow-request-freq = <DT_FREQ_K(500)>;
fast-request-freq = <DT_FREQ_M(24)>;
clock-state-names = "default", "sleep";
};
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright (c) 2024 Tenstorrent AI ULC
*
* SPDX-License-Identifier: Apache-2.0
*/

/*
* Define clock tree with emulated clock nodes.
* These node labels are chosen so that they won't conflict with SOC clock
* tree nodelabels. The clock driver implementations used by this tree are
* stored within the test itself
*/

#include <freq.h>

/ {
emul_clock_root {
emul_source1: emul-source1 {
compatible = "fixed-clock";
clock-frequency = <DT_FREQ_M(10)>;
#clock-cells = <0>;

emul_div1: emul-div1 {
compatible = "vnd,emul-clock-div";
max-div = <64>;
#clock-cells = <1>;
};
};

emul_source2: emul-source2 {
compatible = "fixed-clock";
clock-frequency = <DT_FREQ_M(50)>;
#clock-cells = <0>;

emul_div2: emul-div2 {
compatible = "vnd,emul-clock-div";
max-div = <256>;
#clock-cells = <1>;
};
};

emul_source3: emul-source3 {
compatible = "fixed-clock";
clock-frequency = <DT_FREQ_M(100)>;
#clock-cells = <0>;
};

emul_mux1: emul-mux1 {
compatible = "vnd,emul-clock-mux";
inputs = <&emul_div1 &emul_div2>;
#clock-cells = <1>;

dev1_out_slow: dev1-out-slow {
compatible = "clock-output";
#clock-cells = <0>;

/* Expect a clock frequency of 10 MHz */
dev1_10mhz: dev1-10mhz {
compatible = "clock-state";
clocks = <&emul_div1 1 &emul_mux1 0>;
clock-frequency = <DT_FREQ_M(10)>;
};

/* Expect a clock frequency of 5 MHz */
dev1_5mhz: dev1-5mhz {
compatible = "clock-state";
clocks = <&emul_div1 2 &emul_mux1 0>;
clock-frequency = <DT_FREQ_M(5)>;
};

/* Expect a clock frequency of 3.333333 MHz */
dev1_3mhz: dev1-3mhz {
compatible = "clock-state";
clocks = <&emul_div1 3 &emul_mux1 0>;
clock-frequency = <3333333>;
};
};
};

emul_mux2: emul-mux2 {
compatible = "vnd,emul-clock-mux";
inputs = <&emul_mux1 &emul_source3>;
#clock-cells = <1>;

dev1_out_fast: dev1-out-fast {
compatible = "clock-output";
#clock-cells = <0>;

/* Expect a clock frequency of 100 MHz */
dev1_100mhz: dev1-100mhz {
compatible = "clock-state";
clocks = <&emul_mux2 1>;
clock-frequency = <DT_FREQ_M(100)>;
};

/* Expect a clock frequency of 50 MHz */
dev1_50mhz: dev1-50mhz {
compatible = "clock-state";
clocks = <&emul_mux2 0
&emul_mux1 1
&emul_div2 1>;
clock-frequency = <DT_FREQ_M(50)>;
};

/* Expect a clock frequency of 25 MHz */
dev1_25mhz: dev1-25mhz {
compatible = "clock-state";
clocks = <&emul_mux2 0
&emul_mux1 1
&emul_div2 2>;
clock-frequency = <DT_FREQ_M(25)>;
};
};
};
};

/* Emulated device clock consumer */
emul_device {
emul_dev1: emul-dev1 {
compatible = "vnd,emul-clock-consumer";
clock-outputs = <&dev1_out_slow &dev1_out_fast>;
clock-output-names = "slow", "fast";
clock-state-0 = <&dev1_10mhz &dev1_100mhz>;
slow-default-freq = <DT_FREQ_M(10)>;
fast-default-freq = <DT_FREQ_M(100)>;
slow-sleep-freq = <3333333>;
fast-sleep-freq = <DT_FREQ_M(25)>;
clock-state-1 = <&dev1_3mhz &dev1_25mhz>;
slow-request-freq = <DT_FREQ_M(5)>;
fast-request-freq = <DT_FREQ_M(50)>;
clock-state-names = "default", "sleep";
};
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright (c) 2024 Tenstorrent AI UL
#
# 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:
fast-default-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying default
clock state for fast output
fast-sleep-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying sleep
clock state for fast output
fast-request-freq:
type: int
required: true
description: |
Frequency this consumer will request from the fast output. Consumer
expects the resulting frequency from this request to match the
requested frequency exactly.
slow-default-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying default
clock state for slow output
slow-sleep-freq:
type: int
required: true
description: |
Frequency this consumer expects to read when applying sleep
clock state for slow output
slow-request-freq:
type: int
required: true
description: |
Frequency this consumer will request from the slow output. Consumer
expects the resulting frequency from this request to match the
requested frequency exactly.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_ZTEST=y
CONFIG_CLOCK_MANAGEMENT=y
CONFIG_CLOCK_MANAGEMENT_RUNTIME=n
CONFIG_CLOCK_MANAGEMENT_SET_RATE=n
Loading

0 comments on commit 91a3f42

Please sign in to comment.