📄 vid_atom.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_atom.c| Purpose: video decoder atom layer.| Changes:| Date: Comment:| ----- --------| 15-Oct-01 create| 25-Jul-03 Added code to allow for more flexible memory map+----------------------------------------------------------------------------*/#include <linux/kernel.h> /* We're doing kernel work */#include <linux/module.h> /* Specifically, a module */#include <linux/version.h>#include <os/os-io.h>#include <os/drv_debug.h>#include <os/os-sync.h>#include <hw/hardware.h>#include "vid_atom_local.h"#include "vid_atom_hw.h"#include "vid_uc.h"#include "vid_osi.h"#include <hw/physical-mem.h>#include <os/pm-alloc.h>#ifdef __DRV_FOR_VULCAN__/*#define OS_CORE_DRIVER_NAME "STBx25xx OS-Core"#ifdef MODULEMODULE_DESCRIPTION("OS Core support driver for IBM STBx25xx Drivers");#endif*/#define DCR_VID_MEMSEG0 0x175#define DCR_VID_MEMSEG1 0x176#define DCR_VID_MEMSEG2 0x177#define DCR_VID_MEMSEG3 0x178#elif defined(__DRV_FOR_PALLAS__)/*#define OS_CORE_DRIVER_NAME "STB04xxx OS-Core"#ifdef MODULEMODULE_DESCRIPTION("OS Core support driver for IBM STB04xxx Drivers");#endif*/#define DCR_VID_MEMSEG0 0x175#define DCR_VID_MEMSEG1 0x176#define DCR_VID_MEMSEG2 0x177#define DCR_VID_MEMSEG3 0x178#elif defined(__DRV_FOR_VESTA__)/*#define OS_CORE_DRIVER_NAME "STB03xxx OS-Core"#ifdef MODULEMODULE_DESCRIPTION("OS Core support driver for IBM STB04xxx Drivers");#endif*/#define DCR_VID_MEMSEG0 0x175#define DCR_VID_MEMSEG1 0x176#define DCR_VID_MEMSEG2 0x177#define DCR_VID_MEMSEG3 0x178#else // why#error "Unsupported architecture, please specify it in 'include/hw/hardware.h'"#endif#define DEF_VID_IRQ_MASK DECOD_HOST_MASK_BLOCK_READ | DECOD_HOST_MASK_CHAN_CHAN | DECOD_HOST_MASK_SERROR | \ DECOD_HOST_MASK_PS_STATUS | DECOD_HOST_MASK_IPDC extern vidsfm_t vid_sfm;extern UINT _fmt;static int vid_mask_save=0;int _initial_cc;volatile int __FF_PENDING = 0;volatile int __FF_COMPLETE = 0;volatile int __PS_SF_COMPLETE;ULONG guFBVideoOffset; //this is set to the start of the frame buffer memory within the logical video memory.ULONG guUserVideoOffset; //this is set to the start of the user data memory within the logical video memory.ULONG guVBI0VideoOffset; //this is set to the start of the vbi0 data memory within the logical video memory.ULONG guVBI1VideoOffset; //this is set to the start of the vbi1 data memory within the logical video memory.ULONG guRBVideoOffset; //this is set to the start of the rate buffer data memory within the logical video memory.ULONG guClipVideoOffset; //this is set to the start of the clip buffer data memory within the logical video memory.ULONG guGraphicsVideoOffset;EXPORT_SYMBOL_NOVERS(vid_atom_set_irq_mask);EXPORT_SYMBOL_NOVERS(vid_atom_get_irq_mask);EXPORT_SYMBOL_NOVERS(guGraphicsVideoOffset);static void __vid_init_segment_reg(int i, UINT32 size, UINT32 addr){ UINT32 uVal=0; PDEBUG("__vid_init_segment_reg: segment = 0x%8.8x size =0x%8.8x address = 0x%8.8x \n",i,size,addr); switch(i&3) { case 0: uVal = MF_DCR(DCR_VID_MEMSEG0); break; case 1: uVal = MF_DCR(DCR_VID_MEMSEG1); break; case 2: uVal = MF_DCR(DCR_VID_MEMSEG2); break; case 3: uVal = MF_DCR(DCR_VID_MEMSEG3); break; } if(i&4) // 0:15 { uVal = (uVal & 0x0000ffff) | (size << 28) | ((addr&0xfff00000) >> 4); } else // 16:31 { uVal = (uVal & 0xffff0000) | (size << 12) | ((addr&0xfff00000) >> 20); } switch(i&3) { case 0: PDEBUG("\nDCR_VID_MEMSEG0 is being set to 0x%8.8x\n",uVal); MT_DCR(DCR_VID_MEMSEG0, uVal); break; case 1: PDEBUG("\nDCR_VID_MEMSEG1 is being set to 0x%8.8x\n",uVal); MT_DCR(DCR_VID_MEMSEG1, uVal); break; case 2: PDEBUG("\nDCR_VID_MEMSEG2 is being set to 0x%8.8x\n",uVal); MT_DCR(DCR_VID_MEMSEG2, uVal); break; case 3: PDEBUG("\nDCR_VID_MEMSEG3 is being set to 0x%8.8x\n",uVal); MT_DCR(DCR_VID_MEMSEG3, uVal); break; }}//initialize screen displayINT vid_atom_init(UINT uDispDelay){ unsigned long addr; unsigned long segreg; unsigned long segsize; unsigned long segnum; unsigned long segaddr; int i; unsigned long ulTempAddr; int iTempSize,iIncrementSize; int videoMemSize=0; /*-------------------------------------------------------------------------+ | Reset video chip +--------------------------------------------------------------------------*/ //reset /*reg = MF_DCR(CICVCR); reg |= 0x00000001; MT_DCR(CICVCR, reg); os_delay(1); reg &= 0xfffffffe; MT_DCR(CICVCR, reg); MT_DCR(VID_CHIP_MODE, 0);*/ /*-------------------------------------------------------------------------+ | Stop the decoder. +-------------------------------------------------------------------------*/ MT_DCR(VID_CHIP_CTRL, 0); /*-------------------------------------------------------------------------+ | Set up the decoder logical memory space as follows: | | Memory segment 0 is reserved for the video frame buffers. Physical memory | for this segment is defined by __STB_V_FB_MEM_BASE_ADDR which must located | on a 1 MB boundry .Segment 0 size is defined by __STB_V_FB_MEM_SIZE however | it is fixed at 2 MB. | | Memory segment 1 contains the video user data buffer, vbi buffer and rate | buffer. Physical memory for this segment is defined by __STB_V_MEM_BASE_ADDR | which must be located on a 128 byte boundry. Segment 1 size is defined by | __STB_V_MEM_SIZE. | | Memory segment 2 is reserved for the Graphics plane OSD buffers. Physical | memory for this segment is defined by __STB_GRAPHICS_MEM_BASE_ADDR which | must be located on 128 byte boundry. Segment 2 size is determined by | __STB_GRAPHICS_MEM_SIZE. | | +-------------------------------------------------------------------------*/ PDEBUG("__STB_V_FB_MEM_BASE_ADDR = 0x%8.8x\n",__STB_V_FB_MEM_BASE_ADDR); if(VID_FRAME_MEM_SIZE!=0x00200000) { printk("__STB_V_FB_MEM_SIZE is not correct\n"); return -1; } segnum = 0; segaddr = 0; guFBVideoOffset = segaddr; segsize = 1; /* 2 MB */ addr = VID_FRAME_MEM_BASE; /* frame buffer physical address */ videoMemSize+=1<<segsize; if((addr%0x00100000)!= 0) { printk("ERROR: __STB_V_FB_MEM_BASE_ADDR must start on 1 MB boundary\n"); return -1; } segreg=(segsize<<12)|((addr&0xFFF00000)>>20); PDEBUG("\nDCR_VID_MEMSEG0 is being set to 0x%8.8x for frame buffer. segment size = %dx\n",segreg, segsize); __vid_init_segment_reg(segnum, segsize,addr); segnum++; segaddr += 0x00100000<<segsize; PDEBUG("__STB_V_MEM_BASE_ADDR = 0x%8.8x\n",__STB_V_MEM_BASE_ADDR); addr = VID_MEM_BASE; if((addr%DECOD_MEM_ALIGN)!= 0) { printk("ERROR: __STB_V_MEM_BASE_ADDR must start on 128 byte boundary\n"); return -1; } guUserVideoOffset = segaddr + (addr&0x000FFFFF); PDEBUG("guUserVideoOffset = 0x%08x\n", guUserVideoOffset); guVBI0VideoOffset = guUserVideoOffset+VID_USER_MEM_SIZE; PDEBUG("guVBI0VideoOffset = 0x%08x\n", guVBI0VideoOffset); guVBI1VideoOffset = guVBI0VideoOffset+VID_VBI0_MEM_SIZE; PDEBUG("guVBI1VideoOffset = 0x%08x\n", guVBI1VideoOffset); guRBVideoOffset = guVBI1VideoOffset+VID_VBI1_MEM_SIZE; PDEBUG("guRBVideoOffset = 0x%08x\n", guRBVideoOffset);/* clip buffer start and end must be on 4k boundries */ guClipVideoOffset = ((guRBVideoOffset + 0x1000-1)/0x1000)*0x1000; PDEBUG("guClipVideoOffset = 0x%08x\n", guClipVideoOffset); i = ((addr&0x000FFFFF)+ VID_MEM_SIZE-1)>>20; PDEBUG("VID_MEM_SIZE = 0x%8.8x\n",VID_MEM_SIZE); PDEBUG("i = 0x%8.8x\n",i); for(segsize = 0; i != 0; segsize++) { i = i>>1; } if(segsize>4) { printk("ERROR: VID_MEM_SIZE must be less than 16MB\n"); return -1; } videoMemSize+=1<<segsize; segreg=(segsize<<12)|((addr&0xFFF00000)>>20); PDEBUG("\nDCR_VID_MEMSEG1 is being set to 0x%8.8x for video buffers. segment size = %d\n",segreg, segsize); __vid_init_segment_reg(segnum, segsize,addr); PDEBUG("__STB_GRAPHICS_MEM_BASE_ADDR = 0x%8.8x __STB_GRAPHICS_MEM_SIZE = 0x%8.8x\n", __STB_GRAPHICS_MEM_BASE_ADDR,__STB_GRAPHICS_MEM_SIZE); if(__STB_GRAPHICS_MEM_SIZE!=0) { if(__STB_GRAPHICS_MEM_SIZE > 0x03700000) { printk("ERROR: __STB_GRAPHICS_MEM_SIZE must be 55 Megabytes or less\n"); return -1; } ulTempAddr = __STB_GRAPHICS_MEM_BASE_ADDR; iTempSize = __STB_GRAPHICS_MEM_SIZE; if((ulTempAddr%DECOD_MEM_ALIGN)!= 0) { printk("ERROR: __STB_GRAPHICS_MEM_BASE_ADDR must start on 128 byte boundary\n"); return -1; } PDEBUG("segaddr = 0x%8.8x segsize= 0x%8.8x 0x00100000<<segsize = 0x%8.8x \n",segaddr,segsize,(0x00100000<<segsize)); guGraphicsVideoOffset = (segaddr + (0x00100000<<segsize))+(ulTempAddr&0x000fffff); PDEBUG("guGraphicsVideoOffset = 0x%8.8x\n",guGraphicsVideoOffset); while((iTempSize > 0) && (segnum < 7)) { segnum++; segaddr += 0x00100000<<segsize; addr = ulTempAddr; PDEBUG("segnum = %d, segaddr = 0x%8.8x, addr = 0x%8.8x\n",segnum,segaddr,addr); if(iTempSize > 0x01000000) iIncrementSize = 0x01000000; else iIncrementSize = iTempSize; PDEBUG("iTempSize = 0x%8.8x\n",iTempSize); PDEBUG("iIncrementSize = 0x%8.8x\n",iIncrementSize); i = ((addr & 0x000FFFFF)+iIncrementSize-1)>>20; PDEBUG("i = 0x%8.8x\n",i); for(segsize = 0; i != 0; segsize++) { i = i>>1; } if(segsize>4) { //max segment size is 4 (16MB) segsize=4; } videoMemSize+=1<<segsize; PDEBUG("segsize = %d, increment size = 0x%8.8x\n",segsize,iIncrementSize); segreg=(segsize<<12)|((addr&0xFFF00000)>>20); PDEBUG("\nsegnum %d is being set to 0x%8.8x for graphics plane. segment size = %d\n",segnum, segreg, segsize); __vid_init_segment_reg(segnum, segsize,addr); iTempSize-=iIncrementSize; ulTempAddr+=iIncrementSize; } if(iTempSize > 0) printk("vid_atom_init: unable to allocate all the memory in the video segments\n"); } else { // graphics memory come from the allocated physcial memory PDEBUG("__STB_ALLOC_MEM_BASE_ADDR = 0x%8.8x\n", ulTempAddr); if(__STB_ALLOC_MEM_SIZE > 0x03700000) { printk("ERROR: __STB_ALLOC_MEM_SIZE must be 55 Megabytes or less\n"); return -1; } ulTempAddr = __STB_ALLOC_MEM_BASE_ADDR; iTempSize = __STB_ALLOC_MEM_SIZE; if((ulTempAddr%DECOD_MEM_ALIGN)!= 0) { printk("ERROR: __STB_ALLOC_MEM_BASE_ADDR must start on 128 byte boundary\n"); return -1; } PDEBUG("segaddr = 0x%8.8x segsize= 0x%8.8x\n",segaddr,segsize); guGraphicsVideoOffset = (segaddr + (0x00100000<<segsize))+(ulTempAddr&0x000fffff); PDEBUG("guGraphicsVideoOffset = 0x%8.8x\n",guGraphicsVideoOffset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -