Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright 2013-2016 Freescale Semiconductor Inc.
0004  * Copyright 2016-2018 NXP
0005  * Copyright 2020 NXP
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/of.h>
0010 #include <linux/of_address.h>
0011 #include <linux/msi.h>
0012 #include <linux/fsl/mc.h>
0013 
0014 #include "dpaa2-ptp.h"
0015 
0016 static int dpaa2_ptp_enable(struct ptp_clock_info *ptp,
0017                 struct ptp_clock_request *rq, int on)
0018 {
0019     struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);
0020     struct fsl_mc_device *mc_dev;
0021     struct device *dev;
0022     u32 mask = 0;
0023     u32 bit;
0024     int err;
0025 
0026     dev = ptp_qoriq->dev;
0027     mc_dev = to_fsl_mc_device(dev);
0028 
0029     switch (rq->type) {
0030     case PTP_CLK_REQ_EXTTS:
0031         switch (rq->extts.index) {
0032         case 0:
0033             bit = DPRTC_EVENT_ETS1;
0034             break;
0035         case 1:
0036             bit = DPRTC_EVENT_ETS2;
0037             break;
0038         default:
0039             return -EINVAL;
0040         }
0041         if (on)
0042             extts_clean_up(ptp_qoriq, rq->extts.index, false);
0043         break;
0044     case PTP_CLK_REQ_PPS:
0045         bit = DPRTC_EVENT_PPS;
0046         break;
0047     default:
0048         return -EOPNOTSUPP;
0049     }
0050 
0051     err = dprtc_get_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
0052                  DPRTC_IRQ_INDEX, &mask);
0053     if (err < 0) {
0054         dev_err(dev, "dprtc_get_irq_mask(): %d\n", err);
0055         return err;
0056     }
0057 
0058     if (on)
0059         mask |= bit;
0060     else
0061         mask &= ~bit;
0062 
0063     err = dprtc_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
0064                  DPRTC_IRQ_INDEX, mask);
0065     if (err < 0) {
0066         dev_err(dev, "dprtc_set_irq_mask(): %d\n", err);
0067         return err;
0068     }
0069 
0070     return 0;
0071 }
0072 
0073 static const struct ptp_clock_info dpaa2_ptp_caps = {
0074     .owner      = THIS_MODULE,
0075     .name       = "DPAA2 PTP Clock",
0076     .max_adj    = 512000,
0077     .n_alarm    = 2,
0078     .n_ext_ts   = 2,
0079     .n_per_out  = 3,
0080     .n_pins     = 0,
0081     .pps        = 1,
0082     .adjfine    = ptp_qoriq_adjfine,
0083     .adjtime    = ptp_qoriq_adjtime,
0084     .gettime64  = ptp_qoriq_gettime,
0085     .settime64  = ptp_qoriq_settime,
0086     .enable     = dpaa2_ptp_enable,
0087 };
0088 
0089 static irqreturn_t dpaa2_ptp_irq_handler_thread(int irq, void *priv)
0090 {
0091     struct ptp_qoriq *ptp_qoriq = priv;
0092     struct ptp_clock_event event;
0093     struct fsl_mc_device *mc_dev;
0094     struct device *dev;
0095     u32 status = 0;
0096     int err;
0097 
0098     dev = ptp_qoriq->dev;
0099     mc_dev = to_fsl_mc_device(dev);
0100 
0101     err = dprtc_get_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
0102                    DPRTC_IRQ_INDEX, &status);
0103     if (unlikely(err)) {
0104         dev_err(dev, "dprtc_get_irq_status err %d\n", err);
0105         return IRQ_NONE;
0106     }
0107 
0108     if (status & DPRTC_EVENT_PPS) {
0109         event.type = PTP_CLOCK_PPS;
0110         ptp_clock_event(ptp_qoriq->clock, &event);
0111     }
0112 
0113     if (status & DPRTC_EVENT_ETS1)
0114         extts_clean_up(ptp_qoriq, 0, true);
0115 
0116     if (status & DPRTC_EVENT_ETS2)
0117         extts_clean_up(ptp_qoriq, 1, true);
0118 
0119     err = dprtc_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
0120                      DPRTC_IRQ_INDEX, status);
0121     if (unlikely(err)) {
0122         dev_err(dev, "dprtc_clear_irq_status err %d\n", err);
0123         return IRQ_NONE;
0124     }
0125 
0126     return IRQ_HANDLED;
0127 }
0128 
0129 static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev)
0130 {
0131     struct device *dev = &mc_dev->dev;
0132     struct ptp_qoriq *ptp_qoriq;
0133     struct device_node *node;
0134     void __iomem *base;
0135     int err;
0136 
0137     ptp_qoriq = devm_kzalloc(dev, sizeof(*ptp_qoriq), GFP_KERNEL);
0138     if (!ptp_qoriq)
0139         return -ENOMEM;
0140 
0141     err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io);
0142     if (err) {
0143         if (err == -ENXIO)
0144             err = -EPROBE_DEFER;
0145         else
0146             dev_err(dev, "fsl_mc_portal_allocate err %d\n", err);
0147         goto err_exit;
0148     }
0149 
0150     err = dprtc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
0151              &mc_dev->mc_handle);
0152     if (err) {
0153         dev_err(dev, "dprtc_open err %d\n", err);
0154         goto err_free_mcp;
0155     }
0156 
0157     ptp_qoriq->dev = dev;
0158 
0159     node = of_find_compatible_node(NULL, NULL, "fsl,dpaa2-ptp");
0160     if (!node) {
0161         err = -ENODEV;
0162         goto err_close;
0163     }
0164 
0165     dev->of_node = node;
0166 
0167     base = of_iomap(node, 0);
0168     if (!base) {
0169         err = -ENOMEM;
0170         goto err_put;
0171     }
0172 
0173     err = fsl_mc_allocate_irqs(mc_dev);
0174     if (err) {
0175         dev_err(dev, "MC irqs allocation failed\n");
0176         goto err_unmap;
0177     }
0178 
0179     ptp_qoriq->irq = mc_dev->irqs[0]->virq;
0180 
0181     err = request_threaded_irq(ptp_qoriq->irq, NULL,
0182                    dpaa2_ptp_irq_handler_thread,
0183                    IRQF_NO_SUSPEND | IRQF_ONESHOT,
0184                    dev_name(dev), ptp_qoriq);
0185     if (err < 0) {
0186         dev_err(dev, "devm_request_threaded_irq(): %d\n", err);
0187         goto err_free_mc_irq;
0188     }
0189 
0190     err = dprtc_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
0191                    DPRTC_IRQ_INDEX, 1);
0192     if (err < 0) {
0193         dev_err(dev, "dprtc_set_irq_enable(): %d\n", err);
0194         goto err_free_threaded_irq;
0195     }
0196 
0197     err = ptp_qoriq_init(ptp_qoriq, base, &dpaa2_ptp_caps);
0198     if (err)
0199         goto err_free_threaded_irq;
0200 
0201     dpaa2_phc_index = ptp_qoriq->phc_index;
0202     dpaa2_ptp = ptp_qoriq;
0203     dev_set_drvdata(dev, ptp_qoriq);
0204 
0205     return 0;
0206 
0207 err_free_threaded_irq:
0208     free_irq(ptp_qoriq->irq, ptp_qoriq);
0209 err_free_mc_irq:
0210     fsl_mc_free_irqs(mc_dev);
0211 err_unmap:
0212     iounmap(base);
0213 err_put:
0214     of_node_put(node);
0215 err_close:
0216     dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
0217 err_free_mcp:
0218     fsl_mc_portal_free(mc_dev->mc_io);
0219 err_exit:
0220     return err;
0221 }
0222 
0223 static int dpaa2_ptp_remove(struct fsl_mc_device *mc_dev)
0224 {
0225     struct device *dev = &mc_dev->dev;
0226     struct ptp_qoriq *ptp_qoriq;
0227 
0228     ptp_qoriq = dev_get_drvdata(dev);
0229 
0230     dpaa2_phc_index = -1;
0231     ptp_qoriq_free(ptp_qoriq);
0232 
0233     fsl_mc_free_irqs(mc_dev);
0234     dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
0235     fsl_mc_portal_free(mc_dev->mc_io);
0236 
0237     return 0;
0238 }
0239 
0240 static const struct fsl_mc_device_id dpaa2_ptp_match_id_table[] = {
0241     {
0242         .vendor = FSL_MC_VENDOR_FREESCALE,
0243         .obj_type = "dprtc",
0244     },
0245     {}
0246 };
0247 MODULE_DEVICE_TABLE(fslmc, dpaa2_ptp_match_id_table);
0248 
0249 static struct fsl_mc_driver dpaa2_ptp_drv = {
0250     .driver = {
0251         .name = KBUILD_MODNAME,
0252         .owner = THIS_MODULE,
0253     },
0254     .probe = dpaa2_ptp_probe,
0255     .remove = dpaa2_ptp_remove,
0256     .match_id_table = dpaa2_ptp_match_id_table,
0257 };
0258 
0259 module_fsl_mc_driver(dpaa2_ptp_drv);
0260 
0261 MODULE_LICENSE("GPL v2");
0262 MODULE_DESCRIPTION("DPAA2 PTP Clock Driver");