Message ID | 20220630045133.32251-13-me@pjd.dev |
---|---|
State | New |
Headers | show |
Series | hw/i2c/aspeed: I2C slave mode DMA RX w/ new regs | expand |
On 6/30/22 06:51, Peter Delevoryas wrote: > From: Peter Delevoryas <pdel@fb.com> > > fby35 machines have 1 BMC on a baseboard and 2-4 server boards with BIC's. > There are also CPLD's on each of the boards, one type of CPLD on the > baseboard and another type on each of the server boards. This commit adds an > implementation of some of the logic performed by the server board CPLD, > which is connected to the server board BIC. > > fby35 machines have 1 baseboard with a BMC (AST2600) and 4 server boards > with bridge interconnects (BIC's, AST1030's). Each server board has a CPLD > on it which provides FRU information and some synchronization functionality > with the BMC. The baseboard also has one CPLD, but it does other stuff. > > This commit just adds some of the FRU functionality to allow the BIC to > startup without any errors. > > Signed-off-by: Peter Delevoryas <pdel@fb.com> > --- > MAINTAINERS | 1 + > hw/misc/fby35_sb_cpld.c | 128 ++++++++++++++++++++++++++++++++++++++++ > hw/misc/meson.build | 3 +- > 3 files changed, 131 insertions(+), 1 deletion(-) > create mode 100644 hw/misc/fby35_sb_cpld.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index 05cf84b58c..3ffd473db1 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1067,6 +1067,7 @@ F: hw/net/ftgmac100.c > F: include/hw/net/ftgmac100.h > F: docs/system/arm/aspeed.rst > F: tests/qtest/*aspeed* > +F: hw/misc/fby35_sb_cpld.c > > NRF51 > M: Joel Stanley <joel@jms.id.au> > diff --git a/hw/misc/fby35_sb_cpld.c b/hw/misc/fby35_sb_cpld.c > new file mode 100644 > index 0000000000..f170a6c781 > --- /dev/null > +++ b/hw/misc/fby35_sb_cpld.c > @@ -0,0 +1,128 @@ > +/* > + * fby35 Server Board CPLD > + * > + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com) > + * > + * This code is licensed under the GPL version 2 or later. See the COPYING > + * file in the top-level directory. > + */ > + > +#include "qemu/osdep.h" > +#include "qemu/log.h" > +#include "hw/i2c/i2c.h" > +#include "hw/registerfields.h" > + > +#define BOARD_ID_CLASS1 0b0000 > +#define BOARD_ID_CLASS2 0b0001 > + > +#define TYPE_FBY35_SB_CPLD "fby35-sb-cpld" > +OBJECT_DECLARE_SIMPLE_TYPE(Fby35SbCpldState, FBY35_SB_CPLD); > + > +REG8(CLASS_TYPE, 0x5); > + FIELD(CLASS_TYPE, RESERVED, 0, 2); > + FIELD(CLASS_TYPE, 1OU_EXPANSION_NOT_PRESENT, 2, 1); > + FIELD(CLASS_TYPE, 2OU_EXPANSION_NOT_PRESENT, 3, 1); > + FIELD(CLASS_TYPE, BOARD_ID, 4, 4); > +REG8(BOARD_REVISION, 0x8); > + FIELD(BOARD_REVISION, VALUE, 0, 4); > + FIELD(BOARD_REVISION, RESERVED, 4, 4); > + > +struct Fby35SbCpldState { > + I2CSlave parent_obj; > + > + uint8_t target_reg; > + uint32_t regs[10]; > +}; > + > +static void fby35_sb_cpld_realize(DeviceState *dev, Error **errp) > +{ > + Fby35SbCpldState *s = FBY35_SB_CPLD(dev); > + > + memset(s->regs, 0, sizeof(s->regs)); > + s->target_reg = 0; > + > + ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, BOARD_ID, 0b0000); > + ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, 1OU_EXPANSION_NOT_PRESENT, 1); > + ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, 2OU_EXPANSION_NOT_PRESENT, 1); > + ARRAY_FIELD_DP32(s->regs, BOARD_REVISION, VALUE, 0x1); > +} This is a reset handler. C. > +static int fby35_sb_cpld_i2c_event(I2CSlave *i2c, enum i2c_event event) > +{ > + Fby35SbCpldState *s = FBY35_SB_CPLD(i2c); > + > + switch (event) { > + case I2C_START_RECV: > + break; > + case I2C_START_SEND: > + s->target_reg = 0; > + break; > + case I2C_START_SEND_ASYNC: > + case I2C_FINISH: > + case I2C_NACK: > + break; > + } > + > + return 0; > +} > + > +static uint8_t fby35_sb_cpld_i2c_recv(I2CSlave *i2c) > +{ > + Fby35SbCpldState *s = FBY35_SB_CPLD(i2c); > + > + switch (s->target_reg) { > + case R_CLASS_TYPE: > + case R_BOARD_REVISION: > + return s->regs[s->target_reg]; > + default: > + qemu_log_mask(LOG_UNIMP, "%s: Register read unimplemented: 0x%02x\n", > + __func__, s->target_reg); > + return 0xff; > + } > +} > + > +static int fby35_sb_cpld_i2c_send(I2CSlave *i2c, uint8_t data) > +{ > + Fby35SbCpldState *s = FBY35_SB_CPLD(i2c); > + > + if (s->target_reg == 0) { > + s->target_reg = data; > + return 0; > + } > + > + switch (s->target_reg) { > + case R_CLASS_TYPE: > + case R_BOARD_REVISION: > + s->regs[s->target_reg] = data; > + break; > + default: > + qemu_log_mask(LOG_UNIMP, > + "%s: Register write unimplemented: 0x%02x 0x%02x\n", > + __func__, s->target_reg, data); > + break; > + } > + > + return 0; > +} > + > +static void fby35_sb_cpld_class_init(ObjectClass *oc, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(oc); > + I2CSlaveClass *i2c = I2C_SLAVE_CLASS(oc); > + > + dc->realize = fby35_sb_cpld_realize; > + i2c->event = fby35_sb_cpld_i2c_event; > + i2c->recv = fby35_sb_cpld_i2c_recv; > + i2c->send = fby35_sb_cpld_i2c_send; > +} > + > +static const TypeInfo types[] = { > + { > + .name = TYPE_FBY35_SB_CPLD, > + .parent = TYPE_I2C_SLAVE, > + .instance_size = sizeof(Fby35SbCpldState), > + .class_init = fby35_sb_cpld_class_init, > + }, > +}; > + > +DEFINE_TYPES(types); > diff --git a/hw/misc/meson.build b/hw/misc/meson.build > index 95268eddc0..948e25c440 100644 > --- a/hw/misc/meson.build > +++ b/hw/misc/meson.build > @@ -117,7 +117,8 @@ softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files( > 'aspeed_sbc.c', > 'aspeed_sdmc.c', > 'aspeed_xdma.c', > - 'aspeed_peci.c')) > + 'aspeed_peci.c', > + 'fby35_sb_cpld.c')) > > softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c')) > softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_rng.c'))
diff --git a/MAINTAINERS b/MAINTAINERS index 05cf84b58c..3ffd473db1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1067,6 +1067,7 @@ F: hw/net/ftgmac100.c F: include/hw/net/ftgmac100.h F: docs/system/arm/aspeed.rst F: tests/qtest/*aspeed* +F: hw/misc/fby35_sb_cpld.c NRF51 M: Joel Stanley <joel@jms.id.au> diff --git a/hw/misc/fby35_sb_cpld.c b/hw/misc/fby35_sb_cpld.c new file mode 100644 index 0000000000..f170a6c781 --- /dev/null +++ b/hw/misc/fby35_sb_cpld.c @@ -0,0 +1,128 @@ +/* + * fby35 Server Board CPLD + * + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com) + * + * This code is licensed under the GPL version 2 or later. See the COPYING + * file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/i2c/i2c.h" +#include "hw/registerfields.h" + +#define BOARD_ID_CLASS1 0b0000 +#define BOARD_ID_CLASS2 0b0001 + +#define TYPE_FBY35_SB_CPLD "fby35-sb-cpld" +OBJECT_DECLARE_SIMPLE_TYPE(Fby35SbCpldState, FBY35_SB_CPLD); + +REG8(CLASS_TYPE, 0x5); + FIELD(CLASS_TYPE, RESERVED, 0, 2); + FIELD(CLASS_TYPE, 1OU_EXPANSION_NOT_PRESENT, 2, 1); + FIELD(CLASS_TYPE, 2OU_EXPANSION_NOT_PRESENT, 3, 1); + FIELD(CLASS_TYPE, BOARD_ID, 4, 4); +REG8(BOARD_REVISION, 0x8); + FIELD(BOARD_REVISION, VALUE, 0, 4); + FIELD(BOARD_REVISION, RESERVED, 4, 4); + +struct Fby35SbCpldState { + I2CSlave parent_obj; + + uint8_t target_reg; + uint32_t regs[10]; +}; + +static void fby35_sb_cpld_realize(DeviceState *dev, Error **errp) +{ + Fby35SbCpldState *s = FBY35_SB_CPLD(dev); + + memset(s->regs, 0, sizeof(s->regs)); + s->target_reg = 0; + + ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, BOARD_ID, 0b0000); + ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, 1OU_EXPANSION_NOT_PRESENT, 1); + ARRAY_FIELD_DP32(s->regs, CLASS_TYPE, 2OU_EXPANSION_NOT_PRESENT, 1); + ARRAY_FIELD_DP32(s->regs, BOARD_REVISION, VALUE, 0x1); +} + +static int fby35_sb_cpld_i2c_event(I2CSlave *i2c, enum i2c_event event) +{ + Fby35SbCpldState *s = FBY35_SB_CPLD(i2c); + + switch (event) { + case I2C_START_RECV: + break; + case I2C_START_SEND: + s->target_reg = 0; + break; + case I2C_START_SEND_ASYNC: + case I2C_FINISH: + case I2C_NACK: + break; + } + + return 0; +} + +static uint8_t fby35_sb_cpld_i2c_recv(I2CSlave *i2c) +{ + Fby35SbCpldState *s = FBY35_SB_CPLD(i2c); + + switch (s->target_reg) { + case R_CLASS_TYPE: + case R_BOARD_REVISION: + return s->regs[s->target_reg]; + default: + qemu_log_mask(LOG_UNIMP, "%s: Register read unimplemented: 0x%02x\n", + __func__, s->target_reg); + return 0xff; + } +} + +static int fby35_sb_cpld_i2c_send(I2CSlave *i2c, uint8_t data) +{ + Fby35SbCpldState *s = FBY35_SB_CPLD(i2c); + + if (s->target_reg == 0) { + s->target_reg = data; + return 0; + } + + switch (s->target_reg) { + case R_CLASS_TYPE: + case R_BOARD_REVISION: + s->regs[s->target_reg] = data; + break; + default: + qemu_log_mask(LOG_UNIMP, + "%s: Register write unimplemented: 0x%02x 0x%02x\n", + __func__, s->target_reg, data); + break; + } + + return 0; +} + +static void fby35_sb_cpld_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + I2CSlaveClass *i2c = I2C_SLAVE_CLASS(oc); + + dc->realize = fby35_sb_cpld_realize; + i2c->event = fby35_sb_cpld_i2c_event; + i2c->recv = fby35_sb_cpld_i2c_recv; + i2c->send = fby35_sb_cpld_i2c_send; +} + +static const TypeInfo types[] = { + { + .name = TYPE_FBY35_SB_CPLD, + .parent = TYPE_I2C_SLAVE, + .instance_size = sizeof(Fby35SbCpldState), + .class_init = fby35_sb_cpld_class_init, + }, +}; + +DEFINE_TYPES(types); diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 95268eddc0..948e25c440 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -117,7 +117,8 @@ softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files( 'aspeed_sbc.c', 'aspeed_sdmc.c', 'aspeed_xdma.c', - 'aspeed_peci.c')) + 'aspeed_peci.c', + 'fby35_sb_cpld.c')) softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-sysreg.c')) softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_rng.c'))