Message ID | 20220627195506.403715-9-pdel@fb.com |
---|---|
State | New |
Headers | show |
Series | aspeed: Add I2C new register DMA slave mode support | expand |
On 6/27/22 21:55, Peter Delevoryas wrote: > Signed-off-by: Peter Delevoryas <pdel@fb.com> some intro ? > --- > hw/misc/fby35_cpld.c | 137 +++++++++++++++++++++++++++++++++++++++++++ > hw/misc/meson.build | 3 +- > 2 files changed, 139 insertions(+), 1 deletion(-) > create mode 100644 hw/misc/fby35_cpld.c > > diff --git a/hw/misc/fby35_cpld.c b/hw/misc/fby35_cpld.c > new file mode 100644 > index 0000000000..a783a0a2c8 > --- /dev/null > +++ b/hw/misc/fby35_cpld.c > @@ -0,0 +1,137 @@ > +/* > + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com) > + * > + * Permission is hereby granted, free of charge, to any person obtaining a copy > + * of this software and associated documentation files (the "Software"), to deal > + * in the Software without restriction, including without limitation the rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > + * THE SOFTWARE. > + */ I prefer the short version of the license. > +#include "qemu/osdep.h" > +#include "hw/i2c/i2c.h" > +#include "hw/registerfields.h" > + > +#define BOARD_ID_CLASS1 0b0000 > +#define BOARD_ID_CLASS2 0b0001 > + > +#define TYPE_FBY35_CPLD "fby35-cpld" > +OBJECT_DECLARE_SIMPLE_TYPE(Fby35CpldState, FBY35_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 Fby35CpldState { > + I2CSlave parent_obj; > + > + uint8_t target_reg; > + uint32_t regs[10]; > +}; > + > +static void fby35_cpld_realize(DeviceState *dev, Error **errp) > +{ > + Fby35CpldState *s = FBY35_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_cpld_i2c_event(I2CSlave *i2c, enum i2c_event event) > +{ > + Fby35CpldState *s = FBY35_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_cpld_i2c_recv(I2CSlave *i2c) > +{ > + Fby35CpldState *s = FBY35_CPLD(i2c); > + > + switch (s->target_reg) { > + case R_CLASS_TYPE: > + case R_BOARD_REVISION: > + return s->regs[s->target_reg]; > + default: > + printf("%s: unexpected register read 0x%02x\n", __func__, s->target_reg); please use the qemu logging system > + return 0xff; > + } > +} > + > +static int fby35_cpld_i2c_send(I2CSlave *i2c, uint8_t data) > +{ > + Fby35CpldState *s = FBY35_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: > + printf("%s: unexpected register write 0x%02x 0x%02x\n", __func__, s->target_reg, data); > + break; > + } > + > + return 0; > +} > + > +static void fby35_cpld_class_init(ObjectClass *oc, void *data) > +{ > + DeviceClass *dc = DEVICE_CLASS(oc); > + I2CSlaveClass *i2c = I2C_SLAVE_CLASS(oc); > + > + dc->realize = fby35_cpld_realize; > + i2c->event = fby35_cpld_i2c_event; > + i2c->recv = fby35_cpld_i2c_recv; > + i2c->send = fby35_cpld_i2c_send; > +} > + > +static const TypeInfo types[] = { > + { > + .name = TYPE_FBY35_CPLD, > + .parent = TYPE_I2C_SLAVE, > + .instance_size = sizeof(Fby35CpldState), > + .class_init = fby35_cpld_class_init, > + }, > +}; > + > +DEFINE_TYPES(types); > diff --git a/hw/misc/meson.build b/hw/misc/meson.build > index 95268eddc0..1edad44b6b 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_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'))
> On Jun 27, 2022, at 11:50 PM, Cédric Le Goater <clg@kaod.org> wrote: > > On 6/27/22 21:55, Peter Delevoryas wrote: >> Signed-off-by: Peter Delevoryas <pdel@fb.com> > > > some intro ? Will do. > >> --- >> hw/misc/fby35_cpld.c | 137 +++++++++++++++++++++++++++++++++++++++++++ >> hw/misc/meson.build | 3 +- >> 2 files changed, 139 insertions(+), 1 deletion(-) >> create mode 100644 hw/misc/fby35_cpld.c >> diff --git a/hw/misc/fby35_cpld.c b/hw/misc/fby35_cpld.c >> new file mode 100644 >> index 0000000000..a783a0a2c8 >> --- /dev/null >> +++ b/hw/misc/fby35_cpld.c >> @@ -0,0 +1,137 @@ >> +/* >> + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com) >> + * >> + * Permission is hereby granted, free of charge, to any person obtaining a copy >> + * of this software and associated documentation files (the "Software"), to deal >> + * in the Software without restriction, including without limitation the rights >> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell >> + * copies of the Software, and to permit persons to whom the Software is >> + * furnished to do so, subject to the following conditions: >> + * >> + * The above copyright notice and this permission notice shall be included in >> + * all copies or substantial portions of the Software. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER >> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, >> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN >> + * THE SOFTWARE. >> + */ > > I prefer the short version of the license. Oh, yes, I can see if I can reduce this. To be honest I was copying this from our legal wiki, and I’m not that familiar with licensing or what shortening it implies, but I can look into that. > >> +#include "qemu/osdep.h" >> +#include "hw/i2c/i2c.h" >> +#include "hw/registerfields.h" >> + >> +#define BOARD_ID_CLASS1 0b0000 >> +#define BOARD_ID_CLASS2 0b0001 >> + >> +#define TYPE_FBY35_CPLD "fby35-cpld" >> +OBJECT_DECLARE_SIMPLE_TYPE(Fby35CpldState, FBY35_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 Fby35CpldState { >> + I2CSlave parent_obj; >> + >> + uint8_t target_reg; >> + uint32_t regs[10]; >> +}; >> + >> +static void fby35_cpld_realize(DeviceState *dev, Error **errp) >> +{ >> + Fby35CpldState *s = FBY35_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_cpld_i2c_event(I2CSlave *i2c, enum i2c_event event) >> +{ >> + Fby35CpldState *s = FBY35_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_cpld_i2c_recv(I2CSlave *i2c) >> +{ >> + Fby35CpldState *s = FBY35_CPLD(i2c); >> + >> + switch (s->target_reg) { >> + case R_CLASS_TYPE: >> + case R_BOARD_REVISION: >> + return s->regs[s->target_reg]; >> + default: >> + printf("%s: unexpected register read 0x%02x\n", __func__, s->target_reg); > > please use the qemu logging system Yes, sorry about that, I’ll fix this. In the future I’ll probably try to just use qemu_log from the start, to avoid these. > >> + return 0xff; >> + } >> +} >> + >> +static int fby35_cpld_i2c_send(I2CSlave *i2c, uint8_t data) >> +{ >> + Fby35CpldState *s = FBY35_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: >> + printf("%s: unexpected register write 0x%02x 0x%02x\n", __func__, s->target_reg, data); >> + break; >> + } >> + >> + return 0; >> +} >> + >> +static void fby35_cpld_class_init(ObjectClass *oc, void *data) >> +{ >> + DeviceClass *dc = DEVICE_CLASS(oc); >> + I2CSlaveClass *i2c = I2C_SLAVE_CLASS(oc); >> + >> + dc->realize = fby35_cpld_realize; >> + i2c->event = fby35_cpld_i2c_event; >> + i2c->recv = fby35_cpld_i2c_recv; >> + i2c->send = fby35_cpld_i2c_send; >> +} >> + >> +static const TypeInfo types[] = { >> + { >> + .name = TYPE_FBY35_CPLD, >> + .parent = TYPE_I2C_SLAVE, >> + .instance_size = sizeof(Fby35CpldState), >> + .class_init = fby35_cpld_class_init, >> + }, >> +}; >> + >> +DEFINE_TYPES(types); >> diff --git a/hw/misc/meson.build b/hw/misc/meson.build >> index 95268eddc0..1edad44b6b 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_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/hw/misc/fby35_cpld.c b/hw/misc/fby35_cpld.c new file mode 100644 index 0000000000..a783a0a2c8 --- /dev/null +++ b/hw/misc/fby35_cpld.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/i2c/i2c.h" +#include "hw/registerfields.h" + +#define BOARD_ID_CLASS1 0b0000 +#define BOARD_ID_CLASS2 0b0001 + +#define TYPE_FBY35_CPLD "fby35-cpld" +OBJECT_DECLARE_SIMPLE_TYPE(Fby35CpldState, FBY35_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 Fby35CpldState { + I2CSlave parent_obj; + + uint8_t target_reg; + uint32_t regs[10]; +}; + +static void fby35_cpld_realize(DeviceState *dev, Error **errp) +{ + Fby35CpldState *s = FBY35_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_cpld_i2c_event(I2CSlave *i2c, enum i2c_event event) +{ + Fby35CpldState *s = FBY35_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_cpld_i2c_recv(I2CSlave *i2c) +{ + Fby35CpldState *s = FBY35_CPLD(i2c); + + switch (s->target_reg) { + case R_CLASS_TYPE: + case R_BOARD_REVISION: + return s->regs[s->target_reg]; + default: + printf("%s: unexpected register read 0x%02x\n", __func__, s->target_reg); + return 0xff; + } +} + +static int fby35_cpld_i2c_send(I2CSlave *i2c, uint8_t data) +{ + Fby35CpldState *s = FBY35_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: + printf("%s: unexpected register write 0x%02x 0x%02x\n", __func__, s->target_reg, data); + break; + } + + return 0; +} + +static void fby35_cpld_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + I2CSlaveClass *i2c = I2C_SLAVE_CLASS(oc); + + dc->realize = fby35_cpld_realize; + i2c->event = fby35_cpld_i2c_event; + i2c->recv = fby35_cpld_i2c_recv; + i2c->send = fby35_cpld_i2c_send; +} + +static const TypeInfo types[] = { + { + .name = TYPE_FBY35_CPLD, + .parent = TYPE_I2C_SLAVE, + .instance_size = sizeof(Fby35CpldState), + .class_init = fby35_cpld_class_init, + }, +}; + +DEFINE_TYPES(types); diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 95268eddc0..1edad44b6b 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_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'))
Signed-off-by: Peter Delevoryas <pdel@fb.com> --- hw/misc/fby35_cpld.c | 137 +++++++++++++++++++++++++++++++++++++++++++ hw/misc/meson.build | 3 +- 2 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 hw/misc/fby35_cpld.c