> Subject: [PATCH 14/19] hw/i3c/dw-i3c: Add ctrl MMIO handling > > Adds functionality to the CTRL register. > > Signed-off-by: Joe Komlodi <[email protected]> > > Reviewed-by: Titus Rwantare <[email protected]> > Reviewed-by: Patrick Venture <[email protected]> > --- > hw/i3c/dw-i3c.c | 35 +++++++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > > diff --git a/hw/i3c/dw-i3c.c b/hw/i3c/dw-i3c.c index c5af331ac4..61845c909f > 100644 > --- a/hw/i3c/dw-i3c.c > +++ b/hw/i3c/dw-i3c.c > @@ -361,6 +361,8 @@ static const uint32_t dw_i3c_ro[DW_I3C_NR_REGS] = { > [R_SLAVE_CONFIG] = 0xffffffff, > }; > > +static void dw_i3c_cmd_queue_execute(DWI3C *s); > + > static inline bool dw_i3c_has_hdr_ts(DWI3C *s) { > return ARRAY_FIELD_EX32(s->regs, HW_CAPABILITY, HDR_TS); @@ > -520,6 +522,36 @@ static int dw_i3c_recv_data(DWI3C *s, bool is_i2c, uint8_t > *data, > return ret; > } > > +static void dw_i3c_ctrl_w(DWI3C *s, uint32_t val) { > + /* > + * If the user is setting I3C_RESUME, the controller was halted. > + * Try and resume execution and leave the bit cleared. > + */ > + if (FIELD_EX32(val, DEVICE_CTRL, I3C_RESUME)) { > + dw_i3c_cmd_queue_execute(s); > + val = FIELD_DP32(val, DEVICE_CTRL, I3C_RESUME, 0); > + } > + /* > + * I3C_ABORT being set sends an I3C STOP. It's cleared when the STOP is > + * sent. > + */ > + if (FIELD_EX32(val, DEVICE_CTRL, I3C_ABORT)) { > + dw_i3c_end_transfer(s, /*is_i2c=*/true); > + dw_i3c_end_transfer(s, /*is_i2c=*/false); > + val = FIELD_DP32(val, DEVICE_CTRL, I3C_ABORT, 0); > + ARRAY_FIELD_DP32(s->regs, INTR_STATUS, TRANSFER_ABORT, 1); > + dw_i3c_update_irq(s); > + } > + /* Update present state. */ > + ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS, > + DW_I3C_TRANSFER_STATE_IDLE); > + ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS, > + DW_I3C_TRANSFER_STATUS_IDLE); > + > + s->regs[R_DEVICE_CTRL] = val; > +} > + > static inline bool dw_i3c_target_is_i2c(DWI3C *s, uint16_t offset) { > /* / sizeof(uint32_t) because we're indexing into our 32-bit reg array. > */ > @@ -1592,6 +1624,9 @@ static void dw_i3c_write(void *opaque, hwaddr > offset, uint64_t value, > "] = 0x%08" PRIx64 "\n", > __func__, offset, value); > break; > + case R_DEVICE_CTRL: > + dw_i3c_ctrl_w(s, val32); > + break; > case R_RX_TX_DATA_PORT: > dw_i3c_push_tx(s, val32); > break; > -- > 2.50.0.rc1.591.g9c95f17f64-goog
Reviewed-by: Jamin Lin <[email protected]> Thanks, Jamin
