Implements the second CMDFIFO2 queue for Voodoo 3, fixing BeOS's Voodoo 3/Banshee drivers, fixes #4794.
This commit is contained in:
@@ -408,6 +408,7 @@ typedef struct voodoo_t {
|
||||
atomic_int cmd_read;
|
||||
atomic_int cmd_written;
|
||||
atomic_int cmd_written_fifo;
|
||||
atomic_int cmd_written_fifo_2;
|
||||
|
||||
voodoo_params_t params_buffer[PARAM_SIZE];
|
||||
atomic_int params_read_idx[4];
|
||||
@@ -426,7 +427,20 @@ typedef struct voodoo_t {
|
||||
uint32_t cmdfifo_amax;
|
||||
int cmdfifo_holecount;
|
||||
|
||||
atomic_uint cmd_status;
|
||||
uint32_t cmdfifo_base_2;
|
||||
uint32_t cmdfifo_end_2;
|
||||
uint32_t cmdfifo_size_2;
|
||||
int cmdfifo_rp_2;
|
||||
int cmdfifo_ret_addr_2;
|
||||
int cmdfifo_in_sub_2;
|
||||
atomic_int cmdfifo_depth_rd_2;
|
||||
atomic_int cmdfifo_depth_wr_2;
|
||||
atomic_int cmdfifo_enabled_2;
|
||||
uint32_t cmdfifo_amin_2;
|
||||
uint32_t cmdfifo_amax_2;
|
||||
int cmdfifo_holecount_2;
|
||||
|
||||
atomic_uint cmd_status, cmd_status_2;
|
||||
|
||||
uint32_t sSetupMode;
|
||||
vert_t verts[4];
|
||||
|
||||
@@ -222,12 +222,12 @@ voodoo_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
int fifo_entries = FIFO_ENTRIES;
|
||||
int swap_count = voodoo->swap_count;
|
||||
int written = voodoo->cmd_written + voodoo->cmd_written_fifo;
|
||||
int written = voodoo->cmd_written + voodoo->cmd_written_fifo + voodoo->cmd_written_fifo_2;
|
||||
int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr);
|
||||
|
||||
if (SLI_ENABLED && voodoo->type != VOODOO_2) {
|
||||
voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0];
|
||||
int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo;
|
||||
int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo + voodoo->cmd_written_fifo_2;
|
||||
|
||||
if (voodoo_other->swap_count > swap_count)
|
||||
swap_count = voodoo_other->swap_count;
|
||||
|
||||
@@ -204,6 +204,17 @@ enum {
|
||||
cmdFifoDepth0 = 0x44,
|
||||
cmdHoleCnt0 = 0x48,
|
||||
|
||||
cmdBaseAddr1 = 0x50,
|
||||
cmdBaseSize1 = 0x50 + 0x4,
|
||||
cmdBump1 = 0x50 + 0x8,
|
||||
cmdRdPtrL1 = 0x50 + 0xc,
|
||||
cmdRdPtrH1 = 0x50 + 0x10,
|
||||
cmdAMin1 = 0x50 + 0x14,
|
||||
cmdAMax1 = 0x50 + 0x1c,
|
||||
cmdStatus1 = 0x50 + 0x20,
|
||||
cmdFifoDepth1 = 0x50 + 0x24,
|
||||
cmdHoleCnt1 = 0x50 + 0x28,
|
||||
|
||||
Agp_agpReqSize = 0x00,
|
||||
Agp_agpHostAddressLow = 0x04,
|
||||
Agp_agpHostAddressHigh = 0x08,
|
||||
@@ -1341,6 +1352,29 @@ banshee_cmd_read(banshee_t *banshee, uint32_t addr)
|
||||
ret = voodoo->cmdfifo_size;
|
||||
break;
|
||||
|
||||
case cmdBaseAddr1:
|
||||
ret = voodoo->cmdfifo_base_2 >> 12;
|
||||
// banshee_log("Read cmdfifo_base %08x\n", ret);
|
||||
break;
|
||||
|
||||
case cmdRdPtrL1:
|
||||
ret = voodoo->cmdfifo_rp_2;
|
||||
// banshee_log("Read cmdfifo_rp %08x\n", ret);
|
||||
break;
|
||||
|
||||
case cmdFifoDepth1:
|
||||
ret = voodoo->cmdfifo_depth_wr_2 - voodoo->cmdfifo_depth_rd_2;
|
||||
// banshee_log("Read cmdfifo_depth %08x\n", ret);
|
||||
break;
|
||||
|
||||
case cmdStatus1:
|
||||
ret = voodoo->cmd_status_2;
|
||||
break;
|
||||
|
||||
case cmdBaseSize1:
|
||||
ret = voodoo->cmdfifo_size_2;
|
||||
break;
|
||||
|
||||
case 0x108:
|
||||
break;
|
||||
|
||||
@@ -1625,6 +1659,45 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val)
|
||||
voodoo->cmdfifo_depth_wr = val & 0xffff;
|
||||
break;
|
||||
|
||||
case cmdBaseAddr1:
|
||||
voodoo->cmdfifo_base_2 = (val & 0xfff) << 12;
|
||||
voodoo->cmdfifo_end_2 = voodoo->cmdfifo_base_2 + (((voodoo->cmdfifo_size_2 & 0xff) + 1) << 12);
|
||||
#if 0
|
||||
banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, val);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case cmdBaseSize1:
|
||||
voodoo->cmdfifo_size_2 = val;
|
||||
voodoo->cmdfifo_end_2 = voodoo->cmdfifo_base_2 + (((voodoo->cmdfifo_size_2 & 0xff) + 1) << 12);
|
||||
voodoo->cmdfifo_enabled_2 = val & 0x100;
|
||||
if (!voodoo->cmdfifo_enabled_2)
|
||||
voodoo->cmdfifo_in_sub_2 = 0; /*Not sure exactly when this should be reset*/
|
||||
#if 0
|
||||
banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if 0
|
||||
voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12;
|
||||
banshee_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case cmdRdPtrL1:
|
||||
voodoo->cmdfifo_rp_2 = val;
|
||||
break;
|
||||
case cmdAMin1:
|
||||
voodoo->cmdfifo_amin_2 = val;
|
||||
break;
|
||||
case cmdAMax1:
|
||||
voodoo->cmdfifo_amax_2 = val;
|
||||
break;
|
||||
case cmdFifoDepth1:
|
||||
voodoo->cmdfifo_depth_rd_2 = 0;
|
||||
voodoo->cmdfifo_depth_wr_2 = val & 0xffff;
|
||||
break;
|
||||
|
||||
default:
|
||||
banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x reg=0x%03x\n", addr, val, addr & 0x1fc);
|
||||
break;
|
||||
@@ -2064,6 +2137,60 @@ banshee_write_linear_l(uint32_t addr, uint32_t val, void *priv)
|
||||
voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1;
|
||||
#if 0
|
||||
banshee_log("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (voodoo->cmdfifo_enabled_2 && addr >= voodoo->cmdfifo_base_2 && addr < voodoo->cmdfifo_end_2) {
|
||||
#if 0
|
||||
banshee_log("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp);
|
||||
#endif
|
||||
if (addr == voodoo->cmdfifo_base_2 && !voodoo->cmdfifo_holecount_2) {
|
||||
#if 0
|
||||
if (voodoo->cmdfifo_holecount)
|
||||
fatal("CMDFIFO reset pointers while outstanding holes\n");
|
||||
#endif
|
||||
/*Reset pointers*/
|
||||
voodoo->cmdfifo_amin_2 = voodoo->cmdfifo_base_2;
|
||||
voodoo->cmdfifo_amax_2 = voodoo->cmdfifo_base_2;
|
||||
voodoo->cmdfifo_depth_wr_2++;
|
||||
voodoo_wake_fifo_thread(voodoo);
|
||||
} else if (voodoo->cmdfifo_holecount_2) {
|
||||
#if 0
|
||||
if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax)
|
||||
fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount);
|
||||
banshee_log("holecount %i\n", voodoo->cmdfifo_holecount);
|
||||
#endif
|
||||
voodoo->cmdfifo_holecount_2--;
|
||||
if (!voodoo->cmdfifo_holecount_2) {
|
||||
/*Filled in holes, resume normal operation*/
|
||||
voodoo->cmdfifo_depth_wr_2 += ((voodoo->cmdfifo_amax_2 - voodoo->cmdfifo_amin_2) >> 2);
|
||||
voodoo->cmdfifo_amin_2 = voodoo->cmdfifo_amax_2;
|
||||
voodoo_wake_fifo_thread(voodoo);
|
||||
#if 0
|
||||
banshee_log("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add);
|
||||
#endif
|
||||
}
|
||||
} else if (addr == voodoo->cmdfifo_amax_2 + 4) {
|
||||
/*In-order write*/
|
||||
voodoo->cmdfifo_amin_2 = addr;
|
||||
voodoo->cmdfifo_amax_2 = addr;
|
||||
voodoo->cmdfifo_depth_wr_2++;
|
||||
voodoo_wake_fifo_thread(voodoo);
|
||||
} else {
|
||||
/*Out-of-order write*/
|
||||
if (addr < voodoo->cmdfifo_amin_2) {
|
||||
/*Reset back to start. Note that write is still out of order!*/
|
||||
voodoo->cmdfifo_amin_2 = voodoo->cmdfifo_base_2 - 4;
|
||||
}
|
||||
#if 0
|
||||
else if (addr < voodoo->cmdfifo_amax)
|
||||
fatal("Out-of-order write really out of order\n");
|
||||
#endif
|
||||
voodoo->cmdfifo_amax_2 = addr;
|
||||
voodoo->cmdfifo_holecount_2 = ((voodoo->cmdfifo_amax_2 - voodoo->cmdfifo_amin_2) >> 2) - 1;
|
||||
#if 0
|
||||
banshee_log("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -3313,6 +3440,7 @@ banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int
|
||||
banshee->voodoo->tex_mem_w[1] = (uint16_t *) banshee->svga.vram;
|
||||
banshee->voodoo->texture_mask = banshee->svga.vram_mask;
|
||||
banshee->voodoo->cmd_status = (1 << 28);
|
||||
banshee->voodoo->cmd_status_2 = (1 << 28);
|
||||
voodoo_generate_filter_v1(banshee->voodoo);
|
||||
|
||||
banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W;
|
||||
|
||||
@@ -188,6 +188,40 @@ cmdfifo_get_f(voodoo_t *voodoo)
|
||||
return tempif.f;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
cmdfifo_get_2(voodoo_t *voodoo)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if (!voodoo->cmdfifo_in_sub_2) {
|
||||
while (voodoo->fifo_thread_run && (voodoo->cmdfifo_depth_rd_2 == voodoo->cmdfifo_depth_wr_2)) {
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
}
|
||||
}
|
||||
|
||||
val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp_2 & voodoo->fb_mask];
|
||||
|
||||
if (!voodoo->cmdfifo_in_sub_2)
|
||||
voodoo->cmdfifo_depth_rd_2++;
|
||||
voodoo->cmdfifo_rp_2 += 4;
|
||||
|
||||
// voodoo_fifo_log(" CMDFIFO get %08x\n", val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline float
|
||||
cmdfifo_get_f_2(voodoo_t *voodoo)
|
||||
{
|
||||
union {
|
||||
uint32_t i;
|
||||
float f;
|
||||
} tempif;
|
||||
|
||||
tempif.i = cmdfifo_get(voodoo);
|
||||
return tempif.f;
|
||||
}
|
||||
|
||||
enum {
|
||||
CMDFIFO3_PC_MASK_RGB = (1 << 10),
|
||||
CMDFIFO3_PC_MASK_ALPHA = (1 << 11),
|
||||
@@ -283,6 +317,7 @@ voodoo_fifo_thread(void *param)
|
||||
}
|
||||
|
||||
voodoo->cmd_status |= (1 << 24);
|
||||
voodoo->cmd_status_2 |= (1 << 24);
|
||||
|
||||
while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) {
|
||||
uint64_t start_time = plat_timer_read();
|
||||
@@ -545,6 +580,269 @@ voodoo_fifo_thread(void *param)
|
||||
end_time = plat_timer_read();
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
|
||||
while (voodoo->cmdfifo_enabled_2 && (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2 || voodoo->cmdfifo_in_sub_2)) {
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
uint32_t header = cmdfifo_get_2(voodoo);
|
||||
uint32_t addr;
|
||||
uint32_t mask;
|
||||
int smode;
|
||||
int num;
|
||||
int num_verticies;
|
||||
int v_num;
|
||||
|
||||
#if 0
|
||||
voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp);
|
||||
#endif
|
||||
|
||||
voodoo->cmd_status_2 &= ~7;
|
||||
voodoo->cmd_status_2 |= (header & 7);
|
||||
voodoo->cmd_status_2 |= (1 << 11);
|
||||
switch (header & 7) {
|
||||
case 0:
|
||||
#if 0
|
||||
voodoo_fifo_log("CMDFIFO0\n");
|
||||
#endif
|
||||
voodoo->cmd_status_2 = (voodoo->cmd_status_2 & 0xffff8fff) | (((header >> 3) & 7) << 12);
|
||||
switch ((header >> 3) & 7) {
|
||||
case 0: /*NOP*/
|
||||
break;
|
||||
|
||||
case 1: /*JSR*/
|
||||
#if 0
|
||||
voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc);
|
||||
#endif
|
||||
voodoo->cmdfifo_ret_addr_2 = voodoo->cmdfifo_rp_2;
|
||||
voodoo->cmdfifo_rp_2 = (header >> 4) & 0xfffffc;
|
||||
voodoo->cmdfifo_in_sub_2 = 1;
|
||||
break;
|
||||
|
||||
case 2: /*RET*/
|
||||
voodoo->cmdfifo_rp_2 = voodoo->cmdfifo_ret_addr_2;
|
||||
voodoo->cmdfifo_in_sub_2 = 0;
|
||||
break;
|
||||
|
||||
case 3: /*JMP local frame buffer*/
|
||||
voodoo->cmdfifo_rp_2 = (header >> 4) & 0xfffffc;
|
||||
#if 0
|
||||
voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Bad CMDFIFO0 %08x\n", header);
|
||||
}
|
||||
voodoo->cmd_status_2 = (voodoo->cmd_status_2 & ~(1 << 27)) | (voodoo->cmdfifo_in_sub_2 << 27);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
num = header >> 16;
|
||||
addr = (header & 0x7ff8) >> 1;
|
||||
#if 0
|
||||
voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr);
|
||||
#endif
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get_2(voodoo);
|
||||
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) {
|
||||
#if 0
|
||||
if (voodoo->type != VOODOO_BANSHEE)
|
||||
fatal("CMDFIFO1: Not Banshee\n");
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
|
||||
#endif
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
} else {
|
||||
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
|
||||
voodoo->cmd_written_fifo_2++;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
|
||||
voodoo->cmd_written_fifo_2++;
|
||||
voodoo_reg_writel(addr, val, voodoo);
|
||||
}
|
||||
|
||||
if (header & (1 << 15))
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (voodoo->type < VOODOO_2)
|
||||
fatal("CMDFIFO2: Not Voodoo 2\n");
|
||||
mask = (header >> 3);
|
||||
addr = 8;
|
||||
while (mask) {
|
||||
if (mask & 1) {
|
||||
uint32_t val = cmdfifo_get_2(voodoo);
|
||||
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
mask >>= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
num = (header >> 29) & 7;
|
||||
mask = header; //(header >> 10) & 0xff;
|
||||
smode = (header >> 22) & 0xf;
|
||||
voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo);
|
||||
num_verticies = (header >> 6) & 0xf;
|
||||
v_num = 0;
|
||||
if (((header >> 3) & 7) == 2)
|
||||
v_num = 1;
|
||||
#if 0
|
||||
voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff);
|
||||
voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7);
|
||||
#endif
|
||||
|
||||
while (num_verticies--) {
|
||||
voodoo->verts[3].sVx = cmdfifo_get_f_2(voodoo);
|
||||
voodoo->verts[3].sVy = cmdfifo_get_f_2(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_RGB) {
|
||||
if (header & CMDFIFO3_PC) {
|
||||
uint32_t val = cmdfifo_get_2(voodoo);
|
||||
voodoo->verts[3].sBlue = (float) (val & 0xff);
|
||||
voodoo->verts[3].sGreen = (float) ((val >> 8) & 0xff);
|
||||
voodoo->verts[3].sRed = (float) ((val >> 16) & 0xff);
|
||||
voodoo->verts[3].sAlpha = (float) ((val >> 24) & 0xff);
|
||||
} else {
|
||||
voodoo->verts[3].sRed = cmdfifo_get_f_2(voodoo);
|
||||
voodoo->verts[3].sGreen = cmdfifo_get_f_2(voodoo);
|
||||
voodoo->verts[3].sBlue = cmdfifo_get_f_2(voodoo);
|
||||
}
|
||||
}
|
||||
if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC))
|
||||
voodoo->verts[3].sAlpha = cmdfifo_get_f_2(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_Z)
|
||||
voodoo->verts[3].sVz = cmdfifo_get_f_2(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_Wb)
|
||||
voodoo->verts[3].sWb = cmdfifo_get_f_2(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_W0)
|
||||
voodoo->verts[3].sW0 = cmdfifo_get_f_2(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_S0_T0) {
|
||||
voodoo->verts[3].sS0 = cmdfifo_get_f_2(voodoo);
|
||||
voodoo->verts[3].sT0 = cmdfifo_get_f_2(voodoo);
|
||||
}
|
||||
if (mask & CMDFIFO3_PC_MASK_W1)
|
||||
voodoo->verts[3].sW1 = cmdfifo_get_f_2(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_S1_T1) {
|
||||
voodoo->verts[3].sS1 = cmdfifo_get_f_2(voodoo);
|
||||
voodoo->verts[3].sT1 = cmdfifo_get_f_2(voodoo);
|
||||
}
|
||||
if (v_num)
|
||||
voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo);
|
||||
else
|
||||
voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo);
|
||||
v_num++;
|
||||
if (v_num == 3 && ((header >> 3) & 7) == 0)
|
||||
v_num = 0;
|
||||
}
|
||||
while (num--)
|
||||
cmdfifo_get_2(voodoo);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
num = (header >> 29) & 7;
|
||||
mask = (header >> 15) & 0x3fff;
|
||||
addr = (header & 0x7ff8) >> 1;
|
||||
#if 0
|
||||
voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr);
|
||||
#endif
|
||||
while (mask) {
|
||||
if (mask & 1) {
|
||||
uint32_t val = cmdfifo_get_2(voodoo);
|
||||
|
||||
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) {
|
||||
if (voodoo->type < VOODOO_BANSHEE)
|
||||
fatal("CMDFIFO1: Not Banshee\n");
|
||||
#if 0
|
||||
voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
|
||||
#endif
|
||||
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
} else {
|
||||
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
|
||||
voodoo->cmd_written_fifo_2++;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
|
||||
voodoo->cmd_written_fifo_2++;
|
||||
voodoo_reg_writel(addr, val, voodoo);
|
||||
}
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
mask >>= 1;
|
||||
}
|
||||
while (num--)
|
||||
cmdfifo_get_2(voodoo);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
#if 0
|
||||
if (header & 0x3fc00000)
|
||||
fatal("CMDFIFO packet 5 has byte disables set %08x\n", header);
|
||||
#endif
|
||||
num = (header >> 3) & 0x7ffff;
|
||||
addr = cmdfifo_get_2(voodoo) & 0xffffff;
|
||||
if (!num)
|
||||
num = 1;
|
||||
#if 0
|
||||
voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num);
|
||||
#endif
|
||||
switch (header >> 30) {
|
||||
case 0: /*Linear framebuffer (Banshee)*/
|
||||
case 1: /*Planar YUV*/
|
||||
if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) {
|
||||
#if 0
|
||||
voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
|
||||
#endif
|
||||
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0);
|
||||
}
|
||||
if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) {
|
||||
#if 0
|
||||
voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
|
||||
#endif
|
||||
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1);
|
||||
}
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get_2(voodoo);
|
||||
if (addr <= voodoo->fb_mask)
|
||||
*(uint32_t *) &voodoo->fb_mem[addr] = val;
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
case 2: /*Framebuffer*/
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get_2(voodoo);
|
||||
voodoo_fb_writel(addr, val, voodoo);
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
case 3: /*Texture*/
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get_2(voodoo);
|
||||
voodoo_tex_writel(addr, val, voodoo);
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
}
|
||||
|
||||
end_time = plat_timer_read();
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
|
||||
voodoo->voodoo_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user