1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell PTP driver 3 * 4 * Copyright (C) 2020 Marvell. 5 * 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/device.h> 10 #include <linux/module.h> 11 #include <linux/pci.h> 12 13 #include "ptp.h" 14 #include "mbox.h" 15 #include "rvu.h" 16 17 #define DRV_NAME "Marvell PTP Driver" 18 19 #define PCI_DEVID_OCTEONTX2_PTP 0xA00C 20 #define PCI_SUBSYS_DEVID_OCTX2_98xx_PTP 0xB100 21 #define PCI_SUBSYS_DEVID_OCTX2_96XX_PTP 0xB200 22 #define PCI_SUBSYS_DEVID_OCTX2_95XX_PTP 0xB300 23 #define PCI_SUBSYS_DEVID_OCTX2_95XXN_PTP 0xB400 24 #define PCI_SUBSYS_DEVID_OCTX2_95MM_PTP 0xB500 25 #define PCI_SUBSYS_DEVID_OCTX2_95XXO_PTP 0xB600 26 #define PCI_DEVID_OCTEONTX2_RST 0xA085 27 #define PCI_DEVID_CN10K_PTP 0xA09E 28 #define PCI_SUBSYS_DEVID_CN10K_A_PTP 0xB900 29 #define PCI_SUBSYS_DEVID_CNF10K_A_PTP 0xBA00 30 #define PCI_SUBSYS_DEVID_CNF10K_B_PTP 0xBC00 31 32 #define PCI_PTP_BAR_NO 0 33 34 #define PTP_CLOCK_CFG 0xF00ULL 35 #define PTP_CLOCK_CFG_PTP_EN BIT_ULL(0) 36 #define PTP_CLOCK_CFG_EXT_CLK_EN BIT_ULL(1) 37 #define PTP_CLOCK_CFG_EXT_CLK_IN_MASK GENMASK_ULL(7, 2) 38 #define PTP_CLOCK_CFG_TSTMP_EDGE BIT_ULL(9) 39 #define PTP_CLOCK_CFG_TSTMP_EN BIT_ULL(8) 40 #define PTP_CLOCK_CFG_TSTMP_IN_MASK GENMASK_ULL(15, 10) 41 #define PTP_CLOCK_CFG_PPS_EN BIT_ULL(30) 42 #define PTP_CLOCK_CFG_PPS_INV BIT_ULL(31) 43 44 #define PTP_PPS_HI_INCR 0xF60ULL 45 #define PTP_PPS_LO_INCR 0xF68ULL 46 #define PTP_PPS_THRESH_HI 0xF58ULL 47 48 #define PTP_CLOCK_LO 0xF08ULL 49 #define PTP_CLOCK_HI 0xF10ULL 50 #define PTP_CLOCK_COMP 0xF18ULL 51 #define PTP_TIMESTAMP 0xF20ULL 52 #define PTP_CLOCK_SEC 0xFD0ULL 53 54 #define CYCLE_MULT 1000 55 56 static struct ptp *first_ptp_block; 57 static const struct pci_device_id ptp_id_table[]; 58 59 static bool cn10k_ptp_errata(struct ptp *ptp) 60 { 61 if (ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_A_PTP || 62 ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_A_PTP) 63 return true; 64 return false; 65 } 66 67 static bool is_ptp_tsfmt_sec_nsec(struct ptp *ptp) 68 { 69 if (ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CN10K_A_PTP || 70 ptp->pdev->subsystem_device == PCI_SUBSYS_DEVID_CNF10K_A_PTP) 71 return true; 72 return false; 73 } 74 75 static u64 read_ptp_tstmp_sec_nsec(struct ptp *ptp) 76 { 77 u64 sec, sec1, nsec; 78 unsigned long flags; 79 80 spin_lock_irqsave(&ptp->ptp_lock, flags); 81 sec = readq(ptp->reg_base + PTP_CLOCK_SEC) & 0xFFFFFFFFUL; 82 nsec = readq(ptp->reg_base + PTP_CLOCK_HI); 83 sec1 = readq(ptp->reg_base + PTP_CLOCK_SEC) & 0xFFFFFFFFUL; 84 /* check nsec rollover */ 85 if (sec1 > sec) { 86 nsec = readq(ptp->reg_base + PTP_CLOCK_HI); 87 sec = sec1; 88 } 89 spin_unlock_irqrestore(&ptp->ptp_lock, flags); 90 91 return sec * NSEC_PER_SEC + nsec; 92 } 93 94 static u64 read_ptp_tstmp_nsec(struct ptp *ptp) 95 { 96 return readq(ptp->reg_base + PTP_CLOCK_HI); 97 } 98 99 static u64 ptp_calc_adjusted_comp(u64 ptp_clock_freq) 100 { 101 u64 comp, adj = 0, cycles_per_sec, ns_drift = 0; 102 u32 ptp_clock_nsec, cycle_time; 103 int cycle; 104 105 /* Errata: 106 * Issue #1: At the time of 1 sec rollover of the nano-second counter, 107 * the nano-second counter is set to 0. However, it should be set to 108 * (existing counter_value - 10^9). 109 * 110 * Issue #2: The nano-second counter rolls over at 0x3B9A_C9FF. 111 * It should roll over at 0x3B9A_CA00. 112 */ 113 114 /* calculate ptp_clock_comp value */ 115 comp = ((u64)1000000000ULL << 32) / ptp_clock_freq; 116 /* use CYCLE_MULT to avoid accuracy loss due to integer arithmetic */ 117 cycle_time = NSEC_PER_SEC * CYCLE_MULT / ptp_clock_freq; 118 /* cycles per sec */ 119 cycles_per_sec = ptp_clock_freq; 120 121 /* check whether ptp nanosecond counter rolls over early */ 122 cycle = cycles_per_sec - 1; 123 ptp_clock_nsec = (cycle * comp) >> 32; 124 while (ptp_clock_nsec < NSEC_PER_SEC) { 125 if (ptp_clock_nsec == 0x3B9AC9FF) 126 goto calc_adj_comp; 127 cycle++; 128 ptp_clock_nsec = (cycle * comp) >> 32; 129 } 130 /* compute nanoseconds lost per second when nsec counter rolls over */ 131 ns_drift = ptp_clock_nsec - NSEC_PER_SEC; 132 /* calculate ptp_clock_comp adjustment */ 133 if (ns_drift > 0) { 134 adj = comp * ns_drift; 135 adj = adj / 1000000000ULL; 136 } 137 /* speed up the ptp clock to account for nanoseconds lost */ 138 comp += adj; 139 return comp; 140 141 calc_adj_comp: 142 /* slow down the ptp clock to not rollover early */ 143 adj = comp * cycle_time; 144 adj = adj / 1000000000ULL; 145 adj = adj / CYCLE_MULT; 146 comp -= adj; 147 148 return comp; 149 } 150 151 struct ptp *ptp_get(void) 152 { 153 struct ptp *ptp = first_ptp_block; 154 155 /* Check PTP block is present in hardware */ 156 if (!pci_dev_present(ptp_id_table)) 157 return ERR_PTR(-ENODEV); 158 /* Check driver is bound to PTP block */ 159 if (!ptp) 160 ptp = ERR_PTR(-EPROBE_DEFER); 161 else 162 pci_dev_get(ptp->pdev); 163 164 return ptp; 165 } 166 167 void ptp_put(struct ptp *ptp) 168 { 169 if (!ptp) 170 return; 171 172 pci_dev_put(ptp->pdev); 173 } 174 175 static int ptp_adjfine(struct ptp *ptp, long scaled_ppm) 176 { 177 bool neg_adj = false; 178 u32 freq, freq_adj; 179 u64 comp, adj; 180 s64 ppb; 181 182 if (scaled_ppm < 0) { 183 neg_adj = true; 184 scaled_ppm = -scaled_ppm; 185 } 186 187 /* The hardware adds the clock compensation value to the PTP clock 188 * on every coprocessor clock cycle. Typical convention is that it 189 * represent number of nanosecond betwen each cycle. In this 190 * convention compensation value is in 64 bit fixed-point 191 * representation where upper 32 bits are number of nanoseconds 192 * and lower is fractions of nanosecond. 193 * The scaled_ppm represent the ratio in "parts per million" by which 194 * the compensation value should be corrected. 195 * To calculate new compenstation value we use 64bit fixed point 196 * arithmetic on following formula 197 * comp = tbase + tbase * scaled_ppm / (1M * 2^16) 198 * where tbase is the basic compensation value calculated 199 * initialy in the probe function. 200 */ 201 /* convert scaled_ppm to ppb */ 202 ppb = 1 + scaled_ppm; 203 ppb *= 125; 204 ppb >>= 13; 205 206 if (cn10k_ptp_errata(ptp)) { 207 /* calculate the new frequency based on ppb */ 208 freq_adj = (ptp->clock_rate * ppb) / 1000000000ULL; 209 freq = neg_adj ? ptp->clock_rate + freq_adj : ptp->clock_rate - freq_adj; 210 comp = ptp_calc_adjusted_comp(freq); 211 } else { 212 comp = ((u64)1000000000ull << 32) / ptp->clock_rate; 213 adj = comp * ppb; 214 adj = div_u64(adj, 1000000000ull); 215 comp = neg_adj ? comp - adj : comp + adj; 216 } 217 writeq(comp, ptp->reg_base + PTP_CLOCK_COMP); 218 219 return 0; 220 } 221 222 static int ptp_get_clock(struct ptp *ptp, u64 *clk) 223 { 224 /* Return the current PTP clock */ 225 *clk = ptp->read_ptp_tstmp(ptp); 226 227 return 0; 228 } 229 230 void ptp_start(struct ptp *ptp, u64 sclk, u32 ext_clk_freq, u32 extts) 231 { 232 struct pci_dev *pdev; 233 u64 clock_comp; 234 u64 clock_cfg; 235 236 if (!ptp) 237 return; 238 239 pdev = ptp->pdev; 240 241 if (!sclk) { 242 dev_err(&pdev->dev, "PTP input clock cannot be zero\n"); 243 return; 244 } 245 246 /* sclk is in MHz */ 247 ptp->clock_rate = sclk * 1000000; 248 249 /* Enable PTP clock */ 250 clock_cfg = readq(ptp->reg_base + PTP_CLOCK_CFG); 251 252 if (ext_clk_freq) { 253 ptp->clock_rate = ext_clk_freq; 254 /* Set GPIO as PTP clock source */ 255 clock_cfg &= ~PTP_CLOCK_CFG_EXT_CLK_IN_MASK; 256 clock_cfg |= PTP_CLOCK_CFG_EXT_CLK_EN; 257 } 258 259 if (extts) { 260 clock_cfg |= PTP_CLOCK_CFG_TSTMP_EDGE; 261 /* Set GPIO as timestamping source */ 262 clock_cfg &= ~PTP_CLOCK_CFG_TSTMP_IN_MASK; 263 clock_cfg |= PTP_CLOCK_CFG_TSTMP_EN; 264 } 265 266 clock_cfg |= PTP_CLOCK_CFG_PTP_EN; 267 clock_cfg |= PTP_CLOCK_CFG_PPS_EN | PTP_CLOCK_CFG_PPS_INV; 268 writeq(clock_cfg, ptp->reg_base + PTP_CLOCK_CFG); 269 270 /* Set 50% duty cycle for 1Hz output */ 271 writeq(0x1dcd650000000000, ptp->reg_base + PTP_PPS_HI_INCR); 272 writeq(0x1dcd650000000000, ptp->reg_base + PTP_PPS_LO_INCR); 273 274 if (cn10k_ptp_errata(ptp)) 275 clock_comp = ptp_calc_adjusted_comp(ptp->clock_rate); 276 else 277 clock_comp = ((u64)1000000000ull << 32) / ptp->clock_rate; 278 279 /* Initial compensation value to start the nanosecs counter */ 280 writeq(clock_comp, ptp->reg_base + PTP_CLOCK_COMP); 281 } 282 283 static int ptp_get_tstmp(struct ptp *ptp, u64 *clk) 284 { 285 *clk = readq(ptp->reg_base + PTP_TIMESTAMP); 286 287 return 0; 288 } 289 290 static int ptp_set_thresh(struct ptp *ptp, u64 thresh) 291 { 292 writeq(thresh, ptp->reg_base + PTP_PPS_THRESH_HI); 293 294 return 0; 295 } 296 297 static int ptp_probe(struct pci_dev *pdev, 298 const struct pci_device_id *ent) 299 { 300 struct device *dev = &pdev->dev; 301 struct ptp *ptp; 302 int err; 303 304 ptp = devm_kzalloc(dev, sizeof(*ptp), GFP_KERNEL); 305 if (!ptp) { 306 err = -ENOMEM; 307 goto error; 308 } 309 310 ptp->pdev = pdev; 311 312 err = pcim_enable_device(pdev); 313 if (err) 314 goto error_free; 315 316 err = pcim_iomap_regions(pdev, 1 << PCI_PTP_BAR_NO, pci_name(pdev)); 317 if (err) 318 goto error_free; 319 320 ptp->reg_base = pcim_iomap_table(pdev)[PCI_PTP_BAR_NO]; 321 322 pci_set_drvdata(pdev, ptp); 323 if (!first_ptp_block) 324 first_ptp_block = ptp; 325 326 spin_lock_init(&ptp->ptp_lock); 327 if (is_ptp_tsfmt_sec_nsec(ptp)) 328 ptp->read_ptp_tstmp = &read_ptp_tstmp_sec_nsec; 329 else 330 ptp->read_ptp_tstmp = &read_ptp_tstmp_nsec; 331 332 return 0; 333 334 error_free: 335 devm_kfree(dev, ptp); 336 337 error: 338 /* For `ptp_get()` we need to differentiate between the case 339 * when the core has not tried to probe this device and the case when 340 * the probe failed. In the later case we pretend that the 341 * initialization was successful and keep the error in 342 * `dev->driver_data`. 343 */ 344 pci_set_drvdata(pdev, ERR_PTR(err)); 345 if (!first_ptp_block) 346 first_ptp_block = ERR_PTR(err); 347 348 return 0; 349 } 350 351 static void ptp_remove(struct pci_dev *pdev) 352 { 353 struct ptp *ptp = pci_get_drvdata(pdev); 354 u64 clock_cfg; 355 356 if (IS_ERR_OR_NULL(ptp)) 357 return; 358 359 /* Disable PTP clock */ 360 clock_cfg = readq(ptp->reg_base + PTP_CLOCK_CFG); 361 clock_cfg &= ~PTP_CLOCK_CFG_PTP_EN; 362 writeq(clock_cfg, ptp->reg_base + PTP_CLOCK_CFG); 363 } 364 365 static const struct pci_device_id ptp_id_table[] = { 366 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP, 367 PCI_VENDOR_ID_CAVIUM, 368 PCI_SUBSYS_DEVID_OCTX2_98xx_PTP) }, 369 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP, 370 PCI_VENDOR_ID_CAVIUM, 371 PCI_SUBSYS_DEVID_OCTX2_96XX_PTP) }, 372 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP, 373 PCI_VENDOR_ID_CAVIUM, 374 PCI_SUBSYS_DEVID_OCTX2_95XX_PTP) }, 375 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP, 376 PCI_VENDOR_ID_CAVIUM, 377 PCI_SUBSYS_DEVID_OCTX2_95XXN_PTP) }, 378 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP, 379 PCI_VENDOR_ID_CAVIUM, 380 PCI_SUBSYS_DEVID_OCTX2_95MM_PTP) }, 381 { PCI_DEVICE_SUB(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_PTP, 382 PCI_VENDOR_ID_CAVIUM, 383 PCI_SUBSYS_DEVID_OCTX2_95XXO_PTP) }, 384 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CN10K_PTP) }, 385 { 0, } 386 }; 387 388 struct pci_driver ptp_driver = { 389 .name = DRV_NAME, 390 .id_table = ptp_id_table, 391 .probe = ptp_probe, 392 .remove = ptp_remove, 393 }; 394 395 int rvu_mbox_handler_ptp_op(struct rvu *rvu, struct ptp_req *req, 396 struct ptp_rsp *rsp) 397 { 398 int err = 0; 399 400 /* This function is the PTP mailbox handler invoked when 401 * called by AF consumers/netdev drivers via mailbox mechanism. 402 * It is used by netdev driver to get the PTP clock and to set 403 * frequency adjustments. Since mailbox can be called without 404 * notion of whether the driver is bound to ptp device below 405 * validation is needed as first step. 406 */ 407 if (!rvu->ptp) 408 return -ENODEV; 409 410 switch (req->op) { 411 case PTP_OP_ADJFINE: 412 err = ptp_adjfine(rvu->ptp, req->scaled_ppm); 413 break; 414 case PTP_OP_GET_CLOCK: 415 err = ptp_get_clock(rvu->ptp, &rsp->clk); 416 break; 417 case PTP_OP_GET_TSTMP: 418 err = ptp_get_tstmp(rvu->ptp, &rsp->clk); 419 break; 420 case PTP_OP_SET_THRESH: 421 err = ptp_set_thresh(rvu->ptp, req->thresh); 422 break; 423 default: 424 err = -EINVAL; 425 break; 426 } 427 428 return err; 429 } 430