diff --git a/.clang-format b/.clang-format index 1f61625..ea7d5aa 100644 --- a/.clang-format +++ b/.clang-format @@ -53,7 +53,7 @@ BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeComma BreakAfterJavaFieldAnnotations: false BreakStringLiterals: false -ColumnLimit: 80 +ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false diff --git a/config.h b/config.h index 048d24a..f43eb40 100644 --- a/config.h +++ b/config.h @@ -101,6 +101,7 @@ extern "C" { #define INCLUDE_DISK_UTIL #endif +#define DRV_FS_LITTLEFS 1 /*#define INCLUDE_HRFS*/ #define DRV_VXBEND_FTGMAC @@ -190,7 +191,7 @@ extern "C" { #define SPI_BOOTROM_SIZE (0x400000) #define SPI_KERNEL_SIZE (0x600000) -#ifdef INCLUDE_TFFS +#if defined(INCLUDE_TFFS) || defined(DRV_FS_LITTLEFS) # define INCLUDE_TFFS_MOUNT # define INCLUDE_TFFS_SHOW diff --git a/ft2000-4.h b/ft2000-4.h index 3ff3eeb..f14c7c6 100644 --- a/ft2000-4.h +++ b/ft2000-4.h @@ -97,6 +97,8 @@ enum can_bitrate{ #define REG208 0x208 #define REG210 0x210 #define REG214 0x214 +#define REG218 0x218 + #define CAN_TXD_0 (1<<24) #define CAN_RXD_0 (1<<12) #define CAN_TXD_1 (1<<20) diff --git a/hwconf.c b/hwconf.c index 597320f..1f97523 100644 --- a/hwconf.c +++ b/hwconf.c @@ -259,21 +259,29 @@ struct hcfResource qspiResources[] = { #endif /* DRV_FTQSPI */ #ifdef DRV_FTSPI -struct vxbSpiDevInfo spiDevTbl1[] = { +struct vxbSpiDevInfo sm2130DevRes[] = { /* name cs width freq mode */ { "SM2130", 0, 8, 5000000, 3}, }; +struct hcfResource spiResources0[] = { + { "regBase", HCF_RES_INT, { (void *)(FTSPI0_BASE) } }, + { "clkFreq", HCF_RES_INT, { (void *)(FT2000_SPI_CLK) } }, + { "speed", HCF_RES_INT, { (void *)(4000000) } }, + { "mode", HCF_RES_INT, { (void *)3} }, +}; +#define spiNum0 NELEMENTS(spiResources0) + struct hcfResource spiResources1[] = { { "regBase", HCF_RES_INT, { (void *)(FTSPI1_BASE) } }, { "clkFreq", HCF_RES_INT, { (void *)(FT2000_SPI_CLK) } }, { "speed", HCF_RES_INT, { (void *)(4000000) } }, { "mode", HCF_RES_INT, { (void *)3} }, - { "spiDev", HCF_RES_ADDR, { (void *)&spiDevTbl1[0]} }, - { "spiDevNum", HCF_RES_INT, { (void *)NELEMENTS(spiDevTbl1)}}, + { "spiDev", HCF_RES_ADDR, { (void *)&sm2130DevRes[0]} }, + { "spiDevNum", HCF_RES_INT, { (void *)NELEMENTS(sm2130DevRes)}}, }; -# define spiNum1 NELEMENTS(spiResources1) -#endif /* DRV_FTQSPI */ +#define spiNum1 NELEMENTS(spiResources1) +#endif /* DRV_FTSPI */ #ifdef DRV_FTI2C @@ -506,6 +514,16 @@ struct hcfResource gmac1Resources[] = { #define gmac1Num NELEMENTS(gmac1Resources) #endif /* DRV_VXBEND_FTGMAC */ +#ifdef DRV_FS_LITTLEFS +struct hcfResource lfsResources[] = { + { "mountPoint" , HCF_RES_STRING, {(void *)"/lfs0"}}, + { "flashName" , HCF_RES_STRING, {(void *)TFFS_PART0_FLASH_NAME}}, + { "flashOffset", HCF_RES_INT, {(void *)(TFFS_PART0_FLASH_BOOT_SIZE)}}, + { "flashSize" , HCF_RES_INT, {(void *)((TFFS_PART0_FLASH_SIZE) - (TFFS_PART0_FLASH_BOOT_SIZE))}}, +}; +#define lfsResNum NELEMENTS(lfsResources) +#endif + const struct hcfDevice hcfDeviceList[] = { #ifdef DRV_ARM_GICV3 { "armGicDev", 0, VXB_BUSID_PLB, 0, armGICv3Num, armGICv3Resources}, @@ -557,6 +575,7 @@ const struct hcfDevice hcfDeviceList[] = { #endif #ifdef DRV_FTSPI +{ FT_SPI_NAME, 0, VXB_BUSID_PLB, 0, spiNum0, spiResources0 }, { FT_SPI_NAME, 1, VXB_BUSID_PLB, 0, spiNum1, spiResources1 }, #endif @@ -564,6 +583,9 @@ const struct hcfDevice hcfDeviceList[] = { { "ftGpio", 0, VXB_BUSID_PLB, 0, gpioDev0Num, gpioDev0Resources }, { "ftGpio", 1, VXB_BUSID_PLB, 0, gpioDev1Num, gpioDev1Resources }, #endif +#ifdef DRV_FS_LITTLEFS +{ "lfs", 0, VXB_BUSID_PLB, 0, lfsResNum, lfsResources}, +#endif }; const int hcfDeviceNum = NELEMENTS(hcfDeviceList); diff --git a/sysLib.c b/sysLib.c index 4ce69bc..d089574 100644 --- a/sysLib.c +++ b/sysLib.c @@ -1,13 +1,13 @@ +/* vim: set ts=4 sw=4 et fdm=marker: */ /* sysLib.c - system-dependent routines */ /* - * - * This program is OPEN SOURCE software: you can redistribute it and/or modify it; - * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; + * + * This program is OPEN SOURCE software: you can redistribute it and/or modify it; + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * */ - /* includes */ #include @@ -27,18 +27,18 @@ #include #include -#ifdef INCLUDE_MMU +#ifdef INCLUDE_MMU #include #include -#endif /* INCLUDE_MMU */ +#endif /* INCLUDE_MMU */ #include #ifdef INCLUDE_VXIPI -# include +#include #endif /* INCLUDE_VXIPI */ #ifdef _WRS_CONFIG_SMP -# include +#include #include #endif /* _WRS_CONFIG_SMP */ @@ -46,8 +46,8 @@ #include #include #include -LOCAL UINT32 sysSdhcClkFreqGet (void); -LOCAL void sysGmacAddrSet (UINT8* ); +LOCAL UINT32 sysSdhcClkFreqGet(void); +LOCAL void sysGmacAddrSet(UINT8 *); #ifdef INCLUDE_VXBUS #include "vxbArmGenIntCtlrV3.h" @@ -55,27 +55,26 @@ LOCAL void sysGmacAddrSet (UINT8* ); #include "hwconf.c" #include "ft2000-4.h" -IMPORT void hardWareInterFaceInit (void); +IMPORT void hardWareInterFaceInit(void); #ifdef INCLUDE_SIO_UTILS -IMPORT void sysSerialConnectAll (void); +IMPORT void sysSerialConnectAll(void); #endif /* INCLUDE_SIO_UTILS */ #endif /* INCLUDE_VXBUS */ -#ifdef INCLUDE_PCI_BUS /* BSP PCI bus & config support */ -# include -# include -# include +#ifdef INCLUDE_PCI_BUS /* BSP PCI bus & config support */ +#include +#include +#include /* 24-bit PCI network class ethernet subclass and prog. I/F code */ -# include "pciCfgIntStub.c" -#endif /* INCLUDE_PCI_BUS */ +#include "pciCfgIntStub.c" +#endif /* INCLUDE_PCI_BUS */ #if defined(INCLUDE_PC_CONSOLE) || defined(INCLUDE_WINDML) -#include "vxbM6845Vga.c" /* X100 VGA */ +#include "vxbM6845Vga.c" /* X100 VGA */ #endif -typedef struct arm_smc_regs -{ +typedef struct arm_smc_regs { int a0; int a1; int a2; @@ -89,57 +88,57 @@ typedef struct arm_smc_regs /* constant used with IPI to request reboot of application processors */ -#define APPCORE_REBOOT 0xFEFEFEF0 +#define APPCORE_REBOOT 0xFEFEFEF0 -LOCAL UINT32 rebootVar = 0; /* it passes the CPU index */ +LOCAL UINT32 rebootVar = 0; /* it passes the CPU index */ /* it protect from multiple reboots */ -LOCAL SPIN_LOCK_ISR_DECL (rebootLock, 0); +LOCAL SPIN_LOCK_ISR_DECL(rebootLock, 0); /* Non-Boot CPU Start info. Managed by sysCpuEnable */ -typedef struct sysMPCoreStartup_s - { - UINT32 newPC; /* Address of 'C' based startup code */ - UINT32 newSP; /* Stack pointer for startup */ - UINT32 newArg; /* vxWorks kernel entry point */ +typedef struct sysMPCoreStartup_s { + UINT32 newPC; /* Address of 'C' based startup code */ + UINT32 newSP; /* Stack pointer for startup */ + UINT32 newArg; /* vxWorks kernel entry point */ #ifndef _WRS_CONFIG_ARM_LPAE - UINT32 newSync; /* Translation Table Base and sync */ + UINT32 newSync; /* Translation Table Base and sync */ #else /* _WRS_CONFIG_ARM_LPAE */ - UINT32 ttbcr; /* Translation Table Base Control Register */ - UINT64 newSync; /* 64 bits Translation Table Base and sync */ + UINT32 ttbcr; /* Translation Table Base Control Register */ + UINT64 newSync; /* 64 bits Translation Table Base and sync */ #endif /* !_WRS_CONFIG_ARM_LPAE */ - }sysMPCoreStartup_t; +} sysMPCoreStartup_t; extern sysMPCoreStartup_t sysMPCoreStartup[VX_SMP_NUM_CPUS]; - extern unsigned int arm_mmu_ttbr; -IMPORT void sysInit (void); -IMPORT void sysInit32 (void); -IMPORT void mmuCortexA8DacrSet (UINT32 dacrVal); -IMPORT STATUS sysArmGicDevInit (void); -IMPORT void mmuCortexA8AEnable (UINT32 cacheState); -IMPORT void mmuCortexA8ADisable (void); -IMPORT void armInitExceptionModes (void); -IMPORT void sysCpuInit (void); -IMPORT void cacheCortexA9MPCoreSMPInit (void); -IMPORT void mmuCortexA8TLBIDFlushAll (void); -IMPORT MMU_LEVEL_1_DESC * mmuCortexA8TtbrGet (void); - -UINT32 sysCpuAvailableGet (void); -STATUS sysCpuEnable (unsigned int, void (* startFunc) (void), char *); +IMPORT void lfsDevRegister(void); + +IMPORT void sysInit(void); +IMPORT void sysInit32(void); +IMPORT void mmuCortexA8DacrSet(UINT32 dacrVal); +IMPORT STATUS sysArmGicDevInit(void); +IMPORT void mmuCortexA8AEnable(UINT32 cacheState); +IMPORT void mmuCortexA8ADisable(void); +IMPORT void armInitExceptionModes(void); +IMPORT void sysCpuInit(void); +IMPORT void cacheCortexA9MPCoreSMPInit(void); +IMPORT void mmuCortexA8TLBIDFlushAll(void); +IMPORT MMU_LEVEL_1_DESC *mmuCortexA8TtbrGet(void); + +UINT32 sysCpuAvailableGet(void); +STATUS sysCpuEnable(unsigned int, void (*startFunc)(void), char *); void sysUsDelay(int us); #endif /* _WRS_CONFIG_SMP */ -int uartf(const char * fmt, /* format string */... /* optional arguments to format */); +int uartf(const char *fmt, /* format string */... /* optional arguments to format */); /* imports */ -IMPORT char end []; /* end of system, created by ld */ +IMPORT char end[]; /* end of system, created by ld */ #ifndef _ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK -IMPORT VOIDFUNCPTR _func_armIntStackSplit; /* ptr to fn to split stack */ -#endif /* !_ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK */ +IMPORT VOIDFUNCPTR _func_armIntStackSplit; /* ptr to fn to split stack */ +#endif /* !_ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK */ /* globals */ @@ -163,136 +162,89 @@ IMPORT VOIDFUNCPTR _func_armIntStackSplit; /* ptr to fn to split stack */ * critical, they could be reduced. */ -PHYS_MEM_DESC sysPhysMemDesc [] = -{ +PHYS_MEM_DESC sysPhysMemDesc[] = { - { - LOCAL_MEM_LOCAL_ADRS, /* virtual address */ - LOCAL_MEM_LOCAL_ADRS, /* physical address */ - LOCAL_MEM_SIZE, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_WRITEALLOCATE_MSK, + { LOCAL_MEM_LOCAL_ADRS, /* virtual address */ + LOCAL_MEM_LOCAL_ADRS, /* physical address */ + LOCAL_MEM_SIZE, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_WRITEALLOCATE_MSK, #if defined(_WRS_CONFIG_SMP) /* needs to be shared */ - MMU_ATTR_VALID | MMU_ATTR_SUP_RWX | MMU_ATTR_WRITEALLOCATE_SHARED + MMU_ATTR_VALID | MMU_ATTR_SUP_RWX | MMU_ATTR_WRITEALLOCATE_SHARED #else - MMU_ATTR_VALID | MMU_ATTR_SUP_RWX | MMU_ATTR_WRITEALLOCATE + MMU_ATTR_VALID | MMU_ATTR_SUP_RWX | MMU_ATTR_WRITEALLOCATE #endif /* _WRS_CONFIG_SMP */ }, - { - PIN_DEMUX_BASE, /* pin MUX/DEMUX */ - PIN_DEMUX_BASE, - 0x10000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - - { - UART_0_BASE_ADR, /* UART */ - UART_0_BASE_ADR, - 0x18000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - { - 0x28207000, /* CAN*/ - 0x28207000, - 0x1000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - { - 0x2820b000, /* GMAC*/ - 0x2820b000, - 0x00009000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - { - 0x29900000, /* GIC */ - 0x29900000, - 0x100000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - - { - FT_PCI_CONFIG_ADDR, /* PCI Memory address spcae */ - FT_PCI_CONFIG_ADDR, - 0x10000000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - - { - 0x50000000, /* PCI io32Addr */ - 0x50000000, - 0x08000000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - - { - 0x58000000, /* PCI mem32Addr */ - 0x58000000, - 0x27000000, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, - + { PIN_DEMUX_BASE, /* pin MUX/DEMUX */ + PIN_DEMUX_BASE, 0x10000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, + + { UART_0_BASE_ADR, /* UART */ + UART_0_BASE_ADR, 0x18000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, + { 0x28207000, /* CAN*/ + 0x28207000, 0x1000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, + { 0x2820b000, /* GMAC*/ + 0x2820b000, 0x00009000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, + { 0x29900000, /* GIC */ + 0x29900000, 0x100000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, + + { FT_PCI_CONFIG_ADDR, /* PCI Memory address spcae */ + FT_PCI_CONFIG_ADDR, 0x10000000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, + + { 0x50000000, /* PCI io32Addr */ + 0x50000000, 0x08000000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, + + { 0x58000000, /* PCI mem32Addr */ + 0x58000000, 0x27000000, MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, #ifdef DRV_FTQSPI - { /* Qspi BootRom */ - SPI_FLASH_BASE_ADRS, - SPI_FLASH_BASE_ADRS, - SPI_BOOTROM_SIZE, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RO | MMU_ATTR_DEVICE_SHARED - }, - - { /* Qspi Flash */ - SPI_FLASH_BASE_ADRS + SPI_BOOTROM_SIZE, - SPI_FLASH_BASE_ADRS + SPI_BOOTROM_SIZE, - SPI_FLASH_SIZE - SPI_BOOTROM_SIZE, - MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, - MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED - }, + { /* Qspi BootRom */ + SPI_FLASH_BASE_ADRS, SPI_FLASH_BASE_ADRS, SPI_BOOTROM_SIZE, + MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RO | MMU_ATTR_DEVICE_SHARED }, + + { /* Qspi Flash */ + SPI_FLASH_BASE_ADRS + SPI_BOOTROM_SIZE, SPI_FLASH_BASE_ADRS + SPI_BOOTROM_SIZE, SPI_FLASH_SIZE - SPI_BOOTROM_SIZE, + MMU_ATTR_VALID_MSK | MMU_ATTR_PROT_MSK | MMU_ATTR_DEVICE_SHARED_MSK, + MMU_ATTR_VALID | MMU_ATTR_SUP_RW | MMU_ATTR_DEVICE_SHARED }, #endif }; -int sysPhysMemDescNumEnt = NELEMENTS (sysPhysMemDesc); +int sysPhysMemDescNumEnt = NELEMENTS(sysPhysMemDesc); #endif /* defined(INCLUDE_MMU) */ -int sysBus = BUS_TYPE_PCI; /* system bus type (VME_BUS, etc) */ -int sysCpu = CPU; /* system CPU type (e.g. ARMARCH6) */ -char * sysBootLine = BOOT_LINE_ADRS; /* address of boot line */ -char * sysExcMsg = EXC_MSG_ADRS; /* catastrophic message area */ -int sysProcNum; /* processor number of this CPU */ - +int sysBus = BUS_TYPE_PCI; /* system bus type (VME_BUS, etc) */ +int sysCpu = CPU; /* system CPU type (e.g. ARMARCH6) */ +char *sysBootLine = BOOT_LINE_ADRS; /* address of boot line */ +char *sysExcMsg = EXC_MSG_ADRS; /* catastrophic message area */ +int sysProcNum; /* processor number of this CPU */ /* locals */ - /* defines */ /* externals */ #ifndef _ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK -IMPORT void sysIntStackSplit (char *, long); -#endif /* !_ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK */ +IMPORT void sysIntStackSplit(char *, long); +#endif /* !_ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK */ /* globals */ -char * sysPhysMemTop (void); +char *sysPhysMemTop(void); /* included source files */ - #include - - /******************************************************************************* * * sysModel - return the model name of the CPU board @@ -304,10 +256,10 @@ char * sysPhysMemTop (void); * ERRNO */ -char *sysModel (void) - { +char *sysModel(void) +{ return SYS_MODEL; - } +} /******************************************************************************* * @@ -322,75 +274,68 @@ char *sysModel (void) * ERRNO */ -char * sysBspRev (void) - { +char *sysBspRev(void) +{ return (BSP_VERSION BSP_REV); - } -extern VIRT_ADDR mmuPhysToVirt - ( - PHYS_ADDR physAddr /* physical address to be translated */ - ); - -extern PHYS_ADDR mmuVirtToPhys - ( - VIRT_ADDR virtAddr /* virtual address to be translated */ - ); +} +extern VIRT_ADDR mmuPhysToVirt(PHYS_ADDR physAddr /* physical address to be translated */ +); + +extern PHYS_ADDR mmuVirtToPhys(VIRT_ADDR virtAddr /* virtual address to be translated */ +); #ifndef _WRS_CONFIG_ARM_LPAE -extern void cacheCortexA9LibInstall (VIRT_ADDR (physToVirt)(PHYS_ADDR), - PHYS_ADDR (virtToPhys)(VIRT_ADDR)); +extern void cacheCortexA9LibInstall(VIRT_ADDR(physToVirt)(PHYS_ADDR), PHYS_ADDR(virtToPhys)(VIRT_ADDR)); #else -extern void cacheCortexA15LibInstall (VIRT_ADDR (physToVirt)(PHYS_ADDR), - PHYS_ADDR (virtToPhys)(VIRT_ADDR)); +extern void cacheCortexA15LibInstall(VIRT_ADDR(physToVirt)(PHYS_ADDR), PHYS_ADDR(virtToPhys)(VIRT_ADDR)); #endif -void writeq(int data,int addr) +void writeq(int data, int addr) { - *((volatile UINT32*)addr) = (UINT32)data; + *((volatile UINT32 *)addr) = (UINT32)data; } int readq(int addr) { - return *((volatile UINT32*) addr); + return *((volatile UINT32 *)addr); } void v8_outer_disable_l3cache(void) { int i, pstate; for (i = 0; i < 8; i++) - writeq(0x1, 0x3A200010 + i*0x10000); + writeq(0x1, 0x3A200010 + i * 0x10000); for (i = 0; i < 8; i++) { do { - pstate = readq(0x3A200018 + i* 0x10000); - } while ((pstate & 0xf) != (0x1<< 2)); + pstate = readq(0x3A200018 + i * 0x10000); + } while ((pstate & 0xf) != (0x1 << 2)); } - } void v8_outer_cache_flush_all(void) { - int i,pstate; + int i, pstate; for (i = 0; i < 8; i++) - writeq(0x1, 0x3A200010 + i*0x10000); - for (i = 0; i < 8; i++) { - do { - pstate = readq(0x3A200018 + i* 0x10000); - } while ((pstate & 0xf) != (0x1<< 2)); - } - for (i = 0; i < 8; i++) - writeq(0x3, 0x3A200010 + i*0x10000); + writeq(0x1, 0x3A200010 + i * 0x10000); + for (i = 0; i < 8; i++) { + do { + pstate = readq(0x3A200018 + i * 0x10000); + } while ((pstate & 0xf) != (0x1 << 2)); + } + for (i = 0; i < 8; i++) + writeq(0x3, 0x3A200010 + i * 0x10000); } -void sysHwInit0 (void) +void sysHwInit0(void) { /*v8_outer_cache_flush_all();*/ - excVecBaseSet (LOCAL_MEM_LOCAL_ADRS); + excVecBaseSet(LOCAL_MEM_LOCAL_ADRS); #ifdef INCLUDE_CACHE_SUPPORT -#ifndef _WRS_CONFIG_ARM_LPAE - cacheCortexA9LibInstall (mmuPhysToVirt, mmuVirtToPhys); +#ifndef _WRS_CONFIG_ARM_LPAE + cacheCortexA9LibInstall(mmuPhysToVirt, mmuVirtToPhys); #else - cacheCortexA15LibInstall (mmuPhysToVirt, mmuVirtToPhys); + cacheCortexA15LibInstall(mmuPhysToVirt, mmuVirtToPhys); #endif #endif - mmuCortexA8LibInstall (mmuPhysToVirt, mmuVirtToPhys); + mmuCortexA8LibInstall(mmuPhysToVirt, mmuVirtToPhys); } #ifdef _WRS_CONFIG_SMP /******************************************************************************* @@ -403,13 +348,11 @@ void sysHwInit0 (void) * RETURNS: N/A */ -void sysMsDelay - ( - UINT delay /* length of time in ms to delay */ - ) - { - sysUsDelay (1000 * delay); - } +void sysMsDelay(UINT delay /* length of time in ms to delay */ +) +{ + sysUsDelay(1000 * delay); +} /******************************************************************************* * @@ -420,13 +363,12 @@ void sysMsDelay * RETURNS: N/A */ -void sysDelay (void) - { - sysMsDelay (1); - } - -LOCAL UINT32 genTimerFreq = 0; +void sysDelay(void) +{ + sysMsDelay(1); +} +LOCAL UINT32 genTimerFreq = 0; /******************************************************************************* * @@ -439,18 +381,16 @@ LOCAL UINT32 genTimerFreq = 0; * ERRNO: N/A */ -LOCAL UINT64 armGenGetSysCount (void) - { +LOCAL UINT64 armGenGetSysCount(void) +{ UINT64 count1; + _WRS_ASM("ISB"); - _WRS_ASM ("ISB"); - - count1 = __inline__GetPhyTimerCnt (); - + count1 = __inline__GetPhyTimerCnt(); return count1; - } +} /******************************************************************************* * @@ -463,26 +403,22 @@ LOCAL UINT64 armGenGetSysCount (void) * ERRNO: N/A */ #ifndef __DCC__ -LOCAL void armGenGetFreq (void) - { - _WRS_ASM ("MRC p15, 0, %0, c14, c0, 0" : "=r" (genTimerFreq)); - } +LOCAL void armGenGetFreq(void) +{ + _WRS_ASM("MRC p15, 0, %0, c14, c0, 0" : "=r"(genTimerFreq)); +} #else -__asm volatile UINT32 __inline__GetCntFreq (void) - { -! "r0" - mrc p15, 0, r0, c14, c0, 0 - } +__asm volatile UINT32 __inline__GetCntFreq(void){ !"r0" mrc p15, 0, r0, c14, c0, 0 } -LOCAL UINT32 armGenGetFreq (void) - { +LOCAL UINT32 armGenGetFreq(void) +{ static UINT32 freq = 0; - freq = __inline__GetCntFreq (); + freq = __inline__GetCntFreq(); genTimerFreq = freq; /* update global value. */ return freq; - } +} #endif /******************************************************************************* @@ -503,48 +439,40 @@ LOCAL UINT32 armGenGetFreq (void) *\NOMANUAL */ -void sysUsDelay - ( - int us - ) - { - volatile UINT64 oldVal; - volatile UINT64 newVal; - volatile UINT64 incElapsed = 0; - volatile UINT64 totalDelta; - volatile UINT64 maxCount; - - if (us <= 0) - { - printf ("usDelay, wrong parameter: %d us\n", us); +void sysUsDelay(int us) +{ + volatile UINT64 oldVal; + volatile UINT64 newVal; + volatile UINT64 incElapsed = 0; + volatile UINT64 totalDelta; + volatile UINT64 maxCount; + + if (us <= 0) { + printf("usDelay, wrong parameter: %d us\n", us); return; - } + } totalDelta = (genTimerFreq * (UINT64)us + 1000000 - 1) / 1000000; maxCount = 0xffffffffffffffffull; - oldVal = armGenGetSysCount (); - while (incElapsed < totalDelta) - { - newVal = armGenGetSysCount (); + oldVal = armGenGetSysCount(); + while (incElapsed < totalDelta) { + newVal = armGenGetSysCount(); if (newVal == oldVal) continue; - if (newVal > oldVal) - { + if (newVal > oldVal) { incElapsed += (newVal - oldVal); - } - else - { + } else { incElapsed += ((maxCount - oldVal) + newVal); - } + } oldVal = newVal; - } } +} -#endif/*_WRS_CONFIG_SMP*/ +#endif /*_WRS_CONFIG_SMP*/ /******************************************************************************* * @@ -560,68 +488,103 @@ void sysUsDelay * ERRNO */ extern void vxbftCanRegister(void); -#ifdef INCLUDE_DRV_STORAGE_NVME -extern void vxbNvmeStorageRegister (void); +#ifdef INCLUDE_DRV_STORAGE_NVME +extern void vxbNvmeStorageRegister(void); #endif -#ifdef DRV_X100DC -extern void ftX100DcDevicePciRegister (void); +#ifdef DRV_X100DC +extern void ftX100DcDevicePciRegister(void); #endif -void sysHwInit (void) +void sysHwInit(void) { - uartf("...............................\r\n"); + uartf("...............................\r\n"); /* swdo_swj_pad: can_rxd_1 i2c_2_scl tdo_swj_pad: can_rxd_2 i2c_2_sda CAN_1,CAN_2 and I2C_2, only choose ONE. */ - // writeq(readq(PIN_DEMUX_BASE+REG204)|CAN_TXD_0|CAN_RXD_0|CAN_TXD_1|CAN_RXD_1, - // PIN_DEMUX_BASE+REG204); /* pad pin DeMux. enable CAN */ + // writeq(readq(PIN_DEMUX_BASE+REG204)|CAN_TXD_0|CAN_RXD_0|CAN_TXD_1|CAN_RXD_1, + // PIN_DEMUX_BASE+REG204); /* pad pin DeMux. enable CAN */ - /* pin_mux: + /* + * pin_mux (SPI0): + * spi0_csn0_pad: spi0_csn0 gpio1_porta_5 + * spi0_sck_pad: spi0_sck gpio1_porta_6 + * spi0_so_pad: spi0_so gpio1_porta_7 + * spi0_si_pad: spi0_si gpio1_portb_0 + */ + unsigned int reg = readl(PIN_DEMUX_BASE + REG208); + reg &= ~((0x3 << 16) | (0x3 << 12) | (0x3 << 8) | (0x3 << 4)); + writel(reg, PIN_DEMUX_BASE + REG208); + + /* + * pin_mux (SPI1): * uart_2_rxd_pad: uart_2_rxd spi1_csn0 gpio0_portb_5 * uart_2_txd_pad: uart_2_txd spi1_sck hda_sdi1 * uart_3_rxd_pad: uart_3_rxd spi1_so hda_sdi2 * uart_3_txd_pad: uart_3_txd spi1_si hda_sdi3 */ - /* SM2130 1553B SPI1 */ - unsigned int reg = readl(PIN_DEMUX_BASE + REG210); - reg &= ~0x3; - reg |= 0x1; /* spi1_csn0 */ - writel(reg, PIN_DEMUX_BASE + REG210); - reg = readl(PIN_DEMUX_BASE + REG214); - reg &= ~((0x3 << 28) | (0x3 << 24) | (0x3 << 20)); - reg |= (1 << 28) | (1 << 24) | (1 << 20); - writel(reg, PIN_DEMUX_BASE + REG214); - - #ifdef DRV_X100DC - ftX100DcDevicePciRegister(); - #endif - -#ifdef INCLUDE_VXBUS + /* SPI1 */ + reg = readl(PIN_DEMUX_BASE + REG210); + reg &= ~0xf; + reg |= 0x9; /* spi1_csn0 */ + writel(reg, PIN_DEMUX_BASE + REG210); + + reg = readl(PIN_DEMUX_BASE + REG214); + reg &= ~((0xf << 28) | (0xf << 24) | (0xf << 20)); + reg |= (0x9 << 28) | (0x9 << 24) | (0x9 << 20); /* enable pullup */ + writel(reg, PIN_DEMUX_BASE + REG214); + + /* + * GPIO1_B7: SM2130_MR + * GPIO0_B6: SM2130_ACKIRQ + * GPIO0_B7: SM2130_READY + * + * qspi_csn1_pad: qspi_csn1 gpio1_portb_7 + * qspi_csn2_pad: spi_csn2 spi1_csn1 gpio0_portb_6 + * qspi_csn3_pad: qspi_csn3 spi1_csn2 gpio0_portb_7 + */ + reg = readl(PIN_DEMUX_BASE + REG214); + reg &= ~((0x3 << 12) | (0x3 << 8) | (0x3 << 4)); + reg |= (0x1 << 12) | (0x2 << 8) | (0x2 << 4); + writel(reg, PIN_DEMUX_BASE + REG214); + /* + * GPIO1_A4: SM2130_IRQ + * + * ext_lpc_lad_1_pad: ext_lpc_lad_1 gpio1_porta_4 + */ + reg = readl(PIN_DEMUX_BASE + REG218); + reg &= ~(0x3 << 8); + reg |= (0x1 << 8); + writel(reg, PIN_DEMUX_BASE + REG218); + +#ifdef DRV_X100DC + ftX100DcDevicePciRegister(); +#endif + + lfsDevRegister(); + +#ifdef INCLUDE_VXBUS hardWareInterFaceInit(); -#endif /* INCLUDE_VXBUS */ -#ifdef DRV_PCIBUS_FT - ftPciRegister(); +#endif /* INCLUDE_VXBUS */ +#ifdef DRV_PCIBUS_FT + ftPciRegister(); #endif -#ifdef INCLUDE_DRV_STORAGE_NVME - vxbNvmeStorageRegister (); +#ifdef INCLUDE_DRV_STORAGE_NVME + vxbNvmeStorageRegister(); #endif - -#ifdef FORCE_DEFAULT_BOOT_LINE - strncpy(sysBootLine, DEFAULT_BOOT_LINE, strlen(DEFAULT_BOOT_LINE)+1); -#endif /* FORCE_DEFAULT_BOOT_LINE */ +#ifdef FORCE_DEFAULT_BOOT_LINE + strncpy(sysBootLine, DEFAULT_BOOT_LINE, strlen(DEFAULT_BOOT_LINE) + 1); +#endif /* FORCE_DEFAULT_BOOT_LINE */ #ifdef _WRS_CONFIG_SMP - - _vxb_delayRtn = (void (*) ())sysDelay; - _vxb_msDelayRtn = (void (*) (int))sysMsDelay; - _vxb_usDelayRtn = (void (*) (int))sysUsDelay; + _vxb_delayRtn = (void (*)())sysDelay; + _vxb_msDelayRtn = (void (*)(int))sysMsDelay; + _vxb_usDelayRtn = (void (*)(int))sysUsDelay; armGenGetFreq(); -#endif/*_WRS_CONFIG_SMP*/ - +#endif /*_WRS_CONFIG_SMP*/ } /******************************************************************************* @@ -636,37 +599,32 @@ void sysHwInit (void) * * ERRNO */ - -void sysHwInit2 (void) - { +void sysHwInit2(void) +{ static BOOL initialised = FALSE; - - if (initialised) - { + + if (initialised) { return; } -#ifdef INCLUDE_VXBUS +#ifdef INCLUDE_VXBUS - vxbDevInit(); + vxbDevInit(); -#ifdef INCLUDE_SIO_UTILS +#ifdef INCLUDE_SIO_UTILS sysSerialConnectAll(); -#endif /* INCLUDE_SIO_UTILS */ +#endif /* INCLUDE_SIO_UTILS */ - taskSpawn("tDevConn", 11, 0, 10000, - vxbDevConnect, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); -#endif /* INCLUDE_VXBUS */ - + taskSpawn("tDevConn", 11, 0, 10000, vxbDevConnect, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); +#endif /* INCLUDE_VXBUS */ initialised = TRUE; #if defined(INCLUDE_IPFTPS) - ipcom_sysvar_set("ipftps.root", TFFS_FLASH_MOUNT_POINTOT, IPCOM_SYSVAR_FLAG_OVERWRITE); - ipcom_sysvar_set("ipftps.dir", TFFS_FLASH_MOUNT_POINTOT, IPCOM_SYSVAR_FLAG_OVERWRITE); + ipcom_sysvar_set("ipftps.root", TFFS_FLASH_MOUNT_POINTOT, IPCOM_SYSVAR_FLAG_OVERWRITE); + ipcom_sysvar_set("ipftps.dir", TFFS_FLASH_MOUNT_POINTOT, IPCOM_SYSVAR_FLAG_OVERWRITE); #endif - - } +} /******************************************************************************* * @@ -691,19 +649,16 @@ void sysHwInit2 (void) * SEE ALSO: sysMemTop() */ -char * sysPhysMemTop (void) - { - static char * physTop = NULL; - - if (physTop == NULL) - { - - physTop = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE); +char *sysPhysMemTop(void) +{ + static char *physTop = NULL; + if (physTop == NULL) { + physTop = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE); } return physTop; - } +} /******************************************************************************* * @@ -721,17 +676,16 @@ char * sysPhysMemTop (void) * ERRNO */ -char * sysMemTop (void) - { - static char * memTop = NULL; +char *sysMemTop(void) +{ + static char *memTop = NULL; #ifdef INCLUDE_EDR_PM - memTop = (char *)sysPhysMemTop () - USER_RESERVED_MEM - PM_RESERVED_MEM; + memTop = (char *)sysPhysMemTop() - USER_RESERVED_MEM - PM_RESERVED_MEM; #else - memTop = (char *)sysPhysMemTop () - USER_RESERVED_MEM; + memTop = (char *)sysPhysMemTop() - USER_RESERVED_MEM; #endif /* INCLUDE_EDR_PM */ return (memTop); - } - +} /******************************************************************************* * @@ -746,32 +700,29 @@ char * sysMemTop (void) * * ERRNO */ - /*Please refer to FT-1500A-4V1.5.pdf for GPIO general description.*/ +/*Please refer to FT-1500A-4V1.5.pdf for GPIO general description.*/ + +STATUS sysToMonitor(int startType /* passed to ROM to tell it how to boot */ +) +{ + ARM_SMC_REGS input = { 0 }; + ARM_SMC_REGS output = { 0 }; -STATUS sysToMonitor - ( - int startType /* passed to ROM to tell it how to boot */ - ) - { - - ARM_SMC_REGS input = {0}; - ARM_SMC_REGS output = {0}; - #ifdef _WRS_CONFIG_ARM_LPAE /* reset TTBCR */ - mmuCortexA8TtbcrSet (0); -#endif /* _WRS_CONFIG_ARM_LPAE */ + mmuCortexA8TtbcrSet(0); +#endif /* _WRS_CONFIG_ARM_LPAE */ input.a0 = 0x84000009; - armSmcCall (&input, &output); - while(1) - {} - - return OK; /* in case we ever continue from ROM monitor */ + armSmcCall(&input, &output); + while (1) { } -#if defined (_WRS_CONFIG_SMP) + return OK; /* in case we ever continue from ROM monitor */ +} + +#if defined(_WRS_CONFIG_SMP) extern void armv7a_secondary_wake(); extern void arm_int_enable(); @@ -794,41 +745,31 @@ extern void arm_int_enable(); IMPORT void excVBARSet(UINT32 adr); -LOCAL void sysCpuStart -( - void (*startFunc)(void), - UINT32 cpuNum -) +LOCAL void sysCpuStart(void (*startFunc)(void), UINT32 cpuNum) { - - - /* sysMsDelay(cpuNum*100);*/ + /* sysMsDelay(cpuNum*100);*/ #ifdef INCLUDE_VFP vfpEnable(); #endif - - excVBARSet( LOCAL_MEM_LOCAL_ADRS ); + + excVBARSet(LOCAL_MEM_LOCAL_ADRS); /* Initialise ARM exception mode registers */ - - armInitExceptionModes (); - + + armInitExceptionModes(); + /* Enable Local S/W interrupts */ - - sysArmGicDevInit (); + + sysArmGicDevInit(); sysMPCoreStartup[cpuNum].newSync = 0; /* Enter the Kernel */ - if (cpuNum == VX_SMP_NUM_CPUS -1) + if (cpuNum == VX_SMP_NUM_CPUS - 1) uartf("sysCpuStart(). cpu to start : %d done! \r\n", cpuNum); - - + (*startFunc)(); } - - - /******************************************************************************* * * sysCpuEnable - enable a multi core CPU @@ -842,14 +783,8 @@ LOCAL void sysCpuStart * \NOMANUAL */ -STATUS sysCpuEnable - ( - unsigned int cpuNum, - void (*startFunc) (void), - char *stackPtr - ) - { - +STATUS sysCpuEnable(unsigned int cpuNum, void (*startFunc)(void), char *stackPtr) +{ static INT32 sysCpuEnableFirst = 1; /* Validate cpuNum */ @@ -857,9 +792,7 @@ STATUS sysCpuEnable if (cpuNum < 1 || cpuNum >= VX_SMP_NUM_CPUS) return (ERROR); - if (sysCpuEnableFirst == 1) - { - + if (sysCpuEnableFirst == 1) { /* * IPIs cannot be connected in sysToMonitor, because interrupt handlers * cannot be installed in interrupt context. @@ -872,10 +805,9 @@ STATUS sysCpuEnable * The INT_LVL_MPCORE_IPI08 is sent by core 0 to all the AP cores. */ - vxIpiConnect (INT_LVL_MPCORE_IPI08, (IPI_HANDLER_FUNC)(sysToMonitor), - (void *)(APPCORE_REBOOT)); + vxIpiConnect(INT_LVL_MPCORE_IPI08, (IPI_HANDLER_FUNC)(sysToMonitor), (void *)(APPCORE_REBOOT)); - vxIpiEnable (INT_LVL_MPCORE_IPI08); + vxIpiEnable(INT_LVL_MPCORE_IPI08); /* * Connect and enable IPI for core0. @@ -883,35 +815,33 @@ STATUS sysCpuEnable * to core0. */ - vxIpiConnect (INT_LVL_MPCORE_RESET, (IPI_HANDLER_FUNC)(sysToMonitor), - (void *) &rebootVar); + vxIpiConnect(INT_LVL_MPCORE_RESET, (IPI_HANDLER_FUNC)(sysToMonitor), (void *)&rebootVar); - vxIpiEnable (INT_LVL_MPCORE_RESET); + vxIpiEnable(INT_LVL_MPCORE_RESET); sysCpuEnableFirst = 0; - } + } /* Setup init values */ - sysMPCoreStartup[cpuNum].newPC = (UINT32)sysCpuStart; - sysMPCoreStartup[cpuNum].newSP = (UINT32)stackPtr; - sysMPCoreStartup[cpuNum].newArg = (UINT32)startFunc; + sysMPCoreStartup[cpuNum].newPC = (UINT32)sysCpuStart; + sysMPCoreStartup[cpuNum].newSP = (UINT32)stackPtr; + sysMPCoreStartup[cpuNum].newArg = (UINT32)startFunc; #ifndef _WRS_CONFIG_ARM_LPAE sysMPCoreStartup[cpuNum].newSync = mmuCortexA8TtbrGetAll(); #else /* _WRS_CONFIG_ARM_LPAE */ sysMPCoreStartup[cpuNum].ttbcr = mmuCortexA8TtbcrGet(); sysMPCoreStartup[cpuNum].newSync = mmuCortexA8TtbrGet64(); #endif /* !_WRS_CONFIG_ARM_LPAE */ - + arm_mmu_ttbr = sysMPCoreStartup[cpuNum].newSync; /* Make sure data hits memory */ - cacheFlush ((CACHE_TYPE)DATA_CACHE, (void *)sysMPCoreStartup, - (size_t)(sizeof (sysMPCoreStartup))); + cacheFlush((CACHE_TYPE)DATA_CACHE, (void *)sysMPCoreStartup, (size_t)(sizeof(sysMPCoreStartup))); - cachePipeFlush (); - #if 0 + cachePipeFlush(); +#if 0 if (cpuNum == (VX_SMP_NUM_CPUS-1)) { *(volatile unsigned int *)(FT_SECONDARY_BOOT_ADDR) = (UINT32)sysCpuInit; @@ -931,42 +861,37 @@ STATUS sysCpuEnable /* uartf("sysCpuEnable(). cpu to waken : %d done! \r\n", cpuNum);*/ } #else -{ - ARM_SMC_REGS input = {0}; - ARM_SMC_REGS output = {0}; - PHYS_ADDR physAddr; - - if (vmTranslate (NULL, (VIRT_ADDR)sysCpuInit, &physAddr) == ERROR) - return ERROR; - + { + ARM_SMC_REGS input = { 0 }; + ARM_SMC_REGS output = { 0 }; + PHYS_ADDR physAddr; + + if (vmTranslate(NULL, (VIRT_ADDR)sysCpuInit, &physAddr) == ERROR) + return ERROR; input.a0 = 0x84000003; input.a1 = cpuNum; - if(2 == input.a1) - { - input.a1 = 0x100; /* Core2's number is 0x100 */ + if (2 == input.a1) { + input.a1 = 0x100; /* Core2's number is 0x100 */ } - if(3 == input.a1) - { - input.a1 = 0x101; /* Core3's number is 0x101 */ + if (3 == input.a1) { + input.a1 = 0x101; /* Core3's number is 0x101 */ } /*input.a2 = (UINT32)(physAddr >> 32);*/ input.a2 = (UINT32)(physAddr & 0xFFFFFFFF); - armSmcCall (&input, &output); - - VX_SYNC_BARRIER (); - #ifdef _WRS_CONFIG_ARM_LPAE - sysMsDelay(cpuNum*100); - #endif + armSmcCall(&input, &output); - /* wake up core from wfe using sev. */ + VX_SYNC_BARRIER(); +#ifdef _WRS_CONFIG_ARM_LPAE + sysMsDelay(cpuNum * 100); +#endif - -} + /* wake up core from wfe using sev. */ + } #endif return OK; - } +} /******************************************************************************* * @@ -979,10 +904,10 @@ STATUS sysCpuEnable * ERRNO: N/A */ -UINT32 sysCpuAvailableGet (void) - { +UINT32 sysCpuAvailableGet(void) +{ return VX_SMP_NUM_CPUS; - } +} #endif /* if defined (_WRS_CONFIG_SMP) */ /**************************************************************************** @@ -999,10 +924,10 @@ UINT32 sysCpuAvailableGet (void) * SEE ALSO: sysProcNumSet() */ -int sysProcNumGet (void) - { +int sysProcNumGet(void) +{ return 0; - } +} /**************************************************************************** * @@ -1021,16 +946,13 @@ int sysProcNumGet (void) * SEE ALSO: sysProcNumGet() */ -void sysProcNumSet - ( - int procNum /* processor number */ - ) - { +void sysProcNumSet(int procNum /* processor number */ +) +{ sysProcNum = procNum; - } - +} -#ifdef INCLUDE_SIO_UTILS +#ifdef INCLUDE_SIO_UTILS /****************************************************************************** * * bspSerialChanGet - get the SIO_CHAN device associated with a serial channel @@ -1052,21 +974,16 @@ void sysProcNumSet * \NOMANUAL */ -SIO_CHAN * bspSerialChanGet - ( - int channel /* serial channel */ - ) - { - return ((SIO_CHAN *) ERROR); - } -#endif /* INCLUDE_SIO_UTILS */ - - - +SIO_CHAN *bspSerialChanGet(int channel /* serial channel */ +) +{ + return ((SIO_CHAN *)ERROR); +} +#endif /* INCLUDE_SIO_UTILS */ #ifdef DRV_PCIBUS_FT -LOCAL UCHAR sysPciExIntRoute[4] = {60, 61, 62, 63}; +LOCAL UCHAR sysPciExIntRoute[4] = { 60, 61, 62, 63 }; /******************************************************************************* * @@ -1077,18 +994,16 @@ LOCAL UCHAR sysPciExIntRoute[4] = {60, 61, 62, 63}; * RETURNS: OK or ERROR */ -STATUS sysPciExAutoconfigInclude - ( - PCI_SYSTEM * pSys, /* PCI_SYSTEM structure pointer */ - PCI_LOC * pLoc, /* pointer to function in question */ - UINT devVend /* deviceID/vendorID of device */ - ) - { +STATUS sysPciExAutoconfigInclude(PCI_SYSTEM *pSys, /* PCI_SYSTEM structure pointer */ + PCI_LOC *pLoc, /* pointer to function in question */ + UINT devVend /* deviceID/vendorID of device */ +) +{ if (pLoc->bus == 0 && pLoc->device == 0 && pLoc->function == 0) return ERROR; return OK; - } +} /******************************************************************************* * @@ -1099,151 +1014,135 @@ STATUS sysPciExAutoconfigInclude * * RETURNS: PCI interrupt line number given pin mask */ -UCHAR pci_int_log[32] ={0}; -int pci_int_idx =0; -UCHAR sysPciExAutoconfigIntrAssign - ( - PCI_SYSTEM * pSys, /* PCI_SYSTEM structure pointer */ - PCI_LOC * pLoc, /* pointer to function in question */ - UCHAR pin /* contents of PCI int pin register */ - ) - { +UCHAR pci_int_log[32] = { 0 }; +int pci_int_idx = 0; +UCHAR sysPciExAutoconfigIntrAssign(PCI_SYSTEM *pSys, /* PCI_SYSTEM structure pointer */ + PCI_LOC *pLoc, /* pointer to function in question */ + UCHAR pin /* contents of PCI int pin register */ +) +{ pci_int_log[pci_int_idx++] = pin; - if(pci_int_idx == 32) - { + if (pci_int_idx == 32) { pci_int_idx = 0; } return sysPciExIntRoute[pin - 1]; - } +} #endif /* DRV_PCIBUS_M85XX */ - - /* this is for multi cluster*/ #if defined(_WRS_CONFIG_SMP) -UINT32 cpuIndexMap[4] = {0,1,0x100,0x101}; +UINT32 cpuIndexMap[4] = { 0, 1, 0x100, 0x101 }; -UINT32 vxCpuIdGetByIndex - ( - UINT32 idx - ) - { +UINT32 vxCpuIdGetByIndex(UINT32 idx) +{ if (idx >= VX_MAX_SMP_CPUS) return (UINT32)-1; return cpuIndexMap[idx]; - } +} #endif /* _WRS_CONFIG_SMP */ -UCHAR sysPciInByte(ULONG address) +UCHAR sysPciInByte(ULONG address) { return *(volatile UCHAR *)address; } - void sysPciOutByte(ULONG address, UCHAR data) - { +void sysPciOutByte(ULONG address, UCHAR data) +{ *(volatile UCHAR *)address = data; - } - - UINT16 sysPciInWord(ULONG address) +} + +UINT16 sysPciInWord(ULONG address) { return *(volatile UINT16 *)address; } - void sysPciOutWord(ULONG address, UINT16 data) +void sysPciOutWord(ULONG address, UINT16 data) { *(volatile UINT16 *)address = data; } - - UINT sysPciInLong(ULONG address) + +UINT sysPciInLong(ULONG address) { return *(volatile UINT *)address; } - void sysPciOutLong(ULONG address, UINT data) +void sysPciOutLong(ULONG address, UINT data) { *(volatile UINT *)address = data; } +extern int fioFormatV(FAST const char *fmt, /* format string */ + va_list vaList, /* pointer to varargs list */ + FUNCPTR outRoutine, /* handler for args as they're formatted */ + int outarg /* argument to routine */ +); - extern int fioFormatV - ( - FAST const char *fmt, /* format string */ - va_list vaList, /* pointer to varargs list */ - FUNCPTR outRoutine, /* handler for args as they're formatted */ - int outarg /* argument to routine */ - ); - -UINT32 uart_tx_fifo_addr = UART_1_BASE_ADR; /* FT UART BASE ADDR */ +UINT32 uart_tx_fifo_addr = UART_1_BASE_ADR; /* FT UART BASE ADDR */ /* prime cell sio constants */ -#define UARTFR 0x18 /* Flag register */ -#define FLG_UTXFF (1 << 5) /* UART Tx FIFO Full */ -#define FLG_UTXFE (1 << 7) /* UART Tx FIFO Empty */ +#define UARTFR 0x18 /* Flag register */ +#define FLG_UTXFF (1 << 5) /* UART Tx FIFO Full */ +#define FLG_UTXFE (1 << 7) /* UART Tx FIFO Empty */ static void charout(char cha) { volatile UINT32 reg_val32; /* for PrimeCell sio */ - reg_val32 = *(volatile UINT32 *)(uart_tx_fifo_addr+UARTFR); + reg_val32 = *(volatile UINT32 *)(uart_tx_fifo_addr + UARTFR); /* is the transmitter ready to accept a character? */ - while ((reg_val32 & FLG_UTXFF) != 0x00) - { - reg_val32 = *(volatile UINT32 *)(uart_tx_fifo_addr+UARTFR); + while ((reg_val32 & FLG_UTXFF) != 0x00) { + reg_val32 = *(volatile UINT32 *)(uart_tx_fifo_addr + UARTFR); } - - + *(volatile UINT32 *)uart_tx_fifo_addr = cha; } -void stringout(char * str) +void stringout(char *str) { - char * pbuf = str; + char *pbuf = str; char cha; volatile UINT32 reg_val32; - while((cha = *pbuf++) != 0) + while ((cha = *pbuf++) != 0) charout(cha); do { - reg_val32 = *(volatile UINT32 *)(uart_tx_fifo_addr+UARTFR); + reg_val32 = *(volatile UINT32 *)(uart_tx_fifo_addr + UARTFR); } while ((reg_val32 & FLG_UTXFE) == 0); } -static int bufferPut - ( - char *inbuf, /* pointer to source buffer */ - int length, /* number of bytes to copy */ - char **outptr /* pointer to destination buffer */ - ) - { - bcopy (inbuf, *outptr, length); +static int bufferPut(char *inbuf, /* pointer to source buffer */ + int length, /* number of bytes to copy */ + char **outptr /* pointer to destination buffer */ +) +{ + bcopy(inbuf, *outptr, length); *outptr += length; return (OK); - } +} -int uartf(const char * fmt, /* format string */ - ... /* optional arguments to format */ - ) +int uartf(const char *fmt, /* format string */ + ... /* optional arguments to format */ +) { - char charArray[128] = {0,}; - char * buffer = charArray; - va_list vaList; /* traverses argument list */ - int nChars; - + char charArray[128] = { + 0, + }; + char *buffer = charArray; + va_list vaList; /* traverses argument list */ + int nChars; - va_start (vaList, fmt); - nChars = fioFormatV (fmt, vaList, bufferPut, (int) &buffer); - va_end (vaList); + va_start(vaList, fmt); + nChars = fioFormatV(fmt, vaList, bufferPut, (int)&buffer); + va_end(vaList); *buffer = EOS; stringout(charArray); return (nChars); - } - /******************************************************************************* * * sysSdhcClkFreqGet - get sdhc freq @@ -1253,11 +1152,10 @@ int uartf(const char * fmt, /* format string */ * RETURNS: freq */ -LOCAL UINT32 sysSdhcClkFreqGet (void) - { - +LOCAL UINT32 sysSdhcClkFreqGet(void) +{ return 600000000; - } +} /******************************************************************************* * @@ -1268,18 +1166,17 @@ LOCAL UINT32 sysSdhcClkFreqGet (void) * RETURNS: void */ -LOCAL void sysGmacAddrSet (UINT8* macAddr) - { +LOCAL void sysGmacAddrSet(UINT8 *macAddr) +{ static int addr = 0x38; - macAddr[0] =0; - macAddr[1] =0; - macAddr[2] =0x3e; - macAddr[3] =0x2; - macAddr[4] =0x2; + macAddr[0] = 0; + macAddr[1] = 0; + macAddr[2] = 0x3e; + macAddr[3] = 0x2; + macAddr[4] = 0x2; macAddr[5] = addr; - addr += 2; - return ; - } - + addr += 2; + return; +} diff --git a/usrStubs.c b/usrStubs.c index 504c939..11c9af3 100644 --- a/usrStubs.c +++ b/usrStubs.c @@ -9,21 +9,24 @@ int usr_ipftps_authenticate_nopasswd(Ipftps_session *session, char *password) { - printf("auth: it\r\n"); - return 0; + printf("ftp passthor\r\n"); + return 0; } #endif -#if 0 -void usrAppInit (void) +#if defined(__DCC__) +void usrAppInit(void) { - - printf("appInited\r\n"); + printf("appInited\r\n"); } #endif -#if defined(__GNUC__) -#include "lfs/lfs.c" -#include "lfs/lfs_util.c" -#endif +int mw(unsigned long addr, unsigned int val) +{ + volatile unsigned int long *ptr = (volatile unsigned long *)(addr); + + *ptr = val; + + return 0; +} diff --git a/vxbFtSpi.c b/vxbFtSpi.c index ada5e1b..613ad3d 100644 --- a/vxbFtSpi.c +++ b/vxbFtSpi.c @@ -1,635 +1,1147 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include <../src/hwif/h/vxbus/vxbAccess.h> -#include -#include "vxbFtSpi.h" -#include "ft2000-4.h" - -#define CTRLR0 0x0 -#define CTRLR1 0x4 -#define SSIENR 0x8 -#define MWCR 0xc -#define SER 0x10 -#define BAUDR 0x14 -#define TXFTLR 0x18 -#define RXFTLR 0x1c -#define TXFLR 0x20 -#define RXFLR 0x24 -#define SR 0x28 -#define IMR 0x2c -#define ISR 0x30 -#define DMACR 0x4c -#define DR 0x60 -#define RX_SAMPLE_DLY 0xfc -/* debug macro */ -#undef SPI_DBG_ON -#ifdef SPI_DBG_ON - -#undef LOCAL -#define LOCAL - -#define SPI_DBG_OFF 0x00000000 -#define SPI_DBG_ISR 0x00000001 -#define SPI_DBG_RW 0x00000002 -#define SPI_DBG_ERR 0x00000004 -#define SPI_DBG_RTN 0x00000008 -#define SPI_DBG_INFO 0x00000010 -#define SPI_DBG_ALL 0xffffffff - -LOCAL UINT32 spiDbgMask = SPI_DBG_ALL; -IMPORT FUNCPTR _func_logMsg; - -#define SPI_DBG(mask, string, X1, X2, X3, X4, X5, X6) \ - if ((spiDbgMask & mask) || (mask == SPI_DBG_ALL)) \ - if (_func_logMsg != NULL) \ - (* _func_logMsg)(string, (int)X1, (int)X2, (int)X3, \ - (int)X4, (int)X5, (int)X6) -#else -#define SPI_DBG(mask, string, X1, X2, X3, X4, X5, X6) -#endif /* SPI_DBG_ON */ - -#if _BYTE_ORDER == _BIG_ENDIAN -# define SPI_REG_HANDLE_SWAP(x) VXB_HANDLE_SWAP(x) -#else -# define SPI_REG_HANDLE_SWAP(x) (x) -#endif /* _BYTE_ORDER == _BIG_ENDIAN */ - -/* read write macros */ -#define VXB_FT_SPI_REG(pChan, reg) \ - (UINT32 *)((UINT32) ((pChan)->regBase) + (reg)) - -#define VXB_FT_SPI_REG16(pChan, reg) \ - (UINT16 *)((UINT32) ((pChan)->regBase) + (reg)) - -#define VXB_FT_SPI_REG8(pChan, reg) \ - (UINT8 *)((UINT32) ((pChan)->regBase) + (reg)) - -#define VXB_FT_SPI_REG_READ(pChan, reg, result) \ - (result) = vxbRead32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) - -#define VXB_FT_SPI_REG_WRITE(pChan, reg, data) \ - vxbWrite32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg), (data)) - -#define VXB_FT_SPI_REG_BIT_SET(pChan, reg, data) \ - VXB_FT_SPI_REG_WRITE (pChan, reg, \ - vxbRead32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) | (data)) - -#define VXB_FT_SPI_REG_BIT_CLR(pChan, reg, data) \ - VXB_FT_SPI_REG_WRITE (pChan, reg, \ - vxbRead32 ((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) & (~(data))) - -/* VxBus methods */ -LOCAL void vxbFtSpiInstInit (VXB_DEVICE_ID pDev); -LOCAL void vxbFtSpiInstInit2 (VXB_DEVICE_ID pDev); -LOCAL void vxbFtSpiInstConnect (VXB_DEVICE_ID pDev); -LOCAL VXB_SPI_BUS_CTRL * vxbFtSpiCtrlGet (VXB_DEVICE_ID pDev); -LOCAL void vxbFtSpiShow (VXB_DEVICE_ID, int); -LOCAL STATUS vxbFtSpiInstUnlink (VXB_DEVICE_ID pDev, void * unused); - -/* forward declarations */ -LOCAL void vxbFtSpiCtrlInit (VXB_DEVICE_ID pDev); - -LOCAL STATUS vxbFtSpiTransfer (VXB_DEVICE_ID pDev, SPI_HARDWARE * pSpiDev, - SPI_TRANSFER * pPkg); -/* locals */ -LOCAL struct drvBusFuncs vxbFtSpiVxbFuncs = { - vxbFtSpiInstInit, /* devInstanceInit */ - vxbFtSpiInstInit2, /* devInstanceInit2 */ - vxbFtSpiInstConnect /* devConnect */ -}; - -LOCAL device_method_t vxbFtSpiDeviceMethods[] = { - DEVMETHOD (vxbSpiControlGet, vxbFtSpiCtrlGet), - DEVMETHOD (busDevShow, vxbFtSpiShow), - DEVMETHOD (vxbDrvUnlink, vxbFtSpiInstUnlink), - DEVMETHOD_END -}; - -LOCAL struct vxbPlbRegister vxbFtSpiDevRegistration = { - { - NULL, /* pNext */ - VXB_DEVID_DEVICE, /* devID */ - VXB_BUSID_PLB, /* busID = PLB */ - VXB_VER_4_0_0, /* vxbVersion */ - FT_SPI_NAME, /* drvName */ - &vxbFtSpiVxbFuncs, /* pDrvBusFuncs */ - &vxbFtSpiDeviceMethods[0], /* pMethods */ - NULL, /* devProbe */ - NULL, /* pParamDefaults */ - }, -}; - -/* - * vxbFtSpiRegister - register with the VxBus subsystem - * - * This routine registers the SPI driver with VxBus Systems. - * - * RETURNS: N/A - * - * ERRNO: N/A - */ -void vxbFtSpiRegister (void) -{ - vxbDevRegister ((struct vxbDevRegInfo *) &vxbFtSpiDevRegistration); -} - -/* - * vxbFtSpiInstInit - initialize SPI controller - * - * This function implements the VxBus instInit handler for a SPI controller - * device instance. - * - * Initialize the device by the following: - * - * - retrieve the resource from the hwconf - * - per-device init - * - announce SPI Bus and create device instance - * - * RETURNS: N/A - * - * ERRNO: N/A - */ -LOCAL void vxbFtSpiInstInit(VXB_DEVICE_ID pDev) -{ - FT_SPI_CTRL * pDrvCtrl; - struct hcfDevice *pHcf; - int i; - - /* check for valid parameter */ - VXB_ASSERT_NONNULL_V (pDev); - - /* create controller driver context structure for core */ - pDrvCtrl = (FT_SPI_CTRL *) hwMemAlloc (sizeof (FT_SPI_CTRL)); - if (pDrvCtrl == NULL) { - return; - } - pDev->pDrvCtrl = pDrvCtrl; - pDrvCtrl->pDev = pDev; - - for (i = 0; i < VXB_MAXBARS; i++) { - if (pDev->regBaseFlags[i] == VXB_REG_MEM) { - break; - } - } - if (i == VXB_MAXBARS) { -#ifndef _VXBUS_BASIC_HWMEMLIB - hwMemFree((char *)pDrvCtrl); -#endif - pDev->pDrvCtrl = NULL; - return; - } - pDrvCtrl->regBase = pDev->pRegBase[i]; - vxbRegMap(pDev, i, &pDrvCtrl->regHandle); - pDrvCtrl->regHandle = (void *)SPI_REG_HANDLE_SWAP ((ULONG)pDrvCtrl->regHandle); - pHcf = (struct hcfDevice *) hcfDeviceGet (pDev); - if (pHcf == NULL) { -#ifndef _VXBUS_BASIC_HWMEMLIB - hwMemFree((char *)pDrvCtrl); -#endif - pDev->pDrvCtrl = NULL; - return; - } - - if (devResourceGet (pHcf, "clkFreq", HCF_RES_INT,(void *) &pDrvCtrl->clkFreq) != OK) { - pDrvCtrl->clkFreq = FT2000_SPI_CLK; - } - - if (devResourceGet (pHcf, "speed", HCF_RES_INT,(void *) &pDrvCtrl->speed) != OK) { - pDrvCtrl->speed = 1000000; - } - - if (devResourceGet (pHcf, "mode", HCF_RES_INT,(void *) &pDrvCtrl->mode) != OK) { - pDrvCtrl->mode = 0; - } - - if (devResourceGet (pHcf, "dataWidth", HCF_RES_INT,(void *) &pDrvCtrl->dataWidth) != OK) { - pDrvCtrl->dataWidth = 8; - } - - if (devResourceGet (pHcf, "spiDevNum", HCF_RES_INT, (void *) &pDrvCtrl->spiDevNum) != OK) { - pDrvCtrl->spiDevNum = 0; - } - pDrvCtrl->cs = 0; - - vxbFtSpiCtrlInit(pDev); - - pDrvCtrl->vxbSpiCtrl.spiTransfer = (void *)vxbFtSpiTransfer; - - /* announce that there's a SPI bus */ - (void) vxbBusAnnounce (pDev, VXB_BUSID_SPI); - - /* notify the bus subsystem of all devices on SPI */ - (void) spiBusAnnounceDevices (pDev); - - pDrvCtrl->initPhase = 1; -} - -/* - * vxbFtSpiInstInit2 - second level initialization routine of SPI controller - * - * This routine performs the second level initialization of the SPI controller. - * - * RETURNS: N/A - * - * ERRNO: N/A - */ -LOCAL void vxbFtSpiInstInit2(VXB_DEVICE_ID pDev) -{ - FT_SPI_CTRL * pDrvCtrl; - - /* check for valid parameter */ - - VXB_ASSERT_NONNULL_V (pDev); - - pDrvCtrl = (FT_SPI_CTRL *) pDev->pDrvCtrl; - - /* used for mutex accessing of the controller */ - pDrvCtrl->muxSem = semMCreate (SEM_Q_PRIORITY); - - if (pDrvCtrl->muxSem == NULL) { - SPI_DBG (SPI_DBG_ERR, "semMCreate failed for muxSem\n", - 0, 0, 0, 0, 0, 0); - return; - } - - pDrvCtrl->initPhase = 2; -} - -/* - * vxbFtSpiInstConnect - third level initialization - * - * This routine performs the third level initialization of the QSPI controller - * driver. - * - * RETURNS: N/A - * - * ERRNO : N/A - */ -LOCAL void vxbFtSpiInstConnect(VXB_DEVICE_ID pDev) -{ - FT_SPI_CTRL * pDrvCtrl; - - pDrvCtrl = pDev->pDrvCtrl; - pDrvCtrl->initPhase = 3; -} - -/* - * vxbFtSpiCtrlGet - get the SPI controller struct - * - * This routine returns the QSPI controller struct pointer (VXB_SPI_BUS_CTRL *) - * to caller (SPI Lib) by vxbSpiControlGet method. Currently, this struct - * only contain the spiTransfer routine(eg: vxbFtQspiTransfer) for SPI Lib, - * other parameters can be easily added in this struct. - * - * RETURNS: the pointer of SPI controller struct - * - * ERRNO: N/A - */ -LOCAL VXB_SPI_BUS_CTRL * vxbFtSpiCtrlGet(VXB_DEVICE_ID pDev) -{ - FT_SPI_CTRL * pDrvCtrl; - - /* check if the pDev pointer is valid */ - VXB_ASSERT (pDev != NULL, NULL) - - pDrvCtrl = (FT_SPI_CTRL *) pDev->pDrvCtrl; - - SPI_DBG (SPI_DBG_RTN, "vxbFtQspiCtrlGet(0x08%x) called\n", - (_Vx_usr_arg_t)pDev, 2, 3, 4, 5, 6); - - return (&(pDrvCtrl->vxbSpiCtrl)); -} - -/* - * vxbFtSpiCtrlInit - SPI controller initialization - * - * This routine performs the SPI controller initialization. - * - * RETURNS: N/A - * - * ERRNO: N/A - */ -LOCAL void vxbFtSpiCtrlInit(VXB_DEVICE_ID pDev) -{ - FT_SPI_CTRL *pDrvCtrl; - UINT32 regval, clkDiv; - - pDrvCtrl = (FT_SPI_CTRL *) pDev->pDrvCtrl; - - /* disable the controller */ - VXB_FT_SPI_REG_WRITE(pDrvCtrl, SSIENR, 0x0); - - /* CTRLR0 */ - VXB_FT_SPI_REG_READ(pDrvCtrl, CTRLR0, regval); - - /* normal mode */ - regval &= ~(1 << 11); - - /* data width */ - regval &= ~(0xf); - regval |= (pDrvCtrl->dataWidth - 1) & 0xf; - - /* - * spi mode mapping: - * - * CPOL CPHA - * 0 0 mode 0 - * 0 1 mode 1 - * 1 0 mode 2 - * 1 1 mode 3 - */ - if (pDrvCtrl->mode & 0x1) { - regval |= (1 << 6); /* CPHA */ - } else { - regval &= ~(1 << 6); - } - if (pDrvCtrl->mode & 0x2) { - regval |= (1 << 7); - } else { - regval &= ~(1 << 7); - } - /* rx & tx */ - regval &= ~(0x3 << 8); - - /* slv_oe = 1 (slave disable) */ - regval &= ~(1 << 10); - - VXB_FT_SPI_REG_WRITE(pDrvCtrl, CTRLR0, regval); - - VXB_FT_SPI_REG_WRITE(pDrvCtrl, CTRLR1, 0); - - /* disable DMA */ - VXB_FT_SPI_REG_WRITE(pDrvCtrl, DMACR, 0); - - /* baudrate */ - clkDiv = pDrvCtrl->clkFreq / pDrvCtrl->speed; - if (clkDiv < 2) { - clkDiv = 2; - } - - if (clkDiv > 65534) { - clkDiv = 65534; - } - - VXB_FT_SPI_REG_WRITE(pDrvCtrl, BAUDR, clkDiv); - - VXB_FT_SPI_REG_WRITE(pDrvCtrl, RX_SAMPLE_DLY, 0); - - VXB_FT_SPI_REG_WRITE(pDrvCtrl, RXFTLR, 0); - VXB_FT_SPI_REG_WRITE(pDrvCtrl, TXFTLR, 0); - - VXB_FT_SPI_REG_BIT_CLR(pDrvCtrl, IMR, 0x1f); /* disable all interrupts */ - regval = (1 << pDrvCtrl->cs); - VXB_FT_SPI_REG_BIT_SET(pDrvCtrl, SER, regval); -} - -/* - * vxbFtSpiTransfer - SPI transfer routine - * - * This routine is used to perform one transmission. It is the interface which - * can be called by SPI device driver to send and receive data via the QSPI - * controller. - * - * RETURNS: OK or ERROR - * - * ERRNO: N/A - */ -LOCAL STATUS vxbFtSpiTransfer( - VXB_DEVICE_ID pDev, /* controller pDev */ - SPI_HARDWARE * pSpiDev, /* device info */ - SPI_TRANSFER * pPkg /* transfer data info */ -) -{ - STATUS sts = OK; - UINT32 alignSize; - FT_SPI_CTRL * pDrvCtrl; - int i, len; - UINT8 dummy8; - UINT16 dummy16, *dptr; - /* check if the pointers are valid */ - - if (pDev == NULL || pSpiDev == NULL || pPkg == NULL || pSpiDev->devInfo == NULL) { - SPI_DBG (SPI_DBG_ERR, "vxbFtQspiTransfer NULL pointer\n", - 1, 2, 3, 4, 5, 6); - return ERROR; - } - - pDrvCtrl = (FT_SPI_CTRL *) pDev->pDrvCtrl; - if (pDrvCtrl == NULL) { - SPI_DBG (SPI_DBG_ERR, "vxbFtQspiTransfer pDrvCtrl is NULL\n", - 1, 2, 3, 4, 5, 6); - return ERROR; - } - - SPI_DBG (SPI_DBG_RTN, "vxbFtQspiTransfer txLen[%d] rxLen[%d]\n", - pPkg->txLen, pPkg->rxLen, 3, 4, 5, 6); - - if (pPkg->txLen == 0 && pPkg->rxLen == 0) { - SPI_DBG (SPI_DBG_ERR, "vxbFtQspiTransfer tx and rx both are 0\n", - 1, 2, 3, 4, 5, 6); - return ERROR; - } - - if ((pPkg->txLen != 0 && pPkg->txBuf == NULL ) || (pPkg->rxLen != 0 && pPkg->rxBuf == NULL)) { - SPI_DBG (SPI_DBG_ERR, - "vxbFtQspiTransfer invalid parameters[%x %x %x %x] \n", - pPkg->txBuf, pPkg->txLen, pPkg->rxLen, pPkg->rxBuf, 5, 6); - - return ERROR; - } - - if (pSpiDev->devInfo->bitWidth <= 8) { /* 4 to 8 bits */ - alignSize = sizeof(char); - } else if (pSpiDev->devInfo->bitWidth <= 16) { /* 9 to 16 bits */ - alignSize = sizeof(UINT16); - } else { /* 17 to 32 bits */ - SPI_DBG (SPI_DBG_ERR, - "vxbFtQspiTransfer: data word length must between 2-16\n", - 1, 2, 3, 4, 5, 6); - return ERROR; - } - - /* check to see if the address is aligned with SPI bit width */ - if ((pPkg->txLen != 0 && - (((UINT32)pPkg->txBuf & (alignSize - 1)) != 0 || - (pPkg->txLen & (alignSize - 1)) != 0)) || - (pPkg->rxLen != 0 && - (((UINT32)pPkg->rxBuf & (alignSize - 1)) != 0 || - (pPkg->rxLen & (alignSize - 1)) != 0))) { - SPI_DBG (SPI_DBG_ERR, - "vxbFtQspiTransfer address or len is not aligned:" - "[tx:%x-%x rx:%x-%x] with %d \n", - pPkg->txBuf, pPkg->txLen, pPkg->rxBuf, pPkg->rxLen, - alignSize, 6); - - return ERROR; - } - - if ( pSpiDev->devInfo->chipSelect >= SPI_MAX_CS_NUM) { - SPI_DBG (SPI_DBG_ERR, - "vxbFtQspiTransfer invalid channel[%x] \n", - pDrvCtrl->channel, 2, 3, 4, 5, 6); - - return ERROR; - } - - /* - * The controller can not be used by multichannel at the same time. - * If the initPhase < 2, there is no multi-task context. So, the - * semTake is not needed. - */ - if (pDrvCtrl->initPhase >= 2) { - (void)semTake (pDrvCtrl->muxSem, WAIT_FOREVER); - } - - if ((pSpiDev->devInfo->devFreq != pDrvCtrl->speed) || (pSpiDev->devInfo->bitWidth != pDrvCtrl->dataWidth) - || (pSpiDev->devInfo->mode != pDrvCtrl->mode) || (pSpiDev->devInfo->chipSelect != pDrvCtrl->cs)) { - pDrvCtrl->mode = pSpiDev->devInfo->mode; - pDrvCtrl->speed = pSpiDev->devInfo->devFreq; - pDrvCtrl->dataWidth = pSpiDev->devInfo->bitWidth; - pDrvCtrl->cs = pSpiDev->devInfo->chipSelect; - vxbFtSpiCtrlInit(pDev); - } - - VXB_FT_SPI_REG_WRITE(pDrvCtrl, SSIENR, 0x1); - if (pPkg->txLen > 0) { - if (alignSize == 1) { - for (i = 0;i < pPkg->txLen; ++i) { - vxbWrite8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR), pPkg->txBuf[i]); - dummy8 = vxbRead8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR)); - (void)dummy8; - } - } else { - dptr = (UINT16 *)(pPkg->txBuf); - len = pPkg->txLen >> 1; - for (i = 0; i < len; ++i) { - vxbWrite16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR), dptr[i]); - dummy16 = vxbRead16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR)); - (void)dummy16; - } - } - } - - if (pPkg->rxLen > 0) { - if (alignSize == 1) { - dummy8 = 0x0; - for (i = 0;i < pPkg->rxLen; ++i) { - vxbWrite8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR), dummy8); - pPkg->rxBuf[i] = vxbRead8(pDrvCtrl->regHandle, VXB_FT_SPI_REG8(pDrvCtrl, DR)); - } - } else { - dummy16 = 0; - dptr = (UINT16 *)(pPkg->rxBuf); - len = pPkg->rxLen >> 1; - for (i = 0; i < len; ++i) { - vxbWrite16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR), dummy16); - dptr[i] = vxbRead16(pDrvCtrl->regHandle, VXB_FT_SPI_REG16(pDrvCtrl, DR)); - } - } - - } - VXB_FT_SPI_REG_WRITE(pDrvCtrl, SSIENR, 0x0); - - printf(" xfer : tx %d bytes, rx %d bytes\n",pPkg->txLen, pPkg->rxLen); - - if (pPkg->usDelay > 0) { - vxbUsDelay(pPkg->usDelay); - } - - if (pDrvCtrl->initPhase >= 2) { - semGive (pDrvCtrl->muxSem); - } - return sts; -} - -/* - * vxbFtSpiShow - show the controller info - * - * This function shows the SPI controller's info. - * - * RETURNS: N/A - * - * ERRNO: N/A - */ -LOCAL void vxbFtSpiShow(VXB_DEVICE_ID pDev,int verbose) -{ - FT_SPI_CTRL * pDrvCtrl; - - /* check for valid parameter */ - VXB_ASSERT_NONNULL_V (pDev); - - pDrvCtrl = (FT_SPI_CTRL *) pDev->pDrvCtrl; - - printf (" %s unit %d on %s @ %p with busInfo %08p\n", - pDev->pName, - pDev->unitNumber, - vxbBusTypeString (pDev->busID), - pDev, - pDev->u.pSubordinateBus); - - if (verbose > 0) { - printf (" BAR0 @ 0x%08x (memory mapped)\n",pDev->pRegBase[0]); - printf (" pDrvCtrl @ 0x%08x\n", pDev->pDrvCtrl); - printf (" initPhase : %u\n", pDrvCtrl->initPhase); - printf (" clkFreq : %u\n", pDrvCtrl->clkFreq); - printf (" speed : %u\n", pDrvCtrl->speed); - printf (" bitWidth : %u\n", pDrvCtrl->dataWidth); - printf (" mode : %u\n", pDrvCtrl->mode); - printf (" spiDevNum : %u\n", pDrvCtrl->spiDevNum); - } -} - -/* - * vxbFtSpiInstUnlink - VxBus unlink handler - * - * This function shuts down a SPI controller instance in response to an - * an unlink event from VxBus. This may occur if our VxBus instance has - * been terminated, or if the SPI driver has been unloaded. - * - * RETURNS: OK if device was successfully destroyed, otherwise ERROR - * - * ERRNO: N/A - */ -LOCAL STATUS vxbFtSpiInstUnlink(VXB_DEVICE_ID pDev, void * unused) -{ - FT_SPI_CTRL * pDrvCtrl; - - /* check if the pDev pointer is valid */ - VXB_ASSERT (pDev != NULL, ERROR) - - pDrvCtrl = (FT_SPI_CTRL *) pDev->pDrvCtrl; - - /* - * The semaphore and interrupt resource are released here . The - * semaphore was created at phase 2 and interrupt was installed - * at phase 3. - */ - - if (pDrvCtrl->initPhase >= 2) { - (void)semTake (pDrvCtrl->muxSem, WAIT_FOREVER); - - (void) semDelete (pDrvCtrl->muxSem); - pDrvCtrl->muxSem = NULL; - } - -#ifndef _VXBUS_BASIC_HWMEMLIB - hwMemFree ((char *) pDrvCtrl); -#endif /* _VXBUS_BASIC_HWMEMLIB */ - - pDev->pDrvCtrl = NULL; - pDrvCtrl->initPhase = 0; - - return (OK); -} +/* vim: set ts=4 sw=4 et fdm=marker: */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include <../src/hwif/h/vxbus/vxbAccess.h> +#include +#include "vxbFtSpi.h" +#include "ft2000-4.h" + +/* offset map of SPI register */ +/* clang-format off */ +#define FSPIM_CTRL_R0_OFFSET 0x00 /* Ctrl register 0 */ +#define FSPIM_CTRL_R1_OFFSET 0x04 /* Ctrl register 1 */ +#define FSPIM_SSIENR_OFFSET 0x08 /* SPI enable register */ +#define FSPIM_MWCR_OFFSET 0x0c /* Microwire ctrl register */ +#define FSPIM_SER_OFFSET 0x10 /* Slave enable register */ +#define FSPIM_BAUD_R_OFFSET 0x14 /* Baudrate set register */ +#define FSPIM_TXFTL_R_OFFSET 0x18 /* Tx threshold register */ +#define FSPIM_RXFTL_R_OFFSET 0x1c /* Rx threshold register */ +#define FSPIM_TXFLR_OFFSET 0x20 /* Tx level register */ +#define FSPIM_RXFLR_OFFSET 0x24 /* Rx level register */ +#define FSPIM_SR_OFFSET 0x28 /* Status register */ +#define FSPIM_IMR_OFFSET 0x2c /* Intr mask register */ +#define FSPIM_ISR_OFFSET 0x30 /* Irq Status register */ +#define FSPIM_RIS_R_OFFSET 0x34 /* Intr status register */ +#define FSPIM_TXOI_CR_OFFSET 0x38 /* TX FIFO overflow intr clear register */ +#define FSPIM_RXOI_CR_OFFSET 0x3c /* RX FIFO overflow intr clear register */ +#define FSPIM_RXUI_CR_OFFSET 0x40 /* TX FIFO underflow intr clear register */ +#define FSPIM_MSTI_CR_OFFSET 0x44 /* Multi slave intr clear register */ +#define FSPIM_ICR_OFFSET 0x48 /* Intr clear register */ +#define FSPIM_DMA_CR_OFFSET 0x4c /* DMA ctrl register */ +#define FSPIM_DMA_TDLR_OFFSET 0x50 /* DMA TX Data level register */ +#define FSPIM_DMA_RDLR_OFFSET 0x54 /* DMA RX Data level register */ +#define FSPIM_IDR_OFFSET 0x58 /* Identification register */ +#define FSPIM_DR_OFFSET 0x60 /* Data register */ +#define FSPIM_RX_SAMPLE_DLY_OFFSET 0xfc /* RX Data delay register */ +#define FSPIM_CS_OFFSET 0x100 /* Chip selection register */ + +#define FSPIM_SSIENR_SSI_EN(x) ((x) << 0) + +#define FSPIM_MIN_FIFO_DEPTH 0 +#define FSPIM_MAX_FIFO_DEPTH 256 +#define FSPIM_TIMEOUT 256 + +#define BITS_PER_LONG 32 +#define BITS_PER_WORD 32 +#define BIT(bitnum) (1 << (bitnum % BITS_PER_WORD)) + +#define min3(x, y, z) min((typeof(x))min(x, y), z) + +#define FSPIM_CHIP_SEL_EN(cs) BIT((cs) + SPI_MAX_CS_NUM) /* 1: enable chip selection */ +#define FSPIM_CHIP_SEL(cs) BIT(cs) +/* + CPOL = 0, CPHA = 0, sample at the first rising edge + CPOL = 1, CPHA = 1, sample at the second rising edge + CPOL = 1, CPHA = 0, sample at the second falling edge + CPOL = 0, CPHA = 1, sample at the first falling edge +*/ +typedef enum { + FSPIM_CPOL_LOW = 0, /* pharse 0 CPOL=0 */ + FSPIM_CPOL_HIGH /* pharse 1 CPOL=1 */ +} FSpimCpolType; + +typedef enum { + FSPIM_CPHA_1_EDGE = 0, /* sample at the 1st edge, CPHA=0 */ + FSPIM_CPHA_2_EDGE /* sample at the 2nd edge, CPHA=1 */ +} FSpimCphaType; + +/* + * Create a contiguous bitmask starting at bit position @l and ending at + * position @h. For example + * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. + */ +#define GENMASK(h, l) \ + (((~0U) - (1U << (l)) + 1) & (~0U >> (BITS_PER_LONG - 1U - (h)))) + +#define GENMASK_ULL(h, l) \ + (((~0ULL) - (1ULL << (l)) + 1) & \ + (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h)))) + +/** @name FSPIM_CTRL_R0_OFFSET Register + */ +#define FSPIM_CTRL_R0_DFS_MASK GENMASK(3, 0) +#define FSPIM_CTRL_R0_DFS(x) (FSPIM_CTRL_R0_DFS_MASK & ((x) << 0)) /* data len */ +#define FSPIM_CTRL_R0_FRF(x) (GENMASK(5, 4) & ((x) << 4)) /* transfer mode */ +#define FSPIM_CTRL_R0_SCPHA(x) ((x) << 6) /* phrase & cpol */ +#define FSPIM_CTRL_R0_SCPHA_MASK BIT(6) + +enum { + FSPIM_SCPHA_SWITCH_DATA_MID = 0x0, + FSPIM_SCPHA_SWITCH_DATA_BEG = 0x1 +}; +#define FSPIM_CTRL_R0_SCPOL(x) ((x) << 7) /* cpol */ +#define FSPIM_CTRL_R0_SCPOL_MASK BIT(7) + +enum { + FSPIM_SCPOL_INACTIVE_LOW = 0, + FSPIM_SCPOL_INACTIVE_HIGH = 1 +}; +#define FSPIM_CTRL_R0_TMOD_MASK GENMASK(9, 8) +#define FSPIM_CTRL_R0_TMOD(x) (FSPIM_CTRL_R0_TMOD_MASK & ((x) << 8)) /* transfer mode bit */ +#define FSPIM_CTRL_R0_TMOD_SHIFT 8 + +enum { + FSPIM_TMOD_RX_TX = 0b00, + FSPIM_TMOD_TX_ONLY = 0b01, + FSPIM_TMOD_RX_ONLY = 0b10, + FSPIM_TMOD_RD_EEPROM = 0b11 +}; +#define FSPIM_CTRL_R0_SLV_OE(x) ((x) << 10) /* slaver enable */ +#define FSPIM_CTRL_R0_SLV_OE_MASK BIT(10) + +enum { + FSPIM_SRL_NORAML = 0, + FSPIM_SRL_TEST = 1 +}; +#define FSPIM_CTRL_R0_CFS(x) (GENMASK(15, 12) & ((x) << 12)) /* data size in Microwire mode */ +enum { + FSPIM_SLAVE_TX_ENABLE = 0, + FSPIM_SLAVE_TX_DISALE = 1 +}; +#define FSPIM_CTRL_R0_SLV_SRL(x) ((x) << 11) /* shift regiter loopback */ + +/** @name FSPIM_IMR_OFFSET Register + */ +#define FSPIM_IMR_TXEIS BIT(0) /* tx FIFO empty */ +#define FSPIM_IMR_TXOIS BIT(1) /* tx FIFO overflow */ +#define FSPIM_IMR_RXUIS BIT(2) /* rx FIFO underflow */ +#define FSPIM_IMR_RXOIS BIT(3) /* rx FIFO overflow */ +#define FSPIM_IMR_RXFIS BIT(4) /* rx FIFO full */ +#define FSPIM_IMR_ALL_BITS GENMASK(4, 0) + +typedef enum { + FSPIM_TRANS_MODE_RX_TX = 0x0, + FSPIM_TRANS_MODE_TX_ONLY = 0x1, + FSPIM_TRANS_MODE_RX_ONLY = 0x2, + FSPIM_TRANS_MODE_READ_EEPROM = 0x3, + FSPIM_TRANS_MODE_MAX +} FSpimTransMode; + +/** @name FSPIM_SER_OFFSET Register + */ +#define FSPIM_SER(x) (GENMASK(3, 0) & ((x) << 0)) /* slave flag */ +/* bit map to SPI slave's cs (ss_x_n]). when bit == 1, start transfering */ +enum { + FSPIM_SER_UNSELECT = 0x0, + FSPIM_SER_SELECT = 0x1 +}; + +typedef enum { + FSPIM_SLAVE_DEV_0 = 0, + FSPIM_SLAVE_DEV_1, + FSPIM_SLAVE_DEV_2, + FSPIM_SLAVE_DEV_3, + + FSPIM_NUM_OF_SLAVE_DEV +} FSpimSlaveDevice; + +/** @name FSPIM_DR_OFFSET Register + */ +#define FSPIM_DR(x) (GENMASK(15, 0) & ((x) << 0)) /* data register */ +/* clang-format on */ + +/* debug macro */ +#undef SPI_DBG_ON +#ifdef SPI_DBG_ON + +#undef LOCAL +#define LOCAL + +#define SPI_DBG_OFF 0x00000000 +#define SPI_DBG_ISR 0x00000001 +#define SPI_DBG_RW 0x00000002 +#define SPI_DBG_ERR 0x00000004 +#define SPI_DBG_RTN 0x00000008 +#define SPI_DBG_INFO 0x00000010 +#define SPI_DBG_ALL 0xffffffff + +LOCAL UINT32 spiDbgMask = SPI_DBG_ALL; +IMPORT FUNCPTR _func_logMsg; + +#define SPI_DBG(mask, string, X1, X2, X3, X4, X5, X6) \ + if ((spiDbgMask & mask) || (mask == SPI_DBG_ALL)) \ + if (_func_logMsg != NULL) \ + (*_func_logMsg)(string, (int)X1, (int)X2, (int)X3, (int)X4, (int)X5, (int)X6) +#else +#define SPI_DBG(mask, string, X1, X2, X3, X4, X5, X6) +#endif /* SPI_DBG_ON */ + +#if _BYTE_ORDER == _BIG_ENDIAN +#define SPI_REG_HANDLE_SWAP(x) VXB_HANDLE_SWAP(x) +#else +#define SPI_REG_HANDLE_SWAP(x) (x) +#endif /* _BYTE_ORDER == _BIG_ENDIAN */ + +/* read write macros */ +#define VXB_FT_SPI_REG(pChan, reg) (UINT32 *)((UINT32)((pChan)->regBase) + (reg)) + +#define VXB_FT_SPI_REG16(pChan, reg) (UINT16 *)((UINT32)((pChan)->regBase) + (reg)) + +#define VXB_FT_SPI_REG8(pChan, reg) (UINT8 *)((UINT32)((pChan)->regBase) + (reg)) + +#define VXB_FT_SPI_REG_READ(pChan, reg, result) (result) = vxbRead32((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) + +#define VXB_FT_SPI_REG_WRITE(pChan, reg, data) vxbWrite32((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg), (data)) + +#define VXB_FT_SPI_REG_BIT_SET(pChan, reg, data) \ + VXB_FT_SPI_REG_WRITE(pChan, reg, vxbRead32((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) | (data)) + +#define VXB_FT_SPI_REG_BIT_CLR(pChan, reg, data) \ + VXB_FT_SPI_REG_WRITE(pChan, reg, vxbRead32((pChan)->regHandle, VXB_FT_SPI_REG(pChan, reg)) & (~(data))) + +/* VxBus methods */ +LOCAL void vxbFtSpiInstInit(VXB_DEVICE_ID pDev); +LOCAL void vxbFtSpiInstInit2(VXB_DEVICE_ID pDev); +LOCAL void vxbFtSpiInstConnect(VXB_DEVICE_ID pDev); +LOCAL VXB_SPI_BUS_CTRL *vxbFtSpiCtrlGet(VXB_DEVICE_ID pDev); +LOCAL void vxbFtSpiShow(VXB_DEVICE_ID, int); +LOCAL STATUS vxbFtSpiInstUnlink(VXB_DEVICE_ID pDev, void *unused); + +/* forward declarations */ +LOCAL void vxbFtSpiCtrlInit(VXB_DEVICE_ID pDev); + +LOCAL STATUS vxbFtSpiTransfer(VXB_DEVICE_ID pDev, SPI_HARDWARE *pSpiDev, SPI_TRANSFER *pPkg); +/* locals */ +LOCAL struct drvBusFuncs vxbFtSpiVxbFuncs = { + vxbFtSpiInstInit, /* devInstanceInit */ + vxbFtSpiInstInit2, /* devInstanceInit2 */ + vxbFtSpiInstConnect /* devConnect */ +}; + +LOCAL device_method_t vxbFtSpiDeviceMethods[] = { DEVMETHOD(vxbSpiControlGet, vxbFtSpiCtrlGet), + DEVMETHOD(busDevShow, vxbFtSpiShow), + DEVMETHOD(vxbDrvUnlink, vxbFtSpiInstUnlink), DEVMETHOD_END }; + +LOCAL struct vxbPlbRegister vxbFtSpiDevRegistration = { + { + NULL, /* pNext */ + VXB_DEVID_DEVICE, /* devID */ + VXB_BUSID_PLB, /* busID = PLB */ + VXB_VER_4_0_0, /* vxbVersion */ + FT_SPI_NAME, /* drvName */ + &vxbFtSpiVxbFuncs, /* pDrvBusFuncs */ + &vxbFtSpiDeviceMethods[0], /* pMethods */ + NULL, /* devProbe */ + NULL, /* pParamDefaults */ + }, +}; + +/* + * vxbFtSpiRegister - register with the VxBus subsystem + * + * This routine registers the SPI driver with VxBus Systems. + * + * RETURNS: N/A + * + * ERRNO: N/A + */ +void vxbFtSpiRegister(void) +{ + vxbDevRegister((struct vxbDevRegInfo *)&vxbFtSpiDevRegistration); +} + +/* + * vxbFtSpiInstInit - initialize SPI controller + * + * This function implements the VxBus instInit handler for a SPI controller + * device instance. + * + * Initialize the device by the following: + * + * - retrieve the resource from the hwconf + * - per-device init + * - announce SPI Bus and create device instance + * + * RETURNS: N/A + * + * ERRNO: N/A + */ +LOCAL void vxbFtSpiInstInit(VXB_DEVICE_ID pDev) +{ + FT_SPI_CTRL *pDrvCtrl; + struct hcfDevice *pHcf; + int i; + + /* check for valid parameter */ + VXB_ASSERT_NONNULL_V(pDev); + + /* create controller driver context structure for core */ + pDrvCtrl = (FT_SPI_CTRL *)hwMemAlloc(sizeof(FT_SPI_CTRL)); + if (pDrvCtrl == NULL) { + return; + } + pDev->pDrvCtrl = pDrvCtrl; + pDrvCtrl->pDev = pDev; + + for (i = 0; i < VXB_MAXBARS; i++) { + if (pDev->regBaseFlags[i] == VXB_REG_MEM) { + break; + } + } + if (i == VXB_MAXBARS) { +#ifndef _VXBUS_BASIC_HWMEMLIB + hwMemFree((char *)pDrvCtrl); +#endif + pDev->pDrvCtrl = NULL; + return; + } + pDrvCtrl->regBase = pDev->pRegBase[i]; + vxbRegMap(pDev, i, &pDrvCtrl->regHandle); + pDrvCtrl->regHandle = (void *)SPI_REG_HANDLE_SWAP((ULONG)pDrvCtrl->regHandle); + pHcf = (struct hcfDevice *)hcfDeviceGet(pDev); + if (pHcf == NULL) { +#ifndef _VXBUS_BASIC_HWMEMLIB + hwMemFree((char *)pDrvCtrl); +#endif + pDev->pDrvCtrl = NULL; + return; + } + + if (devResourceGet(pHcf, "clkFreq", HCF_RES_INT, (void *)&pDrvCtrl->clkFreq) != OK) { + pDrvCtrl->clkFreq = FT2000_SPI_CLK; + } + + if (devResourceGet(pHcf, "speed", HCF_RES_INT, (void *)&pDrvCtrl->speed) != OK) { + pDrvCtrl->speed = 1000000; + } + + if (devResourceGet(pHcf, "mode", HCF_RES_INT, (void *)&pDrvCtrl->mode) != OK) { + pDrvCtrl->mode = 0; + } + + if (devResourceGet(pHcf, "dataWidth", HCF_RES_INT, (void *)&pDrvCtrl->dataWidth) != OK) { + pDrvCtrl->dataWidth = 8; + } + + if (devResourceGet(pHcf, "loopback", HCF_RES_INT, (void *)&pDrvCtrl->en_test) != OK) { + pDrvCtrl->en_test = 0; + } + + if (devResourceGet(pHcf, "txFifoLen", HCF_RES_INT, (void *)&pDrvCtrl->tx_fifo_len) != OK) { + pDrvCtrl->tx_fifo_len = 0; + } + + if (devResourceGet(pHcf, "rxFifoLen", HCF_RES_INT, (void *)&pDrvCtrl->rx_fifo_len) != OK) { + pDrvCtrl->rx_fifo_len = 0; + } + + if (devResourceGet(pHcf, "spiDevNum", HCF_RES_INT, (void *)&pDrvCtrl->spiDevNum) != OK) { + pDrvCtrl->spiDevNum = 0; + } + + pDrvCtrl->cs = 0; + + vxbFtSpiCtrlInit(pDev); + + pDrvCtrl->vxbSpiCtrl.spiTransfer = (void *)vxbFtSpiTransfer; + + /* announce that there's a SPI bus */ + (void)vxbBusAnnounce(pDev, VXB_BUSID_SPI); + + /* notify the bus subsystem of all devices on SPI */ + (void)spiBusAnnounceDevices(pDev); + + pDrvCtrl->initPhase = 1; +} + +/* + * vxbFtSpiInstInit2 - second level initialization routine of SPI controller + * + * This routine performs the second level initialization of the SPI controller. + * + * RETURNS: N/A + * + * ERRNO: N/A + */ +LOCAL void vxbFtSpiInstInit2(VXB_DEVICE_ID pDev) +{ + FT_SPI_CTRL *pDrvCtrl; + + /* check for valid parameter */ + + VXB_ASSERT_NONNULL_V(pDev); + + pDrvCtrl = (FT_SPI_CTRL *)pDev->pDrvCtrl; + + /* used for mutex accessing of the controller */ + pDrvCtrl->muxSem = semMCreate(SEM_Q_PRIORITY); + + if (pDrvCtrl->muxSem == NULL) { + SPI_DBG(SPI_DBG_ERR, "semMCreate failed for muxSem\n", 0, 0, 0, 0, 0, 0); + return; + } + + pDrvCtrl->initPhase = 2; +} + +/* + * vxbFtSpiInstConnect - third level initialization + * + * This routine performs the third level initialization of the QSPI controller + * driver. + * + * RETURNS: N/A + * + * ERRNO : N/A + */ +LOCAL void vxbFtSpiInstConnect(VXB_DEVICE_ID pDev) +{ + FT_SPI_CTRL *pDrvCtrl; + + pDrvCtrl = pDev->pDrvCtrl; + pDrvCtrl->initPhase = 3; +} + +/* + * vxbFtSpiCtrlGet - get the SPI controller struct + * + * This routine returns the QSPI controller struct pointer (VXB_SPI_BUS_CTRL *) + * to caller (SPI Lib) by vxbSpiControlGet method. Currently, this struct + * only contain the spiTransfer routine(eg: vxbFtQspiTransfer) for SPI Lib, + * other parameters can be easily added in this struct. + * + * RETURNS: the pointer of SPI controller struct + * + * ERRNO: N/A + */ +LOCAL VXB_SPI_BUS_CTRL *vxbFtSpiCtrlGet(VXB_DEVICE_ID pDev) +{ + FT_SPI_CTRL *pDrvCtrl; + + /* check if the pDev pointer is valid */ + VXB_ASSERT(pDev != NULL, NULL) + + pDrvCtrl = (FT_SPI_CTRL *)pDev->pDrvCtrl; + + SPI_DBG(SPI_DBG_RTN, "vxbFtQspiCtrlGet(0x08%x) called\n", (_Vx_usr_arg_t)pDev, 2, 3, 4, 5, 6); + + return (&(pDrvCtrl->vxbSpiCtrl)); +} + +/* {{{ SPI functions */ +static inline void FSpimSetEnable(FT_SPI_CTRL *pDrvCtrl, int enable) +{ + if (enable) { + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_SSIENR_OFFSET, FSPIM_SSIENR_SSI_EN(1)); + } else { + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_SSIENR_OFFSET, FSPIM_SSIENR_SSI_EN(0)); + } +} + +static inline void FSpimSetCtrlR0(FT_SPI_CTRL *pDrvCtrl, UINT32 val) +{ + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_CTRL_R0_OFFSET, val); +} + +static inline UINT32 FSpimGetCtrlR0(FT_SPI_CTRL *pDrvCtrl) +{ + UINT32 reg = 0; + VXB_FT_SPI_REG_READ(pDrvCtrl, FSPIM_CTRL_R0_OFFSET, reg); + + return reg; +} + +static inline void FSpimSetTxFifoThreshold(FT_SPI_CTRL *pDrvCtrl, UINT32 val) +{ + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_TXFTL_R_OFFSET, val); +} + +static inline UINT32 FSpimGetTxFifoThreshold(FT_SPI_CTRL *pDrvCtrl) +{ + UINT32 reg = 0; + VXB_FT_SPI_REG_READ(pDrvCtrl, FSPIM_TXFTL_R_OFFSET, reg); + + return reg; +} + +static inline void FSpimSetRxFifoThreshold(FT_SPI_CTRL *pDrvCtrl, UINT32 val) +{ + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_RXFTL_R_OFFSET, val); +} + +static inline UINT32 FSpimGetRxFifoThreshold(FT_SPI_CTRL *pDrvCtrl) +{ + UINT32 reg = 0; + VXB_FT_SPI_REG_READ(pDrvCtrl, FSPIM_RXFTL_R_OFFSET, reg); + + return reg; +} + +static inline void FSpimMaskIrq(FT_SPI_CTRL *pDrvCtrl, UINT32 mask) +{ + UINT32 curr_mask = 0; + + VXB_FT_SPI_REG_READ(pDrvCtrl, FSPIM_IMR_OFFSET, curr_mask); + + curr_mask = curr_mask & ~mask; /* = 0 interrupt inactive */ + + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_IMR_OFFSET, curr_mask); +} + +static inline void FSpimWriteData(FT_SPI_CTRL *pDrvCtrl, UINT16 dat) +{ + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_DR_OFFSET, FSPIM_DR(dat)); +} + +static inline UINT16 FSpimReadData(FT_SPI_CTRL *pDrvCtr) +{ + UINT32 reg; + + VXB_FT_SPI_REG_READ(pDrvCtr, FSPIM_DR_OFFSET, reg); + + return (UINT16)(reg); +} + +static void FSpimSetCpha(FT_SPI_CTRL *pDrvCtrl, UINT32 cpha_mode) +{ + UINT32 reg_val = FSpimGetCtrlR0(pDrvCtrl); + + reg_val &= ~FSPIM_CTRL_R0_SCPHA_MASK; /* clear bits */ + if (FSPIM_CPHA_1_EDGE == cpha_mode) { + reg_val |= FSPIM_CTRL_R0_SCPHA(FSPIM_SCPHA_SWITCH_DATA_MID); + } else if (FSPIM_CPHA_2_EDGE == cpha_mode) { + reg_val |= FSPIM_CTRL_R0_SCPHA(FSPIM_SCPHA_SWITCH_DATA_BEG); + } else { + SPI_DBG(SPI_DBG_RTN, "FSpimSetCpha(0x08%x) Warning chpa\n", (_Vx_usr_arg_t)pDev, 2, 3, 4, 5, 6); + } + + FSpimSetCtrlR0(pDrvCtrl, reg_val); +} + +static inline int FSpimGetEnable(FT_SPI_CTRL *pDrvCtrl) +{ + UINT32 reg = 0; + VXB_FT_SPI_REG_READ(pDrvCtrl, FSPIM_SSIENR_OFFSET, reg); + + return reg; +} + +static void FSpimSetCpol(FT_SPI_CTRL *pDrvCtrl, UINT32 cpol_mode) +{ + UINT32 reg_val = FSpimGetCtrlR0(pDrvCtrl); + + reg_val &= ~FSPIM_CTRL_R0_SCPOL_MASK; /* clear bits */ + if (FSPIM_CPOL_LOW == cpol_mode) { + reg_val |= FSPIM_CTRL_R0_SCPOL(FSPIM_SCPOL_INACTIVE_LOW); + } else if (FSPIM_CPOL_HIGH == cpol_mode) { + reg_val |= FSPIM_CTRL_R0_SCPOL(FSPIM_SCPOL_INACTIVE_HIGH); + } else { + SPI_DBG(SPI_DBG_RTN, "FSpimSetCpol(0x08%x) Warning Cpol\n", (_Vx_usr_arg_t)pDrvCtrl, 2, 3, 4, 5, 6); + } + + FSpimSetCtrlR0(pDrvCtrl, reg_val); +} + +static void FSpimSetSlaveEnable(FT_SPI_CTRL *pDrvCtrl, int enable) +{ + UINT32 reg_val; + int enabled = FSpimGetEnable(pDrvCtrl); + + if (enabled) { + FSpimSetEnable(pDrvCtrl, FALSE); + } + + reg_val = FSpimGetCtrlR0(pDrvCtrl); + + reg_val &= ~FSPIM_CTRL_R0_SLV_OE_MASK; + if (enable) { + reg_val |= FSPIM_CTRL_R0_SLV_OE(FSPIM_SLAVE_TX_ENABLE); + } else { + reg_val |= FSPIM_CTRL_R0_SLV_OE(FSPIM_SLAVE_TX_DISALE); + } + + FSpimSetCtrlR0(pDrvCtrl, reg_val); + + if (enabled) { + FSpimSetEnable(pDrvCtrl, TRUE); + } + + return; +} + +static void FSpimSetTransMode(FT_SPI_CTRL *pDrvCtr, UINT32 trans_mode) +{ + UINT32 reg_val; + int enabled = FSpimGetEnable(pDrvCtr); + + if (trans_mode > FSPIM_TRANS_MODE_MAX) { + return; + } + + if (enabled) { + FSpimSetEnable(pDrvCtr, FALSE); + } + + reg_val = FSpimGetCtrlR0(pDrvCtr); + reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK; /* clear trans mode bits */ + switch (trans_mode) { + case FSPIM_TRANS_MODE_RX_TX: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + break; + case FSPIM_TRANS_MODE_TX_ONLY: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_TX_ONLY); + break; + case FSPIM_TRANS_MODE_RX_ONLY: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY); + break; + case FSPIM_TRANS_MODE_READ_EEPROM: + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RD_EEPROM); + break; + default: + return; + break; + } + + FSpimSetCtrlR0(pDrvCtr, reg_val); + + if (enabled) { + FSpimSetEnable(pDrvCtr, TRUE); + } + + return; +} + +static void FSpimSelSlaveDev(FT_SPI_CTRL *pDrvCtr, UINT32 slave_dev_id) +{ + UINT32 reg_val; + + if (slave_dev_id >= SPI_MAX_CS_NUM) { + return; + } + + reg_val = (FSPIM_SER_SELECT << slave_dev_id); + + VXB_FT_SPI_REG_WRITE(pDrvCtr, FSPIM_SER_OFFSET, reg_val); +} + +static UINT32 FSpimGetTxFifoDepth(FT_SPI_CTRL *pDrvCtr) +{ + UINT32 fifo_depth; + + for (fifo_depth = 1; fifo_depth < FSPIM_MAX_FIFO_DEPTH; fifo_depth++) { + FSpimSetTxFifoThreshold(pDrvCtr, fifo_depth); /* try until failed */ + if (fifo_depth != FSpimGetTxFifoThreshold(pDrvCtr)) { + SPI_DBG(SPI_DBG_RTN, "The Tx fifo threshold is %d", fifo_depth, 2, 3, 4, 5, 6); + break; + } + } + + FSpimSetTxFifoThreshold(pDrvCtr, 0); + return fifo_depth; +} + +static UINT32 FSpimGetRxFifoDepth(FT_SPI_CTRL *pDrvCtr) +{ + UINT32 fifo_depth = FSPIM_MIN_FIFO_DEPTH; + + while (FSPIM_MAX_FIFO_DEPTH >= fifo_depth) { + FSpimSetRxFifoThreshold(pDrvCtr, fifo_depth); + if (fifo_depth != FSpimGetRxFifoThreshold(pDrvCtr)) { + SPI_DBG(SPI_DBG_RTN, "The Rx fifo threshold is %d", fifo_depth, 2, 3, 4, 5, 6); + break; + } + + fifo_depth++; + } + + return fifo_depth; +} + +static int FSpimSetSpeed(FT_SPI_CTRL *pDrvCtr, UINT32 clk_freq) +{ + UINT32 clk_div; + + if (clk_freq == 0) { + printf("Input spi clock frequency is %d => do not support, this parameter should not be 0.", clk_freq); + return -1; + } else { + clk_div = pDrvCtr->clkFreq / clk_freq; + } + + if ((clk_div >= 2) && (clk_div <= 65534)) { + if ((clk_div % 2) != 0) { + clk_div += 1; + } + + FSpimSetEnable(pDrvCtr, FALSE); + SPI_DBG(SPI_DBG_RTN, "Set spi clock divider as %d", clk_div, 2, 3, 4, 5, 6); + VXB_FT_SPI_REG_WRITE(pDrvCtr, FSPIM_BAUD_R_OFFSET, clk_div); + FSpimSetEnable(pDrvCtr, TRUE); + return 0; + } else { + printf( + "Input spi clock frequency is %ld, this parameter be set wrong. spi clock divider = %d, this parameter should be an even from 2 to 65534.", + clk_freq, clk_div); + return -2; + } +} + +void FSpimSetChipSelection(FT_SPI_CTRL *pDrvCtr, int on) +{ + UINT32 reg_val; + FSpimSlaveDevice cs_n = pDrvCtr->cs; + + VXB_FT_SPI_REG_READ(pDrvCtr, FSPIM_CS_OFFSET, reg_val); + + if (on) { + reg_val |= FSPIM_CHIP_SEL_EN((UINT32)cs_n); + reg_val |= FSPIM_CHIP_SEL((UINT32)cs_n); + } else { + reg_val &= ~FSPIM_CHIP_SEL_EN((UINT32)cs_n); + reg_val &= ~FSPIM_CHIP_SEL((UINT32)cs_n); + } + + VXB_FT_SPI_REG_WRITE(pDrvCtr, FSPIM_CS_OFFSET, reg_val); + + return; +} + +static UINT32 FSpimGetTxRound(FT_SPI_CTRL *pDrvCtr) +{ + UINT32 data_width = pDrvCtr->dataWidth >> 3; + UINT32 tx_left_round, tx_fifo_room, rx_tx_gap; + UINT32 lvl = 0; + + tx_left_round = (UINT32)(pDrvCtr->length - pDrvCtr->tx_count) / data_width; + + VXB_FT_SPI_REG_READ(pDrvCtr, FSPIM_TXFLR_OFFSET, lvl); + + tx_fifo_room = pDrvCtr->tx_fifo_len - lvl; + + rx_tx_gap = + ((UINT32)(pDrvCtr->length - pDrvCtr->rx_count) - (UINT32)(pDrvCtr->length - pDrvCtr->tx_count)) / data_width; + + SPI_DBG(SPI_DBG_RTN, "tx_left_round: %d, tx_fifo_room: %d, gap: %d, instance_p->tx_count: %ld", tx_left_round, + tx_fifo_room, ((UINT32)(pDrvCtr->tx_fifo_len) - rx_tx_gap), pDrvCtr->tx_count, 5, 6); + return min3(tx_left_round, tx_fifo_room, ((UINT32)(pDrvCtr->tx_fifo_len) - rx_tx_gap)); +} + +static void FSpimFifoTx(FT_SPI_CTRL *pDrvCtr) +{ + UINT32 tx_round = FSpimGetTxRound(pDrvCtr); + UINT32 data_width = pDrvCtr->dataWidth >> 3; + UINT16 data = 0; + + if (2 == data_width) { + data = 0xffff; + } else { + data = 0xff; + } + + while (tx_round) { + if (pDrvCtr->tx_buff) { + if (1 == data_width) { + /* + * Data Transfer Width is Byte (8 bit). + */ + data = *(UINT8 *)(pDrvCtr->tx_buff); + } else if (2 == data_width) { + /* + * Data Transfer Width is Half Word (16 bit). + */ + data = *(UINT16 *)(pDrvCtr->tx_buff); + } + + pDrvCtr->tx_buff += data_width; + } + pDrvCtr->tx_count += data_width; + FSpimWriteData(pDrvCtr, data); + SPI_DBG(SPI_DBG_RTN, " send 0x%x", data, 2, 3, 4, 5, 6); + tx_round--; + } +} + +static UINT32 FSpimGetRxRound(FT_SPI_CTRL *pDrvCtr) +{ + UINT32 data_width = pDrvCtr->dataWidth >> 3; + UINT32 lvl = 0; + UINT32 rx_left_round = (UINT32)(pDrvCtr->length - pDrvCtr->rx_count) / data_width; + + VXB_FT_SPI_REG_READ(pDrvCtr, FSPIM_RXFLR_OFFSET, lvl); + + SPI_DBG(SPI_DBG_RTN, "left round %d, rx level %d,instance_p->rx_count %ld", rx_left_round, lvl, pDrvCtr->rx_count, + 4, 5, 6); + return min(rx_left_round, lvl); +} + +static void FSpimFifoRx(FT_SPI_CTRL *pDrvCtr) +{ + UINT32 rx_round = FSpimGetRxRound(pDrvCtr); + UINT32 data_width = pDrvCtr->dataWidth >> 3; + UINT16 data; + + while (rx_round) { + data = FSpimReadData(pDrvCtr); + if (pDrvCtr->rx_buff) { + if (1 == data_width) { + /* + * Data Transfer Width is Byte (8 bit). + */ + *(UINT8 *)(pDrvCtr->rx_buff) = (UINT8)data; + SPI_DBG(SPI_DBG_RTN, " recv 0x%x", *(UINT8 *)(pDrvCtr->rx_buff), 2, 3, 4, 5, 6); + } else if (2 == data_width) { + /* + * Data Transfer Width is Half Word (16 bit). + */ + *(UINT16 *)(pDrvCtr->rx_buff) = (UINT16)data; + SPI_DBG(SPI_DBG_RTN, " recv 0x%x", *(u16 *)(pDrvCtr->rx_buff), 2, 3, 4, 5, 6); + } + pDrvCtr->rx_buff += data_width; + } + pDrvCtr->rx_count += data_width; + rx_round--; + } +} + +static void FSpimTransferPollFifo(FT_SPI_CTRL *pDrvCtr, const void *tx_buf, void *rx_buf, UINT32 len) +{ + UINT32 reg_val; + UINT32 data_width = pDrvCtr->dataWidth; + + SPI_DBG(SPI_DBG_RTN, "buff address rx= %x, tx=%x\r\n", rx_buf, tx_buf, 3, 4, 5, 6); + + FSpimSetEnable(pDrvCtr, FALSE); + + reg_val = FSpimGetCtrlR0(pDrvCtr); + + reg_val &= ~FSPIM_CTRL_R0_DFS_MASK; + reg_val |= FSPIM_CTRL_R0_DFS(data_width - 1); + + reg_val &= ~FSPIM_CTRL_R0_TMOD_MASK; + if (tx_buf && rx_buf) { + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } else if (rx_buf) { + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_ONLY); + } else { + reg_val |= FSPIM_CTRL_R0_TMOD(FSPIM_TMOD_RX_TX); + } + + FSpimSetCtrlR0(pDrvCtr, reg_val); + + FSpimMaskIrq(pDrvCtr, FSPIM_IMR_ALL_BITS); + + pDrvCtr->tx_count = 0; + pDrvCtr->rx_count = 0; + pDrvCtr->length = len; + pDrvCtr->tx_buff = tx_buf; + pDrvCtr->rx_buff = rx_buf; + + SPI_DBG(SPI_DBG_RTN, "tx buff@%p-%d, rx buff@%p-%d", pDrvCtr->tx_buff, len, pDrvCtr->rx_buff, len, 5, 6); + + FSpimSetEnable(pDrvCtr, TRUE); + do { + FSpimFifoTx(pDrvCtr); + FSpimFifoRx(pDrvCtr); + } while (pDrvCtr->tx_count < len || pDrvCtr->rx_count < len); +} + +/* }}} */ + +/* + * vxbFtSpiCtrlInit - SPI controller initialization + * + * This routine performs the SPI controller initialization. + * + * RETURNS: N/A + * + * ERRNO: N/A + */ +LOCAL void vxbFtSpiCtrlInit(VXB_DEVICE_ID pDev) +{ + FT_SPI_CTRL *pDrvCtrl; + UINT32 reg_val, fifo; + STATUS ret; + + pDrvCtrl = (FT_SPI_CTRL *)pDev->pDrvCtrl; + + /* disable controller */ + FSpimSetEnable(pDrvCtrl, FALSE); + + /* data frame format */ + reg_val = FSPIM_CTRL_R0_DFS(pDrvCtrl->dataWidth - 1) | FSPIM_CTRL_R0_FRF(FSPIM_DEFAULT_FRF) | + FSPIM_CTRL_R0_CFS(FSPIM_DEFAULT_CFS); + + if (pDrvCtrl->en_test) { + reg_val |= FSPIM_CTRL_R0_SLV_SRL(FSPIM_SRL_TEST); /* loopback */ + } else { + reg_val |= FSPIM_CTRL_R0_SLV_SRL(FSPIM_SRL_NORAML); /* normal */ + } + + FSpimSetCtrlR0(pDrvCtrl, reg_val); + + /* phrase and polarity + * spi mode mapping: + * + * CPOL CPHA + * 0 0 mode 0 + * 0 1 mode 1 + * 1 0 mode 2 + * 1 1 mode 3 + */ + FSpimSetCpha(pDrvCtrl, pDrvCtrl->mode & 0x1); + FSpimSetCpol(pDrvCtrl, (pDrvCtrl->mode & 0x2) >> 1); + + /* transfer mode */ + FSpimSetTransMode(pDrvCtrl, FSPIM_TRANS_MODE_RX_TX); + + /* disable slave output */ + FSpimSetSlaveEnable(pDrvCtrl, FALSE); + + /* disable interrup*/ + FSpimMaskIrq(pDrvCtrl, FSPIM_IMR_ALL_BITS); + FSpimSelSlaveDev(pDrvCtrl, pDrvCtrl->cs); + + /* query SPI RX/TX FIFO depth */ + if (0 == pDrvCtrl->tx_fifo_len) { + fifo = FSpimGetTxFifoDepth(pDrvCtrl); /* fifo depth */ + pDrvCtrl->tx_fifo_len = fifo; + SPI_DBG(SPI_DBG_RTN, "The fifo depth is %d ,tx effective length bits %d", fifo, pDrvCtrl->tx_fifo_len, 3, 4, 5, + 6); + } + + if (0 == pDrvCtrl->rx_fifo_len) { + fifo = FSpimGetRxFifoDepth(pDrvCtrl); + pDrvCtrl->rx_fifo_len = fifo; + SPI_DBG(SPI_DBG_RTN, "The fifo depth is %d ,rx effective length bits %d", fifo, pDrvCtrl->rx_fifo_len, 3, 4, 5, + 6); + } + + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_DMA_CR_OFFSET, 0x0); /* disable ddma */ + + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_CTRL_R1_OFFSET, 0); + + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_DMA_RDLR_OFFSET, 0); + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_DMA_TDLR_OFFSET, 0); + + FSpimSetRxFifoThreshold(pDrvCtrl, 0); + FSpimSetTxFifoThreshold(pDrvCtrl, 0); + + ret = FSpimSetSpeed(pDrvCtrl, pDrvCtrl->speed); + if (0 != ret) { + return; + } + + VXB_FT_SPI_REG_WRITE(pDrvCtrl, FSPIM_RX_SAMPLE_DLY_OFFSET, 0); +} + +/* + * vxbFtSpiTransfer - SPI transfer routine + * + * This routine is used to perform one transmission. It is the interface which + * can be called by SPI device driver to send and receive data via the QSPI + * controller. + * + * RETURNS: OK or ERROR + * + * ERRNO: N/A + */ +LOCAL STATUS vxbFtSpiTransfer(VXB_DEVICE_ID pDev, /* controller pDev */ + SPI_HARDWARE *pSpiDev, /* device info */ + SPI_TRANSFER *pPkg /* transfer data info */ +) +{ + STATUS sts = OK; + UINT32 alignSize; + FT_SPI_CTRL *pDrvCtrl; + /* check if the pointers are valid */ + + if (pDev == NULL || pSpiDev == NULL || pPkg == NULL || pSpiDev->devInfo == NULL) { + SPI_DBG(SPI_DBG_ERR, "vxbFtQspiTransfer NULL pointer\n", 1, 2, 3, 4, 5, 6); + return ERROR; + } + + pDrvCtrl = (FT_SPI_CTRL *)pDev->pDrvCtrl; + if (pDrvCtrl == NULL) { + SPI_DBG(SPI_DBG_ERR, "vxbFtQspiTransfer pDrvCtrl is NULL\n", 1, 2, 3, 4, 5, 6); + return ERROR; + } + + SPI_DBG(SPI_DBG_RTN, "vxbFtQspiTransfer txLen[%d] rxLen[%d]\n", pPkg->txLen, pPkg->rxLen, 3, 4, 5, 6); + + if (pPkg->txLen == 0 && pPkg->rxLen == 0) { + SPI_DBG(SPI_DBG_ERR, "vxbFtQspiTransfer tx and rx both are 0\n", 1, 2, 3, 4, 5, 6); + return ERROR; + } + + if ((pPkg->txLen != 0 && pPkg->txBuf == NULL) || (pPkg->rxLen != 0 && pPkg->rxBuf == NULL)) { + SPI_DBG(SPI_DBG_ERR, "vxbFtQspiTransfer invalid parameters[%x %x %x %x] \n", pPkg->txBuf, pPkg->txLen, + pPkg->rxLen, pPkg->rxBuf, 5, 6); + + return ERROR; + } + + if (pSpiDev->devInfo->bitWidth <= 8) { /* 4 to 8 bits */ + alignSize = sizeof(char); + } else if (pSpiDev->devInfo->bitWidth <= 16) { /* 9 to 16 bits */ + alignSize = sizeof(UINT16); + } else { /* 17 to 32 bits */ + SPI_DBG(SPI_DBG_ERR, "vxbFtQspiTransfer: data word length must between 2-16\n", 1, 2, 3, 4, 5, 6); + return ERROR; + } + + /* check to see if the address is aligned with SPI bit width */ + if ((pPkg->txLen != 0 && (((UINT32)pPkg->txBuf & (alignSize - 1)) != 0 || (pPkg->txLen & (alignSize - 1)) != 0)) || + (pPkg->rxLen != 0 && (((UINT32)pPkg->rxBuf & (alignSize - 1)) != 0 || (pPkg->rxLen & (alignSize - 1)) != 0))) { + SPI_DBG(SPI_DBG_ERR, + "vxbFtQspiTransfer address or len is not aligned:" + "[tx:%x-%x rx:%x-%x] with %d \n", + pPkg->txBuf, pPkg->txLen, pPkg->rxBuf, pPkg->rxLen, alignSize, 6); + + return ERROR; + } + + if (pSpiDev->devInfo->chipSelect >= SPI_MAX_CS_NUM) { + SPI_DBG(SPI_DBG_ERR, "vxbFtQspiTransfer invalid channel[%x] \n", pDrvCtrl->channel, 2, 3, 4, 5, 6); + + return ERROR; + } + + /* + * The controller can not be used by multichannel at the same time. + * If the initPhase < 2, there is no multi-task context. So, the + * semTake is not needed. + */ + if (pDrvCtrl->initPhase >= 2) { + (void)semTake(pDrvCtrl->muxSem, WAIT_FOREVER); + } + + /* reconfigure */ + if ((pSpiDev->devInfo->devFreq != pDrvCtrl->speed) || (pSpiDev->devInfo->mode != pDrvCtrl->mode) || + (pSpiDev->devInfo->chipSelect != pDrvCtrl->cs) || (pDrvCtrl->dataWidth != pSpiDev->devInfo->bitWidth)) { + pDrvCtrl->mode = pSpiDev->devInfo->mode; + pDrvCtrl->speed = pSpiDev->devInfo->devFreq; + pDrvCtrl->cs = pSpiDev->devInfo->chipSelect; + pDrvCtrl->dataWidth = pSpiDev->devInfo->bitWidth; + vxbFtSpiCtrlInit(pDev); + } + + FSpimSetEnable(pDrvCtrl, FALSE); + + /* FSpimSetChipSelection(pDrvCtrl, TRUE); */ + + FSpimTransferPollFifo(pDrvCtrl, pPkg->txBuf, pPkg->rxBuf, max(pPkg->txLen, pPkg->rxLen)); + +/* FSpimSetChipSelection(pDrvCtrl, FALSE); */ + + SPI_DBG(SPI_DBG_ERR," xfer : tx %d bytes, rx %d bytes\n", pPkg->txLen, pPkg->rxLen, 3, 4, 5, 6); + + if (pDrvCtrl->initPhase >= 2) { + semGive(pDrvCtrl->muxSem); + } + + if (pPkg->usDelay > 0) { + vxbUsDelay(pPkg->usDelay); + } + + return sts; +} + +/* + * vxbFtSpiShow - show the controller info + * + * This function shows the SPI controller's info. + * + * RETURNS: N/A + * + * ERRNO: N/A + */ +LOCAL void vxbFtSpiShow(VXB_DEVICE_ID pDev, int verbose) +{ + FT_SPI_CTRL *pDrvCtrl; + + /* check for valid parameter */ + VXB_ASSERT_NONNULL_V(pDev); + + pDrvCtrl = (FT_SPI_CTRL *)pDev->pDrvCtrl; + + printf(" %s unit %d on %s @ %p with busInfo %08p\n", pDev->pName, pDev->unitNumber, + vxbBusTypeString(pDev->busID), pDev, pDev->u.pSubordinateBus); + + if (verbose > 0) { + printf(" BAR0 @ 0x%08x (memory mapped)\n", pDev->pRegBase[0]); + printf(" pDrvCtrl @ 0x%08x\n", pDev->pDrvCtrl); + printf(" initPhase : %u\n", pDrvCtrl->initPhase); + printf(" clkFreq : %u\n", pDrvCtrl->clkFreq); + printf(" speed : %u\n", pDrvCtrl->speed); + printf(" bitWidth : %u\n", pDrvCtrl->dataWidth); + printf(" mode : %u\n", pDrvCtrl->mode); + printf(" txFifoLen : %u\n", pDrvCtrl->tx_fifo_len); + printf(" rxFifoLen : %u\n", pDrvCtrl->rx_fifo_len); + printf(" spiDevNum : %u\n", pDrvCtrl->spiDevNum); + } +} + +/* + * vxbFtSpiInstUnlink - VxBus unlink handler + * + * This function shuts down a SPI controller instance in response to an + * an unlink event from VxBus. This may occur if our VxBus instance has + * been terminated, or if the SPI driver has been unloaded. + * + * RETURNS: OK if device was successfully destroyed, otherwise ERROR + * + * ERRNO: N/A + */ +LOCAL STATUS vxbFtSpiInstUnlink(VXB_DEVICE_ID pDev, void *unused) +{ + FT_SPI_CTRL *pDrvCtrl; + + /* check if the pDev pointer is valid */ + VXB_ASSERT(pDev != NULL, ERROR) + + pDrvCtrl = (FT_SPI_CTRL *)pDev->pDrvCtrl; + + /* + * The semaphore and interrupt resource are released here . The + * semaphore was created at phase 2 and interrupt was installed + * at phase 3. + */ + + if (pDrvCtrl->initPhase >= 2) { + (void)semTake(pDrvCtrl->muxSem, WAIT_FOREVER); + + (void)semDelete(pDrvCtrl->muxSem); + pDrvCtrl->muxSem = NULL; + } + +#ifndef _VXBUS_BASIC_HWMEMLIB + hwMemFree((char *)pDrvCtrl); +#endif /* _VXBUS_BASIC_HWMEMLIB */ + + pDev->pDrvCtrl = NULL; + pDrvCtrl->initPhase = 0; + + return (OK); +} diff --git a/vxbFtSpi.h b/vxbFtSpi.h index 0980ae5..82f7c53 100644 --- a/vxbFtSpi.h +++ b/vxbFtSpi.h @@ -13,6 +13,8 @@ #define FT_SPI_NAME "ftSpi" #define SPI_MAX_CS_NUM 4 +#define FSPIM_DEFAULT_FRF 0 +#define FSPIM_DEFAULT_CFS 0 /* structure holding the instance specific details */ typedef struct _ft_spi_drv_ctrl { VXB_DEVICE_ID pDev; @@ -24,6 +26,13 @@ typedef struct _ft_spi_drv_ctrl { int dataWidth; int cs; UINT32 length; + UINT32 tx_fifo_len; + UINT32 rx_fifo_len; + UINT32 tx_count; + UINT32 rx_count; + const UINT8* tx_buff; + UINT8* rx_buff; + BOOL en_test; UINT32 spiDevNum; UINT32 initPhase; SEM_ID muxSem; diff --git a/vxbLfsLib.c b/vxbLfsLib.c index c1c0b98..1ad3935 100644 --- a/vxbLfsLib.c +++ b/vxbLfsLib.c @@ -1,3 +1,4 @@ +/* vim: set ts=4 sw=4 et fdm=marker: */ #include #include #include @@ -7,12 +8,508 @@ #include #include #include +#include #include #include #include #include #include - #include -#include "vxbSp25SpiFlash.h" +#include <../h/flash/vxbFlash.h> +#include <../h/flash/vxbFlashCommon.h> #include + +#if !defined(__DCC__) +#define LFS_THREADSAFE 1 +#include "lfs/lfs.c" +#include "lfs/lfs_util.c" +#endif + + +typedef struct __lfs_drv_ctrl lfsDrvCtrl; +typedef struct lfs_ios_drv lfsIosDrv; + +struct __lfs_file_descr { + union { + lfs_file_t file; + lfs_dir_t dir; + } u; + BOOL isDir; + lfsDrvCtrl *ctrl; +}; + +typedef struct __lfs_file_descr LFS_FILE_DESC; + +struct lfs_ios_drv { + DEV_HDR devHdr; + lfsDrvCtrl *pDrvCtrl; +}; + +struct __lfs_drv_ctrl { + VXB_DEVICE_ID pDev; + /* per-driver info */ + void *pDrvCtrl; + const char *mountPoint; + + const char *flashDrvName; + int flashUnit; + + UINT32 flashOffset; + UINT32 flashSize; + UINT32 pageSize; + + UINT32 blkNum; + + int lfsDrvNum; + + lfsIosDrv lfsDrv; + FLASH_CHIP_ID mtd; + + struct lfs_config lfsConfig; + + SEM_ID lock; + lfs_t fsh; +}; + +/* {{{ lfsDevFuncs */ +LOCAL void lfsDevInstInit(VXB_DEVICE_ID pDev) +{ + lfsDrvCtrl *drv; + struct hcfDevice *pHcf; + + drv = (lfsDrvCtrl *)hwMemAlloc(sizeof(*drv)); + if (drv == NULL) { + return; + } + drv->pDrvCtrl = pDev; + pDev->pDrvCtrl = drv; + + drv->mtd = NULL; + + pHcf = (struct hcfDevice *)hcfDeviceGet(pDev); + if (pHcf == NULL) { +#ifndef _VXBUS_BASIC_HWMEMLIB + hwMemFree((char *)drv); +#endif /* _VXBUS_BASIC_HWMEMLIB */ + pDev->pDrvCtrl = NULL; + return; + } + + if (devResourceGet(pHcf, "flashName", HCF_RES_STRING, (void *)&drv->flashDrvName) != OK) { + goto err; + } + + if (devResourceGet(pHcf, "flashUnit", HCF_RES_INT, (void *)&drv->flashUnit) != OK) { + drv->flashUnit = 0; + } + + if (devResourceGet(pHcf, "flashOffset", HCF_RES_INT, (void *)&drv->flashOffset) != OK) { + drv->flashOffset = 0; + } + + if (devResourceGet(pHcf, "flashSize", HCF_RES_INT, (void *)&drv->flashSize) != OK) { + drv->flashSize = 0; + } + + if (devResourceGet(pHcf, "pageSize", HCF_RES_INT, (void *)&drv->pageSize) != OK) { + drv->pageSize = 256; + } + + if (devResourceGet(pHcf, "mountPoint", HCF_RES_STRING, (void *)&drv->mountPoint) != OK) { + drv->mountPoint = "/lfs0"; + } + + vxbNextUnitGet(pDev); + return; +err: +#ifndef _VXBUS_BASIC_HWMEMLIB + hwMemFree((char *)drv); +#endif /* _VXBUS_BASIC_HWMEMLIB */ + pDev->pDrvCtrl = NULL; +} + +LOCAL void lfsDevInstInit2(VXB_DEVICE_ID pDev) +{ + lfsDrvCtrl *pDrvCtrl = (lfsDrvCtrl *)pDev->pDrvCtrl; + + pDrvCtrl->lock = semBCreate(SEM_Q_FIFO, SEM_FULL); +} + +/* {{{ lfs handler */ +LOCAL LFS_FILE_DESC *lfsFuncOpen(lfsIosDrv *dev, const char *name, int flags, int mode) +{ + int err; + LFS_FILE_DESC *ptr; + + if (S_ISDIR(mode)) { + printf("is dir not support\r\n"); + return (LFS_FILE_DESC *)(ERROR); + } + + printf("mode: %x, flags: %x, name=%p, %c(%s)\r\n", mode, flags, name, name); + + ptr = calloc(1, sizeof *ptr); + if (!ptr) { + goto end; + } + + ptr->ctrl = dev->pDrvCtrl; + + if (name == NULL || name[0] == '\0') { + err = lfs_dir_open(&ptr->ctrl->fsh, &ptr->u.dir, "."); + printf("dir_open: %d\r\n", err); + if (err != LFS_ERR_OK) { + free(ptr); + goto end; + } + printf("open: %p\r\n", ptr); + ptr->isDir = 1; + return ptr; + } + + printf("open: %s\r\n", name); + + if (lfs_file_open(&ptr->ctrl->fsh, &ptr->u.file, name, LFS_O_RDWR) == LFS_ERR_OK) { + return ptr; + } else { + free(ptr); + } + end: + return (LFS_FILE_DESC *)(ERROR); +} + +LOCAL int lfsFuncClose(LFS_FILE_DESC *pfd) +{ + lfsDrvCtrl *pDrvCtrl = pfd->ctrl; + + printf("close: %p\r\n", pfd); + + if (pfd->isDir) { + lfs_dir_close(&pDrvCtrl->fsh, &pfd->u.dir); + } else { + lfs_file_close(&pDrvCtrl->fsh, &pfd->u.file); + } + free(pfd); + + return OK; +} + +LOCAL int lfsFuncIoctl(LFS_FILE_DESC *pfd, int cmd, _Vx_ioctl_arg_t arg) +{ + struct stat *stbuf; + lfsDrvCtrl *pDrvCtrl = pfd->ctrl; + + printf("ioctl: %d\r\n", cmd); + switch (cmd) { + case FIOFSTATGET: + stbuf = (struct stat *)(arg); + stbuf->st_dev = (u_long)&pDrvCtrl->lfsDrv.devHdr; + stbuf->st_nlink = 1; + stbuf->st_attrib = 0; + if (pfd->isDir) { + stbuf->st_mode = S_IRWXU | S_IRWXG | S_IRWXO | S_IFDIR; + stbuf->st_size = pDrvCtrl->pageSize; + stbuf->st_blocks = 1; + break; + } + } + return (OK); +} + +LOCAL ssize_t lfsFuncRead(LFS_FILE_DESC *pfd, char *buffer, size_t maxbytes) +{ + lfsDrvCtrl *pDrvCtrl = pfd->ctrl; + + printf("read: %p\r\n", pfd); + if (pfd->isDir) { + printf("read dir\r\n"); + return 0; + } + return lfs_file_read(&pDrvCtrl->fsh, &pfd->u.file, buffer, maxbytes); +} + +LOCAL ssize_t lfsFuncWrite(LFS_FILE_DESC *pfd, char *buffer, size_t nbytes) +{ + lfsDrvCtrl *pDrvCtrl = pfd->ctrl; + + printf("write: %p\r\n", pfd); + if (pfd->isDir) { + printf("write dir\r\n"); + return 0; + } + return lfs_file_write(&pDrvCtrl->fsh, &pfd->u.file, buffer, nbytes); +} + +LOCAL STATUS lfsFuncRemove(LFS_FILE_DESC *pfd, char *pPath) +{ + lfsDrvCtrl *pDrvCtrl = pfd->ctrl; + + printf("remove: %s\r\n", pPath); + lfs_remove(&pDrvCtrl->fsh, pPath); + + return OK; +} +/* }}} */ + +/* {{{ lfs flash operations */ +LOCAL int lfsFlashRead(const struct lfs_config *cfg, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) +{ + UINT32 pos; + lfsDrvCtrl *pDrvCtrl = cfg->context; + UINT8 *buffers[2] = {buffer, NULL}; + + pos = pDrvCtrl->flashOffset + block * cfg->block_size + off; + + printf("%s: block: %lu, off: %lu, size: %lu, pos: 0x%lx\n", __FUNCTION__, block, off, size, pos); + + if (pDrvCtrl->mtd->flashOPs.read(pDrvCtrl->mtd, pos, 1, size, buffers, NULL) == OK) { + return LFS_ERR_OK; + } + return LFS_ERR_IO; +} + +LOCAL int lfsFlashProg(const struct lfs_config *cfg, lfs_block_t block, lfs_off_t off, const void *buffer, + lfs_size_t size) +{ + STATUS r; + UINT32 pos; + lfsDrvCtrl *pDrvCtrl = cfg->context; + UINT8 *buffers[2] = {(void *)buffer, NULL}; + + pos = pDrvCtrl->flashOffset + block * cfg->block_size + off; + + printf("%s: block: %lu, off: %lu, size: %lu, pos: 0x%lx\n", __FUNCTION__, block, off, size, pos); + + r = pDrvCtrl->mtd->flashOPs.write(pDrvCtrl->mtd, pos, 1, size, buffers, NULL); + printf("prog done: %d\r\n", r); + + return r == OK ? LFS_ERR_OK : LFS_ERR_IO; +} + +LOCAL int lfsFlashErase(const struct lfs_config *cfg, lfs_block_t block) +{ + UINT32 pos; + lfsDrvCtrl *pDrvCtrl = cfg->context; + + printf("%s: block: %lu\n", __FUNCTION__, block); + pos = pDrvCtrl->flashOffset + block * cfg->block_size; + if (pDrvCtrl->mtd->flashOPs.blkErase(pDrvCtrl->mtd, pos, 1) == OK) { + return LFS_ERR_OK; + } + return LFS_ERR_IO; +} + +LOCAL int lfsFlashSync(const struct lfs_config *c) +{ + return LFS_ERR_OK; +} + +#ifdef LFS_THREADSAFE + +LOCAL int lfsFlashLock(const struct lfs_config *cfg) +{ + lfsDrvCtrl *pDrvCtrl = cfg->context; + + semTake(pDrvCtrl->lock, WAIT_FOREVER); + + return LFS_ERR_OK; +} + +LOCAL int lfsFlashUnlock(const struct lfs_config *cfg) +{ + lfsDrvCtrl *pDrvCtrl = cfg->context; + + semGive(pDrvCtrl->lock); + + return LFS_ERR_OK; +} + +#endif + +LOCAL void lfsCfgInit(lfsDrvCtrl *drv, FLASH_CHIP_ID flash) +{ + int buffer_size = flash->uPageSize > 0 ? flash->uPageSize : drv->pageSize; + + memset(&drv->lfsConfig, 0, sizeof drv->lfsConfig); + + drv->lfsConfig.context = drv; + drv->lfsConfig.read = lfsFlashRead; + drv->lfsConfig.prog = lfsFlashProg; + drv->lfsConfig.erase = lfsFlashErase; + drv->lfsConfig.sync = lfsFlashSync; + + drv->lfsConfig.read_size = buffer_size; + drv->lfsConfig.prog_size = buffer_size; + + drv->lfsConfig.block_size = flash->uEraseSize; + drv->lfsConfig.block_count = drv->blkNum; + + drv->lfsConfig.cache_size = buffer_size; + drv->lfsConfig.lookahead_size = flash->uEraseSize / 8; + + drv->lfsConfig.block_cycles = 100; +#ifdef LFS_THREADSAFE + drv->lfsConfig.lock = lfsFlashLock; + drv->lfsConfig.unlock = lfsFlashUnlock; +#endif +} +/* }}} */ + +LOCAL void lfsDevInstConnect(VXB_DEVICE_ID pDev) +{ + lfsDrvCtrl *pDrvCtrl; + VXB_DEVICE_ID pFlashDev; + FLASH_CHIP_ID (*flashChipInfoGet)(VXB_DEVICE_ID pDev, UINT32 chipId); + + pDrvCtrl = (lfsDrvCtrl *)pDev->pDrvCtrl; + + pFlashDev = vxbInstByNameFind((char *)pDrvCtrl->flashDrvName, pDrvCtrl->flashUnit); + if (!pFlashDev) { + return; + } + semTake(pDrvCtrl->lock, WAIT_FOREVER); + flashChipInfoGet = (void *)vxbDevMethodGet(pFlashDev, DEVMETHOD_CALL(vxbFlashChipInfoGet)); + pDrvCtrl->mtd = flashChipInfoGet(pFlashDev, 0); + if (pDrvCtrl->mtd) { + if (pDrvCtrl->flashSize <= 0) { + pDrvCtrl->flashSize = pDrvCtrl->mtd->uChipSize - pDrvCtrl->flashOffset; + } + pDrvCtrl->blkNum = pDrvCtrl->flashSize / pDrvCtrl->mtd->uEraseSize; + + /* clang-format off */ + pDrvCtrl->lfsDrvNum = iosDrvInstall( + (DRV_CREATE_PTR) lfsFuncOpen, + (DRV_REMOVE_PTR) lfsFuncRemove, + (DRV_OPEN_PTR) lfsFuncOpen, + (DRV_CLOSE_PTR) lfsFuncClose, + (DRV_READ_PTR) lfsFuncRead, + (DRV_WRITE_PTR) lfsFuncWrite, + (DRV_IOCTL_PTR) lfsFuncIoctl + ); + /* clang-format on */ + if (pDrvCtrl->lfsDrvNum > 0) { + if (iosDevAdd(&pDrvCtrl->lfsDrv.devHdr, pDrvCtrl->mountPoint, pDrvCtrl->lfsDrvNum) == OK) { + pDrvCtrl->lfsDrv.pDrvCtrl = pDrvCtrl; + lfsCfgInit(pDrvCtrl, pDrvCtrl->mtd); + } else { + pDrvCtrl->mtd = NULL; + } + } else { + pDrvCtrl->mtd = NULL; + } + } + semGive(pDrvCtrl->lock); + if (pDrvCtrl->mtd) + lfs_mount(&pDrvCtrl->fsh, &pDrvCtrl->lfsConfig); +} + +LOCAL struct drvBusFuncs lfsDevFuncs = { + lfsDevInstInit, /* devInstanceInit */ + lfsDevInstInit2, /* devInstanceInit2 */ + lfsDevInstConnect /* devConnect */ +}; +/* }}} */ + +/* {{{ lfsMethods */ +LOCAL void lfsDevShow(VXB_DEVICE_ID pDev, int verbose) +{ + lfsDrvCtrl *pDrvCtrl = (lfsDrvCtrl *)pDev->pDrvCtrl; + printf(" %s unit %d on %s @ 0x%08x", pDev->pName, pDev->unitNumber, vxbBusTypeString(pDev->busID), pDev); + printf(" with busInfo %p\n", pDev->u.pSubordinateBus); + + if (verbose) { + printf(" mountPoint: %s\n", pDrvCtrl->mountPoint); + printf(" flashName: %s\n", pDrvCtrl->flashDrvName); + printf(" mtd: %p\n", pDrvCtrl->mtd); + printf(" read_size: %d\n", pDrvCtrl->lfsConfig.read_size); + printf(" prog_size: %d\n", pDrvCtrl->lfsConfig.prog_size); + printf(" block_size: %d\n", pDrvCtrl->lfsConfig.block_size); + if (pDrvCtrl->mtd) { + printf(" flashChip: %s\n", pDrvCtrl->mtd->chipName); + } + } +} + +LOCAL STATUS lfsDevInstUnlink(VXB_DEVICE_ID pDev, void *unused) +{ + lfsDrvCtrl *pDrvCtrl = (lfsDrvCtrl *)pDev->pDrvCtrl; + + /* Check for vaild parameter */ + VXB_ASSERT_NONNULL_V(pDev); + +#ifndef _VXBUS_BASIC_HWMEMLIB + hwMemFree((char *)pDrvCtrl); +#endif /* _VXBUS_BASIC_HWMEMLIB */ + pDev->pDrvCtrl = NULL; + + return OK; +} +/* }}} */ + +/* Publish the methods for the resources controlled with this file */ +/* clang-format off */ +LOCAL struct vxbDeviceMethod lfsDevMethods[] = { + DEVMETHOD(busDevShow , lfsDevShow), + DEVMETHOD(vxbDrvUnlink, lfsDevInstUnlink), + { 0, 0 } +}; + +LOCAL struct vxbSpiRegister lfsDevDriver = { + { + NULL, /* pNext */ + VXB_DEVID_DEVICE, /* devID */ + VXB_BUSID_PLB, /* busID */ + VXBUS_VERSION_5, /* vxbVersion */ + "lfs", /* drvName */ + &lfsDevFuncs, /* pDrvBusFuncs */ + lfsDevMethods, /* pMethods */ + NULL, /* devProbe */ + NULL, /* pParamDefaults */ + }, +}; +/* clang-format on */ + +void lfsDevRegister(void) +{ + (void)vxbDevRegister((struct vxbDevRegInfo *)&lfsDevDriver); +} + +STATUS lfsFormat(int unit) +{ + VXB_DEVICE_ID pDev; + lfsDrvCtrl *pDrvCtrl; + + pDev = vxbInstByNameFind("lfs", unit); + if (pDev == NULL) { + printf("Can't find lfs%d\n", unit); + return ERROR; + } + + pDrvCtrl = (lfsDrvCtrl *)pDev->pDrvCtrl; + if (!pDrvCtrl->mtd) { + printf("mtd is null\n"); + return ERROR; + } + return lfs_format(&pDrvCtrl->fsh, &pDrvCtrl->lfsConfig); +} + +STATUS lfsMount(int unit) +{ + VXB_DEVICE_ID pDev; + lfsDrvCtrl *pDrvCtrl; + + pDev = vxbInstByNameFind("lfs", unit); + if (pDev == NULL) { + printf("Can't find lfs%d\n", unit); + return ERROR; + } + + pDrvCtrl = (lfsDrvCtrl *)pDev->pDrvCtrl; + if (!pDrvCtrl->mtd) { + printf("mtd is null\n"); + return ERROR; + } + return lfs_mount(&pDrvCtrl->fsh, &pDrvCtrl->lfsConfig); +} + + diff --git a/vxbSm2130SpiDev.c b/vxbSm2130SpiDev.c index c1ab7b2..8d71088 100644 --- a/vxbSm2130SpiDev.c +++ b/vxbSm2130SpiDev.c @@ -1,3 +1,4 @@ +/* vim: set ts=4 sw=4 et fdm=marker: */ #include #include #include @@ -7,6 +8,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -17,10 +21,20 @@ #include "vxbSm2130SpiDev.h" #include +#define SPI_DEV_MUTEX_OPT (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE) + +typedef struct _Sm2310_DEV_HANDLE { + DEV_HDR devHdr; + + SEL_WAKEUP_LIST selList; + + SM2130_SPI_DEV *pDevCtrl; +} SM2310_DEV_HANDLE; + /* locals */ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose); -LOCAL INT32 spiDevRead(VXB_DEVICE_ID pDev, UINT8 cmd); -LOCAL STATUS spiDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var); +LOCAL INT32 sm2130BusDevRead(VXB_DEVICE_ID pDev, UINT8 cmd); +LOCAL STATUS sm2130BusDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var); /* VxBus methods */ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev); @@ -37,26 +51,28 @@ LOCAL struct drvBusFuncs sm2130SpiDevFuncs = { }; /* Publish the methods for the resources controlled with this file */ - +/* clang-format off */ LOCAL struct vxbDeviceMethod sm2130SpiDevMethods[] = { - DEVMETHOD(busDevShow, sm2130SpiDevShow), - DEVMETHOD(vxbDrvUnlink, sm2130SpiDevInstUnlink), - { 0, 0 } + DEVMETHOD(busDevShow , sm2130SpiDevShow), + DEVMETHOD(vxbDrvUnlink, sm2130SpiDevInstUnlink), + { 0, 0 } }; LOCAL struct vxbSpiRegister sm2130SpiDevRegister = { { - NULL, /* pNext */ - VXB_DEVID_DEVICE, /* devID */ - VXB_BUSID_SPI, /* busID = SPI */ - VXB_VER_4_0_0, /* vxbVersion */ - SPI_DEV_SM2130, /* drvName */ - &sm2130SpiDevFuncs, /* pDrvBusFuncs */ - sm2130SpiDevMethods, /* pMethods */ - NULL, //sm2130Probe, /* devProbe */ - NULL, /* pParamDefaults */ + NULL, /* pNext */ + VXB_DEVID_DEVICE, /* devID */ + VXB_BUSID_SPI, /* busID = SPI */ + VXB_VER_4_0_0, /* vxbVersion */ + SPI_DEV_SM2130, /* drvName */ + &sm2130SpiDevFuncs, /* pDrvBusFuncs */ + sm2130SpiDevMethods, /* pMethods */ + NULL, /* devProbe */ + NULL, /* pParamDefaults */ }, }; +/* clang-format on */ + /* * * vxbSm2130SpiDevRegister - register with the VxBus subsystem @@ -85,6 +101,7 @@ void vxbSm2130SpiDevRegister(void) LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev) { SM2130_SPI_DEV *pDrvCtrl; + struct hcfDevice *pHcf; /* Check for vaild parameter */ VXB_ASSERT_NONNULL_V(pDev); @@ -97,9 +114,19 @@ LOCAL void sm2130SpiDevInstInit(VXB_DEVICE_ID pDev) pDrvCtrl->pDev = pDev; pDev->pDrvCtrl = pDrvCtrl; - pDrvCtrl->read = spiDevRead; - pDrvCtrl->write = spiDevWrite; - + pDrvCtrl->drvNode = -1; + pDrvCtrl->devHandle = NULL; + pDrvCtrl->devName = SM2310_DEV_NAME; + pHcf = (struct hcfDevice *)hcfDeviceGet(pDev); + if (pHcf) { + if (devResourceGet(pHcf, "devName", HCF_RES_STRING, (void *)&pDrvCtrl->devName) != OK) { + pDrvCtrl->devName = SM2310_DEV_NAME; + } + } + + pDrvCtrl->read = sm2130BusDevRead; + pDrvCtrl->write = sm2130BusDevWrite; + vxbNextUnitGet(pDev); } @@ -125,14 +152,75 @@ LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev) /* Mutex semaphore is initialized and necessary at this point */ pDrvCtrl->muteSem = semMCreate(SPI_DEV_MUTEX_OPT); - pFunc = vxbDevMethodGet(vxbDevParent(pDev), - (VXB_METHOD_ID)vxbSpiSpecialGet_desc); + pFunc = vxbDevMethodGet(vxbDevParent(pDev), (VXB_METHOD_ID)vxbSpiSpecialGet_desc); /* Retrieve the SPI master special information */ if (pFunc != NULL) (*pFunc)(vxbDevParent(pDev), &pDrvCtrl->specialInfo); } +/* {{{ device driver api */ +LOCAL SM2310_DEV_HANDLE *drv1553bOpen(SM2310_DEV_HANDLE *dev, const char *name, int flags, int mode) +{ + SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; + + (void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); + ++pDrvCtrl->refcount; + (void)semGive(pDrvCtrl->muteSem); + printf("open: %p\n", dev); + return dev; +} + +LOCAL int drv1553bClose(SM2310_DEV_HANDLE *dev) +{ + SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; + + (void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); + --pDrvCtrl->refcount; + (void)semGive(pDrvCtrl->muteSem); + + printf("close: %p\n", dev); + return (OK); +} + +LOCAL int drv1553bIoctl(SM2310_DEV_HANDLE *dev, int cmd, _Vx_ioctl_arg_t arg) +{ + SM2130_XFER *xfer; + SM2130_SPI_DEV *pDrvCtrl = dev->pDevCtrl; + STATUS ret = OK; + + printf("ioctl: %p\n", dev); + + (void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); + switch (cmd) { + case FIOSELECT: + ret = selNodeAdd(&dev->selList, (SEL_WAKEUP_NODE *)arg); + break; + case FIOUNSELECT: + ret = selNodeDelete(&dev->selList, (SEL_WAKEUP_NODE *)arg); + break; + case FIO_XFER: + xfer = (SM2130_XFER *)(arg); + switch (xfer->type) { + case FIO_XFER_TX: + pDrvCtrl->write(pDrvCtrl->pDev, xfer->reg, xfer->val); + break; + case FIO_XFER_RX: + xfer->val = pDrvCtrl->read(pDrvCtrl->pDev, xfer->reg); + break; + default: + errnoSet(EINVAL); + ret = ERROR; + } + break; + default: + break; + } + (void)semGive(pDrvCtrl->muteSem); + return (ret); +} +/* }}} */ + /* * sm2130SpiDevInstConnect - third level initialization routine of spi flash * @@ -146,11 +234,41 @@ LOCAL void sm2130SpiDevInstInit2(VXB_DEVICE_ID pDev) LOCAL void sm2130SpiDevInstConnect(VXB_DEVICE_ID pDev) { SM2130_SPI_DEV *pDrvCtrl; - + SM2310_DEV_HANDLE *dev; /* Check for vaild parameter */ VXB_ASSERT_NONNULL_V(pDev); pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl; + + (void)semTake(pDrvCtrl->muteSem, WAIT_FOREVER); + if (pDrvCtrl->drvNode < 0) { + /* clang-format off */ + pDrvCtrl->drvNode = iosDrvInstall( + (DRV_CREATE_PTR)drv1553bOpen , + (DRV_REMOVE_PTR)NULL , + (DRV_OPEN_PTR)drv1553bOpen , + (DRV_CLOSE_PTR)drv1553bClose , + (DRV_READ_PTR)NULL , + (DRV_WRITE_PTR)NULL , + (DRV_IOCTL_PTR)drv1553bIoctl); + /* clang-format on */ + if (pDrvCtrl->drvNode > 0) { + dev = (SM2310_DEV_HANDLE *)hwMemAlloc(sizeof(SM2310_DEV_HANDLE)); + if (dev) { + pDrvCtrl->refcount = 0; + selWakeupListInit(&dev->selList); + if (iosDevAdd(&dev->devHdr, pDrvCtrl->devName, pDrvCtrl->drvNode) == OK) { + pDrvCtrl->devHandle = dev; + dev->pDevCtrl = pDrvCtrl; + } else { +#ifndef _VXBUS_BASIC_HWMEMLIB + hwMemFree((char *)dev); +#endif /* _VXBUS_BASIC_HWMEMLIB */ + } + } + } + } + (void)semGive(pDrvCtrl->muteSem); } /* @@ -198,19 +316,26 @@ LOCAL STATUS sm2130SpiDevInstUnlink(VXB_DEVICE_ID pDev, void *unused) */ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose) { - printf(" %s unit %d on %s @ 0x%08x", pDev->pName, pDev->unitNumber, - vxbBusTypeString(pDev->busID), pDev); + SM2130_SPI_DEV *pDrvCtrl = (SM2130_SPI_DEV *)pDev->pDrvCtrl; + + printf(" %s unit %d on %s @ 0x%08x", pDev->pName, pDev->unitNumber, vxbBusTypeString(pDev->busID), pDev); printf(" with busInfo %p\n", pDev->u.pSubordinateBus); if (verbose) { - + printf(" chipSelect: %d\n", pDrvCtrl->cs); + printf(" mode: %d\n", pDrvCtrl->mode); + printf(" speed: %u\n", pDrvCtrl->freq); + printf(" devName: %s\n", pDrvCtrl->devName); + printf(" devHandle: %p\n", pDrvCtrl->devHandle); + printf(" drvNode: %d\n", pDrvCtrl->drvNode); + printf(" refCount: %d\n", pDrvCtrl->refcount); } return; } /* - * spiDevWrite - VxBus SPI device write by name support routine + * sm2130BusDevWrite - VxBus SPI device write by name support routine * * This routine firstly finds the VXB_DEVICE_ID for a given instance * identified by name and unit number, then call vxbI2cDevWrite() routine to @@ -220,25 +345,25 @@ LOCAL void sm2130SpiDevShow(VXB_DEVICE_ID pDev, int verbose) * * ERRNO : N/A */ -LOCAL STATUS spiDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var) +LOCAL STATUS sm2130BusDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var) { - SPI_TRANSFER transInfo = {NULL, NULL, 0, 0, 0}; + SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 }; UINT8 buf[3]; - /* Check if the pDev pointer is valid */ + /* Check if the pDev pointer is valid */ VXB_ASSERT(pDev != NULL, ERROR) buf[0] = cmd; buf[1] = var & 0xff; buf[1] = (var >> 8) & 0xff; - + transInfo.txBuf = buf; transInfo.txLen = 3; - - return (vxbSpiTransfer(pDev, &transInfo)); + + return vxbSpiTransfer(pDev, &transInfo); } /* - * spiDevRead - read register routine + * sm2130BusDevRead - read register routine * * This is the SPI flash status /config register read out routine. * @@ -246,57 +371,62 @@ LOCAL STATUS spiDevWrite(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var) * * ERRNO: N/A */ -LOCAL INT32 spiDevRead(VXB_DEVICE_ID pDev, UINT8 cmd) +LOCAL INT32 sm2130BusDevRead(VXB_DEVICE_ID pDev, UINT8 cmd) { - SPI_TRANSFER transInfo = {NULL, NULL, 0, 0, 0}; - UINT16 buffer = 0xffff; + SPI_TRANSFER transInfo = { NULL, NULL, 0, 0, 0 }; + UINT16 buffer; + UINT8 buf[3] = { 0xff, 0xff, 0xff }; /* check if the pDev pointer is valid */ VXB_ASSERT(pDev != NULL, ERROR) - transInfo.txBuf = &cmd; + buf[0] = cmd; + + transInfo.txBuf = buf; transInfo.txLen = 1; - transInfo.rxBuf = (UINT8 *)&buffer; - transInfo.rxLen = 2; + transInfo.rxBuf = buf; + transInfo.rxLen = 3; if (vxbSpiTransfer(pDev, &transInfo) != OK) return ERROR; - else - return (buffer); -} + buffer = (buf[2] << 8) | buf[1]; + return (buffer); +} +/* {{{ Test Read write */ INT32 sm2130Read(UINT8 cmd) { VXB_DEVICE_ID pDev; - SM2130_SPI_DEV * pCtrl; + SM2130_SPI_DEV *pCtrl; pDev = vxbInstByNameFind(SPI_DEV_SM2130, 0); if (pDev == NULL) { return ERROR; } - + pCtrl = pDev->pDrvCtrl; - - /* printf("pDev @ %p, pCtrl %p\n", pDev, pCtrl); */ - + + /* printf("pDev @ %p, pCtrl %p\n", pDev, pCtrl); */ + return pCtrl->read(pDev, cmd); } STATUS sm2130Write(UINT8 cmd, UINT16 var) { VXB_DEVICE_ID pDev; - SM2130_SPI_DEV * pCtrl; + SM2130_SPI_DEV *pCtrl; pDev = vxbInstByNameFind(SPI_DEV_SM2130, 0); if (pDev == NULL) { return ERROR; } - + pCtrl = pDev->pDrvCtrl; - - /* printf("pDev @ %p, pCtrl %p\n", pDev, pCtrl); */ - + + /* printf("pDev @ %p, pCtrl %p\n", pDev, pCtrl); */ + return pCtrl->write(pDev, cmd, var); } +/* }}} */ diff --git a/vxbSm2130SpiDev.h b/vxbSm2130SpiDev.h index ca55ee5..3561482 100644 --- a/vxbSm2130SpiDev.h +++ b/vxbSm2130SpiDev.h @@ -3,8 +3,19 @@ #define SPI_DEV_SM2130 "SM2130" -#define SPI_DEV_MUTEX_OPT \ - (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE) +#define SM2310_DEV_NAME "/sm2130" + +#define FIO_XFER_TX (1) +#define FIO_XFER_RX (2) + +#define FIO_XFER (200) + +struct sm2130_xfer { + UINT8 type; + UINT8 reg; + UINT16 val; +}; +typedef struct sm2130_xfer SM2130_XFER; typedef struct _spi_1553b_drv_ctrl { VXB_DEVICE_ID pDev; @@ -12,6 +23,13 @@ typedef struct _spi_1553b_drv_ctrl { int cs; int mode; unsigned int freq; + + const char *devName; + + int refcount; + + int drvNode; + void *devHandle; INT32 (*read)(VXB_DEVICE_ID pDev, UINT8 cmd); STATUS (*write)(VXB_DEVICE_ID pDev, UINT8 cmd, UINT16 var);