Commit 8d491953 authored by Alessandro Rubini's avatar Alessandro Rubini

Tom's sources, from svn:software/drivers (rev. 623)

This is a simple copy for files from the white-rabbit svn,
currently at revision 623. No local modification is there
at this commit. The author of the code is Tomasz Wlostowski,
even though I haven't marked him as --author (lazy me).
parent e55357b6
include ../../Makedefs
all:
cd wr_vic && ./build.sh && cd ..
cd wr_minic && ./build.sh && cd ..
cp wr_minic/*.ko wr_vic/*.ko bin
clean:
cd wr_vic && ./build.sh clean && cd ..
cd wr_minic && ./build.sh clean && cd ..
deploy: all
mkdir -p $(WR_INSTALL_ROOT)/lib
mkdir -p $(WR_INSTALL_ROOT)/lib/modules
cp bin/*.ko $(WR_INSTALL_ROOT)/lib/modules
run: all
scp bin/*.ko root@$(T):/wr/lib/modules
\ No newline at end of file
obj-m := wr_minic.o
KDIR := ../../../kernel
PWD := $(shell pwd)
EXTRA_CFLAGS := -I$(SUBDIRS)/../wr_vic
MAKE = make
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
\ No newline at end of file
This is a very simple, but working kernel driver for WhiteRabbit mini-NIC (hdl/modules/wrsw_mini_nic) with proper WR timestamping.
TODO:
- add calibration/DMTD ioctls()
- add support for more than 1 endpoint + miNIC (configurable platform_devices)
- add NAPI polling
- add support for sending multiple descriptors (TX ring buffer)
- cleanup, adapt to kernel coding rules
- add TX_TS interrupt handler for proper reception of TX timestamps
BUGS:
- sometimes drops a warning like this one:
# ping 192.168.100.1
PING 192.168.100.1 (192.168.100.1): 56 data bytes
------------[ cut here ]------------
WARNING: at kernel/softirq.c:143 local_bh_enable+0x44/0xac()
Modules linked in: wr_minic whiterabbit_vic
[<c00291f8>] (unwind_backtrace+0x0/0xf0) from [<c00390fc>] (warn_slowpath_common+0x4c/0x64)
[<c00390fc>] (warn_slowpath_common+0x4c/0x64) from [<c003912c>] (warn_slowpath_null+0x18/0x1c)
[<c003912c>] (warn_slowpath_null+0x18/0x1c) from [<c003e23c>] (local_bh_enable+0x44/0xac)
[<c003e23c>] (local_bh_enable+0x44/0xac) from [<c01982d0>] (neigh_lookup+0xb0/0xb8)
[<c01982d0>] (neigh_lookup+0xb0/0xb8) from [<c01ccd10>] (arp_process+0x514/0x680)
[<c01ccd10>] (arp_process+0x514/0x680) from [<c018ece8>] (__netif_receive_skb+0x244/0x26c)
[<c018ece8>] (__netif_receive_skb+0x244/0x26c) from [<bf01484c>] (minic_rx_frame+0x1f4/0x238 [wr_minic])
[<bf01484c>] (minic_rx_frame+0x1f4/0x238 [wr_minic]) from [<00000002>] (0x2)
---[ end trace b836ae4c93691b2b ]---
- fix compilation warning:
MODPOST 1 modules
WARNING: "wrmch_vic_request_irq" [/home/slayer/wrdev-new/software/drivers/wr_minic/wr-minic.ko] undefined!
WARNING: "wrmch_vic_free_irq" [/home/slayer/wrdev-new/software/drivers/wr_minic/wr-minic.ko] undefined!
\ No newline at end of file
#!/bin/sh
. ../../../settings
make CONFIG_DEBUG_SECTION_MISMATCH=y ARCH=arm CROSS_COMPILE=$CROSS_COMPILE_ARM -C ../../../kernel SUBDIRS=`pwd` modules $1
#cp wr_minic.ko ../bin
\ No newline at end of file
This diff is collapsed.
/*
Register definitions for slave core: WR switch endpoint controller
* File : ../../../software/include/hw/endpoint_regs.h
* Author : auto-generated by wbgen2 from ep_wishbone_controller.wb
* Created : Wed Nov 3 19:00:12 2010
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ep_wishbone_controller.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_EP_WISHBONE_CONTROLLER_WB
#define __WBGEN2_REGDEFS_EP_WISHBONE_CONTROLLER_WB
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Endpoint Control Register */
/* definitions for field: Port identifier in reg: Endpoint Control Register */
#define EP_ECR_PORTID_MASK WBGEN2_GEN_MASK(0, 5)
#define EP_ECR_PORTID_SHIFT 0
#define EP_ECR_PORTID_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define EP_ECR_PORTID_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Reset event counters in reg: Endpoint Control Register */
#define EP_ECR_RST_CNT WBGEN2_GEN_MASK(5, 1)
/* definitions for field: Transmit framer enable in reg: Endpoint Control Register */
#define EP_ECR_TX_EN_FRA WBGEN2_GEN_MASK(6, 1)
/* definitions for field: Receive deframer enable in reg: Endpoint Control Register */
#define EP_ECR_RX_EN_FRA WBGEN2_GEN_MASK(7, 1)
/* definitions for register: Timestamping Control Register */
/* definitions for field: Transmit timestamping enable in reg: Timestamping Control Register */
#define EP_TSCR_EN_TXTS WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Receive timestamping enable in reg: Timestamping Control Register */
#define EP_TSCR_EN_RXTS WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Timestamping counter synchronization start in reg: Timestamping Control Register */
#define EP_TSCR_CS_START WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Timestamping counter synchronization done in reg: Timestamping Control Register */
#define EP_TSCR_CS_DONE WBGEN2_GEN_MASK(3, 1)
/* definitions for register: RX Deframer Control Register */
/* definitions for field: RX accept runts in reg: RX Deframer Control Register */
#define EP_RFCR_A_RUNT WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX accept giants in reg: RX Deframer Control Register */
#define EP_RFCR_A_GIANT WBGEN2_GEN_MASK(1, 1)
/* definitions for field: RX accept HP in reg: RX Deframer Control Register */
#define EP_RFCR_A_HP WBGEN2_GEN_MASK(2, 1)
/* definitions for field: RX accept fragments in reg: RX Deframer Control Register */
#define EP_RFCR_A_FRAG WBGEN2_GEN_MASK(3, 1)
/* definitions for field: RX 802.1q port mode in reg: RX Deframer Control Register */
#define EP_RFCR_QMODE_MASK WBGEN2_GEN_MASK(4, 2)
#define EP_RFCR_QMODE_SHIFT 4
#define EP_RFCR_QMODE_W(value) WBGEN2_GEN_WRITE(value, 4, 2)
#define EP_RFCR_QMODE_R(reg) WBGEN2_GEN_READ(reg, 4, 2)
/* definitions for field: Force 802.1q priority in reg: RX Deframer Control Register */
#define EP_RFCR_FIX_PRIO WBGEN2_GEN_MASK(6, 1)
/* definitions for field: Port-assigned 802.1x priority in reg: RX Deframer Control Register */
#define EP_RFCR_PRIO_VAL_MASK WBGEN2_GEN_MASK(8, 3)
#define EP_RFCR_PRIO_VAL_SHIFT 8
#define EP_RFCR_PRIO_VAL_W(value) WBGEN2_GEN_WRITE(value, 8, 3)
#define EP_RFCR_PRIO_VAL_R(reg) WBGEN2_GEN_READ(reg, 8, 3)
/* definitions for field: Port-assigned VID in reg: RX Deframer Control Register */
#define EP_RFCR_VID_VAL_MASK WBGEN2_GEN_MASK(16, 12)
#define EP_RFCR_VID_VAL_SHIFT 16
#define EP_RFCR_VID_VAL_W(value) WBGEN2_GEN_WRITE(value, 16, 12)
#define EP_RFCR_VID_VAL_R(reg) WBGEN2_GEN_READ(reg, 16, 12)
/* definitions for register: Flow Control Register */
/* definitions for field: RX Pause enable in reg: Flow Control Register */
#define EP_FCR_RXPAUSE WBGEN2_GEN_MASK(0, 1)
/* definitions for field: TX Pause enable in reg: Flow Control Register */
#define EP_FCR_TXPAUSE WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX pause threshold in reg: Flow Control Register */
#define EP_FCR_TX_THR_MASK WBGEN2_GEN_MASK(8, 8)
#define EP_FCR_TX_THR_SHIFT 8
#define EP_FCR_TX_THR_W(value) WBGEN2_GEN_WRITE(value, 8, 8)
#define EP_FCR_TX_THR_R(reg) WBGEN2_GEN_READ(reg, 8, 8)
/* definitions for field: TX pause quanta in reg: Flow Control Register */
#define EP_FCR_TX_QUANTA_MASK WBGEN2_GEN_MASK(16, 16)
#define EP_FCR_TX_QUANTA_SHIFT 16
#define EP_FCR_TX_QUANTA_W(value) WBGEN2_GEN_WRITE(value, 16, 16)
#define EP_FCR_TX_QUANTA_R(reg) WBGEN2_GEN_READ(reg, 16, 16)
/* definitions for register: Endpoint MAC address high part register */
/* definitions for register: Endpoint MAC address low part register */
/* definitions for register: DMTD Control Register */
/* definitions for field: DMTD Phase measurement enable in reg: DMTD Control Register */
#define EP_DMCR_EN WBGEN2_GEN_MASK(0, 1)
/* definitions for field: DMTD averaging samples in reg: DMTD Control Register */
#define EP_DMCR_N_AVG_MASK WBGEN2_GEN_MASK(16, 12)
#define EP_DMCR_N_AVG_SHIFT 16
#define EP_DMCR_N_AVG_W(value) WBGEN2_GEN_WRITE(value, 16, 12)
#define EP_DMCR_N_AVG_R(reg) WBGEN2_GEN_READ(reg, 16, 12)
/* definitions for register: DMTD Status register */
/* definitions for field: DMTD Phase shift value in reg: DMTD Status register */
#define EP_DMSR_PS_VAL_MASK WBGEN2_GEN_MASK(0, 24)
#define EP_DMSR_PS_VAL_SHIFT 0
#define EP_DMSR_PS_VAL_W(value) WBGEN2_GEN_WRITE(value, 0, 24)
#define EP_DMSR_PS_VAL_R(reg) WBGEN2_GEN_READ(reg, 0, 24)
/* definitions for field: DMTD Phase shift value ready in reg: DMTD Status register */
#define EP_DMSR_PS_RDY WBGEN2_GEN_MASK(24, 1)
/* definitions for register: MDIO Control Register */
/* definitions for field: MDIO Register Value in reg: MDIO Control Register */
#define EP_MDIO_CR_DATA_MASK WBGEN2_GEN_MASK(0, 16)
#define EP_MDIO_CR_DATA_SHIFT 0
#define EP_MDIO_CR_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define EP_MDIO_CR_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: MDIO Register Address in reg: MDIO Control Register */
#define EP_MDIO_CR_ADDR_MASK WBGEN2_GEN_MASK(16, 8)
#define EP_MDIO_CR_ADDR_SHIFT 16
#define EP_MDIO_CR_ADDR_W(value) WBGEN2_GEN_WRITE(value, 16, 8)
#define EP_MDIO_CR_ADDR_R(reg) WBGEN2_GEN_READ(reg, 16, 8)
/* definitions for field: MDIO Read/Write select in reg: MDIO Control Register */
#define EP_MDIO_CR_RW WBGEN2_GEN_MASK(31, 1)
/* definitions for register: MDIO Status Register */
/* definitions for field: MDIO Read Value in reg: MDIO Status Register */
#define EP_MDIO_SR_RDATA_MASK WBGEN2_GEN_MASK(0, 16)
#define EP_MDIO_SR_RDATA_SHIFT 0
#define EP_MDIO_SR_RDATA_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define EP_MDIO_SR_RDATA_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: MDIO Ready in reg: MDIO Status Register */
#define EP_MDIO_SR_READY WBGEN2_GEN_MASK(31, 1)
/* definitions for RAM: Event counters memory */
#define EP_RMON_RAM_BYTES 0x00000080 /* size in bytes */
#define EP_RMON_RAM_WORDS 0x00000020 /* size in 32-bit words, 32-bit aligned */
/* [0x0]: REG Endpoint Control Register */
#define EP_REG_ECR 0x00000000
/* [0x4]: REG Timestamping Control Register */
#define EP_REG_TSCR 0x00000004
/* [0x8]: REG RX Deframer Control Register */
#define EP_REG_RFCR 0x00000008
/* [0xc]: REG Flow Control Register */
#define EP_REG_FCR 0x0000000c
/* [0x10]: REG Endpoint MAC address high part register */
#define EP_REG_MACH 0x00000010
/* [0x14]: REG Endpoint MAC address low part register */
#define EP_REG_MACL 0x00000014
/* [0x18]: REG DMTD Control Register */
#define EP_REG_DMCR 0x00000018
/* [0x1c]: REG DMTD Status register */
#define EP_REG_DMSR 0x0000001c
/* [0x20]: REG MDIO Control Register */
#define EP_REG_MDIO_CR 0x00000020
/* [0x24]: REG MDIO Status Register */
#define EP_REG_MDIO_SR 0x00000024
#define EP_REG_IDCODE 0x00000028
/* definitions for register: WhiteRabbit-specific Configuration Register */
/* definitions for field: TX Calibration Pattern in reg: WhiteRabbit-specific Configuration Register */
#define MDIO_WR_SPEC_TX_CAL WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Calibration Pattern RX Status in reg: WhiteRabbit-specific Configuration Register */
#define MDIO_WR_SPEC_RX_CAL_STAT WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Reset calibration counter in reg: WhiteRabbit-specific Configuration Register */
#define MDIO_WR_SPEC_CAL_CRST WBGEN2_GEN_MASK(2, 1)
/* [0x10]: REG WhiteRabbit-specific Configuration Register */
#define MDIO_REG_WR_SPEC 0x00000010
#endif
/*
Register definitions for slave core: Mini NIC for WhiteRabbit
* File : ../../../software/include/hw/minic_regs.h
* Author : auto-generated by wbgen2 from mini_nic.wb
* Created : Fri Jul 30 00:33:27 2010
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE mini_nic.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_MINI_NIC_WB
#define __WBGEN2_REGDEFS_MINI_NIC_WB
//#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: miNIC Control Register */
/* definitions for field: TX DMA start in reg: miNIC Control Register */
#define MINIC_MCR_TX_START WBGEN2_GEN_MASK(0, 1)
/* definitions for field: TX DMA idle in reg: miNIC Control Register */
#define MINIC_MCR_TX_IDLE WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX DMA error in reg: miNIC Control Register */
#define MINIC_MCR_TX_ERROR WBGEN2_GEN_MASK(2, 1)
/* definitions for field: RX DMA ready in reg: miNIC Control Register */
#define MINIC_MCR_RX_READY WBGEN2_GEN_MASK(8, 1)
/* definitions for field: RX DMA buffer full in reg: miNIC Control Register */
#define MINIC_MCR_RX_FULL WBGEN2_GEN_MASK(9, 1)
/* definitions for field: RX DMA enable in reg: miNIC Control Register */
#define MINIC_MCR_RX_EN WBGEN2_GEN_MASK(10, 1)
/* definitions for register: TX DMA Address */
/* definitions for register: RX DMA Address */
/* definitions for register: RX buffer size register */
/* definitions for register: Interrupt disable register */
/* definitions for field: TX DMA interrupt in reg: Interrupt disable register */
#define MINIC_EIC_IDR_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt disable register */
#define MINIC_EIC_IDR_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt disable register */
#define MINIC_EIC_IDR_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: Interrupt enable register */
/* definitions for field: TX DMA interrupt in reg: Interrupt enable register */
#define MINIC_EIC_IER_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt enable register */
#define MINIC_EIC_IER_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt enable register */
#define MINIC_EIC_IER_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: Interrupt mask register */
/* definitions for field: TX DMA interrupt in reg: Interrupt mask register */
#define MINIC_EIC_IMR_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt mask register */
#define MINIC_EIC_IMR_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt mask register */
#define MINIC_EIC_IMR_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: Interrupt status register */
/* definitions for field: TX DMA interrupt in reg: Interrupt status register */
#define MINIC_EIC_ISR_TX WBGEN2_GEN_MASK(0, 1)
/* definitions for field: RX DMA interrupt in reg: Interrupt status register */
#define MINIC_EIC_ISR_RX WBGEN2_GEN_MASK(1, 1)
/* definitions for field: TX timestamp available in reg: Interrupt status register */
#define MINIC_EIC_ISR_TXTS WBGEN2_GEN_MASK(2, 1)
/* definitions for register: FIFO 'TX timestamp FIFO' data output register 0 */
/* definitions for field: Timestamp value in reg: FIFO 'TX timestamp FIFO' data output register 0 */
#define MINIC_TSFIFO_R0_TSVAL_MASK WBGEN2_GEN_MASK(0, 32)
#define MINIC_TSFIFO_R0_TSVAL_SHIFT 0
#define MINIC_TSFIFO_R0_TSVAL_W(value) WBGEN2_GEN_WRITE(value, 0, 32)
#define MINIC_TSFIFO_R0_TSVAL_R(reg) WBGEN2_GEN_READ(reg, 0, 32)
/* definitions for register: FIFO 'TX timestamp FIFO' data output register 1 */
/* definitions for field: Port ID in reg: FIFO 'TX timestamp FIFO' data output register 1 */
#define MINIC_TSFIFO_R1_PID_MASK WBGEN2_GEN_MASK(0, 5)
#define MINIC_TSFIFO_R1_PID_SHIFT 0
#define MINIC_TSFIFO_R1_PID_W(value) WBGEN2_GEN_WRITE(value, 0, 5)
#define MINIC_TSFIFO_R1_PID_R(reg) WBGEN2_GEN_READ(reg, 0, 5)
/* definitions for field: Frame ID in reg: FIFO 'TX timestamp FIFO' data output register 1 */
#define MINIC_TSFIFO_R1_FID_MASK WBGEN2_GEN_MASK(5, 16)
#define MINIC_TSFIFO_R1_FID_SHIFT 5
#define MINIC_TSFIFO_R1_FID_W(value) WBGEN2_GEN_WRITE(value, 5, 16)
#define MINIC_TSFIFO_R1_FID_R(reg) WBGEN2_GEN_READ(reg, 5, 16)
/* definitions for register: FIFO 'TX timestamp FIFO' control/status register */
/* definitions for field: FIFO empty flag in reg: FIFO 'TX timestamp FIFO' control/status register */
#define MINIC_TSFIFO_CSR_EMPTY WBGEN2_GEN_MASK(17, 1)
/* [0x0]: REG miNIC Control Register */
#define MINIC_REG_MCR 0x00000000
/* [0x4]: REG TX DMA Address */
#define MINIC_REG_TX_ADDR 0x00000004
/* [0x8]: REG RX DMA Address */
#define MINIC_REG_RX_ADDR 0x00000008
/* [0xc]: REG RX buffer size register */
#define MINIC_REG_RX_AVAIL 0x0000000c
/* [0x20]: REG Interrupt disable register */
#define MINIC_REG_EIC_IDR 0x00000020
/* [0x24]: REG Interrupt enable register */
#define MINIC_REG_EIC_IER 0x00000024
/* [0x28]: REG Interrupt mask register */
#define MINIC_REG_EIC_IMR 0x00000028
/* [0x2c]: REG Interrupt status register */
#define MINIC_REG_EIC_ISR 0x0000002c
/* [0x30]: REG FIFO 'TX timestamp FIFO' data output register 0 */
#define MINIC_REG_TSFIFO_R0 0x00000030
/* [0x34]: REG FIFO 'TX timestamp FIFO' data output register 1 */
#define MINIC_REG_TSFIFO_R1 0x00000034
/* [0x38]: REG FIFO 'TX timestamp FIFO' control/status register */
#define MINIC_REG_TSFIFO_CSR 0x00000038
#define MINIC_PBUF_SIZE_LOG2 (12)
#define MINIC_PBUF_SIZE (1<<(MINIC_PBUF_SIZE_LOG2+2))
#define MINIC_BASE_IO 0x0
#define MINIC_BASE_PBUF (2<<(MINIC_PBUF_SIZE_LOG2+2))
#define MINIC_BASE_ENDPOINT (1<<(MINIC_PBUF_SIZE_LOG2+2))
#define MINIC_BASE_GIGASPY (3<<(MINIC_PBUF_SIZE_LOG2+2))
#endif
/*
Register definitions for slave core: WR Switch PPS generator and RTC
* File : ../../../software/include/hw/pps_gen_regs.h
* Author : auto-generated by wbgen2 from wrsw_pps_gen.wb
* Created : Sat Sep 11 22:22:55 2010
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrsw_pps_gen.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WRSW_PPS_GEN_WB
#define __WBGEN2_REGDEFS_WRSW_PPS_GEN_WB
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Control Register */
/* definitions for field: Reset counter in reg: Control Register */
#define PPSG_CR_CNT_RST WBGEN2_GEN_MASK(0, 1)
/* definitions for field: Enable counter in reg: Control Register */
#define PPSG_CR_CNT_EN WBGEN2_GEN_MASK(1, 1)
/* definitions for field: Adjust offset in reg: Control Register */
#define PPSG_CR_CNT_ADJ WBGEN2_GEN_MASK(2, 1)
/* definitions for field: Set time in reg: Control Register */
#define PPSG_CR_CNT_SET WBGEN2_GEN_MASK(3, 1)
/* definitions for field: PPS Pulse width in reg: Control Register */
#define PPSG_CR_PWIDTH_MASK WBGEN2_GEN_MASK(4, 28)
#define PPSG_CR_PWIDTH_SHIFT 4
#define PPSG_CR_PWIDTH_W(value) WBGEN2_GEN_WRITE(value, 4, 28)
#define PPSG_CR_PWIDTH_R(reg) WBGEN2_GEN_READ(reg, 4, 28)
/* definitions for register: Nanosecond counter register */
/* definitions for register: UTC Counter register (least-significant part) */
/* definitions for register: UTC Counter register (most-significant part) */
/* definitions for register: Nanosecond adjustment register */
/* definitions for register: UTC Adjustment register (least-significant part) */
/* definitions for register: UTC Adjustment register (most-significant part) */
/* [0x0]: REG Control Register */
#define PPSG_REG_CR 0x00000000
/* [0x4]: REG Nanosecond counter register */
#define PPSG_REG_CNTR_NSEC 0x00000004
/* [0x8]: REG UTC Counter register (least-significant part) */
#define PPSG_REG_CNTR_UTCLO 0x00000008
/* [0xc]: REG UTC Counter register (most-significant part) */
#define PPSG_REG_CNTR_UTCHI 0x0000000c
/* [0x10]: REG Nanosecond adjustment register */
#define PPSG_REG_ADJ_NSEC 0x00000010
/* [0x14]: REG UTC Adjustment register (least-significant part) */
#define PPSG_REG_ADJ_UTCLO 0x00000014
/* [0x18]: REG UTC Adjustment register (most-significant part) */
#define PPSG_REG_ADJ_UTCHI 0x00000018
#endif
This diff is collapsed.
obj-m := wr_vic.o
KDIR := ../../../kernel
PWD := $(shell pwd)
MAKE = make
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
White Rabbit MCH Vectored Interrupt Controller driver
------
This driver adds support for the Interrupt Controller in the main FPGA of White Rabbit MCH. The VIC multiplexes 32 source interrupts
into single interrupt CPU interrupt line (AT91SAM9263_ID_IRQ0).
exported functions:
---------------------
void wrmch_vic_free_irq(int irq, void *dev_id);
int wrmch_vic_request_irq(int irq, wrvic_irq_t handler, void *dev_id);
void wrmch_vic_enable_irq(int irq);
void wrmch_vic_disable_irq(int irq);
dev_id = private data of requesting device/driver.
\ No newline at end of file
#!/bin/sh
. ../../../settings
make CONFIG_DEBUG_SECTION_MISMATCH=y ARCH=arm CROSS_COMPILE=$CROSS_COMPILE_ARM -C ../../../kernel SUBDIRS=`pwd` modules $1
#cp wr_vic.ko ../bin
\ No newline at end of file
/*
* whiterabbit_vic.c
*
* Copyright (c) 2009 Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/atomic.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include "wr_vic.h"
#define DRV_MODULE_VERSION "0.1"
#define DRV_NAME "wr_vic"
#define PFX DRV_NAME ": "
/* [0x0]: REG VIC Control Register */
#define VIC_REG_CTL 0x00000000
/* [0x4]: REG Raw Interrupt Status Register */
#define VIC_REG_RISR 0x00000004
/* [0x8]: REG Interrupt Enable Register */
#define VIC_REG_IER 0x00000008
/* [0xc]: REG Interrupt Disable Register */
#define VIC_REG_IDR 0x0000000c
/* [0x10]: REG Interrupt Mask Register */
#define VIC_REG_IMR 0x00000010
/* [0x14]: REG Vector Address Register */
#define VIC_REG_VAR 0x00000014
/* [0x1c]: REG End Of Interrupt Acknowledge Register */
#define VIC_REG_EOIR 0x0000001c
#define VIC_CTL_ENABLE (1<<0)
#define VIC_CTL_POL (1<<1)
#define VIC_IVT_BASE 0x00000080
#define VIC_SPURIOUS_IRQ 0x12345678
#define vic_readl(vic, offs) \
__raw_readl((vic)->regs+ (offs))
#define vic_writel(vic, offs, value) \
__raw_writel((value), (vic)->regs + (offs))
struct wrmch_vic {
void __iomem *regs;
wrvic_irq_t handlers[WRMCH_VIC_MAX_IRQS];
void *dev_ids[WRMCH_VIC_MAX_IRQS];
};
static struct wrmch_vic *VIC;
static irqreturn_t wrmch_vic_interrupt(int irq, void *dev_id)
{
u32 reg_var;
wrvic_irq_t handler;
reg_var = vic_readl(VIC, VIC_REG_VAR); // determine the interrupt source
if (reg_var == VIC_SPURIOUS_IRQ)
printk(KERN_ERR PFX "spurious interrupt");
else
{
// printk("Got irq: var %d\n", reg_var);
handler = VIC->handlers[reg_var];
handler(VIC->dev_ids[reg_var]);
}
vic_writel(VIC, VIC_REG_EOIR, 0); // clear the interrupt pending flag
return IRQ_HANDLED;
}
int wrmch_vic_request_irq(int irq, wrvic_irq_t handler, void *dev_id)
{
if (irq < 0 || irq >= WRMCH_VIC_MAX_IRQS)
return -EINVAL;
if (VIC->handlers[irq])
return -EADDRINUSE;
VIC->handlers[irq] = handler;
VIC->dev_ids[irq] = dev_id;
vic_writel(VIC, VIC_IVT_BASE + (irq << 2), irq); //(u32)handler);
wrmch_vic_enable_irq(irq);
return 0;
}
void wrmch_vic_free_irq(int irq, void *dev_id)
{
if (irq < 0 || irq >= WRMCH_VIC_MAX_IRQS)
return;
if (VIC->dev_ids[irq] != dev_id)
return;
wrmch_vic_disable_irq(irq);
vic_writel(VIC, VIC_IVT_BASE + (irq << 2), VIC_SPURIOUS_IRQ);
VIC->handlers[irq] = NULL;
VIC->dev_ids[irq] = NULL;
}
void wrmch_vic_enable_irq(int irq)
{
if (irq < 0 || irq >= WRMCH_VIC_MAX_IRQS)
return;
vic_writel(VIC, VIC_REG_IER, (1<<irq));
// printk("vic_enable_irq: irq %d imr %x\n", irq, vic_readl(VIC, VIC_REG_IMR));
}
void wrmch_vic_disable_irq(int irq)
{
if (irq < 0 || irq >= WRMCH_VIC_MAX_IRQS)
return;
vic_writel(VIC, VIC_REG_IDR, (1<<irq));
// printk("vic_disable_irq: irq %d imr %x\n", irq, vic_readl(VIC, VIC_REG_IMR));
}
static int __devinit wrmch_vic_init_module(void)
{
int err, i;
VIC = kzalloc(sizeof(struct wrmch_vic), GFP_KERNEL);
VIC->regs = ioremap(FPGA_BASE_VIC, 0x1000);
vic_writel(VIC, VIC_REG_CTL, 0); // output is active LO
vic_writel(VIC, VIC_REG_IDR, 0xffffffff); // disable all interrupts
err = request_irq(AT91SAM9263_ID_IRQ0, wrmch_vic_interrupt,
IRQF_TRIGGER_LOW | IRQF_SHARED, "whiterabbit_vic",
VIC);
if (unlikely(err)) {
printk(KERN_ERR PFX "request IRQ for WR VIC failed");
return err;
}
/* clear the vector table */
for (i = 0; i < WRMCH_VIC_MAX_IRQS; i++)
vic_writel(VIC, VIC_IVT_BASE + (i<<2), VIC_SPURIOUS_IRQ);
vic_writel(VIC, VIC_REG_CTL, VIC_CTL_ENABLE); // enable the VIC
printk(KERN_INFO PFX "module initialized");
return 0;
}
static void __devexit wrmch_vic_cleanup_module(void)
{
free_irq(AT91SAM9263_ID_IRQ0, VIC);
if (VIC) {
if (VIC->regs) {
iounmap(VIC->regs);
VIC->regs = NULL;
}
kfree(VIC);
VIC = NULL;
}
printk(KERN_INFO PFX "module cleanup");
}
EXPORT_SYMBOL_GPL(wrmch_vic_request_irq);
EXPORT_SYMBOL_GPL(wrmch_vic_free_irq);
EXPORT_SYMBOL_GPL(wrmch_vic_enable_irq);
EXPORT_SYMBOL_GPL(wrmch_vic_disable_irq);
module_init(wrmch_vic_init_module);
module_exit(wrmch_vic_cleanup_module);
MODULE_AUTHOR("Tomasz Wlostowski");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("White Rabbit MCH Vectored Interrupt Controller driver");
MODULE_VERSION(DRV_MODULE_VERSION