2 * Copyright 2017 Broadcom
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
8 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/err.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/ptp_clock_kernel.h>
19 #include <linux/types.h>
21 #define DTE_NCO_LOW_TIME_REG 0x00
22 #define DTE_NCO_TIME_REG 0x04
23 #define DTE_NCO_OVERFLOW_REG 0x08
24 #define DTE_NCO_INC_REG 0x0c
26 #define DTE_NCO_SUM2_MASK 0xffffffff
27 #define DTE_NCO_SUM2_SHIFT 4ULL
29 #define DTE_NCO_SUM3_MASK 0xff
30 #define DTE_NCO_SUM3_SHIFT 36ULL
31 #define DTE_NCO_SUM3_WR_SHIFT 8
33 #define DTE_NCO_TS_WRAP_MASK 0xfff
34 #define DTE_NCO_TS_WRAP_LSHIFT 32
36 #define DTE_NCO_INC_DEFAULT 0x80000000
37 #define DTE_NUM_REGS_TO_RESTORE 4
39 /* Full wrap around is 44bits in ns (~4.887 hrs) */
40 #define DTE_WRAP_AROUND_NSEC_SHIFT 44
43 #define DTE_NCO_MAX_NS 0xFFFFFFFFFFFLL
45 /* 125MHz with 3.29 reg cfg */
46 #define DTE_PPB_ADJ(ppb) (u32)(div64_u64((((u64)abs(ppb) * BIT(28)) +\
47 62500000ULL), 125000000ULL))
49 /* ptp dte priv structure */
52 struct ptp_clock
*ptp_clk
;
53 struct ptp_clock_info caps
;
58 u32 reg_val
[DTE_NUM_REGS_TO_RESTORE
];
61 static void dte_write_nco(void __iomem
*regs
, s64 ns
)
65 sum2
= (u32
)((ns
>> DTE_NCO_SUM2_SHIFT
) & DTE_NCO_SUM2_MASK
);
66 /* compensate for ignoring sum1 */
67 if (sum2
!= DTE_NCO_SUM2_MASK
)
70 /* to write sum3, bits [15:8] needs to be written */
71 sum3
= (u32
)(((ns
>> DTE_NCO_SUM3_SHIFT
) & DTE_NCO_SUM3_MASK
) <<
72 DTE_NCO_SUM3_WR_SHIFT
);
74 writel(0, (regs
+ DTE_NCO_LOW_TIME_REG
));
75 writel(sum2
, (regs
+ DTE_NCO_TIME_REG
));
76 writel(sum3
, (regs
+ DTE_NCO_OVERFLOW_REG
));
79 static s64
dte_read_nco(void __iomem
*regs
)
85 * ignoring sum1 (4 bits) gives a 16ns resolution, which
86 * works due to the async register read.
88 sum3
= readl(regs
+ DTE_NCO_OVERFLOW_REG
) & DTE_NCO_SUM3_MASK
;
89 sum2
= readl(regs
+ DTE_NCO_TIME_REG
);
90 ns
= ((s64
)sum3
<< DTE_NCO_SUM3_SHIFT
) |
91 ((s64
)sum2
<< DTE_NCO_SUM2_SHIFT
);
96 static void dte_write_nco_delta(struct ptp_dte
*ptp_dte
, s64 delta
)
100 ns
= dte_read_nco(ptp_dte
->regs
);
102 /* handle wraparound conditions */
103 if ((delta
< 0) && (abs(delta
) > ns
)) {
104 if (ptp_dte
->ts_wrap_cnt
) {
105 ns
+= DTE_NCO_MAX_NS
+ delta
;
106 ptp_dte
->ts_wrap_cnt
--;
112 if (ns
> DTE_NCO_MAX_NS
) {
113 ptp_dte
->ts_wrap_cnt
++;
114 ns
-= DTE_NCO_MAX_NS
;
118 dte_write_nco(ptp_dte
->regs
, ns
);
120 ptp_dte
->ts_ovf_last
= (ns
>> DTE_NCO_TS_WRAP_LSHIFT
) &
121 DTE_NCO_TS_WRAP_MASK
;
124 static s64
dte_read_nco_with_ovf(struct ptp_dte
*ptp_dte
)
129 ns
= dte_read_nco(ptp_dte
->regs
);
131 /*Timestamp overflow: 8 LSB bits of sum3, 4 MSB bits of sum2 */
132 ts_ovf
= (ns
>> DTE_NCO_TS_WRAP_LSHIFT
) & DTE_NCO_TS_WRAP_MASK
;
134 /* Check for wrap around */
135 if (ts_ovf
< ptp_dte
->ts_ovf_last
)
136 ptp_dte
->ts_wrap_cnt
++;
138 ptp_dte
->ts_ovf_last
= ts_ovf
;
140 /* adjust for wraparounds */
141 ns
+= (s64
)(BIT_ULL(DTE_WRAP_AROUND_NSEC_SHIFT
) * ptp_dte
->ts_wrap_cnt
);
146 static int ptp_dte_adjfreq(struct ptp_clock_info
*ptp
, s32 ppb
)
150 struct ptp_dte
*ptp_dte
= container_of(ptp
, struct ptp_dte
, caps
);
152 if (abs(ppb
) > ptp_dte
->caps
.max_adj
) {
153 dev_err(ptp_dte
->dev
, "ppb adj too big\n");
158 nco_incr
= DTE_NCO_INC_DEFAULT
- DTE_PPB_ADJ(ppb
);
160 nco_incr
= DTE_NCO_INC_DEFAULT
+ DTE_PPB_ADJ(ppb
);
162 spin_lock_irqsave(&ptp_dte
->lock
, flags
);
163 writel(nco_incr
, ptp_dte
->regs
+ DTE_NCO_INC_REG
);
164 spin_unlock_irqrestore(&ptp_dte
->lock
, flags
);
169 static int ptp_dte_adjtime(struct ptp_clock_info
*ptp
, s64 delta
)
172 struct ptp_dte
*ptp_dte
= container_of(ptp
, struct ptp_dte
, caps
);
174 spin_lock_irqsave(&ptp_dte
->lock
, flags
);
175 dte_write_nco_delta(ptp_dte
, delta
);
176 spin_unlock_irqrestore(&ptp_dte
->lock
, flags
);
181 static int ptp_dte_gettime(struct ptp_clock_info
*ptp
, struct timespec64
*ts
)
184 struct ptp_dte
*ptp_dte
= container_of(ptp
, struct ptp_dte
, caps
);
186 spin_lock_irqsave(&ptp_dte
->lock
, flags
);
187 *ts
= ns_to_timespec64(dte_read_nco_with_ovf(ptp_dte
));
188 spin_unlock_irqrestore(&ptp_dte
->lock
, flags
);
193 static int ptp_dte_settime(struct ptp_clock_info
*ptp
,
194 const struct timespec64
*ts
)
197 struct ptp_dte
*ptp_dte
= container_of(ptp
, struct ptp_dte
, caps
);
199 spin_lock_irqsave(&ptp_dte
->lock
, flags
);
201 /* Disable nco increment */
202 writel(0, ptp_dte
->regs
+ DTE_NCO_INC_REG
);
204 dte_write_nco(ptp_dte
->regs
, timespec64_to_ns(ts
));
206 /* reset overflow and wrap counter */
207 ptp_dte
->ts_ovf_last
= 0;
208 ptp_dte
->ts_wrap_cnt
= 0;
210 /* Enable nco increment */
211 writel(DTE_NCO_INC_DEFAULT
, ptp_dte
->regs
+ DTE_NCO_INC_REG
);
213 spin_unlock_irqrestore(&ptp_dte
->lock
, flags
);
218 static int ptp_dte_enable(struct ptp_clock_info
*ptp
,
219 struct ptp_clock_request
*rq
, int on
)
224 static const struct ptp_clock_info ptp_dte_caps
= {
225 .owner
= THIS_MODULE
,
226 .name
= "DTE PTP timer",
231 .adjfreq
= ptp_dte_adjfreq
,
232 .adjtime
= ptp_dte_adjtime
,
233 .gettime64
= ptp_dte_gettime
,
234 .settime64
= ptp_dte_settime
,
235 .enable
= ptp_dte_enable
,
238 static int ptp_dte_probe(struct platform_device
*pdev
)
240 struct ptp_dte
*ptp_dte
;
241 struct device
*dev
= &pdev
->dev
;
242 struct resource
*res
;
244 ptp_dte
= devm_kzalloc(dev
, sizeof(struct ptp_dte
), GFP_KERNEL
);
248 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
249 ptp_dte
->regs
= devm_ioremap_resource(dev
, res
);
250 if (IS_ERR(ptp_dte
->regs
)) {
252 "%s: io remap failed\n", __func__
);
253 return PTR_ERR(ptp_dte
->regs
);
256 spin_lock_init(&ptp_dte
->lock
);
259 ptp_dte
->caps
= ptp_dte_caps
;
260 ptp_dte
->ptp_clk
= ptp_clock_register(&ptp_dte
->caps
, &pdev
->dev
);
261 if (IS_ERR(ptp_dte
->ptp_clk
)) {
263 "%s: Failed to register ptp clock\n", __func__
);
264 return PTR_ERR(ptp_dte
->ptp_clk
);
267 platform_set_drvdata(pdev
, ptp_dte
);
269 dev_info(dev
, "ptp clk probe done\n");
274 static int ptp_dte_remove(struct platform_device
*pdev
)
276 struct ptp_dte
*ptp_dte
= platform_get_drvdata(pdev
);
279 ptp_clock_unregister(ptp_dte
->ptp_clk
);
281 for (i
= 0; i
< DTE_NUM_REGS_TO_RESTORE
; i
++)
282 writel(0, ptp_dte
->regs
+ (i
* sizeof(u32
)));
287 #ifdef CONFIG_PM_SLEEP
288 static int ptp_dte_suspend(struct device
*dev
)
290 struct platform_device
*pdev
= to_platform_device(dev
);
291 struct ptp_dte
*ptp_dte
= platform_get_drvdata(pdev
);
294 for (i
= 0; i
< DTE_NUM_REGS_TO_RESTORE
; i
++) {
295 ptp_dte
->reg_val
[i
] =
296 readl(ptp_dte
->regs
+ (i
* sizeof(u32
)));
299 /* disable the nco */
300 writel(0, ptp_dte
->regs
+ DTE_NCO_INC_REG
);
305 static int ptp_dte_resume(struct device
*dev
)
307 struct platform_device
*pdev
= to_platform_device(dev
);
308 struct ptp_dte
*ptp_dte
= platform_get_drvdata(pdev
);
311 for (i
= 0; i
< DTE_NUM_REGS_TO_RESTORE
; i
++) {
312 if ((i
* sizeof(u32
)) != DTE_NCO_OVERFLOW_REG
)
313 writel(ptp_dte
->reg_val
[i
],
314 (ptp_dte
->regs
+ (i
* sizeof(u32
))));
316 writel(((ptp_dte
->reg_val
[i
] &
317 DTE_NCO_SUM3_MASK
) << DTE_NCO_SUM3_WR_SHIFT
),
318 (ptp_dte
->regs
+ (i
* sizeof(u32
))));
324 static const struct dev_pm_ops ptp_dte_pm_ops
= {
325 .suspend
= ptp_dte_suspend
,
326 .resume
= ptp_dte_resume
329 #define PTP_DTE_PM_OPS (&ptp_dte_pm_ops)
331 #define PTP_DTE_PM_OPS NULL
334 static const struct of_device_id ptp_dte_of_match
[] = {
335 { .compatible
= "brcm,ptp-dte", },
338 MODULE_DEVICE_TABLE(of
, ptp_dte_of_match
);
340 static struct platform_driver ptp_dte_driver
= {
343 .pm
= PTP_DTE_PM_OPS
,
344 .of_match_table
= ptp_dte_of_match
,
346 .probe
= ptp_dte_probe
,
347 .remove
= ptp_dte_remove
,
349 module_platform_driver(ptp_dte_driver
);
351 MODULE_AUTHOR("Broadcom");
352 MODULE_DESCRIPTION("Broadcom DTE PTP Clock driver");
353 MODULE_LICENSE("GPL v2");