xref: /openbmc/linux/drivers/ptp/ptp_ocp.c (revision 6a143a7c)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2020 Facebook */
3 
4 #include <linux/err.h>
5 #include <linux/kernel.h>
6 #include <linux/module.h>
7 #include <linux/init.h>
8 #include <linux/pci.h>
9 #include <linux/ptp_clock_kernel.h>
10 
11 static const struct pci_device_id ptp_ocp_pcidev_id[] = {
12 	{ PCI_DEVICE(0x1d9b, 0x0400) },
13 	{ 0 }
14 };
15 MODULE_DEVICE_TABLE(pci, ptp_ocp_pcidev_id);
16 
17 #define OCP_REGISTER_OFFSET	0x01000000
18 
19 struct ocp_reg {
20 	u32	ctrl;
21 	u32	status;
22 	u32	select;
23 	u32	version;
24 	u32	time_ns;
25 	u32	time_sec;
26 	u32	__pad0[2];
27 	u32	adjust_ns;
28 	u32	adjust_sec;
29 	u32	__pad1[2];
30 	u32	offset_ns;
31 	u32	offset_window_ns;
32 };
33 
34 #define OCP_CTRL_ENABLE		BIT(0)
35 #define OCP_CTRL_ADJUST_TIME	BIT(1)
36 #define OCP_CTRL_ADJUST_OFFSET	BIT(2)
37 #define OCP_CTRL_READ_TIME_REQ	BIT(30)
38 #define OCP_CTRL_READ_TIME_DONE	BIT(31)
39 
40 #define OCP_STATUS_IN_SYNC	BIT(0)
41 
42 #define OCP_SELECT_CLK_NONE	0
43 #define OCP_SELECT_CLK_REG	6
44 
45 struct tod_reg {
46 	u32	ctrl;
47 	u32	status;
48 	u32	uart_polarity;
49 	u32	version;
50 	u32	correction_sec;
51 	u32	__pad0[3];
52 	u32	uart_baud;
53 	u32	__pad1[3];
54 	u32	utc_status;
55 	u32	leap;
56 };
57 
58 #define TOD_REGISTER_OFFSET	0x01050000
59 
60 #define TOD_CTRL_PROTOCOL	BIT(28)
61 #define TOD_CTRL_DISABLE_FMT_A	BIT(17)
62 #define TOD_CTRL_DISABLE_FMT_B	BIT(16)
63 #define TOD_CTRL_ENABLE		BIT(0)
64 #define TOD_CTRL_GNSS_MASK	((1U << 4) - 1)
65 #define TOD_CTRL_GNSS_SHIFT	24
66 
67 #define TOD_STATUS_UTC_MASK	0xff
68 #define TOD_STATUS_UTC_VALID	BIT(8)
69 #define TOD_STATUS_LEAP_VALID	BIT(16)
70 
71 struct ptp_ocp {
72 	struct pci_dev		*pdev;
73 	spinlock_t		lock;
74 	void __iomem		*base;
75 	struct ocp_reg __iomem	*reg;
76 	struct tod_reg __iomem	*tod;
77 	struct ptp_clock	*ptp;
78 	struct ptp_clock_info	ptp_info;
79 };
80 
81 static int
82 __ptp_ocp_gettime_locked(struct ptp_ocp *bp, struct timespec64 *ts,
83 			 struct ptp_system_timestamp *sts)
84 {
85 	u32 ctrl, time_sec, time_ns;
86 	int i;
87 
88 	ctrl = ioread32(&bp->reg->ctrl);
89 	ctrl |= OCP_CTRL_READ_TIME_REQ;
90 
91 	ptp_read_system_prets(sts);
92 	iowrite32(ctrl, &bp->reg->ctrl);
93 
94 	for (i = 0; i < 100; i++) {
95 		ctrl = ioread32(&bp->reg->ctrl);
96 		if (ctrl & OCP_CTRL_READ_TIME_DONE)
97 			break;
98 	}
99 	ptp_read_system_postts(sts);
100 
101 	time_ns = ioread32(&bp->reg->time_ns);
102 	time_sec = ioread32(&bp->reg->time_sec);
103 
104 	ts->tv_sec = time_sec;
105 	ts->tv_nsec = time_ns;
106 
107 	return ctrl & OCP_CTRL_READ_TIME_DONE ? 0 : -ETIMEDOUT;
108 }
109 
110 static int
111 ptp_ocp_gettimex(struct ptp_clock_info *ptp_info, struct timespec64 *ts,
112 		 struct ptp_system_timestamp *sts)
113 {
114 	struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info);
115 	unsigned long flags;
116 	int err;
117 
118 	spin_lock_irqsave(&bp->lock, flags);
119 	err = __ptp_ocp_gettime_locked(bp, ts, sts);
120 	spin_unlock_irqrestore(&bp->lock, flags);
121 
122 	return err;
123 }
124 
125 static void
126 __ptp_ocp_settime_locked(struct ptp_ocp *bp, const struct timespec64 *ts)
127 {
128 	u32 ctrl, time_sec, time_ns;
129 	u32 select;
130 
131 	time_ns = ts->tv_nsec;
132 	time_sec = ts->tv_sec;
133 
134 	select = ioread32(&bp->reg->select);
135 	iowrite32(OCP_SELECT_CLK_REG, &bp->reg->select);
136 
137 	iowrite32(time_ns, &bp->reg->adjust_ns);
138 	iowrite32(time_sec, &bp->reg->adjust_sec);
139 
140 	ctrl = ioread32(&bp->reg->ctrl);
141 	ctrl |= OCP_CTRL_ADJUST_TIME;
142 	iowrite32(ctrl, &bp->reg->ctrl);
143 
144 	/* restore clock selection */
145 	iowrite32(select >> 16, &bp->reg->select);
146 }
147 
148 static int
149 ptp_ocp_settime(struct ptp_clock_info *ptp_info, const struct timespec64 *ts)
150 {
151 	struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info);
152 	unsigned long flags;
153 
154 	if (ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC)
155 		return 0;
156 
157 	spin_lock_irqsave(&bp->lock, flags);
158 	__ptp_ocp_settime_locked(bp, ts);
159 	spin_unlock_irqrestore(&bp->lock, flags);
160 
161 	return 0;
162 }
163 
164 static int
165 ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
166 {
167 	struct ptp_ocp *bp = container_of(ptp_info, struct ptp_ocp, ptp_info);
168 	struct timespec64 ts;
169 	unsigned long flags;
170 	int err;
171 
172 	if (ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC)
173 		return 0;
174 
175 	spin_lock_irqsave(&bp->lock, flags);
176 	err = __ptp_ocp_gettime_locked(bp, &ts, NULL);
177 	if (likely(!err)) {
178 		timespec64_add_ns(&ts, delta_ns);
179 		__ptp_ocp_settime_locked(bp, &ts);
180 	}
181 	spin_unlock_irqrestore(&bp->lock, flags);
182 
183 	return err;
184 }
185 
186 static int
187 ptp_ocp_null_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
188 {
189 	if (scaled_ppm == 0)
190 		return 0;
191 
192 	return -EOPNOTSUPP;
193 }
194 
195 static const struct ptp_clock_info ptp_ocp_clock_info = {
196 	.owner		= THIS_MODULE,
197 	.name		= KBUILD_MODNAME,
198 	.max_adj	= 100000000,
199 	.gettimex64	= ptp_ocp_gettimex,
200 	.settime64	= ptp_ocp_settime,
201 	.adjtime	= ptp_ocp_adjtime,
202 	.adjfine	= ptp_ocp_null_adjfine,
203 };
204 
205 static int
206 ptp_ocp_check_clock(struct ptp_ocp *bp)
207 {
208 	struct timespec64 ts;
209 	bool sync;
210 	u32 ctrl;
211 
212 	/* make sure clock is enabled */
213 	ctrl = ioread32(&bp->reg->ctrl);
214 	ctrl |= OCP_CTRL_ENABLE;
215 	iowrite32(ctrl, &bp->reg->ctrl);
216 
217 	if ((ioread32(&bp->reg->ctrl) & OCP_CTRL_ENABLE) == 0) {
218 		dev_err(&bp->pdev->dev, "clock not enabled\n");
219 		return -ENODEV;
220 	}
221 
222 	sync = ioread32(&bp->reg->status) & OCP_STATUS_IN_SYNC;
223 	if (!sync) {
224 		ktime_get_real_ts64(&ts);
225 		ptp_ocp_settime(&bp->ptp_info, &ts);
226 	}
227 	if (!ptp_ocp_gettimex(&bp->ptp_info, &ts, NULL))
228 		dev_info(&bp->pdev->dev, "Time: %lld.%ld, %s\n",
229 			 ts.tv_sec, ts.tv_nsec,
230 			 sync ? "in-sync" : "UNSYNCED");
231 
232 	return 0;
233 }
234 
235 static void
236 ptp_ocp_tod_info(struct ptp_ocp *bp)
237 {
238 	static const char * const proto_name[] = {
239 		"NMEA", "NMEA_ZDA", "NMEA_RMC", "NMEA_none",
240 		"UBX", "UBX_UTC", "UBX_LS", "UBX_none"
241 	};
242 	static const char * const gnss_name[] = {
243 		"ALL", "COMBINED", "GPS", "GLONASS", "GALILEO", "BEIDOU",
244 	};
245 	u32 version, ctrl, reg;
246 	int idx;
247 
248 	version = ioread32(&bp->tod->version);
249 	dev_info(&bp->pdev->dev, "TOD Version %d.%d.%d\n",
250 		 version >> 24, (version >> 16) & 0xff, version & 0xffff);
251 
252 	ctrl = ioread32(&bp->tod->ctrl);
253 	ctrl |= TOD_CTRL_PROTOCOL | TOD_CTRL_ENABLE;
254 	ctrl &= ~(TOD_CTRL_DISABLE_FMT_A | TOD_CTRL_DISABLE_FMT_B);
255 	iowrite32(ctrl, &bp->tod->ctrl);
256 
257 	ctrl = ioread32(&bp->tod->ctrl);
258 	idx = ctrl & TOD_CTRL_PROTOCOL ? 4 : 0;
259 	idx += (ctrl >> 16) & 3;
260 	dev_info(&bp->pdev->dev, "control: %x\n", ctrl);
261 	dev_info(&bp->pdev->dev, "TOD Protocol %s %s\n", proto_name[idx],
262 		 ctrl & TOD_CTRL_ENABLE ? "enabled" : "");
263 
264 	idx = (ctrl >> TOD_CTRL_GNSS_SHIFT) & TOD_CTRL_GNSS_MASK;
265 	if (idx < ARRAY_SIZE(gnss_name))
266 		dev_info(&bp->pdev->dev, "GNSS %s\n", gnss_name[idx]);
267 
268 	reg = ioread32(&bp->tod->status);
269 	dev_info(&bp->pdev->dev, "status: %x\n", reg);
270 
271 	reg = ioread32(&bp->tod->correction_sec);
272 	dev_info(&bp->pdev->dev, "correction: %d\n", reg);
273 
274 	reg = ioread32(&bp->tod->utc_status);
275 	dev_info(&bp->pdev->dev, "utc_status: %x\n", reg);
276 	dev_info(&bp->pdev->dev, "utc_offset: %d  valid:%d  leap_valid:%d\n",
277 		 reg & TOD_STATUS_UTC_MASK, reg & TOD_STATUS_UTC_VALID ? 1 : 0,
278 		 reg & TOD_STATUS_LEAP_VALID ? 1 : 0);
279 }
280 
281 static void
282 ptp_ocp_info(struct ptp_ocp *bp)
283 {
284 	static const char * const clock_name[] = {
285 		"NO", "TOD", "IRIG", "PPS", "PTP", "RTC", "REGS", "EXT"
286 	};
287 	u32 version, select;
288 
289 	version = ioread32(&bp->reg->version);
290 	select = ioread32(&bp->reg->select);
291 	dev_info(&bp->pdev->dev, "Version %d.%d.%d, clock %s, device ptp%d\n",
292 		 version >> 24, (version >> 16) & 0xff, version & 0xffff,
293 		 clock_name[select & 7],
294 		 ptp_clock_index(bp->ptp));
295 
296 	ptp_ocp_tod_info(bp);
297 }
298 
299 static int
300 ptp_ocp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
301 {
302 	struct ptp_ocp *bp;
303 	int err;
304 
305 	bp = kzalloc(sizeof(*bp), GFP_KERNEL);
306 	if (!bp)
307 		return -ENOMEM;
308 	bp->pdev = pdev;
309 	pci_set_drvdata(pdev, bp);
310 
311 	err = pci_enable_device(pdev);
312 	if (err) {
313 		dev_err(&pdev->dev, "pci_enable_device\n");
314 		goto out_free;
315 	}
316 
317 	err = pci_request_regions(pdev, KBUILD_MODNAME);
318 	if (err) {
319 		dev_err(&pdev->dev, "pci_request_region\n");
320 		goto out_disable;
321 	}
322 
323 	bp->base = pci_ioremap_bar(pdev, 0);
324 	if (!bp->base) {
325 		dev_err(&pdev->dev, "io_remap bar0\n");
326 		err = -ENOMEM;
327 		goto out;
328 	}
329 	bp->reg = bp->base + OCP_REGISTER_OFFSET;
330 	bp->tod = bp->base + TOD_REGISTER_OFFSET;
331 	bp->ptp_info = ptp_ocp_clock_info;
332 	spin_lock_init(&bp->lock);
333 
334 	err = ptp_ocp_check_clock(bp);
335 	if (err)
336 		goto out;
337 
338 	bp->ptp = ptp_clock_register(&bp->ptp_info, &pdev->dev);
339 	if (IS_ERR(bp->ptp)) {
340 		dev_err(&pdev->dev, "ptp_clock_register\n");
341 		err = PTR_ERR(bp->ptp);
342 		goto out;
343 	}
344 
345 	ptp_ocp_info(bp);
346 
347 	return 0;
348 
349 out:
350 	pci_release_regions(pdev);
351 out_disable:
352 	pci_disable_device(pdev);
353 out_free:
354 	kfree(bp);
355 
356 	return err;
357 }
358 
359 static void
360 ptp_ocp_remove(struct pci_dev *pdev)
361 {
362 	struct ptp_ocp *bp = pci_get_drvdata(pdev);
363 
364 	ptp_clock_unregister(bp->ptp);
365 	pci_iounmap(pdev, bp->base);
366 	pci_release_regions(pdev);
367 	pci_disable_device(pdev);
368 	pci_set_drvdata(pdev, NULL);
369 	kfree(bp);
370 }
371 
372 static struct pci_driver ptp_ocp_driver = {
373 	.name		= KBUILD_MODNAME,
374 	.id_table	= ptp_ocp_pcidev_id,
375 	.probe		= ptp_ocp_probe,
376 	.remove		= ptp_ocp_remove,
377 };
378 
379 static int __init
380 ptp_ocp_init(void)
381 {
382 	int err;
383 
384 	err = pci_register_driver(&ptp_ocp_driver);
385 	return err;
386 }
387 
388 static void __exit
389 ptp_ocp_fini(void)
390 {
391 	pci_unregister_driver(&ptp_ocp_driver);
392 }
393 
394 module_init(ptp_ocp_init);
395 module_exit(ptp_ocp_fini);
396 
397 MODULE_DESCRIPTION("OpenCompute TimeCard driver");
398 MODULE_LICENSE("GPL v2");
399