radeon_hd: Begin work on radeon_hd command processor

* First steps at getting card command processor wired
  up to the ring buffers.
* Code doesn't run yet as I have *no* idea what happens
  when these rings are in an invalid state.
This commit is contained in:
Alexander von Gluck IV
2012-04-17 16:10:40 -05:00
parent 582c97352d
commit 9e195872df
4 changed files with 132 additions and 3 deletions
@@ -75,6 +75,8 @@
#define CP_QUEUE_THRESHOLDS 0x8760
#define ROQ_IB1_START(x) ((x) << 0)
#define ROQ_IB2_START(x) ((x) << 8)
#define CP_DEBUG 0xC1FC
#define CP_RB_BASE 0xC100
#define CP_RB_CNTL 0xC104
#define RB_BUFSZ(x) ((x) << 0)
#define RB_BLKSZ(x) ((x) << 8)
+121 -1
View File
@@ -531,7 +531,127 @@ radeon_gpu_ring_boot(uint32 ringType)
return B_ERROR;
}
// TODO: Write initial ring state
// We don't execute this code until it's more complete.
ERROR("%s: TODO\n", __func__);
return B_OK;
// TODO: Write initial ring PACKET3 STATE
// *** r600_cp_init_ring_buffer
// Reset command processor
Write32(OUT, GRBM_SOFT_RESET, RADEON_SOFT_RESET_CP);
Read32(OUT, GRBM_SOFT_RESET);
snooze(15000);
Write32(OUT, GRBM_SOFT_RESET, 0);
// Set ring buffer size
uint32 controlScratch = RB_NO_UPDATE
| (compute_order(4096 / 8) << 8) // rptr_update_l2qw
| compute_order(ring->GetSize() / 8); // size_l2qw
#ifdef __BIG_ENDIAN
controlScratch |= BUF_SWAP_32BIT;
#endif
Write32(OUT, CP_RB_CNTL, controlScratch);
// Set delays and timeouts
Write32(OUT, CP_SEM_WAIT_TIMER, 0);
Write32(OUT, CP_RB_WPTR_DELAY, 0);
// Enable RenderBuffer Reads
controlScratch |= RB_RPTR_WR_ENA;
Write32(OUT, CP_RB_CNTL, controlScratch);
// Zero out command processor read and write pointers
Write32(OUT, CP_RB_RPTR_WR, 0);
Write32(OUT, CP_RB_WPTR, 0);
#if 0
int ringPointer = 0;
// TODO: AGP cards
/*
if (RADEON_IS_AGP) {
ringPointer = dev_priv->ring_rptr->offset
- dev->agp->base
+ dev_priv->gart_vm_start;
} else {
*/
ringPointer = dev_priv->ring_rptr->offset
- ((unsigned long) dev->sg->virtual)
+ dev_priv->gart_vm_start;
Write32(OUT, CP_RB_RPTR_ADDR, (ringPointer & 0xfffffffc));
Write32(OUT, CP_RB_RPTR_ADDR_HI, upper_32_bits(ringPointer));
// Drop RPTR_WR_ENA and update CP RB Control
controlScratch &= ~R600_RB_RPTR_WR_ENA;
Write32(OUT, CP_RB_CNTL, controlScratch);
#endif
#if 0
// Update command processor pointer
int commandPointer = 0;
// TODO: AGP cards
/*
if (RADEON_IS_AGP) {
commandPointer = (dev_priv->cp_ring->offset
- dev->agp->base
+ dev_priv->gart_vm_start);
}
*/
commandPointer = (dev_priv->cp_ring->offset
- (unsigned long)dev->sg->virtual
+ dev_priv->gart_vm_start);
#endif
#if 0
Write32(OUT, CP_RB_BASE, commandPointer >> 8);
Write32(OUT, CP_ME_CNTL, 0xff);
Write32(OUT, CP_DEBUG, (1 << 27) | (1 << 28));
#endif
#if 0
// Initialize scratch register pointer.
// This wil lcause the scratch register values to be wtitten
// to memory whenever they are updated.
uint64 scratchAddr = Read32(OUT, CP_RB_RPTR_ADDR) & 0xFFFFFFFC;
scratchAddr |= ((uint64)Read32(OUT, CP_RB_RPTR_ADDR_HI)) << 32;
scratchAddr += R600_SCRATCH_REG_OFFSET;
scratchAddr >>= 8;
scratchAddr &= 0xffffffff;
Write32(OUT, R600_SCRATCH_ADDR, (uint32)scratchAddr);
Write32(OUT, R600_SCRATCH_UMSK, 0x7);
#endif
#if 0
// Enable bus mastering
radeon_enable_bm(dev_priv);
radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0);
Write32(OUT, R600_LAST_FRAME_REG, 0);
radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
Write32(OUT, R600_LAST_DISPATCH_REG, 0);
radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0);
Write32(OUT, R600_LAST_CLEAR_REG, 0);
#endif
// Reset sarea?
#if 0
master_priv = file_priv->master->driver_priv;
if (master_priv->sarea_priv) {
master_priv->sarea_priv->last_frame = 0;
master_priv->sarea_priv->last_dispatch = 0;
master_priv->sarea_priv->last_clear = 0;
}
r600_do_wait_for_idle(dev_priv);
#endif
return B_OK;
}
@@ -31,7 +31,7 @@ static const char* queueName[RADEON_QUEUE_MAX] = {
};
static int
int
compute_order(unsigned long size)
{
int order;
@@ -11,15 +11,20 @@
#include "Accelerant.h"
#include <stdint.h>
#define RADEON_QUEUE_MAX 3
// Basic r100+ graphic data ring
// Basic r100+ graphic data ring
#define RADEON_QUEUE_TYPE_GFX_INDEX 0
// Cayman+ have two compute command processor rings
#define CAYMAN_QUEUE_TYPE_CP1_INDEX 1
#define CAYMAN_QUEUE_TYPE_CP2_INDEX 2
int compute_order(unsigned long size);
// A basic ring buffer for passing render data into card.
// Data flows from the host to the GPU
class RingQueue {
@@ -33,6 +38,8 @@ public:
size_t GetSize() {return fSize;};
size_t GetWriteAvail() {return fWriteBytesAvail;}
size_t GetReadAvail() {return fSize - fWriteBytesAvail;}
intptr_t GetLocation() {return (intptr_t)fData;}
private:
uint32 fQueueType;