Module Name:    src
Committed By:   jmcneill
Date:           Fri Nov 12 22:53:21 UTC 2021

Modified Files:
        src/sys/arch/arm/rockchip: rk3288_iomux.c

Log Message:
Fix register accesses to PMU registers. Unlike the GRF ones, a RMW cycle
is required to update settings here.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/rockchip/rk3288_iomux.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/rockchip/rk3288_iomux.c
diff -u src/sys/arch/arm/rockchip/rk3288_iomux.c:1.1 src/sys/arch/arm/rockchip/rk3288_iomux.c:1.2
--- src/sys/arch/arm/rockchip/rk3288_iomux.c:1.1	Fri Nov 12 22:02:08 2021
+++ src/sys/arch/arm/rockchip/rk3288_iomux.c	Fri Nov 12 22:53:20 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: rk3288_iomux.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $ */
+/* $NetBSD: rk3288_iomux.c,v 1.2 2021/11/12 22:53:20 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk3288_iomux.c,v 1.1 2021/11/12 22:02:08 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk3288_iomux.c,v 1.2 2021/11/12 22:53:20 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -84,6 +84,8 @@ struct rk3288_iomux_reg {
 	syscon_read_4((reg)->syscon, (off))
 #define	WR4(reg, off, val)	\
 	syscon_write_4((reg)->syscon, (off), (val))
+#define	ISPMU(sc, reg)		\
+	((reg)->syscon == (sc)->sc_pmu)
 
 static int	rk3288_iomux_match(device_t, cfdata_t, void *);
 static void	rk3288_iomux_attach(device_t, device_t, void *);
@@ -178,17 +180,13 @@ rk3288_iomux_set_bias(struct rk3288_iomu
 		return;
 	}
 
-	val = GPIO_P_CTL_MASK << (reg->pull_bit + 16);
+	if (ISPMU(sc, reg)) {
+		val = RD4(reg, reg->pull_reg);
+		val &= ~(GPIO_P_CTL_MASK << reg->pull_bit);
+	} else {
+		val = GPIO_P_CTL_MASK << (reg->pull_bit + 16);
+	}
 	val |= p << reg->pull_bit;
-
-#ifdef RK3288_IOMUX_DEBUG
-	const uint32_t oval = RD4(reg, reg->pull_reg);
-	printf("%s: wr %#x -> %#x (%#x)\n", __func__,
-	    oval & (GPIO_P_CTL_MASK << reg->pull_bit),
-	    val & 0xffff,
-	    GPIO_P_CTL_MASK << reg->pull_bit);
-#endif
-
 	WR4(reg, reg->pull_reg, val);
 }
 
@@ -216,8 +214,13 @@ rk3288_iomux_set_drive_strength(struct r
 		return;
 	}
 
-	val = GPIO_E_CTL_MASK << (reg->drv_bit + 16);
-	val |= e << reg->drv_bit;
+	if (ISPMU(sc, reg)) {
+		val = RD4(reg, reg->drv_reg);
+		val &= ~(GPIO_E_CTL_MASK << reg->drv_bit);
+	} else {
+		val = GPIO_E_CTL_MASK << (reg->drv_bit + 16);
+	}
+	val = e << reg->drv_bit;
 	WR4(reg, reg->drv_reg, val);
 }
 
@@ -229,9 +232,14 @@ rk3288_iomux_set_mux(struct rk3288_iomux
 
 	KASSERT(reg->mux_reg != -1);
 
-	val = ((reg->flags & IOMUX_4BIT) ? 0xf : 0x3) << (reg->mux_bit + 16);
+	const uint32_t mask = (reg->flags & IOMUX_4BIT) ? 0xf : 0x3;
+	if (ISPMU(sc, reg)) {
+		val = RD4(reg, reg->mux_reg);
+		val &= ~(mask << reg->mux_bit);
+	} else {
+		val = mask << (reg->mux_bit + 16);
+	}
 	val |= mux << reg->mux_bit;
-
 	WR4(reg, reg->mux_reg, val);
 }
 
@@ -254,14 +262,6 @@ rk3288_iomux_config(struct rk3288_iomux_
 	printf("     bias %d drv %d mux %u\n", bias, drv, mux);
 #endif
 
-	/* XXX
-	 * ASUS Tinkerboard goes nuts if we update any PMU bias fields.
-	 * Skip them until we figure out why.
-	 */
-	if (reg->syscon == sc->sc_pmu) {
-		bias = -1;
-	}
-
 	LOCK(reg);
 
 	if (bias != -1) {

Reply via email to