Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * PTP 1588 clock using the EG20T PCH
0004  *
0005  * Copyright (C) 2010 OMICRON electronics GmbH
0006  * Copyright (C) 2011-2012 LAPIS SEMICONDUCTOR Co., LTD.
0007  *
0008  * This code was derived from the IXP46X driver.
0009  */
0010 
0011 #include <linux/device.h>
0012 #include <linux/err.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/io.h>
0015 #include <linux/io-64-nonatomic-lo-hi.h>
0016 #include <linux/io-64-nonatomic-hi-lo.h>
0017 #include <linux/irq.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/pci.h>
0021 #include <linux/ptp_clock_kernel.h>
0022 #include <linux/ptp_pch.h>
0023 #include <linux/slab.h>
0024 
0025 #define STATION_ADDR_LEN    20
0026 #define PCI_DEVICE_ID_PCH_1588  0x8819
0027 #define IO_MEM_BAR 1
0028 
0029 #define DEFAULT_ADDEND 0xA0000000
0030 #define TICKS_NS_SHIFT  5
0031 #define N_EXT_TS    2
0032 
0033 enum pch_status {
0034     PCH_SUCCESS,
0035     PCH_INVALIDPARAM,
0036     PCH_NOTIMESTAMP,
0037     PCH_INTERRUPTMODEINUSE,
0038     PCH_FAILED,
0039     PCH_UNSUPPORTED,
0040 };
0041 
0042 /*
0043  * struct pch_ts_regs - IEEE 1588 registers
0044  */
0045 struct pch_ts_regs {
0046     u32 control;
0047     u32 event;
0048     u32 addend;
0049     u32 accum;
0050     u32 test;
0051     u32 ts_compare;
0052     u32 rsystime_lo;
0053     u32 rsystime_hi;
0054     u32 systime_lo;
0055     u32 systime_hi;
0056     u32 trgt_lo;
0057     u32 trgt_hi;
0058     u32 asms_lo;
0059     u32 asms_hi;
0060     u32 amms_lo;
0061     u32 amms_hi;
0062     u32 ch_control;
0063     u32 ch_event;
0064     u32 tx_snap_lo;
0065     u32 tx_snap_hi;
0066     u32 rx_snap_lo;
0067     u32 rx_snap_hi;
0068     u32 src_uuid_lo;
0069     u32 src_uuid_hi;
0070     u32 can_status;
0071     u32 can_snap_lo;
0072     u32 can_snap_hi;
0073     u32 ts_sel;
0074     u32 ts_st[6];
0075     u32 reserve1[14];
0076     u32 stl_max_set_en;
0077     u32 stl_max_set;
0078     u32 reserve2[13];
0079     u32 srst;
0080 };
0081 
0082 #define PCH_TSC_RESET       (1 << 0)
0083 #define PCH_TSC_TTM_MASK    (1 << 1)
0084 #define PCH_TSC_ASMS_MASK   (1 << 2)
0085 #define PCH_TSC_AMMS_MASK   (1 << 3)
0086 #define PCH_TSC_PPSM_MASK   (1 << 4)
0087 #define PCH_TSE_TTIPEND     (1 << 1)
0088 #define PCH_TSE_SNS     (1 << 2)
0089 #define PCH_TSE_SNM     (1 << 3)
0090 #define PCH_TSE_PPS     (1 << 4)
0091 #define PCH_CC_MM       (1 << 0)
0092 #define PCH_CC_TA       (1 << 1)
0093 
0094 #define PCH_CC_MODE_SHIFT   16
0095 #define PCH_CC_MODE_MASK    0x001F0000
0096 #define PCH_CC_VERSION      (1 << 31)
0097 #define PCH_CE_TXS      (1 << 0)
0098 #define PCH_CE_RXS      (1 << 1)
0099 #define PCH_CE_OVR      (1 << 0)
0100 #define PCH_CE_VAL      (1 << 1)
0101 #define PCH_ECS_ETH     (1 << 0)
0102 
0103 #define PCH_ECS_CAN     (1 << 1)
0104 
0105 #define PCH_IEEE1588_ETH    (1 << 0)
0106 #define PCH_IEEE1588_CAN    (1 << 1)
0107 
0108 /*
0109  * struct pch_dev - Driver private data
0110  */
0111 struct pch_dev {
0112     struct pch_ts_regs __iomem *regs;
0113     struct ptp_clock *ptp_clock;
0114     struct ptp_clock_info caps;
0115     int exts0_enabled;
0116     int exts1_enabled;
0117 
0118     u32 irq;
0119     struct pci_dev *pdev;
0120     spinlock_t register_lock;
0121 };
0122 
0123 /*
0124  * struct pch_params - 1588 module parameter
0125  */
0126 struct pch_params {
0127     u8 station[STATION_ADDR_LEN];
0128 };
0129 
0130 /* structure to hold the module parameters */
0131 static struct pch_params pch_param = {
0132     "00:00:00:00:00:00"
0133 };
0134 
0135 /*
0136  * Register access functions
0137  */
0138 static inline void pch_eth_enable_set(struct pch_dev *chip)
0139 {
0140     u32 val;
0141     /* SET the eth_enable bit */
0142     val = ioread32(&chip->regs->ts_sel) | (PCH_ECS_ETH);
0143     iowrite32(val, (&chip->regs->ts_sel));
0144 }
0145 
0146 static u64 pch_systime_read(struct pch_ts_regs __iomem *regs)
0147 {
0148     u64 ns;
0149 
0150     ns = ioread64_lo_hi(&regs->systime_lo);
0151 
0152     return ns << TICKS_NS_SHIFT;
0153 }
0154 
0155 static void pch_systime_write(struct pch_ts_regs __iomem *regs, u64 ns)
0156 {
0157     iowrite64_lo_hi(ns >> TICKS_NS_SHIFT, &regs->systime_lo);
0158 }
0159 
0160 static inline void pch_block_reset(struct pch_dev *chip)
0161 {
0162     u32 val;
0163     /* Reset Hardware Assist block */
0164     val = ioread32(&chip->regs->control) | PCH_TSC_RESET;
0165     iowrite32(val, (&chip->regs->control));
0166     val = val & ~PCH_TSC_RESET;
0167     iowrite32(val, (&chip->regs->control));
0168 }
0169 
0170 void pch_ch_control_write(struct pci_dev *pdev, u32 val)
0171 {
0172     struct pch_dev *chip = pci_get_drvdata(pdev);
0173 
0174     iowrite32(val, (&chip->regs->ch_control));
0175 }
0176 EXPORT_SYMBOL(pch_ch_control_write);
0177 
0178 u32 pch_ch_event_read(struct pci_dev *pdev)
0179 {
0180     struct pch_dev *chip = pci_get_drvdata(pdev);
0181     u32 val;
0182 
0183     val = ioread32(&chip->regs->ch_event);
0184 
0185     return val;
0186 }
0187 EXPORT_SYMBOL(pch_ch_event_read);
0188 
0189 void pch_ch_event_write(struct pci_dev *pdev, u32 val)
0190 {
0191     struct pch_dev *chip = pci_get_drvdata(pdev);
0192 
0193     iowrite32(val, (&chip->regs->ch_event));
0194 }
0195 EXPORT_SYMBOL(pch_ch_event_write);
0196 
0197 u32 pch_src_uuid_lo_read(struct pci_dev *pdev)
0198 {
0199     struct pch_dev *chip = pci_get_drvdata(pdev);
0200     u32 val;
0201 
0202     val = ioread32(&chip->regs->src_uuid_lo);
0203 
0204     return val;
0205 }
0206 EXPORT_SYMBOL(pch_src_uuid_lo_read);
0207 
0208 u32 pch_src_uuid_hi_read(struct pci_dev *pdev)
0209 {
0210     struct pch_dev *chip = pci_get_drvdata(pdev);
0211     u32 val;
0212 
0213     val = ioread32(&chip->regs->src_uuid_hi);
0214 
0215     return val;
0216 }
0217 EXPORT_SYMBOL(pch_src_uuid_hi_read);
0218 
0219 u64 pch_rx_snap_read(struct pci_dev *pdev)
0220 {
0221     struct pch_dev *chip = pci_get_drvdata(pdev);
0222     u64 ns;
0223 
0224     ns = ioread64_lo_hi(&chip->regs->rx_snap_lo);
0225 
0226     return ns << TICKS_NS_SHIFT;
0227 }
0228 EXPORT_SYMBOL(pch_rx_snap_read);
0229 
0230 u64 pch_tx_snap_read(struct pci_dev *pdev)
0231 {
0232     struct pch_dev *chip = pci_get_drvdata(pdev);
0233     u64 ns;
0234 
0235     ns = ioread64_lo_hi(&chip->regs->tx_snap_lo);
0236 
0237     return ns << TICKS_NS_SHIFT;
0238 }
0239 EXPORT_SYMBOL(pch_tx_snap_read);
0240 
0241 /* This function enables all 64 bits in system time registers [high & low].
0242 This is a work-around for non continuous value in the SystemTime Register*/
0243 static void pch_set_system_time_count(struct pch_dev *chip)
0244 {
0245     iowrite32(0x01, &chip->regs->stl_max_set_en);
0246     iowrite32(0xFFFFFFFF, &chip->regs->stl_max_set);
0247     iowrite32(0x00, &chip->regs->stl_max_set_en);
0248 }
0249 
0250 static void pch_reset(struct pch_dev *chip)
0251 {
0252     /* Reset Hardware Assist */
0253     pch_block_reset(chip);
0254 
0255     /* enable all 32 bits in system time registers */
0256     pch_set_system_time_count(chip);
0257 }
0258 
0259 /**
0260  * pch_set_station_address() - This API sets the station address used by
0261  *                  IEEE 1588 hardware when looking at PTP
0262  *                  traffic on the  ethernet interface
0263  * @addr:   dress which contain the column separated address to be used.
0264  * @pdev:   PCI device.
0265  */
0266 int pch_set_station_address(u8 *addr, struct pci_dev *pdev)
0267 {
0268     struct pch_dev *chip = pci_get_drvdata(pdev);
0269     bool valid;
0270     u64 mac;
0271 
0272     /* Verify the parameter */
0273     if ((chip->regs == NULL) || addr == (u8 *)NULL) {
0274         dev_err(&pdev->dev,
0275             "invalid params returning PCH_INVALIDPARAM\n");
0276         return PCH_INVALIDPARAM;
0277     }
0278 
0279     valid = mac_pton(addr, (u8 *)&mac);
0280     if (!valid) {
0281         dev_err(&pdev->dev, "invalid params returning PCH_INVALIDPARAM\n");
0282         return PCH_INVALIDPARAM;
0283     }
0284 
0285     dev_dbg(&pdev->dev, "invoking pch_station_set\n");
0286     iowrite64_lo_hi(mac, &chip->regs->ts_st);
0287     return 0;
0288 }
0289 EXPORT_SYMBOL(pch_set_station_address);
0290 
0291 /*
0292  * Interrupt service routine
0293  */
0294 static irqreturn_t isr(int irq, void *priv)
0295 {
0296     struct pch_dev *pch_dev = priv;
0297     struct pch_ts_regs __iomem *regs = pch_dev->regs;
0298     struct ptp_clock_event event;
0299     u32 ack = 0, val;
0300 
0301     val = ioread32(&regs->event);
0302 
0303     if (val & PCH_TSE_SNS) {
0304         ack |= PCH_TSE_SNS;
0305         if (pch_dev->exts0_enabled) {
0306             event.type = PTP_CLOCK_EXTTS;
0307             event.index = 0;
0308             event.timestamp = ioread64_hi_lo(&regs->asms_hi);
0309             event.timestamp <<= TICKS_NS_SHIFT;
0310             ptp_clock_event(pch_dev->ptp_clock, &event);
0311         }
0312     }
0313 
0314     if (val & PCH_TSE_SNM) {
0315         ack |= PCH_TSE_SNM;
0316         if (pch_dev->exts1_enabled) {
0317             event.type = PTP_CLOCK_EXTTS;
0318             event.index = 1;
0319             event.timestamp = ioread64_hi_lo(&regs->asms_hi);
0320             event.timestamp <<= TICKS_NS_SHIFT;
0321             ptp_clock_event(pch_dev->ptp_clock, &event);
0322         }
0323     }
0324 
0325     if (val & PCH_TSE_TTIPEND)
0326         ack |= PCH_TSE_TTIPEND; /* this bit seems to be always set */
0327 
0328     if (ack) {
0329         iowrite32(ack, &regs->event);
0330         return IRQ_HANDLED;
0331     } else
0332         return IRQ_NONE;
0333 }
0334 
0335 /*
0336  * PTP clock operations
0337  */
0338 
0339 static int ptp_pch_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
0340 {
0341     u64 adj;
0342     u32 diff, addend;
0343     int neg_adj = 0;
0344     struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps);
0345     struct pch_ts_regs __iomem *regs = pch_dev->regs;
0346 
0347     if (ppb < 0) {
0348         neg_adj = 1;
0349         ppb = -ppb;
0350     }
0351     addend = DEFAULT_ADDEND;
0352     adj = addend;
0353     adj *= ppb;
0354     diff = div_u64(adj, 1000000000ULL);
0355 
0356     addend = neg_adj ? addend - diff : addend + diff;
0357 
0358     iowrite32(addend, &regs->addend);
0359 
0360     return 0;
0361 }
0362 
0363 static int ptp_pch_adjtime(struct ptp_clock_info *ptp, s64 delta)
0364 {
0365     s64 now;
0366     unsigned long flags;
0367     struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps);
0368     struct pch_ts_regs __iomem *regs = pch_dev->regs;
0369 
0370     spin_lock_irqsave(&pch_dev->register_lock, flags);
0371     now = pch_systime_read(regs);
0372     now += delta;
0373     pch_systime_write(regs, now);
0374     spin_unlock_irqrestore(&pch_dev->register_lock, flags);
0375 
0376     return 0;
0377 }
0378 
0379 static int ptp_pch_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
0380 {
0381     u64 ns;
0382     unsigned long flags;
0383     struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps);
0384     struct pch_ts_regs __iomem *regs = pch_dev->regs;
0385 
0386     spin_lock_irqsave(&pch_dev->register_lock, flags);
0387     ns = pch_systime_read(regs);
0388     spin_unlock_irqrestore(&pch_dev->register_lock, flags);
0389 
0390     *ts = ns_to_timespec64(ns);
0391     return 0;
0392 }
0393 
0394 static int ptp_pch_settime(struct ptp_clock_info *ptp,
0395                const struct timespec64 *ts)
0396 {
0397     u64 ns;
0398     unsigned long flags;
0399     struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps);
0400     struct pch_ts_regs __iomem *regs = pch_dev->regs;
0401 
0402     ns = timespec64_to_ns(ts);
0403 
0404     spin_lock_irqsave(&pch_dev->register_lock, flags);
0405     pch_systime_write(regs, ns);
0406     spin_unlock_irqrestore(&pch_dev->register_lock, flags);
0407 
0408     return 0;
0409 }
0410 
0411 static int ptp_pch_enable(struct ptp_clock_info *ptp,
0412               struct ptp_clock_request *rq, int on)
0413 {
0414     struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps);
0415 
0416     switch (rq->type) {
0417     case PTP_CLK_REQ_EXTTS:
0418         switch (rq->extts.index) {
0419         case 0:
0420             pch_dev->exts0_enabled = on ? 1 : 0;
0421             break;
0422         case 1:
0423             pch_dev->exts1_enabled = on ? 1 : 0;
0424             break;
0425         default:
0426             return -EINVAL;
0427         }
0428         return 0;
0429     default:
0430         break;
0431     }
0432 
0433     return -EOPNOTSUPP;
0434 }
0435 
0436 static const struct ptp_clock_info ptp_pch_caps = {
0437     .owner      = THIS_MODULE,
0438     .name       = "PCH timer",
0439     .max_adj    = 50000000,
0440     .n_ext_ts   = N_EXT_TS,
0441     .n_pins     = 0,
0442     .pps        = 0,
0443     .adjfreq    = ptp_pch_adjfreq,
0444     .adjtime    = ptp_pch_adjtime,
0445     .gettime64  = ptp_pch_gettime,
0446     .settime64  = ptp_pch_settime,
0447     .enable     = ptp_pch_enable,
0448 };
0449 
0450 static void pch_remove(struct pci_dev *pdev)
0451 {
0452     struct pch_dev *chip = pci_get_drvdata(pdev);
0453 
0454     free_irq(pdev->irq, chip);
0455     ptp_clock_unregister(chip->ptp_clock);
0456 }
0457 
0458 static s32
0459 pch_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0460 {
0461     s32 ret;
0462     unsigned long flags;
0463     struct pch_dev *chip;
0464 
0465     chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
0466     if (chip == NULL)
0467         return -ENOMEM;
0468 
0469     /* enable the 1588 pci device */
0470     ret = pcim_enable_device(pdev);
0471     if (ret != 0) {
0472         dev_err(&pdev->dev, "could not enable the pci device\n");
0473         return ret;
0474     }
0475 
0476     ret = pcim_iomap_regions(pdev, BIT(IO_MEM_BAR), "1588_regs");
0477     if (ret) {
0478         dev_err(&pdev->dev, "could not locate IO memory address\n");
0479         return ret;
0480     }
0481 
0482     /* get the virtual address to the 1588 registers */
0483     chip->regs = pcim_iomap_table(pdev)[IO_MEM_BAR];
0484     chip->caps = ptp_pch_caps;
0485     chip->ptp_clock = ptp_clock_register(&chip->caps, &pdev->dev);
0486     if (IS_ERR(chip->ptp_clock))
0487         return PTR_ERR(chip->ptp_clock);
0488 
0489     spin_lock_init(&chip->register_lock);
0490 
0491     ret = request_irq(pdev->irq, &isr, IRQF_SHARED, KBUILD_MODNAME, chip);
0492     if (ret != 0) {
0493         dev_err(&pdev->dev, "failed to get irq %d\n", pdev->irq);
0494         goto err_req_irq;
0495     }
0496 
0497     /* indicate success */
0498     chip->irq = pdev->irq;
0499     chip->pdev = pdev;
0500     pci_set_drvdata(pdev, chip);
0501 
0502     spin_lock_irqsave(&chip->register_lock, flags);
0503     /* reset the ieee1588 h/w */
0504     pch_reset(chip);
0505 
0506     iowrite32(DEFAULT_ADDEND, &chip->regs->addend);
0507     iowrite64_lo_hi(1, &chip->regs->trgt_lo);
0508     iowrite32(PCH_TSE_TTIPEND, &chip->regs->event);
0509 
0510     pch_eth_enable_set(chip);
0511 
0512     if (strcmp(pch_param.station, "00:00:00:00:00:00") != 0) {
0513         if (pch_set_station_address(pch_param.station, pdev) != 0) {
0514             dev_err(&pdev->dev,
0515             "Invalid station address parameter\n"
0516             "Module loaded but station address not set correctly\n"
0517             );
0518         }
0519     }
0520     spin_unlock_irqrestore(&chip->register_lock, flags);
0521     return 0;
0522 
0523 err_req_irq:
0524     ptp_clock_unregister(chip->ptp_clock);
0525 
0526     dev_err(&pdev->dev, "probe failed(ret=0x%x)\n", ret);
0527 
0528     return ret;
0529 }
0530 
0531 static const struct pci_device_id pch_ieee1588_pcidev_id[] = {
0532     {
0533       .vendor = PCI_VENDOR_ID_INTEL,
0534       .device = PCI_DEVICE_ID_PCH_1588
0535      },
0536     {0}
0537 };
0538 MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id);
0539 
0540 static struct pci_driver pch_driver = {
0541     .name = KBUILD_MODNAME,
0542     .id_table = pch_ieee1588_pcidev_id,
0543     .probe = pch_probe,
0544     .remove = pch_remove,
0545 };
0546 module_pci_driver(pch_driver);
0547 
0548 module_param_string(station,
0549             pch_param.station, sizeof(pch_param.station), 0444);
0550 MODULE_PARM_DESC(station,
0551      "IEEE 1588 station address to use - colon separated hex values");
0552 
0553 MODULE_AUTHOR("LAPIS SEMICONDUCTOR, <tshimizu818@gmail.com>");
0554 MODULE_DESCRIPTION("PTP clock using the EG20T timer");
0555 MODULE_LICENSE("GPL");