Lines Matching +full:tegra30 +full:- +full:tsensor
1 // SPDX-License-Identifier: GPL-2.0
3 * Tegra30 SoC Thermal Sensor driver
9 * Copyright (C) 2021 GRATE-DRIVER project
96 err = reset_control_assert(ts->rst); in tegra_tsensor_hw_enable()
98 dev_err(ts->dev, "failed to assert hardware reset: %d\n", err); in tegra_tsensor_hw_enable()
102 err = clk_prepare_enable(ts->clk); in tegra_tsensor_hw_enable()
104 dev_err(ts->dev, "failed to enable clock: %d\n", err); in tegra_tsensor_hw_enable()
110 err = reset_control_deassert(ts->rst); in tegra_tsensor_hw_enable()
112 dev_err(ts->dev, "failed to deassert hardware reset: %d\n", err); in tegra_tsensor_hw_enable()
129 writel_relaxed(val, ts->regs + 0x40 + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_hw_enable()
130 writel_relaxed(val, ts->regs + 0x80 + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_hw_enable()
135 clk_disable_unprepare(ts->clk); in tegra_tsensor_hw_enable()
144 err = reset_control_assert(ts->rst); in tegra_tsensor_hw_disable()
146 dev_err(ts->dev, "failed to assert hardware reset: %d\n", err); in tegra_tsensor_hw_disable()
150 clk_disable_unprepare(ts->clk); in tegra_tsensor_hw_disable()
164 const struct tegra_tsensor_channel *tsc = tz->devdata; in tegra_tsensor_get_temp()
165 const struct tegra_tsensor *ts = tsc->ts; in tegra_tsensor_get_temp()
173 err = readl_relaxed_poll_timeout(tsc->regs + TSENSOR_SENSOR0_STATUS0, val, in tegra_tsensor_get_temp()
178 dev_err_once(ts->dev, "ch%u: counter invalid\n", tsc->id); in tegra_tsensor_get_temp()
182 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_TS_STATUS1); in tegra_tsensor_get_temp()
191 dev_err_once(ts->dev, "ch%u: counter overflow\n", tsc->id); in tegra_tsensor_get_temp()
192 return -EINVAL; in tegra_tsensor_get_temp()
199 c1 = DIV_ROUND_CLOSEST(ts->calib.a * counter + ts->calib.b, 1000000); in tegra_tsensor_get_temp()
201 c2 = DIV_ROUND_CLOSEST(ts->calib.p, c1); in tegra_tsensor_get_temp()
202 c3 = c1 * ts->calib.m; in tegra_tsensor_get_temp()
203 c4 = ts->calib.n; in tegra_tsensor_get_temp()
214 c1 = DIV_ROUND_CLOSEST(ts->calib.p - temp * 1000, ts->calib.m); in tegra_tsensor_temp_to_counter()
215 c2 = -ts->calib.r - int_sqrt(ts->calib.r * ts->calib.r - c1); in tegra_tsensor_temp_to_counter()
217 return DIV_ROUND_CLOSEST(c2 * 1000000 - ts->calib.b, ts->calib.a); in tegra_tsensor_temp_to_counter()
222 const struct tegra_tsensor_channel *tsc = tz->devdata; in tegra_tsensor_set_trips()
223 const struct tegra_tsensor *ts = tsc->ts; in tegra_tsensor_set_trips()
227 * TSENSOR doesn't trigger interrupt on the "low" temperature breach, in tegra_tsensor_set_trips()
233 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG1); in tegra_tsensor_set_trips()
238 writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG1); in tegra_tsensor_set_trips()
252 const struct tegra_tsensor_channel *tsc = &ts->ch[id]; in tegra_tsensor_handle_channel_interrupt()
255 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_STATUS0); in tegra_tsensor_handle_channel_interrupt()
256 writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_STATUS0); in tegra_tsensor_handle_channel_interrupt()
259 dev_err_ratelimited(ts->dev, "ch%u: counter overflowed\n", id); in tegra_tsensor_handle_channel_interrupt()
264 thermal_zone_device_update(tsc->tzd, THERMAL_EVENT_UNSPECIFIED); in tegra_tsensor_handle_channel_interrupt()
275 for (i = 0; i < ARRAY_SIZE(ts->ch); i++) in tegra_tsensor_isr()
284 const struct tegra_tsensor_channel *tsc = &ts->ch[id]; in tegra_tsensor_disable_hw_channel()
285 struct thermal_zone_device *tzd = tsc->tzd; in tegra_tsensor_disable_hw_channel()
294 dev_err(ts->dev, "ch%u: failed to disable zone: %d\n", id, err); in tegra_tsensor_disable_hw_channel()
300 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_disable_hw_channel()
302 writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_disable_hw_channel()
313 * 90C is the maximal critical temperature of all Tegra30 SoC variants, in tegra_tsensor_get_hw_channel_trips()
314 * use it for the default trip if unspecified in a device-tree. in tegra_tsensor_get_hw_channel_trips()
319 for (i = 0; i < tzd->num_trips; i++) { in tegra_tsensor_get_hw_channel_trips()
323 tzd->ops->get_trip_temp(tzd, i, &trip_temp); in tegra_tsensor_get_hw_channel_trips()
324 tzd->ops->get_trip_type(tzd, i, &type); in tegra_tsensor_get_hw_channel_trips()
349 const struct tegra_tsensor_channel *tsc = &ts->ch[id]; in tegra_tsensor_enable_hw_channel()
350 struct thermal_zone_device *tzd = tsc->tzd; in tegra_tsensor_enable_hw_channel()
355 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_enable_hw_channel()
357 writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_enable_hw_channel()
365 mutex_lock(&tzd->lock); in tegra_tsensor_enable_hw_channel()
367 dev_info_once(ts->dev, "ch%u: PMC emergency shutdown trip set to %dC\n", in tegra_tsensor_enable_hw_channel()
374 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG1); in tegra_tsensor_enable_hw_channel()
377 writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG1); in tegra_tsensor_enable_hw_channel()
380 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG2); in tegra_tsensor_enable_hw_channel()
383 writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG2); in tegra_tsensor_enable_hw_channel()
399 val = readl_relaxed(tsc->regs + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_enable_hw_channel()
407 writel_relaxed(val, tsc->regs + TSENSOR_SENSOR0_CONFIG0); in tegra_tsensor_enable_hw_channel()
409 mutex_unlock(&tzd->lock); in tegra_tsensor_enable_hw_channel()
413 dev_err(ts->dev, "ch%u: failed to enable zone: %d\n", id, err); in tegra_tsensor_enable_hw_channel()
436 dev_err_probe(ts->dev, err, "failed to get ATE version\n"); in tegra_tsensor_nvmem_setup()
441 dev_info(ts->dev, "unsupported ATE version: %u\n", ate_ver); in tegra_tsensor_nvmem_setup()
442 return -ENODEV; in tegra_tsensor_nvmem_setup()
446 * We have two TSENSOR channels in a two different spots on SoC. in tegra_tsensor_nvmem_setup()
451 dev_info_once(ts->dev, in tegra_tsensor_nvmem_setup()
453 ts->swap_channels = true; in tegra_tsensor_nvmem_setup()
458 dev_err(ts->dev, "failed to get calibration data: %d\n", err); in tegra_tsensor_nvmem_setup()
475 if (c2_90C - c1_25C <= t2_90C - t1_25C) { in tegra_tsensor_nvmem_setup()
476 dev_err(ts->dev, "invalid calibration data: %d %d %u %u\n", in tegra_tsensor_nvmem_setup()
478 return -EINVAL; in tegra_tsensor_nvmem_setup()
483 ts->calib.a = DIV_ROUND_CLOSEST((t2_90C - t1_25C) * 1000000, in tegra_tsensor_nvmem_setup()
484 (c2_90C - c1_25C)); in tegra_tsensor_nvmem_setup()
486 ts->calib.b = t1_25C * 1000000 - ts->calib.a * c1_25C; in tegra_tsensor_nvmem_setup()
489 ts->calib.m = -2775; in tegra_tsensor_nvmem_setup()
490 ts->calib.n = 1338811; in tegra_tsensor_nvmem_setup()
491 ts->calib.p = -7300000; in tegra_tsensor_nvmem_setup()
493 ts->calib.m = -3512; in tegra_tsensor_nvmem_setup()
494 ts->calib.n = 1528943; in tegra_tsensor_nvmem_setup()
495 ts->calib.p = -11100000; in tegra_tsensor_nvmem_setup()
499 ts->calib.r = DIV_ROUND_CLOSEST(ts->calib.n, ts->calib.m * 2); in tegra_tsensor_nvmem_setup()
501 dev_info_once(ts->dev, in tegra_tsensor_nvmem_setup()
512 struct tegra_tsensor_channel *tsc = &ts->ch[id]; in tegra_tsensor_register_channel()
513 unsigned int hw_id = ts->swap_channels ? !id : id; in tegra_tsensor_register_channel()
515 tsc->ts = ts; in tegra_tsensor_register_channel()
516 tsc->id = id; in tegra_tsensor_register_channel()
517 tsc->regs = ts->regs + 0x40 * (hw_id + 1); in tegra_tsensor_register_channel()
519 tsc->tzd = devm_thermal_of_zone_register(ts->dev, id, tsc, &ops); in tegra_tsensor_register_channel()
520 if (IS_ERR(tsc->tzd)) { in tegra_tsensor_register_channel()
521 if (PTR_ERR(tsc->tzd) != -ENODEV) in tegra_tsensor_register_channel()
522 return dev_err_probe(ts->dev, PTR_ERR(tsc->tzd), in tegra_tsensor_register_channel()
527 * in a device-tree. in tegra_tsensor_register_channel()
529 tsc->tzd = NULL; in tegra_tsensor_register_channel()
533 if (devm_thermal_add_hwmon_sysfs(tsc->tzd)) in tegra_tsensor_register_channel()
534 dev_warn(ts->dev, "failed to add hwmon sysfs attributes\n"); in tegra_tsensor_register_channel()
545 ts = devm_kzalloc(&pdev->dev, sizeof(*ts), GFP_KERNEL); in tegra_tsensor_probe()
547 return -ENOMEM; in tegra_tsensor_probe()
553 ts->dev = &pdev->dev; in tegra_tsensor_probe()
556 ts->regs = devm_platform_ioremap_resource(pdev, 0); in tegra_tsensor_probe()
557 if (IS_ERR(ts->regs)) in tegra_tsensor_probe()
558 return PTR_ERR(ts->regs); in tegra_tsensor_probe()
560 ts->clk = devm_clk_get(&pdev->dev, NULL); in tegra_tsensor_probe()
561 if (IS_ERR(ts->clk)) in tegra_tsensor_probe()
562 return dev_err_probe(&pdev->dev, PTR_ERR(ts->clk), in tegra_tsensor_probe()
565 ts->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); in tegra_tsensor_probe()
566 if (IS_ERR(ts->rst)) in tegra_tsensor_probe()
567 return dev_err_probe(&pdev->dev, PTR_ERR(ts->rst), in tegra_tsensor_probe()
578 err = devm_add_action_or_reset(&pdev->dev, in tegra_tsensor_probe()
584 for (i = 0; i < ARRAY_SIZE(ts->ch); i++) { in tegra_tsensor_probe()
590 err = devm_request_threaded_irq(&pdev->dev, irq, NULL, in tegra_tsensor_probe()
594 return dev_err_probe(&pdev->dev, err, in tegra_tsensor_probe()
597 for (i = 0; i < ARRAY_SIZE(ts->ch); i++) { in tegra_tsensor_probe()
612 for (i = 0; i < ARRAY_SIZE(ts->ch); i++) { in tegra_tsensor_suspend()
625 while (i--) in tegra_tsensor_suspend()
641 for (i = 0; i < ARRAY_SIZE(ts->ch); i++) { in tegra_tsensor_resume()
656 { .compatible = "nvidia,tegra30-tsensor", },
664 .name = "tegra30-tsensor",
671 MODULE_DESCRIPTION("NVIDIA Tegra30 Thermal Sensor driver");