Message ID | 20220519153829.356889-3-fkonrad@amd.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | xlnx-zcu102: fix the display port. | expand |
On Thu, 19 May 2022 at 16:39, Frederic Konrad <fkonrad@amd.com> wrote: > > From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com> > > Add a periodic timer which raises vblank at a frequency of 30Hz. > > Signed-off-by: Sai Pavan Boddu <saipava@xilinx.com> > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> > Changes by fkonrad: > - Switched to transaction-based ptimer API. > - Added the DP_INT_VBLNK_START macro. > Signed-off-by: Frederic Konrad <fkonrad@amd.com> > --- > @@ -107,6 +108,8 @@ struct XlnxDPState { > */ > DPCDState *dpcd; > I2CDDCState *edid; > + > + ptimer_state *vblank; > }; The ptimer has internal state which needs to be considered in migration. This means you need to either include it in the device vmstate struct (there is a VMSTATE_PTIMER macro for this), or else set it up again in a post-load hook. Otherwise if you do a migration or state save/load when the timer is running then on resume the timer won't be running when it should. Apologies for not noticing this in my first review. -- PMM
> -----Original Message----- > From: Peter Maydell <peter.maydell@linaro.org> > Sent: 23 May 2022 14:52 > To: Frederic Konrad <fkonrad@amd.com> > Cc: qemu-devel@nongnu.org; qemu-arm@nongnu.org; > edgar.iglesias@gmail.com; alistair@alistair23.me; Sai Pavan Boddu > <saipava@xilinx.com>; Edgar Iglesias <edgari@xilinx.com>; Sai Pavan Boddu > <saipava@xilinx.com>; Edgar Iglesias <edgari@xilinx.com> > Subject: Re: [PATCH v2 2/4] xlnx_dp: Introduce a vblank signal > > [CAUTION: External Email] > > On Thu, 19 May 2022 at 16:39, Frederic Konrad <fkonrad@amd.com> wrote: > > > > From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com> > > > > Add a periodic timer which raises vblank at a frequency of 30Hz. > > > > Signed-off-by: Sai Pavan Boddu <saipava@xilinx.com> > > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> > > Changes by fkonrad: > > - Switched to transaction-based ptimer API. > > - Added the DP_INT_VBLNK_START macro. > > Signed-off-by: Frederic Konrad <fkonrad@amd.com> > > --- > > > > @@ -107,6 +108,8 @@ struct XlnxDPState { > > */ > > DPCDState *dpcd; > > I2CDDCState *edid; > > + > > + ptimer_state *vblank; > > }; > > The ptimer has internal state which needs to be considered in > migration. This means you need to either include it in the device > vmstate struct (there is a VMSTATE_PTIMER macro for this), or > else set it up again in a post-load hook. Otherwise if you do > a migration or state save/load when the timer is running then > on resume the timer won't be running when it should. Ah yes indeed, I forgot about that. Since cross version migration is not relevant here, the VMSTATE_PTIMER would be acceptable right? > > Apologies for not noticing this in my first review. No worries, thanks for the review :). Fred > > -- PMM
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 0378570459..2686ca0f2e 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -114,6 +114,7 @@ #define DP_TX_N_AUD (0x032C >> 2) #define DP_TX_AUDIO_EXT_DATA(n) ((0x0330 + 4 * n) >> 2) #define DP_INT_STATUS (0x03A0 >> 2) +#define DP_INT_VBLNK_START (1 << 13) #define DP_INT_MASK (0x03A4 >> 2) #define DP_INT_EN (0x03A8 >> 2) #define DP_INT_DS (0x03AC >> 2) @@ -274,6 +275,10 @@ static const VMStateDescription vmstate_dp = { } }; +#define DP_VBLANK_PTIMER_POLICY (PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD | \ + PTIMER_POLICY_CONTINUOUS_TRIGGER | \ + PTIMER_POLICY_NO_IMMEDIATE_TRIGGER) + static void xlnx_dp_update_irq(XlnxDPState *s); static uint64_t xlnx_dp_audio_read(void *opaque, hwaddr offset, unsigned size) @@ -773,6 +778,13 @@ static void xlnx_dp_write(void *opaque, hwaddr offset, uint64_t value, break; case DP_TRANSMITTER_ENABLE: s->core_registers[offset] = value & 0x01; + ptimer_transaction_begin(s->vblank); + if (value & 0x1) { + ptimer_run(s->vblank, 0); + } else { + ptimer_stop(s->vblank); + } + ptimer_transaction_commit(s->vblank); break; case DP_FORCE_SCRAMBLER_RESET: /* @@ -1177,9 +1189,6 @@ static void xlnx_dp_update_display(void *opaque) return; } - s->core_registers[DP_INT_STATUS] |= (1 << 13); - xlnx_dp_update_irq(s); - xlnx_dpdma_trigger_vsync_irq(s->dpdma); /* @@ -1275,6 +1284,14 @@ static void xlnx_dp_finalize(Object *obj) fifo8_destroy(&s->rx_fifo); } +static void vblank_hit(void *opaque) +{ + XlnxDPState *s = XLNX_DP(opaque); + + s->core_registers[DP_INT_STATUS] |= DP_INT_VBLNK_START; + xlnx_dp_update_irq(s); +} + static void xlnx_dp_realize(DeviceState *dev, Error **errp) { XlnxDPState *s = XLNX_DP(dev); @@ -1309,6 +1326,10 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp) &as); AUD_set_volume_out(s->amixer_output_stream, 0, 255, 255); xlnx_dp_audio_activate(s); + s->vblank = ptimer_init(vblank_hit, s, DP_VBLANK_PTIMER_POLICY); + ptimer_transaction_begin(s->vblank); + ptimer_set_freq(s->vblank, 30); + ptimer_transaction_commit(s->vblank); } static void xlnx_dp_reset(DeviceState *dev) diff --git a/include/hw/display/xlnx_dp.h b/include/hw/display/xlnx_dp.h index 1ef5a89ee7..e86a87f235 100644 --- a/include/hw/display/xlnx_dp.h +++ b/include/hw/display/xlnx_dp.h @@ -35,6 +35,7 @@ #include "hw/dma/xlnx_dpdma.h" #include "audio/audio.h" #include "qom/object.h" +#include "hw/ptimer.h" #define AUD_CHBUF_MAX_DEPTH (32 * KiB) #define MAX_QEMU_BUFFER_SIZE (4 * KiB) @@ -107,6 +108,8 @@ struct XlnxDPState { */ DPCDState *dpcd; I2CDDCState *edid; + + ptimer_state *vblank; }; #define TYPE_XLNX_DP "xlnx.v-dp"