Skip to content

Commit 13fe1f3

Browse files
committed
[ot] hw/opentitan: ot_pwrmgr: fix multi top support
Fix constant definitions and bitfields that were still hardcoded for a specific top (likely EarlGrey) Replace some constants with top-dependent macros Defer creation of reset request lines to the realize function, as the number of reset active lines are not know before this execution point. Signed-off-by: Emmanuel Blot <[email protected]>
1 parent 61d88f6 commit 13fe1f3

File tree

2 files changed

+52
-51
lines changed

2 files changed

+52
-51
lines changed

hw/opentitan/ot_pwrmgr.c

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@
4545
#include "sysemu/runstate.h"
4646
#include "trace.h"
4747

48-
#define PARAM_NUM_RST_REQS 2u
49-
#define PARAM_NUM_INT_RST_REQS 2u
50-
#define PARAM_NUM_DEBUG_RST_REQS 1u
51-
#define PARAM_RESET_MAIN_PWR_IDX 2u
52-
#define PARAM_RESET_ESC_IDX 3u
53-
#define PARAM_RESET_NDM_IDX 4u
54-
#define PARAM_NUM_ALERTS 1u
48+
#define NUM_INT_RST_REQS 2u
49+
#define NUM_DEBUG_RST_REQS 1u
50+
#define NUM_SW_RST_REQ 1u
51+
#define NUM_ALERTS 1u
52+
#define RESET_MAIN_PWR_IDX 2u
53+
#define RESET_ESC_IDX 3u
54+
#define RESET_NDM_IDX 4u
5555

5656
/* clang-format off */
5757
REG32(INTR_STATE, 0x0u)
@@ -74,12 +74,7 @@ REG32(CFG_CDC_SYNC, 0x18u)
7474
REG32(WAKEUP_EN_REGWEN, 0x1cu)
7575
FIELD(WAKEUP_EN_REGWEN, EN, 0u, 1u)
7676
REG32(WAKEUP_EN, 0x20u)
77-
SHARED_FIELD(WAKEUP_CHANNEL_0, 0u, 1u)
78-
SHARED_FIELD(WAKEUP_CHANNEL_1, 1u, 1u)
79-
SHARED_FIELD(WAKEUP_CHANNEL_2, 2u, 1u)
80-
SHARED_FIELD(WAKEUP_CHANNEL_3, 3u, 1u)
81-
SHARED_FIELD(WAKEUP_CHANNEL_4, 4u, 1u)
82-
SHARED_FIELD(WAKEUP_CHANNEL_5, 5u, 1u)
77+
/* note: wake up channel count depends on top */
8378
REG32(WAKE_STATUS, 0x24u)
8479
REG32(RESET_EN_REGWEN, 0x28u)
8580
FIELD(RESET_EN_REGWEN, EN, 0u, 1u)
@@ -90,39 +85,21 @@ REG32(ESCALATE_RESET_STATUS, 0x34u)
9085
REG32(WAKE_INFO_CAPTURE_DIS, 0x38u)
9186
FIELD(WAKE_INFO_CAPTURE_DIS, VAL, 0u, 1u)
9287
REG32(WAKE_INFO, 0x3cu)
93-
FIELD(WAKE_INFO, REASONS, 0u, 6u)
94-
FIELD(WAKE_INFO, FALL_THROUGH, 6u, 1u)
95-
FIELD(WAKE_INFO, ABORT, 7u, 1u)
88+
/* note: wake info fields depend on top */
9689
REG32(FAULT_STATUS, 0x40u)
9790
FIELD(FAULT_STATUS, REG_INTG_ERR, 0u, 1u)
9891
FIELD(FAULT_STATUS, ESC_TIMEOUT, 1u, 1u)
9992
FIELD(FAULT_STATUS, MAIN_PD_GLITCH, 2u, 1u)
10093
/* clang-format on */
10194

102-
#define CONTROL_MASK \
103-
(R_CONTROL_LOW_POWER_HINT_MASK | R_CONTROL_CORE_CLK_EN_MASK | \
104-
R_CONTROL_IO_CLK_EN_MASK | R_CONTROL_USB_CLK_EN_LP_MASK | \
105-
R_CONTROL_USB_CLK_EN_ACTIVE_MASK | R_CONTROL_MAIN_PD_N_MASK)
106-
#define WAKEUP_MASK \
107-
(WAKEUP_CHANNEL_0_MASK | WAKEUP_CHANNEL_1_MASK | WAKEUP_CHANNEL_2_MASK | \
108-
WAKEUP_CHANNEL_3_MASK | WAKEUP_CHANNEL_4_MASK | WAKEUP_CHANNEL_5_MASK)
109-
#define WAKE_INFO_MASK \
110-
(R_WAKE_INFO_REASONS_MASK | R_WAKE_INFO_FALL_THROUGH_MASK | \
111-
R_WAKE_INFO_ABORT_MASK)
11295

11396
#define CDC_SYNC_PULSE_DURATION_NS 100000u /* 100us */
114-
115-
#define PWRMGR_WAKEUP_MAX 6u
97+
#define PWRMGR_WAKEUP_MAX ((unsigned)OT_PWRMGR_WAKEUP_COUNT)
98+
#define PWRMGR_RST_REQ_MAX 2u
11699

117100
/* special exit error code to report escalation panic */
118101
#define EXIT_ESCALATION_PANIC 39
119102

120-
/* Verbatim definitions from RTL */
121-
#define NUM_SW_RST_REQ 1u
122-
#define HW_RESET_WIDTH \
123-
(PARAM_NUM_RST_REQS + PARAM_NUM_INT_RST_REQS + PARAM_NUM_DEBUG_RST_REQS)
124-
#define RESET_SW_REQ_IDX (HW_RESET_WIDTH)
125-
126103
#define R32_OFF(_r_) ((_r_) / sizeof(uint32_t))
127104

128105
#define R_LAST_REG (R_FAULT_STATUS)
@@ -328,6 +305,8 @@ typedef struct {
328305
unsigned wakeup_count;
329306
unsigned reset_count;
330307
uint32_t reset_mask;
308+
uint32_t control_mask;
309+
uint32_t control_res_val; /* reset value for CONTROL regsisters */
331310
} OtPwrMgrConfig;
332311

333312
typedef struct {
@@ -340,16 +319,36 @@ static const OtPwrMgrConfig PWRMGR_CONFIG[OT_PWRMGR_VERSION_COUNT] = {
340319
[OT_PWRMGR_VERSION_EG_1_0_0] = {
341320
.wakeup_count = 6u,
342321
.reset_count = 2u,
343-
.reset_mask = 0x3u
322+
.reset_mask = 0x3u,
323+
.control_mask = 0x1f1u,
324+
.control_res_val = 0x180u, /* MAIN_PD_N | USB_CLK_EN_ACTIVE */
344325
},
345326
[OT_PWRMGR_VERSION_DJ_PRE] = {
346-
.wakeup_count = 6u,
327+
.wakeup_count = 4u,
347328
.reset_count = 2u,
348-
.reset_mask = 0x3u
329+
.reset_mask = 0x3u,
330+
.control_mask = 0x71u,
331+
.control_res_val = 0x40u, /* MAIN_PD_N */
349332
},
350333
};
351334

352-
static int PWRMGR_RESET_DISPATCH[OT_PWRMGR_VERSION_COUNT][PARAM_NUM_RST_REQS] = {
335+
#define WAKE_INFO_REASONS_MASK(_s_) \
336+
((1u << (PWRMGR_CONFIG[(_s_)->version].wakeup_count)) - 1u)
337+
#define WAKE_INFO_FALL_THROUGH_MASK(_s_) \
338+
(1u << (PWRMGR_CONFIG[(_s_)->version].wakeup_count))
339+
#define WAKE_INFO_ABORT_MASK_MASK(_s_) \
340+
(1u << (PWRMGR_CONFIG[(_s_)->version].wakeup_count + 1u))
341+
#define WAKE_INFO_MASK(_s_) \
342+
((1u << (PWRMGR_CONFIG[(_s_)->version].wakeup_count + 2u)) - 1u)
343+
#define WAKEUP_MASK(_s_) WAKE_INFO_REASONS_MASK(_s_)
344+
#define CONTROL_MASK(_s_) (PWRMGR_CONFIG[(_s_)->version].control_mask)
345+
#define HW_RESET_WIDTH(_s_) \
346+
((PWRMGR_CONFIG[(_s_)->version].wakeup_count) + \
347+
NUM_INT_RST_REQS + NUM_DEBUG_RST_REQS)
348+
#define RESET_SW_REQ_IDX(_s_) HW_RESET_WIDTH(_s_)
349+
350+
static int
351+
PWRMGR_RESET_DISPATCH[OT_PWRMGR_VERSION_COUNT][PWRMGR_RST_REQ_MAX] = {
353352
[OT_PWRMGR_VERSION_EG_1_0_0] = {
354353
[0] = OT_RSTMGR_RESET_SYSCTRL,
355354
[1] = OT_RSTMGR_RESET_AON_TIMER,
@@ -380,7 +379,8 @@ PWRMGR_WAKEUP_NAMES[OT_PWRMGR_VERSION_COUNT][PWRMGR_WAKEUP_MAX] = {
380379
},
381380
};
382381

383-
static const char *PWRMGR_RST_NAMES[OT_PWRMGR_VERSION_COUNT][PARAM_NUM_RST_REQS] = {
382+
static const char *
383+
PWRMGR_RST_NAMES[OT_PWRMGR_VERSION_COUNT][PWRMGR_RST_REQ_MAX] = {
384384
[OT_PWRMGR_VERSION_EG_1_0_0] = {
385385
[0] = "SYSRST",
386386
[1] = "AON_TIMER",
@@ -563,7 +563,7 @@ static void ot_pwrmgr_sw_rst_req(void *opaque, int irq, int level)
563563
unsigned src = (unsigned)irq;
564564
g_assert(src < NUM_SW_RST_REQ);
565565

566-
uint32_t rstbit = 1u << (RESET_SW_REQ_IDX + src);
566+
uint32_t rstbit = 1u << (RESET_SW_REQ_IDX(s) + src);
567567

568568
if (level) {
569569
trace_ot_pwrmgr_rst_req(s->ot_id, "SW", src);
@@ -869,17 +869,17 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64,
869869
pc);
870870
switch (reg) {
871871
case R_INTR_STATE:
872-
val32 &= WAKEUP_MASK;
872+
val32 &= WAKEUP_MASK(s);
873873
s->regs[R_INTR_STATE] &= ~val32; /* RW1C */
874874
ot_pwrmgr_update_irq(s);
875875
break;
876876
case R_INTR_ENABLE:
877-
val32 &= WAKEUP_MASK;
877+
val32 &= WAKEUP_MASK(s);
878878
s->regs[R_INTR_ENABLE] = val32;
879879
ot_pwrmgr_update_irq(s);
880880
break;
881881
case R_INTR_TEST:
882-
val32 &= WAKEUP_MASK;
882+
val32 &= WAKEUP_MASK(s);
883883
s->regs[R_INTR_STATE] |= val32;
884884
ot_pwrmgr_update_irq(s);
885885
break;
@@ -890,7 +890,7 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64,
890890
break;
891891
case R_CONTROL:
892892
/* TODO: clear LOW_POWER_HINT on next WFI? */
893-
val32 &= CONTROL_MASK;
893+
val32 &= CONTROL_MASK(s);
894894
s->regs[reg] = val32;
895895
break;
896896
case R_CFG_CDC_SYNC:
@@ -907,7 +907,7 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64,
907907
break;
908908
case R_WAKEUP_EN:
909909
if (s->regs[R_WAKEUP_EN_REGWEN] & R_WAKEUP_EN_REGWEN_EN_MASK) {
910-
val32 &= WAKEUP_MASK;
910+
val32 &= WAKEUP_MASK(s);
911911
s->regs[reg] = val32;
912912
} else {
913913
qemu_log_mask(LOG_GUEST_ERROR, "%s: %s: %s protected w/ REGWEN\n",
@@ -932,7 +932,7 @@ static void ot_pwrmgr_regs_write(void *opaque, hwaddr addr, uint64_t val64,
932932
s->regs[reg] = val32;
933933
break;
934934
case R_WAKE_INFO:
935-
val32 &= WAKE_INFO_MASK;
935+
val32 &= WAKE_INFO_MASK(s);
936936
s->regs[reg] &= ~val32; /* RW1C */
937937
break;
938938
case R_CTRL_CFG_REGWEN:
@@ -978,7 +978,7 @@ static void ot_pwrmgr_reset_enter(Object *obj, ResetType type)
978978
OtPwrMgrState *s = OT_PWRMGR(obj);
979979

980980
/* sanity checks for platform reset count and mask */
981-
g_assert(PWRMGR_CONFIG[s->version].reset_count <= PARAM_NUM_RST_REQS);
981+
g_assert(PWRMGR_CONFIG[s->version].reset_count <= PWRMGR_RST_REQ_MAX);
982982
g_assert(ctpop32(PWRMGR_CONFIG[s->version].reset_mask + 1u) == 1);
983983
g_assert(PWRMGR_CONFIG[s->version].reset_mask <
984984
(1u << PWRMGR_CONFIG[s->version].reset_count));
@@ -993,7 +993,7 @@ static void ot_pwrmgr_reset_enter(Object *obj, ResetType type)
993993
memset(s->regs, 0, REGS_SIZE);
994994

995995
s->regs[R_CTRL_CFG_REGWEN] = 0x1u;
996-
s->regs[R_CONTROL] = 0x180u;
996+
s->regs[R_CONTROL] = PWRMGR_CONFIG[s->version].control_res_val;
997997
s->regs[R_WAKEUP_EN_REGWEN] = 0x1u;
998998
s->regs[R_RESET_EN_REGWEN] = 0x1u;
999999
s->fsm_events.bitmap = 0;
@@ -1039,6 +1039,9 @@ static void ot_pwrmgr_realize(DeviceState *dev, Error **errp)
10391039
g_assert(s->clock_ctrl);
10401040
OBJECT_CHECK(OtClockCtrlIf, s->clock_ctrl, TYPE_OT_CLOCK_CTRL_IF);
10411041

1042+
qdev_init_gpio_in_named(dev, &ot_pwrmgr_rst_req, OT_PWRMGR_RST,
1043+
(int)PWRMGR_CONFIG[s->version].reset_count);
1044+
10421045
if (s->num_rom) {
10431046
if (s->num_rom > 8u * sizeof(uint8_t)) {
10441047
error_setg(&error_fatal, "too many ROMs\n");
@@ -1080,8 +1083,6 @@ static void ot_pwrmgr_init(Object *obj)
10801083

10811084
qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_wkup, OT_PWRMGR_WKUP,
10821085
PWRMGR_WAKEUP_MAX);
1083-
qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_rst_req, OT_PWRMGR_RST,
1084-
PARAM_NUM_RST_REQS);
10851086
qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_sw_rst_req,
10861087
OT_PWRMGR_SW_RST, NUM_SW_RST_REQ);
10871088
qdev_init_gpio_in_named(DEVICE(obj), &ot_pwrmgr_pwr_lc_rsp,

include/hw/opentitan/ot_pwrmgr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ typedef enum {
4141
OT_PWRMGR_VERSION_COUNT,
4242
} OtPwrMgrVersion;
4343

44-
/* Match PWRMGR_PARAM_*_WKUP_REQ_IDX definitions */
44+
/* Union of PWRMGR_PARAM_*_WKUP_REQ_IDX definitions for all supported tops */
4545
typedef enum {
4646
OT_PWRMGR_WAKEUP_SYSRST,
4747
OT_PWRMGR_WAKEUP_ADC_CTRL,

0 commit comments

Comments
 (0)