| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * Copyright (C) 2010 OMICRON electronics GmbH |
| 4 | * Copyright 2018 NXP |
| 5 | */ |
| 6 | #ifndef __PTP_QORIQ_H__ |
| 7 | #define __PTP_QORIQ_H__ |
| 8 | |
| 9 | #include <linux/io.h> |
| 10 | #include <linux/interrupt.h> |
| 11 | #include <linux/ptp_clock_kernel.h> |
| 12 | |
| 13 | /* |
| 14 | * qoriq ptp registers |
| 15 | */ |
| 16 | struct ctrl_regs { |
| 17 | u32 tmr_ctrl; /* Timer control register */ |
| 18 | u32 tmr_tevent; /* Timestamp event register */ |
| 19 | u32 tmr_temask; /* Timer event mask register */ |
| 20 | u32 tmr_pevent; /* Timestamp event register */ |
| 21 | u32 tmr_pemask; /* Timer event mask register */ |
| 22 | u32 tmr_stat; /* Timestamp status register */ |
| 23 | u32 tmr_cnt_h; /* Timer counter high register */ |
| 24 | u32 tmr_cnt_l; /* Timer counter low register */ |
| 25 | u32 tmr_add; /* Timer drift compensation addend register */ |
| 26 | u32 tmr_acc; /* Timer accumulator register */ |
| 27 | u32 tmr_prsc; /* Timer prescale */ |
| 28 | u8 res1[4]; |
| 29 | u32 tmroff_h; /* Timer offset high */ |
| 30 | u32 tmroff_l; /* Timer offset low */ |
| 31 | }; |
| 32 | |
| 33 | struct alarm_regs { |
| 34 | u32 tmr_alarm1_h; /* Timer alarm 1 high register */ |
| 35 | u32 tmr_alarm1_l; /* Timer alarm 1 high register */ |
| 36 | u32 tmr_alarm2_h; /* Timer alarm 2 high register */ |
| 37 | u32 tmr_alarm2_l; /* Timer alarm 2 high register */ |
| 38 | }; |
| 39 | |
| 40 | struct fiper_regs { |
| 41 | u32 tmr_fiper1; /* Timer fixed period interval */ |
| 42 | u32 tmr_fiper2; /* Timer fixed period interval */ |
| 43 | u32 tmr_fiper3; /* Timer fixed period interval */ |
| 44 | }; |
| 45 | |
| 46 | struct etts_regs { |
| 47 | u32 tmr_etts1_h; /* Timestamp of general purpose external trigger */ |
| 48 | u32 tmr_etts1_l; /* Timestamp of general purpose external trigger */ |
| 49 | u32 tmr_etts2_h; /* Timestamp of general purpose external trigger */ |
| 50 | u32 tmr_etts2_l; /* Timestamp of general purpose external trigger */ |
| 51 | }; |
| 52 | |
| 53 | struct ptp_qoriq_registers { |
| 54 | struct ctrl_regs __iomem *ctrl_regs; |
| 55 | struct alarm_regs __iomem *alarm_regs; |
| 56 | struct fiper_regs __iomem *fiper_regs; |
| 57 | struct etts_regs __iomem *etts_regs; |
| 58 | }; |
| 59 | |
| 60 | /* Offset definitions for the four register groups */ |
| 61 | #define ETSEC_CTRL_REGS_OFFSET 0x0 |
| 62 | #define ETSEC_ALARM_REGS_OFFSET 0x40 |
| 63 | #define ETSEC_FIPER_REGS_OFFSET 0x80 |
| 64 | #define ETSEC_ETTS_REGS_OFFSET 0xa0 |
| 65 | |
| 66 | #define CTRL_REGS_OFFSET 0x80 |
| 67 | #define ALARM_REGS_OFFSET 0xb8 |
| 68 | #define FIPER_REGS_OFFSET 0xd0 |
| 69 | #define ETTS_REGS_OFFSET 0xe0 |
| 70 | |
| 71 | |
| 72 | /* Bit definitions for the TMR_CTRL register */ |
| 73 | #define ALM1P (1<<31) /* Alarm1 output polarity */ |
| 74 | #define ALM2P (1<<30) /* Alarm2 output polarity */ |
| 75 | #define FIPERST (1<<28) /* FIPER start indication */ |
| 76 | #define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */ |
| 77 | #define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */ |
| 78 | #define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */ |
| 79 | #define TCLK_PERIOD_MASK (0x3ff) |
| 80 | #define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */ |
| 81 | #define FRD (1<<14) /* FIPER Realignment Disable */ |
| 82 | #define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */ |
| 83 | #define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */ |
| 84 | #define ETEP2 (1<<9) /* External trigger 2 edge polarity */ |
| 85 | #define ETEP1 (1<<8) /* External trigger 1 edge polarity */ |
| 86 | #define COPH (1<<7) /* Generated clock output phase. */ |
| 87 | #define CIPH (1<<6) /* External oscillator input clock phase */ |
| 88 | #define TMSR (1<<5) /* Timer soft reset. */ |
| 89 | #define BYP (1<<3) /* Bypass drift compensated clock */ |
| 90 | #define TE (1<<2) /* 1588 timer enable. */ |
| 91 | #define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */ |
| 92 | #define CKSEL_MASK (0x3) |
| 93 | |
| 94 | /* Bit definitions for the TMR_TEVENT register */ |
| 95 | #define ETS2 (1<<25) /* External trigger 2 timestamp sampled */ |
| 96 | #define ETS1 (1<<24) /* External trigger 1 timestamp sampled */ |
| 97 | #define ALM2 (1<<17) /* Current time = alarm time register 2 */ |
| 98 | #define ALM1 (1<<16) /* Current time = alarm time register 1 */ |
| 99 | #define PP1 (1<<7) /* periodic pulse generated on FIPER1 */ |
| 100 | #define PP2 (1<<6) /* periodic pulse generated on FIPER2 */ |
| 101 | #define PP3 (1<<5) /* periodic pulse generated on FIPER3 */ |
| 102 | |
| 103 | /* Bit definitions for the TMR_TEMASK register */ |
| 104 | #define ETS2EN (1<<25) /* External trigger 2 timestamp enable */ |
| 105 | #define ETS1EN (1<<24) /* External trigger 1 timestamp enable */ |
| 106 | #define ALM2EN (1<<17) /* Timer ALM2 event enable */ |
| 107 | #define ALM1EN (1<<16) /* Timer ALM1 event enable */ |
| 108 | #define PP1EN (1<<7) /* Periodic pulse event 1 enable */ |
| 109 | #define PP2EN (1<<6) /* Periodic pulse event 2 enable */ |
| 110 | |
| 111 | /* Bit definitions for the TMR_PEVENT register */ |
| 112 | #define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */ |
| 113 | #define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */ |
| 114 | #define RXP (1<<0) /* PTP frame has been received */ |
| 115 | |
| 116 | /* Bit definitions for the TMR_PEMASK register */ |
| 117 | #define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */ |
| 118 | #define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */ |
| 119 | #define RXPEN (1<<0) /* Receive PTP packet event enable */ |
| 120 | |
| 121 | /* Bit definitions for the TMR_STAT register */ |
| 122 | #define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */ |
| 123 | #define STAT_VEC_MASK (0x3f) |
| 124 | #define ETS1_VLD (1<<24) |
| 125 | #define ETS2_VLD (1<<25) |
| 126 | |
| 127 | /* Bit definitions for the TMR_PRSC register */ |
| 128 | #define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */ |
| 129 | #define PRSC_OCK_MASK (0xffff) |
| 130 | |
| 131 | |
| 132 | #define DRIVER "ptp_qoriq" |
| 133 | #define N_EXT_TS 2 |
| 134 | |
| 135 | #define DEFAULT_CKSEL 1 |
| 136 | #define DEFAULT_TMR_PRSC 2 |
| 137 | #define DEFAULT_FIPER1_PERIOD 1000000000 |
| 138 | #define DEFAULT_FIPER2_PERIOD 1000000000 |
| 139 | #define DEFAULT_FIPER3_PERIOD 1000000000 |
| 140 | |
| 141 | struct ptp_qoriq { |
| 142 | void __iomem *base; |
| 143 | struct ptp_qoriq_registers regs; |
| 144 | spinlock_t lock; /* protects regs */ |
| 145 | struct ptp_clock *clock; |
| 146 | struct ptp_clock_info caps; |
| 147 | struct resource *rsrc; |
| 148 | struct device *dev; |
| 149 | bool extts_fifo_support; |
| 150 | bool fiper3_support; |
| 151 | bool etsec; |
| 152 | int irq; |
| 153 | int phc_index; |
| 154 | u32 tclk_period; /* nanoseconds */ |
| 155 | u32 tmr_prsc; |
| 156 | u32 tmr_add; |
| 157 | u32 cksel; |
| 158 | u32 tmr_fiper1; |
| 159 | u32 tmr_fiper2; |
| 160 | u32 tmr_fiper3; |
| 161 | u32 (*read)(unsigned __iomem *addr); |
| 162 | void (*write)(unsigned __iomem *addr, u32 val); |
| 163 | }; |
| 164 | |
| 165 | static inline u32 qoriq_read_be(unsigned __iomem *addr) |
| 166 | { |
| 167 | return ioread32be(addr); |
| 168 | } |
| 169 | |
| 170 | static inline void qoriq_write_be(unsigned __iomem *addr, u32 val) |
| 171 | { |
| 172 | iowrite32be(val, addr); |
| 173 | } |
| 174 | |
| 175 | static inline u32 qoriq_read_le(unsigned __iomem *addr) |
| 176 | { |
| 177 | return ioread32(addr); |
| 178 | } |
| 179 | |
| 180 | static inline void qoriq_write_le(unsigned __iomem *addr, u32 val) |
| 181 | { |
| 182 | iowrite32(val, addr); |
| 183 | } |
| 184 | |
| 185 | irqreturn_t ptp_qoriq_isr(int irq, void *priv); |
| 186 | int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base, |
| 187 | const struct ptp_clock_info *caps); |
| 188 | void ptp_qoriq_free(struct ptp_qoriq *ptp_qoriq); |
| 189 | int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm); |
| 190 | int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta); |
| 191 | int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts); |
| 192 | int ptp_qoriq_settime(struct ptp_clock_info *ptp, |
| 193 | const struct timespec64 *ts); |
| 194 | int ptp_qoriq_enable(struct ptp_clock_info *ptp, |
| 195 | struct ptp_clock_request *rq, int on); |
| 196 | int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index, bool update_event); |
| 197 | |
| 198 | #endif |
| 199 | |