All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/3] thermal: rcar_gen3_thermal: read calibration from hardware
@ 2017-09-13 11:01 Niklas Söderlund
  2017-09-13 11:01 ` [RFC 1/3] " Niklas Söderlund
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Niklas Söderlund @ 2017-09-13 11:01 UTC (permalink / raw)
  To: linux-pm, Simon Horman, Wolfram Sang
  Cc: linux-renesas-soc, Niklas Söderlund

Hi,

This series extend the Renesas R-Car Gen3 thermal driver to try and read 
its calibration constants from hardware instead of using pseudo values 
hard-coded in the driver.

Unfortunately one registers involved in are not yet documented in 
datasheets and I don't have access to any board where the calibration 
data is fused. For the not documented register the BSP code was used as 
a reference. I do believe the code is ready for upstream consumption but 
pending new datasheet and/or access to hardware where calibration is 
fused to test it marked it as RFC. Once I have addressed one or both of 
these concerns I will resend without the RFC prefix.

The code is tested on H3 and M3-W where the calibration registers are 
not fused so only the fallback logic to pseudo values are truly tested.

Niklas Söderlund (3):
  thermal: rcar_gen3_thermal: read calibration from hardware
  arm64: dts: r8a7795: update register size for thermal
  arm64: dts: r8a7796: update register size for thermal

 arch/arm64/boot/dts/renesas/r8a7795.dtsi |  2 +-
 arch/arm64/boot/dts/renesas/r8a7796.dtsi |  2 +-
 drivers/thermal/rcar_gen3_thermal.c      | 70 +++++++++++++++++++++++++++++++-
 3 files changed, 70 insertions(+), 4 deletions(-)

-- 
2.14.1

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

* [RFC 1/3] thermal: rcar_gen3_thermal: read calibration from hardware
  2017-09-13 11:01 [RFC 0/3] thermal: rcar_gen3_thermal: read calibration from hardware Niklas Söderlund
@ 2017-09-13 11:01 ` Niklas Söderlund
  2017-09-13 11:01 ` [RFC 2/3] arm64: dts: r8a7795: update register size for thermal Niklas Söderlund
  2017-09-13 11:01 ` [RFC 3/3] arm64: dts: r8a7796: " Niklas Söderlund
  2 siblings, 0 replies; 4+ messages in thread
From: Niklas Söderlund @ 2017-09-13 11:01 UTC (permalink / raw)
  To: linux-pm, Simon Horman, Wolfram Sang
  Cc: linux-renesas-soc, Niklas Söderlund

In production hardware the calibration values used to convert register
values to temperatures can be read from hardware. While pre-production
hardware still depends on pseudo values hard-coded in the driver.

Add support for reading out calibration values from hardware if it's
fused. The presence of fused calibration is indicated in the THSCP
register, unfortunately this register where not present in early
datasheets. The resource size used in early DT descriptions do not cover
this register. This change takes this into account and fallback to the
pseudo values if the resource size in DT is to small.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/thermal/rcar_gen3_thermal.c | 70 +++++++++++++++++++++++++++++++++++--
 1 file changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/rcar_gen3_thermal.c b/drivers/thermal/rcar_gen3_thermal.c
index 528a65b05b304ca3..29d041d79c6856d6 100644
--- a/drivers/thermal/rcar_gen3_thermal.c
+++ b/drivers/thermal/rcar_gen3_thermal.c
@@ -43,6 +43,10 @@
 #define REG_GEN3_THCODE1	0x50
 #define REG_GEN3_THCODE2	0x54
 #define REG_GEN3_THCODE3	0x58
+#define REG_GEN3_PTAT1		0x5c
+#define REG_GEN3_PTAT2		0x60
+#define REG_GEN3_PTAT3		0x64
+#define REG_GEN3_THSCP		0x68
 
 /* IRQ{STR,MSK,EN} bits */
 #define IRQ_TEMP1		BIT(0)
@@ -64,6 +68,9 @@
 #define THCTR_PONM	BIT(6)
 #define THCTR_THSST	BIT(0)
 
+/* THSCP bits */
+#define THSCP_COR_PARA_VLD	(BIT(15) | BIT(14))
+
 #define CTEMP_MASK	0xFFF
 
 #define MCELSIUS(temp)	((temp) * 1000)
@@ -81,6 +88,7 @@ struct equation_coefs {
 
 struct rcar_gen3_thermal_tsc {
 	void __iomem *base;
+	resource_size_t size;
 	struct thermal_zone_device *zone;
 	struct equation_coefs coef;
 	int low;
@@ -284,6 +292,55 @@ static const struct soc_device_attribute r8a7795es1[] = {
 	{ /* sentinel */ }
 };
 
+static bool rcar_gen3_thermal_update_fuses(struct rcar_gen3_thermal_priv *priv)
+{
+	int i, ptat[3], thcode[3];
+	u32 thscp;
+
+	if (!priv->num_tscs)
+		return false;
+
+	/*
+	 * If resource size of TSC1 is less then 0x6c0 old DT is used, not
+	 * possible to read all fusees, fallback to pseudo values.
+	 */
+	if (priv->tscs[0]->size < 0x6c)
+		return false;
+
+	/* If fuses are not set, fallback to pseudo values. */
+	thscp = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_THSCP);
+	if ((thscp & THSCP_COR_PARA_VLD) != THSCP_COR_PARA_VLD)
+		return false;
+
+	/*
+	 * Update the pseudo calibration points with fused values.
+	 * PTAT is shared between all TSC:s but only fused for the first
+	 * TSC while THCODEs are fused for each TSC.
+	 */
+
+	ptat[0] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT1) &
+		GEN3_FUSE_MASK;
+	ptat[1] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT2) &
+		GEN3_FUSE_MASK;
+	ptat[2] = rcar_gen3_thermal_read(priv->tscs[0], REG_GEN3_PTAT3) &
+		GEN3_FUSE_MASK;
+
+	for (i = 0; i < priv->num_tscs; i++) {
+		struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
+
+		thcode[0] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE1) &
+			GEN3_FUSE_MASK;
+		thcode[1] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE2) &
+			GEN3_FUSE_MASK;
+		thcode[2] = rcar_gen3_thermal_read(tsc, REG_GEN3_THCODE3) &
+			GEN3_FUSE_MASK;
+
+		rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode);
+	}
+
+	return true;
+}
+
 static void r8a7796_thermal_init(struct rcar_gen3_thermal_tsc *tsc)
 {
 	u32 reg_val;
@@ -432,11 +489,22 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
 			ret = PTR_ERR(tsc->base);
 			goto error_unregister;
 		}
+		tsc->size = resource_size(res);
 
 		priv->tscs[i] = tsc;
 
 		priv->data->thermal_init(tsc);
+
 		rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]);
+	}
+
+	priv->num_tscs = i;
+
+	if (rcar_gen3_thermal_update_fuses(priv))
+		dev_info(dev, "Using fused calibration values\n");
+
+	for (i = 0; i < priv->num_tscs; i++) {
+		struct rcar_gen3_thermal_tsc *tsc = priv->tscs[i];
 
 		zone = devm_thermal_zone_of_sensor_register(dev, i, tsc,
 							    &rcar_gen3_tz_of_ops);
@@ -454,8 +522,6 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
 		dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret);
 	}
 
-	priv->num_tscs = i;
-
 	if (!priv->num_tscs) {
 		ret = -ENODEV;
 		goto error_unregister;
-- 
2.14.1

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

* [RFC 2/3] arm64: dts: r8a7795: update register size for thermal
  2017-09-13 11:01 [RFC 0/3] thermal: rcar_gen3_thermal: read calibration from hardware Niklas Söderlund
  2017-09-13 11:01 ` [RFC 1/3] " Niklas Söderlund
@ 2017-09-13 11:01 ` Niklas Söderlund
  2017-09-13 11:01 ` [RFC 3/3] arm64: dts: r8a7796: " Niklas Söderlund
  2 siblings, 0 replies; 4+ messages in thread
From: Niklas Söderlund @ 2017-09-13 11:01 UTC (permalink / raw)
  To: linux-pm, Simon Horman, Wolfram Sang
  Cc: linux-renesas-soc, Niklas Söderlund

To be able to read fused calibration values from hardware the size of
the register resource of TSC1 needs to be incremented to cover one more
register which holds the information if the calibration values have been
fused or not.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 arch/arm64/boot/dts/renesas/r8a7795.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
index 1818fd20660d0315..be3c7ff6999af57e 100644
--- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
@@ -2805,7 +2805,7 @@
 
 		tsc: thermal@e6198000 {
 			compatible = "renesas,r8a7795-thermal";
-			reg = <0 0xe6198000 0 0x68>,
+			reg = <0 0xe6198000 0 0x6c>,
 			      <0 0xe61a0000 0 0x5c>,
 			      <0 0xe61a8000 0 0x5c>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.14.1

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

* [RFC 3/3] arm64: dts: r8a7796: update register size for thermal
  2017-09-13 11:01 [RFC 0/3] thermal: rcar_gen3_thermal: read calibration from hardware Niklas Söderlund
  2017-09-13 11:01 ` [RFC 1/3] " Niklas Söderlund
  2017-09-13 11:01 ` [RFC 2/3] arm64: dts: r8a7795: update register size for thermal Niklas Söderlund
@ 2017-09-13 11:01 ` Niklas Söderlund
  2 siblings, 0 replies; 4+ messages in thread
From: Niklas Söderlund @ 2017-09-13 11:01 UTC (permalink / raw)
  To: linux-pm, Simon Horman, Wolfram Sang
  Cc: linux-renesas-soc, Niklas Söderlund

To be able to read fused calibration values from hardware the size of
the register resource of TSC1 needs to be incremented to cover one more
register which holds the information if the calibration values have been
fused or not.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 arch/arm64/boot/dts/renesas/r8a7796.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/renesas/r8a7796.dtsi b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
index 0b805dc30925e9be..b1428c10e703b37c 100644
--- a/arch/arm64/boot/dts/renesas/r8a7796.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a7796.dtsi
@@ -2098,7 +2098,7 @@
 
 		tsc: thermal@e6198000 {
 			compatible = "renesas,r8a7796-thermal";
-			reg = <0 0xe6198000 0 0x68>,
+			reg = <0 0xe6198000 0 0x6c>,
 			      <0 0xe61a0000 0 0x5c>,
 			      <0 0xe61a8000 0 0x5c>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.14.1

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

end of thread, other threads:[~2017-09-13 11:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-13 11:01 [RFC 0/3] thermal: rcar_gen3_thermal: read calibration from hardware Niklas Söderlund
2017-09-13 11:01 ` [RFC 1/3] " Niklas Söderlund
2017-09-13 11:01 ` [RFC 2/3] arm64: dts: r8a7795: update register size for thermal Niklas Söderlund
2017-09-13 11:01 ` [RFC 3/3] arm64: dts: r8a7796: " Niklas Söderlund

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.