/* FIFO setup */ #include #include #include #include #include "screen.h" #include "object.h" #define DEBUG 0 /* Global variables */ struct drm_nouveau_channel_alloc init; /* Local variables */ static uint32_t *fifo = NULL; static uint32_t *fifo_regs = NULL; static uint32_t *notifier_block = NULL; static uint32_t fifo_current, fifo_free; /* Functions */ int fifo_open(void) { int ret; init.fb_ctxdma_handle = NvDmaFB; init.tt_ctxdma_handle = NvDmaTT; ret = drmCommandWriteRead(drm_fd, DRM_NOUVEAU_CHANNEL_ALLOC, &init, sizeof(init)); if (ret) { fprintf(stderr,"Failed to create GPU channel: %d\n", ret); return 1; } printf("Fifo %d: cb_handle=0x%08x, cb_size=0x%08x\n", init.channel, init.cmdbuf, init.cmdbuf_size); ret = drmMap(drm_fd, init.cmdbuf, init.cmdbuf_size, (void*)&fifo); if (ret) { fprintf(stderr, "Mapping DMA push buffer returned %d\n", ret); return 1; } ret = drmMap(drm_fd, init.ctrl, init.ctrl_size, (void*)&fifo_regs); if (ret) { fprintf(stderr, "Mapping FIFO regs returned %d\n", ret); return 1; } ret = drmMap(drm_fd, init.notifier, init.notifier_size, (void*)¬ifier_block); if (ret) { fprintf(stderr, "Mapping notifier block returned %d\n", ret); return 1; } printf("FIFO:\t%p (0x%08x)\n", fifo, init.cmdbuf); printf("FIFO regs:\t%p (0x%08x)\n", fifo_regs, init.ctrl); printf("Notifiers:\t%p (0x%08x)\n", notifier_block, init.notifier); printf("PUT base:\t0x%08x\n", init.put_base); fifo_current = 0; fifo_free = (init.cmdbuf_size>>2) - 1; printf("FIFO current:\t0x%x free=0x%x\n", fifo_current, fifo_free); return 0; } void fifo_print_getput(void) { printf("FIFO put=0x%08x, get=0x%08x, current=0x%08x\n", fifo_regs[0x40/4], fifo_regs[0x44/4], fifo_current ); } void OUT_RING(uint32_t data) { #if DEBUG printf("out_ring(0x%08x)\n", data); #else fifo[fifo_current++] = data; #endif } void OUT_RINGf(float data) { #if DEBUG printf("out_ringf(0x%08x)= %.f\n", data, data); #else fifo[fifo_current++] = data; #endif } void FIRE_RING(void) { #if DEBUG printf("fire_ring()\n"); #else fifo_regs[0x40/4] = (fifo_current<<2) + init.put_base; #endif } void BEGIN_RING(int subchannel, int method, int size) { size &= (1<<11)-1; subchannel &= (1<<3)-1; method &= 0x40001ffc; if (fifo_free<=size) { fprintf(stderr,"FIFO full\n"); return; } OUT_RING(method|(size<<18)|(subchannel<<13)); fifo_free -= size; } void SetSubchannel(int subchannel, int obj) { BEGIN_RING(subchannel, 0, 1); OUT_RING(obj); }