Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'ptp_qoriq'

Yangbo Lu says:

====================
External trigger stamp fifo support for ptp_qoriq

This patch-set is to add external trigger stamp fifo support by a new
binding "fsl,extts-fifo", and to add fiper pulse loopback support which
is very useful for validating trigger without external hardware.
Also fixed issues in interrupt enabling/handling.

"fsl,extts-fifo" is required to be added into 1588 timer dts node whose
hardware supports it. The work will be done for some QorIQ platforms dts in
the near future.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+210 -45
+2
Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
··· 17 17 - fsl,tmr-fiper1 Fixed interval period pulse generator. 18 18 - fsl,tmr-fiper2 Fixed interval period pulse generator. 19 19 - fsl,max-adj Maximum frequency adjustment in parts per billion. 20 + - fsl,extts-fifo The presence of this property indicates hardware 21 + support for the external trigger stamp FIFO. 20 22 21 23 These properties set the operational parameters for the PTP 22 24 clock. You must choose these carefully for the clock to work right.
+1
MAINTAINERS
··· 6087 6087 L: netdev@vger.kernel.org 6088 6088 S: Maintained 6089 6089 F: drivers/ptp/ptp_qoriq.c 6090 + F: drivers/ptp/ptp_qoriq_debugfs.c 6090 6091 F: include/linux/fsl/ptp_qoriq.h 6091 6092 F: Documentation/devicetree/bindings/ptp/ptp-qoriq.txt 6092 6093
+1
arch/arm/boot/dts/ls1021a.dtsi
··· 706 706 fsl,tmr-fiper1 = <999999995>; 707 707 fsl,tmr-fiper2 = <99990>; 708 708 fsl,max-adj = <499999999>; 709 + fsl,extts-fifo; 709 710 }; 710 711 711 712 enet0: ethernet@2d10000 {
+1 -1
drivers/ptp/Kconfig
··· 53 53 packets using the SO_TIMESTAMPING API. 54 54 55 55 To compile this driver as a module, choose M here: the module 56 - will be called ptp_qoriq. 56 + will be called ptp-qoriq. 57 57 58 58 config PTP_1588_CLOCK_IXP46X 59 59 tristate "Intel IXP46x as PTP clock"
+3 -1
drivers/ptp/Makefile
··· 9 9 obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o 10 10 obj-$(CONFIG_PTP_1588_CLOCK_PCH) += ptp_pch.o 11 11 obj-$(CONFIG_PTP_1588_CLOCK_KVM) += ptp_kvm.o 12 - obj-$(CONFIG_PTP_1588_CLOCK_QORIQ) += ptp_qoriq.o 12 + obj-$(CONFIG_PTP_1588_CLOCK_QORIQ) += ptp-qoriq.o 13 + ptp-qoriq-y += ptp_qoriq.o 14 + ptp-qoriq-$(CONFIG_DEBUG_FS) += ptp_qoriq_debugfs.o
+86 -43
drivers/ptp/ptp_qoriq.c
··· 88 88 qoriq_write(&regs->fiper_regs->tmr_fiper2, qoriq_ptp->tmr_fiper2); 89 89 } 90 90 91 + static int extts_clean_up(struct qoriq_ptp *qoriq_ptp, int index, 92 + bool update_event) 93 + { 94 + struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; 95 + struct ptp_clock_event event; 96 + void __iomem *reg_etts_l; 97 + void __iomem *reg_etts_h; 98 + u32 valid, stat, lo, hi; 99 + 100 + switch (index) { 101 + case 0: 102 + valid = ETS1_VLD; 103 + reg_etts_l = &regs->etts_regs->tmr_etts1_l; 104 + reg_etts_h = &regs->etts_regs->tmr_etts1_h; 105 + break; 106 + case 1: 107 + valid = ETS2_VLD; 108 + reg_etts_l = &regs->etts_regs->tmr_etts2_l; 109 + reg_etts_h = &regs->etts_regs->tmr_etts2_h; 110 + break; 111 + default: 112 + return -EINVAL; 113 + } 114 + 115 + event.type = PTP_CLOCK_EXTTS; 116 + event.index = index; 117 + 118 + do { 119 + lo = qoriq_read(reg_etts_l); 120 + hi = qoriq_read(reg_etts_h); 121 + 122 + if (update_event) { 123 + event.timestamp = ((u64) hi) << 32; 124 + event.timestamp |= lo; 125 + ptp_clock_event(qoriq_ptp->clock, &event); 126 + } 127 + 128 + stat = qoriq_read(&regs->ctrl_regs->tmr_stat); 129 + } while (qoriq_ptp->extts_fifo_support && (stat & valid)); 130 + 131 + return 0; 132 + } 133 + 91 134 /* 92 135 * Interrupt service routine 93 136 */ ··· 141 98 struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; 142 99 struct ptp_clock_event event; 143 100 u64 ns; 144 - u32 ack = 0, lo, hi, mask, val; 101 + u32 ack = 0, lo, hi, mask, val, irqs; 102 + 103 + spin_lock(&qoriq_ptp->lock); 145 104 146 105 val = qoriq_read(&regs->ctrl_regs->tmr_tevent); 106 + mask = qoriq_read(&regs->ctrl_regs->tmr_temask); 147 107 148 - if (val & ETS1) { 108 + spin_unlock(&qoriq_ptp->lock); 109 + 110 + irqs = val & mask; 111 + 112 + if (irqs & ETS1) { 149 113 ack |= ETS1; 150 - hi = qoriq_read(&regs->etts_regs->tmr_etts1_h); 151 - lo = qoriq_read(&regs->etts_regs->tmr_etts1_l); 152 - event.type = PTP_CLOCK_EXTTS; 153 - event.index = 0; 154 - event.timestamp = ((u64) hi) << 32; 155 - event.timestamp |= lo; 156 - ptp_clock_event(qoriq_ptp->clock, &event); 114 + extts_clean_up(qoriq_ptp, 0, true); 157 115 } 158 116 159 - if (val & ETS2) { 117 + if (irqs & ETS2) { 160 118 ack |= ETS2; 161 - hi = qoriq_read(&regs->etts_regs->tmr_etts2_h); 162 - lo = qoriq_read(&regs->etts_regs->tmr_etts2_l); 163 - event.type = PTP_CLOCK_EXTTS; 164 - event.index = 1; 165 - event.timestamp = ((u64) hi) << 32; 166 - event.timestamp |= lo; 167 - ptp_clock_event(qoriq_ptp->clock, &event); 119 + extts_clean_up(qoriq_ptp, 1, true); 168 120 } 169 121 170 - if (val & ALM2) { 122 + if (irqs & ALM2) { 171 123 ack |= ALM2; 172 124 if (qoriq_ptp->alarm_value) { 173 125 event.type = PTP_CLOCK_ALARM; ··· 174 136 ns = qoriq_ptp->alarm_value + qoriq_ptp->alarm_interval; 175 137 hi = ns >> 32; 176 138 lo = ns & 0xffffffff; 177 - spin_lock(&qoriq_ptp->lock); 178 139 qoriq_write(&regs->alarm_regs->tmr_alarm2_l, lo); 179 140 qoriq_write(&regs->alarm_regs->tmr_alarm2_h, hi); 180 - spin_unlock(&qoriq_ptp->lock); 181 141 qoriq_ptp->alarm_value = ns; 182 142 } else { 183 - qoriq_write(&regs->ctrl_regs->tmr_tevent, ALM2); 184 143 spin_lock(&qoriq_ptp->lock); 185 144 mask = qoriq_read(&regs->ctrl_regs->tmr_temask); 186 145 mask &= ~ALM2EN; ··· 188 153 } 189 154 } 190 155 191 - if (val & PP1) { 156 + if (irqs & PP1) { 192 157 ack |= PP1; 193 158 event.type = PTP_CLOCK_PPS; 194 159 ptp_clock_event(qoriq_ptp->clock, &event); ··· 295 260 struct qoriq_ptp *qoriq_ptp = container_of(ptp, struct qoriq_ptp, caps); 296 261 struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; 297 262 unsigned long flags; 298 - u32 bit, mask; 263 + u32 bit, mask = 0; 299 264 300 265 switch (rq->type) { 301 266 case PTP_CLK_REQ_EXTTS: ··· 309 274 default: 310 275 return -EINVAL; 311 276 } 312 - spin_lock_irqsave(&qoriq_ptp->lock, flags); 313 - mask = qoriq_read(&regs->ctrl_regs->tmr_temask); 314 - if (on) 315 - mask |= bit; 316 - else 317 - mask &= ~bit; 318 - qoriq_write(&regs->ctrl_regs->tmr_temask, mask); 319 - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); 320 - return 0; 321 277 322 - case PTP_CLK_REQ_PPS: 323 - spin_lock_irqsave(&qoriq_ptp->lock, flags); 324 - mask = qoriq_read(&regs->ctrl_regs->tmr_temask); 325 278 if (on) 326 - mask |= PP1EN; 327 - else 328 - mask &= ~PP1EN; 329 - qoriq_write(&regs->ctrl_regs->tmr_temask, mask); 330 - spin_unlock_irqrestore(&qoriq_ptp->lock, flags); 331 - return 0; 279 + extts_clean_up(qoriq_ptp, rq->extts.index, false); 332 280 333 - default: 334 281 break; 282 + case PTP_CLK_REQ_PPS: 283 + bit = PP1EN; 284 + break; 285 + default: 286 + return -EOPNOTSUPP; 335 287 } 336 288 337 - return -EOPNOTSUPP; 289 + spin_lock_irqsave(&qoriq_ptp->lock, flags); 290 + 291 + mask = qoriq_read(&regs->ctrl_regs->tmr_temask); 292 + if (on) { 293 + mask |= bit; 294 + qoriq_write(&regs->ctrl_regs->tmr_tevent, bit); 295 + } else { 296 + mask &= ~bit; 297 + } 298 + 299 + qoriq_write(&regs->ctrl_regs->tmr_temask, mask); 300 + 301 + spin_unlock_irqrestore(&qoriq_ptp->lock, flags); 302 + return 0; 338 303 } 339 304 340 305 static const struct ptp_clock_info ptp_qoriq_caps = { ··· 471 436 472 437 err = -EINVAL; 473 438 439 + qoriq_ptp->dev = &dev->dev; 474 440 qoriq_ptp->caps = ptp_qoriq_caps; 475 441 476 442 if (of_property_read_u32(node, "fsl,cksel", &qoriq_ptp->cksel)) 477 443 qoriq_ptp->cksel = DEFAULT_CKSEL; 444 + 445 + if (of_property_read_bool(node, "fsl,extts-fifo")) 446 + qoriq_ptp->extts_fifo_support = true; 447 + else 448 + qoriq_ptp->extts_fifo_support = false; 478 449 479 450 if (of_property_read_u32(node, 480 451 "fsl,tclk-period", &qoriq_ptp->tclk_period) || ··· 573 532 } 574 533 qoriq_ptp->phc_index = ptp_clock_index(qoriq_ptp->clock); 575 534 535 + ptp_qoriq_create_debugfs(qoriq_ptp); 576 536 platform_set_drvdata(dev, qoriq_ptp); 577 537 578 538 return 0; ··· 599 557 qoriq_write(&regs->ctrl_regs->tmr_temask, 0); 600 558 qoriq_write(&regs->ctrl_regs->tmr_ctrl, 0); 601 559 560 + ptp_qoriq_remove_debugfs(qoriq_ptp); 602 561 ptp_clock_unregister(qoriq_ptp->clock); 603 562 iounmap(qoriq_ptp->base); 604 563 release_resource(qoriq_ptp->rsrc);
+101
drivers/ptp/ptp_qoriq_debugfs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* Copyright 2019 NXP 3 + */ 4 + #include <linux/device.h> 5 + #include <linux/debugfs.h> 6 + #include <linux/fsl/ptp_qoriq.h> 7 + 8 + static int ptp_qoriq_fiper1_lpbk_get(void *data, u64 *val) 9 + { 10 + struct qoriq_ptp *qoriq_ptp = data; 11 + struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; 12 + u32 ctrl; 13 + 14 + ctrl = qoriq_read(&regs->ctrl_regs->tmr_ctrl); 15 + *val = ctrl & PP1L ? 1 : 0; 16 + 17 + return 0; 18 + } 19 + 20 + static int ptp_qoriq_fiper1_lpbk_set(void *data, u64 val) 21 + { 22 + struct qoriq_ptp *qoriq_ptp = data; 23 + struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; 24 + u32 ctrl; 25 + 26 + ctrl = qoriq_read(&regs->ctrl_regs->tmr_ctrl); 27 + if (val == 0) 28 + ctrl &= ~PP1L; 29 + else 30 + ctrl |= PP1L; 31 + 32 + qoriq_write(&regs->ctrl_regs->tmr_ctrl, ctrl); 33 + return 0; 34 + } 35 + 36 + DEFINE_SIMPLE_ATTRIBUTE(ptp_qoriq_fiper1_fops, ptp_qoriq_fiper1_lpbk_get, 37 + ptp_qoriq_fiper1_lpbk_set, "%llu\n"); 38 + 39 + static int ptp_qoriq_fiper2_lpbk_get(void *data, u64 *val) 40 + { 41 + struct qoriq_ptp *qoriq_ptp = data; 42 + struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; 43 + u32 ctrl; 44 + 45 + ctrl = qoriq_read(&regs->ctrl_regs->tmr_ctrl); 46 + *val = ctrl & PP2L ? 1 : 0; 47 + 48 + return 0; 49 + } 50 + 51 + static int ptp_qoriq_fiper2_lpbk_set(void *data, u64 val) 52 + { 53 + struct qoriq_ptp *qoriq_ptp = data; 54 + struct qoriq_ptp_registers *regs = &qoriq_ptp->regs; 55 + u32 ctrl; 56 + 57 + ctrl = qoriq_read(&regs->ctrl_regs->tmr_ctrl); 58 + if (val == 0) 59 + ctrl &= ~PP2L; 60 + else 61 + ctrl |= PP2L; 62 + 63 + qoriq_write(&regs->ctrl_regs->tmr_ctrl, ctrl); 64 + return 0; 65 + } 66 + 67 + DEFINE_SIMPLE_ATTRIBUTE(ptp_qoriq_fiper2_fops, ptp_qoriq_fiper2_lpbk_get, 68 + ptp_qoriq_fiper2_lpbk_set, "%llu\n"); 69 + 70 + void ptp_qoriq_create_debugfs(struct qoriq_ptp *qoriq_ptp) 71 + { 72 + struct dentry *root; 73 + 74 + root = debugfs_create_dir(dev_name(qoriq_ptp->dev), NULL); 75 + if (IS_ERR(root)) 76 + return; 77 + if (!root) 78 + goto err_root; 79 + 80 + qoriq_ptp->debugfs_root = root; 81 + 82 + if (!debugfs_create_file("fiper1-loopback", 0600, root, qoriq_ptp, 83 + &ptp_qoriq_fiper1_fops)) 84 + goto err_node; 85 + if (!debugfs_create_file("fiper2-loopback", 0600, root, qoriq_ptp, 86 + &ptp_qoriq_fiper2_fops)) 87 + goto err_node; 88 + return; 89 + 90 + err_node: 91 + debugfs_remove_recursive(root); 92 + qoriq_ptp->debugfs_root = NULL; 93 + err_root: 94 + dev_err(qoriq_ptp->dev, "failed to initialize debugfs\n"); 95 + } 96 + 97 + void ptp_qoriq_remove_debugfs(struct qoriq_ptp *qoriq_ptp) 98 + { 99 + debugfs_remove_recursive(qoriq_ptp->debugfs_root); 100 + qoriq_ptp->debugfs_root = NULL; 101 + }
+15
include/linux/fsl/ptp_qoriq.h
··· 120 120 /* Bit definitions for the TMR_STAT register */ 121 121 #define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */ 122 122 #define STAT_VEC_MASK (0x3f) 123 + #define ETS1_VLD (1<<24) 124 + #define ETS2_VLD (1<<25) 123 125 124 126 /* Bit definitions for the TMR_PRSC register */ 125 127 #define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */ ··· 143 141 struct ptp_clock *clock; 144 142 struct ptp_clock_info caps; 145 143 struct resource *rsrc; 144 + struct dentry *debugfs_root; 145 + struct device *dev; 146 + bool extts_fifo_support; 146 147 int irq; 147 148 int phc_index; 148 149 u64 alarm_interval; /* for periodic alarm */ ··· 170 165 { 171 166 iowrite32be(val, addr); 172 167 } 168 + 169 + #ifdef CONFIG_DEBUG_FS 170 + void ptp_qoriq_create_debugfs(struct qoriq_ptp *qoriq_ptp); 171 + void ptp_qoriq_remove_debugfs(struct qoriq_ptp *qoriq_ptp); 172 + #else 173 + static inline void ptp_qoriq_create_debugfs(struct qoriq_ptp *qoriq_ptp) 174 + { } 175 + static inline void ptp_qoriq_remove_debugfs(struct qoriq_ptp *qoriq_ptp) 176 + { } 177 + #endif 173 178 174 179 #endif