Message ID | 20211117141841.4696-6-francisco.iglesias@xilinx.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Xilinx Versal's PMC SLCR and OSPI support | expand |
On Wed, Nov 17, 2021 at 02:18:37PM +0000, Francisco Iglesias wrote: > Implement the DMA control interface for allowing control of DMA operations > from inside models that contain instances of (and reuse) the Xilinx CSU > DMA. Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> > > Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com> > --- > hw/dma/xlnx_csu_dma.c | 32 ++++++++++++++++++++++++++++++++ > include/hw/dma/xlnx_csu_dma.h | 4 ++++ > 2 files changed, 36 insertions(+) > > diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c > index 896bb3574d..9ed6e82225 100644 > --- a/hw/dma/xlnx_csu_dma.c > +++ b/hw/dma/xlnx_csu_dma.c > @@ -277,6 +277,11 @@ static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, uint32_t len) > s->regs[R_ADDR_MSB] = dst >> 32; > } > > + /* Notify dma-ctrl clients when the transfer has been completed */ > + if (size == 0 && s->dma_ctrl_notify) { > + s->dma_ctrl_notify(s->dma_ctrl_opaque); > + } > + > if (size == 0) { > xlnx_csu_dma_done(s); > } > @@ -472,6 +477,29 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, uint64_t val) > return val & R_ADDR_MSB_ADDR_MSB_MASK; > } > > +static void xlnx_csu_dma_dma_ctrl_read(DmaCtrl *dma_ctrl, hwaddr addr, > + uint32_t len, DmaCtrlNotify *notify, > + bool start_dma) > +{ > + XlnxCSUDMA *s = XLNX_CSU_DMA(dma_ctrl); > + RegisterInfo *reg = &s->regs_info[R_SIZE]; > + uint64_t we = MAKE_64BIT_MASK(0, 4 * 8); > + > + s->regs[R_ADDR] = addr; > + s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32; > + > + if (notify) { > + s->dma_ctrl_notify = notify->cb; > + s->dma_ctrl_opaque = notify->opaque; > + } > + > + if (start_dma) { > + register_write(reg, len, we, object_get_typename(OBJECT(s)), false); > + } else { > + s->regs[R_SIZE] = len; > + } > +} > + > static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = { > #define DMACH_REGINFO(NAME, snd) \ > (const RegisterAccessInfo []) { \ > @@ -696,6 +724,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data) > { > DeviceClass *dc = DEVICE_CLASS(klass); > StreamSinkClass *ssc = STREAM_SINK_CLASS(klass); > + DmaCtrlClass *dcc = DMA_CTRL_CLASS(klass); > > dc->reset = xlnx_csu_dma_reset; > dc->realize = xlnx_csu_dma_realize; > @@ -704,6 +733,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data) > > ssc->push = xlnx_csu_dma_stream_push; > ssc->can_push = xlnx_csu_dma_stream_can_push; > + > + dcc->read = xlnx_csu_dma_dma_ctrl_read; > } > > static void xlnx_csu_dma_init(Object *obj) > @@ -731,6 +762,7 @@ static const TypeInfo xlnx_csu_dma_info = { > .instance_init = xlnx_csu_dma_init, > .interfaces = (InterfaceInfo[]) { > { TYPE_STREAM_SINK }, > + { TYPE_DMA_CTRL }, > { } > } > }; > diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h > index 8c39e46f58..f7f086593c 100644 > --- a/include/hw/dma/xlnx_csu_dma.h > +++ b/include/hw/dma/xlnx_csu_dma.h > @@ -23,6 +23,7 @@ > > #include "hw/ptimer.h" > #include "hw/stream.h" > +#include "hw/dma/dma-ctrl.h" > > #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma" > > @@ -45,6 +46,9 @@ typedef struct XlnxCSUDMA { > StreamCanPushNotifyFn notify; > void *notify_opaque; > > + dmactrl_notify_fn dma_ctrl_notify; > + void *dma_ctrl_opaque; > + > uint32_t regs[XLNX_CSU_DMA_R_MAX]; > RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX]; > } XlnxCSUDMA; > -- > 2.11.0 >
diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c index 896bb3574d..9ed6e82225 100644 --- a/hw/dma/xlnx_csu_dma.c +++ b/hw/dma/xlnx_csu_dma.c @@ -277,6 +277,11 @@ static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, uint32_t len) s->regs[R_ADDR_MSB] = dst >> 32; } + /* Notify dma-ctrl clients when the transfer has been completed */ + if (size == 0 && s->dma_ctrl_notify) { + s->dma_ctrl_notify(s->dma_ctrl_opaque); + } + if (size == 0) { xlnx_csu_dma_done(s); } @@ -472,6 +477,29 @@ static uint64_t addr_msb_pre_write(RegisterInfo *reg, uint64_t val) return val & R_ADDR_MSB_ADDR_MSB_MASK; } +static void xlnx_csu_dma_dma_ctrl_read(DmaCtrl *dma_ctrl, hwaddr addr, + uint32_t len, DmaCtrlNotify *notify, + bool start_dma) +{ + XlnxCSUDMA *s = XLNX_CSU_DMA(dma_ctrl); + RegisterInfo *reg = &s->regs_info[R_SIZE]; + uint64_t we = MAKE_64BIT_MASK(0, 4 * 8); + + s->regs[R_ADDR] = addr; + s->regs[R_ADDR_MSB] = (uint64_t)addr >> 32; + + if (notify) { + s->dma_ctrl_notify = notify->cb; + s->dma_ctrl_opaque = notify->opaque; + } + + if (start_dma) { + register_write(reg, len, we, object_get_typename(OBJECT(s)), false); + } else { + s->regs[R_SIZE] = len; + } +} + static const RegisterAccessInfo *xlnx_csu_dma_regs_info[] = { #define DMACH_REGINFO(NAME, snd) \ (const RegisterAccessInfo []) { \ @@ -696,6 +724,7 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); StreamSinkClass *ssc = STREAM_SINK_CLASS(klass); + DmaCtrlClass *dcc = DMA_CTRL_CLASS(klass); dc->reset = xlnx_csu_dma_reset; dc->realize = xlnx_csu_dma_realize; @@ -704,6 +733,8 @@ static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data) ssc->push = xlnx_csu_dma_stream_push; ssc->can_push = xlnx_csu_dma_stream_can_push; + + dcc->read = xlnx_csu_dma_dma_ctrl_read; } static void xlnx_csu_dma_init(Object *obj) @@ -731,6 +762,7 @@ static const TypeInfo xlnx_csu_dma_info = { .instance_init = xlnx_csu_dma_init, .interfaces = (InterfaceInfo[]) { { TYPE_STREAM_SINK }, + { TYPE_DMA_CTRL }, { } } }; diff --git a/include/hw/dma/xlnx_csu_dma.h b/include/hw/dma/xlnx_csu_dma.h index 8c39e46f58..f7f086593c 100644 --- a/include/hw/dma/xlnx_csu_dma.h +++ b/include/hw/dma/xlnx_csu_dma.h @@ -23,6 +23,7 @@ #include "hw/ptimer.h" #include "hw/stream.h" +#include "hw/dma/dma-ctrl.h" #define TYPE_XLNX_CSU_DMA "xlnx.csu_dma" @@ -45,6 +46,9 @@ typedef struct XlnxCSUDMA { StreamCanPushNotifyFn notify; void *notify_opaque; + dmactrl_notify_fn dma_ctrl_notify; + void *dma_ctrl_opaque; + uint32_t regs[XLNX_CSU_DMA_R_MAX]; RegisterInfo regs_info[XLNX_CSU_DMA_R_MAX]; } XlnxCSUDMA;
Implement the DMA control interface for allowing control of DMA operations from inside models that contain instances of (and reuse) the Xilinx CSU DMA. Signed-off-by: Francisco Iglesias <francisco.iglesias@xilinx.com> --- hw/dma/xlnx_csu_dma.c | 32 ++++++++++++++++++++++++++++++++ include/hw/dma/xlnx_csu_dma.h | 4 ++++ 2 files changed, 36 insertions(+)