123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- From f8b54d1120b81ed57bed96cc8e814ba08886d1e5 Mon Sep 17 00:00:00 2001
- From: Andre Przywara <[email protected]>
- Date: Mon, 19 Feb 2024 15:36:37 +0000
- Subject: [PATCH] thermal/drivers/sun8i: Add SRAM register access code
- The Allwinner H616 SoC needs to clear a bit in one register in the SRAM
- controller, to report reasonable temperature values. On reset, bit 16 in
- register 0x3000000 is set, which leads to the driver reporting
- temperatures around 200C. Clearing this bit brings the values down to the
- expected range. The BSP code does a one-time write in U-Boot, with a
- comment just mentioning the effect on the THS, but offering no further
- explanation.
- To not rely on firmware to set things up for us, add code that queries
- the SRAM controller device via a DT phandle link, then clear just this
- single bit.
- Signed-off-by: Andre Przywara <[email protected]>
- Acked-by: Vasily Khoruzhick <[email protected]>
- Signed-off-by: Daniel Lezcano <[email protected]>
- Link: https://lore.kernel.org/r/[email protected]
- ---
- drivers/thermal/sun8i_thermal.c | 51 +++++++++++++++++++++++++++++++++
- 1 file changed, 51 insertions(+)
- --- a/drivers/thermal/sun8i_thermal.c
- +++ b/drivers/thermal/sun8i_thermal.c
- @@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/nvmem-consumer.h>
- #include <linux/of_device.h>
- +#include <linux/of_platform.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
- #include <linux/reset.h>
- @@ -68,6 +69,7 @@ struct tsensor {
- struct ths_thermal_chip {
- bool has_mod_clk;
- bool has_bus_clk_reset;
- + bool needs_sram;
- int sensor_num;
- int offset;
- int scale;
- @@ -85,12 +87,16 @@ struct ths_device {
- const struct ths_thermal_chip *chip;
- struct device *dev;
- struct regmap *regmap;
- + struct regmap_field *sram_regmap_field;
- struct reset_control *reset;
- struct clk *bus_clk;
- struct clk *mod_clk;
- struct tsensor sensor[MAX_SENSOR_NUM];
- };
-
- +/* The H616 needs to have a bit 16 in the SRAM control register cleared. */
- +static const struct reg_field sun8i_ths_sram_reg_field = REG_FIELD(0x0, 16, 16);
- +
- /* Temp Unit: millidegree Celsius */
- static int sun8i_ths_calc_temp(struct ths_device *tmdev,
- int id, int reg)
- @@ -337,6 +343,34 @@ static void sun8i_ths_reset_control_asse
- reset_control_assert(data);
- }
-
- +static struct regmap *sun8i_ths_get_sram_regmap(struct device_node *node)
- +{
- + struct device_node *sram_node;
- + struct platform_device *sram_pdev;
- + struct regmap *regmap = NULL;
- +
- + sram_node = of_parse_phandle(node, "allwinner,sram", 0);
- + if (!sram_node)
- + return ERR_PTR(-ENODEV);
- +
- + sram_pdev = of_find_device_by_node(sram_node);
- + if (!sram_pdev) {
- + /* platform device might not be probed yet */
- + regmap = ERR_PTR(-EPROBE_DEFER);
- + goto out_put_node;
- + }
- +
- + /* If no regmap is found then the other device driver is at fault */
- + regmap = dev_get_regmap(&sram_pdev->dev, NULL);
- + if (!regmap)
- + regmap = ERR_PTR(-EINVAL);
- +
- + platform_device_put(sram_pdev);
- +out_put_node:
- + of_node_put(sram_node);
- + return regmap;
- +}
- +
- static int sun8i_ths_resource_init(struct ths_device *tmdev)
- {
- struct device *dev = tmdev->dev;
- @@ -381,6 +415,19 @@ static int sun8i_ths_resource_init(struc
- if (ret)
- return ret;
-
- + if (tmdev->chip->needs_sram) {
- + struct regmap *regmap;
- +
- + regmap = sun8i_ths_get_sram_regmap(dev->of_node);
- + if (IS_ERR(regmap))
- + return PTR_ERR(regmap);
- + tmdev->sram_regmap_field = devm_regmap_field_alloc(dev,
- + regmap,
- + sun8i_ths_sram_reg_field);
- + if (IS_ERR(tmdev->sram_regmap_field))
- + return PTR_ERR(tmdev->sram_regmap_field);
- + }
- +
- ret = sun8i_ths_calibrate(tmdev);
- if (ret)
- return ret;
- @@ -427,6 +474,10 @@ static int sun50i_h6_thermal_init(struct
- {
- int val;
-
- + /* The H616 needs to have a bit in the SRAM control register cleared. */
- + if (tmdev->sram_regmap_field)
- + regmap_field_write(tmdev->sram_regmap_field, 0);
- +
- /*
- * The manual recommends an overall sample frequency of 50 KHz (20us,
- * 480 cycles at 24 MHz), which provides plenty of time for both the
|