Lines Matching +full:cs +full:- +full:value +full:- +full:bit

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2019-2025 NVIDIA Corporation. All rights reserved.
27 #define TMRCR_ENABLE BIT(31)
28 #define TMRCR_PERIODIC BIT(30)
32 #define TMRSR_INTR_CLR BIT(30)
40 #define WDTCR_SYSTEM_POR_RESET_ENABLE BIT(16)
41 #define WDTCR_SYSTEM_DEBUG_RESET_ENABLE BIT(15)
42 #define WDTCR_REMOTE_INT_ENABLE BIT(14)
43 #define WDTCR_LOCAL_FIQ_ENABLE BIT(13)
44 #define WDTCR_LOCAL_INT_ENABLE BIT(12)
54 #define WDTCMDR_DISABLE_COUNTER BIT(1)
55 #define WDTCMDR_START_COUNTER BIT(0)
98 static void tmr_writel(struct tegra186_tmr *tmr, u32 value, unsigned int offset) in tmr_writel() argument
100 writel_relaxed(value, tmr->regs + offset); in tmr_writel()
103 static void wdt_writel(struct tegra186_wdt *wdt, u32 value, unsigned int offset) in wdt_writel() argument
105 writel_relaxed(value, wdt->regs + offset); in wdt_writel()
110 return readl_relaxed(wdt->regs + offset); in wdt_readl()
119 tmr = devm_kzalloc(tegra->dev, sizeof(*tmr), GFP_KERNEL); in tegra186_tmr_create()
121 return ERR_PTR(-ENOMEM); in tegra186_tmr_create()
123 tmr->parent = tegra; in tegra186_tmr_create()
124 tmr->regs = tegra->regs + offset; in tegra186_tmr_create()
125 tmr->index = index; in tegra186_tmr_create()
126 tmr->hwirq = 0; in tegra186_tmr_create()
143 tmr_writel(wdt->tmr, 0, TMRCR); in tegra186_wdt_disable()
148 struct tegra186_timer *tegra = wdt->tmr->parent; in tegra186_wdt_enable()
149 u32 value; in tegra186_wdt_enable() local
152 value = TKEIE_WDT_MASK(wdt->index, 1); in tegra186_wdt_enable()
153 writel(value, tegra->regs + TKEIE(wdt->tmr->hwirq)); in tegra186_wdt_enable()
156 tmr_writel(wdt->tmr, TMRSR_INTR_CLR, TMRSR); in tegra186_wdt_enable()
159 tmr_writel(wdt->tmr, TMRCSSR_SRC_USEC, TMRCSSR); in tegra186_wdt_enable()
162 value = TMRCR_PTV(wdt->base.timeout * USEC_PER_SEC / 5) | in tegra186_wdt_enable()
164 tmr_writel(wdt->tmr, value, TMRCR); in tegra186_wdt_enable()
166 if (!wdt->locked) { in tegra186_wdt_enable()
167 value = wdt_readl(wdt, WDTCR); in tegra186_wdt_enable()
170 value &= ~WDTCR_TIMER_SOURCE_MASK; in tegra186_wdt_enable()
171 value |= WDTCR_TIMER_SOURCE(wdt->tmr->index); in tegra186_wdt_enable()
174 value &= ~WDTCR_PERIOD_MASK; in tegra186_wdt_enable()
175 value |= WDTCR_PERIOD(1); in tegra186_wdt_enable()
178 value |= WDTCR_SYSTEM_POR_RESET_ENABLE; in tegra186_wdt_enable()
180 wdt_writel(wdt, value, WDTCR); in tegra186_wdt_enable()
219 if (watchdog_active(&wdt->base)) in tegra186_wdt_set_timeout()
222 wdt->base.timeout = timeout; in tegra186_wdt_set_timeout()
224 if (watchdog_active(&wdt->base)) in tegra186_wdt_set_timeout()
236 if (!watchdog_active(&wdt->base)) { in tegra186_wdt_get_timeleft()
244 * the actual value programmed into the counter is 1/5 of the in tegra186_wdt_get_timeleft()
245 * timeout value. Once the counter reaches 0, expiration count in tegra186_wdt_get_timeleft()
249 * 1. value of the current down counter in tegra186_wdt_get_timeleft()
254 * value between 0 and 4 in tegra186_wdt_get_timeleft()
256 val = readl_relaxed(wdt->regs + WDTSR); in tegra186_wdt_get_timeleft()
261 /* Get the current counter value in microsecond. */ in tegra186_wdt_get_timeleft()
262 val = readl_relaxed(wdt->tmr->regs + TMRSR); in tegra186_wdt_get_timeleft()
267 * counter value to the time of the counter expirations that in tegra186_wdt_get_timeleft()
270 timeleft += (((u64)wdt->base.timeout * USEC_PER_SEC) / 5) * (4 - expiration); in tegra186_wdt_get_timeleft()
273 * Convert the current counter value to seconds, in tegra186_wdt_get_timeleft()
300 u32 value; in tegra186_wdt_create() local
303 offset += tegra->soc->num_timers * 0x10000 + index * 0x10000; in tegra186_wdt_create()
305 wdt = devm_kzalloc(tegra->dev, sizeof(*wdt), GFP_KERNEL); in tegra186_wdt_create()
307 return ERR_PTR(-ENOMEM); in tegra186_wdt_create()
309 wdt->regs = tegra->regs + offset; in tegra186_wdt_create()
310 wdt->index = index; in tegra186_wdt_create()
313 value = wdt_readl(wdt, WDTCR); in tegra186_wdt_create()
315 if (value & WDTCR_LOCAL_INT_ENABLE) in tegra186_wdt_create()
316 wdt->locked = true; in tegra186_wdt_create()
318 source = value & WDTCR_TIMER_SOURCE_MASK; in tegra186_wdt_create()
320 wdt->tmr = tegra186_tmr_create(tegra, source); in tegra186_wdt_create()
321 if (IS_ERR(wdt->tmr)) in tegra186_wdt_create()
322 return ERR_CAST(wdt->tmr); in tegra186_wdt_create()
324 wdt->base.info = &tegra186_wdt_info; in tegra186_wdt_create()
325 wdt->base.ops = &tegra186_wdt_ops; in tegra186_wdt_create()
326 wdt->base.min_timeout = 1; in tegra186_wdt_create()
327 wdt->base.max_timeout = 255; in tegra186_wdt_create()
328 wdt->base.parent = tegra->dev; in tegra186_wdt_create()
330 err = watchdog_init_timeout(&wdt->base, 5, tegra->dev); in tegra186_wdt_create()
332 dev_err(tegra->dev, "failed to initialize timeout: %d\n", err); in tegra186_wdt_create()
336 err = devm_watchdog_register_device(tegra->dev, &wdt->base); in tegra186_wdt_create()
338 dev_err(tegra->dev, "failed to register WDT: %d\n", err); in tegra186_wdt_create()
345 static u64 tegra186_timer_tsc_read(struct clocksource *cs) in tegra186_timer_tsc_read() argument
347 struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer, in tegra186_timer_tsc_read()
351 hi = readl_relaxed(tegra->regs + TKETSC1); in tegra186_timer_tsc_read()
354 * The 56-bit value of the TSC is spread across two registers that are in tegra186_timer_tsc_read()
362 lo = readl_relaxed(tegra->regs + TKETSC0); in tegra186_timer_tsc_read()
363 hi = readl_relaxed(tegra->regs + TKETSC1); in tegra186_timer_tsc_read()
371 tegra->tsc.name = "tsc"; in tegra186_timer_tsc_init()
372 tegra->tsc.rating = 300; in tegra186_timer_tsc_init()
373 tegra->tsc.read = tegra186_timer_tsc_read; in tegra186_timer_tsc_init()
374 tegra->tsc.mask = CLOCKSOURCE_MASK(56); in tegra186_timer_tsc_init()
375 tegra->tsc.flags = CLOCK_SOURCE_IS_CONTINUOUS; in tegra186_timer_tsc_init()
377 return clocksource_register_hz(&tegra->tsc, 31250000); in tegra186_timer_tsc_init()
380 static u64 tegra186_timer_osc_read(struct clocksource *cs) in tegra186_timer_osc_read() argument
382 struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer, in tegra186_timer_osc_read()
385 return readl_relaxed(tegra->regs + TKEOSC); in tegra186_timer_osc_read()
390 tegra->osc.name = "osc"; in tegra186_timer_osc_init()
391 tegra->osc.rating = 300; in tegra186_timer_osc_init()
392 tegra->osc.read = tegra186_timer_osc_read; in tegra186_timer_osc_init()
393 tegra->osc.mask = CLOCKSOURCE_MASK(32); in tegra186_timer_osc_init()
394 tegra->osc.flags = CLOCK_SOURCE_IS_CONTINUOUS; in tegra186_timer_osc_init()
396 return clocksource_register_hz(&tegra->osc, 38400000); in tegra186_timer_osc_init()
399 static u64 tegra186_timer_usec_read(struct clocksource *cs) in tegra186_timer_usec_read() argument
401 struct tegra186_timer *tegra = container_of(cs, struct tegra186_timer, in tegra186_timer_usec_read()
404 return readl_relaxed(tegra->regs + TKEUSEC); in tegra186_timer_usec_read()
409 tegra->usec.name = "usec"; in tegra186_timer_usec_init()
410 tegra->usec.rating = 300; in tegra186_timer_usec_init()
411 tegra->usec.read = tegra186_timer_usec_read; in tegra186_timer_usec_init()
412 tegra->usec.mask = CLOCKSOURCE_MASK(32); in tegra186_timer_usec_init()
413 tegra->usec.flags = CLOCK_SOURCE_IS_CONTINUOUS; in tegra186_timer_usec_init()
415 return clocksource_register_hz(&tegra->usec, USEC_PER_SEC); in tegra186_timer_usec_init()
420 struct device *dev = &pdev->dev; in tegra186_timer_probe()
426 return -ENOMEM; in tegra186_timer_probe()
428 tegra->soc = of_device_get_match_data(dev); in tegra186_timer_probe()
430 tegra->dev = dev; in tegra186_timer_probe()
432 tegra->regs = devm_platform_ioremap_resource(pdev, 0); in tegra186_timer_probe()
433 if (IS_ERR(tegra->regs)) in tegra186_timer_probe()
434 return PTR_ERR(tegra->regs); in tegra186_timer_probe()
441 tegra->wdt = tegra186_wdt_create(tegra, 0); in tegra186_timer_probe()
442 if (IS_ERR(tegra->wdt)) { in tegra186_timer_probe()
443 err = PTR_ERR(tegra->wdt); in tegra186_timer_probe()
469 clocksource_unregister(&tegra->osc); in tegra186_timer_probe()
471 clocksource_unregister(&tegra->tsc); in tegra186_timer_probe()
479 clocksource_unregister(&tegra->usec); in tegra186_timer_remove()
480 clocksource_unregister(&tegra->osc); in tegra186_timer_remove()
481 clocksource_unregister(&tegra->tsc); in tegra186_timer_remove()
488 if (watchdog_active(&tegra->wdt->base)) in tegra186_timer_suspend()
489 tegra186_wdt_disable(tegra->wdt); in tegra186_timer_suspend()
498 if (watchdog_active(&tegra->wdt->base)) in tegra186_timer_resume()
499 tegra186_wdt_enable(tegra->wdt); in tegra186_timer_resume()
518 { .compatible = "nvidia,tegra186-timer", .data = &tegra186_timer },
519 { .compatible = "nvidia,tegra234-timer", .data = &tegra234_timer },
526 .name = "tegra186-timer",