1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2019-2020 NVIDIA Corporation. All rights reserved.
4  */
5 
6 #include <linux/clocksource.h>
7 #include <linux/module.h>
8 #include <linux/interrupt.h>
9 #include <linux/io.h>
10 #include <linux/of.h>
11 #include <linux/of_device.h>
12 #include <linux/platform_device.h>
13 #include <linux/pm.h>
14 #include <linux/watchdog.h>
15 
16 /* shared registers */
17 #define TKETSC0 0x000
18 #define TKETSC1 0x004
19 #define TKEUSEC 0x008
20 #define TKEOSC  0x00c
21 
22 #define TKEIE(x) (0x100 + ((x) * 4))
23 #define  TKEIE_WDT_MASK(x, y) ((y) << (16 + 4 * (x)))
24 
25 /* timer registers */
26 #define TMRCR 0x000
27 #define  TMRCR_ENABLE BIT(31)
28 #define  TMRCR_PERIODIC BIT(30)
29 #define  TMRCR_PTV(x) ((x) & 0x0fffffff)
30 
31 #define TMRSR 0x004
32 #define  TMRSR_INTR_CLR BIT(30)
33 
34 #define TMRCSSR 0x008
35 #define  TMRCSSR_SRC_USEC (0 << 0)
36 
37 /* watchdog registers */
38 #define WDTCR 0x000
39 #define  WDTCR_SYSTEM_POR_RESET_ENABLE BIT(16)
40 #define  WDTCR_SYSTEM_DEBUG_RESET_ENABLE BIT(15)
41 #define  WDTCR_REMOTE_INT_ENABLE BIT(14)
42 #define  WDTCR_LOCAL_FIQ_ENABLE BIT(13)
43 #define  WDTCR_LOCAL_INT_ENABLE BIT(12)
44 #define  WDTCR_PERIOD_MASK (0xff << 4)
45 #define  WDTCR_PERIOD(x) (((x) & 0xff) << 4)
46 #define  WDTCR_TIMER_SOURCE_MASK 0xf
47 #define  WDTCR_TIMER_SOURCE(x) ((x) & 0xf)
48 
49 #define WDTCMDR 0x008
50 #define  WDTCMDR_DISABLE_COUNTER BIT(1)
51 #define  WDTCMDR_START_COUNTER BIT(0)
52 
53 #define WDTUR 0x00c
54 #define  WDTUR_UNLOCK_PATTERN 0x0000c45a
55 
56 struct tegra186_timer_soc {
57 	unsigned int num_timers;
58 	unsigned int num_wdts;
59 };
60 
61 struct tegra186_tmr {
62 	struct tegra186_timer *parent;
63 	void __iomem *regs;
64 	unsigned int index;
65 	unsigned int hwirq;
66 };
67 
68 struct tegra186_wdt {
69 	struct watchdog_device base;
70 
71 	void __iomem *regs;
72 	unsigned int index;
73 	bool locked;
74 
75 	struct tegra186_tmr *tmr;
76 };
77 
78 static inline struct tegra186_wdt *to_tegra186_wdt(struct watchdog_device *wdd)
79 {
80 	return container_of(wdd, struct tegra186_wdt, base);
81 }
82 
83 struct tegra186_timer {
84 	const struct tegra186_timer_soc *soc;
85 	struct device *dev;
86 	void __iomem *regs;
87 
88 	struct tegra186_wdt *wdt;
89 	struct clocksource usec;
90 	struct clocksource tsc;
91 	struct clocksource osc;
92 };
93 
94 static void tmr_writel(struct tegra186_tmr *tmr, u32 value, unsigned int offset)
95 {
96 	writel_relaxed(value, tmr->regs + offset);
97 }
98 
99 static void wdt_writel(struct tegra186_wdt *wdt, u32 value, unsigned int offset)
100 {
101 	writel_relaxed(value, wdt->regs + offset);
102 }
103 
104 static u32 wdt_readl(struct tegra186_wdt *wdt, unsigned int offset)
105 {
106 	return readl_relaxed(wdt->regs + offset);
107 }
108 
109 static struct tegra186_tmr *tegra186_tmr_create(struct tegra186_timer *tegra,
110 						unsigned int index)
111 {
112 	unsigned int offset = 0x10000 + index * 0x10000;
113 	struct tegra186_tmr *tmr;
114 
115 	tmr = devm_kzalloc(tegra->dev, sizeof(*tmr), GFP_KERNEL);
116 	if (!tmr)
117 		return ERR_PTR(-ENOMEM);
118 
119 	tmr->parent = tegra;
120 	tmr->regs = tegra->regs + offset;
121 	tmr->index = index;
122 	tmr->hwirq = 0;
123 
124 	return tmr;
125 }
126 
127 static const struct watchdog_info tegra186_wdt_info = {
128 	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
129 	.identity = "NVIDIA Tegra186 WDT",
130 };
131 
132 static void tegra186_wdt_disable(struct tegra186_wdt *wdt)
133 {
134 	/* unlock and disable the watchdog */
135 	wdt_writel(wdt, WDTUR_UNLOCK_PATTERN, WDTUR);
136 	wdt_writel(wdt, WDTCMDR_DISABLE_COUNTER, WDTCMDR);
137 
138 	/* disable timer */
139 	tmr_writel(wdt->tmr, 0, TMRCR);
140 }
141 
142 static void tegra186_wdt_enable(struct tegra186_wdt *wdt)
143 {
144 	struct tegra186_timer *tegra = wdt->tmr->parent;
145 	u32 value;
146 
147 	/* unmask hardware IRQ, this may have been lost across powergate */
148 	value = TKEIE_WDT_MASK(wdt->index, 1);
149 	writel(value, tegra->regs + TKEIE(wdt->tmr->hwirq));
150 
151 	/* clear interrupt */
152 	tmr_writel(wdt->tmr, TMRSR_INTR_CLR, TMRSR);
153 
154 	/* select microsecond source */
155 	tmr_writel(wdt->tmr, TMRCSSR_SRC_USEC, TMRCSSR);
156 
157 	/* configure timer (system reset happens on the fifth expiration) */
158 	value = TMRCR_PTV(wdt->base.timeout * USEC_PER_SEC / 5) |
159 		TMRCR_PERIODIC | TMRCR_ENABLE;
160 	tmr_writel(wdt->tmr, value, TMRCR);
161 
162 	if (!wdt->locked) {
163 		value = wdt_readl(wdt, WDTCR);
164 
165 		/* select the proper timer source */
166 		value &= ~WDTCR_TIMER_SOURCE_MASK;
167 		value |= WDTCR_TIMER_SOURCE(wdt->tmr->index);
168 
169 		/* single timer period since that's already configured */
170 		value &= ~WDTCR_PERIOD_MASK;
171 		value |= WDTCR_PERIOD(1);
172 
173 		/* enable local interrupt for WDT petting */
174 		value |= WDTCR_LOCAL_INT_ENABLE;
175 
176 		/* enable local FIQ and remote interrupt for debug dump */
177 		if (0)
178 			value |= WDTCR_REMOTE_INT_ENABLE |
179 				 WDTCR_LOCAL_FIQ_ENABLE;
180 
181 		/* enable system debug reset (doesn't properly reboot) */
182 		if (0)
183 			value |= WDTCR_SYSTEM_DEBUG_RESET_ENABLE;
184 
185 		/* enable system POR reset */
186 		value |= WDTCR_SYSTEM_POR_RESET_ENABLE;
187 
188 		wdt_writel(wdt, value, WDTCR);
189 	}
190 
191 	wdt_writel(wdt, WDTCMDR_START_COUNTER, WDTCMDR);
192 }
193 
194 static int tegra186_wdt_start(struct watchdog_device *wdd)
195 {
196 	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
197 
198 	tegra186_wdt_enable(wdt);
199 
200 	return 0;
201 }
202 
203 static int tegra186_wdt_stop(struct watchdog_device *wdd)
204 {
205 	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
206 
207 	tegra186_wdt_disable(wdt);
208 
209 	return 0;
210 }
211 
212 static int tegra186_wdt_ping(struct watchdog_device *wdd)
213 {
214 	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
215 
216 	tegra186_wdt_disable(wdt);
217 	tegra186_wdt_enable(wdt);
218 
219 	return 0;
220 }
221 
222 static int tegra186_wdt_set_timeout(struct watchdog_device *wdd,
223 				    unsigned int timeout)
224 {
225 	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
226 
227 	if (watchdog_active(&wdt->base))
228 		tegra186_wdt_disable(wdt);
229 
230 	wdt->base.timeout = timeout;
231 
232 	if (watchdog_active(&wdt->base))
233 		tegra186_wdt_enable(wdt);
234 
235 	return 0;
236 }
237 
238 static const struct watchdog_ops tegra186_wdt_ops = {
239 	.owner = THIS_MODULE,
240 	.start = tegra186_wdt_start,
241 	.stop = tegra186_wdt_stop,
242 	.ping = tegra186_wdt_ping,
243 	.set_timeout = tegra186_wdt_set_timeout,
244 };
245 
246 static struct tegra186_wdt *tegra186_wdt_create(struct tegra186_timer *tegra,
247 						unsigned int index)
248 {
249 	unsigned int offset = 0x10000, source;
250 	struct tegra186_wdt *wdt;
251 	u32 value;
252 	int err;
253 
254 	offset += tegra->soc->num_timers * 0x10000 + index * 0x10000;
255 
256 	wdt = devm_kzalloc(tegra->dev, sizeof(*wdt), GFP_KERNEL);
257 	if (!wdt)
258 		return ERR_PTR(-ENOMEM);
259 
260 	wdt->regs = tegra->regs + offset;
261 	wdt->index = index;
262 
263 	/* read the watchdog configuration since it might be locked down */
264 	value = wdt_readl(wdt, WDTCR);
265 
266 	if (value & WDTCR_LOCAL_INT_ENABLE)
267 		wdt->locked = true;
268 
269 	source = value & WDTCR_TIMER_SOURCE_MASK;
270 
271 	wdt->tmr = tegra186_tmr_create(tegra, source);
272 	if (IS_ERR(wdt->tmr))
273 		return ERR_CAST(wdt->tmr);
274 
275 	wdt->base.info = &tegra186_wdt_info;
276 	wdt->base.ops = &tegra186_wdt_ops;
277 	wdt->base.min_timeout = 1;
278 	wdt->base.max_timeout = 255;
279 	wdt->base.parent = tegra->dev;
280 
281 	err = watchdog_init_timeout(&wdt->base, 5, tegra->dev);
282 	if (err < 0) {
283 		dev_err(tegra->dev, "failed to initialize timeout: %d\n", err);
284 		return ERR_PTR(err);
285 	}
286 
287 	err = devm_watchdog_register_device(tegra->dev, &wdt->base);
288 	if (err < 0) {
289 		dev_err(tegra->dev, "failed to register WDT: %d\n", err);
290 		return ERR_PTR(err);
291 	}
292 
293 	return wdt;
294 }
295 
296 static u64 tegra186_timer_tsc_read(struct clocksource *cs)
297 {
298 	struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer,
299 						    tsc);
300 	u32 hi, lo, ss;
301 
302 	hi = readl_relaxed(tegra->regs + TKETSC1);
303 
304 	/*
305 	 * The 56-bit value of the TSC is spread across two registers that are
306 	 * not synchronized. In order to read them atomically, ensure that the
307 	 * high 24 bits match before and after reading the low 32 bits.
308 	 */
309 	do {
310 		/* snapshot the high 24 bits */
311 		ss = hi;
312 
313 		lo = readl_relaxed(tegra->regs + TKETSC0);
314 		hi = readl_relaxed(tegra->regs + TKETSC1);
315 	} while (hi != ss);
316 
317 	return (u64)hi << 32 | lo;
318 }
319 
320 static int tegra186_timer_tsc_init(struct tegra186_timer *tegra)
321 {
322 	tegra->tsc.name = "tsc";
323 	tegra->tsc.rating = 300;
324 	tegra->tsc.read = tegra186_timer_tsc_read;
325 	tegra->tsc.mask = CLOCKSOURCE_MASK(56);
326 	tegra->tsc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
327 
328 	return clocksource_register_hz(&tegra->tsc, 31250000);
329 }
330 
331 static u64 tegra186_timer_osc_read(struct clocksource *cs)
332 {
333 	struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer,
334 						    osc);
335 
336 	return readl_relaxed(tegra->regs + TKEOSC);
337 }
338 
339 static int tegra186_timer_osc_init(struct tegra186_timer *tegra)
340 {
341 	tegra->osc.name = "osc";
342 	tegra->osc.rating = 300;
343 	tegra->osc.read = tegra186_timer_osc_read;
344 	tegra->osc.mask = CLOCKSOURCE_MASK(32);
345 	tegra->osc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
346 
347 	return clocksource_register_hz(&tegra->osc, 38400000);
348 }
349 
350 static u64 tegra186_timer_usec_read(struct clocksource *cs)
351 {
352 	struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer,
353 						    usec);
354 
355 	return readl_relaxed(tegra->regs + TKEUSEC);
356 }
357 
358 static int tegra186_timer_usec_init(struct tegra186_timer *tegra)
359 {
360 	tegra->usec.name = "usec";
361 	tegra->usec.rating = 300;
362 	tegra->usec.read = tegra186_timer_usec_read;
363 	tegra->usec.mask = CLOCKSOURCE_MASK(32);
364 	tegra->usec.flags = CLOCK_SOURCE_IS_CONTINUOUS;
365 
366 	return clocksource_register_hz(&tegra->usec, USEC_PER_SEC);
367 }
368 
369 static irqreturn_t tegra186_timer_irq(int irq, void *data)
370 {
371 	struct tegra186_timer *tegra = data;
372 
373 	if (watchdog_active(&tegra->wdt->base)) {
374 		tegra186_wdt_disable(tegra->wdt);
375 		tegra186_wdt_enable(tegra->wdt);
376 	}
377 
378 	return IRQ_HANDLED;
379 }
380 
381 static int tegra186_timer_probe(struct platform_device *pdev)
382 {
383 	struct device *dev = &pdev->dev;
384 	struct tegra186_timer *tegra;
385 	unsigned int irq;
386 	int err;
387 
388 	tegra = devm_kzalloc(dev, sizeof(*tegra), GFP_KERNEL);
389 	if (!tegra)
390 		return -ENOMEM;
391 
392 	tegra->soc = of_device_get_match_data(dev);
393 	dev_set_drvdata(dev, tegra);
394 	tegra->dev = dev;
395 
396 	tegra->regs = devm_platform_ioremap_resource(pdev, 0);
397 	if (IS_ERR(tegra->regs))
398 		return PTR_ERR(tegra->regs);
399 
400 	err = platform_get_irq(pdev, 0);
401 	if (err < 0)
402 		return err;
403 
404 	irq = err;
405 
406 	/* create a watchdog using a preconfigured timer */
407 	tegra->wdt = tegra186_wdt_create(tegra, 0);
408 	if (IS_ERR(tegra->wdt)) {
409 		err = PTR_ERR(tegra->wdt);
410 		dev_err(dev, "failed to create WDT: %d\n", err);
411 		return err;
412 	}
413 
414 	err = tegra186_timer_tsc_init(tegra);
415 	if (err < 0) {
416 		dev_err(dev, "failed to register TSC counter: %d\n", err);
417 		return err;
418 	}
419 
420 	err = tegra186_timer_osc_init(tegra);
421 	if (err < 0) {
422 		dev_err(dev, "failed to register OSC counter: %d\n", err);
423 		goto unregister_tsc;
424 	}
425 
426 	err = tegra186_timer_usec_init(tegra);
427 	if (err < 0) {
428 		dev_err(dev, "failed to register USEC counter: %d\n", err);
429 		goto unregister_osc;
430 	}
431 
432 	err = devm_request_irq(dev, irq, tegra186_timer_irq, 0,
433 			       "tegra186-timer", tegra);
434 	if (err < 0) {
435 		dev_err(dev, "failed to request IRQ#%u: %d\n", irq, err);
436 		goto unregister_usec;
437 	}
438 
439 	return 0;
440 
441 unregister_usec:
442 	clocksource_unregister(&tegra->usec);
443 unregister_osc:
444 	clocksource_unregister(&tegra->osc);
445 unregister_tsc:
446 	clocksource_unregister(&tegra->tsc);
447 	return err;
448 }
449 
450 static int tegra186_timer_remove(struct platform_device *pdev)
451 {
452 	struct tegra186_timer *tegra = platform_get_drvdata(pdev);
453 
454 	clocksource_unregister(&tegra->usec);
455 	clocksource_unregister(&tegra->osc);
456 	clocksource_unregister(&tegra->tsc);
457 
458 	return 0;
459 }
460 
461 static int __maybe_unused tegra186_timer_suspend(struct device *dev)
462 {
463 	struct tegra186_timer *tegra = dev_get_drvdata(dev);
464 
465 	if (watchdog_active(&tegra->wdt->base))
466 		tegra186_wdt_disable(tegra->wdt);
467 
468 	return 0;
469 }
470 
471 static int __maybe_unused tegra186_timer_resume(struct device *dev)
472 {
473 	struct tegra186_timer *tegra = dev_get_drvdata(dev);
474 
475 	if (watchdog_active(&tegra->wdt->base))
476 		tegra186_wdt_enable(tegra->wdt);
477 
478 	return 0;
479 }
480 
481 static SIMPLE_DEV_PM_OPS(tegra186_timer_pm_ops, tegra186_timer_suspend,
482 			 tegra186_timer_resume);
483 
484 static const struct tegra186_timer_soc tegra186_timer = {
485 	.num_timers = 10,
486 	.num_wdts = 3,
487 };
488 
489 static const struct tegra186_timer_soc tegra234_timer = {
490 	.num_timers = 16,
491 	.num_wdts = 3,
492 };
493 
494 static const struct of_device_id tegra186_timer_of_match[] = {
495 	{ .compatible = "nvidia,tegra186-timer", .data = &tegra186_timer },
496 	{ .compatible = "nvidia,tegra234-timer", .data = &tegra234_timer },
497 	{ }
498 };
499 MODULE_DEVICE_TABLE(of, tegra186_timer_of_match);
500 
501 static struct platform_driver tegra186_wdt_driver = {
502 	.driver = {
503 		.name = "tegra186-timer",
504 		.pm = &tegra186_timer_pm_ops,
505 		.of_match_table = tegra186_timer_of_match,
506 	},
507 	.probe = tegra186_timer_probe,
508 	.remove = tegra186_timer_remove,
509 };
510 module_platform_driver(tegra186_wdt_driver);
511 
512 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
513 MODULE_DESCRIPTION("NVIDIA Tegra186 timers driver");
514 MODULE_LICENSE("GPL v2");
515