Lines Matching +full:ptp +full:- +full:timer
1 // SPDX-License-Identifier: GPL-2.0-only
3 * PTP 1588 clock using the EG20T PCH
6 * Copyright (C) 2011-2012 LAPIS SEMICONDUCTOR Co., LTD.
15 #include <linux/io-64-nonatomic-lo-hi.h>
16 #include <linux/io-64-nonatomic-hi-lo.h>
43 * struct pch_ts_regs - IEEE 1588 registers
109 * struct pch_dev - Driver private data
124 * struct pch_params - 1588 module parameter
142 val = ioread32(&chip->regs->ts_sel) | (PCH_ECS_ETH); in pch_eth_enable_set()
143 iowrite32(val, (&chip->regs->ts_sel)); in pch_eth_enable_set()
150 ns = ioread64_lo_hi(®s->systime_lo); in pch_systime_read()
157 iowrite64_lo_hi(ns >> TICKS_NS_SHIFT, ®s->systime_lo); in pch_systime_write()
164 val = ioread32(&chip->regs->control) | PCH_TSC_RESET; in pch_block_reset()
165 iowrite32(val, (&chip->regs->control)); in pch_block_reset()
167 iowrite32(val, (&chip->regs->control)); in pch_block_reset()
174 iowrite32(val, (&chip->regs->ch_control)); in pch_ch_control_write()
183 val = ioread32(&chip->regs->ch_event); in pch_ch_event_read()
193 iowrite32(val, (&chip->regs->ch_event)); in pch_ch_event_write()
202 val = ioread32(&chip->regs->src_uuid_lo); in pch_src_uuid_lo_read()
213 val = ioread32(&chip->regs->src_uuid_hi); in pch_src_uuid_hi_read()
224 ns = ioread64_lo_hi(&chip->regs->rx_snap_lo); in pch_rx_snap_read()
235 ns = ioread64_lo_hi(&chip->regs->tx_snap_lo); in pch_tx_snap_read()
242 This is a work-around for non continuous value in the SystemTime Register*/
245 iowrite32(0x01, &chip->regs->stl_max_set_en); in pch_set_system_time_count()
246 iowrite32(0xFFFFFFFF, &chip->regs->stl_max_set); in pch_set_system_time_count()
247 iowrite32(0x00, &chip->regs->stl_max_set_en); in pch_set_system_time_count()
260 * pch_set_station_address() - This API sets the station address used by
261 * IEEE 1588 hardware when looking at PTP
273 if ((chip->regs == NULL) || addr == (u8 *)NULL) { in pch_set_station_address()
274 dev_err(&pdev->dev, in pch_set_station_address()
281 dev_err(&pdev->dev, "invalid params returning PCH_INVALIDPARAM\n"); in pch_set_station_address()
285 dev_dbg(&pdev->dev, "invoking pch_station_set\n"); in pch_set_station_address()
286 iowrite64_lo_hi(mac, &chip->regs->ts_st); in pch_set_station_address()
297 struct pch_ts_regs __iomem *regs = pch_dev->regs; in isr()
301 val = ioread32(®s->event); in isr()
305 if (pch_dev->exts0_enabled) { in isr()
308 event.timestamp = ioread64_hi_lo(®s->asms_hi); in isr()
310 ptp_clock_event(pch_dev->ptp_clock, &event); in isr()
316 if (pch_dev->exts1_enabled) { in isr()
319 event.timestamp = ioread64_hi_lo(®s->asms_hi); in isr()
321 ptp_clock_event(pch_dev->ptp_clock, &event); in isr()
329 iowrite32(ack, ®s->event); in isr()
336 * PTP clock operations
339 static int ptp_pch_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) in ptp_pch_adjfine() argument
342 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_adjfine()
343 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_adjfine()
347 iowrite32(addend, ®s->addend); in ptp_pch_adjfine()
352 static int ptp_pch_adjtime(struct ptp_clock_info *ptp, s64 delta) in ptp_pch_adjtime() argument
356 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_adjtime()
357 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_adjtime()
359 spin_lock_irqsave(&pch_dev->register_lock, flags); in ptp_pch_adjtime()
363 spin_unlock_irqrestore(&pch_dev->register_lock, flags); in ptp_pch_adjtime()
368 static int ptp_pch_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) in ptp_pch_gettime() argument
372 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_gettime()
373 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_gettime()
375 spin_lock_irqsave(&pch_dev->register_lock, flags); in ptp_pch_gettime()
377 spin_unlock_irqrestore(&pch_dev->register_lock, flags); in ptp_pch_gettime()
383 static int ptp_pch_settime(struct ptp_clock_info *ptp, in ptp_pch_settime() argument
388 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_settime()
389 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_settime()
393 spin_lock_irqsave(&pch_dev->register_lock, flags); in ptp_pch_settime()
395 spin_unlock_irqrestore(&pch_dev->register_lock, flags); in ptp_pch_settime()
400 static int ptp_pch_enable(struct ptp_clock_info *ptp, in ptp_pch_enable() argument
403 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_enable()
405 switch (rq->type) { in ptp_pch_enable()
407 switch (rq->extts.index) { in ptp_pch_enable()
409 pch_dev->exts0_enabled = on ? 1 : 0; in ptp_pch_enable()
412 pch_dev->exts1_enabled = on ? 1 : 0; in ptp_pch_enable()
415 return -EINVAL; in ptp_pch_enable()
422 return -EOPNOTSUPP; in ptp_pch_enable()
427 .name = "PCH timer",
443 free_irq(pdev->irq, chip); in pch_remove()
444 ptp_clock_unregister(chip->ptp_clock); in pch_remove()
454 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); in pch_probe()
456 return -ENOMEM; in pch_probe()
461 dev_err(&pdev->dev, "could not enable the pci device\n"); in pch_probe()
467 dev_err(&pdev->dev, "could not locate IO memory address\n"); in pch_probe()
472 chip->regs = pcim_iomap_table(pdev)[IO_MEM_BAR]; in pch_probe()
473 chip->caps = ptp_pch_caps; in pch_probe()
474 chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev); in pch_probe()
475 if (IS_ERR(chip->ptp_clock)) in pch_probe()
476 return PTR_ERR(chip->ptp_clock); in pch_probe()
478 spin_lock_init(&chip->register_lock); in pch_probe()
480 ret = request_irq(pdev->irq, &isr, IRQF_SHARED, KBUILD_MODNAME, chip); in pch_probe()
482 dev_err(&pdev->dev, "failed to get irq %d\n", pdev->irq); in pch_probe()
487 chip->irq = pdev->irq; in pch_probe()
488 chip->pdev = pdev; in pch_probe()
491 spin_lock_irqsave(&chip->register_lock, flags); in pch_probe()
495 iowrite32(DEFAULT_ADDEND, &chip->regs->addend); in pch_probe()
496 iowrite64_lo_hi(1, &chip->regs->trgt_lo); in pch_probe()
497 iowrite32(PCH_TSE_TTIPEND, &chip->regs->event); in pch_probe()
503 dev_err(&pdev->dev, in pch_probe()
509 spin_unlock_irqrestore(&chip->register_lock, flags); in pch_probe()
513 ptp_clock_unregister(chip->ptp_clock); in pch_probe()
515 dev_err(&pdev->dev, "probe failed(ret=0x%x)\n", ret); in pch_probe()
540 "IEEE 1588 station address to use - colon separated hex values");
543 MODULE_DESCRIPTION("PTP clock using the EG20T timer");