Commit 040a3ead authored by Zhang Rui's avatar Zhang Rui

Merge branches 'thermal-soc', 'thermal-core', 'thermal-intel' and...

Merge branches 'thermal-soc', 'thermal-core', 'thermal-intel' and 'thermal-tegra-hw-throttle' into next
......@@ -10,8 +10,14 @@ Required properties :
- compatible : For Tegra124, must contain "nvidia,tegra124-soctherm".
For Tegra132, must contain "nvidia,tegra132-soctherm".
For Tegra210, must contain "nvidia,tegra210-soctherm".
- reg : Should contain 1 entry:
- reg : Should contain at least 2 entries for each entry in reg-names:
- SOCTHERM register set
- Tegra CAR register set: Required for Tegra124 and Tegra210.
- CCROC register set: Required for Tegra132.
- reg-names : Should contain at least 2 entries:
- soctherm-reg
- car-reg
- ccroc-reg
- interrupts : Defines the interrupt used by SOCTHERM
- clocks : Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
......@@ -25,17 +31,45 @@ Required properties :
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description
of this property. See <dt-bindings/thermal/tegra124-soctherm.h> for a
list of valid values when referring to thermal sensors.
- throttle-cfgs: A sub-node which is a container of configuration for each
hardware throttle events. These events can be set as cooling devices.
* throttle events: Sub-nodes must be named as "light" or "heavy".
Properties:
- nvidia,priority: Each throttles has its own throttle settings, so the
SW need to set priorities for various throttle, the HW arbiter can select
the final throttle settings.
Bigger value indicates higher priority, In general, higher priority
translates to lower target frequency. SW needs to ensure that critical
thermal alarms are given higher priority, and ensure that there is
no race if priority of two vectors is set to the same value.
The range of this value is 1~100.
- nvidia,cpu-throt-percent: This property is for Tegra124 and Tegra210.
It is the throttling depth of pulse skippers, it's the percentage
throttling.
- nvidia,cpu-throt-level: This property is only for Tegra132, it is the
level of pulse skippers, which used to throttle clock frequencies. It
indicates cpu clock throttling depth, and the depth can be programmed.
Must set as following values:
TEGRA_SOCTHERM_THROT_LEVEL_LOW, TEGRA_SOCTHERM_THROT_LEVEL_MED
TEGRA_SOCTHERM_THROT_LEVEL_HIGH, TEGRA_SOCTHERM_THROT_LEVEL_NONE
- #cooling-cells: Should be 1. This cooling device only support on/off state.
See ./thermal.txt for a description of this property.
Note:
- the "critical" type trip points will be set to SOC_THERM hardware as the
shut down temperature. Once the temperature of this thermal zone is higher
than it, the system will be shutdown or reset by hardware.
- the "hot" type trip points will be set to SOC_THERM hardware as the throttle
temperature. Once the the temperature of this thermal zone is higher
than it, it will trigger the HW throttle event.
Example :
soctherm@700e2000 {
compatible = "nvidia,tegra124-soctherm";
reg = <0x0 0x700e2000 0x0 0x1000>;
reg = <0x0 0x700e2000 0x0 0x600 /* SOC_THERM reg_base */
0x0 0x60006000 0x0 0x400 /* CAR reg_base */
reg-names = "soctherm-reg", "car-reg";
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA124_CLK_TSENSOR>,
<&tegra_car TEGRA124_CLK_SOC_THERM>;
......@@ -44,6 +78,76 @@ Example :
reset-names = "soctherm";
#thermal-sensor-cells = <1>;
throttle-cfgs {
/*
* When the "heavy" cooling device triggered,
* the HW will skip cpu clock's pulse in 85% depth
*/
throttle_heavy: heavy {
nvidia,priority = <100>;
nvidia,cpu-throt-percent = <85>;
#cooling-cells = <1>;
};
/*
* When the "light" cooling device triggered,
* the HW will skip cpu clock's pulse in 50% depth
*/
throttle_light: light {
nvidia,priority = <80>;
nvidia,cpu-throt-percent = <50>;
#cooling-cells = <1>;
};
/*
* If these two devices are triggered in same time, the HW throttle
* arbiter will select the highest priority as the final throttle
* settings to skip cpu pulse.
*/
};
};
Example: referring to Tegra132's "reg", "reg-names" and "throttle-cfgs" :
soctherm@700e2000 {
compatible = "nvidia,tegra132-soctherm";
reg = <0x0 0x700e2000 0x0 0x600 /* SOC_THERM reg_base */
0x0 0x70040000 0x0 0x200>; /* CCROC reg_base */;
reg-names = "soctherm-reg", "ccroc-reg";
throttle-cfgs {
/*
* When the "heavy" cooling device triggered,
* the HW will skip cpu clock's pulse in HIGH level
*/
throttle_heavy: heavy {
nvidia,priority = <100>;
nvidia,cpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_HIGH>;
#cooling-cells = <1>;
};
/*
* When the "light" cooling device triggered,
* the HW will skip cpu clock's pulse in MED level
*/
throttle_light: light {
nvidia,priority = <80>;
nvidia,cpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_MED>;
#cooling-cells = <1>;
};
/*
* If these two devices are triggered in same time, the HW throttle
* arbiter will select the highest priority as the final throttle
* settings to skip cpu pulse.
*/
};
};
Example: referring to thermal sensors :
......@@ -62,6 +166,19 @@ Example: referring to thermal sensors :
hysteresis = <1000>;
type = "critical";
};
cpu_throttle_trip: throttle-trip {
temperature = <100000>;
hysteresis = <1000>;
type = "hot";
};
};
cooling-maps {
map0 {
trip = <&cpu_throttle_trip>;
cooling-device = <&throttle_heavy 1 1>;
};
};
};
};
......@@ -2045,44 +2045,32 @@ sound {
thermal-zones {
cpu {
trips {
trip {
cpu-shutdown-trip {
temperature = <101000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
/* There are currently no cooling maps because there are no cooling devices */
};
};
mem {
trips {
trip {
mem-shutdown-trip {
temperature = <101000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
/* There are currently no cooling maps because there are no cooling devices */
};
};
gpu {
trips {
trip {
gpu-shutdown-trip {
temperature = <101000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
/* There are currently no cooling maps because there are no cooling devices */
};
};
};
};
......@@ -851,7 +851,9 @@ sdhci@700b0600 {
soctherm: thermal-sensor@700e2000 {
compatible = "nvidia,tegra124-soctherm";
reg = <0x0 0x700e2000 0x0 0x1000>;
reg = <0x0 0x700e2000 0x0 0x600 /* SOC_THERM reg_base */
0x0 0x60006000 0x0 0x400>; /* CAR reg_base */
reg-names = "soctherm-reg", "car-reg";
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA124_CLK_TSENSOR>,
<&tegra_car TEGRA124_CLK_SOC_THERM>;
......@@ -859,6 +861,15 @@ soctherm: thermal-sensor@700e2000 {
resets = <&tegra_car 78>;
reset-names = "soctherm";
#thermal-sensor-cells = <1>;
throttle-cfgs {
throttle_heavy: heavy {
nvidia,priority = <100>;
nvidia,cpu-throt-percent = <85>;
#cooling-cells = <2>;
};
};
};
dfll: clock@70110000 {
......@@ -1154,6 +1165,26 @@ cpu {
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
trips {
cpu-shutdown-trip {
temperature = <103000>;
hysteresis = <0>;
type = "critical";
};
cpu_throttle_trip: throttle-trip {
temperature = <100000>;
hysteresis = <1000>;
type = "hot";
};
};
cooling-maps {
map0 {
trip = <&cpu_throttle_trip>;
cooling-device = <&throttle_heavy 1 1>;
};
};
};
mem {
......@@ -1162,6 +1193,21 @@ mem {
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>;
trips {
mem-shutdown-trip {
temperature = <103000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
/*
* There are currently no cooling maps,
* because there are no cooling devices.
*/
};
};
gpu {
......@@ -1170,6 +1216,26 @@ gpu {
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>;
trips {
gpu-shutdown-trip {
temperature = <101000>;
hysteresis = <0>;
type = "critical";
};
gpu_throttle_trip: throttle-trip {
temperature = <99000>;
hysteresis = <1000>;
type = "hot";
};
};
cooling-maps {
map0 {
trip = <&gpu_throttle_trip>;
cooling-device = <&throttle_heavy 1 1>;
};
};
};
pllx {
......@@ -1178,6 +1244,21 @@ pllx {
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>;
trips {
pllx-shutdown-trip {
temperature = <103000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
/*
* There are currently no cooling maps,
* because there are no cooling devices.
*/
};
};
};
......
......@@ -4,6 +4,7 @@
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/thermal/tegra124-soctherm.h>
/ {
compatible = "nvidia,tegra132", "nvidia,tegra124";
......@@ -727,8 +728,10 @@ sdhci@700b0600 {
};
soctherm: thermal-sensor@700e2000 {
compatible = "nvidia,tegra124-soctherm";
reg = <0x0 0x700e2000 0x0 0x1000>;
compatible = "nvidia,tegra132-soctherm";
reg = <0x0 0x700e2000 0x0 0x600 /* 0: SOC_THERM reg_base */
0x0 0x70040000 0x0 0x200>; /* 2: CCROC reg_base */
reg-names = "soctherm-reg", "ccroc-reg";
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA124_CLK_TSENSOR>,
<&tegra_car TEGRA124_CLK_SOC_THERM>;
......@@ -736,6 +739,118 @@ soctherm: thermal-sensor@700e2000 {
resets = <&tegra_car 78>;
reset-names = "soctherm";
#thermal-sensor-cells = <1>;
throttle-cfgs {
throttle_heavy: heavy {
nvidia,priority = <100>;
nvidia,cpu-throt-level = <TEGRA_SOCTHERM_THROT_LEVEL_HIGH>;
#cooling-cells = <2>;
};
};
};
thermal-zones {
cpu {
polling-delay-passive = <1000>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
trips {
cpu_shutdown_trip {
temperature = <105000>;
hysteresis = <1000>;
type = "critical";
};
cpu_throttle_trip: throttle-trip {
temperature = <102000>;
hysteresis = <1000>;
type = "hot";
};
};
cooling-maps {
map0 {
trip = <&cpu_throttle_trip>;
cooling-device = <&throttle_heavy 1 1>;
};
};
};
mem {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>;
trips {
mem_shutdown_trip {
temperature = <101000>;
hysteresis = <1000>;
type = "critical";
};
};
cooling-maps {
/*
* There are currently no cooling maps,
* because there are no cooling devices.
*/
};
};
gpu {
polling-delay-passive = <1000>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>;
trips {
gpu_shutdown_trip {
temperature = <101000>;
hysteresis = <1000>;
type = "critical";
};
gpu_throttle_trip: throttle-trip {
temperature = <99000>;
hysteresis = <1000>;
type = "hot";
};
};
cooling-maps {
map0 {
trip = <&gpu_throttle_trip>;
cooling-device = <&throttle_heavy 1 1>;
};
};
};
pllx {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>;
trips {
pllx_shutdown_trip {
temperature = <105000>;
hysteresis = <1000>;
type = "critical";
};
};
cooling-maps {
/*
* There are currently no cooling maps,
* because there are no cooling devices.
*/
};
};
};
ahub@70300000 {
......
......@@ -3,6 +3,7 @@
#include <dt-bindings/memory/tegra210-mc.h>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/thermal/tegra124-soctherm.h>
/ {
compatible = "nvidia,tegra210";
......@@ -1094,4 +1095,130 @@ timer {
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
interrupt-parent = <&gic>;
};
soctherm: thermal-sensor@700e2000 {
compatible = "nvidia,tegra210-soctherm";
reg = <0x0 0x700e2000 0x0 0x600 /* SOC_THERM reg_base */
0x0 0x60006000 0x0 0x400>; /* CAR reg_base */
reg-names = "soctherm-reg", "car-reg";
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_TSENSOR>,
<&tegra_car TEGRA210_CLK_SOC_THERM>;
clock-names = "tsensor", "soctherm";
resets = <&tegra_car 78>;
reset-names = "soctherm";
#thermal-sensor-cells = <1>;
throttle-cfgs {
throttle_heavy: heavy {
nvidia,priority = <100>;
nvidia,cpu-throt-percent = <85>;
#cooling-cells = <2>;
};
};
};
thermal-zones {
cpu {
polling-delay-passive = <1000>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_CPU>;
trips {
cpu-shutdown-trip {
temperature = <102500>;
hysteresis = <0>;
type = "critical";
};
cpu_throttle_trip: throttle-trip {
temperature = <98500>;
hysteresis = <1000>;
type = "hot";
};
};
cooling-maps {
map0 {
trip = <&cpu_throttle_trip>;
cooling-device = <&throttle_heavy 1 1>;
};
};
};
mem {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_MEM>;
trips {
mem-shutdown-trip {
temperature = <103000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
/*
* There are currently no cooling maps,
* because there are no cooling devices.
*/
};
};
gpu {
polling-delay-passive = <1000>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_GPU>;
trips {
gpu-shutdown-trip {
temperature = <103000>;
hysteresis = <0>;
type = "critical";
};
gpu_throttle_trip: throttle-trip {
temperature = <100000>;
hysteresis = <1000>;
type = "hot";
};
};
cooling-maps {
map0 {
trip = <&gpu_throttle_trip>;
cooling-device = <&throttle_heavy 1 1>;
};
};
};
pllx {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors =
<&soctherm TEGRA124_SOCTHERM_SENSOR_PLLX>;
trips {
pllx-shutdown-trip {
temperature = <103000>;
hysteresis = <0>;
type = "critical";
};
};
cooling-maps {
/*
* There are currently no cooling maps,
* because there are no cooling devices.
*/
};
};
};
};
......@@ -352,6 +352,16 @@ menu "ACPI INT340X thermal drivers"
source drivers/thermal/int340x_thermal/Kconfig
endmenu
config INTEL_BXT_PMIC_THERMAL
tristate "Intel Broxton PMIC thermal driver"
depends on X86 && INTEL_SOC_PMIC && REGMAP
help
Select this driver for Intel Broxton PMIC with ADC channels monitoring
system temperature measurements and alerts.
This driver is used for monitoring the ADC channels of PMIC and handles
the alert trip point interrupts and notifies the thermal framework with
the trip point and temperature details of the zone.
config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
......
......@@ -47,6 +47,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL) += intel_soc_dts_thermal.o
obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL) += intel_quark_dts_thermal.o
obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/
obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/
obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o
obj-$(CONFIG_ST_THERMAL) += st/
obj-$(CONFIG_QCOM_TSENS) += qcom/
......
......@@ -74,7 +74,7 @@ struct power_table {
* cpufreq frequencies.
* @allowed_cpus: all the cpus involved for this cpufreq_cooling_device.
* @node: list_head to link all cpufreq_cooling_device together.
* @last_load: load measured by the latest call to cpufreq_get_actual_power()
* @last_load: load measured by the latest call to cpufreq_get_requested_power()
* @time_in_idle: previous reading of the absolute time that this cpu was idle
* @time_in_idle_timestamp: wall time of the last invocation of
* get_cpu_idle_time_us()
......
/*
* Intel Broxton PMIC thermal driver
*
* Copyright (C) 2016 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/thermal.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/mfd/intel_soc_pmic.h>
#define BXTWC_THRM0IRQ 0x4E04
#define BXTWC_THRM1IRQ 0x4E05
#define BXTWC_THRM2IRQ 0x4E06
#define BXTWC_MTHRM0IRQ 0x4E12
#define BXTWC_MTHRM1IRQ 0x4E13
#define BXTWC_MTHRM2IRQ 0x4E14
#define BXTWC_STHRM0IRQ 0x4F19
#define BXTWC_STHRM1IRQ 0x4F1A
#define BXTWC_STHRM2IRQ 0x4F1B
struct trip_config_map {
u16 irq_reg;
u16 irq_en;
u16 evt_stat;
u8 irq_mask;
u8 irq_en_mask;
u8 evt_mask;
u8 trip_num;
};
struct thermal_irq_map {
char handle[20];
int num_trips;
const struct trip_config_map *trip_config;
};
struct pmic_thermal_data {
const struct thermal_irq_map *maps;
int num_maps;
};
static const struct trip_config_map bxtwc_str0_trip_config[] = {
{
.irq_reg = BXTWC_THRM0IRQ,
.irq_mask = 0x01,
.irq_en = BXTWC_MTHRM0IRQ,
.irq_en_mask = 0x01,
.evt_stat = BXTWC_STHRM0IRQ,
.evt_mask = 0x01,
.trip_num = 0
},
{
.irq_reg = BXTWC_THRM0IRQ,
.irq_mask = 0x10,
.irq_en = BXTWC_MTHRM0IRQ,
.irq_en_mask = 0x10,
.evt_stat = BXTWC_STHRM0IRQ,
.evt_mask = 0x10,
.trip_num = 1
}
};
static const struct trip_config_map bxtwc_str1_trip_config[] = {
{
.irq_reg = BXTWC_THRM0IRQ,
.irq_mask = 0x02,
.irq_en = BXTWC_MTHRM0IRQ,
.irq_en_mask = 0x02,
.evt_stat = BXTWC_STHRM0IRQ,
.evt_mask = 0x02,
.trip_num = 0
},
{
.irq_reg = BXTWC_THRM0IRQ,
.irq_mask = 0x20,
.irq_en = BXTWC_MTHRM0IRQ,
.irq_en_mask = 0x20,
.evt_stat = BXTWC_STHRM0IRQ,
.evt_mask = 0x20,
.trip_num = 1
},
};
static const struct trip_config_map bxtwc_str2_trip_config[] = {
{
.irq_reg = BXTWC_THRM0IRQ,
.irq_mask = 0x04,
.irq_en = BXTWC_MTHRM0IRQ,
.irq_en_mask = 0x04,
.evt_stat = BXTWC_STHRM0IRQ,
.evt_mask = 0x04,
.trip_num = 0
},
{
.irq_reg = BXTWC_THRM0IRQ,
.irq_mask = 0x40,
.irq_en = BXTWC_MTHRM0IRQ,
.irq_en_mask = 0x40,
.evt_stat = BXTWC_STHRM0IRQ,
.evt_mask = 0x40,
.trip_num = 1
},
};
static const struct trip_config_map bxtwc_str3_trip_config[] = {
{
.irq_reg = BXTWC_THRM2IRQ,
.irq_mask = 0x10,
.irq_en = BXTWC_MTHRM2IRQ,
.irq_en_mask = 0x10,
.evt_stat = BXTWC_STHRM2IRQ,
.evt_mask = 0x10,
.trip_num = 0
},
};
static const struct thermal_irq_map bxtwc_thermal_irq_map[] = {
{
.handle = "STR0",
.trip_config = bxtwc_str0_trip_config,
.num_trips = ARRAY_SIZE(bxtwc_str0_trip_config),
},
{
.handle = "STR1",
.trip_config = bxtwc_str1_trip_config,
.num_trips = ARRAY_SIZE(bxtwc_str1_trip_config),
},
{
.handle = "STR2",
.trip_config = bxtwc_str2_trip_config,
.num_trips = ARRAY_SIZE(bxtwc_str2_trip_config),
},
{
.handle = "STR3",
.trip_config = bxtwc_str3_trip_config,
.num_trips = ARRAY_SIZE(bxtwc_str3_trip_config),
},
};
static const struct pmic_thermal_data bxtwc_thermal_data = {
.maps = bxtwc_thermal_irq_map,
.num_maps = ARRAY_SIZE(bxtwc_thermal_irq_map),
};
static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
{
struct platform_device *pdev = data;
struct thermal_zone_device *tzd;
struct pmic_thermal_data *td;
struct intel_soc_pmic *pmic;
struct regmap *regmap;
u8 reg_val, mask, irq_stat, trip;
u16 reg, evt_stat_reg;
int i, j, ret;
pmic = dev_get_drvdata(pdev->dev.parent);
regmap = pmic->regmap;
td = (struct pmic_thermal_data *)
platform_get_device_id(pdev)->driver_data;
/* Resolve thermal irqs */
for (i = 0; i < td->num_maps; i++) {
for (j = 0; j < td->maps[i].num_trips; j++) {
reg = td->maps[i].trip_config[j].irq_reg;
mask = td->maps[i].trip_config[j].irq_mask;
/*
* Read the irq register to resolve whether the
* interrupt was triggered for this sensor
*/
if (regmap_read(regmap, reg, &ret))
return IRQ_HANDLED;
reg_val = (u8)ret;
irq_stat = ((u8)ret & mask);
if (!irq_stat)
continue;
/*
* Read the status register to find out what
* event occurred i.e a high or a low
*/
evt_stat_reg = td->maps[i].trip_config[j].evt_stat;
if (regmap_read(regmap, evt_stat_reg, &ret))
return IRQ_HANDLED;
trip = td->maps[i].trip_config[j].trip_num;
tzd = thermal_zone_get_zone_by_name(td->maps[i].handle);
if (!IS_ERR(tzd))
thermal_zone_device_update(tzd);
/* Clear the appropriate irq */
regmap_write(regmap, reg, reg_val & mask);
}
}
return IRQ_HANDLED;
}
static int pmic_thermal_probe(struct platform_device *pdev)
{
struct regmap_irq_chip_data *regmap_irq_chip;
struct pmic_thermal_data *thermal_data;
int ret, irq, virq, i, j, pmic_irq_count;
struct intel_soc_pmic *pmic;
struct regmap *regmap;
struct device *dev;
u16 reg;
u8 mask;
dev = &pdev->dev;
pmic = dev_get_drvdata(pdev->dev.parent);
if (!pmic) {
dev_err(dev, "Failed to get struct intel_soc_pmic pointer\n");
return -ENODEV;
}
thermal_data = (struct pmic_thermal_data *)
platform_get_device_id(pdev)->driver_data;
if (!thermal_data) {
dev_err(dev, "No thermal data initialized!!\n");
return -ENODEV;
}
regmap = pmic->regmap;
regmap_irq_chip = pmic->irq_chip_data_level2;
pmic_irq_count = 0;
while ((irq = platform_get_irq(pdev, pmic_irq_count)) != -ENXIO) {
virq = regmap_irq_get_virq(regmap_irq_chip, irq);
if (virq < 0) {
dev_err(dev, "failed to get virq by irq %d\n", irq);
return virq;
}
ret = devm_request_threaded_irq(&pdev->dev, virq,
NULL, pmic_thermal_irq_handler,
IRQF_ONESHOT, "pmic_thermal", pdev);
if (ret) {
dev_err(dev, "request irq(%d) failed: %d\n", virq, ret);
return ret;
}
pmic_irq_count++;
}
/* Enable thermal interrupts */
for (i = 0; i < thermal_data->num_maps; i++) {
for (j = 0; j < thermal_data->maps[i].num_trips; j++) {
reg = thermal_data->maps[i].trip_config[j].irq_en;
mask = thermal_data->maps[i].trip_config[j].irq_en_mask;
ret = regmap_update_bits(regmap, reg, mask, 0x00);
if (ret)
return ret;
}
}
return 0;
}
static const struct platform_device_id pmic_thermal_id_table[] = {
{
.name = "bxt_wcove_thermal",
.driver_data = (kernel_ulong_t)&bxtwc_thermal_data,
},
{},
};
static struct platform_driver pmic_thermal_driver = {
.probe = pmic_thermal_probe,
.driver = {
.name = "pmic_thermal",
},
.id_table = pmic_thermal_id_table,
};
MODULE_DEVICE_TABLE(platform, pmic_thermal_id_table);
module_platform_driver(pmic_thermal_driver);
MODULE_AUTHOR("Yegnesh S Iyer <yegnesh.s.iyer@intel.com>");
MODULE_DESCRIPTION("Intel Broxton PMIC Thermal Driver");
MODULE_LICENSE("GPL v2");
This diff is collapsed.
......@@ -15,6 +15,11 @@
#ifndef __DRIVERS_THERMAL_TEGRA_SOCTHERM_H
#define __DRIVERS_THERMAL_TEGRA_SOCTHERM_H
#define THERMCTL_LEVEL0_GROUP_CPU 0x0
#define THERMCTL_LEVEL0_GROUP_GPU 0x4
#define THERMCTL_LEVEL0_GROUP_MEM 0x8
#define THERMCTL_LEVEL0_GROUP_TSENSE 0xc
#define SENSOR_CONFIG2 8
#define SENSOR_CONFIG2_THERMA_MASK (0xffff << 16)
#define SENSOR_CONFIG2_THERMA_SHIFT 16
......@@ -65,6 +70,9 @@ struct tegra_tsensor_group {
u32 thermtrip_enable_mask;
u32 thermtrip_any_en_mask;
u32 thermtrip_threshold_mask;
u16 thermctl_lvl0_offset;
u32 thermctl_lvl0_up_thresh_mask;
u32 thermctl_lvl0_dn_thresh_mask;
};
struct tegra_tsensor_configuration {
......@@ -103,6 +111,8 @@ struct tegra_soctherm_soc {
const unsigned int num_ttgs;
const struct tegra_soctherm_fuse *tfuse;
const int thresh_grain;
const unsigned int bptt;
const bool use_ccroc;
};
int tegra_calc_shared_calib(const struct tegra_soctherm_fuse *tfuse,
......
......@@ -28,7 +28,11 @@
#define TEGRA124_THERMTRIP_CPU_THRESH_MASK (0xff << 8)
#define TEGRA124_THERMTRIP_TSENSE_THRESH_MASK 0xff
#define TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK (0xff << 17)
#define TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK (0xff << 9)
#define TEGRA124_THRESH_GRAIN 1000
#define TEGRA124_BPTT 8
static const struct tegra_tsensor_configuration tegra124_tsensor_config = {
.tall = 16300,
......@@ -51,6 +55,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
.thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA124_THERMTRIP_CPU_EN_MASK,
.thermtrip_threshold_mask = TEGRA124_THERMTRIP_CPU_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
.thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
......@@ -66,6 +73,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
.thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA124_THERMTRIP_GPU_EN_MASK,
.thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
.thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra124_tsensor_group_pll = {
......@@ -79,6 +89,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_pll = {
.thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA124_THERMTRIP_TSENSE_EN_MASK,
.thermtrip_threshold_mask = TEGRA124_THERMTRIP_TSENSE_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
.thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra124_tsensor_group_mem = {
......@@ -94,6 +107,9 @@ static const struct tegra_tsensor_group tegra124_tsensor_group_mem = {
.thermtrip_any_en_mask = TEGRA124_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA124_THERMTRIP_MEM_EN_MASK,
.thermtrip_threshold_mask = TEGRA124_THERMTRIP_GPUMEM_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
.thermctl_lvl0_up_thresh_mask = TEGRA124_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA124_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group *tegra124_tsensor_groups[] = {
......@@ -193,4 +209,6 @@ const struct tegra_soctherm_soc tegra124_soctherm = {
.num_ttgs = ARRAY_SIZE(tegra124_tsensor_groups),
.tfuse = &tegra124_soctherm_fuse,
.thresh_grain = TEGRA124_THRESH_GRAIN,
.bptt = TEGRA124_BPTT,
.use_ccroc = false,
};
......@@ -28,7 +28,11 @@
#define TEGRA132_THERMTRIP_CPU_THRESH_MASK (0xff << 8)
#define TEGRA132_THERMTRIP_TSENSE_THRESH_MASK 0xff
#define TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK (0xff << 17)
#define TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK (0xff << 9)
#define TEGRA132_THRESH_GRAIN 1000
#define TEGRA132_BPTT 8
static const struct tegra_tsensor_configuration tegra132_tsensor_config = {
.tall = 16300,
......@@ -51,6 +55,9 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_cpu = {
.thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA132_THERMTRIP_CPU_EN_MASK,
.thermtrip_threshold_mask = TEGRA132_THERMTRIP_CPU_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
.thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra132_tsensor_group_gpu = {
......@@ -66,6 +73,9 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_gpu = {
.thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA132_THERMTRIP_GPU_EN_MASK,
.thermtrip_threshold_mask = TEGRA132_THERMTRIP_GPUMEM_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
.thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra132_tsensor_group_pll = {
......@@ -79,6 +89,9 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_pll = {
.thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA132_THERMTRIP_TSENSE_EN_MASK,
.thermtrip_threshold_mask = TEGRA132_THERMTRIP_TSENSE_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
.thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra132_tsensor_group_mem = {
......@@ -94,6 +107,9 @@ static const struct tegra_tsensor_group tegra132_tsensor_group_mem = {
.thermtrip_any_en_mask = TEGRA132_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA132_THERMTRIP_MEM_EN_MASK,
.thermtrip_threshold_mask = TEGRA132_THERMTRIP_GPUMEM_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
.thermctl_lvl0_up_thresh_mask = TEGRA132_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA132_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group *tegra132_tsensor_groups[] = {
......@@ -193,4 +209,6 @@ const struct tegra_soctherm_soc tegra132_soctherm = {
.num_ttgs = ARRAY_SIZE(tegra132_tsensor_groups),
.tfuse = &tegra132_soctherm_fuse,
.thresh_grain = TEGRA132_THRESH_GRAIN,
.bptt = TEGRA132_BPTT,
.use_ccroc = true,
};
......@@ -29,7 +29,11 @@
#define TEGRA210_THERMTRIP_CPU_THRESH_MASK (0x1ff << 9)
#define TEGRA210_THERMTRIP_TSENSE_THRESH_MASK 0x1ff
#define TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK (0x1ff << 18)
#define TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK (0x1ff << 9)
#define TEGRA210_THRESH_GRAIN 500
#define TEGRA210_BPTT 9
static const struct tegra_tsensor_configuration tegra210_tsensor_config = {
.tall = 16300,
......@@ -52,6 +56,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_cpu = {
.thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA210_THERMTRIP_CPU_EN_MASK,
.thermtrip_threshold_mask = TEGRA210_THERMTRIP_CPU_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_CPU,
.thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra210_tsensor_group_gpu = {
......@@ -67,6 +74,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_gpu = {
.thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA210_THERMTRIP_GPU_EN_MASK,
.thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_GPU,
.thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra210_tsensor_group_pll = {
......@@ -80,6 +90,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_pll = {
.thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA210_THERMTRIP_TSENSE_EN_MASK,
.thermtrip_threshold_mask = TEGRA210_THERMTRIP_TSENSE_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_TSENSE,
.thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group tegra210_tsensor_group_mem = {
......@@ -95,6 +108,9 @@ static const struct tegra_tsensor_group tegra210_tsensor_group_mem = {
.thermtrip_any_en_mask = TEGRA210_THERMTRIP_ANY_EN_MASK,
.thermtrip_enable_mask = TEGRA210_THERMTRIP_MEM_EN_MASK,
.thermtrip_threshold_mask = TEGRA210_THERMTRIP_GPUMEM_THRESH_MASK,
.thermctl_lvl0_offset = THERMCTL_LEVEL0_GROUP_MEM,
.thermctl_lvl0_up_thresh_mask = TEGRA210_THERMCTL_LVL0_UP_THRESH_MASK,
.thermctl_lvl0_dn_thresh_mask = TEGRA210_THERMCTL_LVL0_DN_THRESH_MASK,
};
static const struct tegra_tsensor_group *tegra210_tsensor_groups[] = {
......@@ -194,4 +210,6 @@ const struct tegra_soctherm_soc tegra210_soctherm = {
.num_ttgs = ARRAY_SIZE(tegra210_tsensor_groups),
.tfuse = &tegra210_soctherm_fuse,
.thresh_grain = TEGRA210_THRESH_GRAIN,
.bptt = TEGRA210_BPTT,
.use_ccroc = false,
};
......@@ -11,4 +11,9 @@
#define TEGRA124_SOCTHERM_SENSOR_PLLX 3
#define TEGRA124_SOCTHERM_SENSOR_NUM 4
#define TEGRA_SOCTHERM_THROT_LEVEL_LOW 0
#define TEGRA_SOCTHERM_THROT_LEVEL_MED 1
#define TEGRA_SOCTHERM_THROT_LEVEL_HIGH 2
#define TEGRA_SOCTHERM_THROT_LEVEL_NONE -1
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment