📄 vp.c
字号:
/* Copyright 1996, ESS Technology, Inc. *//* SCCSID @(#)vp.c 1.87 1/22/98 *//* * $Log$ */#include "common.h"#include "mvd.h"#include "util.h"#include "vp.h"#include "const.h"#include "debug.h"#include "display.h"#include "vpucode.h"#include "low.h"#include "constvar.h"/***************************************************************************** * compile option *****************************************************************************/#define PRINTF(a)#ifndef UCODE_IN_DRAM#define UCODE_CACHE#endif/***************************************************************************** * Some local defines *****************************************************************************/#define VPRESETOFF 1#define VPLOADMODEON 2#define VPDMBASEMD 0x200#define VPZIGZAG 0x104#define VPPACKMD 0x102#ifndef NEW_DIGEST_OSDint rev3210; /* 3210 revision number */#define VP_ASSIGN_VERSION(x) rev3210 = x#else#define VP_ASSIGN_VERSION(x)#endif#ifdef UCODE_IN_DRAMstatic int next_start;#endifvoid load_vp(RAMCODE name, int direct);void register_ucode(RAMCODE name, int *ucode, int size, int offset);static void register_all_ucode(void);/***************************************************************************** Private data *****************************************************************************/RAMCODE RamCode = rnone; /* convey what is paged inside VP now */int ucode_start[rdummy]; /* addr of ucode in DRAM/SRAM */int ucode_size[rdummy]; /* ucode size in dwords */int ucode_offset[rdummy]; /* ucode offset from 0x800 in dwords */#ifdef UCODE_CACHERAMCODE ucode_in_dram0; /* What's in ucode cache 0 */RAMCODE ucode_in_dram1; /* What's in ucode cache 1 */int mru_ucode; /* Which page is most recently used */#endifDEBUGVAR(vp_load_error, 0);DEBUGVAR(loading_ucode, rnone);/***************************************************************************** Register ucode. *****************************************************************************/void register_ucode(RAMCODE name, int *ucode, int size, int offset){#ifdef UCODE_IN_DRAM ucode_start[name] = next_start; sram_to_dram(next_start, ucode, size); PRINTF(("name %d next %d ucode %d size %d\n",name,next_start,ucode,size)); next_start += size; assert(next_start < END_UCODE);#else ucode_start[name] = (int)ucode;#endif ucode_size[name] = size; ucode_offset[name] = offset;}/***************************************************************************** Load ucode to VP. We either load direct from sram/eprom and go through the cmd bus, or we load from dram and use DMA. *****************************************************************************/void load_vp(RAMCODE name, int direct){ int code; int n = ucode_size[name]; int addr = ucode_offset[name];#ifdef UCODE_CACHE if (!direct) { if (ucode_in_dram0 == name) { code = START_UCODE0; mru_ucode = 0; /* page 0 is now the most recently used */#ifdef BF43 } else if (ucode_in_dram1 == name) {#else } else if ((!mineomine) && (ucode_in_dram1 == name)) {#endif code = START_UCODE1; mru_ucode = 1; /* page 1 is now the most recently used */ } else { /* Cache miss. Load to the least recently used page. */ if (name==rksearch) { code = ucode_start[name]; direct = 1; goto hack; }#ifdef BF43 if (mru_ucode) {#else if (mru_ucode || mineomine) {#endif code = START_UCODE0; ucode_in_dram0 = rnone; } else { code = START_UCODE1; ucode_in_dram1 = rnone; } RISC_to_dram(code, (int *)ucode_start[name], ucode_size[name]);#ifdef BF43 if (mru_ucode) {#else if (mru_ucode || mineomine) {#endif ucode_in_dram0 = name; mru_ucode = 0; } else { ucode_in_dram1 = name; mru_ucode = 1; } } } else#endif code = ucode_start[name];hack: PRINTF(("Loading ucode %d at %d to 0x%x, %d dwords.\n", loading_ucode,code,addr,n)); VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty; mvd[buscon_vp_control] = VPLOADMODEON | VPRESETOFF; asm("nop"); asm("nop"); asm("nop"); asm("nop"); mvd[buscon_cmdque_vpcbuswr] = 0x0100; /* loaducode write mode */ mvd[buscon_cmdque_vpcbuswr] = addr;#if defined(UCODE_IN_DRAM) || defined(UCODE_CACHE) if (!direct) { VP_cmdq_deltas(n, 1); VP_cmdq_dmax(VPDMA_MEM2VP | a2x(code)); VP_cmdq_dmay(a2y(code)); }#ifdef UCODE_CACHE else { int i; int *p = (int *)code; for (i=0; i<n; i++) { VP_cmdq_wait_empty; mvd[buscon_cmdque_vpdbuswrhi] = ((*p)>>16) & 0xffff; mvd[buscon_cmdque_vpdbuswrlow] = (*p++) & 0xffff; } VP_endio(0); }#endif#else /* No UCODE_IN_DRAM nor UCODE_CACHE */ if (direct) { int i; int *p = (int *)code; for (i=0; i<n; i++) { VP_cmdq_wait_empty; mvd[buscon_cmdque_vpdbuswrhi] = ((*p)>>16) & 0xffff; mvd[buscon_cmdque_vpdbuswrlow] = (*p++) & 0xffff; } VP_endio(0); }#endif VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty; mvd[buscon_vp_control] = VPRESETOFF; asm("nop"); asm("nop"); asm("nop"); asm("nop"); /* keep these modes because the reset in loadvp will clear all these modes, causing video rla data to be transferred without zigzag translation */ mvd[buscon_cmdque_vpcbuswr] = (VPZIGZAG | VPPACKMD); mvd[buscon_cmdque_vpcbuswr] = VPDMBASEMD; /* no dm bank/word displacement */}/***************************************************************************** Register all ucode. *****************************************************************************/static void register_all_ucode(){#ifdef UCODE_IN_DRAM next_start = START_UCODE;#endif#ifdef AC3 register_ucode(rac3both, ac3both_ucode, ac3both_SIZE, ac3both_OFFSET); register_ucode(rac3shot, ac3shot_ucode, ac3shot_SIZE, ac3shot_OFFSET); register_ucode(rac3long, ac3long_ucode, ac3long_SIZE, ac3long_OFFSET); register_ucode(rfft64, fft64_ucode, fft64_SIZE, fft64_OFFSET);#endif#ifdef MPEG2 register_ucode(rvideo, vid_ucode, VID_UCODE_SIZE, VID_UCODE_OFFSET);#endif#ifdef MPEG1#ifdef SVCD register_ucode(rvideo, vid_ucode, VID_UCODE_SIZE, VID_UCODE_OFFSET);#endif register_ucode(rnonpage, T_nonpage_ucode, nonpage_SIZE, nonpage_OFFSET); register_ucode(rtwo2one, T_two2one_ucode, two2one_SIZE, two2one_OFFSET); register_ucode(rntsc2pal, T_ntsc2pal_ucode, ntsc2pal_SIZE,ntsc2pal_OFFSET); register_ucode(rpal2ntsc, T_pal2ntsc_ucode, pal2ntsc_SIZE,pal2ntsc_OFFSET); register_ucode(rksearch, T_ksearch_ucode, ksearch_SIZE, ksearch_OFFSET); register_ucode(rcdda, T_cdda_ucode, cdda_SIZE, cdda_OFFSET);#ifdef SPATIAL register_ucode(rspatial, T_spatial_ucode, spatial_SIZE, spatial_OFFSET);#endif#ifdef BF43 register_ucode(rhscale, T_hscale_ucode, hscale_SIZE, hscale_OFFSET);#endif#endif /* end of #ifdef MPEG1 */}/***************************************************************************** Initialise the VP. *****************************************************************************/void VP_init(){ VP_reset(); register_all_ucode();#ifdef AC3 VP_load_ucode(rac3both);#endif#ifdef MPEG1 VP_load_ucode(rnonpage);#endif#ifdef UCODE_CACHE ucode_in_dram0 = ucode_in_dram1 = rnone; mru_ucode = 1;#endif VP_ucode(0, clr_pcstack); VP_ucode_wait();}/***************************************************************************** Make a wild guess. *****************************************************************************//* * Detect 3210 version by reading location 0x390 of VP microcode ROM. * * Different 3210 versions have different VP ucode address, so it is * extremely important to make sure the version number matches the chip. * Therefore, we'll do equality checking for all versions (no default), * and we'll loop until the version number matches. * * Side effect: * Sets rev3210 (3210 revision) and VP_ucode_offset. * */void VP_version(){ int i, rddata; volatile unsigned int *ptrdelay = (unsigned int *) x1c060000;#if 0 /* * When life is easier, there is only 1 VP ROM, the following code * is sufficient. */ VP_ASSIGN_VERSION(0); VP_ucode_offset = T_VP_ucode_offset1;#else /* Do automatic version detection */ do { /* read VPROM at location 0x390 */ mvd[buscon_vp_control] = 0; (void) *ptrdelay; mvd[buscon_vp_control] = VPRESETOFF; (void) *ptrdelay; mvd[buscon_cmdque_vpcbuswr] = 0x0000; /* soft init */ (void) *ptrdelay; mvd[buscon_cmdque_vpcbuswr] = 0x0101; /* house keeping- rd ucode */ /* * Needs lots of delay here. If there is not enough delay, * we may NEVER detect the chip version, and the loop will * last forever! */ for (i = 0; i < 1000; i++) (void) *ptrdelay; mvd[buscon_vp_control] = (VPLOADMODEON | VPRESETOFF); (void) *ptrdelay; mvd[buscon_cmdque_vpcbuswr] = 0x0390; /* ucode rom addr */ (void) *ptrdelay; mvd[buscon_cmdque_vprd] = 0x0000; /* reads vp */ (void) *ptrdelay; (void) *ptrdelay; rddata = mvd[buscon_cmdque_rdrlatchh]; (void) *ptrdelay; rddata <<= 16; rddata |= mvd[buscon_cmdque_rdrlatchl] & 0xffffL; /* reading is done */ /* * Determine 3210 versions. Depending on chip version, some VP * ucode offsets are different. * * To avoid making mistake, we'll retry until we see the value * we are expecting. */ if (rddata == 0x40678000) { VP_ASSIGN_VERSION(1); VP_ucode_offset = T_VP_ucode_offset2; break; } else if (rddata == 0x484e8583) { VP_ASSIGN_VERSION(0); VP_ucode_offset = T_VP_ucode_offset1; break; } } while (1);#endif}void VP_reset(){ volatile unsigned int *ptrdelay = (unsigned int *) x1c060000; mvd[buscon_vp_control] = 0; (void) *ptrdelay; mvd[buscon_vp_control] = VPRESETOFF; (void) *ptrdelay; mvd[buscon_cmdque_vpcbuswr] = (VPZIGZAG | VPPACKMD); mvd[buscon_cmdque_vpcbuswr] = VPDMBASEMD; /* no dm bank/word displacement */ mvd[buscon_cmdque_vpcbuswr]= loading; /* loading */ VP_ucode(0, clr_pcstack); VP_cmdq_wait_empty; RamCode = rnone; DEBUGASSIGN(loading_ucode, rnone);}/***************************************************************************** On the fly loading of VP ucode. Exported. *****************************************************************************/#if defined(UCODE_IN_DRAM) || defined(UCODE_CACHE)#define direct_from_eprom 0#else#define direct_from_eprom 1#endifvoid VP_load_ucode(RAMCODE name){ if (name == rnone) return;#ifdef MPEG1 if (name == rnonpage) { load_vp(rnonpage, 1); return; }#endif if (RamCode != name) { RamCode = rnone; DEBUGASSIGN(loading_ucode, name); load_vp(name, direct_from_eprom); RamCode = name; }}/***************************************************************************** On the fly loading of VP ucode. Exported. *****************************************************************************/void VP_xfer_wait(void){ VP_block_twice(NCMDQ_VP_block_twice, UCODE_IDLE); VP_cmdq_wait_empty;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -