📄 dm642.c
字号:
#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/uaccess.h>#include <asm/arch/irqs.h>#include <asm/io.h>#include <asm/semaphore.h> #include <linux/major.h>#include <linux/vmalloc.h>#include <linux/fs.h>#include <linux/delay.h>#include "DM642a.h"#include "COFF_defs.h"#include "COFF_lib.h"#include "c642params.h"#define DM642_MAJOR 169 static struct semaphore dm642_sem;devfs_handle_t devfs_dm642;static int iomap;static int tiomap;static int logomap;static int maciomap;static unsigned long getbuf_flag[4];static unsigned long getbuf[4*1024];static unsigned char logobuf[0x20000];static struct ioctl_get_osdparams osdparam[4];static unsigned long frameon[4], frameoff[4];static unsigned long g_I_QUANT[4];static unsigned long g_P_QUANT[4];static unsigned long g_SIZEX[4];static unsigned long led,setled;static unsigned long gStandard =DefaultStandard;void readflash(int * addr){ *addr = 0x50; *addr = 0xff;}void writeflash16(unsigned long lStart, unsigned long *pnData, unsigned long lCount){ int i; volatile unsigned short * addr; unsigned short stat; for(i=0; i<lCount; i+=2) { addr = (unsigned short *)(lStart + i); *addr = 0x40; *addr = *(unsigned short*)((unsigned char*)pnData + i); do { *addr = 0x70; stat = *addr; }while(!(stat & 0x80)); } *addr = 0x50; *((volatile unsigned short*)lStart) = 0xff;}void EraseFlash(unsigned long lStart, unsigned long lCount){ int i; volatile unsigned short * addr; unsigned short stat; int section = lCount >> 17; if((lCount & 0x1ffff) != 0) section += 1; for(i=0; i<section; i++) { addr = (unsigned short *)(lStart + i * 0x20000); *addr = 0x20; *addr = 0xd0; do { *addr = 0x70; stat = *addr; }while(!(stat & 0x80)); } *addr = 0x50; *((volatile unsigned short*)lStart) = 0xff;}int COFF_ParseHeader(tCOFFMainHeader *pHeader){ UINT16 scratch = pHeader->flags; if ((scratch & COFF_FLAG_RELO_STRIPPED) == 0) return 0; if ((scratch & COFF_FLAG_RELOCATABLE) == 0) return 0; if ((scratch & COFF_FLAG_LITTLE_ENDIAN) == 0) return 0; if (pHeader->targetID != 0x0099) return 0; return (int)pHeader->sectionCount;}int COFF_OptionalHeaderExists(tCOFFMainHeader *pHeader){ if (pHeader->optionalHeaderSize == 0x001c) return 0; else return 1;}tSectionXferRecord COFF_ParseSectionHeader(tCOFFSectionHeader *pHeader){ UINT32 scratch; tSectionXferRecord rec = {0,0,0}; scratch = pHeader->rawDataOffset; if (scratch == 0) return rec; scratch = pHeader->relocationEntriesCount; if (scratch != 0) return rec; rec.count = pHeader->size; rec.dest = pHeader->physicalAddress; rec.src = pHeader->rawDataOffset; return rec;}static int bootdm642(unsigned long point){ int numSections; int i, j; int nCount; tCOFFMainHeader tCode; tCOFFSectionHeader tHeader; unsigned char *pWork, *pHeader; unsigned long data; tSectionXferRecord rec; write_gpio_bit(GPIO_G1,1); *(volatile unsigned long *)(iomap+0) = 0; *(volatile unsigned long *)(iomap+4) = DM642_GCTL; *(volatile unsigned long *)(iomap+8) = 0x00092078; *(volatile unsigned long *)(iomap+8) = 0xF3A88E02; *(volatile unsigned long *)(iomap+8) = 0xFFFFFFDE; *(volatile unsigned long *)(iomap+4) = DM642_CE2; *(volatile unsigned long *)(iomap+8) = 0x22a28a22; *(volatile unsigned long *)(iomap+8) = 0x22a28a42; *(volatile unsigned long *)(iomap+8) = 0x57229000; *(volatile unsigned long *)(iomap+8) = 0x00000926; *(volatile unsigned long *)(iomap+8) = 0x000a8529; *(volatile unsigned long *)(iomap+4) = DM642_CE1ECCTL; *(volatile unsigned long *)(iomap+8) = 0x00000002; *(volatile unsigned long *)(iomap+8) = 0x00000002; *(volatile unsigned long *)(iomap+4) = DM642_CE2ECCTL; *(volatile unsigned long *)(iomap+8) = 0x00000002; *(volatile unsigned long *)(iomap+8) = 0x00000073; pHeader=point; copy_from_user(&tCode, point, sizeof(tCOFFMainHeader)); numSections = COFF_ParseHeader(&tCode); if (numSections == 0) goto FAILED; pHeader+=COFF_MAIN_HEADER_SIZE; if (COFF_OptionalHeaderExists(&tCode) == 0) pHeader+=COFF_OPTIONAL_HEADER_SIZE; pHeader+=COFF_SECTION_HEADER_SIZE; for (i=1; i<numSections; i++, pHeader+=COFF_SECTION_HEADER_SIZE) { copy_from_user(&tHeader, pHeader, sizeof(tCOFFSectionHeader)); rec = COFF_ParseSectionHeader(&tHeader); if (rec.count == 0) continue; pWork=point+rec.src; *(volatile unsigned long *)(iomap+4) = rec.dest&0xfffffffc; if(rec.dest&0x03) { data=*(volatile unsigned long *)(iomap+0x1c); copy_from_user((unsigned char*)&data+(rec.dest&0x03), pWork, 4-(rec.dest&0x03)); *(volatile unsigned long *)(iomap+8)=data; pWork+=4-(rec.dest&0x03); rec.count-=4-(rec.dest&0x03); } nCount=rec.count>>2; for(j=0; j<nCount; j++, pWork+=4) { copy_from_user((unsigned char*)&data, pWork, 4); *(volatile unsigned long *)(iomap+8)=data; } if(rec.count&0x03) { data=*(volatile unsigned long *)(iomap+0x1c); copy_from_user((unsigned char*)&data, pWork, rec.count&0x03); *(volatile unsigned long *)(iomap+8)=data; } } *(volatile unsigned long *)(iomap+4) = STANDARD0 + 0 * 128; *(volatile unsigned long *)(iomap+0x0c) = gStandard; *(volatile unsigned long *)(iomap+4) = STANDARD0 + 1 * 128; *(volatile unsigned long *)(iomap+0x0c) = gStandard; *(volatile unsigned long *)(iomap+4) = STANDARD0 + 2 * 128; *(volatile unsigned long *)(iomap+0x0c) = gStandard; *(volatile unsigned long *)(iomap+4) = STANDARD0 + 3 * 128; *(volatile unsigned long *)(iomap+0x0c) = gStandard; *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC2; *(volatile unsigned long *)(iomap+0x0c) = 0x55555555; *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC1; *(volatile unsigned long *)(iomap+0x0c) = 0xaaaaaaaa; *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC; *(volatile unsigned long *)(iomap+0x0c) = 0; *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC2; if(*(volatile unsigned long *)(iomap+0x1c) != 0x55555555) { DEBUG_ERR_PRINT("SDRAM write faile!0x55555555\n"); return -1; } *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC1; if(*(volatile unsigned long *)(iomap+0x1c) != 0xaaaaaaaa) { DEBUG_ERR_PRINT("SDRAM write faile!0xaaaaaaaa\n"); return -1; }#ifdef Design_For_GDW *(volatile unsigned long *)(iomap+4) = SERIAL_RECEIVEDFLAG; *(volatile unsigned long *)(iomap+0x0c) = 1; *(volatile unsigned long *)(iomap+4) = PASS_RECEIVEDFLAG; *(volatile unsigned long *)(iomap+0x0c) = 1; *(volatile unsigned long *)(iomap+4) = WATCHDOG_STATUS; *(volatile unsigned long *)(iomap+0x0c) = 1;#endif *(volatile unsigned long *)(iomap+0) = 0x00020002; *(volatile unsigned long *)(iomap+4) = 0x81fdc000; for(i=0; i<4*32*1024; i+=4) {#ifndef Design_For_GDW *(volatile unsigned long *)(iomap+8)=*(volatile unsigned long *)(logomap + i);#else udelay(5);#endif } udelay(200); *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC; for(i=0; i<10000; i++) { if(*(volatile unsigned long *)(iomap+0x1c) == 1) { break; } udelay(200); } if(i == 10000) {DEBUG_ERR_PRINT("dm642_boot DSP_PC_SYNC false!%x\n",*(volatile unsigned long *)(iomap+0x1c));} if(i == 10000) goto FAILED; udelay(200); *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC1; for(i=0; i<10000; i++) { if(*(volatile unsigned long *)(iomap+0x1c) == 0x86) { break; } udelay(200); } if(i == 10000) {DEBUG_ERR_PRINT("dm642_boot DSP_PC_SYNC1 false!\n");} if(i == 10000) goto FAILED; udelay(200); *(volatile unsigned long *)(iomap+4) = DSP_PC_SYNC2; for(i=0; i<1000; i++) { if(*(volatile unsigned long *)(iomap+0x1c) == 0x86) { break; } udelay(200); } if(i == 1000) {DEBUG_ERR_PRINT("dm642_boot DSP_PC_SYNC2 false!\n");} if(i == 1000) goto FAILED; write_gpio_bit(GPIO_G1,0); return 0;FAILED: return -1;}static void startdm642(unsigned long point){ if(point & 1) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START0; *(volatile unsigned long *)(iomap+0x0c) = 1; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC0; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point & 2) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START1; *(volatile unsigned long *)(iomap+0x0c) = 1; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC1; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point & 4) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START2; *(volatile unsigned long *)(iomap+0x0c) = 1; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC2; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point & 8) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START3; *(volatile unsigned long *)(iomap+0x0c) = 1; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC3; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point&0x0f) { *(volatile unsigned long *)(iomap+0) = 0x00020002; }}static void stopdm642(unsigned long point){ if(point & 1) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START0; *(volatile unsigned long *)(iomap+0x0c) = 0; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC0; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point & 2) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START1; *(volatile unsigned long *)(iomap+0x0c) = 0; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC1; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point & 4) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START2; *(volatile unsigned long *)(iomap+0x0c) = 0; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC2; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point & 8) { *(volatile unsigned long *)(iomap+4) = COMPRESS_START3; *(volatile unsigned long *)(iomap+0x0c) = 0; *(volatile unsigned long *)(iomap+4) = SET_COMPRESS_FUNC3; *(volatile unsigned long *)(iomap+0x0c) = 1; } if(point&0x0f) { *(volatile unsigned long *)(iomap+0) = 0x00020002; }}static void resetdm642(unsigned long point){ *(volatile unsigned long *)(iomap+4) = 0x020; write_gpio_bit(GPIO_B5,1); mdelay(180); write_gpio_bit(GPIO_B5,0);}static int getdm642(unsigned long point){ unsigned long bufaddr, buflen, alllen, fragments; unsigned long nCount; unsigned long * pWork; unsigned long data; int j; struct ioctl_get_data tpoint; copy_from_user(&tpoint, point, sizeof(struct ioctl_get_data)); if(tpoint.channel > 3) { DEBUG_ERR_PRINT("get channel > 3\n"); return 0; } if(tpoint.flag < 2) { *(volatile unsigned long *)(iomap+4) = COMPRESS_FRAME_ON0 + tpoint.channel * 128; *(volatile unsigned long *)(iomap+8) = 0; *(volatile unsigned long *)(iomap+8) = 1; DEBUG_ERR_PRINT("get flag < 2\n"); return 0; } else if(tpoint.flag < 5) { *(volatile unsigned long *)(iomap+4) = COMPRESS_FRAME_ON0 + tpoint.channel * 128; *(volatile unsigned long *)(iomap+8) = 0; *(volatile unsigned long *)(iomap+8) = 1; } else if(tpoint.flag < 15) { *(volatile unsigned long *)(iomap+4) = COMPRESS_FRAME_ON0 + tpoint.channel * 128; *(volatile unsigned long *)(iomap+8) = 1; *(volatile unsigned long *)(iomap+8) = 1; } else { *(volatile unsigned long *)(iomap+4) = COMPRESS_FRAME_ON0 + tpoint.channel * 128; *(volatile unsigned long *)(iomap+8) = frameon[tpoint.channel]; *(volatile unsigned long *)(iomap+8) = frameoff[tpoint.channel]; } pWork = tpoint.buf; if(getbuf_flag[tpoint.channel] != 0) { buflen = getbuf[tpoint.channel * 1024 + 1]; copy_to_user(pWork, &getbuf[tpoint.channel * 1024], buflen); getbuf_flag[tpoint.channel] = 0; return buflen; } *(volatile unsigned long *)(iomap+4) = COMPRESS_BUFFER_RECEIVEDFLAG0 + tpoint.channel * 128; if(*(volatile unsigned long *)(iomap+0x1c) != 0) return 0; *(volatile unsigned long *)(iomap+4) = COMPRESS_BUFFER_ADDRESS0 + tpoint.channel * 128; bufaddr = *(volatile unsigned long *)(iomap+0x18); alllen = *(volatile unsigned long *)(iomap+0x18); *(volatile unsigned long *)(iomap+4) = bufaddr; nCount = *(volatile unsigned long *)(iomap+0x18); buflen = *(volatile unsigned long *)(iomap+0x18); fragments = *(volatile unsigned long *)(iomap+0x18); if(alllen != 4096 * fragments) { getbuf_flag[tpoint.channel] = bufaddr + 4096 * fragments; } if(tpoint.size < buflen) { DEBUG_ERR_PRINT("get tpoint.size < buflen %x < %x\n",tpoint.size,buflen); return -1; } *(volatile unsigned long *)(iomap+4) = bufaddr; nCount=buflen>>2; for(j=0; j<nCount; j++, pWork++) { put_user(*(volatile unsigned long *)(iomap+0x18), pWork); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -