[rstmgr, top] Streamline rstmgr controls for software resets Address #3089 Since our reggen tool does not currently support assigning a different reggen per multireg slot, implement this outside in the module. Once we work out that feature from reggen, we should return to change this. Signed-off-by: Timothy Chen <timothytim@google.com> [rstmgr] Add exclusions Signed-off-by: Timothy Chen <timothytim@google.com> [rstmgr] update exclusions once more Signed-off-by: Timothy Chen <timothytim@google.com> [rstmgr] update header generation Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/rstmgr/data/rstmgr.hjson.tpl b/hw/ip/rstmgr/data/rstmgr.hjson.tpl index 15d15a3..bc18fd6 100644 --- a/hw/ip/rstmgr/data/rstmgr.hjson.tpl +++ b/hw/ip/rstmgr/data/rstmgr.hjson.tpl
@@ -204,45 +204,55 @@ # Templated registers for software control ######################## -% for rst in sw_rsts: - { name: "${rst['name'].upper()}_REGEN", - desc: ''' - Register write enable for ${rst['name']} reset. - ''', - swaccess: "rw1c", - hwaccess: "none", - fields: [ - { - bits: "0", - desc: ''' When 1, rst_${rst['name']}_n is software programmable. - ''' - resval: 1, - }, - ] - tags: [// Don't reset other IPs as it will affect CSR access on these IPs - "excl:CsrAllTests:CsrExclWrite"] - }, + { multireg: { + cname: "RSTMGR_SW_RST", + name: "SW_RST_REGEN", + desc: ''' + Register write enable for software controllabe resets. + When a particular bit value is 0, the corresponding value in !SW_RST_CTRL can no longer be changed. + When a particular bit value is 1, the corresponding value in !SW_RST_CTRL can be changed. + ''', + count: ${len(sw_rsts)}, + swaccess: "rw0c", + hwaccess: "hro", + fields: [ + { + bits: "0", + name: "EN", + desc: "Register write enable for software controllable resets", + resval: "1", + tags: [// Don't reset other IPs as it will affect CSR access on these IPs + "excl:CsrAllTests:CsrExclCheck"] + }, + ], + } + } - { name: "RST_${rst['name'].upper()}_N", - regwen: "${rst['name'].upper()}_REGEN", - desc: ''' - Software reset control for ${rst['name']} - ''', - swaccess: "rw", - hwaccess: "hro", - fields: [ - { - bits: "0", - desc: ''' When set to 0, ${rst['name']} is held in reset. This bit can only be - programmed when ${rst['name']}_regen is 1. - ''' - resval: 1, - }, - ] - tags: [// Don't reset other IPs as it will affect CSR access on these IPs - "excl:CsrAllTests:CsrExclWrite"] - }, -% endfor + { multireg: { + cname: "RSTMGR_SW_RST", + name: "SW_RST_CTRL_N", + desc: ''' + Software controllabe resets. + When a particular bit value is 0, the corresponding module is held in reset. + When a particular bit value is 1, the corresponding module is not held in reset. + ''', + count: ${len(sw_rsts)}, + swaccess: "rw", + hwaccess: "hro", + hwext: "true", + hwqe: "true", + fields: [ + { + bits: "0", + name: "VAL", + desc: "Software reset value", + resval: "1", + tags: [// Don't reset other IPs as it will affect CSR access on these IPs + "excl:CsrAllTests:CsrExclCheck"] + }, + ], + } + } ]
diff --git a/hw/ip/rstmgr/data/rstmgr.sv.tpl b/hw/ip/rstmgr/data/rstmgr.sv.tpl index 620020c..43b0dd9 100644 --- a/hw/ip/rstmgr/data/rstmgr.sv.tpl +++ b/hw/ip/rstmgr/data/rstmgr.sv.tpl
@@ -146,6 +146,30 @@ assign pwr_o.rst_lc_src_n = rst_lc_src_n; assign pwr_o.rst_sys_src_n = rst_sys_src_n; + + //////////////////////////////////////////////////// + // Software reset controls external reg // + //////////////////////////////////////////////////// + logic [${len(sw_rsts)}-1:0] sw_rst_ctrl_n; + + for (genvar i=0; i < ${len(sw_rsts)}; i++) begin : gen_sw_rst_ext_regs + prim_subreg #( + .DW(1), + .SWACCESS("RW"), + .RESVAL(1) + ) u_rst_sw_ctrl_reg ( + .clk_i, + .rst_ni(local_rst_n), + .we(reg2hw.sw_rst_ctrl_n[i].qe & reg2hw.sw_rst_regen[i]), + .wd(reg2hw.sw_rst_ctrl_n[i].q), + .de('0), + .d('0), + .qe(), + .q(sw_rst_ctrl_n[i]), + .qs(hw2reg.sw_rst_ctrl_n[i].d) + ); + end + //////////////////////////////////////////////////// // leaf reset in the system // // These should all be generated // @@ -165,7 +189,7 @@ .rst_ni(rst_${rst['parent']}_n), % endif % if "sw" in rst: - .d_i(reg2hw.rst_${rst['name']}_n.q), + .d_i(sw_rst_ctrl_n[${rst['name'].upper()}]), % else: .d_i(1'b1), % endif
diff --git a/hw/ip/rstmgr/data/rstmgr_pkg.sv.tpl b/hw/ip/rstmgr/data/rstmgr_pkg.sv.tpl index b40fafa..538c5a1 100644 --- a/hw/ip/rstmgr/data/rstmgr_pkg.sv.tpl +++ b/hw/ip/rstmgr/data/rstmgr_pkg.sv.tpl
@@ -18,8 +18,10 @@ // calculated domains parameter int OffDomains = PowerDomains-1; - // low power exit + ndm_reset_req + external reasons - //parameter int ResetReasons = 1 + 1 + HwResetReqs; + // positions of software controllable reset bits +% for rst in sw_rsts: + parameter int ${rst['name'].upper()} = ${loop.index}; +% endfor // ast interface typedef struct packed {
diff --git a/hw/top_earlgrey/data/top_earlgrey.h.tpl b/hw/top_earlgrey/data/top_earlgrey.h.tpl index 1343122..3d94a52 100644 --- a/hw/top_earlgrey/data/top_earlgrey.h.tpl +++ b/hw/top_earlgrey/data/top_earlgrey.h.tpl
@@ -150,6 +150,11 @@ */ ${helper.pwrmgr_wakeups.render()} +/** + * Reset Manager Software Controlled Resets + */ +${helper.rstmgr_sw_rsts.render()} + // Header Extern Guard #ifdef __cplusplus } // extern "C"
diff --git a/util/topgen/c.py b/util/topgen/c.py index 77ec472..d98e16d 100644 --- a/util/topgen/c.py +++ b/util/topgen/c.py
@@ -139,6 +139,7 @@ self._init_alert_mapping() self._init_pinmux_mapping() self._init_pwrmgr_wakeups() + self._init_rstmgr_sw_rsts() def modules(self): return [(m["name"], @@ -368,3 +369,17 @@ enum.add_last_constant("Last valid pwrmgr wakeup signal") self.pwrmgr_wakeups = enum + + # Enumerates the positions of all software controllable resets + def _init_rstmgr_sw_rsts(self): + sw_rsts = [rst for rst in self.top["resets"]["nodes"] if 'sw' in rst + and rst['sw'] == 1] + + enum = CEnum(self._top_name + Name(["reset", "manager", "sw", "resets"])) + + for rst in sw_rsts: + enum.add_constant(Name.from_snake_case(rst["name"])) + + enum.add_last_constant("Last valid rstmgr software reset request") + + self.rstmgr_sw_rsts = enum