linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V1 00/10] Add T210 support in tegra_soctherm
@ 2016-01-13  7:58 Wei Ni
  2016-01-13  7:58 ` [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory Wei Ni
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Wei Ni @ 2016-01-13  7:58 UTC (permalink / raw)
  To: rui.zhang, mikko.perttunen, swarren; +Cc: linux-tegra, linux-kernel, Wei Ni

This patchset adds following functions for tegra_soctherm driver:
1. add T210 support.
2. export debugfs to show some registers.
3. add thermtrip funciton.
4. add suspend/resume function.

Wei Ni (10):
  thermal: tegra: move tegra thermal files into tegra directory
  thermal: tegra: combine sensor group-related data
  thermal: tegra: split tegra_soctherm driver
  thermal: tegra: add T210-specific SOC_THERM driver
  thermal: tegra: add sysfs to dump registers
  of: Add bindings of hw-trips for soctherm
  thermal: tegra: add thermtrip function
  thermal: tegra: add PM support
  arm64: tegra: add soctherm node for Tegra210
  ARM: tegra: set hw trips for Tegra124

 .../devicetree/bindings/thermal/tegra-soctherm.txt |  29 +
 arch/arm/boot/dts/tegra124.dtsi                    |   9 +
 arch/arm64/boot/dts/nvidia/tegra210.dtsi           |  56 ++
 drivers/thermal/Kconfig                            |  15 +-
 drivers/thermal/Makefile                           |   2 +-
 drivers/thermal/tegra/Kconfig                      |  24 +
 drivers/thermal/tegra/Makefile                     |   8 +
 drivers/thermal/tegra/tegra124_soctherm.c          | 237 +++++++
 drivers/thermal/tegra/tegra210_soctherm.c          | 246 +++++++
 drivers/thermal/tegra/tegra_soctherm.c             | 722 +++++++++++++++++++++
 drivers/thermal/tegra/tegra_soctherm.h             | 120 ++++
 drivers/thermal/tegra/tegra_soctherm_fuse.c        | 154 +++++
 drivers/thermal/tegra_soctherm.c                   | 476 --------------
 include/dt-bindings/thermal/tegra124-soctherm.h    |   1 +
 14 files changed, 1612 insertions(+), 487 deletions(-)
 create mode 100644 drivers/thermal/tegra/Kconfig
 create mode 100644 drivers/thermal/tegra/Makefile
 create mode 100644 drivers/thermal/tegra/tegra124_soctherm.c
 create mode 100644 drivers/thermal/tegra/tegra210_soctherm.c
 create mode 100644 drivers/thermal/tegra/tegra_soctherm.c
 create mode 100644 drivers/thermal/tegra/tegra_soctherm.h
 create mode 100644 drivers/thermal/tegra/tegra_soctherm_fuse.c
 delete mode 100644 drivers/thermal/tegra_soctherm.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory
  2016-01-13  7:58 [PATCH V1 00/10] Add T210 support in tegra_soctherm Wei Ni
@ 2016-01-13  7:58 ` Wei Ni
  2016-01-13 14:24   ` Thierry Reding
  2016-01-13  7:58 ` [PATCH V1 02/10] thermal: tegra: combine sensor group-related data Wei Ni
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: Wei Ni @ 2016-01-13  7:58 UTC (permalink / raw)
  To: rui.zhang, mikko.perttunen, swarren; +Cc: linux-tegra, linux-kernel, Wei Ni

Move tegra soctherm driver to tegra directory, it's easy to maintain
and add more new function support for tegra platforms.
This will also help to split soctherm driver into common parts and
chip specific data related parts.

Signed-off-by: Wei Ni <wni@nvidia.com>
---
 drivers/thermal/Kconfig                      | 15 +++++----------
 drivers/thermal/Makefile                     |  2 +-
 drivers/thermal/tegra/Kconfig                |  9 +++++++++
 drivers/thermal/tegra/Makefile               |  6 ++++++
 drivers/thermal/{ => tegra}/tegra_soctherm.c |  0
 5 files changed, 21 insertions(+), 11 deletions(-)
 create mode 100644 drivers/thermal/tegra/Kconfig
 create mode 100644 drivers/thermal/tegra/Makefile
 rename drivers/thermal/{ => tegra}/tegra_soctherm.c (100%)

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index c463c89b90ef..7984cba6b340 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -254,16 +254,6 @@ config ARMADA_THERMAL
 	  Enable this option if you want to have support for thermal management
 	  controller present in Armada 370 and Armada XP SoC.
 
-config TEGRA_SOCTHERM
-	tristate "Tegra SOCTHERM thermal management"
-	depends on ARCH_TEGRA
-	help
-	  Enable this option for integrated thermal management support on NVIDIA
-	  Tegra124 systems-on-chip. The driver supports four thermal zones
-	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
-	  zones to manage temperatures. This option is also required for the
-	  emergency thermal reset (thermtrip) feature to function.
-
 config DB8500_CPUFREQ_COOLING
 	tristate "DB8500 cpufreq cooling"
 	depends on ARCH_U8500
@@ -380,6 +370,11 @@ depends on ARCH_STI && OF
 source "drivers/thermal/st/Kconfig"
 endmenu
 
+menu "Tegra thermal drivers"
+depends on ARCH_TEGRA
+source "drivers/thermal/tegra/Kconfig"
+endmenu
+
 config QCOM_SPMI_TEMP_ALARM
 	tristate "Qualcomm SPMI PMIC Temperature Alarm"
 	depends on OF && (SPMI || COMPILE_TEST) && IIO
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index cfae6a654793..119e25cdcc66 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -46,5 +46,5 @@ obj-$(CONFIG_TI_SOC_THERMAL)	+= ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
 obj-$(CONFIG_INTEL_PCH_THERMAL)	+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)	+= st/
-obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
+obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra/
 obj-$(CONFIG_HISI_THERMAL)     += hisi_thermal.o
diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
new file mode 100644
index 000000000000..a6e6cd4528dc
--- /dev/null
+++ b/drivers/thermal/tegra/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_SOCTHERM
+	tristate "Tegra SOCTHERM thermal management"
+	depends on ARCH_TEGRA
+	help
+	  Enable this option for integrated thermal management support on NVIDIA
+	  Tegra124 systems-on-chip. The driver supports four thermal zones
+	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
+	  zones to manage temperatures. This option is also required for the
+	  emergency thermal reset (thermtrip) feature to function.
diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile
new file mode 100644
index 000000000000..8c51076e4b1e
--- /dev/null
+++ b/drivers/thermal/tegra/Makefile
@@ -0,0 +1,6 @@
+#
+# Tegra thermal specific Makefile
+#
+
+# Tegra soc thermal drivers
+obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra/tegra_soctherm.c
similarity index 100%
rename from drivers/thermal/tegra_soctherm.c
rename to drivers/thermal/tegra/tegra_soctherm.c
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH V1 02/10] thermal: tegra: combine sensor group-related data
  2016-01-13  7:58 [PATCH V1 00/10] Add T210 support in tegra_soctherm Wei Ni
  2016-01-13  7:58 ` [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory Wei Ni
@ 2016-01-13  7:58 ` Wei Ni
  2016-01-13 14:31   ` Thierry Reding
  2016-01-13  7:58 ` [PATCH V1 03/10] thermal: tegra: split tegra_soctherm driver Wei Ni
  2016-01-13  7:58 ` [PATCH V1 04/10] thermal: tegra: add T210-specific SOC_THERM driver Wei Ni
  3 siblings, 1 reply; 13+ messages in thread
From: Wei Ni @ 2016-01-13  7:58 UTC (permalink / raw)
  To: rui.zhang, mikko.perttunen, swarren; +Cc: linux-tegra, linux-kernel, Wei Ni

Combine sensor group-related data structures into struct
tegra_tsensor_group. This provides a single location for
sensor group data storage.
More sensor group data will be added in subsequent patches.

Get rid of T124-specific PDIV/HOTSPOT hack.
tegra-soctherm.c contained a hack to set the SENSOR_PDIV and
SENSOR_HOTSPOT_OFFSET registers - it just did two writes of
T124-specific opaque values.  Convert these into a form that can be
substituted on a per-chip basis, and into structure fields that have
at least some independent meaning.

Signed-off-by: Wei Ni <wni@nvidia.com>
---
 drivers/thermal/tegra/tegra_soctherm.c          | 165 +++++++++++++++++++-----
 include/dt-bindings/thermal/tegra124-soctherm.h |   1 +
 2 files changed, 135 insertions(+), 31 deletions(-)

diff --git a/drivers/thermal/tegra/tegra_soctherm.c b/drivers/thermal/tegra/tegra_soctherm.c
index 74ea5765938b..80d97151739e 100644
--- a/drivers/thermal/tegra/tegra_soctherm.c
+++ b/drivers/thermal/tegra/tegra_soctherm.c
@@ -28,6 +28,7 @@
 #include <linux/thermal.h>
 
 #include <soc/tegra/fuse.h>
+#include <dt-bindings/thermal/tegra124-soctherm.h>
 
 #define SENSOR_CONFIG0				0
 #define SENSOR_CONFIG0_STOP			BIT(0)
@@ -47,13 +48,23 @@
 #define SENSOR_CONFIG2_THERMB_SHIFT		0
 
 #define SENSOR_PDIV				0x1c0
-#define SENSOR_PDIV_T124			0x8888
+#define SENSOR_PDIV_CPU_MASK			(0xf << 12)
+#define SENSOR_PDIV_GPU_MASK			(0xf << 8)
+#define SENSOR_PDIV_MEM_MASK			(0xf << 4)
+#define SENSOR_PDIV_PLLX_MASK			(0xf << 0)
+
 #define SENSOR_HOTSPOT_OFF			0x1c4
-#define SENSOR_HOTSPOT_OFF_T124			0x00060600
+#define SENSOR_HOTSPOT_CPU_MASK			(0xff << 16)
+#define SENSOR_HOTSPOT_GPU_MASK			(0xff << 8)
+#define SENSOR_HOTSPOT_MEM_MASK			(0xff << 0)
+
 #define SENSOR_TEMP1				0x1c8
+#define SENSOR_TEMP1_CPU_TEMP_MASK		(0xffff << 16)
+#define SENSOR_TEMP1_GPU_TEMP_MASK		0xffff
 #define SENSOR_TEMP2				0x1cc
+#define SENSOR_TEMP2_MEM_TEMP_MASK		(0xffff << 16)
+#define SENSOR_TEMP2_PLLX_TEMP_MASK		0xffff
 
-#define SENSOR_TEMP_MASK			0xffff
 #define READBACK_VALUE_MASK			0xff00
 #define READBACK_VALUE_SHIFT			8
 #define READBACK_ADD_HALF			BIT(7)
@@ -77,8 +88,36 @@
 #define NOMINAL_CALIB_FT_T124			105
 #define NOMINAL_CALIB_CP_T124			25
 
+/* get val from register(r) mask bits(m) */
+#define REG_GET_MASK(r, m)	(((r) & (m)) >> (ffs(m) - 1))
+/* set val(v) to mask bits(m) of register(r) */
+#define REG_SET_MASK(r, m, v)	(((r) & ~(m)) | \
+				 (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
+
+/**
+ * struct tegra_tsensor_group - SOC_THERM sensor group data
+ * @name: short name of the temperature sensor group
+ * @id: numeric ID of the temperature sensor group
+ * @sensor_temp_offset: offset of the SENSOR_TEMP* register
+ * @sensor_temp_mask: bit mask for this sensor group in SENSOR_TEMP* register
+ * @pdiv: the sensor count post-divider to use during runtime
+ * @pdiv_ate: the sensor count post-divider used during automated test
+ * @pdiv_mask: register bitfield mask for the PDIV field for this sensor
+ * @pllx_hotspot_diff: hotspot offset from the PLLX sensor, must be 0 for
+    PLLX sensor group
+ * @pllx_hotspot_mask: register bitfield mask for the HOTSPOT field
+ */
+struct tegra_tsensor_group {
+	const char	*name;
+	u8		id;
+	u16		sensor_temp_offset;
+	u32		sensor_temp_mask;
+	u32		pdiv, pdiv_ate, pdiv_mask;
+	u32		pllx_hotspot_diff, pllx_hotspot_mask;
+};
+
 struct tegra_tsensor_configuration {
-	u32 tall, tsample, tiddq_en, ten_count, pdiv, tsample_ate, pdiv_ate;
+	u32 tall, tiddq_en, ten_count, tsample, tsample_ate;
 };
 
 struct tegra_tsensor {
@@ -86,21 +125,74 @@ struct tegra_tsensor {
 	u32 base, calib_fuse_offset;
 	/* Correction values used to modify values read from calibration fuses */
 	s32 fuse_corr_alpha, fuse_corr_beta;
+	const struct tegra_tsensor_group *group;
 };
 
 struct tegra_thermctl_zone {
 	void __iomem *reg;
-	unsigned int shift;
+	u32 mask;
 };
 
 static const struct tegra_tsensor_configuration t124_tsensor_config = {
 	.tall = 16300,
-	.tsample = 120,
 	.tiddq_en = 1,
 	.ten_count = 1,
-	.pdiv = 8,
+	.tsample = 120,
 	.tsample_ate = 480,
-	.pdiv_ate = 8
+};
+
+static struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_CPU,
+	.name				= "cpu",
+	.sensor_temp_offset		= SENSOR_TEMP1,
+	.sensor_temp_mask		= SENSOR_TEMP1_CPU_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_CPU_MASK,
+	.pllx_hotspot_diff		= 10,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_CPU_MASK,
+};
+
+static struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_GPU,
+	.name				= "gpu",
+	.sensor_temp_offset		= SENSOR_TEMP1,
+	.sensor_temp_mask		= SENSOR_TEMP1_GPU_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_GPU_MASK,
+	.pllx_hotspot_diff		= 5,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_GPU_MASK,
+};
+
+static struct tegra_tsensor_group tegra124_tsensor_group_pll = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_PLLX,
+	.name				= "pll",
+	.sensor_temp_offset		= SENSOR_TEMP2,
+	.sensor_temp_mask		= SENSOR_TEMP2_PLLX_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_PLLX_MASK,
+	.pllx_hotspot_diff		= 0,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_MEM_MASK,
+};
+
+static struct tegra_tsensor_group tegra124_tsensor_group_mem = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_MEM,
+	.name				= "mem",
+	.sensor_temp_offset		= SENSOR_TEMP2,
+	.sensor_temp_mask		= SENSOR_TEMP2_MEM_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_MEM_MASK,
+};
+
+static struct tegra_tsensor_group *
+tegra124_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
+	&tegra124_tsensor_group_cpu,
+	&tegra124_tsensor_group_gpu,
+	&tegra124_tsensor_group_pll,
+	&tegra124_tsensor_group_mem,
 };
 
 static const struct tegra_tsensor t124_tsensors[] = {
@@ -110,6 +202,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x098,
 		.fuse_corr_alpha = 1135400,
 		.fuse_corr_beta = -6266900,
+		.group = &tegra124_tsensor_group_cpu,
 	},
 	{
 		.config = &t124_tsensor_config,
@@ -117,6 +210,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x084,
 		.fuse_corr_alpha = 1122220,
 		.fuse_corr_beta = -5700700,
+		.group = &tegra124_tsensor_group_cpu,
 	},
 	{
 		.config = &t124_tsensor_config,
@@ -124,6 +218,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x088,
 		.fuse_corr_alpha = 1127000,
 		.fuse_corr_beta = -6768200,
+		.group = &tegra124_tsensor_group_cpu,
 	},
 	{
 		.config = &t124_tsensor_config,
@@ -131,6 +226,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x12c,
 		.fuse_corr_alpha = 1110900,
 		.fuse_corr_beta = -6232000,
+		.group = &tegra124_tsensor_group_cpu,
 	},
 	{
 		.config = &t124_tsensor_config,
@@ -138,6 +234,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x158,
 		.fuse_corr_alpha = 1122300,
 		.fuse_corr_beta = -5936400,
+		.group = &tegra124_tsensor_group_mem,
 	},
 	{
 		.config = &t124_tsensor_config,
@@ -145,6 +242,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x15c,
 		.fuse_corr_alpha = 1145700,
 		.fuse_corr_beta = -7124600,
+		.group = &tegra124_tsensor_group_mem,
 	},
 	{
 		.config = &t124_tsensor_config,
@@ -152,6 +250,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x154,
 		.fuse_corr_alpha = 1120100,
 		.fuse_corr_beta = -6000500,
+		.group = &tegra124_tsensor_group_gpu,
 	},
 	{
 		.config = &t124_tsensor_config,
@@ -159,6 +258,7 @@ static const struct tegra_tsensor t124_tsensors[] = {
 		.calib_fuse_offset = 0x160,
 		.fuse_corr_alpha = 1106500,
 		.fuse_corr_beta = -6729300,
+		.group = &tegra124_tsensor_group_pll,
 	},
 };
 
@@ -168,7 +268,7 @@ struct tegra_soctherm {
 	struct clk *clock_soctherm;
 	void __iomem *regs;
 
-	struct thermal_zone_device *thermctl_tzs[4];
+	struct thermal_zone_device *thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_NUM];
 };
 
 struct tsensor_shared_calibration {
@@ -237,8 +337,8 @@ calculate_tsensor_calibration(const struct tegra_tsensor *sensor,
 	delta_sens = actual_tsensor_ft - actual_tsensor_cp;
 	delta_temp = shared->actual_temp_ft - shared->actual_temp_cp;
 
-	mult = sensor->config->pdiv * sensor->config->tsample_ate;
-	div = sensor->config->tsample * sensor->config->pdiv_ate;
+	mult = sensor->group->pdiv * sensor->config->tsample_ate;
+	div = sensor->config->tsample * sensor->group->pdiv_ate;
 
 	therma = div64_s64_precise((s64) delta_temp * (1LL << 13) * mult,
 				   (s64) delta_sens * div);
@@ -311,7 +411,8 @@ static int tegra_thermctl_get_temp(void *data, int *out_temp)
 	struct tegra_thermctl_zone *zone = data;
 	u32 val;
 
-	val = (readl(zone->reg) >> zone->shift) & SENSOR_TEMP_MASK;
+	val = readl(zone->reg);
+	val = REG_GET_MASK(val, zone->mask);
 	*out_temp = translate_temp(val);
 
 	return 0;
@@ -327,18 +428,6 @@ static const struct of_device_id tegra_soctherm_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
 
-struct thermctl_zone_desc {
-	unsigned int offset;
-	unsigned int shift;
-};
-
-static const struct thermctl_zone_desc t124_thermctl_temp_zones[] = {
-	{ SENSOR_TEMP1, 16 },
-	{ SENSOR_TEMP2, 16 },
-	{ SENSOR_TEMP1, 0 },
-	{ SENSOR_TEMP2, 0 }
-};
-
 static int tegra_soctherm_probe(struct platform_device *pdev)
 {
 	struct tegra_soctherm *tegra;
@@ -347,8 +436,10 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
 	struct resource *res;
 	unsigned int i;
 	int err;
+	u32 pdiv, hotspot;
 
 	const struct tegra_tsensor *tsensors = t124_tsensors;
+	struct tegra_tsensor_group **ttgs = tegra124_tsensor_groups;
 
 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
 	if (!tegra)
@@ -403,12 +494,23 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
 			goto disable_clocks;
 	}
 
-	writel(SENSOR_PDIV_T124, tegra->regs + SENSOR_PDIV);
-	writel(SENSOR_HOTSPOT_OFF_T124, tegra->regs + SENSOR_HOTSPOT_OFF);
+	/* program pdiv and hotspot offsets per THERM */
+	pdiv = readl(tegra->regs + SENSOR_PDIV);
+	hotspot = readl(tegra->regs + SENSOR_HOTSPOT_OFF);
+	for (i = 0; i < TEGRA124_SOCTHERM_SENSOR_NUM; ++i) {
+		pdiv = REG_SET_MASK(pdiv, ttgs[i]->pdiv_mask,
+				   ttgs[i]->pdiv);
+		if (ttgs[i]->id != TEGRA124_SOCTHERM_SENSOR_PLLX)
+			hotspot =  REG_SET_MASK(hotspot,
+						ttgs[i]->pllx_hotspot_mask,
+						ttgs[i]->pllx_hotspot_diff);
+	}
+	writel(pdiv, tegra->regs + SENSOR_PDIV);
+	writel(hotspot, tegra->regs + SENSOR_HOTSPOT_OFF);
 
 	/* Initialize thermctl sensors */
 
-	for (i = 0; i < ARRAY_SIZE(tegra->thermctl_tzs); ++i) {
+	for (i = 0; i < TEGRA124_SOCTHERM_SENSOR_NUM; ++i) {
 		struct tegra_thermctl_zone *zone =
 			devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL);
 		if (!zone) {
@@ -416,10 +518,11 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
 			goto unregister_tzs;
 		}
 
-		zone->reg = tegra->regs + t124_thermctl_temp_zones[i].offset;
-		zone->shift = t124_thermctl_temp_zones[i].shift;
+		zone->reg = tegra->regs + ttgs[i]->sensor_temp_offset;
+		zone->mask = ttgs[i]->sensor_temp_mask;
 
-		tz = thermal_zone_of_sensor_register(&pdev->dev, i, zone,
+		tz = thermal_zone_of_sensor_register(&pdev->dev,
+						     ttgs[i]->id, zone,
 						     &tegra_of_thermal_ops);
 		if (IS_ERR(tz)) {
 			err = PTR_ERR(tz);
@@ -428,7 +531,7 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
 			goto unregister_tzs;
 		}
 
-		tegra->thermctl_tzs[i] = tz;
+		tegra->thermctl_tzs[ttgs[i]->id] = tz;
 	}
 
 	return 0;
diff --git a/include/dt-bindings/thermal/tegra124-soctherm.h b/include/dt-bindings/thermal/tegra124-soctherm.h
index 85aaf66690f9..729ab9fc325e 100644
--- a/include/dt-bindings/thermal/tegra124-soctherm.h
+++ b/include/dt-bindings/thermal/tegra124-soctherm.h
@@ -9,5 +9,6 @@
 #define TEGRA124_SOCTHERM_SENSOR_MEM 1
 #define TEGRA124_SOCTHERM_SENSOR_GPU 2
 #define TEGRA124_SOCTHERM_SENSOR_PLLX 3
+#define TEGRA124_SOCTHERM_SENSOR_NUM 4
 
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH V1 03/10] thermal: tegra: split tegra_soctherm driver
  2016-01-13  7:58 [PATCH V1 00/10] Add T210 support in tegra_soctherm Wei Ni
  2016-01-13  7:58 ` [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory Wei Ni
  2016-01-13  7:58 ` [PATCH V1 02/10] thermal: tegra: combine sensor group-related data Wei Ni
@ 2016-01-13  7:58 ` Wei Ni
  2016-01-13 15:04   ` Thierry Reding
  2016-01-13  7:58 ` [PATCH V1 04/10] thermal: tegra: add T210-specific SOC_THERM driver Wei Ni
  3 siblings, 1 reply; 13+ messages in thread
From: Wei Ni @ 2016-01-13  7:58 UTC (permalink / raw)
  To: rui.zhang, mikko.perttunen, swarren; +Cc: linux-tegra, linux-kernel, Wei Ni

Split most of the T124 data and code into a T124-specific driver.
Split most of the fuse-related code into a fuse-related source file.
Now drivers/thermal/tegra_soctherm.c contains common SOC_THERM library
code.  This is in preparation for adding a T210-specific driver in a
future patch.

Beyond the maintainability improvements, this is intended to separate
chip-specific ATE and characterization-related hacks into chip-specific
drivers, in the hopes that they won't pollute code for other chips.

Signed-off-by: Wei Ni <wni@nvidia.com>
---
 drivers/thermal/tegra/Kconfig               |   8 +-
 drivers/thermal/tegra/Makefile              |   3 +-
 drivers/thermal/tegra/tegra124_soctherm.c   | 201 +++++++++++++++++
 drivers/thermal/tegra/tegra_soctherm.c      | 333 ++--------------------------
 drivers/thermal/tegra/tegra_soctherm.h      | 106 +++++++++
 drivers/thermal/tegra/tegra_soctherm_fuse.c | 143 ++++++++++++
 6 files changed, 474 insertions(+), 320 deletions(-)
 create mode 100644 drivers/thermal/tegra/tegra124_soctherm.c
 create mode 100644 drivers/thermal/tegra/tegra_soctherm.h
 create mode 100644 drivers/thermal/tegra/tegra_soctherm_fuse.c

diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
index a6e6cd4528dc..ae7e5e93dab9 100644
--- a/drivers/thermal/tegra/Kconfig
+++ b/drivers/thermal/tegra/Kconfig
@@ -1,6 +1,10 @@
 config TEGRA_SOCTHERM
-	tristate "Tegra SOCTHERM thermal management"
-	depends on ARCH_TEGRA
+	bool
+
+config TEGRA124_SOCTHERM
+	bool "Tegra124 SOCTHERM thermal management"
+	depends on ARCH_TEGRA_124_SOC
+	select TEGRA_SOCTHERM
 	help
 	  Enable this option for integrated thermal management support on NVIDIA
 	  Tegra124 systems-on-chip. The driver supports four thermal zones
diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile
index 8c51076e4b1e..7a864ec07a25 100644
--- a/drivers/thermal/tegra/Makefile
+++ b/drivers/thermal/tegra/Makefile
@@ -3,4 +3,5 @@
 #
 
 # Tegra soc thermal drivers
-obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
+obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o tegra_soctherm_fuse.o
+obj-$(CONFIG_TEGRA124_SOCTHERM)	+= tegra124_soctherm.o
diff --git a/drivers/thermal/tegra/tegra124_soctherm.c b/drivers/thermal/tegra/tegra124_soctherm.c
new file mode 100644
index 000000000000..56bf26d58a04
--- /dev/null
+++ b/drivers/thermal/tegra/tegra124_soctherm.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/platform_device.h>
+
+#include <dt-bindings/thermal/tegra124-soctherm.h>
+
+#include "tegra_soctherm.h"
+
+static const struct tegra_tsensor_configuration t124_tsensor_config = {
+	.tall = 16300,
+	.tiddq_en = 1,
+	.ten_count = 1,
+	.tsample = 120,
+	.tsample_ate = 480,
+};
+
+static const struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_CPU,
+	.name				= "cpu",
+	.sensor_temp_offset		= SENSOR_TEMP1,
+	.sensor_temp_mask		= SENSOR_TEMP1_CPU_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_CPU_MASK,
+	.pllx_hotspot_diff		= 10,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_CPU_MASK,
+};
+
+static const struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_GPU,
+	.name				= "gpu",
+	.sensor_temp_offset		= SENSOR_TEMP1,
+	.sensor_temp_mask		= SENSOR_TEMP1_GPU_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_GPU_MASK,
+	.pllx_hotspot_diff		= 5,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_GPU_MASK,
+};
+
+static const struct tegra_tsensor_group tegra124_tsensor_group_pll = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_PLLX,
+	.name				= "pll",
+	.sensor_temp_offset		= SENSOR_TEMP2,
+	.sensor_temp_mask		= SENSOR_TEMP2_PLLX_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_PLLX_MASK,
+};
+
+static const struct tegra_tsensor_group tegra124_tsensor_group_mem = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_MEM,
+	.name				= "mem",
+	.sensor_temp_offset		= SENSOR_TEMP2,
+	.sensor_temp_mask		= SENSOR_TEMP2_MEM_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_MEM_MASK,
+	.pllx_hotspot_diff		= 0,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_MEM_MASK,
+};
+
+static const struct tegra_tsensor_group *
+tegra124_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
+	&tegra124_tsensor_group_cpu,
+	&tegra124_tsensor_group_gpu,
+	&tegra124_tsensor_group_pll,
+	&tegra124_tsensor_group_mem,
+};
+
+static struct tegra_tsensor tegra124_tsensors[] = {
+	{
+		.name = "cpu0",
+		.base = 0xc0,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x098,
+		.fuse_corr_alpha = 1135400,
+		.fuse_corr_beta = -6266900,
+		.group = &tegra124_tsensor_group_cpu,
+	},
+	{
+		.name = "cpu1",
+		.base = 0xe0,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x084,
+		.fuse_corr_alpha = 1122220,
+		.fuse_corr_beta = -5700700,
+		.group = &tegra124_tsensor_group_cpu,
+	},
+	{
+		.name = "cpu2",
+		.base = 0x100,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x088,
+		.fuse_corr_alpha = 1127000,
+		.fuse_corr_beta = -6768200,
+		.group = &tegra124_tsensor_group_cpu,
+	},
+	{
+		.name = "cpu3",
+		.base = 0x120,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x12c,
+		.fuse_corr_alpha = 1110900,
+		.fuse_corr_beta = -6232000,
+		.group = &tegra124_tsensor_group_cpu,
+	},
+	{
+		.name = "mem0",
+		.base = 0x140,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x158,
+		.fuse_corr_alpha = 1122300,
+		.fuse_corr_beta = -5936400,
+		.group = &tegra124_tsensor_group_mem,
+	},
+	{
+		.name = "mem1",
+		.base = 0x160,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x15c,
+		.fuse_corr_alpha = 1145700,
+		.fuse_corr_beta = -7124600,
+		.group = &tegra124_tsensor_group_mem,
+	},
+	{
+		.name = "gpu",
+		.base = 0x180,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x154,
+		.fuse_corr_alpha = 1120100,
+		.fuse_corr_beta = -6000500,
+		.group = &tegra124_tsensor_group_gpu,
+	},
+	{
+		.name = "pllx",
+		.base = 0x1a0,
+		.config = &t124_tsensor_config,
+		.calib_fuse_offset = 0x160,
+		.fuse_corr_alpha = 1106500,
+		.fuse_corr_beta = -6729300,
+		.group = &tegra124_tsensor_group_pll,
+	},
+	{ .name = NULL },
+};
+
+/*
+ * Mask/shift bits in FUSE_TSENSOR_COMMON and
+ * FUSE_TSENSOR_COMMON, which are described in
+ * tegra_soctherm_fuse.c
+ */
+static const struct tegra_soctherm_fuse tegra124_soctherm_fuse = {
+	.fuse_base_cp_mask = 0x3ff,
+	.fuse_base_cp_shift = 0,
+	.fuse_base_ft_mask = 0x7ff << 10,
+	.fuse_base_ft_shift = 10,
+	.fuse_shift_ft_mask = 0x1f << 21,
+	.fuse_shift_ft_shift = 21,
+	.fuse_spare_realignment = 0x1fc,
+};
+
+static const struct of_device_id tegra124_soctherm_of_match[] = {
+	{ .compatible = "nvidia,tegra124-soctherm" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
+
+static int tegra124_soctherm_probe(struct platform_device *pdev)
+{
+	return tegra_soctherm_probe(pdev,
+				    tegra124_tsensors,
+				    tegra124_tsensor_groups,
+				    &tegra124_soctherm_fuse);
+}
+
+static struct platform_driver tegra124_soctherm_driver = {
+	.probe = tegra124_soctherm_probe,
+	.remove = tegra_soctherm_remove,
+	.driver = {
+		.name = "tegra124_soctherm",
+		.of_match_table = tegra124_soctherm_of_match,
+	},
+};
+module_platform_driver(tegra124_soctherm_driver);
+
+MODULE_AUTHOR("NVIDIA");
+MODULE_DESCRIPTION("Tegra124 SOCTHERM thermal management driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/tegra/tegra_soctherm.c b/drivers/thermal/tegra/tegra_soctherm.c
index 80d97151739e..cc5a3e14948f 100644
--- a/drivers/thermal/tegra/tegra_soctherm.c
+++ b/drivers/thermal/tegra/tegra_soctherm.c
@@ -27,9 +27,10 @@
 #include <linux/reset.h>
 #include <linux/thermal.h>
 
-#include <soc/tegra/fuse.h>
 #include <dt-bindings/thermal/tegra124-soctherm.h>
 
+#include "tegra_soctherm.h"
+
 #define SENSOR_CONFIG0				0
 #define SENSOR_CONFIG0_STOP			BIT(0)
 #define SENSOR_CONFIG0_TALL_SHIFT		8
@@ -43,225 +44,27 @@
 #define SENSOR_CONFIG1_TEN_COUNT_SHIFT		24
 #define SENSOR_CONFIG1_TEMP_ENABLE		BIT(31)
 
-#define SENSOR_CONFIG2				8
-#define SENSOR_CONFIG2_THERMA_SHIFT		16
-#define SENSOR_CONFIG2_THERMB_SHIFT		0
-
-#define SENSOR_PDIV				0x1c0
-#define SENSOR_PDIV_CPU_MASK			(0xf << 12)
-#define SENSOR_PDIV_GPU_MASK			(0xf << 8)
-#define SENSOR_PDIV_MEM_MASK			(0xf << 4)
-#define SENSOR_PDIV_PLLX_MASK			(0xf << 0)
-
-#define SENSOR_HOTSPOT_OFF			0x1c4
-#define SENSOR_HOTSPOT_CPU_MASK			(0xff << 16)
-#define SENSOR_HOTSPOT_GPU_MASK			(0xff << 8)
-#define SENSOR_HOTSPOT_MEM_MASK			(0xff << 0)
-
-#define SENSOR_TEMP1				0x1c8
-#define SENSOR_TEMP1_CPU_TEMP_MASK		(0xffff << 16)
-#define SENSOR_TEMP1_GPU_TEMP_MASK		0xffff
-#define SENSOR_TEMP2				0x1cc
-#define SENSOR_TEMP2_MEM_TEMP_MASK		(0xffff << 16)
-#define SENSOR_TEMP2_PLLX_TEMP_MASK		0xffff
+/*
+ * SENSOR_CONFIG2 is defined in tegra_soctherm.h
+ * because, it will be used by tegra_soctherm_fuse.c
+ */
 
 #define READBACK_VALUE_MASK			0xff00
 #define READBACK_VALUE_SHIFT			8
 #define READBACK_ADD_HALF			BIT(7)
 #define READBACK_NEGATE				BIT(1)
 
-#define FUSE_TSENSOR8_CALIB			0x180
-#define FUSE_SPARE_REALIGNMENT_REG_0		0x1fc
-
-#define FUSE_TSENSOR_CALIB_CP_TS_BASE_MASK	0x1fff
-#define FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK	(0x1fff << 13)
-#define FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT	13
-
-#define FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK	0x3ff
-#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK	(0x7ff << 10)
-#define FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT	10
-
-#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_CP_MASK 0x3f
-#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK (0x1f << 21)
-#define FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT 21
-
-#define NOMINAL_CALIB_FT_T124			105
-#define NOMINAL_CALIB_CP_T124			25
-
 /* get val from register(r) mask bits(m) */
 #define REG_GET_MASK(r, m)	(((r) & (m)) >> (ffs(m) - 1))
 /* set val(v) to mask bits(m) of register(r) */
 #define REG_SET_MASK(r, m, v)	(((r) & ~(m)) | \
 				 (((v) & (m >> (ffs(m) - 1))) << (ffs(m) - 1)))
 
-/**
- * struct tegra_tsensor_group - SOC_THERM sensor group data
- * @name: short name of the temperature sensor group
- * @id: numeric ID of the temperature sensor group
- * @sensor_temp_offset: offset of the SENSOR_TEMP* register
- * @sensor_temp_mask: bit mask for this sensor group in SENSOR_TEMP* register
- * @pdiv: the sensor count post-divider to use during runtime
- * @pdiv_ate: the sensor count post-divider used during automated test
- * @pdiv_mask: register bitfield mask for the PDIV field for this sensor
- * @pllx_hotspot_diff: hotspot offset from the PLLX sensor, must be 0 for
-    PLLX sensor group
- * @pllx_hotspot_mask: register bitfield mask for the HOTSPOT field
- */
-struct tegra_tsensor_group {
-	const char	*name;
-	u8		id;
-	u16		sensor_temp_offset;
-	u32		sensor_temp_mask;
-	u32		pdiv, pdiv_ate, pdiv_mask;
-	u32		pllx_hotspot_diff, pllx_hotspot_mask;
-};
-
-struct tegra_tsensor_configuration {
-	u32 tall, tiddq_en, ten_count, tsample, tsample_ate;
-};
-
-struct tegra_tsensor {
-	const struct tegra_tsensor_configuration *config;
-	u32 base, calib_fuse_offset;
-	/* Correction values used to modify values read from calibration fuses */
-	s32 fuse_corr_alpha, fuse_corr_beta;
-	const struct tegra_tsensor_group *group;
-};
-
 struct tegra_thermctl_zone {
 	void __iomem *reg;
 	u32 mask;
 };
 
-static const struct tegra_tsensor_configuration t124_tsensor_config = {
-	.tall = 16300,
-	.tiddq_en = 1,
-	.ten_count = 1,
-	.tsample = 120,
-	.tsample_ate = 480,
-};
-
-static struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
-	.id				= TEGRA124_SOCTHERM_SENSOR_CPU,
-	.name				= "cpu",
-	.sensor_temp_offset		= SENSOR_TEMP1,
-	.sensor_temp_mask		= SENSOR_TEMP1_CPU_TEMP_MASK,
-	.pdiv				= 8,
-	.pdiv_ate			= 8,
-	.pdiv_mask			= SENSOR_PDIV_CPU_MASK,
-	.pllx_hotspot_diff		= 10,
-	.pllx_hotspot_mask		= SENSOR_HOTSPOT_CPU_MASK,
-};
-
-static struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
-	.id				= TEGRA124_SOCTHERM_SENSOR_GPU,
-	.name				= "gpu",
-	.sensor_temp_offset		= SENSOR_TEMP1,
-	.sensor_temp_mask		= SENSOR_TEMP1_GPU_TEMP_MASK,
-	.pdiv				= 8,
-	.pdiv_ate			= 8,
-	.pdiv_mask			= SENSOR_PDIV_GPU_MASK,
-	.pllx_hotspot_diff		= 5,
-	.pllx_hotspot_mask		= SENSOR_HOTSPOT_GPU_MASK,
-};
-
-static struct tegra_tsensor_group tegra124_tsensor_group_pll = {
-	.id				= TEGRA124_SOCTHERM_SENSOR_PLLX,
-	.name				= "pll",
-	.sensor_temp_offset		= SENSOR_TEMP2,
-	.sensor_temp_mask		= SENSOR_TEMP2_PLLX_TEMP_MASK,
-	.pdiv				= 8,
-	.pdiv_ate			= 8,
-	.pdiv_mask			= SENSOR_PDIV_PLLX_MASK,
-	.pllx_hotspot_diff		= 0,
-	.pllx_hotspot_mask		= SENSOR_HOTSPOT_MEM_MASK,
-};
-
-static struct tegra_tsensor_group tegra124_tsensor_group_mem = {
-	.id				= TEGRA124_SOCTHERM_SENSOR_MEM,
-	.name				= "mem",
-	.sensor_temp_offset		= SENSOR_TEMP2,
-	.sensor_temp_mask		= SENSOR_TEMP2_MEM_TEMP_MASK,
-	.pdiv				= 8,
-	.pdiv_ate			= 8,
-	.pdiv_mask			= SENSOR_PDIV_MEM_MASK,
-};
-
-static struct tegra_tsensor_group *
-tegra124_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
-	&tegra124_tsensor_group_cpu,
-	&tegra124_tsensor_group_gpu,
-	&tegra124_tsensor_group_pll,
-	&tegra124_tsensor_group_mem,
-};
-
-static const struct tegra_tsensor t124_tsensors[] = {
-	{
-		.config = &t124_tsensor_config,
-		.base = 0xc0,
-		.calib_fuse_offset = 0x098,
-		.fuse_corr_alpha = 1135400,
-		.fuse_corr_beta = -6266900,
-		.group = &tegra124_tsensor_group_cpu,
-	},
-	{
-		.config = &t124_tsensor_config,
-		.base = 0xe0,
-		.calib_fuse_offset = 0x084,
-		.fuse_corr_alpha = 1122220,
-		.fuse_corr_beta = -5700700,
-		.group = &tegra124_tsensor_group_cpu,
-	},
-	{
-		.config = &t124_tsensor_config,
-		.base = 0x100,
-		.calib_fuse_offset = 0x088,
-		.fuse_corr_alpha = 1127000,
-		.fuse_corr_beta = -6768200,
-		.group = &tegra124_tsensor_group_cpu,
-	},
-	{
-		.config = &t124_tsensor_config,
-		.base = 0x120,
-		.calib_fuse_offset = 0x12c,
-		.fuse_corr_alpha = 1110900,
-		.fuse_corr_beta = -6232000,
-		.group = &tegra124_tsensor_group_cpu,
-	},
-	{
-		.config = &t124_tsensor_config,
-		.base = 0x140,
-		.calib_fuse_offset = 0x158,
-		.fuse_corr_alpha = 1122300,
-		.fuse_corr_beta = -5936400,
-		.group = &tegra124_tsensor_group_mem,
-	},
-	{
-		.config = &t124_tsensor_config,
-		.base = 0x160,
-		.calib_fuse_offset = 0x15c,
-		.fuse_corr_alpha = 1145700,
-		.fuse_corr_beta = -7124600,
-		.group = &tegra124_tsensor_group_mem,
-	},
-	{
-		.config = &t124_tsensor_config,
-		.base = 0x180,
-		.calib_fuse_offset = 0x154,
-		.fuse_corr_alpha = 1120100,
-		.fuse_corr_beta = -6000500,
-		.group = &tegra124_tsensor_group_gpu,
-	},
-	{
-		.config = &t124_tsensor_config,
-		.base = 0x1a0,
-		.calib_fuse_offset = 0x160,
-		.fuse_corr_alpha = 1106500,
-		.fuse_corr_beta = -6729300,
-		.group = &tegra124_tsensor_group_pll,
-	},
-};
-
 struct tegra_soctherm {
 	struct reset_control *reset;
 	struct clk *clock_tsensor;
@@ -271,103 +74,15 @@ struct tegra_soctherm {
 	struct thermal_zone_device *thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_NUM];
 };
 
-struct tsensor_shared_calibration {
-	u32 base_cp, base_ft;
-	u32 actual_temp_cp, actual_temp_ft;
-};
-
-static int calculate_shared_calibration(struct tsensor_shared_calibration *r)
-{
-	u32 val, shifted_cp, shifted_ft;
-	int err;
-
-	err = tegra_fuse_readl(FUSE_TSENSOR8_CALIB, &val);
-	if (err)
-		return err;
-	r->base_cp = val & FUSE_TSENSOR8_CALIB_CP_TS_BASE_MASK;
-	r->base_ft = (val & FUSE_TSENSOR8_CALIB_FT_TS_BASE_MASK)
-		>> FUSE_TSENSOR8_CALIB_FT_TS_BASE_SHIFT;
-	val = ((val & FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_MASK)
-		>> FUSE_SPARE_REALIGNMENT_REG_SHIFT_FT_SHIFT);
-	shifted_ft = sign_extend32(val, 4);
-
-	err = tegra_fuse_readl(FUSE_SPARE_REALIGNMENT_REG_0, &val);
-	if (err)
-		return err;
-	shifted_cp = sign_extend32(val, 5);
-
-	r->actual_temp_cp = 2 * NOMINAL_CALIB_CP_T124 + shifted_cp;
-	r->actual_temp_ft = 2 * NOMINAL_CALIB_FT_T124 + shifted_ft;
-
-	return 0;
-}
-
-static s64 div64_s64_precise(s64 a, s64 b)
-{
-	s64 r, al;
-
-	/* Scale up for increased precision division */
-	al = a << 16;
-
-	r = div64_s64(al * 2 + 1, 2 * b);
-	return r >> 16;
-}
-
-static int
-calculate_tsensor_calibration(const struct tegra_tsensor *sensor,
-			      const struct tsensor_shared_calibration *shared,
-			      u32 *calib)
-{
-	u32 val;
-	s32 actual_tsensor_ft, actual_tsensor_cp, delta_sens, delta_temp,
-	    mult, div;
-	s16 therma, thermb;
-	s64 tmp;
-	int err;
-
-	err = tegra_fuse_readl(sensor->calib_fuse_offset, &val);
-	if (err)
-		return err;
-
-	actual_tsensor_cp = (shared->base_cp * 64) + sign_extend32(val, 12);
-	val = (val & FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK)
-		>> FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT;
-	actual_tsensor_ft = (shared->base_ft * 32) + sign_extend32(val, 12);
-
-	delta_sens = actual_tsensor_ft - actual_tsensor_cp;
-	delta_temp = shared->actual_temp_ft - shared->actual_temp_cp;
-
-	mult = sensor->group->pdiv * sensor->config->tsample_ate;
-	div = sensor->config->tsample * sensor->group->pdiv_ate;
-
-	therma = div64_s64_precise((s64) delta_temp * (1LL << 13) * mult,
-				   (s64) delta_sens * div);
-
-	tmp = (s64)actual_tsensor_ft * shared->actual_temp_cp -
-	      (s64)actual_tsensor_cp * shared->actual_temp_ft;
-	thermb = div64_s64_precise(tmp, (s64)delta_sens);
-
-	therma = div64_s64_precise((s64)therma * sensor->fuse_corr_alpha,
-				   (s64)1000000LL);
-	thermb = div64_s64_precise((s64)thermb * sensor->fuse_corr_alpha +
-				   sensor->fuse_corr_beta, (s64)1000000LL);
-
-	*calib = ((u16)therma << SENSOR_CONFIG2_THERMA_SHIFT) |
-		 ((u16)thermb << SENSOR_CONFIG2_THERMB_SHIFT);
-
-	return 0;
-}
-
 static int enable_tsensor(struct tegra_soctherm *tegra,
-			  const struct tegra_tsensor *sensor,
+			  struct tegra_tsensor *sensor,
 			  const struct tsensor_shared_calibration *shared)
 {
 	void __iomem *base = tegra->regs + sensor->base;
 	unsigned int val;
-	u32 calib;
 	int err;
 
-	err = calculate_tsensor_calibration(sensor, shared, &calib);
+	err = tegra_soctherm_calculate_tsensor_calibration(sensor, shared);
 	if (err)
 		return err;
 
@@ -380,7 +95,7 @@ static int enable_tsensor(struct tegra_soctherm *tegra,
 	val |= SENSOR_CONFIG1_TEMP_ENABLE;
 	writel(val, base + SENSOR_CONFIG1);
 
-	writel(calib, base + SENSOR_CONFIG2);
+	writel(sensor->calib, base + SENSOR_CONFIG2);
 
 	return 0;
 }
@@ -422,13 +137,10 @@ static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
 	.get_temp = tegra_thermctl_get_temp,
 };
 
-static const struct of_device_id tegra_soctherm_of_match[] = {
-	{ .compatible = "nvidia,tegra124-soctherm" },
-	{ },
-};
-MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
-
-static int tegra_soctherm_probe(struct platform_device *pdev)
+int tegra_soctherm_probe(struct platform_device *pdev,
+			 struct tegra_tsensor *tsensors,
+			 const struct tegra_tsensor_group **ttgs,
+			 const struct tegra_soctherm_fuse *tfuse)
 {
 	struct tegra_soctherm *tegra;
 	struct thermal_zone_device *tz;
@@ -438,9 +150,6 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
 	int err;
 	u32 pdiv, hotspot;
 
-	const struct tegra_tsensor *tsensors = t124_tsensors;
-	struct tegra_tsensor_group **ttgs = tegra124_tsensor_groups;
-
 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
 	if (!tegra)
 		return -ENOMEM;
@@ -484,11 +193,11 @@ static int tegra_soctherm_probe(struct platform_device *pdev)
 
 	/* Initialize raw sensors */
 
-	err = calculate_shared_calibration(&shared_calib);
+	err = tegra_soctherm_calculate_shared_calibration(tfuse, &shared_calib);
 	if (err)
 		goto disable_clocks;
 
-	for (i = 0; i < ARRAY_SIZE(t124_tsensors); ++i) {
+	for (i = 0; tsensors[i].name; ++i) {
 		err = enable_tsensor(tegra, tsensors + i, &shared_calib);
 		if (err)
 			goto disable_clocks;
@@ -548,7 +257,7 @@ disable_clocks:
 	return err;
 }
 
-static int tegra_soctherm_remove(struct platform_device *pdev)
+int tegra_soctherm_remove(struct platform_device *pdev)
 {
 	struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
 	unsigned int i;
@@ -564,16 +273,6 @@ static int tegra_soctherm_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver tegra_soctherm_driver = {
-	.probe = tegra_soctherm_probe,
-	.remove = tegra_soctherm_remove,
-	.driver = {
-		.name = "tegra-soctherm",
-		.of_match_table = tegra_soctherm_of_match,
-	},
-};
-module_platform_driver(tegra_soctherm_driver);
-
 MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
 MODULE_DESCRIPTION("NVIDIA Tegra SOCTHERM thermal management driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/tegra/tegra_soctherm.h b/drivers/thermal/tegra/tegra_soctherm.h
new file mode 100644
index 000000000000..8d06f4f75ff9
--- /dev/null
+++ b/drivers/thermal/tegra/tegra_soctherm.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __DRIVERS_THERMAL_TEGRA_SOCTHERM_H
+#define __DRIVERS_THERMAL_TEGRA_SOCTHERM_H
+
+#define SENSOR_CONFIG2                          8
+#define SENSOR_CONFIG2_THERMA_SHIFT		16
+#define SENSOR_CONFIG2_THERMB_SHIFT		0
+
+#define SENSOR_PDIV				0x1c0
+#define SENSOR_PDIV_CPU_MASK			(0xf << 12)
+#define SENSOR_PDIV_GPU_MASK			(0xf << 8)
+#define SENSOR_PDIV_MEM_MASK			(0xf << 4)
+#define SENSOR_PDIV_PLLX_MASK			(0xf << 0)
+
+#define SENSOR_HOTSPOT_OFF			0x1c4
+#define SENSOR_HOTSPOT_CPU_MASK			(0xff << 16)
+#define SENSOR_HOTSPOT_GPU_MASK			(0xff << 8)
+#define SENSOR_HOTSPOT_MEM_MASK			(0xff << 0)
+
+#define SENSOR_TEMP1				0x1c8
+#define SENSOR_TEMP1_CPU_TEMP_MASK		(0xffff << 16)
+#define SENSOR_TEMP1_GPU_TEMP_MASK		0xffff
+#define SENSOR_TEMP2				0x1cc
+#define SENSOR_TEMP2_MEM_TEMP_MASK		(0xffff << 16)
+#define SENSOR_TEMP2_PLLX_TEMP_MASK		0xffff
+
+/**
+ * struct tegra_tsensor_group - SOC_THERM sensor group data
+ * @name: short name of the temperature sensor group
+ * @id: numeric ID of the temperature sensor group
+ * @sensor_temp_offset: offset of the SENSOR_TEMP* register
+ * @sensor_temp_mask: bit mask for this sensor group in SENSOR_TEMP* register
+ * @pdiv: the sensor count post-divider to use during runtime
+ * @pdiv_ate: the sensor count post-divider used during automated test
+ * @pdiv_mask: register bitfield mask for the PDIV field for this sensor
+ * @pllx_hotspot_diff: hotspot offset from the PLLX sensor, must be 0 for
+    PLLX sensor group
+ * @pllx_hotspot_mask: register bitfield mask for the HOTSPOT field
+ */
+struct tegra_tsensor_group {
+	const char	*name;
+	u8		id;
+	u16		sensor_temp_offset;
+	u32		sensor_temp_mask;
+	u32		pdiv, pdiv_ate, pdiv_mask;
+	u32		pllx_hotspot_diff, pllx_hotspot_mask;
+};
+
+struct tegra_tsensor_configuration {
+	u32 tall, tiddq_en, ten_count, pdiv, pdiv_ate, tsample, tsample_ate;
+};
+
+struct tegra_tsensor {
+	const char *name;
+	u32 base;
+	const struct tegra_tsensor_configuration *config;
+	u32 calib_fuse_offset;
+	/*
+	 * Correction values used to modify values read from
+	 * calibration fuses
+	 */
+	s32 fuse_corr_alpha, fuse_corr_beta;
+	u32 calib;
+	const struct tegra_tsensor_group *group;
+};
+
+struct tegra_soctherm_fuse {
+	u32 fuse_base_cp_mask, fuse_base_cp_shift;
+	u32 fuse_base_ft_mask, fuse_base_ft_shift;
+	u32 fuse_shift_ft_mask, fuse_shift_ft_shift;
+	u32 fuse_spare_realignment;
+};
+
+struct tsensor_shared_calibration {
+	u32 base_cp, base_ft;
+	u32 actual_temp_cp, actual_temp_ft;
+};
+
+int tegra_soctherm_calculate_shared_calibration(
+				const struct tegra_soctherm_fuse *tfuse,
+				struct tsensor_shared_calibration *shared);
+int tegra_soctherm_calculate_tsensor_calibration(
+			struct tegra_tsensor *sensor,
+			const struct tsensor_shared_calibration *shared);
+
+int tegra_soctherm_probe(struct platform_device *pdev,
+			 struct tegra_tsensor *tsensors,
+			 const struct tegra_tsensor_group **ttgs,
+			 const struct tegra_soctherm_fuse *tfuse);
+int tegra_soctherm_remove(struct platform_device *pdev);
+
+#endif
+
diff --git a/drivers/thermal/tegra/tegra_soctherm_fuse.c b/drivers/thermal/tegra/tegra_soctherm_fuse.c
new file mode 100644
index 000000000000..7c608698f1ae
--- /dev/null
+++ b/drivers/thermal/tegra/tegra_soctherm_fuse.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/platform_device.h>
+#include <soc/tegra/fuse.h>
+
+#include "tegra_soctherm.h"
+
+#define NOMINAL_CALIB_FT			105
+#define NOMINAL_CALIB_CP			25
+
+#define FUSE_TSENSOR_CALIB_CP_TS_BASE_MASK	0x1fff
+#define FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK	(0x1fff << 13)
+#define FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT	13
+
+#define FUSE_TSENSOR_COMMON			0x180
+
+/*
+ * T12x, etc: FUSE_TSENSOR_COMMON:
+ *    3                   2                   1                   0
+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |-----------| SHFT_FT |       BASE_FT       |      BASE_CP      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * FUSE_SPARE_REALIGNMENT_REG:
+ *    3                   2                   1                   0
+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |---------------------------------------------------| SHIFT_CP  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+static s64 div64_s64_precise(s64 a, s64 b)
+{
+	s64 r, al;
+
+	/* Scale up for increased precision division */
+	al = a << 16;
+
+	r = div64_s64(al * 2 + 1, 2 * b);
+	return r >> 16;
+}
+
+int tegra_soctherm_calculate_shared_calibration(
+				const struct tegra_soctherm_fuse *tfuse,
+				struct tsensor_shared_calibration *r)
+{
+	u32 val;
+	s32 shifted_cp, shifted_ft;
+	int err;
+
+	err = tegra_fuse_readl(FUSE_TSENSOR_COMMON, &val);
+	if (err)
+		return err;
+
+	r->base_cp = (val & tfuse->fuse_base_cp_mask)
+			>> tfuse->fuse_base_cp_shift;
+	r->base_ft = (val & tfuse->fuse_base_ft_mask)
+			>> tfuse->fuse_base_ft_shift;
+
+	shifted_ft = (val & tfuse->fuse_shift_ft_mask)
+			>> tfuse->fuse_shift_ft_shift;
+	shifted_ft = sign_extend32(shifted_ft, 4);
+
+	if (tfuse->fuse_spare_realignment) {
+		err = tegra_fuse_readl(tfuse->fuse_spare_realignment, &val);
+		if (err)
+			return err;
+	}
+
+	shifted_cp = sign_extend32(val, 5);
+
+	r->actual_temp_cp = 2 * NOMINAL_CALIB_CP + shifted_cp;
+	r->actual_temp_ft = 2 * NOMINAL_CALIB_FT + shifted_ft;
+
+	return 0;
+}
+
+int tegra_soctherm_calculate_tsensor_calibration(
+				struct tegra_tsensor *sensor,
+				const struct tsensor_shared_calibration *shared)
+{
+	const struct tegra_tsensor_group *sensor_group;
+	u32 val, calib;
+	s32 actual_tsensor_ft, actual_tsensor_cp;
+	s32 delta_sens, delta_temp;
+	s32 mult, div;
+	s16 therma, thermb;
+	int err;
+
+	sensor_group = sensor->group;
+
+	err = tegra_fuse_readl(sensor->calib_fuse_offset, &val);
+	if (err)
+		return err;
+
+	actual_tsensor_cp = (shared->base_cp * 64) + sign_extend32(val, 12);
+	val = (val & FUSE_TSENSOR_CALIB_FT_TS_BASE_MASK)
+		>> FUSE_TSENSOR_CALIB_FT_TS_BASE_SHIFT;
+	actual_tsensor_ft = (shared->base_ft * 32) + sign_extend32(val, 12);
+
+	delta_sens = actual_tsensor_ft - actual_tsensor_cp;
+	delta_temp = shared->actual_temp_ft - shared->actual_temp_cp;
+
+	mult = sensor_group->pdiv * sensor->config->tsample_ate;
+	div = sensor->config->tsample * sensor_group->pdiv_ate;
+
+	therma = div64_s64_precise((s64)delta_temp * (1LL << 13) * mult,
+			(s64)delta_sens * div);
+	thermb = div64_s64_precise(
+			((s64)actual_tsensor_ft * shared->actual_temp_cp) -
+			((s64)actual_tsensor_cp * shared->actual_temp_ft),
+			(s64)delta_sens);
+
+	therma = div64_s64_precise((s64)therma * sensor->fuse_corr_alpha,
+			(s64)1000000LL);
+	thermb = div64_s64_precise((s64)thermb * sensor->fuse_corr_alpha +
+			sensor->fuse_corr_beta,
+			(s64)1000000LL);
+	calib = ((u16)therma << SENSOR_CONFIG2_THERMA_SHIFT) |
+		 ((u16)thermb << SENSOR_CONFIG2_THERMB_SHIFT);
+
+	sensor->calib = calib;
+
+	return 0;
+}
+
+MODULE_AUTHOR("NVIDIA");
+MODULE_DESCRIPTION("Tegra SOCTHERM fuse management");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH V1 04/10] thermal: tegra: add T210-specific SOC_THERM driver
  2016-01-13  7:58 [PATCH V1 00/10] Add T210 support in tegra_soctherm Wei Ni
                   ` (2 preceding siblings ...)
  2016-01-13  7:58 ` [PATCH V1 03/10] thermal: tegra: split tegra_soctherm driver Wei Ni
@ 2016-01-13  7:58 ` Wei Ni
  2016-01-13 15:06   ` Thierry Reding
  3 siblings, 1 reply; 13+ messages in thread
From: Wei Ni @ 2016-01-13  7:58 UTC (permalink / raw)
  To: rui.zhang, mikko.perttunen, swarren; +Cc: linux-tegra, linux-kernel, Wei Ni

Add Tegra210 specific SOC_THERM driver.

Signed-off-by: Wei Ni <wni@nvidia.com>
---
 drivers/thermal/tegra/Kconfig               |  11 ++
 drivers/thermal/tegra/Makefile              |   1 +
 drivers/thermal/tegra/tegra210_soctherm.c   | 210 ++++++++++++++++++++++++++++
 drivers/thermal/tegra/tegra_soctherm_fuse.c |  11 ++
 4 files changed, 233 insertions(+)
 create mode 100644 drivers/thermal/tegra/tegra210_soctherm.c

diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
index ae7e5e93dab9..902ef8bdbc91 100644
--- a/drivers/thermal/tegra/Kconfig
+++ b/drivers/thermal/tegra/Kconfig
@@ -11,3 +11,14 @@ config TEGRA124_SOCTHERM
 	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
 	  zones to manage temperatures. This option is also required for the
 	  emergency thermal reset (thermtrip) feature to function.
+
+config TEGRA210_SOCTHERM
+	bool "Tegra210 SOCTHERM thermal management"
+	depends on ARCH_TEGRA_210_SOC
+	select TEGRA_SOCTHERM
+	help
+	  Enable this option for integrated thermal management support on NVIDIA
+	  Tegra210 systems-on-chip. The driver supports four thermal zones
+	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
+	  zones to manage temperatures. This option is also required for the
+	  emergency thermal reset (thermtrip) feature to function.
diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile
index 7a864ec07a25..272dd84c7995 100644
--- a/drivers/thermal/tegra/Makefile
+++ b/drivers/thermal/tegra/Makefile
@@ -5,3 +5,4 @@
 # Tegra soc thermal drivers
 obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o tegra_soctherm_fuse.o
 obj-$(CONFIG_TEGRA124_SOCTHERM)	+= tegra124_soctherm.o
+obj-$(CONFIG_TEGRA210_SOCTHERM)	+= tegra210_soctherm.o
diff --git a/drivers/thermal/tegra/tegra210_soctherm.c b/drivers/thermal/tegra/tegra210_soctherm.c
new file mode 100644
index 000000000000..70c748c6bed6
--- /dev/null
+++ b/drivers/thermal/tegra/tegra210_soctherm.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2014-2016, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/platform_device.h>
+#include <soc/tegra/fuse.h>
+
+#include <dt-bindings/thermal/tegra124-soctherm.h>
+
+#include "tegra_soctherm.h"
+
+static const struct tegra_tsensor_configuration tegra210_tsensor_config = {
+	.tall = 16300,
+	.tiddq_en = 1,
+	.ten_count = 1,
+	.tsample = 120,
+	.tsample_ate = 480,
+};
+
+static const struct tegra_tsensor_group tegra210_tsensor_group_cpu = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_CPU,
+	.name				= "cpu",
+	.sensor_temp_offset		= SENSOR_TEMP1,
+	.sensor_temp_mask		= SENSOR_TEMP1_CPU_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_CPU_MASK,
+	.pllx_hotspot_diff		= 10,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_CPU_MASK,
+};
+
+static const struct tegra_tsensor_group tegra210_tsensor_group_gpu = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_GPU,
+	.name				= "gpu",
+	.sensor_temp_offset		= SENSOR_TEMP1,
+	.sensor_temp_mask		= SENSOR_TEMP1_GPU_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_GPU_MASK,
+	.pllx_hotspot_diff		= 5,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_GPU_MASK,
+};
+
+static const struct tegra_tsensor_group tegra210_tsensor_group_pll = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_PLLX,
+	.name				= "pll",
+	.sensor_temp_offset		= SENSOR_TEMP2,
+	.sensor_temp_mask		= SENSOR_TEMP2_PLLX_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_PLLX_MASK,
+};
+
+static const struct tegra_tsensor_group tegra210_tsensor_group_mem = {
+	.id				= TEGRA124_SOCTHERM_SENSOR_MEM,
+	.name				= "mem",
+	.sensor_temp_offset		= SENSOR_TEMP2,
+	.sensor_temp_mask		= SENSOR_TEMP2_MEM_TEMP_MASK,
+	.pdiv				= 8,
+	.pdiv_ate			= 8,
+	.pdiv_mask			= SENSOR_PDIV_MEM_MASK,
+	.pllx_hotspot_diff		= 0,
+	.pllx_hotspot_mask		= SENSOR_HOTSPOT_MEM_MASK,
+};
+
+static const struct tegra_tsensor_group *
+tegra210_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
+	&tegra210_tsensor_group_cpu,
+	&tegra210_tsensor_group_gpu,
+	&tegra210_tsensor_group_pll,
+	&tegra210_tsensor_group_mem,
+};
+
+static struct tegra_tsensor tegra210_tsensors[] = {
+	{
+		.name = "cpu0",
+		.base = 0xc0,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x098,
+		.fuse_corr_alpha = 1085000,
+		.fuse_corr_beta = 3244200,
+		.group = &tegra210_tsensor_group_cpu,
+	},
+	{
+		.name = "cpu1",
+		.base = 0xe0,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x084,
+		.fuse_corr_alpha = 1126200,
+		.fuse_corr_beta = -67500,
+		.group = &tegra210_tsensor_group_cpu,
+	},
+	{
+		.name = "cpu2",
+		.base = 0x100,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x088,
+		.fuse_corr_alpha = 1098400,
+		.fuse_corr_beta = 2251100,
+		.group = &tegra210_tsensor_group_cpu,
+	},
+	{
+		.name = "cpu3",
+		.base = 0x120,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x12c,
+		.fuse_corr_alpha = 1108000,
+		.fuse_corr_beta = 602700,
+		.group = &tegra210_tsensor_group_cpu,
+	},
+	{
+		.name = "mem0",
+		.base = 0x140,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x158,
+		.fuse_corr_alpha = 1069200,
+		.fuse_corr_beta = 3549900,
+		.group = &tegra210_tsensor_group_mem,
+	},
+	{
+		.name = "mem1",
+		.base = 0x160,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x15c,
+		.fuse_corr_alpha = 1173700,
+		.fuse_corr_beta = -6263600,
+		.group = &tegra210_tsensor_group_mem,
+	},
+	{
+		.name = "gpu",
+		.base = 0x180,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x154,
+		.fuse_corr_alpha = 1074300,
+		.fuse_corr_beta = 2734900,
+		.group = &tegra210_tsensor_group_gpu,
+	},
+	{
+		.name = "pllx",
+		.base = 0x1a0,
+		.config = &tegra210_tsensor_config,
+		.calib_fuse_offset = 0x160,
+		.fuse_corr_alpha = 1039700,
+		.fuse_corr_beta = 6829100,
+		.group = &tegra210_tsensor_group_pll,
+	},
+	{ .name = NULL },
+};
+
+/*
+ * Mask/shift bits in FUSE_TSENSOR_COMMON and
+ * FUSE_TSENSOR_COMMON, which are described in
+ * tegra_soctherm_fuse.c
+ */
+static const struct tegra_soctherm_fuse tegra210_soctherm_fuse = {
+	.fuse_base_cp_mask = 0x3ff << 11,
+	.fuse_base_cp_shift = 11,
+	.fuse_base_ft_mask = 0x7ff << 21,
+	.fuse_base_ft_shift = 21,
+	.fuse_shift_ft_mask = 0x1f << 6,
+	.fuse_shift_ft_shift = 6,
+	.fuse_spare_realignment = 0,
+};
+
+static const struct of_device_id tegra210_soctherm_of_match[] = {
+	{ .compatible = "nvidia,tegra210-soctherm" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
+
+#define TEGRA210_FUSE_CP_REV 0x90
+
+static int tegra210_soctherm_probe(struct platform_device *pdev)
+{
+	u32 rev;
+
+	tegra_fuse_readl(TEGRA210_FUSE_CP_REV, &rev);
+	pr_debug("tsosc: CP rev %d.%d\n", (rev & 0x1f), ((rev >> 5) & 0x3f));
+
+	return tegra_soctherm_probe(pdev,
+				    tegra210_tsensors,
+				    tegra210_tsensor_groups,
+				    &tegra210_soctherm_fuse);
+}
+
+static struct platform_driver tegra210_soctherm_driver = {
+	.probe = tegra210_soctherm_probe,
+	.remove = tegra_soctherm_remove,
+	.driver = {
+		.name = "tegra210_soctherm",
+		.owner = THIS_MODULE,
+		.of_match_table = tegra210_soctherm_of_match,
+	},
+};
+module_platform_driver(tegra210_soctherm_driver);
+
+MODULE_AUTHOR("NVIDIA");
+MODULE_DESCRIPTION("Tegra210 SOCTHERM thermal management driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/tegra/tegra_soctherm_fuse.c b/drivers/thermal/tegra/tegra_soctherm_fuse.c
index 7c608698f1ae..22f402240672 100644
--- a/drivers/thermal/tegra/tegra_soctherm_fuse.c
+++ b/drivers/thermal/tegra/tegra_soctherm_fuse.c
@@ -28,6 +28,17 @@
 #define FUSE_TSENSOR_COMMON			0x180
 
 /*
+ * T210: Layout of bits in FUSE_TSENSOR_COMMON:
+ *    3                   2                   1                   0
+ *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |       BASE_FT       |      BASE_CP      | SHFT_FT | SHIFT_CP  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * In chips prior to T210, this fuse was incorrectly sized as 26 bits,
+ * and didn't hold SHIFT_CP in [31:26]. Therefore these missing six bits
+ * were obtained via the FUSE_SPARE_REALIGNMENT_REG register [5:0].
+ *
  * T12x, etc: FUSE_TSENSOR_COMMON:
  *    3                   2                   1                   0
  *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory
  2016-01-13  7:58 ` [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory Wei Ni
@ 2016-01-13 14:24   ` Thierry Reding
  2016-01-14  5:33     ` Wei Ni
  0 siblings, 1 reply; 13+ messages in thread
From: Thierry Reding @ 2016-01-13 14:24 UTC (permalink / raw)
  To: Wei Ni; +Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3620 bytes --]

On Wed, Jan 13, 2016 at 03:58:40PM +0800, Wei Ni wrote:
> Move tegra soctherm driver to tegra directory, it's easy to maintain
> and add more new function support for tegra platforms.

Please use the proper spelling "Tegra", except where you refer to
directory or file names.

> This will also help to split soctherm driver into common parts and
> chip specific data related parts.
> 
> Signed-off-by: Wei Ni <wni@nvidia.com>
> ---
>  drivers/thermal/Kconfig                      | 15 +++++----------
>  drivers/thermal/Makefile                     |  2 +-
>  drivers/thermal/tegra/Kconfig                |  9 +++++++++
>  drivers/thermal/tegra/Makefile               |  6 ++++++
>  drivers/thermal/{ => tegra}/tegra_soctherm.c |  0
>  5 files changed, 21 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/thermal/tegra/Kconfig
>  create mode 100644 drivers/thermal/tegra/Makefile
>  rename drivers/thermal/{ => tegra}/tegra_soctherm.c (100%)
> 
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index c463c89b90ef..7984cba6b340 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -254,16 +254,6 @@ config ARMADA_THERMAL
>  	  Enable this option if you want to have support for thermal management
>  	  controller present in Armada 370 and Armada XP SoC.
>  
> -config TEGRA_SOCTHERM
> -	tristate "Tegra SOCTHERM thermal management"
> -	depends on ARCH_TEGRA
> -	help
> -	  Enable this option for integrated thermal management support on NVIDIA
> -	  Tegra124 systems-on-chip. The driver supports four thermal zones
> -	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
> -	  zones to manage temperatures. This option is also required for the
> -	  emergency thermal reset (thermtrip) feature to function.
> -
>  config DB8500_CPUFREQ_COOLING
>  	tristate "DB8500 cpufreq cooling"
>  	depends on ARCH_U8500
> @@ -380,6 +370,11 @@ depends on ARCH_STI && OF
>  source "drivers/thermal/st/Kconfig"
>  endmenu
>  
> +menu "Tegra thermal drivers"
> +depends on ARCH_TEGRA
> +source "drivers/thermal/tegra/Kconfig"
> +endmenu
> +

I think it'd be more idiomatic to only source the file here and move the
menu declaration and the dependencies into that file. Perhaps also make
the menu description "NVIDIA Tegra thermal drivers", I think we've been
using that consistently elsewhere.

> diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
> new file mode 100644
> index 000000000000..a6e6cd4528dc
> --- /dev/null
> +++ b/drivers/thermal/tegra/Kconfig
> @@ -0,0 +1,9 @@
> +config TEGRA_SOCTHERM
> +	tristate "Tegra SOCTHERM thermal management"
> +	depends on ARCH_TEGRA
> +	help
> +	  Enable this option for integrated thermal management support on NVIDIA
> +	  Tegra124 systems-on-chip. The driver supports four thermal zones
> +	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
> +	  zones to manage temperatures. This option is also required for the
> +	  emergency thermal reset (thermtrip) feature to function.
> diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile
> new file mode 100644
> index 000000000000..8c51076e4b1e
> --- /dev/null
> +++ b/drivers/thermal/tegra/Makefile
> @@ -0,0 +1,6 @@
> +#
> +# Tegra thermal specific Makefile
> +#
> +
> +# Tegra soc thermal drivers
> +obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o

I personally don't think these comments are helpful. They're really
redundant given that they're in a Makefile within a subdirectory of
drivers/thermal.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 02/10] thermal: tegra: combine sensor group-related data
  2016-01-13  7:58 ` [PATCH V1 02/10] thermal: tegra: combine sensor group-related data Wei Ni
@ 2016-01-13 14:31   ` Thierry Reding
  2016-01-14  5:40     ` Wei Ni
  0 siblings, 1 reply; 13+ messages in thread
From: Thierry Reding @ 2016-01-13 14:31 UTC (permalink / raw)
  To: Wei Ni; +Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1953 bytes --]

On Wed, Jan 13, 2016 at 03:58:41PM +0800, Wei Ni wrote:
> Combine sensor group-related data structures into struct
> tegra_tsensor_group. This provides a single location for
> sensor group data storage.
> More sensor group data will be added in subsequent patches.
> 
> Get rid of T124-specific PDIV/HOTSPOT hack.
> tegra-soctherm.c contained a hack to set the SENSOR_PDIV and
> SENSOR_HOTSPOT_OFFSET registers - it just did two writes of
> T124-specific opaque values.  Convert these into a form that can be
> substituted on a per-chip basis, and into structure fields that have
> at least some independent meaning.

This reads as two completely separate commit messages. Should the patch
be split up to separate out the two logical changes?

> diff --git a/drivers/thermal/tegra/tegra_soctherm.c b/drivers/thermal/tegra/tegra_soctherm.c
[...]
> +static struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
[...]
> +};
> +
> +static struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
[...]
> +};
> +
> +static struct tegra_tsensor_group tegra124_tsensor_group_pll = {
[...]
> +};
> +
> +static struct tegra_tsensor_group tegra124_tsensor_group_mem = {
[...]
> +};
> +
> +static struct tegra_tsensor_group *
> +tegra124_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
[...]
>  };

These look like they should all be static const.

> @@ -168,7 +268,7 @@ struct tegra_soctherm {
>  	struct clk *clock_soctherm;
>  	void __iomem *regs;
>  
> -	struct thermal_zone_device *thermctl_tzs[4];
> +	struct thermal_zone_device *thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_NUM];
>  };

Does it make sense to use macros here for the number of zones? I suspect
that since you do parameterize the Tegra210 support that will be added
later on will have a different maximum number, in which case macros will
not work very well.

But perhaps I'll see how you solved that problem in a later patch.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 03/10] thermal: tegra: split tegra_soctherm driver
  2016-01-13  7:58 ` [PATCH V1 03/10] thermal: tegra: split tegra_soctherm driver Wei Ni
@ 2016-01-13 15:04   ` Thierry Reding
  2016-01-14  9:54     ` Wei Ni
  0 siblings, 1 reply; 13+ messages in thread
From: Thierry Reding @ 2016-01-13 15:04 UTC (permalink / raw)
  To: Wei Ni; +Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 6654 bytes --]

On Wed, Jan 13, 2016 at 03:58:42PM +0800, Wei Ni wrote:
> Split most of the T124 data and code into a T124-specific driver.
> Split most of the fuse-related code into a fuse-related source file.
> Now drivers/thermal/tegra_soctherm.c contains common SOC_THERM library

That path no longer exists since patch 01/10.

> diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
> index a6e6cd4528dc..ae7e5e93dab9 100644
> --- a/drivers/thermal/tegra/Kconfig
> +++ b/drivers/thermal/tegra/Kconfig
> @@ -1,6 +1,10 @@
>  config TEGRA_SOCTHERM
> -	tristate "Tegra SOCTHERM thermal management"
> -	depends on ARCH_TEGRA
> +	bool
> +
> +config TEGRA124_SOCTHERM
> +	bool "Tegra124 SOCTHERM thermal management"
> +	depends on ARCH_TEGRA_124_SOC
> +	select TEGRA_SOCTHERM
>  	help
>  	  Enable this option for integrated thermal management support on NVIDIA
>  	  Tegra124 systems-on-chip. The driver supports four thermal zones

I'd like to do this differently to reduce the number of Kconfig symbols.
The alternate proposal would be for the TEGRA_SOCTHERM symbol to remain
as it is and then build in driver support depending on the selected
ARCH_TEGRA_*_SOC options.

> diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile
> index 8c51076e4b1e..7a864ec07a25 100644
> --- a/drivers/thermal/tegra/Makefile
> +++ b/drivers/thermal/tegra/Makefile
> @@ -3,4 +3,5 @@
>  #
>  
>  # Tegra soc thermal drivers
> -obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
> +obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o tegra_soctherm_fuse.o
> +obj-$(CONFIG_TEGRA124_SOCTHERM)	+= tegra124_soctherm.o

So this would look roughly like:

	obj-$(CONFIG_TEGRA_SOCTHERM) += tegra-soctherm.o

	tegra-soctherm-y := soctherm.c
	tegra-soctherm-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o
	tegra-soctherm-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o

Two things to note here: I've replaced the underscore in the filename
with a dash, because that's more commonly used in filenames for other
drivers on Tegra. This could be done in patch 01/10 since the file is
already moved anyway. The second thing to note here is that the SoC-
generation specific drivers don't contain the redundant _soctherm
suffix. I suppose that if this directory will ever contain anything
other than soctherm drivers it might be useful to have the suffix to
differentiate between different drivers, so feel free to ignore that
suggestion if you have plans to add other thermal-related drivers to
this directory.

The advantage of the above is that we'll have a single Kconfig option
to worry about and also everything will be included in a single driver
rather than per-SoC "drivers" that merely provide the SoC-specific
data. This will require some slight changes to the driver code, see
below.

> diff --git a/drivers/thermal/tegra/tegra124_soctherm.c b/drivers/thermal/tegra/tegra124_soctherm.c
[...]
> +static const struct tegra_tsensor_group *
> +tegra124_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
> +	&tegra124_tsensor_group_cpu,
> +	&tegra124_tsensor_group_gpu,
> +	&tegra124_tsensor_group_pll,
> +	&tegra124_tsensor_group_mem,
> +};
> +
> +static struct tegra_tsensor tegra124_tsensors[] = {
[...]
> +	{ .name = NULL },
> +};

I think it'd be good not to rely on this sentinel entry being there.
It's more error-prone than simply storing the number of entries in a
separate location. See below.

> +static const struct of_device_id tegra124_soctherm_of_match[] = {
> +	{ .compatible = "nvidia,tegra124-soctherm" },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);

The general idea would be to keep the of_device_id table in the
tegra_soctherm.c file and have it include entries depending on which SoC
generation is being supported. See for example the memory controller
driver in drivers/memory/tegra for a reference that uses this style of
multi-SoC support.

> +
> +static int tegra124_soctherm_probe(struct platform_device *pdev)
> +{
> +	return tegra_soctherm_probe(pdev,
> +				    tegra124_tsensors,
> +				    tegra124_tsensor_groups,
> +				    &tegra124_soctherm_fuse);
> +}
> +
> +static struct platform_driver tegra124_soctherm_driver = {
> +	.probe = tegra124_soctherm_probe,
> +	.remove = tegra_soctherm_remove,
> +	.driver = {
> +		.name = "tegra124_soctherm",
> +		.of_match_table = tegra124_soctherm_of_match,
> +	},
> +};
> +module_platform_driver(tegra124_soctherm_driver);
> +
> +MODULE_AUTHOR("NVIDIA");
> +MODULE_DESCRIPTION("Tegra124 SOCTHERM thermal management driver");
> +MODULE_LICENSE("GPL v2");

With the alternate proposal you can get rid of all of this, which has a
number of other advantages like not having to export all of the library
functions that these subdrivers rely on.

What you'd do instead is add a new structure, along the lines of this:

	struct tegra_soctherm_soc {
		const struct tegra_tsensor_groups *groups;
		unsigned int num_groups;
		const struct tegra_tsensor *sensors;
		unsigned int num_sensors;
		const struct tegra_soctherm_fuse *fuse;
	};

and create one of these with the SoC-specific groups, sensors and FUSE
parameters. Then you pass these structures to the generic driver as the
struct of_device_id's .data field:

	static const struct of_device_id tegra_soctherm_of_match[] = {
		{ .compatible = "nvidia,tegra124-soctherm", .data = &tegra124_soctherm },
		{ .compatible = "nvidia,tegra210-soctherm", .data = &tegra210_soctherm },
		{ }
	};

Also, please use your name and email address if you're the author.
Companies don't write code, people do.

> -static int tegra_soctherm_probe(struct platform_device *pdev)
> +int tegra_soctherm_probe(struct platform_device *pdev,
> +			 struct tegra_tsensor *tsensors,
> +			 const struct tegra_tsensor_group **ttgs,
> +			 const struct tegra_soctherm_fuse *tfuse)
>  {
[...]
>  }
>  
> -static int tegra_soctherm_remove(struct platform_device *pdev)
> +int tegra_soctherm_remove(struct platform_device *pdev)
>  {
>  	struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
>  	unsigned int i;
> @@ -564,16 +273,6 @@ static int tegra_soctherm_remove(struct platform_device *pdev)
>  	return 0;
>  }

Both the tegra_soctherm_probe() and tegra_soctherm_remove() functions
would need to be exported with this type of driver design, otherwise
building everything as modules the per-SoC drivers couldn't access the
functions.

If you create a single driver there is no need to export any of the
symbols because they are never required by another module.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 04/10] thermal: tegra: add T210-specific SOC_THERM driver
  2016-01-13  7:58 ` [PATCH V1 04/10] thermal: tegra: add T210-specific SOC_THERM driver Wei Ni
@ 2016-01-13 15:06   ` Thierry Reding
  2016-01-14 10:18     ` Wei Ni
  0 siblings, 1 reply; 13+ messages in thread
From: Thierry Reding @ 2016-01-13 15:06 UTC (permalink / raw)
  To: Wei Ni; +Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1118 bytes --]

On Wed, Jan 13, 2016 at 03:58:43PM +0800, Wei Ni wrote:
[...]
> diff --git a/drivers/thermal/tegra/tegra_soctherm_fuse.c b/drivers/thermal/tegra/tegra_soctherm_fuse.c
> index 7c608698f1ae..22f402240672 100644
> --- a/drivers/thermal/tegra/tegra_soctherm_fuse.c
> +++ b/drivers/thermal/tegra/tegra_soctherm_fuse.c
> @@ -28,6 +28,17 @@
>  #define FUSE_TSENSOR_COMMON			0x180
>  
>  /*
> + * T210: Layout of bits in FUSE_TSENSOR_COMMON:
> + *    3                   2                   1                   0
> + *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + * |       BASE_FT       |      BASE_CP      | SHFT_FT | SHIFT_CP  |
> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + *
> + * In chips prior to T210, this fuse was incorrectly sized as 26 bits,
> + * and didn't hold SHIFT_CP in [31:26]. Therefore these missing six bits

The above diagram aso doesn't contain SHIFT_CP in bits [31:26] but
rather in bits [5:0]. Which one is correct: the text or the diagram?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory
  2016-01-13 14:24   ` Thierry Reding
@ 2016-01-14  5:33     ` Wei Ni
  0 siblings, 0 replies; 13+ messages in thread
From: Wei Ni @ 2016-01-14  5:33 UTC (permalink / raw)
  To: Thierry Reding
  Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel

Thierry, thanks for you comments, will fix them.

On 2016年01月13日 22:24, Thierry Reding wrote:
> * PGP Signed by an unknown key
> 
> On Wed, Jan 13, 2016 at 03:58:40PM +0800, Wei Ni wrote:
>> Move tegra soctherm driver to tegra directory, it's easy to maintain
>> and add more new function support for tegra platforms.
> 
> Please use the proper spelling "Tegra", except where you refer to
> directory or file names.
> 
>> This will also help to split soctherm driver into common parts and
>> chip specific data related parts.
>>
>> Signed-off-by: Wei Ni <wni@nvidia.com>
>> ---
>>  drivers/thermal/Kconfig                      | 15 +++++----------
>>  drivers/thermal/Makefile                     |  2 +-
>>  drivers/thermal/tegra/Kconfig                |  9 +++++++++
>>  drivers/thermal/tegra/Makefile               |  6 ++++++
>>  drivers/thermal/{ => tegra}/tegra_soctherm.c |  0
>>  5 files changed, 21 insertions(+), 11 deletions(-)
>>  create mode 100644 drivers/thermal/tegra/Kconfig
>>  create mode 100644 drivers/thermal/tegra/Makefile
>>  rename drivers/thermal/{ => tegra}/tegra_soctherm.c (100%)
>>
>> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
>> index c463c89b90ef..7984cba6b340 100644
>> --- a/drivers/thermal/Kconfig
>> +++ b/drivers/thermal/Kconfig
>> @@ -254,16 +254,6 @@ config ARMADA_THERMAL
>>  	  Enable this option if you want to have support for thermal management
>>  	  controller present in Armada 370 and Armada XP SoC.
>>  
>> -config TEGRA_SOCTHERM
>> -	tristate "Tegra SOCTHERM thermal management"
>> -	depends on ARCH_TEGRA
>> -	help
>> -	  Enable this option for integrated thermal management support on NVIDIA
>> -	  Tegra124 systems-on-chip. The driver supports four thermal zones
>> -	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
>> -	  zones to manage temperatures. This option is also required for the
>> -	  emergency thermal reset (thermtrip) feature to function.
>> -
>>  config DB8500_CPUFREQ_COOLING
>>  	tristate "DB8500 cpufreq cooling"
>>  	depends on ARCH_U8500
>> @@ -380,6 +370,11 @@ depends on ARCH_STI && OF
>>  source "drivers/thermal/st/Kconfig"
>>  endmenu
>>  
>> +menu "Tegra thermal drivers"
>> +depends on ARCH_TEGRA
>> +source "drivers/thermal/tegra/Kconfig"
>> +endmenu
>> +
> 
> I think it'd be more idiomatic to only source the file here and move the
> menu declaration and the dependencies into that file. Perhaps also make
> the menu description "NVIDIA Tegra thermal drivers", I think we've been
> using that consistently elsewhere.
>> diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
>> new file mode 100644
>> index 000000000000..a6e6cd4528dc
>> --- /dev/null
>> +++ b/drivers/thermal/tegra/Kconfig
>> @@ -0,0 +1,9 @@
>> +config TEGRA_SOCTHERM
>> +	tristate "Tegra SOCTHERM thermal management"
>> +	depends on ARCH_TEGRA
>> +	help
>> +	  Enable this option for integrated thermal management support on NVIDIA
>> +	  Tegra124 systems-on-chip. The driver supports four thermal zones
>> +	  (CPU, GPU, MEM, PLLX). Cooling devices can be bound to the thermal
>> +	  zones to manage temperatures. This option is also required for the
>> +	  emergency thermal reset (thermtrip) feature to function.
>> diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile
>> new file mode 100644
>> index 000000000000..8c51076e4b1e
>> --- /dev/null
>> +++ b/drivers/thermal/tegra/Makefile
>> @@ -0,0 +1,6 @@
>> +#
>> +# Tegra thermal specific Makefile
>> +#
>> +
>> +# Tegra soc thermal drivers
>> +obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
> 
> I personally don't think these comments are helpful. They're really
> redundant given that they're in a Makefile within a subdirectory of
> drivers/thermal.
> 
> Thierry
> 
> * Unknown Key
> * 0x7F3EB3A1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 02/10] thermal: tegra: combine sensor group-related data
  2016-01-13 14:31   ` Thierry Reding
@ 2016-01-14  5:40     ` Wei Ni
  0 siblings, 0 replies; 13+ messages in thread
From: Wei Ni @ 2016-01-14  5:40 UTC (permalink / raw)
  To: Thierry Reding
  Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel



On 2016年01月13日 22:31, Thierry Reding wrote:
> * PGP Signed by an unknown key
> 
> On Wed, Jan 13, 2016 at 03:58:41PM +0800, Wei Ni wrote:
>> Combine sensor group-related data structures into struct
>> tegra_tsensor_group. This provides a single location for
>> sensor group data storage.
>> More sensor group data will be added in subsequent patches.
>>
>> Get rid of T124-specific PDIV/HOTSPOT hack.
>> tegra-soctherm.c contained a hack to set the SENSOR_PDIV and
>> SENSOR_HOTSPOT_OFFSET registers - it just did two writes of
>> T124-specific opaque values.  Convert these into a form that can be
>> substituted on a per-chip basis, and into structure fields that have
>> at least some independent meaning.
> 
> This reads as two completely separate commit messages. Should the patch
> be split up to separate out the two logical changes?

Hmm, you are right, will do it.

> 
>> diff --git a/drivers/thermal/tegra/tegra_soctherm.c b/drivers/thermal/tegra/tegra_soctherm.c
> [...]
>> +static struct tegra_tsensor_group tegra124_tsensor_group_cpu = {
> [...]
>> +};
>> +
>> +static struct tegra_tsensor_group tegra124_tsensor_group_gpu = {
> [...]
>> +};
>> +
>> +static struct tegra_tsensor_group tegra124_tsensor_group_pll = {
> [...]
>> +};
>> +
>> +static struct tegra_tsensor_group tegra124_tsensor_group_mem = {
> [...]
>> +};
>> +
>> +static struct tegra_tsensor_group *
>> +tegra124_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
> [...]
>>  };
> 
> These look like they should all be static const.

Yes, they should be "static const", I fixed them in the next patch [03/10].
I will change it in this patch.

> 
>> @@ -168,7 +268,7 @@ struct tegra_soctherm {
>>  	struct clk *clock_soctherm;
>>  	void __iomem *regs;
>>  
>> -	struct thermal_zone_device *thermctl_tzs[4];
>> +	struct thermal_zone_device *thermctl_tzs[TEGRA124_SOCTHERM_SENSOR_NUM];
>>  };
> 
> Does it make sense to use macros here for the number of zones? I suspect
> that since you do parameterize the Tegra210 support that will be added
> later on will have a different maximum number, in which case macros will
> not work very well.

All the Tegra serial chips support 4 thermal zones: cpu, gpu, mem, pllx,
including the Tegra 210, so we can use the TEGRA124_SOCTHERM_SENSOR_NUM.

> 
> But perhaps I'll see how you solved that problem in a later patch.
> 
> Thierry
> 
> * Unknown Key
> * 0x7F3EB3A1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 03/10] thermal: tegra: split tegra_soctherm driver
  2016-01-13 15:04   ` Thierry Reding
@ 2016-01-14  9:54     ` Wei Ni
  0 siblings, 0 replies; 13+ messages in thread
From: Wei Ni @ 2016-01-14  9:54 UTC (permalink / raw)
  To: Thierry Reding
  Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel

Thierry,

On 2016年01月13日 23:04, Thierry Reding wrote:
> * PGP Signed by an unknown key
> 
> On Wed, Jan 13, 2016 at 03:58:42PM +0800, Wei Ni wrote:
>> Split most of the T124 data and code into a T124-specific driver.
>> Split most of the fuse-related code into a fuse-related source file.
>> Now drivers/thermal/tegra_soctherm.c contains common SOC_THERM library
> 
> That path no longer exists since patch 01/10.

Yes, will remove it.

> 
>> diff --git a/drivers/thermal/tegra/Kconfig b/drivers/thermal/tegra/Kconfig
>> index a6e6cd4528dc..ae7e5e93dab9 100644
>> --- a/drivers/thermal/tegra/Kconfig
>> +++ b/drivers/thermal/tegra/Kconfig
>> @@ -1,6 +1,10 @@
>>  config TEGRA_SOCTHERM
>> -	tristate "Tegra SOCTHERM thermal management"
>> -	depends on ARCH_TEGRA
>> +	bool
>> +
>> +config TEGRA124_SOCTHERM
>> +	bool "Tegra124 SOCTHERM thermal management"
>> +	depends on ARCH_TEGRA_124_SOC
>> +	select TEGRA_SOCTHERM
>>  	help
>>  	  Enable this option for integrated thermal management support on NVIDIA
>>  	  Tegra124 systems-on-chip. The driver supports four thermal zones
> 
> I'd like to do this differently to reduce the number of Kconfig symbols.
> The alternate proposal would be for the TEGRA_SOCTHERM symbol to remain
> as it is and then build in driver support depending on the selected
> ARCH_TEGRA_*_SOC options.

Yes, it will make the kconfig more clear. Will change it.

> 
>> diff --git a/drivers/thermal/tegra/Makefile b/drivers/thermal/tegra/Makefile
>> index 8c51076e4b1e..7a864ec07a25 100644
>> --- a/drivers/thermal/tegra/Makefile
>> +++ b/drivers/thermal/tegra/Makefile
>> @@ -3,4 +3,5 @@
>>  #
>>  
>>  # Tegra soc thermal drivers
>> -obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o
>> +obj-$(CONFIG_TEGRA_SOCTHERM)	+= tegra_soctherm.o tegra_soctherm_fuse.o
>> +obj-$(CONFIG_TEGRA124_SOCTHERM)	+= tegra124_soctherm.o
> 
> So this would look roughly like:
> 
> 	obj-$(CONFIG_TEGRA_SOCTHERM) += tegra-soctherm.o
> 
> 	tegra-soctherm-y := soctherm.c
> 	tegra-soctherm-$(CONFIG_ARCH_TEGRA_124_SOC) += tegra124.o
> 	tegra-soctherm-$(CONFIG_ARCH_TEGRA_210_SOC) += tegra210.o
> 
> Two things to note here: I've replaced the underscore in the filename
> with a dash, because that's more commonly used in filenames for other
> drivers on Tegra. This could be done in patch 01/10 since the file is

Yes, will change to use dash.

> already moved anyway. The second thing to note here is that the SoC-
> generation specific drivers don't contain the redundant _soctherm
> suffix. I suppose that if this directory will ever contain anything
> other than soctherm drivers it might be useful to have the suffix to
> differentiate between different drivers, so feel free to ignore that
> suggestion if you have plans to add other thermal-related drivers to
> this directory.

Yes, I plan to add thermal-throttle driver in this directory, so will keep the
name tegraxxx_soctherm.c

> 
> The advantage of the above is that we'll have a single Kconfig option
> to worry about and also everything will be included in a single driver
> rather than per-SoC "drivers" that merely provide the SoC-specific
> data. This will require some slight changes to the driver code, see
> below.
> 
>> diff --git a/drivers/thermal/tegra/tegra124_soctherm.c b/drivers/thermal/tegra/tegra124_soctherm.c
> [...]
>> +static const struct tegra_tsensor_group *
>> +tegra124_tsensor_groups[TEGRA124_SOCTHERM_SENSOR_NUM] = {
>> +	&tegra124_tsensor_group_cpu,
>> +	&tegra124_tsensor_group_gpu,
>> +	&tegra124_tsensor_group_pll,
>> +	&tegra124_tsensor_group_mem,
>> +};
>> +
>> +static struct tegra_tsensor tegra124_tsensors[] = {
> [...]
>> +	{ .name = NULL },
>> +};
> 
> I think it'd be good not to rely on this sentinel entry being there.
> It's more error-prone than simply storing the number of entries in a
> separate location. See below.

Ok, will do it.

> 
>> +static const struct of_device_id tegra124_soctherm_of_match[] = {
>> +	{ .compatible = "nvidia,tegra124-soctherm" },
>> +	{ },
>> +};
>> +MODULE_DEVICE_TABLE(of, tegra_soctherm_of_match);
> 
> The general idea would be to keep the of_device_id table in the
> tegra_soctherm.c file and have it include entries depending on which SoC
> generation is being supported. See for example the memory controller
> driver in drivers/memory/tegra for a reference that uses this style of
> multi-SoC support.

Got it, will do it.

> 
>> +
>> +static int tegra124_soctherm_probe(struct platform_device *pdev)
>> +{
>> +	return tegra_soctherm_probe(pdev,
>> +				    tegra124_tsensors,
>> +				    tegra124_tsensor_groups,
>> +				    &tegra124_soctherm_fuse);
>> +}
>> +
>> +static struct platform_driver tegra124_soctherm_driver = {
>> +	.probe = tegra124_soctherm_probe,
>> +	.remove = tegra_soctherm_remove,
>> +	.driver = {
>> +		.name = "tegra124_soctherm",
>> +		.of_match_table = tegra124_soctherm_of_match,
>> +	},
>> +};
>> +module_platform_driver(tegra124_soctherm_driver);
>> +
>> +MODULE_AUTHOR("NVIDIA");
>> +MODULE_DESCRIPTION("Tegra124 SOCTHERM thermal management driver");
>> +MODULE_LICENSE("GPL v2");
> 
> With the alternate proposal you can get rid of all of this, which has a
> number of other advantages like not having to export all of the library
> functions that these subdrivers rely on.
> 
> What you'd do instead is add a new structure, along the lines of this:
> 
> 	struct tegra_soctherm_soc {
> 		const struct tegra_tsensor_groups *groups;
> 		unsigned int num_groups;
> 		const struct tegra_tsensor *sensors;
> 		unsigned int num_sensors;
> 		const struct tegra_soctherm_fuse *fuse;
> 	};
> 
> and create one of these with the SoC-specific groups, sensors and FUSE
> parameters. Then you pass these structures to the generic driver as the
> struct of_device_id's .data field:
> 
> 	static const struct of_device_id tegra_soctherm_of_match[] = {
> 		{ .compatible = "nvidia,tegra124-soctherm", .data = &tegra124_soctherm },
> 		{ .compatible = "nvidia,tegra210-soctherm", .data = &tegra210_soctherm },
> 		{ }
> 	};
> 
> Also, please use your name and email address if you're the author.
> Companies don't write code, people do.

Will do it.

> 
>> -static int tegra_soctherm_probe(struct platform_device *pdev)
>> +int tegra_soctherm_probe(struct platform_device *pdev,
>> +			 struct tegra_tsensor *tsensors,
>> +			 const struct tegra_tsensor_group **ttgs,
>> +			 const struct tegra_soctherm_fuse *tfuse)
>>  {
> [...]
>>  }
>>  
>> -static int tegra_soctherm_remove(struct platform_device *pdev)
>> +int tegra_soctherm_remove(struct platform_device *pdev)
>>  {
>>  	struct tegra_soctherm *tegra = platform_get_drvdata(pdev);
>>  	unsigned int i;
>> @@ -564,16 +273,6 @@ static int tegra_soctherm_remove(struct platform_device *pdev)
>>  	return 0;
>>  }
> 
> Both the tegra_soctherm_probe() and tegra_soctherm_remove() functions
> would need to be exported with this type of driver design, otherwise
> building everything as modules the per-SoC drivers couldn't access the
> functions.
> 
> If you create a single driver there is no need to export any of the
> symbols because they are never required by another module.

I will use the new type, so will not export them.

> 
> Thierry
> 
> * Unknown Key
> * 0x7F3EB3A1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH V1 04/10] thermal: tegra: add T210-specific SOC_THERM driver
  2016-01-13 15:06   ` Thierry Reding
@ 2016-01-14 10:18     ` Wei Ni
  0 siblings, 0 replies; 13+ messages in thread
From: Wei Ni @ 2016-01-14 10:18 UTC (permalink / raw)
  To: Thierry Reding
  Cc: rui.zhang, mikko.perttunen, swarren, linux-tegra, linux-kernel



On 2016年01月13日 23:06, Thierry Reding wrote:
> * PGP Signed by an unknown key
> 
> On Wed, Jan 13, 2016 at 03:58:43PM +0800, Wei Ni wrote:
> [...]
>> diff --git a/drivers/thermal/tegra/tegra_soctherm_fuse.c b/drivers/thermal/tegra/tegra_soctherm_fuse.c
>> index 7c608698f1ae..22f402240672 100644
>> --- a/drivers/thermal/tegra/tegra_soctherm_fuse.c
>> +++ b/drivers/thermal/tegra/tegra_soctherm_fuse.c
>> @@ -28,6 +28,17 @@
>>  #define FUSE_TSENSOR_COMMON			0x180
>>  
>>  /*
>> + * T210: Layout of bits in FUSE_TSENSOR_COMMON:
>> + *    3                   2                   1                   0
>> + *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
>> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>> + * |       BASE_FT       |      BASE_CP      | SHFT_FT | SHIFT_CP  |
>> + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>> + *
>> + * In chips prior to T210, this fuse was incorrectly sized as 26 bits,
>> + * and didn't hold SHIFT_CP in [31:26]. Therefore these missing six bits
> 
> The above diagram aso doesn't contain SHIFT_CP in bits [31:26] but
> rather in bits [5:0]. Which one is correct: the text or the diagram?

Hmm, sorry for the confusion. The diagram is for Tegra210, and the text is used
to explain why the Tegra124 would use the FUSE_SPARE_REALIGNMENT_REG.
For Tegra210, the FUSE_TSENSOR_COMMON contain four values, including SHIFT_CP in
the bits of [5:0]
But for Tegra124, the FUSE_TSENSOR_COMMON only contain three values, the
SHIFT_CP is in the FUSE_SPARE_REALIGNMENT_REG which didn't be used in Tegra210.
I will move the text under the line of "* T12x, etc: FUSE_TSENSOR_COMMON:", so
that it will be more readable.

> 
> Thierry
> 
> * Unknown Key
> * 0x7F3EB3A1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-01-14 10:18 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-13  7:58 [PATCH V1 00/10] Add T210 support in tegra_soctherm Wei Ni
2016-01-13  7:58 ` [PATCH V1 01/10] thermal: tegra: move tegra thermal files into tegra directory Wei Ni
2016-01-13 14:24   ` Thierry Reding
2016-01-14  5:33     ` Wei Ni
2016-01-13  7:58 ` [PATCH V1 02/10] thermal: tegra: combine sensor group-related data Wei Ni
2016-01-13 14:31   ` Thierry Reding
2016-01-14  5:40     ` Wei Ni
2016-01-13  7:58 ` [PATCH V1 03/10] thermal: tegra: split tegra_soctherm driver Wei Ni
2016-01-13 15:04   ` Thierry Reding
2016-01-14  9:54     ` Wei Ni
2016-01-13  7:58 ` [PATCH V1 04/10] thermal: tegra: add T210-specific SOC_THERM driver Wei Ni
2016-01-13 15:06   ` Thierry Reding
2016-01-14 10:18     ` Wei Ni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).