diff options
| author | Takahiro Shimizu <tshimizu818@gmail.com> | 2012-03-07 17:16:26 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-03-09 16:55:34 -0500 |
| commit | 863d08ece9bf11043541e8017cfbdd16b800fbe5 (patch) | |
| tree | 3974d8ffc9c4da70094f6cf6eb5989d7f934cc9b | |
| parent | 74dd1521d0b4f940cdd3ce7b9d988836bef589b8 (diff) | |
supports eg20t ptp clock
Supports EG20T ptp clock in the driver
Changes e-mail address.
Adds number.
Signed-off-by: Takahiro Shimizu <tshimizu818@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/ptp/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/ptp/Makefile | 1 | ||||
| -rw-r--r-- | drivers/ptp/ptp_pch.c | 730 |
3 files changed, 744 insertions, 0 deletions
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index 68d720102296..cd9bc3b129bc 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig | |||
| @@ -72,4 +72,17 @@ config DP83640_PHY | |||
| 72 | In order for this to work, your MAC driver must also | 72 | In order for this to work, your MAC driver must also |
| 73 | implement the skb_tx_timetamp() function. | 73 | implement the skb_tx_timetamp() function. |
| 74 | 74 | ||
| 75 | config PTP_1588_CLOCK_PCH | ||
| 76 | tristate "Intel PCH EG20T as PTP clock" | ||
| 77 | depends on PTP_1588_CLOCK | ||
| 78 | depends on PCH_GBE | ||
| 79 | help | ||
| 80 | This driver adds support for using the PCH EG20T as a PTP | ||
| 81 | clock. This clock is only useful if your PTP programs are | ||
| 82 | getting hardware time stamps on the PTP Ethernet packets | ||
| 83 | using the SO_TIMESTAMPING API. | ||
| 84 | |||
| 85 | To compile this driver as a module, choose M here: the module | ||
| 86 | will be called ptp_pch. | ||
| 87 | |||
| 75 | endmenu | 88 | endmenu |
diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile index f6933e83de72..8b58597298de 100644 --- a/drivers/ptp/Makefile +++ b/drivers/ptp/Makefile | |||
| @@ -5,3 +5,4 @@ | |||
| 5 | ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o | 5 | ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o |
| 6 | obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o | 6 | obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o |
| 7 | obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o | 7 | obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o |
| 8 | obj-$(CONFIG_PTP_1588_CLOCK_PCH) += ptp_pch.o | ||
diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c new file mode 100644 index 000000000000..0b38ee1b0f85 --- /dev/null +++ b/drivers/ptp/ptp_pch.c | |||
| @@ -0,0 +1,730 @@ | |||
| 1 | /* | ||
| 2 | * PTP 1588 clock using the EG20T PCH | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 OMICRON electronics GmbH | ||
| 5 | * Copyright (C) 2011-2012 LAPIS SEMICONDUCTOR Co., LTD. | ||
| 6 | * | ||
| 7 | * This code was derived from the IXP46X driver. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; version 2 of the License. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/device.h> | ||
| 24 | #include <linux/err.h> | ||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/io.h> | ||
| 28 | #include <linux/irq.h> | ||
| 29 | #include <linux/kernel.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/pci.h> | ||
| 32 | #include <linux/ptp_clock_kernel.h> | ||
| 33 | |||
| 34 | #define STATION_ADDR_LEN 20 | ||
| 35 | #define PCI_DEVICE_ID_PCH_1588 0x8819 | ||
| 36 | #define IO_MEM_BAR 1 | ||
| 37 | |||
| 38 | #define DEFAULT_ADDEND 0xA0000000 | ||
| 39 | #define TICKS_NS_SHIFT 5 | ||
| 40 | #define N_EXT_TS 2 | ||
| 41 | |||
| 42 | enum pch_status { | ||
| 43 | PCH_SUCCESS, | ||
| 44 | PCH_INVALIDPARAM, | ||
| 45 | PCH_NOTIMESTAMP, | ||
| 46 | PCH_INTERRUPTMODEINUSE, | ||
| 47 | PCH_FAILED, | ||
| 48 | PCH_UNSUPPORTED, | ||
| 49 | }; | ||
| 50 | /** | ||
| 51 | * struct pch_ts_regs - IEEE 1588 registers | ||
| 52 | */ | ||
| 53 | struct pch_ts_regs { | ||
| 54 | u32 control; | ||
| 55 | u32 event; | ||
| 56 | u32 addend; | ||
| 57 | u32 accum; | ||
| 58 | u32 test; | ||
| 59 | u32 ts_compare; | ||
| 60 | u32 rsystime_lo; | ||
| 61 | u32 rsystime_hi; | ||
| 62 | u32 systime_lo; | ||
| 63 | u32 systime_hi; | ||
| 64 | u32 trgt_lo; | ||
| 65 | u32 trgt_hi; | ||
| 66 | u32 asms_lo; | ||
| 67 | u32 asms_hi; | ||
| 68 | u32 amms_lo; | ||
| 69 | u32 amms_hi; | ||
| 70 | u32 ch_control; | ||
| 71 | u32 ch_event; | ||
| 72 | u32 tx_snap_lo; | ||
| 73 | u32 tx_snap_hi; | ||
| 74 | u32 rx_snap_lo; | ||
| 75 | u32 rx_snap_hi; | ||
| 76 | u32 src_uuid_lo; | ||
| 77 | u32 src_uuid_hi; | ||
| 78 | u32 can_status; | ||
| 79 | u32 can_snap_lo; | ||
| 80 | u32 can_snap_hi; | ||
| 81 | u32 ts_sel; | ||
| 82 | u32 ts_st[6]; | ||
| 83 | u32 reserve1[14]; | ||
| 84 | u32 stl_max_set_en; | ||
| 85 | u32 stl_max_set; | ||
| 86 | u32 reserve2[13]; | ||
| 87 | u32 srst; | ||
| 88 | }; | ||
| 89 | |||
| 90 | #define PCH_TSC_RESET (1 << 0) | ||
| 91 | #define PCH_TSC_TTM_MASK (1 << 1) | ||
| 92 | #define PCH_TSC_ASMS_MASK (1 << 2) | ||
| 93 | #define PCH_TSC_AMMS_MASK (1 << 3) | ||
| 94 | #define PCH_TSC_PPSM_MASK (1 << 4) | ||
| 95 | #define PCH_TSE_TTIPEND (1 << 1) | ||
| 96 | #define PCH_TSE_SNS (1 << 2) | ||
| 97 | #define PCH_TSE_SNM (1 << 3) | ||
| 98 | #define PCH_TSE_PPS (1 << 4) | ||
| 99 | #define PCH_CC_MM (1 << 0) | ||
| 100 | #define PCH_CC_TA (1 << 1) | ||
| 101 | |||
| 102 | #define PCH_CC_MODE_SHIFT 16 | ||
| 103 | #define PCH_CC_MODE_MASK 0x001F0000 | ||
| 104 | #define PCH_CC_VERSION (1 << 31) | ||
| 105 | #define PCH_CE_TXS (1 << 0) | ||
| 106 | #define PCH_CE_RXS (1 << 1) | ||
| 107 | #define PCH_CE_OVR (1 << 0) | ||
| 108 | #define PCH_CE_VAL (1 << 1) | ||
| 109 | #define PCH_ECS_ETH (1 << 0) | ||
| 110 | |||
| 111 | #define PCH_ECS_CAN (1 << 1) | ||
| 112 | #define PCH_STATION_BYTES 6 | ||
| 113 | |||
| 114 | #define PCH_IEEE1588_ETH (1 << 0) | ||
| 115 | #define PCH_IEEE1588_CAN (1 << 1) | ||
| 116 | /** | ||
| 117 | * struct pch_dev - Driver private data | ||
| 118 | */ | ||
| 119 | struct pch_dev { | ||
| 120 | struct pch_ts_regs *regs; | ||
| 121 | struct ptp_clock *ptp_clock; | ||
| 122 | struct ptp_clock_info caps; | ||
| 123 | int exts0_enabled; | ||
| 124 | int exts1_enabled; | ||
| 125 | |||
| 126 | u32 mem_base; | ||
| 127 | u32 mem_size; | ||
| 128 | u32 irq; | ||
| 129 | struct pci_dev *pdev; | ||
| 130 | spinlock_t register_lock; | ||
| 131 | }; | ||
| 132 | |||
| 133 | /** | ||
| 134 | * struct pch_params - 1588 module parameter | ||
| 135 | */ | ||
| 136 | struct pch_params { | ||
| 137 | u8 station[STATION_ADDR_LEN]; | ||
| 138 | }; | ||
| 139 | |||
| 140 | /* structure to hold the module parameters */ | ||
| 141 | static struct pch_params pch_param = { | ||
| 142 | "00:00:00:00:00:00" | ||
| 143 | }; | ||
| 144 | |||
| 145 | /* | ||
| 146 | * Register access functions | ||
| 147 | */ | ||
| 148 | static inline void pch_eth_enable_set(struct pch_dev *chip) | ||
| 149 | { | ||
| 150 | u32 val; | ||
| 151 | /* SET the eth_enable bit */ | ||
| 152 | val = ioread32(&chip->regs->ts_sel) | (PCH_ECS_ETH); | ||
| 153 | iowrite32(val, (&chip->regs->ts_sel)); | ||
| 154 | } | ||
| 155 | |||
| 156 | static u64 pch_systime_read(struct pch_ts_regs *regs) | ||
| 157 | { | ||
| 158 | u64 ns; | ||
| 159 | u32 lo, hi; | ||
| 160 | |||
| 161 | lo = ioread32(®s->systime_lo); | ||
| 162 | hi = ioread32(®s->systime_hi); | ||
| 163 | |||
| 164 | ns = ((u64) hi) << 32; | ||
| 165 | ns |= lo; | ||
| 166 | ns <<= TICKS_NS_SHIFT; | ||
| 167 | |||
| 168 | return ns; | ||
| 169 | } | ||
| 170 | |||
| 171 | static void pch_systime_write(struct pch_ts_regs *regs, u64 ns) | ||
| 172 | { | ||
| 173 | u32 hi, lo; | ||
| 174 | |||
