lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20251013-hiword-rockchip-dfi-v1-1-4f2a63098553@collabora.com>
Date: Mon, 13 Oct 2025 09:34:04 +0200
From: Nicolas Frattaroli <nicolas.frattaroli@...labora.com>
To: Yury Norov <yury.norov@...il.com>, Chanwoo Choi <cw00.choi@...sung.com>, 
 MyungJoo Ham <myungjoo.ham@...sung.com>, 
 Kyungmin Park <kyungmin.park@...sung.com>, Heiko Stuebner <heiko@...ech.de>
Cc: kernel@...labora.com, linux-pm@...r.kernel.org, 
 linux-arm-kernel@...ts.infradead.org, linux-rockchip@...ts.infradead.org, 
 linux-kernel@...r.kernel.org, 
 Nicolas Frattaroli <nicolas.frattaroli@...labora.com>
Subject: [PATCH] PM / devfreq: rockchip-dfi: switch to FIELD_PREP_WM16
 macro

The era of hand-rolled HIWORD_UPDATE macros is over, at least for those
drivers that use constant masks.

Like many other Rockchip drivers, rockchip-dfi brings with it its own
HIWORD_UPDATE macro. This variant doesn't shift the value (and like the
others, doesn't do any checking).

Remove it, and replace instances of it with hw_bitfield.h's
FIELD_PREP_WM16.  Since FIELD_PREP_WM16 requires contiguous masks and
shifts the value for us, some reshuffling of definitions needs to
happen.

This gives us better compile-time error checking, and in my opinion,
nicer code.

Tested on an RK3568 ODROID-M1 board (LPDDR4X at 1560 MHz, an RK3588
Radxa ROCK 5B board (LPDDR4X at 2112 MHz) and an RK3588 Radxa ROCK 5T
board (LPDDR5 at 2400 MHz). perf measurements were consistent with the
measurements of stress-ng --stream in all cases.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@...labora.com>
---
Hi Yury,

as promised[1], here's the follow-up patch to move rockchip-dfi to the
new FIELD_PREP_WM16 macro after the LPDDR5 changes, which caused a
conflict during the last merge window.

I've re-tested it on three boards, as outlined in the commit message.

Link: https://lore.kernel.org/all/14358105.O9o76ZdvQC@workhorse/t/#m6b5b01cb30a04745ea3167a660b4794c608f387b [1]
---
 drivers/devfreq/event/rockchip-dfi.c | 45 ++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index 5a2c9badcc64..5e6e7e900bda 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -20,6 +20,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/bitfield.h>
+#include <linux/hw_bitfield.h>
 #include <linux/bits.h>
 #include <linux/perf_event.h>
 
@@ -30,8 +31,6 @@
 
 #define DMC_MAX_CHANNELS	4
 
-#define HIWORD_UPDATE(val, mask)	((val) | (mask) << 16)
-
 /* DDRMON_CTRL */
 #define DDRMON_CTRL	0x04
 #define DDRMON_CTRL_LPDDR5		BIT(6)
@@ -41,10 +40,6 @@
 #define DDRMON_CTRL_LPDDR23		BIT(2)
 #define DDRMON_CTRL_SOFTWARE_EN		BIT(1)
 #define DDRMON_CTRL_TIMER_CNT_EN	BIT(0)
-#define DDRMON_CTRL_DDR_TYPE_MASK	(DDRMON_CTRL_LPDDR5 | \
-					 DDRMON_CTRL_DDR4 | \
-					 DDRMON_CTRL_LPDDR4 | \
-					 DDRMON_CTRL_LPDDR23)
 #define DDRMON_CTRL_LP5_BANK_MODE_MASK	GENMASK(8, 7)
 
 #define DDRMON_CH0_WR_NUM		0x20
@@ -124,27 +119,31 @@ struct rockchip_dfi {
 	unsigned int count_multiplier;	/* number of data clocks per count */
 };
 
-static int rockchip_dfi_ddrtype_to_ctrl(struct rockchip_dfi *dfi, u32 *ctrl,
-					u32 *mask)
+static int rockchip_dfi_ddrtype_to_ctrl(struct rockchip_dfi *dfi, u32 *ctrl)
 {
 	u32 ddrmon_ver;
 
-	*mask = DDRMON_CTRL_DDR_TYPE_MASK;
-
 	switch (dfi->ddr_type) {
 	case ROCKCHIP_DDRTYPE_LPDDR2:
 	case ROCKCHIP_DDRTYPE_LPDDR3:
-		*ctrl = DDRMON_CTRL_LPDDR23;
+		*ctrl = FIELD_PREP_WM16(DDRMON_CTRL_LPDDR23, 1) |
+			FIELD_PREP_WM16(DDRMON_CTRL_LPDDR4, 0) |
+			FIELD_PREP_WM16(DDRMON_CTRL_LPDDR5, 0);
 		break;
 	case ROCKCHIP_DDRTYPE_LPDDR4:
 	case ROCKCHIP_DDRTYPE_LPDDR4X:
-		*ctrl = DDRMON_CTRL_LPDDR4;
+		*ctrl = FIELD_PREP_WM16(DDRMON_CTRL_LPDDR23, 0) |
+			FIELD_PREP_WM16(DDRMON_CTRL_LPDDR4, 1) |
+			FIELD_PREP_WM16(DDRMON_CTRL_LPDDR5, 0);
 		break;
 	case ROCKCHIP_DDRTYPE_LPDDR5:
 		ddrmon_ver = readl_relaxed(dfi->regs);
 		if (ddrmon_ver < 0x40) {
-			*ctrl = DDRMON_CTRL_LPDDR5 | dfi->lp5_bank_mode;
-			*mask |= DDRMON_CTRL_LP5_BANK_MODE_MASK;
+			*ctrl = FIELD_PREP_WM16(DDRMON_CTRL_LPDDR23, 0) |
+				FIELD_PREP_WM16(DDRMON_CTRL_LPDDR4, 0) |
+				FIELD_PREP_WM16(DDRMON_CTRL_LPDDR5, 1) |
+				FIELD_PREP_WM16(DDRMON_CTRL_LP5_BANK_MODE_MASK,
+						dfi->lp5_bank_mode);
 			break;
 		}
 
@@ -172,7 +171,6 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
 	void __iomem *dfi_regs = dfi->regs;
 	int i, ret = 0;
 	u32 ctrl;
-	u32 ctrl_mask;
 
 	mutex_lock(&dfi->mutex);
 
@@ -186,7 +184,7 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
 		goto out;
 	}
 
-	ret = rockchip_dfi_ddrtype_to_ctrl(dfi, &ctrl, &ctrl_mask);
+	ret = rockchip_dfi_ddrtype_to_ctrl(dfi, &ctrl);
 	if (ret)
 		goto out;
 
@@ -196,15 +194,16 @@ static int rockchip_dfi_enable(struct rockchip_dfi *dfi)
 			continue;
 
 		/* clear DDRMON_CTRL setting */
-		writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_TIMER_CNT_EN |
-			       DDRMON_CTRL_SOFTWARE_EN | DDRMON_CTRL_HARDWARE_EN),
+		writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_TIMER_CNT_EN, 0) |
+			       FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 0) |
+			       FIELD_PREP_WM16(DDRMON_CTRL_HARDWARE_EN, 0),
 			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
 
-		writel_relaxed(HIWORD_UPDATE(ctrl, ctrl_mask),
-			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
+		writel_relaxed(ctrl, dfi_regs + i * dfi->ddrmon_stride +
+			       DDRMON_CTRL);
 
 		/* enable count, use software mode */
-		writel_relaxed(HIWORD_UPDATE(DDRMON_CTRL_SOFTWARE_EN, DDRMON_CTRL_SOFTWARE_EN),
+		writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 1),
 			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
 
 		if (dfi->ddrmon_ctrl_single)
@@ -234,8 +233,8 @@ static void rockchip_dfi_disable(struct rockchip_dfi *dfi)
 		if (!(dfi->channel_mask & BIT(i)))
 			continue;
 
-		writel_relaxed(HIWORD_UPDATE(0, DDRMON_CTRL_SOFTWARE_EN),
-			      dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
+		writel_relaxed(FIELD_PREP_WM16(DDRMON_CTRL_SOFTWARE_EN, 0),
+			       dfi_regs + i * dfi->ddrmon_stride + DDRMON_CTRL);
 
 		if (dfi->ddrmon_ctrl_single)
 			break;

---
base-commit: cb6649f6217c0331b885cf787f1d175963e2a1d2
change-id: 20251013-hiword-rockchip-dfi-41060f664820

Best regards,
-- 
Nicolas Frattaroli <nicolas.frattaroli@...labora.com>


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ