Drivers for the r100 submit packets using the ring buffer. The real
CP engine operates asynchronously. This is a synchronous implementation
of it. Packet processing is triggered by a write to CP_RB_WPTR and
proceeds until the buffer has been emptied.

Signed-off-by: Chad Jablonski <[email protected]>
---
 hw/display/ati.c      | 50 +++++++++++++++++++++++++++++++++++++++++++
 hw/display/ati_int.h  |  5 +++++
 hw/display/ati_regs.h |  5 +++++
 3 files changed, 60 insertions(+)

diff --git a/hw/display/ati.c b/hw/display/ati.c
index ad32965866..d758e652b5 100644
--- a/hw/display/ati.c
+++ b/hw/display/ati.c
@@ -606,6 +606,23 @@ static uint64_t ati_mm_read(void *opaque, hwaddr addr, 
unsigned int size)
     case MC_FB_LOCATION:
         val = s->regs.mc_fb_location;
         break;
+    case CP_CSQ_CNTL:
+        if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY) {
+            val = s->regs.cp_csq_cntl;
+        }
+        break;
+    case CP_RB_BASE:
+        val = s->regs.cp_rb_base;
+        break;
+    case CP_RB_CNTL:
+        val = s->regs.cp_rb_cntl;
+        break;
+    case CP_RB_RPTR:
+        val = s->regs.cp_rb_rptr;
+        break;
+    case CP_RB_WPTR:
+        val = s->regs.cp_rb_wptr;
+        break;
     default:
         break;
     }
@@ -1129,6 +1146,35 @@ void ati_mm_write(void *opaque, hwaddr addr,
          */
         s->regs.mc_fb_location = (data & 0xffc0ffc0) | 0x003f0000;
         break;
+    case CP_CSQ_CNTL:
+        if (s->dev_id == PCI_DEVICE_ID_ATI_RADEON_QY) {
+            s->regs.cp_csq_cntl = data & 0xf0000000;
+        }
+        break;
+    case CP_RB_BASE:
+        s->regs.cp_rb_base = data & 0xfffffffc;
+        break;
+    case CP_RB_CNTL:
+        s->regs.cp_rb_cntl = data & 0x880f3f3f;
+        break;
+    case CP_RB_WPTR:
+    {
+        uint32_t size_l2qw = s->regs.cp_rb_cntl & 0x3f;
+        /*
+         * RPTR and WPTR are only 23 bits wide, sizes larger
+         * than this make no sense.
+         */
+        unsigned shift = size_l2qw > 22 ? 23 : size_l2qw + 1;
+        uint32_t size_msk = (1U << shift) - 1;
+        s->regs.cp_rb_wptr = data & size_msk;
+        while (s->regs.cp_rb_rptr != s->regs.cp_rb_wptr) {
+            uint32_t offs = s->regs.cp_rb_base +
+                            s->regs.cp_rb_rptr * sizeof(uint32_t);
+            ati_pkt_receive_data(s, &s->cur_packet, ati_mc_read(s, offs));
+            s->regs.cp_rb_rptr = (s->regs.cp_rb_rptr + 1) & size_msk;
+        }
+        break;
+    }
     default:
         break;
     }
@@ -1251,6 +1297,10 @@ static void ati_vga_reset(DeviceState *dev)
     s->host_data.next = 0;
     s->host_data.row = 0;
     s->host_data.col = 0;
+    s->regs.cp_rb_rptr = 0;
+    s->regs.cp_rb_wptr = 0;
+    s->regs.cp_rb_base = 0;
+    s->regs.cp_rb_cntl = 0;
     memset(&s->cur_packet, 0, sizeof(s->cur_packet));
 }
 
diff --git a/hw/display/ati_int.h b/hw/display/ati_int.h
index bbc360b636..00fb03c4b4 100644
--- a/hw/display/ati_int.h
+++ b/hw/display/ati_int.h
@@ -124,6 +124,11 @@ typedef struct ATIVGARegs {
     uint32_t aic_lo_addr;
     uint32_t aic_hi_addr;
     uint32_t mc_fb_location;
+    uint32_t cp_csq_cntl;
+    uint32_t cp_rb_base;
+    uint32_t cp_rb_cntl;
+    uint32_t cp_rb_rptr;
+    uint32_t cp_rb_wptr;
 } ATIVGARegs;
 
 typedef struct ATIHostDataState {
diff --git a/hw/display/ati_regs.h b/hw/display/ati_regs.h
index 5e9396bd7a..755b9656b1 100644
--- a/hw/display/ati_regs.h
+++ b/hw/display/ati_regs.h
@@ -117,11 +117,15 @@
 #define OV0_SCALE_CNTL                          0x0420
 #define SUBPIC_CNTL                             0x0540
 #define PM4_BUFFER_OFFSET                       0x0700
+#define CP_RB_BASE                              0x0700
 #define PM4_BUFFER_CNTL                         0x0704
+#define CP_RB_CNTL                              0x0704
 #define PM4_BUFFER_WM_CNTL                      0x0708
 #define PM4_BUFFER_DL_RPTR_ADDR                 0x070c
 #define PM4_BUFFER_DL_RPTR                      0x0710
+#define CP_RB_RPTR                              0x0710
 #define PM4_BUFFER_DL_WPTR                      0x0714
+#define CP_RB_WPTR                              0x0714
 #define PM4_VC_FPU_SETUP                        0x071c
 #define PM4_FPU_CNTL                            0x0720
 #define PM4_VC_FORMAT                           0x0724
@@ -132,6 +136,7 @@
 #define PM4_IW_INDOFF                           0x0738
 #define PM4_IW_INDSIZE                          0x073c
 #define PM4_FPU_FPX0                            0x0740
+#define CP_CSQ_CNTL                             0x0740
 #define PM4_FPU_FPY0                            0x0744
 #define PM4_FPU_FPX1                            0x0748
 #define PM4_FPU_FPY1                            0x074c
-- 
2.54.0


Reply via email to