1 // SPDX-License-Identifier: GPL-2.0 2 /* Renesas R-Car Gen4 gPTP device driver 3 * 4 * Copyright (C) 2022 Renesas Electronics Corporation 5 */ 6 7 #include <linux/err.h> 8 #include <linux/etherdevice.h> 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/slab.h> 13 14 #include "rcar_gen4_ptp.h" 15 16 #define PTPTMEC_REG 0x0010 17 #define PTPTMDC_REG 0x0014 18 #define PTPTIVC0_REG 0x0020 19 #define PTPTOVC00_REG 0x0030 20 #define PTPTOVC10_REG 0x0034 21 #define PTPTOVC20_REG 0x0038 22 #define PTPGPTPTM00_REG 0x0050 23 #define PTPGPTPTM10_REG 0x0054 24 #define PTPGPTPTM20_REG 0x0058 25 26 #define ptp_to_priv(ptp) container_of(ptp, struct rcar_gen4_ptp_private, info) 27 28 static int rcar_gen4_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) 29 { 30 struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp); 31 s64 addend = ptp_priv->default_addend; 32 bool neg_adj = scaled_ppm < 0; 33 s64 diff; 34 35 if (neg_adj) 36 scaled_ppm = -scaled_ppm; 37 diff = div_s64(addend * scaled_ppm_to_ppb(scaled_ppm), NSEC_PER_SEC); 38 addend = neg_adj ? addend - diff : addend + diff; 39 40 iowrite32(addend, ptp_priv->addr + PTPTIVC0_REG); 41 42 return 0; 43 } 44 45 static void _rcar_gen4_ptp_gettime(struct ptp_clock_info *ptp, 46 struct timespec64 *ts) 47 { 48 struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp); 49 50 lockdep_assert_held(&ptp_priv->lock); 51 52 ts->tv_nsec = ioread32(ptp_priv->addr + PTPGPTPTM00_REG); 53 ts->tv_sec = ioread32(ptp_priv->addr + PTPGPTPTM10_REG) | 54 ((s64)ioread32(ptp_priv->addr + PTPGPTPTM20_REG) << 32); 55 } 56 57 static int rcar_gen4_ptp_gettime(struct ptp_clock_info *ptp, 58 struct timespec64 *ts) 59 { 60 struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp); 61 unsigned long flags; 62 63 spin_lock_irqsave(&ptp_priv->lock, flags); 64 _rcar_gen4_ptp_gettime(ptp, ts); 65 spin_unlock_irqrestore(&ptp_priv->lock, flags); 66 67 return 0; 68 } 69 70 /* Caller must hold the lock */ 71 static void _rcar_gen4_ptp_settime(struct ptp_clock_info *ptp, 72 const struct timespec64 *ts) 73 { 74 struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp); 75 76 iowrite32(1, ptp_priv->addr + PTPTMDC_REG); 77 iowrite32(0, ptp_priv->addr + PTPTOVC20_REG); 78 iowrite32(0, ptp_priv->addr + PTPTOVC10_REG); 79 iowrite32(0, ptp_priv->addr + PTPTOVC00_REG); 80 iowrite32(1, ptp_priv->addr + PTPTMEC_REG); 81 iowrite32(ts->tv_sec >> 32, ptp_priv->addr + PTPTOVC20_REG); 82 iowrite32(ts->tv_sec, ptp_priv->addr + PTPTOVC10_REG); 83 iowrite32(ts->tv_nsec, ptp_priv->addr + PTPTOVC00_REG); 84 } 85 86 static int rcar_gen4_ptp_settime(struct ptp_clock_info *ptp, 87 const struct timespec64 *ts) 88 { 89 struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp); 90 unsigned long flags; 91 92 spin_lock_irqsave(&ptp_priv->lock, flags); 93 _rcar_gen4_ptp_settime(ptp, ts); 94 spin_unlock_irqrestore(&ptp_priv->lock, flags); 95 96 return 0; 97 } 98 99 static int rcar_gen4_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) 100 { 101 struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp); 102 struct timespec64 ts; 103 unsigned long flags; 104 s64 now; 105 106 spin_lock_irqsave(&ptp_priv->lock, flags); 107 _rcar_gen4_ptp_gettime(ptp, &ts); 108 now = ktime_to_ns(timespec64_to_ktime(ts)); 109 ts = ns_to_timespec64(now + delta); 110 _rcar_gen4_ptp_settime(ptp, &ts); 111 spin_unlock_irqrestore(&ptp_priv->lock, flags); 112 113 return 0; 114 } 115 116 static int rcar_gen4_ptp_enable(struct ptp_clock_info *ptp, 117 struct ptp_clock_request *rq, int on) 118 { 119 return -EOPNOTSUPP; 120 } 121 122 static struct ptp_clock_info rcar_gen4_ptp_info = { 123 .owner = THIS_MODULE, 124 .name = "rcar_gen4_ptp", 125 .max_adj = 50000000, 126 .adjfine = rcar_gen4_ptp_adjfine, 127 .adjtime = rcar_gen4_ptp_adjtime, 128 .gettime64 = rcar_gen4_ptp_gettime, 129 .settime64 = rcar_gen4_ptp_settime, 130 .enable = rcar_gen4_ptp_enable, 131 }; 132 133 static s64 rcar_gen4_ptp_rate_to_increment(u32 rate) 134 { 135 /* Timer increment in ns. 136 * bit[31:27] - integer 137 * bit[26:0] - decimal 138 * increment[ns] = perid[ns] * 2^27 => (1ns * 2^27) / rate[hz] 139 */ 140 return div_s64(1000000000LL << 27, rate); 141 } 142 143 int rcar_gen4_ptp_register(struct rcar_gen4_ptp_private *ptp_priv, u32 rate) 144 { 145 if (ptp_priv->initialized) 146 return 0; 147 148 spin_lock_init(&ptp_priv->lock); 149 150 ptp_priv->default_addend = rcar_gen4_ptp_rate_to_increment(rate); 151 iowrite32(ptp_priv->default_addend, ptp_priv->addr + PTPTIVC0_REG); 152 ptp_priv->clock = ptp_clock_register(&ptp_priv->info, NULL); 153 if (IS_ERR(ptp_priv->clock)) 154 return PTR_ERR(ptp_priv->clock); 155 156 iowrite32(0x01, ptp_priv->addr + PTPTMEC_REG); 157 ptp_priv->initialized = true; 158 159 return 0; 160 } 161 EXPORT_SYMBOL_GPL(rcar_gen4_ptp_register); 162 163 int rcar_gen4_ptp_unregister(struct rcar_gen4_ptp_private *ptp_priv) 164 { 165 iowrite32(1, ptp_priv->addr + PTPTMDC_REG); 166 167 return ptp_clock_unregister(ptp_priv->clock); 168 } 169 EXPORT_SYMBOL_GPL(rcar_gen4_ptp_unregister); 170 171 struct rcar_gen4_ptp_private *rcar_gen4_ptp_alloc(struct platform_device *pdev) 172 { 173 struct rcar_gen4_ptp_private *ptp; 174 175 ptp = devm_kzalloc(&pdev->dev, sizeof(*ptp), GFP_KERNEL); 176 if (!ptp) 177 return NULL; 178 179 ptp->info = rcar_gen4_ptp_info; 180 181 return ptp; 182 } 183 EXPORT_SYMBOL_GPL(rcar_gen4_ptp_alloc); 184 185 MODULE_AUTHOR("Yoshihiro Shimoda"); 186 MODULE_DESCRIPTION("Renesas R-Car Gen4 gPTP driver"); 187 MODULE_LICENSE("GPL"); 188