mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Lukasz Luba <lukasz.luba@arm.com>
To: Mateusz Majewski <m.majewski2@samsung.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org,
	Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>,
	"Rafael J. Wysocki" <rafael@kernel.org>,
	Daniel Lezcano <daniel.lezcano@linaro.org>,
	linux-kernel@vger.kernel.org, Amit Kucheria <amitk@kernel.org>,
	Zhang Rui <rui.zhang@intel.com>,
	Alim Akhtar <alim.akhtar@samsung.com>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Mark Brown <broonie@kernel.org>,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	linux-pm@vger.kernel.org
Subject: Re: [PATCH v4 8/8] thermal: exynos: use set_trips
Date: Tue, 31 Oct 2023 09:26:19 +0000	[thread overview]
Message-ID: <2c4b6c1b-b9e7-42b2-8f7b-446ebe9d15ac@arm.com> (raw)
In-Reply-To: <20231025133027.524152-9-m.majewski2@samsung.com>



On 10/25/23 14:30, Mateusz Majewski wrote:
> Currently, each trip point defined in the device tree corresponds to a
> single hardware interrupt. This commit instead switches to using two
> hardware interrupts, whose values are set dynamically using the
> set_trips callback. Additionally, the critical temperature threshold is
> handled specifically.
> 

[snip]

>   
> -static void exynos4210_tmu_set_trip_temp(struct exynos_tmu_data *data,
> -					 int trip_id, u8 temp)
> +static void exynos_tmu_update_bit(struct exynos_tmu_data *data, int reg_off,
> +				  int bit_off, bool enable)
>   {
> -	temp = temp_to_code(data, temp);
> -	writeb(temp, data->base + EXYNOS4210_TMU_REG_TRIG_LEVEL0 + trip_id * 4);
> +	u32 interrupt_en;
> +
> +	interrupt_en = readl(data->base + reg_off);
> +	if (enable)
> +		interrupt_en |= 1 << bit_off;
> +	else
> +		interrupt_en &= ~(1 << bit_off);

Why not to use dedicated stuff for this?
val |= BIT(x)
val &= ~BIT(x)
You can find plenty of example in the kernel

> +	writel(interrupt_en, data->base + reg_off);
>   }
>   

[snip]

> -static void exynos4412_tmu_set_trip_temp(struct exynos_tmu_data *data,
> -					 int trip, u8 temp)
> -{
> -	u32 th, con;
> -
> -	th = readl(data->base + EXYNOS_THD_TEMP_RISE);
> -	th &= ~(0xff << 8 * trip);
> -	th |= temp_to_code(data, temp) << 8 * trip;
> -	writel(th, data->base + EXYNOS_THD_TEMP_RISE);
> -
> -	if (trip == 3) {
> -		con = readl(data->base + EXYNOS_TMU_REG_CONTROL);
> -		con |= (1 << EXYNOS_TMU_THERM_TRIP_EN_SHIFT);
> -		writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
> -	}
> -}
> -
> -static void exynos4412_tmu_set_trip_hyst(struct exynos_tmu_data *data,
> -					 int trip, u8 temp, u8 hyst)
> +static void exynos4412_tmu_set_low_temp(struct exynos_tmu_data *data, u8 temp)
>   {
>   	u32 th;
>   
>   	th = readl(data->base + EXYNOS_THD_TEMP_FALL);
> -	th &= ~(0xff << 8 * trip);
> -	if (hyst)
> -		th |= temp_to_code(data, temp - hyst) << 8 * trip;
> +	th &= ~(0xff << 0);
> +	th |= temp_to_code(data, temp) << 0;

This 2-line pattern repeats a few times. It looks like a nice cadidate
for an inline function which can abstract that. Something like:

val = update_temp_value(data, temp, threshold, LOW_TEMP_SHIFT)

Assisted with the macros {LOW|HIGH|CRIT}_TEMP_SHIFT, the code
would look less convoluted IMO.
(The old code with the multiplication for the shift value wasn't
cleaner nor faster).

>   	writel(th, data->base + EXYNOS_THD_TEMP_FALL);
> +
> +	exynos_tmu_update_bit(data, EXYNOS_TMU_REG_INTEN,
> +			      EXYNOS_TMU_INTEN_FALL0_SHIFT, true);
> +}

[snip]

> -static void exynos7_tmu_set_trip_temp(struct exynos_tmu_data *data,
> -				      int trip, u8 temp)
> +static void exynos7_tmu_update_temp(struct exynos_tmu_data *data, u8 temp,
> +				    int idx, bool rise)
>   {
>   	unsigned int reg_off, bit_off;
>   	u32 th;
> +	void __iomem *reg;
>   
> -	reg_off = ((7 - trip) / 2) * 4;
> -	bit_off = ((8 - trip) % 2);
> +	reg_off = ((7 - idx) / 2) * 4;

Why can't we just have a set of defined register macros and pick one
in some small function?
A lot of operations here, also some assumption.

> +	bit_off = ((8 - idx) % 2);

So this can only be 0 or 1 and than it's used for the shift
multiplication. Also I don't know the history of older code and
if it was missed after some cleaning, but 'idx % 2' gives
equal values but w/o subtraction.

BTW, the code assumes the 'idx' values are under control somewhere else.
Is that because the DT make sure in the schema that the range cannot be
too big?
What are the possible values for 'idx'?

>   
> -	th = readl(data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
> +	reg = data->base +
> +	      (rise ? EXYNOS7_THD_TEMP_RISE7_6 : EXYNOS7_THD_TEMP_FALL7_6) +
> +	      reg_off;
> +	th = readl(reg);
>   	th &= ~(EXYNOS7_TMU_TEMP_MASK << (16 * bit_off));
>   	th |= temp_to_code(data, temp) << (16 * bit_off);

Can you simplify and abstract those bit_off usage and use some
macros and less math operations?

> -	writel(th, data->base + EXYNOS7_THD_TEMP_RISE7_6 + reg_off);
> +	writel(th, reg);
> +
> +	exynos_tmu_update_bit(data, EXYNOS5433_TMU_REG_INTEN,
> +			      (rise ? EXYNOS7_TMU_INTEN_RISE0_SHIFT :
> +				      EXYNOS_TMU_INTEN_FALL0_SHIFT) +
> +				      idx,
> +			      true);
>   }

[snip]

>   
> -	if (on) {
> -		for (i = 0; i < data->ntrip; i++) {
> -			if (thermal_zone_get_trip(tz, i, &trip))
> -				continue;
> -
> -			interrupt_en |=
> -				(1 << (EXYNOS_TMU_INTEN_RISE0_SHIFT + i * 4));
> -		}
> -
> -		if (data->soc != SOC_ARCH_EXYNOS4210)
> -			interrupt_en |=
> -				interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
> -
> +	if (on)
>   		con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
> -	} else {
> +	else
>   		con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);

Please also consider the BIT() helper here and above...

> -	}
>   
> -	writel(interrupt_en, data->base + EXYNOS_TMU_REG_INTEN);
>   	writel(con, data->base + EXYNOS_TMU_REG_CONTROL);
>   }
>   
>   static void exynos5433_tmu_control(struct platform_device *pdev, bool on)
>   {
>   	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> -	struct thermal_zone_device *tz = data->tzd;
> -	struct thermal_trip trip;
> -	unsigned int con, interrupt_en = 0, pd_det_en, i;
> +	unsigned int con, pd_det_en;
>   
>   	con = get_con_reg(data, readl(data->base + EXYNOS_TMU_REG_CONTROL));
>   
> -	if (on) {
> -		for (i = 0; i < data->ntrip; i++) {
> -			if (thermal_zone_get_trip(tz, i, &trip))
> -				continue;
> -
> -			interrupt_en |=
> -				(1 << (EXYNOS7_TMU_INTEN_RISE0_SHIFT + i));
> -		}
> -
> -		interrupt_en |=
> -			interrupt_en << EXYNOS_TMU_INTEN_FALL0_SHIFT;
> -
> +	if (on)
>   		con |= (1 << EXYNOS_TMU_CORE_EN_SHIFT);
> -	} else
> +	else
>   		con &= ~(1 << EXYNOS_TMU_CORE_EN_SHIFT);

... and here. Basically in all places where it's possible.

Regards,
Lukasz

  reply	other threads:[~2023-10-31  9:25 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20231025133043eucas1p2f882c015c25c185fb4c1cd5b3d3027e8@eucas1p2.samsung.com>
2023-10-25 13:30 ` [PATCH v4 0/8] Improve Exynos thermal driver Mateusz Majewski
     [not found]   ` <CGME20231025133047eucas1p2bef6136656645815da1ff884f4f8d1d0@eucas1p2.samsung.com>
2023-10-25 13:30     ` [PATCH v4 1/8] thermal: exynos: remove an unnecessary field description Mateusz Majewski
     [not found]   ` <CGME20231025133049eucas1p11f9c4dc6d235418175c94340ad15f5a7@eucas1p1.samsung.com>
2023-10-25 13:30     ` [PATCH v4 2/8] thermal: exynos: drop id field Mateusz Majewski
     [not found]   ` <CGME20231025133051eucas1p1e9ed4202abb45c5d2f738fdd213503ee@eucas1p1.samsung.com>
2023-10-25 13:30     ` [PATCH v4 3/8] thermal: exynos: switch from workqueue-driven interrupt handling to threaded interrupts Mateusz Majewski
     [not found]   ` <CGME20231025133052eucas1p2278dc2030aa8fd20868cd4f3605a8a2f@eucas1p2.samsung.com>
2023-10-25 13:30     ` [PATCH v4 4/8] thermal: exynos: handle devm_regulator_get_optional return value correctly Mateusz Majewski
     [not found]   ` <CGME20231025133054eucas1p23c3ad3e8a8f96608f5574a3b7910589d@eucas1p2.samsung.com>
2023-10-25 13:30     ` [PATCH v4 5/8] thermal: exynos: simplify regulator (de)initialization Mateusz Majewski
     [not found]   ` <CGME20231025133055eucas1p13779e9c86720bf460c12b28c6d830f2a@eucas1p1.samsung.com>
2023-10-25 13:30     ` [PATCH v4 6/8] thermal: exynos: stop using the threshold mechanism on Exynos 4210 Mateusz Majewski
     [not found]   ` <CGME20231025133058eucas1p149f79722039a90e6e61172ae323b813a@eucas1p1.samsung.com>
2023-10-25 13:30     ` [PATCH v4 7/8] thermal: exynos: split initialization of TMU and the thermal zone Mateusz Majewski
     [not found]   ` <CGME20231025133100eucas1p14e6de58e52560d165bdb8b809e406278@eucas1p1.samsung.com>
2023-10-25 13:30     ` [PATCH v4 8/8] thermal: exynos: use set_trips Mateusz Majewski
2023-10-31  9:26       ` Lukasz Luba [this message]
     [not found]       ` <CGME20231025133100eucas1p14e6de58e52560d165bdb8b809e406278@eucms1p4>
2023-11-02 10:35         ` Mateusz Majewski
2023-11-06  9:19           ` Lukasz Luba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2c4b6c1b-b9e7-42b2-8f7b-446ebe9d15ac@arm.com \
    --to=lukasz.luba@arm.com \
    --cc=alim.akhtar@samsung.com \
    --cc=amitk@kernel.org \
    --cc=broonie@kernel.org \
    --cc=bzolnier@gmail.com \
    --cc=daniel.lezcano@linaro.org \
    --cc=krzysztof.kozlowski@linaro.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=m.majewski2@samsung.com \
    --cc=m.szyprowski@samsung.com \
    --cc=rafael@kernel.org \
    --cc=rui.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®