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