spbx/roms/srcs/images/ethernet/mv_netdev/mvGpp.c

376 lines
7.4 KiB
C

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/io.h>
#include "mvGpp.h"
#define MV_DEBUG
#ifdef MV_DEBUG
#define mvOsPrintf printk
#define DB(x) x
#else
#define mvOsPrintf
#define DB(x)
#endif
static void* mv_reg_base = NULL;
static inline uint32_t MV_REG_READ(uint32_t regOffs)
{
return *((volatile uint32_t*)(mv_reg_base + regOffs));
}
static inline void MV_REG_WRITE(uint32_t regOffs, uint32_t value)
{
*((volatile uint32_t*)(mv_reg_base + regOffs)) = value;
}
static void gppRegSet(uint32_t regOffs, uint32_t mask, uint32_t value)
{
uint32_t gppData;
gppData = MV_REG_READ(regOffs);
gppData &= ~mask;
gppData |= (value & mask);
MV_REG_WRITE(regOffs, gppData);
#ifdef MV_DEBUG
if(regOffs != 0x18154)
{
do
{
uint32_t value;
value = MV_REG_READ(regOffs);
// DB(mvOsPrintf("regOffs:0x%x,write:0x%x,read:0x%x\n", regOffs, gppData, value));
}
while(0);
}
#endif
}
#define DUMP_GPIO_REG(off) do{ \
uint32_t value; \
value = MV_REG_READ(off); \
printk("*(0x%x)=0x%x\n",off,value);\
}while(0)
void mvGppRegDump(int grp)
{
DUMP_GPIO_REG(MPP_CONTROL_REG(0));
DUMP_GPIO_REG(MPP_CONTROL_REG(1));
DUMP_GPIO_REG(MPP_CONTROL_REG(2));
DUMP_GPIO_REG(MPP_CONTROL_REG(3));
DUMP_GPIO_REG(MPP_CONTROL_REG(4));
DUMP_GPIO_REG(MPP_CONTROL_REG(5));
DUMP_GPIO_REG(MPP_CONTROL_REG(6));
DUMP_GPIO_REG(MPP_CONTROL_REG(7));
DUMP_GPIO_REG(MPP_CONTROL_REG(8));
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x0);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x4);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x8);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0xc);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x10);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x14);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x18);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x1c);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x20);
DUMP_GPIO_REG(MV_GPP_REGS_BASE(grp) + 0x24);
}
int mvGppCtlSet(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_MPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
return -1;
}
gppRegSet(MPP_CONTROL_REG(group), mask, value);
return 0;
}
uint32_t mvGppCtlGet(uint32_t group)
{
uint32_t value;
value = MV_REG_READ(MPP_CONTROL_REG(group));
// DB(mvOsPrintf("regOffs:0x%x,read:0x%x\n", MPP_CONTROL_REG(group), value));
return value;
}
int mvGppTypeSet(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
return -1;
}
gppRegSet(GPP_DATA_OUT_EN_REG(group), mask, value);
return 0;
}
int mvGppBlinkEn(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
return -1;
}
gppRegSet(GPP_BLINK_EN_REG(group), mask, value);
return 0;
}
int mvGppBlinkSel(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
return -1;
}
gppRegSet(GPP_BLINK_SEL_REG(group), mask, value);
return 0;
}
int mvGppBlinkOnDiv(uint32_t group, uint32_t div)
{
if(group >= MV_BLINK_COUNTER_MAX_GROUP)
{
DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
return -1;
}
MV_REG_WRITE(GPP_BLINK_COUNT_ON(group), div);
#ifdef MV_DEBUG
do
{
uint32_t value;
value = MV_REG_READ(GPP_BLINK_COUNT_ON(group));
// DB(mvOsPrintf("regOffs:0x%x,write:0x%x,read:0x%x\n", GPP_BLINK_COUNT_ON(group), div, value));
}
while(0);
#endif
return 0;
}
int mvGppBlinkOffDiv(uint32_t group, uint32_t div)
{
if(group >= MV_BLINK_COUNTER_MAX_GROUP)
{
DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
return -1;
}
MV_REG_WRITE(GPP_BLINK_COUNT_OFF(group), div);
#ifdef MV_DEBUG
do
{
uint32_t value;
value = MV_REG_READ(GPP_BLINK_COUNT_OFF(group));
// DB(mvOsPrintf("regOffs:0x%x,write:0x%x,read:0x%x\n", GPP_BLINK_COUNT_OFF(group), div, value));
}
while(0);
#endif
return 0;
}
int mvGppPolaritySet(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));
return -1;
}
gppRegSet(GPP_DATA_IN_POL_REG(group), mask, value);
return 0;
}
uint32_t mvGppPolarityGet(uint32_t group, uint32_t mask)
{
uint32_t regVal;
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
return 0;
}
regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));
return (regVal & mask);
}
uint32_t mvGppValueGet(uint32_t group, uint32_t mask)
{
uint32_t gppData;
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
return 0;
}
gppData = MV_REG_READ(GPP_DATA_IN_REG(group));
gppData &= mask;
return gppData;
}
int mvGppValueSet(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
return -1;
}
gppRegSet(GPP_DATA_OUT_REG(group), mask, value);
return 0;
}
int mvGPPIntCauseSet(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
return -1;
}
gppRegSet(GPP_INT_CAUSE_REG(group), mask, value);
return 0;
}
uint32_t mvGPPIntCauseGet(uint32_t group, uint32_t mask)
{
uint32_t gppData;
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
return 0;
}
gppData = MV_REG_READ(GPP_INT_CAUSE_REG(group));
return (gppData & mask);
}
int mvGPPIntMask(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
return -1;
}
gppRegSet(GPP_INT_MASK_REG(group), mask, value);
return 0;
}
int mvGPPIntLvlMask(uint32_t group, uint32_t mask, uint32_t value)
{
if(group >= MV_GPP_MAX_GROUP)
{
DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
return -1;
}
gppRegSet(GPP_INT_LVL_REG(group), mask, value);
return 0;
}
void mvGppAtomicValueClear(uint32_t gpionumber)
{
if(gpionumber < 64)
{
MV_REG_WRITE(GPP_OUT_CLEAR_REG((int)(gpionumber >> 5)) , 1 << (gpionumber % 32));
}
else
{
MV_REG_WRITE(GPP_64_66_DATA_OUT_CLEAR_REG , 1 << (gpionumber % 32));
}
}
void mvGppAtomicValueSet(uint32_t gpionumber)
{
if(gpionumber < 64)
{
MV_REG_WRITE(GPP_OUT_SET_REG((int)(gpionumber >> 5)) , 1 << (gpionumber % 32));
}
else
{
MV_REG_WRITE(GPP_64_66_DATA_OUT_SET_REG , 1 << (gpionumber % 32));
}
}
int mvGppInit(void)
{
if(!mv_reg_base)
{
mv_reg_base = (void*)ioremap(CSBAR, CSBAR_MAP_WIDTH);
}
return 0;
}
void mvGppExit(void)
{
if(mv_reg_base)
{
iounmap(mv_reg_base);
mv_reg_base = NULL;
}
}