soctherm.c (d7180be0d580ffc721da873dfa006680a9f14e63) soctherm.c (5c9d6ac23170e672101bce965a8180af24c40adb)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2014 - 2018, NVIDIA CORPORATION. All rights reserved.
4 *
5 * Author:
6 * Mikko Perttunen <mperttunen@nvidia.com>
7 *
8 * This software is licensed under the terms of the GNU General Public

--- 73 unchanged lines hidden (view full) ---

82#define THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY 0x2
83#define THERMCTL_LVL0_CPU0_MEM_THROT_MASK BIT(2)
84#define THERMCTL_LVL0_CPU0_STATUS_MASK 0x3
85
86#define THERMCTL_LVL0_UP_STATS 0x10
87#define THERMCTL_LVL0_DN_STATS 0x14
88
89#define THERMCTL_INTR_STATUS 0x84
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2014 - 2018, NVIDIA CORPORATION. All rights reserved.
4 *
5 * Author:
6 * Mikko Perttunen <mperttunen@nvidia.com>
7 *
8 * This software is licensed under the terms of the GNU General Public

--- 73 unchanged lines hidden (view full) ---

82#define THERMCTL_LVL0_CPU0_GPU_THROT_HEAVY 0x2
83#define THERMCTL_LVL0_CPU0_MEM_THROT_MASK BIT(2)
84#define THERMCTL_LVL0_CPU0_STATUS_MASK 0x3
85
86#define THERMCTL_LVL0_UP_STATS 0x10
87#define THERMCTL_LVL0_DN_STATS 0x14
88
89#define THERMCTL_INTR_STATUS 0x84
90#define THERMCTL_INTR_ENABLE 0x88
91#define THERMCTL_INTR_DISABLE 0x8c
92
93#define TH_INTR_MD0_MASK BIT(25)
94#define TH_INTR_MU0_MASK BIT(24)
95#define TH_INTR_GD0_MASK BIT(17)
96#define TH_INTR_GU0_MASK BIT(16)
97#define TH_INTR_CD0_MASK BIT(9)
98#define TH_INTR_CU0_MASK BIT(8)
99#define TH_INTR_PD0_MASK BIT(1)

--- 160 unchanged lines hidden (view full) ---

260
261 u32 *calib;
262 struct thermal_zone_device **thermctl_tzs;
263 struct tegra_soctherm_soc *soc;
264
265 struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
266
267 struct dentry *debugfs_dir;
90
91#define TH_INTR_MD0_MASK BIT(25)
92#define TH_INTR_MU0_MASK BIT(24)
93#define TH_INTR_GD0_MASK BIT(17)
94#define TH_INTR_GU0_MASK BIT(16)
95#define TH_INTR_CD0_MASK BIT(9)
96#define TH_INTR_CU0_MASK BIT(8)
97#define TH_INTR_PD0_MASK BIT(1)

--- 160 unchanged lines hidden (view full) ---

258
259 u32 *calib;
260 struct thermal_zone_device **thermctl_tzs;
261 struct tegra_soctherm_soc *soc;
262
263 struct soctherm_throt_cfg throt_cfgs[THROTTLE_SIZE];
264
265 struct dentry *debugfs_dir;
266
267 struct mutex thermctl_lock;
268};
269
270/**
271 * ccroc_writel() - writes a value to a CCROC register
272 * @ts: pointer to a struct tegra_soctherm
273 * @v: the value to write
274 * @reg: the register offset
275 *

--- 292 unchanged lines hidden (view full) ---

568 *trend = THERMAL_TREND_DROPPING;
569 } else {
570 *trend = THERMAL_TREND_STABLE;
571 }
572
573 return 0;
574}
575
268};
269
270/**
271 * ccroc_writel() - writes a value to a CCROC register
272 * @ts: pointer to a struct tegra_soctherm
273 * @v: the value to write
274 * @reg: the register offset
275 *

--- 292 unchanged lines hidden (view full) ---

568 *trend = THERMAL_TREND_DROPPING;
569 } else {
570 *trend = THERMAL_TREND_STABLE;
571 }
572
573 return 0;
574}
575
576static void thermal_irq_enable(struct tegra_thermctl_zone *zn)
577{
578 u32 r;
579
580 /* multiple zones could be handling and setting trips at once */
581 mutex_lock(&zn->ts->thermctl_lock);
582 r = readl(zn->ts->regs + THERMCTL_INTR_ENABLE);
583 r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, TH_INTR_UP_DN_EN);
584 writel(r, zn->ts->regs + THERMCTL_INTR_ENABLE);
585 mutex_unlock(&zn->ts->thermctl_lock);
586}
587
588static void thermal_irq_disable(struct tegra_thermctl_zone *zn)
589{
590 u32 r;
591
592 /* multiple zones could be handling and setting trips at once */
593 mutex_lock(&zn->ts->thermctl_lock);
594 r = readl(zn->ts->regs + THERMCTL_INTR_DISABLE);
595 r = REG_SET_MASK(r, zn->sg->thermctl_isr_mask, 0);
596 writel(r, zn->ts->regs + THERMCTL_INTR_DISABLE);
597 mutex_unlock(&zn->ts->thermctl_lock);
598}
599
600static int tegra_thermctl_set_trips(void *data, int lo, int hi)
601{
602 struct tegra_thermctl_zone *zone = data;
603 u32 r;
604
605 thermal_irq_disable(zone);
606
607 r = readl(zone->ts->regs + zone->sg->thermctl_lvl0_offset);
608 r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 0);
609 writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
610
611 lo = enforce_temp_range(zone->dev, lo) / zone->ts->soc->thresh_grain;
612 hi = enforce_temp_range(zone->dev, hi) / zone->ts->soc->thresh_grain;
613 dev_dbg(zone->dev, "%s hi:%d, lo:%d\n", __func__, hi, lo);
614
615 r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_up_thresh_mask, hi);
616 r = REG_SET_MASK(r, zone->sg->thermctl_lvl0_dn_thresh_mask, lo);
617 r = REG_SET_MASK(r, THERMCTL_LVL0_CPU0_EN_MASK, 1);
618 writel(r, zone->ts->regs + zone->sg->thermctl_lvl0_offset);
619
620 thermal_irq_enable(zone);
621
622 return 0;
623}
624
576static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
577 .get_temp = tegra_thermctl_get_temp,
578 .set_trip_temp = tegra_thermctl_set_trip_temp,
579 .get_trend = tegra_thermctl_get_trend,
625static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
626 .get_temp = tegra_thermctl_get_temp,
627 .set_trip_temp = tegra_thermctl_set_trip_temp,
628 .get_trend = tegra_thermctl_get_trend,
629 .set_trips = tegra_thermctl_set_trips,
580};
581
582static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
583{
584 int ntrips, i, ret;
585 enum thermal_trip_type type;
586
587 ntrips = of_thermal_get_ntrips(tz);

--- 100 unchanged lines hidden (view full) ---

688 return 0;
689}
690
691static irqreturn_t soctherm_thermal_isr(int irq, void *dev_id)
692{
693 struct tegra_soctherm *ts = dev_id;
694 u32 r;
695
630};
631
632static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
633{
634 int ntrips, i, ret;
635 enum thermal_trip_type type;
636
637 ntrips = of_thermal_get_ntrips(tz);

--- 100 unchanged lines hidden (view full) ---

738 return 0;
739}
740
741static irqreturn_t soctherm_thermal_isr(int irq, void *dev_id)
742{
743 struct tegra_soctherm *ts = dev_id;
744 u32 r;
745
746 /* Case for no lock:
747 * Although interrupts are enabled in set_trips, there is still no need
748 * to lock here because the interrupts are disabled before programming
749 * new trip points. Hence there cant be a interrupt on the same sensor.
750 * An interrupt can however occur on a sensor while trips are being
751 * programmed on a different one. This beign a LEVEL interrupt won't
752 * cause a new interrupt but this is taken care of by the re-reading of
753 * the STATUS register in the thread function.
754 */
696 r = readl(ts->regs + THERMCTL_INTR_STATUS);
697 writel(r, ts->regs + THERMCTL_INTR_DISABLE);
698
699 return IRQ_WAKE_THREAD;
700}
701
702/**
703 * soctherm_thermal_isr_thread() - Handles a thermal interrupt request

--- 836 unchanged lines hidden (view full) ---

1540 soc = (struct tegra_soctherm_soc *)match->data;
1541 if (soc->num_ttgs > TEGRA124_SOCTHERM_SENSOR_NUM)
1542 return -EINVAL;
1543
1544 tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
1545 if (!tegra)
1546 return -ENOMEM;
1547
755 r = readl(ts->regs + THERMCTL_INTR_STATUS);
756 writel(r, ts->regs + THERMCTL_INTR_DISABLE);
757
758 return IRQ_WAKE_THREAD;
759}
760
761/**
762 * soctherm_thermal_isr_thread() - Handles a thermal interrupt request

--- 836 unchanged lines hidden (view full) ---

1599 soc = (struct tegra_soctherm_soc *)match->data;
1600 if (soc->num_ttgs > TEGRA124_SOCTHERM_SENSOR_NUM)
1601 return -EINVAL;
1602
1603 tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
1604 if (!tegra)
1605 return -ENOMEM;
1606
1607 mutex_init(&tegra->thermctl_lock);
1548 dev_set_drvdata(&pdev->dev, tegra);
1549
1550 tegra->soc = soc;
1551
1552 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1553 "soctherm-reg");
1554 tegra->regs = devm_ioremap_resource(&pdev->dev, res);
1555 if (IS_ERR(tegra->regs)) {

--- 187 unchanged lines hidden ---
1608 dev_set_drvdata(&pdev->dev, tegra);
1609
1610 tegra->soc = soc;
1611
1612 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
1613 "soctherm-reg");
1614 tegra->regs = devm_ioremap_resource(&pdev->dev, res);
1615 if (IS_ERR(tegra->regs)) {

--- 187 unchanged lines hidden ---