Browse Source

import from: https://gitee.com/vxworks-phy/ft2004-vxworks-6.9.4

Signed-off-by: surenyi <surenyi82@163.com>
master
surenyi 3 weeks ago
commit
4043fa882d
  1. 53
      20bsp.cdf
  2. 25
      40vxbArmGenIntCtlrV3.cdf
  3. 23
      40vxbArmv7AuxTimer.cdf
  4. 23
      40vxbArmv7GenTimer.cdf
  5. 24
      40vxbFtCan.cdf
  6. 21
      40vxbFtGmacEnd.cdf
  7. 22
      40vxbFtGpio.cdf
  8. 26
      40vxbFtI2c.cdf
  9. 26
      40vxbFtQspi.cdf
  10. 29
      40vxbFtSdhc.cdf
  11. 21
      40vxbYt8521Phy.cdf
  12. 46
      Makefile
  13. 276
      config.h
  14. 4634
      font_8x16.h
  15. 196
      ft2000-4.h
  16. 697
      genericPhy.c
  17. 555
      hwconf.c
  18. 11803
      hwif/vxbPci.bc
  19. BIN
      lib/libFtX100dcdrv.a
  20. 87
      miiBus.h
  21. 127
      pcConsole.h
  22. 455
      pciCfgIntStub.c
  23. 940
      sysALib.s
  24. 1247
      sysLib.c
  25. 2098
      sysTffs.c
  26. 519
      target.ref
  27. 9
      usbPciStub.c
  28. 3082
      vxbAhciStorage.c
  29. 654
      vxbAhciStorage.h
  30. 2442
      vxbArmGenIntCtlrV3.c
  31. 264
      vxbArmGenIntCtlrV3.h
  32. 1291
      vxbArmv7AuxTimer.c
  33. 1541
      vxbArmv7GenTimer.c
  34. 2986
      vxbFtGmacEnd.c
  35. 530
      vxbFtGmacEnd.h
  36. 763
      vxbFtGpio.c
  37. 134
      vxbFtGpio.h
  38. 1636
      vxbFtI2c.c
  39. 286
      vxbFtI2c.h
  40. 1423
      vxbFtPcie.c
  41. 1046
      vxbFtQspi.c
  42. 268
      vxbFtQspi.h
  43. 1260
      vxbFtSdCtrl.c
  44. 309
      vxbFtSdCtrl.h
  45. 1208
      vxbFtcan.c
  46. 287
      vxbFtcan.h
  47. 881
      vxbM6845Vga.c
  48. 120
      vxbM6845Vga.h
  49. 5054
      vxbPci.c
  50. 539
      vxbPciLib.h
  51. 2990
      vxbSp25SpiFlash.c
  52. 416
      vxbSp25SpiFlash.h
  53. 657
      vxbYt8521Phy.c
  54. 33
      vxbYt8521Phy.h

53
20bsp.cdf

@ -0,0 +1,53 @@
/* 20bsp.cdf - BSP component description file */
/*
*
* 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.
*
*/
Bsp ft20004_km02 {
NAME board support package
CPU ARMARCH7
ENDIAN little
MP_OPTIONS SMP
REQUIRES INCLUDE_KERNEL \
DRV_ARM_GEN_SYS_TIMER \
DRV_ARM_GICV3
}
Component INCLUDE_BOOT_NET_DEVICES {
REQUIRES INCLUDE_GEI825XX_VXB_END
}
/* Define INCLUDE_BOOT_ETH_MAC_HANDLER when BootApp Networking is enabled */
Component INCLUDE_BOOT_ETH_MAC_HANDLER {
INCLUDE_WHEN INCLUDE_BOOT_NETWORK
}
Parameter RAM_HIGH_ADRS {
NAME Bootrom Copy region
DEFAULT (INCLUDE_BOOT_RAM_IMAGE)::(0x82500000) \
(INCLUDE_BOOT_APP)::(0x82000000) \
0x81000000
}
Parameter RAM_LOW_ADRS {
NAME Runtime kernel load address
DEFAULT (INCLUDE_BOOT_RAM_IMAGE)::(0x81a00000) \
(INCLUDE_BOOT_APP)::(0x81000000) \
0x80100000
}
Parameter VX_SMP_NUM_CPUS {
NAME Number of CPUs available to be enabled for VxWorks SMP
TYPE UINT
DEFAULT 4
}

25
40vxbArmGenIntCtlrV3.cdf

@ -0,0 +1,25 @@
/* 40vxbArmGenIntCtlrV3.cdf - ARM GIC Version3 interrupt controller */
/*
*
* 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.
*
*/
Component DRV_ARM_GICV3 {
NAME ARM Generic Version3 Interrupt Controller driver
SYNOPSIS ARM Generic Version3 Interrupt Controller driver
REQUIRES INCLUDE_VXBUS \
INCLUDE_PLB_BUS \
INCLUDE_INTCTLR_LIB
_CHILDREN FOLDER_DRIVERS
INIT_RTN vxbFTIntCtlrRegister();
PROTOTYPE void vxbFTIntCtlrRegister (void);
INIT_AFTER INCLUDE_PLB_BUS
_INIT_ORDER hardWareInterFaceBusInit
}

23
40vxbArmv7AuxTimer.cdf

@ -0,0 +1,23 @@
/* 40vxbArmv7AuxTimer.cdf - ARMV7A aux timer configuration file */
/*
*
* 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.
*
*/
Component DRV_ARM_GEN_AUX_TIMER {
NAME armv7a Aux Timer Driver
SYNOPSIS armv7a Aux Timer Driver
_CHILDREN FOLDER_DRIVERS
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN armv7AuxTimerRegister();
PROTOTYPE void armv7AuxTimerRegister (void);
REQUIRES INCLUDE_PLB_BUS \
INCLUDE_VXB_AUX_CLK
}

23
40vxbArmv7GenTimer.cdf

@ -0,0 +1,23 @@
/* 40vxbArmv7GenTimer.cdf - ARMV7A general timer configuration file */
/*
*
* 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.
*
*/
Component DRV_ARM_GEN_SYS_TIMER {
NAME armv7a General Timer Driver
SYNOPSIS armv7a General Timer Driver
_CHILDREN FOLDER_DRIVERS
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN armv7GenTimerRegister();
PROTOTYPE void armv7GenTimerRegister (void);
REQUIRES INCLUDE_PLB_BUS \
INCLUDE_PARAM_SYS \
INCLUDE_TIMER_SYS
}

24
40vxbFtCan.cdf

@ -0,0 +1,24 @@
/* 40vxbFtCan.cdf - Can controller configuration file */
/*
*
* 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.
*
*/
Component DRV_FTCAN {
NAME FT CAN controller driver
SYNOPSIS FT CAN controller driver
_CHILDREN FOLDER_DRIVERS
CONFIGLETTES
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN vxbFtCanRegister();
PROTOTYPE void vxbFtCanRegister (void);
REQUIRES INCLUDE_VXBUS \
INCLUDE_PLB_BUS
INIT_AFTER INCLUDE_PLB_BUS
}

21
40vxbFtGmacEnd.cdf

@ -0,0 +1,21 @@
/* 40vxbFtGmacEnd.cdf - GMAC configuration file */
/*
*
* 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.
*
*/
Component DRV_VXBEND_FTGMAC {
NAME FT2000 GEM Enhanced Network Driver
SYNOPSIS FT2000 GEM Enhanced Network Driver
_CHILDREN FOLDER_DRIVERS
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN ftGmacRegister();
REQUIRES INCLUDE_PLB_BUS \
INCLUDE_PARAM_SYS \
INCLUDE_MII_BUS
INIT_AFTER INCLUDE_PLB_BUS
}

22
40vxbFtGpio.cdf

@ -0,0 +1,22 @@
/* 40vxbFtGpio.cdf - GPIO configuration file */
/*
*
* 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.
*
*/
Component DRV_FTGPIO {
NAME FT GPIO controller driver
SYNOPSIS FT GPIO controller driver
_CHILDREN FOLDER_DRIVERS
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN vxbFtGpioDrvRegister();
PROTOTYPE void vxbFtGpioDrvRegister (void);
REQUIRES INCLUDE_PLB_BUS
INIT_AFTER INCLUDE_PLB_BUS
}

26
40vxbFtI2c.cdf

@ -0,0 +1,26 @@
/* 40vxbFtI2c.cdf - I2C controller configuration file */
/*
*
* 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.
*
*/
Component DRV_FTI2C {
NAME FT I2C controller driver
SYNOPSIS FT I2C controller driver
_CHILDREN FOLDER_DRIVERS
CONFIGLETTES
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN vxbFtI2cRegister();
PROTOTYPE void vxbFtI2cRegister (void);
REQUIRES INCLUDE_VXBUS \
INCLUDE_PLB_BUS \
INCLUDE_I2C_BUS
INIT_AFTER INCLUDE_PLB_BUS \
INCLUDE_I2C_BUS
}

26
40vxbFtQspi.cdf

@ -0,0 +1,26 @@
/* 40vxbFtQspi.cdf - QSPI controller configuration file */
/*
*
* 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.
*
*/
Component DRV_FTQSPI {
NAME FT QSPI controller driver
SYNOPSIS FT QSPI controller driver
_CHILDREN FOLDER_DRIVERS
CONFIGLETTES
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN vxbFtQspiRegister();
PROTOTYPE void vxbFtQspiRegister (void);
REQUIRES INCLUDE_VXBUS \
INCLUDE_PLB_BUS \
INCLUDE_SPI_BUS
INIT_AFTER INCLUDE_PLB_BUS \
INCLUDE_SPI_BUS
}

29
40vxbFtSdhc.cdf

@ -0,0 +1,29 @@
/* 40vxbFtSdhc.cdf - SD controller configuration file */
/*
*
* 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.
*
*/
Component INCLUDE_FT_SD {
NAME FT SDHC host controller driver
SYNOPSIS FT SDHC host controller driver
_CHILDREN FOLDER_DRIVERS
CONFIGLETTES usrSdMmc.c
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN ftSdhcRegister();\
usrSdMmcInit();
PROTOTYPE void ftSdhcRegister (void);
REQUIRES DRV_SDSTORAGE_CARD\
INCLUDE_VXBUS \
INCLUDE_PLB_BUS \
INCLUDE_ERF \
INCLUDE_SD_BUS
INIT_AFTER INCLUDE_PLB_BUS \
INCLUDE_SD_BUS
}

21
40vxbYt8521Phy.cdf

@ -0,0 +1,21 @@
/* 40vxbYt8521Phy.cdf - Yt8521 phy configuration file */
/*
*
* 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.
*
*/
Component INCLUDE_YT8521PHY {
NAME yt8521 Phy driver
SYNOPSIS yt8521 10/100/1000 ethernet PHY
_CHILDREN FOLDER_DRIVERS
_INIT_ORDER hardWareInterFaceBusInit
INIT_RTN ytPhyRegister();
REQUIRES INCLUDE_MII_BUS
INIT_AFTER INCLUDE_MII_BUS
}

46
Makefile

@ -0,0 +1,46 @@
CPU = ARMARCH7
TOOL = gnu
EXTRA_DEFINE = -DCPU_CORTEXA8 -DARMMMU=ARMMMU_CORTEXA8 \
-DARMCACHE=ARMCACHE_CORTEXA8
TGT_DIR = $(WIND_BASE)/target
include $(TGT_DIR)/h/make/defs.bsp
## Only redefine make definitions below this point, or your definitions will
## be overwritten by the makefile stubs above.
TARGET_DIR = ft2000_4
BOARD = ft2000/4 reference board
RELEASE += bootrom_uncmp.hex
MACH_EXTRA += vxbArmGenIntCtlrV3.o vxbArmv7GenTimer.o vxbArmv7AuxTimer.o \
vxbFtPcie.o vxbAhciStorage.o vxbFtGmacEnd.o vxbFtcan.o vxbPci.o \
vxbFtSdCtrl.o vxbFtI2c.o vxbYt8521Phy.o genericPhy.o vxbFtQspi.o\
vxbSp25SpiFlash.o vxbFtGpio.o
ifneq ($(findstring bootrom,$(MAKECMDGOALS)),bootrom)
LIB_EXTRA = lib/libFtX100dcdrv.a
endif
RAM_LOW_ADRS = 80100000 # RAM text/data address
RAM_HIGH_ADRS = 81000000 # RAM text/data address
VMA_START = 0x$(ROM_TEXT_ADRS)
#EXTRA_INCLUDE += -I./include
ADDED_CFLAGS += -DARM_AARCH64
include $(TGT_DIR)/h/make/rules.bsp
# uboot cmd:
# setenv ipaddr 192.168.2.145
# tftpboot 0x80100000 192.168.2.144:vxWorks.bin
# bootvx32 0x80100000
#

276
config.h

@ -0,0 +1,276 @@
/* config.h - FT2000/4 configuration header */
/*
*
* 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.
*
*/
#ifndef __INCconfigh
#define __INCconfigh
#ifdef __cplusplus
extern "C" {
#endif
/* BSP version/revision identification, before configAll.h */
#define BSP_VERSION "1.0"
#define BSP_REV "/0" /* 0 for first revision */
#include <vsbConfig.h>
#include <configAll.h>
#define SYS_MODEL "FT2000/4 BOARD"
#define INCLUDE_VXBUS
#ifdef INCLUDE_VXBUS
#define INCLUDE_VXBUS_SHOW
#define INCLUDE_HWMEM_ALLOC
#define INCLUDE_PLB_BUS
#define DRV_ARM_GICV3
#define DRV_SIO_PRIMECELL /* UART */
#define DRV_ARM_GEN_SYS_TIMER
#define INCLUDE_AUX_CLK
#undef DRV_ARM_GEN_AUX_TIMER
#define INCLUDE_SYSCLK_INIT
#define INCLUDE_PARAM_SYS
#define DRV_FTCAN
#define INCLUDE_FT_SD
#define DRV_FTI2C
#define DRV_FTQSPI
#define DRV_SPIFLASH_SP25
#undef INCLUDE_YT8521PHY
#define DRV_FTGPIO
#if defined(INCLUDE_PC_CONSOLE)||defined(INCLUDE_WINDML)
#define DRV_X100DC
#endif
/* ARM PrimeCell SIO for VxBus */
#define INCLUDE_SIO_UTILS
#undef INCLUDE_USB
#ifdef INCLUDE_USB
#define INCLUDE_USB_INIT
#define INCLUDE_USB_XHCI_HCD
#define INCLUDE_USB_XHCI_HCD_INIT
#define INCLUDE_USB_GEN2_STORAGE
#define INCLUDE_USB_GEN2_STORAGE_INIT
#endif
#define INCLUDE_DRV_STORAGE_AHCI
#if defined(INCLUDE_USB) || defined(INCLUDE_TFFS) || \
defined(INCLUDE_DRV_STORAGE_PIIX) || defined(INCLUDE_DRV_STORAGE_AHCI)
#define INCLUDE_DOSFS
#define INCLUDE_DOSFS_MAIN
#define INCLUDE_DOSFS_CHKDSK
#define INCLUDE_DOSFS_FMT
#define INCLUDE_DOSFS_FAT
#define INCLUDE_DOSFS_SHOW
#define INCLUDE_DOSFS_DIR_VFAT
#define INCLUDE_DOSFS_DIR_FIXED
#define INCLUDE_FS_MONITOR
#define INCLUDE_FS_EVENT_UTIL
#define INCLUDE_ERF
#define INCLUDE_XBD
#define INCLUDE_XBD_BLKDEV
#define INCLUDE_XBD_TRANS
#define INCLUDE_DEVICE_MANAGER
#define INCLUDE_XBD_BLK_DEV
#define INCLUDE_XBD_PART_LIB
#define INCLUDE_DISK_UTIL
#endif
/*#define INCLUDE_HRFS*/
#define DRV_VXBEND_FTGMAC
#define DRV_PCIBUS_FT
#ifdef DRV_PCIBUS_FT
# define INCLUDE_PCI_BUS
# define INCLUDE_PCI_BUS_AUTOCONF
# define INCLUDE_PCI_BUS_SHOW
# define INCLUDE_GEI825XX_VXB_END
# define INCLUDE_VXBUS_SHOW
# define INCLUDE_VXB_LEGACY_INTERRUPTS
#endif /* DRV_PCIBUS_FT */
#if defined(INCLUDE_GEI825XX_VXB_END) || defined(DRV_VXBEND_FTGMAC)
# define INCLUDE_GENERICPHY
# define INCLUDE_MII_BUS
# define INCLUDE_IFCONFIG /* old coreip stack ifconfig command line/API */
# define INCLUDE_PING /* old coreip stack ping client */
# define INCLUDE_ISR_SHOW
# define INCLUDE_WATCHDOGS
# define INCLUDE_NETWORK
# define INCLUDE_NET_INIT
# define INCLUDE_BOOT_LINE_INIT
#endif
/* ARM Versatile EB Generic Interrupt Controller for VxBus */
#define INCLUDE_INTCTLR_LIB
/* ARM AMBA timer for VxBus */
#define INCLUDE_TIMER_SYS
#define INCLUDE_TIMESTAMP /* time stamp for benchmark */
#define HWMEM_POOL_SIZE 500000
#define INCLUDE_VXB_CMDLINE
#endif /* INCLUDE_VXBUS */
#define FORCE_DEFAULT_BOOT_LINE
#define DEFAULT_BOOT_LINE \
"gmac(0,0) host:/vxWorks " \
"h=192.168.4.162 e=192.168.4.127:ffffff00 u=target pw=target tn=target"
/* Memory configuration */
#define USER_RESERVED_MEM 0 /* see sysMemTop() */
/*
* bootapp speed ups.
*/
#define BSP_COPY_LONGS bcopyLongs
#define BSP_FILL_LONGS bfillLongs
#define INCLUDE_BOOT_D_CACHE_ENABLE /* Enable Data Cache for bootrom */
/*
* Local-to-Bus memory address constants:
* the local memory address always appears at 0 locally;
* it is not dual ported.
*/
#define LOCAL_MEM_LOCAL_ADRS 0x80000000
#define LOCAL_MEM_BUS_ADRS 0x80000000
#define LOCAL_MEM_SIZE 0x70000000
#define LOCAL_MEM_END_ADRS (LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE)
#define ROM_BASE_ADRS 0x40000000 /* base of NOR Flash/EPROM */
#define ROM_TEXT_ADRS 0x44040000 /* code start addr in ROM */
#define ROM_SIZE 0x00100000 /* size of ROM holding VxWorks*/
#define ROM_COPY_SIZE ROM_SIZE
#define ROM_SIZE_TOTAL 0x04000000 /* total size of ROM */
/* Flash memory configuration */
#define SPI_FLASH_DEVICE_NAME "spiFlash_s25fs256s"
#define SZ_32M (0x02000000)
#define SZ_64K (0x00010000)
#define SPI_FLASH_SIZE (SZ_32M)
#define SPI_FLASH_SECTOR_SIZE (SZ_64K)
#define SPI_FLASH_PAGE_SIZE (0x100)
#define SPI_FLASH_BASE_ADRS 0
#define SPI_FLASH_SECTOR_NUM ((SPI_FLASH_SIZE) / (SPI_FLASH_SECTOR_SIZE))
#define SPI_BOOTROM_SIZE (0x500000)
#define INCLUDE_TFFS
#ifdef INCLUDE_TFFS
# define INCLUDE_TFFS_MOUNT
# define INCLUDE_TFFS_SHOW
/* TFFS stub to vxBus Flash interface */
# define INCLUDE_TFFS_STUB_VXBFLASH
# define TFFS_FORMAT_PRINT /* print the tffs format process */
/* TrueFFS partition 0 */
# define TFFS_PART0_NAME "RFA0"
# define TFFS_PART0_FLASH_NAME SPI_FLASH_DEVICE_NAME
# define TFFS_PART0_FLASH_UNIT 0
# define TFFS_PART0_FLASH_BASE_ADRS SPI_FLASH_BASE_ADRS
# define TFFS_PART0_FLASH_OFFSET 0
# define TFFS_PART0_FLASH_SIZE SPI_FLASH_SIZE
# define TFFS_PART0_FLASH_BOOT_SIZE SPI_BOOTROM_SIZE
#endif /* INCLUDE_TFFS */
/* clock rate configuration*/
#define SYS_CLK_RATE_MIN 10
#define SYS_CLK_RATE_MAX 15000
#define AUX_CLK_RATE_MIN 10
#define AUX_CLK_RATE_MAX 15000
/* Serial port configuration */
#undef NUM_TTY
#define NUM_TTY 4
#define DEFAULT_BAUD 115200
#undef CONSOLE_BAUD_RATE
#define CONSOLE_BAUD_RATE 115200
#undef CONSOLE_TTY
#define CONSOLE_TTY 1
#undef INCLUDE_WDB
#undef USER_I_CACHE_MODE
#define USER_I_CACHE_MODE (CACHE_COPYBACK)
#undef USER_D_CACHE_MODE
#define USER_D_CACHE_MODE (CACHE_COPYBACK)
/*
* Include MMU BASIC and CACHE support for command line and project builds
*/
# define INCLUDE_MMU_BASIC
# define INCLUDE_MMU_FULL
# define INCLUDE_CACHE_SUPPORT
/*
* Vector Floating Point Support
*/
#define INCLUDE_VFP
/*
* miscellaneous definitions
* Note: ISR_STACK_SIZE is defined here rather than in ../all/configAll.h
* (as is more usual) because the stack size depends on the interrupt
* structure of the BSP.
*/
#define ISR_STACK_SIZE 0x2000 /* size of ISR stack, in bytes */
#define INCLUDE_PCI_OLD_CONFIG_ROUTINES
#define INCLUDE_SYS_HW_INIT_0
#define SYS_HW_INIT_0() (sysHwInit0())
#ifdef _WRS_CONFIG_SMP
# define INCLUDE_VXIPI
#endif /* _WRS_CONFIG_SMP */
#define INCLUDE_SHELL
#define INCLUDE_SYM_TBL
#define INCLUDE_SYM_TBL_INIT
/*#define INCLUDE_STANDALONE_SYM_TBL*/
#define INCLUDE_ISR_OBJECTS
#ifdef __cplusplus
}
#endif
#endif /* __INCconfigh */
#if defined(PRJ_BUILD)
#include "prjParams.h"
#endif /* PRJ_BUILD */

4634
font_8x16.h

File diff suppressed because it is too large

196
ft2000-4.h

@ -0,0 +1,196 @@
/* ft2000-4.h - FT2000A/4 chip file */
/*
*
* 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.
*
*/
#ifndef __INCft2000_4_h
#define __INCft2000_4_h
#ifdef __cplusplus
extern "C"
{
#endif
#define FT2000_UART_CLK (48000000) /* UART clock */
#define UART_0_BASE_ADR (0x28000000) /* UART 0 base address */
#define UART_1_BASE_ADR (0x28001000) /* UART 1 base address */
#define UART_2_BASE_ADR (0x28002000) /* UART 2 base address */
#define UART_3_BASE_ADR (0x28003000) /* UART 3 base address */
#define GPIO_0_BASE_ADR (0x28004000) /* GPIO 0 base address */
#define GPIO_1_BASE_ADR (0x28005000) /* GPIO 1 base address */
#define GIC_BASE_ADR (0x29900000)
#define INT_VEC_UART0INTR 38
#define INT_VEC_UART1INTR 39
#define INT_VEC_UART2INTR 40
#define INT_VEC_UART3INTR 41
#define INT_VEC_GPIO0INTR 42
#define INT_VEC_GPIO1INTR 43
/*CAN Baudrate*/
enum can_bitrate{
CAN_BRATE_5 = 5, /* */
CAN_BRATE_10 = 10, /* */
CAN_BRATE_20 = 20, /* */
CAN_BRATE_40 = 40, /* */
CAN_BRATE_50 = 50, /* */
CAN_BRATE_80 = 80, /* */
CAN_BRATE_100 = 100, /* */
CAN_BRATE_125 = 125, /* */
CAN_BRATE_200 = 200, /* */
CAN_BRATE_250 = 250, /* */
CAN_BRATE_400 = 400, /* */
CAN_BRATE_500 = 500, /* */
CAN_BRATE_800 = 800, /* */
CAN_BRATE_1000 = 1000, /* */
};
#define FT2000_I2C_CLK (48000000) /* I2C clock */
#define I2C_0_INTR_IRQ (44)
#define I2C_1_INTR_IRQ (45)
#define I2C_2_INTR_IRQ (46)
#define I2C_3_INTR_IRQ (47)
#define REG_I2C0_BASE (0x28006000)
#define REG_I2C1_BASE (0x28007000)
#define REG_I2C2_BASE (0x28008000)
#define REG_I2C3_BASE (0x28009000)
#define FT_SDHC0_BASE (0x28207c00)
#define FTCAN_BRATE_DEFAULT (CAN_BRATE_1000*1000)
#define FTCAN0_BASE 0x28207000
#define FTCAN0_IRQ 119
#define FTCAN0_BITRATE FTCAN_BRATE_DEFAULT
#define FTCAN1_BASE 0x28207400
#define FTCAN1_IRQ 123
#define FTCAN1_BITRATE FTCAN_BRATE_DEFAULT
#define FTCAN2_BASE 0x28207800
#define FTCAN2_IRQ 124
#define FTCAN2_BITRATE FTCAN_BRATE_DEFAULT
/* pad pin multi-function demux component */
#define PIN_DEMUX_BASE 0x28180000
#define REG200 0x200
#define REG204 0x204
#define REG208 0x208
#define CAN_TXD_0 (1<<24)
#define CAN_RXD_0 (1<<12)
#define CAN_TXD_1 (1<<20)
#define CAN_RXD_1 (1<<8)
#define CAN_TXD_2 (1<<16)
#define CAN_RXD_2 (1<<4)
#define I2C_2_SCL (2<<8) /* can_rxd_1 = I2C_2_scl: ONLY choose one component! */
#define I2C_2_SDA (2<<4) /* can_rxd_2 = i2c_2_sda */
#define FUNC1_GPIO1_PORTA_5 (1<<16)
#define FUNC1_GPIO1_PORTA_6 (1<<12)
/*
* FT2004C size usage
* 0x000_40000000~0x000_4FFFFFFF 256MB Config
* 0x000_50000000~0x000_57FFFFFF 128MB i/o
* 0x000_58000000~0x000_7FFFFFFF 640MB mem32
* 0x010_00000000~0x01F_FFFFFFFF 64GB mem64
*/
#define FT_PCI_CONFIG_ADDR 0x40000000
#define FT_PCI_CONFIG_LEN 0x10000000 /*256MB*/
#define CPU_IO_SPACE_OFFSET 0x50000000
#define FT_SECONDARY_BOOT_ADDR 0x8007fff0
typedef unsigned char u8, __u8, unchar;
typedef char s8, __s8;
typedef unsigned short u16, __u16, __be16;
typedef short s16, __s16;
typedef unsigned int u32, __u32, __be32, uint;
typedef int s32, __s32;
typedef unsigned long long u64;
/* ARM ARCH7 later. */
#define ISB __asm__ volatile ("isb sy" : : : "memory")
#define DSB __asm__ volatile ("dsb sy" : : : "memory")
#define DMB __asm__ volatile ("dmb sy" : : : "memory")
#define isb() ISB
#define dsb() DSB
#define dmb() DMB
/*
* Generic virtual read/write. Note that we don't support half-word
* read/writes. We define __arch_*[bl] here, and leave __arch_*w
* to the architecture specific code.
*/
#define __arch_getb(a) (*(volatile unsigned char *)(a))
#define __arch_getw(a) (*(volatile unsigned short *)(a))
#define __arch_getl(a) (*(volatile unsigned int *)(a))
#define __arch_getq(a) (*(volatile unsigned long long *)(a))
#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
#define __arch_putq(v,a) (*(volatile unsigned long long *)(a) = (v))
#define __raw_writeb(v,a) __arch_putb(v,a)
#define __raw_writew(v,a) __arch_putw(v,a)
#define __raw_writel(v,a) __arch_putl(v,a)
#define __raw_writeq(v,a) __arch_putq(v,a)
#define __raw_readb(a) __arch_getb(a)
#define __raw_readw(a) __arch_getw(a)
#define __raw_readl(a) __arch_getl(a)
#define __raw_readq(a) __arch_getq(a)
/*
* TODO: The kernel offers some more advanced versions of barriers, it might
* have some advantages to use them instead of the simple one here.
*/
#define mb() dsb()
#define __iormb() dmb()
#define __iowmb() dmb()
#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; })
#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; })
#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; })
#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; })
#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; })
#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; })
/* assembly functions */
void sys_icc_igrpen1_set(unsigned int);
unsigned int sys_icc_igrpen1_get(void);
void sys_icc_ctlr_set(unsigned int);
unsigned int sys_icc_hppir1_get(void);
void sys_icc_eoir1_set(unsigned int);
void sys_icc_pmr_set(unsigned int);
unsigned int sys_icc_iar1_get(void);
void sys_icc_dir_set(unsigned int);
void sys_icc_bpr1_set(unsigned int);
unsigned int sys_icc_sre_get(void);
unsigned int vxMpidrGet();
unsigned int sys_dfar_get();
unsigned int sys_dfsr_get();
unsigned int sys_ifar_get();
unsigned int sys_ifsr_get();
#ifdef __cplusplus
}
#endif
#endif /* __INCft2000_4_h */

697
genericPhy.c

@ -0,0 +1,697 @@
/* genericPhy.c - driver for generic 10/100/1000 ethernet PHY chips */
/*
* Copyright (c) 2005-2011, 2013-2017 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
14mar17,myt fix link issue for 82574L and I210T (VXW6-86128)
27jun16,fao fix the genPhyInit routine. (VXW6-85481)
30oct15,wyt release pDrvCtl in genPhyInstUnlink(). (VXW6-84942)
24jul15,d_l add flow control advertise selection. (VXW6-84701)
fix genPhyProbe comment. (VXW6-84685)
16mar15,p_x Use MII_CR_RESTART instead of reset to restart
auto negotiation in genPhyModeSet(). (VXW6-84227)
02feb15,p_x Support turning off auto-negotiation. (VXW6-83965)
16mar14,xms add handle error status. (VXW6-28077)
20jan14,xms optimize the genPhyInit routine. (VXW6-38227)
01r,04sep13,xms fix NULL_RETURNS error. (WIND00414265)
01q,27feb13,y_y Add timeout check when phy reset. (WIND00404792)
01p,15mar11,x_z Remove workaround for MICREL KS8001 rev3
01o,14sep10,d_c Cleanup debug prints
01n,10sep10,d_c Add debug prints
01m,06aug10,x_z Add workaround for MICREL KS8001 rev3.
01l,09dec09,h_k increased VxBus version.
01k,05may08,tor update version
01k,21mar08,z_l Fix 1000M mode support error. (WIND00120712)
01j,20sep07,tor VXB_VERSION_3
01i,05jul07,wap Be sure to initialize BMCR register correctly in genPhyInit()
01h,25oct06,wap Detect gigE mode in modeSet routine when autoneg is disabled
01g,17oct06,pdg replaced VXB_METHOD_DRIVER_UNLINK with an address
01f,20jun06,wap Advertise manually set modes
01e,25may06,wap Add removal support
01d,31jan06,pdg updated vxbus version
01c,19jan06,wap Fix probe routine, use correct extended caps bit in status
register
01b,05jan06,wap Swap InstInit2 and InstConnect methods
01a,15sep05,wap written
*/
/*
DESCRIPTION
This module implements generic PHY access routines for 10/100/1000 copper
ethernet PHYs that comply with the 802.3u MII specification. Methods
are provided to initialize the PHY, set the media mode and check
the current media mode and link status. Ideally, this driver should
work with any 10/100 MII PHY. In practice, this isn't always feasible.
Some chips have quirks that require the use of custom code. Also, the
MII spec does not cover the use of interrupts. Not all PHYs are capable
of generating interrupts, but those that do must be configured through
vendor-specific registers, meaning that providing generic interrupt
methods is pretty much impossible.
The methods are accessed by calling the genPhyMethodsGet() routine,
which returns a pointer to a phyFuncs structure that contains
function pointers to the method routines. The functions can be invoked
through convenience macros declared in phyLib.h.
The initialization method resets always resets the PHY to a known
state, usually by toggling the power down bit in the control register
and then setting the reset bit. Then it programs the PHY for
autonegotiation. Chip-specific drivers may also do additional
setup or fixups if necessary.
The mode set routine can be used to program the PHY for a specific
media configuration. The mode word is based on the generic ifmedia
mode definitions, i.e. IFM_AUTO, IFM_100_TX, IFM_10_T, IFM_FDX and
IFM_HDX. Selecting a specific mode (other than auto) programs the
PHY for just that mode. This can be used to force the chip to run
at 10, 100Mbps or 1000Mbps and full or half duplex.
The mode get routine retrieves the current link speed and duplex
mode (i.e. what the link setting is right now) and the link state.
If the IFM_ACTIVE bit is not set in the link state, then the mode
information is set to IFM_NONE (no link available).
The interrupt control method can be used to turn interrupts for
link state change events on or off. Interrupts may be generated
for duplex, speed and link state changes.
The interrupt acknowledge method acks any pending interrupts so
that the chip will de-assert its interrupt pin.
By default, this driver doesn't advertise the flow control ability
when do auto-negotiation. But this can be overrided by adding a
parameter to the VXB_INST_PARAM_OVERRIDE table in hwconf.c
{ "genericPhy", 0, "fcmode", VXB_PARAM_INT32, {(void *)<fcmode>} }
The <fcmode> selection can be MII_FCADV_NONE, MII_FCADV_PAUSE,
MII_FCADV_ASM, MII_FCADV_PAUSE_ASM.
*/
#include <vxWorks.h>
#include <vxBusLib.h>
#include <logLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/util/hwMemLib.h>
#include <hwif/util/vxbParamSys.h>
#include "miiBus.h"
#include <../src/hwif/h/mii/genericPhy.h>
/* defines */
#undef GENERICPHY_DEBUG
#ifdef GENERICPHY_DEBUG
#define GENERICPHY_LOGMSG(fmt,p1,p2,p3,p4,p5,p6) logMsg(fmt,p1,p2,p3,p4,p5,p6)
#else
#define GENERICPHY_LOGMSG(fmt,p1,p2,p3,p4,p5,p6)
#endif
/* externs */
IMPORT BOOL autoNegForce;
/* locals */
LOCAL void genPhyInit (VXB_DEVICE_ID);
LOCAL STATUS genPhyModeSet (VXB_DEVICE_ID, UINT32);
LOCAL STATUS genPhyModeGet (VXB_DEVICE_ID, UINT32 *, UINT32 *);
LOCAL STATUS genPhyIntCtl (VXB_DEVICE_ID, int);
LOCAL STATUS genPhyIntAck (VXB_DEVICE_ID);
LOCAL void genPhyDevInstInit(VXB_DEVICE_ID pDev);
LOCAL void genPhyDevInstInit2(VXB_DEVICE_ID pDev);
LOCAL void genPhyDevInstConnect(VXB_DEVICE_ID pDev);
LOCAL BOOL genPhyProbe(VXB_DEVICE_ID pDev);
LOCAL STATUS genPhyInstUnlink (VXB_DEVICE_ID, void *);
LOCAL device_method_t genPhyMethods[] =
{
DEVMETHOD(miiModeGet, genPhyModeGet),
DEVMETHOD(miiModeSet, genPhyModeSet),
DEVMETHOD(vxbDrvUnlink, genPhyInstUnlink),
{ 0, 0 }
};
LOCAL struct drvBusFuncs genPhyFuncs =
{
genPhyDevInstInit, /* devInstanceInit */
genPhyDevInstInit2, /* devInstanceInit2 */
genPhyDevInstConnect /* devInstanceConnect */
};
LOCAL VXB_PARAMETERS genPhyParamDefaults[] =
{
{"fcmode", VXB_PARAM_INT32, {(void *)MII_FCADV_NONE}},
{NULL, VXB_PARAM_END_OF_LIST, {NULL}}
};
struct vxbDevRegInfo genPhyDevRegistration =
{
NULL, /* pNext */
VXB_DEVID_DEVICE, /* devID */
VXB_BUSID_MII, /* busID = MII Bus */
VXB_VER_5_0_0, /* busVer */
"genericPhy", /* drvName */
&genPhyFuncs, /* pDrvBusFuncs */
genPhyMethods, /* pMethods */
genPhyProbe, /* devProbe */
genPhyParamDefaults /* parameter defaults */
};
void genPhyRegister(void)
{
vxbDevRegister (&genPhyDevRegistration);
return;
}
LOCAL void genPhyDevInstInit
(
VXB_DEVICE_ID pDev
)
{
vxbNextUnitGet (pDev);
return;
}
LOCAL void genPhyDevInstConnect
(
VXB_DEVICE_ID pDev
)
{
return;
}
/*********************************************************************
*
* genPhyInstUnlink - VxBus unlink handler
*
* This function implements the VxBus unlink method for this driver.
* We delete each media type that was originally added to the MII bus
* instance by this device and take ourselves off the miiMonitor task
* list.
*
* RETURNS: OK if shutdown succeeds, else ERROR
*
* ERRNO: N/A
*/
LOCAL STATUS genPhyInstUnlink
(
VXB_DEVICE_ID pDev,
void * unused
)
{
VXB_DEVICE_ID pBus;
MII_DRV_CTRL * pDrvCtrl;
UINT16 miiSts;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
if (pDrvCtrl->miiInitialized == FALSE)
return (ERROR);
/* Only our parent bus can delete us. */
if (pDrvCtrl->miiLeaving == FALSE)
return (ERROR);
/* Remove ourselves from the miiMonitor task list. */
miiBusListDel (pDev);
/* Remove media list entries. */
if ((pBus = vxbDevParent (pDev)) == NULL)
return (ERROR);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
if (miiSts & MII_SR_EXT_STS)
{
miiBusMediaDel (pBus, IFM_ETHER|IFM_1000_T);
miiBusMediaDel (pBus, IFM_ETHER|IFM_1000_T|IFM_FDX);
}
if (miiSts & MII_SR_TX_HALF_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_100_TX);
if (miiSts & MII_SR_TX_FULL_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_100_TX|IFM_FDX);
if (miiSts & MII_SR_10T_HALF_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_10_T);
if (miiSts & MII_SR_10T_FULL_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_10_T|IFM_FDX);
if (miiSts & MII_SR_AUTO_SEL)
miiBusMediaDel (pBus, IFM_ETHER|IFM_AUTO);
pDrvCtrl->miiInitialized = FALSE;
free (pDrvCtrl);
return (OK);
}
/*********************************************************************
*
* genPhyDevInstInit2 - vxBus instInit2 handler
*
* This routine does the final driver setup. The PHY registers
* its media types with its parent bus and adds itself to the MII
* monitoring list.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void genPhyDevInstInit2
(
VXB_DEVICE_ID pDev
)
{
VXB_DEVICE_ID pBus;
MII_DRV_CTRL * pDrvCtrl;
VXB_INST_PARAM_VALUE val;
UINT16 miiSts;
GENERICPHY_LOGMSG("genPhyDevInstInit2(): entry for pDev: 0x%x\n",
(int)pDev, 0,0,0,0,0);
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
if (pDrvCtrl->miiInitialized == TRUE)
{
GENERICPHY_LOGMSG("genPhyDevInstInit2(): already initialized\n",
0,0,0,0,0,0);
return;
}
pDrvCtrl->miiInitialized = TRUE;
/*
* Tell miiBus about the media we support.
*/
if ((pBus = vxbDevParent (pDev)) == NULL)
return;
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
if (miiSts & MII_SR_EXT_STS)
{
miiBusMediaAdd (pBus, IFM_ETHER|IFM_1000_T);
miiBusMediaAdd (pBus, IFM_ETHER|IFM_1000_T|IFM_FDX);
}
if (miiSts & MII_SR_TX_HALF_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_100_TX);
if (miiSts & MII_SR_TX_FULL_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_100_TX|IFM_FDX);
if (miiSts & MII_SR_10T_HALF_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_10_T);
if (miiSts & MII_SR_10T_FULL_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_10_T|IFM_FDX);
if (miiSts & MII_SR_AUTO_SEL)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_AUTO);
miiBusMediaDefaultSet (pBus, IFM_ETHER|IFM_AUTO);
/*
* Initialize the PHY. This may perform DSP code
* tweaking as needed.
*/
genPhyInit (pDev);
/* Add to the monitor list. */
miiBusListAdd (pDev);
/*
* paramDesc {
* The fcmode parameter specifies how we advertise
* the device flow control ability. The selection can be
* MII_FCADV_NONE, MII_FCADV_PAUSE, MII_FCADV_ASM,
* MII_FCADV_PAUSE_ASM. }
*/
if (vxbInstParamByNameGet (pDev, "fcmode", VXB_PARAM_INT32, &val) == OK)
{
pDrvCtrl->fcmode = (UINT16) (val.int32Val);
}
else
pDrvCtrl->fcmode = (UINT16) MII_FCADV_NONE;
return;
}
/*********************************************************************
*
* genPhyProbe - vxBus genericPhy probe handler
*
* This routine always returns TRUE.
*
* RETURNS: TRUE always.
*
* ERRNO: N/A
*/
LOCAL
BOOL genPhyProbe
(
VXB_DEVICE_ID pDev
)
{
return (TRUE);
}
LOCAL void genPhyInit
(
VXB_DEVICE_ID pDev
)
{
MII_DRV_CTRL * pDrvCtrl;
UINT16 miiSts;
UINT16 miiCtl;
UINT16 miiVal;
int i;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
/* Get status register so we can look for extended capabilities. */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
miiVal = MII_CR_POWER_DOWN;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
miiVal = 0;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
/* Set reset bit and then wait for it to clear. */
miiVal = MII_CR_RESET;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
for (i = 0; i < 1000; i++)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, &miiCtl);
if (!(miiCtl & MII_CR_RESET))
break;
}
if (i == 1000)
{
return;
}
/*
* If the extended capabilities bit is set, this is a gigE
* PHY, so make sure we advertise gigE modes.
*/
if (miiSts & MII_SR_EXT_STS)
{
/* Enable advertisement of gigE modes. */
miiVal = MII_MASSLA_CTRL_1000T_FD|MII_MASSLA_CTRL_1000T_HD;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, miiVal);
}
/*
* Some PHYs come out of reset with their isolate bit set. Make
* sure we don't write that bit back when setting the control
* register.
*/
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiCtl);
return;
}
LOCAL STATUS genPhyModeSet
(
VXB_DEVICE_ID pDev,
UINT32 mode
)
{
MII_DRV_CTRL * pDrvCtrl;
UINT16 miiVal;
UINT16 miiAnar = 0;
UINT16 gmiiAnar = 0;
UINT16 miiCtl = 0;
UINT16 miiSts;
BOOL autoneg = TRUE;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
/* Get status register so we can look for extended capabilities. */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
switch(IFM_SUBTYPE(mode)) {
case IFM_AUTO:
/* Set autoneg advertisement to advertise all modes. */
miiAnar = MII_ANAR_10TX_HD|MII_ANAR_10TX_FD|
MII_ANAR_100TX_HD|MII_ANAR_100TX_FD;
if (miiSts & MII_SR_EXT_STS)
gmiiAnar = MII_MASSLA_CTRL_1000T_FD|MII_MASSLA_CTRL_1000T_HD;
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
break;
case IFM_1000_T:
/* Auto-negotiation is mandatory per IEEE in 1000BASE-T. */
if (!(miiSts & MII_SR_EXT_STS))
return(ERROR);
if ((mode & IFM_GMASK) == IFM_FDX)
gmiiAnar = MII_MASSLA_CTRL_1000T_FD;
else
gmiiAnar = MII_MASSLA_CTRL_1000T_HD;
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
break;
case IFM_100_TX:
if (autoNegForce)
{
miiCtl = MII_CR_100|MII_CR_AUTO_EN|MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
{
miiAnar = MII_ANAR_100TX_FD;
miiCtl |= MII_CR_FDX;
}
else
miiAnar = MII_ANAR_100TX_HD;
}
else
{
autoneg = FALSE;
/*
* Intel's PHY requires restarting auto-negotiation
* or software reset in order for speed/duplex changes
* to take effect. Use restarting auto-neg here.
*/
miiCtl = MII_CR_100|MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
miiCtl |= MII_CR_FDX;
}
break;
case IFM_10_T:
if (autoNegForce)
{
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
{
miiAnar = MII_ANAR_10TX_FD;
miiCtl |= MII_CR_FDX;
}
else
miiAnar = MII_ANAR_10TX_HD;
}
else
{
autoneg = FALSE;
miiCtl = MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
miiCtl |= MII_CR_FDX;
}
break;
default:
return (ERROR);
}
genPhyInit (pDev);
/* set flow control advertise ability */
miiAnar |= (pDrvCtrl->fcmode) << MII_ANAR_PAUSE_SHIFT;
if (autoneg)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_AN_ADS_REG, &miiVal);
miiVal &= ~(MII_ANAR_10TX_HD|MII_ANAR_10TX_FD|
MII_ANAR_100TX_HD|MII_ANAR_100TX_FD);
miiVal |= miiAnar;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_AN_ADS_REG, miiVal);
if (miiSts & MII_SR_EXT_STS)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, &miiVal);
miiVal &= ~(MII_MASSLA_CTRL_1000T_HD|MII_MASSLA_CTRL_1000T_FD);
miiVal |= gmiiAnar;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, miiVal);
}
}
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, &miiVal);
miiVal &= ~(MII_CR_FDX|MII_CR_100|MII_CR_1000|MII_CR_AUTO_EN|MII_CR_RESTART);
miiVal |= miiCtl;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
return(OK);
}
LOCAL STATUS genPhyModeGet
(
VXB_DEVICE_ID pDev,
UINT32 * mode,
UINT32 * status
)
{
UINT16 miiSts;
UINT16 miiCtl;
UINT16 miiAnar;
UINT16 miiLpar;
UINT16 gmiiAnar = 0;
UINT16 gmiiLpar = 0;
UINT16 anlpar;
MII_DRV_CTRL * pDrvCtrl;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
*mode = IFM_ETHER;
*status = IFM_AVALID;
GENERICPHY_LOGMSG("genPhyModeGet(): entry\n", 0,0,0,0,0,0);
/* read MII status register once to unlatch link status bit */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
/* read again to know its current value */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
/* no link bit means no carrier. */
if (!(miiSts & MII_SR_LINK_STATUS) || (miiSts == 0xFFFF))
{
*mode |= IFM_NONE;
GENERICPHY_LOGMSG("genPhyModeGet(): pDev: 0x%x no carrier\n",
(int)pDev,0,0,0,0,0);
return (OK);
}
*status |= IFM_ACTIVE;
/*
* read the control, ability advertisement and link
* partner advertisement registers.
*/
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, &miiCtl);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_AN_ADS_REG, &miiAnar);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_AN_PRTN_REG, &miiLpar);
if (miiSts & MII_SR_EXT_STS)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, &gmiiAnar);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_STAT_REG, &gmiiLpar);
}
/*
* If autoneg is on, figure out the link settings from the
* advertisement and partner ability registers. If autoneg is
* off, use the settings in the control register.
*/
if (miiCtl & MII_CR_AUTO_EN)
{
anlpar = miiAnar & miiLpar;
if ((gmiiAnar & MII_MASSLA_CTRL_1000T_FD) && \
(gmiiLpar & MII_MASSLA_STAT_LP1000T_FD))
*mode |= IFM_1000_T|IFM_FDX;
else if ((gmiiAnar & MII_MASSLA_CTRL_1000T_HD) && \
(gmiiLpar & MII_MASSLA_STAT_LP1000T_HD))
*mode |= IFM_1000_T|IFM_HDX;
else if (anlpar & MII_ANAR_100TX_FD)
*mode |= IFM_100_TX|IFM_FDX;
else if (anlpar & MII_ANAR_100TX_HD)
*mode |= IFM_100_TX|IFM_HDX;
else if (anlpar & MII_ANAR_10TX_FD)
*mode |= IFM_10_T|IFM_FDX;
else if (anlpar & MII_ANAR_10TX_HD)
*mode |= IFM_10_T|IFM_HDX;
else
*mode |= IFM_NONE;
GENERICPHY_LOGMSG("genPhyModeGet(): pDev: 0x%x auto-neg ON,"
" mode: 0x%x\n", (int)pDev,(int)*mode,0,0,0,0);
}
else
{
if (miiCtl & MII_CR_FDX)
*mode |= IFM_FDX;
else
*mode |= IFM_HDX;
if ((miiCtl & (MII_CR_100 | MII_CR_1000)) == (MII_CR_100 | MII_CR_1000))
*mode |= IFM_1000_T;
else if (miiCtl & MII_CR_100)
*mode |= IFM_100_TX;
else
*mode |= IFM_10_T;
GENERICPHY_LOGMSG("genPhyModeGet(): pDev: 0x%x auto-neg off,"
" mode: 0x%x\n",(int)pDev,(int)*mode,0,0,0,0);
}
return (OK);
}
/*
* Enable or disable PHY interrupts. If no interrupts supported,
* return ERROR.
*/
LOCAL STATUS genPhyIntCtl
(
VXB_DEVICE_ID pDev,
int ctl
)
{
return (ERROR);
}
/*
* Ack PHY interrupts. Return OK if an interrupt was pending, error
* if not.
*/
LOCAL STATUS genPhyIntAck
(
VXB_DEVICE_ID pDev
)
{
return (ERROR);
}

555
hwconf.c

@ -0,0 +1,555 @@
/* hwconf.c - Hardware configuration support module */
/*
*
* 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.
*
*/
#include <vxWorks.h>
#include <vsbConfig.h>
#include <vxBusLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/vxbus/vxbIntrCtlr.h>
#include <hwif/util/vxbParamSys.h>
#include <hwif/vxbus/hwConf.h>
#include "config.h"
#include "ft2000-4.h"
#ifdef DRV_FTI2C
#include <hwif/vxbus/vxbI2cLib.h>
#endif
#ifdef DRV_FTQSPI
#include "vxbFtQspi.h"
#endif
#ifdef DRV_PCIBUS_FT
# include <drv/pci/pciAutoConfigLib.h>
#endif
#define GEN_TIMER_IRQ 30
#define AUX_GEN_TIMER_IRQ 27
#define SYS_CLK_REG_BASE 0xeeee0000
#define SYS_CLK_FREQ 50000000
#define AUX_CLK_REG_BASE 0xeeef0000
#define AUX_CLK_FREQ 50000000
#ifdef DRV_ARM_GICV3
LOCAL struct intrCtlrInputs gicInputs[] = {
/* pin, driver, unit, index */
{ GEN_TIMER_IRQ, "armGenTimer", 0, 0 },
#ifdef DRV_ARM_GEN_AUX_TIMER
{ AUX_GEN_TIMER_IRQ, "armAuxTimer", 0, 0 },
#endif
{ INT_VEC_UART0INTR, "primeCellSioDev", 0, 0 },
{ INT_VEC_UART1INTR, "primeCellSioDev", 1, 0 },
{ INT_VEC_UART2INTR, "primeCellSioDev", 2, 0 },
{ INT_VEC_UART3INTR, "primeCellSioDev", 3, 0 },
{ 81, "gmac", 0, 0 },
{ 82, "gmac", 1, 0 },
{ FTCAN0_IRQ, "ftCan", 0, 0 },
{ FTCAN1_IRQ, "ftCan", 1, 0 },
{ FTCAN2_IRQ, "ftCan", 2, 0 },
{ 60, "legacy", 0, 60 }, /* Peu0 legacy interrupt number : 60,61,62,63*/
{ 61, "legacy", 0, 61 },
{ 62, "legacy", 0, 62 },
{ 63, "legacy", 0, 63 },
{ 52, "ftSdhci", 0, 0 },
{ 53, "ftSdhci", 0, 1 },
{ 54, "ftSdhci", 0, 2 },
{ I2C_0_INTR_IRQ, "ftI2c", 0, 0 },
{ I2C_1_INTR_IRQ, "ftI2c", 1, 0 },
{ I2C_2_INTR_IRQ, "ftI2c", 2, 0 },
{ I2C_3_INTR_IRQ, "ftI2c", 3, 0 },
{ INT_VEC_GPIO0INTR, "ftGpio", 0, 0 },
{ INT_VEC_GPIO1INTR, "ftGpio", 1, 0 },
{ INT_VEC_GPIO0INTR, "legacy", 0, INT_VEC_GPIO0INTR },
{ INT_VEC_GPIO1INTR, "legacy", 0, INT_VEC_GPIO1INTR },
};
LOCAL const struct intrCtlrPriority gicPriority[] = {
/* pin, priority */
{ GEN_TIMER_IRQ, 0x0 },
#ifdef DRV_ARM_GEN_AUX_TIMER
{ AUX_GEN_TIMER_IRQ, 0x0 },
#endif
{ INT_VEC_UART0INTR, 0x10 },
{ INT_VEC_UART1INTR, 0x10 },
{ INT_VEC_UART2INTR, 0x10 },
{ INT_VEC_UART3INTR, 0x10 },
{ 81, 0x10 }, /*gmac0*/
{ 82, 0x10 }, /*gmac1*/
{ FTCAN0_IRQ, 0x10 },
{ FTCAN1_IRQ, 0x10 },
{ FTCAN2_IRQ, 0x10 },
{ 60, 0x10 }, /* Peu0 legacy interrupt number : 60,61,62,63*/
{ 61, 0x10 },
{ 62, 0x10 },
{ 63, 0x10 },
{ 52, 0x20 }, /*ftSdhci interrupt number : 52,53,54*/
{ 53, 0x20 },
{ 54, 0x20 },
{ I2C_0_INTR_IRQ, 0x20 },
{ I2C_1_INTR_IRQ, 0x20 },
{ I2C_2_INTR_IRQ, 0x20 },
{ I2C_3_INTR_IRQ, 0x20 },
{ INT_VEC_GPIO0INTR, 0x20 },
{ INT_VEC_GPIO1INTR, 0x20 },
};
#ifdef _WRS_CONFIG_SMP
struct intrCtlrCpu gicCpu[] = {
/* pin, CPU */
{ INT_VEC_UART0INTR, 0 },
{ INT_VEC_UART1INTR, 2 },
{ INT_VEC_UART2INTR, 0 },
{ INT_VEC_UART3INTR, 0 },
{ 81, 1 }, /*gmac0*/
{ 82, 0 }, /*gmac1*/
{ FTCAN0_IRQ, 0 },
{ FTCAN1_IRQ, 0 },
{ FTCAN2_IRQ, 0 },
{ 60, 0 }, /* Peu0 legacy interrupt number : 60,61,62,63*/
{ 61, 0 },
{ 62, 0 },
{ 63, 0 },
{ 52, 0 }, /*ftSdhci interrupt number : 52,53,54*/
{ 53, 0 },
{ 54, 0 },
{ I2C_0_INTR_IRQ, 0 },
{ I2C_1_INTR_IRQ, 3 },
{ I2C_2_INTR_IRQ, 0 },
{ I2C_3_INTR_IRQ, 0 },
{ INT_VEC_GPIO0INTR, 0 },
{ INT_VEC_GPIO1INTR, 0 },
};
#endif /* _WRS_CONFIG_SMP */
LOCAL const struct intrCtlrTrigger gicTrigger[] = {
/* pin, sensitivity */
{ INT_VEC_GPIO0INTR, VXB_INTR_TRIG_RISING_EDGE },
{ INT_VEC_GPIO1INTR, VXB_INTR_TRIG_RISING_EDGE },
};
/* dts info:
interrupt-controller;
reg = <0x0 0x29900000 0 0x20000>, GICD
<0x0 0x29980000 0 0x80000>, GICR
<0x0 0x29c00000 0 0x10000>, GICC
<0x0 0x29c10000 0 0x10000>, GICH
<0x0 0x29c20000 0 0x10000>; GICV
*/
/*
* interrupt mode - interrupts can be in either preemptive or non-preemptive
* mode. For preemptive mode, change INT_MODE to INT_PREEMPT_MODEL
*/
#define INT_MODE INT_NON_PREEMPT_MODEL
LOCAL const struct hcfResource armGICv3Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GIC_BASE_ADR } },
{ "distOffset", HCF_RES_INT, {(void *)0 } },
{ "redistOffset", HCF_RES_INT, {(void *)0x80000 } },
{ "input", HCF_RES_ADDR, {(void *)&gicInputs[0] } },
#ifdef _WRS_CONFIG_SMP
{ "cpuRoute", HCF_RES_ADDR, {(void *)&gicCpu[0] } },
{ "cpuRouteTableSize", HCF_RES_INT, {(void *)NELEMENTS(gicCpu) } },
#endif
{ "inputTableSize", HCF_RES_INT, {(void *)NELEMENTS(gicInputs) } },
{ "priority", HCF_RES_ADDR, {(void *)&gicPriority[0]} },
{ "priorityTableSize", HCF_RES_INT, {(void *)NELEMENTS(gicPriority) } },
{ "trigger", HCF_RES_ADDR, {(void *)&gicTrigger[0]} },
{ "triggerTableSize", HCF_RES_INT, {(void *)NELEMENTS(gicTrigger) } },
{ "intMode", HCF_RES_INT, {(void *)INT_MODE } },
#ifdef _WRS_CONFIG_SMP
{ "maxCpuNum", HCF_RES_INT, {(void *)4} },
#endif /* _WRS_CONFIG_SMP */
};
#define armGICv3Num NELEMENTS(armGICv3Resources)
#endif /* DRV_ARM_GICV3 */
struct hcfResource primeCellSioDev0Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)UART_0_BASE_ADR} },
{ "clkFreq", HCF_RES_INT, {(void *)FT2000_UART_CLK} },
};
#define primeCellSioDev0Num NELEMENTS(primeCellSioDev0Resources)
struct hcfResource primeCellSioDev1Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)UART_1_BASE_ADR} },
{ "clkFreq", HCF_RES_INT, {(void *)FT2000_UART_CLK} },
};
#define primeCellSioDev1Num NELEMENTS(primeCellSioDev1Resources)
struct hcfResource primeCellSioDev2Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)UART_2_BASE_ADR} },
{ "clkFreq", HCF_RES_INT, {(void *)FT2000_UART_CLK} },
};
#define primeCellSioDev2Num NELEMENTS(primeCellSioDev2Resources)
struct hcfResource primeCellSioDev3Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)UART_3_BASE_ADR} },
{ "clkFreq", HCF_RES_INT, {(void *)FT2000_UART_CLK} },
};
#define primeCellSioDev3Num NELEMENTS(primeCellSioDev3Resources)
struct hcfResource ftCanDev0Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)FTCAN0_BASE} },
{ "irq", HCF_RES_INT, {(void *)FTCAN0_IRQ} },
{ "bitrate", HCF_RES_INT, {(void *)FTCAN0_BITRATE} },
};
#define ftCanDev0Num NELEMENTS(ftCanDev0Resources)
struct hcfResource ftCanDev1Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)FTCAN1_BASE} },
{ "irq", HCF_RES_INT, {(void *)FTCAN1_IRQ} },
{ "bitrate", HCF_RES_INT, {(void *)FTCAN1_BITRATE} },
};
#define ftCanDev1Num NELEMENTS(ftCanDev1Resources)
struct hcfResource ftCanDev2Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)FTCAN2_BASE} },
{ "irq", HCF_RES_INT, {(void *)FTCAN2_IRQ} },
{ "bitrate", HCF_RES_INT, {(void *)FTCAN2_BITRATE} },
};
#define ftCanDev2Num NELEMENTS(ftCanDev2Resources)
#ifdef DRV_FTQSPI
struct vxbSpiDevInfo spiDevTbl[] = {
/* name cs width freq mode */
#ifdef DRV_SPIFLASH_SP25
{ SPI_FLASH_DEVICE_NAME, 0, 8, 30000000, 1},
#endif
};
struct hcfResource qspiResources[] = {
{ "regBase", HCF_RES_INT, { (void *)(0x28014000) } },
{ "capacity", HCF_RES_INT, { (void *)(QSPI_FLASH_CAP_32MB) } },
{ "clkDiv", HCF_RES_INT, { (void *)(QSPI_SCK_DIV_128) } },
{ "transMode", HCF_RES_INT, { (void *)(QSPI_TRANSFER_1_1_1) } },
{ "addrMode", HCF_RES_INT, { (void *)(QSPI_ADDR_SEL_3) } },
{ "spiDev", HCF_RES_ADDR, { (void *)&spiDevTbl[0]} },
{ "spiDevNum", HCF_RES_INT, { (void *)NELEMENTS(spiDevTbl)}},
};
# define qspiNum NELEMENTS(qspiResources)
#endif /* DRV_FTQSPI */
#ifdef DRV_FTI2C
LOCAL struct i2cDevInputs i2cDev0Input[] = {
/* Name */ /* Addr (7-bit) */ /* flag */
#ifdef DRV_I2C_EEPROM
{ "eeprom_at24c32", (0x57), I2C_WORDADDR },
#endif
};
struct hcfResource i2cDev0Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)REG_I2C0_BASE} },
{ "irq", HCF_RES_INT, {(void *)I2C_0_INTR_IRQ} },
{ "clkFreq", HCF_RES_INT,{(void *)FT2000_I2C_CLK} },
{ "busSpeed", HCF_RES_INT,{(void *)400000} },
{ "polling", HCF_RES_INT,{(void *)TRUE} },
{ "i2cDev", HCF_RES_ADDR, {(void *)&i2cDev0Input[0] } },
{ "i2cDevNum", HCF_RES_INT,{(void *)NELEMENTS(i2cDev0Input)} },
/* I2C0 pin default is I2C0. Need not DeMux.
{ "pinDemuxReg", HCF_RES_INT,{(void *)0} },
{ "pinDemuxBit", HCF_RES_INT,{(void *)0} },
*/
};
#define i2cDev0Num NELEMENTS(i2cDev0Resources)
LOCAL struct i2cDevInputs i2cDev1Input[] = {
/* Name */ /* Addr (7-bit) */ /* flag */
#ifdef DRV_I2C_RTC
{ "rtc_ds1339", (0xD0>>1), 0 },
#endif
};
struct hcfResource i2cDev1Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)REG_I2C1_BASE} },
{ "irq", HCF_RES_INT, {(void *)I2C_1_INTR_IRQ} },
{ "clkFreq", HCF_RES_INT,{(void *)FT2000_I2C_CLK} },
{ "busSpeed", HCF_RES_INT,{(void *)400000} },
{ "polling", HCF_RES_INT,{(void *)TRUE} },
{ "i2cDev", HCF_RES_ADDR, {(void *)&i2cDev1Input[0] } },
{ "i2cDevNum", HCF_RES_INT,{(void *)NELEMENTS(i2cDev1Input)} },
{ "pinDemuxReg", HCF_RES_INT,{(void *)0x28180200} }, /* pin MUX/DEMUX register */
{ "pinDemuxBit", HCF_RES_INT,{(void *)0x22000000} }, /* pin MUX/DEMUX bit value */
};
#define i2cDev1Num NELEMENTS(i2cDev1Resources)
LOCAL struct i2cDevInputs i2cDev2Input[] = {
};
struct hcfResource i2cDev2Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)REG_I2C2_BASE} },
{ "irq", HCF_RES_INT, {(void *)I2C_2_INTR_IRQ} },
{ "clkFreq", HCF_RES_INT,{(void *)FT2000_I2C_CLK} },
{ "busSpeed", HCF_RES_INT,{(void *)400000} },
{ "polling", HCF_RES_INT,{(void *)TRUE} },
{ "i2cDev", HCF_RES_ADDR, {(void *)&i2cDev2Input[0] } },
{ "i2cDevNum", HCF_RES_INT,{(void *)NELEMENTS(i2cDev2Input)} },
{ "pinDemuxReg", HCF_RES_INT,{(void *)0x28180204} }, /* pin MUX/DEMUX register */
{ "pinDemuxBit", HCF_RES_INT,{(void *)0x00000220} }, /* pin MUX/DEMUX bit value */
};
#define i2cDev2Num NELEMENTS(i2cDev2Resources)
LOCAL struct i2cDevInputs i2cDev3Input[] = {
};
struct hcfResource i2cDev3Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)REG_I2C3_BASE} },
{ "irq", HCF_RES_INT, {(void *)I2C_3_INTR_IRQ} },
{ "clkFreq", HCF_RES_INT,{(void *)FT2000_I2C_CLK} },
{ "busSpeed", HCF_RES_INT,{(void *)400000} },
{ "polling", HCF_RES_INT,{(void *)TRUE} },
{ "i2cDev", HCF_RES_ADDR, {(void *)&i2cDev3Input[0] } },
{ "i2cDevNum", HCF_RES_INT,{(void *)NELEMENTS(i2cDev3Input)} },
{ "pinDemuxReg", HCF_RES_INT,{(void *)0x28180204} }, /* pin MUX/DEMUX register */
{ "pinDemuxBit", HCF_RES_INT,{(void *)0x00000002} }, /* pin MUX/DEMUX bit value */
{ "pinDemuxRegEx", HCF_RES_INT,{(void *)0x28180208} }, /* pin MUX/DEMUX register */
{ "pinDemuxBitEx", HCF_RES_INT,{(void *)0x20000000} }, /* pin MUX/DEMUX bit value */
};
#define i2cDev3Num NELEMENTS(i2cDev3Resources)
#endif
#ifdef DRV_FTGPIO
/*This table is used to set the default pin mode of portA*/
LOCAL UINT8 gpio0PortAModeTable[] = {
/*pin of portA can be used as interrupt mode*/
/*portA-pinX: 0 1 2 3 4 5 6 7 */
3, 2, 1, 0, 0, 0, 0, 0 /* 0:GPIO_MODE_NOT_USED 1:GPIO_MODE_IN
2:GPIO_MODE_OUT 3:GPIO_MODE_INT*/
};
/*This table is used to set the default pin mode of portB*/
LOCAL UINT8 gpio0PortBModeTable[] = {
/*pin of portB can not be used as interrupt mode*/
/*portB-pinX: 0 1 2 3 4 5 6 7 */
1, 2, 1, 0, 0, 0, 0, 0
};
struct hcfResource gpioDev0Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_0_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio0PortAModeTable[0] } },
{ "portAModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio0PortAModeTable)} },
{ "portBModeTable", HCF_RES_ADDR, { (void *)&gpio0PortBModeTable[0] } },
{ "portBModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio0PortBModeTable)} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_RISING_EDGE} },
};
#define gpioDev0Num NELEMENTS(gpioDev0Resources)
LOCAL UINT8 gpio1PortAModeTable[] = {
/*portA-pinX: 0 1 2 3 4 5 6 7 */
0, 0, 0, 0, 0, 0, 0, 0 /* 0:GPIO_MODE_NOT_USED 1:GPIO_MODE_IN
2:GPIO_MODE_OUT 3:GPIO_MODE_INT*/
};
LOCAL UINT8 gpio1PortBModeTable[] = {
/*portB-pinX: 0 1 2 3 4 5 6 7 */
0, 0, 0, 0, 0, 0, 0, 0
};
struct hcfResource gpioDev1Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)GPIO_1_BASE_ADR } },
{ "portAModeTable", HCF_RES_ADDR, { (void *)&gpio1PortAModeTable[0] } },
{ "portAModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio1PortAModeTable)} },
{ "portBModeTable", HCF_RES_ADDR, { (void *)&gpio1PortBModeTable[0] } },
{ "portBModeTableNum", HCF_RES_INT, { (void *)NELEMENTS(gpio1PortBModeTable)} },
{ "trigger", HCF_RES_INT, { (void *)VXB_INTR_TRIG_RISING_EDGE} },
};
#define gpioDev1Num NELEMENTS(gpioDev1Resources)
#endif
#ifdef DRV_ARM_GEN_SYS_TIMER
struct hcfResource armGenSysTimerResources[] = {
{ "regBase", HCF_RES_INT, {(void *)0xeeee0000} },
{ "irq", HCF_RES_INT, {(void *)GEN_TIMER_IRQ} },
{ "clkFreq", HCF_RES_INT, {(void *)SYS_CLK_FREQ} },
{ "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} },
{ "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} },
};
#define armGenSysTimerNum NELEMENTS(armGenSysTimerResources)
#endif /* DRV_ARM_GEN_SYS_TIMER */
#ifdef DRV_ARM_GEN_AUX_TIMER
struct hcfResource armAuxGenTimerResources[] = {
{ "regBase", HCF_RES_INT, {(void *)AUX_CLK_REG_BASE} },
{ "irq", HCF_RES_INT, {(void *)AUX_GEN_TIMER_IRQ} },
{ "clkFreq", HCF_RES_INT, {(void *)AUX_CLK_FREQ} },
{ "minClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MIN} },
{ "maxClkRate", HCF_RES_INT, {(void *)SYS_CLK_RATE_MAX} },
};
#define armAuxGenTimerNum NELEMENTS(armAuxGenTimerResources)
#endif /* DRV_ARM_GEN_SYS_TIMER */
#ifdef DRV_PCIBUS_FT
IMPORT STATUS sysPciExAutoconfigInclude(PCI_SYSTEM *, PCI_LOC *, UINT);
IMPORT UCHAR sysPciExAutoconfigIntrAssign(PCI_SYSTEM *, PCI_LOC *, UCHAR);
IMPORT VOID sysPciPirqEnable (BOOL enable);
const struct hcfResource ftPci0Resources[] = {
{ "regBase", HCF_RES_INT, { (void *)(FT_PCI_CONFIG_ADDR) } },
{ "memIo32Addr", HCF_RES_ADDR, { (void *)0x58000000 } },
{ "memIo32Size", HCF_RES_INT, { (void *)0x27f00000 } },
{ "io32Addr", HCF_RES_ADDR, { (void *)0x50000000 } },
{ "io32Size", HCF_RES_INT, { (void *)0x08000000 } },
{ "io16Addr", HCF_RES_ADDR, { (void *)0x1000 } },
{ "io16Size", HCF_RES_INT, { (void *)0x0ffff000 } },
{ "ioStart", HCF_RES_ADDR, { (void *)0x50000000 } },
{ "fbbEnable", HCF_RES_INT, { (void *)TRUE } },
{ "cacheSize", HCF_RES_INT, { (void *)(8) } },
{ "maxLatAllSet", HCF_RES_INT, { (void *)0x40 } },
{ "autoIntRouteSet", HCF_RES_INT, { (void *)FALSE } },
{ "includeFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigInclude } },
{ "intAssignFuncSet", HCF_RES_ADDR, { (void *)sysPciExAutoconfigIntrAssign } },
{ "funcPirqEnable", HCF_RES_ADDR, { (void *)sysPciPirqEnable}},
{ "maxBusSet", HCF_RES_INT, { (void *)32 } },
/* Window Attributes - Defaults to 8540 type if none given */
{ "autoConfig", HCF_RES_INT, { (void *)(FALSE)} },
#ifdef INCLUDE_INTCTLR_DYNAMIC_LIB
{ "msiEnable", HCF_RES_INT, { (void *)(TRUE)} },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(TRUE)} }
#else
{ "msiEnable", HCF_RES_INT, { (void *)(FALSE)} },
{ "dynamicInterrupts", HCF_RES_INT, { (void *)(FALSE)} }
#endif /* INCLUDE_INTCTLR_DYNAMIC_LIB */
};
#define ftPci0Num NELEMENTS(ftPci0Resources)
#endif /* DRV_PCIBUS_M85XX */
LOCAL struct hcfResource ftSdhc0Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)FT_SDHC0_BASE} },
{ "clkFreq", HCF_RES_ADDR, {(void *)sysSdhcClkFreqGet} },
{ "polling", HCF_RES_INT, {(void *)TRUE} } /* interrupt mode dose not support*/
};
#define ftSdhc0Num NELEMENTS(ftSdhc0Resources)
#ifdef INCLUDE_PC_CONSOLE
LOCAL const struct hcfResource pentiumM6845VgaResources[] =
{
{ "colorMode", HCF_RES_INT, {(void *) 1} },
{ "colorSetting",HCF_RES_INT, {(void *) 0x1f} },
};
#define pentiumM6845VgaNum NELEMENTS(pentiumM6845VgaResources)
#endif
#ifdef DRV_VXBEND_FTGMAC
#define PHYADDR_OF_GREEN_BOARD 4 /* for reference green board. hardware V1 */
#define PHYADDR_OF_BLACK_BOARD 3 /* for reference black board. hardware V2 */
#define PHYADDR_OF_AUTO -1 /* auto probe when start */
struct hcfResource gmac0Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)0x2820c000} },
{ "phyAddr", HCF_RES_INT, {(void *)PHYADDR_OF_AUTO} },
{ "macAddrSet", HCF_RES_ADDR, {(void *)sysGmacAddrSet} },
{ "miiIfName", HCF_RES_STRING, {(void *)"gmac"} },
{ "miiIfUnit", HCF_RES_INT, {(void *)0} },
/*
* The clkMDC resource specifies the CSR clock range. Use clk_csr_i frequency
* to compute MDC clock frequency. To be sure MDC clock is in [1.0MHz ~2.5MHz] }
* Table GMII Address Register
* bit[5:2] clk_csr_i MDC clock
* 0000 60-100MHz clk_csr_i
* 0001 100-150 MHz clk_csr_i/62
* 0010 20-35 MHz clk_csr_i/16
* 0011 35-60 MHz clk_csr_i/26
* 0100 150-250 MHz clk_csr_i/102
* 0101 250-300 MHz clk_csr_i/124 <==
* 0110, 0111 Reserved
*/
{ "clkMDC", HCF_RES_INT, {(void *)0x5} }
};
#define gmac0Num NELEMENTS(gmac0Resources)
struct hcfResource gmac1Resources[] = {
{ "regBase", HCF_RES_INT, {(void *)0x28210000} },
{ "phyAddr", HCF_RES_INT, {(void *)PHYADDR_OF_AUTO} },
{ "macAddrSet", HCF_RES_ADDR, {(void *)sysGmacAddrSet} },
{ "miiIfName", HCF_RES_STRING, {(void *)"gmac"} },
{ "miiIfUnit", HCF_RES_INT, {(void *)1} },
{ "clkMDC", HCF_RES_INT, {(void *)0x5} }
};
#define gmac1Num NELEMENTS(gmac1Resources)
#endif /* DRV_VXBEND_FTGMAC */
const struct hcfDevice hcfDeviceList[] = {
#ifdef DRV_ARM_GICV3
{ "armGicDev", 0, VXB_BUSID_PLB, 0, armGICv3Num, armGICv3Resources},
#endif /* DRV_ARM_GIC */
{ "primeCellSioDev", 0, VXB_BUSID_PLB, 0, primeCellSioDev0Num , primeCellSioDev0Resources },
{ "primeCellSioDev", 1, VXB_BUSID_PLB, 0, primeCellSioDev1Num , primeCellSioDev1Resources },
{ "primeCellSioDev", 2, VXB_BUSID_PLB, 0, primeCellSioDev2Num , primeCellSioDev2Resources },
{ "primeCellSioDev", 3, VXB_BUSID_PLB, 0, primeCellSioDev3Num , primeCellSioDev3Resources },
#ifdef DRV_VXBEND_FTGMAC
{ "gmac", 0, VXB_BUSID_PLB, 0, gmac0Num, gmac0Resources},
{ "gmac", 1, VXB_BUSID_PLB, 0, gmac1Num, gmac1Resources},
#endif
#ifdef DRV_ARM_GEN_SYS_TIMER
{ "armGenTimer", 0, VXB_BUSID_PLB, 0, armGenSysTimerNum, armGenSysTimerResources },
#endif /* DRV_ARM_GEN_SYS_TIMER */
#ifdef DRV_ARM_GEN_AUX_TIMER
{ "armAuxTimer", 0, VXB_BUSID_PLB, 0, armAuxGenTimerNum, armAuxGenTimerResources },
#endif /* DRV_ARM_GEN_SYS_TIMER */
#ifdef DRV_PCIBUS_FT
{ "ftPcie", 0, VXB_BUSID_PLB, 0, ftPci0Num, ftPci0Resources },
#endif /* DRV_PCIBUS_M85XX */
#ifdef DRV_FTCAN
{ "ftCan", 0, VXB_BUSID_PLB, 0, ftCanDev0Num, ftCanDev0Resources },
{ "ftCan", 1, VXB_BUSID_PLB, 0, ftCanDev1Num, ftCanDev1Resources },
/*{ "ftCan", 2, VXB_BUSID_PLB, 0, ftCanDev2Num, ftCanDev2Resources },*/
#endif
#ifdef INCLUDE_FT_SD
{ "ftSdhci",0,VXB_BUSID_PLB, 0,ftSdhc0Num, ftSdhc0Resources },
#endif
#ifdef INCLUDE_PC_CONSOLE
{ "m6845Vga", 0, VXB_BUSID_PLB, 0, pentiumM6845VgaNum, pentiumM6845VgaResources },
#endif
#ifdef DRV_FTI2C
{ "ftI2c", 0, VXB_BUSID_PLB, 0, i2cDev0Num, i2cDev0Resources },
{ "ftI2c", 1, VXB_BUSID_PLB, 0, i2cDev1Num, i2cDev1Resources },
/* CAN1,CAN2 & I2C_2: ONLY choose ONE. (pad pin demux) */
/*
{ "ftI2c", 2, VXB_BUSID_PLB, 0, i2cDev2Num, i2cDev2Resources },
{ "ftI2c", 3, VXB_BUSID_PLB, 0, i2cDev3Num, i2cDev3Resources },
*/
#endif
#ifdef DRV_FTQSPI
{ FT_QSPI_NAME, 0, VXB_BUSID_PLB, 0, qspiNum, qspiResources },
#endif
#ifdef DRV_FTGPIO
{ "ftGpio", 0, VXB_BUSID_PLB, 0, gpioDev0Num, gpioDev0Resources },
{ "ftGpio", 1, VXB_BUSID_PLB, 0, gpioDev1Num, gpioDev1Resources },
#endif
};
const int hcfDeviceNum = NELEMENTS(hcfDeviceList);
VXB_INST_PARAM_OVERRIDE sysInstParamTable[] =
{
{ NULL, 0, NULL, VXB_PARAM_END_OF_LIST, {(void *)0} }
};

11803
hwif/vxbPci.bc

File diff suppressed because it is too large

BIN
lib/libFtX100dcdrv.a

Binary file not shown.

87
miiBus.h

@ -0,0 +1,87 @@
/* miiBus.h - MII bus controller and API library */
/* Copyright (c) 2005-2008, 2012, 2013, 2015 Wind River Systems, Inc. */
/*
modification history
--------------------
24jul15,d_l add flow control advertise ability support. (VXW6-84701)
31dec13,xms add miiBusLpiModeGet routine. (WIND00440439)
01g,10jan12,rec WIND00326681 - miiBusMonitor task polling inhibits power
management. Add miiBusQuiesce and miiBusWakeup.
01f,04sep08,wap Add miiBusIdleErrorCheck() routine (WIND00129165)
01e,29mar07,tor update methods
01d,05sep06,kch Replaced if_media.h include with endMedia.h.
01c,20jun06,wap Remove prototype for vxbNextUnitGet
01b,25may06,wap Add support for miibus device deletion
01a,04dec05,wap Written.
*/
#ifndef __INCmiiBush
#define __INCmiiBush
#include <lstLib.h>
#include <miiLib.h>
#include <endLib.h>
#include <endMedia.h>
#include <vxBusLib.h>
#define IDR2_OUILSB 0xfc00 /* OUI LSB */
#define IDR2_MODEL 0x03f0 /* vendor model */
#define IDR2_REV 0x000f /* vendor revision */
#define MII_OUI(id1, id2) (((id1) << 6) | ((id2) >> 10))
#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4)
#define MII_REV(id2) ((id2) & IDR2_REV)
/* Flow control ability */
#define MII_FCADV_NONE (0)
#define MII_FCADV_PAUSE (1)
#define MII_FCADV_ASM (2)
#define MII_FCADV_PAUSE_ASM (MII_FCADV_PAUSE|MII_FCADV_ASM)
#define MII_ANAR_PAUSE_SHIFT (10)
IMPORT void miiBusRegister(void);
IMPORT STATUS miiBusCreate(VXB_DEVICE_ID, VXB_DEVICE_ID *);
IMPORT STATUS miiBusDelete(VXB_DEVICE_ID);
IMPORT STATUS miiBusGet(VXB_DEVICE_ID, VXB_DEVICE_ID *);
IMPORT STATUS miiBusRead(VXB_DEVICE_ID, int, int, UINT16 *);
IMPORT STATUS miiBusWrite(VXB_DEVICE_ID, int, int, UINT16);
IMPORT STATUS miiBusLpiModeGet(VXB_DEVICE_ID, UINT16 *);
IMPORT STATUS miiBusModeGet(VXB_DEVICE_ID, UINT32 *, UINT32 *);
IMPORT STATUS miiBusModeSet(VXB_DEVICE_ID, UINT32);
IMPORT STATUS miiBusMediaUpdate(VXB_DEVICE_ID);
IMPORT STATUS miiBusMediaAdd(VXB_DEVICE_ID, UINT32);
IMPORT STATUS miiBusMediaDel(VXB_DEVICE_ID, UINT32);
IMPORT STATUS miiBusMediaDefaultSet(VXB_DEVICE_ID, UINT32);
IMPORT STATUS miiBusMediaListGet(VXB_DEVICE_ID, END_MEDIALIST **);
IMPORT void miiBusListAdd(VXB_DEVICE_ID);
IMPORT void miiBusListDel(VXB_DEVICE_ID);
IMPORT STATUS miiBusIdleErrorCheck(VXB_DEVICE_ID);
#ifdef _WRS_CONFIG_PWR_MGMT
IMPORT STATUS miiBusQuiesce (void);
IMPORT void miiBusWakeup (void);
IMPORT STATUS miiBusStateSet(UINT32 state, void * context);
#endif /* _WRS_CONFIG_PWR_MGMT */
typedef struct mii_drv_ctrl
{
NODE miiNode;
VXB_DEVICE_ID miiSelf;
VXB_DEVICE_ID miiParent;
VXB_DEVICE_ID miiActivePhy;
int miiPhyCnt;
VXB_DEVICE_ID miiPhyList[32];
BOOL miiInitialized;
int miiPhyAddr;
UINT16 miiId1;
UINT16 miiId2;
UINT16 miiSts;
BOOL miiLeaving;
END_MEDIALIST *miiMediaList;
UINT16 fcmode;
} MII_DRV_CTRL;
#endif /* __INCmiiBush */

127
pcConsole.h

@ -0,0 +1,127 @@
/* pcConsole.h - PC Keyboard and VGA Controller header file */
/*
* Copyright (c) 1984-2007, 2010 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01f,09feb10,jc0 LP64 adaptation.
01e,20feb07,pmr converted to VxBus.
01d,06dec01,jlb options to send scan codes and set LEDs
01c,12oct99,jmb fix build warning, conflict with SH cpu type
01b,29sep98,fle made it refgen parsable
01a,24sep93,vin created
*/
#ifndef __INCpcConsoleh
#define __INCpcConsoleh
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ASMLANGUAGE
#include <tyLib.h>
/* typedefs */
typedef int (*PC_CON_WRITE_FUNCPTR)(void *);
IMPORT TY_DEV * pcConDevBind (int, PC_CON_WRITE_FUNCPTR, void *);
/* pc console device descriptor */
typedef struct /* PC_CON_DEV */
{
TY_DEV tyDev;
BOOL created; /* true if this device is created */
int number; /* number for this console */
PC_CON_WRITE_FUNCPTR pWriteFunc; /* video tyWrite routine */
void * pWriteArg; /* argument for this routine */
} PC_CON_DEV;
typedef struct
{
int unit;
int * pArg;
BOOL get;
} VGA_QUERY;
/* ioctl and attribute definitions */
#define CONIOSETATRB 1001
#define CONIOGETATRB 1002
#define CONIOSETKBD 1003
#define CONIOSCREENREV 1004
#define CONIOBEEP 1005
#define CONIOCURSORON 1006
#define CONIOCURSOROFF 1007
#define CONIOCURSORMOVE 1008
#define CONIOCURCONSOLE 1009
#define CONIOCONVERTSCAN 1010
#define CONIOLEDS 1011
#define UNDERLINE 0x01 /* only if monochrome */
#define ATRB_FG_BLACK 0x00
#define ATRB_FG_BLUE 0x01
#define ATRB_FG_GREEN 0x02
#define ATRB_FG_CYAN 0x03
#define ATRB_FG_RED 0x04
#define ATRB_FG_MAGENTA 0x05
#define ATRB_FG_BROWN 0x06
#define ATRB_FG_WHITE 0x07
#define ATRB_BRIGHT 0x08
#define ATRB_FG_GRAY (ATRB_FG_BLACK | ATRB_BRIGHT)
#define ATRB_FG_LIGHTBLUE (ATRB_FG_BLUE | ATRB_BRIGHT)
#define ATRB_FG_LIGHTGREEN (ATRB_FG_GREEN | ATRB_BRIGHT)
#define ATRB_FG_LIGHTCYAN (ATRB_FG_CYAN | ATRB_BRIGHT)
#define ATRB_FG_LIGHTRED (ATRB_FG_RED | ATRB_BRIGHT)
#define ATRB_FG_LIGHTMAGENTA (ATRB_FG_MAGENTA | ATRB_BRIGHT)
#define ATRB_FG_YELLOW (ATRB_FG_BROWN | ATRB_BRIGHT)
#define ATRB_FG_BRIGHTWHITE (ATRB_FG_WHITE | ATRB_BRIGHT)
#define ATRB_BG_BLACK 0x00
#define ATRB_BG_BLUE 0x10
#define ATRB_BG_GREEN 0x20
#define ATRB_BG_CYAN 0x30
#define ATRB_BG_RED 0x40
#define ATRB_BG_MAGENTA 0x50
#define ATRB_BG_BROWN 0x60
#define ATRB_BG_WHITE 0x70
#define ATRB_BLINK 0x80
#define ATRB_CHR_REV 0x0100
#define MONO 0
#define COLOR 1
#define JAPANES_KBD 0
#define ENGLISH_KBD 1
/* function declarations */
#if defined(__STDC__) || defined(__cplusplus)
extern int pcConDrv (void);
extern int pcConDevCreate (char *name, FAST int channel, size_t rdBufSize,
size_t wrtBufSize);
#else
extern int pcConDrv ();
extern int pcConDevCreate ();
#endif /* __STDC__ */
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* __INCpcConsoleh */

455
pciCfgIntStub.c

@ -0,0 +1,455 @@
/* pciCfgIntStub.c - BSP stub for PCI shared interrupts */
/*
*
* 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.
*
*/
#include <vxWorks.h>
#include <hwif/util/hwMemLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/vxbus/vxbPlbLib.h>
#include <hwif/vxbus/hwConf.h>
#include "vxbPciLib.h"
#include <drv/pci/pciConfigLib.h>
#include <drv/pci/pciIntLib.h>
#include <drv/pci/pciAutoConfigLib.h>
IMPORT VXB_DEVICE_ID globalBusCtrlID;
/* macros */
/*
* PCI_INT_BASE: PCI base IRQ number (not intNum) is
* - IRQ 0 in the PIC or VIRTUAL_WIRE mode
* - IRQ 0 in the SYMMETRIC_IO mode
*/
#define PCI_INT_BASE (0)
/* typedefs */
/* globals */
typedef struct _PIRQ_ENABLE_ARG
{
BOOL enable;
} PIRQ_ENABLE_ARG;
VOID sysPciPirqEnable (BOOL enable);
/* locals */
/*
* These globals (glbMpApicNioint, glbMpApicNloint, glbMpApicInterruptTable)
* are used in pciConfigIntStub.c, they avoid calling
* through vxbus and reduces overhead, potential spinLock nesting...
*
* They are only present for INCLUDE_SYMMETRIC_IO_MODE, used with IO APIC.
*/
/* store PCI bridge device information */
struct pciBridgeDevice
{
int bus; /* bridge bus number */
int dev;
int func;
int priBus; /* priBus bus number */
int secBus; /* child bsu number*/
int pin; /* bridge's int pin */
int type; /* P2P or Card Bus */
struct pciBridgeDevice *pNext; /* next bridge pointer */
};
/* pci bridge device list pointer */
LOCAL struct pciBridgeDevice * pPciBridgeList = NULL ;
LOCAL UCHAR sysPciIntRoute [4][4] =
{
{
1, 2,
3, 4
},
{
2, 3,
4, 1
},
{
3, 4,
1, 2
},
{
4, 1,
2, 3
}
};
/*****************************************************************************
*
* sysPciRootFind - find the root of a PCI<->PCI bridge tree
*
* This function returns the root of a PCI<->PCI bridge tree, given the <bus>
* number of a leaf PCI bus. The MPtable data contains interrupt pin to IRQ
* mappings based soley on the root slot where a PCI<->PCI bridge is attached,
* so for a given device on the other side of a bridge (or group of bridges),
* we have to climb up the tree from the leaf bridge to get the information
* for the root node.
*
* RETURNS: pointer to root PCI bridge device, or NULL if not found
*
* ERRNO: N/A
*/
struct pciBridgeDevice * sysPciRootFind
(
VXB_DEVICE_ID ctrl,
int bus,
UINT8 pin
)
{
struct pciBridgeDevice * pList;
struct pciBridgeDevice * pNext;
pList = pPciBridgeList;
while (pList != NULL)
{
if (pList->secBus == bus)
break;
pList = pList->pNext;
}
if (pList != NULL)
{
pNext = sysPciRootFind (ctrl, pList->priBus, pin);
if (pNext != NULL)
pList = pNext;
}
return (pList);
}
/*****************************************************************************
*
* sysPciPinSwizzle - apply PCI<->PCI bridge swizzle to an interrupt pin
*
* This function modifies the interrupt pin value for a PCI device using
* the "swizzle" algorithm required when a device is on the other side of a
* PCI<->PCI bridge. For devices on the other side of a bridge, a
* transformation must be applied to the pin number if the slot number is
* not 0 and not a multiple of 4. For those cases, the four INTA/B/C/D
* interrupt pins are rotated in a "barber pole" pattern, sometimes also
* called a swizzle
*
* The critical thing here is that the transformation must be applied at
* all bridging levels, all the way up to the root slot (pri bus == 0).
* This means that if a device is separated from the root slot by several
* PCI<->PCI brides, multiple rounds of swizzling may be needed to obtain
* the INTx pin number for the root slot.
*
* RETURNS: swizzled pin number
*
* ERRNO: N/A
*/
LOCAL int sysPciPinSwizzle
(
VXB_DEVICE_ID ctrl,
int bus,
int dev,
int func,
int pin
)
{
struct pciBridgeDevice * pList;
int finalpin = -1;
/* If we're already on the root bus, no swizzle is needed. */
if (bus == 0)
return (pin);
/*
* If we reached a node with an MP entry, then we can stop
* swizzling here too.
*/
finalpin = sysPciIntRoute[dev & 3][pin - 1];
pList = pPciBridgeList;
while (pList != NULL)
{
if (pList->secBus == bus)
break;
pList = pList->pNext;
}
if (pList != NULL)
finalpin = sysPciPinSwizzle (ctrl, pList->priBus,
pList->dev, pList->func, finalpin);
return (finalpin);
}
/*******************************************************************************
*
* sysPciProgIrq - program a interrupt line register
*
* This function is responsible for write interrupt line register in
* symmetric IO mode.
*
* RETURNS: return ERROR/irq number
*
*/
LOCAL void sysPciProgIrq
(
VXB_DEVICE_ID ctrl,
int bus,
int dev,
int func,
void * arg,
int irq
)
{
PIRQ_ENABLE_ARG * pArg = arg;
if (irq > 0xff)
return;
if (pArg->enable)
{
if (vxbPciConfigOutByte (ctrl, bus, dev, func, PCI_CFG_DEV_INT_LINE,
irq) == ERROR)
{
return;
}
}
}
/*******************************************************************************
*
* sysPciFindBridge - scan and store the bridge device information
*
* This function is responsible for find bridge
*
* RETURNS: OK
* ERROR on PCI Config Space read failure or memory allocation failure
*
*/
LOCAL STATUS sysPciFindBridge
(
VXB_DEVICE_ID ctrl,
int bus,
int dev,
int func,
void * arg
)
{
UINT16 pciClass; /* Class field of function */
UINT8 priBus, secBus, subBus, pin;
struct pciBridgeDevice *pList;
static struct pciBridgeDevice *pListPri = NULL;
if (pciConfigInWord (bus, dev, func, PCI_CFG_SUBCLASS, &pciClass) != OK)
{
return ERROR; /* PCI read failure */
}
if ((pciClass == ((PCI_CLASS_BRIDGE_CTLR << 8) |
PCI_SUBCLASS_P2P_BRIDGE)) ||
(pciClass == ((PCI_CLASS_BRIDGE_CTLR << 8) |
PCI_SUBCLASS_CARDBUS_BRIDGE)))
{
pList = (struct pciBridgeDevice *)
hwMemAlloc(sizeof(struct pciBridgeDevice));
if (pList != NULL)
{
if (pListPri != NULL)
{
pListPri->pNext = pList;
}
}
else
{
return ERROR;
}
(void) vxbPciConfigInByte (ctrl, bus, dev, func, PCI_CFG_PRIMARY_BUS,
(UINT8 *)&priBus);
(void) vxbPciConfigInByte (ctrl, bus, dev, func, PCI_CFG_SECONDARY_BUS,
(UINT8 *)&secBus);
(void) vxbPciConfigInByte (ctrl, bus, dev, func, PCI_CFG_SUBORDINATE_BUS,
(UINT8 *)&subBus);
(void) vxbPciConfigInByte (ctrl, bus, dev, func, PCI_CFG_BRG_INT_PIN,
(UINT8 *)&pin);
pList->bus = bus;
pList->dev = dev;
pList->func = func;
pList->priBus = priBus;
pList->secBus = secBus;
pList->pNext = NULL;
pList->pin = pin;
pList->type = pciClass;
pListPri = pList;
if (pPciBridgeList == NULL)
pPciBridgeList = pList;
}
return OK;
}
/*******************************************************************************
*
* sysPciPirqEnable2 - scan mptable and configure device interrupt line
*
* This function is responsible configure device interrupt line base on mptable
*
* RETURNS: OK or ERROR
*
*/
LOCAL UCHAR sysPeu0IntRoute[4] = {60, 61, 62, 63};
LOCAL UCHAR sysPeu1IntRoute[4] = {60, 61, 62, 63};
LOCAL STATUS sysPciPirqEnable2
(
VXB_DEVICE_ID ctrl,
int bus,
int dev,
int func,
void * arg
)
{
UINT8 pin, pinPri;
int irq = 0, copyBus, copyDev, copyPin;
struct pciBridgeDevice * pList = pPciBridgeList ;
struct pciBridgeDevice * pRoot;
if (vxbPciConfigInByte (ctrl, bus, dev, func, PCI_CFG_DEV_INT_PIN,
(UINT8 *)&pin) == ERROR)
{
return ERROR;
}
if ((pin > 4) || (pin == 0))
return OK;
{
copyBus = bus;
copyDev = dev;
copyPin = pin;
/* try to use PCI specification method */
while (pList)
{
/* TODO, if ARI enable dev = 0 */
/* Swizzle the pin number. */
pinPri = sysPciPinSwizzle (ctrl, copyBus, copyDev, 0, copyPin);
while (pList)
{
if (pList->secBus == copyBus)
break;
pList = pList->pNext;
}
if (pList == NULL)
return OK;
if ((pList->type == ((PCI_CLASS_BRIDGE_CTLR << 8) |
PCI_SUBCLASS_CARDBUS_BRIDGE)) &&
(pList->pin != 0))
pinPri = pList->pin;
pRoot = sysPciRootFind (ctrl, copyBus, pinPri);
if (pRoot == NULL)
irq = ERROR;
else
irq = sysPeu0IntRoute[pinPri-1];
if (irq != ERROR )
{
sysPciProgIrq (ctrl, bus, dev, func, arg, irq);
return OK;
}
if ((pList->bus == 0) &&
(pList->priBus == 0))
return OK;
/*
* MP entry not found for this intermediate bridge.
* Prepare to climb up the bridge tree. (VXW6-8220)
*/
copyPin = pinPri + 1;
copyDev = pList->dev;
copyBus = pList->bus;
pList = pPciBridgeList; /* rescan from a root bridge */
}
}
return OK;
}
/***********************************************************************
*
* sysPciPirqEnable - enable or disbable PCI PIRQ direct handling
*
* This routine enables or disbales the PCI PIRQ direct handling.
*
* RETURNS: N/A
*/
VOID sysPciPirqEnable
(
BOOL enable /* TRUE to enable, FALSE to disable */
)
{
/*
* Can't use pciConfigInLong() because it depends upon the
* software device lists which haven't been initialized yet.
*/
PIRQ_ENABLE_ARG arg;
VXB_DEVICE_ID ctrl = globalBusCtrlID;
arg.enable = enable;
/* Take action based on each and every device/function/pin combination */
/* return value of vxbPciConfigForeachFunc() not used */
(void) vxbPciConfigForeachFunc (ctrl, 0, TRUE,
(VXB_PCI_FOREACH_FUNC)sysPciFindBridge,
&arg,0);
(void) vxbPciConfigForeachFunc (ctrl, 0, TRUE,
(VXB_PCI_FOREACH_FUNC)sysPciPirqEnable2,
&arg,0);
}

940
sysALib.s

@ -0,0 +1,940 @@
/* sysALib.s - 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;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#define _ASMLANGUAGE
#include <vxWorks.h>
#include <vsbConfig.h>
#include <asm.h>
#include <regs.h>
#include <arch/arm/arm.h>
#include <arch/arm/mmuArmLib.h>
#include <arch/arm/cacheArmArch7.h>
#include <sysLib.h>
#include "config.h"
#ifdef _WRS_CONFIG_SMP
# include <private/windLibP.h>
# include <private/vxSmpP.h>
#endif /* _WRS_CONFIG_SMP */
#undef ARM_AARCH64
#undef SLAVE_ARM_AARCH64
/* macros */
/* uncomment to enable the static MMU, it is only available when LPAE enabled. */
/* D-cache enable, Control Register bit */
#define SYS_CTL_DCACHE_ENABLE (0x1 << 2)
/* I-cache enable, Control Register bit */
#define SYS_CTL_ICACHE_ENABLE (0x1 << 12)
/* SMP mode enable, Aux Ctrl register bit */
#define AUX_CTL_SMP_MODE_EN (0x1 << 6)
/* invalidate branch target buffer with I-cache, Aux Ctrl register bit */
#define AUX_CTL_BTB_INVAL_EN (0x1)
/* force in-order D-cache requests to same set/way, Aux Ctrl register bit */
#define AUX_CTL_INORDER_DCACHE_REQ_EN (0x1 << 23)
/* internals */
FUNC_EXPORT(sysInit) /* start of system code */
#ifndef _ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK
FUNC_EXPORT(sysIntStackSplit) /* routine to split interrupt stack */
#endif /* !_ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK */
FUNC_EXPORT(archPwrDown) /* power down callback */
#ifdef _WRS_CONFIG_SMP
FUNC_EXPORT(sysCpuInit) /* secondary CPU initialization */
FUNC_EXPORT(sysMPCoreApResetLoop) /* secondary CPU Reset loop */
DATA_EXPORT(sysMPCoreStartup) /* startup Data for secondary CPUs */
#endif /* _WRS_CONFIG_SMP */
.globl FUNC(arm_mmu_ttbr)
.globl FUNC(armv7a_secondary_wake)
.globl FUNC(arm_int_enable)
.globl FUNC(arm_cpu_phy_index)
/* externals */
FUNC_IMPORT(usrInit) /* system initialization routine */
FUNC_IMPORT(excVBARSet) /* set exception address */
FUNC_EXPORT(__inline__GetVirtTimerCnt)
FUNC_EXPORT(__inline__GetPhyTimerCnt)
FUNC_EXPORT(__inline__ArmGicIpiGen)
#ifndef _ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK
DATA_IMPORT(vxSvcIntStackBase) /* base of SVC-mode interrupt stack */
DATA_IMPORT(vxSvcIntStackEnd) /* end of SVC-mode interrupt stack */
DATA_IMPORT(vxIrqIntStackBase) /* base of IRQ-mode interrupt stack */
DATA_IMPORT(vxIrqIntStackEnd) /* end of IRQ-mode interrupt stack */
#endif /* !_ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK */
#ifdef _WRS_CONFIG_SMP
DATA_IMPORT(vxKernelVars)
#endif /* _WRS_CONFIG_SMP */
.globl FUNC(sys_icc_igrpen1_set)
.globl FUNC(sys_icc_igrpen1_get)
.globl FUNC(sys_icc_ctlr_set)
.globl FUNC(sys_icc_bpr1_set)
.globl FUNC(sys_icc_hppir1_get)
.globl FUNC(sys_icc_eoir1_set)
.globl FUNC(sys_icc_pmr_set)
.globl FUNC(sys_icc_pmr_get)
.globl FUNC(sys_icc_rpr_get)
.globl FUNC(sys_icc_iar1_get)
.globl FUNC(vxMpidrGet)
.globl FUNC(armSmcCall)
.globl FUNC(sys_cntkctl_get)
.globl FUNC(sys_dfar_get)
.globl FUNC(sys_dfsr_get)
.globl FUNC(sys_ifar_get)
.globl FUNC(sys_ifsr_get)
.text
.balign 4
/*******************************************************************************
*
* sysInit - start after boot
*
* This routine is the system start-up entry point for VxWorks in RAM, the
* first code executed after booting. It disables interrupts, sets up
* the stack, and jumps to the C routine usrInit() in usrConfig.c.
*
* The initial stack is set to grow down from the address of sysInit(). This
* stack is used only by usrInit() and is never used again. Memory for the
* stack must be accounted for when determining the system load address.
*
* NOTE: This routine should not be called by the user.
*
* RETURNS: N/A
*
* void sysInit (UINT32 startType) /@ THIS IS NOT A CALLABLE ROUTINE @/
*
*/
FUNC_BEGIN(sysInit)
#ifdef ARM_AARCH64
.long 0xd5384240 /* mrs x0, currentel */
.long 0xd342fc00 /* lsr x0, x0, #2 */
.long 0x92400400 /* and x0, x0, #0x3 */
.long 0xf1000c1f /* cmp x0, #0x3 */
.long 0x540003a1 /* b.ne 1d0080c4 <el2_mode> */
el3_mode:
.long 0xd53ecca0 /* mrs x0, s3_6_c12_c12_5 - ICC_SRE_EL3 */
.long 0xb2400c00 /* orr x0, x0, #0xf */
.long 0xd51ecca0 /* msr s3_6_c12_c12_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */
.long 0xb2400c00 /* orr x0, x0, #0xf */
.long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */
.long 0xb2400000 /* orr x0, x0, #0x1 */
.long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd2803620 /* mov x0, #0x1b1 */
.long 0xd51e1100 /* msr scr_el3, x0 */
.long 0xd2867fe0 /* mov x0, #0x33ff */
.long 0xd51c1140 /* msr cptr_el2, x0 */
.long 0xd2810000 /* mov x0, #0x800 */
.long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */
.long 0xd5181000 /* msr sctlr_el1, x0 */
.long 0x910003e0 /* mov x0, sp */
.long 0xd51c4100 /* msr sp_el1, x0 */
.long 0xd53ec000 /* mrs x0, vbar_el3 */
.long 0xd518c000 /* msr vbar_el1, x0 */
.long 0xd2803a60 /* mov x0, #0x1d3 */
.long 0xd51e4000 /* msr spsr_el3, x0 */
.long 0x10000500 /* adr x0, 1d008158 <el1_mode> */
.long 0xd51e4020 /* msr elr_el3, x0 */
.long 0xd69f03e0 /* eret */
el2_mode:
.long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */
.long 0xb2400c00 /* orr x0, x0, #0xf */
.long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */
.long 0xb2400000 /* orr x0, x0, #0x1 */
.long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd53ce100 /* mrs x0, cnthctl_el2 */
.long 0xb2400400 /* orr x0, x0, #0x3 */
.long 0xd51ce100 /* msr cnthctl_el2, x0 */
.long 0xd51ce07f /* msr cntvoff_el2, xzr */
.long 0xd5380000 /* mrs x0, midr_el1 */
.long 0xd53800a1 /* mrs x1, mpidr_el1 */
.long 0xd51c0000 /* msr vpidr_el2, x0 */
.long 0xd51c00a1 /* msr vmpidr_el2, x1 */
.long 0xd2867fe0 /* mov x0, #0x33ff */
.long 0xd51c1140 /* msr cptr_el2, x0 */
.long 0xd51c117f /* msr hstr_el2, xzr */
.long 0xd2a00600 /* mov x0, #0x300000 */
.long 0xd5181040 /* msr cpacr_el1, x0 */
.long 0xd2800000 /* mov x0, #0x0 */
.long 0xb2630000 /* orr x0, x0, #0x20000000 */
.long 0xd51c1100 /* msr hcr_el2, x0 */
.long 0xd53c1100 /* mrs x0, hcr_el2 */
.long 0xd2810000 /* mov x0, #0x800 */
.long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */
.long 0xd5181000 /* msr sctlr_el1, x0 */
.long 0x910003e0 /* mov x0, sp */
.long 0xd51c4100 /* msr sp_el1, x0 */
.long 0xd53cc000 /* mrs x0, vbar_el2 */
.long 0xd518c000 /* msr vbar_el1, x0 */
.long 0xd2803a60 /* mov x0, #0x1d3 */
.long 0xd51c4000 /* msr spsr_el2, x0 */
.long 0x10000060 /* adr x0, 1d008158 <el1_mode> */
.long 0xd51c4020 /* msr elr_el2, x0 */
.long 0xd69f03e0 /* eret */
el1_mode:
#endif /* ARM_AARCH64 */
MOV r12, r0 /* save startType */
/* Set initial stack pointer so stack grows down from start of code */
ADR sp, FUNC(sysInit) /* Initialize stack pointer */
/*
* Set the processor to a known state: the reset state with
* MMU and caches disabled and program flow/branch prediction enabled.
* See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition"
* (ARM DDI 0406) and "Cortex-A15 Processor Technical Reference Manual"
* (ARM DDI 0438) for details.
*/
MRC p15, 0, r2, c1, c0, 0 /* Read control register into r2 */
LDR r1, =MMU_INIT_VALUE /* Defined in mmuCortexA8Lib.h */
MCR p15, 0, r1, c1, c0, 0 /* Write to control register */
ISB /* Ensure processor state is set */
/* invalidate the data caches, flushing them if necessary */
LDR r1, =SYS_CTL_DCACHE_ENABLE
AND r2, r2, r1
TEQ r2, r1 /* Check if data caches were enabled */
BNE dCacheFlushBypass
/*
* Note the following about _CORTEX_AR_ENTIRE_DATA_CACHE_OP:
* Registers r0-r3 are modified, r4-r8 are preserved via the stack and
* a DSB is performed before returning.
*/
_CORTEX_AR_ENTIRE_DATA_CACHE_OP (c14) /* Flush & invalidate data caches */
B dCacheInvalDone
dCacheFlushBypass:
_CORTEX_AR_ENTIRE_DATA_CACHE_OP (c6) /* Invalidate data caches */
dCacheInvalDone:
ISB /* Instruction Synch Barrier */
/* set Context ID Register to zero, including Address Space ID */
MCR p15, 0, r1, c13, c0, 1
/* disable interrupts in CPU and switch to SVC32 mode */
MRS r1, cpsr
BIC r1, r1, #MASK_MODE
ORR r1, r1, #MODE_SVC32 | I_BIT | F_BIT
MSR cpsr, r1
ADR sp, FUNC(sysInit) /* Initialize stack pointer */
MOV fp, #0 /* Initialize frame pointer */
/* Make sure Boot type is set correctly. */
MOV r0, r12 /* restore startType */
MOV r1,#BOOT_NORMAL
CMP r1,r0
BEQ L$_Good_Boot
MOV r1,#BOOT_NO_AUTOBOOT
CMP r1,r0
BEQ L$_Good_Boot
MOV r1,#BOOT_CLEAR
CMP r1,r0
BEQ L$_Good_Boot
MOV r1,#BOOT_QUICK_AUTOBOOT
CMP r1,r0
BEQ L$_Good_Boot
MOV r0, #BOOT_NORMAL /* default startType */
L$_Good_Boot:
/* now call usrInit (startType) */
B FUNC(usrInit)
FUNC_END(sysInit)
#ifndef _ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK
/*******************************************************************************
*
* sysIntStackSplit - split interrupt stack and set interrupt stack pointers
*
* This routine is called, via a function pointer, during kernel
* initialisation. It splits the allocated interrupt stack into IRQ and
* SVC-mode stacks and sets the processor's IRQ stack pointer. Note that
* the pointer passed points to the bottom of the stack allocated i.e.
* highest address+1.
*
* IRQ stack needs 6 words per nested interrupt;
* SVC-mode will need a good deal more for the C interrupt handlers.
* For now, use ratio 1:7 with any excess allocated to the SVC-mode stack
* at the lowest address.
*
* Note that FIQ is not handled by VxWorks so no stack is allocated for it.
*
* The stacks and the variables that describe them look like this.
* \cs
*
* - HIGH MEMORY -
* ------------------------ <--- vxIrqIntStackBase (r0 on entry)
* | |
* | IRQ-mode |
* | interrupt stack |
* | |
* ------------------------ <--{ vxIrqIntStackEnd
* | | { vxSvcIntStackBase
* | SVC-mode |
* | interrupt stack |
* | |
* ------------------------ <--- vxSvcIntStackEnd
* - LOW MEMORY -
* \ce
*
* NOTE: This routine should not be called by the user.
*
* void sysIntStackSplit
* (
* char *pBotStack /@ pointer to bottom of interrupt stack @/
* long size /@ size of stack @/
* )
*/
FUNC_BEGIN(sysIntStackSplit)
/*
* r0 = base of space allocated for stacks (i.e. highest address)
* r1 = size of space
*/
SUB r2, r0, r1 /* r2->lowest usable address */
LDR r3, =vxSvcIntStackEnd
STR r2, [r3] /* == end of SVC-mode stack */
SUB r2, r0, r1, ASR #3 /* leave 1/8 for IRQ */
LDR r3, =vxSvcIntStackBase
STR r2, [r3]
/* now allocate IRQ stack, setting irq_sp */
LDR r3, =vxIrqIntStackEnd
STR r2, [r3]
LDR r3, =vxIrqIntStackBase
STR r0, [r3]
MRS r2, cpsr
BIC r3, r2, #MASK_MODE
ORR r3, r3, #MODE_IRQ32 | I_BIT /* set irq_sp */
MSR cpsr, r3
MOV sp, r0
/* switch back to original mode and return */
MSR cpsr, r2
MOV pc, lr
FUNC_END(sysIntStackSplit)
#endif /* !_ARCH_SUPPORTS_PROTECT_INTERRUPT_STACK */
_ARM_FUNCTION_CALLED_FROM_C(arm_int_enable)
MRS r1, cpsr
BIC r1, r1, #(I_BIT | F_BIT)
MSR cpsr, r1
MOV pc,lr
_ARM_FUNCTION_CALLED_FROM_C(armv7a_secondary_wake)
DSB
SEV
ISB
#if (ARM_THUMB)
BX lr
#else
MOV pc,lr
#endif
_ARM_FUNCTION_CALLED_FROM_C(arm_cpu_phy_index)
MRC p15, 0, r0, c0, c0, 5
AND r0, r0, #0x0f
MOV pc,lr
/*******************************************************************************
*
* archPwrDown - turn the processor into reduced power mode
*
* This routine activates the reduced power mode.
* It is called by the scheduler when the kernel enters the idle loop.
* This function is called by default. Overload it by using routine
* vxArchPowerDownRtnSet().
*
* RETURNS: void.
*
* SEE ALSO: vxArchPowerDownRtnSet().
*
* void archPwrDown (void)
*
*/
FUNC_BEGIN(archPwrDown)
/*
* NB debugger doesn't like powering down.
* Use foreverloop for debug.
*foreverLoop:
* B foreverLoop
*/
/*
* Write to coprocessor 15 register 7 (the core control)
* register to set idle
*/
MOV r0, #PWRMODE_IDLE
MCR CP_CORECTL, 0, r0, c7, c0, 4 /* idle processor */
/* Return after waking up */
MOV pc, lr
FUNC_END(archPwrDown)
#ifdef _WRS_CONFIG_SMP
/*******************************************************************************
*
* sysCpuInit - Entry point for non-boot CPUs
*
* This routine performs initial CPU init, copies startup parameters
* from the sysMPCoreStartup structure, and enters sysCpuStart to
* complete the per-CPU startup.
*
* There are no arguments to this routine.
*
* RETURNS: Does not return.
*
*/
FUNC_BEGIN(sysCpuInit)
#ifdef SLAVE_ARM_AARCH64
.long 0xd5384240 /* mrs x0, currentel */
.long 0xd342fc00 /* lsr x0, x0, #2 */
.long 0x92400400 /* and x0, x0, #0x3 */
.long 0xf1000c1f /* cmp x0, #0x3 */
.long 0x540003a1 /* b.ne 1d0080c4 <slave_el2_mode> */
slave_el3_mode:
.long 0xd53ecca0 /* mrs x0, s3_6_c12_c12_5 - ICC_SRE_EL3 */
.long 0xb2400c00 /* orr x0, x0, #0xf */
.long 0xd51ecca0 /* msr s3_6_c12_c12_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */
.long 0xb2400c00 /* orr x0, x0, #0xf */
.long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */
.long 0xb2400000 /* orr x0, x0, #0x1 */
.long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd2803620 /* mov x0, #0x1b1 */
.long 0xd51e1100 /* msr scr_el3, x0 */
.long 0xd2867fe0 /* mov x0, #0x33ff */
.long 0xd51c1140 /* msr cptr_el2, x0 */
.long 0xd2810000 /* mov x0, #0x800 */
.long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */
.long 0xd5181000 /* msr sctlr_el1, x0 */
.long 0x910003e0 /* mov x0, sp */
.long 0xd51c4100 /* msr sp_el1, x0 */
.long 0xd53ec000 /* mrs x0, vbar_el3 */
.long 0xd518c000 /* msr vbar_el1, x0 */
.long 0xd2803a60 /* mov x0, #0x1d3 */
.long 0xd51e4000 /* msr spsr_el3, x0 */
.long 0x10000500 /* adr x0, 1d008158 <slave_el1_mode> */
.long 0xd51e4020 /* msr elr_el3, x0 */
.long 0xd69f03e0 /* eret */
slave_el2_mode:
.long 0xd53cc9a0 /* mrs x0, s3_4_c12_c9_5 - ICC_SRE_EL2 */
.long 0xb2400c00 /* orr x0, x0, #0xf */
.long 0xd51cc9a0 /* msr s3_4_c12_c9_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd538cca0 /* mrs x0, s3_0_c12_c12_5 - ICC_SRE_EL1 */
.long 0xb2400000 /* orr x0, x0, #0x1 */
.long 0xd518cca0 /* msr s3_0_c12_c12_5, x0 */
.long 0xd5033fdf /* isb */
.long 0xd53ce100 /* mrs x0, cnthctl_el2 */
.long 0xb2400400 /* orr x0, x0, #0x3 */
.long 0xd51ce100 /* msr cnthctl_el2, x0 */
.long 0xd51ce07f /* msr cntvoff_el2, xzr */
.long 0xd5380000 /* mrs x0, midr_el1 */
.long 0xd53800a1 /* mrs x1, mpidr_el1 */
.long 0xd51c0000 /* msr vpidr_el2, x0 */
.long 0xd51c00a1 /* msr vmpidr_el2, x1 */
.long 0xd2867fe0 /* mov x0, #0x33ff */
.long 0xd51c1140 /* msr cptr_el2, x0 */
.long 0xd51c117f /* msr hstr_el2, xzr */
.long 0xd2a00600 /* mov x0, #0x300000 */
.long 0xd5181040 /* msr cpacr_el1, x0 */
.long 0xd2800000 /* mov x0, #0x0 */
.long 0xb2630000 /* orr x0, x0, #0x20000000 */
.long 0xd51c1100 /* msr hcr_el2, x0 */
.long 0xd53c1100 /* mrs x0, hcr_el2 */
.long 0xd2810000 /* mov x0, #0x800 */
.long 0xf2a61a00 /* movk x0, #0x30d0, lsl #16 */
.long 0xd5181000 /* msr sctlr_el1, x0 */
.long 0x910003e0 /* mov x0, sp */
.long 0xd51c4100 /* msr sp_el1, x0 */
.long 0xd53cc000 /* mrs x0, vbar_el2 */
.long 0xd518c000 /* msr vbar_el1, x0 */
.long 0xd2803a60 /* mov x0, #0x1d3 */
.long 0xd51c4000 /* msr spsr_el2, x0 */
.long 0x10000060 /* adr x0, 1d008158 <slave_el1_mode> */
.long 0xd51c4020 /* msr elr_el2, x0 */
.long 0xd69f03e0 /* eret */
slave_el1_mode:
#endif /* ARM_AARCH64 */
/* disable interrupts in CPU and switch to SVC32 mode */
#if 0
ldr r2, =0x28001000
mov r1, #0x41
strb r1,[r2]
ISB
DSB
#endif
MRS r1, cpsr
BIC r1, r1, #MASK_MODE
ORR r1, r1, #MODE_SVC32 | I_BIT | F_BIT
MSR cpsr, r1
/*
* SPSR does not have pre-defined reset value.
* Here correct endianess (BE bit) in SPSR
*/
MRS r0, spsr
BIC r0, r0, #(0x1 << 9) /* Little Endian */
MSR spsr_x, r0
/*
* Set the processor to a known state: the reset state with
* MMU and caches disabled and program flow/branch prediction enabled.
* See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition"
* (ARM DDI 0406) and "Cortex-A15 Processor Technical Reference Manual"
* (ARM DDI 0438) for details.
*/
LDR r1, =MMU_INIT_VALUE /* Defined in mmuArmLib.h */
MCR p15, 0, r1, c1, c0, 0 /* Write to control register */
ISB /* Ensure processor state is set */
/*
* _CORTEX_AR_ENTIRE_DATA_CACHE_OP macro uses the stack to save and
* restore registers, so set the stack pointer before the macro is called.
*/
LDR sp, =startupStack
/*
* Flush & invalidate the data caches.
*
* Note the following about _CORTEX_AR_ENTIRE_DATA_CACHE_OP:
* Registers r0-r3 are modified, other registers used are preserved via
* the stack and a DSB is performed before returning.
*/
_CORTEX_AR_ENTIRE_DATA_CACHE_OP (c14) /* Flush & invalidate data caches */
/* Invalidate TLBs */
MCR p15, 0, r1, c8, c7, 0 /* R1 = 0 from above, data SBZ */
/* Set Context ID Register to zero, including Address Space ID */
MOV r1, #0
MCR p15, 0, r1, c13, c0, 1
/* set exception base address */
MOV r0, #LOCAL_MEM_LOCAL_ADRS
BL FUNC(excVBARSet)
/* Get cpuIndex */
#if 0
MRC p15, 0, r5, c0, c0, 5
MOV r0, r5
MOV r0, r0, LSR#6
AND r5, r5, #0xF
ADD r5, r5, r0
AND r5, r5, #0xF
#else
MRC p15, 0, r5, c0, c0, 5
AND r2, r5, #0xff
MOVS r5, r5, LSR #8
AND r3, r5, #0xff
MOVS r3, r3, LSL#1
ADDS r5, r2, r3
#endif
/* Get the address of the startup data, sysMPCoreStartup[cpuIndex] */
#ifndef _WRS_CONFIG_ARM_LPAE
MOV r4, r5, LSL #4
#else /* _WRS_CONFIG_ARM_LPAE */
MOV r4, #24
MUL r4, r4, r5
#endif /* !_WRS_CONFIG_ARM_LPAE */
LDR r0, =sysMPCoreStartup
ADD r4, r4, r0
/*
* Set the Translation Table Base Register
*
* r4 = Pointer to the startup data for this CPU
*/
#ifndef _WRS_CONFIG_ARM_LPAE
LDR r0, [r4, #0xC] /* Get Trans. Tbl Base address */
MOV r1, #VXWORKS_KERNEL_ASID
BL mmuCortexA8TtbrSetAll
#else /* _WRS_CONFIG_ARM_LPAE */
LDR r0, [r4, #0xC] /* Get Trans. Tbl Base Ctrl address */
BL mmuCortexA8TtbcrSet
LDR r0, [r4, #0x10] /* Get Trans. Tbl Base Low address */
LDR r1, [r4, #0x14] /* Get Trans. Tbl Base High address */
BL mmuCortexA8TtbrSet64
#endif /* !_WRS_CONFIG_ARM_LPAE */
#ifndef _WRS_CONFIG_ARM_LPAE
MOV r0, #MMU_DACR_VAL_NORMAL
BL mmuCortexA8DacrSet
#else /* _WRS_CONFIG_ARM_LPAE */
LDR r0, =MMU_MAIR0_VALUE
LDR r1, =MMU_MAIR1_VALUE
BL mmuCortexA8MairSet
#endif /* !_WRS_CONFIG_ARM_LPAE */
/* Enable MMU and caches */
LDR r0, =(SYS_CTL_ICACHE_ENABLE | SYS_CTL_DCACHE_ENABLE)
BL mmuCortexA8AEnable
/* Save the cache state */
MOV r2, r0
_ARM_PER_CPU_ADRS_GET(r0, r1, cacheArchState)
STR r2, [r0]
/*
* Clear the kernel interrupt counter and
* architecture interrupt nesting counter.
* This is needed because the secondary CPU startup process
* will bypass the normal interrupt exit path (intExit).
*/
_ARM_PER_CPU_ADRS_GET(r0, r1, intCnt)
MOV r1, #0
STR r1, [r0]
_ARM_PER_CPU_ADRS_GET(r0, r1, intNestingLevel)
MOV r1, #0
STR r1, [r0]
/*
* r4 = Pointer to sysMPCoreStartup arguments array
* r5 = CPU number
*
* Set up call to start VxWorks such that:
*
* r0 = vxWorks Kernel Entry point
* r1 = CPU number
* r2 = CPU startup entry point, sysCpuStart
*
*/
LDR sp, [r4, #4] /* set the kernel stack pointer */
MOV r1, r5
sysMPCoreApStartLoop:
LDR r2, [r4]
CMP r2, #0
LDRNE r0, [r4, #8] /* Load vxWorks Kernel Entry point */
BLXNE r2 /* Enter vxWorks */
FUNC_END(sysCpuInit)
#endif /* _WRS_CONFIG_SMP */
/******************************************************************************/
/*
* PC-relative-addressable pointers
* note "_" after "$" to stop preprocessor preforming substitution
*/
.balign 4
#ifdef _WRS_CONFIG_SMP
L$_vxKernelVars:
.long FUNC(vxKernelVars)
L$_arm_mmu_ttbr:
.long FUNC(arm_mmu_ttbr)
arm_mmu_ttbr:
.long 0
#endif /* _WRS_CONFIG_SMP */
/*******************************************************************************
*
* Array used for passing startup parameters from boot CPU to secondary CPUs,
* aligned on a cache line.
*
* struct sysMPCoreStartup
* {
* 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 @/
* #else /@ _WRS_CONFIG_ARM_LPAE @/
* UINT32 ttbcr; /@ Translation Table Base Control Register @/
* UINT64 newSync; /@ Translation Table Base and sync @/
* #endif /@ !_WRS_CONFIG_ARM_LPAE @/
* };
*/
.data
.balign 64
VAR_LABEL(sysMPCoreStartup)
#ifndef _WRS_CONFIG_ARM_LPAE
.fill 32,4 /* array for 4 cores */
#else /* _WRS_CONFIG_ARM_LPAE */
.fill 48,4 /* array for 4 cores */
#endif /* !_WRS_CONFIG_ARM_LPAE */
.text
.balign 4
/* void sys_icc_igrpen1_set(unsigned int) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_igrpen1_set)
mcr p15, 0, r0, c12, c12, 7
isb
mov pc, lr
/* void sys_icc_igrpen1_get(unsigned int) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_igrpen1_get)
mrc p15, 0, r0, c12, c12, 7
isb
mov pc, lr
/* void sys_icc_ctlr_set(unsigned int) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_ctlr_set)
mcr p15, 0, r0, c12, c12, 4
mov pc, lr
/* unsigned int sys_icc_hppir1_get(void) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_hppir1_get)
mrc p15, 0, r0, c12, c12, 2
isb
mov pc, lr
/* void sys_icc_bpr1_set(unsigned int) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_bpr1_set)
mcr p15, 0, r0, c12, c12, 3
isb
mov pc, lr
/* void sys_icc_eoir1_set(unsigned int) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_eoir1_set)
mcr p15, 0, r0, c12, c12, 1
isb
mov pc, lr
/* void sys_icc_pmr_set(unsigned int) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_pmr_set)
mcr p15, 0, r0, c4, c6, 0
isb
mov pc, lr
/* unsigned int sys_icc_pmr_get(void) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_pmr_get)
mrc p15, 0, r0, c4, c6, 0
isb
mov pc, lr
/* unsigned int sys_icc_rpr_get(void). read only */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_rpr_get)
mrc p15, 0, r0, c12, c11, 3
isb
mov pc, lr
/* unsigned int sys_icc_iar1_get(void) */
_ARM_FUNCTION_CALLED_FROM_C(sys_icc_iar1_get)
mrc p15, 0, r0, c12, c12, 0
isb
mov pc, lr
/* unsigned int sys_cntkctl_get(void) */
_ARM_FUNCTION_CALLED_FROM_C(sys_cntkctl_get)
mcr p15, 0, r0, c14, c1, 0
isb
mov pc, lr
_ARM_FUNCTION_CALLED_FROM_C(sys_dfar_get)
MRC p15,0,r0,c6,c0,0
isb
mov pc, lr
_ARM_FUNCTION_CALLED_FROM_C(sys_dfsr_get)
MRC p15,0,r0,c5,c0,0
isb
mov pc, lr
_ARM_FUNCTION_CALLED_FROM_C(sys_ifar_get)
MRC p15,0,r0,c6,c0,2
isb
mov pc, lr
_ARM_FUNCTION_CALLED_FROM_C(sys_ifsr_get)
MRC p15,0,r0,c5,c0,1
isb
mov pc, lr
#if 0
_ARM_FUNCTION_CALLED_FROM_C(vxCpsrGet)
MRS r0, cpsr
isb
mov pc, lr
#endif
_ARM_FUNCTION_CALLED_FROM_C(vxMpidrGet)
MRC p15, 0, r0, c0, c0, 5
MOV pc, lr
.code 32
.balign 4
/*******************************************************************************
*
* armSmcCall - initiate SMC call
*
* This routine initiates SMC call which traps the processor into Monitor Mode.
* The ARM SMC Call Convetion defines that up to eight registers can be exchanged
* during an SMC call. The input parameter contains eight INT32 valeus which are
* to be passed in the SMC call; similarily the output parameter also contains
* eight INT32 values which are returned from the SMC call.
*
* \NOMANUAL
*
* RETURNS: OK
*
* void armSmcCall
* (
* ARM_SMC_REGS * input, /@ r0 - input register values @/
* ARM_SMC_REGS * output /@ r1 - output register values @/
* )
*/
FUNC_BEGIN(armSmcCall)
stmdb sp!, {r0-r7} /* save clobbered registers to stack */
ldr r12, [sp, #(4 * 0)] /* get 1st argument (ptr to input struct) */
ldmia r12, {r0-r7} /* save input argument to r0-r7 */
smc #0
ldr r12, [sp, #(4 * 1)] /* get 2th argument (ptr to output result) */
stmia r12, {r0-r7} /* get output argument from r0-r7 */
ldmfd sp!, {r0-r7} /* restore clobbered registers from stack */
bx lr
FUNC_END(armSmcCall)
FUNC_BEGIN(__inline__GetVirtTimerCnt)
DSB
.long 0xec510f1e /* mrrc p15, 1, r0, r1, c14 */
ISB
MOV pc, lr
FUNC_END(__inline__GetVirtTimerCnt)
FUNC_BEGIN(__inline__GetPhyTimerCnt)
DSB
.long 0xec510f0e /* mrrc p15, 0, r0, r1, c14 */
ISB
MOV pc, lr
FUNC_END(__inline__GetPhyTimerCnt)
#ifdef __DCC__
FUNC_BEGIN( __inline__ArmGicIpiGen)
DSB
.word 0xec410f0c /*MCRR p15,0,r0,r1,c12*/
ISB
MOV pc, lr
FUNC_END(__inline__ArmGicIpiGen)
#endif
/*******************************************************************************
*
* Temporary stack for secondary core.
* Align on a separate cache line to avoid conflict with boot core's cache
* contents during the secondary core's initial cache cleaning.
*/
.balign 64
.fill 6,4 /* depth of 6 registers */
VAR_LABEL(startupStack)

1247
sysLib.c

File diff suppressed because it is too large

2098
sysTffs.c

File diff suppressed because it is too large

519
target.ref

@ -0,0 +1,519 @@
\" ft2000-4/target.ref - 飞腾FT-2000四核开发板描述文档
\"--------------------------------------------------------------------------------
简介
FT-2000/4 是一款面向桌面应用的高性能通用4 核处理器。每2 个核构成1
个处理器核簇(Cluster),并共享L2 Cache。主要技术特征如下:
* 兼容ARM v8 64 位指令系统,兼容32 位指令
* 支持单精度、双精度浮点运算指令
* 支持ASIMD 处理指令
* L2 Cache:每个Cluster内有2MB,共4MB;FT-2000/4工业级单核版L2Cache 2MB
* L3 Cache:分为8个Bank,共4MB
* 集成2 个DDR4-3200控制器
* 集成34 Lanes PCIe3.0 接口:2 个X16(每个可拆分成2 个X8),2 个X1
* 集成2 个千兆Ethernet(RGMII 接口),支持10/100/1000Mbps 自适应
* 集成1 个SD 卡控制器,兼容SD 2.0 规范
* 集成4 个UART,32 个GPIO,4 个I2C,1 个QSPI,2 个通用SPI,3 个CAN,2 个WDT,16 个外部中断
* 集成温度传感器
* 集成128KB On Chip Memory
\"--------------------------------------------------------------------------------
\"--------------------------------------------------------------------------------
VxWorks编译环境搭建
1. 更新源码
把本项目的源码按对应位置复制、替换到VxWorks6.9开发环境。(WIND_HOME代表安装根目录)
这些源码分两部分:BSP和库
BSP的路径是: <WIND_HOME>\vxworks-6.9\target\config\<BSP-source>
库的根路径是:<WIND_HOME>\vxworks-6.9\target\{src,h}\
如果只更新BSP,可以直接用Workbench编译环境进行开发。
如果库的源文件有任何更新,则先编译库,再用Workbench开发。
2. 命令行编译库
库的运行模式有两种,SMP(Symmetrical Multi-Processing)和UP(Uni-Processing),简称多核和单核。
开发者首先确定用多核,还是单核模式,再做具体的步骤,选择其中的一种模式进行编译。
打开CMD命令窗口,设置开发环境:
cd <WIND_HOME>
wrenv.exe -p vxworks-6.9
cd <WIND_HOME>\vxworks-6.9\target\src
(1)编译SMP库:
make CPU=ARMARCH7 TOOL=diab VXBUILD=SMP
命令结束后,即完成<WIND_HOME>\vxworks-6.9\target\lib_smp\库目录下的文件更新。
(2)编译UP库:
make CPU=ARMARCH7 TOOL=diab
命令结束后,即完成<WIND_HOME>\vxworks-6.9\target\lib\库目录下的文件更新。
补充说明:
(1)清理整个库用rclean目标,比如:
make CPU=ARMARCH7 TOOL=diab rclean //删除整个UP库
make CPU=ARMARCH7 TOOL=diab //重新编译整个UP库
make CPU=ARMARCH7 TOOL=diab VXBUILD=SMP rclean //删除整个SMP库
make CPU=ARMARCH7 TOOL=diab VXBUILD=SMP //重新编译整个SMP库
3. 图形化编译库
以上命令行编译库的方法,可以用Workbench工具的VxWorks Source Build(Kernel Library) Project菜单命令完全替代,
简称VSB工程。 只是VSB工程不会修改系统默认库 <WIND_HOME>\vxworks-6.9\target\lib或lib_smp,而是在VSB工程
目录下保存新的库文件。新建VxWorks Image Project(简称VIP工程)时,要基于此VSB。
推荐使用图形化编译。
\"--------------------------------------------------------------------------------
VxWorks运行环境搭建
参考板使用uboot启动vxWorks操作系统。用bin格式的镜像,即默认文件名为vxWorks.bin
启动操作系统镜像的方法不止一种,有网络、USB盘、SATA硬盘等方式加载,用户选择方便的
一种即可。
1. 通过tftp网络加载镜像
Workbench集成开发环境编译后,默认生成 vxWorks 镜像文件,是ELF格式的。可以进一步指定
生成vxWorks.bin文件镜像,这里称作bin格式。 一般地,这两种格式,uboot都是可以加载运行的。
加载的过程和方法都是一样的,区别仅仅是内存基地址不同。
(1)对于bin格式,取基地址 0x80100000
(2)对于ELF格式,取基地址 0x90100000
uboot命令行里,0x前缀可以省略。
1.1 PC端设置 TFTP 服务器
PC机和参考板通过网口相连。在PC机上启动TFTP服务器,以windows系统为例,直接双击
<workbench安装目录>\vxworks-6.9\host\x86-win32\bin\Tftpd32.exe
只需要设置 Current Directory 指向vxWorks.bin(或vxWorks)文件所在的路径即可,无其他设置。
1.2 参考板设置uboot环境变量
参考板和PC机通过TTL电平的3线UART串口连接。在PC机上打开终端软件(比如超级终端、TeraTerm等),
连接此串口,波特率设置为 115200,其他无需设置。上电,在终端软件中停止uboot的自动启动,在
uboot提示符中,输入如下命令:
setenv ethaddr 98:0e:24:00:11:22
setenv eth1addr 98:0e:24:00:11:23
setenv ipaddr 192.168.3.119
setenv serverip 192.168.3.118
saveenv
1.3 下载和启动操作系统镜像
(1)bin格式镜像:
在uboot里执行命令:
tftpboot 0x80100000 vxWorks.bin
bootvx32 0x80100000
即可启动vxWorks系统
(2)ELF格式镜像:
在uboot里执行命令:
tftpboot 0x90100000 vxWorks
bootvx32 0x90100000
即可启动vxWorks系统
(以下命令相同,仅以bin格式为例。用ELF格式时,只需要替换基地址和文件名即可,其他部分相同。)
2. 通过文件系统加载镜像
2.1 USB盘加载
把vxWorks.bin文件提前拷贝到FAT32格式的USB盘中,再把此盘插入参考板的USB口,上电,执行uboot命令:
usb xhci start
fatload usb 0 0x80100000 vxWorks.bin
bootvx32 0x80100000
2.2 FAT32硬盘加载
把vxWorks.bin文件提前拷贝到FAT32格式的硬盘中,再把此盘插入参考板的SATA口,上电,执行uboot命令:
fatload scsi 0:1 0x80100000 vxWorks.bin
bootvx32 0x80100000
2.3 EXT4硬盘加载
把vxWorks.bin文件提前拷贝到ext4格式的硬盘中,再把此盘插入参考板的SATA口,上电,执行uboot命令:
ext4load scsi 0:1 0x80100000 vxWorks.bin
bootvx32 0x80100000
文件系统加载后,在vxWorks运行时,如果gmac网络不通,则仍然需要在uboot阶段提前设置一个有效合理的MAC地址:
setenv ethaddr 98:0e:24:00:11:22
setenv eth1addr 98:0e:24:00:11:23
3. 设置板载FLASH自动启动,避免人工干预
此项设置是把vxworks镜像保存到和UBOOT相同的NOR FLASH芯片里。此芯片一般32MB。目前uboot里的flash读写命令,最大支持16MB。
评估uboot固件一般4MB左右。以下命令例子,把前6MB给uboot,从6MB到16MB的空间给VxWorks镜像用。VxWorks是ELF格式的文件。操作命令如下:
tftpboot 0x90100000 vxWorks 网络下载到内存
flashe 0x600000 0xa00000
flashw 0x90100000 0x600000 0xa00000
cmp.b 0x600000 0x90100000 0xa00000
cp.b 0x600000 0x90100000 0xa00000
setenv bootcmd "cp.b 0x600000 0x90100000 0xa00000; bootvx32 0x90100000"
saveenv
然后就可以下电、上电启动,自动引导系统。如果用vxWorks.bin文件,则把0x90100000改成0x80100000即可。
4. CPU ID映射
对于UP版本,只在一个核上运行操作系统,不涉及CPU ID映射。
只有SMP版本时,才需要映射。在sysLib.c里,使用数组cpuIndexMap[]进行物理ID号和逻辑ID号的转换。
物理ID号取自MPIDR(Multiprocessor Affinity Register)寄存器的低24位。 cpuIndexMap[0] 必须
为操作系统启动核(主核)的MPIDR,各个从核的物理ID依次填入cpuIndexMap[]数组后续项。该数组索引
就是逻辑ID。上层函数usrSmpInit唤醒每个逻辑核,就对应cpuIndexMap[]数组所配的每个实际物理核。
\"--------------------------------------------------------------------------------
驱动描述
1. 参考板支持的硬件接口驱动列表:
Hardware Interface | Controller | Driver/Component | Status | Component
---------------------------------------------------------------------------------------------
UART:0 | PrimeCell PL011 | vxbPrimeCellSio.c | SUPPORTED | DRV_SIO_PRIMECELL
UART:1 | PrimeCell PL011 | vxbPrimeCellSio.c | SUPPORTED | DRV_SIO_PRIMECELL
UART:2 | PrimeCell PL011 | vxbPrimeCellSio.c | SUPPORTED | DRV_SIO_PRIMECELL
UART:3 | PrimeCell PL011 | vxbPrimeCellSio.c | SUPPORTED | DRV_SIO_PRIMECELL
10/100/1000Mb-ETHERNET | FT GAMC | vxbFtGmacEnd.c | SUPPORTED | DRV_VXBEND_FTGMAC
TIMER | generic timer | vxbArmv7GenTimer.c | SUPPORTED | DRV_ARM_GEN_SYS_TIMER
TIMER | auxiliary timer | vxbArmv7AuxTimer.c | SUPPORTED | DRV_ARM_GEN_AUX_TIMER
PCIe | FT pcie | vxbFtPcie.c | SUPPORTED | DRV_PCIBUS_FT, INCLUDE_PCI_BUS
USB Bus | D720201 | XHCI | SUPPORTED | INCLUDE_USB_XHCI_HCD_INIT
USB Disk | D720201 | XHCI | SUPPORTED | INCLUDE_USB_GEN2_STORAGE_INIT
USB Keyboard | D720201 | XHCI | SUPPORTED | INCLUDE_USB_GEN2_KEYBOARD_INIT
USB Mouse | D720201 | XHCI | SUPPORTED | INCLUDE_USB_GEN2_MOUSE_INIT
SATA | AHCI | vxbAhciStorage.c | SUPPORTED | INCLUDE_DRV_STORAGE_AHCI
I2C | FT I2C | vxbFtI2c.c | SUPPORTED | DRV_FTI2C, INCLUDE_I2C_BUS
RTC | DS1339 | vxbI2cRtc.c | SUPPORTED | DRV_I2C_RTC, INCLUDE_TIMER_RTC
CAN | FT CAN | vxbFtCan.c | SUPPORTED | DRV_FTCAN
SD Card | FT SD | vxbFtSdCtrl.c | SUPPORTED | INCLUDE_FT_SD
PHY | YT8521 | vxbYt8521Phy.c | SUPPORTED | INCLUDE_YT8521PHY
QSPI | FT QSPI | vxbFtQspi.c | SUPPORTED | DRV_FTQSPI, INCLUDE_SPI_BUS
SP25FLASH | FT QSPI | vxbSp25SpiFlash.c | SUPPORTED | DRV_SPIFLASH_SP25
DisplayPort | X100 | vxbM6845Vga.c & lib | SUPPORTED | INCLUDE_PC_CONSOLE
EEPROM | AT24C32 | vxbI2cEeprom.c | SUPPORTED | DRV_I2C_EEPROM, INCLUDE_EEPROMDRV
GPIO | FT_GPIO | vxbFtGpio.c | SUPPORTED | DRV_FTGPIO
从飞腾官方网站 https://www.phytium.com.cn/ 可以下载编程手册
<< FT-2000_4软件编程手册.pdf >>, 用户需下载最新版。
2. 串口配置
四个 PrimeCell UART 串口,默认配置为
\ts
Baud Rate : 115200
Data : 8 bit
Parity : None
Stop : 1 bit
Flow Control: None
\te
3. 网络和MAC地址
网口是集成的 SOC GMACs 10/100/1000 MAC 和 PHY.
MAC地址格式: 98:0e:24:xx:xx:xx. 其中前三个字节 98:0e:24 代表飞腾公司
\ts
`gmac0' | - Ethernet
`gmac1' | - Ethernet
\te
vxWorks的ifconfig命令,不带参数时,可以查看网口信息。
配置IP地址时,可以用如下格式:
-> ifconfig "gmac0 192.168.100.100 up"
4. 块设备文件系统
块设备 SD/USB/SATA 等设备,一般需要加载文件系统。
VxWorks 支持两种文件系统 dosFs 和 HRFS. 配置dosFs时,可能需要以下常用组件:
\cs
#define INCLUDE_DOSFS
#define INCLUDE_DOSFS_MAIN
#define INCLUDE_DOSFS_CHKDSK
#define INCLUDE_DOSFS_FMT
#define INCLUDE_DOSFS_FAT
#define INCLUDE_DOSFS_SHOW
#define INCLUDE_DOSFS_DIR_VFAT
#define INCLUDE_DOSFS_DIR_FIXED
#define INCLUDE_FS_MONITOR
#define INCLUDE_FS_EVENT_UTIL
#define INCLUDE_ERF
#define INCLUDE_XBD
#define INCLUDE_XBD_BLKDEV
#define INCLUDE_XBD_TRANS
#define INCLUDE_DEVICE_MANAGER
#define INCLUDE_XBD_BLK_DEV
#define INCLUDE_XBD_PART_LIB
#define INCLUDE_DISK_UTIL
\ce
格式化命令:
\cs
dosFsVolFormat ("NameOfTheBlockDevice", 0x20, 0); /@ FAT32 format @/
或者
dosFsVolFormat ("NameOfTheBlockDevice", 0x10, 0); /@ FAT16 format @/
\ce
格式化后,可以用文件系统的相关命令,比如
\cs
copy ("vxWorks", "NameOfTheBlockDevice/vxWorks");
pwd
cd("/ata0:2")
ls
ll
dosFsShow("NameOfTheBlockDevice", level)
\ce
devs 命令可以查看vxWorks系统添加的设备列表。比如:
/tyCo/0
host:
/ata0:1
/bd0
5. CPU 个数
宏 VX_SMP_NUM_CPUS 的值是SMP启动的核的个数。默认取最大值4,即所有核都启动。
可以在Workbench组件窗口中,修改此宏的值,选择启动的核数。
6. I2C驱动组件配置及使用方法
基本组件配置:
\cs
#define DRV_FTI2C
#define INCLUDE_I2C_BUS
\ce
可以在hwconf.c中配置I2C控制器的总线速率以及中断模式。例如,将I2C控制器0配置为总线速率为400kHz的轮询模式:
\cs
/@ hwconf.c @/
...
struct hcfResource i2cDev0Resources[] = {
...
{ "busSpeed", HCF_RES_INT, {(void *)400000}},
{ "polling", HCF_RES_INT, {(void *)TRUE}},
...
};
...
\ce
如果访问I2C的RTC设备,比如DS1339器件,则添加组件
\cs
#define INCLUDE_TIMER_RTC
#define DRV_I2C_RTC
\ce
并且在hwconf.c的I2C设备列表中添加DS1339设备:
\cs
/@ hwconf.c @/
...
LOCAL struct i2cDevInputs i2cDev1Input[] = {
/* Name */ /* Addr (7-bit) */ /* flag */
...
#ifdef DRV_I2C_RTC
{ "rtc_ds1339", (0xD0>>1), 0 },
#endif
...
};
...
\ce
访问RTC设备的用户接口主要有:
STATUS vxbRtcGet (struct tm * rtcTime); /*读取RTC时间。*/
STATUS vxbRtcSet (struct tm * rtcTime); /*设置RTC时间。*/
(系统中如果存在多个RTC设备,软件会自动选用最合适的一个)。
如果访问I2C的EEPROM设备,比如at24c32器件,则添加组件
\cs
# define DRV_I2C_EEPROM
# define INCLUDE_EEPROMDRV
\ce
并且在hwconf.c的I2C设备列表中添加at24c32设备:
\cs
/@ hwconf.c @/
...
LOCAL struct i2cDevInputs i2cDev1Input[] = {
/* Name */ /* Addr (7-bit) */ /* flag */
...
#ifdef DRV_I2C_EEPROM
{ "eeprom_at24c32", (0x57), I2C_WORDADDR },
#endif
...
};
...
\ce
这样就在文件系统里添加了一个eeprom设备,
可以通过devs命令查看到eeprom设备:
\cs
-> devs
drv name
...
7 /eeprom/0
...
\ce
可以通过标准的文件系统接口open,read,write,close等操作来访问EERROM。
7. CAN组件配置
基本组件配置:
\cs
#define DRV_FTCAN
\ce
设置波特率的函数接口为:ftCanSetBitrate(),可以运行时修改波特率。
发包函数接口为ftCanSend(),在参数中设置帧格式的各类参数。
收包是被动且异步的,通过ftCanRecvCallback()挂接回调函数实现。如果不设置,则默认打印shell显示接收信息。
8. SD卡组件配置
基本组件配置:
\cs
#define INCLUDE_FT_SD
#define RV_SDSTORAGE_CARD
\ce
仅支持FAT32文件系统 ,devs命令显示的默认设备名称 /sd0:0
9. QSPI组件配置及使用方法
基本组件配置:
\cs
#define DRV_FTQSPI
#define INCLUDE_SPI_BUS
\ce
如果访问QSPI的FLASH设备,比如sp25系列器件,则添加组件
\cs
#define DRV_SPIFLASH_SP25
\ce
并且在hwconf.c的SPI设备列表中添加sp25器件:
\cs
/@ hwconf.c @/
...
LOCAL struct vxbSpiDevInfo spiDevTbl[] = {
/* name cs width freq mode */
...
#ifdef DRV_SPIFLASH_SP25
{ SPI_FLASH_DEVICE_NAME, 0, 8, 30000000, 1},
#endif
...
};
...
\ce
可以通过TFFS文件系统访问SPIFLASH,具体操作参考下面的"10. TFFS组件配置及使用方法"一节
10. TFFS组件配置及使用方法
若要支持TFFS文件系统,需要包含TFFS及dosFs文件系统组件。
dosFs文件系统相关组件参考上面的“4.块设备文件系统”一节;
TFFS文件系统相关组件如下:
\cs
#define INCLUDE_TFFS
#define INCLUDE_TFFS_MOUNT
#define INCLUDE_TFFS_SHOW
#define INCLUDE_TFFS_STUB_VXBFLASH
\ce
第一次使用TFFS文件系统时,需要格式化FLASH,并且格式化DOS分区:
在shell里执行:
-> sysTffsFormat 0 对FLASH格式化
-> usrTffsConfig 0,0,"/tffs0" 创建设备
-> devs 显示设备/tffs0
-> dosFsVolFormat("/tffs0",0,0) 分区格式化为DOS
第二次上电以后,无需格式化,只需要创建设备就可以了,在shell里执行创建设备后,就可以用了:
-> usrTffsConfig 0,0,"/tffs0"
使用方法举例:
-> cd "/tffs0"
-> fd=open("test.txt",0x202,0777)
-> write(fd, "hello world\r\n",13)
-> close (fd)
-> copy "test.txt"
11. PC CONSOLE组件配置
基本组件配置:
\cs
#define INCLUDE_PC_CONSOLE
#define INCLUDE_USB_GEN2_KEYBOARD_INIT
#define INCLUDE_USB_GEN2_KEYBOARD_SHELL_ATTACH
\ce
PC CONSOLE组件可以在显示器屏幕上显示控制台信息,这需要X100套片硬件的支持。控制台需要USB键盘作为
输入设备,挂载到vxWorks系统的shell任务上。
12. GPIO组件配置及使用方法
基本组件配置:
#define DRV_FTGPIO
在hwconf.c的GPIO管脚工作模式列表中设置各个管脚的默认工作模式:
/@ hwconf.c @/
...
/*This table is used to set the default pin mode of portA*/
/* 0:GPIO_MODE_NOT_USED 1:GPIO_MODE_IN
2:GPIO_MODE_OUT 3:GPIO_MODE_INT*/
LOCAL UINT8 gpio0PortAModeTable[] = {
/*portA-pinX: 0 1 2 3 4 5 6 7 */
3, 2, 1, 0, 0, 0, 0, 0
};
...
\"--------------------------------------------------------------------------------
参考资源
\tb ARM Architecture Reference Manual
\tb Wind River Workbench User's Guide
\tb VxWorks Kernel Programmer's Guide
\tb VxWorks Architecture Supplement
\tb FT-2000_4软件编程手册.pdf
\"--------------------------------------------------------------------------------
已知问题列表
1. CAN ID过滤帧问题
现象:设置ID过滤寄存器之后,一旦收到ID不匹配的帧,将会导致随后第一个ID匹配的帧
在硬件FIFO里是内容错误的,需要丢弃此帧。第二个ID匹配帧以后,就能正常接收了。
建议:不设置硬件过滤,所有帧全收,再用软件实现ID过滤功能。
2. Workbench WDB调试连接SMP内核问题
现象:调试连接失败
PC机上workbench工具在建立连接过程中,默认会检查PC机上程序映像文件,和目标板上正在运行的
文件是否一致。这通过检查文件checksum实现。由于SMP版本映像文件上电启动时,动态修改了代码段内容,
这会导致检查失败,WDB报错退出。(UP版本映像文件无此问题)
建议:为了使用WDB,可以在WDB连接选项中禁用此校验。只要用户保证PC机上WDB使用的映像文件,和目标板上正在运行的程序,是同一个文件,则不影响正常调试。
具体选项为: Target Server Options >> Kernel image >> Bypass checksum comparison 打上勾选中。
3. Workbench WDB连接IP地址问题
现象:系统启动后,用ifconfig "网口 IP地址" 命令修改了IP地址后,WDB连接失败。
建议:由于WDB组件初始化时就要获取IP地址,因此不要启动后再修改WDB用的IP地址。
在组件配置窗口里,修改 DEFAULT_BOOT_LINE 字符串里的IP地址,然后编译镜像。
4. SATA硬盘驱动vxbAhciStorage.c 文件版本问题
在vxWorks 6.9.4.x 的不同小版本之间,vxbAhciStorage.c这个文件的代码差异还是比较多的。最合理的方法是从对应
版本的<WIND_HOME>\vxworks-6.9\target\src\hwif\storage\目录下取vxbAhciStorage.c这个文件放到BSP目录下,然后
在vxbAhciInstInit2()函数的最后,添加以下几行代码:
LOCAL void vxbAhciInstInit2
(
VXB_DEVICE_ID pDev
)
{
... 省略 ...
if (pDev->busID != VXB_BUSID_PCI)
pAhciDrvCtrl->regHandle = (void *)AHCI_REG_HANDLE_SWAP((ULONG)pAhciDrvCtrl->regHandle);
/*----------------------------- 新加以下几行 ----------------------------------------*/
/* reset AHCI controller. Here we must reset AHCI as soon as early when using PCI legacy interrupt!
* Because both Net Card and SATA Card use int-pin 1, with the same int line 83 for FT1500 board.
* When Net Card init, there are too many SATA interrupts to boot board if the AHCI not reset here.
*/
(void) CTRL_REG_READ(pAhciDrvCtrl, AHCI_GHC);
CTRL_REG_WRITE(pAhciDrvCtrl, AHCI_GHC, AHCI_GHC_HR);
/*------------------------------------------------------------------------------------*/
}
由于本BSP从6.9.4.8支持,基于此版本的vxbAhciStorage.c 文件作为一个示例。如果用户版本更新,则取更新的版本作为基线。
旧版本识别SATA的速度比较慢一些,新版本更新ahciDrv()函数会加快识别速度。

9
usbPciStub.c

@ -0,0 +1,9 @@
/* usbPciStub.c - System-specific PCI Functions */
/*
*
* 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.
*
*/

3082
vxbAhciStorage.c

File diff suppressed because it is too large

654
vxbAhciStorage.h

@ -0,0 +1,654 @@
/* vxbAhciStorage.h - AHCI SATA disk controller header */
/*
* Copyright (c) 2011-2016, 2018 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01j,25sep18,syt add bit fields definitions for FIS-based Switching
Control Register (VXW6-86615)
01i,17jun16,hma fix the sata test error (VXW6-83903)
01h,27feb15,m_y reduce the default watch dog time (VXW6-84034)
01g,19nov14,m_y modify watch dog time (VXW6-83672)
01f,18jun13,m_y add code to support XBD sched policy and NCQ
01e,02jul12,sye fixed static analyze issue. (WIND00354953)
01d,06apr12,sye fixed compile issue when included by a CPP file. (WIND00342562)
01c,15mar12,e_d added portPhyNum in AHCI_DRIVE struct
to identify physical port. (WIND00335995)
01b,29feb12,syt added macro AHCI_REG_HANDLE_SWAP to fit big endian
type register bank.
01a,22oct11,e_d adapted from vxbintelAhciStorage.h version 01s.
*/
#ifndef __INCvxbAhciStorageh
#define __INCvxbAhciStorageh
#ifndef _ASMLANGUAGE
/* includes */
#include <dosFsLib.h>
#include <blkIo.h>
#include <semLib.h>
#include <wdLib.h>
#include <drv/xbd/xbd.h> /* XBD library header */
#include <drv/erf/erfLib.h> /* event frame work library header */
#include "vxbSataLib.h"
#include <../src/hwif/h/storage/vxbSataXbd.h>
#include <lstLib.h>
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifndef _ASMLANGUAGE
/* defines */
#define AHCI_NAME "ahciSata"
enum
{
INTEL_VENDOR_ID = 0x8086,
ICH6_DEVICE_ID = 0x2654,
ICH6R_DEVICE_ID = 0x2652,
ICH6M_DEVICE_ID = 0x2653,
ESB2_DEVICE_ID = 0x2681,
ICH7M_DEVICE_ID = 0x27c5,
ICH8M_DEVICE_ID = 0x2829,
ICH9R_DEVICE_ID = 0x2922,
ICH9M_DEVICE_ID = 0x2929,
ICH10R_DEVICE_ID = 0x3a22,
ICH10_DEVICE_ID = 0x3a02,
PCH_6PORT_DEVICE_ID_0 = 0x3b22,
PCH_6PORT_DEVICE_ID_1 = 0x3b2f,
PCH_PATSBURG_DEVICE_ID = 0x1D02,
PCH_COUGAR_POINT_DEVICE_ID = 0x1c03,
IOH_TOPCILFF_DEVICE_ID = 0x880b
};
#define HIGHPOINT_VERDOR_ID 0x1103
#define HIGHPOINT_ROCKETRAID640L_DEVICE_ID 0x0641
#define AHCI_CLASS_ID 0x01060100
#define AHCI_MAX_CTRLS 6 /* max number of ATA controller */
#define AHCI_MAX_DRIVES 32 /* max number of SATA drives/controller */
#define AHCI_MAX_CMD_SLOTS 32 /* max number of command slots per port */
#define AHCI_MAX_PRD_ENTRIES 256/* max prd entries modify from 16 to 256 */
#define AHCI_ATAPI_MAX_CMD_LENGTH 16 /* maximum length in bytes of a ATAPI command */
/* device types */
#define AHCI_TYPE_NONE 0x00 /* device is faulty or not present */
#define AHCI_TYPE_ATA 0x01 /* ATA device */
#define AHCI_TYPE_ATAPI 0x02 /* ATAPI device */
#define AHCI_TYPE_INIT 255 /* device must be identified */
/* device states */
#define AHCI_DEV_OK 0 /* device is OK */
#define AHCI_DEV_NONE 1 /* device absent or does not respond */
#define AHCI_DEV_DIAG_F 2 /* device diagnostic failed */
#define AHCI_DEV_PREAD_F 3 /* read device parameters failed */
#define AHCI_DEV_MED_CH 4 /* medium have been changed */
#define AHCI_DEV_NO_BLKDEV 5 /* No block device available */
#define AHCI_DEV_INIT 255 /* uninitialized device */
typedef struct ahciPrd
{
UINT32 dataBaseAddressLow;
UINT32 dataBaseAddressHigh;
UINT32 reserved;
UINT32 dataByteCountInterrupt;
} AHCI_PRD;
typedef struct ahciCmdTable
{
UINT8 commandFis[64];
UINT8 atapiCommand[16];
UINT8 reserved[48];
AHCI_PRD prd[AHCI_MAX_PRD_ENTRIES];
} AHCI_CMD_TABLE;
typedef struct ahciCmdList
{
UINT32 flagsPrdLength;
UINT32 recvByteCount;
UINT32 cmdTableAddressLow;
UINT32 cmdTableAddressHigh;
UINT32 reserved0;
UINT32 reserved1;
UINT32 reserved2;
UINT32 reserved3;
} AHCI_CMD_LIST;
typedef struct ahciRecvFis
{
UINT8 dmaSetupFis[28];
UINT8 reserved0[4];
UINT8 pioSetupFis[20];
UINT8 reserved1[12];
UINT8 d2hRegisterFis[20];
UINT8 reserved2[4];
UINT8 setDeviceBitsFis[8];
UINT8 unknownFis[64];
UINT8 reserved3[96];
} AHCI_RECV_FIS;
#if _BYTE_ORDER == _BIG_ENDIAN
# define AHCI_SWAP(x) LONGSWAP(x)
# define AHCI_REG_HANDLE_SWAP(x) VXB_HANDLE_SWAP(x)
#else
# define AHCI_SWAP(x) (x)
# define AHCI_REG_HANDLE_SWAP(x) (x)
#endif /* _BYTE_ORDER == _BIG_ENDIAN */
typedef struct ahciDrive
{
SATA_DEVICE sataPortDev;
void * regsAddr;
AHCI_CMD_LIST *commandList;
AHCI_RECV_FIS *recvFis;
AHCI_CMD_TABLE *commandTable;
SEM_ID syncSem[AHCI_MAX_CMD_SLOTS];
SEM_ID muteSem;
SEM_ID tagMuteSem;
SEM_ID queueSlotSem;
SEM_ID monSyncSem;
UINT32 cmdStarted;
int intCount; /* interrupt count */
UINT32 intStatus; /* interrupt status */
UINT32 intError; /* interrupt status */
int taskFileErrorCount; /* Error counters*/
int timeoutErrorCount; /* Error counters */
BOOL portError;
int nextTag;
BOOL queuedMode;
int queueDepth;
WDOG_ID wdgId;
BOOL wdgOkay;
int semTimeout; /* timeout ticks for sync semaphore */
int wdgTimeout; /* timeout ticks for watch dog */
UINT8 state;
UINT8 portPhyNum; /* physical port number */
UINT32 initActive;
UINT32 slotBit; /* use tagMuteSem to protect */
SEM_ID portCmdSem; /* mutex for commands to the port*/
UINT32 attr; /* attribute of the current transfer*/
} AHCI_DRIVE;
typedef struct vxbAhciMsg
{
SATA_HOST * pCtrl; /* AHCI controller structure pointer */
char drive; /* drive number */
char msgId; /* message ID */
} VXB_AHCI_MSG;
#define VXB_AHCI_MSG_SIZE sizeof(VXB_AHCI_MSG)
/* AHCI SATA Controller Generic Host Control Register Offsets */
#define AHCI_CAP 0x00 /* Host Capabilities */
#define AHCI_GHC 0x04 /* Global Host Control */
#define AHCI_IS 0x08 /* Interrupt Status */
#define AHCI_PI 0x0C /* Ports Implemented */
#define AHCI_VS 0x10 /* Version */
/* AHCI SATA Controller Generic Host Control Register WIDTH */
#define AHCI_PI_WIDTH 0x20 /*Ports Implemented Register width*/
/* AHCI SATA Controller Generic Host Control Register Offsets */
#define AHCI_PxCLB 0x00 /* Port x Command List Base Address Lower 32bits */
#define AHCI_PxCLBU 0x04 /* Port x Command List Base Address Upper 32bits */
#define AHCI_PxFB 0x08 /* Port x FIS Base Address Lower 32bits */
#define AHCI_PxFBU 0x0C /* Port x FIS Base Address Upper 32bits */
#define AHCI_PxIS 0x10 /* Port x Interrupt Status */
#define AHCI_PxIE 0x14 /* Port x Interrupt Enable */
#define AHCI_PxCMD 0x18 /* Port x Command and Status */
#define AHCI_PxTFD 0x20 /* Port x Task File Data */
#define AHCI_PxSIG 0x24 /* Port x Signature */
#define AHCI_PxSSTS 0x28 /* Port x Serial ATA Status */
#define AHCI_PxSCTL 0x2C /* Port x Serial ATA Control */
#define AHCI_PxSERR 0x30 /* Port x Serial ATA Error */
#define AHCI_PxSACT 0x34 /* Port x Serial ATA Active */
#define AHCI_PxCI 0x38 /* Port x Command Issue */
#define AHCI_PxSNTF 0x3C /* Port x SNotification */
#define AHCI_PxVS 0x70 /* Port x Vendor Specific */
/* register access macros */
#define CTRL_REG_READ(pCtrl,offset) \
vxbRead32 (pCtrl->regHandle, \
(UINT32 *)((ULONG)(pCtrl)->regBase[0] + offset))
#define CTRL_REG_WRITE(pCtrl,offset,value) \
vxbWrite32 (pCtrl->regHandle, \
(UINT32 *)((ULONG)(pCtrl)->regBase[0] + offset), value)
#define PORT_REG_READ(port,offset) \
vxbRead32 (port->sataPortDev.host->regHandle, \
(UINT32 *)((ULONG)(port)->regsAddr + offset))
#define PORT_REG_WRITE(port,offset,value) \
vxbWrite32 (port->sataPortDev.host->regHandle, \
(UINT32 *)((ULONG)(port)->regsAddr + offset),value)
/* AHCI Host Capabilities Bit Mask Definitions */
#define AHCI_CAP_S64A 0x80000000 /* Supports 64Bit Addressing */
#define AHCI_CAP_SNCQ 0x40000000 /* Supports NCQ */
#define AHCI_CAP_SSNTF 0x20000000 /* Supports SNotification register */
#define AHCI_CAP_SMPS 0x10000000 /* Supports Mechanical Presence Switch */
#define AHCI_CAP_SSS 0x08000000 /* Supports Staggered Spin Up */
#define AHCI_CAP_SALP 0x04000000 /* Supports Agressive Link Power Manage */
#define AHCI_CAP_SAL 0x02000000 /* Supports Activity LED */
#define AHCI_CAP_SCLO 0x01000000 /* Supports Command List Override */
#define AHCI_CAP_ISS 0x00F00000 /* Interface Speed Support */
#define AHCI_CAP_ISS_SHFT 20
#define AHCI_CAP_SNZO 0x00080000 /* Supports Non-Zero DMA Offsets */
#define AHCI_CAP_SAM 0x00040000 /* Supports ACHI mode only */
#define AHCI_CAP_SPM 0x00020000 /* Supports Port Multiplier */
#define AHCI_CAP_FBSS 0x00010000 /* Supports FIS Based Switching */
#define AHCI_CAP_PMD 0x00008000 /* PIO Multiple DRQ Block */
#define AHCI_CAP_SSC 0x00004000 /* Slumber State Capable */
#define AHCI_CAP_PSC 0x00002000 /* Parial State Capable */
#define AHCI_CAP_NCS 0x00001F00 /* Number of Command Slots per port */
#define AHCI_CAP_NCS_SHFT 8
#define AHCI_CAP_CCCS 0x00000080 /* Supports Command Completion Coalescing */
#define AHCI_CAP_EMS 0x00000040 /* Supports Enclosure Management */
#define AHCI_CAP_SXS 0x00000020 /* Supports External SATA */
#define AHCI_CAP_NP 0x0000001F /* Number of Ports */
/* AHCI Global Host Control Bit Mask Definitions */
#define AHCI_GHC_AE 0x80000000 /* AHCI Enable */
#define AHCI_GHC_IE 0x00000002 /* Interrupt Enable */
#define AHCI_GHC_HR 0x00000001 /* Controller Reset */
/* AHCI Port Interrupt Status Bit Mask Definitions */
#define AHCI_PIS_CPDS 0x80000000 /* Cold Port Detect Status */
#define AHCI_PIS_TFES 0x40000000 /* Task File Error Status */
#define AHCI_PIS_HBFS 0x20000000 /* Host Bus Fatal Error Status */
#define AHCI_PIS_HBDS 0x10000000 /* Host Bus Data Error Status */
#define AHCI_PIS_IFS 0x08000000 /* Interface Fatal Error Status */
#define AHCI_PIS_INFS 0x04000000 /* Interface Non-Fatal Error Status */
#define AHCI_PIS_OFS 0x01000000 /* Overflow Status */
#define AHCI_PIS_IPMS 0x00800000 /* Incorrect Port Multiplier Status */
#define AHCI_PIS_PRCS 0x00400000 /* PhyDry Change Status */
#define AHCI_PIS_DPMS 0x00000080 /* Device Mechanical Presence Status */
#define AHCI_PIS_PCS 0x00000040 /* Port Connect Change Status */
#define AHCI_PIS_DPS 0x00000020 /* Descriptor Processed Status */
#define AHCI_PIS_UFS 0x00000010 /* Umknown FIS Interrupt Status */
#define AHCI_PIS_SDBS 0x00000008 /* Set Device Bits Interrupt Status */
#define AHCI_PIS_DSS 0x00000004 /* DMA Setup FIS Interrupt Status */
#define AHCI_PIS_PSS 0x00000002 /* PIO Setup FIS Interrupt Status */
#define AHCI_PIS_DHRS 0x00000001 /* Device to Host Register FIS Status */
/* AHCI Port Interrupt Enable Bit Mask Definitions */
#define AHCI_PIE_CPDE 0x80000000 /* Cold Port Detect Enable */
#define AHCI_PIE_TFEE 0x40000000 /* Task File Error Enable */
#define AHCI_PIE_HBFE 0x20000000 /* Host Bus Fatal Error Enable */
#define AHCI_PIE_HBDE 0x10000000 /* Host Bus Data Error Enable */
#define AHCI_PIE_IFE 0x08000000 /* Interface Fatal Error Enable */
#define AHCI_PIE_INFE 0x04000000 /* Interface Non-Fatal Error Enable */
#define AHCI_PIE_OFE 0x01000000 /* Overflow Enable */
#define AHCI_PIE_IPME 0x00800000 /* Incorrect Port Multiplier Enable */
#define AHCI_PIE_PRCE 0x00400000 /* PhyDry Change Enable */
#define AHCI_PIE_DPME 0x00000080 /* Device Mechanical Presence Enable */
#define AHCI_PIE_PCE 0x00000040 /* Port Connect Change Enable */
#define AHCI_PIE_DPE 0x00000020 /* Descriptor Processed Enable */
#define AHCI_PIE_UFE 0x00000010 /* Unknown FIS Interrupt Enable */
#define AHCI_PIE_SDBE 0x00000008 /* Set Device Bits Interrupt Enable */
#define AHCI_PIE_DSE 0x00000004 /* DMA Setup FIS Interrupt Enable */
#define AHCI_PIE_PSE 0x00000002 /* PIO Setup FIS Interrupt Enable */
#define AHCI_PIE_DHRE 0x00000001 /* Device to Host Register FIS Enable */
/* AHCI Port Command and Status Bit Mask Definitions */
#define AHCI_PCMD_ICC 0xF0000000 /* Interface Communication Control */
#define AHCI_PCMD_ICC_A 0x10000000 /* Active */
#define AHCI_PCMD_ICC_P 0x20000000 /* Partial */
#define AHCI_PCMD_ICC_S 0x60000000 /* Slumber */
#define AHCI_PCMD_ICC_SHFT 28
#define AHCI_PCMD_ASP 0x08000000 /* Aggressive Slumber/Partial */
#define AHCI_PCMD_ALPE 0x04000000 /* Aggressive Link Power Manage Enable */
#define AHCI_PCMD_DLAE 0x02000000 /* Drive LED on ATAPI Enable */
#define AHCI_PCMD_ATAPI 0x01000000 /* Device is ATAPI */
#define AHCI_PCMD_ESP 0x00200000 /* External SATA Port*/
#define AHCI_PCMD_CPD 0x00100000 /* Cold Presence Detection */
#define AHCI_PCMD_MPSP 0x00080000 /* Mechanical Presence Switch Attached */
#define AHCI_PCMD_HPCP 0x00040000 /* Hot Plug Capable Port */
#define AHCI_PCMD_PMA 0x00020000 /* Port Multiplier Attached */
#define AHCI_PCMD_CPS 0x00010000 /* Cold Presence State */
#define AHCI_PCMD_CR 0x00008000 /* Command List Running */
#define AHCI_PCMD_FR 0x00004000 /* FIS Receive Running */
#define AHCI_PCMD_MPSS 0x00002000 /* Mechanical Presence Switch */
#define AHCI_PCMD_CCS 0x00001F00 /* Current Command Slot */
#define AHCI_PCMD_CCS_SHFT 8
#define AHCI_PCMD_FRE 0x00000010 /* FIS Receive Enable */
#define AHCI_PCMD_CLO 0x00000008 /* Command List Override */
#define AHCI_PCMD_POD 0x00000004 /* Power On Device */
#define AHCI_PCMD_SUD 0x00000002 /* Spin-Up Device */
#define AHCI_PCMD_ST 0x00000001 /* Start */
/* AHCI Port Serial ATA Status Bit Mask Definitions */
#define AHCI_PSSTS_IPM_MSK 0x00000F00 /* Interface Power Management */
#define AHCI_PSSTS_IPM_NO_DEVICE 0x00000000
#define AHCI_PSSTS_IPM_ACTIVE 0x00000100
#define AHCI_PSSTS_IPM_PARTIAL 0x00000200
#define AHCI_PSSTS_IPM_SLUMBER 0x00000600
#define AHCI_PSSTS_SPD_MSK 0x000000F0 /* Current Interface Speed */
#define AHCI_PSSTS_SPD_NO_DEVICE 0x00000000
#define AHCI_PSSTS_SPD_GEN1 0x00000010
#define AHCI_PSSTS_SPD_GEN2 0x00000020
#define AHCI_PSSTS_DET_MSK 0x0000000F /* Device Detection */
#define AHCI_PSSTS_DET_NO_DEVICE 0x00000000
#define AHCI_PSSTS_DET_NO_PHY 0x00000001
#define AHCI_PSSTS_DET_PHY 0x00000003
#define AHCI_PSSTS_DET_PHY_OFF 0x00000004
/* AHCI Port Serial ATA Control Bit Mask Definitions */
#define AHCI_PSCTL_IPM_MSK 0x00000F00 /* Interface Power Management */
#define AHCI_PSCTL_IPM_NO_RESTRICT 0x00000000
#define AHCI_PSCTL_IPM_NO_PARTIAL 0x00000100
#define AHCI_PSCTL_IPM_NO_SLUMBER 0x00000200
#define AHCI_PSCTL_IPM_NO_PARSLUM 0x00000300
#define AHCI_PSCTL_SPD_MSK 0x000000F0 /* Speed Allowed */
#define AHCI_PSCTL_SPD_NO_RESTRICT 0x00000000
#define AHCI_PSCTL_SPD_LIMIT_GEN1 0x00000010
#define AHCI_PSCTL_SPD_LIMIT_GEN2 0x00000020
#define AHCI_PSCTL_DET_MSK 0x0000000F /* Speed Allowed */
#define AHCI_PSCTL_DET_NO_ACTION 0x00000000
#define AHCI_PSCTL_DET_RESET 0x00000001
#define AHCI_PSCTL_DET_DISABLE 0x00000004
/* AHCI Port Interrupt Enable Bit Mask Definitions */
#define AHCI_PSERR_DIAG_X 0x04000000 /* Exchanged */
#define AHCI_PSERR_DIAG_F 0x02000000 /* Unknown FIS Type */
#define AHCI_PSERR_DIAG_T 0x01000000 /* Transport State Transition Error */
#define AHCI_PSERR_DIAG_S 0x00800000 /* Link Sequence Error */
#define AHCI_PSERR_DIAG_H 0x00400000 /* Handshake Error */
#define AHCI_PSERR_DIAG_C 0x00200000 /* CRC Error */
#define AHCI_PSERR_DIAG_D 0x00100000 /* Disparity Error */
#define AHCI_PSERR_DIAG_B 0x00080000 /* 10B to 8B Decode Error */
#define AHCI_PSERR_DIAG_W 0x00040000 /* Comm Wake */
#define AHCI_PSERR_DIAG_I 0x00020000 /* Phy Internal Error*/
#define AHCI_PSERR_DIAG_N 0x00010000 /* Phy Rdy Change */
#define AHCI_PSERR_ERR_E 0x00000800 /* Internal Error */
#define AHCI_PSERR_ERR_P 0x00000400 /* Protocol Error */
#define AHCI_PSERR_ERR_C 0x00000200 /* Data Integrity Error */
#define AHCI_PSERR_ERR_T 0x00000100 /* Transient Data Integrity Error */
#define AHCI_PSERR_ERR_M 0x00000002 /* Recovered Communication Error */
#define AHCI_PSERR_ERR_I 0x00000001 /* Recoever Data Integrity Error */
/* AHCI Command List Bit Mask Definitions */
#define AHCI_CMD_LIST_PRDTL 0xFFFF0000 /* PDT Table Length (entries) */
#define AHCI_CMD_LIST_PRDTL_SHFT 16
#define AHCI_CMD_LIST_PMP 0x0000F000 /* Port Multiplier Port */
#define AHCI_CMD_LIST_PMP_SHFT 12
#define AHCI_CMD_LIST_C 0x00000400 /* Clear Busy upon R_OK */
#define AHCI_CMD_LIST_B 0x00000200 /* BIST FIS */
#define AHCI_CMD_LIST_R 0x00000100 /* Reset Command */
#define AHCI_CMD_LIST_P 0x00000080 /* Prefetchable */
#define AHCI_CMD_LIST_W 0x00000040 /* Write */
#define AHCI_CMD_LIST_A 0x00000020 /* ATAPI */
#define AHCI_CMD_LIST_CFL 0x0000001F /* Command Length (in 32 bit words */
/* AHCI PRD Bit Maks Definitions */
#define AHCI_PRD_I 0x80000000 /* Interrupt upon completion */
#define AHCI_PRD_MAX_BYTES 0x400000
#define AHCI_NCQ_MODE 0x1000 /* Native Command Queueing Mode */
#define AHCI_DMA_ULTRA 0x0c00 /* RW DMA ultra */
#define AHCI_DMA_AUTO 0x0017 /* DMA max supported mode */
#define AHCI_MODE_ALL (AHCI_DMA_AUTO | AHCI_DMA_ULTRA | AHCI_NCQ_MODE)
/* default timeout for ATA sync sem */
#define AHCI_SEM_TIMEOUT_DEF (10*sysClkRateGet())
/* default timeout for ATA watch dog */
#define AHCI_WDG_TIMEOUT_DEF (5*sysClkRateGet())
/* default for number of service tasks per drive */
#define AHCI_SVC_TASK_COUNT_DEF 1
#ifndef AHCI_SVC_TASK_COUNT
# define AHCI_SVC_TASK_COUNT 1 /* Number of service tasks per drive */
#endif /* AHCI_SVC_TASK_COUNT */
/* Monitor Task Message types */
#define AHCI_ATTACH_MSG 'A'
#define AHCI_REMOVE_MSG 'R'
#define AHCI_PORT_ERROR_MSG 'E'
/* diagnostic code */
#define AHCI_DIAG_OK 0x01
/* control register */
#define AHCI_CTL_4BIT 0x8 /* use 4 head bits (wd1003) */
#define AHCI_CTL_RST 0x4 /* reset controller */
#define AHCI_CTL_IDS 0x2 /* disable interrupts */
/* status register */
#define AHCI_STAT_ACCESS (AHCI_STAT_BUSY | AHCI_STAT_DRQ)
/* device accessible */
#define AHCI_STAT_BUSY 0x80 /* controller busy */
#define AHCI_STAT_READY 0x40 /* selected drive ready */
#define AHCI_STAT_WRTFLT 0x20 /* write fault */
#define AHCI_STAT_SEEKCMPLT 0x10 /* seek complete */
#define AHCI_STAT_DRQ 0x08 /* data request */
#define AHCI_STAT_ECCCOR 0x04 /* ECC correction made in data */
#define AHCI_STAT_INDEX 0x02 /* index pulse from selected drive */
#define AHCI_STAT_ERR 0x01 /* error detect */
/* size/drive/head register: addressing mode CHS or LBA */
#define AHCI_SDH_IBM 0xa0 /* chs, 512 bytes sector, ecc */
#define AHCI_SDH_LBA 0xe0 /* lba, 512 bytes sector, ecc */
#define AHCI_MAX_RW_SECTORS 0x100 /* max sectors per transfer */
#define AHCI_MAX_RW_48LBA_SECTORS 0x10000 /* max sectors per transfer in 48-bit LBA mode */
/* configuration flags: transfer mode, bits, unit, geometry */
#define AHCI_PIO_DEF_0 AHCI_PIO_DEF_W /* PIO default mode */
#define AHCI_PIO_DEF_1 AHCI_PIO_DEF_WO /* PIO default mode, no IORDY */
#define AHCI_PIO_0 AHCI_PIO_W_0 /* PIO mode 0 */
#define AHCI_PIO_1 AHCI_PIO_W_1 /* PIO mode 1 */
#define AHCI_PIO_2 AHCI_PIO_W_2 /* PIO mode 2 */
#define AHCI_PIO_3 AHCI_PIO_W_3 /* PIO mode 3 */
#define AHCI_PIO_4 AHCI_PIO_W_4 /* PIO mode 4 */
#define AHCI_PIO_AUTO 0x000d /* PIO max supported mode */
#define AHCI_DMA_0 0x0010 /* DMA mode 0 */
#define AHCI_DMA_1 0x0011 /* DMA mode 1 */
#define AHCI_DMA_2 0x0012 /* DMA mode 2 */
#define AHCI_DMA_3 0x0013 /* DMA mode 3 */
#define AHCI_DMA_4 0x0014 /* DMA mode 4 */
#define AHCI_DMA_5 0x0015 /* DMA mode 5 */
#define AHCI_DMA_6 0x0016 /* DMA mode 6 */
#define AHCI_MODE_MASK 0x00FF /* transfer mode mask */
#define AHCI_PIO_SINGLE 0x0100 /* RW PIO single sector */
#define AHCI_PIO_MULTI 0x0200 /* RW PIO multi sector */
#define AHCI_PIO_MASK 0x0300 /* RW PIO mask */
#define AHCI_DMA_SINGLE 0x0400 /* RW DMA single word */
#define AHCI_DMA_MULTI 0x0800 /* RW DMA multi word */
#define AHCI_DMA_MASK 0x0c00 /* RW DMA mask */
#define AHCI_NCQ_MASK 0x1000 /* Native Command Queueing Mask */
/* config */
#define AHCI_CONFIG_PROT_TYPE 0xc000 /* Protocol Type */
#define AHCI_CONFIG_PROT_TYPE_ATAPI 0x8000 /* ATAPI */
#define AHCI_CONFIG_DEV_TYPE 0x1f00 /* Device Type */
#define AHCI_CONFIG_DEV_TYPE_CD_ROM 0x0500
#define AHCI_CONFIG_REMOVABLE 0x0080 /* Removable */
#define AHCI_CONFIG_PKT_TYPE 0x0060 /* CMD DRQ Type */
#define AHCI_CONFIG_PKT_TYPE_MICRO 0x0000 /* Microprocessor DRQ */
#define AHCI_CONFIG_PKT_TYPE_INTER 0x0020 /* Interrupt DRQ */
#define AHCI_CONFIG_PKT_TYPE_ACCEL 0x0040 /* Accelerated DRQ */
#define AHCI_CONFIG_PKT_SIZE 0x0003 /* Command Packet Size */
#define AHCI_CONFIG_PKT_SIZE_12 0x0000 /* 12 bytes */
/* capabilities */
#define AHCI_CAPABIL_DMA 0x0100 /* DMA Supported */
#define AHCI_CAPABIL_LBA 0x0200 /* LBA Supported */
#define AHCI_CAPABIL_IORDY_CTRL 0x0400 /* IORDY can be disabled */
#define AHCI_CAPABIL_IORDY 0x0800 /* IORDY Supported */
#define AHCI_CAPABIL_OVERLAP 0x2000 /* Overlap Operation Supported */
/* valid */
#define AHCI_FIELDS_VALID 0x0002
/* singleDma */
#define AHCI_SINGLEDMA_MODE 0xff00 /* 15-8: mode active */
#define AHCI_SINGLEDMA_SUPPORT 0x00ff /* 7-0: modes supported */
/* multiDma */
#define AHCI_MULTIDMA_MODE 0xff00 /* 15-8: mode active */
#define AHCI_MULTIDMA_SUPPORT 0x00ff /* 7-0: modes supported */
/* advPio */
#define AHCI_ADVPIO_MODE3 0x0001 /* The Device supports PIO Mode 3 */
/* Error Register */
#define AHCI_ERR_SENSE_KEY 0xf0 /* Sense Key mask */
#define AHCI_SENSE_NO_SENSE 0x00 /* no sense sense key */
#define AHCI_SENSE_RECOVERED_ERROR 0x10 /* recovered error sense key */
#define AHCI_SENSE_NOT_READY 0x20 /* not ready sense key */
#define AHCI_SENSE_MEDIUM_ERROR 0x30 /* medium error sense key */
#define AHCI_SENSE_HARDWARE_ERROR 0x40 /* hardware error sense key */
#define AHCI_SENSE_ILLEGAL_REQUEST 0x50 /* illegal request sense key */
#define AHCI_SENSE_UNIT_ATTENTION 0x60 /* unit attention sense key */
#define AHCI_SENSE_DATA_PROTECT 0x70 /* data protect sense key */
#define AHCI_SENSE_ABBORTED_COMMAND 0xb0 /* aborted command sense key */
#define AHCI_SENSE_MISCOMPARE 0xe0 /* miscompare sense key */
#define AHCI_ERR_MCR 0x08 /* Media Change Requested */
#define AHCI_ERR_ABRT 0x04 /* Aborted command */
#define AHCI_ERR_EOM 0x02 /* End Of Media */
#define AHCI_ERR_ILI 0x01 /* Illegal Length Indication */
/* Feature Register */
#define AHCI_FEAT_OVERLAP 0x02 /* command may be overlapped */
#define AHCI_FEAT_DMA 0x01 /* data will be transferred via DMA */
/* Interrupt Reason Register */
#define AHCI_INTR_RELEASE 0x04 /* Bus released before completing the command */
#define AHCI_INTR_IO 0x02 /* 1 - In to the Host; 0 - Out to the device */
#define AHCI_INTR_COD 0x01 /* 1 - Command; 0 - user Data */
/* Drive Select Register */
#define AHCI_DSEL_FILLER 0xa0 /* to fill static fields */
#define AHCI_DSEL_DRV 0x10 /* Device 0 (DRV=0) or 1 (DRV=1) */
/* Status Register */
#define AHCI_STAT_BUSY 0x80 /* controller busy */
#define AHCI_STAT_READY 0x40 /* selected drive ready */
#define AHCI_STAT_DMA_READY 0x20 /* ready to a DMA data transfer */
#define AHCI_STAT_WRTFLT 0x20 /* write fault */
#define AHCI_STAT_SERVICE 0x10 /* service or interrupt request */
#define AHCI_STAT_SEEKCMPLT 0x10 /* seek complete */
#define AHCI_STAT_DRQ 0x08 /* data request */
#define AHCI_STAT_ECCCOR 0x04 /* ECC correction made in data */
#define AHCI_STAT_ERR 0x01 /* error detect */
/* Device Control Register */
#define AHCI_CTL_FILLER 0x8 /* bit 3 must be always set */
#define AHCI_CTL_RST 0x4 /* reset controller */
#define AHCI_CTL_IDS 0x2 /* disable interrupts */
/* Power Management States */
#define AHCI_PM_ACTIVE_IDLE 0
#define AHCI_PM_STANDBY 1
#define AHCI_PM_SLEEP 2
/* ATA Ioctl function codes */
#define AHCIIOAPMENABLE 0x100
#define AHCIIOAPMDISABLE 0x101
#define AHCIIOAPMGET 0x102
#define AHCIIOCHECKPOWERLEVEL 0x103
#define AHCIIOPMIDLE 0x104
#define AHCIIOPMSTANDBY 0x105
#define AHCIIOPMSLEEP 0x106
#define AHCIIOPMWAKE 0x107
#define AHCIIOSMARTENABLE 0x108
#define AHCIIOSMARTDISABLE 0x109
#define AHCIIOSMARTSAVEATTR 0x10A
#define AHCIIOSMARTISENABLED 0x10B
#define AHCIIOSMARTAUTOSAVEENABLE 0x10C
#define AHCIIOSMARTAUTOSAVEDISABLE 0x10D
#define AHCIIOSMARTOFFLINEDIAG 0x10E
#define AHCIIOSMARTRETURNSTATUS 0x10F
#define AHCIIOSMARTREADDATA 0x110
#define AHCIIOSMARTREADTHRESHOLDS 0x111
#define AHCIIOPARMSGET 0x112
#define AHCIIOMAXSECTORXFERSET 0x113
#define AHCIIOMAXSECTORXFERGET 0x114
#define AHCIIODRIVEHALT 0x115
#define AHCIIODRIVESTOP 0x116
#define AHCIIODRIVESTART 0x117
/* attribute of the current */
#define AHCI_TRANSFER_WITH_DATA 0x00000001
#define AHCI_TRANSFER_NCQ_CMD 0x00000002
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __INCvxbAhciStorageh */

2442
vxbArmGenIntCtlrV3.c

File diff suppressed because it is too large

264
vxbArmGenIntCtlrV3.h

@ -0,0 +1,264 @@
/* vxbArmGenIntCtlrV3.h - ARM Generic interrupt controller driver */
/*
*
* 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.
*
*/
#ifndef __INCvxbArmGenIntCtlrV3h
#define __INCvxbArmGenIntCtlrV3h
#ifdef __cplusplus
extern "C"{
#endif
#define GIC_VERSION_DEFAULT 2
#define GIC_VERSION_GIC400 3
/*
* the explanation of some abbreviations
*
* CPC - Cross Processor Call
* IPI - Inter Processor Interrupt
* GIC - General Interrupt Controller
* SGI - Software Generated Interrupt
* PPI - Private Peripheral Interrupt
* SPI - Shared Peripheral Interrupt
*/
/* MPCore GIC interrupt levels */
#define INT_LVL_MPCORE_IPI00 0 /* This is vxWorks CPC IPI */
#define INT_LVL_MPCORE_CPC INT_LVL_MPCORE_IPI00
#define INT_LVL_MPCORE_IPI01 1 /* This is vxWorks Debug IPI */
#define INT_LVL_MPCORE_DEBUG INT_LVL_MPCORE_IPI01
#define INT_LVL_MPCORE_IPI02 2 /* This is vxWorks Reschedule IPI */
#define INT_LVL_MPCORE_SCHED INT_LVL_MPCORE_IPI02
#define INT_LVL_MPCORE_IPI03 3 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI04 4 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI05 5 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI06 6 /* This is vxWorks Core Reset IPI */
#define INT_LVL_MPCORE_RESET INT_LVL_MPCORE_IPI06
#define INT_LVL_MPCORE_IPI07 7 /* This is vxWorks Core Start IPI */
#define INT_LVL_MPCORE_START INT_LVL_MPCORE_IPI07
#define INT_LVL_MPCORE_IPI08 8 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI09 9 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI10 10 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI11 11 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI12 12 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI13 13 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI14 14 /* IPI -> use SWI register in GIC */
#define INT_LVL_MPCORE_IPI15 15 /* IPI -> use SWI register in GIC */
#define SGI_INT_MAX 16
#define ARM_GIC_IPI_COUNT 16 /* MPCore IPI count */
#define SPI_START_INT_NUM 32 /* SPI start at ID32 */
#define PPI_START_INT_NUM 16 /* PPI start at ID16 */
#define GIC_INT_MAX_NUM 1020 /* GIC max interrupts count */
#define GIC_INT_ALL_ENABLED 0xFF /* priority 0-0xFF can run */
#define GIC_INT_ALL_DISABLED 0x00 /* nothing higher than 0 hence disabled */
#define GIC_INT_SPURIOUS 0x3FF /* no interrupt currently */
#define GIC_INT_ONEMINUS_HIGH 0x55555555 /* interrupt config to 1-N, High */
#define GIC_CPU_BINP_DEFAULT 0x07 /* split all priority to subpriority */
#define GIC_CPU_BINP_PREEMPT_VAL 0x00 /* split all priority to group-priority */
#define GIC_CPU_BINP_NONPREEMPT_VAL 0x07 /* split all priority to sub-priority */
#define GIC_CPU_CONTROL_ENABLE 0x1 /* enable the processor interface */
#define GIC_CPU_ALL_ENABLED 0xFF /* priority 0-E can run */
#define GIC_CPU_ALL_DISABLED 0x00 /* nothing higher than 0 */
#define GIC_SGI_SRC_CPU_ID_MASK 0x1C00
#define GIC_INT_HIGHEST_PRIORITY 0x0 /* the highest priority for interrupts */
#define GIC_INT_LOWEST_PRIORITY 0x1F /* the lowest priority for interrupts */
#define GIC_INT_PRIORITY_SHIFT 0x8
#define GIC_INT_PRIORITY_MASK 0xFF
#define GIC_INT_TRIGGER_SHIFT 0x2
#define GIC_CPU_DIR_DEFAULT 0x01010101 /* all interrupts are directed to CPU0 */
#define GIC_V3_CPU_DIR_DEFAULT 0x0llu /* all interrupts are directed to CPU0 */
#define GIC_CONTROL_ENABLE 0x01
#define ALL_PPI_INT_MASK 0xFFFF0000 /* bit field for all PPI interrupts */
#define ALL_SGI_INT_MASK 0x0000FFFF /* bit field for all SGI interrupts */
#define GIC_AFF_ALL_MASK 0xff00ffffff
#define GIC_AFF_LOW32_MASK 0x00ffffff
/* ARM GIC interrupt distributor and CPU interface register access macros */
#define SHIFT_PER_WORD 5
#define BITS_PER_WORD 32
#define CONFIGS_PER_WORD 16
#define PRIOS_PER_WORD 4
#define TARGETS_PER_WORD 4
#define NWORD(bitnum) (bitnum / 32)
#define BIT(bitnum) (1 << (bitnum % BITS_PER_WORD))
/* trigger modes */
#define GIC_TRIG_RISING_EDGE (0x1)
#define GIC_TRIG_FALLING_EDGE (0x2)
#define GIC_TRIG_ACTIVE_HIGH (0x4)
#define GIC_TRIG_ACTIVE_LOW (0x8)
/* SGI & PPI configuration for GIC 400 */
#define GIC_SGI_OFF (1 << 16)
#define GICR_ICFGR0 (0x0C00) /* SGI & PPI Configuration Register */
#define GICR_ICFGR1 (0x0C04) /* PPI Configuration Register */
#define GICR_ISENABLER0 (0x100)
#define GICR_ICENABLER0 (0x180)
/* SGI Configuration Register */
#define IMR (1 << (40 - 32))
#define ipiId_MASK (0xffff)
#define GICR_WAKER_CPU(cpu) ((volatile UINT32 *)(GIC_REDIST + cpu*(2<<16) + 0x14))
#define GICR_IntEnable_CPU(cpu) ((volatile UINT32 *)(GIC_SGI_BASE + cpu*(2<<16) +0x100))
#define GICR_IntEnClr_CPU(cpu) ((volatile UINT32 *)(GIC_SGI_BASE + cpu*(2<<16) + 0x180))
#define GICR_IntPendClr_CPU(cpu) ((volatile UINT32 *)(GIC_SGI_BASE + cpu*(2<<16) + 0x280))
#define GICR_Prio_CPU(cpu,Periph) ((volatile UINT32 *)(GIC_SGI_BASE+ cpu*(2<<16) + 0x400 + \
(0x4 * (Periph / PRIOS_PER_WORD))))
#define GICR_WAKER ((volatile UINT32 *)(GIC_REDIST + 0x14))
#define GICR_TYPERLO ((volatile UINT32 *)(GIC_REDIST + 0x8))
#define GICR_TYPERHI ((volatile UINT32 *)(GIC_REDIST + 0xC))
#define GICR_Config0 ((volatile UINT32 *)(GIC_SGI_BASE + 0xC00))
/* PPI Configuration Register */
#define GICR_Config1 ((volatile UINT32 *)(GIC_SGI_BASE + 0xC04))
/*Interrupt Group Register 0*/
#define GICR_IGROUPR0 ((volatile UINT32 *)(GIC_SGI_BASE + 0x80))
/* interrupt enable */
#define GICR_IntEnable ((volatile UINT32 *)(GIC_SGI_BASE + 0x100))
/* clear interrupt enable */
#define GICR_IntEnClr ((volatile UINT32 *)(GIC_SGI_BASE + 0x180))
/* set pending interrupt */
#define GICR_IntPendSet ((volatile UINT32 *)(GIC_SGI_BASE + 0x200))
/* clear pending interrupt */
#define GICR_IntPendClr ((volatile UINT32 *)(GIC_SGI_BASE + 0x280))
/* interrupt priority */
#define GICR_Prio(Periph) ((volatile UINT32 *)(GIC_SGI_BASE + 0x400 + \
(0x4 * (Periph / PRIOS_PER_WORD))))
#ifndef _ASMLANGUAGE
/* GIC distributor and CPU interface register base offsets */
#define GIC_REDIST (armGicBase + armGicReDistOffset)
#define GIC_SGI_BASE (armGicBase + armGicReDistOffset+ GIC_SGI_OFF)
#define GIC_DIST (armGicBase + armGicDistOffset)
#ifdef SUPPORT_GICC
#define GIC_CPU (armGicBase + armGicCpuOffset)
#endif
/* interrupt distributor control */
#define GIC_Control ((volatile UINT32 *)(GIC_DIST + 0x000))
/* interrupt distributor control */
#define GIC_SET_SPI ((volatile UINT32 *)(GIC_DIST + 0x040))
#define GIC_CL_SPI ((volatile UINT32 *)(GIC_DIST + 0x048))
/* interrupt controller type */
#define GIC_Type ((volatile UINT32 *)(GIC_DIST + 0x004))
/* interrupt enable */
#define GIC_IntEnable(Periph) ((volatile UINT32 *)(GIC_DIST + 0x100 + \
(0x4 * NWORD(Periph))))
/* clear interrupt enable */
#define GIC_IntEnClr(Periph) ((volatile UINT32 *)(GIC_DIST + 0x180 + \
(0x4 * NWORD(Periph))))
/* interrupt active status */
#define GIC_IntActSts(Periph) ((volatile UINT32 *)(GIC_DIST + 0x300 + \
(0x4 * NWORD(Periph))))
/* set pending interrupt */
#define GIC_IntPendSet(Periph) ((volatile UINT32 *)(GIC_DIST + 0x200 + \
(0x4 * NWORD(Periph))))
/* clear pending interrupt */
#define GIC_IntPendClr(Periph) ((volatile UINT32 *)(GIC_DIST + 0x280 + \
(0x4 * NWORD(Periph))))
/* interrupt configuration */
#define GIC_Config(Periph) ((volatile UINT32 *)(GIC_DIST + 0xC00 + \
(0x4 * (Periph / CONFIGS_PER_WORD))))
/* interrupt priority */
#define GIC_Prio(Periph) ((volatile UINT32 *)(GIC_DIST + 0x400 + \
(0x4 * (Periph / PRIOS_PER_WORD))))
/* CPU target */
#define GIC_CPUTarg(Periph) ((volatile UINT32 *)(GIC_DIST + 0x800 + \
(0x4 * (Periph / TARGETS_PER_WORD))))
/* Interrupt Routing */
#define GIC_IntRpute(Periph) ((volatile UINT64 *)(GIC_DIST + 0x6000 + \
(0x8 * (Periph))))
/* software interrupt generate */
#define GIC_SWInterrupt ((volatile UINT32 *)(GIC_DIST + 0xF00))
/* CPU interrupt control */
#ifdef SUPPORT_GICC
#define GIC_CPU_Control ((volatile UINT32 *)(GIC_CPU + 0x00))
/* CPU priority mask */
#define GIC_CPU_PriMask ((volatile UINT32 *)(GIC_CPU + 0x04))
/* CPU binary point */
#define GIC_CPU_BinPoint ((volatile UINT32 *)(GIC_CPU + 0x08))
/* CPU interrupt acknowledge */
#define GIC_CPU_IntAck ((volatile UINT32 *)(GIC_CPU + 0x0C))
/* CPU end of interrupt */
#define GIC_CPU_EOInt ((volatile UINT32 *)(GIC_CPU + 0x10))
/* CPU running priority */
#define GIC_CPU_RunPri ((volatile UINT32 *)(GIC_CPU + 0x14))
#endif
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* __INCvxbArmGenIntCtlrV3h */

1291
vxbArmv7AuxTimer.c

File diff suppressed because it is too large

1541
vxbArmv7GenTimer.c

File diff suppressed because it is too large

2986
vxbFtGmacEnd.c

File diff suppressed because it is too large

530
vxbFtGmacEnd.h

@ -0,0 +1,530 @@
/* vxbFtGmac.h - GMAC driver */
/*
*
* 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.
*
*/
#ifndef __INCvxbFtGmacEndh
#define __INCvxbFtGmacEndh
#ifdef __cplusplus
extern "C" {
#endif
IMPORT void ftGmacRegister (void);
#ifndef BSP_VERSION
#define GMAC_TUPLE_CNT 576
#define GMAC_ADJ(x) (x)->m_data += 2
#define GMAC_INC_DESC(x, y) (x) = (((x) + 1) % y)
#define GMAC_MAXFRAG 32
#define GMAC_MAX_RX 128
#define GMAC_RX_DESC_CNT 4096
#define GMAC_TX_DESC_CNT 4096
#define GMAC_RX_BUFF_SIZE 1536
#define GMAC_MTU 1500
#define GMAC_JUMBO_MTU 9000
#define GMAC_CLSIZE 1536
#define GMAC_NAME "gmac"
#define GMAC_TIMEOUT 100000
#define MII_BUSY 0x00000001
#undef MII_WRITE
#define MII_WRITE 0x00000002
#define AR8021_MMD_ACCESS_CONTROL 0x0D
#define AR8021_MMD_ACCESS_ADDRESS 0x0E
#define AR8021_MMD_ADDRESS_7 0x7
#define AR8021_MMD_ACCESS_CONTROL_ADDR 0x0000
#define AR8021_MMD_ACCESS_CONTROL_DATA 0x4000
#define AR8021_CLK_SELECT_OFFSET 0x8016
#define AR8021_CLK_SELECT_VALUE 0x0018
#define BITS_PER_LONG 32
#define BITS_PER_WORD 32
#define BIT(bitnum) (1 << (bitnum % BITS_PER_WORD))
#define GENMASK(h, l) \
(((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
#define GMAC_CONTROL 0x00000000 /* Configuration */
#define GMAC_FRAME_FILTER 0x00000004 /* Frame Filter */
#define GMAC_HASH_HIGH 0x00000008 /* Multicast Hash Table High */
#define GMAC_HASH_LOW 0x0000000c /* Multicast Hash Table Low */
#define GMAC_MII_ADDR 0x00000010 /* MII Address */
#define GMAC_MII_DATA 0x00000014 /* MII Data */
#define GMAC_FLOW_CTRL 0x00000018 /* Flow Control */
#define GMAC_VLAN_TAG 0x0000001c /* VLAN Tag */
#define GMAC_VERSION 0x00000020 /* GMAC CORE Version */
#define GMAC_ADDR0_HIGH 0x00000040
#define GMAC_ADDR0_LOW 0x00000044
#define GMAC_INT_STATUS 0x00000038 /* interrupt status register */
#define GMAC_INT_STATUS_LINKCHANGED BIT(0)
#define GMAC_INT_STATUS_PMT BIT(3)
#define GMAC_INT_STATUS_MMCIS BIT(4)
#define GMAC_INT_STATUS_MMCRIS BIT(5)
#define GMAC_INT_STATUS_MMCTIS BIT(6)
#define GMAC_INT_STATUS_MMCCSUM BIT(7)
#define GMAC_INT_STATUS_TSTAMP BIT(9)
#define GMAC_INT_STATUS_LPIIS BIT(10)
/* interrupt mask register */
#define GMAC_INT_MASK 0x0000003c
#define GMAC_INT_DISABLE_RGMII BIT(0)
#define GMAC_INT_DISABLE_PCSLINK BIT(1)
#define GMAC_INT_DISABLE_PCSAN BIT(2)
#define GMAC_INT_DISABLE_PMT BIT(3)
#define GMAC_INT_DISABLE_TIMESTAMP BIT(9)
#define GMAC_INT_DISABLE_PCS (GMAC_INT_DISABLE_RGMII | \
GMAC_INT_DISABLE_PCSLINK | \
GMAC_INT_DISABLE_PCSAN)
#define GMAC_INT_DEFAULT_MASK (GMAC_INT_DISABLE_TIMESTAMP | \
GMAC_INT_DISABLE_PCS)
#define GMAC_HI_REG_AE 0x80000000
/* GMAC HW ADDR regs */
#define GMAC_ADDR_HIGH 0x0040
#define GMAC_ADDR_LOW 0x0044
#define GMAC_AN_CTRL 0x00c0 /* Auto-Neg. control */
#define GMAC_AN_STATUS 0x00c4 /* Auto-Neg. status */
#define GMAC_ANE_ADV 0x00c8 /* Auto-Neg. Advertisement */
#define GMAC_ANE_LINK 0x00cc /* Auto-Neg. link partener ability */
#define GMAC_ANE_EXP 0x00d0 /* ANE expansion */
#define GMAC_TBI 0x00d4 /* TBI extend status */
#define GMAC_GMII_STATUS 0x00d8 /* S/R-GMII status */
/* MMC control */
#define MMC_CNTRL 0x0100 /* MMC Control */
#define MMC_RX_INTR 0x0104 /* MMC RX Interrupt */
#define MMC_TX_INTR 0x0108 /* MMC TX Interrupt */
#define MMC_RX_INTR_MASK 0x010c /* MMC Interrupt Mask */
#define MMC_TX_INTR_MASK 0x0110 /* MMC Interrupt Mask */
#define MMC_RX_IPC_INTR_MASK 0x0200
#define MMC_RX_IPC_INTR 0x0208
#define MMC_DEFAULT_MASK 0xffffffff
/* DMA CRS Control and Status Register Mapping */
#define DMA_BUS_MODE 0x00001000 /* Bus Mode */
#define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */
#define DMA_RCV_POLL_DEMAND 0x00001008 /* Received Poll Demand */
#define DMA_RCV_BASE_ADDR 0x0000100c /* Receive List Base */
#define DMA_TX_BASE_ADDR 0x00001010 /* Transmit List Base */
#define DMA_STATUS 0x00001014 /* Status Register */
#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */
#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */
#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
#define DMA_RX_WATCHDOG 0x1024 /* Receive Interrupt Watchdog */
#define DMA_BUS_RPBL(x) ((x & 0x3f) << 17)
#define DMA_BUS_FB (1 << 16) /* Fixed Burst */
#define DMA_BUS_PBL(x) ((x & 0x3f) << 8)
#define DMA_BUS_DSL(x) ((x & 0x1F) << 2) /* Descriptor Skip Length */
#define DMA_BUS_DA (1 << 1) /* DMA Arbitration Scheme,Rx High Pro */
#define DMA_BUS_SWR (1 << 0) /* Software Reset */
#define DMA_BUS_INIT (DMA_BUS_FB | DMA_BUS_PBL(16) | DMA_BUS_RPBL(16))
#define DMA_OP_MODE 0x1018 /* Operational Mode */
#define DMA_OP_DT (1 << 26) /* No Dropping of TCP/IP csum Err Frame */
#define DMA_OP_RSF (1 << 25) /* Rx Store and Forward */
#define DMA_OP_TSF (1 << 21) /* Tx Store and Forward */
#define DMA_OP_FTF (1 << 20) /* Flush Tx FIFO */
#define DMA_OP_TTC(x) ((x & 7) << 14) /* Tx Threshold Control */
#define DMA_OP_ST (1 << 13) /* Start/Stop Tx */
#define DMA_OP_RFD(x) ((x & 3) << 11) /* Threshold for DeActive Flow Control */
#define DMA_OP_RFA(x) ((x & 3) << 9) /* Threshold for Active Flow Control */
#define DMA_OP_EFC (1 << 8) /* Enable HW Flow control */
#define DMA_OP_FEF (1 << 7) /* Forward Error Frame */
#define DMA_OP_FUF (1 << 6) /* Forward Undersize Good Frame */
#define DMA_OP_RTC(x) ((x & 3) << 3) /* Rx Threshold Control */
#define DMA_OP_OSF (1 << 2) /* Operate On Second Mode */
#define DMA_OP_SR (1 << 1) /* Start/Stop Rx */
#define DMA_OP_INIT (DMA_OP_TSF | DMA_OP_OSF | DMA_OP_RSF)
#define GMAC_MMC_CNTRL 0x0100 /* MMC Control */
#define GMAC_MMC_RX_INT 0x0104 /* MMC Rx Int */
#define GMAC_MMC_TX_INT 0x0108 /* MMC Tx Int */
#define GMAC_MMC_RXINT_MASK 0x010C /* MMC Rx Int Mask */
#define GMAC_MMC_TXINT_MASK 0x0110 /* MMC Tx Int Mask */
#define DMA_INT_EN 0x101C /* Int Enable */
/* DMA Normal interrupt */
#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */
#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */
#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavailable */
#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */
#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */
#define DMA_INTR_ENA_TX_IRQS (DMA_INTR_ENA_TIE | DMA_INTR_ENA_ETE)
#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
DMA_INTR_ENA_TX_IRQS)
/* DMA Abnormal interrupt */
#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */
#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */
#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */
#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */
#define DMA_INTR_ENA_RSE 0x00000100 /* Receive Stopped */
#define DMA_INTR_ENA_RUE 0x00000080 /* Receive Buffer Unavailable */
#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */
#define DMA_INTR_ENA_OVE 0x00000010 /* Receive Overflow */
#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */
#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */
#define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */
#define MAC_ENABLE_RX 0x00000004 /* Receiver Enable */
#define CFG_SMII_FTERR (1 << 26) /* SMII Force Tx Error */
#define CFG_CST (1 << 25) /* CRC stripping for type frames */
#define CFG_TX_CONFIG (1 << 24) /* Tx Configuration in RGMII/SGMII/SMII */
#define CFG_WD_DIS (1 << 23) /* Watchdog Disable */
#define CFG_JABBER_DIS (1 << 22) /* Jabber Disable */
#define CFG_FRAME_BST_EN (1 << 21) /* Frame Burst Enable */
#define CFG_JUMBO_EN (1 << 20) /* Jumbo Frame Enable */
#define CFG_IFG(x) (((x) & 7) << 17) /* Inter-Frame Gap */
#define CFG_DIS_CRS (1 << 16) /* Disable carrier sense during Tx */
#define CFG_MII_PORT_SEL (1 << 15) /* Port Select 0:GMII, 1:MII */
#define CFG_FES_100 (1 << 14) /* Seep 0:10,1:100 */
#define CFG_DIS_RX_OWN (1 << 13) /* Disable Rx Own */
#define CFG_LOOPBACK (1 << 12) /* Loop-back Mode */
#define CFG_DPLX_MODE (1 << 11) /* Duplex Mode */
#define CFG_IPC (1 << 10) /* Checksum offload */
#define CFG_DIS_RETRY (1 << 9) /* Disable Retry */
#define CFG_LINK_UD (1 << 8) /* LINK Up/Down */
#define CFG_AUTO_PCS (1 << 7) /* Automatic Pad/CRC Stripping */
#define CFG_DEF_CHECK (1 << 4) /* Deferral Check */
#define CFG_TX_EN (1 << 3) /* Tx Enable */
#define CFG_RX_EN (1 << 2) /* Rx Enable */
#define GMAC_INIT (CFG_DIS_RX_OWN | CFG_JABBER_DIS | CFG_AUTO_PCS | CFG_IPC | \
CFG_FRAME_BST_EN | CFG_DPLX_MODE | CFG_WD_DIS | CFG_CST)
/* DMA Status register */
#define DMA_LINE_INTF_INT 0x04000000 /* Line interface interrupt */
#define DMA_ERROR_BIT2 0x02000000 /* err. 0-data buffer, 1-desc. access, read only */
#define DMA_ERROR_BIT1 0x01000000 /* err. 0-write trnsf, 1-read transfr, read only */
#define DMA_ERROR_BIT0 0x00800000 /* err. 0-Rx DMA, 1-Tx DMA, read only */
#define DMA_TX_STATE 0x00700000 /* Transmit process state, read only */
#define DMA_TX_STOPPED 0x00000000 /* Stopped */
#define DMA_TX_FETCHING 0x00100000 /* Running - fetching the descriptor */
#define DMA_TX_WAITING 0x00200000 /* Running - waiting for end of transmission */
#define DMA_TX_READING 0x00300000 /* Running - reading the data from memory */
#define DMA_TX_SUSPENDED 0x00600000 /* Suspended */
#define DMA_TX_CLOSING 0x00700000 /* Running - closing descriptor */
#define DMA_RX_STATE 0x000E0000 /* Receive process state, read only */
#define DMA_RX_STOPPED 0x00000000 /* Stopped */
#define DMA_RX_FETCHING 0x00020000 /* Running - fetching the descriptor */
#define DMA_RX_WAITING 0x00060000 /* Running - waiting for packet */
#define DMA_RX_SUSPENDED 0x00080000 /* Suspended */
#define DMA_RX_CLOSING 0x000A0000 /* Running - closing descriptor */
#define DMA_RX_QUEUING 0x000E0000 /* Running - queuing the recieve frame into host memory */
#define DMA_INT_NORMAL 0x00010000 /* Normal interrupt summary, RW */
#define DMA_INT_ABNORMAL 0x00008000 /* Abnormal interrupt summary, RW */
#define DMA_INT_EARLY_RX 0x00004000 /* Early receive interrupt (Normal) RW 0 */
#define DMA_INT_BUS_ERROR 0x00002000 /* Fatal bus error (Abnormal) RW 0 */
#define DMA_INT_EARLY_TX 0x00000400 /* Early transmit interrupt (Abnormal) RW 0 */
#define DMA_INT_RX_WDOG_TO 0x00000200 /* Receive Watchdog Timeout (Abnormal) RW 0 */
#define DMA_INT_RX_STOPPED 0x00000100 /* Receive process stopped (Abnormal) RW 0 */
#define DMA_INT_RX_NO_BUFFER 0x00000080 /* Receive buffer unavailable (Abnormal) RW 0 */
#define DMA_INT_RX_COMPLETED 0x00000040 /* Completion of frame reception (Normal) RW 0 */
#define DMA_INT_TX_UNDERFLOW 0x00000020 /* Transmit underflow (Abnormal) RW 0 */
#define DMA_INT_RX_OVERFLOW 0x00000010 /* Receive Buffer overflow interrupt RW 0 */
#define DMA_INT_TX_JABBER_TO 0x00000008 /* Transmit Jabber Timeout (Abnormal) RW 0 */
#define DMA_INT_TX_NO_BUFFER 0x00000004 /* Transmit buffer unavailable (Normal) RW 0 */
#define DMA_INT_TX_STOPPED 0x00000002 /* Transmit process stopped (Abnormal) RW 0 */
#define DMA_INT_TX_COMPLETED 0x00000001 /* Transmit completed (Normal) RW 0 */
/* DMA default interrupt mask */
#define DMA_INT_ENABLE (DMA_INT_NORMAL | DMA_INT_ABNORMAL | DMA_INT_BUS_ERROR \
| DMA_INT_RX_NO_BUFFER | DMA_INT_RX_COMPLETED | DMA_INT_RX_STOPPED\
| DMA_INT_TX_UNDERFLOW | DMA_INT_TX_COMPLETED | DMA_INT_TX_STOPPED)
/* DMA Control register defines */
#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */
#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */
/* SW Reset */
#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */
/* DMA Status register defines */
#define DMA_STATUS_GLPII 0x40000000 /* GMAC LPI interrupt */
#define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */
#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */
#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int */
#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */
#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */
#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */
#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */
#define DMA_STATUS_TS_SHIFT 20
#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */
#define DMA_STATUS_RS_SHIFT 17
#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */
#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */
#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */
#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */
#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */
#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */
#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */
#define DMA_STATUS_RU 0x00000080 /* Receive Buffer Unavailable */
#define DMA_STATUS_RI 0x00000040 /* Receive Interrupt */
#define DMA_STATUS_UNF 0x00000020 /* Transmit Underflow */
#define DMA_STATUS_OVF 0x00000010 /* Receive Overflow */
#define DMA_STATUS_TJT 0x00000008 /* Transmit Jabber Timeout */
#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavailable */
#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */
#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */
#define DMA_STATUS_IRQS (DMA_STATUS_TI)
/* Normal receive descriptor defines */
/* RDES0 */
#define RDES0_PAYLOAD_CSUM_ERR BIT(0)
#define RDES0_CRC_ERROR BIT(1)
#define RDES0_DRIBBLING BIT(2)
#define RDES0_MII_ERROR BIT(3)
#define RDES0_RECEIVE_WATCHDOG BIT(4)
#define RDES0_FRAME_TYPE BIT(5)
#define RDES0_COLLISION BIT(6)
#define RDES0_IPC_CSUM_ERROR BIT(7)
#define RDES0_LAST_DESCRIPTOR BIT(8)
#define RDES0_FIRST_DESCRIPTOR BIT(9)
#define RDES0_VLAN_TAG BIT(10)
#define RDES0_OVERFLOW_ERROR BIT(11)
#define RDES0_LENGTH_ERROR BIT(12)
#define RDES0_SA_FILTER_FAIL BIT(13)
#define RDES0_DESCRIPTOR_ERROR BIT(14)
#define RDES0_ERROR_SUMMARY BIT(15)
#define RDES0_FRAME_LEN_MASK (0x3FFF << 16)/*GENMASK(29, 16)*/
#define RDES0_FRAME_LEN_SHIFT 16
#define RDES0_DA_FILTER_FAIL BIT(30)
#define RDES0_OWN BIT(31)
/* RDES1 */
#define RDES1_BUFFER1_SIZE_MASK GENMASK(10, 0)
#define RDES1_BUFFER2_SIZE_MASK GENMASK(21, 11)
#define RDES1_BUFFER2_SIZE_SHIFT 11
#define RDES1_SECOND_ADDRESS_CHAINED BIT(24)
#define RDES1_END_RING BIT(25)
#define RDES1_DISABLE_IC BIT(31)
/* Enhanced receive descriptor defines */
/* RDES0 (similar to normal RDES) */
#define ERDES0_RX_MAC_ADDR BIT(0)
/* RDES1: completely differ from normal desc definitions */
#define ERDES1_BUFFER1_SIZE_MASK GENMASK(12, 0)
#define ERDES1_SECOND_ADDRESS_CHAINED BIT(14)
#define ERDES1_END_RING BIT(15)
#define ERDES1_BUFFER2_SIZE_MASK GENMASK(28, 16)
#define ERDES1_BUFFER2_SIZE_SHIFT 16
#define ERDES1_DISABLE_IC BIT(31)
/* Normal transmit descriptor defines */
/* TDES0 */
#define TDES0_DEFERRED BIT(0)
#define TDES0_UNDERFLOW_ERROR BIT(1)
#define TDES0_EXCESSIVE_DEFERRAL BIT(2)
#define TDES0_COLLISION_COUNT_MASK GENMASK(6, 3)
#define TDES0_VLAN_FRAME BIT(7)
#define TDES0_EXCESSIVE_COLLISIONS BIT(8)
#define TDES0_LATE_COLLISION BIT(9)
#define TDES0_NO_CARRIER BIT(10)
#define TDES0_LOSS_CARRIER BIT(11)
#define TDES0_PAYLOAD_ERROR BIT(12)
#define TDES0_FRAME_FLUSHED BIT(13)
#define TDES0_JABBER_TIMEOUT BIT(14)
#define TDES0_ERROR_SUMMARY BIT(15)
#define TDES0_IP_HEADER_ERROR BIT(16)
#define TDES0_TIME_STAMP_STATUS BIT(17)
#define TDES0_OWN ((UINT32)BIT(31)) /* silence sparse */
/* TDES1 */
#define TDES1_BUFFER1_SIZE_MASK GENMASK(10, 0)
#define TDES1_BUFFER2_SIZE_MASK GENMASK(21, 11)
#define TDES1_BUFFER2_SIZE_SHIFT 11
#define TDES1_TIME_STAMP_ENABLE BIT(22)
#define TDES1_DISABLE_PADDING BIT(23)
#define TDES1_SECOND_ADDRESS_CHAINED BIT(24)
#define TDES1_END_RING BIT(25)
#define TDES1_CRC_DISABLE BIT(26)
#define TDES1_CHECKSUM_INSERTION_MASK GENMASK(28, 27)
#define TDES1_CHECKSUM_INSERTION_SHIFT 27
#define TDES1_FIRST_SEGMENT BIT(29)
#define TDES1_LAST_SEGMENT BIT(30)
#define TDES1_INTERRUPT BIT(31)
#define DESC_TXCTRL_SIZE1MASK (0x7FF << 0)
#define GMAC_CONTROL_DCRS 0x00010000 /* Disable carrier sense */
#define GMAC_CONTROL_PS 0x00008000 /* Port Select 0:GMI 1:MII */
#define GMAC_CONTROL_FES 0x00004000 /* Speed 0:10 1:100 */
#define GMAC_CONTROL_DO 0x00002000 /* Disable Rx Own */
#define GMAC_CONTROL_LM 0x00001000 /* Loop-back mode */
#define GMAC_CONTROL_DM 0x00000800 /* Duplex Mode */
#define GMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */
#define GMAC_CONTROL_DR 0x00000200 /* Disable Retry */
#define GMAC_CONTROL_LUD 0x00000100 /* Link up/down */
#define GMAC_CONTROL_ACS 0x00000080 /* Auto Pad/FCS Stripping */
#define GMAC_CONTROL_DC 0x00000010 /* Deferral Check */
#define GMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */
#define GMAC_CONTROL_2K 0x08000000 /* IEEE 802.3as 2K packets */
#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
#define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on receive */
#define GMAC_CONTROL_JD 0x00400000 /* Jabber disable */
#define GMAC_CONTROL_BE 0x00200000 /* Frame Burst Enable */
#define GMAC_CONTROL_JE 0x00100000 /* Jumbo frame */
#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
GMAC_CONTROL_BE | GMAC_CONTROL_DCRS)
#define RDES1_BUFFER1_SIZE_MASK GENMASK(10, 0)
#define FFILTER_PROMIS_MODE (1 << 0) /* Promiscuous Mode */
#define FFILTER_HASH_MCAST (1 << 2)
#define FFILTER_PASSALL_MCAST (1 << 4)
typedef struct gmac_desc
{
volatile UINT32 status;
volatile UINT32 ctrl;
volatile UINT32 addr;
volatile UINT32 next;
}GMAC_DESC;
/*
* Private adapter context structure.
*/
typedef struct gmac_drv_ctrl
{
END_OBJ gmacEndObj;
VXB_DEVICE_ID gmacDev;
void * gmacBar;
void * gmacHandle;
FUNCPTR clkSetup;
FUNCPTR ifCached;
void * gmacMuxDevCookie;
JOB_QUEUE_ID gmacJobQueue;
QJOB gmacIntJob;
volatile atomicVal_t gmacIntPending;
volatile atomicVal_t gmacRxPending;
volatile atomicVal_t gmacTxPending;
BOOL gmacPolling;
M_BLK_ID gmacPollBuf;
UINT32 gmacIntrs;
UINT8 gmacAddr[ETHER_ADDR_LEN];
END_CAPABILITIES gmacCaps;
END_IFDRVCONF gmacEndStatsConf;
END_IFCOUNTERS gmacEndStatsCounters;
UINT32 gmacInErrors;
UINT32 gmacInDiscards;
UINT32 gmacInUcasts;
UINT32 gmacInMcasts;
UINT32 gmacInBcasts;
UINT32 gmacInOctets;
UINT32 gmacOutErrors;
UINT32 gmacOutUcasts;
UINT32 gmacOutMcasts;
UINT32 gmacOutBcasts;
UINT32 gmacOutOctets;
/* Begin MII/ifmedia required fields. */
END_MEDIALIST * gmacMediaList;
END_ERR gmacLastError;
UINT32 gmacCurMedia;
UINT32 gmacCurStatus;
VXB_DEVICE_ID gmacMiiBus;
VXB_DEVICE_ID gmacMiiDev;
FUNCPTR gmacMiiPhyRead;
FUNCPTR gmacMiiPhyWrite;
int gmacMiiPhyAddr;
/* End MII/ifmedia required fields */
/* DMA tags and maps. */
GMAC_DESC * gmacRxDescMem;
GMAC_DESC * gmacTxDescMem;
M_BLK_ID gmacTxMblk[GMAC_TX_DESC_CNT];
M_BLK_ID gmacRxMblk[GMAC_RX_DESC_CNT];
UINT32 gmacTxProd;
UINT32 gmacTxCons;
UINT32 gmacTxFree;
UINT32 gmacRxIdx;
UINT32 gmacTxLast;
UINT32 gmacTxStall;
SEM_ID gmacMiiSem;
spinlockIsr_t gmacLock;
int gmacMaxMtu;
BOOL gmacExPhy; /* if true, indicates it's using external PHY */
SEM_ID gmacDevSem;
int unit;
/* MDC clock access PHY. [1.0MHz ~2.5MHz] */
UINT32 clkMDC;
void (*gmacAddrSet)(UINT8* macAddr);
} GMAC_DRV_CTRL;
#define GMAC_CACHE_DRV_VIRT_TO_PHYS(adrs) \
CACHE_DRV_VIRT_TO_PHYS(&cacheDmaFuncs, (void *) (adrs))
#define GMAC_BAR(p) ((GMAC_DRV_CTRL *)(p)->pDrvCtrl)->gmacBar
#define GMAC_HANDLE(p) ((GMAC_DRV_CTRL *)(p)->pDrvCtrl)->gmacHandle
#define CSR_READ_4(pDev, addr) \
vxbRead32(GMAC_HANDLE(pDev), \
(UINT32 *)((char *)GMAC_BAR(pDev) + addr))
#define CSR_WRITE_4(pDev, addr, data) \
vxbWrite32(GMAC_HANDLE(pDev), \
(UINT32 *)((char *)GMAC_BAR(pDev) + addr), data)
#define CSR_SETBIT_4(pDev, offset, val) \
CSR_WRITE_4(pDev, offset, CSR_READ_4(pDev, offset) | (val))
#define CSR_CLRBIT_4(pDev, offset, val) \
CSR_WRITE_4(pDev, offset, CSR_READ_4(pDev, offset) & ~(val))
#endif /* BSP_VERSION */
#ifdef __cplusplus
}
#endif
#endif /* __INCvxbFtGmacEndh */

763
vxbFtGpio.c

@ -0,0 +1,763 @@
/* vxbFtGpioCtrl.c - Driver for GPIO controller */
/*
*
* 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 <vxWorks.h>
#include <vsbConfig.h>
#include <intLib.h>
#include <errnoLib.h>
#include <errno.h>
#include <sioLib.h>
#include <ioLib.h>
#include <stdio.h>
#include <string.h>
#include <logLib.h>
#include <hwif/util/hwMemLib.h>
#include <hwif/util/vxbParamSys.h>
#include <hwif/vxbus/vxbIntrCtlr.h>
#include <hwif/vxbus/vxBus.h>
#include <vxbFtGpio.h>
#define GPIO_DBG_ON
#ifdef GPIO_DBG_ON
#define GPIO_DBG_IRQ 0x00000001
#define GPIO_DBG_RW 0x00000002
#define GPIO_DBG_ERR 0x00000004
#define GPIO_DBG_ALL 0xffffffff
#define GPIO_DBG_OFF 0x00000000
LOCAL UINT32 gpioDbgMask = GPIO_DBG_ALL;
IMPORT FUNCPTR _func_logMsg;
#define GPIO_DBG(mask, string, a, b, c, d, e, f) \
if ((gpioDbgMask & mask) || (mask == GPIO_DBG_ALL)) \
if (_func_logMsg != NULL) \
(* _func_logMsg)(string, a, b, c, d, e, f)
#else
#define GPIO_DBG(mask, string, a, b, c, d, e, f)
#endif /* GPIO_DBG_ON */
LOCAL void vxbFtGpioInstInit(VXB_DEVICE_ID pInst);
LOCAL void vxbFtGpioInstInit2(VXB_DEVICE_ID pInst);
LOCAL void vxbFtGpioInstConnect(VXB_DEVICE_ID pInst);
LOCAL STATUS vxbFtGpioPinModeSet (VXB_DEVICE_ID pDev, UINT32 port, UINT32 pin,UINT32 mode);
LOCAL UINT32 vxbFtGpioPinInput (VXB_DEVICE_ID pDev, UINT32 port, UINT32 pin);
LOCAL STATUS vxbFtGpioPinOuput (VXB_DEVICE_ID pDev, UINT32 port, UINT32 pin,
UINT32 value);
LOCAL STATUS vxbFtGpioISRSet (VXB_DEVICE_ID pDev, UINT32 pin,
VOIDFUNCPTR pIsr, void * pArg);
LOCAL void vxbFtGpioISR (FT_GPIO_DRVCTRL * pDrvCtrl);
LOCAL struct drvBusFuncs vxbFtGpioDrvFuncs =
{
vxbFtGpioInstInit, /* devInstanceInit */
vxbFtGpioInstInit2, /* devInstanceInit2 */
vxbFtGpioInstConnect /* devConnect */
};
LOCAL device_method_t vxbFtGpioDrv_methods[] =
{
DEVMETHOD_END
};
/* FT2000/4 GPIO VxBus registration info */
LOCAL struct vxbDevRegInfo vxbFtGpioDrvRegistration =
{
NULL, /* pNext */
VXB_DEVID_DEVICE, /* devID */
VXB_BUSID_PLB, /* busID = PLB */
VXB_VER_4_0_0, /* busVer */
"ftGpio", /* drvName */
&vxbFtGpioDrvFuncs, /* pDrvBusFuncs */
&vxbFtGpioDrv_methods[0], /* pMethods */
NULL /* devProbe */
};
/******************************************************************************
*
* vxbFtGpioDrvRegister - register FT2000/4 GPIO driver
*
* This routine registers the FT2000/4 GPIO driver with the vxBus subsystem.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
void vxbFtGpioDrvRegister (void)
{
/* call the vxBus routine to register the GPIO driver */
vxbDevRegister (&vxbFtGpioDrvRegistration);
}
/*******************************************************************************
*
* vxbFtGpioInstInit - first level initialization routine of GPIO modules
*
* This is the function called to perform the first level initialization of
* the six FT2000/4 GPIO modules.
*
* NOTE:
*
* This routine is called early during system initialization, and
* *MUST NOT* make calls to OS facilities such as memory allocation
* and I/O.
*
* RETURNS: N/A
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL void vxbFtGpioInstInit
(
VXB_DEVICE_ID pInst
)
{
}
/*******************************************************************************
*
* vxbFtGpioInstInit2 - second level initialization routine of GPIO modules
*
* This routine performs the second level initialization of the GPIO modules.
*
* This routine is called later during system initialization. OS features
* such as memory allocation are available at this time.
*
* RETURNS: N/A
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL void vxbFtGpioInstInit2
(
VXB_DEVICE_ID pInst
)
{
STATUS st[GPIO_PORT_MUM];
FT_GPIO_DRVCTRL * pDrvCtrl;
UINT32 port = 0, pin = 0;
HCF_DEVICE * pHcf;
UINT32 ** ppPortModeTable[GPIO_PORT_MUM];
UINT32 *pPortModeTable[GPIO_PORT_MUM];
pDrvCtrl = (FT_GPIO_DRVCTRL *)hwMemAlloc(sizeof (FT_GPIO_DRVCTRL));
if (pDrvCtrl == NULL)
{
GPIO_DBG(GPIO_DBG_ERR, "vxbFtGpioInstInit: pDrvCtrl alloc failed\r\n.",1,2,3,4,5,6);
return;
}
pInst->pDrvCtrl = pDrvCtrl;
pDrvCtrl->pInst = pInst;
/* map register base */
if (vxbRegMap(pInst, 0, &pDrvCtrl->gpioHandle) == ERROR)
{
GPIO_DBG (GPIO_DBG_ERR, "vxbFtGpioInstInit: vxbRegMap GPIO ERROR\n", 1, 2, 3, 4, 5, 6);
#ifndef _VXBUS_BASIC_HWMEMLIB
hwMemFree ((char *)pDrvCtrl);
#endif /* _VXBUS_BASIC_HWMEMLIB */
pInst->pDrvCtrl = NULL;
return;
}
pDrvCtrl->gpioModeSet = vxbFtGpioPinModeSet;
pDrvCtrl->gpioInput = vxbFtGpioPinInput;
pDrvCtrl->gpioOutput = vxbFtGpioPinOuput;
pDrvCtrl->gpioISRSet = vxbFtGpioISRSet;
pDrvCtrl->intEnabled = FALSE;
/* clear all interrupt */
GPIO_WRITE_4 (pDrvCtrl, GPIO_INTEN_A, 0);
ppPortModeTable[0] = &pPortModeTable[0];
ppPortModeTable[1] = &pPortModeTable[1];
pHcf = (struct hcfDevice *) hcfDeviceGet (pInst);
if (pHcf == NULL)
{
#ifndef _VXBUS_BASIC_HWMEMLIB
hwMemFree ((char *)pDrvCtrl);
#endif /* _VXBUS_BASIC_HWMEMLIB */
pInst->pDrvCtrl = NULL;
return;
}
if (devResourceGet (pHcf, "trigger", HCF_RES_INT,(void *) &pDrvCtrl->triggerMode) != OK)
{
pDrvCtrl->triggerMode = 0;
}
st[0] = devResourceGet (pHcf, "portAModeTable", HCF_RES_ADDR, (void **)ppPortModeTable[0]);
st[1] = devResourceGet (pHcf, "portBModeTable", HCF_RES_ADDR, (void **)ppPortModeTable[1]);
for(port = 0; port < GPIO_PORT_MUM; port++)
{
for(pin = 0; pin < FT_GPIO_PORT_WIDTH; pin ++)
{
if(st[port] == OK)
vxbFtGpioPinModeSet(pInst, port, pin, *(pPortModeTable[port] + pin));
else
vxbFtGpioPinModeSet(pInst, port, pin, GPIO_MODE_NOT_USED);
}
}
return;
}
/*******************************************************************************
*
* vxbFtInstConnect - third level initialization routine of GPIO modules
*
* This is the function called to perform the third level initialization of
* the GPIO modules.
*
* RETURNS: N/A
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL void vxbFtGpioInstConnect
(
VXB_DEVICE_ID pInst
)
{
/* nothing is done here */
}
LOCAL STATUS vxbFtGpioBitSet(FT_GPIO_DRVCTRL * pDrvCtrl, UINT32 reg, UINT32 pin, UINT32 bit)
{
UINT32 value=0;
if(pin >= FT_GPIO_PORT_WIDTH)
{
GPIO_DBG(GPIO_DBG_ERR, "[reg 0x%x]Bad pin %d! Only support pin: 0~%d \r\n", reg, pin, FT_GPIO_PORT_WIDTH - 1,4,5,6);
return ERROR;
}
if((bit!=0)&&(bit!=1))
{
GPIO_DBG(GPIO_DBG_ERR, "[reg 0x%x]Bad bit value %d! \r\n", reg, bit,3,4,5,6);
return ERROR;
}
value = GPIO_READ_4(pDrvCtrl, reg);
switch(bit)
{
case 0:
value &= ~(1<<pin);
break;
case 1:
value |= (1<<pin);
break;
default:
return ERROR;
}
GPIO_WRITE_4(pDrvCtrl, reg, value);
return OK;
}
/*******************************************************************************
*
* vxbFtGpioPinIntEnable - enable interrupt of a pin
*
* the function enable interrupt of a pin.
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL STATUS vxbFtGpioPinIntEnable
(
VXB_DEVICE_ID pDev,
UINT32 pin
)
{
FT_GPIO_DRVCTRL * pDrvCtrl = pDev->pDrvCtrl;
STATUS st = OK;
/*all pin of portA use a common interrupt number*/
if(pDrvCtrl->intEnabled == FALSE)
{
st |= vxbIntConnect(pDev, 0, vxbFtGpioISR, pDrvCtrl);
st |= vxbIntEnable(pDev, 0, vxbFtGpioISR, pDrvCtrl);
if (OK == st)
pDrvCtrl->intEnabled = TRUE;
else
GPIO_DBG(GPIO_DBG_ERR, "Failed to enable port 0 pin %d interrupt\r\n", pin, 2,3,4,5,6);
}
return st;
}
/*******************************************************************************
*
* vxbFtGpioPinIntDisable - disable interrupt of a pin
*
* the function disable interrupt of a pin.
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL STATUS vxbFtGpioPinIntDisable
(
VXB_DEVICE_ID pDev,
UINT32 pin
)
{
FT_GPIO_DRVCTRL * pDrvCtrl = pDev->pDrvCtrl;
STATUS st = OK;
STATUS disableFlag = TRUE;
UINT32 i;
/*all pin of a portA use a common interrupt number,
so only if all of pins of portA are not used as interrupt pin,
we need to disable the interrupt*/
if(pDrvCtrl->intEnabled == TRUE)
{
for(i = 0; i < FT_GPIO_PORT_WIDTH; i++)
{
if((pDrvCtrl->pinMode[0][i] == GPIO_MODE_INT) && (i != pin))
{
/*have another pin that used as interrupt pin, so don't need to disable interrupt */
disableFlag = FALSE;
break;
}
}
if(disableFlag == TRUE)
{
st |= vxbIntDisable(pDev, 0, vxbFtGpioISR, pDrvCtrl);
st |= vxbIntDisconnect(pDev, 0, vxbFtGpioISR, pDrvCtrl);
if (OK == st)
pDrvCtrl->intEnabled = FALSE;
else
GPIO_DBG(GPIO_DBG_ERR, "Failed to disable port 0 pin %d interrupt\r\n", pin, 2,3,4,5,6);
}
}
return st;
}
/*******************************************************************************
*
* vxbFtGpioPinModeSet - set mode of a pin
*
* the function set mode of a pin.
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL STATUS vxbFtGpioPinModeSet
(
VXB_DEVICE_ID pDev,
UINT32 port,
UINT32 pin,
UINT32 mode
)
{
FT_GPIO_DRVCTRL * pDrvCtrl = pDev->pDrvCtrl;
STATUS st = OK;
UINT32 level = 0, polar = 0;
if ((port > GPIO_PORT_B) || (pin >= FT_GPIO_PORT_WIDTH) || (mode > GPIO_MODE_INT))
{
GPIO_DBG(GPIO_DBG_ERR, "Parameter is out of range : GPIO port %d, pin %d, mode %d\r\n", port, pin, mode,4,5,6);
return ERROR;
}
/* only port A support interrupt */
if((mode == GPIO_MODE_INT) && (port != GPIO_PORT_A))
{
GPIO_DBG(GPIO_DBG_ERR, "Only port A support interrupt \r\n", 1,2,3,4,5,6);
return ERROR;
}
switch(mode)
{
case GPIO_MODE_NOT_USED:
case GPIO_MODE_IN:
if (port == GPIO_PORT_A)
{
st |= vxbFtGpioPinIntDisable(pDev, pin);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_A, pin, GPIO_DIR_IN);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTMASK_A, pin, GPIO_INT_MASK);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTEN_A, pin, GPIO_INT_DIS);
}
else
{
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_B, pin, GPIO_DIR_IN);
}
break;
case GPIO_MODE_OUT:
if (port == GPIO_PORT_A)
{
st |= vxbFtGpioPinIntDisable(pDev, pin);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_A, pin, GPIO_DIR_OUT);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTMASK_A, pin, GPIO_INT_MASK);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTEN_A, pin, GPIO_INT_DIS);
}
else
{
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_B, pin, GPIO_DIR_OUT);
}
break;
case GPIO_MODE_INT:
if(port == GPIO_PORT_A)
{
switch(pDrvCtrl->triggerMode)
{
case VXB_INTR_TRIG_FALLING_EDGE:
level = GPIO_INT_TYPE_EDGE;
polar = GPIO_INT_POL_LOW_DOWN;
break;
case VXB_INTR_TRIG_RISING_EDGE:
level = GPIO_INT_TYPE_EDGE;
polar = GPIO_INT_POL_HIGH_UP;
break;
case VXB_INTR_TRIG_ACTIVE_LOW:
level = GPIO_INT_TYPE_LEVEL;
polar = GPIO_INT_POL_LOW_DOWN;
break;
case VXB_INTR_TRIG_ACTIVE_HIGH:
level = GPIO_INT_TYPE_LEVEL;
polar = GPIO_INT_POL_HIGH_UP;
break;
default:
pDrvCtrl->pinMode[port][pin] = GPIO_MODE_NOT_USED;
GPIO_DBG(GPIO_DBG_ERR, "Mode set error of port %d pin %d: trigger mode error \r\n", port, pin,3,4,5,6);
return ERROR;
}
st |= vxbFtGpioPinIntEnable(pDev, pin);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DDR_A, pin, GPIO_DIR_IN);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTMASK_A, pin, GPIO_INT_NOT_MASK);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTTYPE_LEVEL_A, pin, level);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INT_POLARITY_A, pin, polar);
st |= vxbFtGpioBitSet(pDrvCtrl, GPIO_INTEN_A, pin, GPIO_INT_ENA);
}
break;
default:
return ERROR;
}
if (OK != st)
{
pDrvCtrl->pinMode[port][pin] = GPIO_MODE_NOT_USED;
GPIO_DBG(GPIO_DBG_ERR, "Mode set error of port %d pin %d\r\n", port, pin,3,4,5,6);
return ERROR;
}
else
{
pDrvCtrl->pinMode[port][pin] = mode;
}
return OK;
}
/*******************************************************************************
*
* vxbFtGpioPinInput - gpio pin input value
*
* The function return value of specified intput pin.
*
* RETURNS: input value
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL UINT32 vxbFtGpioPinInput
(
VXB_DEVICE_ID pDev,
UINT32 port,
UINT32 pin
)
{
FT_GPIO_DRVCTRL * pDrvCtrl = pDev->pDrvCtrl;
if ((port > GPIO_PORT_B) || (pin >= FT_GPIO_PORT_WIDTH))
{
GPIO_DBG(GPIO_DBG_ERR, "Parameter is out of range :GPIO port %d, pin %d \r\n", port, pin,3,4,5,6);
return (UINT32)ERROR;
}
if (pDrvCtrl->pinMode[port][pin] != GPIO_MODE_IN)
{
GPIO_DBG(GPIO_DBG_ERR, "port %d pin %d is not in input mode\r\n",port, pin,3,4,5,6);
return (UINT32)ERROR;
}
if ( port == GPIO_PORT_A)
return ((GPIO_READ_4(pDrvCtrl, GPIO_EXT_A) >> pin) & 1);
else
return ((GPIO_READ_4(pDrvCtrl, GPIO_EXT_B) >> pin) & 1);
}
/*******************************************************************************
*
* vxbFtGpioPinOuput - output value to gpio pin
*
* Write value to the specified pin.
*
* RETURNS: OK or ERROR if the pin is invalid.
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL STATUS vxbFtGpioPinOuput
(
VXB_DEVICE_ID pDev,
UINT32 port,
UINT32 pin,
UINT32 value
)
{
FT_GPIO_DRVCTRL * pDrvCtrl = pDev->pDrvCtrl;
if ((port > GPIO_PORT_B) || (pin >= FT_GPIO_PORT_WIDTH))
{
GPIO_DBG(GPIO_DBG_ERR, "Parameter is out of range :GPIO port %d, pin %d \r\n", port, pin,3,4,5,6);
return ERROR;
}
if (pDrvCtrl->pinMode[port][pin] != GPIO_MODE_OUT)
{
GPIO_DBG(GPIO_DBG_ERR, "port %d pin %d is not in output mode\r\n",port, pin,3,4,5,6);
return ERROR;
}
if((value!=0)&&(value!=1))
{
GPIO_DBG(GPIO_DBG_ERR, "Bad pin value %d! Only support value: 0,1 \r\n", value,2,3,4,5,6);
return ERROR;
}
if (port == GPIO_PORT_A)
vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DR_A, pin, value);
else
vxbFtGpioBitSet(pDrvCtrl, GPIO_SW_DR_B, pin, value);
return OK;
}
/*******************************************************************************
*
* vxbFtGpioISRSet - set a function to be called on the gpio interrupt
*
* This function is called to set a function which can be called when
* the gpio interrupt occurs.
*
* RETURNS: OK or ERROR if the pin is invalid.
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL STATUS vxbFtGpioISRSet
(
VXB_DEVICE_ID pDev,
UINT32 pin,
VOIDFUNCPTR pIsr, /* ISR */
void * pArg /* parameter */
)
{
FT_GPIO_DRVCTRL * pDrvCtrl = pDev->pDrvCtrl;
if (pin >= FT_GPIO_PORT_WIDTH)
{
GPIO_DBG(GPIO_DBG_ERR, "Parameter is out of range :GPIO pin %d \r\n", pin, 2,3,4,5,6);
return ERROR;
}
if (pDrvCtrl->pinMode[0][pin] != GPIO_MODE_INT)
{
GPIO_DBG(GPIO_DBG_ERR, "port 0 pin %d is not in interrupt mode\r\n",pin,2,3,4,5,6);
return ERROR;
}
pDrvCtrl->isrTable[pin].pIsr = pIsr;
pDrvCtrl->isrTable[pin].pArg = pArg;
return OK;
}
/*******************************************************************************
*
* vxbFtGpioISR - interrupt level processing for gpio module
*
* This routine handles gpio interrupts. It acknowledges the interrupt and
* calls the routine installed by vxbFtGpioISRSet().
*
* RETURNS: N/A
*
* ERRNO: N/A
*
* \NOMANUAL
*
*/
LOCAL void vxbFtGpioISR
(
FT_GPIO_DRVCTRL * pDrvCtrl
)
{
UINT32 val;
UINT32 ix;
/* read interrupt flags */
val = GPIO_READ_4 (pDrvCtrl, GPIO_INTSTATUS_A);
if (val == 0)
{
GPIO_DBG(GPIO_DBG_ERR, "vxFtGpioISR: it's not a gpio interrupt. \r\n.",
1,2,3,4,5,6);
goto exit;
}
for (ix = 0; ix < FT_GPIO_PORT_WIDTH; ix++)
{
UINT32 bit = 1 << ix;
if (val & bit)
{
if (pDrvCtrl->isrTable[ix].pIsr != NULL)
{
pDrvCtrl->isrTable[ix].pIsr(pDrvCtrl->isrTable[ix].pArg);
}
else
{
/* suspicious int */
GPIO_DBG(GPIO_DBG_ERR, "vxFtGpioISR: neet to set ISR for pin %d \r\n.",
ix,2,3,4,5,6);
goto exit;
}
}
}
exit:
/* clear interrupt flags */
GPIO_WRITE_4 (pDrvCtrl, GPIO_PORTA_EOI_A, val);
return;
}
#define FT_GPIO_DEBUD
#ifdef FT_GPIO_DEBUD
void gpioModeShow(UINT32 gpio)
{
int i,j;
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
pCtrl = pDev->pDrvCtrl;
for(i = 0; i < GPIO_PORT_MUM; i++)
{
for(j = 0; j < FT_GPIO_PORT_WIDTH; j++)
printf("port %d pin %d mode %d\n", i, j, pCtrl->pinMode[i][j]);
}
printf("intEnabled %d\n", pCtrl->intEnabled);
printf("triggerMode %x\n", pCtrl->triggerMode);
}
void gpioModeSetTest (UINT32 gpio, UINT32 port, UINT32 pin, UINT32 mode)
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
pCtrl = pDev->pDrvCtrl;
pCtrl->gpioModeSet(pDev, port, pin, mode);
}
void gpioOutTest (UINT32 gpio, UINT32 port, UINT32 pin, UINT32 val)
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
pCtrl = pDev->pDrvCtrl;
pCtrl->gpioOutput(pDev, port, pin, val);
}
void gpioInTest (UINT32 gpio, UINT32 port, UINT32 pin)
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
pCtrl = pDev->pDrvCtrl;
printf("input val %d\n", pCtrl->gpioInput(pDev, port, pin));
}
LOCAL void gpioIsrFunction(void * arg)
{
UINT32 * pin = (UINT32 *)arg;
logMsg("GPIO pin %d ISR \n",* pin,0,0,0,0,0);
}
LOCAL UINT32 isrArgTest = 0;
void gpioIsrSetTest (UINT32 gpio, UINT32 pin)
{
VXB_DEVICE_ID pDev;
FT_GPIO_DRVCTRL * pCtrl;
pDev = vxbInstByNameFind("ftGpio", gpio);
pCtrl = pDev->pDrvCtrl;
isrArgTest = pin;
pCtrl->gpioISRSet(pDev, pin, gpioIsrFunction, &isrArgTest);
}
#endif

134
vxbFtGpio.h

@ -0,0 +1,134 @@
/* vxbFtGpio.h - Driver for GPIO controller*/
/*
*
* 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.
*
*/
#ifndef __INCvxbFtGpioh
#define __INCvxbFtGpioh
#ifdef __cplusplus
extern "C" {
#endif
#define GPIO_READ_4(pCtrl, addr) \
vxbRead32 ((pCtrl->gpioHandle), \
(UINT32 *)((char *)(pCtrl->pInst->pRegBase[0]) + (addr)))
#define GPIO_WRITE_4(pCtrl, addr, data) \
vxbWrite32 ((pCtrl->gpioHandle), \
(UINT32 *)((char *)(pCtrl->pInst->pRegBase[0]) + (addr)), data)
/* gpio mode */
#define GPIO_MODE_NOT_USED 0
#define GPIO_MODE_IN 1
#define GPIO_MODE_OUT 2
#define GPIO_MODE_INT 3
#define FT_GPIO_PORT_WIDTH 8
/* Register offset */
#define GPIO_SW_DR_A 0x00 /* output register for port A*/
#define GPIO_SW_DDR_A 0x04 /* director register for port A. 0:input; 1:output */
#define GPIO_EXT_A 0x08 /* input register for port A*/
#define GPIO_SW_DR_B 0x0c /* output register for port B*/
#define GPIO_SW_DDR_B 0x10 /* director register for port B. 0:input; 1:output */
#define GPIO_EXT_B 0x14 /* input register for port B*/
#define GPIO_INTEN_A 0x18 /* only Port A support interrupt */
#define GPIO_INTMASK_A 0x1c
#define GPIO_INTTYPE_LEVEL_A 0x20
#define GPIO_INT_POLARITY_A 0x24
#define GPIO_INTSTATUS_A 0x28
#define GPIO_RAW_INTSTATUS_A 0x2c
#define GPIO_LS_SYNC_A 0x30
#define GPIO_DEBOUNCE 0x34
#define GPIO_PORTA_EOI_A 0x38
/* group index */
#define GPIO_PORT_A 0
#define GPIO_PORT_B 1
#define GPIO_PORT_MUM 2
/* gpio direction */
#define GPIO_DIR_IN 0
#define GPIO_DIR_OUT 1
/* int enable/disable */
#define GPIO_INT_DIS 0
#define GPIO_INT_ENA 1
/* int mask */
#define GPIO_INT_NOT_MASK 0
#define GPIO_INT_MASK 1
/* int type */
#define GPIO_INT_TYPE_LEVEL 0
#define GPIO_INT_TYPE_EDGE 1
/* int polarity */
#define GPIO_INT_POL_LOW_DOWN 0
#define GPIO_INT_POL_HIGH_UP 1
/* Private context structure */
typedef struct ftIsrEntry
{
VOIDFUNCPTR pIsr; /* ISR */
void * pArg; /* parameter */
} FT_ISR_ENTRY;
typedef struct ftGpioDrvCtrl
{
VXB_DEVICE_ID pInst; /* pointer to the controller instance */
void * gpioHandle; /* handle of GPIO vxbRead/vxbWrite */
FT_ISR_ENTRY isrTable[FT_GPIO_PORT_WIDTH]; /* ISR handler table */
UINT8 pinMode[GPIO_PORT_MUM][FT_GPIO_PORT_WIDTH]; /* GPIO_MODE_NOT_USED 0
GPIO_MODE_IN 1
GPIO_MODE_OUT 2
GPIO_MODE_INT 3
*/
STATUS intEnabled; /*whether have pin of portA used as interrupt mode */
UINT32 triggerMode; /*Trigger mode*/
/* set pin mode */
STATUS (*gpioModeSet)
(
VXB_DEVICE_ID pDev,
UINT32 port,
UINT32 pin,
UINT32 mode
);
/* get input value of a pin */
UINT32 (*gpioInput)
(
VXB_DEVICE_ID pDev,
UINT32 port,
UINT32 pin
);
/* output value to a pin */
STATUS (*gpioOutput)
(
VXB_DEVICE_ID pDev,
UINT32 port,
UINT32 pin,
UINT32 value
);
/* set ISR for a pin */
STATUS (*gpioISRSet)
(
VXB_DEVICE_ID pDev,
UINT32 pin,
VOIDFUNCPTR pIsr, /* ISR */
void * pArg /* parameter */
);
} FT_GPIO_DRVCTRL;
#ifdef __cplusplus
}
#endif
#endif /* __INCvxbFtGpioh */

1636
vxbFtI2c.c

File diff suppressed because it is too large

286
vxbFtI2c.h

@ -0,0 +1,286 @@
/* vxbFtI2c.h - I2C Controller hardware driver */
/*
*
* 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.
*
*/
#ifndef __INCvxbFtI2ch
#define __INCvxbFtI2ch
/* includes */
#include <vxWorks.h>
#include <intLib.h>
#include <arch/arm/intArmLib.h>
#include <spinLockLib.h>
#include <vxBusLib.h>
#include <vxAtomicLib.h>
#include <isrDeferLib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* defines */
#define FT_I2C_DRIVER_NAME "ftI2c"
#define I2C_TIMEOUT 500
#define I2C_DELAY 100
#define I2C_STANDARD_SPEED 100000
#define I2C_FAST_SPEED 400000
#define I2C_DEFAULT_SYSCLK_RATE 100
#define I2C_S_TO_US 1000000
#define I2C_ERR_STATUS_RX_UNDER 1
#define I2C_ERR_STATUS_RX_OVER 2
#define I2C_ERR_STATUS_TX_ABRT 3
/* Register Definition */
#define I2C_CON 0x00
#define I2C_TAR 0x04
#define I2C_SAR 0x08
#define I2C_HS_MADDR 0x0C
#define I2C_DATA_CMD 0x10
#define I2C_SS_SCL_HCNT 0x14
#define I2C_SS_SCL_LCNT 0x18
#define I2C_FS_SCL_HCNT 0x1C
#define I2C_FS_SCL_LCNT 0x20
#define I2C_HS_SCL_HCNT 0x24
#define I2C_HS_SCL_LCNT 0x28
#define I2C_INTR_STAT 0x2C
#define I2C_INTR_MASK 0x30
#define I2C_RAW_INTR_STAT 0x34
#define I2C_RX_TL 0x38
#define I2C_TX_TL 0x3C
#define I2C_CLR_INTR 0x40
#define I2C_CLR_RX_UNDER 0x44
#define I2C_CLR_RX_OVER 0x48
#define I2C_CLR_TX_OVER 0x4C
#define I2C_CLR_RD_REQ 0x50
#define I2C_CLR_TX_ABRT 0x54
#define I2C_CLR_RX_DONE 0x58
#define I2C_CLR_ACTIVITY 0x5c
#define I2C_CLR_STOP_DET 0x60
#define I2C_CLR_START_DET 0x64
#define I2C_CLR_GEN_CALL 0x68
#define I2C_ENABLE 0x6C
#define I2C_STATUS 0x70
#define I2C_TXFLR 0x74
#define I2C_RXFLR 0x78
#define I2C_TX_ABRT_SOURCE 0x80
#define I2C_SLV_DATA_NACK_ONLY 0x84
#define I2C_DMA_CR 0x88
#define I2C_DMA_TDLR 0x8c
#define I2C_DMA_RDLR 0x90
#define I2C_SDA_SETUP 0x94
#define I2C_ACK_GENERAL_CALL 0x98
#define I2C_ENABLE_STATUS 0x9C
#define I2C_COMP_PARAM_1 0xf4
#define I2C_COMP_VERSION 0xf8
#define I2C_COMP_TYPE 0xfc
#define I2C_RAW_INTR_STAT_RX_UNDER 0x1
#define I2C_RAW_INTR_STAT_RX_OVER 0x2
#define I2C_RAW_INTR_STAT_RX_FULL 0x4
#define I2C_RAW_INTR_STAT_TX_OVER 0x8
#define I2C_RAW_INTR_STAT_TX_EMPTY 0x10
/* Default parameters */
#define I2C_CON_ME (0x1 << 0)
#define I2C_CON_MS_SS (0x1 << 1)
#define I2C_CON_MS_FS (0x2 << 1)
#define I2C_CON_SLAVE_ADR_7BIT (0x0 << 3)
#define I2C_CON_SLAVE_ADR_10BIT (0x1 << 3)
#define I2C_CON_MASTER_ADR_7BIT (0x0 << 4)
#define I2C_CON_MASTER_ADR_10BIT (0x1 << 4)
#define I2C_CON_RESTART_EN (0x1 << 5)
#define I2C_CON_SLAVE_DISABLE (0x1 << 6)
#define I2C_CTR_DEFAULT (I2C_CON_ME | I2C_CON_MASTER_ADR_7BIT | \
I2C_CON_SLAVE_DISABLE)
#define I2C_IRQ_NONE_MASK 0x0
#define I2C_IRQ_ALL_MASK 0x8ff
#define I2C_TAR_STARTBYTE (0x1 << 10)
#define I2C_TAR_SPECIAL_STARTBYTE (0x1 << 11)
#define I2C_TAR_ADR_7BIT (0x0)
#define I2C_TAR_ADR_10BIT (0x1 << 12)
#define I2C_SLAVE_DISABLE_DEFAULT 0
#define I2C_RESTART_EN_DEFAULT 1
#define I2C_10BITADDR_MASTER_DEFAULT 0
#define I2C_10BITADDR_SLAVE_DEFAULT 1
#define I2C_MAX_SPEED_MODE_DEFAULT 3
#define I2C_MASTER_MODE_DEFAULT 1
#define I2C_DEFAULT_TAR_ADDR_DEFAULT 0x055
#define I2C_DEFAULT_SLAVE_ADDR_DEFAULT 0x055
#define I2C_COMP_VERSION_DEFAULT 0x3131352A
#define I2C_HS_MASTER_CODE_DEFAULT 1
#define I2C_SS_SCL_HIGH_COUNT_DEFAULT 0x0190
#define I2C_SS_SCL_LOW_COUNT_DEFAULT 0x01d6
#define I2C_FS_SCL_HIGH_COUNT_DEFAULT 0x003c
#define I2C_FS_SCL_LOW_COUNT_DEFAULT 0x0082
#define I2C_HS_SCL_HIGH_COUNT_DEFAULT 0x006
#define I2C_HS_SCL_LOW_COUNT_DEFAULT 0x0010
#define I2C_RX_TL_DEFAULT 0
#define I2C_TX_TL_DEFAULT 0
#define I2C_DEFAULT_SDA_SETUP_DEFAULT 0x64
#define I2C_DEFAULT_ACK_GENERAL_CALL_DEFAULT 1
#define I2C_DYNAMI2C_TAR_UPDATE_DEFAULT 1
#define I2C_RX_BUFFER_DEPTH_DEFAULT 8
#define I2C_TX_BUFFER_DEPTH_DEFAULT 8
#define I2C_ADD_ENCODED_PARAMS_DEFAULT 1
#define I2C_HAS_DMA_DEFAULT 0
#define I2C_INTR_IO_DEFAULT 0
#define I2C_HC_COUNT_VALUES_DEFAULT 0
#define APB_DATA_WIDTH_DEFAULT 0
#define I2C_SLV_DATA_NACK_ONLY_DEFAULT 0
#define I2C_USE_COUNTS_DEFAULT 0
#define I2C_CLK_TYPE_DEFAULT 1
#define I2C_CLOCK_PERIOD_DEFAULT 10
/* Raw Interrupt Status */
#define I2C_IRQ_NONE 0x000
#define I2C_IRQ_RX_UNDER 0x001
#define I2C_IRQ_RX_OVER 0x002
#define I2C_IRQ_RX_FULL 0x004
#define I2C_IRQ_TX_OVER 0x008
#define I2C_IRQ_TX_EMPTY 0x010
#define I2C_IRQ_RD_REQ 0x020
#define I2C_IRQ_TX_ABRT 0x040
#define I2C_IRQ_RX_DONE 0x080
#define I2C_IRQ_ACTIVITY 0x100
#define I2C_IRQ_STOP_DET 0x200
#define I2C_IRQ_START_DET 0x400
#define I2C_IRQ_GEN_CALL 0x800
#define I2C_IRQ_ALL 0xFFF
/* Default IRQ Mask Bit Setting */
#define I2C_IRQ_DEFAULT_MASK (I2C_IRQ_RX_FULL | I2C_IRQ_TX_EMPTY | \
I2C_IRQ_TX_ABRT | I2C_IRQ_STOP_DET | \
I2C_IRQ_START_DET | I2C_IRQ_RX_UNDER | \
I2C_IRQ_RX_OVER | I2C_IRQ_TX_OVER)
/* Data command stop bit */
#define I2C_DATA_CMD_RD 0x100
#define I2C_DATA_CMD_WR 0x000
#define I2C_DATA_CMD_RESTART 0x400
#define I2C_DATA_CMD_STOP 0x200
#define I2C_DATA_CMD_WR_STOP_BIT 0x200
#define I2C_DATA_CMD_RD_STOP_BIT 0x300
/* I2C TX Abort Source*/
#define I2C_ABRT_7B_ADDR_NOACK 0x001
#define I2C_ABRT_10_ADDR1_NOACK 0x002
#define I2C_ABRT_10_ADDR2_NOACK 0x004
#define I2C_ABRT_TXDATA_NOACK 0x008
#define I2C_ABRT_GCALL_NOACK 0x010
#define I2C_ABRT_GCALL_READ 0x020
#define I2C_ABRT_HS_ACKDET 0x040
#define I2C_ABRT_SBYTE_ACKDET 0x080
#define I2C_ABRT_HS_NORSTRT 0x100
#define I2C_ABRT_SBYTE_NORSTRT 0x200
#define I2C_ABRT_10B_RD_NORSTRT 0x400
#define I2C_ABRT_MASTER_DIS 0x800
#define I2C_ABRT_ARB_LOST 0x1000
#define I2C_ABRT_SLVFLUSH_TXFIFO 0x2000
#define I2C_ABRT_SLV_ARBLOST 0x5000
#define I2C_ABRT_SLVRD_INTX 0x8000
/* I2C_STATUS */
#define I2C_STATUS_ACTIVITY (0x1 << 0)
#define I2C_STATUS_TFNF (0x1 << 1)
#define I2C_STATUS_TFE (0x1 << 2)
#define I2C_STATUS_RFNE (0x1 << 3)
#define I2C_STATUS_RFF (0x1 << 4)
#define I2C_STATUS_MST_ACTIVITY (0x1 << 5)
#define I2C_STATUS_SLV_ACTIVITY (0x1 << 6)
/* I2C_ENABLE_STATUS */
#define IC_ENABLE_STATUS_IC_EN (0x1 << 0)
/* Interrupts status */
#define I2C_INTR_RX_UNDER (0x1 << 0)
#define I2C_INTR_RX_OVER (0x1 << 1)
#define I2C_INTR_RX_FULL (0x1 << 2)
#define I2C_INTR_TX_OVER (0x1 << 3)
#define I2C_INTR_TX_EMPTY (0x1 << 4)
#define I2C_INTR_RD_REQ (0x1 << 5)
#define I2C_INTR_TX_ABRT (0x1 << 6)
#define I2C_INTR_RX_DONE (0x1 << 7)
#define I2C_INTR_ACTIVITY (0x1 << 8)
#define I2C_INTR_STOP_DET (0x1 << 9)
#define I2C_INTR_START_DET (0x1 << 10)
#define I2C_INTR_GEN_CALL (0x1 << 11)
#define I2C_INTR_MAX_BITS 12
/* I2C Component Parameter */
#define I2C_COMP_PARAM_1_TX_SHIFT (16)
#define I2C_COMP_PARAM_1_TX_MASK (0xff)
#define I2C_COMP_PARAM_1_RX_SHIFT (8)
#define I2C_COMP_PARAM_1_RX_MASK (0xff)
/* structure holding the instance specific details */
typedef struct i2c_drv_ctrl
{
VXB_DEVICE_ID i2cDev;
void * i2cHandle;
SEM_ID i2cDevSem;
SEM_ID i2cDataSem;
UINT32 clkFrequency;
UINT32 busSpeed;
UINT32 defBusSpeed;
BOOL polling;
UINT32 errorStatus;
UINT32 rxFifoSize;
UINT32 txFifoSize;
I2C_MSG * msgs;
UINT32 num;
UINT32 totalLen;
UINT64 timeout; /* unit : us */
UINT32 pollIrqMask;
spinlockIsr_t lock;
UINT32 msgsRxIdx;
UINT32 msgRxLen;
UINT8 * msgRxBuf;
UINT32 fifoRdLvl;
UINT32 msgsTxIdx;
UINT32 msgTxLen;
UINT8 * msgTxBuf;
ISR_DEFER_QUEUE_ID trxQueueId;
ISR_DEFER_JOB txIsrDef;
ISR_DEFER_JOB rxIsrDef;
} I2C_DRV_CTRL;
/* I2C controller read and write interface */
#define FT_I2C_BAR(pCtrl) ((char *)(((VXB_DEVICE_ID)(pCtrl)->i2cDev)->pRegBase[0]))
#define FT_I2C_HANDLE(pCtrl) ((I2C_DRV_CTRL *)((pCtrl)->i2cHandle))
#ifdef __cplusplus
}
#endif
#endif /* __INC_vxbFtI2c_H */

1423
vxbFtPcie.c

File diff suppressed because it is too large

1046
vxbFtQspi.c

File diff suppressed because it is too large

268
vxbFtQspi.h

@ -0,0 +1,268 @@
/* vxbFtQspi.h - QSPI driver */
/*
*
* 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.
*
*/
#ifndef __INCvxbFtQspih
#define __INCvxbFtQspih
#include <vxWorks.h>
#include <config.h>
#include <sysLib.h>
#include <vxBusLib.h>
#include <string.h>
#include <memLib.h>
#include <stdlib.h>
#include <semLibCommon.h>
#include <hwif/vxbus/vxbSpiLib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* defines */
#define FT_QSPI_NAME "ftQspi"
/* chip selects supported */
#define QSPI_MAX_CS_NUM (4)
/* qspi flash controller registers */
#define REG_BASE_QSPI 0x28014000
/* register definition */
#define REG_QSPI_CAP (0x00)
#define REG_QSPI_RD_CFG (0x04)
#define REG_QSPI_WR_CFG (0x08)
#define REG_QSPI_FLUSH (0x0C)
#define REG_QSPI_CMD_PORT (0x10)
#define REG_QSPI_ADDR_PORT (0x14)
#define REG_QSPI_HD_PORT (0x18)
#define REG_QSPI_LD_PORT (0x1C)
#define REG_QSPI_FUN_SET (0x20)
#define REG_QSPI_WIP_RD (0x24)
#define REG_QSPI_WP (0x28)
#define REG_QSPI_MODE (0x2C)
/*QSPI_CAP*/
#define CAP_FLASH_NUM(data) ((data) << 3)
#define CAP_FLASH_CAP(data) ((data) << 0)
/*QSPI_RD_CFG*/
#define RD_CFG_CMD(data) ((data) << 24)
#define RD_CFG_THROUGH(data) ((data) << 23)
#define RD_CFG_TRANSFER(data) ((data) << 20)
#define RD_CFG_ADDR_SEL(data) ((data) << 19)
#define RD_CFG_LATENCY(data) ((data) << 18)
#define RD_CFG_MODE_BYTE(data) ((data) << 17)
#define RD_CFG_CMD_SIGN(data) ((data) << 9)
#define RD_CFG_DUMMY(data) ((data) << 4)
#define RD_CFG_D_BUFFER(data) ((data) << 3)
#define RD_CFG_SCK_SEL(data) ((data) << 0)
/*QSPI_WR_CFG*/
#define WR_CFG_CMD(data) ((data) << 24)
#define WR_CFG_WAIT(data) ((data) << 9)
#define WR_CFG_THROUGH(data) ((data) << 8)
#define WR_CFG_TRANSFER(data) ((data) << 5)
#define WR_CFG_ADDRSEL(data) ((data) << 4)
#define WR_CFG_MODE(data) ((data) << 3)
#define WR_CFG_SCK_SEL(data) ((data) << 0)
/*QSPI_CMD_PORT*/
#define CMD_PORT_CMD(data) ((data) << 24)
#define CMD_PORT_WAIT(data) ((data) << 22)
#define CMD_PORT_THROUGH(data) ((data) << 21)
#define CMD_PORT_CS(data) ((data) << 19)
#define CMD_PORT_TRANSFER(data) ((data) << 16)
#define CMD_PORT_ADDR(data) ((data) << 15)
#define CMD_PORT_LATENCY(data) ((data) << 14)
#define CMD_PORT_DATA_TRANS(data) ((data) << 13)
#define CMD_PORT_ADDR_SEL(data) ((data) << 12)
#define CMD_PORT_DUMMY(data) ((data) << 7)
#define CMD_PORT_P_BUFFER(data) ((data) << 6)
#define CMD_PORT_RW_NUM(data) ((data) << 3)
#define CMD_PORT_CLK_SEL(data) ((data) << 0)
/*QSPI_FUN_SET*/
#define FUN_SET_CS_HOLD(data) ((data) << 24)
#define FUN_SET_CS_SETUP(data) ((data) << 16)
#define FUN_SET_CS_DELAY(data) ((data) << 0)
/*QSPI_WIP_RD*/
#define WIP_RD_CMD(data) ((data) << 24)
#define WIP_RD_TRANSFER(data) ((data) << 3)
#define WIP_RD_SCK_SEL(data) ((data) << 0)
/*QSPI_WP*/
#define WP_EN(data) ((data) << 17)
#define WP_WP(data) ((data) << 16)
#define WP_HOLD(data) ((data) << 8)
#define WP_SETUP(data) ((data) << 0)
/*QSPI_MODE*/
#define MODE_VALID(data) ((data) << 8)
#define MODE_MODE(data) ((data) << 0)
#define QSPI_FLASH_CAP_4MB 0
#define QSPI_FLASH_CAP_8MB 1
#define QSPI_FLASH_CAP_16MB 2
#define QSPI_FLASH_CAP_32MB 3
#define QSPI_FLASH_CAP_64MB 4
#define QSPI_FLASH_CAP_128MB 5
#define QSPI_FLASH_CAP_256MB 6
#define QSPI_ADDR_SEL_3 0
#define QSPI_ADDR_SEL_4 1
#define QSPI_SCK_DIV_128 0
#define QSPI_SCK_DIV_2 1
#define QSPI_SCK_DIV_4 2
#define QSPI_SCK_DIV_8 3
#define QSPI_SCK_DIV_16 4
#define QSPI_SCK_DIV_32 5
#define QSPI_SCK_DIV_64 6
#define QSPI_TRANSFER_1_1_1 0
#define QSPI_TRANSFER_1_1_2 1
#define QSPI_TRANSFER_1_1_4 2
#define QSPI_TRANSFER_1_2_2 3
#define QSPI_TRANSFER_1_4_4 4
#define QSPI_TRANSFER_2_2_2 5
#define QSPI_TRANSFER_4_4_4 6
/* qspi command instruction */
#define QSPI_FLASH_CMD_WRR 0x01 /* Write status register */
#define QSPI_FLASH_CMD_PP 0x02 /* Page program */
#define QSPI_FLASH_CMD_READ 0x03 /* Normal read data bytes */
#define QSPI_FLASH_CMD_WRDI 0x04 /* Write disable */
#define QSPI_FLASH_CMD_RDSR1 0x05 /* Read status register */
#define QSPI_FLASH_CMD_WREN 0x06 /* Write enable */
#define QSPI_FLASH_CMD_RDSR2 0x07 /* Read status register */
#define QSPI_FLASH_CMD_FAST_READ 0x0B /* Fast read data bytes */
#define QSPI_FLASH_CMD_4FAST_READ 0x0C /* Fast read data bytes */
#define QSPI_FLASH_CMD_4PP 0x12 /* Page program */
#define QSPI_FLASH_CMD_4READ 0x13 /* Normal read data bytes */
#define QSPI_FLASH_CMD_P4E 0x20 /* Erase 4kb sector */
#define QSPI_FLASH_CMD_4P4E 0x21 /* Erase 4kb sector */
#define QSPI_FLASH_CMD_QPP 0x32 /* Quad Page program */
#define QSPI_FLASH_CMD_4QPP 0x34 /* Quad Page program */
#define QSPI_FLASH_CMD_RDCR 0x35 /* Read config register */
#define QSPI_FLASH_CMD_BE 0x60 /* Bulk erase */
#define QSPI_FLASH_CMD_RDAR 0x65 /* Read Any Register */
#define QSPI_FLASH_CMD_QOR 0x6B /* Quad read data bytes */
#define QSPI_FLASH_CMD_4QOR 0x6C /* Quad read data bytes */
#define QSPI_FLASH_CMD_WRAR 0x71 /* Write Any Register */
#define QSPI_FLASH_CMD_RDID 0x9F /* Read JEDEC ID */
#define QSPI_FLASH_CMD_4BAM 0xB7 /* Enter 4 Bytes Mode */
#define QSPI_FLASH_CMD_4BE 0xC7 /* Bulk erase */
#define QSPI_FLASH_CMD_SE 0xD8 /* Sector erase */
#define QSPI_FLASH_CMD_4SE 0xDC /* Sector erase */
#define QSPI_FLASH_CMD_4BEX 0xE9 /* Exit 4 Bytes Mode */
#define QSPI_FLASH_CMD_QIOR 0xEB /* Quad read data bytes */
#define QSPI_FLASH_CMD_4QIOR 0xEC /* Quad read data bytes */
/* S25FL256 status register bit defined */
#define SR_SRWD (0x1 << 7) /* SR write protect */
#define SR_PERR (0x1 << 6) /* Program err bit */
#define SR_EERR (0x1 << 5) /* erase err bit */
#define SR_BP2 (0x1 << 4) /* Block protect 2 */
#define SR_BP1 (0x1 << 3) /* Block protect 1 */
#define SR_BP0 (0x1 << 2) /* Block protect 0 */
#define SR_WEL (0x1 << 1) /* Write enable latch */
#define SR_WIP (0x1 << 0) /* Write in progress */
#define WIP_TOUT 300000 /* max 300s */
/* typedefs */
/*QSPI_RD_CFG*/
typedef union
{
UINT32 data;
struct
{
UINT32 rd_sck_sel :3; /* 2:0 */
UINT32 d_buffer :1; /* 3 */
UINT32 dummy :5; /* 8:4 */
UINT32 cmd_sign :8; /* 16:9 */
UINT32 mode_byte :1; /* 17 */
UINT32 rd_latency :1; /* 18 */
UINT32 rd_addr_sel :1; /* 19 */
UINT32 rd_transfer :3; /* 22:20 */
UINT32 rd_through :1; /* 23 */
UINT32 rd_cmd :8; /* 31:24 */
} val;
} QSPI_RD_CFG_REG_T;
/*QSPI_WR_CFG*/
typedef union
{
UINT32 data;
struct
{
UINT32 wr_sck_sel :3; /* 2:0 */
UINT32 wr_mode :1; /* 3 */
UINT32 wr_addrsel :1; /* 4 */
UINT32 wr_transfer :3; /* 7:5 */
UINT32 wr_through :1; /* 8 */
UINT32 wr_wait :1; /* 9 */
UINT32 wr_res :14; /* 23:10 */
UINT32 wr_cmd :8; /* 31:24 */
} val;
} QSPI_WR_CFG_REG_T;
/*QSPI_CMD_PORT*/
typedef union
{
UINT32 data;
struct
{
UINT32 sck_sel :3; /* 2:0 */
UINT32 rw_mum :3; /* 5:3 */
UINT32 p_buffer :1; /* 6 */
UINT32 dummy :5; /* 11:7 */
UINT32 addr_sel :1; /* 12 */
UINT32 data_transfer :1;/* 13 */
UINT32 latency :1; /* 14 */
UINT32 cmd_addr :1; /* 15 */
UINT32 transfer :3; /* 18:16 */
UINT32 cs :2; /* 20:19 */
UINT32 through :1; /* 21 */
UINT32 wait :1; /* 22 */
UINT32 res :1; /* 23 */
UINT32 cmd :8; /* 31:24 */
} val;
} QSPI_CMD_PORT_REG_T;
/* structure holding the instance specific details */
typedef struct tf_qspi_drv_ctrl
{
VXB_DEVICE_ID pDev;
void * regBase;
void * regHandle;
UINT32 capacity;
UINT32 clkDiv;
UINT32 transMode;
UINT32 addrMode;
UINT32 spiDevNum;
UINT32 channel;
UINT32 initPhase;
UINT8 * txBuf;
UINT32 txLen;
UINT8 * rxBuf;
UINT32 rxLen;
BOOL initDone;
SEM_ID muxSem;
VXB_SPI_BUS_CTRL vxbSpiCtrl;
} FT_QSPI_CTRL;
#ifdef __cplusplus
}
#endif
#endif /* __INCvxbFtQspih */

1260
vxbFtSdCtrl.c

File diff suppressed because it is too large

309
vxbFtSdCtrl.h

@ -0,0 +1,309 @@
/* vxbFtSdCtrl.h - SD card driver */
/*
*
* 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.
*
*/
#ifndef __INCvxbFtSdCtrlh
#define __INCvxbFtSdCtrlh
#ifdef __cplusplus
extern "C" {
#endif
#define FT_SDHC_NAME "ftSdhci"
#define SDHC_MAX_RW_SECTORS 512
/* SDCI CMD_SETTING_REG */
#define SDCI_CMD_ADTC_MASK (0x00008000) /* ADTC*/
#define SDCI_CMD_CICE_MASK (0x00000010) /**/
#define SDCI_CMD_CRCE_MASK (0x00000008) /**/
#define SDCI_CMD_RES_NONE_MASK (0x00000000) /* no response */
#define SDCI_CMD_RES_LONG_MASK (0x00000001) /* long response */
#define SDCI_CMD_RES_SHORT_MASK (0x00000002) /* short response */
/* SDCI_NORMAL_ISR mask */
#define SDCI_NORMAL_ISR_CC (0x1 << 0) /* R */
#define SDCI_NORMAL_ISR_CR (0x1 << 1) /* R */
#define SDCI_NORMAL_ISR_CI (0x1 << 2) /* R */
#define SDCI_NORMAL_ISR_TIMEOUT (0x1 << 3) /* R */
#define SDCI_SD_DRV_VALUE 0
#define SDCI_SD_SAMP_VALUE_MAX 50
#define SDCI_SD_SAMP_VALUE_MIN 0
#define SDCI_TIMEOUT_DATA_VALUE 2000000
#define SDCI_TIMEOUT_CMD_VALUE 0xFFFFFFFF
#define SDCI_POWER_ON 1
#define SDCI_POWER_OFF 0
#define SDCI_CMD_TIMEOUT 10
#define SDCI_DAT_TIMEOUT 5000
#define SDCI_CMD_TYPE_ADTC 0x2
#define SDCI_F_MIN 400000
#define SDCI_F_MAX 30000000
/* SDCI_NORMAL_ISER mask */
#define SDCI_SDCI_NORMAL_ISER_ECC_EN (0x1 << 0) /* RW */
#define SDCI_SDCI_NORMAL_ISER_ECR (0x1 << 1) /* RW */
#define SDCI_SDCI_NORMAL_ISER_EEI_EN (0x1 << 15) /* RW */
/* SDCI_SOFTWARE mask */
#define SDCI_SOFTWARE_SRST (0x1 << 0) /* RW */
#define SDCI_SOFTWARE_BDRST (0x1 << 2) /* RW */
#define SDCI_SOFTWARE_CFCLF (0x1 << 3) /* RW */
/* SDCI_STATUS mask */
#define SDCI_STATUS_CMD_BUSY (0x0 << 0) /* R */
#define SDCI_STATUS_CMD_READY (0x1 << 0) /* R */
#define SDCI_STATUS_IDIE (0x1 << 12) /* R */
/* SDCI NORMAL_INT_STATUS_REG */
#define SDCI_NORMAL_EI_STATUS (0x00008000) /* command error */
#define SDCI_NORMAL_CR_STATUS (0x00000002) /* card remove */
#define SDCI_NORMAL_CC_STATUS (0x00000001) /* command done */
#define MMC_CMD_ALL_SEND_CID 2
#define SDCI_CONTROLLER ( 0x00) /* the controller config reg */
#define SDCI_ARGUMENT (0x04) /* the argument reg */
#define SDCI_COMMAND (0x08) /* the command reg */
#define SDCI_CLOCK_D (0x0c) /* the clock divide reg */
#define SDCI_SOFTWARE (0x10) /* the controller reset reg */
#define SDCI_POWER (0x14) /* THE POWRE CONTROL REG */
#define SDCI_TIMEOUT_CMD (0x18) /* the cmd timeout config reg */
#define SDCI_TIMEOUT_DATA (0x1c)
#define SDCI_NORMAL_ISER (0x20) /* the normal ISR config reg */
#define SDCI_ERROR_ISER (0x24) /* the erroe ISR config reg */
#define SDCI_BD_ISER (0x28) /* the BD ISR config reg */
#define SDCI_SD_DRV (0x30) /* the SD card driving phase position reg */
#define SDCI_SD_SAMP (0x34) /* the SD card sampling phase position reg */
#define SDCI_SD_SEN (0x38) /* the SD card detection reg */
#define SDCI_HDS_AXI (0x3c) /* AIX boundary config reg */
#define SDCI_BD_RX (0x40) /* the BD rx addr reg */
#define SDCI_BD_TX ( 0x60) /* the BD tx addr reg */
#define SDCI_BLK_CNT (0x80) /* the r/w block num reg */
#define SDCI_NORMAL_ISR ( 0xC0) /* the normal ISR status reg */
#define SDCI_ERROR_ISR (0xC4) /* the error ISR status reg */
#define SDCI_BD_ISR ( 0xC8) /* the BD ISR status reg */
#define SDCI_STATUS (0xD0) /* the status reg */
#define SDCI_BLOCK ( 0xD4) /* the block len reg */
#define SDCI_RESP0 ( 0xE0) /* response reg0 */
#define SDCI_RESP1 ( 0xE4) /* response reg1 */
#define SDCI_RESP2 ( 0xE8) /* response reg2 */
#define SDCI_RESP3 ( 0xEC) /* response reg3 */
#define SD_BLOCK_SIZE 512
#define MMC_DATA_WRITE BIT(8)
#define MMC_DATA_READ BIT(9)
/* Extra flags used by CQE */
#define MMC_DATA_QBR BIT(10) /* CQE queue barrier*/
#define MMC_DATA_PRIO BIT(11) /* CQE high priority */
#define MMC_DATA_REL_WR BIT(12) /* Reliable write */
#define MMC_DATA_DAT_TAG BIT(13) /* Tag request */
#define MMC_DATA_FORCED_PRG BIT(14) /* Forced programming */
#define MMC_GO_IDLE_STATE 0 /* bc */
#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define MMC_ALL_SEND_CID 2 /* bcr R2 */
#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define MMC_SET_DSR 4 /* bc [31:16] RCA */
#define MMC_SLEEP_AWAKE 5 /* ac [31:16] RCA 15:flg R1b */
#define MMC_SWITCH 6 /* ac [31:0] See below R1b */
#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define MMC_SEND_EXT_CSD 8 /* adtc R1 */
#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define MMC_BUS_TEST_R 14 /* adtc R1 */
#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define MMC_BUS_TEST_W 19 /* adtc R1 */
#define MMC_SPI_READ_OCR 58 /* spi spi_R3 */
#define MMC_SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
/* SDCI ERROR_INT_STATUS_REG */
#define SDCI_ERROR_CNR_ERROR_STATUS (0x00000010) /**/
#define SDCI_ERROR_CIR_ERROR_STATUS (0x00000008) /**/
#define SDCI_ERROR_CCRCE_ERROR_STATUS (0x00000002) /**/
#define SDCI_ERROR_CTE_ERROR_STATUS (0x00000001) /**/
/* SDCI BD_ISR_REG */
#define SDCI_BD_DAIS_ERROR_STATUS (0x00008000) /* */
#define SDCI_BD_RESPE_STATUS (0x00000100) /* */
#define SDCI_BD_DATFRAX_ERROR_STATUS (0x00000080) /* */
#define SDCI_BD_NRCRC_ERROR_STATUS (0x00000040) /* */
#define SDCI_BD_TRE_ERROR_STATUS (0x00000020) /* */
#define SDCI_BD_CMDE_ERROR_STATUS (0x00000010) /* */
#define SDCI_BD_DTE_ERROR_STATUS (0x00000008) /* */
#define SDCI_BD_TRS_STATUS (0x00000001) /* */
#ifdef SDCI_BDINT_MODE_0
#define SDCI_BD_ISR_TRS (0x1 << 0) /* R */
#else
#define SDCI_BD_ISR_TRS_W (0x1 << 0) /* R */ /*the hardware update*/
#define SDCI_BD_ISR_TRS_R (0x1 << 8) /* R */ /*the hardware update*/
#endif
#define SDCI_BD_ISR_EDTE (0x1 << 3) /* R */
/* SDCI_HDS_AXI mask */
#define SDCI_HDS_AXI_AWDOMAIN (0x1 << 0) /* RW */
#define SDCI_HDS_AXI_ARDOMAIN (0x1 << 12) /* RW */
#define SDCI_HDS_AXI_AWCACHE (0x6 << 24) /* RW */
#define SDCI_HDS_AXI_ARCACHE (0xB << 28) /* RW */
/* SDCI_STATUS mask */
#define SDCI_STATUS_CMD_BUSY (0x0 << 0) /* R */
#define SDCI_STATUS_CMD_READY (0x1 << 0) /* R */
#define SDCI_STATUS_IDIE (0x1 << 12) /* R */
/* SDCI_NORMAL_ISR mask */
#define SDCI_NORMAL_ISR_CC (0x1 << 0) /* R */
#define SDCI_NORMAL_ISR_CR (0x1 << 1) /* R */
#define SDCI_NORMAL_ISR_TIMEOUT (0x1 << 3) /* R */
/* SDCI_ERROR_ISER mask */
#define SDCI_ERROR_ISER_ECTE_EN (0x1 << 0) /* RW */
/* SDCI_ERROR_ISR mask */
#define SDCI_ERROR_ISR_CTE (0x1 << 0) /* R */
/* SDCI_BD_ISER mask */
#ifdef SDCI_BDINT_MODE_0
#define SDCI_BD_ISER_ETRS_EN (0x1 << 0) /* RW */
#else
#define SDCI_BD_ISER_ETRS_EN (0x1 << 8) /* RW */ /*the hardware update*/
#endif
#define MMC_APP_CMD 55
#define SD_APP_SET_BUS_WIDTH 6
#define SDCI_CMD_INDEX_MASK (0x00003F00)
#define SDCI_CMD_INDEX_SHIFT (8)
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#define SDCI_SDCI_NORMAL_ISER_ECC_EN (0x1 << 0)
#define SDCI_BD_ISER_ETRS_EN (0x1 << 8)
#define SDCI_SOURCE_CLOCK_RATE 48000000
/* SDCI SOFTWARE_RESET_REG */
#define SDCI_RESET_CFCLF (0x00000008) /* 0 */
#define SDCI_BDRST (0x00000004) /* DMA BD set */
#define SDCI_SRST (0x00000001) /* soft reset controller */
/*irq */
#define IRQ_err 0x1<<15
#define IRQ_CMD_FT 0X1<<0
#define IRQ_DMA
#define IRQ_REMOVE 0X1<<1
#define MMC_CMD23_ARG_REL_WR (1 << 31)
#define MMC_CMD23_ARG_PACKED ((0 << 31) | (1 << 30))
#define MMC_CMD23_ARG_TAG_REQ (1 << 29)
unsigned int flags; /* expected response type */
#define MMC_CMD_MASK (3 << 5) /* non-SPI command type */
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */
#define MMC_RSP_SPI_S2 (1 << 8) /* second byte */
#define MMC_RSP_SPI_B4 (1 << 9) /* four data bytes */
#define MMC_RSP_SPI_BUSY (1 << 10) /* card may send busy */
#define SDCI_SDCI_NORMAL_ISER_ECI (0x1 << 2)
/* SDHC driver control */
typedef struct ftsdhcDrvCtrl
{
SD_HOST_CTRL sdHostCtrl;
VXB_DEVICE_ID pDev;
void * regBase;
void * regHandle;
struct vxbSdioInt * pIntInfo;
UINT32 intSts;
UINT32 intMask;
} FTSDHC_DEV_CTRL;
/* register low level access routines */
#define FTSDHC_BAR(p) ((FTSDHC_DEV_CTRL *)(p)->pDrvCtrl)->regBase
#define FTSDHC_HANDLE(p) ((FTSDHC_DEV_CTRL *)(p)->pDrvCtrl)->regHandle
#define CSR_READ_4(pDev, addr) \
vxbRead32(FTSDHC_HANDLE(pDev), \
(UINT32 *)((char *)FTSDHC_BAR(pDev) + addr))
#define CSR_WRITE_4(pDev, addr, data) \
vxbWrite32(FTSDHC_HANDLE(pDev), \
(UINT32 *)((char *)FTSDHC_BAR(pDev) + addr), data)
#define CSR_SETBIT_4(pDev, offset, val) \
CSR_WRITE_4(pDev, offset, CSR_READ_4(pDev, offset) | (val))
#define CSR_CLRBIT_4(pDev, offset, val) \
CSR_WRITE_4(pDev, offset, CSR_READ_4(pDev, offset) & (UINT32)(~(val)))
void sdhcCtrlInstInit(VXB_DEVICE_ID);
void sdhcCtrlInstInit2 (VXB_DEVICE_ID);
STATUS sdhcCtrlInstConnect (SD_HOST_CTRL * pSdHostCtrl);
STATUS sdhcCtrlIsr (VXB_DEVICE_ID);
STATUS sdhcCtrlCmdIssue (VXB_DEVICE_ID, SD_CMD *);
STATUS sdhcCtrlCmdPrepare (VXB_DEVICE_ID, SD_CMD *);
STATUS sdhcCtrlCmdIssuePoll (VXB_DEVICE_ID, SD_CMD *);
STATUS sdhcCtrlInit (VXB_DEVICE_ID);
STATUS sdhcInterruptInfo (VXB_DEVICE_ID, UINT32 *);
STATUS sdhcDevControl (VXB_DEVICE_ID, pVXB_DEVCTL_HDR);
void sdhcCtrlBusWidthSetup (VXB_DEVICE_ID, UINT32);
void sdhcCtrlCardMonTaskPoll (VXB_DEVICE_ID);
void ftsdhcCtrlClkFreqSetup (VXB_DEVICE_ID, UINT32);
BOOL sdhcCtrlCardWpCheck (VXB_DEVICE_ID);
BOOL sdhcCtrlCardInsertSts (VXB_DEVICE_ID);
#ifdef __cplusplus
}
#endif
#endif /* __INCvxbFtSdCtrlh */

1208
vxbFtcan.c

File diff suppressed because it is too large

287
vxbFtcan.h

@ -0,0 +1,287 @@
/* vxbFtcan.h - CAN driver */
/*
*
* 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.
*
*/
#ifndef __INCvxbftcanh
#define __INCvxbftcanh
#ifdef __cplusplus
extern "C" {
#endif
#define FTCAN_QUEUE_SIZE 1024
#define VXB_FTCAN_MSG_SIZE 64
/* CAN payload length and DLC definitions according to ISO 11898-1 */
#define CAN_MAX_DLC 8
#define CAN_MAX_DLEN 8
#define CAN_MAX_CTL 3
#define CAN_SFF_ID_BITS 11
#define CAN_EFF_ID_BITS 29
/* special address description flags for the CAN_ID */
#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
#define CAN_ERR_FLAG 0x20000000U /* error message frame */
/* valid bits in CAN ID for frame formats */
#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
/* Frame type */
#define STANDARD_FRAME 0 /* standard frame */
#define EXTEND_FRAME 1 /* extended frame */
/*
* Controller Area Network Identifier structure
*
* bit 0-28 : CAN identifier (11/29 bit)
* bit 29 : error message frame flag (0 = data frame, 1 = error message)
* bit 30 : remote transmission request flag (1 = rtr frame)
* bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
*/
#define min_t(type, x, y) ({ \
type __min1 = (x); \
type __min2 = (y); \
__min1 < __min2 ? __min1: __min2; })
/*
* get_can_dlc(value) - helper macro to cast a given data length code (dlc)
* to __u8 and ensure the dlc value to be max. 8 bytes.
*
* To be used in the CAN netdriver receive path to ensure conformance with
* ISO 11898-1 Chapter 8.4.2.3 (DLC field)
*/
#define get_can_dlc(i) (min_t(UINT8, (i), CAN_MAX_DLC))
/***ft CAN REGISTER offset*/
#define FTCAN_CTRL_OFFSET 0x00 /* Global control register */
#define FTCAN_INTR_OFFSET 0x04 /* Interrupt register */
#define FTCAN_ARB_RATE_CTRL_OFFSET 0x08 /* Arbitration rate control register */
#define FTCAN_DAT_RATE_CTRL_OFFSET 0x0C /* Data rate control register */
#define FTCAN_ACC_ID0_OFFSET 0x10 /* Acceptance identifier0 register */
#define FTCAN_ACC_ID1_OFFSET 0x14 /* Acceptance identifier1 register */
#define FTCAN_ACC_ID2_OFFSET 0x18 /* Acceptance identifier2 register */
#define FTCAN_ACC_ID3_OFFSET 0x1C /* Acceptance identifier3 register */
#define FTCAN_ACC_ID0_MASK_OFFSET 0x20 /* Acceptance identifier0 mask register */
#define FTCAN_ACC_ID1_MASK_OFFSET 0x24 /* Acceptance identifier1 mask register */
#define FTCAN_ACC_ID2_MASK_OFFSET 0x28 /* Acceptance identifier2 mask register */
#define FTCAN_ACC_ID3_MASK_OFFSET 0x2C /* Acceptance identifier3 mask register */
#define FTCAN_XFER_STS_OFFSET 0x30 /* Transfer status register */
#define FTCAN_ERR_CNT_OFFSET 0x34 /* Error counter register */
#define FTCAN_FIFO_CNT_OFFSET 0x38 /* FIFO counter register */
#define FTCAN_DMA_CTRL_OFFSET 0x3C /* DMA request control register */
#define FTCAN_TX_FIFO_OFFSET 0x100 /* TX FIFO shadow register */
#define FTCAN_RX_FIFO_OFFSET 0x200 /* RX FIFO shadow register */
/*----------------------------------------------------------------------------*/
/* CAN register bit masks - FTCAN_<REG>_<BIT>_MASK */
/*----------------------------------------------------------------------------*/
/* FTCAN_CTRL mask */
#define FTCAN_CTRL_XFER_MASK (0x1 << 0) /* RW */ /*Transfer enable*/
#define FTCAN_CTRL_TXREQ_MASK (0x1 << 1) /* RW */ /*Transmit request*/
#define FTCAN_CTRL_AIME_MASK (0x1 << 2) /* RW */ /*Acceptance identifier mask enable*/
/* FTCAN_INTR mask */
#define FTCAN_INTR_STATUS_MASK (0xFF << 0) /* RO */ /*the interrupt status*/
#define FTCAN_INTR_BOIS_MASK (0x1 << 0) /* RO */ /*Bus off interrupt status*/
#define FTCAN_INTR_PWIS_MASK (0x1 << 1) /* RO */ /*Passive warning interrupt status*/
#define FTCAN_INTR_PEIS_MASK (0x1 << 2) /* RO */ /*Passive error interrupt status*/
#define FTCAN_INTR_RFIS_MASK (0x1 << 3) /* RO */ /*RX FIFO full interrupt status*/
#define FTCAN_INTR_TFIS_MASK (0x1 << 4) /* RO */ /*TX FIFO empty interrupt status*/
#define FTCAN_INTR_REIS_MASK (0x1 << 5) /* RO */ /*RX frame end interrupt status*/
#define FTCAN_INTR_TEIS_MASK (0x1 << 6) /* RO */ /*TX frame end interrupt status*/
#define FTCAN_INTR_EIS_MASK (0x1 << 7) /* RO */ /*Error interrupt status*/
#define FTCAN_INTR_EN_MASK (0xFF << 8) /* RO */ /*the interrupt enable*/
#define FTCAN_INTR_BOIE_MASK (0x1 << 8) /* RW */ /*Bus off interrupt enable*/
#define FTCAN_INTR_PWIE_MASK (0x1 << 9) /* RW */ /*Passive warning interrupt enable*/
#define FTCAN_INTR_PEIE_MASK (0x1 << 10) /* RW */ /*Passive error interrupt enable*/
#define FTCAN_INTR_RFIE_MASK (0x1 << 11) /* RW */ /*RX FIFO full interrupt enable*/
#define FTCAN_INTR_TFIE_MASK (0x1 << 12) /* RW */ /*TX FIFO empty interrupt enable*/
#define FTCAN_INTR_REIE_MASK (0x1 << 13) /* RW */ /*RX frame end interrupt enable*/
#define FTCAN_INTR_TEIE_MASK (0x1 << 14) /* RW */ /*TX frame end interrupt enable*/
#define FTCAN_INTR_EIE_MASK (0x1 << 15) /* RW */ /*Error interrupt enable*/
#define FTCAN_INTR_BOIC_MASK (0x1 << 16) /* WO */ /*Bus off interrupt clear*/
#define FTCAN_INTR_PWIC_MASK (0x1 << 17) /* WO */ /*Passive warning interrupt clear*/
#define FTCAN_INTR_PEIC_MASK (0x1 << 18) /* WO */ /*Passive error interrupt clear*/
#define FTCAN_INTR_RFIC_MASK (0x1 << 19) /* WO */ /*RX FIFO full interrupt clear*/
#define FTCAN_INTR_TFIC_MASK (0x1 << 20) /* WO */ /*TX FIFO empty interrupt clear*/
#define FTCAN_INTR_REIC_MASK (0x1 << 21) /* WO */ /*RX frame end interrupt clear*/
#define FTCAN_INTR_TEIC_MASK (0x1 << 22) /* WO */ /*TX frame end interrupt clear*/
#define FTCAN_INTR_EIC_MASK (0x1 << 23) /* WO */ /*Error interrupt clear*/
/* FTCAN_ACC_ID(0-3)_MASK mask */
#define FTCAN_ACC_IDN_MASK 0x1FFFFFFF /* WO */ /*don’t care the matching */
/* FTCAN_DAT_RATE_CTRL mask */
/* FTCAN_ERR_CNT_OFFSET mask */
#define FTCAN_ERR_CNT_RFN_MASK (0xFF << 0) /* RO */ /*Receive error counter*/
#define FTCAN_ERR_CNT_TFN_MASK (0xFF << 16)/* RO */ /*Transmit error counter*/
/* FTCAN_FIFO_CNT_OFFSET mask */
#define FTCAN_FIFO_CNT_RFN_MASK (0xFF << 0) /* RO */ /*Receive FIFO valid data number*/
#define FTCAN_FIFO_CNT_TFN_MASK (0xFF << 16)/* RO */ /*Transmit FIFO valid data number*/
#define FTCAN_ERR_CNT_TFN_SHIFT 16 /* Tx Error Count shift */
#define FTCAN_FIFO_CNT_TFN_SHIFT 16 /* Tx FIFO Count shift*/
#define FTCAN_IDR_ID1_SHIFT 21 /* Standard Messg Identifier */
#define FTCAN_IDR_ID2_SHIFT 1 /* Extended Message Identifier */
#define FTCAN_IDR_SDLC_SHIFT 14
#define FTCAN_IDR_EDLC_SHIFT 26
#define FTCAN_ACC_IDN_SHIFT 18 /*Standard ACC ID shift*/
#define FTCAN_IDR_ID2_MASK 0x0007FFFE /* Extended message ident */
#define FTCAN_IDR_ID1_MASK 0xFFE00000 /* Standard msg identifier */
#define FTCAN_IDR_IDE_MASK 0x00080000 /* Identifier extension */
#define FTCAN_IDR_SRR_MASK 0x00100000 /* Substitute remote TXreq */
#define FTCAN_IDR_RTR_MASK 0x00000001 /* Extended frames remote TX request */
#define FTCAN_IDR_DLC_MASK 0x0003C000 /* Standard msg dlc */
#define FTCAN_IDR_PAD_MASK 0x00003FFF /* Standard msg padding 1 */
#define FTCAN_IDR_EDLC_MASK 0x3C000000 /* Extended msg dlc */
/*#define FTCAN_INTR_EN (FTCAN_INTR_TEIE_MASK | FTCAN_INTR_BOIE_MASK |\
FTCAN_INTR_RFIE_MASK | FTCAN_INTR_EIE_MASK | \
FTCAN_INTR_REIE_MASK)*/
#define FTCAN_INTR_EN (FTCAN_INTR_TEIE_MASK | FTCAN_INTR_REIE_MASK)
#define FTCAN_INTR_DIS 0x00000000
#define FTCAN_FIFOFRAME_SIZE 4
#define FTCAN_TX_FIFO_MAX 0x40
#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
#define CAN_CALC_SYNC_SEG 1
#define clamp(x, low, high) (min(max(low, x), high))
#define CAN_CLK_FREQ 600000000
#define FWOHCI_CPU_TO_BE32(x) (htobe32((uint32_t)x))
#define cpu_to_be32p(x) (htobe32((uint32_t)x))
#define be32_to_cpup(x) (be32toh((uint32_t)x))
#define DMA_CACHE_DRV_VIRT_TO_PHYS(adrs) \
CACHE_DRV_VIRT_TO_PHYS(&cacheDmaFuncs, (void *) (adrs))
/*
* CAN bit-timing parameters
*
* For further information, please read chapter "8 BIT TIMING
* REQUIREMENTS" of the "Bosch CAN Specification version 2.0"
* at http://www.semiconductors.bosch.de/pdf/can2spec.pdf.
*/
typedef struct can_bittiming {
UINT bitrate; /* Bit-rate in bits/second */
UINT sample_point; /* Sample point in one-tenth of a percent */
UINT tq; /* Time quanta (TQ) in nanoseconds */
UINT prop_seg; /* Propagation segment in TQs */
UINT phase_seg1; /* Phase buffer segment 1 in TQs */
UINT phase_seg2; /* Phase buffer segment 2 in TQs */
UINT sjw; /* Synchronisation jump width in TQs */
UINT brp; /* Bit-rate prescaler */
} FTCAN_BITTIMING;
/*
* CAN harware-dependent bit-timing constant
*
* Used for calculating and checking bit-timing parameters
*/
typedef struct can_bittiming_const {
char name[16]; /* Name of the CAN controller hardware */
UINT tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */
UINT tseg1_max;
UINT tseg2_min; /* Time segement 2 = phase_seg2 */
UINT tseg2_max;
UINT sjw_max; /* Synchronisation jump width */
UINT brp_min; /* Bit-rate prescaler */
UINT brp_max;
UINT brp_inc;
} FTCAN_BITTIMING_CONST;
typedef struct can_frame {
UINT can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
UINT8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
UINT8 data[CAN_MAX_DLEN];
} FTCAN_FRAME;
typedef struct ftCan_drv_ctrl
{
VXB_DEVICE_ID ftCanDev;
void * ftCanHandle;
void * ftCanRegbase;
UINT irq;
UINT txCfCnt;
UINT txCfMax;
FTCAN_BITTIMING ftcan_bittiming;
MSG_Q_ID ftcanQueue;
void (*ftCanRecvRtn)(FTCAN_FRAME* pFtCanFrame);
SEM_ID canTxSem;
} FTCAN_DRV_CTRL;
#define FTCAN_BASE(p) ((FTCAN_DRV_CTRL *)(p)->pDrvCtrl)->ftCanRegbase
#define FTCAN_HANDLE(p) ((FTCAN_DRV_CTRL *)(p)->pDrvCtrl)->ftCanHandle
#define CSR_READ_4(pDev, addr) \
vxbRead32 (FTCAN_HANDLE(pDev), (UINT32 *)((char *)FTCAN_BASE(pDev) + addr))
#define CSR_WRITE_4(pDev, addr, data) \
vxbWrite32 (FTCAN_HANDLE(pDev), \
(UINT32 *)((char *)FTCAN_BASE(pDev) + addr), data)
#define CSR_SETBIT_4(pDev, offset, val) \
CSR_WRITE_4(pDev, offset, CSR_READ_4(pDev, offset) | (val))
#define CSR_CLRBIT_4(pDev, offset, val) \
CSR_WRITE_4(pDev, offset, CSR_READ_4(pDev, offset) & (UINT32)(~(val)))
#define CSR_READ_2(pDev, addr) \
vxbRead16 (FTCAN_HANDLE(pDev), \
(UINT16 *)((char *)FTCAN_BASE(pDev) + addr))
#define CSR_WRITE_2(pDev, addr, data) \
vxbWrite16 (FTCAN_HANDLE(pDev), \
(UINT16 *)((char *)FTCAN_BASE(pDev) + addr), data)
#define CSR_READ_1(pDev, addr) \
vxbRead8 (FTCAN_HANDLE(pDev), \
((UINT8 *)FTCAN_BASE(pDev) + addr))
#define CSR_WRITE_1(pDev, addr, data) \
vxbWrite8 (FTCAN_HANDLE(pDev), \
((UINT8 *)FTCAN_BASE(pDev) + addr), data)
STATUS ftCanRecvCallback
(
unsigned char ctlNo,
void (*ftCanRecvRtn)(FTCAN_FRAME* pFtCanFrame)
);
STATUS ftCanSend
(
unsigned char ctlNo,
char * sendbuff,
int lenth
);
#ifdef __cplusplus
}
#endif
#endif /*end of __INCvxbftcanh*/

881
vxbM6845Vga.c

@ -0,0 +1,881 @@
/* vxbM6845Vga.c - motorola 6845 VGA console driver */
/*
* Copyright (c) 2007, 2008, 2010, 2012, 2013 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01p,21may13,y_y initialized the paramter escFlags. (WIND00416649)
01o,17aug12,clx Removed unnecessary import function declare. (WIND00365597)
01n,02feb12,sye Removed redundant auto wrapped blank line. (WIND00311642)
01m,06sep10,jxu Replace inclusion of funcBindP.h with selectLibP.h
01l,03may10,h_k cleaned up a compiler warning.
01k,07jan10,jc0 LP64 adaptation.
01j,12dec08,h_k added more information in the API reference manual.
01i,27aug08,jpb Renamed VSB header file
01h,18jun08,jpb Renamed _WRS_VX_SMP to _WRS_CONFIG_SMP. Added include path
for kernel configurations options set in vsb.
01g,16jun08,pmr resource documentation
01f,05may08,tor update version
01e,06mar08,tor resource meta-data update
01d,20sep07,tor VXB_VERSION_3
01c,17aug07,pmr new register access methods
01b,09mar07,pmr SMP-safe.
01a,20feb07,pmr adapted for VxBus from version 01e.
*/
/*
DESCRIPTION
This is the driver fo Video Contoroller Chip (6845) normally used in the
386/486 personal computers.
USER CALLABLE ROUTINES
This driver provides several VxBus methods for external access to its
routines.
All virtual consoles are mapped to the same screen buffer. This is a
very basic implementation of virtual consoles. Multiple screen
buffers are not used to switch between consoles. This implementation
is left for the future. Mutual exclusion for the screen buffer is
guaranteed within the same console but it is not implemented across multiple
virtual consoles because all virtual consoles use the same screen buffer. If
multiple screen buffers are implemented then the mutual exclusion between
virtual consoles can be implemented.
This driver suports the ansi escape sequences and special processing in the
m6845 driver will be done if an escape sequence exists.
If the ansi escape sequences are not required, please rebuild this driver
without defining INCLUDE_ANSI_ESC_SEQUENCE macro, which is explicitly defined
in this file.
TARGET-SPECIFIC PARAMETERS
The parameters are provided through `m6845Vga' registration defined in
hwconf.c in the target BSP.
\is
\i <regBase>
The Video Contoroller Chip register base address.
The parameter type is HCF_RES_INT, or HCF_RES_ADDR for 64-bit address in LP64.
If not specified, 0 will be set in the register base address and VXB_REG_NONE
will be set in the register base flag that will cause a failure at vxbRegMap()
to obtain the access handle.
\i <regBase1>
The address of video memory.
If not specified, the address passed by <memBase> will be set as the video
memory address.
The parameter type is HCF_RES_INT, or HCF_RES_ADDR for 64-bit address in LP64.
\i <memBase>
The address of video memory (for backward compatibility).
If not specified here nor in <regBase1>, 0 will be set as the video memory
address.
The parameter type is HCF_RES_INT, or HCF_RES_ADDR for 64-bit address in LP64.
\i <colorMode>
Specify color mode, COLOR(1) or MONO(0).
If not specified, MONO(0) will be set as the color mode.
The parameter type is HCF_RES_INT.
\i <colorSetting>
Specify the foreground and background display colors.
If not specifed, (ATRB_FG_BRIGHTWHITE | ATRB_BG_BROWN) will be set when the
<colorMode> is COLOR(1) and (ATRB_FG_WHITE | ATRB_BG_BLACK) will be set when
the <colorMode> is MONO(0) for the display attributes.
The parameter type is HCF_RES_INT.
\ie
By convention all the BSP-specific device parameters are registered in
a file called hwconf.c, which is #include'ed by sysLib.c.
The following is an example in pcPentium4 BSP:
\cs
LOCAL const struct hcfResource pentiumM6845VgaResources[] =
{
{ "regBase", HCF_RES_ADDR, {(void *) CTRL_SEL_REG} },
{ "regBase1", HCF_RES_ADDR, {(void *) CTRL_MEM_BASE} },
{ "colorMode", HCF_RES_INT, {(void *) COLOR_MODE} },
{ "colorSetting",HCF_RES_INT, {(void *) DEFAULT_ATR} },
};
#define pentiumM6845VgaNum NELEMENTS(pentiumM6845VgaResources)
const struct hcfDevice hcfDeviceList[] = {
...
{ "m6845Vga", 0, VXB_BUSID_PLB, 0, pentiumM6845VgaNum,
pentiumM6845VgaResources },
...
};
\ce
CONFIGURATION
To use the driver, configure VxWorks with the
DRV_VGA_M6845 component.
The required components for this driver are
INCLUDE_VXBUS
INCLUDE_PLB_BUS
INCLUDE_PC_CONSOLE
which will be dragged by Kernel Configuration tool if not included in the
VxWorks Image Project (VIP) when the DRV_VGA_M6845 is added.
You need to define all the required components when the DRV_VGA_M6845
is added in config.h for BSP build unless they are already defined.
NOTES
The macro N_VIRTUAL_CONSOLES should be defined in config.h file.
This refers to the number of virtual consoles which the user wishes to have.
SEE ALSO: tyLib, vxbPcConsole and VxWorks Device Driver Developer's Guide.
*/
/* includes */
#include <vxWorks.h>
#include <vsbConfig.h>
#include <iv.h>
#include <ioLib.h>
#include <iosLib.h>
#include <memLib.h>
#include <private/funcBindP.h>
#include <intLib.h>
#include <taskLib.h>
#include <errnoLib.h>
#include <stdio.h>
#include <string.h>
#include "font_8x16.h"
#include <private/funcBindP.h>
#include <private/selectLibP.h> /* _func_selWakeupAll */
/* SMP */
#ifdef _WRS_CONFIG_SMP
#include <spinLockLib.h>
#define M6845_LOCK_TAKE(p) \
if (INT_CONTEXT()) \
SPIN_LOCK_ISR_TAKE(&p->pTyDev->spinlockIsr)
#define M6845_LOCK_GIVE(p) \
if (INT_CONTEXT()) \
SPIN_LOCK_ISR_GIVE(&p->pTyDev->spinlockIsr)
#else /* _WRS_CONFIG_SMP */
#define M6845_LOCK_TAKE(p)
#define M6845_LOCK_GIVE(p)
#endif /* _WRS_CONFIG_SMP */
#define DEFAULT_FB_MEM 0x00000000
/* VXBUS */
#include <vxBusLib.h>
#include <hwif/util/hwMemLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/vxbus/vxbPlbLib.h>
#include <hwif/vxbus/hwConf.h>
#include <../src/hwif/h/vxbus/vxbAccess.h>
/*#define INCLUDE_ANSI_ESC_SEQUENCE*/
#include "vxbM6845Vga.h"
/* VxBus structures and methods */
/* imports */
IMPORT TY_DEV * pcConDevBind (int, FUNCPTR, void *);
UINT32 pcConframeBufferAddr;
/* locals */
LOCAL UINT32 defaultFbBase = 0;
LOCAL size_t tyWrtThreshold = 20;
LOCAL BOOL m6845vxbProbe (VXB_DEVICE_ID pDev);
LOCAL void m6845vxbInstInit (VXB_DEVICE_ID pDev);
LOCAL void m6845vxbInstInit2 (VXB_DEVICE_ID pDev);
LOCAL void m6845vxbInstConnect (VXB_DEVICE_ID pDev);
LOCAL struct drvBusFuncs m6845vxbFuncs =
{
m6845vxbInstInit, /* devInstanceInit */
m6845vxbInstInit2, /* devInstanceInit2 */
m6845vxbInstConnect /* devConnect */
};
LOCAL void m6845ScreenRevMethod (VXB_DEVICE_ID, int);
LOCAL void m6845CurAttribMethod (VXB_DEVICE_ID, int);
LOCAL void m6845CursorSetMethod (VXB_DEVICE_ID, int);
LOCAL void m6845CursorMoveMethod (VXB_DEVICE_ID, int);
LOCAL struct vxbDeviceMethod m6845VgaMethods[] =
{
DEVMETHOD(vgaScreenRev, m6845ScreenRevMethod),
DEVMETHOD(vgaCurAttrib, m6845CurAttribMethod),
DEVMETHOD(vgaCursorSet, m6845CursorSetMethod),
DEVMETHOD(vgaCursorMove, m6845CursorMoveMethod),
{0, 0}
};
LOCAL struct vxbDevRegInfo m6845vxbDevRegistration =
{
NULL, /* pNext */
VXB_DEVID_DEVICE, /* devID */
VXB_BUSID_PLB, /* busID = PLB */
VXB_VER_4_0_0, /* vxbVersion */
"m6845Vga", /* drvName */
&m6845vxbFuncs, /* pDrvBusFuncs */
m6845VgaMethods, /* pMethods */
m6845vxbProbe /* devProbe */
};
LOCAL UCHAR * m6845CharTable [] =
{
/* 8-bit Latin-1 mapped to the PC charater set: '\0' means non-printable */
(unsigned char *)
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
"\376\245\376\376\376\376\231\376\235\376\376\376\232\376\376\341"
"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
"\376\244\225\242\223\376\224\366\233\227\243\226\201\376\376\230",
/* vt100 graphics */
(unsigned char *)
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ "
"\004\261\007\007\007\007\370\361\040\007\331\277\332\300\305\007"
"\007\304\007\007\303\264\301\302\263\007\007\007\007\007\234\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
"\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
"\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
"\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341"
"\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
"\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230",
/* IBM graphics: minimal translations (CR, LF, LL, SO, SI and ESC) */
(unsigned char *)
"\000\001\002\003\004\005\006\007\010\011\000\013\000\000\000\000"
"\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037"
"\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057"
"\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077"
"\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117"
"\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137"
"\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157"
"\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177"
"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"
};
/* forward declarations */
LOCAL void m6845HrdInit (M6845_CON_DEV *);
LOCAL void m6845StatInit (M6845_CON_DEV *);
LOCAL int m6845WriteString (M6845_CON_DEV *);
/******************************************************************************
*
* m6845HrdInit - initialize the VGA Display
*
* This function is called externally to initialize the m6845 display
*
* RETURNS: N/A
*
* NOMANUAL
*/
#define PCCON_BUFFER_SIZE (1*1024*1024)
LOCAL void m6845HrdInit
(
M6845_CON_DEV * pDrvCtrl
)
{
pcConframeBufferAddr = (UINT32)cacheDmaMalloc(PCCON_BUFFER_SIZE);
defaultFbBase = pcConframeBufferAddr;
m6845StatInit (pDrvCtrl);
}
/*******************************************************************************
*
* m6845StatInit - initialize the VGA Display state
*
* RETURNS: N/A
*/
LOCAL void m6845StatInit
(
M6845_CON_DEV * pDrvCtrl
)
{
HCF_DEVICE * pHcf = hcfDeviceGet (pDrvCtrl->pDev);
pDrvCtrl->memBase = (void*)defaultFbBase;
devResourceGet (pHcf, "colorMode", HCF_RES_INT, (void *)&pDrvCtrl->colorMode);
if (pDrvCtrl->colorMode == COLOR)
pDrvCtrl->defAttrib = ATRB_FG_BRIGHTWHITE | ATRB_BG_BROWN;
else
pDrvCtrl->defAttrib = ATRB_FG_WHITE | ATRB_BG_BLACK;
devResourceGet (pHcf, "colorSetting", HCF_RES_INT, (void *)&pDrvCtrl->defAttrib);
pDrvCtrl->sv_curAttrib = pDrvCtrl->defAttrib;
pDrvCtrl->curAttrib = pDrvCtrl->defAttrib;
pDrvCtrl->sv_col = pDrvCtrl->col = 0;
pDrvCtrl->sv_row = pDrvCtrl->row = 0;
pDrvCtrl->curChrPos = pDrvCtrl->memBase; /* current position */
pDrvCtrl->sv_rev = pDrvCtrl->rev = FALSE;
pDrvCtrl->ncol = (screen_size_x/2/8); /* Number of columns */
pDrvCtrl->nrow = screen_size_y/16; /* Number of text rows */
pDrvCtrl->scst = 0; /* scroll start */
pDrvCtrl->sced = screen_size_y/16-1; /* scroll end */
pDrvCtrl->autoWrap = TRUE; /* auto Wrap mode */
pDrvCtrl->scrollCheck = FALSE; /* scroll flag off */
pDrvCtrl->charSet = m6845CharTable [TEXT_SET]; /* character set */
pDrvCtrl->vgaMode = TEXT_MODE; /* video mode */
pDrvCtrl->insMode = INSERT_MODE_OFF; /* insert mode */
pDrvCtrl->escParaCount = 0; /* zero parameters */
pDrvCtrl->escQuestion = FALSE; /* ? flag set to false */
bzero ((char *)pDrvCtrl->escPara, sizeof(pDrvCtrl->escPara));
bzero (pDrvCtrl->tab_stop, sizeof(pDrvCtrl->tab_stop));
pDrvCtrl->tab_stop [ 0] = 1;
pDrvCtrl->tab_stop [ 8] = 1;
pDrvCtrl->tab_stop [16] = 1;
pDrvCtrl->tab_stop [24] = 1;
pDrvCtrl->tab_stop [32] = 1;
pDrvCtrl->tab_stop [40] = 1;
pDrvCtrl->tab_stop [48] = 1;
pDrvCtrl->tab_stop [56] = 1;
pDrvCtrl->tab_stop [64] = 1;
pDrvCtrl->tab_stop [72] = 1;
}
/******************************************************************************
*
* m6845ScreenRev - Reverse Screen
*
* RETURNS: N/A
*/
LOCAL void m6845ScreenRev
(
FAST M6845_CON_DEV * pDrvCtrl /* pointer to the m6845 descriptor */
)
{
UCHAR * cp; /* to hold the current pointer */
UCHAR atr; /* to hold the attribute character */
for (cp = pDrvCtrl->memBase; cp < pDrvCtrl->memBase + 2000 * 2;
cp += 2)
{
atr = *(cp+1);
*(cp+1) = atr & INT_BLINK_MASK;
*(cp+1) |= (atr << 4) & BG_ATTR_MASK;
*(cp+1) |= (atr >> 4) & FG_ATTR_MASK;
}
}
/******************************************************************************
*
* m6845CursorPos - Put the cursor at a specified location
*
* RETURNS: N/A
*/
LOCAL void m6845CursorPos
(
M6845_CON_DEV * pDrvCtrl,
FAST UINT16 pos /* position of the cursor */
)
{
return;
}
/******************************************************************************
*
* m6845CursorOn - switch the cursor on
*
* RETURNS: N/A
*/
LOCAL void m6845CursorOn
(
M6845_CON_DEV * pDrvCtrl
)
{
return;
}
/******************************************************************************
*
* m6845CursorOff - switch the cursor off
*
* RETURNS: N/A
*/
LOCAL void m6845CursorOff
(
M6845_CON_DEV * pDrvCtrl
)
{
return;
}
/* VxBus routines */
/******************************************************************************
*
* m6845vxbRegister - register m6845vxb driver
*
* This routine registers the m6845vxb driver and device recognition
* data with the vxBus subsystem.
*
* NOTE:
*
* This routine is called early during system initialization, and
* *MUST NOT* make calls to OS facilities such as memory allocation
* and I/O.
*
* RETURNS: N/A
*
* ERRNO
*/
void m6845vxbRegister(void)
{
vxbDevRegister(&m6845vxbDevRegistration);
}
/******************************************************************************
*
* m6845vxbProbe - probe for device presence
*
* NOTE:
*
* This routine is called early during system initialization, and
* *MUST* *NOT* make calls to OS facilities such as memory allocation
* and I/O.
*
* RETURNS: TRUE if probe passes and assumed a valid m6845vxb
* (or compatible) device. FALSE otherwise.
*
*/
LOCAL BOOL m6845vxbProbe
(
VXB_DEVICE_ID pDev /* Device information */
)
{
return (TRUE);
}
/******************************************************************************
*
* m6845vxbInstInit - initialize m6845vxb device
*
* This is the m6845vxb initialization routine.
*
* NOTE:
*
* This routine is called early during system initialization, and
* *MUST NOT* make calls to OS facilities such as memory allocation
* and I/O.
*
* RETURNS: N/A
*
* ERRNO
*/
LOCAL void m6845vxbInstInit
(
VXB_DEVICE_ID pDev
)
{
return;
}
/******************************************************************************
*
* m6845vxbInstInit2 - initialize m6845vxb device
*
* This is the m6845vxb initialization routine.
*
* NOTE:
*
* This routine is called early during system initialization, and
* *MUST NOT* make calls to OS facilities such as memory allocation
* and I/O.
*
* RETURNS: N/A
*
* ERRNO
*/
LOCAL void m6845vxbInstInit2
(
VXB_DEVICE_ID pDev
)
{
M6845_CON_DEV * pDrvCtrl = (M6845_CON_DEV *) malloc (sizeof (M6845_CON_DEV));
pDrvCtrl->pDev = pDev;
pDev->pDrvCtrl = pDrvCtrl;
pDev->pMethods = m6845VgaMethods;
vxbRegMap (pDev, 0, &pDrvCtrl->regHandle);
m6845HrdInit (pDrvCtrl);
}
/******************************************************************************
*
* m6845vxbInstConnect - connect m6845vxb device
*
* This is the m6845vxb connect routine.
*
* NOTE:
*
* This routine is called early during system initialization, and
* *MUST NOT* make calls to OS facilities such as memory allocation
* and I/O.
*
* RETURNS: N/A
*
* ERRNO
*/
LOCAL void m6845vxbInstConnect
(
VXB_DEVICE_ID pDev
)
{
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
pDrvCtrl->pTyDev = pcConDevBind (pDev->unitNumber,
m6845WriteString, (void *) pDrvCtrl);
}
void draw_char(unsigned char c, int x, int y)
{
int i,j;
unsigned char *VGA_DEV;
unsigned char *base;
unsigned char line;
VGA_DEV = (unsigned char *)(defaultFbBase + DEFAULT_FB_MEM);
base = &((VGA_DEV)[y*screen_size_x + x * depth]);
for(i=0; i<CHAR_HEIGHT; i++) {
line = FONT[c * CHAR_HEIGHT + i];
for(j=CHAR_WIDTH * depth; j > 0; j -= 2 ) {
base[ j ] = (line & 0x1) ? draw_color_1 : back_color_1;
base[ j - 1] = (line & 0x1) ? draw_color_2 : back_color_2;
line = line >> 1;
}
base += screen_size_x;
}
}
LOCAL char pre = -1;
void fb_putchar(M6845_CON_DEV * pVgaConDv, char c)
{
if(defaultFbBase == 0)
return;
if (c == '\n') {
if(pre != '\r')
{
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
}
pVgaConDv->col = 0;
pVgaConDv->row++;
}
else if (c == '\r') {
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
pVgaConDv->col = 0;
}
else if (c== '\t') {
/*pVgaConDv->col += 8;*/
}
else if (c == '\b'){
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
pVgaConDv->col--;
draw_char('\0', pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
}
else {
draw_char(c, pVgaConDv->col * CHAR_WIDTH , pVgaConDv->row * CHAR_HEIGHT);
pVgaConDv->col++;
}
if(pVgaConDv->col > (pVgaConDv->ncol-1)) {
pVgaConDv->col = 0;
pVgaConDv->row++;
}
#ifdef LITTLE_WINDOWS
if(pVgaConDv->row >= pVgaConDv->nrow) {
memcpy(defaultFbBase + (CHAR_HEIGHT * (num_rows - lw_rows)) * screen_size_x,
defaultFbBase + (CHAR_HEIGHT * (num_rows - lw_rows + 1)) * screen_size_x,
screen_size_x * (CHAR_HEIGHT * (lw_rows - 1)));
memset(pVgaConDv->nrow + (CHAR_HEIGHT * (num_rows - 1)) * screen_size_x, 0, screen_size_x * CHAR_HEIGHT);
pVgaConDv->row--;
}
#else
if(pVgaConDv->row >=pVgaConDv->nrow) {
memcpy((void*)defaultFbBase, (void*)(defaultFbBase + screen_size_x*CHAR_HEIGHT), screen_size_x * screen_size_y - screen_size_x*CHAR_HEIGHT);
pVgaConDv->row--;
memset((void*)defaultFbBase + (/*592*/pVgaConDv->nrow*16-16)*screen_size_x, 0, screen_size_x*CHAR_HEIGHT);
}
#endif
if(c != '\r')
{
draw_char(95/*219*/, pVgaConDv->col * CHAR_WIDTH, pVgaConDv->row * CHAR_HEIGHT);
}
pre = c;
}
/*******************************************************************************
*
* m6845WriteString - Write Character string to VGA Display
*
* This function does the write to the m6845 routine. This routine is provided as
* transmitter startup routine when tyDevInit is called.
*
* RETURNS: number of bytes written to the screen
*
* NOMANUAL
*/
LOCAL int m6845WriteString
(
M6845_CON_DEV * pDrvCtrl /* pointer to the console descriptor */
)
{
int dummy;
UCHAR ch;
FAST int nBytes;
FAST UCHAR atr;
TY_DEV * pTyDev = pDrvCtrl->pTyDev;
FAST RING_ID ringId = pTyDev->wrtBuf;
M6845_LOCK_TAKE(pDrvCtrl);
pTyDev->wrtState.busy = TRUE;
atr = pDrvCtrl->curAttrib;
nBytes = 0;
/* check if we need to output XON/XOFF for the read side */
if (pTyDev->wrtState.xoff || pTyDev->wrtState.flushingWrtBuf)
{
pTyDev->wrtState.busy = FALSE;
M6845_LOCK_GIVE(pDrvCtrl);
return nBytes;
}
while (RNG_ELEM_GET (ringId,&ch,dummy) != 0)
{
nBytes++;
fb_putchar(pDrvCtrl, ch);
}
pTyDev->wrtState.busy = FALSE;
M6845_LOCK_GIVE(pDrvCtrl);
if (rngFreeBytes (ringId) >= tyWrtThreshold)
{
semGive (&pTyDev->wrtSyncSem);
if (_func_selWakeupAll != NULL)
(* _func_selWakeupAll) (&pTyDev->selWakeupList, SELWRITE);
}
return nBytes;
}
/*******************************************************************************
*
* m6845ScreenRevMethod - reverse the screen (method)
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void m6845ScreenRevMethod
(
VXB_DEVICE_ID pDev,
int value
)
{
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
VGA_QUERY * pQuery = (VGA_QUERY *) value;
if (pQuery->unit != pDev->unitNumber)
return;
pDrvCtrl->rev = pDrvCtrl->rev ? FALSE : TRUE;
m6845ScreenRev (pDrvCtrl);
}
/*******************************************************************************
*
* m6845CurAttribMethod - get or set the color attributes (method)
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void m6845CurAttribMethod
(
VXB_DEVICE_ID pDev,
int value
)
{
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
VGA_QUERY * pQuery = (VGA_QUERY *) value;
if (pQuery->unit != pDev->unitNumber)
return;
if (pQuery->get)
*pQuery->pArg = pDrvCtrl->curAttrib;
else
pDrvCtrl->curAttrib = *pQuery->pArg;
}
/*******************************************************************************
*
* m6845CursorSetMethod - turn the cursor off or on (method)
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void m6845CursorSetMethod
(
VXB_DEVICE_ID pDev,
int value
)
{
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
VGA_QUERY * pQuery = (VGA_QUERY *) value;
if (pQuery->unit != pDev->unitNumber)
return;
if (*pQuery->pArg == 0)
m6845CursorOff (pDrvCtrl);
else
m6845CursorOn (pDrvCtrl);
}
/*******************************************************************************
*
* m6845CursorMoveMethod - move the cursor (method)
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void m6845CursorMoveMethod
(
VXB_DEVICE_ID pDev,
int value
)
{
M6845_CON_DEV * pDrvCtrl = pDev->pDrvCtrl;
VGA_QUERY * pQuery = (VGA_QUERY *) value;
int arg = *pQuery->pArg;
if (pQuery->unit != pDev->unitNumber)
return;
pDrvCtrl->row = (arg >> 8) & 0xff;
pDrvCtrl->col = arg & 0xff;
if (pDrvCtrl->row >= pDrvCtrl->nrow)
pDrvCtrl->row = pDrvCtrl->nrow - 1;
if (pDrvCtrl->col >= pDrvCtrl->ncol)
pDrvCtrl->col = pDrvCtrl->ncol - 1;
m6845CursorPos (pDrvCtrl, (UINT16) (pDrvCtrl->row * pDrvCtrl->ncol
+ pDrvCtrl->col));
}
#ifdef INCLUDE_ANSI_ESC_SEQUENCE
/*****************************************************************************
*
* m6845EscResponse - This function gives back a response to an escape sequence.
* The valid response Ids are
* 0 for cursor position, 1 for terminal status,
* 2 for terminal device attributes.
*
* RETURNS: N/A
*/
LOCAL void m6845EscResponse
(
M6845_CON_DEV * pDrvCtrl, /* pointer to the m6845 descriptor */
int responseId /* response Id */
)
{
tyIoctl (pDrvCtrl->pTyDev, FIORFLUSH, 0);
if ( responseId == 0)
{
sprintf (pDrvCtrl->escResp, "\033[%d;%dR", pDrvCtrl->row,
pDrvCtrl->col);
}
else if ( responseId == 1)
{
sprintf (pDrvCtrl->escResp, "\033[0n");
}
else if ( responseId == 2)
{
sprintf (pDrvCtrl->escResp, "\033[?1;0c");
}
else
{
pDrvCtrl->escResp[0] = '\0';
}
rngBufPut (pDrvCtrl->pTyDev->rdBuf, pDrvCtrl->escResp,
strlen (pDrvCtrl->escResp) );
semGive (&pDrvCtrl->pTyDev->rdSyncSem);
selWakeupAll (&pDrvCtrl->pTyDev->selWakeupList, SELREAD);
}
#endif /* INCLUDE_ANSI_ESC_SEQUENCE */

120
vxbM6845Vga.h

@ -0,0 +1,120 @@
/* vxbM6845Vga.h - PC Keyboard and VGA Controller header file */
/*
* Copyright (c) 2007, 2010 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01c,25jan10,jc0 add videoMemHandle for video memory handler.
01b,17aug07,pmr new register access methods
01a,20feb07,pmr adapted for VxBus from version 01d.
*/
#ifndef __INCvxbM6845Vgah
#define __INCvxbM6845Vgah
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ASMLANGUAGE
#include <tyLib.h>
#include <vxBusLib.h>
#include "pcConsole.h"
#include <hwif/vxbus/vxBus.h>
#define NPARS 16 /* number of escape parameters */
/* method ids */
METHOD_DECL(vgaScreenRev);
METHOD_DECL(vgaCurAttrib);
METHOD_DECL(vgaCursorSet);
METHOD_DECL(vgaCursorMove);
METHOD_DECL(kbdInit);
METHOD_DECL(kbdNumSet);
METHOD_DECL(pcConBeep);
/* vga console device descriptor */
typedef struct
{
VXB_DEVICE_ID pDev;
TY_DEV * pTyDev;
UCHAR * memBase; /* video memory base */
UCHAR * selReg; /* select register */
UCHAR * valReg; /* value register */
UCHAR curSt, curEd; /* current cursor mode */
int row, col; /* current cursor position */
UCHAR * curChrPos; /* current character position */
UCHAR curAttrib; /* current attribute */
UCHAR defAttrib; /* current default attribute */
int nrow, ncol; /* current screen geometry */
int scst, sced; /* scroll region from to */
BOOL rev; /* revarse mode char */
BOOL autoWrap; /* auto Wrap mode */
BOOL sv_rev; /* saved revarse mode char */
int sv_row, sv_col; /* saved cursor position */
UCHAR sv_curAttrib; /* saved attributes */
BOOL scrollCheck; /* scroll check */
UCHAR * charSet; /* character set Text or Graphics */
int vgaMode; /* added to support graphics Mode */
BOOL colorMode; /* color mode MONO / COLOR */
BOOL insMode; /* insert mode on / off */
char tab_stop [80]; /* tab stop mark */
char escResp[10]; /* esc sequence response buffer */
UINT16 escFlags; /* 16 bit escape flags */
int escParaCount; /* seen escape parameters (count) */
int escPara[NPARS]; /* parameters */
BOOL escQuestion; /* ? mark in escape sequence */
void * regHandle; /* register access map handle */
void *videoMemHandle; /* memory access map handle */
} M6845_CON_DEV;
/* monitor definitions */
#define TEXT_SET 0 /* Normal text set */
#define GRAPHICS_VT100_SET 1 /* vt100 graphics set */
#define IBM_GRAPHICS_SET 2 /* IBM graphics character set */
#define TEXT_MODE 0 /* monitor in text mode */
#define GRAPHICS_MODE 1 /* monitor in graphics mode */
#define INSERT_MODE_OFF 0 /* character insert mode off */
#define INSERT_MODE_ON 1 /* character insert mode on */
#define FG_ATTR_MASK 0x07 /* foreground attribute mask */
#define BG_ATTR_MASK 0x70 /* background attribute mask */
#define INT_BLINK_MASK 0x88 /* intensity and blinking mask */
#define FORWARD 1 /* scroll direction forward */
#define BACKWARD 0 /* scroll direction backward */
/* escape flags */
#define ESC_NORMAL 0x0001 /* normal state */
#define ESC_ESC 0x0002 /* ESC state */
#define ESC_BRACE 0x0004 /* ESC [ state */
#define ESC_GET_PARAMS 0x0008 /* ESC [ n state */
#define ESC_GOT_PARAMS 0x0010 /* ESC [ n;n;n; state */
#define ESC_FUNC_KEY 0x0020 /* ESC [ [ state */
#define ESC_HASH 0x0040 /* ESC # state */
#define ESC_SET_TEXT 0x0080 /* ESC ( state */
#define ESC_SET_GPRAHICS 0x0100 /* ESC ) state */
#define M6845_SEL_REG 0
#define M6845_CTRL_REG 1
#define M6845_CHR 2
/* video memory size */
#define M6845_VIDEO_MEM 2048
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus
}
#endif
#endif /* __INCvxbM6845Vgah */

5054
vxbPci.c

File diff suppressed because it is too large

539
vxbPciLib.h

@ -0,0 +1,539 @@
/* vxbPciLib.h - PCI bus header file for vxBus */
/*
* Copyright (c) 2005-2013 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01v,15jan13,j_z added some PCI MSI process functions declaration.
and PCI MSI/MSI-X type defines. (WIND00333514)
01u,31oct12,l_z Add vxbPciMSIGet declaration. (WIND00373602)
01t,04sep12,l_z Add vxbPciIntEnable/Disable support. (WIND365027)
01s,26jul12,sye Removed duplicate method declaration. (WIND00365654)
01r,17oct11,h_k added pciMinBus member in vxbPciConfig structure.
added vxbPciConfigLibWithMinBusInit() prototype. (CQ:288091)
01q,29apr10,pad Moved extern C statement after include statements.
01p,21apr09,h_k updated vxbPciIntDisconnect2() for LP64.
moved vxbPciConfigBdfPack, vxbPciBusTypeInit, vxbPciIntLibInit
vxbPciConfigLibInit, vxbPciAutoConfig, vxbPciIntConnect to
vxbPciLib.h.
01o,23feb09,h_k updated for LP64 support.
01n,01aug08,h_k added missing vxbPciConfigModifyXxx. (CQ:120805)
01m,09jul08,tor add struct pciDevAnnounceInfo
01l,18jun08,h_k changed struct vxbAccessList to VXB_ACCESS_LIST.
01k,01may08,h_k added busCtlrDevCfgRead_desc and busCtlrDevCfgWrite_desc.
removed unused fields from vxbPciDevice structure.
01j,14apr08,h_k Change structure elements to remove dead code.
01i,20aug07,dtr Provide spinlock for dll protection.
01h,15jul07,tor MSI API
01g,11jun07,tor remove VIRT_ADDR
01f,08mar07,h_k moved type declarations from vxbPci.c.
01e,06mar07,h_k added missing dllLib.h inclusion.
01d,17jan07,dtr Add in Config and IntLib info ptrs here in vxbPciDevice.
01e,09oct06,pdg placed the earlier method id macros back with the updated id
values
01d,19sep06,pdg replaced method constants with addresses
01c,25oct05,mdo Add new PCI ctlr define
01b,01sep05,mdo Add vxb prefix
01a,10aug05,mdo Phase in new access method
17Jan05,tor written
*/
#ifndef INC_VXBPCILIB_H
#define INC_VXBPCILIB_H
#include <dllLib.h>
#include <hwif/vxbus/vxbPlbLib.h>
#include <hwif/vxbus/hwConf.h>
#include <spinLockLib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* defines */
#define PCI_CONTROLLER_METHOD_CFG_READ \
((VXB_METHOD_ID)busCtlrCfgRead_desc)
#define PCI_CONTROLLER_METHOD_CFG_WRITE \
((VXB_METHOD_ID)busCtlrCfgWrite_desc)
#define PCI_CONTROLLER_METHOD_DEV_CFG_READ \
((VXB_METHOD_ID)busCtlrDevCfgRead_desc)
#define PCI_CONTROLLER_METHOD_DEV_CFG_WRITE \
((VXB_METHOD_ID)busCtlrDevCfgWrite_desc)
#define PCI_CONTROLLER_METHOD_BUS_ACCESS_OVERRIDE \
((VXB_METHOD_ID)busCtlrAccessOverride_desc)
#define PCI_CONTROLLER_METHOD_CONVERT_BASE_ADDR \
((VXB_METHOD_ID)busCtlrBaseAddrCvt_desc)
/*
* Provide method to access PCI bus controllers config lib and
* interrupt information.
*/
#define PCI_CONTROLLER_METHOD_CFG_INFO \
((VXB_METHOD_ID)busCtlrCfgInfo_desc)
#define PCI_CONTROLLER_METHOD_INTERRUPT_INFO \
((VXB_METHOD_ID)busCtlrInterruptInfo_desc)
#define VXB_INT_PCI_INTX (0x0)
#define VXB_INT_PCI_MSI (0x1)
#define VXB_INT_PCI_MSIX (0x2)
/*
* The previous MSI implementation doesn't use vxbIntAlloc and vxbIntFree
* routines, but it also allocate the MSI vectors. The vxbIntDisconnect
* routine doesn't know if it should free the vectors, so add this flag
* to distinguish this, it is called internal in vxbIntDynaVecConnect
* method. When this flag is used, vxbIntDisconnect will free the vectors,
* otherwise vxbIntDisconnect doesn't do anyting, and the driver should
* explicitly call vxbIntFree to release the vectors.
*/
#define VXB_INT_PCI_LEGACY_MSI (0x3)
#define VXB_IS_CONTINUOUS_MSI(type) \
(((type)&(VXB_INT_PCI_MSI))?TRUE:FALSE)
#define VXB_IS_MSI_INT(type) \
(((type)&(0xF))?TRUE:FALSE)
#ifndef DOC
#define PCI_INT_LINES 255
#endif /* !DOC */
/* typedefs */
typedef struct vxbPciID PCI_DEVVEND;
typedef struct vxbPciRegister PCI_DRIVER_REGISTRATION;
typedef struct vxbPciDevice PCI_HARDWARE;
typedef struct vxbPciInt PCI_INTERRUPT_RECORD;
typedef STATUS (*VXB_PCI_FOREACH_FUNC)(VXB_DEVICE_ID busCtrlID,int bus, int dev,
int func, void *pArg);
/*
* The PCI busType uses DEV_ID and VEND_ID to pair devices up
* with their drivers. The driver provides a busPciRegInfo
* structure when it registers with the bus subsystem. If the
* bus subsystem finds that the driver registered a bus type
* of PCI (or one of the PCI variants), and finds that PCI is
* present on the system, then the bus subsystem calls the
* PCI-specific device check routine.
*
* In addition, the PCI bus tracks the standard bus, device,
* and function values.
*/
struct vxbPciID
{
UINT16 pciDevId;
UINT16 pciVendId;
};
struct vxbPciRegister
{
struct vxbDevRegInfo b;
int idListLen;
struct vxbPciID * idList;
};
struct vxbPciConfig
{
int pciMaxBus; /* Max number of sub-busses */
STATUS pciLibInitStatus;
int pciMinBus; /* Minimum number of sub-busses */
};
struct vxbPciInt
{
struct plbIntrEntry plbIntr; /* must be first */
void * pCookie; /* PCI bus cookie: see pciAutoConfigLib */
spinlockIsr_t pciIntLibSpinlockIsr;
/* [b,d,f] */
UINT8 pciBus; /* bus: device identification */
UINT8 pciDev; /* device: device identification */
/* function: not required. */
/* PCI interrupt lines */
VOIDFUNCPTR * intA; /* interrupt vector on int-A */
VOIDFUNCPTR * intB; /* interrupt vector on int-B */
VOIDFUNCPTR * intC; /* interrupt vector on int-C */
VOIDFUNCPTR * intD; /* interrupt vector on int-D */
DL_LIST * pciIntList;
void * msiAddress;
UINT16 msiData;
/* interrupt route functions */
FUNCPTR intEnable; /* enable interrupt line on intr controller */
FUNCPTR intDisable; /* disable interrupt line on intr controller */
FUNCPTR intAcknowledge; /* acknowledge & clear int line on intr ctrl */
STATUS pciIntLibInitStatus;
BOOL pciIntEnableUsed; /*
* true when using the vxbPciIntEnable/Disable
* this field is added for compatible.
*/
};
struct vxbPciIntHandlerInfo
{
DL_NODE node;
struct vxbPciInt *pIntInfo;
int irq;
spinlockIsr_t pciIntHandlerSpinlockIsr;
DL_LIST pciIntHandlerList;
};
struct vxbPciDevice
{
UINT8 pciBus;
UINT8 pciDev;
UINT8 pciFunc;
UINT16 pciDevId;
UINT16 pciVendId;
void * pCookie;
struct vxbPciConfig *pPciConfig; /* PCI config lib info */
struct vxbPciInt *pIntInfo; /* interrupt info */
VXB_DEVICE_ID devID; /* bus controller vxBus ID */
};
/*
*
* pciDevAnnounceInfo - structure used by pciBusAnnounceDevices()
*
* pciBusAnnounceDevices is called after the legacy PCI bus configuration
* has been performed. The purpose of the routine is to traverse the
* bus and find all devices which are present on the bus. For each device
* found, the bus subsystem calls vxbDeviceAnnounce() to notify the bus
* subsystem that a device is present, and establish an instance if the
* driver can be found.
*
* The pciBusAnnounceDevices() routine uses pciConfigForeachFunc() to
* traverse the PCI bus hierarchy. The information required by each
* device, in order to establish a working instance, is contained in
* the pciDevAnnounceInfo structure. This includes the PCI bus methods
* which the driver will use to access methods, as well as a vxbDev
* struct pointer to indicate the pci controller, which contains
* information about the PCI device's parent bus.
*/
struct pciDevAnnounceInfo
{
struct vxbDev * pDev;
pVXB_ACCESS_LIST pMethods;
void * pCookie;
};
IMPORT STATUS pciRegister (void);
IMPORT void pciBusAnnounceDevices
(
pVXB_ACCESS_LIST pArg,
struct vxbDev * pDev,
void * pCookie
);
IMPORT STATUS vxbPciConfigInByte
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT8 * pData /* data read from the offset */
);
IMPORT STATUS vxbPciConfigInWord
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT16 * pData /* data read from the offset */
);
IMPORT STATUS vxbPciConfigInLong
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT32 * pData /* data read from the offset */
);
IMPORT STATUS vxbPciConfigOutByte
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT8 data /* data written to the offset */
);
IMPORT STATUS vxbPciConfigOutWord
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT16 data /* data written to the offset */
);
IMPORT STATUS vxbPciConfigOutLong
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT32 data /* data written to the offset */
);
IMPORT STATUS vxbPciConfigModifyByte
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT8 bitMask, /* Mask which defines field to alter */
UINT8 data /* data written to the offset */
);
IMPORT STATUS vxbPciConfigModifyWord
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT16 bitMask, /* Mask which defines field to alter */
UINT16 data /* data written to the offset */
);
IMPORT STATUS vxbPciConfigModifyLong
(
VXB_DEVICE_ID busCtrlID,
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo, /* function number */
int offset, /* offset into the configuration space */
UINT32 bitMask, /* Mask which defines field to alter */
UINT32 data /* data written to the offset */
);
IMPORT STATUS vxbPciConfigForeachFunc
(
VXB_DEVICE_ID pDev,
UINT8 bus, /* bus to start on */
BOOL recurse, /* if TRUE, do subordinate busses */
VXB_PCI_FOREACH_FUNC funcCheckRtn, /* routine to call for each PCI func */
void *pArg , /* argument to funcCheckRtn */
int skip
);
IMPORT STATUS vxbPciConfigForeachFunc2
(
VXB_DEVICE_ID pDev,
UINT8 bus, /* bus to start on */
BOOL recurse, /* if TRUE, do subordinate busses */
VXB_PCI_FOREACH_FUNC funcCheckRtn, /* routine to call for each PCI func */
void *pArg , /* argument to funcCheckRtn */
int skip
);
IMPORT STATUS vxbPciMSIProgram
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo *dynaVec
);
IMPORT STATUS vxbPciMSIEnable
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo *dynaVec
);
IMPORT STATUS vxbPciMSIDisable
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo *dynaVec
);
IMPORT STATUS vxbPciMSIGet
(
VXB_DEVICE_ID pInst,
struct vxbIntDynaVecInfo *dynaVec
);
IMPORT BOOL vxbPciMSIIsCap
(
VXB_DEVICE_ID
);
IMPORT HCF_DEVICE * pciHcfRecordFind
(
int pciBus, /* PCI Bus number */
int pciDevice /* PCI device number */
);
IMPORT STATUS pciDeviceAnnounce
(
VXB_DEVICE_ID busCtrlID,
UINT8 bus, /* PCI bus number */
UINT8 dev, /* PCI device number */
UINT8 func, /* PCI function number */
void * pArg /* pDev */
);
IMPORT STATUS vxbPciFindDevice
(
VXB_DEVICE_ID busCtrlID,
int vendorId, /* vendor ID */
int deviceId, /* device ID */
int index, /* desired instance of device */
int * pBusNo, /* bus number */
int * pDeviceNo, /* device number */
int * pFuncNo /* function number */
);
IMPORT STATUS vxbPciFindClass
(
VXB_DEVICE_ID busCtrlID,
int classCode, /* 24-bit class code */
int index, /* desired instance of device */
int * pBusNo, /* bus number */
int * pDeviceNo, /* device number */
int * pFuncNo /* function number */
);
IMPORT STATUS vxbPciDevConfig
(
VXB_DEVICE_ID busCtrlID,
int pciBusNo, /* PCI bus number */
int pciDevNo, /* PCI device number */
int pciFuncNo, /* PCI function number */
UINT32 devIoBaseAdrs, /* device IO base address */
UINT32 devMemBaseAdrs, /* device memory base address */
UINT32 command /* command to issue */
);
IMPORT STATUS vxbPciConfigReset
(
VXB_DEVICE_ID busCtrlID,
int startType /* for reboot hook, ignored */
);
IMPORT STATUS vxbPciMSICtl
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo *dynaVec,
BOOL enable
);
IMPORT void vxbPciInt
(
struct vxbPciIntHandlerInfo *pIntHandlerInfo
);
IMPORT STATUS vxbPciIntDisconnect
(
VXB_DEVICE_ID pDev,
VOIDFUNCPTR *vector, /* interrupt vector to attach to */
VOIDFUNCPTR routine /* routine to be called */
);
IMPORT STATUS vxbPciIntDisconnect2
(
VXB_DEVICE_ID pDev,
VOIDFUNCPTR *vector, /* interrupt vector to attach to */
VOIDFUNCPTR routine, /* routine to be called */
_Vx_usr_arg_t parameter /* routine parameter */
);
IMPORT void pciConfigEnable
(
VXB_DEVICE_ID busCtrlID
);
IMPORT int vxbPciConfigBdfPack
(
int busNo, /* bus number */
int deviceNo, /* device number */
int funcNo /* function number */
);
IMPORT STATUS vxbPciBusTypeInit
(
struct vxbDev * pDev
);
IMPORT STATUS vxbPciIntLibInit
(
struct vxbPciInt * pIntInfo
);
IMPORT STATUS vxbPciConfigLibInit
(
struct vxbPciConfig *pPciConfig,
int pciMaxBus /* Max number of sub-busses */
);
IMPORT STATUS vxbPciConfigLibWithMinBusInit
(
struct vxbPciConfig *pPciConfig,
int pciMaxBus, /* Max number of sub-busses */
int pciMinBus /* Minimum number of sub-busses */
);
IMPORT STATUS vxbPciAutoConfig
(
VXB_DEVICE_ID busCtrlID
);
IMPORT STATUS vxbPciIntConnect
(
VXB_DEVICE_ID pDev,
VOIDFUNCPTR *vector, /* interrupt vector to attach to */
VOIDFUNCPTR routine, /* routine to be called */
_Vx_usr_arg_t parameter /* parameter to be passed to routine */
);
IMPORT STATUS vxbPciIntEnable
(
VXB_DEVICE_ID pDev,
VOIDFUNCPTR *vector, /* interrupt vector to attach to */
VOIDFUNCPTR routine, /* routine to be called */
_Vx_usr_arg_t parameter, /* parameter to be passed to routine */
int level
);
IMPORT STATUS vxbPciIntDisable
(
VXB_DEVICE_ID pDev,
VOIDFUNCPTR *vector, /* interrupt vector to attach to */
VOIDFUNCPTR routine, /* routine to be called */
_Vx_usr_arg_t parameter, /* parameter to be passed to routine */
int level
);
IMPORT STATUS vxbPciMSIEnable
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo * dynaVec
);
IMPORT STATUS vxbPciMSIDisable
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo * dynaVec
);
IMPORT STATUS vxbPciMSIProgram
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo * dynaVec
);
IMPORT STATUS vxbPciMSIErase
(
VXB_DEVICE_ID pDev,
struct vxbIntDynaVecInfo * dynaVec
);
IMPORT STATUS vxbPciDevIntCapabCheck
(
VXB_DEVICE_ID pDev,
UINT32 type,
UINT32 count
);
IMPORT VXB_DEVICE_ID vxbPciGetDevInstance
(
VXB_DEVICE_ID busCtrlID,
UINT8 busNo,
UINT8 deviceNo,
UINT8 funcNo
);
#ifdef __cplusplus
}
#endif
#endif /* INC_VXBPCILIB_H */

2990
vxbSp25SpiFlash.c

File diff suppressed because it is too large

416
vxbSp25SpiFlash.h

@ -0,0 +1,416 @@
/* vxbSp25SpiFlash.h - Spansion S25XX serials SPI Flash Head File */
/*
* Copyright (c) 2012, 2013 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01d,14Oct13,d_l add cfi offset macros and remove structure cfi_ident
WRS_PACK_ALIGN(1) attribute to eliminate a warning.
01c,01feb13,ylu Change the parameter flash from pointer to
struct in pDrvCtrl.
01b,24jan13,y_y Added support for SST chips.
01a,14sep12,y_y created.
*/
#ifndef __INCvxbSp25SpiFlashh
#define __INCvxbSp25SpiFlashh
#ifdef __cplusplus
extern "C"
{
#endif
#include <../h/flash/vxbFlash.h>
#include <../h/flash/vxbFlashCommon.h>
/* defines */
/* macros for mutex */
#define SPIFLASH_MUTEX_OPT SEM_Q_PRIORITY | \
SEM_DELETE_SAFE | \
SEM_INVERSION_SAFE
#define SPIFLASH_LOCK(x) semTake((SEM_ID)(x), WAIT_FOREVER)
#define SPIFLASH_UNLOCK(x) semGive((SEM_ID)(x))
/* manufacturer ID */
#define SPANSION (0x01) /* The manufacturer id for SPANSION */
#define FUJITSU (0x04) /* The manufacturer id for FUJITSU */
#define NEC (0x10) /* The manufacturer id for NEC */
#define EON (0x1C) /* The manufacturer id for EON */
#define ATMEL (0x1F) /* The manufacturer id for ATMEL */
#define MICRO (0x20) /* The manufacturer id for MICRO */
#define AMIC (0x37) /* The manufacturer id for AMIC */
#define ESI (0x4A) /* The manufacturer id for ESI */
#define INTEL (0x89) /* The manufacturer id for INTEL */
#define ESMT (0x8C) /* The manufacturer id for ESMT */
#define TOSHIBA (0x98) /* The manufacturer id for TOSHIBA */
#define PMC (0x9D) /* The manufacturer id for PMC */
#define HYUNDAI (0xAD) /* The manufacturer id for HYUNDAI */
#define SHARP (0xB0) /* The manufacturer id for SHARP */
#define SST (0xBF) /* The manufacturer id for SST */
#define MXIC (0xC2) /* The manufacturer id for MXIC */
#define SAMSUNG (0xEC) /* The manufacturer id for SAMSUNG */
#define WINBOND (0xEF) /* The manufacturer id for SAMSUNG */
#define MISSING (0xFF)
/* Spansion SPI Flash Commands info */
#define SPI_WRSR_CMD (0x01)
#define SPI_WRR_CMD (0x01)
#define SPI_PP_CMD (0x02)
#define SPI_READ_CMD (0x03)
#define SPI_WRDI_CMD (0x04)
#define SPI_RDSR_CMD (0x05)
#define SPI_WREN_CMD (0x06)
#define SPI_RDSR2_CMD (0x07)
#define SPI_FAST_READ_CMD (0x0B)
#define SPI_FAST_READ_4B_CMD (0x0C)
#define SPI_FAST_READ_DDR_CMD (0x0D)
#define SPI_FAST_READ_DDR_4B_CMD (0x0E)
#define SPI_PP_4B_CMD (0x12)
#define SPI_READ_4B_CMD (0x13)
#define SPI_RABT_CMD (0x14)
#define SPI_WABT_CMD (0x15)
#define SPI_RBNK_CMD (0x16)
#define SPI_WBNK_CMD (0x17)
#define SPI_RECC_CMD (0x18)
#define SPI_P4E_CMD (0x20)
#define SPI_P4E_4B_CMD (0x21)
#define SPI_RASP_CMD (0x2B)
#define SPI_WASP_CMD (0x2F)
#define SPI_CLSR_CMD (0x30)
#define SPI_QPP_CMD (0x32)
#define SPI_QPP_4B_CMD (0x34)
#define SPI_RCR_CMD (0x35)
#define SPI_DUALIO_RD_CMD (0x3B)
#define SPI_DUALIO_RD_4B_CMD (0x3C)
#define SPI_P8E_CMD (0x40)
#define SPI_DLPRD_CMD (0x41)
#define SPI_OTPP_CMD (0x42)
#define SPI_PROGRAM_SECURITY_CMD (0x42) /* Program Security Register */
#define SPI_PNVDLR_CMD (0x43)
#define SPI_ERASE_SECURITY_CMD (0x44) /* Erase Security Register */
#define SPI_READ_SECURITY_CMD (0x48) /* Read Security Register */
#define SPI_WVDLR_CMD (0x4A)
#define SPI_OTPR_CMD (0x4B)
#define SPI_READ_UNIQUE_ID_CMD (0x4B) /* Read Unique ID Number */
#define SPI_P8E_4B_CMD (0x4C)
#define SPI_WRITE_VOLATILE_CMD (0x50) /* Write Enable for Volatile Status Register */
#define SPI_BE32KB_CMD (0x52) /* Block Erase 32KB */
#define SPI_READ_SFDP_CMD (0x5A) /* Read Serial Flash Discoverable Parameter Register */
#define SPI_BE1_CMD (0x60)
#define SPI_QUADIO_RD_CMD (0x6B)
#define SPI_QUADIO_RD_4B_CMD (0x6C)
#define SPI_ERS_SSP_CMD (0x75) /* Erase / Program Suspend */
#define SPI_SETBURSTWRAP_CMD (0x77) /* Set Burst with Wrap */
#define SPI_ERS_RES_CMD (0x7A) /* Erase / Program Resume */
#define SPI_PRG_SSP_CMD (0x85)
#define SPI_PRG_RES_CMD (0x8A)
#define SPI_READID_90_CMD (0x90)
#define SPI_READID_DUAL_CMD (0x92)
#define SPI_READID_QUAD_CMD (0x94)
#define SPI_RDID_9F_CMD (0x9F)
#define SPI_READ_ID_9F_CMD (0x9F)
#define SPI_MPM_CMD (0xA3)
#define SPI_PLBWR_CMD (0xA6)
#define SPI_PLBRD_CMD (0xA7)
#define SPI_READ_ID_AB_CMD (0xAB)
#define SPI_RDID_AB_CMD (0xAB)
#define SPI_RES_CMD (0xAB)
#define SPI_SP_CMD (0xB9)
#define SPI_DP_CMD (0xB9)
#define SPI_DUALIO_HPRD_CMD (0xBB)
#define SPI_DUALIO_HPRD_4B_CMD (0xBC)
#define SPI_DDR_DUALIO_HPRD_CMD (0xBD)
#define SPI_DDR_DUALIO_HPRD_4B_CMD (0xBE)
#define SPI_BE_CMD (0xC7)
#define SPI_SE_CMD (0xD8)
#define SPI_SE_4B_CMD (0xDC)
#define SPI_DYB_RD_CMD (0xE0)
#define SPI_DYB_PG_CMD (0xE1)
#define SPI_PPB_RD_CMD (0xE2)
#define SPI_PPB_PG_CMD (0xE3)
#define SPI_OCTALWORDREADQUAD_CMD (0xE3) /* Octal Word Read Quad */
#define SPI_PPB_ERS_CMD (0xE4)
#define SPI_WDBRD_CMD (0xE5)
#define SPI_WDBP_CMD (0xE6)
#define SPI_RPWD_CMD (0xE7)
#define SPI_WORDREADQUAD_CMD (0xE7) /* Word Read Quad */
#define SPI_WPWD_CMD (0xE8)
#define SPI_PWDU_CMD (0xE9)
#define SPI_QUADIO_HPRD_CMD (0xEB)
#define SPI_QUADIO_HPRD_4B_CMD (0xEC)
#define SPI_DDR_QUADIO_HPRD_CMD (0xED)
#define SPI_DDR_QUADIO_HPRD_4B_CMD (0xEE)
#define SPI_SOFTWARE_RESET (0xF0)
#define SPI_RMB_CMD (0xFF)
#define SPI_READMODE_RESET_CMD (0xFF) /* Continuous Read Mode Reset */
/* SST OPERATION INSTRUCTIONS */
#define SST_AAI_WORD_CMD (0xAD) /* Auto Address Increment Programming*/
/* Fast read */
#undef FAST_READ
#ifdef FAST_READ
#define SPI_READ_OPCODE SPI_FAST_READ_CMD
#define READ_CMD_BYTE 5
#else
#define SPI_READ_OPCODE SPI_READ_CMD
#define READ_CMD_BYTE 4
#endif
/* Generic JEDEC ID get func */
#ifndef JEDEC_ID_GET
#define JEDEC_ID_GET(pDev, jedecId, length) \
do \
{ \
UINT8 cmd = SPI_READ_ID_9F_CMD; \
SPI_TRANSFER transInfo; \
memset(&transInfo, 0, sizeof(SPI_TRANSFER)); \
transInfo.txBuf = &cmd; \
transInfo.txLen = 1; \
transInfo.rxBuf = jedecId; \
transInfo.rxLen = length; \
(void)vxbSpiTransfer (pDev, &transInfo); \
} \
while (0)
#endif
/* Spi Flash flags features */
#define NO_JEDEC_ID 0x0001
#define JEDECID_NO_EXT 0x0002
/* define macros */
#define SR_SRWD 0x80
#define SR_BP2 0x10
#define SR_BP1 0x08
#define SR_BP0 0x04
#define SR_WEL 0x02
#define SR_WIP 0x01
#define MAX_CMD_SIZE 5
#define TIMEOUT 2000000
#define SPI_3B_MAX 0x1000000
#define DEFAULT_PP_TIME 500
/*
* Device Interface Code Assignments from the "Common Flash Memory Interface
* Publication 100" dated December 1, 2001.
*/
#define CFI_INTERFACE_X8_ASYNC 0x0000
#define CFI_INTERFACE_X16_ASYNC 0x0001
#define CFI_INTERFACE_X8_BY_X16_ASYNC 0x0002
#define CFI_INTERFACE_X32_ASYNC 0x0003
#define CFI_INTERFACE_SINGLE_IO_SPI_ASYNC 0x0004
#define CFI_INTERFACE_MULTI_IO_SPI_ASYNC 0x0005
#define CFI_INTERFACE_NOT_ALLOWED 0xff
/* byte Swap */
#if (_BYTE_ORDER == _BIG_ENDIAN)
#define CPU_TO_SPI_FLASH_16(bigEndian, x) \
((bigEndian != 0) ? (UINT16) (x) : vxbSwap16 (x))
#define CPU_TO_SPI_FLASH_32(bigEndian, x) \
((bigEndian != 0) ? (UINT32) (x) : vxbSwap32 (x))
#define SPI_FLASH_LE16_TO_CPU(x) vxbSwap16 (x)
#define SPI_FLASH_LE32_TO_CPU(x) vxbSwap32 (x)
#else
#define CPU_TO_SPI_FLASH_16(bigEndian, x) \
((bigEndian == 0) ? (UINT16) (x) : vxbSwap16 (x))
#define CPU_TO_SPI_FLASH_32(bigEndian, x) \
((bigEndian == 0) ? (UINT32) (x) : vxbSwap32 (x))
#define SPI_FLASH_LE16_TO_CPU(x) ((UINT16) (x))
#define SPI_FLASH_LE32_TO_CPU(x) ((UINT32) (x))
#endif /* _BIG_ENDIAN */
#define SPI_FLASH_16_TO_CPU(bigEndian, x) CPU_TO_SPI_FLASH_16 (bigEndian, x)
#define SPI_FLASH_32_TO_CPU(bigEndian, x) CPU_TO_SPI_FLASH_32 (bigEndian, x)
/* Basic Query Structure */
#define SPI_CFI_ERASE_REGIONS 4
#define CFI_MAGIC_STR_LEN 3
#define SPI_CFI_OFFSET 0x10 /* Start of CFI data in RDID result */
/*
* Erase Block(s) within this Region are (blkSize) times 256 bytes
* in size. The value blkSize = 0 is used for 128-byte block size.
*/
#define CFI_BLK_SIZE(x) (((x) == 0) ? 0x80 : ((x) << 8))
#define OFF_QS (0)
#define OFF_PCS (3)
#define OFF_PETA (5)
#define OFF_ACS (7)
#define OFF_AETA (9)
#define OFF_VCCMIN (11)
#define OFF_VCCMAX (12)
#define OFF_VPPMIN (13)
#define OFF_VPPMAX (14)
#define OFF_WTO (15)
#define OFF_WBTO (16)
#define OFF_BETO (17)
#define OFF_CETO (18)
#define OFF_WTOM (19)
#define OFF_WBTOM (20)
#define OFF_BETOM (21)
#define OFF_CETOM (22)
#define OFF_DS (23)
#define OFF_ID (24)
#define OFF_WBL (26)
#define OFF_RN (28)
#define OFF_ERI0 (29)
#define OFF_ERI1 (33)
#define OFF_ERI2 (37)
#define OFF_ERI3 (41)
#define SPI_CFI_LEN (45)
struct cfi_ident
{
/* CFI Query Identification String */
UINT8 qryStr[CFI_MAGIC_STR_LEN]; /* Query-unique ASCII string */
UINT16 priCmdSet; /* Primary Vendor Command Set and Control */
/* Interface ID code */
UINT16 priExtTblAdrs; /* Address for Primary Algorithm extended Query */
/* table */
UINT16 altCmdSet; /* Alternate Vendor Command Set and Control */
/* Interface ID code */
UINT16 altExtTblAdrs; /* Address for Alternate Algorithm extended Query */
/* table */
/* CFI Query System Interface Information */
/* Vcc Logic Supply Minimum/Maximum Write/Erase voltage */
UINT8 vccMin;
UINT8 vccMax;
/* Vpp [Programming] Supply Minimum/Maximum Write/Erase voltage */
UINT8 vppMin;
UINT8 vppMax;
/*
* Typical timeout per single byte/word write (buffer write count = 1),
* 2**N microsecond
*/
UINT8 wrTimeout;
/*
* Typical timeout for minimum-size buffer write, 2**N microsecond
* (if supported; 00h=not supported)
*/
UINT8 wrBufTimeout;
/* Typical timeout per individual block erase, 2**N millisecond */
UINT8 blkEraseTimeout;
/*
* Typical timeout for full chip erase, 2**N millisecond
* (if supported; 00h=not supported)
*/
UINT8 chipEraseTimeout;
/* Maximum timeout for byte/word write, 2**N times typical */
UINT8 wrTimeoutMax;
/* Maximum timeout for buffer write, 2**N times typical */
UINT8 wrBufTimeoutMax;
/* Maximum timeout per individual block erase, 2**N times typical */
UINT8 blkEraseTimeoutMax;
/* Maximum timeout per individual block erase, 2**N times typical */
UINT8 chipEraseTimeoutMax;
/* Device Geometry Definition */
UINT8 devSize; /* Device Size(2**n in number of bytes) */
UINT16 ifDesc; /* Flash Device Interface description */
UINT16 wrBufLen; /* Maximum number of bytes in multi-byte write = 2**n */
UINT8 regionNum; /* Number of Erase Block Regions within device */
UINT32 EraseRegionInfo[SPI_CFI_ERASE_REGIONS];
};
/* CFI standard query structure region information */
struct cfi_region
{
UINT16 blkSize; /* Erase Block Size devided by 256 */
UINT16 blkNum; /* Number of Erase Blocks - 1 */
};
/* typedef */
typedef struct spiFlash_info
{
char name[MAX_DRV_NAME_LEN];
UINT16 manuId;
UINT16 devId;
UINT16 extId;
UINT16 pageSize;
UINT32 sectorSize;
UINT32 sectorNum;
UINT32 flags;
}SPIFLASH_INFO;
/* SPI_NOR_FLASH device struct */
typedef struct spi_norFlash_drv_ctrl
{
VXB_DEVICE_ID pDev;
char type[MAX_DRV_NAME_LEN];
int index;
UINT32 chipSize;
UINT32 ppTime;
UINT8 * pWrBuf;
SEM_ID muteSem; /* operation semaphore */
UINT8 addrWidth; /* 4-byte or 3-byte address */
BOOL isProbeOk; /* whether probe ok */
FLASH_CHIP mtd; /* FileSystem used */
VXB_SPI_MAST_SPEC * specialInfo;
SPIFLASH_INFO flash;
} SPI_FLASH_DEV;
#define PageSize(x) ((x)->flash.pageSize)
#define SectorSize(x) ((x)->flash.sectorSize)
#define SectorNum(x) ((x)->flash.sectorNum)
#define ChipSize(x) ((x)->chipSize)
#ifdef __cplusplus
}
#endif
#endif /* __INCvxbSp25SpiFlashh */

657
vxbYt8521Phy.c

@ -0,0 +1,657 @@
/* vxbYt8521Phy.c - driver for yt8521 10/100/1000 ethernet PHY chips */
/*
*
* 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.
*
*/
#include <vxWorks.h>
#include <vxBusLib.h>
#include <logLib.h>
#include <hwif/vxbus/vxBus.h>
#include <hwif/util/hwMemLib.h>
#include <hwif/util/vxbParamSys.h>
#include <../src/hwif/h/mii/miiBus.h>
#include <vxbYt8521Phy.h>
/* defines */
#undef YT8521PHY_DEBUG
#ifdef YT8521PHY_DEBUG
#define YT8521PHY_LOGMSG(fmt,p1,p2,p3,p4,p5,p6) logMsg(fmt,p1,p2,p3,p4,p5,p6)
#else
#define YT8521PHY_LOGMSG(fmt,p1,p2,p3,p4,p5,p6)
#endif
/* externs */
IMPORT BOOL autoNegForce;
/* locals */
LOCAL STATUS ytPhyExtRead(VXB_DEVICE_ID ,UINT32 , UINT16*);
LOCAL STATUS ytPhyExtWrite(VXB_DEVICE_ID ,UINT32 ,UINT16);
LOCAL STATUS ytPhyConfigInit(VXB_DEVICE_ID pDev);
LOCAL void ytPhyInit (VXB_DEVICE_ID);
LOCAL STATUS ytPhyModeSet (VXB_DEVICE_ID, UINT32);
LOCAL STATUS ytPhyModeGet (VXB_DEVICE_ID, UINT32 *, UINT32 *);
LOCAL void ytPhyDevInstInit(VXB_DEVICE_ID pDev);
LOCAL void ytPhyDevInstInit2(VXB_DEVICE_ID pDev);
LOCAL void ytPhyDevInstConnect(VXB_DEVICE_ID pDev);
LOCAL BOOL ytPhyProbe(VXB_DEVICE_ID pDev);
LOCAL STATUS ytPhyInstUnlink (VXB_DEVICE_ID, void *);
LOCAL device_method_t ytPhyMethods[] =
{
DEVMETHOD(miiModeGet, ytPhyModeGet),
DEVMETHOD(miiModeSet, ytPhyModeSet),
DEVMETHOD(vxbDrvUnlink, ytPhyInstUnlink),
{ 0, 0 }
};
LOCAL struct drvBusFuncs ytPhyFuncs =
{
ytPhyDevInstInit, /* devInstanceInit */
ytPhyDevInstInit2, /* devInstanceInit2 */
ytPhyDevInstConnect /* devInstanceConnect */
};
LOCAL VXB_PARAMETERS ytPhyParamDefaults[] =
{
{"fcmode", VXB_PARAM_INT32, {(void *)MII_FCADV_NONE}},
{NULL, VXB_PARAM_END_OF_LIST, {NULL}}
};
struct vxbDevRegInfo ytPhyDevRegistration =
{
NULL, /* pNext */
VXB_DEVID_DEVICE, /* devID */
VXB_BUSID_MII, /* busID = MII Bus */
VXB_VER_5_0_0, /* busVer */
"yt8521Phy", /* drvName */
&ytPhyFuncs, /* pDrvBusFuncs */
ytPhyMethods, /* pMethods */
ytPhyProbe, /* devProbe */
ytPhyParamDefaults /* parameter defaults */
};
void ytPhyRegister(void)
{
vxbDevRegister (&ytPhyDevRegistration);
return;
}
LOCAL void ytPhyDevInstInit
(
VXB_DEVICE_ID pDev
)
{
vxbNextUnitGet (pDev);
return;
}
LOCAL void ytPhyDevInstConnect
(
VXB_DEVICE_ID pDev
)
{
return;
}
/*********************************************************************
*
* ytPhyInstUnlink - VxBus unlink handler
*
* This function implements the VxBus unlink method for this driver.
* We delete each media type that was originally added to the MII bus
* instance by this device and take ourselves off the miiMonitor task
* list.
*
* RETURNS: OK if shutdown succeeds, else ERROR
*
* ERRNO: N/A
*/
LOCAL STATUS ytPhyInstUnlink
(
VXB_DEVICE_ID pDev,
void * unused
)
{
VXB_DEVICE_ID pBus;
MII_DRV_CTRL * pDrvCtrl;
UINT16 miiSts;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
if (pDrvCtrl->miiInitialized == FALSE)
return (ERROR);
/* Only our parent bus can delete us. */
if (pDrvCtrl->miiLeaving == FALSE)
return (ERROR);
/* Remove ourselves from the miiMonitor task list. */
miiBusListDel (pDev);
/* Remove media list entries. */
if ((pBus = vxbDevParent (pDev)) == NULL)
return (ERROR);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
if (miiSts & MII_SR_EXT_STS)
{
miiBusMediaDel (pBus, IFM_ETHER|IFM_1000_T);
miiBusMediaDel (pBus, IFM_ETHER|IFM_1000_T|IFM_FDX);
}
if (miiSts & MII_SR_TX_HALF_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_100_TX);
if (miiSts & MII_SR_TX_FULL_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_100_TX|IFM_FDX);
if (miiSts & MII_SR_10T_HALF_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_10_T);
if (miiSts & MII_SR_10T_FULL_DPX)
miiBusMediaDel (pBus, IFM_ETHER|IFM_10_T|IFM_FDX);
if (miiSts & MII_SR_AUTO_SEL)
miiBusMediaDel (pBus, IFM_ETHER|IFM_AUTO);
pDrvCtrl->miiInitialized = FALSE;
free (pDrvCtrl);
return (OK);
}
/*********************************************************************
*
* ytPhyDevInstInit2 - vxBus instInit2 handler
*
* This routine does the final driver setup. The PHY registers
* its media types with its parent bus and adds itself to the MII
* monitoring list.
*
* RETURNS: N/A
*
* ERRNO: N/A
*/
LOCAL void ytPhyDevInstInit2
(
VXB_DEVICE_ID pDev
)
{
VXB_DEVICE_ID pBus;
MII_DRV_CTRL * pDrvCtrl;
VXB_INST_PARAM_VALUE val;
UINT16 miiSts;
YT8521PHY_LOGMSG("ytPhyDevInstInit2(): entry for pDev: 0x%x\n",
(int)pDev, 0,0,0,0,0);
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
if (pDrvCtrl->miiInitialized == TRUE)
{
YT8521PHY_LOGMSG("ytPhyDevInstInit2(): already initialized\n",
0,0,0,0,0,0);
return;
}
pDrvCtrl->miiInitialized = TRUE;
/*
* Tell miiBus about the media we support.
*/
if ((pBus = vxbDevParent (pDev)) == NULL)
return;
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
if (miiSts & MII_SR_EXT_STS)
{
miiBusMediaAdd (pBus, IFM_ETHER|IFM_1000_T);
miiBusMediaAdd (pBus, IFM_ETHER|IFM_1000_T|IFM_FDX);
}
if (miiSts & MII_SR_TX_HALF_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_100_TX);
if (miiSts & MII_SR_TX_FULL_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_100_TX|IFM_FDX);
if (miiSts & MII_SR_10T_HALF_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_10_T);
if (miiSts & MII_SR_10T_FULL_DPX)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_10_T|IFM_FDX);
if (miiSts & MII_SR_AUTO_SEL)
miiBusMediaAdd (pBus, IFM_ETHER|IFM_AUTO);
miiBusMediaDefaultSet (pBus, IFM_ETHER|IFM_AUTO);
/*
* Initialize the PHY. This may perform DSP code
* tweaking as needed.
*/
ytPhyInit (pDev);
/* Add to the monitor list. */
miiBusListAdd (pDev);
/*
* paramDesc {
* The fcmode parameter specifies how we advertise
* the device flow control ability. The selection can be
* MII_FCADV_NONE, MII_FCADV_PAUSE, MII_FCADV_ASM,
* MII_FCADV_PAUSE_ASM. }
*/
if (vxbInstParamByNameGet (pDev, "fcmode", VXB_PARAM_INT32, &val) == OK)
{
pDrvCtrl->fcmode = (UINT16) (val.int32Val);
}
else
pDrvCtrl->fcmode = (UINT16) MII_FCADV_NONE;
return;
}
/*********************************************************************
*
* ytPhyProbe - vxBus yt8521Phy probe handler
*
* This routine always returns TRUE.
*
* RETURNS: TRUE always.
*
* ERRNO: N/A
*/
LOCAL BOOL ytPhyProbe
(
VXB_DEVICE_ID pDev
)
{
MII_DRV_CTRL * pDrvCtrl;
UINT16 miiId1;
UINT16 miiId2;
pDrvCtrl = pDev->pDrvCtrl;
miiId1 = pDrvCtrl->miiId1;
miiId2 = pDrvCtrl->miiId2;
if ((miiId1 == 0x0000)&&(miiId2==0x011a))
return (TRUE);
return (FALSE);
}
LOCAL void ytPhyInit
(
VXB_DEVICE_ID pDev
)
{
MII_DRV_CTRL * pDrvCtrl;
UINT16 miiSts;
UINT16 miiCtl;
UINT16 miiVal;
int i;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
ytPhyConfigInit(pDev);
/* Get status register so we can look for extended capabilities. */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
miiVal = MII_CR_POWER_DOWN;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
miiVal = 0;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
/* Set reset bit and then wait for it to clear. */
miiVal = MII_CR_RESET;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
for (i = 0; i < 1000; i++)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, &miiCtl);
if (!(miiCtl & MII_CR_RESET))
break;
}
if (i == 1000)
{
return;
}
/*
* If the extended capabilities bit is set, this is a gigE
* PHY, so make sure we advertise gigE modes.
*/
if (miiSts & MII_SR_EXT_STS)
{
/* Enable advertisement of gigE modes. */
miiVal = MII_MASSLA_CTRL_1000T_FD|MII_MASSLA_CTRL_1000T_HD;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, miiVal);
}
/*
* Some PHYs come out of reset with their isolate bit set. Make
* sure we don't write that bit back when setting the control
* register.
*/
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiCtl);
return;
}
LOCAL STATUS ytPhyModeSet
(
VXB_DEVICE_ID pDev,
UINT32 mode
)
{
MII_DRV_CTRL * pDrvCtrl;
UINT16 miiVal;
UINT16 miiAnar = 0;
UINT16 gmiiAnar = 0;
UINT16 miiCtl = 0;
UINT16 miiSts;
BOOL autoneg = TRUE;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
/* Get status register so we can look for extended capabilities. */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
switch(IFM_SUBTYPE(mode)) {
case IFM_AUTO:
/* Set autoneg advertisement to advertise all modes. */
miiAnar = MII_ANAR_10TX_HD|MII_ANAR_10TX_FD|
MII_ANAR_100TX_HD|MII_ANAR_100TX_FD;
if (miiSts & MII_SR_EXT_STS)
gmiiAnar = MII_MASSLA_CTRL_1000T_FD|MII_MASSLA_CTRL_1000T_HD;
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
break;
case IFM_1000_T:
/* Auto-negotiation is mandatory per IEEE in 1000BASE-T. */
if (!(miiSts & MII_SR_EXT_STS))
return(ERROR);
if ((mode & IFM_GMASK) == IFM_FDX)
gmiiAnar = MII_MASSLA_CTRL_1000T_FD;
else
gmiiAnar = MII_MASSLA_CTRL_1000T_HD;
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
break;
case IFM_100_TX:
if (autoNegForce)
{
miiCtl = MII_CR_100|MII_CR_AUTO_EN|MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
{
miiAnar = MII_ANAR_100TX_FD;
miiCtl |= MII_CR_FDX;
}
else
miiAnar = MII_ANAR_100TX_HD;
}
else
{
autoneg = FALSE;
/*
* Intel's PHY requires restarting auto-negotiation
* or software reset in order for speed/duplex changes
* to take effect. Use restarting auto-neg here.
*/
miiCtl = MII_CR_100|MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
miiCtl |= MII_CR_FDX;
}
break;
case IFM_10_T:
if (autoNegForce)
{
miiCtl = MII_CR_AUTO_EN|MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
{
miiAnar = MII_ANAR_10TX_FD;
miiCtl |= MII_CR_FDX;
}
else
miiAnar = MII_ANAR_10TX_HD;
}
else
{
autoneg = FALSE;
miiCtl = MII_CR_RESTART;
if ((mode & IFM_GMASK) == IFM_FDX)
miiCtl |= MII_CR_FDX;
}
break;
default:
return (ERROR);
}
ytPhyInit (pDev);
/* set flow control advertise ability */
miiAnar |= (pDrvCtrl->fcmode) << MII_ANAR_PAUSE_SHIFT;
if (autoneg)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_AN_ADS_REG, &miiVal);
miiVal &= ~(MII_ANAR_10TX_HD|MII_ANAR_10TX_FD|
MII_ANAR_100TX_HD|MII_ANAR_100TX_FD);
miiVal |= miiAnar;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_AN_ADS_REG, miiVal);
if (miiSts & MII_SR_EXT_STS)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, &miiVal);
miiVal &= ~(MII_MASSLA_CTRL_1000T_HD|MII_MASSLA_CTRL_1000T_FD);
miiVal |= gmiiAnar;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, miiVal);
}
}
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, &miiVal);
miiVal &= ~(MII_CR_FDX|MII_CR_100|MII_CR_1000|MII_CR_AUTO_EN|MII_CR_RESTART);
miiVal |= miiCtl;
miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, miiVal);
return(OK);
}
LOCAL STATUS ytPhyModeGet
(
VXB_DEVICE_ID pDev,
UINT32 * mode,
UINT32 * status
)
{
UINT16 miiSts;
UINT16 miiCtl;
UINT16 miiAnar;
UINT16 miiLpar;
UINT16 gmiiAnar = 0;
UINT16 gmiiLpar = 0;
UINT16 anlpar;
MII_DRV_CTRL * pDrvCtrl;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
*mode = IFM_ETHER;
*status = IFM_AVALID;
YT8521PHY_LOGMSG("ytPhyModeGet(): entry\n", 0,0,0,0,0,0);
/* read MII status register once to unlatch link status bit */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
/* read again to know its current value */
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_STAT_REG, &miiSts);
/* no link bit means no carrier. */
if (!(miiSts & MII_SR_LINK_STATUS) || (miiSts == 0xFFFF))
{
*mode |= IFM_NONE;
YT8521PHY_LOGMSG("ytPhyModeGet(): pDev: 0x%x no carrier\n",
(int)pDev,0,0,0,0,0);
return (OK);
}
*status |= IFM_ACTIVE;
/*
* read the control, ability advertisement and link
* partner advertisement registers.
*/
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_CTRL_REG, &miiCtl);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_AN_ADS_REG, &miiAnar);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_AN_PRTN_REG, &miiLpar);
if (miiSts & MII_SR_EXT_STS)
{
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_CTRL_REG, &gmiiAnar);
miiBusRead (pDev, pDrvCtrl->miiPhyAddr, MII_MASSLA_STAT_REG, &gmiiLpar);
}
/*
* If autoneg is on, figure out the link settings from the
* advertisement and partner ability registers. If autoneg is
* off, use the settings in the control register.
*/
if (miiCtl & MII_CR_AUTO_EN)
{
anlpar = miiAnar & miiLpar;
if ((gmiiAnar & MII_MASSLA_CTRL_1000T_FD) && \
(gmiiLpar & MII_MASSLA_STAT_LP1000T_FD))
*mode |= IFM_1000_T|IFM_FDX;
else if ((gmiiAnar & MII_MASSLA_CTRL_1000T_HD) && \
(gmiiLpar & MII_MASSLA_STAT_LP1000T_HD))
*mode |= IFM_1000_T|IFM_HDX;
else if (anlpar & MII_ANAR_100TX_FD)
*mode |= IFM_100_TX|IFM_FDX;
else if (anlpar & MII_ANAR_100TX_HD)
*mode |= IFM_100_TX|IFM_HDX;
else if (anlpar & MII_ANAR_10TX_FD)
*mode |= IFM_10_T|IFM_FDX;
else if (anlpar & MII_ANAR_10TX_HD)
*mode |= IFM_10_T|IFM_HDX;
else
*mode |= IFM_NONE;
YT8521PHY_LOGMSG("ytPhyModeGet(): pDev: 0x%x auto-neg ON,"
" mode: 0x%x\n", (int)pDev,(int)*mode,0,0,0,0);
}
else
{
if (miiCtl & MII_CR_FDX)
*mode |= IFM_FDX;
else
*mode |= IFM_HDX;
if ((miiCtl & (MII_CR_100 | MII_CR_1000)) == (MII_CR_100 | MII_CR_1000))
*mode |= IFM_1000_T;
else if (miiCtl & MII_CR_100)
*mode |= IFM_100_TX;
else
*mode |= IFM_10_T;
YT8521PHY_LOGMSG("ytPhyModeGet(): pDev: 0x%x auto-neg off,"
" mode: 0x%x\n",(int)pDev,(int)*mode,0,0,0,0);
}
return (OK);
}
LOCAL STATUS ytPhyConfigInit
(
VXB_DEVICE_ID pDev
)
{
STATUS ret;
UINT16 miiVal;
/* disable auto sleep */
ret = ytPhyExtRead(pDev,YT8521_EXTREG_SLEEP_CONTROL1,&miiVal);
if (ret < 0)
return ret;
miiVal &= ~(1 << YT8521_EN_SLEEP_SW_BIT);
ret = ytPhyExtWrite(pDev,YT8521_EXTREG_SLEEP_CONTROL1,miiVal);
if (ret < 0)
return ret;
/* enable RXC clock when no wire plug */
ret = ytPhyExtWrite(pDev,YT8521_EXTREG_SMI_SDS_PHY,0);
if (ret < 0)
return ret;
ret = ytPhyExtRead(pDev,YT8521_EXTREG_C,&miiVal);
if (ret < 0)
return ret;
miiVal &= ~(1 << 12);
ret = ytPhyExtWrite(pDev,YT8521_EXTREG_C,miiVal);
return ret;
}
LOCAL STATUS ytPhyExtRead
(
VXB_DEVICE_ID pDev,
UINT32 reg,
UINT16* val
)
{
STATUS ret;
MII_DRV_CTRL * pDrvCtrl;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
ret = miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, REG_DEBUG_ADDR_OFFSET, reg);
if (ret < 0)
return ret;
ret = miiBusRead (pDev, pDrvCtrl->miiPhyAddr, REG_DEBUG_DATA, val);
return ret;
}
LOCAL STATUS ytPhyExtWrite
(
VXB_DEVICE_ID pDev,
UINT32 reg,
UINT16 val
)
{
STATUS ret;
MII_DRV_CTRL * pDrvCtrl;
pDrvCtrl = (MII_DRV_CTRL *)pDev->pDrvCtrl;
ret = miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, REG_DEBUG_ADDR_OFFSET, reg);
if (ret < 0)
return ret;
ret = miiBusWrite (pDev, pDrvCtrl->miiPhyAddr, REG_DEBUG_DATA, val);
return (ret);
}

33
vxbYt8521Phy.h

@ -0,0 +1,33 @@
/* vxbYt8521Phy.h - register definitions for yt8521 PHY chips */
/*
*
* 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.
*
*/
#ifndef __INCyt8521Phyh
#define __INCyt8521Phyh
#ifdef __cplusplus
extern "C" {
#endif
IMPORT void ytPhyRegister (void);
#define REG_DEBUG_ADDR_OFFSET 0x1e
#define REG_DEBUG_DATA 0x1f
#define YT8521_EXTREG_SLEEP_CONTROL1 0x27
#define YT8521_EXTREG_SMI_SDS_PHY 0xA000
#define YT8521_EXTREG_C 0xc
#define YT8521_EN_SLEEP_SW_BIT 15
#ifdef __cplusplus
}
#endif
#endif /* __INCyt8521Phyh */
Loading…
Cancel
Save