[clkmgr] - Minor clock and power updates/fixes to enable integration

Signed-off-by: Timothy Chen <timothytim@google.com>

[clkmgr] - Flatten the hierarchical clock gating since this makes FPGA unhappy.

- I personally prefer hierarhical gating, but it is not absolutely critical here.

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/clkmgr/data/clkmgr.hjson b/hw/ip/clkmgr/data/clkmgr.hjson
index f91901d..73dee81 100644
--- a/hw/ip/clkmgr/data/clkmgr.hjson
+++ b/hw/ip/clkmgr/data/clkmgr.hjson
@@ -16,6 +16,12 @@
     "clk_fixed_i",
     "clk_usb_48mhz_i",
   ],
+  reset_primary: "rst_ni",
+  other_reset_list: [
+    "rst_main_ni"
+    "rst_fixed_ni"
+    "rst_usb_48mhz_ni"
+  ]
   bus_device: "tlul",
   regwidth: "32",
   param_list: [
@@ -36,6 +42,12 @@
       package: "clkmgr_pkg",
     },
 
+    { struct:  "pwr_clk",
+      type:    "req_rsp",
+      name:    "pwr",
+      act:     "rsp",
+    },
+
     { struct:  "clk_dft",
       type:    "uni",
       name:    "dft",
diff --git a/hw/ip/clkmgr/data/clkmgr.hjson.tpl b/hw/ip/clkmgr/data/clkmgr.hjson.tpl
index 7028d6c..70af9b0 100644
--- a/hw/ip/clkmgr/data/clkmgr.hjson.tpl
+++ b/hw/ip/clkmgr/data/clkmgr.hjson.tpl
@@ -21,6 +21,12 @@
     "clk_${src['name']}_i",
 % endfor
   ],
+  reset_primary: "rst_ni",
+  other_reset_list: [
+% for src in srcs:
+    "rst_${src['name']}_ni"
+% endfor
+  ]
   bus_device: "tlul",
   regwidth: "32",
   param_list: [
@@ -41,6 +47,12 @@
       package: "clkmgr_pkg",
     },
 
+    { struct:  "pwr_clk",
+      type:    "req_rsp",
+      name:    "pwr",
+      act:     "rsp",
+    },
+
     { struct:  "clk_dft",
       type:    "uni",
       name:    "dft",
diff --git a/hw/ip/clkmgr/data/clkmgr.sv.tpl b/hw/ip/clkmgr/data/clkmgr.sv.tpl
index 5582288..0dcff9c 100644
--- a/hw/ip/clkmgr/data/clkmgr.sv.tpl
+++ b/hw/ip/clkmgr/data/clkmgr.sv.tpl
@@ -56,15 +56,6 @@
     .devmode_i(1'b1)
   );
 
-  ////////////////////////////////////////////////////
-  // Power up group - feedthrough
-  ////////////////////////////////////////////////////
-  ## This group is hardcoded right now because it is the only one.
-  ## In the future if there are more, feedthrough should be converted to an attribute
-
-% for k,v in ft_clks.items():
-  assign clocks_o.${k} = clk_${v}_i;
-% endfor
 
   ////////////////////////////////////////////////////
   // Root gating
@@ -82,7 +73,7 @@
 % endfor
 
 % for src in srcs:
-  prim_clock_gating_sync i_${src['name']}_sync (
+  prim_clock_gating_sync i_${src['name']}_cg (
     .clk_i(clk_${src['name']}_i),
     .rst_ni(rst_${src['name']}_ni),
     .test_en_i(dft_i.test_en),
@@ -143,16 +134,27 @@
   // the rst_ni connection below is incorrect, need to find a proper reset in the sequence to use
   // if the clkmgr is always on, can use por synced directly
   // if not, then need to generate something ahead of lc/sys
+% for k in sw_clks:
+  logic ${k}_sw_en;
+% endfor
 
 % for k,v in sw_clks.items():
-  prim_clock_gating_sync i_${k}_sync (
-    .clk_i(clk_${v}_root),
+  prim_flop_2sync #(
+    .Width(1)
+  ) i_${k}_sw_en_sync (
+    .clk_i(clk_${v}_i),
     .rst_ni(rst_${v}_ni),
+    .d(reg2hw.clk_enables.${k}_en.q),
+    .q(${k}_sw_en)
+  );
+
+  prim_clock_gating i_${k}_cg (
+    .clk_i(clk_${v}_i),
+    .en_i(${k}_sw_en & clk_${v}_en),
     .test_en_i(dft_i.test_en),
-    .async_en_i(reg2hw.clk_enables.${k}_en.q),
-    .en_o(), // should this be fedback for software?
     .clk_o(clocks_o.${k})
   );
+
 % endfor
 
   ////////////////////////////////////////////////////
@@ -176,15 +178,15 @@
   prim_flop_2sync #(
     .Width(1)
   ) i_${k}_hint_sync (
-    .clk_i(clk_${v}_root),
+    .clk_i(clk_${v}_i),
     .rst_ni(rst_${v}_ni),
     .d(reg2hw.clk_hints.${k}_hint.q),
     .q(${k}_hint)
   );
 
-  prim_clock_gating i_${k}_sync (
-    .clk_i(clk_${v}_root),
-    .en_i(${k}_en),
+  prim_clock_gating i_${k}_cg (
+    .clk_i(clk_${v}_i),
+    .en_i(${k}_en & clk_${v}_en),
     .test_en_i(dft_i.test_en),
     .clk_o(clocks_o.${k})
   );
diff --git a/hw/ip/clkmgr/rtl/clkmgr.sv b/hw/ip/clkmgr/rtl/clkmgr.sv
index 0e8d705..f143e3e 100644
--- a/hw/ip/clkmgr/rtl/clkmgr.sv
+++ b/hw/ip/clkmgr/rtl/clkmgr.sv
@@ -55,13 +55,6 @@
     .devmode_i(1'b1)
   );
 
-  ////////////////////////////////////////////////////
-  // Power up group - feedthrough
-  ////////////////////////////////////////////////////
-
-  assign clocks_o.clk_fixed_powerup = clk_fixed_i;
-  assign clocks_o.clk_main_powerup = clk_main_i;
-  assign clocks_o.clk_usb_48mhz_powerup = clk_usb_48mhz_i;
 
   ////////////////////////////////////////////////////
   // Root gating
@@ -80,7 +73,7 @@
   logic clk_usb_48mhz_root;
   logic clk_usb_48mhz_en;
 
-  prim_clock_gating_sync i_main_sync (
+  prim_clock_gating_sync i_main_cg (
     .clk_i(clk_main_i),
     .rst_ni(rst_main_ni),
     .test_en_i(dft_i.test_en),
@@ -88,7 +81,7 @@
     .en_o(clk_main_en),
     .clk_o(clk_main_root)
   );
-  prim_clock_gating_sync i_fixed_sync (
+  prim_clock_gating_sync i_fixed_cg (
     .clk_i(clk_fixed_i),
     .rst_ni(rst_fixed_ni),
     .test_en_i(dft_i.test_en),
@@ -96,7 +89,7 @@
     .en_o(clk_fixed_en),
     .clk_o(clk_fixed_root)
   );
-  prim_clock_gating_sync i_usb_48mhz_sync (
+  prim_clock_gating_sync i_usb_48mhz_cg (
     .clk_i(clk_usb_48mhz_i),
     .rst_ni(rst_usb_48mhz_ni),
     .test_en_i(dft_i.test_en),
@@ -155,24 +148,42 @@
   // the rst_ni connection below is incorrect, need to find a proper reset in the sequence to use
   // if the clkmgr is always on, can use por synced directly
   // if not, then need to generate something ahead of lc/sys
+  logic clk_fixed_peri_sw_en;
+  logic clk_usb_48mhz_peri_sw_en;
 
-  prim_clock_gating_sync i_clk_fixed_peri_sync (
-    .clk_i(clk_fixed_root),
+  prim_flop_2sync #(
+    .Width(1)
+  ) i_clk_fixed_peri_sw_en_sync (
+    .clk_i(clk_fixed_i),
     .rst_ni(rst_fixed_ni),
+    .d(reg2hw.clk_enables.clk_fixed_peri_en.q),
+    .q(clk_fixed_peri_sw_en)
+  );
+
+  prim_clock_gating i_clk_fixed_peri_cg (
+    .clk_i(clk_fixed_i),
+    .en_i(clk_fixed_peri_sw_en & clk_fixed_en),
     .test_en_i(dft_i.test_en),
-    .async_en_i(reg2hw.clk_enables.clk_fixed_peri_en.q),
-    .en_o(), // should this be fedback for software?
     .clk_o(clocks_o.clk_fixed_peri)
   );
-  prim_clock_gating_sync i_clk_usb_48mhz_peri_sync (
-    .clk_i(clk_usb_48mhz_root),
+
+  prim_flop_2sync #(
+    .Width(1)
+  ) i_clk_usb_48mhz_peri_sw_en_sync (
+    .clk_i(clk_usb_48mhz_i),
     .rst_ni(rst_usb_48mhz_ni),
+    .d(reg2hw.clk_enables.clk_usb_48mhz_peri_en.q),
+    .q(clk_usb_48mhz_peri_sw_en)
+  );
+
+  prim_clock_gating i_clk_usb_48mhz_peri_cg (
+    .clk_i(clk_usb_48mhz_i),
+    .en_i(clk_usb_48mhz_peri_sw_en & clk_usb_48mhz_en),
     .test_en_i(dft_i.test_en),
-    .async_en_i(reg2hw.clk_enables.clk_usb_48mhz_peri_en.q),
-    .en_o(), // should this be fedback for software?
     .clk_o(clocks_o.clk_usb_48mhz_peri)
   );
 
+
   ////////////////////////////////////////////////////
   // Software hint group
   // The idle hint feedback is assumed to be synchronous to the
@@ -193,15 +204,15 @@
   prim_flop_2sync #(
     .Width(1)
   ) i_clk_main_aes_hint_sync (
-    .clk_i(clk_main_root),
+    .clk_i(clk_main_i),
     .rst_ni(rst_main_ni),
     .d(reg2hw.clk_hints.clk_main_aes_hint.q),
     .q(clk_main_aes_hint)
   );
 
-  prim_clock_gating i_clk_main_aes_sync (
-    .clk_i(clk_main_root),
-    .en_i(clk_main_aes_en),
+  prim_clock_gating i_clk_main_aes_cg (
+    .clk_i(clk_main_i),
+    .en_i(clk_main_aes_en & clk_main_en),
     .test_en_i(dft_i.test_en),
     .clk_o(clocks_o.clk_main_aes)
   );
@@ -211,15 +222,15 @@
   prim_flop_2sync #(
     .Width(1)
   ) i_clk_main_hmac_hint_sync (
-    .clk_i(clk_main_root),
+    .clk_i(clk_main_i),
     .rst_ni(rst_main_ni),
     .d(reg2hw.clk_hints.clk_main_hmac_hint.q),
     .q(clk_main_hmac_hint)
   );
 
-  prim_clock_gating i_clk_main_hmac_sync (
-    .clk_i(clk_main_root),
-    .en_i(clk_main_hmac_en),
+  prim_clock_gating i_clk_main_hmac_cg (
+    .clk_i(clk_main_i),
+    .en_i(clk_main_hmac_en & clk_main_en),
     .test_en_i(dft_i.test_en),
     .clk_o(clocks_o.clk_main_hmac)
   );
diff --git a/hw/ip/pwrmgr/data/pwrmgr.hjson b/hw/ip/pwrmgr/data/pwrmgr.hjson
index 589c07d..668e142 100644
--- a/hw/ip/pwrmgr/data/pwrmgr.hjson
+++ b/hw/ip/pwrmgr/data/pwrmgr.hjson
@@ -28,7 +28,7 @@
     },
 
     { struct:  "pwr_clk",
-      type:    "uni",
+      type:    "req_rsp",
       name:    "pwr_clk",
       act:     "req",
       package: "pwrmgr_pkg",
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr.sv b/hw/ip/pwrmgr/rtl/pwrmgr.sv
index 8e0b808..2edd8e7 100644
--- a/hw/ip/pwrmgr/rtl/pwrmgr.sv
+++ b/hw/ip/pwrmgr/rtl/pwrmgr.sv
@@ -29,6 +29,7 @@
 
   // clkmgr interface
   output pwr_clk_req_t pwr_clk_o,
+  input  pwr_clk_rsp_t pwr_clk_i,
 
   // otp interface
   input  pwr_otp_rsp_t pwr_otp_i,