[pinmux] This updates the pinmux hjson file with sleep features

Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl.hjson b/hw/ip/flash_ctrl/data/flash_ctrl.hjson
index 64d7b87..377dfd6 100644
--- a/hw/ip/flash_ctrl/data/flash_ctrl.hjson
+++ b/hw/ip/flash_ctrl/data/flash_ctrl.hjson
@@ -143,6 +143,8 @@
         },
       ]
     },
+
+// TODO(#1412):
 // This multireg is temporarily removed until the nested multireg compact feature is fully implemented.
 // Until then, use only one register wen for all flash regions.
 // Another alternative solution is to move flash into topgen, this may have to be done anyways.
diff --git a/hw/ip/pinmux/data/pinmux.hjson b/hw/ip/pinmux/data/pinmux.hjson
index e4b2990..e1e7eac 100644
--- a/hw/ip/pinmux/data/pinmux.hjson
+++ b/hw/ip/pinmux/data/pinmux.hjson
@@ -5,36 +5,129 @@
 # PINMUX register template
 #
 # Parameter (given by Python tool)
-#  - n_periph_in:     Number of peripheral inputs
-#  - n_periph_out:    Number of peripheral outputs
-#  - n_mio_pads:      Number of muxed IO pads
-#
+#  - n_mio_periph_in:     Number of muxed peripheral inputs
+#  - n_mio_periph_out:    Number of muxed peripheral outputs
+#  - n_mio_pads:          Number of muxed IO pads
+#  - n_dio_periph_in:     Number of dedicated peripheral inputs
+#  - n_dio_periph_out:    Number of dedicated peripheral outputs
+#  - n_dio_pads:          Number of dedicated IO pads
+#  - n_wkup_detect:       Number of wakeup condition detectors
+#  - wkup_cnt_width:      Width of wakeup counters
+# 
 {
   name: "PINMUX",
   clock_primary: "clk_i",
+  reset_primary: "rst_ni",
+  other_clock_list: [
+    "clk_aon_i",
+  ],
+  other_reset_list:
+  [
+    "rst_aon_ni"
+  ],
   bus_device: "tlul",
   regwidth: "32",
+
+  inter_signal_list: [
+    // Define lc <-> pinmux signal for strap sampling
+    { struct:  "lc_pinmux_strap",
+      type:    "req_rsp",
+      name:    "lc_pinmux_strap",
+      act:     "rsp",
+      package: "pinmux_pkg",
+    }
+    // Define pwr mgr <-> pinmux signals
+    { struct:  "logic",
+      type:    "uni",
+      name:    "sleep_en",
+      act:     "rcv",
+      package: ""
+    },
+    { struct:  "logic",
+      type:    "uni",
+      name:    "aon_wkup_req",
+      act:     "req",
+      package: ""
+    },
+  ]
+
   param_list: [
-    { name: "NPeriphIn",
-      desc: "Number of peripheral inputs",
+    { name: "NMioPeriphIn",
+      desc: "Number of muxed peripheral inputs",
       type: "int",
-      default: "16",
+      default: "32",
       local: "true"
     },
-    { name: "NPeriphOut",
-      desc: "Number of peripheral outputs",
+    { name: "NMioPeriphOut",
+      desc: "Number of muxed peripheral outputs",
       type: "int",
-      default: "16",
+      default: "32",
       local: "true"
     },
     { name: "NMioPads",
       desc: "Number of muxed IO pads",
       type: "int",
+      default: "32",
+      local: "true"
+    },
+    { name: "NDioPads",
+      desc: "Number of dedicated IO pads",
+      type: "int",
+      default: "16",
+      local: "true"
+    },
+    { name: "NWkupDetect",
+      desc: "Number of wakeup detectors",
+      type: "int",
       default: "8",
       local: "true"
     },
+    { name: "WkupCntWidth",
+      desc: "Number of wakeup counter bits",
+      type: "int",
+      default: "8",
+      local: "true"
+    },
+    // TODO: Enable these once supported by topgen and the C header generation script.
+    // These parameters are currently located in pinmux_pkg.sv
+    // // If a bit is set to 1 in this vector, this MIO activates low power
+    // // behavior when going to sleep.
+    // { name: "MioPeriphHasSleepMode",
+    //   desc: '''
+    //         Indicates whether a MIO channel activates low power behavior
+    //         when going to sleep.
+    //         '''
+    //   type: "logic [NMioPeriphOut-1:0]",
+    //   // TODO: need to generate this via topgen
+    //   default: "'1",
+    //   local: "true"
+    // },
+    // // If a bit is set to 1 in this vector, this DIO activates low power
+    // // behavior when going to sleep.
+    // { name: "DioPeriphHasSleepMode",
+    //   desc: '''
+    //         Indicates whether a DIO channel activates low power behavior
+    //         when going to sleep.
+    //         ''',
+    //   type: "logic [NDioPads-1:0]",
+    //   // TODO: need to generate this via topgen
+    //   default: "'1",
+    //   local: "true"
+    // },
+    // // If a bit is set to 1 in this vector, wakeup detectors are connected
+    // // to this DIO.
+    // { name: "DioPeriphHasWkup",
+    //   desc: "Indicates which DIOs shall be connected to the WakeupDetectors.",
+    //   type: "logic [NDioPads-1:0]",
+    //   // TODO: need to generate this via topgen
+    //   default: "'1",
+    //   local: "true"
+    // },
   ],
   registers: [
+    // TODO(#1412): this register enable signal should be split into multiregs such that
+    // each pin / peripheral select can be locked down individually. this needs support
+    // for compact, nested multireg enable registers in our regtool.
     { name: "REGEN",
       desc: '''
             Register write enable for all control registers.
@@ -44,6 +137,7 @@
       fields: [
         {
             bits:   "0",
+            name: "wen",
             desc: ''' When true, all configuration registers can be modified.
             When false, they become read-only. Defaults true, write zero to clear.
             '''
@@ -52,21 +146,22 @@
       ]
     },
 # inputs
-    { multireg: { name:     "PERIPH_INSEL",
+    { multireg: { name:     "PERIPH_INSEL", // TODO: update this name to MIO_PERIPH_INSEL
                   desc:     "Mux select for peripheral inputs.",
-                  count:    "NPeriphIn",
+                  count:    "NMioPeriphIn",
                   swaccess: "rw",
                   hwaccess: "hro",
                   regwen:   "REGEN",
                   cname:    "IN",
                   fields: [
-                    { bits: "3:0",
+                    { bits: "5:0",
                       name: "IN",
                       desc: '''
-                      0: tie constantly to zero, 1: tie constantly to 1.
+                      0: tie constantly to zero, 1: tie constantly to 1,
                       >=2: MIO pads (i.e., add 2 to the native MIO pad index).
                       '''
                       resval: 0,
+                      // TODO: is this exclusion still required?
                       tags: [// Random writes to this field may result in array index going OOB.
                              "excl:CsrNonInitTests:CsrExclWriteCheck"]
                     }
@@ -82,18 +177,268 @@
                   regwen:   "REGEN",
                   cname:    "OUT",
                   fields: [
-                    { bits: "4:0",
+                    { bits: "5:0",
                       name: "OUT",
                       desc: '''
-                      0: tie constantly to zero, 1: tie constantly to 1. 2: high-Z
+                      0: tie constantly to zero, 1: tie constantly to 1, 2: high-Z,
                       >=3: peripheral outputs (i.e., add 3 to the native peripheral pad index).
                       '''
                       resval: 2,
+                      // TODO: is this exclusion still required?
                       tags: [// Random writes to this field may result in array index going OOB.
                              "excl:CsrNonInitTests:CsrExclWriteCheck"]
                     }
                   ]
                 }
     },
+# sleep behavior of MIO peripheral outputs
+# TODO: add individual sleep disable bits
+    { multireg: { name:     "MIO_OUT_SLEEP_VAL",
+                  desc:     '''Defines sleep behavior of muxed output or inout. Note that
+                            the MIO output will only switch into sleep mode if the the corresponding
+                            !!MIO_OUTSEL is either set to 0-2, or if !!MIO_OUTSEL selects a peripheral
+                            output that can go into sleep. If an always on peripheral is selected with
+                            !!MIO_OUTSEL, the !!MIO_OUT_SLEEP_VAL configuration has no effect.
+                            '''
+                  count:    "NMioPads",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "OUT",
+                  fields: [
+                    { bits: "1:0",
+                      name: "OUT",
+                      resval: 2,
+                      desc:"Value to drive in deep sleep."
+                      enum: [
+                        { value: "0",
+                          name: "Tie-Low",
+                          desc: "The pin is driven actively to zero in deep sleep mode."
+                        },
+                        { value: "1",
+                          name: "Tie-High",
+                          desc: "The pin is driven actively to one in deep sleep mode."
+                        },
+                        { value: "2",
+                          name: "High-Z",
+                          desc: '''
+                            The pin is left undriven in deep sleep mode. Note that the actual
+                            driving behavior during deep sleep will then depend on the pull-up/-down
+                            configuration of padctrl.
+                            '''
+                        },
+                        { value: "3",
+                          name: "Keep",
+                          desc: "Keep last driven value (including high-Z)."
+                        },
+                      ]
+                    }
+                  ]
+                }
+    },
+# sleep behavior of DIO peripheral outputs
+# TODO: add individual sleep disable bits
+    { multireg: { name:     "DIO_OUT_SLEEP_VAL",
+                  desc:     '''Defines sleep behavior of dedicated output or inout. Note this
+                            register has WARL behavior since the sleep value settings are
+                            meaningless for always-on and input-only DIOs. For these DIOs,
+                            this register always reads 0.
+                            '''
+                  count:    "NDioPads",
+                  swaccess: "rw",
+                  hwaccess: "hrw",
+                  hwext:    "true",
+                  hwqe:     "true",
+                  regwen:   "REGEN",
+                  cname:    "OUT",
+                  fields: [
+                    { bits: "1:0",
+                      name: "OUT",
+                      resval: 2,
+                      desc:"Value to drive in deep sleep."
+                      enum: [
+                        { value: "0",
+                          name: "Tie-Low",
+                          desc: "The pin is driven actively to zero in deep sleep mode."
+                        },
+                        { value: "1",
+                          name: "Tie-High",
+                          desc: "The pin is driven actively to one in deep sleep mode."
+                        },
+                        { value: "2",
+                          name: "High-Z",
+                          desc: '''
+                            The pin is left undriven in deep sleep mode. Note that the actual
+                            driving behavior during deep sleep will then depend on the pull-up/-down
+                            configuration of padctrl.
+                            '''
+                        },
+                        { value: "3",
+                          name: "Keep",
+                          desc: "Keep last driven value (including high-Z)."
+                        },
+                      ]
+                    }
+                  ]
+                  // these CSRs have WARL behavior and may not
+                  // read back the same value that was written to them.
+                  tags: ["excl:CsrAllTests:CsrExclWriteCheck"]
+                }
+    },
+# wakeup detector enables
+    { multireg: { name:     "WKUP_DETECTOR_EN",
+                  desc:     "Enables for the wakeup detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "0:0",
+                      name: "EN",
+                      resval: 0,
+                      desc: '''
+                      Setting this bit activates the corresponding wakeup detector.
+                      The behavior is as specified in !!WKUP_DETECTOR,
+                      !!WKUP_DETECTOR_CNT_TH and !!WKUP_DETECTOR_PADSEL.
+                      '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector config
+    { multireg: { name:     "WKUP_DETECTOR",
+                  desc:     "Configuration of wakeup condition detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "2:0",
+                      name: "MODE",
+                      resval: 0,
+                      desc: "Wakeup detection mode."
+                      enum: [
+                        { value: "0",
+                          name: "Disabled",
+                          desc: "Pin wakeup detector is disabled."
+                        },
+                        { value: "1",
+                          name: "Negedge",
+                          desc: "Trigger a wakeup request when observing a negative edge."
+                        },
+                        { value: "2",
+                          name: "Posedge",
+                          desc: "Trigger a wakeup request when observing a positive edge."
+                        },
+                        { value: "3",
+                          name: "Edge",
+                          desc: "Trigger a wakeup request when observing an edge in any direction."
+                        },
+                        { value: "4",
+                          name: "TimedLow",
+                          desc: '''
+                            Trigger a wakeup request when pin is driven LOW for a certain amount
+                            of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH.
+                            '''
+                        },
+                        { value: "5",
+                          name: "TimedHigh",
+                          desc: '''
+                            Trigger a wakeup request when pin is driven HIGH for a certain amount
+                            of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH.
+                            '''
+                        },
+                      ]
+                    }
+                    { bits: "3",
+                      name: "FILTER",
+                      resval: 0,
+                      desc: '''0: signal filter disabled, 1: signal filter enabled. the signal must
+                        be stable for 4 always-on clock cycles before the value is being forwarded.
+                        can be used for debouncing.
+                        '''
+                    }
+                    { bits: "4",
+                      name: "MIODIO",
+                      resval: 0,
+                      desc: '''0: select index !!WKUP_DETECTOR_PADSEL from MIO pads,
+                        1: select index !!WKUP_DETECTOR_PADSEL from DIO pads.
+                        '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector count thresholds
+    { multireg: { name:     "WKUP_DETECTOR_CNT_TH",
+                  desc:     "Counter thresholds for wakeup condition detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "WkupCntWidth-1:0",
+                      name: "TH",
+                      resval: 0,
+                      desc: '''Counter threshold for TimedLow and TimedHigh wakeup detector modes (see !!WKUP_DETECTOR).
+                      The threshold is in terms of always-on clock cycles.
+                      '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector pad selectors
+    { multireg: { name:     "WKUP_DETECTOR_PADSEL",
+                  desc:     "Pad selects for pad wakeup condition detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "4:0",
+                      name: "SEL",
+                      resval: 0,
+                      desc: '''Selects a specific MIO or DIO pad (depending on !!WKUP_DETECTOR configuration).
+                      In case of MIO, the pad select index is the same as used for !!PERIPH_INSEL, meaning that index
+                      0 and 1 just select constant 0, and the MIO pads live at indices >= 2. In case of DIO pads,
+                      the pad select index corresponds 1:1 to the DIO pad to be selected.
+                      '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector cause regs
+    { multireg: { name:     "WKUP_CAUSE",
+                  desc:     "Cause registers for wakeup detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw0c",
+                  hwaccess: "hrw",
+                  hwext:    "true",
+                  hwqe:     "true",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "0",
+                      name: "CAUSE",
+                      resval: 0,
+                      desc: '''Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear.
+                      '''
+                    }
+                  ]
+                  // these CSRs live in the slow AON clock domain and
+                  // clearing them will be very slow and the changes
+                  // are not immediately visible.
+                  tags: ["excl:CsrAllTests:CsrExclWriteCheck"]
+                }
+
+    },
   ],
 }
+
diff --git a/hw/ip/pinmux/data/pinmux.hjson.tpl b/hw/ip/pinmux/data/pinmux.hjson.tpl
index 604ddb2..764b1dc 100644
--- a/hw/ip/pinmux/data/pinmux.hjson.tpl
+++ b/hw/ip/pinmux/data/pinmux.hjson.tpl
@@ -5,26 +5,63 @@
 # PINMUX register template
 #
 # Parameter (given by Python tool)
-#  - n_periph_in:     Number of peripheral inputs
-#  - n_periph_out:    Number of peripheral outputs
-#  - n_mio_pads:      Number of muxed IO pads
+#  - n_mio_periph_in:     Number of muxed peripheral inputs
+#  - n_mio_periph_out:    Number of muxed peripheral outputs
+#  - n_mio_pads:          Number of muxed IO pads
+#  - n_dio_periph_in:     Number of dedicated peripheral inputs
+#  - n_dio_periph_out:    Number of dedicated peripheral outputs
+#  - n_dio_pads:          Number of dedicated IO pads
+#  - n_wkup_detect:       Number of wakeup condition detectors
+#  - wkup_cnt_width:      Width of wakeup counters
 # <% import math %>
 {
   name: "PINMUX",
   clock_primary: "clk_i",
+  reset_primary: "rst_ni",
+  other_clock_list: [
+    "clk_aon_i",
+  ],
+  other_reset_list:
+  [
+    "rst_aon_ni"
+  ],
   bus_device: "tlul",
   regwidth: "32",
+
+  inter_signal_list: [
+    // Define lc <-> pinmux signal for strap sampling
+    { struct:  "lc_pinmux_strap",
+      type:    "req_rsp",
+      name:    "lc_pinmux_strap",
+      act:     "rsp",
+      package: "pinmux_pkg",
+    }
+    // Define pwr mgr <-> pinmux signals
+    { struct:  "logic",
+      type:    "uni",
+      name:    "sleep_en",
+      act:     "rcv",
+      package: ""
+    },
+    { struct:  "logic",
+      type:    "uni",
+      name:    "aon_wkup_req",
+      act:     "req",
+      package: ""
+    },
+  ]
+
   param_list: [
-    { name: "NPeriphIn",
-      desc: "Number of peripheral inputs",
+    { name: "NMioPeriphIn",
+      desc: "Number of muxed peripheral inputs",
       type: "int",
-      default: "${n_periph_in}",
+      default: "${n_mio_periph_in}",
       local: "true"
     },
-    { name: "NPeriphOut",
-      desc: "Number of peripheral outputs",
+    { name: "NMioPeriphOut",
+      desc: "Number of muxed peripheral outputs",
       type: "int",
-      default: "${n_periph_out}",
+      default: "${n_mio_periph_out}",
       local: "true"
     },
     { name: "NMioPads",
@@ -33,8 +70,64 @@
       default: "${n_mio_pads}",
       local: "true"
     },
+    { name: "NDioPads",
+      desc: "Number of dedicated IO pads",
+      type: "int",
+      default: "${n_dio_pads}",
+      local: "true"
+    },
+    { name: "NWkupDetect",
+      desc: "Number of wakeup detectors",
+      type: "int",
+      default: "${n_wkup_detect}",
+      local: "true"
+    },
+    { name: "WkupCntWidth",
+      desc: "Number of wakeup counter bits",
+      type: "int",
+      default: "${wkup_cnt_width}",
+      local: "true"
+    },
+    // TODO: Enable these once supported by topgen and the C header generation script.
+    // These parameters are currently located in pinmux_pkg.sv
+    // // If a bit is set to 1 in this vector, this MIO activates low power
+    // // behavior when going to sleep.
+    // { name: "MioPeriphHasSleepMode",
+    //   desc: '''
+    //         Indicates whether a MIO channel activates low power behavior
+    //         when going to sleep.
+    //         '''
+    //   type: "logic [NMioPeriphOut-1:0]",
+    //   // TODO: need to generate this via topgen
+    //   default: "'1",
+    //   local: "true"
+    // },
+    // // If a bit is set to 1 in this vector, this DIO activates low power
+    // // behavior when going to sleep.
+    // { name: "DioPeriphHasSleepMode",
+    //   desc: '''
+    //         Indicates whether a DIO channel activates low power behavior
+    //         when going to sleep.
+    //         ''',
+    //   type: "logic [NDioPads-1:0]",
+    //   // TODO: need to generate this via topgen
+    //   default: "'1",
+    //   local: "true"
+    // },
+    // // If a bit is set to 1 in this vector, wakeup detectors are connected
+    // // to this DIO.
+    // { name: "DioPeriphHasWkup",
+    //   desc: "Indicates which DIOs shall be connected to the WakeupDetectors.",
+    //   type: "logic [NDioPads-1:0]",
+    //   // TODO: need to generate this via topgen
+    //   default: "'1",
+    //   local: "true"
+    // },
   ],
   registers: [
+    // TODO(#1412): this register enable signal should be split into multiregs such that
+    // each pin / peripheral select can be locked down individually. this needs support
+    // for compact, nested multireg enable registers in our regtool.
     { name: "REGEN",
       desc: '''
             Register write enable for all control registers.
@@ -53,9 +146,9 @@
       ]
     },
 # inputs
-    { multireg: { name:     "PERIPH_INSEL",
+    { multireg: { name:     "PERIPH_INSEL", // TODO: update this name to MIO_PERIPH_INSEL
                   desc:     "Mux select for peripheral inputs.",
-                  count:    "NPeriphIn",
+                  count:    "NMioPeriphIn",
                   swaccess: "rw",
                   hwaccess: "hro",
                   regwen:   "REGEN",
@@ -64,10 +157,11 @@
                     { bits: "${(n_mio_pads+1).bit_length()-1}:0",
                       name: "IN",
                       desc: '''
-                      0: tie constantly to zero, 1: tie constantly to 1.
+                      0: tie constantly to zero, 1: tie constantly to 1,
                       >=2: MIO pads (i.e., add 2 to the native MIO pad index).
                       '''
                       resval: 0,
+                      // TODO: is this exclusion still required?
                       tags: [// Random writes to this field may result in array index going OOB.
                              "excl:CsrNonInitTests:CsrExclWriteCheck"]
                     }
@@ -83,18 +177,267 @@
                   regwen:   "REGEN",
                   cname:    "OUT",
                   fields: [
-                    { bits: "${(n_periph_out+2).bit_length()-1}:0",
+                    { bits: "${(n_mio_periph_out+2).bit_length()-1}:0",
                       name: "OUT",
                       desc: '''
-                      0: tie constantly to zero, 1: tie constantly to 1. 2: high-Z
+                      0: tie constantly to zero, 1: tie constantly to 1, 2: high-Z,
                       >=3: peripheral outputs (i.e., add 3 to the native peripheral pad index).
                       '''
                       resval: 2,
+                      // TODO: is this exclusion still required?
                       tags: [// Random writes to this field may result in array index going OOB.
                              "excl:CsrNonInitTests:CsrExclWriteCheck"]
                     }
                   ]
                 }
     },
+# sleep behavior of MIO peripheral outputs
+# TODO: add individual sleep disable bits
+    { multireg: { name:     "MIO_OUT_SLEEP_VAL",
+                  desc:     '''Defines sleep behavior of muxed output or inout. Note that
+                            the MIO output will only switch into sleep mode if the the corresponding
+                            !!MIO_OUTSEL is either set to 0-2, or if !!MIO_OUTSEL selects a peripheral
+                            output that can go into sleep. If an always on peripheral is selected with
+                            !!MIO_OUTSEL, the !!MIO_OUT_SLEEP_VAL configuration has no effect.
+                            '''
+                  count:    "NMioPads",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "OUT",
+                  fields: [
+                    { bits: "1:0",
+                      name: "OUT",
+                      resval: 2,
+                      desc:"Value to drive in deep sleep."
+                      enum: [
+                        { value: "0",
+                          name: "Tie-Low",
+                          desc: "The pin is driven actively to zero in deep sleep mode."
+                        },
+                        { value: "1",
+                          name: "Tie-High",
+                          desc: "The pin is driven actively to one in deep sleep mode."
+                        },
+                        { value: "2",
+                          name: "High-Z",
+                          desc: '''
+                            The pin is left undriven in deep sleep mode. Note that the actual
+                            driving behavior during deep sleep will then depend on the pull-up/-down
+                            configuration of padctrl.
+                            '''
+                        },
+                        { value: "3",
+                          name: "Keep",
+                          desc: "Keep last driven value (including high-Z)."
+                        },
+                      ]
+                    }
+                  ]
+                }
+    },
+# sleep behavior of DIO peripheral outputs
+# TODO: add individual sleep disable bits
+    { multireg: { name:     "DIO_OUT_SLEEP_VAL",
+                  desc:     '''Defines sleep behavior of dedicated output or inout. Note this
+                            register has WARL behavior since the sleep value settings are
+                            meaningless for always-on and input-only DIOs. For these DIOs,
+                            this register always reads 0.
+                            '''
+                  count:    "NDioPads",
+                  swaccess: "rw",
+                  hwaccess: "hrw",
+                  hwext:    "true",
+                  hwqe:     "true",
+                  regwen:   "REGEN",
+                  cname:    "OUT",
+                  fields: [
+                    { bits: "1:0",
+                      name: "OUT",
+                      resval: 2,
+                      desc:"Value to drive in deep sleep."
+                      enum: [
+                        { value: "0",
+                          name: "Tie-Low",
+                          desc: "The pin is driven actively to zero in deep sleep mode."
+                        },
+                        { value: "1",
+                          name: "Tie-High",
+                          desc: "The pin is driven actively to one in deep sleep mode."
+                        },
+                        { value: "2",
+                          name: "High-Z",
+                          desc: '''
+                            The pin is left undriven in deep sleep mode. Note that the actual
+                            driving behavior during deep sleep will then depend on the pull-up/-down
+                            configuration of padctrl.
+                            '''
+                        },
+                        { value: "3",
+                          name: "Keep",
+                          desc: "Keep last driven value (including high-Z)."
+                        },
+                      ]
+                    }
+                  ]
+                  // these CSRs have WARL behavior and may not
+                  // read back the same value that was written to them.
+                  tags: ["excl:CsrAllTests:CsrExclWriteCheck"]
+                }
+    },
+# wakeup detector enables
+    { multireg: { name:     "WKUP_DETECTOR_EN",
+                  desc:     "Enables for the wakeup detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "0:0",
+                      name: "EN",
+                      resval: 0,
+                      desc: '''
+                      Setting this bit activates the corresponding wakeup detector.
+                      The behavior is as specified in !!WKUP_DETECTOR,
+                      !!WKUP_DETECTOR_CNT_TH and !!WKUP_DETECTOR_PADSEL.
+                      '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector config
+    { multireg: { name:     "WKUP_DETECTOR",
+                  desc:     "Configuration of wakeup condition detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "2:0",
+                      name: "MODE",
+                      resval: 0,
+                      desc: "Wakeup detection mode."
+                      enum: [
+                        { value: "0",
+                          name: "Disabled",
+                          desc: "Pin wakeup detector is disabled."
+                        },
+                        { value: "1",
+                          name: "Negedge",
+                          desc: "Trigger a wakeup request when observing a negative edge."
+                        },
+                        { value: "2",
+                          name: "Posedge",
+                          desc: "Trigger a wakeup request when observing a positive edge."
+                        },
+                        { value: "3",
+                          name: "Edge",
+                          desc: "Trigger a wakeup request when observing an edge in any direction."
+                        },
+                        { value: "4",
+                          name: "TimedLow",
+                          desc: '''
+                            Trigger a wakeup request when pin is driven LOW for a certain amount
+                            of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH.
+                            '''
+                        },
+                        { value: "5",
+                          name: "TimedHigh",
+                          desc: '''
+                            Trigger a wakeup request when pin is driven HIGH for a certain amount
+                            of always-on clock cycles as configured in !!WKUP_DETECTOR_CNT_TH.
+                            '''
+                        },
+                      ]
+                    }
+                    { bits: "3",
+                      name: "FILTER",
+                      resval: 0,
+                      desc: '''0: signal filter disabled, 1: signal filter enabled. the signal must
+                        be stable for 4 always-on clock cycles before the value is being forwarded.
+                        can be used for debouncing.
+                        '''
+                    }
+                    { bits: "4",
+                      name: "MIODIO",
+                      resval: 0,
+                      desc: '''0: select index !!WKUP_DETECTOR_PADSEL from MIO pads,
+                        1: select index !!WKUP_DETECTOR_PADSEL from DIO pads.
+                        '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector count thresholds
+    { multireg: { name:     "WKUP_DETECTOR_CNT_TH",
+                  desc:     "Counter thresholds for wakeup condition detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "WkupCntWidth-1:0",
+                      name: "TH",
+                      resval: 0,
+                      desc: '''Counter threshold for TimedLow and TimedHigh wakeup detector modes (see !!WKUP_DETECTOR).
+                      The threshold is in terms of always-on clock cycles.
+                      '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector pad selectors
+    { multireg: { name:     "WKUP_DETECTOR_PADSEL",
+                  desc:     "Pad selects for pad wakeup condition detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw",
+                  hwaccess: "hro",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "${max(n_mio_pads-1, n_dio_periph_in-1).bit_length()-1}:0",
+                      name: "SEL",
+                      resval: 0,
+                      desc: '''Selects a specific MIO or DIO pad (depending on !!WKUP_DETECTOR configuration).
+                      In case of MIO, the pad select index is the same as used for !!PERIPH_INSEL, meaning that index
+                      0 and 1 just select constant 0, and the MIO pads live at indices >= 2. In case of DIO pads,
+                      the pad select index corresponds 1:1 to the DIO pad to be selected.
+                      '''
+                    }
+                  ]
+                }
+
+    },
+# wakeup detector cause regs
+    { multireg: { name:     "WKUP_CAUSE",
+                  desc:     "Cause registers for wakeup detectors."
+                  count:    "NWkupDetect",
+                  swaccess: "rw0c",
+                  hwaccess: "hrw",
+                  hwext:    "true",
+                  hwqe:     "true",
+                  regwen:   "REGEN",
+                  cname:    "DETECTOR",
+                  fields: [
+                    { bits: "0",
+                      name: "CAUSE",
+                      resval: 0,
+                      desc: '''Set to 1 if the corresponding detector has detected a wakeup pattern. Write 0 to clear.
+                      '''
+                    }
+                  ]
+                  // these CSRs live in the slow AON clock domain and
+                  // clearing them will be very slow and the changes
+                  // are not immediately visible.
+                  tags: ["excl:CsrAllTests:CsrExclWriteCheck"]
+                }
+
+    },
   ],
 }
diff --git a/hw/ip/pinmux/util/reg_pinmux.py b/hw/ip/pinmux/util/reg_pinmux.py
index 856d9be..4bb6e93 100755
--- a/hw/ip/pinmux/util/reg_pinmux.py
+++ b/hw/ip/pinmux/util/reg_pinmux.py
@@ -19,17 +19,37 @@
                         type=argparse.FileType('r'),
                         default=sys.stdin,
                         help='input template file')
-    parser.add_argument('--n_periph_in',
+    parser.add_argument('--n_mio_periph_in',
                         type=int,
-                        help='Number of peripheral inputs',
-                        default = 16)
-    parser.add_argument('--n_periph_out',
+                        help='Number of muxed peripheral inputs',
+                        default = 32)
+    parser.add_argument('--n_mio_periph_out',
                         type=int,
-                        help='Number of peripheral outputs',
-                        default = 16)
+                        help='Number of muxed peripheral outputs',
+                        default = 32)
     parser.add_argument('--n_mio_pads',
                         type=int,
                         help='Number of muxed IO pads',
+                        default = 32)
+    parser.add_argument('--n_dio_periph_in',
+                        type=int,
+                        help='Number of dedicated peripheral inputs',
+                        default = 16)
+    parser.add_argument('--n_dio_periph_out',
+                        type=int,
+                        help='Number of dedicated peripheral outputs',
+                        default = 16)
+    parser.add_argument('--n_dio_pads',
+                        type=int,
+                        help='Number of dedicated IO pads',
+                        default = 16)
+    parser.add_argument('--n_wkup_detect',
+                        type=int,
+                        help='Number of wakeup condition detectors',
+                        default = 8)
+    parser.add_argument('--wkup_cnt_width',
+                        type=int,
+                        help='With of wakeup counters',
                         default = 8)
 
     args = parser.parse_args()
@@ -39,9 +59,14 @@
 
     reg_tpl = Template(args.input.read())
     out.write(
-        reg_tpl.render(n_periph_in=args.n_periph_in,
-                       n_periph_out=args.n_periph_out,
-                       n_mio_pads=args.n_mio_pads))
+        reg_tpl.render(n_mio_periph_in=args.n_mio_periph_in,
+                       n_mio_periph_out=args.n_mio_periph_out,
+                       n_mio_pads=args.n_mio_pads,
+                       n_dio_periph_in=args.n_dio_periph_in,
+                       n_dio_periph_out=args.n_dio_periph_out,
+                       n_dio_pads=args.n_dio_pads,
+                       n_wkup_detect=args.n_wkup_detect,
+                       wkup_cnt_width=args.wkup_cnt_width))
 
     print(out.getvalue())