git: e8f8b17c3018 - main - rk_pinctrl: Fix the drive strength of the RK3568 pins

From: Emmanuel Vadot <manu_at_FreeBSD.org>
Date: Thu, 29 Oct 2026 16:01:44 UTC
The branch main has been updated by manu:

URL: https://cgit.FreeBSD.org/src/commit/?id=e8f8b17c30184687e3f6dd02a72345bcad7e92aa

commit e8f8b17c30184687e3f6dd02a72345bcad7e92aa
Author:     Emmanuel Vadot <manu@FreeBSD.org>
AuthorDate: 2026-10-27 14:27:57 +0000
Commit:     Emmanuel Vadot <manu@FreeBSD.org>
CommitDate: 2026-10-29 16:00:38 +0000

    rk_pinctrl: Fix the drive strength of the RK3568 pins
    
    The drive strength of the RK3568 pins was never programmed.  The drive-strength
    property was tested with OF_getencprop() == 0 but that function returns the
    size of the property on success, so the branch was dead code and the pins kept
    whatever the previous stage of the boot left in the registers.
    
    The register layout was also wrong: each pin has an 8 bits wide drive field
    and a register holds two pins, but the value was shifted by pin % 2 bits
    instead of (pin % 2) * 8 and the mask only covered six bits.  An odd pin would
    have overwritten part of the field of the even pin next to it.
    
    Test the size of the property, put the field at (pin % 2) * 8 and write the
    whole 8 bits, like Linux does.
    
    Tested on a Quartz64 Model A and on a NanoPi R5S.
    
    Reviewed by:    mmel
---
 sys/arm64/rockchip/rk_pinctrl.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sys/arm64/rockchip/rk_pinctrl.c b/sys/arm64/rockchip/rk_pinctrl.c
index cbe7f29937cb..027e6a79266f 100644
--- a/sys/arm64/rockchip/rk_pinctrl.c
+++ b/sys/arm64/rockchip/rk_pinctrl.c
@@ -1182,15 +1182,16 @@ rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, uint32_t *pindata)
 	    "rockchip,rk3568-pinctrl")) {
 		uint32_t value;
 		if (OF_getencprop(pin_conf, "drive-strength", &value,
-		    sizeof(value)) == 0) {
+		    sizeof(value)) == sizeof(value)) {
 			if (bank)
 				reg = 0x01c0 + (bank * 0x40) + (pin / 2 * 4);
 			else
 				reg = 0x0070 + (pin / 2 * 4);
 
-			drive = ((1 << (value + 1)) - 1) << (pin % 2);
-
-			mask = 0x3f << (pin % 2);
+			/* Each pin has an 8 bits field, two pins per register */
+			bit = (pin % 2) * 8;
+			drive = ((1 << (value + 1)) - 1) << bit;
+			mask = 0xff << bit;
 
 			SYSCON_WRITE_4(syscon, reg, drive | (mask << 16));
 		}