1
0
Fork 0

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal

Pull thermal management updates from Eduardo Valentin:

 - rework tsens driver to add support for tsens-v2 (Amit Kucheria)

 - rework armada thermal driver to use syscon and multichannel support
   (Miquel Raynal)

 - fixes to TI SoC, IMX, Exynos, RCar, and hwmon drivers

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal: (34 commits)
  thermal: armada: fix copy-paste error in armada_thermal_probe()
  thermal: rcar_thermal: avoid NULL dereference in absence of IRQ resources
  thermal: samsung: Remove Exynos5440 clock handling left-overs
  thermal: tsens: Fix negative temperature reporting
  thermal: tsens: switch from of_iomap() to devm_ioremap_resource()
  thermal: tsens: Rename variable
  thermal: tsens: Add generic support for TSENS v2 IP
  thermal: tsens: Rename tsens-8996 to tsens-v2 for reuse
  thermal: tsens: Add support to split up register address space into two
  dt: thermal: tsens: Document the fallback DT property for v2 of TSENS IP
  thermal: tsens: Get rid of unused fields in structure
  thermal_hwmon: Pass the originating device down to hwmon_device_register_with_info
  thermal_hwmon: Sanitize attribute name passed to hwmon
  dt-bindings: thermal: armada: add reference to new bindings
  dt-bindings: cp110: add the thermal node in the syscon file
  dt-bindings: cp110: update documentation since DT de-duplication
  dt-bindings: ap806: add the thermal node in the syscon file
  dt-bindings: cp110: prepare the syscon file to list other syscons nodes
  dt-bindings: ap806: prepare the syscon file to list other syscons nodes
  dt-bindings: cp110: rename cp110 syscon file
  ...
hifive-unleashed-5.1
Linus Torvalds 2018-08-16 10:21:18 -07:00
commit d01e12dd3f
24 changed files with 649 additions and 907 deletions

View File

@ -2,14 +2,17 @@ Marvell Armada AP806 System Controller
======================================
The AP806 is one of the two core HW blocks of the Marvell Armada 7K/8K
SoCs. It contains a system controller, which provides a number
registers giving access to numerous features: clocks, pin-muxing and
many other SoC configuration items. This DT binding allows to describe
this system controller.
SoCs. It contains system controllers, which provide several registers
giving access to numerous features: clocks, pin-muxing and many other
SoC configuration items. This DT binding allows to describe these
system controllers.
For the top level node:
- compatible: must be: "syscon", "simple-mfd";
- reg: register area of the AP806 system controller
- reg: register area of the AP806 system controller
SYSTEM CONTROLLER 0
===================
Clocks:
-------
@ -98,3 +101,38 @@ ap_syscon: system-controller@6f4000 {
gpio-ranges = <&ap_pinctrl 0 0 19>;
};
};
SYSTEM CONTROLLER 1
===================
Thermal:
--------
For common binding part and usage, refer to
Documentation/devicetree/bindings/thermal/thermal.txt
The thermal IP can probe the temperature all around the processor. It
may feature several channels, each of them wired to one sensor.
Required properties:
- compatible: must be one of:
* marvell,armada-ap806-thermal
- reg: register range associated with the thermal functions.
Optional properties:
- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
to this IP and represents the channel ID. There is one sensor per
channel. O refers to the thermal IP internal channel, while positive
IDs refer to each CPU.
Example:
ap_syscon1: system-controller@6f8000 {
compatible = "syscon", "simple-mfd";
reg = <0x6f8000 0x1000>;
ap_thermal: thermal-sensor@80 {
compatible = "marvell,armada-ap806-thermal";
reg = <0x80 0x10>;
#thermal-sensor-cells = <1>;
};
};

View File

@ -1,15 +1,18 @@
Marvell Armada CP110 System Controller 0
========================================
Marvell Armada CP110 System Controller
======================================
The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K
SoCs. It contains two sets of system control registers, System
Controller 0 and System Controller 1. This Device Tree binding allows
to describe the first system controller, which provides registers to
configure various aspects of the SoC.
SoCs. It contains system controllers, which provide several registers
giving access to numerous features: clocks, pin-muxing and many other
SoC configuration items. This DT binding allows to describe these
system controllers.
For the top level node:
- compatible: must be: "syscon", "simple-mfd";
- reg: register area of the CP110 system controller 0
- reg: register area of the CP110 system controller
SYSTEM CONTROLLER 0
===================
Clocks:
-------
@ -163,26 +166,60 @@ Required properties:
Example:
cpm_syscon0: system-controller@440000 {
CP110_LABEL(syscon0): system-controller@440000 {
compatible = "syscon", "simple-mfd";
reg = <0x440000 0x1000>;
cpm_clk: clock {
CP110_LABEL(clk): clock {
compatible = "marvell,cp110-clock";
#clock-cells = <2>;
};
cpm_pinctrl: pinctrl {
CP110_LABEL(pinctrl): pinctrl {
compatible = "marvell,armada-8k-cpm-pinctrl";
};
cpm_gpio1: gpio@100 {
CP110_LABEL(gpio1): gpio@100 {
compatible = "marvell,armada-8k-gpio";
offset = <0x100>;
ngpios = <32>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&cpm_pinctrl 0 0 32>;
gpio-ranges = <&CP110_LABEL(pinctrl) 0 0 32>;
};
};
SYSTEM CONTROLLER 1
===================
Thermal:
--------
The thermal IP can probe the temperature all around the processor. It
may feature several channels, each of them wired to one sensor.
For common binding part and usage, refer to
Documentation/devicetree/bindings/thermal/thermal.txt
Required properties:
- compatible: must be one of:
* marvell,armada-cp110-thermal
- reg: register range associated with the thermal functions.
Optional properties:
- #thermal-sensor-cells: shall be <1> when thermal-zones subnodes refer
to this IP and represents the channel ID. There is one sensor per
channel. O refers to the thermal IP internal channel.
Example:
CP110_LABEL(syscon1): system-controller@6f8000 {
compatible = "syscon", "simple-mfd";
reg = <0x6f8000 0x1000>;
CP110_LABEL(thermal): thermal-sensor@70 {
compatible = "marvell,armada-cp110-thermal";
reg = <0x70 0x10>;
#thermal-sensor-cells = <1>;
};
};

View File

@ -10,6 +10,11 @@ Required properties:
* marvell,armada-ap806-thermal
* marvell,armada-cp110-thermal
Note: these bindings are deprecated for AP806/CP110 and should instead
follow the rules described in:
Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
Documentation/devicetree/bindings/arm/marvell/cp110-system-controller.txt
- reg: Device's register space.
Two entries are expected, see the examples below. The first one points
to the status register (4B). The second one points to the control

View File

@ -1,18 +1,28 @@
* QCOM SoC Temperature Sensor (TSENS)
Required properties:
- compatible :
- "qcom,msm8916-tsens" : For 8916 Family of SoCs
- "qcom,msm8974-tsens" : For 8974 Family of SoCs
- "qcom,msm8996-tsens" : For 8996 Family of SoCs
- compatible:
Must be one of the following:
- "qcom,msm8916-tsens" (MSM8916)
- "qcom,msm8974-tsens" (MSM8974)
- "qcom,msm8996-tsens" (MSM8996)
- "qcom,msm8998-tsens", "qcom,tsens-v2" (MSM8998)
- "qcom,sdm845-tsens", "qcom,tsens-v2" (SDM845)
The generic "qcom,tsens-v2" property must be used as a fallback for any SoC
with version 2 of the TSENS IP. MSM8996 is the only exception because the
generic property did not exist when support was added.
- reg: Address range of the thermal registers.
New platforms containing v2.x.y of the TSENS IP must specify the SROT and TM
register spaces separately, with order being TM before SROT.
See Example 2, below.
- reg: Address range of the thermal registers
- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
- #qcom,sensors: Number of sensors in tsens block
- Refer to Documentation/devicetree/bindings/nvmem/nvmem.txt to know how to specify
nvmem cells
Example:
Example 1 (legacy support before a fallback tsens-v2 property was introduced):
tsens: thermal-sensor@900000 {
compatible = "qcom,msm8916-tsens";
reg = <0x4a8000 0x2000>;
@ -20,3 +30,12 @@ tsens: thermal-sensor@900000 {
nvmem-cell-names = "caldata", "calsel";
#thermal-sensor-cells = <1>;
};
Example 2 (for any platform containing v2 of the TSENS IP):
tsens0: thermal-sensor@c263000 {
compatible = "qcom,sdm845-tsens", "qcom,tsens-v2";
reg = <0xc263000 0x1ff>, /* TM */
<0xc222000 0x1ff>; /* SROT */
#qcom,sensors = <13>;
#thermal-sensor-cells = <1>;
};

View File

@ -24,6 +24,8 @@
#include <linux/of_device.h>
#include <linux/thermal.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
/* Thermal Manager Control and Status Register */
#define PMU_TDC0_SW_RST_MASK (0x1 << 1)
@ -39,24 +41,24 @@
#define A375_READOUT_INVERT BIT(15)
#define A375_HW_RESETn BIT(8)
/* Legacy bindings */
#define LEGACY_CONTROL_MEM_LEN 0x4
/* Current bindings with the 2 control registers under the same memory area */
#define LEGACY_CONTROL1_OFFSET 0x0
#define CONTROL0_OFFSET 0x0
#define CONTROL1_OFFSET 0x4
/* Errata fields */
#define CONTROL0_TSEN_TC_TRIM_MASK 0x7
#define CONTROL0_TSEN_TC_TRIM_VAL 0x3
/* TSEN refers to the temperature sensors within the AP */
#define CONTROL0_TSEN_START BIT(0)
#define CONTROL0_TSEN_RESET BIT(1)
#define CONTROL0_TSEN_ENABLE BIT(2)
#define CONTROL0_TSEN_AVG_BYPASS BIT(6)
#define CONTROL0_TSEN_CHAN_SHIFT 13
#define CONTROL0_TSEN_CHAN_MASK 0xF
#define CONTROL0_TSEN_OSR_SHIFT 24
#define CONTROL0_TSEN_OSR_MAX 0x3
#define CONTROL0_TSEN_MODE_SHIFT 30
#define CONTROL0_TSEN_MODE_EXTERNAL 0x2
#define CONTROL0_TSEN_MODE_MASK 0x3
/* EXT_TSEN refers to the external temperature sensors, out of the AP */
#define CONTROL1_TSEN_AVG_SHIFT 0
#define CONTROL1_TSEN_AVG_MASK 0x7
#define CONTROL1_EXT_TSEN_SW_RESET BIT(7)
#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8)
@ -67,19 +69,19 @@ struct armada_thermal_data;
/* Marvell EBU Thermal Sensor Dev Structure */
struct armada_thermal_priv {
void __iomem *status;
void __iomem *control0;
void __iomem *control1;
struct device *dev;
struct regmap *syscon;
char zone_name[THERMAL_NAME_LENGTH];
/* serialize temperature reads/updates */
struct mutex update_lock;
struct armada_thermal_data *data;
int current_channel;
};
struct armada_thermal_data {
/* Initialize the sensor */
void (*init_sensor)(struct platform_device *pdev,
struct armada_thermal_priv *);
/* Test for a valid sensor value (optional) */
bool (*is_valid)(struct armada_thermal_priv *);
/* Initialize the thermal IC */
void (*init)(struct platform_device *pdev,
struct armada_thermal_priv *priv);
/* Formula coeficients: temp = (b - m * reg) / div */
s64 coef_b;
@ -92,141 +94,242 @@ struct armada_thermal_data {
unsigned int temp_shift;
unsigned int temp_mask;
u32 is_valid_bit;
bool needs_control0;
/* Syscon access */
unsigned int syscon_control0_off;
unsigned int syscon_control1_off;
unsigned int syscon_status_off;
/* One sensor is in the thermal IC, the others are in the CPUs if any */
unsigned int cpu_nr;
};
static void armadaxp_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
struct armada_drvdata {
enum drvtype {
LEGACY,
SYSCON
} type;
union {
struct armada_thermal_priv *priv;
struct thermal_zone_device *tz;
} data;
};
/*
* struct armada_thermal_sensor - hold the information of one thermal sensor
* @thermal: pointer to the local private structure
* @tzd: pointer to the thermal zone device
* @id: identifier of the thermal sensor
*/
struct armada_thermal_sensor {
struct armada_thermal_priv *priv;
int id;
};
static void armadaxp_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
struct armada_thermal_data *data = priv->data;
u32 reg;
reg = readl_relaxed(priv->control1);
regmap_read(priv->syscon, data->syscon_control1_off, &reg);
reg |= PMU_TDC0_OTF_CAL_MASK;
writel(reg, priv->control1);
/* Reference calibration value */
reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
writel(reg, priv->control1);
/* Reset the sensor */
reg = readl_relaxed(priv->control1);
writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1);
reg |= PMU_TDC0_SW_RST_MASK;
writel(reg, priv->control1);
regmap_write(priv->syscon, data->syscon_control1_off, reg);
/* Enable the sensor */
reg = readl_relaxed(priv->status);
regmap_read(priv->syscon, data->syscon_status_off, &reg);
reg &= ~PMU_TM_DISABLE_MASK;
writel(reg, priv->status);
regmap_write(priv->syscon, data->syscon_status_off, reg);
}
static void armada370_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
static void armada370_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
struct armada_thermal_data *data = priv->data;
u32 reg;
reg = readl_relaxed(priv->control1);
regmap_read(priv->syscon, data->syscon_control1_off, &reg);
reg |= PMU_TDC0_OTF_CAL_MASK;
writel(reg, priv->control1);
/* Reference calibration value */
reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
writel(reg, priv->control1);
/* Reset the sensor */
reg &= ~PMU_TDC0_START_CAL_MASK;
writel(reg, priv->control1);
regmap_write(priv->syscon, data->syscon_control1_off, reg);
msleep(10);
}
static void armada375_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
static void armada375_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
struct armada_thermal_data *data = priv->data;
u32 reg;
reg = readl(priv->control1);
regmap_read(priv->syscon, data->syscon_control1_off, &reg);
reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
reg &= ~A375_READOUT_INVERT;
reg &= ~A375_HW_RESETn;
regmap_write(priv->syscon, data->syscon_control1_off, reg);
writel(reg, priv->control1);
msleep(20);
reg |= A375_HW_RESETn;
writel(reg, priv->control1);
regmap_write(priv->syscon, data->syscon_control1_off, reg);
msleep(50);
}
static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
static int armada_wait_sensor_validity(struct armada_thermal_priv *priv)
{
u32 reg;
readl_relaxed_poll_timeout(priv->status, reg,
reg & priv->data->is_valid_bit,
STATUS_POLL_PERIOD_US,
STATUS_POLL_TIMEOUT_US);
return regmap_read_poll_timeout(priv->syscon,
priv->data->syscon_status_off, reg,
reg & priv->data->is_valid_bit,
STATUS_POLL_PERIOD_US,
STATUS_POLL_TIMEOUT_US);
}
static void armada380_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
static void armada380_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
u32 reg = readl_relaxed(priv->control1);
struct armada_thermal_data *data = priv->data;
u32 reg;
/* Disable the HW/SW reset */
regmap_read(priv->syscon, data->syscon_control1_off, &reg);
reg |= CONTROL1_EXT_TSEN_HW_RESETn;
reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
writel(reg, priv->control1);
regmap_write(priv->syscon, data->syscon_control1_off, reg);
/* Set Tsen Tc Trim to correct default value (errata #132698) */
if (priv->control0) {
reg = readl_relaxed(priv->control0);
reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
reg |= CONTROL0_TSEN_TC_TRIM_VAL;
writel(reg, priv->control0);
}
/* Wait the sensors to be valid or the core will warn the user */
armada_wait_sensor_validity(priv);
regmap_read(priv->syscon, data->syscon_control0_off, &reg);
reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
reg |= CONTROL0_TSEN_TC_TRIM_VAL;
regmap_write(priv->syscon, data->syscon_control0_off, reg);
}
static void armada_ap806_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
static void armada_ap806_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
struct armada_thermal_data *data = priv->data;
u32 reg;
reg = readl_relaxed(priv->control0);
regmap_read(priv->syscon, data->syscon_control0_off, &reg);
reg &= ~CONTROL0_TSEN_RESET;
reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
writel(reg, priv->control0);
/* Wait the sensors to be valid or the core will warn the user */
armada_wait_sensor_validity(priv);
/* Sample every ~2ms */
reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
/* Enable average (2 samples by default) */
reg &= ~CONTROL0_TSEN_AVG_BYPASS;
regmap_write(priv->syscon, data->syscon_control0_off, reg);
}
static void armada_cp110_init(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
struct armada_thermal_data *data = priv->data;
u32 reg;
armada380_init(pdev, priv);
/* Sample every ~2ms */
regmap_read(priv->syscon, data->syscon_control0_off, &reg);
reg |= CONTROL0_TSEN_OSR_MAX << CONTROL0_TSEN_OSR_SHIFT;
regmap_write(priv->syscon, data->syscon_control0_off, reg);
/* Average the output value over 2^1 = 2 samples */
regmap_read(priv->syscon, data->syscon_control1_off, &reg);
reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT;
reg |= 1 << CONTROL1_TSEN_AVG_SHIFT;
regmap_write(priv->syscon, data->syscon_control1_off, reg);
}
static bool armada_is_valid(struct armada_thermal_priv *priv)
{
u32 reg = readl_relaxed(priv->status);
u32 reg;
if (!priv->data->is_valid_bit)
return true;
regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
return reg & priv->data->is_valid_bit;
}
static int armada_get_temp(struct thermal_zone_device *thermal,
int *temp)
/* There is currently no board with more than one sensor per channel */
static int armada_select_channel(struct armada_thermal_priv *priv, int channel)
{
struct armada_thermal_priv *priv = thermal->devdata;
u32 reg, div;
s64 sample, b, m;
struct armada_thermal_data *data = priv->data;
u32 ctrl0;
/* Valid check */
if (priv->data->is_valid && !priv->data->is_valid(priv)) {
dev_err(&thermal->device,
if (channel < 0 || channel > priv->data->cpu_nr)
return -EINVAL;
if (priv->current_channel == channel)
return 0;
/* Stop the measurements */
regmap_read(priv->syscon, data->syscon_control0_off, &ctrl0);
ctrl0 &= ~CONTROL0_TSEN_START;
regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
/* Reset the mode, internal sensor will be automatically selected */
ctrl0 &= ~(CONTROL0_TSEN_MODE_MASK << CONTROL0_TSEN_MODE_SHIFT);
/* Other channels are external and should be selected accordingly */
if (channel) {
/* Change the mode to external */
ctrl0 |= CONTROL0_TSEN_MODE_EXTERNAL <<
CONTROL0_TSEN_MODE_SHIFT;
/* Select the sensor */
ctrl0 &= ~(CONTROL0_TSEN_CHAN_MASK << CONTROL0_TSEN_CHAN_SHIFT);
ctrl0 |= (channel - 1) << CONTROL0_TSEN_CHAN_SHIFT;
}
/* Actually set the mode/channel */
regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
priv->current_channel = channel;
/* Re-start the measurements */
ctrl0 |= CONTROL0_TSEN_START;
regmap_write(priv->syscon, data->syscon_control0_off, ctrl0);
/*
* The IP has a latency of ~15ms, so after updating the selected source,
* we must absolutely wait for the sensor validity bit to ensure we read
* actual data.
*/
if (armada_wait_sensor_validity(priv)) {
dev_err(priv->dev,
"Temperature sensor reading not valid\n");
return -EIO;
}
reg = readl_relaxed(priv->status);
return 0;
}
static int armada_read_sensor(struct armada_thermal_priv *priv, int *temp)
{
u32 reg, div;
s64 sample, b, m;
regmap_read(priv->syscon, priv->data->syscon_status_off, &reg);
reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
if (priv->data->signed_sample)
/* The most significant bit is the sign bit */
@ -247,45 +350,93 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
return 0;
}
static struct thermal_zone_device_ops ops = {
static int armada_get_temp_legacy(struct thermal_zone_device *thermal,
int *temp)
{
struct armada_thermal_priv *priv = thermal->devdata;
int ret;
/* Valid check */
if (armada_is_valid(priv)) {
dev_err(priv->dev,
"Temperature sensor reading not valid\n");
return -EIO;
}
/* Do the actual reading */
ret = armada_read_sensor(priv, temp);
return ret;
}
static struct thermal_zone_device_ops legacy_ops = {
.get_temp = armada_get_temp_legacy,
};
static int armada_get_temp(void *_sensor, int *temp)
{
struct armada_thermal_sensor *sensor = _sensor;
struct armada_thermal_priv *priv = sensor->priv;
int ret;
mutex_lock(&priv->update_lock);
/* Select the desired channel */
ret = armada_select_channel(priv, sensor->id);
if (ret)
goto unlock_mutex;
/* Do the actual reading */
ret = armada_read_sensor(priv, temp);
unlock_mutex:
mutex_unlock(&priv->update_lock);
return ret;
}
static struct thermal_zone_of_device_ops of_ops = {
.get_temp = armada_get_temp,
};
static const struct armada_thermal_data armadaxp_data = {
.init_sensor = armadaxp_init_sensor,
.init = armadaxp_init,
.temp_shift = 10,
.temp_mask = 0x1ff,
.coef_b = 3153000000ULL,
.coef_m = 10000000ULL,
.coef_div = 13825,
.syscon_status_off = 0xb0,
.syscon_control1_off = 0xd0,
};
static const struct armada_thermal_data armada370_data = {
.is_valid = armada_is_valid,
.init_sensor = armada370_init_sensor,
.init = armada370_init,
.is_valid_bit = BIT(9),
.temp_shift = 10,
.temp_mask = 0x1ff,
.coef_b = 3153000000ULL,
.coef_m = 10000000ULL,
.coef_div = 13825,
.syscon_status_off = 0x0,
.syscon_control1_off = 0x4,
};
static const struct armada_thermal_data armada375_data = {
.is_valid = armada_is_valid,
.init_sensor = armada375_init_sensor,
.init = armada375_init,
.is_valid_bit = BIT(10),
.temp_shift = 0,
.temp_mask = 0x1ff,
.coef_b = 3171900000ULL,
.coef_m = 10000000ULL,
.coef_div = 13616,
.needs_control0 = true,
.syscon_status_off = 0x78,
.syscon_control0_off = 0x7c,
.syscon_control1_off = 0x80,
};
static const struct armada_thermal_data armada380_data = {
.is_valid = armada_is_valid,
.init_sensor = armada380_init_sensor,
.init = armada380_init,
.is_valid_bit = BIT(10),
.temp_shift = 0,
.temp_mask = 0x3ff,
@ -293,11 +444,13 @@ static const struct armada_thermal_data armada380_data = {
.coef_m = 2000096ULL,
.coef_div = 4201,
.inverted = true,
.syscon_control0_off = 0x70,
.syscon_control1_off = 0x74,
.syscon_status_off = 0x78,
};
static const struct armada_thermal_data armada_ap806_data = {
.is_valid = armada_is_valid,
.init_sensor = armada_ap806_init_sensor,
.init = armada_ap806_init,
.is_valid_bit = BIT(16),
.temp_shift = 0,
.temp_mask = 0x3ff,
@ -306,12 +459,14 @@ static const struct armada_thermal_data armada_ap806_data = {
.coef_div = 1,
.inverted = true,
.signed_sample = true,
.needs_control0 = true,
.syscon_control0_off = 0x84,
.syscon_control1_off = 0x88,
.syscon_status_off = 0x8C,
.cpu_nr = 4,
};
static const struct armada_thermal_data armada_cp110_data = {
.is_valid = armada_is_valid,
.init_sensor = armada380_init_sensor,
.init = armada_cp110_init,
.is_valid_bit = BIT(10),
.temp_shift = 0,
.temp_mask = 0x3ff,
@ -319,7 +474,9 @@ static const struct armada_thermal_data armada_cp110_data = {
.coef_m = 2000096ULL,
.coef_div = 4201,
.inverted = true,
.needs_control0 = true,
.syscon_control0_off = 0x70,
.syscon_control1_off = 0x74,
.syscon_status_off = 0x78,
};
static const struct of_device_id armada_thermal_id_table[] = {
@ -353,13 +510,97 @@ static const struct of_device_id armada_thermal_id_table[] = {
};
MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
static const struct regmap_config armada_thermal_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
};
static int armada_thermal_probe_legacy(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
struct armada_thermal_data *data = priv->data;
struct resource *res;
void __iomem *base;
/* First memory region points towards the status register */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (IS_ERR(res))
return PTR_ERR(res);
/*
* Edit the resource start address and length to map over all the
* registers, instead of pointing at them one by one.
*/
res->start -= data->syscon_status_off;
res->end = res->start + max(data->syscon_status_off,
max(data->syscon_control0_off,
data->syscon_control1_off)) +
sizeof(unsigned int) - 1;
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
priv->syscon = devm_regmap_init_mmio(&pdev->dev, base,
&armada_thermal_regmap_config);
if (IS_ERR(priv->syscon))
return PTR_ERR(priv->syscon);
return 0;
}
static int armada_thermal_probe_syscon(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
priv->syscon = syscon_node_to_regmap(pdev->dev.parent->of_node);
if (IS_ERR(priv->syscon))
return PTR_ERR(priv->syscon);
return 0;
}
static void armada_set_sane_name(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
const char *name = dev_name(&pdev->dev);
char *insane_char;
if (strlen(name) > THERMAL_NAME_LENGTH) {
/*
* When inside a system controller, the device name has the
* form: f06f8000.system-controller:ap-thermal so stripping
* after the ':' should give us a shorter but meaningful name.
*/
name = strrchr(name, ':');
if (!name)
name = "armada_thermal";
else
name++;
}
/* Save the name locally */
strncpy(priv->zone_name, name, THERMAL_NAME_LENGTH - 1);
priv->zone_name[THERMAL_NAME_LENGTH - 1] = '\0';
/* Then check there are no '-' or hwmon core will complain */
do {
insane_char = strpbrk(priv->zone_name, "-");
if (insane_char)
*insane_char = '_';
} while (insane_char);
}
static int armada_thermal_probe(struct platform_device *pdev)
{
void __iomem *control = NULL;
struct thermal_zone_device *thermal;
struct thermal_zone_device *tz;
struct armada_thermal_sensor *sensor;
struct armada_drvdata *drvdata;
const struct of_device_id *match;
struct armada_thermal_priv *priv;
struct resource *res;
int sensor_id;
int ret;
match = of_match_device(armada_thermal_id_table, &pdev->dev);
if (!match)
@ -369,58 +610,99 @@ static int armada_thermal_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->status = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->status))
return PTR_ERR(priv->status);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
control = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(control))
return PTR_ERR(control);
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
priv->dev = &pdev->dev;
priv->data = (struct armada_thermal_data *)match->data;
mutex_init(&priv->update_lock);
/*
* Legacy DT bindings only described "control1" register (also referred
* as "control MSB" on old documentation). New bindings cover
* as "control MSB" on old documentation). Then, bindings moved to cover
* "control0/control LSB" and "control1/control MSB" registers within
* the same resource, which is then of size 8 instead of 4.
* the same resource, which was then of size 8 instead of 4.
*
* The logic of defining sporadic registers is broken. For instance, it
* blocked the addition of the overheat interrupt feature that needed
* another resource somewhere else in the same memory area. One solution
* is to define an overall system controller and put the thermal node
* into it, which requires the use of regmaps across all the driver.
*/
if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) {
/* ->control0 unavailable in this configuration */
if (priv->data->needs_control0) {
dev_err(&pdev->dev, "No access to control0 register\n");
return -EINVAL;
if (IS_ERR(syscon_node_to_regmap(pdev->dev.parent->of_node))) {
/* Ensure device name is correct for the thermal core */
armada_set_sane_name(pdev, priv);
ret = armada_thermal_probe_legacy(pdev, priv);
if (ret)
return ret;
priv->data->init(pdev, priv);
/* Wait the sensors to be valid */
armada_wait_sensor_validity(priv);
tz = thermal_zone_device_register(priv->zone_name, 0, 0, priv,
&legacy_ops, NULL, 0, 0);
if (IS_ERR(tz)) {
dev_err(&pdev->dev,
"Failed to register thermal zone device\n");
return PTR_ERR(tz);
}
priv->control1 = control + LEGACY_CONTROL1_OFFSET;
} else {
priv->control0 = control + CONTROL0_OFFSET;
priv->control1 = control + CONTROL1_OFFSET;
drvdata->type = LEGACY;
drvdata->data.tz = tz;
platform_set_drvdata(pdev, drvdata);
return 0;
}
priv->data->init_sensor(pdev, priv);
ret = armada_thermal_probe_syscon(pdev, priv);
if (ret)
return ret;
thermal = thermal_zone_device_register(dev_name(&pdev->dev), 0, 0, priv,
&ops, NULL, 0, 0);
if (IS_ERR(thermal)) {
dev_err(&pdev->dev,
"Failed to register thermal zone device\n");
return PTR_ERR(thermal);
priv->current_channel = -1;
priv->data->init(pdev, priv);
drvdata->type = SYSCON;
drvdata->data.priv = priv;
platform_set_drvdata(pdev, drvdata);
/*
* There is one channel for the IC and one per CPU (if any), each
* channel has one sensor.
*/
for (sensor_id = 0; sensor_id <= priv->data->cpu_nr; sensor_id++) {
sensor = devm_kzalloc(&pdev->dev,
sizeof(struct armada_thermal_sensor),
GFP_KERNEL);
if (!sensor)
return -ENOMEM;
/* Register the sensor */
sensor->priv = priv;
sensor->id = sensor_id;
tz = devm_thermal_zone_of_sensor_register(&pdev->dev,
sensor->id, sensor,
&of_ops);
if (IS_ERR(tz)) {
dev_info(&pdev->dev, "Thermal sensor %d unavailable\n",
sensor_id);
devm_kfree(&pdev->dev, sensor);
continue;
}
}
platform_set_drvdata(pdev, thermal);
return 0;
}
static int armada_thermal_exit(struct platform_device *pdev)
{
struct thermal_zone_device *armada_thermal =
platform_get_drvdata(pdev);
struct armada_drvdata *drvdata = platform_get_drvdata(pdev);
thermal_zone_device_unregister(armada_thermal);
if (drvdata->type == LEGACY)
thermal_zone_device_unregister(drvdata->data.tz);
return 0;
}

View File

@ -605,7 +605,10 @@ static int imx_init_from_nvmem_cells(struct platform_device *pdev)
ret = nvmem_cell_read_u32(&pdev->dev, "calib", &val);
if (ret)
return ret;
imx_init_calib(pdev, val);
ret = imx_init_calib(pdev, val);
if (ret)
return ret;
ret = nvmem_cell_read_u32(&pdev->dev, "temp_grade", &val);
if (ret)

View File

@ -1,2 +1,2 @@
obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-8996.o
qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-v2.o

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2015, The Linux Foundation. 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 and
* only 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/platform_device.h>
#include <linux/regmap.h>
#include "tsens.h"
#define STATUS_OFFSET 0x10a0
#define LAST_TEMP_MASK 0xfff
#define STATUS_VALID_BIT BIT(21)
#define CODE_SIGN_BIT BIT(11)
static int get_temp_8996(struct tsens_device *tmdev, int id, int *temp)
{
struct tsens_sensor *s = &tmdev->sensor[id];
u32 code;
unsigned int sensor_addr;
int last_temp = 0, last_temp2 = 0, last_temp3 = 0, ret;
sensor_addr = STATUS_OFFSET + s->hw_id * 4;
ret = regmap_read(tmdev->map, sensor_addr, &code);
if (ret)
return ret;
last_temp = code & LAST_TEMP_MASK;
if (code & STATUS_VALID_BIT)
goto done;
/* Try a second time */
ret = regmap_read(tmdev->map, sensor_addr, &code);
if (ret)
return ret;
if (code & STATUS_VALID_BIT) {
last_temp = code & LAST_TEMP_MASK;
goto done;
} else {
last_temp2 = code & LAST_TEMP_MASK;
}
/* Try a third/last time */
ret = regmap_read(tmdev->map, sensor_addr, &code);
if (ret)
return ret;
if (code & STATUS_VALID_BIT) {
last_temp = code & LAST_TEMP_MASK;
goto done;
} else {
last_temp3 = code & LAST_TEMP_MASK;
}
if (last_temp == last_temp2)
last_temp = last_temp2;
else if (last_temp2 == last_temp3)
last_temp = last_temp3;
done:
/* Code sign bit is the sign extension for a negative value */
if (last_temp & CODE_SIGN_BIT)
last_temp |= ~CODE_SIGN_BIT;
/* Temperatures are in deciCelicius */
*temp = last_temp * 100;
return 0;
}
static const struct tsens_ops ops_8996 = {
.init = init_common,
.get_temp = get_temp_8996,
};
const struct tsens_data data_8996 = {
.num_sensors = 13,
.ops = &ops_8996,
};

View File

@ -16,6 +16,7 @@
#include <linux/io.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include "tsens.h"
@ -103,11 +104,11 @@ int get_temp_common(struct tsens_device *tmdev, int id, int *temp)
{
struct tsens_sensor *s = &tmdev->sensor[id];
u32 code;
unsigned int sensor_addr;
unsigned int status_reg;
int last_temp = 0, ret;
sensor_addr = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET;
ret = regmap_read(tmdev->map, sensor_addr, &code);
status_reg = S0_ST_ADDR + s->hw_id * SN_ADDR_OFFSET;
ret = regmap_read(tmdev->map, status_reg, &code);
if (ret)
return ret;
last_temp = code & SN_ST_TEMP_MASK;
@ -126,16 +127,28 @@ static const struct regmap_config tsens_config = {
int __init init_common(struct tsens_device *tmdev)
{
void __iomem *base;
struct resource *res;
struct platform_device *op = of_find_device_by_node(tmdev->dev->of_node);
base = of_iomap(tmdev->dev->of_node, 0);
if (!base)
if (!op)
return -EINVAL;
tmdev->map = devm_regmap_init_mmio(tmdev->dev, base, &tsens_config);
if (IS_ERR(tmdev->map)) {
iounmap(base);
return PTR_ERR(tmdev->map);
/* The driver only uses the TM register address space for now */
if (op->num_resources > 1) {
tmdev->tm_offset = 0;
} else {
/* old DTs where SROT and TM were in a contiguous 2K block */
tmdev->tm_offset = 0x1000;
}
res = platform_get_resource(op, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&op->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
tmdev->map = devm_regmap_init_mmio(tmdev->dev, base, &tsens_config);
if (IS_ERR(tmdev->map))
return PTR_ERR(tmdev->map);
return 0;
}

View File

@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
* Copyright (c) 2018, Linaro Limited
*/
#include <linux/regmap.h>
#include <linux/bitops.h>
#include "tsens.h"
#define STATUS_OFFSET 0xa0
#define LAST_TEMP_MASK 0xfff
#define STATUS_VALID_BIT BIT(21)
static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp)
{
struct tsens_sensor *s = &tmdev->sensor[id];
u32 code;
unsigned int status_reg;
u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0;
int ret;
status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4;
ret = regmap_read(tmdev->map, status_reg, &code);
if (ret)
return ret;
last_temp = code & LAST_TEMP_MASK;
if (code & STATUS_VALID_BIT)
goto done;
/* Try a second time */
ret = regmap_read(tmdev->map, status_reg, &code);
if (ret)
return ret;
if (code & STATUS_VALID_BIT) {
last_temp = code & LAST_TEMP_MASK;
goto done;
} else {
last_temp2 = code & LAST_TEMP_MASK;
}
/* Try a third/last time */
ret = regmap_read(tmdev->map, status_reg, &code);
if (ret)
return ret;
if (code & STATUS_VALID_BIT) {
last_temp = code & LAST_TEMP_MASK;
goto done;
} else {
last_temp3 = code & LAST_TEMP_MASK;
}
if (last_temp == last_temp2)
last_temp = last_temp2;
else if (last_temp2 == last_temp3)
last_temp = last_temp3;
done:
/* Convert temperature from deciCelsius to milliCelsius */
*temp = sign_extend32(last_temp, fls(LAST_TEMP_MASK) - 1) * 100;
return 0;
}
static const struct tsens_ops ops_generic_v2 = {
.init = init_common,
.get_temp = get_temp_tsens_v2,
};
const struct tsens_data data_tsens_v2 = {
.ops = &ops_generic_v2,
};
/* Kept around for backward compatibility with old msm8996.dtsi */
const struct tsens_data data_8996 = {
.num_sensors = 13,
.ops = &ops_generic_v2,
};

View File

@ -72,6 +72,9 @@ static const struct of_device_id tsens_table[] = {
}, {
.compatible = "qcom,msm8996-tsens",
.data = &data_8996,
}, {
.compatible = "qcom,tsens-v2",
.data = &data_tsens_v2,
},
{}
};

View File

@ -77,9 +77,8 @@ struct tsens_device {
struct device *dev;
u32 num_sensors;
struct regmap *map;
struct regmap_field *status_field;
u32 tm_offset;
struct tsens_context ctx;
bool trdy;
const struct tsens_ops *ops;
struct tsens_sensor sensor[0];
};
@ -89,6 +88,9 @@ void compute_intercept_slope(struct tsens_device *, u32 *, u32 *, u32);
int init_common(struct tsens_device *);
int get_temp_common(struct tsens_device *, int, int *);
extern const struct tsens_data data_8916, data_8974, data_8960, data_8996;
/* TSENS v1 targets */
extern const struct tsens_data data_8916, data_8974, data_8960;
/* TSENS v2 targets */
extern const struct tsens_data data_8996, data_tsens_v2;
#endif /* __QCOM_TSENS_H__ */

View File

@ -598,7 +598,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
enr_bits |= 3 << (i * 8);
}
if (enr_bits)
if (common->base && enr_bits)
rcar_thermal_common_write(common, ENR, enr_bits);
dev_info(dev, "%d sensor probed\n", i);

View File

@ -789,11 +789,6 @@ static void exynos_tmu_work(struct work_struct *work)
struct exynos_tmu_data *data = container_of(work,
struct exynos_tmu_data, irq_work);
if (!IS_ERR(data->clk_sec))
clk_enable(data->clk_sec);
if (!IS_ERR(data->clk_sec))
clk_disable(data->clk_sec);
thermal_zone_device_update(data->tzd, THERMAL_EVENT_UNSPECIFIED);
mutex_lock(&data->lock);

View File

@ -142,7 +142,8 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
INIT_LIST_HEAD(&hwmon->tz_list);
strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
hwmon->device = hwmon_device_register_with_info(NULL, hwmon->type,
strreplace(hwmon->type, '-', '_');
hwmon->device = hwmon_device_register_with_info(&tz->device, hwmon->type,
hwmon, NULL, NULL);
if (IS_ERR(hwmon->device)) {
result = PTR_ERR(hwmon->device);

View File

@ -54,56 +54,36 @@
#define DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET 0x8
#define DRA752_TEMP_SENSOR_CORE_OFFSET 0x154
#define DRA752_BANDGAP_THRESHOLD_CORE_OFFSET 0x1ac
#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET 0x1c4
#define DRA752_DTEMP_CORE_0_OFFSET 0x208
#define DRA752_DTEMP_CORE_1_OFFSET 0x20c
#define DRA752_DTEMP_CORE_2_OFFSET 0x210
#define DRA752_DTEMP_CORE_3_OFFSET 0x214
#define DRA752_DTEMP_CORE_4_OFFSET 0x218
/* DRA752.iva register offsets */
#define DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET 0x388
#define DRA752_TEMP_SENSOR_IVA_OFFSET 0x398
#define DRA752_BANDGAP_THRESHOLD_IVA_OFFSET 0x3a4
#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET 0x3b4
#define DRA752_DTEMP_IVA_0_OFFSET 0x3d0
#define DRA752_DTEMP_IVA_1_OFFSET 0x3d4
#define DRA752_DTEMP_IVA_2_OFFSET 0x3d8
#define DRA752_DTEMP_IVA_3_OFFSET 0x3dc
#define DRA752_DTEMP_IVA_4_OFFSET 0x3e0
/* DRA752.mpu register offsets */
#define DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET 0x4
#define DRA752_TEMP_SENSOR_MPU_OFFSET 0x14c
#define DRA752_BANDGAP_THRESHOLD_MPU_OFFSET 0x1a4
#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET 0x1bc
#define DRA752_DTEMP_MPU_0_OFFSET 0x1e0
#define DRA752_DTEMP_MPU_1_OFFSET 0x1e4
#define DRA752_DTEMP_MPU_2_OFFSET 0x1e8
#define DRA752_DTEMP_MPU_3_OFFSET 0x1ec
#define DRA752_DTEMP_MPU_4_OFFSET 0x1f0
/* DRA752.dspeve register offsets */
#define DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET 0x384
#define DRA752_TEMP_SENSOR_DSPEVE_OFFSET 0x394
#define DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET 0x3a0
#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET 0x3b0
#define DRA752_DTEMP_DSPEVE_0_OFFSET 0x3bc
#define DRA752_DTEMP_DSPEVE_1_OFFSET 0x3c0
#define DRA752_DTEMP_DSPEVE_2_OFFSET 0x3c4
#define DRA752_DTEMP_DSPEVE_3_OFFSET 0x3c8
#define DRA752_DTEMP_DSPEVE_4_OFFSET 0x3cc
/* DRA752.gpu register offsets */
#define DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET 0x0
#define DRA752_TEMP_SENSOR_GPU_OFFSET 0x150
#define DRA752_BANDGAP_THRESHOLD_GPU_OFFSET 0x1a8
#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET 0x1c0
#define DRA752_DTEMP_GPU_0_OFFSET 0x1f4
#define DRA752_DTEMP_GPU_1_OFFSET 0x1f8
#define DRA752_DTEMP_GPU_2_OFFSET 0x1fc
#define DRA752_DTEMP_GPU_3_OFFSET 0x200
#define DRA752_DTEMP_GPU_4_OFFSET 0x204
/**
* Register bitfields for DRA752
@ -114,7 +94,6 @@
*/
/* DRA752.BANDGAP_STATUS_1 */
#define DRA752_BANDGAP_STATUS_1_ALERT_MASK BIT(31)
#define DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK BIT(5)
#define DRA752_BANDGAP_STATUS_1_COLD_CORE_MASK BIT(4)
#define DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK BIT(3)
@ -125,10 +104,6 @@
/* DRA752.BANDGAP_CTRL_2 */
#define DRA752_BANDGAP_CTRL_2_FREEZE_IVA_MASK BIT(22)
#define DRA752_BANDGAP_CTRL_2_FREEZE_DSPEVE_MASK BIT(21)
#define DRA752_BANDGAP_CTRL_2_CLEAR_IVA_MASK BIT(19)
#define DRA752_BANDGAP_CTRL_2_CLEAR_DSPEVE_MASK BIT(18)
#define DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_IVA_MASK BIT(16)
#define DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_DSPEVE_MASK BIT(15)
#define DRA752_BANDGAP_CTRL_2_MASK_HOT_IVA_MASK BIT(3)
#define DRA752_BANDGAP_CTRL_2_MASK_COLD_IVA_MASK BIT(2)
#define DRA752_BANDGAP_CTRL_2_MASK_HOT_DSPEVE_MASK BIT(1)
@ -141,17 +116,10 @@
#define DRA752_BANDGAP_STATUS_2_COLD_DSPEVE_MASK BIT(0)
/* DRA752.BANDGAP_CTRL_1 */
#define DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK (0x3 << 30)
#define DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK (0x7 << 27)
#define DRA752_BANDGAP_CTRL_1_FREEZE_CORE_MASK BIT(23)
#define DRA752_BANDGAP_CTRL_1_FREEZE_GPU_MASK BIT(22)
#define DRA752_BANDGAP_CTRL_1_FREEZE_MPU_MASK BIT(21)
#define DRA752_BANDGAP_CTRL_1_CLEAR_CORE_MASK BIT(20)
#define DRA752_BANDGAP_CTRL_1_CLEAR_GPU_MASK BIT(19)
#define DRA752_BANDGAP_CTRL_1_CLEAR_MPU_MASK BIT(18)
#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_CORE_MASK BIT(17)
#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_GPU_MASK BIT(16)
#define DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_MPU_MASK BIT(15)
#define DRA752_BANDGAP_CTRL_1_MASK_HOT_CORE_MASK BIT(5)
#define DRA752_BANDGAP_CTRL_1_MASK_COLD_CORE_MASK BIT(4)
#define DRA752_BANDGAP_CTRL_1_MASK_HOT_GPU_MASK BIT(3)
@ -168,22 +136,6 @@
#define DRA752_BANDGAP_THRESHOLD_HOT_MASK (0x3ff << 16)
#define DRA752_BANDGAP_THRESHOLD_COLD_MASK (0x3ff << 0)
/* DRA752.BANDGAP_CUMUL_DTEMP_CORE */
#define DRA752_BANDGAP_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0)
/* DRA752.BANDGAP_CUMUL_DTEMP_IVA */
#define DRA752_BANDGAP_CUMUL_DTEMP_IVA_MASK (0xffffffff << 0)
/* DRA752.BANDGAP_CUMUL_DTEMP_MPU */
#define DRA752_BANDGAP_CUMUL_DTEMP_MPU_MASK (0xffffffff << 0)
/* DRA752.BANDGAP_CUMUL_DTEMP_DSPEVE */
#define DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_MASK (0xffffffff << 0)
/* DRA752.BANDGAP_CUMUL_DTEMP_GPU */
#define DRA752_BANDGAP_CUMUL_DTEMP_GPU_MASK (0xffffffff << 0)
/**
* Temperature limits and thresholds for DRA752
*
@ -202,10 +154,6 @@
/* bandgap clock limits */
#define DRA752_GPU_MAX_FREQ 1500000
#define DRA752_GPU_MIN_FREQ 1000000
/* sensor limits */
#define DRA752_GPU_MIN_TEMP -40000
#define DRA752_GPU_MAX_TEMP 125000
#define DRA752_GPU_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_GPU_T_HOT 800
#define DRA752_GPU_T_COLD 795
@ -214,10 +162,6 @@
/* bandgap clock limits */
#define DRA752_MPU_MAX_FREQ 1500000
#define DRA752_MPU_MIN_FREQ 1000000
/* sensor limits */
#define DRA752_MPU_MIN_TEMP -40000
#define DRA752_MPU_MAX_TEMP 125000
#define DRA752_MPU_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_MPU_T_HOT 800
#define DRA752_MPU_T_COLD 795
@ -226,10 +170,6 @@
/* bandgap clock limits */
#define DRA752_CORE_MAX_FREQ 1500000
#define DRA752_CORE_MIN_FREQ 1000000
/* sensor limits */
#define DRA752_CORE_MIN_TEMP -40000
#define DRA752_CORE_MAX_TEMP 125000
#define DRA752_CORE_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_CORE_T_HOT 800
#define DRA752_CORE_T_COLD 795
@ -238,10 +178,6 @@
/* bandgap clock limits */
#define DRA752_DSPEVE_MAX_FREQ 1500000
#define DRA752_DSPEVE_MIN_FREQ 1000000
/* sensor limits */
#define DRA752_DSPEVE_MIN_TEMP -40000
#define DRA752_DSPEVE_MAX_TEMP 125000
#define DRA752_DSPEVE_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_DSPEVE_T_HOT 800
#define DRA752_DSPEVE_T_COLD 795
@ -250,10 +186,6 @@
/* bandgap clock limits */
#define DRA752_IVA_MAX_FREQ 1500000
#define DRA752_IVA_MIN_FREQ 1000000
/* sensor limits */
#define DRA752_IVA_MIN_TEMP -40000
#define DRA752_IVA_MAX_TEMP 125000
#define DRA752_IVA_HYST_VAL 5000
/* interrupts thresholds */
#define DRA752_IVA_T_HOT 800
#define DRA752_IVA_T_COLD 795

View File

@ -41,24 +41,16 @@ dra752_core_temp_sensor_registers = {
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
.mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_CORE_MASK,
.mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_CORE_MASK,
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
.mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
.mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_CORE_MASK,
.mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_CORE_MASK,
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_CORE_MASK,
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_CORE_OFFSET,
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
.bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
.status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_CORE_MASK,
.status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_CORE_MASK,
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_CORE_OFFSET,
.ctrl_dtemp_0 = DRA752_DTEMP_CORE_0_OFFSET,
.ctrl_dtemp_1 = DRA752_DTEMP_CORE_1_OFFSET,
.ctrl_dtemp_2 = DRA752_DTEMP_CORE_2_OFFSET,
.ctrl_dtemp_3 = DRA752_DTEMP_CORE_3_OFFSET,
.ctrl_dtemp_4 = DRA752_DTEMP_CORE_4_OFFSET,
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_CORE_OFFSET,
};
@ -74,24 +66,16 @@ dra752_iva_temp_sensor_registers = {
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_2_OFFSET,
.mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_IVA_MASK,
.mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_IVA_MASK,
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
.mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
.mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_IVA_MASK,
.mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_IVA_MASK,
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_IVA_MASK,
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_IVA_OFFSET,
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
.bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
.status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_IVA_MASK,
.status_cold_mask = DRA752_BANDGAP_STATUS_2_COLD_IVA_MASK,
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_IVA_OFFSET,
.ctrl_dtemp_0 = DRA752_DTEMP_IVA_0_OFFSET,
.ctrl_dtemp_1 = DRA752_DTEMP_IVA_1_OFFSET,
.ctrl_dtemp_2 = DRA752_DTEMP_IVA_2_OFFSET,
.ctrl_dtemp_3 = DRA752_DTEMP_IVA_3_OFFSET,
.ctrl_dtemp_4 = DRA752_DTEMP_IVA_4_OFFSET,
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_IVA_OFFSET,
};
@ -107,24 +91,16 @@ dra752_mpu_temp_sensor_registers = {
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
.mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_MPU_MASK,
.mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_MPU_MASK,
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
.mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
.mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_MPU_MASK,
.mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_MPU_MASK,
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_MPU_MASK,
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_MPU_OFFSET,
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
.bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
.status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_MPU_MASK,
.status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_MPU_MASK,
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_MPU_OFFSET,
.ctrl_dtemp_0 = DRA752_DTEMP_MPU_0_OFFSET,
.ctrl_dtemp_1 = DRA752_DTEMP_MPU_1_OFFSET,
.ctrl_dtemp_2 = DRA752_DTEMP_MPU_2_OFFSET,
.ctrl_dtemp_3 = DRA752_DTEMP_MPU_3_OFFSET,
.ctrl_dtemp_4 = DRA752_DTEMP_MPU_4_OFFSET,
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_MPU_OFFSET,
};
@ -140,24 +116,16 @@ dra752_dspeve_temp_sensor_registers = {
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_2_OFFSET,
.mask_hot_mask = DRA752_BANDGAP_CTRL_2_MASK_HOT_DSPEVE_MASK,
.mask_cold_mask = DRA752_BANDGAP_CTRL_2_MASK_COLD_DSPEVE_MASK,
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
.mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
.mask_freeze_mask = DRA752_BANDGAP_CTRL_2_FREEZE_DSPEVE_MASK,
.mask_clear_mask = DRA752_BANDGAP_CTRL_2_CLEAR_DSPEVE_MASK,
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_2_CLEAR_ACCUM_DSPEVE_MASK,
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_DSPEVE_OFFSET,
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
.bgap_status = DRA752_BANDGAP_STATUS_2_OFFSET,
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
.status_hot_mask = DRA752_BANDGAP_STATUS_2_HOT_DSPEVE_MASK,
.status_cold_mask = DRA752_BANDGAP_STATUS_2_COLD_DSPEVE_MASK,
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_DSPEVE_OFFSET,
.ctrl_dtemp_0 = DRA752_DTEMP_DSPEVE_0_OFFSET,
.ctrl_dtemp_1 = DRA752_DTEMP_DSPEVE_1_OFFSET,
.ctrl_dtemp_2 = DRA752_DTEMP_DSPEVE_2_OFFSET,
.ctrl_dtemp_3 = DRA752_DTEMP_DSPEVE_3_OFFSET,
.ctrl_dtemp_4 = DRA752_DTEMP_DSPEVE_4_OFFSET,
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_DSPEVE_OFFSET,
};
@ -173,24 +141,16 @@ dra752_gpu_temp_sensor_registers = {
.bgap_mask_ctrl = DRA752_BANDGAP_CTRL_1_OFFSET,
.mask_hot_mask = DRA752_BANDGAP_CTRL_1_MASK_HOT_GPU_MASK,
.mask_cold_mask = DRA752_BANDGAP_CTRL_1_MASK_COLD_GPU_MASK,
.mask_sidlemode_mask = DRA752_BANDGAP_CTRL_1_SIDLEMODE_MASK,
.mask_counter_delay_mask = DRA752_BANDGAP_CTRL_1_COUNTER_DELAY_MASK,
.mask_freeze_mask = DRA752_BANDGAP_CTRL_1_FREEZE_GPU_MASK,
.mask_clear_mask = DRA752_BANDGAP_CTRL_1_CLEAR_GPU_MASK,
.mask_clear_accum_mask = DRA752_BANDGAP_CTRL_1_CLEAR_ACCUM_GPU_MASK,
.bgap_threshold = DRA752_BANDGAP_THRESHOLD_GPU_OFFSET,
.threshold_thot_mask = DRA752_BANDGAP_THRESHOLD_HOT_MASK,
.threshold_tcold_mask = DRA752_BANDGAP_THRESHOLD_COLD_MASK,
.bgap_status = DRA752_BANDGAP_STATUS_1_OFFSET,
.status_bgap_alert_mask = DRA752_BANDGAP_STATUS_1_ALERT_MASK,
.status_hot_mask = DRA752_BANDGAP_STATUS_1_HOT_GPU_MASK,
.status_cold_mask = DRA752_BANDGAP_STATUS_1_COLD_GPU_MASK,
.bgap_cumul_dtemp = DRA752_BANDGAP_CUMUL_DTEMP_GPU_OFFSET,
.ctrl_dtemp_0 = DRA752_DTEMP_GPU_0_OFFSET,
.ctrl_dtemp_1 = DRA752_DTEMP_GPU_1_OFFSET,
.ctrl_dtemp_2 = DRA752_DTEMP_GPU_2_OFFSET,
.ctrl_dtemp_3 = DRA752_DTEMP_GPU_3_OFFSET,
.ctrl_dtemp_4 = DRA752_DTEMP_GPU_4_OFFSET,
.bgap_efuse = DRA752_STD_FUSE_OPP_BGAP_GPU_OFFSET,
};
@ -200,11 +160,6 @@ static struct temp_sensor_data dra752_mpu_temp_sensor_data = {
.t_cold = DRA752_MPU_T_COLD,
.min_freq = DRA752_MPU_MIN_FREQ,
.max_freq = DRA752_MPU_MAX_FREQ,
.max_temp = DRA752_MPU_MAX_TEMP,
.min_temp = DRA752_MPU_MIN_TEMP,
.hyst_val = DRA752_MPU_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/* Thresholds and limits for DRA752 GPU temperature sensor */
@ -213,11 +168,6 @@ static struct temp_sensor_data dra752_gpu_temp_sensor_data = {
.t_cold = DRA752_GPU_T_COLD,
.min_freq = DRA752_GPU_MIN_FREQ,
.max_freq = DRA752_GPU_MAX_FREQ,
.max_temp = DRA752_GPU_MAX_TEMP,
.min_temp = DRA752_GPU_MIN_TEMP,
.hyst_val = DRA752_GPU_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/* Thresholds and limits for DRA752 CORE temperature sensor */
@ -226,11 +176,6 @@ static struct temp_sensor_data dra752_core_temp_sensor_data = {
.t_cold = DRA752_CORE_T_COLD,
.min_freq = DRA752_CORE_MIN_FREQ,
.max_freq = DRA752_CORE_MAX_FREQ,
.max_temp = DRA752_CORE_MAX_TEMP,
.min_temp = DRA752_CORE_MIN_TEMP,
.hyst_val = DRA752_CORE_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/* Thresholds and limits for DRA752 DSPEVE temperature sensor */
@ -239,11 +184,6 @@ static struct temp_sensor_data dra752_dspeve_temp_sensor_data = {
.t_cold = DRA752_DSPEVE_T_COLD,
.min_freq = DRA752_DSPEVE_MIN_FREQ,
.max_freq = DRA752_DSPEVE_MAX_FREQ,
.max_temp = DRA752_DSPEVE_MAX_TEMP,
.min_temp = DRA752_DSPEVE_MIN_TEMP,
.hyst_val = DRA752_DSPEVE_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/* Thresholds and limits for DRA752 IVA temperature sensor */
@ -252,11 +192,6 @@ static struct temp_sensor_data dra752_iva_temp_sensor_data = {
.t_cold = DRA752_IVA_T_COLD,
.min_freq = DRA752_IVA_MIN_FREQ,
.max_freq = DRA752_IVA_MAX_FREQ,
.max_temp = DRA752_IVA_MAX_TEMP,
.min_temp = DRA752_IVA_MIN_TEMP,
.hyst_val = DRA752_IVA_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/*

View File

@ -48,9 +48,6 @@ omap34xx_mpu_temp_sensor_registers = {
static struct temp_sensor_data omap34xx_mpu_temp_sensor_data = {
.min_freq = 32768,
.max_freq = 32768,
.max_temp = 125000,
.min_temp = -40000,
.hyst_val = 5000,
};
/*
@ -119,9 +116,6 @@ omap36xx_mpu_temp_sensor_registers = {
static struct temp_sensor_data omap36xx_mpu_temp_sensor_data = {
.min_freq = 32768,
.max_freq = 32768,
.max_temp = 125000,
.min_temp = -40000,
.hyst_val = 5000,
};
/*

View File

@ -42,9 +42,6 @@ omap4430_mpu_temp_sensor_registers = {
static struct temp_sensor_data omap4430_mpu_temp_sensor_data = {
.min_freq = OMAP4430_MIN_FREQ,
.max_freq = OMAP4430_MAX_FREQ,
.max_temp = OMAP4430_MAX_TEMP,
.min_temp = OMAP4430_MIN_TEMP,
.hyst_val = OMAP4430_HYST_VAL,
};
/*
@ -121,8 +118,6 @@ omap4460_mpu_temp_sensor_registers = {
.tshut_cold_mask = OMAP4460_TSHUT_COLD_MASK,
.bgap_status = OMAP4460_BGAP_STATUS_OFFSET,
.status_clean_stop_mask = OMAP4460_CLEAN_STOP_MASK,
.status_bgap_alert_mask = OMAP4460_BGAP_ALERT_MASK,
.status_hot_mask = OMAP4460_HOT_FLAG_MASK,
.status_cold_mask = OMAP4460_COLD_FLAG_MASK,
@ -137,11 +132,6 @@ static struct temp_sensor_data omap4460_mpu_temp_sensor_data = {
.t_cold = OMAP4460_T_COLD,
.min_freq = OMAP4460_MIN_FREQ,
.max_freq = OMAP4460_MAX_FREQ,
.max_temp = OMAP4460_MAX_TEMP,
.min_temp = OMAP4460_MIN_TEMP,
.hyst_val = OMAP4460_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/*

View File

@ -73,10 +73,6 @@
/* bandgap clock limits (no control on 4430) */
#define OMAP4430_MAX_FREQ 32768
#define OMAP4430_MIN_FREQ 32768
/* sensor limits */
#define OMAP4430_MIN_TEMP -40000
#define OMAP4430_MAX_TEMP 125000
#define OMAP4430_HYST_VAL 5000
/**
* *** OMAP4460 *** Applicable for OMAP4470
@ -143,8 +139,6 @@
#define OMAP4460_TSHUT_COLD_MASK (0x3ff << 0)
/* OMAP4460.BANDGAP_STATUS bits */
#define OMAP4460_CLEAN_STOP_MASK BIT(3)
#define OMAP4460_BGAP_ALERT_MASK BIT(2)
#define OMAP4460_HOT_FLAG_MASK BIT(1)
#define OMAP4460_COLD_FLAG_MASK BIT(0)
@ -162,10 +156,6 @@
/* bandgap clock limits */
#define OMAP4460_MAX_FREQ 1500000
#define OMAP4460_MIN_FREQ 1000000
/* sensor limits */
#define OMAP4460_MIN_TEMP -40000
#define OMAP4460_MAX_TEMP 123000
#define OMAP4460_HYST_VAL 5000
/* interrupts thresholds */
#define OMAP4460_TSHUT_HOT 900 /* 122 deg C */
#define OMAP4460_TSHUT_COLD 895 /* 100 deg C */

View File

@ -38,12 +38,8 @@ omap5430_mpu_temp_sensor_registers = {
.bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET,
.mask_hot_mask = OMAP5430_MASK_HOT_MPU_MASK,
.mask_cold_mask = OMAP5430_MASK_COLD_MPU_MASK,
.mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK,
.mask_counter_delay_mask = OMAP5430_MASK_COUNTER_DELAY_MASK,
.mask_freeze_mask = OMAP5430_MASK_FREEZE_MPU_MASK,
.mask_clear_mask = OMAP5430_MASK_CLEAR_MPU_MASK,
.mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK,
.bgap_counter = OMAP5430_BGAP_CTRL_OFFSET,
.counter_mask = OMAP5430_COUNTER_MASK,
@ -57,17 +53,11 @@ omap5430_mpu_temp_sensor_registers = {
.tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK,
.bgap_status = OMAP5430_BGAP_STATUS_OFFSET,
.status_clean_stop_mask = 0x0,
.status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK,
.status_hot_mask = OMAP5430_HOT_MPU_FLAG_MASK,
.status_cold_mask = OMAP5430_COLD_MPU_FLAG_MASK,
.bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET,
.ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_MPU_0_OFFSET,
.ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_MPU_1_OFFSET,
.ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_MPU_2_OFFSET,
.ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_MPU_3_OFFSET,
.ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_MPU_4_OFFSET,
.bgap_efuse = OMAP5430_FUSE_OPP_BGAP_MPU,
};
@ -84,11 +74,8 @@ omap5430_gpu_temp_sensor_registers = {
.bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET,
.mask_hot_mask = OMAP5430_MASK_HOT_GPU_MASK,
.mask_cold_mask = OMAP5430_MASK_COLD_GPU_MASK,
.mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK,
.mask_counter_delay_mask = OMAP5430_MASK_COUNTER_DELAY_MASK,
.mask_freeze_mask = OMAP5430_MASK_FREEZE_GPU_MASK,
.mask_clear_mask = OMAP5430_MASK_CLEAR_GPU_MASK,
.mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK,
.bgap_counter = OMAP5430_BGAP_CTRL_OFFSET,
.counter_mask = OMAP5430_COUNTER_MASK,
@ -102,17 +89,11 @@ omap5430_gpu_temp_sensor_registers = {
.tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK,
.bgap_status = OMAP5430_BGAP_STATUS_OFFSET,
.status_clean_stop_mask = 0x0,
.status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK,
.status_hot_mask = OMAP5430_HOT_GPU_FLAG_MASK,
.status_cold_mask = OMAP5430_COLD_GPU_FLAG_MASK,
.bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET,
.ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_GPU_0_OFFSET,
.ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_GPU_1_OFFSET,
.ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_GPU_2_OFFSET,
.ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_GPU_3_OFFSET,
.ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_GPU_4_OFFSET,
.bgap_efuse = OMAP5430_FUSE_OPP_BGAP_GPU,
};
@ -130,11 +111,8 @@ omap5430_core_temp_sensor_registers = {
.bgap_mask_ctrl = OMAP5430_BGAP_CTRL_OFFSET,
.mask_hot_mask = OMAP5430_MASK_HOT_CORE_MASK,
.mask_cold_mask = OMAP5430_MASK_COLD_CORE_MASK,
.mask_sidlemode_mask = OMAP5430_MASK_SIDLEMODE_MASK,
.mask_counter_delay_mask = OMAP5430_MASK_COUNTER_DELAY_MASK,
.mask_freeze_mask = OMAP5430_MASK_FREEZE_CORE_MASK,
.mask_clear_mask = OMAP5430_MASK_CLEAR_CORE_MASK,
.mask_clear_accum_mask = OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK,
.bgap_counter = OMAP5430_BGAP_CTRL_OFFSET,
.counter_mask = OMAP5430_COUNTER_MASK,
@ -148,17 +126,11 @@ omap5430_core_temp_sensor_registers = {
.tshut_cold_mask = OMAP5430_TSHUT_COLD_MASK,
.bgap_status = OMAP5430_BGAP_STATUS_OFFSET,
.status_clean_stop_mask = 0x0,
.status_bgap_alert_mask = OMAP5430_BGAP_ALERT_MASK,
.status_hot_mask = OMAP5430_HOT_CORE_FLAG_MASK,
.status_cold_mask = OMAP5430_COLD_CORE_FLAG_MASK,
.bgap_cumul_dtemp = OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET,
.ctrl_dtemp_0 = OMAP5430_BGAP_DTEMP_CORE_0_OFFSET,
.ctrl_dtemp_1 = OMAP5430_BGAP_DTEMP_CORE_1_OFFSET,
.ctrl_dtemp_2 = OMAP5430_BGAP_DTEMP_CORE_2_OFFSET,
.ctrl_dtemp_3 = OMAP5430_BGAP_DTEMP_CORE_3_OFFSET,
.ctrl_dtemp_4 = OMAP5430_BGAP_DTEMP_CORE_4_OFFSET,
.bgap_efuse = OMAP5430_FUSE_OPP_BGAP_CORE,
};
@ -171,11 +143,6 @@ static struct temp_sensor_data omap5430_mpu_temp_sensor_data = {
.t_cold = OMAP5430_MPU_T_COLD,
.min_freq = OMAP5430_MPU_MIN_FREQ,
.max_freq = OMAP5430_MPU_MAX_FREQ,
.max_temp = OMAP5430_MPU_MAX_TEMP,
.min_temp = OMAP5430_MPU_MIN_TEMP,
.hyst_val = OMAP5430_MPU_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/* Thresholds and limits for OMAP5430 GPU temperature sensor */
@ -186,11 +153,6 @@ static struct temp_sensor_data omap5430_gpu_temp_sensor_data = {
.t_cold = OMAP5430_GPU_T_COLD,
.min_freq = OMAP5430_GPU_MIN_FREQ,
.max_freq = OMAP5430_GPU_MAX_FREQ,
.max_temp = OMAP5430_GPU_MAX_TEMP,
.min_temp = OMAP5430_GPU_MIN_TEMP,
.hyst_val = OMAP5430_GPU_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/* Thresholds and limits for OMAP5430 CORE temperature sensor */
@ -201,11 +163,6 @@ static struct temp_sensor_data omap5430_core_temp_sensor_data = {
.t_cold = OMAP5430_CORE_T_COLD,
.min_freq = OMAP5430_CORE_MIN_FREQ,
.max_freq = OMAP5430_CORE_MAX_FREQ,
.max_temp = OMAP5430_CORE_MAX_TEMP,
.min_temp = OMAP5430_CORE_MIN_TEMP,
.hyst_val = OMAP5430_CORE_HYST_VAL,
.update_int1 = 1000,
.update_int2 = 2000,
};
/*
@ -319,8 +276,7 @@ const struct ti_bandgap_data omap5430_data = {
TI_BANDGAP_FEATURE_FREEZE_BIT |
TI_BANDGAP_FEATURE_TALERT |
TI_BANDGAP_FEATURE_COUNTER_DELAY |
TI_BANDGAP_FEATURE_HISTORY_BUFFER |
TI_BANDGAP_FEATURE_ERRATA_813,
TI_BANDGAP_FEATURE_HISTORY_BUFFER,
.fclock_name = "l3instr_ts_gclk_div",
.div_ck_name = "l3instr_ts_gclk_div",
.conv_table = omap5430_adc_to_temp,

View File

@ -44,36 +44,24 @@
#define OMAP5430_TEMP_SENSOR_GPU_OFFSET 0x150
#define OMAP5430_BGAP_THRESHOLD_GPU_OFFSET 0x1A8
#define OMAP5430_BGAP_TSHUT_GPU_OFFSET 0x1B4
#define OMAP5430_BGAP_CUMUL_DTEMP_GPU_OFFSET 0x1C0
#define OMAP5430_BGAP_DTEMP_GPU_0_OFFSET 0x1F4
#define OMAP5430_BGAP_DTEMP_GPU_1_OFFSET 0x1F8
#define OMAP5430_BGAP_DTEMP_GPU_2_OFFSET 0x1FC
#define OMAP5430_BGAP_DTEMP_GPU_3_OFFSET 0x200
#define OMAP5430_BGAP_DTEMP_GPU_4_OFFSET 0x204
/* OMAP5430.MPU register offsets */
#define OMAP5430_FUSE_OPP_BGAP_MPU 0x4
#define OMAP5430_TEMP_SENSOR_MPU_OFFSET 0x14C
#define OMAP5430_BGAP_THRESHOLD_MPU_OFFSET 0x1A4
#define OMAP5430_BGAP_TSHUT_MPU_OFFSET 0x1B0
#define OMAP5430_BGAP_CUMUL_DTEMP_MPU_OFFSET 0x1BC
#define OMAP5430_BGAP_DTEMP_MPU_0_OFFSET 0x1E0
#define OMAP5430_BGAP_DTEMP_MPU_1_OFFSET 0x1E4
#define OMAP5430_BGAP_DTEMP_MPU_2_OFFSET 0x1E8
#define OMAP5430_BGAP_DTEMP_MPU_3_OFFSET 0x1EC
#define OMAP5430_BGAP_DTEMP_MPU_4_OFFSET 0x1F0
/* OMAP5430.MPU register offsets */
#define OMAP5430_FUSE_OPP_BGAP_CORE 0x8
#define OMAP5430_TEMP_SENSOR_CORE_OFFSET 0x154
#define OMAP5430_BGAP_THRESHOLD_CORE_OFFSET 0x1AC
#define OMAP5430_BGAP_TSHUT_CORE_OFFSET 0x1B8
#define OMAP5430_BGAP_CUMUL_DTEMP_CORE_OFFSET 0x1C4
#define OMAP5430_BGAP_DTEMP_CORE_0_OFFSET 0x208
#define OMAP5430_BGAP_DTEMP_CORE_1_OFFSET 0x20C
#define OMAP5430_BGAP_DTEMP_CORE_2_OFFSET 0x210
#define OMAP5430_BGAP_DTEMP_CORE_3_OFFSET 0x214
#define OMAP5430_BGAP_DTEMP_CORE_4_OFFSET 0x218
/* OMAP5430.common register offsets */
#define OMAP5430_BGAP_CTRL_OFFSET 0x1A0
@ -94,17 +82,10 @@
#define OMAP5430_BGAP_TEMP_SENSOR_DTEMP_MASK (0x3ff << 0)
/* OMAP5430.BANDGAP_CTRL */
#define OMAP5430_MASK_SIDLEMODE_MASK (0x3 << 30)
#define OMAP5430_MASK_COUNTER_DELAY_MASK (0x7 << 27)
#define OMAP5430_MASK_FREEZE_CORE_MASK BIT(23)
#define OMAP5430_MASK_FREEZE_GPU_MASK BIT(22)
#define OMAP5430_MASK_FREEZE_MPU_MASK BIT(21)
#define OMAP5430_MASK_CLEAR_CORE_MASK BIT(20)
#define OMAP5430_MASK_CLEAR_GPU_MASK BIT(19)
#define OMAP5430_MASK_CLEAR_MPU_MASK BIT(18)
#define OMAP5430_MASK_CLEAR_ACCUM_CORE_MASK BIT(17)
#define OMAP5430_MASK_CLEAR_ACCUM_GPU_MASK BIT(16)
#define OMAP5430_MASK_CLEAR_ACCUM_MPU_MASK BIT(15)
#define OMAP5430_MASK_HOT_CORE_MASK BIT(5)
#define OMAP5430_MASK_COLD_CORE_MASK BIT(4)
#define OMAP5430_MASK_HOT_GPU_MASK BIT(3)
@ -123,17 +104,7 @@
#define OMAP5430_TSHUT_HOT_MASK (0x3ff << 16)
#define OMAP5430_TSHUT_COLD_MASK (0x3ff << 0)
/* OMAP5430.BANDGAP_CUMUL_DTEMP_MPU */
#define OMAP5430_CUMUL_DTEMP_MPU_MASK (0xffffffff << 0)
/* OMAP5430.BANDGAP_CUMUL_DTEMP_GPU */
#define OMAP5430_CUMUL_DTEMP_GPU_MASK (0xffffffff << 0)
/* OMAP5430.BANDGAP_CUMUL_DTEMP_CORE */
#define OMAP5430_CUMUL_DTEMP_CORE_MASK (0xffffffff << 0)
/* OMAP5430.BANDGAP_STATUS */
#define OMAP5430_BGAP_ALERT_MASK BIT(31)
#define OMAP5430_HOT_CORE_FLAG_MASK BIT(5)
#define OMAP5430_COLD_CORE_FLAG_MASK BIT(4)
#define OMAP5430_HOT_GPU_FLAG_MASK BIT(3)
@ -159,10 +130,6 @@
/* bandgap clock limits */
#define OMAP5430_GPU_MAX_FREQ 1500000
#define OMAP5430_GPU_MIN_FREQ 1000000
/* sensor limits */
#define OMAP5430_GPU_MIN_TEMP -40000
#define OMAP5430_GPU_MAX_TEMP 125000
#define OMAP5430_GPU_HYST_VAL 5000
/* interrupts thresholds */
#define OMAP5430_GPU_TSHUT_HOT 915
#define OMAP5430_GPU_TSHUT_COLD 900
@ -173,10 +140,6 @@
/* bandgap clock limits */
#define OMAP5430_MPU_MAX_FREQ 1500000
#define OMAP5430_MPU_MIN_FREQ 1000000
/* sensor limits */
#define OMAP5430_MPU_MIN_TEMP -40000
#define OMAP5430_MPU_MAX_TEMP 125000
#define OMAP5430_MPU_HYST_VAL 5000
/* interrupts thresholds */
#define OMAP5430_MPU_TSHUT_HOT 915
#define OMAP5430_MPU_TSHUT_COLD 900
@ -187,10 +150,6 @@
/* bandgap clock limits */
#define OMAP5430_CORE_MAX_FREQ 1500000
#define OMAP5430_CORE_MIN_FREQ 1000000
/* sensor limits */
#define OMAP5430_CORE_MIN_TEMP -40000
#define OMAP5430_CORE_MAX_TEMP 125000
#define OMAP5430_CORE_HYST_VAL 5000
/* interrupts thresholds */
#define OMAP5430_CORE_TSHUT_HOT 915
#define OMAP5430_CORE_TSHUT_COLD 900

View File

@ -305,217 +305,6 @@ int ti_bandgap_adc_to_mcelsius(struct ti_bandgap *bgp, int adc_val, int *t)
return 0;
}
/**
* ti_bandgap_mcelsius_to_adc() - converts a mCelsius value to ADC scale
* @bgp: struct ti_bandgap pointer
* @temp: value in mCelsius
* @adc: address where to write the resulting temperature in ADC representation
*
* Simple conversion from mCelsius to ADC values. In case the temp value
* is out of the ADC conv table range, it returns -ERANGE, 0 on success.
* The conversion table is indexed by the ADC values.
*
* Return: 0 if conversion was successful, else -ERANGE in case the @temp
* argument is out of the ADC conv table range.
*/
static
int ti_bandgap_mcelsius_to_adc(struct ti_bandgap *bgp, long temp, int *adc)
{
const struct ti_bandgap_data *conf = bgp->conf;
const int *conv_table = bgp->conf->conv_table;
int high, low, mid;
low = 0;
high = conf->adc_end_val - conf->adc_start_val;
mid = (high + low) / 2;
if (temp < conv_table[low] || temp > conv_table[high])
return -ERANGE;
while (low < high) {
if (temp < conv_table[mid])
high = mid - 1;
else
low = mid + 1;
mid = (low + high) / 2;
}
*adc = conf->adc_start_val + low;
return 0;
}
/**
* ti_bandgap_add_hyst() - add hysteresis (in mCelsius) to an ADC value
* @bgp: struct ti_bandgap pointer
* @adc_val: temperature value in ADC representation
* @hyst_val: hysteresis value in mCelsius
* @sum: address where to write the resulting temperature (in ADC scale)
*
* Adds an hysteresis value (in mCelsius) to a ADC temperature value.
*
* Return: 0 on success, -ERANGE otherwise.
*/
static
int ti_bandgap_add_hyst(struct ti_bandgap *bgp, int adc_val, int hyst_val,
u32 *sum)
{
int temp, ret;
/*
* Need to add in the mcelsius domain, so we have a temperature
* the conv_table range
*/
ret = ti_bandgap_adc_to_mcelsius(bgp, adc_val, &temp);
if (ret < 0)
return ret;
temp += hyst_val;
ret = ti_bandgap_mcelsius_to_adc(bgp, temp, sum);
return ret;
}
/*** Helper functions handling device Alert/Shutdown signals ***/
/**
* ti_bandgap_unmask_interrupts() - unmasks the events of thot & tcold
* @bgp: struct ti_bandgap pointer
* @id: bandgap sensor id
* @t_hot: hot temperature value to trigger alert signal
* @t_cold: cold temperature value to trigger alert signal
*
* Checks the requested t_hot and t_cold values and configures the IRQ event
* masks accordingly. Call this function only if bandgap features HAS(TALERT).
*/
static void ti_bandgap_unmask_interrupts(struct ti_bandgap *bgp, int id,
u32 t_hot, u32 t_cold)
{
struct temp_sensor_registers *tsr;
u32 temp, reg_val;
/* Read the current on die temperature */
temp = ti_bandgap_read_temp(bgp, id);
tsr = bgp->conf->sensors[id].registers;
reg_val = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
if (temp < t_hot)
reg_val |= tsr->mask_hot_mask;
else
reg_val &= ~tsr->mask_hot_mask;
if (t_cold < temp)
reg_val |= tsr->mask_cold_mask;
else
reg_val &= ~tsr->mask_cold_mask;
ti_bandgap_writel(bgp, reg_val, tsr->bgap_mask_ctrl);
}
/**
* ti_bandgap_update_alert_threshold() - sequence to update thresholds
* @bgp: struct ti_bandgap pointer
* @id: bandgap sensor id
* @val: value (ADC) of a new threshold
* @hot: desired threshold to be updated. true if threshold hot, false if
* threshold cold
*
* It will program the required thresholds (hot and cold) for TALERT signal.
* This function can be used to update t_hot or t_cold, depending on @hot value.
* It checks the resulting t_hot and t_cold values, based on the new passed @val
* and configures the thresholds so that t_hot is always greater than t_cold.
* Call this function only if bandgap features HAS(TALERT).
*
* Return: 0 if no error, else corresponding error
*/
static int ti_bandgap_update_alert_threshold(struct ti_bandgap *bgp, int id,
int val, bool hot)
{
struct temp_sensor_data *ts_data = bgp->conf->sensors[id].ts_data;
struct temp_sensor_registers *tsr;
u32 thresh_val, reg_val, t_hot, t_cold, ctrl;
int err = 0;
tsr = bgp->conf->sensors[id].registers;
/* obtain the current value */
thresh_val = ti_bandgap_readl(bgp, tsr->bgap_threshold);
t_cold = (thresh_val & tsr->threshold_tcold_mask) >>
__ffs(tsr->threshold_tcold_mask);
t_hot = (thresh_val & tsr->threshold_thot_mask) >>
__ffs(tsr->threshold_thot_mask);
if (hot)
t_hot = val;
else
t_cold = val;
if (t_cold > t_hot) {
if (hot)
err = ti_bandgap_add_hyst(bgp, t_hot,
-ts_data->hyst_val,
&t_cold);
else
err = ti_bandgap_add_hyst(bgp, t_cold,
ts_data->hyst_val,
&t_hot);
}
/* write the new threshold values */
reg_val = thresh_val &
~(tsr->threshold_thot_mask | tsr->threshold_tcold_mask);
reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask)) |
(t_cold << __ffs(tsr->threshold_tcold_mask));
/**
* Errata i813:
* Spurious Thermal Alert: Talert can happen randomly while the device
* remains under the temperature limit defined for this event to trig.
* This spurious event is caused by a incorrect re-synchronization
* between clock domains. The comparison between configured threshold
* and current temperature value can happen while the value is
* transitioning (metastable), thus causing inappropriate event
* generation. No spurious event occurs as long as the threshold value
* stays unchanged. Spurious event can be generated while a thermal
* alert threshold is modified in
* CONTROL_BANDGAP_THRESHOLD_MPU/GPU/CORE/DSPEVE/IVA_n.
*/
if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
/* Mask t_hot and t_cold events at the IP Level */
ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
if (hot)
ctrl &= ~tsr->mask_hot_mask;
else
ctrl &= ~tsr->mask_cold_mask;
ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
}
/* Write the threshold value */
ti_bandgap_writel(bgp, reg_val, tsr->bgap_threshold);
if (TI_BANDGAP_HAS(bgp, ERRATA_813)) {
/* Unmask t_hot and t_cold events at the IP Level */
ctrl = ti_bandgap_readl(bgp, tsr->bgap_mask_ctrl);
if (hot)
ctrl |= tsr->mask_hot_mask;
else
ctrl |= tsr->mask_cold_mask;
ti_bandgap_writel(bgp, ctrl, tsr->bgap_mask_ctrl);
}
if (err) {
dev_err(bgp->dev, "failed to reprogram thot threshold\n");
err = -EIO;
goto exit;
}
ti_bandgap_unmask_interrupts(bgp, id, t_hot, t_cold);
exit:
return err;
}
/**
* ti_bandgap_validate() - helper to check the sanity of a struct ti_bandgap
* @bgp: struct ti_bandgap pointer
@ -543,165 +332,6 @@ static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
return 0;
}
/**
* _ti_bandgap_write_threshold() - helper to update TALERT t_cold or t_hot
* @bgp: struct ti_bandgap pointer
* @id: bandgap sensor id
* @val: value (mCelsius) of a new threshold
* @hot: desired threshold to be updated. true if threshold hot, false if
* threshold cold
*
* It will update the required thresholds (hot and cold) for TALERT signal.
* This function can be used to update t_hot or t_cold, depending on @hot value.
* Validates the mCelsius range and update the requested threshold.
* Call this function only if bandgap features HAS(TALERT).
*
* Return: 0 if no error, else corresponding error value.
*/
static int _ti_bandgap_write_threshold(struct ti_bandgap *bgp, int id, int val,
bool hot)
{
struct temp_sensor_data *ts_data;
struct temp_sensor_registers *tsr;
u32 adc_val;
int ret;
ret = ti_bandgap_validate(bgp, id);
if (ret)
return ret;
if (!TI_BANDGAP_HAS(bgp, TALERT))
return -ENOTSUPP;
ts_data = bgp->conf->sensors[id].ts_data;
tsr = bgp->conf->sensors[id].registers;
if (hot) {
if (val < ts_data->min_temp + ts_data->hyst_val)
ret = -EINVAL;
} else {
if (val > ts_data->max_temp + ts_data->hyst_val)
ret = -EINVAL;
}
if (ret)
return ret;
ret = ti_bandgap_mcelsius_to_adc(bgp, val, &adc_val);
if (ret < 0)
return ret;
spin_lock(&bgp->lock);
ret = ti_bandgap_update_alert_threshold(bgp, id, adc_val, hot);
spin_unlock(&bgp->lock);
return ret;
}
/**
* _ti_bandgap_read_threshold() - helper to read TALERT t_cold or t_hot
* @bgp: struct ti_bandgap pointer
* @id: bandgap sensor id
* @val: value (mCelsius) of a threshold
* @hot: desired threshold to be read. true if threshold hot, false if
* threshold cold
*
* It will fetch the required thresholds (hot and cold) for TALERT signal.
* This function can be used to read t_hot or t_cold, depending on @hot value.
* Call this function only if bandgap features HAS(TALERT).
*
* Return: 0 if no error, -ENOTSUPP if it has no TALERT support, or the
* corresponding error value if some operation fails.
*/
static int _ti_bandgap_read_threshold(struct ti_bandgap *bgp, int id,
int *val, bool hot)
{
struct temp_sensor_registers *tsr;
u32 temp, mask;
int ret = 0;
ret = ti_bandgap_validate(bgp, id);
if (ret)
goto exit;
if (!TI_BANDGAP_HAS(bgp, TALERT)) {
ret = -ENOTSUPP;
goto exit;
}
tsr = bgp->conf->sensors[id].registers;
if (hot)
mask = tsr->threshold_thot_mask;
else
mask = tsr->threshold_tcold_mask;
temp = ti_bandgap_readl(bgp, tsr->bgap_threshold);
temp = (temp & mask) >> __ffs(mask);
ret = ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
if (ret) {
dev_err(bgp->dev, "failed to read thot\n");
ret = -EIO;
goto exit;
}
*val = temp;
exit:
return ret;
}
/*** Exposed APIs ***/
/**
* ti_bandgap_read_thot() - reads sensor current thot
* @bgp: pointer to bandgap instance
* @id: sensor id
* @thot: resulting current thot value
*
* Return: 0 on success or the proper error code
*/
int ti_bandgap_read_thot(struct ti_bandgap *bgp, int id, int *thot)
{
return _ti_bandgap_read_threshold(bgp, id, thot, true);
}
/**
* ti_bandgap_write_thot() - sets sensor current thot
* @bgp: pointer to bandgap instance
* @id: sensor id
* @val: desired thot value
*
* Return: 0 on success or the proper error code
*/
int ti_bandgap_write_thot(struct ti_bandgap *bgp, int id, int val)
{
return _ti_bandgap_write_threshold(bgp, id, val, true);
}
/**
* ti_bandgap_read_tcold() - reads sensor current tcold
* @bgp: pointer to bandgap instance
* @id: sensor id
* @tcold: resulting current tcold value
*
* Return: 0 on success or the proper error code
*/
int ti_bandgap_read_tcold(struct ti_bandgap *bgp, int id, int *tcold)
{
return _ti_bandgap_read_threshold(bgp, id, tcold, false);
}
/**
* ti_bandgap_write_tcold() - sets the sensor tcold
* @bgp: pointer to bandgap instance
* @id: sensor id
* @val: desired tcold value
*
* Return: 0 on success or the proper error code
*/
int ti_bandgap_write_tcold(struct ti_bandgap *bgp, int id, int val)
{
return _ti_bandgap_write_threshold(bgp, id, val, false);
}
/**
* ti_bandgap_read_counter() - read the sensor counter
* @bgp: pointer to bandgap instance

View File

@ -78,11 +78,8 @@
* @bgap_mask_ctrl: BANDGAP_MASK_CTRL register offset
* @mask_hot_mask: mask to bandgap_mask_ctrl.mask_hot
* @mask_cold_mask: mask to bandgap_mask_ctrl.mask_cold
* @mask_sidlemode_mask: mask to bandgap_mask_ctrl.mask_sidlemode
* @mask_counter_delay_mask: mask to bandgap_mask_ctrl.mask_counter_delay
* @mask_freeze_mask: mask to bandgap_mask_ctrl.mask_free
* @mask_clear_mask: mask to bandgap_mask_ctrl.mask_clear
* @mask_clear_accum_mask: mask to bandgap_mask_ctrl.mask_clear_accum
* @bgap_mode_ctrl: BANDGAP_MODE_CTRL register offset
* @mode_ctrl_mask: mask to bandgap_mode_ctrl.mode_ctrl
* @bgap_counter: BANDGAP_COUNTER register offset
@ -91,21 +88,13 @@
* @threshold_thot_mask: mask to bandgap_threhold.thot
* @threshold_tcold_mask: mask to bandgap_threhold.tcold
* @tshut_threshold: TSHUT_THRESHOLD register offset (TSHUT thresholds)
* @tshut_efuse_mask: mask to tshut_threshold.tshut_efuse
* @tshut_efuse_shift: shift to tshut_threshold.tshut_efuse
* @tshut_hot_mask: mask to tshut_threhold.thot
* @tshut_cold_mask: mask to tshut_threhold.thot
* @bgap_status: BANDGAP_STATUS register offset
* @status_clean_stop_mask: mask to bandgap_status.clean_stop
* @status_bgap_alert_mask: mask to bandgap_status.bandgap_alert
* @status_hot_mask: mask to bandgap_status.hot
* @status_cold_mask: mask to bandgap_status.cold
* @bgap_cumul_dtemp: BANDGAP_CUMUL_DTEMP register offset
* @ctrl_dtemp_0: CTRL_DTEMP0 register offset
* @ctrl_dtemp_1: CTRL_DTEMP1 register offset
* @ctrl_dtemp_2: CTRL_DTEMP2 register offset
* @ctrl_dtemp_3: CTRL_DTEMP3 register offset
* @ctrl_dtemp_4: CTRL_DTEMP4 register offset
* @bgap_efuse: BANDGAP_EFUSE register offset
*
* The register offsets and bitfields might change across
@ -121,17 +110,14 @@ struct temp_sensor_registers {
u32 temp_sensor_ctrl;
u32 bgap_tempsoff_mask;
u32 bgap_soc_mask;
u32 bgap_eocz_mask; /* not used: but needs revisit */
u32 bgap_eocz_mask;
u32 bgap_dtemp_mask;
u32 bgap_mask_ctrl;
u32 mask_hot_mask;
u32 mask_cold_mask;
u32 mask_sidlemode_mask; /* not used: but may be needed for pm */
u32 mask_counter_delay_mask;
u32 mask_freeze_mask;
u32 mask_clear_mask; /* not used: but needed for trending */
u32 mask_clear_accum_mask; /* not used: but needed for trending */
u32 bgap_mode_ctrl;
u32 mode_ctrl_mask;
@ -144,23 +130,15 @@ struct temp_sensor_registers {
u32 threshold_tcold_mask;
u32 tshut_threshold;
u32 tshut_efuse_mask; /* not used */
u32 tshut_efuse_shift; /* not used */
u32 tshut_hot_mask;
u32 tshut_cold_mask;
u32 bgap_status;
u32 status_clean_stop_mask; /* not used: but needed for trending */
u32 status_bgap_alert_mask; /* not used */
u32 status_hot_mask;
u32 status_cold_mask;
u32 bgap_cumul_dtemp; /* not used: but needed for trending */
u32 ctrl_dtemp_0; /* not used: but needed for trending */
u32 ctrl_dtemp_1; /* not used: but needed for trending */
u32 ctrl_dtemp_2; /* not used: but needed for trending */
u32 ctrl_dtemp_3; /* not used: but needed for trending */
u32 ctrl_dtemp_4; /* not used: but needed for trending */
u32 ctrl_dtemp_1;
u32 ctrl_dtemp_2;
u32 bgap_efuse;
};
@ -172,11 +150,6 @@ struct temp_sensor_registers {
* @t_cold: temperature to trigger a thermal alert (low initial value)
* @min_freq: sensor minimum clock rate
* @max_freq: sensor maximum clock rate
* @max_temp: sensor maximum temperature
* @min_temp: sensor minimum temperature
* @hyst_val: temperature hysteresis considered while converting ADC values
* @update_int1: update interval
* @update_int2: update interval
*
* This data structure will hold the required thresholds and temperature limits
* for a specific temperature sensor, like shutdown temperature, alert
@ -189,11 +162,6 @@ struct temp_sensor_data {
u32 t_cold;
u32 min_freq;
u32 max_freq;
int max_temp;
int min_temp;
int hyst_val;
u32 update_int1; /* not used */
u32 update_int2; /* not used */
};
struct ti_bandgap_data;
@ -316,8 +284,6 @@ struct ti_temp_sensor {
*
* TI_BANDGAP_FEATURE_ERRATA_814 - used to workaorund when the bandgap device
* has Errata 814
* TI_BANDGAP_FEATURE_ERRATA_813 - used to workaorund when the bandgap device
* has Errata 813
* TI_BANDGAP_FEATURE_UNRELIABLE - used when the sensor readings are too
* inaccurate.
* TI_BANDGAP_HAS(b, f) - macro to check if a bandgap device is capable of a
@ -334,8 +300,7 @@ struct ti_temp_sensor {
#define TI_BANDGAP_FEATURE_COUNTER_DELAY BIT(8)
#define TI_BANDGAP_FEATURE_HISTORY_BUFFER BIT(9)
#define TI_BANDGAP_FEATURE_ERRATA_814 BIT(10)
#define TI_BANDGAP_FEATURE_ERRATA_813 BIT(11)
#define TI_BANDGAP_FEATURE_UNRELIABLE BIT(12)
#define TI_BANDGAP_FEATURE_UNRELIABLE BIT(11)
#define TI_BANDGAP_HAS(b, f) \
((b)->conf->features & TI_BANDGAP_FEATURE_ ## f)