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>
---
hw/display/xlnx_dp.c | 24 +++++++++++++++++++++---
include/hw/display/xlnx_dp.h | 3 +++
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 0378570459..984b0a6bb9 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)
@@ -773,6 +774,14 @@ 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_set_limit(s->vblank, 1, 1);
+ ptimer_run(s->vblank, 0);
+ } else {
+ ptimer_stop(s->vblank);
+ }
+ ptimer_transaction_commit(s->vblank);
break;
case DP_FORCE_SCRAMBLER_RESET:
/*
@@ -1177,9 +1186,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 +1281,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 +1323,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, PTIMER_POLICY_DEFAULT);
+ 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"
--
2.25.1
On Tue, 3 May 2022 at 16:27, <frederic.konrad@xilinx.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> > --- > @@ -1309,6 +1323,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, PTIMER_POLICY_DEFAULT); > + ptimer_transaction_begin(s->vblank); > + ptimer_set_freq(s->vblank, 30); > + ptimer_transaction_commit(s->vblank); The ptimer documentation (in include/hw/ptimer.h) says * The default ptimer policy retains backward compatibility with the legacy * timers. Custom policies are adjusting the default one. Consider providing * a correct policy for your timer. and goes on to describe various weird behaviours of the default policy. You almost certainly don't want to use PTIMER_POLICY_DEFAULT for a new timer -- instead figure out the behaviour you actually want and specify the appropriate flags. thanks -- PMM
> -----Original Message----- > From: Peter Maydell <peter.maydell@linaro.org> > Sent: 16 May 2022 10:57 > To: Frederic Konrad <fkonrad@xilinx.com> > Cc: qemu-devel@nongnu.org; alistair@alistair23.me; > edgar.iglesias@gmail.com; qemu-arm@nongnu.org; Sai Pavan Boddu > <saipava@xilinx.com>; Edgar Iglesias <edgari@xilinx.com>; > fkonrad@amd.com; Sai Pavan Boddu <saipava@xilinx.com>; Edgar Iglesias > <edgari@xilinx.com> > Subject: Re: [PATCH v1 2/4] xlnx_dp: Introduce a vblank signal > > On Tue, 3 May 2022 at 16:27, <frederic.konrad@xilinx.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> > > --- > > > > @@ -1309,6 +1323,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, PTIMER_POLICY_DEFAULT); > > + ptimer_transaction_begin(s->vblank); > > + ptimer_set_freq(s->vblank, 30); > > + ptimer_transaction_commit(s->vblank); > > The ptimer documentation (in include/hw/ptimer.h) says > * The default ptimer policy retains backward compatibility with the legacy > * timers. Custom policies are adjusting the default one. Consider providing > * a correct policy for your timer. > > and goes on to describe various weird behaviours of the default > policy. You almost certainly don't want to use PTIMER_POLICY_DEFAULT > for a new timer -- instead figure out the behaviour you actually > want and specify the appropriate flags. Hi Peter, Thanks for your feedback. Yes, I think, I can just use CONTINUOUS_TRIGGER and NO_IMMEDIATE_TRIGGER instead of forcing the decrementer / reload value to 1. Would that be cleaner? Thanks, Fred > > thanks > -- PMM
On Mon, 16 May 2022 at 11:36, Frederic Konrad <fkonrad@xilinx.com> wrote: > > From: Peter Maydell <peter.maydell@linaro.org> > > > > On Tue, 3 May 2022 at 16:27, <frederic.konrad@xilinx.com> wrote: > > The ptimer documentation (in include/hw/ptimer.h) says > > * The default ptimer policy retains backward compatibility with the legacy > > * timers. Custom policies are adjusting the default one. Consider providing > > * a correct policy for your timer. > > > > and goes on to describe various weird behaviours of the default > > policy. You almost certainly don't want to use PTIMER_POLICY_DEFAULT > > for a new timer -- instead figure out the behaviour you actually > > want and specify the appropriate flags. > > Hi Peter, > > Thanks for your feedback. > > Yes, I think, I can just use CONTINUOUS_TRIGGER and NO_IMMEDIATE_TRIGGER > instead of forcing the decrementer / reload value to 1. Would that be cleaner? I don't know exactly what behaviour you want, but you should probably also consider PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD. -- PMM
On Tue, May 03, 2022 at 04:25:43PM +0100, frederic.konrad@xilinx.com wrote:
> From: Sai Pavan Boddu <sai.pavan.boddu@xilinx.com>
>
> Add a periodic timer which raises vblank at a frequency of 30Hz.
>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
> 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>
> ---
> hw/display/xlnx_dp.c | 24 +++++++++++++++++++++---
> include/hw/display/xlnx_dp.h | 3 +++
> 2 files changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
> index 0378570459..984b0a6bb9 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)
> @@ -773,6 +774,14 @@ 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_set_limit(s->vblank, 1, 1);
> + ptimer_run(s->vblank, 0);
> + } else {
> + ptimer_stop(s->vblank);
> + }
> + ptimer_transaction_commit(s->vblank);
> break;
> case DP_FORCE_SCRAMBLER_RESET:
> /*
> @@ -1177,9 +1186,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 +1281,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 +1323,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, PTIMER_POLICY_DEFAULT);
> + 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"
> --
> 2.25.1
>
© 2016 - 2026 Red Hat, Inc.