Commit c33edd8f authored by Cosmin Tanislav's avatar Cosmin Tanislav Committed by Daniel Lezcano
Browse files

thermal: renesas: rzg3e: make calibration value retrieval per-chip



The Renesas RZ/T2H (R9A09G077) and RZ/N2H (R9A09G087) SoCs expose the
temperature calibration data via SMC SIP calls.

To prepare for supporting these SoCs, do the following changes.

Rename rzg3e_thermal_parse_dt() to rzg3e_thermal_get_syscon_trim().

Move the syscon usage out of rzg3e_thermal_get_calibration() and into
rzg3e_thermal_get_syscon_trim() and remove single-use variables from the
private state.

Place a pointer to rzg3e_thermal_get_syscon_trim() into the
chip-specific struct, and use it in the probe function to retrieve the
calibration values.

Now that syscon usage has been moved out of
rzg3e_thermal_get_calibration(), remove it and inline the calibration
validation into the probe function.

Also, reuse the TSU_CODE_MAX macro to mask the calibration values, as
GEMASK(11, 0) and 0xFFF are equivalent, and replace the hardcoded 0xFFF
with TSU_CODE_MAX in the calibration validation.

Reviewed-by: default avatarJohn Madieu <john.madieu.xa@bp.renesas.com>
Tested-by: default avatarJohn Madieu <john.madieu.xa@bp.renesas.com>
Signed-off-by: default avatarCosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>
Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260108195223.193531-4-cosmin-gabriel.tanislav.xa@renesas.com


Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
parent 6c7f87f5
Loading
Loading
Loading
Loading
+29 −42
Original line number Diff line number Diff line
@@ -70,7 +70,10 @@
#define TSU_POLL_DELAY_US	10	/* Polling interval */
#define TSU_MIN_CLOCK_RATE	24000000  /* TSU_PCLK minimum 24MHz */

struct rzg3e_thermal_priv;

struct rzg3e_thermal_info {
	int (*get_trim)(struct rzg3e_thermal_priv *priv);
	int temp_d_mc;
	int temp_e_mc;
};
@@ -91,13 +94,11 @@ struct rzg3e_thermal_info {
struct rzg3e_thermal_priv {
	void __iomem *base;
	struct device *dev;
	struct regmap *syscon;
	struct thermal_zone_device *zone;
	struct reset_control *rstc;
	const struct rzg3e_thermal_info *info;
	u16 trmval0;
	u16 trmval1;
	u32 trim_offset;
	struct mutex lock;
};

@@ -334,51 +335,33 @@ static const struct thermal_zone_device_ops rzg3e_tz_ops = {
	.set_trips = rzg3e_thermal_set_trips,
};

static int rzg3e_thermal_get_calibration(struct rzg3e_thermal_priv *priv)
static int rzg3e_thermal_get_syscon_trim(struct rzg3e_thermal_priv *priv)
{
	u32 val;
	struct device_node *np = priv->dev->of_node;
	struct regmap *syscon;
	u32 offset;
	int ret;
	u32 val;

	syscon = syscon_regmap_lookup_by_phandle_args(np, "renesas,tsu-trim", 1, &offset);
	if (IS_ERR(syscon))
		return dev_err_probe(priv->dev, PTR_ERR(syscon),
				     "Failed to parse renesas,tsu-trim\n");

	/* Read calibration values from syscon */
	ret = regmap_read(priv->syscon, priv->trim_offset, &val);
	ret = regmap_read(syscon, offset, &val);
	if (ret)
		return ret;
	priv->trmval0 = val & GENMASK(11, 0);
	priv->trmval0 = val & TSU_CODE_MAX;

	ret = regmap_read(priv->syscon, priv->trim_offset + 4, &val);
	ret = regmap_read(syscon, offset + 4, &val);
	if (ret)
		return ret;
	priv->trmval1 = val & GENMASK(11, 0);

	/* Validate calibration data */
	if (!priv->trmval0 || !priv->trmval1 ||
	    priv->trmval0 == priv->trmval1 ||
	    priv->trmval0 == 0xFFF || priv->trmval1 == 0xFFF) {
		dev_err(priv->dev, "Invalid calibration: b=0x%03x, c=0x%03x\n",
			priv->trmval0, priv->trmval1);
		return -EINVAL;
	}

	dev_dbg(priv->dev, "Calibration: b=0x%03x (%u), c=0x%03x (%u)\n",
		priv->trmval0, priv->trmval0, priv->trmval1, priv->trmval1);
	priv->trmval1 = val & TSU_CODE_MAX;

	return 0;
}

static int rzg3e_thermal_parse_dt(struct rzg3e_thermal_priv *priv)
{
	struct device_node *np = priv->dev->of_node;
	u32 offset;

	priv->syscon = syscon_regmap_lookup_by_phandle_args(np, "renesas,tsu-trim", 1, &offset);
	if (IS_ERR(priv->syscon))
		return dev_err_probe(priv->dev, PTR_ERR(priv->syscon),
				     "Failed to parse renesas,tsu-trim\n");

	priv->trim_offset = offset;
	return 0;
}

static int rzg3e_thermal_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
@@ -402,11 +385,20 @@ static int rzg3e_thermal_probe(struct platform_device *pdev)
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	/* Parse device tree for trim register info */
	ret = rzg3e_thermal_parse_dt(priv);
	ret = priv->info->get_trim(priv);
	if (ret)
		return ret;

	if (!priv->trmval0 || !priv->trmval1 ||
	    priv->trmval0 == priv->trmval1 ||
	    priv->trmval0 == TSU_CODE_MAX || priv->trmval1 == TSU_CODE_MAX)
		return dev_err_probe(priv->dev, -EINVAL,
				     "Invalid calibration: b=0x%03x, c=0x%03x\n",
				     priv->trmval0, priv->trmval1);

	dev_dbg(priv->dev, "Calibration: b=0x%03x (%u), c=0x%03x (%u)\n",
		priv->trmval0, priv->trmval0, priv->trmval1, priv->trmval1);

	/* Get clock to verify frequency - clock is managed by power domain */
	clk = devm_clk_get(dev, NULL);
	if (IS_ERR(clk))
@@ -423,12 +415,6 @@ static int rzg3e_thermal_probe(struct platform_device *pdev)
		return dev_err_probe(dev, PTR_ERR(priv->rstc),
				     "Failed to get/deassert reset control\n");

	/* Get calibration data */
	ret = rzg3e_thermal_get_calibration(priv);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to get valid calibration data\n");

	/* Get comparison interrupt */
	irq = platform_get_irq_byname(pdev, "adcmpi");
	if (irq < 0)
@@ -533,6 +519,7 @@ static const struct dev_pm_ops rzg3e_thermal_pm_ops = {
};

static const struct rzg3e_thermal_info rzg3e_thermal_info = {
	.get_trim = rzg3e_thermal_get_syscon_trim,
	.temp_d_mc = -41000,
	.temp_e_mc = 126000,
};