[sca] Disable peripheral clocks during SCA capture

To further reduce unwanted noise during SCA captures, it's better to
disable the peripheral clocks in addition to the clocks of the bigger modules
like (HMAC, OTBN, KMAC, AES).

Special care is required for the IO_DIV4_PERI clock as the UART and GPIO
modules required for communication with the scope are using this clock.
Therefore, this clock can only be disabled during the actual capture and
has to be re-enabled afterwards to resume communication.

Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/sw/device/sca/aes_serial.c b/sw/device/sca/aes_serial.c
index c52c110..0fc1ab1 100644
--- a/sw/device/sca/aes_serial.c
+++ b/sw/device/sca/aes_serial.c
@@ -194,7 +194,7 @@
  * UART.
  */
 void _ottf_main(void) {
-  sca_init(kScaTriggerSourceAes, kScaPeripheralAes);
+  sca_init(kScaTriggerSourceAes, kScaPeripheralIoDiv4 | kScaPeripheralAes);
 
   LOG_INFO("Running AES serial");
 
diff --git a/sw/device/sca/lib/sca.c b/sw/device/sca/lib/sca.c
index 0d59fa5..3d00f9f 100644
--- a/sw/device/sca/lib/sca.c
+++ b/sw/device/sca/lib/sca.c
@@ -207,10 +207,24 @@
     OT_DISCARD(dif_clkmgr_hintable_clock_set_hint(
         &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT, kDifToggleDisabled));
   }
+  if (disable & kScaPeripheralIoDiv4) {
+    OT_DISCARD(dif_clkmgr_gateable_clock_set_enabled(
+        &clkmgr, CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT,
+        kDifToggleDisabled));
+  }
+  if (disable & kScaPeripheralIoDiv2) {
+    OT_DISCARD(dif_clkmgr_gateable_clock_set_enabled(
+        &clkmgr, CLKMGR_CLK_ENABLES_CLK_IO_DIV2_PERI_EN_BIT,
+        kDifToggleDisabled));
+  }
   if (disable & kScaPeripheralUsb) {
     OT_DISCARD(dif_clkmgr_gateable_clock_set_enabled(
         &clkmgr, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT, kDifToggleDisabled));
   }
+  if (disable & kScaPeripheralIo) {
+    OT_DISCARD(dif_clkmgr_gateable_clock_set_enabled(
+        &clkmgr, CLKMGR_CLK_ENABLES_CLK_IO_PERI_EN_BIT, kDifToggleDisabled));
+  }
 
 #if !OT_IS_ENGLISH_BREAKFAST
   if (disable & kScaPeripheralKmac) {
@@ -253,6 +267,14 @@
 }
 
 void sca_call_and_sleep(sca_callee callee, uint32_t sleep_cycles) {
+  // Disable the IO_DIV4_PERI clock to reduce noise during the actual capture.
+  // This also disables the UART(s) and GPIO modules required for
+  // communication with the scope. Therefore, it has to be re-enabled after
+  // the capture.
+  dif_clkmgr_t clkmgr;
+  OT_DISCARD(dif_clkmgr_init(
+      mmio_region_from_addr(TOP_EARLGREY_CLKMGR_AON_BASE_ADDR), &clkmgr));
+
   // Start timer to wake Ibex after the callee is done.
   uint64_t current_time;
   // Return values of below functions are ignored to improve capture
@@ -266,4 +288,8 @@
   callee();
 
   wait_for_interrupt();
+
+  // Re-enable IO_DIV4_PERI clock to resume communication with the scope.
+  OT_DISCARD(dif_clkmgr_gateable_clock_set_enabled(
+      &clkmgr, CLKMGR_CLK_ENABLES_CLK_IO_DIV4_PERI_EN_BIT, kDifToggleEnabled));
 }
diff --git a/sw/device/sca/lib/sca.h b/sw/device/sca/lib/sca.h
index d66f2fb..955e8ec 100644
--- a/sw/device/sca/lib/sca.h
+++ b/sw/device/sca/lib/sca.h
@@ -84,9 +84,21 @@
    */
   kScaPeripheralOtbn = 1 << 6,
   /**
+   * Peripherals using the IO_DIV4_PERI clock (UART, GPIO, I2C, SPI Dev, ...)
+   */
+  kScaPeripheralIoDiv4 = 1 << 7,
+  /**
+   * Peripherals using the IO_DIV2_PERI clock (SPI Host 1)
+   */
+  kScaPeripheralIoDiv2 = 1 << 8,
+  /**
    * USB.
    */
-  kScaPeripheralUsb = 1 << 7,
+  kScaPeripheralUsb = 1 << 9,
+  /**
+   * Peripherals using the IO_PERI clock (SPI Host 0)
+   */
+  kScaPeripheralIo = 1 << 10,
 } sca_peripheral_t;
 
 /**
diff --git a/sw/device/sca/sha3_serial.c b/sw/device/sca/sha3_serial.c
index 6cacfcc..3057bac 100644
--- a/sw/device/sca/sha3_serial.c
+++ b/sw/device/sca/sha3_serial.c
@@ -478,7 +478,7 @@
  * UART.
  */
 void _ottf_main(void) {
-  sca_init(kScaTriggerSourceKmac, kScaPeripheralKmac);
+  sca_init(kScaTriggerSourceKmac, kScaPeripheralIoDiv4 | kScaPeripheralKmac);
 
   LOG_INFO("Running sha3_serial");