From 0c68b88ce574ddaa2f94f3e5d747c25db693dc18 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 3 Aug 2026 18:43:12 +0000 Subject: [PATCH 1/2] include: linux: Import hw_bitfield.h from Linux v6.18 Hardware of various vendors, but very notably Rockchip, often uses 32-bit registers where the upper 16-bit half of the register is a write-enable mask for the lower half. Add hw_bitfield.h with two macros: FIELD_PREP_WM16, and FIELD_PREP_WM16_CONST. The latter is a version that can be used in initializers, like FIELD_PREP_CONST. Import hw_bitfield.h from Linux commit 21368fcbb124 ("bitmap: introduce hardware-specific bitfield operations"), first introduced in v6.18-rc1. This contains two changes compared to the Linux version: - include of linux/limit.h was dropped - use of const_true() in FIELD_PREP_WM16_CONST() was dropped Signed-off-by: Jonas Karlman Acked-by: Quentin Schulz Reviewed-by: Tom Rini Link: https://patch.msgid.link/20260803184314.2240153-2-jonas@kwiboo.se Signed-off-by: Quentin Schulz --- include/linux/hw_bitfield.h | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 include/linux/hw_bitfield.h diff --git a/include/linux/hw_bitfield.h b/include/linux/hw_bitfield.h new file mode 100644 index 00000000000..6e74d902ed3 --- /dev/null +++ b/include/linux/hw_bitfield.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2025, Collabora Ltd. + */ + +#ifndef _LINUX_HW_BITFIELD_H +#define _LINUX_HW_BITFIELD_H + +#include +#include + +/** + * FIELD_PREP_WM16() - prepare a bitfield element with a mask in the upper half + * @_mask: shifted mask defining the field's length and position + * @_val: value to put in the field + * + * FIELD_PREP_WM16() masks and shifts up the value, as well as bitwise ORs the + * result with the mask shifted up by 16. + * + * This is useful for a common design of hardware registers where the upper + * 16-bit half of a 32-bit register is used as a write-enable mask. In such a + * register, a bit in the lower half is only updated if the corresponding bit + * in the upper half is high. + */ +#define FIELD_PREP_WM16(_mask, _val) \ + ({ \ + typeof(_val) __val = _val; \ + typeof(_mask) __mask = _mask; \ + __BF_FIELD_CHECK(__mask, ((u16)0U), __val, \ + "HWORD_UPDATE: "); \ + (((typeof(__mask))(__val) << __bf_shf(__mask)) & (__mask)) | \ + ((__mask) << 16); \ + }) + +/** + * FIELD_PREP_WM16_CONST() - prepare a constant bitfield element with a mask in + * the upper half + * @_mask: shifted mask defining the field's length and position + * @_val: value to put in the field + * + * FIELD_PREP_WM16_CONST() masks and shifts up the value, as well as bitwise ORs + * the result with the mask shifted up by 16. + * + * This is useful for a common design of hardware registers where the upper + * 16-bit half of a 32-bit register is used as a write-enable mask. In such a + * register, a bit in the lower half is only updated if the corresponding bit + * in the upper half is high. + * + * Unlike FIELD_PREP_WM16(), this is a constant expression and can therefore + * be used in initializers. Error checking is less comfortable for this + * version. + */ +#define FIELD_PREP_WM16_CONST(_mask, _val) \ + ( \ + FIELD_PREP_CONST(_mask, _val) | \ + (BUILD_BUG_ON_ZERO((u64)(_mask) > U16_MAX) + \ + ((_mask) << 16)) \ + ) + + +#endif /* _LINUX_HW_BITFIELD_H */ From c8cac405f29896362786c7ced1417fd15e7b8923 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Mon, 3 Aug 2026 18:43:13 +0000 Subject: [PATCH 2/2] rockchip: rk3576: Disable force_jtag by default Rockchip SoCs can automatically switch between jtag and sdmmc based on the following rules: - all the SDMMC pins including SDMMC_DET set as SDMMC function in GRF, - force_jtag bit in GRF is 1, - SDMMC_DET is low (no card detected), Note that the BootROM may mux all SDMMC pins in their SDMMC function or not, depending on the boot medium that were tried. Because SDMMC_DET pin is not guaranteed to be used as an SD card card detect pin, it could be low at boot or even switch at runtime, which would enable the jtag function and render the SD card unusable. Or boards using cd-gpios may switch the SDMMC_DET pin to GPIO function, which would enable the jtag function and render the SD card unusable. With commit d0a838bdc629 ("Subtree merge tag 'v7.1-dts' of dts repo [1] into dts/upstream") there are now RK3576 boards that have changed to use cd-gpios for the SDMMC_DET pin, e.g. NanoPi R76S, that may have issues detecting SD card unless force_jtag is disabled. Signed-off-by: Jonas Karlman Reviewed-by: Quentin Schulz Link: https://patch.msgid.link/20260803184314.2240153-3-jonas@kwiboo.se Signed-off-by: Quentin Schulz --- arch/arm/mach-rockchip/rk3576/rk3576.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/rk3576/rk3576.c b/arch/arm/mach-rockchip/rk3576/rk3576.c index e3e93f66395..76119cdb1ae 100644 --- a/arch/arm/mach-rockchip/rk3576/rk3576.c +++ b/arch/arm/mach-rockchip/rk3576/rk3576.c @@ -9,7 +9,8 @@ #include #include #include -#include +#include +#include #define SYS_GRF_BASE 0x2600A000 #define SYS_GRF_SOC_CON2 0x0008 @@ -21,6 +22,10 @@ #define GPIO0B_PULL_L 0x0024 #define GPIO0B_IE_L 0x002C +#define TOP_IOC_BASE 0x26044000 +#define IOC_MISC_CON 0x00F0 +#define TOP_IOC_FORCE_JTAG BIT(1) + #define SYS_SGRF_BASE 0x26004000 #define SYS_SGRF_SOC_CON14 0x0058 #define SYS_SGRF_SOC_CON15 0x005C @@ -190,6 +195,11 @@ int arch_cpu_init(void) */ writel(0xffffff00, SYS_SGRF_BASE + SYS_SGRF_SOC_CON20); + /* Disable JTAG exposed on SDMMC pins (GPIO2A2 and GPIO2A3) */ + if (IS_ENABLED(CONFIG_ROCKCHIP_DISABLE_FORCE_JTAG)) + writel(FIELD_PREP_WM16(TOP_IOC_FORCE_JTAG, 0), + TOP_IOC_BASE + IOC_MISC_CON); + /* Disable USB3OTG0 U3 port, later enabled by USBDP PHY driver */ writel(0xffff0188, USB_GRF_BASE + USB3OTG0_CON1);