/* Shut down the PVR chip from ready status, leaving it in 2D mode as it was before the init. */ int pvr_shutdown() { if(!pvr_state.valid) return -1; /* Set us invalid */ pvr_state.valid = 0; /* Stop anything that might be going on */ PVR_SET(PVR_RESET, PVR_RESET_ALL); PVR_SET(PVR_RESET, PVR_RESET_NONE); /* Unhook any int handlers */ vblank_handler_remove(pvr_state.vbl_handle); asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEDONE, NULL); asic_evt_disable(ASIC_EVT_PVR_OPAQUEDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEMODDONE, NULL); asic_evt_disable(ASIC_EVT_PVR_OPAQUEMODDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_TRANSDONE, NULL); asic_evt_disable(ASIC_EVT_PVR_TRANSDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_TRANSMODDONE, NULL); asic_evt_disable(ASIC_EVT_PVR_TRANSMODDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_PTDONE, NULL); asic_evt_disable(ASIC_EVT_PVR_PTDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_RENDERDONE, NULL); asic_evt_disable(ASIC_EVT_PVR_RENDERDONE, ASIC_IRQ_DEFAULT); /* Shut down PVR DMA */ pvr_dma_shutdown(); /* Invalidate our memory pool */ pvr_mem_reset(); /* Destroy the semaphore */ sem_destroy((semaphore_t *)&pvr_state.ready_sem); mutex_destroy((mutex_t *)&pvr_state.dma_lock); /* Clear video memory */ vid_empty(); /* Reset the frame buffer offset */ vid_waitvbl(); vid_set_start(0); /* Return success */ return 0; }
/* Initialize the PVR chip to ready status, enabling the specified lists and using the specified parameters; note that bins and vertex buffers come from the texture memory pool! Expects that a 2D mode was initialized already using the vid_* API. */ int pvr_init(pvr_init_params_t *params) { /* If we're already initialized, fail */ if (pvr_state.valid == 1) { dbglog(DBG_WARNING, "pvr: pvr_init called twice!\n"); return -1; } /* Make sure we got valid parameters */ assert(params != NULL); /* Make sure that a video mode has been initialized */ assert(vid_mode != NULL); assert(vid_mode->width != 0 && vid_mode->height != 0); /* Check for compatibility with 3D stuff */ if ((vid_mode->width % 32) != 0) { dbglog(DBG_WARNING, "pvr: mode %dx%d isn't usable for 3D (width not multiples of 32)\n", vid_mode->width, vid_mode->height); return -1; } /* Clear out video memory */ vid_empty(); /* Reset all PVR systems (in case it's still doing something) */ PVR_SET(PVR_RESET, PVR_RESET_ALL); PVR_SET(PVR_RESET, PVR_RESET_NONE); /* Start off with a nice empty structure */ memset((void *)&pvr_state, 0, sizeof(pvr_state)); // Enable DMA if the user wants that. pvr_state.dma_mode = params->dma_enabled; /* Everything's clear, do the initial buffer pointer setup */ pvr_allocate_buffers(params); // Initialize tile matrices pvr_init_tile_matrices(); // Setup all pipeline targets. Yes, this is redundant. :) I just // like to have it explicit. pvr_state.ram_target = 0; pvr_state.ta_target = 0; pvr_state.view_target = 0; pvr_state.list_reg_open = -1; // Sync all the hardware registers with our pipeline state. pvr_sync_view(); pvr_sync_reg_buffer(); // Clear out our stats pvr_state.vbl_count = 0; pvr_state.frame_last_time = 0; pvr_state.buf_start_time = 0; pvr_state.reg_start_time = 0; pvr_state.rnd_start_time = 0; pvr_state.frame_last_len = -1; pvr_state.buf_last_len = -1; pvr_state.reg_last_len = -1; pvr_state.rnd_last_len = -1; pvr_state.vtx_buf_used = 0; pvr_state.vtx_buf_used_max = 0; /* If we're on a VGA box, disable vertical smoothing */ if (vid_mode->cable_type == CT_VGA) { dbglog(DBG_KDEBUG, "pvr: disabling vertical scaling for VGA\n"); PVR_SET(PVR_SCALER_CFG, 0x400); } else { dbglog(DBG_KDEBUG, "pvr: enabling vertical scaling for non-VGA\n"); PVR_SET(PVR_SCALER_CFG, 0x401); } /* Hook the PVR interrupt events on G2 */ pvr_state.vbl_handle = vblank_handler_add(pvr_int_handler); asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEDONE, pvr_int_handler); asic_evt_enable(ASIC_EVT_PVR_OPAQUEDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_OPAQUEMODDONE, pvr_int_handler); asic_evt_enable(ASIC_EVT_PVR_OPAQUEMODDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_TRANSDONE, pvr_int_handler); asic_evt_enable(ASIC_EVT_PVR_TRANSDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_TRANSMODDONE, pvr_int_handler); asic_evt_enable(ASIC_EVT_PVR_TRANSMODDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_PTDONE, pvr_int_handler); asic_evt_enable(ASIC_EVT_PVR_PTDONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_RENDERDONE, pvr_int_handler); asic_evt_enable(ASIC_EVT_PVR_RENDERDONE, ASIC_IRQ_DEFAULT); /* 3d-specific parameters; these are all about rendering and nothing to do with setting up the video; some stuff in here is still unknown. */ PVR_SET(PVR_UNK_00A8, 0x15d1c951); /* M (Unknown magic value) */ PVR_SET(PVR_UNK_00A0, 0x00000020); /* M */ PVR_SET(PVR_FB_CFG_2, 0x00000009); /* alpha config */ PVR_SET(PVR_UNK_0110, 0x00093f39); /* M */ PVR_SET(PVR_UNK_0098, 0x00800408); /* M */ PVR_SET(PVR_TEXTURE_CLIP, 0x00000000); /* texture clip distance */ PVR_SET(PVR_SPANSORT_CFG, 0x00000101); /* M */ PVR_SET(PVR_FOG_TABLE_COLOR, 0x007f7f7f); /* Fog table color */ PVR_SET(PVR_FOG_VERTEX_COLOR, 0x007f7f7f); /* Fog vertex color */ PVR_SET(PVR_COLOR_CLAMP_MIN, 0x00000000); /* color clamp min */ PVR_SET(PVR_COLOR_CLAMP_MAX, 0xffffffff); /* color clamp max */ PVR_SET(PVR_UNK_0080, 0x00000007); /* M */ PVR_SET(PVR_CHEAP_SHADOW, 0x00000001); /* cheap shadow */ PVR_SET(PVR_UNK_007C, 0x0027df77); /* M */ PVR_SET(PVR_TEXTURE_MODULO, 0x00000000); /* stride width */ PVR_SET(PVR_FOG_DENSITY, 0x0000ff07); /* fog density */ PVR_SET(PVR_UNK_00C8, PVR_GET(0x00d4) << 16); /* M */ PVR_SET(PVR_UNK_0118, 0x00008040); /* M */ /* Initialize PVR DMA */ pvr_state.dma_lock = mutex_create(); pvr_dma_init(); /* Setup our wait-ready semaphore */ pvr_state.ready_sem = sem_create(0); /* Set us as valid and return success */ pvr_state.valid = 1; /* Validate our memory pool */ pvr_mem_reset(); /* This doesn't work right now... */ /*#ifndef NDEBUG dbglog(DBG_KDEBUG, "pvr: free memory is %08lx bytes\n", pvr_mem_available()); #endif*//* !NDEBUG */ return 0; }
void yuv_conv_shutdown() { asic_evt_disable(ASIC_EVT_PVR_YUV_DONE, ASIC_IRQ_DEFAULT); asic_evt_set_handler(ASIC_EVT_PVR_YUV_DONE, NULL); sem_destroy(&yuv_done); }
int yuv_conv_init() { asic_evt_set_handler(ASIC_EVT_PVR_YUV_DONE, asic_yuv_evt_handler); asic_evt_enable(ASIC_EVT_PVR_YUV_DONE, ASIC_IRQ_DEFAULT); sem_init(&yuv_done, 0); return 0; }