⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vid_atom_others.c

📁 IBM source for pallas/vulcan/vesta
💻 C
字号:
/*----------------------------------------------------------------------------+|       This source code has been made available to you by IBM on an AS-IS|       basis.  Anyone receiving this source is licensed under IBM|       copyrights to use it in any way he or she deems fit, including|       copying it, modifying it, compiling it, and redistributing it either|       with or without modifications.  No license under IBM patents or|       patent applications is to be implied by the copyright license.||       Any user of this software should understand that IBM cannot provide|       technical support for this software and will not be responsible for|       any consequences resulting from the use of this software.||       Any person who transfers this source code or any derivative work|       must include the IBM copyright notice, this paragraph, and the|       preceding two paragraphs in the transferred software.||       COPYRIGHT   I B M   CORPORATION 1997, 1999, 2001|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Author: Ling shao| File:   vid_others.c| Purpose: video decoder atom layer others PALLAS| Changes:| Date:         Comment:| -----         --------| 15-Oct-01		create                  									SL| 25-Jul-03     added code to support flexible frame buffer base addresses+----------------------------------------------------------------------------*/#include <os/os-generic.h>#include <os/os-io.h>#include <os/drv_debug.h>#include <os/os-sync.h>#include <hw/hardware.h>#include "vid_atom_hw.h"#include "vid_atom_local.h"#include "vid_osi.h"unsigned long buf0_lum, buf0_chr, buf1_lum, buf1_chr, buf2_lum, buf2_chr;unsigned long buf0_lum_size, buf0_chr_size, buf1_lum_size, buf1_chr_size,              buf2_lum_size, buf2_chr_size;extern VDEC _videoDecoder;inline ULONG vid_atom_make_memseg(MEM_SEG *pHigh, MEM_SEG *pLow){    unsigned long reg;    reg = ((pHigh->uSegSize & 0x00000007) << 28) |          ((pHigh->uAddr & 0xFFF00000) >> 4)     |          ((pLow->uSegSize & 0x00000007) << 12)  |          ((pLow->uAddr & 0xFFF00000) >> 20);    return reg;}/*-----------------------------------------------------------| Microcode load and verify+------------------------------------------------------------*/INT vid_atom_load_microcode(USHORT *pCode, INT nCount){    unsigned long reg;    int rc;    int i;    PDEBUG("Loading video code\n");    /*-------------------------------------------------------------------------+    | Stop video processor.  Enable instruction store writes.    +-------------------------------------------------------------------------*/    reg =        MF_DCR(VID_CHIP_CTRL) &        (~(DECOD_CHIP_CONTROL_SVP | DECOD_CHIP_CONTROL_SVD));    MT_DCR(VID_CHIP_CTRL, reg);    MT_DCR(VID_WRT_PROT, DECOD_WR_PROT_DISABLE);    /*-------------------------------------------------------------------------+    | Initialize control store address.    +-------------------------------------------------------------------------*/    MT_DCR(VID_PROC_IADDR, 0x8000);    /*-------------------------------------------------------------------------+    | Load microcode.    +-------------------------------------------------------------------------*/    for (i = 0; i < nCount; i++)    {        MT_DCR(VID_PROC_IDATA, pCode[i]);    }    /*-------------------------------------------------------------------------+    | Verify microcode load.    +-------------------------------------------------------------------------*/    rc = vid_atom_verify_microcode(pCode, nCount);    return (rc);}/*-------------------------------------------------------------------------+| Verify microcode load.+-------------------------------------------------------------------------*/INT vid_atom_verify_microcode(USHORT *pCode, INT nCount){    int i;    PDEBUG("Verifying video code\n");    MT_DCR(VID_WRT_PROT, DECOD_WR_PROT_DISABLE);    for (i = 0; i < nCount; i++)    {        MT_DCR(VID_PROC_IADDR, i);        if (MF_DCR(VID_PROC_IDATA) != pCode[i])            return -1;    }    MT_DCR(VID_PROC_IADDR, 0);    MT_DCR(VID_WRT_PROT, DECOD_WR_PROT_ENABLE);    return (0);}/*WARNING: This function may result in re-shedule*/INT vid_atom_wait_cmd_done(UINT uRetry){    unsigned long cmd_reg;    while (1)    {        cmd_reg = MF_DCR(VID_CMD_STAT);        if ((cmd_reg & DECOD_COMD_STAT_PENDING) == 0)        {            return (0);        }        else        {                        if (--uRetry == 0)            {                return (-1);            }            os_sleep(1);            //PDEBUG("retry = %d\n", uRetry);        }    }}void vid_atom_set_cmd(VIDEOCMD *pCmd){    int i;    for (i = 0; i < pCmd->uNum; i++)    {        MT_DCR(VID_CMD_ADDR, i);        MT_DCR(VID_CMD_DATA, pCmd->uPara[i]);    }}INT vid_atom_exec_cmd(VIDEOCMD *pCmd){    PDEBUG("exec cmd = %d\n", pCmd->uCmd);    //PDEBUG("wait last cmd...\n");    if (vid_atom_wait_cmd_done(pCmd->uRetry) != 0)    {        PDEBUG("OVERTIME\n");        return (-1);    }    //PDEBUG("DONE\n");    //check if this command has parameters    if (pCmd->uNum != 0)        vid_atom_set_cmd(pCmd);    if (pCmd->uChained != 0)    {        MT_DCR(VID_CMD, pCmd->uCmd | DECOD_COMD_CHAIN);    }    else    {        MT_DCR(VID_CMD, pCmd->uCmd);    }    //activate command    MT_DCR(VID_CMD_STAT, DECOD_COMD_STAT_PENDING);    //PDEBUG("wait THIS cmd...\n");    if (vid_atom_wait_cmd_done(pCmd->uRetry) != 0)    {        /*----------------------------------------------------------------------+        | Time-out.  Force microcode to accept our command.  This is done        | by writing 0x8200 to the instruction address register.  The        | only command that can be accepted this way is reset video buffer        | command.  Command chaining is set so that we can issue the original        | command.        +----------------------------------------------------------------------*/        if ((pCmd->uCmd != DECOD_COM_RES_VID_BUF)            || (pCmd->uChained != 0))        {            MT_DCR(VID_CMD, DECOD_COM_RES_VID_BUF | DECOD_COMD_CHAIN);        }        //PDEBUG("OVERTIME\n");        //printk("soft reset\n");        MT_DCR(VID_PROC_IADDR, 0x00008200);        if (vid_atom_wait_cmd_done(pCmd->uRetry) != 0)        {            PDEBUG("OVERTIME\n");            return (-1);        }        //PDEBUG("DONE\n");        PDEBUG("Retry THIS cmd...\n");        if (pCmd->uCmd != DECOD_COM_RES_VID_BUF)        {            if (pCmd->uChained != 0)            {                MT_DCR(VID_CMD, pCmd->uCmd | DECOD_COMD_CHAIN);            }            else            {                MT_DCR(VID_CMD, pCmd->uCmd);            }            MT_DCR(VID_CMD_STAT, DECOD_COMD_STAT_PENDING);            if (vid_atom_wait_cmd_done(pCmd->uRetry) != 0)            {                PDEBUG("OVERTIME\n");                return (-1);            }        }    }    PDEBUG("DONE\n");    return (0);}void vid_atom_reset_vdec(){	PDEBUG("soft reset video decoder\n");	MT_DCR(VID_CMD_STAT, 0);    MT_DCR(VID_PROC_IADDR, 0x00008200);}INT vid_atom_reset_ratebuf(int mode){	    VIDEOCMD vc;		PDEBUG("reset rate buffer\n");		vid_atom_reset_vdec();        vc.uCmd = DECOD_COM_RES_VID_BUF;        vc.uNum = 1;//        vc.uPara[0] = 0;//lingh added for PVR demo		vc.uPara[0] = mode;        vc.uChained = 0;        vc.uRetry = DECOD_TIMEOUT;		/*switch(mode)		{			case VID_RB_NORMAL_PLAY:					vc.uPara[0] = 0x8000;				break;			case VID_RB_SFM:				vc.uPara[0] = 0x8010;				break;			case VID_RB_OTHER:				vc.uPara[0] = 0xa000;				break;			default:				vc.uPara[0] = 0x8000;				break;		}*/        if (vid_atom_exec_cmd(&vc) != 0)        {            printk("execute config command failed\n");            return -1;        }//        _OS_MEMSET((void*)GET_RB_BASE(_ulVidLogAdr), 0x0, VID_RB_MEM_SIZE);		return 0;}INT vid_atom_reset_ratebuf_freeze(){  VIDEOCMD vc;  PDEBUG("reset rate buffer\n");    vid_atom_reset_vdec();  vc.uCmd = DECOD_COM_RES_VID_BUF;  vc.uNum = 1;  vc.uPara[0] = 0;  vc.uChained = 1;  vc.uRetry = DECOD_TIMEOUT;  if (vid_atom_exec_cmd(&vc) != 0)  {    printk("execute RES_VID_BUF command failed\n");    return -1;  }  vc.uCmd = DECOD_COM_FFRAME;  vc.uNum = 0;  vc.uChained = 0;  vc.uRetry = DECOD_TIMEOUT;  if (vid_atom_exec_cmd(&vc) != 0)  {    PDEBUG("exec video freeze frame error\n");    return -1;  }  return 0;}void vid_atom_clear_rb(){    _OS_MEMSET((void*)_videoDecoder.ratebuf.ulLogicalAddr, 0x0, VID_RB_MEM_SIZE);}void vid_atom_clear_framebuf(){   _OS_MEMSET((void*)_videoDecoder.framebuf.ulLogicalAddr + buf0_lum, 0x00, buf0_lum_size);   _OS_MEMSET((void*)_videoDecoder.framebuf.ulLogicalAddr + buf1_lum, 0x00, buf1_lum_size);   _OS_MEMSET((void*)_videoDecoder.framebuf.ulLogicalAddr + buf2_lum, 0x00, buf2_lum_size);   _OS_MEMSET((void*)_videoDecoder.framebuf.ulLogicalAddr + buf0_chr, 0x80, buf0_chr_size);   _OS_MEMSET((void*)_videoDecoder.framebuf.ulLogicalAddr + buf1_chr, 0x80, buf1_chr_size);   _OS_MEMSET((void*)_videoDecoder.framebuf.ulLogicalAddr + buf2_chr, 0x80, buf2_chr_size);}void vid_atom_set_memseg(MEM_SEG *pMem){    unsigned long reg;    reg = vid_atom_make_memseg(&(pMem[4]), &(pMem[0]));    MT_DCR(VID_SEG0, reg);    reg = vid_atom_make_memseg(&(pMem[5]), &(pMem[1]));    MT_DCR(VID_SEG1, reg);    reg = vid_atom_make_memseg(&(pMem[6]), &(pMem[2]));    MT_DCR(VID_SEG2, reg);    reg = vid_atom_make_memseg(&(pMem[7]), &(pMem[3]));    MT_DCR(VID_SEG3, reg);}void vid_atom_set_fb_adr(int mode){   ULONG fb_base;#ifdef __DRV_FOR_PALLAS__    if(mode == 1)       fb_base = 0x1780; // use 0x1780 for PAL    else       fb_base = 0xcb80; // use 0xcb80 for NTSC    if(mode == 1)           //pal    {        buf2_lum = 0X0 + fb_base;        buf2_chr = 0X65400 + fb_base;        buf0_lum = 0X99480 + fb_base;        buf0_chr = 0XFE880 + fb_base;        buf1_lum = 0X131280 +fb_base;        buf1_chr = 0X196680 + fb_base;        //antiflicker_buf = 0X1C9080 + fb_base;        buf2_lum_size   = 0X65400;        buf2_chr_size   = 0X19500;        buf0_lum_size   = 0X65400;        buf0_chr_size   = 0X32A00;        buf1_lum_size   = 0X65400;        buf1_chr_size   = 0X32A00;        //antiflicker_buf_size = DECOD_PAL_ANTIFLICKER_SIZE;   }   else   {                                             /* NTSC mode         */        buf2_lum = 0X0      ;        buf2_chr = 0X54600  ;        buf0_lum = 0X9EE80  ;        buf0_chr = 0XF3480  ;        buf1_lum = 0X11D780 ;        buf1_chr = 0X171D80 ;        //antiflicker_buf = 0X19C080 + fb_base;        buf2_lum_size   = 0X54600;        buf2_chr_size   = 0X2A300;        buf0_lum_size   = 0X54600;        buf0_chr_size   = 0X2A300;        buf1_lum_size   = 0X54600;        buf1_chr_size   = 0X2A300;        //antiflicker_buf_size =  DECOD_NTSC_ANTIFLICKER_SIZE;   }#elif defined(__DRV_FOR_VESTA__) || defined(__DRV_FOR_VULCAN__)   if(mode == 1)       fb_base = 0x16900; // use 0x16900 for 4MB PAL    else       fb_base = 0x21D00; // use 0x21D00 for NTSC          if(mode == 1)   {        buf2_lum = 0x0 + fb_base;        buf2_chr = 0x65400 + fb_base;	buf0_lum = 0x84E00 + fb_base;        buf0_chr = 0xea200 + fb_base;        buf1_lum = 0x11cc00 + fb_base;        buf1_chr = 0x182000 + fb_base;	buf2_lum_size = 0x65400;        buf1_lum_size = 0x65400;        buf0_lum_size = 0x65400;        buf2_chr_size = 0x19E00;        buf1_chr_size = 0x32a00;        buf0_chr_size = 0x32a00;   }   else   {        buf2_lum = 0x0 + fb_base;        buf2_chr = 0x54600 + fb_base;        buf0_lum = 0x89d00 + fb_base;        buf0_chr = 0xde300 + fb_base;        buf1_lum = 0x108600 + fb_base;        buf1_chr = 0x15cc00 + fb_base;        buf2_lum_size = 0x54600;        buf1_lum_size = 0x54600;        buf0_lum_size = 0x54600;        buf2_chr_size = 0x2a300;        buf1_chr_size = 0x2a300;        buf0_chr_size = 0x2a300;   }#else#error "platform not supported"#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -