?? fpgaload.c
字號:
//#include <linux/config.h>
//#include <linux/version.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/errno.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <linux/semaphore.h>
#include <asm/arch/edma.h>
#include <linux/interrupt.h>
#include <asm/hardware/clock.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/syscalls.h>
#define strtoul simple_strtoul
#define dbgprint(szFmt,args...) {if(dbg) printk(szFmt,##args);}
static int dbg;
MODULE_LICENSE("hikvision");
module_param(dbg,int,00777);
MODULE_PARM_DESC(dbg, "FPGALOAD DRIVER DEBUG");
#define EMIF_A3CR 0x1e00018
#define MAX_FPGA_BIN 0x80000
#define DATA (1<<0)
#define DCLK (1<<1)
#define CONF_DONE (1<<2)
#define nSTATUS (1<<3)
#define nCONFIG (1<<4)
#define CONF_CEn (1<<5)
u_short *g_pctrlbase = NULL;
u_short *CPLD_FPGA_R = NULL;//(0x16/2)
u_short *CPLD_FPGA_W = NULL;//(0x18/2)
inline void set_pin(u_short pin)
{
register u_short val;
val = *(CPLD_FPGA_R);
val |= pin;
*(CPLD_FPGA_W) = val;
}
inline void clr_pin(u_short pin)
{
register u_short val;
val = *(CPLD_FPGA_R);
val &= ~pin;
*(CPLD_FPGA_W) = val;
}
inline u_short get_pin(u_short pin)
{
register u_short val;
val = *(CPLD_FPGA_R);
return (val&pin);
}
int load_fpga(u_char *pbuf)
{
int fd;
u_long usr_fs,size=0;
memset(pbuf,0,MAX_FPGA_BIN);
usr_fs = get_fs();
set_fs(KERNEL_DS);
fd = sys_open("./fpga.rbf",O_RDONLY,0);
if(fd>0)
{
size = sys_lseek(fd,0,2);
sys_lseek(fd,0,0);
sys_read(fd,pbuf,size);
sys_close(fd);
printk("load fpga file[%ld]\n",size);
}
set_fs(usr_fs);
return size;
}
void download_fpga(u_char *pbuf,int size)
{
int retrycnt = 0;
register int i,j;
register u8 data;
clr_pin(CONF_CEn);
restart:
udelay(100);
retrycnt++;
if(retrycnt>0x5)
goto exit;
clr_pin(nCONFIG);
clr_pin(DCLK);
udelay(10);
if(get_pin(nSTATUS)!=0)
{
printk("start config fpga error\n");
goto exit;
}
set_pin(nCONFIG);
//udelay(5);
udelay(100);
#if 0
for(i=0;i<20000;i++)
{
udelay(500);
if((i%1000)==0)
printk("cpld_val=0x%04x\n",get_pin(0xffff));
}
#endif
#if 0
for(i=0;i<size;i++)
{
data = pbuf[i];
for(j=0;j<8;j++)
{
if((data>>j)&0x1)
set_pin(DATA);
else
clr_pin(DATA);
set_pin(DCLK);
if(get_pin(nSTATUS)==0)
{
printk("send fpga data error,i=%d,j=%d\n",i,j);
goto restart;
}
clr_pin(DCLK);
}
}
#else
{
u_short val,cpld = *(CPLD_FPGA_R);
for(i=0;i<size;i++)
{
data = pbuf[i];
for(j=0;j<8;j++)
{
val = cpld|0x2;
if((data>>j)&0x1)
val |= 0x0001;
else
val &= 0xfffe;
*(CPLD_FPGA_W) = val;
if( (*(CPLD_FPGA_R) & nSTATUS)==0 )
{
printk("send fpga data error,i=%d,j=%d\n",i,j);
goto restart;
}
*(CPLD_FPGA_W) = val&0xfffd;
//cpld = *(CPLD_FPGA_R);/* low delay */
}
}
}
#endif
for(i=0;i<1200;i++)
{
set_pin(DCLK);
clr_pin(DCLK);
}
clr_pin(DATA);
if(get_pin(CONF_DONE)==0)
{
printk("config fpga failed.\n");
goto restart;
}
else
{
printk("config fpga done...OK\n");
}
//set_pin(DATA);
exit:
//set_pin(CONF_CEn);
return;
}
static volatile int g_stop = 0;
void test_cpld(void)
{
#if 0
register int i,j;
register int time = 120*1000;/* 30s */
printk("cpld_val=0x%04x\n",get_pin(0xffff));
set_pin(CONF_CEn);
for(i=0;i<time;i++)
{
for(j=0;j<500;j++)
{
set_pin(DCLK);
//udelay(1);
clr_pin(DCLK);
//udelay(1);
}
}
clr_pin(CONF_CEn);
#else
while(1)
{
*(CPLD_FPGA_W) = DCLK;
*(CPLD_FPGA_W) = 0x0;
}
#endif
}
int __init fpgaload_init(void)/* must switch to flash */
{
printk("fpgaload driver init\n");
#if 0
while(1)
{
printk("abcdefghijkmlnopqrstuvwxyz\n");
}
#endif
/*-------reset fpga-----------*/
g_pctrlbase = (u_short *)ioremap(0x6000000,0x8000);
#if 0
*g_pctrlbase = 0xfffd;
mdelay(400);
*g_pctrlbase = 0xffff;
mdelay(100);
#endif
CPLD_FPGA_R = g_pctrlbase+(0x16/2);
CPLD_FPGA_W = g_pctrlbase+(0x18/2);
#if 0
test_cpld();
#else
{
int size = 0;
u_char *pdatabuf = (char *)ioremap(0x82000000,MAX_FPGA_BIN);
size = load_fpga(pdatabuf);
if(size)
{
u_int oldval;
//printk("cpld_val=0x%04x\n",get_pin(0xffff));
oldval = *(u32 *)(IO_ADDRESS(EMIF_A3CR));
*(u32 *)(IO_ADDRESS(EMIF_A3CR)) = 0x408605;
download_fpga(pdatabuf,size);
*(u32 *)(IO_ADDRESS(EMIF_A3CR)) = oldval;
}
else
printk("load fpga file failed.\n");
iounmap((void *)pdatabuf);
}
#endif
iounmap((void *)g_pctrlbase);
return 0;
}
void __exit fpgaload_exit(void)
{
g_stop = 1;
printk("fpgaload driver exit\n");
}
module_init(fpgaload_init);
module_exit(fpgaload_exit);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -