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) {