diff mbox series

[v3,2/4] xlnx_dp: Introduce a vblank signal

Message ID 20220601172353.3220232-3-fkonrad@xilinx.com
State New
Headers show
Series xlnx-zcu102: fix the display port. | expand

Commit Message

frederic.konrad@xilinx.com June 1, 2022, 5:23 p.m. UTC
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         | 28 +++++++++++++++++++++++++---
 include/hw/display/xlnx_dp.h |  3 +++
 2 files changed, 28 insertions(+), 3 deletions(-)

Comments

Alistair Francis June 2, 2022, 12:35 a.m. UTC | #1
On Thu, Jun 2, 2022 at 3:29 AM <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>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  hw/display/xlnx_dp.c         | 28 +++++++++++++++++++++++++---
>  include/hw/display/xlnx_dp.h |  3 +++
>  2 files changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
> index 0378570459..d0bea512bd 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)
> @@ -270,10 +271,15 @@ static const VMStateDescription vmstate_dp = {
>                               DP_VBLEND_REG_ARRAY_SIZE),
>          VMSTATE_UINT32_ARRAY(audio_registers, XlnxDPState,
>                               DP_AUDIO_REG_ARRAY_SIZE),
> +        VMSTATE_PTIMER(vblank, XlnxDPState),
>          VMSTATE_END_OF_LIST()
>      }
>  };
>
> +#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 +779,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 +1190,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 +1285,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 +1327,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"
> --
> 2.25.1
>
>
diff mbox series

Patch

diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 0378570459..d0bea512bd 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)
@@ -270,10 +271,15 @@  static const VMStateDescription vmstate_dp = {
                              DP_VBLEND_REG_ARRAY_SIZE),
         VMSTATE_UINT32_ARRAY(audio_registers, XlnxDPState,
                              DP_AUDIO_REG_ARRAY_SIZE),
+        VMSTATE_PTIMER(vblank, XlnxDPState),
         VMSTATE_END_OF_LIST()
     }
 };
 
+#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 +779,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 +1190,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 +1285,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 +1327,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"