Message ID | 20200114190607.29339-3-f.fainelli@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Daniel Lezcano |
Headers | show |
Series | brcmstb_thermal updates for new processes | expand |
On Wed, Jan 15, 2020 at 12:36 AM Florian Fainelli <f.fainelli@gmail.com> wrote: > > The driver is currently assuming that it is operating with a 28nm > process chip, which has a specific formula to convert temperature to a > code and vice versa. Update the code to support providing two key > values: offset and multiplier to derive the correct formulas. > > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Amit Kucheria <amit.kucheria@linaro.org> > --- > drivers/thermal/broadcom/brcmstb_thermal.c | 47 +++++++++++++++------- > 1 file changed, 33 insertions(+), 14 deletions(-) > > diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c > index 680f1a070606..2d555e7b884a 100644 > --- a/drivers/thermal/broadcom/brcmstb_thermal.c > +++ b/drivers/thermal/broadcom/brcmstb_thermal.c > @@ -102,18 +102,27 @@ static struct avs_tmon_trip avs_tmon_trips[] = { > }, > }; > > +struct brcmstb_thermal_params { > + unsigned int offset; > + unsigned int mult; > +}; > + > struct brcmstb_thermal_priv { > void __iomem *tmon_base; > struct device *dev; > struct thermal_zone_device *thermal; > + /* Process specific thermal parameters used for calculations */ > + const struct brcmstb_thermal_params *temp_params; > }; > > /* Convert a HW code to a temperature reading (millidegree celsius) */ > -static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, > +static inline int avs_tmon_code_to_temp(struct brcmstb_thermal_priv *priv, > u32 code) > { > - return (AVS_TMON_TEMP_OFFSET - > - (int)((code & AVS_TMON_TEMP_MAX) * AVS_TMON_TEMP_SLOPE)); > + int offset = priv->temp_params->offset; > + int mult = priv->temp_params->mult; > + > + return (offset - (int)((code & AVS_TMON_TEMP_MASK) * mult)); > } > > /* > @@ -122,21 +131,22 @@ static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, > * @temp: temperature to convert > * @low: if true, round toward the low side > */ > -static inline u32 avs_tmon_temp_to_code(struct thermal_zone_device *tz, > +static inline u32 avs_tmon_temp_to_code(struct brcmstb_thermal_priv *priv, > int temp, bool low) > { > + int offset = priv->temp_params->offset; > + int mult = priv->temp_params->mult; > + > if (temp < AVS_TMON_TEMP_MIN) > return AVS_TMON_TEMP_MAX; /* Maximum code value */ > > - if (temp >= AVS_TMON_TEMP_OFFSET) > + if (temp >= offset) > return 0; /* Minimum code value */ > > if (low) > - return (u32)(DIV_ROUND_UP(AVS_TMON_TEMP_OFFSET - temp, > - AVS_TMON_TEMP_SLOPE)); > + return (u32)(DIV_ROUND_UP(offset - temp, mult)); > else > - return (u32)((AVS_TMON_TEMP_OFFSET - temp) / > - AVS_TMON_TEMP_SLOPE); > + return (u32)((offset - temp) / mult); > } > > static int brcmstb_get_temp(void *data, int *temp) > @@ -154,7 +164,7 @@ static int brcmstb_get_temp(void *data, int *temp) > > val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift; > > - t = avs_tmon_code_to_temp(priv->thermal, val); > + t = avs_tmon_code_to_temp(priv, val); > if (t < 0) > *temp = 0; > else > @@ -188,7 +198,7 @@ static int avs_tmon_get_trip_temp(struct brcmstb_thermal_priv *priv, > val &= trip->reg_msk; > val >>= trip->reg_shift; > > - return avs_tmon_code_to_temp(priv->thermal, val); > + return avs_tmon_code_to_temp(priv, val); > } > > static void avs_tmon_set_trip_temp(struct brcmstb_thermal_priv *priv, > @@ -201,7 +211,7 @@ static void avs_tmon_set_trip_temp(struct brcmstb_thermal_priv *priv, > dev_dbg(priv->dev, "set temp %d to %d\n", type, temp); > > /* round toward low temp for the low interrupt */ > - val = avs_tmon_temp_to_code(priv->thermal, temp, > + val = avs_tmon_temp_to_code(priv, temp, > type == TMON_TRIP_TYPE_LOW); > > val <<= trip->reg_shift; > @@ -218,7 +228,7 @@ static int avs_tmon_get_intr_temp(struct brcmstb_thermal_priv *priv) > u32 val; > > val = __raw_readl(priv->tmon_base + AVS_TMON_TEMP_INT_CODE); > - return avs_tmon_code_to_temp(priv->thermal, val); > + return avs_tmon_code_to_temp(priv, val); > } > > static irqreturn_t brcmstb_tmon_irq_thread(int irq, void *data) > @@ -282,8 +292,13 @@ static const struct thermal_zone_of_device_ops of_ops = { > .set_trips = brcmstb_set_trips, > }; > > +static const struct brcmstb_thermal_params brcmstb_28nm_params = { > + .offset = 410040, > + .mult = 487, > +}; > + > static const struct of_device_id brcmstb_thermal_id_table[] = { > - { .compatible = "brcm,avs-tmon" }, > + { .compatible = "brcm,avs-tmon", .data = &brcmstb_28nm_params }, > {}, > }; > MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table); > @@ -299,6 +314,10 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) > if (!priv) > return -ENOMEM; > > + priv->temp_params = of_device_get_match_data(&pdev->dev); > + if (!priv->temp_params) > + return -EINVAL; > + > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > priv->tmon_base = devm_ioremap_resource(&pdev->dev, res); > if (IS_ERR(priv->tmon_base)) > -- > 2.17.1 >
diff --git a/drivers/thermal/broadcom/brcmstb_thermal.c b/drivers/thermal/broadcom/brcmstb_thermal.c index 680f1a070606..2d555e7b884a 100644 --- a/drivers/thermal/broadcom/brcmstb_thermal.c +++ b/drivers/thermal/broadcom/brcmstb_thermal.c @@ -102,18 +102,27 @@ static struct avs_tmon_trip avs_tmon_trips[] = { }, }; +struct brcmstb_thermal_params { + unsigned int offset; + unsigned int mult; +}; + struct brcmstb_thermal_priv { void __iomem *tmon_base; struct device *dev; struct thermal_zone_device *thermal; + /* Process specific thermal parameters used for calculations */ + const struct brcmstb_thermal_params *temp_params; }; /* Convert a HW code to a temperature reading (millidegree celsius) */ -static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, +static inline int avs_tmon_code_to_temp(struct brcmstb_thermal_priv *priv, u32 code) { - return (AVS_TMON_TEMP_OFFSET - - (int)((code & AVS_TMON_TEMP_MAX) * AVS_TMON_TEMP_SLOPE)); + int offset = priv->temp_params->offset; + int mult = priv->temp_params->mult; + + return (offset - (int)((code & AVS_TMON_TEMP_MASK) * mult)); } /* @@ -122,21 +131,22 @@ static inline int avs_tmon_code_to_temp(struct thermal_zone_device *tz, * @temp: temperature to convert * @low: if true, round toward the low side */ -static inline u32 avs_tmon_temp_to_code(struct thermal_zone_device *tz, +static inline u32 avs_tmon_temp_to_code(struct brcmstb_thermal_priv *priv, int temp, bool low) { + int offset = priv->temp_params->offset; + int mult = priv->temp_params->mult; + if (temp < AVS_TMON_TEMP_MIN) return AVS_TMON_TEMP_MAX; /* Maximum code value */ - if (temp >= AVS_TMON_TEMP_OFFSET) + if (temp >= offset) return 0; /* Minimum code value */ if (low) - return (u32)(DIV_ROUND_UP(AVS_TMON_TEMP_OFFSET - temp, - AVS_TMON_TEMP_SLOPE)); + return (u32)(DIV_ROUND_UP(offset - temp, mult)); else - return (u32)((AVS_TMON_TEMP_OFFSET - temp) / - AVS_TMON_TEMP_SLOPE); + return (u32)((offset - temp) / mult); } static int brcmstb_get_temp(void *data, int *temp) @@ -154,7 +164,7 @@ static int brcmstb_get_temp(void *data, int *temp) val = (val & AVS_TMON_STATUS_data_msk) >> AVS_TMON_STATUS_data_shift; - t = avs_tmon_code_to_temp(priv->thermal, val); + t = avs_tmon_code_to_temp(priv, val); if (t < 0) *temp = 0; else @@ -188,7 +198,7 @@ static int avs_tmon_get_trip_temp(struct brcmstb_thermal_priv *priv, val &= trip->reg_msk; val >>= trip->reg_shift; - return avs_tmon_code_to_temp(priv->thermal, val); + return avs_tmon_code_to_temp(priv, val); } static void avs_tmon_set_trip_temp(struct brcmstb_thermal_priv *priv, @@ -201,7 +211,7 @@ static void avs_tmon_set_trip_temp(struct brcmstb_thermal_priv *priv, dev_dbg(priv->dev, "set temp %d to %d\n", type, temp); /* round toward low temp for the low interrupt */ - val = avs_tmon_temp_to_code(priv->thermal, temp, + val = avs_tmon_temp_to_code(priv, temp, type == TMON_TRIP_TYPE_LOW); val <<= trip->reg_shift; @@ -218,7 +228,7 @@ static int avs_tmon_get_intr_temp(struct brcmstb_thermal_priv *priv) u32 val; val = __raw_readl(priv->tmon_base + AVS_TMON_TEMP_INT_CODE); - return avs_tmon_code_to_temp(priv->thermal, val); + return avs_tmon_code_to_temp(priv, val); } static irqreturn_t brcmstb_tmon_irq_thread(int irq, void *data) @@ -282,8 +292,13 @@ static const struct thermal_zone_of_device_ops of_ops = { .set_trips = brcmstb_set_trips, }; +static const struct brcmstb_thermal_params brcmstb_28nm_params = { + .offset = 410040, + .mult = 487, +}; + static const struct of_device_id brcmstb_thermal_id_table[] = { - { .compatible = "brcm,avs-tmon" }, + { .compatible = "brcm,avs-tmon", .data = &brcmstb_28nm_params }, {}, }; MODULE_DEVICE_TABLE(of, brcmstb_thermal_id_table); @@ -299,6 +314,10 @@ static int brcmstb_thermal_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; + priv->temp_params = of_device_get_match_data(&pdev->dev); + if (!priv->temp_params) + return -EINVAL; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->tmon_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->tmon_base))
The driver is currently assuming that it is operating with a 28nm process chip, which has a specific formula to convert temperature to a code and vice versa. Update the code to support providing two key values: offset and multiplier to derive the correct formulas. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> --- drivers/thermal/broadcom/brcmstb_thermal.c | 47 +++++++++++++++------- 1 file changed, 33 insertions(+), 14 deletions(-)