Merge "Add clock gating tests for video/audio clocks"
diff --git a/hw/top_matcha/dv/chip_sim_cfg.hjson b/hw/top_matcha/dv/chip_sim_cfg.hjson
index 397f411..e9ced65 100644
--- a/hw/top_matcha/dv/chip_sim_cfg.hjson
+++ b/hw/top_matcha/dv/chip_sim_cfg.hjson
@@ -1721,6 +1721,20 @@
       run_opts: ["+clk_idx=5"]
     }
     {
+      name: chip_sw_clkmgr_off_video_trans
+      uvm_test_seq: chip_sw_clkmgr_off_gateable_clk_vseq
+      sw_images: ["//sw/device/tests:clkmgr_off_video_clk_test:1:matcha"]
+      en_run_modes: ["sw_test_mode_test_rom"]
+      run_opts: ["+clk_idx=4"]
+    }
+    {
+      name: chip_sw_clkmgr_off_audio_trans
+      uvm_test_seq: chip_sw_clkmgr_off_gateable_clk_vseq
+      sw_images: ["//sw/device/tests:clkmgr_off_audio_clk_test:1:matcha"]
+      en_run_modes: ["sw_test_mode_test_rom"]
+      run_opts: ["+clk_idx=6"]
+    }
+    {
       name: chip_sw_clkmgr_external_clk_src_for_lc
       uvm_test_seq: chip_sw_lc_ctrl_transition_vseq
       sw_images: ["//sw/device/tests/sim_dv:clkmgr_external_clk_src_for_lc_test:1"]
@@ -2100,9 +2114,11 @@
         "chip_sw_cam_ctrl_test",
         "chip_sw_clkmgr_external_clk_src_for_sw_fast",
         "chip_sw_clkmgr_external_clk_src_for_sw_slow",
+        "chip_sw_clkmgr_off_audio_trans",
         "chip_sw_clkmgr_off_ml_trans",
         "chip_sw_clkmgr_off_peri",
         "chip_sw_clkmgr_off_smc_trans",
+        "chip_sw_clkmgr_off_video_trans",
         "chip_sw_clkmgr_reset_frequency",
         "chip_sw_clkmgr_sleep_frequency",
         "chip_sw_clkmgr_smoketest",
@@ -2203,9 +2219,11 @@
         "chip_sw_cam_ctrl_test",
         "chip_sw_clkmgr_external_clk_src_for_sw_fast",
         "chip_sw_clkmgr_external_clk_src_for_sw_slow",
+        "chip_sw_clkmgr_off_audio_trans",
         "chip_sw_clkmgr_off_ml_trans",
         "chip_sw_clkmgr_off_peri",
         "chip_sw_clkmgr_off_smc_trans",
+        "chip_sw_clkmgr_off_video_trans",
         "chip_sw_clkmgr_reset_frequency",
         "chip_sw_clkmgr_sleep_frequency",
         "chip_sw_clkmgr_smoketest",
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index 9f6e2af..21913dc 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -946,6 +946,22 @@
     ],
 )
 
+matcha_dv_test(
+    name = "clkmgr_off_video_clk_test",
+    srcs = ["clkmgr_off_video_clk_test.c"],
+    deps = [
+        ":clkmgr_off_clk_impl",
+    ],
+)
+
+matcha_dv_test(
+    name = "clkmgr_off_audio_clk_test",
+    srcs = ["clkmgr_off_audio_clk_test.c"],
+    deps = [
+        ":clkmgr_off_clk_impl",
+    ],
+)
+
 cc_library(
     name = "clkmgr_external_clk_src_for_sw_impl",
     srcs = ["@lowrisc_opentitan//sw/device/tests:clkmgr_external_clk_src_for_sw_impl.c"],
diff --git a/sw/device/tests/clkmgr_off_audio_clk_test.c b/sw/device/tests/clkmgr_off_audio_clk_test.c
new file mode 100644
index 0000000..04dee74
--- /dev/null
+++ b/sw/device/tests/clkmgr_off_audio_clk_test.c
@@ -0,0 +1,60 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// This test checks that when audio_clk is disabled, the corresponding output
+// signal from clkmgr will be constant 0
+//
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/memory.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_base.h"
+#include "sw/device/lib/dif/dif_clkmgr.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+
+static dif_aon_timer_t aon_timer;
+
+/**
+ * Turn off the clock for 400us, then turn on
+ * Check the result in chip_sw_clkmgr_off_peri_vseq
+ */
+static void test_gateable_clocks_off_without_reset(
+    const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock) {
+  // Make sure the clock for the unit is on.
+  CHECK_DIF_OK(
+      dif_clkmgr_gateable_clock_set_enabled(clkmgr, clock, kDifToggleEnabled));
+
+  LOG_INFO("Testing gateable clock ...");
+
+  // Disable the peripheral's clock.
+  CHECK_DIF_OK(
+      dif_clkmgr_gateable_clock_set_enabled(clkmgr, clock, kDifToggleDisabled));
+  // Wait for the clock to really turn off.
+  busy_spin_micros(400);
+  // Enalbe the clock
+  CHECK_DIF_OK(
+      dif_clkmgr_gateable_clock_set_enabled(clkmgr, clock, kDifToggleEnabled));
+}
+
+bool test_main(void) {
+  dif_clkmgr_t clkmgr;
+
+  CHECK_DIF_OK(dif_clkmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_CLKMGR_AON_BASE_ADDR), &clkmgr));
+
+  // Initialize aon timer.
+  CHECK_DIF_OK(dif_aon_timer_init(
+      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+  test_gateable_clocks_off_without_reset(&clkmgr,
+                                         kTopMatchaGateableClocksAudioPeri);
+  return true;
+}
diff --git a/sw/device/tests/clkmgr_off_video_clk_test.c b/sw/device/tests/clkmgr_off_video_clk_test.c
new file mode 100644
index 0000000..679fb58
--- /dev/null
+++ b/sw/device/tests/clkmgr_off_video_clk_test.c
@@ -0,0 +1,60 @@
+// Copyright 2023 Google LLC.
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// This test checks that when video_clk is disabled, the corresponding output
+// signal from clkmgr will be constant 0
+//
+
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
+#include "sw/device/lib/base/abs_mmio.h"
+#include "sw/device/lib/base/memory.h"
+#include "sw/device/lib/dif/dif_aon_timer.h"
+#include "sw/device/lib/dif/dif_base.h"
+#include "sw/device/lib/dif/dif_clkmgr.h"
+#include "sw/device/lib/runtime/log.h"
+#include "sw/device/lib/testing/aon_timer_testutils.h"
+#include "sw/device/lib/testing/test_framework/check.h"
+#include "sw/device/lib/testing/test_framework/ottf_main.h"
+
+OTTF_DEFINE_TEST_CONFIG();
+
+static dif_aon_timer_t aon_timer;
+
+/**
+ * Turn off the clock for 400us, then turn on
+ * Check the result in chip_sw_clkmgr_off_peri_vseq
+ */
+static void test_gateable_clocks_off_without_reset(
+    const dif_clkmgr_t *clkmgr, dif_clkmgr_gateable_clock_t clock) {
+  // Make sure the clock for the unit is on.
+  CHECK_DIF_OK(
+      dif_clkmgr_gateable_clock_set_enabled(clkmgr, clock, kDifToggleEnabled));
+
+  LOG_INFO("Testing gateable clock ...");
+
+  // Disable the peripheral's clock.
+  CHECK_DIF_OK(
+      dif_clkmgr_gateable_clock_set_enabled(clkmgr, clock, kDifToggleDisabled));
+  // Wait for the clock to really turn off.
+  busy_spin_micros(400);
+  // Enalbe the clock
+  CHECK_DIF_OK(
+      dif_clkmgr_gateable_clock_set_enabled(clkmgr, clock, kDifToggleEnabled));
+}
+
+bool test_main(void) {
+  dif_clkmgr_t clkmgr;
+
+  CHECK_DIF_OK(dif_clkmgr_init(
+      mmio_region_from_addr(TOP_MATCHA_CLKMGR_AON_BASE_ADDR), &clkmgr));
+
+  // Initialize aon timer.
+  CHECK_DIF_OK(dif_aon_timer_init(
+      mmio_region_from_addr(TOP_MATCHA_AON_TIMER_AON_BASE_ADDR), &aon_timer));
+
+  test_gateable_clocks_off_without_reset(&clkmgr,
+                                         kTopMatchaGateableClocksVideoPeri);
+  return true;
+}