267 lines
5.8 KiB
C
267 lines
5.8 KiB
C
#include <linux/kernel.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/time.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/init.h>
|
|
#include <linux/module.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/io.h>
|
|
|
|
#include "bus.h"
|
|
|
|
#define FPGA_GPIO_DATA_OFFSET (0x12)
|
|
#define FPGA_GPIO_ALARM_LED (1<<0x2)
|
|
#define FPGA_GPIO_RUN_LED (1<<0x3)
|
|
#define FPGA_GPIO4_BIT (1<<0x4)
|
|
#define FPGA_GPIO5_BIT (1<<0x5)
|
|
#define FPGA_GPIO6_BIT (1<<0x6)
|
|
#define FPGA_GPIO7_BIT (1<<0x7)
|
|
|
|
#define FPGA_GPIO_STOP_BIT (FPGA_GPIO7_BIT)
|
|
#define FPGA_GPIO_SIP02_PHY (FPGA_GPIO4_BIT|FPGA_GPIO5_BIT|FPGA_GPIO6_BIT)
|
|
|
|
#define FPGA_CARD_TYPE_OFFSET (0x0)
|
|
#define FPGA_CPLD_VER_OFFSET (0x1)
|
|
#define FPGA_USER_ID_LOW_OFF (0x2)
|
|
#define FPGA_USER_ID_HIGH_OFF (0x3)
|
|
|
|
#define FPGA_ID_CAPTURE_END (4)
|
|
#define FPGA_BOX_ID_CTL_OFF (0x20)
|
|
#define FPGA_BOX_ID_OFF (0x16)
|
|
|
|
static unsigned int g_bIsFPGAInited = 0;
|
|
static unsigned int* g_pFPGAReg = NULL;
|
|
static unsigned short* g_pRegBase = NULL;
|
|
|
|
static inline unsigned short read_fpga16(unsigned short offset)
|
|
{
|
|
volatile unsigned short* addr = (unsigned short*)g_pRegBase + offset;
|
|
|
|
return *addr;
|
|
}
|
|
|
|
static inline int write_fpga16(unsigned short offset, unsigned short value)
|
|
{
|
|
volatile unsigned short* addr = (unsigned short*)g_pRegBase + offset;
|
|
|
|
*addr = value;
|
|
|
|
return 0;
|
|
}
|
|
|
|
unsigned short get_int_status_bit(void)
|
|
{
|
|
unsigned short value;
|
|
|
|
value = read_fpga16(FPGA_INT_STATUS_REG_OFFSET);
|
|
|
|
value &= FPGA_INT_REG_MASK;
|
|
|
|
return value;
|
|
}
|
|
|
|
int clr_int_status_bit(unsigned short value)
|
|
{
|
|
unsigned short reg;
|
|
|
|
// assert((value & FPGA_INT_REG_MASK) > 0);
|
|
|
|
reg = read_fpga16(FPGA_INT_STATUS_REG_OFFSET);
|
|
|
|
reg &= ~value;
|
|
|
|
return write_fpga16(FPGA_INT_STATUS_REG_OFFSET, reg);
|
|
}
|
|
|
|
int clr_int_mask_bit(unsigned short value)
|
|
{
|
|
unsigned short reg;
|
|
int ret;
|
|
|
|
//assert((value & FPGA_INT_REG_MASK) > 0);
|
|
|
|
reg = read_fpga16(FPGA_INT_MASK_REG_OFFSET);
|
|
|
|
reg |= value;
|
|
|
|
ret = write_fpga16(FPGA_INT_MASK_REG_OFFSET, reg);
|
|
|
|
|
|
reg = read_fpga16(FPGA_INT_MASK_REG_OFFSET);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int set_int_mask_bit(unsigned short value)
|
|
{
|
|
unsigned short reg;
|
|
int ret;
|
|
|
|
//assert((value & FPGA_INT_REG_MASK) > 0);
|
|
|
|
reg = read_fpga16(FPGA_INT_MASK_REG_OFFSET);
|
|
|
|
reg &= ~value;
|
|
|
|
ret = write_fpga16(FPGA_INT_MASK_REG_OFFSET, reg);
|
|
|
|
|
|
reg = read_fpga16(FPGA_INT_MASK_REG_OFFSET);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int fpga_RedLedCtrl(int iIsOn)
|
|
{
|
|
unsigned short value;
|
|
value = read_fpga16(FPGA_GPIO_DATA_OFFSET);
|
|
|
|
value = iIsOn ?
|
|
(value | FPGA_GPIO_ALARM_LED) :
|
|
(value & (~FPGA_GPIO_ALARM_LED));
|
|
|
|
write_fpga16(FPGA_GPIO_DATA_OFFSET, value);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(fpga_RedLedCtrl);
|
|
|
|
int fpga_GreenLedCtrl(int flag)
|
|
{
|
|
unsigned short value;
|
|
|
|
value = read_fpga16(FPGA_GPIO_DATA_OFFSET);
|
|
|
|
value = flag ?
|
|
(value | FPGA_GPIO_RUN_LED) :
|
|
(value & (~FPGA_GPIO_RUN_LED));
|
|
|
|
write_fpga16(FPGA_GPIO_DATA_OFFSET, value);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(fpga_GreenLedCtrl);
|
|
|
|
unsigned short fpga_GetCardType(void)
|
|
{
|
|
return read_fpga16(FPGA_CARD_TYPE_OFFSET);
|
|
}
|
|
EXPORT_SYMBOL(fpga_GetCardType);
|
|
|
|
unsigned short fpga_GetFPGAVer(void)
|
|
{
|
|
return read_fpga16(FPGA_CPLD_VER_OFFSET);
|
|
}
|
|
EXPORT_SYMBOL(fpga_GetFPGAVer);
|
|
|
|
unsigned int fpga_GetUserId(void)
|
|
{
|
|
unsigned short value;
|
|
|
|
value = read_fpga16(FPGA_USER_ID_HIGH_OFF);
|
|
|
|
return (value << 16) | read_fpga16(FPGA_USER_ID_LOW_OFF);
|
|
}
|
|
EXPORT_SYMBOL(fpga_GetUserId);
|
|
|
|
/** CPLD GPIO 4; CPLD GPIO 5; CPLD GPIO 6 **/
|
|
unsigned short fpga_GetSlot(void)
|
|
{
|
|
unsigned short value;
|
|
|
|
value = read_fpga16(FPGA_GPIO_DATA_OFFSET);
|
|
|
|
return ((value & FPGA_GPIO_SIP02_PHY) >> 4);
|
|
}
|
|
EXPORT_SYMBOL(fpga_GetSlot);
|
|
|
|
unsigned int fpga_GetChassisSn(void)
|
|
{
|
|
unsigned char temp;
|
|
unsigned short value;
|
|
unsigned char id[4] = {0};
|
|
unsigned int* pId = (unsigned int*)&id[0];
|
|
unsigned int i, j;
|
|
|
|
write_fpga16(FPGA_BOX_ID_CTL_OFF, 8);
|
|
udelay(1);
|
|
write_fpga16(FPGA_BOX_ID_CTL_OFF, 0);
|
|
udelay(1);
|
|
|
|
for(i = 100; i > 0; i--)
|
|
{
|
|
temp = read_fpga16(FPGA_BOX_ID_CTL_OFF);
|
|
|
|
if(temp & FPGA_ID_CAPTURE_END)
|
|
{
|
|
for(j = 0; j < 4; j++)
|
|
{
|
|
write_fpga16(FPGA_BOX_ID_CTL_OFF, j);
|
|
value = read_fpga16(FPGA_BOX_ID_CTL_OFF);
|
|
|
|
if((value & 0x3) != j)
|
|
{
|
|
printk("write %x read value data %x\n", j , (value & 0x3));
|
|
}
|
|
|
|
value = read_fpga16(FPGA_BOX_ID_OFF);
|
|
id[j] = value & 0xff;
|
|
}
|
|
}
|
|
|
|
if(*pId != 0)
|
|
{
|
|
printk("box id :0x%x 0x%x 0x%x 0x%x(0x%08X)\n", id[0], id[1], id[2], id[3], *pId);
|
|
return htonl(*pId);
|
|
}
|
|
|
|
mdelay(10);
|
|
}
|
|
|
|
return 0xffffffff;
|
|
}
|
|
EXPORT_SYMBOL(fpga_GetChassisSn);
|
|
|
|
int fpga_bus_init(void)
|
|
{
|
|
unsigned int* pReg = NULL;
|
|
unsigned short* pCs2 = NULL;
|
|
|
|
if(g_bIsFPGAInited == 0)
|
|
{
|
|
pReg = (unsigned int*)ioremap((CSBAR + FPGA_BUS_REG_OFFSET), FPGA_BUS_REG_MAP_SIZE);
|
|
|
|
//printk("pReq:0x%x,0x%x\n", (unsigned int)pReg, pReg[FPGA_READ_REG_OFF]);
|
|
|
|
pReg[FPGA_READ_REG_OFF] = CS2_READ_REG;
|
|
pReg[FPGA_WRITE_REG_OFF] = CS2_WRITE_REG;
|
|
pReg[FPGE_CTL_REG_OFF] = CS2_CTL_REG;
|
|
|
|
g_pFPGAReg = pReg;
|
|
|
|
pCs2 = (unsigned short*)ioremap(FPGA_BUS_BASE, FPGA_BUS_MAP_SIZE);
|
|
g_pRegBase = pCs2;
|
|
|
|
//printk("fgga base:0x%x\n", (unsigned int)pCs2);
|
|
}
|
|
|
|
g_bIsFPGAInited = 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void fpga_bus_exit(void)
|
|
{
|
|
printk("%s(%d)\n", __FUNCTION__, __LINE__);
|
|
|
|
if(g_bIsFPGAInited == 1)
|
|
{
|
|
iounmap(g_pFPGAReg);
|
|
iounmap(g_pRegBase);
|
|
}
|
|
|
|
g_bIsFPGAInited = 0;
|
|
}
|