1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2019-2020 NVIDIA Corporation. All rights reserved.
6 #include <linux/clocksource.h>
7 #include <linux/module.h>
8 #include <linux/interrupt.h>
11 #include <linux/platform_device.h>
13 #include <linux/watchdog.h>
15 /* shared registers */
21 #define TKEIE(x) (0x100 + ((x) * 4))
22 #define TKEIE_WDT_MASK(x, y) ((y) << (16 + 4 * (x)))
26 #define TMRCR_ENABLE BIT(31)
27 #define TMRCR_PERIODIC BIT(30)
28 #define TMRCR_PTV(x) ((x) & 0x0fffffff)
31 #define TMRSR_INTR_CLR BIT(30)
34 #define TMRCSSR_SRC_USEC (0 << 0)
36 /* watchdog registers */
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)
49 #define WDTCMDR_DISABLE_COUNTER BIT(1)
50 #define WDTCMDR_START_COUNTER BIT(0)
53 #define WDTUR_UNLOCK_PATTERN 0x0000c45a
55 struct tegra186_timer_soc
{
56 unsigned int num_timers
;
57 unsigned int num_wdts
;
61 struct tegra186_timer
*parent
;
68 struct watchdog_device base
;
74 struct tegra186_tmr
*tmr
;
77 static inline struct tegra186_wdt
*to_tegra186_wdt(struct watchdog_device
*wdd
)
79 return container_of(wdd
, struct tegra186_wdt
, base
);
82 struct tegra186_timer
{
83 const struct tegra186_timer_soc
*soc
;
87 struct tegra186_wdt
*wdt
;
88 struct clocksource usec
;
89 struct clocksource tsc
;
90 struct clocksource osc
;
93 static void tmr_writel(struct tegra186_tmr
*tmr
, u32 value
, unsigned int offset
)
95 writel_relaxed(value
, tmr
->regs
+ offset
);
98 static void wdt_writel(struct tegra186_wdt
*wdt
, u32 value
, unsigned int offset
)
100 writel_relaxed(value
, wdt
->regs
+ offset
);
103 static u32
wdt_readl(struct tegra186_wdt
*wdt
, unsigned int offset
)
105 return readl_relaxed(wdt
->regs
+ offset
);
108 static struct tegra186_tmr
*tegra186_tmr_create(struct tegra186_timer
*tegra
,
111 unsigned int offset
= 0x10000 + index
* 0x10000;
112 struct tegra186_tmr
*tmr
;
114 tmr
= devm_kzalloc(tegra
->dev
, sizeof(*tmr
), GFP_KERNEL
);
116 return ERR_PTR(-ENOMEM
);
119 tmr
->regs
= tegra
->regs
+ offset
;
126 static const struct watchdog_info tegra186_wdt_info
= {
127 .options
= WDIOF_SETTIMEOUT
| WDIOF_MAGICCLOSE
| WDIOF_KEEPALIVEPING
,
128 .identity
= "NVIDIA Tegra186 WDT",
131 static void tegra186_wdt_disable(struct tegra186_wdt
*wdt
)
133 /* unlock and disable the watchdog */
134 wdt_writel(wdt
, WDTUR_UNLOCK_PATTERN
, WDTUR
);
135 wdt_writel(wdt
, WDTCMDR_DISABLE_COUNTER
, WDTCMDR
);
138 tmr_writel(wdt
->tmr
, 0, TMRCR
);
141 static void tegra186_wdt_enable(struct tegra186_wdt
*wdt
)
143 struct tegra186_timer
*tegra
= wdt
->tmr
->parent
;
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
));
150 /* clear interrupt */
151 tmr_writel(wdt
->tmr
, TMRSR_INTR_CLR
, TMRSR
);
153 /* select microsecond source */
154 tmr_writel(wdt
->tmr
, TMRCSSR_SRC_USEC
, TMRCSSR
);
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
);
162 value
= wdt_readl(wdt
, WDTCR
);
164 /* select the proper timer source */
165 value
&= ~WDTCR_TIMER_SOURCE_MASK
;
166 value
|= WDTCR_TIMER_SOURCE(wdt
->tmr
->index
);
168 /* single timer period since that's already configured */
169 value
&= ~WDTCR_PERIOD_MASK
;
170 value
|= WDTCR_PERIOD(1);
172 /* enable local interrupt for WDT petting */
173 value
|= WDTCR_LOCAL_INT_ENABLE
;
175 /* enable local FIQ and remote interrupt for debug dump */
177 value
|= WDTCR_REMOTE_INT_ENABLE
|
178 WDTCR_LOCAL_FIQ_ENABLE
;
180 /* enable system debug reset (doesn't properly reboot) */
182 value
|= WDTCR_SYSTEM_DEBUG_RESET_ENABLE
;
184 /* enable system POR reset */
185 value
|= WDTCR_SYSTEM_POR_RESET_ENABLE
;
187 wdt_writel(wdt
, value
, WDTCR
);
190 wdt_writel(wdt
, WDTCMDR_START_COUNTER
, WDTCMDR
);
193 static int tegra186_wdt_start(struct watchdog_device
*wdd
)
195 struct tegra186_wdt
*wdt
= to_tegra186_wdt(wdd
);
197 tegra186_wdt_enable(wdt
);
202 static int tegra186_wdt_stop(struct watchdog_device
*wdd
)
204 struct tegra186_wdt
*wdt
= to_tegra186_wdt(wdd
);
206 tegra186_wdt_disable(wdt
);
211 static int tegra186_wdt_ping(struct watchdog_device
*wdd
)
213 struct tegra186_wdt
*wdt
= to_tegra186_wdt(wdd
);
215 tegra186_wdt_disable(wdt
);
216 tegra186_wdt_enable(wdt
);
221 static int tegra186_wdt_set_timeout(struct watchdog_device
*wdd
,
222 unsigned int timeout
)
224 struct tegra186_wdt
*wdt
= to_tegra186_wdt(wdd
);
226 if (watchdog_active(&wdt
->base
))
227 tegra186_wdt_disable(wdt
);
229 wdt
->base
.timeout
= timeout
;
231 if (watchdog_active(&wdt
->base
))
232 tegra186_wdt_enable(wdt
);
237 static 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
,
245 static struct tegra186_wdt
*tegra186_wdt_create(struct tegra186_timer
*tegra
,
248 unsigned int offset
= 0x10000, source
;
249 struct tegra186_wdt
*wdt
;
253 offset
+= tegra
->soc
->num_timers
* 0x10000 + index
* 0x10000;
255 wdt
= devm_kzalloc(tegra
->dev
, sizeof(*wdt
), GFP_KERNEL
);
257 return ERR_PTR(-ENOMEM
);
259 wdt
->regs
= tegra
->regs
+ offset
;
262 /* read the watchdog configuration since it might be locked down */
263 value
= wdt_readl(wdt
, WDTCR
);
265 if (value
& WDTCR_LOCAL_INT_ENABLE
)
268 source
= value
& WDTCR_TIMER_SOURCE_MASK
;
270 wdt
->tmr
= tegra186_tmr_create(tegra
, source
);
271 if (IS_ERR(wdt
->tmr
))
272 return ERR_CAST(wdt
->tmr
);
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
;
280 err
= watchdog_init_timeout(&wdt
->base
, 5, tegra
->dev
);
282 dev_err(tegra
->dev
, "failed to initialize timeout: %d\n", err
);
286 err
= devm_watchdog_register_device(tegra
->dev
, &wdt
->base
);
288 dev_err(tegra
->dev
, "failed to register WDT: %d\n", err
);
295 static u64
tegra186_timer_tsc_read(struct clocksource
*cs
)
297 struct tegra186_timer
*tegra
= container_of(cs
, struct tegra186_timer
,
301 hi
= readl_relaxed(tegra
->regs
+ TKETSC1
);
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.
309 /* snapshot the high 24 bits */
312 lo
= readl_relaxed(tegra
->regs
+ TKETSC0
);
313 hi
= readl_relaxed(tegra
->regs
+ TKETSC1
);
316 return (u64
)hi
<< 32 | lo
;
319 static int tegra186_timer_tsc_init(struct tegra186_timer
*tegra
)
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
;
327 return clocksource_register_hz(&tegra
->tsc
, 31250000);
330 static u64
tegra186_timer_osc_read(struct clocksource
*cs
)
332 struct tegra186_timer
*tegra
= container_of(cs
, struct tegra186_timer
,
335 return readl_relaxed(tegra
->regs
+ TKEOSC
);
338 static int tegra186_timer_osc_init(struct tegra186_timer
*tegra
)
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
;
346 return clocksource_register_hz(&tegra
->osc
, 38400000);
349 static u64
tegra186_timer_usec_read(struct clocksource
*cs
)
351 struct tegra186_timer
*tegra
= container_of(cs
, struct tegra186_timer
,
354 return readl_relaxed(tegra
->regs
+ TKEUSEC
);
357 static int tegra186_timer_usec_init(struct tegra186_timer
*tegra
)
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
;
365 return clocksource_register_hz(&tegra
->usec
, USEC_PER_SEC
);
368 static irqreturn_t
tegra186_timer_irq(int irq
, void *data
)
370 struct tegra186_timer
*tegra
= data
;
372 if (watchdog_active(&tegra
->wdt
->base
)) {
373 tegra186_wdt_disable(tegra
->wdt
);
374 tegra186_wdt_enable(tegra
->wdt
);
380 static int tegra186_timer_probe(struct platform_device
*pdev
)
382 struct device
*dev
= &pdev
->dev
;
383 struct tegra186_timer
*tegra
;
387 tegra
= devm_kzalloc(dev
, sizeof(*tegra
), GFP_KERNEL
);
391 tegra
->soc
= of_device_get_match_data(dev
);
392 dev_set_drvdata(dev
, tegra
);
395 tegra
->regs
= devm_platform_ioremap_resource(pdev
, 0);
396 if (IS_ERR(tegra
->regs
))
397 return PTR_ERR(tegra
->regs
);
399 err
= platform_get_irq(pdev
, 0);
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
);
413 err
= tegra186_timer_tsc_init(tegra
);
415 dev_err(dev
, "failed to register TSC counter: %d\n", err
);
419 err
= tegra186_timer_osc_init(tegra
);
421 dev_err(dev
, "failed to register OSC counter: %d\n", err
);
425 err
= tegra186_timer_usec_init(tegra
);
427 dev_err(dev
, "failed to register USEC counter: %d\n", err
);
431 err
= devm_request_irq(dev
, irq
, tegra186_timer_irq
, 0,
432 "tegra186-timer", tegra
);
434 dev_err(dev
, "failed to request IRQ#%u: %d\n", irq
, err
);
435 goto unregister_usec
;
441 clocksource_unregister(&tegra
->usec
);
443 clocksource_unregister(&tegra
->osc
);
445 clocksource_unregister(&tegra
->tsc
);
449 static void tegra186_timer_remove(struct platform_device
*pdev
)
451 struct tegra186_timer
*tegra
= platform_get_drvdata(pdev
);
453 clocksource_unregister(&tegra
->usec
);
454 clocksource_unregister(&tegra
->osc
);
455 clocksource_unregister(&tegra
->tsc
);
458 static int __maybe_unused
tegra186_timer_suspend(struct device
*dev
)
460 struct tegra186_timer
*tegra
= dev_get_drvdata(dev
);
462 if (watchdog_active(&tegra
->wdt
->base
))
463 tegra186_wdt_disable(tegra
->wdt
);
468 static int __maybe_unused
tegra186_timer_resume(struct device
*dev
)
470 struct tegra186_timer
*tegra
= dev_get_drvdata(dev
);
472 if (watchdog_active(&tegra
->wdt
->base
))
473 tegra186_wdt_enable(tegra
->wdt
);
478 static SIMPLE_DEV_PM_OPS(tegra186_timer_pm_ops
, tegra186_timer_suspend
,
479 tegra186_timer_resume
);
481 static const struct tegra186_timer_soc tegra186_timer
= {
486 static const struct tegra186_timer_soc tegra234_timer
= {
491 static 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
},
496 MODULE_DEVICE_TABLE(of
, tegra186_timer_of_match
);
498 static struct platform_driver tegra186_wdt_driver
= {
500 .name
= "tegra186-timer",
501 .pm
= &tegra186_timer_pm_ops
,
502 .of_match_table
= tegra186_timer_of_match
,
504 .probe
= tegra186_timer_probe
,
505 .remove
= tegra186_timer_remove
,
507 module_platform_driver(tegra186_wdt_driver
);
509 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
510 MODULE_DESCRIPTION("NVIDIA Tegra186 timers driver");