1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2013-2016 Freescale Semiconductor Inc. 4 * Copyright 2016-2018 NXP 5 */ 6 7 #include <linux/module.h> 8 #include <linux/of.h> 9 #include <linux/of_address.h> 10 #include <linux/msi.h> 11 #include <linux/fsl/mc.h> 12 #include <linux/fsl/ptp_qoriq.h> 13 14 #include "dpaa2-ptp.h" 15 16 static int dpaa2_ptp_enable(struct ptp_clock_info *ptp, 17 struct ptp_clock_request *rq, int on) 18 { 19 struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps); 20 struct fsl_mc_device *mc_dev; 21 struct device *dev; 22 u32 mask = 0; 23 u32 bit; 24 int err; 25 26 dev = ptp_qoriq->dev; 27 mc_dev = to_fsl_mc_device(dev); 28 29 switch (rq->type) { 30 case PTP_CLK_REQ_PPS: 31 bit = DPRTC_EVENT_PPS; 32 break; 33 default: 34 return -EOPNOTSUPP; 35 } 36 37 err = dprtc_get_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle, 38 DPRTC_IRQ_INDEX, &mask); 39 if (err < 0) { 40 dev_err(dev, "dprtc_get_irq_mask(): %d\n", err); 41 return err; 42 } 43 44 if (on) 45 mask |= bit; 46 else 47 mask &= ~bit; 48 49 err = dprtc_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle, 50 DPRTC_IRQ_INDEX, mask); 51 if (err < 0) { 52 dev_err(dev, "dprtc_set_irq_mask(): %d\n", err); 53 return err; 54 } 55 56 return 0; 57 } 58 59 static const struct ptp_clock_info dpaa2_ptp_caps = { 60 .owner = THIS_MODULE, 61 .name = "DPAA2 PTP Clock", 62 .max_adj = 512000, 63 .n_alarm = 2, 64 .n_ext_ts = 2, 65 .n_per_out = 3, 66 .n_pins = 0, 67 .pps = 1, 68 .adjfine = ptp_qoriq_adjfine, 69 .adjtime = ptp_qoriq_adjtime, 70 .gettime64 = ptp_qoriq_gettime, 71 .settime64 = ptp_qoriq_settime, 72 .enable = dpaa2_ptp_enable, 73 }; 74 75 static irqreturn_t dpaa2_ptp_irq_handler_thread(int irq, void *priv) 76 { 77 struct ptp_qoriq *ptp_qoriq = priv; 78 struct ptp_clock_event event; 79 struct fsl_mc_device *mc_dev; 80 struct device *dev; 81 u32 status = 0; 82 int err; 83 84 dev = ptp_qoriq->dev; 85 mc_dev = to_fsl_mc_device(dev); 86 87 err = dprtc_get_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle, 88 DPRTC_IRQ_INDEX, &status); 89 if (unlikely(err)) { 90 dev_err(dev, "dprtc_get_irq_status err %d\n", err); 91 return IRQ_NONE; 92 } 93 94 if (status & DPRTC_EVENT_PPS) { 95 event.type = PTP_CLOCK_PPS; 96 ptp_clock_event(ptp_qoriq->clock, &event); 97 } 98 99 err = dprtc_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle, 100 DPRTC_IRQ_INDEX, status); 101 if (unlikely(err)) { 102 dev_err(dev, "dprtc_clear_irq_status err %d\n", err); 103 return IRQ_NONE; 104 } 105 106 return IRQ_HANDLED; 107 } 108 109 static int dpaa2_ptp_probe(struct fsl_mc_device *mc_dev) 110 { 111 struct device *dev = &mc_dev->dev; 112 struct fsl_mc_device_irq *irq; 113 struct ptp_qoriq *ptp_qoriq; 114 struct device_node *node; 115 void __iomem *base; 116 int err; 117 118 ptp_qoriq = devm_kzalloc(dev, sizeof(*ptp_qoriq), GFP_KERNEL); 119 if (!ptp_qoriq) 120 return -ENOMEM; 121 122 err = fsl_mc_portal_allocate(mc_dev, 0, &mc_dev->mc_io); 123 if (err) { 124 if (err == -ENXIO) 125 err = -EPROBE_DEFER; 126 else 127 dev_err(dev, "fsl_mc_portal_allocate err %d\n", err); 128 goto err_exit; 129 } 130 131 err = dprtc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, 132 &mc_dev->mc_handle); 133 if (err) { 134 dev_err(dev, "dprtc_open err %d\n", err); 135 goto err_free_mcp; 136 } 137 138 ptp_qoriq->dev = dev; 139 140 node = of_find_compatible_node(NULL, NULL, "fsl,dpaa2-ptp"); 141 if (!node) { 142 err = -ENODEV; 143 goto err_close; 144 } 145 146 dev->of_node = node; 147 148 base = of_iomap(node, 0); 149 if (!base) { 150 err = -ENOMEM; 151 goto err_close; 152 } 153 154 err = fsl_mc_allocate_irqs(mc_dev); 155 if (err) { 156 dev_err(dev, "MC irqs allocation failed\n"); 157 goto err_unmap; 158 } 159 160 irq = mc_dev->irqs[0]; 161 ptp_qoriq->irq = irq->msi_desc->irq; 162 163 err = devm_request_threaded_irq(dev, ptp_qoriq->irq, NULL, 164 dpaa2_ptp_irq_handler_thread, 165 IRQF_NO_SUSPEND | IRQF_ONESHOT, 166 dev_name(dev), ptp_qoriq); 167 if (err < 0) { 168 dev_err(dev, "devm_request_threaded_irq(): %d\n", err); 169 goto err_free_mc_irq; 170 } 171 172 err = dprtc_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle, 173 DPRTC_IRQ_INDEX, 1); 174 if (err < 0) { 175 dev_err(dev, "dprtc_set_irq_enable(): %d\n", err); 176 goto err_free_mc_irq; 177 } 178 179 err = ptp_qoriq_init(ptp_qoriq, base, &dpaa2_ptp_caps); 180 if (err) 181 goto err_free_mc_irq; 182 183 dpaa2_phc_index = ptp_qoriq->phc_index; 184 dev_set_drvdata(dev, ptp_qoriq); 185 186 return 0; 187 188 err_free_mc_irq: 189 fsl_mc_free_irqs(mc_dev); 190 err_unmap: 191 iounmap(base); 192 err_close: 193 dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); 194 err_free_mcp: 195 fsl_mc_portal_free(mc_dev->mc_io); 196 err_exit: 197 return err; 198 } 199 200 static int dpaa2_ptp_remove(struct fsl_mc_device *mc_dev) 201 { 202 struct device *dev = &mc_dev->dev; 203 struct ptp_qoriq *ptp_qoriq; 204 205 ptp_qoriq = dev_get_drvdata(dev); 206 207 dpaa2_phc_index = -1; 208 ptp_qoriq_free(ptp_qoriq); 209 210 fsl_mc_free_irqs(mc_dev); 211 dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); 212 fsl_mc_portal_free(mc_dev->mc_io); 213 214 return 0; 215 } 216 217 static const struct fsl_mc_device_id dpaa2_ptp_match_id_table[] = { 218 { 219 .vendor = FSL_MC_VENDOR_FREESCALE, 220 .obj_type = "dprtc", 221 }, 222 {} 223 }; 224 MODULE_DEVICE_TABLE(fslmc, dpaa2_ptp_match_id_table); 225 226 static struct fsl_mc_driver dpaa2_ptp_drv = { 227 .driver = { 228 .name = KBUILD_MODNAME, 229 .owner = THIS_MODULE, 230 }, 231 .probe = dpaa2_ptp_probe, 232 .remove = dpaa2_ptp_remove, 233 .match_id_table = dpaa2_ptp_match_id_table, 234 }; 235 236 module_fsl_mc_driver(dpaa2_ptp_drv); 237 238 MODULE_LICENSE("GPL v2"); 239 MODULE_DESCRIPTION("DPAA2 PTP Clock Driver"); 240