[PATCH 11/16] thermal: mvebu: Add support for Armada XP thermal sensor
Ezequiel Garcia
ezequiel.garcia at free-electrons.com
Wed Mar 20 18:36:32 EDT 2013
With the infrastructure introduced to support more SoC, we can
now easily add another thermal sensor.
The Armada XP sensor has no register to check for a valid temperature,
and has a special formula to obtain the temperature from the thermal
sensor output register.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
.../devicetree/bindings/thermal/mvebu-thermal.txt | 21 ++++++---
drivers/thermal/mvebu_thermal.c | 50 ++++++++++++++++++++
2 files changed, 64 insertions(+), 7 deletions(-)
diff --git a/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt b/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt
index 8c0f5eb..7cc3fd4 100644
--- a/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/mvebu-thermal.txt
@@ -1,13 +1,20 @@
-* Kirkwood Thermal
-
-This version is for Kirkwood 88F8262 & 88F6283 SoCs. Other kirkwoods
-don't contain a thermal sensor.
+* Marvell EBU Thermal
Required properties:
-- compatible : "marvell,kirkwood-thermal"
-- reg : Address range of the thermal registers
-Example:
+- compatible: Should be set to one of the following:
+ marvell,kirkwood-thermal
+ marvell,armadaxp-thermal
+
+- reg: Device's register space.
+ One or two entries are expected, see the examples below.
+ The first one is required for the sensor register;
+ the second one is optional and is used as the control
+ register for sensor calibration.
+ Currently the only SoC variant having one register range
+ is Kirkwood.
+
+Kirkwood example:
thermal at 10078 {
compatible = "marvell,kirkwood-thermal";
diff --git a/drivers/thermal/mvebu_thermal.c b/drivers/thermal/mvebu_thermal.c
index bfe4817..50f13e7 100644
--- a/drivers/thermal/mvebu_thermal.c
+++ b/drivers/thermal/mvebu_thermal.c
@@ -1,6 +1,7 @@
/*
* Marvell EBU thermal sensor driver
*
+ * Copyright (C) 2013 Marvell
* Copyright (C) 2012 Nobuhiro Iwamatsu <iwamatsu at nigauri.org>
*
* This software is licensed under the terms of the GNU General Public
@@ -24,12 +25,21 @@
#include <linux/thermal.h>
#define MVEBU_THERMAL_SOC_VARIANT_KIRKWOOD 0x1
+#define MVEBU_THERMAL_SOC_VARIANT_ARMADA_XP 0x2
#define MVEBU_THERMAL_VALID_OFFSET 9
#define MVEBU_THERMAL_VALID_MASK 0x1
#define MVEBU_THERMAL_TEMP_OFFSET 10
#define MVEBU_THERMAL_TEMP_MASK 0x1FF
+/* Thermal Manager Control and Status Register */
+#define PMU_TDC0_SW_RST_MASK (0x1 << 1)
+#define PMU_TM_DISABLE_OFFS 0
+#define PMU_TM_DISABLE_MASK (0x1 << PMU_TM_DISABLE_OFFS)
+#define PMU_TDC0_REF_CAL_CNT_OFFS 11
+#define PMU_TDC0_REF_CAL_CNT_MASK (0x1ff << PMU_TDC0_REF_CAL_CNT_OFFS)
+#define PMU_TDC0_OTF_CAL_MASK (0x1 << 30)
+
/* Marvell EBU Thermal Sensor Dev Structure */
struct mvebu_thermal_priv {
void __iomem *sensor;
@@ -43,6 +53,35 @@ struct mvebu_thermal_priv {
bool (*is_valid)(struct mvebu_thermal_priv *);
};
+static void armadaxp_init_sensor(struct mvebu_thermal_priv *priv)
+{
+ unsigned long reg;
+
+ if (!priv->control)
+ return;
+
+ /* ??? */
+ reg = readl_relaxed(priv->control);
+ reg |= PMU_TDC0_OTF_CAL_MASK;
+ writel(reg, priv->control);
+
+ /* Reference calibration value */
+ reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
+ reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
+ writel(reg, priv->control);
+
+ /* Reset the sensor */
+ reg = readl_relaxed(priv->control);
+ writel((reg | PMU_TDC0_SW_RST_MASK), priv->control);
+
+ writel(reg, priv->control);
+
+ /* Enable the sensor */
+ reg = readl_relaxed(priv->sensor);
+ reg &= ~PMU_TM_DISABLE_MASK;
+ writel(reg, priv->sensor);
+}
+
static bool mvebu_is_valid(struct mvebu_thermal_priv *priv)
{
unsigned long reg = readl_relaxed(priv->sensor);
@@ -71,6 +110,9 @@ static int mvebu_get_temp(struct thermal_zone_device *thermal,
case MVEBU_THERMAL_SOC_VARIANT_KIRKWOOD:
*temp = ((2363302UL - (7339*reg)) / 10);
break;
+ case MVEBU_THERMAL_SOC_VARIANT_ARMADA_XP:
+ *temp = (3153000000UL - (10000000UL*reg)) / 13825;
+ break;
default:
*temp = 0;
break;
@@ -88,6 +130,10 @@ static const struct of_device_id mvebu_thermal_id_table[] = {
.data = (void *) MVEBU_THERMAL_SOC_VARIANT_KIRKWOOD,
},
{
+ .compatible = "marvell,armadaxp-thermal",
+ .data = (void *) MVEBU_THERMAL_SOC_VARIANT_ARMADA_XP,
+ },
+ {
/* sentinel */
},
};
@@ -130,6 +176,9 @@ static int mvebu_thermal_probe(struct platform_device *pdev)
case MVEBU_THERMAL_SOC_VARIANT_KIRKWOOD:
priv->is_valid = mvebu_is_valid;
break;
+ case MVEBU_THERMAL_SOC_VARIANT_ARMADA_XP:
+ priv->init_sensor = armadaxp_init_sensor;
+ break;
default:
break;
}
@@ -174,5 +223,6 @@ static struct platform_driver mvebu_thermal_driver = {
module_platform_driver(mvebu_thermal_driver);
MODULE_AUTHOR("Nobuhiro Iwamatsu <iwamatsu at nigauri.org>");
+MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia at free-electrons.com>");
MODULE_DESCRIPTION("mvebu thermal driver");
MODULE_LICENSE("GPL v2");
--
1.7.8.6
More information about the linux-arm-kernel
mailing list