static void spu_cb(void * p) { if (p) { dma_chain_t * chain = (dma_chain_t *) p; if (chain->src == NULL) { free_chain(chain); } else { sem_signal(chain->sema); if (chain->waiting_thd) thd_schedule_next(chain->waiting_thd); chain->dest = 0; /* mark dma completed */ } if (spu_chain_head == NULL) ;//draw_unlock(); vid_border_color(0, 0, 0); spu_transfering = 0; } else ;//bba_lock(); //asic_evt_disable(ASIC_EVT_EXP_PCI, ASIC_IRQB); if (spu_chain_head) { dma_chain_t * chain = spu_chain_head; spu_transfering = 1; vid_border_color(0, 255, 0); switch(chain->type) { /* case DMA_TYPE_VRAM: */ /* pvr_txr_load_dma(chain->src, chain->dest, */ /* chain->count, 0, spu_cb, chain); */ /* break; */ case DMA_TYPE_SPU: dma_cache_flush(chain->src, chain->count); spu_dma_transfer(chain->src, chain->dest, chain->count, 0, spu_cb, chain); break; case DMA_TYPE_BBA_RX: g2_dma_transfer(chain->dest, chain->src, chain->count, 0, spu_cb, chain, 1, bba_dma_mode, 1, 3); break; default: panic("got bad dma chain type in spu_cb\n"); } spu_chain_head = chain->next; } else { //asic_evt_enable(ASIC_EVT_EXP_PCI, ASIC_IRQB); ;//bba_unlock(); } }
static void spu_memload_stereo16(int leftpos, int rightpos, void *src0, size_t size) { register uint16 *src = src0; #if 0 sep_data(src, size, 1); dcache_flush_range((unsigned)sep_buffer, size); dmadest = rightpos; dmacnt = size / 2; spu_dma_transfer(sep_buffer[0], leftpos, size / 2, -1, spu_dma_transfer2, 0); //spu_dma_transfer(sep_buffer[1], rightpos, size / 2, -1, NULL, 0); #else register uint32 *left = (uint32*)(leftpos + SPU_RAM_BASE); register uint32 *right = (uint32*)(rightpos + SPU_RAM_BASE); size = (size+7)/8; unsigned lval, rval, old = 0; while(size--) { lval = *src++; rval = *src++; lval|= (*src++)<<16; rval|= (*src++)<<16; g2_fifo_wait(); G2_LOCK(old); *left++=lval; *right++=rval; G2_UNLOCK(old); /* g2_write_32(*left++,lval); g2_write_32(*right++,rval); g2_fifo_wait();*/ } #endif }
static void spu_dma_transfer2(ptr_t data) { spu_dma_transfer(sep_buffer[1], dmadest, dmacnt, -1, NULL, 0); }