mvpp2_tai.c (13167B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Marvell PP2.2 TAI support 4 * 5 * Note: 6 * Do NOT use the event capture support. 7 * Do Not even set the MPP muxes to allow PTP_EVENT_REQ to be used. 8 * It will disrupt the operation of this driver, and there is nothing 9 * that this driver can do to prevent that. Even using PTP_EVENT_REQ 10 * as an output will be seen as a trigger input, which can't be masked. 11 * When ever a trigger input is seen, the action in the TCFCR0_TCF 12 * field will be performed - whether it is a set, increment, decrement 13 * read, or frequency update. 14 * 15 * Other notes (useful, not specified in the documentation): 16 * - PTP_PULSE_OUT (PTP_EVENT_REQ MPP) 17 * It looks like the hardware can't generate a pulse at nsec=0. (The 18 * output doesn't trigger if the nsec field is zero.) 19 * Note: when configured as an output via the register at 0xfX441120, 20 * the input is still very much alive, and will trigger the current TCF 21 * function. 22 * - PTP_CLK_OUT (PTP_TRIG_GEN MPP) 23 * This generates a "PPS" signal determined by the CCC registers. It 24 * seems this is not aligned to the TOD counter in any way (it may be 25 * initially, but if you specify a non-round second interval, it won't, 26 * and you can't easily get it back.) 27 * - PTP_PCLK_OUT 28 * This generates a 50% duty cycle clock based on the TOD counter, and 29 * seems it can be set to any period of 1ns resolution. It is probably 30 * limited by the TOD step size. Its period is defined by the PCLK_CCC 31 * registers. Again, its alignment to the second is questionable. 32 * 33 * Consequently, we support none of these. 34 */ 35#include <linux/io.h> 36#include <linux/ptp_clock_kernel.h> 37#include <linux/slab.h> 38 39#include "mvpp2.h" 40 41#define CR0_SW_NRESET BIT(0) 42 43#define TCFCR0_PHASE_UPDATE_ENABLE BIT(8) 44#define TCFCR0_TCF_MASK (7 << 2) 45#define TCFCR0_TCF_UPDATE (0 << 2) 46#define TCFCR0_TCF_FREQUPDATE (1 << 2) 47#define TCFCR0_TCF_INCREMENT (2 << 2) 48#define TCFCR0_TCF_DECREMENT (3 << 2) 49#define TCFCR0_TCF_CAPTURE (4 << 2) 50#define TCFCR0_TCF_NOP (7 << 2) 51#define TCFCR0_TCF_TRIGGER BIT(0) 52 53#define TCSR_CAPTURE_1_VALID BIT(1) 54#define TCSR_CAPTURE_0_VALID BIT(0) 55 56struct mvpp2_tai { 57 struct ptp_clock_info caps; 58 struct ptp_clock *ptp_clock; 59 void __iomem *base; 60 spinlock_t lock; 61 u64 period; // nanosecond period in 32.32 fixed point 62 /* This timestamp is updated every two seconds */ 63 struct timespec64 stamp; 64}; 65 66static void mvpp2_tai_modify(void __iomem *reg, u32 mask, u32 set) 67{ 68 u32 val; 69 70 val = readl_relaxed(reg) & ~mask; 71 val |= set & mask; 72 writel(val, reg); 73} 74 75static void mvpp2_tai_write(u32 val, void __iomem *reg) 76{ 77 writel_relaxed(val & 0xffff, reg); 78} 79 80static u32 mvpp2_tai_read(void __iomem *reg) 81{ 82 return readl_relaxed(reg) & 0xffff; 83} 84 85static struct mvpp2_tai *ptp_to_tai(struct ptp_clock_info *ptp) 86{ 87 return container_of(ptp, struct mvpp2_tai, caps); 88} 89 90static void mvpp22_tai_read_ts(struct timespec64 *ts, void __iomem *base) 91{ 92 ts->tv_sec = (u64)mvpp2_tai_read(base + 0) << 32 | 93 mvpp2_tai_read(base + 4) << 16 | 94 mvpp2_tai_read(base + 8); 95 96 ts->tv_nsec = mvpp2_tai_read(base + 12) << 16 | 97 mvpp2_tai_read(base + 16); 98 99 /* Read and discard fractional part */ 100 readl_relaxed(base + 20); 101 readl_relaxed(base + 24); 102} 103 104static void mvpp2_tai_write_tlv(const struct timespec64 *ts, u32 frac, 105 void __iomem *base) 106{ 107 mvpp2_tai_write(ts->tv_sec >> 32, base + MVPP22_TAI_TLV_SEC_HIGH); 108 mvpp2_tai_write(ts->tv_sec >> 16, base + MVPP22_TAI_TLV_SEC_MED); 109 mvpp2_tai_write(ts->tv_sec, base + MVPP22_TAI_TLV_SEC_LOW); 110 mvpp2_tai_write(ts->tv_nsec >> 16, base + MVPP22_TAI_TLV_NANO_HIGH); 111 mvpp2_tai_write(ts->tv_nsec, base + MVPP22_TAI_TLV_NANO_LOW); 112 mvpp2_tai_write(frac >> 16, base + MVPP22_TAI_TLV_FRAC_HIGH); 113 mvpp2_tai_write(frac, base + MVPP22_TAI_TLV_FRAC_LOW); 114} 115 116static void mvpp2_tai_op(u32 op, void __iomem *base) 117{ 118 /* Trigger the operation. Note that an external unmaskable 119 * event on PTP_EVENT_REQ will also trigger this action. 120 */ 121 mvpp2_tai_modify(base + MVPP22_TAI_TCFCR0, 122 TCFCR0_TCF_MASK | TCFCR0_TCF_TRIGGER, 123 op | TCFCR0_TCF_TRIGGER); 124 mvpp2_tai_modify(base + MVPP22_TAI_TCFCR0, TCFCR0_TCF_MASK, 125 TCFCR0_TCF_NOP); 126} 127 128/* The adjustment has a range of +0.5ns to -0.5ns in 2^32 steps, so has units 129 * of 2^-32 ns. 130 * 131 * units(s) = 1 / (2^32 * 10^9) 132 * fractional = abs_scaled_ppm / (2^16 * 10^6) 133 * 134 * What we want to achieve: 135 * freq_adjusted = freq_nominal * (1 + fractional) 136 * freq_delta = freq_adjusted - freq_nominal => positive = faster 137 * freq_delta = freq_nominal * (1 + fractional) - freq_nominal 138 * So: freq_delta = freq_nominal * fractional 139 * 140 * However, we are dealing with periods, so: 141 * period_adjusted = period_nominal / (1 + fractional) 142 * period_delta = period_nominal - period_adjusted => positive = faster 143 * period_delta = period_nominal * fractional / (1 + fractional) 144 * 145 * Hence: 146 * period_delta = period_nominal * abs_scaled_ppm / 147 * (2^16 * 10^6 + abs_scaled_ppm) 148 * 149 * To avoid overflow, we reduce both sides of the divide operation by a factor 150 * of 16. 151 */ 152static u64 mvpp22_calc_frac_ppm(struct mvpp2_tai *tai, long abs_scaled_ppm) 153{ 154 u64 val = tai->period * abs_scaled_ppm >> 4; 155 156 return div_u64(val, (1000000 << 12) + (abs_scaled_ppm >> 4)); 157} 158 159static s32 mvpp22_calc_max_adj(struct mvpp2_tai *tai) 160{ 161 return 1000000; 162} 163 164static int mvpp22_tai_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) 165{ 166 struct mvpp2_tai *tai = ptp_to_tai(ptp); 167 unsigned long flags; 168 void __iomem *base; 169 bool neg_adj; 170 s32 frac; 171 u64 val; 172 173 neg_adj = scaled_ppm < 0; 174 if (neg_adj) 175 scaled_ppm = -scaled_ppm; 176 177 val = mvpp22_calc_frac_ppm(tai, scaled_ppm); 178 179 /* Convert to a signed 32-bit adjustment */ 180 if (neg_adj) { 181 /* -S32_MIN warns, -val < S32_MIN fails, so go for the easy 182 * solution. 183 */ 184 if (val > 0x80000000) 185 return -ERANGE; 186 187 frac = -val; 188 } else { 189 if (val > S32_MAX) 190 return -ERANGE; 191 192 frac = val; 193 } 194 195 base = tai->base; 196 spin_lock_irqsave(&tai->lock, flags); 197 mvpp2_tai_write(frac >> 16, base + MVPP22_TAI_TLV_FRAC_HIGH); 198 mvpp2_tai_write(frac, base + MVPP22_TAI_TLV_FRAC_LOW); 199 mvpp2_tai_op(TCFCR0_TCF_FREQUPDATE, base); 200 spin_unlock_irqrestore(&tai->lock, flags); 201 202 return 0; 203} 204 205static int mvpp22_tai_adjtime(struct ptp_clock_info *ptp, s64 delta) 206{ 207 struct mvpp2_tai *tai = ptp_to_tai(ptp); 208 struct timespec64 ts; 209 unsigned long flags; 210 void __iomem *base; 211 u32 tcf; 212 213 /* We can't deal with S64_MIN */ 214 if (delta == S64_MIN) 215 return -ERANGE; 216 217 if (delta < 0) { 218 delta = -delta; 219 tcf = TCFCR0_TCF_DECREMENT; 220 } else { 221 tcf = TCFCR0_TCF_INCREMENT; 222 } 223 224 ts = ns_to_timespec64(delta); 225 226 base = tai->base; 227 spin_lock_irqsave(&tai->lock, flags); 228 mvpp2_tai_write_tlv(&ts, 0, base); 229 mvpp2_tai_op(tcf, base); 230 spin_unlock_irqrestore(&tai->lock, flags); 231 232 return 0; 233} 234 235static int mvpp22_tai_gettimex64(struct ptp_clock_info *ptp, 236 struct timespec64 *ts, 237 struct ptp_system_timestamp *sts) 238{ 239 struct mvpp2_tai *tai = ptp_to_tai(ptp); 240 unsigned long flags; 241 void __iomem *base; 242 u32 tcsr; 243 int ret; 244 245 base = tai->base; 246 spin_lock_irqsave(&tai->lock, flags); 247 /* XXX: the only way to read the PTP time is for the CPU to trigger 248 * an event. However, there is no way to distinguish between the CPU 249 * triggered event, and an external event on PTP_EVENT_REQ. So this 250 * is incompatible with external use of PTP_EVENT_REQ. 251 */ 252 ptp_read_system_prets(sts); 253 mvpp2_tai_modify(base + MVPP22_TAI_TCFCR0, 254 TCFCR0_TCF_MASK | TCFCR0_TCF_TRIGGER, 255 TCFCR0_TCF_CAPTURE | TCFCR0_TCF_TRIGGER); 256 ptp_read_system_postts(sts); 257 mvpp2_tai_modify(base + MVPP22_TAI_TCFCR0, TCFCR0_TCF_MASK, 258 TCFCR0_TCF_NOP); 259 260 tcsr = readl(base + MVPP22_TAI_TCSR); 261 if (tcsr & TCSR_CAPTURE_1_VALID) { 262 mvpp22_tai_read_ts(ts, base + MVPP22_TAI_TCV1_SEC_HIGH); 263 ret = 0; 264 } else if (tcsr & TCSR_CAPTURE_0_VALID) { 265 mvpp22_tai_read_ts(ts, base + MVPP22_TAI_TCV0_SEC_HIGH); 266 ret = 0; 267 } else { 268 /* We don't seem to have a reading... */ 269 ret = -EBUSY; 270 } 271 spin_unlock_irqrestore(&tai->lock, flags); 272 273 return ret; 274} 275 276static int mvpp22_tai_settime64(struct ptp_clock_info *ptp, 277 const struct timespec64 *ts) 278{ 279 struct mvpp2_tai *tai = ptp_to_tai(ptp); 280 unsigned long flags; 281 void __iomem *base; 282 283 base = tai->base; 284 spin_lock_irqsave(&tai->lock, flags); 285 mvpp2_tai_write_tlv(ts, 0, base); 286 287 /* Trigger an update to load the value from the TLV registers 288 * into the TOD counter. Note that an external unmaskable event on 289 * PTP_EVENT_REQ will also trigger this action. 290 */ 291 mvpp2_tai_modify(base + MVPP22_TAI_TCFCR0, 292 TCFCR0_PHASE_UPDATE_ENABLE | 293 TCFCR0_TCF_MASK | TCFCR0_TCF_TRIGGER, 294 TCFCR0_TCF_UPDATE | TCFCR0_TCF_TRIGGER); 295 mvpp2_tai_modify(base + MVPP22_TAI_TCFCR0, TCFCR0_TCF_MASK, 296 TCFCR0_TCF_NOP); 297 spin_unlock_irqrestore(&tai->lock, flags); 298 299 return 0; 300} 301 302static long mvpp22_tai_aux_work(struct ptp_clock_info *ptp) 303{ 304 struct mvpp2_tai *tai = ptp_to_tai(ptp); 305 306 mvpp22_tai_gettimex64(ptp, &tai->stamp, NULL); 307 308 return msecs_to_jiffies(2000); 309} 310 311static void mvpp22_tai_set_step(struct mvpp2_tai *tai) 312{ 313 void __iomem *base = tai->base; 314 u32 nano, frac; 315 316 nano = upper_32_bits(tai->period); 317 frac = lower_32_bits(tai->period); 318 319 /* As the fractional nanosecond is a signed offset, if the MSB (sign) 320 * bit is set, we have to increment the whole nanoseconds. 321 */ 322 if (frac >= 0x80000000) 323 nano += 1; 324 325 mvpp2_tai_write(nano, base + MVPP22_TAI_TOD_STEP_NANO_CR); 326 mvpp2_tai_write(frac >> 16, base + MVPP22_TAI_TOD_STEP_FRAC_HIGH); 327 mvpp2_tai_write(frac, base + MVPP22_TAI_TOD_STEP_FRAC_LOW); 328} 329 330static void mvpp22_tai_init(struct mvpp2_tai *tai) 331{ 332 void __iomem *base = tai->base; 333 334 mvpp22_tai_set_step(tai); 335 336 /* Release the TAI reset */ 337 mvpp2_tai_modify(base + MVPP22_TAI_CR0, CR0_SW_NRESET, CR0_SW_NRESET); 338} 339 340int mvpp22_tai_ptp_clock_index(struct mvpp2_tai *tai) 341{ 342 return ptp_clock_index(tai->ptp_clock); 343} 344 345void mvpp22_tai_tstamp(struct mvpp2_tai *tai, u32 tstamp, 346 struct skb_shared_hwtstamps *hwtstamp) 347{ 348 struct timespec64 ts; 349 int delta; 350 351 /* The tstamp consists of 2 bits of seconds and 30 bits of nanoseconds. 352 * We use our stored timestamp (tai->stamp) to form a full timestamp, 353 * and we must read the seconds exactly once. 354 */ 355 ts.tv_sec = READ_ONCE(tai->stamp.tv_sec); 356 ts.tv_nsec = tstamp & 0x3fffffff; 357 358 /* Calculate the delta in seconds between our stored timestamp and 359 * the value read from the queue. Allow timestamps one second in the 360 * past, otherwise consider them to be in the future. 361 */ 362 delta = ((tstamp >> 30) - (ts.tv_sec & 3)) & 3; 363 if (delta == 3) 364 delta -= 4; 365 ts.tv_sec += delta; 366 367 memset(hwtstamp, 0, sizeof(*hwtstamp)); 368 hwtstamp->hwtstamp = timespec64_to_ktime(ts); 369} 370 371void mvpp22_tai_start(struct mvpp2_tai *tai) 372{ 373 long delay; 374 375 delay = mvpp22_tai_aux_work(&tai->caps); 376 377 ptp_schedule_worker(tai->ptp_clock, delay); 378} 379 380void mvpp22_tai_stop(struct mvpp2_tai *tai) 381{ 382 ptp_cancel_worker_sync(tai->ptp_clock); 383} 384 385static void mvpp22_tai_remove(void *priv) 386{ 387 struct mvpp2_tai *tai = priv; 388 389 if (!IS_ERR(tai->ptp_clock)) 390 ptp_clock_unregister(tai->ptp_clock); 391} 392 393int mvpp22_tai_probe(struct device *dev, struct mvpp2 *priv) 394{ 395 struct mvpp2_tai *tai; 396 int ret; 397 398 tai = devm_kzalloc(dev, sizeof(*tai), GFP_KERNEL); 399 if (!tai) 400 return -ENOMEM; 401 402 spin_lock_init(&tai->lock); 403 404 tai->base = priv->iface_base; 405 406 /* The step size consists of three registers - a 16-bit nanosecond step 407 * size, and a 32-bit fractional nanosecond step size split over two 408 * registers. The fractional nanosecond step size has units of 2^-32ns. 409 * 410 * To calculate this, we calculate: 411 * (10^9 + freq / 2) / (freq * 2^-32) 412 * which gives us the nanosecond step to the nearest integer in 16.32 413 * fixed point format, and the fractional part of the step size with 414 * the MSB inverted. With rounding of the fractional nanosecond, and 415 * simplification, this becomes: 416 * (10^9 << 32 + freq << 31 + (freq + 1) >> 1) / freq 417 * 418 * So: 419 * div = (10^9 << 32 + freq << 31 + (freq + 1) >> 1) / freq 420 * nano = upper_32_bits(div); 421 * frac = lower_32_bits(div) ^ 0x80000000; 422 * Will give the values for the registers. 423 * 424 * This is all seems perfect, but alas it is not when considering the 425 * whole story. The system is clocked from 25MHz, which is multiplied 426 * by a PLL to 1GHz, and then divided by three, giving 333333333Hz 427 * (recurring). This gives exactly 3ns, but using 333333333Hz with 428 * the above gives an error of 13*2^-32ns. 429 * 430 * Consequently, we use the period rather than calculating from the 431 * frequency. 432 */ 433 tai->period = 3ULL << 32; 434 435 mvpp22_tai_init(tai); 436 437 tai->caps.owner = THIS_MODULE; 438 strscpy(tai->caps.name, "Marvell PP2.2", sizeof(tai->caps.name)); 439 tai->caps.max_adj = mvpp22_calc_max_adj(tai); 440 tai->caps.adjfine = mvpp22_tai_adjfine; 441 tai->caps.adjtime = mvpp22_tai_adjtime; 442 tai->caps.gettimex64 = mvpp22_tai_gettimex64; 443 tai->caps.settime64 = mvpp22_tai_settime64; 444 tai->caps.do_aux_work = mvpp22_tai_aux_work; 445 446 ret = devm_add_action(dev, mvpp22_tai_remove, tai); 447 if (ret) 448 return ret; 449 450 tai->ptp_clock = ptp_clock_register(&tai->caps, dev); 451 if (IS_ERR(tai->ptp_clock)) 452 return PTR_ERR(tai->ptp_clock); 453 454 priv->tai = tai; 455 456 return 0; 457}