Lines Matching +full:ixp46x +full:- +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.
8 * This code was derived from the IXP46X driver.
40 * struct pch_ts_regs - IEEE 1588 registers
106 * struct pch_dev - Driver private data
123 * struct pch_params - 1588 module parameter
141 val = ioread32(&chip->regs->ts_sel) | (PCH_ECS_ETH); in pch_eth_enable_set()
142 iowrite32(val, (&chip->regs->ts_sel)); in pch_eth_enable_set()
150 lo = ioread32(®s->systime_lo); in pch_systime_read()
151 hi = ioread32(®s->systime_hi); in pch_systime_read()
168 iowrite32(lo, ®s->systime_lo); in pch_systime_write()
169 iowrite32(hi, ®s->systime_hi); in pch_systime_write()
176 val = ioread32(&chip->regs->control) | PCH_TSC_RESET; in pch_block_reset()
177 iowrite32(val, (&chip->regs->control)); in pch_block_reset()
179 iowrite32(val, (&chip->regs->control)); in pch_block_reset()
187 val = ioread32(&chip->regs->ch_control); in pch_ch_control_read()
197 iowrite32(val, (&chip->regs->ch_control)); in pch_ch_control_write()
206 val = ioread32(&chip->regs->ch_event); in pch_ch_event_read()
216 iowrite32(val, (&chip->regs->ch_event)); in pch_ch_event_write()
225 val = ioread32(&chip->regs->src_uuid_lo); in pch_src_uuid_lo_read()
236 val = ioread32(&chip->regs->src_uuid_hi); in pch_src_uuid_hi_read()
248 lo = ioread32(&chip->regs->rx_snap_lo); in pch_rx_snap_read()
249 hi = ioread32(&chip->regs->rx_snap_hi); in pch_rx_snap_read()
265 lo = ioread32(&chip->regs->tx_snap_lo); in pch_tx_snap_read()
266 hi = ioread32(&chip->regs->tx_snap_hi); in pch_tx_snap_read()
277 This is a work-around for non continuous value in the SystemTime Register*/
280 iowrite32(0x01, &chip->regs->stl_max_set_en); in pch_set_system_time_count()
281 iowrite32(0xFFFFFFFF, &chip->regs->stl_max_set); in pch_set_system_time_count()
282 iowrite32(0x00, &chip->regs->stl_max_set_en); in pch_set_system_time_count()
295 * pch_set_station_address() - This API sets the station address used by
296 * IEEE 1588 hardware when looking at PTP
306 if ((chip->regs == NULL) || addr == (u8 *)NULL) { in pch_set_station_address()
307 dev_err(&pdev->dev, in pch_set_station_address()
318 dev_err(&pdev->dev, in pch_set_station_address()
325 dev_err(&pdev->dev, in pch_set_station_address()
332 dev_err(&pdev->dev, in pch_set_station_address()
339 dev_dbg(&pdev->dev, "invoking pch_station_set\n"); in pch_set_station_address()
340 iowrite32(val, &chip->regs->ts_st[i]); in pch_set_station_address()
352 struct pch_ts_regs __iomem *regs = pch_dev->regs; in isr()
356 val = ioread32(®s->event); in isr()
360 if (pch_dev->exts0_enabled) { in isr()
361 hi = ioread32(®s->asms_hi); in isr()
362 lo = ioread32(®s->asms_lo); in isr()
368 ptp_clock_event(pch_dev->ptp_clock, &event); in isr()
374 if (pch_dev->exts1_enabled) { in isr()
375 hi = ioread32(®s->amms_hi); in isr()
376 lo = ioread32(®s->amms_lo); in isr()
382 ptp_clock_event(pch_dev->ptp_clock, &event); in isr()
390 iowrite32(ack, ®s->event); in isr()
397 * PTP clock operations
400 static int ptp_pch_adjfreq(struct ptp_clock_info *ptp, s32 ppb) in ptp_pch_adjfreq() argument
405 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_adjfreq()
406 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_adjfreq()
410 ppb = -ppb; in ptp_pch_adjfreq()
417 addend = neg_adj ? addend - diff : addend + diff; in ptp_pch_adjfreq()
419 iowrite32(addend, ®s->addend); in ptp_pch_adjfreq()
424 static int ptp_pch_adjtime(struct ptp_clock_info *ptp, s64 delta) in ptp_pch_adjtime() argument
428 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_adjtime()
429 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_adjtime()
431 spin_lock_irqsave(&pch_dev->register_lock, flags); in ptp_pch_adjtime()
435 spin_unlock_irqrestore(&pch_dev->register_lock, flags); in ptp_pch_adjtime()
440 static int ptp_pch_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) in ptp_pch_gettime() argument
444 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_gettime()
445 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_gettime()
447 spin_lock_irqsave(&pch_dev->register_lock, flags); in ptp_pch_gettime()
449 spin_unlock_irqrestore(&pch_dev->register_lock, flags); in ptp_pch_gettime()
455 static int ptp_pch_settime(struct ptp_clock_info *ptp, in ptp_pch_settime() argument
460 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_settime()
461 struct pch_ts_regs __iomem *regs = pch_dev->regs; in ptp_pch_settime()
465 spin_lock_irqsave(&pch_dev->register_lock, flags); in ptp_pch_settime()
467 spin_unlock_irqrestore(&pch_dev->register_lock, flags); in ptp_pch_settime()
472 static int ptp_pch_enable(struct ptp_clock_info *ptp, in ptp_pch_enable() argument
475 struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); in ptp_pch_enable()
477 switch (rq->type) { in ptp_pch_enable()
479 switch (rq->extts.index) { in ptp_pch_enable()
481 pch_dev->exts0_enabled = on ? 1 : 0; in ptp_pch_enable()
484 pch_dev->exts1_enabled = on ? 1 : 0; in ptp_pch_enable()
487 return -EINVAL; in ptp_pch_enable()
494 return -EOPNOTSUPP; in ptp_pch_enable()
499 .name = "PCH timer",
518 ptp_clock_unregister(chip->ptp_clock); in pch_remove()
520 if (pdev->irq != 0) in pch_remove()
521 free_irq(pdev->irq, chip); in pch_remove()
524 if (chip->regs != NULL) { in pch_remove()
525 iounmap(chip->regs); in pch_remove()
526 chip->regs = NULL; in pch_remove()
529 if (chip->mem_base != 0) { in pch_remove()
530 release_mem_region(chip->mem_base, chip->mem_size); in pch_remove()
531 chip->mem_base = 0; in pch_remove()
535 dev_info(&pdev->dev, "complete\n"); in pch_remove()
547 return -ENOMEM; in pch_probe()
552 dev_err(&pdev->dev, "could not enable the pci device\n"); in pch_probe()
556 chip->mem_base = pci_resource_start(pdev, IO_MEM_BAR); in pch_probe()
557 if (!chip->mem_base) { in pch_probe()
558 dev_err(&pdev->dev, "could not locate IO memory address\n"); in pch_probe()
559 ret = -ENODEV; in pch_probe()
564 chip->mem_size = pci_resource_len(pdev, IO_MEM_BAR); in pch_probe()
567 if (!request_mem_region(chip->mem_base, chip->mem_size, "1588_regs")) { in pch_probe()
568 dev_err(&pdev->dev, in pch_probe()
570 ret = -EBUSY; in pch_probe()
575 chip->regs = ioremap(chip->mem_base, chip->mem_size); in pch_probe()
577 if (!chip->regs) { in pch_probe()
578 dev_err(&pdev->dev, "Could not get virtual address\n"); in pch_probe()
579 ret = -ENOMEM; in pch_probe()
583 chip->caps = ptp_pch_caps; in pch_probe()
584 chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev); in pch_probe()
585 if (IS_ERR(chip->ptp_clock)) { in pch_probe()
586 ret = PTR_ERR(chip->ptp_clock); in pch_probe()
590 spin_lock_init(&chip->register_lock); in pch_probe()
592 ret = request_irq(pdev->irq, &isr, IRQF_SHARED, KBUILD_MODNAME, chip); in pch_probe()
594 dev_err(&pdev->dev, "failed to get irq %d\n", pdev->irq); in pch_probe()
599 chip->irq = pdev->irq; in pch_probe()
600 chip->pdev = pdev; in pch_probe()
603 spin_lock_irqsave(&chip->register_lock, flags); in pch_probe()
607 iowrite32(DEFAULT_ADDEND, &chip->regs->addend); in pch_probe()
608 iowrite32(1, &chip->regs->trgt_lo); in pch_probe()
609 iowrite32(0, &chip->regs->trgt_hi); in pch_probe()
610 iowrite32(PCH_TSE_TTIPEND, &chip->regs->event); in pch_probe()
616 dev_err(&pdev->dev, in pch_probe()
622 spin_unlock_irqrestore(&chip->register_lock, flags); in pch_probe()
626 ptp_clock_unregister(chip->ptp_clock); in pch_probe()
628 iounmap(chip->regs); in pch_probe()
629 chip->regs = NULL; in pch_probe()
632 release_mem_region(chip->mem_base, chip->mem_size); in pch_probe()
635 chip->mem_base = 0; in pch_probe()
642 dev_err(&pdev->dev, "probe failed(ret=0x%x)\n", ret); in pch_probe()
687 "IEEE 1588 station address to use - colon separated hex values");
690 MODULE_DESCRIPTION("PTP clock using the EG20T timer");