* [PATCH v4 4/4] MAINTAINERS: add entry for TAS67524 audio amplifier
From: Sen Wang @ 2026-04-08 5:31 UTC (permalink / raw)
To: linux-sound
Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, devicetree, perex,
tiwai, shenghao-ding, kevin-lu, baojun.xu, niranjan.hy,
l-badrinarayanan, devarsht, v-singh1, linux-kernel, sen
In-Reply-To: <20260408053149.1369350-1-sen@ti.com>
Add Sen Wang as maintainer and register file patterns for the newly
added TAS67524 amplifier driver.
Signed-off-by: Sen Wang <sen@ti.com>
---
MAINTAINERS | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index a626dee5c106..a78b6cb9b907 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26191,17 +26191,20 @@ TEXAS INSTRUMENTS AUDIO (ASoC/HDA) DRIVERS
M: Shenghao Ding <shenghao-ding@ti.com>
M: Kevin Lu <kevin-lu@ti.com>
M: Baojun Xu <baojun.xu@ti.com>
+M: Sen Wang <sen@ti.com>
L: linux-sound@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/sound/ti,tas2552.yaml
F: Documentation/devicetree/bindings/sound/ti,tas2562.yaml
F: Documentation/devicetree/bindings/sound/ti,tas2770.yaml
F: Documentation/devicetree/bindings/sound/ti,tas27xx.yaml
+F: Documentation/devicetree/bindings/sound/ti,tas67524.yaml
F: Documentation/devicetree/bindings/sound/ti,tpa6130a2.yaml
F: Documentation/devicetree/bindings/sound/ti,pcm1681.yaml
F: Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml
F: Documentation/devicetree/bindings/sound/ti,tlv320*.yaml
F: Documentation/devicetree/bindings/sound/ti,tlv320adcx140.yaml
+F: Documentation/sound/codecs/tas675x*
F: include/sound/tas2*.h
F: include/sound/tlv320*.h
F: sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
@@ -26215,6 +26218,7 @@ F: sound/soc/codecs/pcm3168a*.*
F: sound/soc/codecs/pcm5102a.c
F: sound/soc/codecs/pcm512x*.*
F: sound/soc/codecs/tas2*.*
+F: sound/soc/codecs/tas675x*.*
F: sound/soc/codecs/tlv320*.*
F: sound/soc/codecs/tpa6130a2.*
--
2.43.0
^ permalink raw reply related
* [PATCH v4 1/4] ASoC: dt-bindings: Add ti,tas67524
From: Sen Wang @ 2026-04-08 5:31 UTC (permalink / raw)
To: linux-sound
Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, devicetree, perex,
tiwai, shenghao-ding, kevin-lu, baojun.xu, niranjan.hy,
l-badrinarayanan, devarsht, v-singh1, linux-kernel, sen
In-Reply-To: <20260408053149.1369350-1-sen@ti.com>
Add device tree binding for the Texas Instruments TAS67524 family
of four-channel Class-D audio amplifiers with integrated DSP.
Signed-off-by: Sen Wang <sen@ti.com>
---
Changes in v4:
- Corrected ti,tas6754 compatible with a fallback of ti,tas67524
- Corrected comment spacing
Changes in v3:
- Renamed ti,tas675x to ti,tas67524.yaml
- Removed tas6754 compatible instance
- Changed pd-gpios to powerdown-gpios
- Cleanup unnessary "|" formatting
Changes in v2:
- None
.../bindings/sound/ti,tas67524.yaml | 280 ++++++++++++++++++
1 file changed, 280 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/ti,tas67524.yaml
diff --git a/Documentation/devicetree/bindings/sound/ti,tas67524.yaml b/Documentation/devicetree/bindings/sound/ti,tas67524.yaml
new file mode 100644
index 000000000000..812a4d39e2a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ti,tas67524.yaml
@@ -0,0 +1,280 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/ti,tas67524.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments TAS67524 Audio Amplifier
+
+maintainers:
+ - Sen Wang <sen@ti.com>
+
+description:
+ The TAS67524 is a four-channel, digital-input, automotive
+ Class-D audio amplifier with load diagnostics and an integrated
+ DSP for audio processing.
+
+allOf:
+ - $ref: dai-common.yaml#
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - ti,tas6754
+ - const: ti,tas67524
+ - const: ti,tas67524
+
+ reg:
+ maxItems: 1
+
+ '#sound-dai-cells':
+ const: 1
+ description: |
+ The device exposes three DAIs, selected by index.
+ 0 - Standard Audio Path (Playback)
+ 1 - Low-Latency Playback Path (Playback)
+ 2 - Sensory Feedback (Capture - Vpredict and Isense)
+ By default, all four channels of each DAI are active.
+
+ interrupts:
+ maxItems: 1
+ description:
+ Active-low falling-edge interrupt from the FAULT pin. When provided,
+ the driver uses IRQ-driven fault reporting instead of polling.
+
+ powerdown-gpios:
+ maxItems: 1
+ description:
+ GPIO connected to the PD pin, active low. Controls the internal
+ digital circuitry power state. When asserted the device enters
+ full power-down mode and all register state is lost. Can be omitted if
+ PD pin is hardwired or externally controlled.
+
+ standby-gpios:
+ maxItems: 1
+ description:
+ GPIO connected to the STBY pin, active low. Controls the analog
+ power stage. When asserted the device enters Deep Sleep mode but
+ remains I2C-accessible with registers retained. Can be omitted if
+ STBY pin is tied to PD or hardwired.
+
+ dvdd-supply:
+ description:
+ Digital logic supply (1.62 V to 3.6 V). All three supply rails must
+ be within their recommended operating ranges before the PD pin is
+ released.
+
+ pvdd-supply:
+ description:
+ Output FET power supply (4.5 V to 19 V). All three supply rails must
+ be within their recommended operating ranges before the PD pin is
+ released.
+
+ vbat-supply:
+ description:
+ Battery supply for the Class-D output stage (4.5 V to 19 V). Optional
+ when PVDD and VBAT are connected to the same supply rail. When absent,
+ VBAT is assumed hardwired to PVDD.
+
+ ti,fast-boot:
+ type: boolean
+ description:
+ Skip DC load diagnostic sweep at power-on to reduce boot latency.
+ Automatic diagnostics after fault conditions remain enabled. Hardware
+ overcurrent protection is always active.
+
+ ti,audio-slot-no:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ TDM slot offset for the standard audio playback path via SDIN1. A value
+ of 4 maps to slot 4. If omitted, slot assignment is derived from the
+ tx_mask provided via set_tdm_slot(). Without either property, no slot
+ mapping is configured.
+
+ ti,llp-slot-no:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ TDM slot offset for the low-latency playback path via SDIN1. If omitted,
+ slot assignment is derived from the tx_mask provided via set_tdm_slot().
+ Without either property, no slot mapping is configured. Disabled outside
+ of LLP mode, and only relevant for TDM formats.
+
+ ti,vpredict-slot-no:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ In TDM mode, enables Vpredict output and assigns its starting slot;
+ four consecutive slots carry Vpredict Ch1-4 on SDOUT1. May coexist
+ with ti,isense-slot-no using separate non-overlapping slots.
+
+ In I2S mode, enables Vpredict output on SDOUT1 (Ch1/Ch2) and SDOUT2
+ (Ch3/Ch4). The slot value is unused. Requires a GPIO configured as
+ sdout2 for Ch3/Ch4; without it only Ch1/Ch2 are output. Mutually
+ exclusive with ti,isense-slot-no; if both are set, Vpredict takes
+ priority.
+
+ Irrelevant in Left-J and Right-J modes.
+
+ ti,isense-slot-no:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ In TDM mode, enables Isense output and assigns its starting slot;
+ four consecutive slots carry Isense Ch1-4 on SDOUT1. May coexist
+ with ti,vpredict-slot-no using separate non-overlapping slots.
+
+ In I2S mode, enables Isense output on SDOUT1 (Ch1/Ch2) and SDOUT2
+ (Ch3/Ch4). The slot value is unused. Requires a GPIO configured as
+ SDOUT2 for Ch3/Ch4; without it only Ch1/Ch2 are output. Mutually
+ exclusive with ti,vpredict-slot-no; Vpredict takes priority if both
+ are set.
+
+ Irrelevant in Left-J and Right-J modes.
+
+ ti,gpio1-function:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ Function for the GPIO_1 pin. When omitted, GPIO_1 remains in its
+ power-on default state.
+ enum:
+ - low # Output: driven low
+ - auto-mute # Output: high when all channels are auto-muted
+ - auto-mute-ch4 # Output: high when channel 4 is auto-muted
+ - auto-mute-ch3 # Output: high when channel 3 is auto-muted
+ - auto-mute-ch2 # Output: high when channel 2 is auto-muted
+ - auto-mute-ch1 # Output: high when channel 1 is auto-muted
+ - sdout2 # Output: Routes secondary serial data output 2
+ - sdout1 # Output: Re-routes secondary serial data output 1
+ - warn # Output: warning signal (OTW, CBC)
+ - fault # Output: fault signal (OTSD, OC, DC)
+ - clock-sync # Output: clock synchronisation
+ - invalid-clock # Output: high when clock is invalid
+ - high # Output: driven high
+ - mute # Input: external mute control
+ - phase-sync # Input: phase synchronisation
+ - sdin2 # Input: secondary SDIN2 for I2S/LJ/RJ ch3/ch4
+ - deep-sleep # Input: asserted transitions device to Deep Sleep
+ - hiz # Input: asserted transitions device to Hi-Z
+ - play # Input: asserted transitions device to Play
+ - sleep # Input: asserted transitions device to Sleep
+
+ ti,gpio2-function:
+ $ref: /schemas/types.yaml#/definitions/string
+ description:
+ Function for the GPIO_2 pin. When omitted, GPIO_2 remains in its
+ power-on default state.
+ enum:
+ - low # Output: driven low
+ - auto-mute # Output: high when all channels are auto-muted
+ - auto-mute-ch4 # Output: high when channel 4 is auto-muted
+ - auto-mute-ch3 # Output: high when channel 3 is auto-muted
+ - auto-mute-ch2 # Output: high when channel 2 is auto-muted
+ - auto-mute-ch1 # Output: high when channel 1 is auto-muted
+ - sdout2 # Output: Routes secondary serial data output 2
+ - sdout1 # Output: Re-routes secondary serial data output 1
+ - warn # Output: warning signal (OTW, CBC)
+ - fault # Output: fault signal (OTSD, OC, DC)
+ - clock-sync # Output: clock synchronisation
+ - invalid-clock # Output: high when clock is invalid
+ - high # Output: driven high
+ - mute # Input: external mute control
+ - phase-sync # Input: phase synchronisation
+ - sdin2 # Input: secondary SDIN2 for I2S/LJ/RJ ch3/ch4
+ - deep-sleep # Input: asserted transitions device to Deep Sleep
+ - hiz # Input: asserted transitions device to Hi-Z
+ - play # Input: asserted transitions device to Play
+ - sleep # Input: asserted transitions device to Sleep
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+ properties:
+ port@0:
+ $ref: audio-graph-port.yaml#
+ unevaluatedProperties: false
+ description: Standard audio playback port (DAI 0).
+
+ port@1:
+ $ref: audio-graph-port.yaml#
+ unevaluatedProperties: false
+ description: Low-latency playback port (LLP) (DAI 1).
+
+ port@2:
+ $ref: audio-graph-port.yaml#
+ unevaluatedProperties: false
+ description: Sensory feedback capture port (DAI 2).
+
+ port:
+ $ref: audio-graph-port.yaml#
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - '#sound-dai-cells'
+ - dvdd-supply
+ - pvdd-supply
+
+anyOf:
+ - required: [powerdown-gpios]
+ - required: [standby-gpios]
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ amplifier@70 {
+ compatible = "ti,tas67524";
+ reg = <0x70>;
+ #sound-dai-cells = <1>;
+ sound-name-prefix = "TAS0";
+
+ standby-gpios = <&main_gpio0 33 GPIO_ACTIVE_LOW>;
+
+ dvdd-supply = <&dvdd_1v8>;
+ pvdd-supply = <&pvdd_12v>;
+ vbat-supply = <&vbat_12v>;
+
+ ti,audio-slot-no = <0>;
+ ti,llp-slot-no = <4>;
+ ti,vpredict-slot-no = <0>;
+ ti,isense-slot-no = <4>;
+
+ ti,gpio2-function = "warn";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tas0_audio_ep: endpoint {
+ dai-format = "dsp_b";
+ remote-endpoint = <&be_tas0_audio_ep>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tas0_anc_ep: endpoint {
+ remote-endpoint = <&be_tas0_anc_ep>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+
+ tas0_fb_ep: endpoint {
+ remote-endpoint = <&be_tas0_fb_ep>;
+ };
+ };
+ };
+ };
+ };
--
2.43.0
^ permalink raw reply related
* [PATCH v4 0/4] ASoC: Add TAS67524 quad-channel Class-D amplifier driver
From: Sen Wang @ 2026-04-08 5:31 UTC (permalink / raw)
To: linux-sound
Cc: broonie, lgirdwood, robh, krzk+dt, conor+dt, devicetree, perex,
tiwai, shenghao-ding, kevin-lu, baojun.xu, niranjan.hy,
l-badrinarayanan, devarsht, v-singh1, linux-kernel, sen
This series adds support for the TI TAS675x (TAS6754, TAS67524)
quad-channel automotive Class-D amplifiers. The devices have an
integrated DSP and load diagnostics, and are controlled over I2C.
Patch 1 adds the dt-binding, patch 2 the codec driver, patch 3 the
ALSA mixer controls documentation, and patch 4 adds the MAINTAINERS
entry.
Tested on AM62D-EVM with a TAS67CD-AEC daughter card. For setup &
test procedures, refer to the GitHub repository.
GitHub: https://github.com/SenWang125/tas67-linux
Changes in v4:
- Corrected dt-binding compatibles (1/4)
- Reverted v3's change and made tas67524.c back to tas675x.c (2/4)
- Links to v3: https://lore.kernel.org/all/20260403050627.635591-1-sen@ti.com/
Changes in v3:
- Renamed ALL tas675x filenames to tas67524, removed tas6754 compatible instance
- Changed pd-gpios to powerdown-gpios, cleanup unnessary .yaml formatting (1/4)
- Opt to use disable delayed_work and re-enable on runtime suspend/resume,
similarly, use disable/enable IRQ on system suspend/resume. (2/4)
- Include IRQ_NONE on ISR returns. (2/4)
- Clarify _check_faults() function which now returns need_clear boolean (2/4)
- Added register section (3/4)
- Added addintional notes: for clarification (3/4)
- Links to v2: https://lore.kernel.org/all/20260401223239.1638881-1-sen@ti.com/
Changes in v2:
- Remove redundant DAPM event function (2/4)
- Move IRQ request past power_on, so regs can be set in a clean state (2/4)
- Add delayed_work at probe time to accomdate no PM configs (2/4)
- Change .set_fmt and .dapm_routes callbacks to the same tas675x_set_fmt name (2/4)
- Links to v1: https://lore.kernel.org/all/20260401024210.28542-1-sen@ti.com/
Sen Wang (4):
ASoC: dt-bindings: Add ti,tas67524
ASoC: codecs: Add TAS67524 quad-channel audio amplifier driver
Documentation: sound: Add TAS675x codec mixer controls documentation
MAINTAINERS: add entry for TAS67524 audio amplifier
.../bindings/sound/ti,tas67524.yaml | 280 +++
Documentation/sound/codecs/index.rst | 1 +
Documentation/sound/codecs/tas675x.rst | 686 ++++++
MAINTAINERS | 4 +
sound/soc/codecs/Kconfig | 11 +
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/tas675x.c | 2172 +++++++++++++++++
sound/soc/codecs/tas675x.h | 367 +++
8 files changed, 3523 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/ti,tas67524.yaml
create mode 100644 Documentation/sound/codecs/tas675x.rst
create mode 100644 sound/soc/codecs/tas675x.c
create mode 100644 sound/soc/codecs/tas675x.h
--
2.43.0
^ permalink raw reply
* Re: [PATCH v1 02/13] dt-bindings: clock: Add system-0 domain PLL clock
From: Changhuang Liang @ 2026-04-08 5:17 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Michael Turquette, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Stephen Boyd, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Philipp Zabel, Emil Renner Berthing, Chen Wang,
Inochi Amaoto, Alexey Charkov, Thomas Bogendoerfer, Keguang Zhang,
linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org,
devicetree@vger.kernel.org, linux-riscv@lists.infradead.org,
Leyfoon Tan
In-Reply-To: <5f2a1946-9ca7-414c-a764-60f46f3b3cf5@kernel.org>
Hi, Krzysztof
> On 07/04/2026 08:56, Changhuang Liang wrote:
> > Hi, Krzysztof
> >
> > Thanks for the review.
> >
> >> On Thu, Apr 02, 2026 at 10:49:34PM -0700, Changhuang Liang wrote:
> >>> Add system-0 domain PLL clock for StarFive JHB100 SoC.
> >>>
> >>> Signed-off-by: Changhuang Liang <changhuang.liang@starfivetech.com>
> >>> ---
> >>> .../bindings/clock/starfive,jhb100-pll.yaml | 44
> +++++++++++++++++++
> >>> .../dt-bindings/clock/starfive,jhb100-crg.h | 6 +++
> >>
> >> You did not test your code. Apply patch #1 and test it. Do you see
> >> build-level errors?
> >
> > I'm very sorry about this. I will reorganize my patch to avoid the related
> errors.
> >
>
> Anyway this one should be folded into the parent. You have one generic,
> system-wide clock as input, so as well this can be the resource of the parent.
> And no address spaces.
>
> Other examples have one-register address spaces, so these are not really
> separate devices.
Just to confirm with you again.
The current version of dts is as follows:
sys0_syscon: syscon@13010000 {
compatible = "starfive,jhb100-sys0-syscon", "syscon",
"simple-mfd";
reg = <0x0 0x13010000 0x0 0x2000>;
#address-cells = <2>;
#size-cells = <2>;
ranges = <0x0 0x0 0x0 0x13010000 0x0 0x2000>;
sys0pll: clock-controller {
compatible = "starfive,jhb100-sys0-pll";
clocks = <&osc>;
#clock-cells = <1>;
};
chipid@38 {
compatible = "starfive,jhb100-socinfo";
reg = <0x0 0x38 0x0 0x4>;
};
};
In the next version, it will be changed to this, correct?
sys0_syscon: syscon@13010000 {
compatible = "starfive,jhb100-sys0-syscon", "syscon";
reg = <0x0 0x13010000 0x0 0x2000>;
clocks = <&osc>;
#clock-cells = <1>;
};
Best Regards,
Changhuang
^ permalink raw reply
* [PATCH] clk: microchip: mpfs-ccc: fix out-of-bounds write
From: Aleš Pečnik via B4 Relay @ 2026-04-08 5:07 UTC (permalink / raw)
To: Conor Dooley, Daire McNamara, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski
Cc: linux-riscv, linux-clk, linux-kernel, devicetree,
Aleš Pečnik
From: Aleš Pečnik <ales.pecnik@skylabs.si>
Issue was allocated array size for clk_data.
When clocks are being registered their index is taken from defines in
dt-bindings. The last 2 clocks had their index outside of allocated range.
Two defines (CLK_CCC_DLL0, CLK_CCC_DLL1) were not used and skipped over
which was not taken into account when allocating the array.
This patch is minimal change to resolve the issue.
Issue was found using KASAN when debugging unrelated xdma driver issue.
Consequently fixing this issue also resolved xdma driver issue.
Related dmesg output:
[ 0.290703] BUG: KASAN: slab-out-of-bounds in mpfs_ccc_register_outputs.constprop.0+0xd0/0x1fa
[ 0.290984] Write of size 8 at addr ffffffe7be6e3ca8 by task swapper/0/1
[ 0.291253] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.1.43-linux4microchip+fpga-2023.09 #1
[ 0.291482] Hardware name: Skylabs HPC (DT)
[ 0.291611] Call Trace:
...
[ 0.292999] [<ffffffff808508c8>] mpfs_ccc_register_outputs.constprop.0+0xd0/0x1fa
[ 0.293245] [<ffffffff80850b66>] mpfs_ccc_probe+0x174/0x30e
[ 0.293437] [<ffffffff808d4af2>] platform_probe+0x74/0xba
...
Fixes: d39fb172760e ("clk: microchip: add PolarFire SoC fabric clock support")
Signed-off-by: Aleš Pečnik <ales.pecnik@skylabs.si>
---
drivers/clk/microchip/clk-mpfs-ccc.c | 3 +--
include/dt-bindings/clock/microchip,mpfs-clock.h | 2 ++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/microchip/clk-mpfs-ccc.c b/drivers/clk/microchip/clk-mpfs-ccc.c
index 3a3ea2d142f8..71fbb6265ea4 100644
--- a/drivers/clk/microchip/clk-mpfs-ccc.c
+++ b/drivers/clk/microchip/clk-mpfs-ccc.c
@@ -234,8 +234,7 @@ static int mpfs_ccc_probe(struct platform_device *pdev)
unsigned int num_clks;
int ret;
- num_clks = ARRAY_SIZE(mpfs_ccc_pll_clks) + ARRAY_SIZE(mpfs_ccc_pll0out_clks) +
- ARRAY_SIZE(mpfs_ccc_pll1out_clks);
+ num_clks = CLK_CCC_NUM;
clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hw_data.hws, num_clks),
GFP_KERNEL);
diff --git a/include/dt-bindings/clock/microchip,mpfs-clock.h b/include/dt-bindings/clock/microchip,mpfs-clock.h
index b52f19a2b480..8d53f2b81a54 100644
--- a/include/dt-bindings/clock/microchip,mpfs-clock.h
+++ b/include/dt-bindings/clock/microchip,mpfs-clock.h
@@ -73,4 +73,6 @@
#define CLK_CCC_DLL1_OUT0 14
#define CLK_CCC_DLL1_OUT1 15
+#define CLK_CCC_NUM 16
+
#endif /* _DT_BINDINGS_CLK_MICROCHIP_MPFS_H_ */
---
base-commit: bfe62a454542cfad3379f6ef5680b125f41e20f4
change-id: 20260407-mpfs-clk-oob-write-a0cec9a5c224
Best regards,
--
Aleš Pečnik <ales.pecnik@skylabs.si>
^ permalink raw reply related
* Re: [PATCH 0/3] PowerPC/Wii: A few devicetree cleanups
From: Madhavan Srinivasan @ 2026-04-08 4:28 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Michael Ellerman,
Nicholas Piggin, Christophe Leroy (CS GROUP), J. Neuschäfer
Cc: devicetree, linuxppc-dev, linux-kernel, Link Mauve
In-Reply-To: <20260311-wii-schema-v1-0-1563ac4aefa8@posteo.net>
On Wed, 11 Mar 2026 18:35:55 +0100, J. Neuschäfer wrote:
> This series contains a few minor fixes to make wii.dts somewhat more
> compliant with the DT schemas.
>
>
Applied to powerpc/next.
[1/3] powerpc: wii: Add unit address to /memory
https://git.kernel.org/powerpc/c/d1620f27ed1aa3be4255513e1a213ab1805ec892
[2/3] powerpc: wii: Fix GPIO key name pattern
https://git.kernel.org/powerpc/c/4a03d824b3204bae7e19cdf47a85ac01027603bb
[3/3] powerpc: wii: Fix LED name pattern
https://git.kernel.org/powerpc/c/47a05517c6edbf5160ce1bff107c10b76aa09ef7
cheers
^ permalink raw reply
* RE: [PATCH v10 00/22] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers
From: Dayananda, Vivekananda @ 2026-04-08 3:52 UTC (permalink / raw)
To: dumitru.ceclan@analog.com, Tomi Valkeinen, Mauro Carvalho Chehab,
Sakari Ailus, Laurent Pinchart, Julien Massot, Rob Herring,
Niklas Söderlund, Greg Kroah-Hartman, Cosmin Tanislav
Cc: mitrutzceclan@gmail.com, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-staging@lists.linux.dev, linux-gpio@vger.kernel.org,
Niklas Söderlund, martin.hecht@avnet.eu, Tomi Valkeinen,
Cosmin Tanislav, Dayananda, Vivekananda, Cory Keitz
In-Reply-To: <20260406-gmsl2-3_serdes-v10-0-645560fedca5@analog.com>
Hi Dumitru,
Thanks for spinning this series again. I was able to run it end-to-end on our bench (IMX219 → MAX96717 → MAX96724) with the deserializer using control-
channel port 1, and everything streamed as expected.
One thing I noticed while testing: in max96724_select_links() (max96724.c:889), we zero MAX96724_REG3 before we loop over the links, and only set the bits
that correspond to disabled links. That means every enabled link finishes with 00, so the priv->cc_port_cfg value we cached from maxim,control-channel-port
(0xAA for port 0, 0x55 for port 1) gets wiped the first time this helper runs. The side effect is that a board requesting port 0 in DT will keep the default
port 1 after any call to select_links(). If we seeded val with priv->cc_port_cfg (or wrote that value back after the loop) before writing to MAX96724_REG3,
we could preserve the DT-configured CC routing.
Vivek
^ permalink raw reply
* Re: [PATCH v12 3/3] of: Respect #{iommu,msi}-cells in maps
From: Vijayanand Jitta @ 2026-04-08 3:46 UTC (permalink / raw)
To: Nipun Gupta, Nikhil Agarwal, Joerg Roedel, Will Deacon,
Robin Murphy, Marc Zyngier, Lorenzo Pieralisi, Thomas Gleixner,
Saravana Kannan, Richard Zhu, Lucas Stach,
Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Helgaas,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
Dmitry Baryshkov, Konrad Dybcio, Bjorn Andersson, Rob Herring,
Conor Dooley, Krzysztof Kozlowski, Prakash Gupta, Vikash Garodia
Cc: linux-kernel, iommu, linux-arm-kernel, devicetree, linux-pci, imx,
xen-devel, linux-arm-msm, Charan Teja Kalla
In-Reply-To: <20260331-parse_iommu_cells-v12-3-decfd305eea9@oss.qualcomm.com>
On 3/31/2026 7:34 PM, Vijayanand Jitta wrote:
> From: Robin Murphy <robin.murphy@arm.com>
>
> So far our parsing of {iommu,msi}-map properties has always blindly
> assumed that the output specifiers will always have exactly 1 cell.
> This typically does happen to be the case, but is not actually enforced
> (and the PCI msi-map binding even explicitly states support for 0 or 1
> cells) - as a result we've now ended up with dodgy DTs out in the field
> which depend on this behaviour to map a 1-cell specifier for a 2-cell
> provider, despite that being bogus per the bindings themselves.
>
> Since there is some potential use in being able to map at least single
> input IDs to multi-cell output specifiers (and properly support 0-cell
> outputs as well), add support for properly parsing and using the target
> nodes' #cells values, albeit with the unfortunate complication of still
> having to work around expectations of the old behaviour too.
>
> Since there are multi-cell output specifiers, the callers of of_map_id()
> may need to get the exact cell output value for further processing.
> Update of_map_id() to set args_count in the output to reflect the actual
> number of output specifier cells.
>
> Signed-off-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Charan Teja Kalla <charan.kalla@oss.qualcomm.com>
> Signed-off-by: Vijayanand Jitta <vijayanand.jitta@oss.qualcomm.com>
> ---
> drivers/of/base.c | 155 ++++++++++++++++++++++++++++++++++++++++-------------
> include/linux/of.h | 6 ++-
> 2 files changed, 123 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index b3d002015192..7b22e2484e1c 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2096,18 +2096,48 @@ int of_find_last_cache_level(unsigned int cpu)
> return cache_level;
> }
>
> +/*
> + * Some DTs have an iommu-map targeting a 2-cell IOMMU node while
> + * specifying only 1 cell. Fortunately they all consist of value '1'
> + * as the 2nd cell entry with the same target, so check for that pattern.
> + *
> + * Example:
> + * IOMMU node:
> + * #iommu-cells = <2>;
> + *
> + * Device node:
> + * iommu-map = <0x0000 &smmu 0x0000 0x1>,
> + * <0x0100 &smmu 0x0100 0x1>;
> + */
> +static bool of_check_bad_map(const __be32 *map, int len)
> +{
> + __be32 phandle = map[1];
> +
> + if (len % 4)
> + return false;
> + for (int i = 0; i < len; i += 4) {
> + if (map[i + 1] != phandle || map[i + 3] != cpu_to_be32(1))
> + return false;
> + }
> + return true;
> +}
> +
> /**
> * of_map_id - Translate an ID through a downstream mapping.
> * @np: root complex device node.
> * @id: device ID to map.
> * @map_name: property name of the map to use.
> + * @cells_name: property name of target specifier cells.
> * @map_mask_name: optional property name of the mask to use.
> * @filter_np: optional device node to filter matches by, or NULL to match any.
> * If non-NULL, only map entries targeting this node will be matched.
> * @arg: pointer to a &struct of_phandle_args for the result. On success,
> - * @arg->args[0] will contain the translated ID. If a map entry was
> - * matched, @arg->np will be set to the target node with a reference
> - * held that the caller must release with of_node_put().
> + * @arg->args_count will be set to the number of output specifier cells
> + * as defined by @cells_name in the target node, and
> + * @arg->args[0..args_count-1] will contain the translated output
> + * specifier values. If a map entry was matched, @arg->np will be set
> + * to the target node with a reference held that the caller must release
> + * with of_node_put().
> *
> * Given a device ID, look up the appropriate implementation-defined
> * platform ID and/or the target device which receives transactions on that
> @@ -2116,17 +2146,19 @@ int of_find_last_cache_level(unsigned int cpu)
> * Return: 0 on success or a standard error code on failure.
> */
> int of_map_id(const struct device_node *np, u32 id,
> - const char *map_name, const char *map_mask_name,
> + const char *map_name, const char *cells_name,
> + const char *map_mask_name,
> const struct device_node *filter_np, struct of_phandle_args *arg)
> {
> u32 map_mask, masked_id;
> - int map_len;
> + int map_bytes, map_len, offset = 0;
> + bool bad_map = false;
> const __be32 *map = NULL;
>
> if (!np || !map_name || !arg)
> return -EINVAL;
>
> - map = of_get_property(np, map_name, &map_len);
> + map = of_get_property(np, map_name, &map_bytes);
> if (!map) {
> if (filter_np)
> return -ENODEV;
> @@ -2136,11 +2168,9 @@ int of_map_id(const struct device_node *np, u32 id,
> return 0;
> }
>
> - if (!map_len || map_len % (4 * sizeof(*map))) {
> - pr_err("%pOF: Error: Bad %s length: %d\n", np,
> - map_name, map_len);
> - return -EINVAL;
> - }
> + if (map_bytes % sizeof(*map))
> + goto err_map_len;
> + map_len = map_bytes / sizeof(*map);
>
> /* The default is to select all bits. */
> map_mask = 0xffffffff;
> @@ -2153,39 +2183,82 @@ int of_map_id(const struct device_node *np, u32 id,
> of_property_read_u32(np, map_mask_name, &map_mask);
>
> masked_id = map_mask & id;
> - for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
> +
> + while (offset < map_len) {
> struct device_node *phandle_node;
> - u32 id_base = be32_to_cpup(map + 0);
> - u32 phandle = be32_to_cpup(map + 1);
> - u32 out_base = be32_to_cpup(map + 2);
> - u32 id_len = be32_to_cpup(map + 3);
> + u32 id_base, phandle, id_len, id_off, cells = 0;
> + const __be32 *out_base;
> +
> + if (map_len - offset < 2)
> + goto err_map_len;
> +
> + id_base = be32_to_cpup(map + offset);
>
> if (id_base & ~map_mask) {
> - pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n",
> - np, map_name, map_name,
> - map_mask, id_base);
> + pr_err("%pOF: Invalid %s translation - %s (0x%x) ignores id-base (0x%x)\n",
> + np, map_name, map_mask_name, map_mask, id_base);
> return -EFAULT;
> }
>
> - if (masked_id < id_base || masked_id >= id_base + id_len)
> - continue;
> -
> + phandle = be32_to_cpup(map + offset + 1);
> phandle_node = of_find_node_by_phandle(phandle);
> if (!phandle_node)
> return -ENODEV;
>
> + if (!bad_map && of_property_read_u32(phandle_node, cells_name, &cells)) {
> + pr_err("%pOF: missing %s property\n", phandle_node, cells_name);
> + of_node_put(phandle_node);
> + return -EINVAL;
> + }
> +
> + if (map_len - offset < 3 + cells) {
> + of_node_put(phandle_node);
> + goto err_map_len;
> + }
> +
> + if (offset == 0 && cells == 2) {
> + bad_map = of_check_bad_map(map, map_len);
> + if (bad_map) {
> + pr_warn_once("%pOF: %s mismatches target %s, assuming extra cell of 0\n",
> + np, map_name, cells_name);
> + cells = 1;
> + }
> + }
> +
> + out_base = map + offset + 2;
> + offset += 3 + cells;
> +
> + id_len = be32_to_cpup(map + offset - 1);
> + if (id_len > 1 && cells > 1) {
> + /*
> + * With 1 output cell we reasonably assume its value
> + * has a linear relationship to the input; with more,
> + * we'd need help from the provider to know what to do.
> + */
> + pr_err("%pOF: Unsupported %s - cannot handle %d-ID range with %d-cell output specifier\n",
> + np, map_name, id_len, cells);
> + of_node_put(phandle_node);
> + return -EINVAL;
> + }
> + id_off = masked_id - id_base;
> + if (masked_id < id_base || id_off >= id_len) {
> + of_node_put(phandle_node);
> + continue;
> + }
> +
> if (filter_np && filter_np != phandle_node) {
> of_node_put(phandle_node);
> continue;
> }
>
> arg->np = phandle_node;
> - arg->args[0] = masked_id - id_base + out_base;
> - arg->args_count = 1;
> + for (int i = 0; i < cells; i++)
> + arg->args[i] = id_off + be32_to_cpu(out_base[i]);
> + arg->args_count = cells;
>
> pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n",
> - np, map_name, map_mask, id_base, out_base,
> - id_len, id, masked_id - id_base + out_base);
> + np, map_name, map_mask, id_base, be32_to_cpup(out_base),
> + id_len, id, id_off + be32_to_cpup(out_base));
> return 0;
> }
>
> @@ -2196,6 +2269,10 @@ int of_map_id(const struct device_node *np, u32 id,
> arg->args[0] = id;
> arg->args_count = 1;
> return 0;
> +
> +err_map_len:
> + pr_err("%pOF: Error: Bad %s length: %d\n", np, map_name, map_bytes);
> + return -EINVAL;
> }
> EXPORT_SYMBOL_GPL(of_map_id);
>
> @@ -2205,18 +2282,21 @@ EXPORT_SYMBOL_GPL(of_map_id);
> * @id: Requester ID of the device (e.g. PCI RID/BDF or a platform
> * stream/device ID) used as the lookup key in the iommu-map table.
> * @arg: pointer to a &struct of_phandle_args for the result. On success,
> - * @arg->args[0] contains the translated ID. If a map entry was matched,
> - * @arg->np holds a reference to the target node that the caller must
> - * release with of_node_put().
> + * @arg->args_count will be set to the number of output specifier cells
> + * and @arg->args[0..args_count-1] will contain the translated output
> + * specifier values. If a map entry was matched, @arg->np holds a
> + * reference to the target node that the caller must release with
> + * of_node_put().
> *
> - * Convenience wrapper around of_map_id() using "iommu-map" and "iommu-map-mask".
> + * Convenience wrapper around of_map_id() using "iommu-map", "#iommu-cells",
> + * and "iommu-map-mask".
> *
> * Return: 0 on success or a standard error code on failure.
> */
> int of_map_iommu_id(const struct device_node *np, u32 id,
> struct of_phandle_args *arg)
> {
> - return of_map_id(np, id, "iommu-map", "iommu-map-mask", NULL, arg);
> + return of_map_id(np, id, "iommu-map", "#iommu-cells", "iommu-map-mask", NULL, arg);
> }
> EXPORT_SYMBOL_GPL(of_map_iommu_id);
>
> @@ -2229,17 +2309,20 @@ EXPORT_SYMBOL_GPL(of_map_iommu_id);
> * to match any. If non-NULL, only map entries targeting this node will
> * be matched.
> * @arg: pointer to a &struct of_phandle_args for the result. On success,
> - * @arg->args[0] contains the translated ID. If a map entry was matched,
> - * @arg->np holds a reference to the target node that the caller must
> - * release with of_node_put().
> + * @arg->args_count will be set to the number of output specifier cells
> + * and @arg->args[0..args_count-1] will contain the translated output
> + * specifier values. If a map entry was matched, @arg->np holds a
> + * reference to the target node that the caller must release with
> + * of_node_put().
> *
> - * Convenience wrapper around of_map_id() using "msi-map" and "msi-map-mask".
> + * Convenience wrapper around of_map_id() using "msi-map", "#msi-cells",
> + * and "msi-map-mask".
> *
> * Return: 0 on success or a standard error code on failure.
> */
> int of_map_msi_id(const struct device_node *np, u32 id,
> const struct device_node *filter_np, struct of_phandle_args *arg)
> {
> - return of_map_id(np, id, "msi-map", "msi-map-mask", filter_np, arg);
> + return of_map_id(np, id, "msi-map", "#msi-cells", "msi-map-mask", filter_np, arg);
> }
> EXPORT_SYMBOL_GPL(of_map_msi_id);
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 8548cd9eb4f1..51ac8539f2c3 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -462,7 +462,8 @@ const char *of_prop_next_string(const struct property *prop, const char *cur);
> bool of_console_check(const struct device_node *dn, char *name, int index);
>
> int of_map_id(const struct device_node *np, u32 id,
> - const char *map_name, const char *map_mask_name,
> + const char *map_name, const char *cells_name,
> + const char *map_mask_name,
> const struct device_node *filter_np, struct of_phandle_args *arg);
>
> int of_map_iommu_id(const struct device_node *np, u32 id,
> @@ -934,7 +935,8 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
> }
>
> static inline int of_map_id(const struct device_node *np, u32 id,
> - const char *map_name, const char *map_mask_name,
> + const char *map_name, const char *cells_name,
> + const char *map_mask_name,
> const struct device_node *filter_np,
> struct of_phandle_args *arg)
> {
>
Gentle ping.
Thanks,
Vijay
^ permalink raw reply
* Re: [PATCH v2 3/4] dt-bindings: PCI: Add UltraRISC DP1000 PCIe controller
From: Jia Wang @ 2026-04-08 3:34 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Jia Wang, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas, Jingoo Han,
Xincheng Zhang, Krzysztof Kozlowski, Conor Dooley, linux-riscv,
linux-kernel, linux-pci, devicetree
In-Reply-To: <20260407-uptight-tody-of-weather-ae1e35@quoll>
On 2026-04-07 09:50 +0200, Krzysztof Kozlowski wrote:
> On Tue, Apr 07, 2026 at 10:40:54AM +0800, Jia Wang wrote:
> > Add UltraRISC DP1000 SoC PCIe controller devicetree bindings.
> >
> > Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> > ---
> > .../bindings/pci/ultrarisc,dp1000-pcie.yaml | 103 +++++++++++++++++++++
> > 1 file changed, 103 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/pci/ultrarisc,dp1000-pcie.yaml b/Documentation/devicetree/bindings/pci/ultrarisc,dp1000-pcie.yaml
> > new file mode 100644
> > index 000000000000..d0517130e127
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/ultrarisc,dp1000-pcie.yaml
> > @@ -0,0 +1,103 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/pci/ultrarisc,dp1000-pcie.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: UltraRISC DP1000 PCIe Host Controller
> > +
> > +description: |
>
> Do not need '|' unless you need to preserve formatting.
>
Hi Krzysztof,
Thanks. I’ll remove the `|` in v3.
> > + UltraRISC DP1000 SoC PCIe host controller is based on the DesignWare PCIe IP.
> > + This binding describes the UltraRISC specific extensions to the base
> > + DesignWare PCIe binding.
>
> Drop sentence. Do not describe in description what the binding
> describes. It's circular / repetitive. Just describe that.
>
Will simplify the description to a single concise statement in v3.
> > +
> > +maintainers:
> > + - Xincheng Zhang <zhangxincheng@ultrarisc.com>
> > + - Jia Wang <wangjia@ultrarisc.com>
> > +
> > +allOf:
> > + - $ref: /schemas/pci/snps,dw-pcie.yaml#
> > +
> > +properties:
> > + compatible:
> > + const: ultrarisc,dp1000-pcie
> > +
> > + reg:
> > + items:
> > + - description: Data Bus Interface (DBI) registers.
> > + - description: PCIe configuration space region.
> > +
> > + reg-names:
> > + items:
> > + - const: dbi
> > + - const: config
> > +
> > + num-lanes:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + enum: [4, 16]
> > + description: Number of lanes to use.
> > +
> > + max-link-speed:
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + const: 4
>
> If const then deducible from the compatible. Drop the property.
>
Will replace `const: 4` with `maximum: 4` in v3.
> > + description: Maximum PCIe link speed supported.
> > +
> > + interrupts:
> > + description: List of interrupt specifiers used by the controller
>
> Drop description. Obvious.
>
Will drop the description in v3.
> > + items:
> > + - description: MSI interrupt
> > + - description: Legacy INTA interrupt
> > + - description: Legacy INTB interrupt
> > + - description: Legacy INTC interrupt
> > + - description: Legacy INTD interrupt
> > +
> > + interrupt-names:
> > + items:
> > + - const: msi
> > + - const: inta
> > + - const: intb
> > + - const: intc
> > + - const: intd
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - reg-names
> > + - interrupts
> > + - interrupt-names
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > + - |
> > + soc {
> > + #address-cells = <2>;
> > + #size-cells = <2>;
> > +
> > + pcie_x16: pcie@21000000 {
>
> Drop unused label
>
Will drop it in v3.
> > + compatible = "ultrarisc,dp1000-pcie";
>
> reg, names and ranges go here. Please follow DTS coding style.
>
Will update the example to include reg, reg-names, and ranges following DTS
coding style in v3.
> > + #address-cells = <3>;
> > + #size-cells = <2>;
> > + #interrupt-cells = <1>;
> > + reg = <0x0 0x21000000 0x0 0x01000000>,
> > + <0x0 0x4fff0000 0x0 0x00010000>;
> > + reg-names = "dbi", "config";
> > + device_type = "pci";
> > + dma-coherent;
> > + bus-range = <0x0 0xff>;
> > + num-lanes = <16>;
> > + ranges = <0x81000000 0x0 0x4fbf0000 0x0 0x4fbf0000 0x0 0x00400000>,
> > + <0x82000000 0x0 0x40000000 0x0 0x40000000 0x0 0x0fbf0000>,
> > + <0xc3000000 0x40 0x00000000 0x40 0x00000000 0xd 0x00000000>;
> > +
> > + max-link-speed = <4>;
>
> Drop, compatible defines this.
>
> Best regards,
> Krzysztof
>
>
Best regards,
Jia Wang
^ permalink raw reply
* Re: [PATCH v4 11/11] drm/mxsfb/lcdif: use DRM_BRIDGE_ATTACH_NO_CONNECTOR and the bridge-connector
From: Liu Ying @ 2026-04-08 3:01 UTC (permalink / raw)
To: Luca Ceresoli, Marek Vasut, Stefan Agner, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Rob Herring, Saravana Kannan
Cc: Damon Ding, Kory Maincent (TI.com), Hervé Codina, Hui Pu,
Ian Ray, Thomas Petazzoni, dri-devel, imx, linux-arm-kernel,
linux-kernel, devicetree, Adam Ford, Alexander Stein,
Christopher Obbard, Daniel Scally, Emanuele Ghidoli,
Fabio Estevam, Francesco Dolcini, Frieder Schrempf, Gilles Talis,
Goran Rađenović, Heiko Schocher, Josua Mayer,
Kieran Bingham, Marco Felsch, Martyn Welch, Oleksij Rempel,
Peng Fan, Richard Hu, Shengjiu Wang, Stefan Eichenberger,
Vitor Soares
In-Reply-To: <20260407-drm-lcdif-dbanc-v4-11-247a16e61ef9@bootlin.com>
Hi Luca,
On Tue, Apr 07, 2026 at 02:24:25PM +0200, Luca Ceresoli wrote:
[...]
> (even though only the pane-bridge is surrently supported), amd all these
s/surrently/currently/
s/amd/and/
With these fixed:
Reviewed-by: Liu Ying <victor.liu@nxp.com>
--
Regards,
Liu Ying
^ permalink raw reply
* Re: [PATCH v4 08/11] drm/bridge: imx8mp-hdmi-tx-connector-fixup: add an hdmi-connector when missing using a DT overlay at boot time
From: Liu Ying @ 2026-04-08 2:58 UTC (permalink / raw)
To: Luca Ceresoli, Marek Vasut, Stefan Agner, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Rob Herring, Saravana Kannan
Cc: Damon Ding, Kory Maincent (TI.com), Hervé Codina, Hui Pu,
Ian Ray, Thomas Petazzoni, dri-devel, imx, linux-arm-kernel,
linux-kernel, devicetree, Adam Ford, Alexander Stein,
Christopher Obbard, Daniel Scally, Emanuele Ghidoli,
Fabio Estevam, Francesco Dolcini, Frieder Schrempf, Gilles Talis,
Goran Rađenović, Heiko Schocher, Josua Mayer,
Kieran Bingham, Marco Felsch, Martyn Welch, Oleksij Rempel,
Peng Fan, Richard Hu, Shengjiu Wang, Stefan Eichenberger,
Vitor Soares
In-Reply-To: <20260407-drm-lcdif-dbanc-v4-8-247a16e61ef9@bootlin.com>
On Tue, Apr 07, 2026 at 02:24:22PM +0200, Luca Ceresoli wrote:
> The imx8mp-hdmi-tx is one of many drivers based on dw-hdmi. dw-hdmi in turn
> can operate in two different modes, depending on the platform data as set
> by the driver:
>
> A. hdmi->plat_data->output_port = 0:
> the HDMI output (port@1) in device tree is not used [0]
>
> B. hdmi->plat_data->output_port = 1:
> the HDMI output (port@1) is parsed to find the next bridge
>
> The imx8mp-hdmi-tx driver falls in case A. This implies next_bridge will
> always be NULL, and so dw_hdmi_bridge_attach() [1] will always fail if
> called with the DRM_BRIDGE_ATTACH_NO_CONNECTOR flag.
>
> In fact case A assumes that DRM_BRIDGE_ATTACH_NO_CONNECTOR is not set and
> in that case it adds an HDMI Type A connector programmatically at bridge
> attach time.
>
> Support for DRM_BRIDGE_ATTACH_NO_CONNECTOR is implemented by dw-hdmi.c in
> case B. However switching to base B requires that port@1 is connected to a
> "next bridge" DT node, typically the HDMI connector, because dw-hdmi won't
> add the connector when using DRM_BRIDGE_ATTACH_NO_CONNECTOR.
>
> Many dts files for imx8mp-based boards in the kernel have such a connector
> described and linked to port@1, so the pipeline will be fully attached up
> to a display-connector and a drm_connector added by the
> bridge-connector. Sadly some of those dts files don't have the connector
> described. Adding it would solve the problem easily, but this would break
> existing devices which do not update the dtb when upgrading to a newer
> kernel.
>
> In preparation for switching to case B while preserving backward
> compatibility for such devices, introduce a module adding the
> hdmi-connector node to the live device tree at init time. This will allow
> the dw-hdmi code to find the next bridge (the one wrapping the
> hdmi-connector) and let the pipeline work as before.
>
> The module is inserted only if there is no endpoint in port@1. So boards
> whose device tree describe the connector will not have the device tre
> modified, and will start isntantiating the correct HDMI connector type as
> described in the device tree.
>
> For boards lacking a connector description in DT the overlay will be added,
> abd the HDMI connector will be Type A, which is a reasonable fallback and
> is what the driver is currently doing.
>
> [0] https://elixir.bootlin.com/linux/v7.0-rc1/source/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c#L3310
> [1] https://elixir.bootlin.com/linux/v7.0-rc1/source/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c#L2907
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
>
> ---
>
> Changes in v4:
> - fixed warning in overlay build
>
> Changes in v3:
> - removed unused variable
> - simplified overlay using full path to port@1
> - handle of_overlay_fdt_apply() errors
> - use of_graph_get_endpoint_by_regs() for more robust endpoint lookup
> - improve subject line
>
> Changes in v2:
> - don't apply the overlay if the SoC is not i.MX8MP
> - build unconditionally, but depend on DRM_IMX_LCDIF
> - remove useless error check
> - add missing cleanup.h and init.h includes, remove unneeded includes
> - avoid dtc warnings on overlay
> - fix typo in Kconfig help text
> - not added the Tested-bys because the code has changed
> - split the 'plat_data->output_port = 1' line to a separate patch
> - improve commit message
>
> This patch is inspired by commit 0ff223d99147 ("drm/tilcdc: Convert legacy
> panel binding via DT overlay at boot time")
> ---
> drivers/gpu/drm/bridge/imx/Kconfig | 18 +++++++
> drivers/gpu/drm/bridge/imx/Makefile | 2 +
> .../bridge/imx/imx8mp-hdmi-tx-connector-fixup.c | 58 ++++++++++++++++++++++
> .../bridge/imx/imx8mp-hdmi-tx-connector-fixup.dtso | 30 +++++++++++
> 4 files changed, 108 insertions(+)
Reviewed-by: Liu Ying <victor.liu@nxp.com>
Thanks!
--
Regards,
Liu Ying
^ permalink raw reply
* [PATCH v2 4/4] arm64: dts: realtek: Add GPIO support for RTD1625
From: Yu-Chun Lin @ 2026-04-08 2:52 UTC (permalink / raw)
To: linusw, brgl, robh, krzk+dt, conor+dt, afaerber, tychang
Cc: linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-realtek-soc, cy.huang, stanley_chang, eleanor.lin,
james.tai
In-Reply-To: <20260408025243.1155482-1-eleanor.lin@realtek.com>
Add the GPIO node for the Realtek RTD1625 SoC.
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v2:
- Merge two reg memory regions.
- Remove redundant status setting.
---
arch/arm64/boot/dts/realtek/kent.dtsi | 39 +++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/arch/arm64/boot/dts/realtek/kent.dtsi b/arch/arm64/boot/dts/realtek/kent.dtsi
index 8d4293cd4c03..dafe56ce7d71 100644
--- a/arch/arm64/boot/dts/realtek/kent.dtsi
+++ b/arch/arm64/boot/dts/realtek/kent.dtsi
@@ -151,6 +151,37 @@ uart0: serial@7800 {
status = "disabled";
};
+ gpio: gpio@31000 {
+ compatible = "realtek,rtd1625-iso-gpio";
+ reg = <0x31000 0x398>;
+ gpio-controller;
+ gpio-ranges = <&isom_pinctrl 0 0 2>,
+ <&ve4_pinctrl 2 0 6>,
+ <&iso_pinctrl 8 0 4>,
+ <&ve4_pinctrl 12 6 2>,
+ <&main2_pinctrl 14 0 2>,
+ <&ve4_pinctrl 16 8 4>,
+ <&main2_pinctrl 20 2 3>,
+ <&ve4_pinctrl 23 12 3>,
+ <&iso_pinctrl 26 4 2>,
+ <&isom_pinctrl 28 2 2>,
+ <&ve4_pinctrl 30 15 6>,
+ <&main2_pinctrl 36 5 6>,
+ <&ve4_pinctrl 42 21 3>,
+ <&iso_pinctrl 45 6 6>,
+ <&ve4_pinctrl 51 24 1>,
+ <&iso_pinctrl 52 12 1>,
+ <&ve4_pinctrl 53 25 11>,
+ <&main2_pinctrl 64 11 28>,
+ <&ve4_pinctrl 92 36 2>,
+ <&iso_pinctrl 94 13 19>,
+ <&iso_pinctrl 128 32 4>,
+ <&ve4_pinctrl 132 38 13>,
+ <&iso_pinctrl 145 36 19>,
+ <&ve4_pinctrl 164 51 2>;
+ #gpio-cells = <2>;
+ };
+
iso_pinctrl: pinctrl@4e000 {
compatible = "realtek,rtd1625-iso-pinctrl";
reg = <0x4e000 0x1a4>;
@@ -161,6 +192,14 @@ main2_pinctrl: pinctrl@4f200 {
reg = <0x4f200 0x50>;
};
+ iso_m_gpio: gpio@89100 {
+ compatible = "realtek,rtd1625-isom-gpio";
+ reg = <0x89100 0x30>;
+ gpio-controller;
+ gpio-ranges = <&isom_pinctrl 0 0 4>;
+ #gpio-cells = <2>;
+ };
+
isom_pinctrl: pinctrl@146200 {
compatible = "realtek,rtd1625-isom-pinctrl";
reg = <0x146200 0x34>;
--
2.34.1
^ permalink raw reply related
* [PATCH v2 3/4] gpio: realtek: Add driver for Realtek DHC RTD1625 SoC
From: Yu-Chun Lin @ 2026-04-08 2:52 UTC (permalink / raw)
To: linusw, brgl, robh, krzk+dt, conor+dt, afaerber, tychang
Cc: linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-realtek-soc, cy.huang, stanley_chang, eleanor.lin,
james.tai
In-Reply-To: <20260408025243.1155482-1-eleanor.lin@realtek.com>
From: Tzuyi Chang <tychang@realtek.com>
Add support for the GPIO controller found on Realtek DHC RTD1625 SoCs.
Unlike the existing Realtek GPIO driver (drivers/gpio/gpio-rtd.c),
which manages pins via shared bank registers, the RTD1625 introduces
a per-pin register architecture. Each GPIO line now has its own
dedicated 32-bit control register to manage configuration independently,
including direction, output value, input value, interrupt enable, and
debounce. Therefore, this distinct hardware design requires a separate
driver.
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Tzuyi Chang <tychang@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v2:
- Remove "default y".
- Add base_offset member to struct rtd1625_gpio_info to handle merged regions.
---
drivers/gpio/Kconfig | 11 +
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-rtd1625.c | 584 ++++++++++++++++++++++++++++++++++++
3 files changed, 596 insertions(+)
create mode 100644 drivers/gpio/gpio-rtd1625.c
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 5ee11a889867..281549ad72ac 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -638,6 +638,17 @@ config GPIO_RTD
Say yes here to support GPIO functionality and GPIO interrupt on
Realtek DHC SoCs.
+config GPIO_RTD1625
+ tristate "Realtek DHC RTD1625 GPIO support"
+ depends on ARCH_REALTEK || COMPILE_TEST
+ select GPIOLIB_IRQCHIP
+ help
+ This option enables support for the GPIO controller on Realtek
+ DHC (Digital Home Center) RTD1625 SoC.
+
+ Say yes here to support both basic GPIO line functionality
+ and GPIO interrupt handling capabilities for this platform.
+
config GPIO_SAMA5D2_PIOBU
tristate "SAMA5D2 PIOBU GPIO support"
depends on MFD_SYSCON
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index c05f7d795c43..c95ba218d53a 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_GPIO_REALTEK_OTTO) += gpio-realtek-otto.o
obj-$(CONFIG_GPIO_REG) += gpio-reg.o
obj-$(CONFIG_GPIO_ROCKCHIP) += gpio-rockchip.o
obj-$(CONFIG_GPIO_RTD) += gpio-rtd.o
+obj-$(CONFIG_GPIO_RTD1625) += gpio-rtd1625.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SAMA5D2_PIOBU) += gpio-sama5d2-piobu.o
obj-$(CONFIG_GPIO_SCH311X) += gpio-sch311x.o
diff --git a/drivers/gpio/gpio-rtd1625.c b/drivers/gpio/gpio-rtd1625.c
new file mode 100644
index 000000000000..bcc1bbb115fa
--- /dev/null
+++ b/drivers/gpio/gpio-rtd1625.c
@@ -0,0 +1,584 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Realtek DHC RTD1625 gpio driver
+ *
+ * Copyright (c) 2023 Realtek Semiconductor Corp.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define RTD1625_GPIO_DIR BIT(0)
+#define RTD1625_GPIO_OUT BIT(2)
+#define RTD1625_GPIO_IN BIT(4)
+#define RTD1625_GPIO_EDGE_INT_DP BIT(6)
+#define RTD1625_GPIO_EDGE_INT_EN BIT(8)
+#define RTD1625_GPIO_LEVEL_INT_EN BIT(16)
+#define RTD1625_GPIO_LEVEL_INT_DP BIT(18)
+#define RTD1625_GPIO_DEBOUNCE GENMASK(30, 28)
+#define RTD1625_GPIO_DEBOUNCE_WREN BIT(31)
+
+#define RTD1625_GPIO_WREN(x) ((x) << 1)
+
+/* Write-enable masks for all GPIO configs and reserved hardware bits */
+#define RTD1625_ISO_GPIO_WREN_ALL 0x8000aa8a
+#define RTD1625_ISOM_GPIO_WREN_ALL 0x800aaa8a
+
+#define RTD1625_GPIO_DEBOUNCE_1US 0
+#define RTD1625_GPIO_DEBOUNCE_10US 1
+#define RTD1625_GPIO_DEBOUNCE_100US 2
+#define RTD1625_GPIO_DEBOUNCE_1MS 3
+#define RTD1625_GPIO_DEBOUNCE_10MS 4
+#define RTD1625_GPIO_DEBOUNCE_20MS 5
+#define RTD1625_GPIO_DEBOUNCE_30MS 6
+#define RTD1625_GPIO_DEBOUNCE_50MS 7
+
+#define GPIO_CONTROL(gpio) ((gpio) * 4)
+
+/**
+ * struct rtd1625_gpio_info - Specific GPIO register information
+ * @num_gpios: The number of GPIOs
+ * @irq_type_support: Supported IRQ types
+ * @gpa_offset: Offset for GPIO assert interrupt status registers
+ * @gpda_offset: Offset for GPIO deassert interrupt status registers
+ * @level_offset: Offset of level interrupt status register
+ * @write_en_all: Write-enable mask for all configurable bits
+ */
+struct rtd1625_gpio_info {
+ unsigned int num_gpios;
+ unsigned int irq_type_support;
+ unsigned int base_offset;
+ unsigned int gpa_offset;
+ unsigned int gpda_offset;
+ unsigned int level_offset;
+ unsigned int write_en_all;
+};
+
+struct rtd1625_gpio {
+ struct gpio_chip gpio_chip;
+ const struct rtd1625_gpio_info *info;
+ void __iomem *base;
+ void __iomem *irq_base;
+ unsigned int irqs[3];
+ raw_spinlock_t lock;
+ unsigned int *save_regs;
+};
+
+static unsigned int rtd1625_gpio_gpa_offset(struct rtd1625_gpio *data, unsigned int offset)
+{
+ return data->info->gpa_offset + ((offset / 32) * 4);
+}
+
+static unsigned int rtd1625_gpio_gpda_offset(struct rtd1625_gpio *data, unsigned int offset)
+{
+ return data->info->gpda_offset + ((offset / 32) * 4);
+}
+
+static unsigned int rtd1625_gpio_level_offset(struct rtd1625_gpio *data, unsigned int offset)
+{
+ return data->info->level_offset + ((offset / 32) * 4);
+}
+
+static unsigned int rtd1625_gpio_set_debounce(struct gpio_chip *chip, unsigned int offset,
+ unsigned int debounce)
+{
+ struct rtd1625_gpio *data = gpiochip_get_data(chip);
+ u8 deb_val;
+ u32 val;
+
+ switch (debounce) {
+ case 1:
+ deb_val = RTD1625_GPIO_DEBOUNCE_1US;
+ break;
+ case 10:
+ deb_val = RTD1625_GPIO_DEBOUNCE_10US;
+ break;
+ case 100:
+ deb_val = RTD1625_GPIO_DEBOUNCE_100US;
+ break;
+ case 1000:
+ deb_val = RTD1625_GPIO_DEBOUNCE_1MS;
+ break;
+ case 10000:
+ deb_val = RTD1625_GPIO_DEBOUNCE_10MS;
+ break;
+ case 20000:
+ deb_val = RTD1625_GPIO_DEBOUNCE_20MS;
+ break;
+ case 30000:
+ deb_val = RTD1625_GPIO_DEBOUNCE_30MS;
+ break;
+ case 50000:
+ deb_val = RTD1625_GPIO_DEBOUNCE_50MS;
+ break;
+ default:
+ return -ENOTSUPP;
+ }
+
+ val = FIELD_PREP(RTD1625_GPIO_DEBOUNCE, deb_val) | RTD1625_GPIO_DEBOUNCE_WREN;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ writel_relaxed(val, data->base + GPIO_CONTROL(offset));
+
+ return 0;
+}
+
+static int rtd1625_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+ unsigned long config)
+{
+ int debounce;
+
+ if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) {
+ debounce = pinconf_to_config_argument(config);
+ return rtd1625_gpio_set_debounce(chip, offset, debounce);
+ }
+
+ return gpiochip_generic_config(chip, offset, config);
+}
+
+static int rtd1625_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+ struct rtd1625_gpio *data = gpiochip_get_data(chip);
+ u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_OUT);
+
+ if (value)
+ val |= RTD1625_GPIO_OUT;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ writel_relaxed(val, data->base + GPIO_CONTROL(offset));
+
+ return 0;
+}
+
+static int rtd1625_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+ struct rtd1625_gpio *data = gpiochip_get_data(chip);
+ u32 val;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ val = readl_relaxed(data->base + GPIO_CONTROL(offset));
+
+ if (val & RTD1625_GPIO_DIR)
+ return !!(val & RTD1625_GPIO_OUT);
+ else
+ return !!(val & RTD1625_GPIO_IN);
+}
+
+static int rtd1625_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+ struct rtd1625_gpio *data = gpiochip_get_data(chip);
+ u32 val;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ val = readl_relaxed(data->base + GPIO_CONTROL(offset));
+
+ if (val & RTD1625_GPIO_DIR)
+ return GPIO_LINE_DIRECTION_OUT;
+
+ return GPIO_LINE_DIRECTION_IN;
+}
+
+static int rtd1625_gpio_set_direction(struct gpio_chip *chip, unsigned int offset, bool out)
+{
+ struct rtd1625_gpio *data = gpiochip_get_data(chip);
+ u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_DIR);
+
+ if (out)
+ val |= RTD1625_GPIO_DIR;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ writel_relaxed(val, data->base + GPIO_CONTROL(offset));
+
+ return 0;
+}
+
+static int rtd1625_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+ return rtd1625_gpio_set_direction(chip, offset, false);
+}
+
+static int rtd1625_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value)
+{
+ rtd1625_gpio_set(chip, offset, value);
+
+ return rtd1625_gpio_set_direction(chip, offset, true);
+}
+
+static void rtd1625_gpio_irq_handle(struct irq_desc *desc)
+{
+ unsigned int (*get_reg_offset)(struct rtd1625_gpio *gpio, unsigned int offset);
+ struct rtd1625_gpio *data = irq_desc_get_handler_data(desc);
+ struct irq_domain *domain = data->gpio_chip.irq.domain;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ unsigned int irq = irq_desc_get_irq(desc);
+ unsigned long status;
+ unsigned int reg_offset, i, j;
+ unsigned int girq;
+ irq_hw_number_t hwirq;
+ u32 irq_type;
+
+ if (irq == data->irqs[0])
+ get_reg_offset = &rtd1625_gpio_gpa_offset;
+ else if (irq == data->irqs[1])
+ get_reg_offset = &rtd1625_gpio_gpda_offset;
+ else if (irq == data->irqs[2])
+ get_reg_offset = &rtd1625_gpio_level_offset;
+ else
+ return;
+
+ chained_irq_enter(chip, desc);
+
+ for (i = 0; i < data->info->num_gpios; i += 32) {
+ reg_offset = get_reg_offset(data, i);
+ status = readl_relaxed(data->irq_base + reg_offset);
+
+ /* Clear edge interrupts; level interrupts are cleared in ->irq_ack() */
+ if (irq != data->irqs[2])
+ writel_relaxed(status, data->irq_base + reg_offset);
+
+ for_each_set_bit(j, &status, 32) {
+ hwirq = i + j;
+ girq = irq_find_mapping(domain, hwirq);
+ irq_type = irq_get_trigger_type(girq);
+
+ if (irq == data->irqs[1] && irq_type != IRQ_TYPE_EDGE_BOTH)
+ continue;
+
+ generic_handle_domain_irq(domain, hwirq);
+ }
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static void rtd1625_gpio_ack_irq(struct irq_data *d)
+{
+ struct rtd1625_gpio *data = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ u32 irq_type = irqd_get_trigger_type(d);
+ u32 bit_mask = BIT(hwirq % 32);
+ int reg_offset;
+
+ if (irq_type & IRQ_TYPE_LEVEL_MASK) {
+ reg_offset = rtd1625_gpio_level_offset(data, hwirq);
+ writel_relaxed(bit_mask, data->irq_base + reg_offset);
+ }
+}
+
+static void rtd1625_gpio_enable_edge_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq)
+{
+ int gpda_reg_offset = rtd1625_gpio_gpda_offset(data, hwirq);
+ int gpa_reg_offset = rtd1625_gpio_gpa_offset(data, hwirq);
+ u32 clr_mask = BIT(hwirq % 32);
+ u32 val;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ writel_relaxed(clr_mask, data->irq_base + gpa_reg_offset);
+ writel_relaxed(clr_mask, data->irq_base + gpda_reg_offset);
+ val = RTD1625_GPIO_EDGE_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_EN);
+ writel_relaxed(val, data->base + GPIO_CONTROL(hwirq));
+}
+
+static void rtd1625_gpio_disable_edge_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq)
+{
+ u32 val;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ val = RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_EN);
+ writel_relaxed(val, data->base + GPIO_CONTROL(hwirq));
+}
+
+static void rtd1625_gpio_enable_level_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq)
+{
+ int level_reg_offset = rtd1625_gpio_level_offset(data, hwirq);
+ u32 clr_mask = BIT(hwirq % 32);
+ u32 val;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ writel_relaxed(clr_mask, data->irq_base + level_reg_offset);
+ val = RTD1625_GPIO_LEVEL_INT_EN | RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_EN);
+ writel_relaxed(val, data->base + GPIO_CONTROL(hwirq));
+}
+
+static void rtd1625_gpio_disable_level_irq(struct rtd1625_gpio *data, irq_hw_number_t hwirq)
+{
+ u32 val;
+
+ guard(raw_spinlock_irqsave)(&data->lock);
+ val = RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_EN);
+ writel_relaxed(val, data->base + GPIO_CONTROL(hwirq));
+}
+
+static void rtd1625_gpio_enable_irq(struct irq_data *d)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct rtd1625_gpio *data = gpiochip_get_data(gc);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ u32 irq_type = irqd_get_trigger_type(d);
+
+ gpiochip_enable_irq(gc, hwirq);
+
+ if (irq_type & IRQ_TYPE_EDGE_BOTH)
+ rtd1625_gpio_enable_edge_irq(data, hwirq);
+ else if (irq_type & IRQ_TYPE_LEVEL_MASK)
+ rtd1625_gpio_enable_level_irq(data, hwirq);
+}
+
+static void rtd1625_gpio_disable_irq(struct irq_data *d)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct rtd1625_gpio *data = gpiochip_get_data(gc);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ u32 irq_type = irqd_get_trigger_type(d);
+
+ if (irq_type & IRQ_TYPE_EDGE_BOTH)
+ rtd1625_gpio_disable_edge_irq(data, hwirq);
+ else if (irq_type & IRQ_TYPE_LEVEL_MASK)
+ rtd1625_gpio_disable_level_irq(data, hwirq);
+
+ gpiochip_disable_irq(gc, hwirq);
+}
+
+static int rtd1625_gpio_irq_set_level_type(struct irq_data *d, bool level)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct rtd1625_gpio *data = gpiochip_get_data(gc);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_LEVEL_INT_DP);
+
+ if (!(data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK))
+ return -EINVAL;
+
+ scoped_guard(raw_spinlock_irqsave, &data->lock) {
+ if (level)
+ val |= RTD1625_GPIO_LEVEL_INT_DP;
+ writel_relaxed(val, data->base + GPIO_CONTROL(hwirq));
+ }
+
+ irq_set_handler_locked(d, handle_level_irq);
+
+ return 0;
+}
+
+static int rtd1625_gpio_irq_set_edge_type(struct irq_data *d, bool polarity)
+{
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct rtd1625_gpio *data = gpiochip_get_data(gc);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+ u32 val = RTD1625_GPIO_WREN(RTD1625_GPIO_EDGE_INT_DP);
+
+ if (!(data->info->irq_type_support & IRQ_TYPE_EDGE_BOTH))
+ return -EINVAL;
+
+ scoped_guard(raw_spinlock_irqsave, &data->lock) {
+ if (polarity)
+ val |= RTD1625_GPIO_EDGE_INT_DP;
+ writel_relaxed(val, data->base + GPIO_CONTROL(hwirq));
+ }
+
+ irq_set_handler_locked(d, handle_edge_irq);
+
+ return 0;
+}
+
+static int rtd1625_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ int ret;
+
+ switch (type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_EDGE_RISING:
+ ret = rtd1625_gpio_irq_set_edge_type(d, 1);
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ ret = rtd1625_gpio_irq_set_edge_type(d, 0);
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ ret = rtd1625_gpio_irq_set_edge_type(d, 1);
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ ret = rtd1625_gpio_irq_set_level_type(d, 0);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ ret = rtd1625_gpio_irq_set_level_type(d, 1);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static struct irq_chip rtd1625_iso_gpio_irq_chip = {
+ .name = "rtd1625-gpio",
+ .irq_ack = rtd1625_gpio_ack_irq,
+ .irq_mask = rtd1625_gpio_disable_irq,
+ .irq_unmask = rtd1625_gpio_enable_irq,
+ .irq_set_type = rtd1625_gpio_irq_set_type,
+ .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SKIP_SET_WAKE,
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
+static int rtd1625_gpio_setup_irq(struct platform_device *pdev, struct rtd1625_gpio *data)
+{
+ struct gpio_irq_chip *irq_chip;
+ int num_irqs;
+ int irq;
+ int i;
+
+ irq = platform_get_irq_optional(pdev, 0);
+ if (irq == -ENXIO)
+ return 0;
+ if (irq < 0)
+ return irq;
+
+ num_irqs = (data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK) ? 3 : 2;
+ data->irqs[0] = irq;
+
+ for (i = 1; i < num_irqs; i++) {
+ irq = platform_get_irq(pdev, i);
+ if (irq < 0)
+ return irq;
+ data->irqs[i] = irq;
+ }
+
+ irq_chip = &data->gpio_chip.irq;
+ irq_chip->handler = handle_bad_irq;
+ irq_chip->default_type = IRQ_TYPE_NONE;
+ irq_chip->parent_handler = rtd1625_gpio_irq_handle;
+ irq_chip->parent_handler_data = data;
+ irq_chip->num_parents = num_irqs;
+ irq_chip->parents = data->irqs;
+
+ gpio_irq_chip_set_chip(irq_chip, &rtd1625_iso_gpio_irq_chip);
+
+ return 0;
+}
+
+static int rtd1625_gpio_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rtd1625_gpio *data;
+ void __iomem *irq_base;
+ int ret;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->info = device_get_match_data(dev);
+ if (!data->info)
+ return -EINVAL;
+
+ raw_spin_lock_init(&data->lock);
+
+ irq_base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(irq_base))
+ return PTR_ERR(irq_base);
+
+ data->irq_base = irq_base;
+ data->base = irq_base + data->info->base_offset;
+
+ data->save_regs = devm_kzalloc(dev, data->info->num_gpios *
+ sizeof(*data->save_regs), GFP_KERNEL);
+ if (!data->save_regs)
+ return -ENOMEM;
+
+ data->gpio_chip.label = dev_name(dev);
+ data->gpio_chip.base = -1;
+ data->gpio_chip.ngpio = data->info->num_gpios;
+ data->gpio_chip.request = gpiochip_generic_request;
+ data->gpio_chip.free = gpiochip_generic_free;
+ data->gpio_chip.get_direction = rtd1625_gpio_get_direction;
+ data->gpio_chip.direction_input = rtd1625_gpio_direction_input;
+ data->gpio_chip.direction_output = rtd1625_gpio_direction_output;
+ data->gpio_chip.set = rtd1625_gpio_set;
+ data->gpio_chip.get = rtd1625_gpio_get;
+ data->gpio_chip.set_config = rtd1625_gpio_set_config;
+ data->gpio_chip.parent = dev;
+
+ ret = rtd1625_gpio_setup_irq(pdev, data);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, data);
+
+ return devm_gpiochip_add_data(dev, &data->gpio_chip, data);
+}
+
+static const struct rtd1625_gpio_info rtd1625_iso_gpio_info = {
+ .num_gpios = 166,
+ .irq_type_support = IRQ_TYPE_EDGE_BOTH,
+ .base_offset = 0x100,
+ .gpa_offset = 0x0,
+ .gpda_offset = 0x20,
+ .write_en_all = RTD1625_ISO_GPIO_WREN_ALL,
+};
+
+static const struct rtd1625_gpio_info rtd1625_isom_gpio_info = {
+ .num_gpios = 4,
+ .irq_type_support = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_LOW |
+ IRQ_TYPE_LEVEL_HIGH,
+ .base_offset = 0x20,
+ .gpa_offset = 0x0,
+ .gpda_offset = 0x4,
+ .level_offset = 0x18,
+ .write_en_all = RTD1625_ISOM_GPIO_WREN_ALL,
+};
+
+static const struct of_device_id rtd1625_gpio_of_matches[] = {
+ { .compatible = "realtek,rtd1625-iso-gpio", .data = &rtd1625_iso_gpio_info },
+ { .compatible = "realtek,rtd1625-isom-gpio", .data = &rtd1625_isom_gpio_info },
+ { }
+};
+MODULE_DEVICE_TABLE(of, rtd1625_gpio_of_matches);
+
+static int rtd1625_gpio_suspend(struct device *dev)
+{
+ struct rtd1625_gpio *data = dev_get_drvdata(dev);
+ const struct rtd1625_gpio_info *info = data->info;
+ int i;
+
+ for (i = 0; i < info->num_gpios; i++)
+ data->save_regs[i] = readl_relaxed(data->base + GPIO_CONTROL(i));
+
+ return 0;
+}
+
+static int rtd1625_gpio_resume(struct device *dev)
+{
+ struct rtd1625_gpio *data = dev_get_drvdata(dev);
+ const struct rtd1625_gpio_info *info = data->info;
+ int i;
+
+ for (i = 0; i < info->num_gpios; i++)
+ writel_relaxed(data->save_regs[i] | info->write_en_all,
+ data->base + GPIO_CONTROL(i));
+
+ return 0;
+}
+
+DEFINE_NOIRQ_DEV_PM_OPS(rtd1625_gpio_pm_ops, rtd1625_gpio_suspend, rtd1625_gpio_resume);
+
+static struct platform_driver rtd1625_gpio_platform_driver = {
+ .driver = {
+ .name = "gpio-rtd1625",
+ .of_match_table = rtd1625_gpio_of_matches,
+ .pm = pm_sleep_ptr(&rtd1625_gpio_pm_ops),
+ },
+ .probe = rtd1625_gpio_probe,
+};
+module_platform_driver(rtd1625_gpio_platform_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Realtek Semiconductor Corporation");
+MODULE_DESCRIPTION("Realtek DHC SoC RTD1625 gpio driver");
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/4] gpio: realtek: Add support for Realtek DHC RTD1625
From: Yu-Chun Lin @ 2026-04-08 2:52 UTC (permalink / raw)
To: linusw, brgl, robh, krzk+dt, conor+dt, afaerber, tychang
Cc: linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-realtek-soc, cy.huang, stanley_chang, eleanor.lin,
james.tai
This series adds GPIO support for the Realtek DHC RTD1625 SoC.
Unlike the existing driver (gpio-rtd.c) which uses shared bank registers,
the RTD1625 features a per-pin register architecture where each GPIO line
is managed by its own dedicated 32-bit control register. This distinct
hardware design requires a new, separate driver.
The device tree changes in this series (Patch 3) depend on the RTD1625 pinctrl
driver, which is currently under review and has not been merged yet.
The dependent pinctrl patch can be found here:
https://lore.kernel.org/lkml/20260317115411.2154365-9-eleanor.lin@realtek.com/
Best Regards,
Yu-Chun Lin
---
Changes in v2:
- Move DTS patch to the end of the series.
Patch 1 (gpio: Remove "default y" in Kconfig):
- New patch.
Patch 2 (dt-bindings: gpio: realtek: Add realtek,rtd1625-gpio):
- Merge two memory regions into one.
- Add a description for the reg region.
Patch 3 (gpio: realtek: Add driver for Realtek DHC RTD1625 SoC):
- Remove "default y".
- Add base_offset member to struct rtd1625_gpio_info to handle merged regions.
Patch 4 (arm64: dts: realtek: Add GPIO support for RTD1625):
- Merge two reg memory regions.
- Remove redundant status setting.
v1: https://lore.kernel.org/lkml/20260331113835.3510341-1-eleanor.lin@realtek.com/
Tzuyi Chang (2):
dt-bindings: gpio: realtek: Add realtek,rtd1625-gpio
gpio: realtek: Add driver for Realtek DHC RTD1625 SoC
Yu-Chun Lin (2):
gpio: Remove "default y" in Kconfig
arm64: dts: realtek: Add GPIO support for RTD1625
.../bindings/gpio/realtek,rtd1625-gpio.yaml | 82 +++
arch/arm64/boot/dts/realtek/kent.dtsi | 39 ++
drivers/gpio/Kconfig | 12 +-
drivers/gpio/Makefile | 1 +
drivers/gpio/gpio-rtd1625.c | 584 ++++++++++++++++++
5 files changed, 717 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.yaml
create mode 100644 drivers/gpio/gpio-rtd1625.c
--
2.34.1
^ permalink raw reply
* [PATCH v2 2/4] dt-bindings: gpio: realtek: Add realtek,rtd1625-gpio
From: Yu-Chun Lin @ 2026-04-08 2:52 UTC (permalink / raw)
To: linusw, brgl, robh, krzk+dt, conor+dt, afaerber, tychang
Cc: linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-realtek-soc, cy.huang, stanley_chang, eleanor.lin,
james.tai
In-Reply-To: <20260408025243.1155482-1-eleanor.lin@realtek.com>
From: Tzuyi Chang <tychang@realtek.com>
Add the device tree bindings for the Realtek DHC (Digital Home Center)
RTD1625 GPIO controllers.
The RTD1625 GPIO controller features a per-pin register architecture
that differs significantly from previous generations. It utilizes
separate register blocks for GPIO configuration and interrupt control.
Signed-off-by: Tzuyi Chang <tychang@realtek.com>
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v2:
- Merge two memory regions into one.
- Add a description for the reg region.
---
.../bindings/gpio/realtek,rtd1625-gpio.yaml | 82 +++++++++++++++++++
1 file changed, 82 insertions(+)
create mode 100644 Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.yaml
diff --git a/Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.yaml b/Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.yaml
new file mode 100644
index 000000000000..de873876b8c6
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/realtek,rtd1625-gpio.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2023 Realtek Semiconductor Corporation
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/realtek,rtd1625-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Realtek DHC RTD1625 GPIO controller
+
+maintainers:
+ - Tzuyi Chang <tychang@realtek.com>
+
+description: |
+ GPIO controller for the Realtek RTD1625 SoC, featuring a per-pin register
+ architecture that differs significantly from earlier RTD series controllers.
+ Each GPIO has dedicated registers for configuration (direction, input/output
+ values, debounce), and interrupt control supporting edge and level detection
+ modes.
+
+properties:
+ compatible:
+ enum:
+ - realtek,rtd1625-iso-gpio
+ - realtek,rtd1625-isom-gpio
+
+ reg:
+ maxItems: 1
+ description: |
+ Memory region containing both interrupt control and GPIO
+ configuration registers in a contiguous address space.
+
+ For realtek,rtd1625-iso-gpio:
+ - Base + 0x0 ~ 0xff: Interrupt control registers
+ - Base + 0x100 ~ 0x397: GPIO configuration registers
+
+ For realtek,rtd1625-isom-gpio:
+ - Base + 0x0 ~ 0x1f: Interrupt control registers
+ - Base + 0x20 ~ 0x2f: GPIO configuration registers
+
+ interrupts:
+ items:
+ - description: Interrupt number of the assert GPIO interrupt, which is
+ triggered when there is a rising edge.
+ - description: Interrupt number of the deassert GPIO interrupt, which is
+ triggered when there is a falling edge.
+ - description: Interrupt number of the level-sensitive GPIO interrupt,
+ triggered by a configured logic level.
+
+ interrupt-controller: true
+
+ "#interrupt-cells":
+ const: 2
+
+ gpio-ranges: true
+
+ gpio-controller: true
+
+ "#gpio-cells":
+ const: 2
+
+required:
+ - compatible
+ - reg
+ - gpio-ranges
+ - gpio-controller
+ - "#gpio-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ gpio@89100 {
+ compatible = "realtek,rtd1625-isom-gpio";
+ reg = <0x89100 0x30>;
+ interrupt-parent = <&iso_m_irq_mux>;
+ interrupts = <0>, <1>, <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ gpio-ranges = <&isom_pinctrl 0 0 4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v2 1/4] gpio: Remove "default y" in Kconfig
From: Yu-Chun Lin @ 2026-04-08 2:52 UTC (permalink / raw)
To: linusw, brgl, robh, krzk+dt, conor+dt, afaerber, tychang
Cc: linux-gpio, devicetree, linux-kernel, linux-arm-kernel,
linux-realtek-soc, cy.huang, stanley_chang, eleanor.lin,
james.tai
In-Reply-To: <20260408025243.1155482-1-eleanor.lin@realtek.com>
Remove the default y to avoid bloating the build for non-Realtek platforms
when COMPILE_TEST is enable on other platforms.
Signed-off-by: Yu-Chun Lin <eleanor.lin@realtek.com>
---
Changes in v2:
- New patch.
---
drivers/gpio/Kconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b45fb799e36c..5ee11a889867 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -629,7 +629,6 @@ config GPIO_ROCKCHIP
config GPIO_RTD
tristate "Realtek DHC GPIO support"
depends on ARCH_REALTEK || COMPILE_TEST
- default y
select GPIOLIB_IRQCHIP
help
This option enables support for GPIOs found on Realtek DHC(Digital
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v2 2/4] MAINTAINERS: Add entry for the UltraRISC DP1000 PCIe controller driver and its DT binding
From: Jia Wang @ 2026-04-08 2:42 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Jia Wang, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas, Jingoo Han,
Xincheng Zhang, Krzysztof Kozlowski, Conor Dooley, linux-riscv,
linux-kernel, linux-pci, devicetree
In-Reply-To: <20260407-gentle-warping-tanuki-0edbda@quoll>
On 2026-04-07 09:44 +0200, Krzysztof Kozlowski wrote:
> On Tue, Apr 07, 2026 at 10:40:53AM +0800, Jia Wang wrote:
> > Add a MAINTAINERS entry for the UltraRISC DP1000 PCIe host driver and its
> > DT binding.
> >
> > Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> > ---
> > MAINTAINERS | 8 ++++++++
> > 1 file changed, 8 insertions(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index c3fe46d7c4bc..c8159670a14d 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -20582,6 +20582,14 @@ S: Maintained
> > F: Documentation/devicetree/bindings/pci/starfive,jh7110-pcie.yaml
> > F: drivers/pci/controller/plda/pcie-starfive.c
> >
> > +PCIE DRIVER FOR ULTRARISC DP1000
> > +M: Xincheng Zhang <zhangxincheng@ultrarisc.com>
> > +M: Jia Wang <wangjia@ultrarisc.com>
> > +L: linux-pci@vger.kernel.org
> > +S: Maintained
> > +F: Documentation/devicetree/bindings/pci/ultrarisc,dp1000-pcie.yaml
>
> There is no such file.
>
> This is not supposed to be a separate commit.
>
Hi Krzysztof,
Thanks for the review.
In the next version I will fold this patch into the commit that adds the
actual driver and DT binding, so the referenced files will exist.
> > +F: drivers/pci/controller/dwc/pcie-ultrarisc.c
>
> No such file.
>
> Best regards,
> Krzysztof
>
>
Best regards,
Jia Wang
^ permalink raw reply
* Re: [PATCH v2 1/4] riscv: add UltraRISC SoC family Kconfig support
From: Jia Wang @ 2026-04-08 1:47 UTC (permalink / raw)
To: Conor Dooley
Cc: Jia Wang, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Bjorn Helgaas, Jingoo Han,
Xincheng Zhang, Krzysztof Kozlowski, Conor Dooley, linux-riscv,
linux-kernel, linux-pci, devicetree
In-Reply-To: <20260407-shown-guileless-5c8b8d94f5e5@spud>
On 2026-04-07 17:29 +0100, Conor Dooley wrote:
> On Tue, Apr 07, 2026 at 10:40:52AM +0800, Jia Wang wrote:
> > The first SoC in the UltraRISC series is UR-DP1000, containing octa
> > UltraRISC C100 cores.
>
> Not gonna lie, I find it odd that pcie is where this platform starts
> off, but sure. What's the plan for adding the rest of the platform?
>
Hi Conor,
Thanks for the question.
Our next step is to upstream the pinctrl driver together with the related
DTS updates. The pinctrl series only affects the SoC’s low-speed peripheral
interfaces. For GMAC, SPI, I2C, and GPIO, we plan to use the existing
kernel drivers, so no new controller drivers are needed
> >
> > Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> > ---
> > arch/riscv/Kconfig.socs | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
> > index d621b85dd63b..98708569ec6a 100644
> > --- a/arch/riscv/Kconfig.socs
> > +++ b/arch/riscv/Kconfig.socs
> > @@ -84,6 +84,15 @@ config ARCH_THEAD
> > help
> > This enables support for the RISC-V based T-HEAD SoCs.
> >
> > +config ARCH_ULTRARISC
> > + bool "UltraRISC RISC-V SoCs"
> > + help
> > + This enables support for UltraRISC SoC platform hardware,
> > + including boards based on the UR-DP1000.
>
> > + UR-DP1000 is an 8-core 64-bit RISC-V SoC that supports
> > + the RV64GCBHX ISA. It supports Hardware Virtualization
> > + and RISC-V RV64 ISA H(v1.0) Extension.
>
> Delete this section IMO, doesn't provide any real value. Don't need nor
> want the marketing brochure in the help text. The first sentence is
> sufficient.
>
I’ll drop the SoC description part from the Kconfig help text as you
suggested.
> > +
> > config ARCH_VIRT
> > bool "QEMU Virt Machine"
> > select POWER_RESET
> >
> > --
> > 2.34.1
> >
Best regards,
Jia Wang
^ permalink raw reply
* [PATCH RFC v3 7/7] arm64: dts: qcom: milos: Add Adreno 810 GPU and GMU nodes
From: Alexander Koskovich @ 2026-04-08 1:46 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich, Konrad Dybcio,
Dmitry Baryshkov
In-Reply-To: <20260407-adreno-810-v3-0-30cb7f196ed4@pm.me>
Add GPU and GMU devicetree nodes for the Adreno 810 GPU found on
Qualcomm SM7635 (Milos) based devices.
The qcom,kaanapali-gxclkctl.h header can be reused here because
Milos uses the same driver and the GX_CLKCTL_GX_GDSC definition
is identical.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
arch/arm64/boot/dts/qcom/milos.dtsi | 146 ++++++++++++++++++++++++++++++++++++
1 file changed, 146 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/milos.dtsi b/arch/arm64/boot/dts/qcom/milos.dtsi
index 621f05820826..0ffd77048659 100644
--- a/arch/arm64/boot/dts/qcom/milos.dtsi
+++ b/arch/arm64/boot/dts/qcom/milos.dtsi
@@ -3,6 +3,7 @@
* Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
*/
+#include <dt-bindings/clock/qcom,kaanapali-gxclkctl.h>
#include <dt-bindings/clock/qcom,milos-camcc.h>
#include <dt-bindings/clock/qcom,milos-dispcc.h>
#include <dt-bindings/clock/qcom,milos-gcc.h>
@@ -1224,6 +1225,151 @@ lpass_ag_noc: interconnect@3c40000 {
qcom,bcm-voters = <&apps_bcm_voter>;
};
+ gpu: gpu@3d00000 {
+ compatible = "qcom,adreno-44010000", "qcom,adreno";
+ reg = <0x0 0x03d00000 0x0 0x40000>,
+ <0x0 0x03d9e000 0x0 0x2000>,
+ <0x0 0x03d61000 0x0 0x800>;
+ reg-names = "kgsl_3d0_reg_memory",
+ "cx_mem",
+ "cx_dbgc";
+
+ interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH 0>;
+
+ iommus = <&adreno_smmu 0 0x0>;
+
+ operating-points-v2 = <&gpu_opp_table>;
+
+ qcom,gmu = <&gmu>;
+ #cooling-cells = <2>;
+
+ interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS
+ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+ interconnect-names = "gfx-mem";
+
+ status = "disabled";
+
+ gpu_zap_shader: zap-shader {
+ memory-region = <&gpu_microcode_mem>;
+ };
+
+ gpu_opp_table: opp-table {
+ compatible = "operating-points-v2-adreno",
+ "operating-points-v2";
+
+ opp-264000000 {
+ opp-hz = /bits/ 64 <264000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+ opp-peak-kBps = <2136718>;
+ qcom,opp-acd-level = <0xc8295ffd>;
+ };
+
+ opp-362000000 {
+ opp-hz = /bits/ 64 <362000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ opp-peak-kBps = <2136718>;
+ qcom,opp-acd-level = <0xc02c5ffd>;
+ };
+
+ opp-510000000 {
+ opp-hz = /bits/ 64 <510000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ opp-peak-kBps = <3972656>;
+ qcom,opp-acd-level = <0x882b5ffd>;
+ };
+
+ opp-644000000 {
+ opp-hz = /bits/ 64 <644000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+ opp-peak-kBps = <5285156>;
+ qcom,opp-acd-level = <0x882a5ffd>;
+ };
+
+ opp-688000000 {
+ opp-hz = /bits/ 64 <688000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+ opp-peak-kBps = <6074218>;
+ qcom,opp-acd-level = <0x882a5ffd>;
+ };
+
+ opp-763000000 {
+ opp-hz = /bits/ 64 <763000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+ opp-peak-kBps = <6671875>;
+ qcom,opp-acd-level = <0xa8295ffd>;
+ };
+
+ opp-895000000 {
+ opp-hz = /bits/ 64 <895000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+ opp-peak-kBps = <8171875>;
+ qcom,opp-acd-level = <0x88295ffd>;
+ };
+
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+ opp-peak-kBps = <8171875>;
+ qcom,opp-acd-level = <0xa8285ffd>;
+ };
+
+ opp-1050000000 {
+ opp-hz = /bits/ 64 <1050000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+ opp-peak-kBps = <18597656>;
+ qcom,opp-acd-level = <0x88285ffd>;
+ };
+ };
+ };
+
+ gmu: gmu@3d37000 {
+ compatible = "qcom,adreno-gmu-810.0", "qcom,adreno-gmu";
+ reg = <0x0 0x03d37000 0x0 0x68000>;
+ reg-names = "gmu";
+
+ interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "hfi", "gmu";
+
+ clocks = <&gpucc GPU_CC_AHB_CLK>,
+ <&gpucc GPU_CC_CX_GMU_CLK>,
+ <&gpucc GPU_CC_CXO_CLK>,
+ <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+ <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&gpucc GPU_CC_HUB_CX_INT_CLK>;
+ clock-names = "ahb",
+ "gmu",
+ "cxo",
+ "axi",
+ "memnoc",
+ "hub";
+
+ power-domains = <&gpucc GPU_CC_CX_GDSC>,
+ <&gxclkctl GX_CLKCTL_GX_GDSC>;
+ power-domain-names = "cx",
+ "gx";
+
+ iommus = <&adreno_smmu 5 0x0>;
+
+ qcom,qmp = <&aoss_qmp>;
+
+ operating-points-v2 = <&gmu_opp_table>;
+
+ gmu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-350000000 {
+ opp-hz = /bits/ 64 <350000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+ };
+
+ opp-650000000 {
+ opp-hz = /bits/ 64 <650000000>;
+ opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+ };
+ };
+ };
+
gxclkctl: clock-controller@3d64000 {
compatible = "qcom,milos-gxclkctl";
reg = <0x0 0x03d64000 0x0 0x6000>;
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v3 6/7] drm/msm/adreno: add Adreno 810 GPU support
From: Alexander Koskovich @ 2026-04-08 1:46 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich
In-Reply-To: <20260407-adreno-810-v3-0-30cb7f196ed4@pm.me>
Add catalog entry and register configuration for the Adreno 810
found in Qualcomm SM7635 (Milos) based devices.
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 291 ++++++++++++++++++++++++++++++
drivers/gpu/drm/msm/adreno/adreno_gpu.h | 5 +
2 files changed, 296 insertions(+)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
index 550ff3a9b82e..328c624db7cb 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -1799,6 +1799,259 @@ static const struct adreno_reglist_pipe x285_dyn_pwrup_reglist_regs[] = {
};
DECLARE_ADRENO_REGLIST_PIPE_LIST(x285_dyn_pwrup_reglist);
+static const struct adreno_reglist_pipe a810_nonctxt_regs[] = {
+ { REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) },
+ { REG_A8XX_GRAS_DBG_ECO_CNTL, 0x00f80800, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A6XX_PC_AUTO_VERTEX_STRIDE, 0x00000001, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_VIS_STREAM_CNTL, 0x10010000, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CONTEXT_SWITCH_STABILIZE_CNTL_1, 0x00000002, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_1, 0x00000003, BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_1, 0x00000023, BIT(PIPE_BV) }, /* Avoid partial waves at VFD */
+ { REG_A8XX_PC_CHICKEN_BITS_2, 0x00000200, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_3, 0x00500000, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_4, 0x00500050, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A7XX_RB_CCU_CNTL, 0x00000068, BIT(PIPE_BR) },
+ { REG_A8XX_RB_RESOLVE_PREFETCH_CNTL, 0x00000007, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CMP_DBG_ECO_CNTL, 0x00004000, BIT(PIPE_BR) },
+ { REG_A8XX_RBBM_NC_MODE_CNTL, 0x00000001, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_SLICE_NC_MODE_CNTL, 0x00000001, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_WAIT_IDLE_CLOCKS_CNTL, 0x00000030, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_WAIT_IDLE_CLOCKS_CNTL2, 0x00000030, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_GBIF_GX_CONFIG, 0x010240e0, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x22122212, BIT(PIPE_NONE) },
+ { REG_A8XX_RBBM_CGC_P2S_CNTL, 0x00000040, BIT(PIPE_NONE) },
+ /*
+ * BIT(22): Disable PS out of order retire
+ * BIT(23): Enable half wave mode and MM instruction src&dst is half precision
+ */
+ { REG_A7XX_SP_CHICKEN_BITS_2, BIT(22) | BIT(23), BIT(PIPE_NONE) },
+ { REG_A7XX_SP_CHICKEN_BITS_3, 0x00300000, BIT(PIPE_NONE) },
+ { REG_A6XX_SP_PERFCTR_SHADER_MASK, 0x0000003f, BIT(PIPE_NONE) },
+ { REG_A7XX_SP_HLSQ_TIMEOUT_THRESHOLD_DP, 0x00000080, BIT(PIPE_NONE) },
+ { REG_A7XX_SP_READ_SEL, 0x0001ff00, BIT(PIPE_NONE) },
+ { REG_A6XX_TPL1_DBG_ECO_CNTL, 0x10000000, BIT(PIPE_NONE) },
+ { REG_A6XX_TPL1_DBG_ECO_CNTL1, 0x00000724, BIT(PIPE_NONE) },
+ { REG_A6XX_UCHE_MODE_CNTL, 0x00020000, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_CCHE_MODE_CNTL, 0x00001000, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_CCHE_CACHE_WAYS, 0x00000800, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_CACHE_WAYS, 0x00080000, BIT(PIPE_NONE) },
+ { REG_A8XX_UCHE_VARB_IDLE_TIMEOUT, 0x00000020, BIT(PIPE_NONE) },
+ { REG_A7XX_VFD_DBG_ECO_CNTL, 0x00008000, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BV_THRESHOLD, 0x00500050, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BR_THRESHOLD, 0x00600060, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BUSY_REQ_CNT, 0x00200020, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_LP_REQ_CNT, 0x00100020, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VPC_FLATSHADE_MODE_CNTL, 0x00000001, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VSC_BIN_SIZE, 0x00010001, BIT(PIPE_NONE) },
+ { REG_A8XX_RB_GC_GMEM_PROTECT, 0x00900000, BIT(PIPE_BR) },
+ { },
+};
+
+static const u32 a810_protect_regs[] = {
+ A6XX_PROTECT_RDONLY(0x00000, 0x03a3),
+ A6XX_PROTECT_RDONLY(0x003b4, 0x008b),
+ A6XX_PROTECT_NORDWR(0x00440, 0x001f),
+ A6XX_PROTECT_RDONLY(0x00580, 0x005f),
+ A6XX_PROTECT_NORDWR(0x005e0, 0x011f),
+ A6XX_PROTECT_RDONLY(0x0074a, 0x0005),
+ A6XX_PROTECT_RDONLY(0x00759, 0x0026),
+ A6XX_PROTECT_RDONLY(0x00789, 0x0000),
+ A6XX_PROTECT_RDONLY(0x0078c, 0x0013),
+ A6XX_PROTECT_NORDWR(0x00800, 0x0029),
+ A6XX_PROTECT_NORDWR(0x00837, 0x00af),
+ A6XX_PROTECT_RDONLY(0x008e7, 0x00c9),
+ A6XX_PROTECT_NORDWR(0x008ec, 0x00c3),
+ A6XX_PROTECT_NORDWR(0x009b1, 0x0250),
+ A6XX_PROTECT_RDONLY(0x00ce0, 0x0001),
+ A6XX_PROTECT_RDONLY(0x00df0, 0x0000),
+ A6XX_PROTECT_NORDWR(0x00df1, 0x0000),
+ A6XX_PROTECT_NORDWR(0x00e01, 0x0000),
+ A6XX_PROTECT_NORDWR(0x00e03, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x03c00, 0x00c5),
+ A6XX_PROTECT_RDONLY(0x03cc6, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x08600, 0x01ff),
+ A6XX_PROTECT_NORDWR(0x08e00, 0x00ff),
+ A6XX_PROTECT_RDONLY(0x08f00, 0x0000),
+ A6XX_PROTECT_NORDWR(0x08f01, 0x01be),
+ A6XX_PROTECT_NORDWR(0x09600, 0x01ff),
+ A6XX_PROTECT_RDONLY(0x0981a, 0x02e5),
+ A6XX_PROTECT_NORDWR(0x09e00, 0x01ff),
+ A6XX_PROTECT_NORDWR(0x0a600, 0x01ff),
+ A6XX_PROTECT_NORDWR(0x0ae00, 0x0006),
+ A6XX_PROTECT_NORDWR(0x0ae08, 0x0006),
+ A6XX_PROTECT_NORDWR(0x0ae10, 0x036f),
+ A6XX_PROTECT_NORDWR(0x0b600, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x0dc00, 0x1fff),
+ A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x18400, 0x003f),
+ A6XX_PROTECT_RDONLY(0x18440, 0x013f),
+ A6XX_PROTECT_NORDWR(0x18580, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x1b400, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x1f400, 0x0477),
+ A6XX_PROTECT_RDONLY(0x1f878, 0x0787),
+ A6XX_PROTECT_NORDWR(0x1f930, 0x0329),
+ A6XX_PROTECT_NORDWR(0x20000, 0x1fff),
+ A6XX_PROTECT_NORDWR(0x27800, 0x007f),
+ A6XX_PROTECT_RDONLY(0x27880, 0x0381),
+ A6XX_PROTECT_NORDWR(0x27882, 0x0001),
+ A6XX_PROTECT_NORDWR(0x27c02, 0x0000),
+};
+DECLARE_ADRENO_PROTECT(a810_protect, 64);
+
+static const uint32_t a810_pwrup_reglist_regs[] = {
+ REG_A6XX_UCHE_MODE_CNTL,
+ REG_A8XX_UCHE_VARB_IDLE_TIMEOUT,
+ REG_A8XX_UCHE_GBIF_GX_CONFIG,
+ REG_A8XX_UCHE_CACHE_WAYS,
+ REG_A8XX_UCHE_CCHE_MODE_CNTL,
+ REG_A8XX_UCHE_CCHE_CACHE_WAYS,
+ REG_A8XX_UCHE_CCHE_GC_GMEM_RANGE_MIN,
+ REG_A8XX_UCHE_CCHE_GC_GMEM_RANGE_MIN + 1,
+ REG_A8XX_UCHE_CCHE_TRAP_BASE,
+ REG_A8XX_UCHE_CCHE_TRAP_BASE + 1,
+ REG_A8XX_UCHE_CCHE_WRITE_THRU_BASE,
+ REG_A8XX_UCHE_CCHE_WRITE_THRU_BASE + 1,
+ REG_A8XX_UCHE_WRITE_THRU_BASE,
+ REG_A8XX_UCHE_WRITE_THRU_BASE + 1,
+ REG_A8XX_UCHE_TRAP_BASE,
+ REG_A8XX_UCHE_TRAP_BASE + 1,
+ REG_A8XX_UCHE_CLIENT_PF,
+ REG_A8XX_VSC_BIN_SIZE,
+ REG_A8XX_RB_CMP_NC_MODE_CNTL,
+ REG_A7XX_SP_HLSQ_TIMEOUT_THRESHOLD_DP,
+ REG_A8XX_SP_HLSQ_GC_GMEM_RANGE_MIN,
+ REG_A8XX_SP_HLSQ_GC_GMEM_RANGE_MIN + 1,
+ REG_A7XX_SP_READ_SEL,
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(1),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(2),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(3),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(4),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(5),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(6),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(7),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(8),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(9),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(10),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(11),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(12),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(13),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(14),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(15),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(16),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(17),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(18),
+ REG_A8XX_TPL1_BICUBIC_WEIGHTS_TABLE(19),
+};
+DECLARE_ADRENO_REGLIST_LIST(a810_pwrup_reglist);
+
+static const u32 a810_ifpc_reglist_regs[] = {
+ REG_A8XX_RBBM_NC_MODE_CNTL,
+ REG_A8XX_RBBM_PERFCTR_CNTL,
+ REG_A8XX_RBBM_SLICE_INTERFACE_HANG_INT_CNTL,
+ REG_A8XX_RBBM_SLICE_NC_MODE_CNTL,
+ REG_A6XX_SP_NC_MODE_CNTL,
+ REG_A7XX_SP_CHICKEN_BITS_2,
+ REG_A7XX_SP_CHICKEN_BITS_3,
+ REG_A6XX_SP_PERFCTR_SHADER_MASK,
+ REG_A6XX_TPL1_NC_MODE_CNTL,
+ REG_A6XX_TPL1_DBG_ECO_CNTL,
+ REG_A6XX_TPL1_DBG_ECO_CNTL1,
+ REG_A8XX_CP_PROTECT_GLOBAL(0),
+ REG_A8XX_CP_PROTECT_GLOBAL(1),
+ REG_A8XX_CP_PROTECT_GLOBAL(2),
+ REG_A8XX_CP_PROTECT_GLOBAL(3),
+ REG_A8XX_CP_PROTECT_GLOBAL(4),
+ REG_A8XX_CP_PROTECT_GLOBAL(5),
+ REG_A8XX_CP_PROTECT_GLOBAL(6),
+ REG_A8XX_CP_PROTECT_GLOBAL(7),
+ REG_A8XX_CP_PROTECT_GLOBAL(8),
+ REG_A8XX_CP_PROTECT_GLOBAL(9),
+ REG_A8XX_CP_PROTECT_GLOBAL(10),
+ REG_A8XX_CP_PROTECT_GLOBAL(11),
+ REG_A8XX_CP_PROTECT_GLOBAL(12),
+ REG_A8XX_CP_PROTECT_GLOBAL(13),
+ REG_A8XX_CP_PROTECT_GLOBAL(14),
+ REG_A8XX_CP_PROTECT_GLOBAL(15),
+ REG_A8XX_CP_PROTECT_GLOBAL(16),
+ REG_A8XX_CP_PROTECT_GLOBAL(17),
+ REG_A8XX_CP_PROTECT_GLOBAL(18),
+ REG_A8XX_CP_PROTECT_GLOBAL(19),
+ REG_A8XX_CP_PROTECT_GLOBAL(20),
+ REG_A8XX_CP_PROTECT_GLOBAL(21),
+ REG_A8XX_CP_PROTECT_GLOBAL(22),
+ REG_A8XX_CP_PROTECT_GLOBAL(23),
+ REG_A8XX_CP_PROTECT_GLOBAL(24),
+ REG_A8XX_CP_PROTECT_GLOBAL(25),
+ REG_A8XX_CP_PROTECT_GLOBAL(26),
+ REG_A8XX_CP_PROTECT_GLOBAL(27),
+ REG_A8XX_CP_PROTECT_GLOBAL(28),
+ REG_A8XX_CP_PROTECT_GLOBAL(29),
+ REG_A8XX_CP_PROTECT_GLOBAL(30),
+ REG_A8XX_CP_PROTECT_GLOBAL(31),
+ REG_A8XX_CP_PROTECT_GLOBAL(32),
+ REG_A8XX_CP_PROTECT_GLOBAL(33),
+ REG_A8XX_CP_PROTECT_GLOBAL(34),
+ REG_A8XX_CP_PROTECT_GLOBAL(35),
+ REG_A8XX_CP_PROTECT_GLOBAL(36),
+ REG_A8XX_CP_PROTECT_GLOBAL(37),
+ REG_A8XX_CP_PROTECT_GLOBAL(38),
+ REG_A8XX_CP_PROTECT_GLOBAL(39),
+ REG_A8XX_CP_PROTECT_GLOBAL(40),
+ REG_A8XX_CP_PROTECT_GLOBAL(41),
+ REG_A8XX_CP_PROTECT_GLOBAL(42),
+ REG_A8XX_CP_PROTECT_GLOBAL(43),
+ REG_A8XX_CP_PROTECT_GLOBAL(44),
+ REG_A8XX_CP_PROTECT_GLOBAL(45),
+ REG_A8XX_CP_PROTECT_GLOBAL(46),
+ REG_A8XX_CP_PROTECT_GLOBAL(47),
+ REG_A8XX_CP_PROTECT_GLOBAL(48),
+ REG_A8XX_CP_PROTECT_GLOBAL(49),
+ REG_A8XX_CP_PROTECT_GLOBAL(50),
+ REG_A8XX_CP_PROTECT_GLOBAL(51),
+ REG_A8XX_CP_PROTECT_GLOBAL(52),
+ REG_A8XX_CP_PROTECT_GLOBAL(53),
+ REG_A8XX_CP_PROTECT_GLOBAL(54),
+ REG_A8XX_CP_PROTECT_GLOBAL(55),
+ REG_A8XX_CP_PROTECT_GLOBAL(56),
+ REG_A8XX_CP_PROTECT_GLOBAL(57),
+ REG_A8XX_CP_PROTECT_GLOBAL(58),
+ REG_A8XX_CP_PROTECT_GLOBAL(59),
+ REG_A8XX_CP_PROTECT_GLOBAL(60),
+ REG_A8XX_CP_PROTECT_GLOBAL(61),
+ REG_A8XX_CP_PROTECT_GLOBAL(62),
+ REG_A8XX_CP_PROTECT_GLOBAL(63),
+};
+DECLARE_ADRENO_REGLIST_LIST(a810_ifpc_reglist);
+
+static const struct adreno_reglist_pipe a810_dyn_pwrup_reglist_regs[] = {
+ { REG_A8XX_CP_PROTECT_CNTL_PIPE, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_CP_PROTECT_PIPE(15), 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_GRAS_TSEFE_DBG_ECO_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_GRAS_NC_MODE_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_GRAS_DBG_ECO_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A7XX_RB_CCU_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CCU_NC_MODE_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CMP_NC_MODE_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_RESOLVE_PREFETCH_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_CMP_DBG_ECO_CNTL, 0, BIT(PIPE_BR) },
+ { REG_A8XX_RB_GC_GMEM_PROTECT, 0, BIT(PIPE_BR) },
+ { REG_A6XX_RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE_ENABLE, 0, BIT(PIPE_BR) },
+ { REG_A8XX_VPC_FLATSHADE_MODE_CNTL, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_1, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_2, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_3, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_PC_CHICKEN_BITS_4, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A6XX_PC_AUTO_VERTEX_STRIDE, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_PC_VIS_STREAM_CNTL, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_PC_CONTEXT_SWITCH_STABILIZE_CNTL_1, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+ { REG_A8XX_VFD_CB_BV_THRESHOLD, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BR_THRESHOLD, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_BUSY_REQ_CNT, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A8XX_VFD_CB_LP_REQ_CNT, 0, BIT(PIPE_BV) | BIT(PIPE_BR) },
+ { REG_A7XX_VFD_DBG_ECO_CNTL, 0, BIT(PIPE_BR) | BIT(PIPE_BV) },
+};
+DECLARE_ADRENO_REGLIST_PIPE_LIST(a810_dyn_pwrup_reglist);
+
static const struct adreno_reglist_pipe a840_nonctxt_regs[] = {
{ REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) },
{ REG_A8XX_GRAS_DBG_ECO_CNTL, 0x00000800, BIT(PIPE_BV) | BIT(PIPE_BR) },
@@ -2193,6 +2446,43 @@ static const struct adreno_info a8xx_gpus[] = {
{ 252, 2 },
{ 221, 3 },
),
+ }, {
+ .chip_ids = ADRENO_CHIP_IDS(0x44010000),
+ .family = ADRENO_8XX_GEN1,
+ .fw = {
+ [ADRENO_FW_SQE] = "gen80300_sqe.fw",
+ [ADRENO_FW_GMU] = "gen80300_gmu.bin",
+ },
+ .gmem = SZ_512K + SZ_64K,
+ .inactive_period = DRM_MSM_INACTIVE_PERIOD,
+ .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+ ADRENO_QUIRK_HAS_HW_APRIV |
+ ADRENO_QUIRK_PREEMPTION |
+ ADRENO_QUIRK_IFPC,
+ .funcs = &a8xx_gpu_funcs,
+ .zapfw = "gen80300_zap.mbn",
+ .a6xx = &(const struct a6xx_info) {
+ .protect = &a810_protect,
+ .nonctxt_reglist = a810_nonctxt_regs,
+ .pwrup_reglist = &a810_pwrup_reglist,
+ .dyn_pwrup_reglist = &a810_dyn_pwrup_reglist,
+ .ifpc_reglist = &a810_ifpc_reglist,
+ .gbif_cx = a840_gbif,
+ .max_slices = 1,
+ .gmu_chipid = 0x8030000,
+ .bcms = (const struct a6xx_bcm[]) {
+ { .name = "SH0", .buswidth = 16 },
+ { .name = "MC0", .buswidth = 4 },
+ {
+ .name = "ACV",
+ .fixed = true,
+ .perfmode = BIT(2),
+ .perfmode_bw = 10687500,
+ },
+ { /* sentinel */ },
+ },
+ },
+ .preempt_record_size = 4558 * SZ_1K,
}
};
@@ -2205,4 +2495,5 @@ static inline __always_unused void __build_asserts(void)
BUILD_BUG_ON(a660_protect.count > a660_protect.count_max);
BUILD_BUG_ON(a690_protect.count > a690_protect.count_max);
BUILD_BUG_ON(a730_protect.count > a730_protect.count_max);
+ BUILD_BUG_ON(a810_protect.count > a810_protect.count_max);
}
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index c0ee544ce257..d474d88b9152 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -596,6 +596,11 @@ static inline int adreno_is_a8xx(struct adreno_gpu *gpu)
return gpu->info->family >= ADRENO_8XX_GEN1;
}
+static inline int adreno_is_a810(struct adreno_gpu *gpu)
+{
+ return gpu->info->chip_ids[0] == 0x44010000;
+}
+
static inline int adreno_is_x285(struct adreno_gpu *gpu)
{
return gpu->info->chip_ids[0] == 0x44070001;
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v3 5/7] drm/msm/a8xx: use pipe protect slot 15 for last-span-unbound feature
From: Alexander Koskovich @ 2026-04-08 1:46 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich, Konrad Dybcio
In-Reply-To: <20260407-adreno-810-v3-0-30cb7f196ed4@pm.me>
A8XX GPUs have two sets of protect registers: 64 global slots and 16
pipe specific slots. The last-span-unbound feature is only available
on pipe protect registers, and should always target pipe slot 15.
This matches the downstream driver which hardcodes pipe slot 15 for
all A8XX GPUs (GRAPHICS.LA.15.0.r1) and resolves protect errors on
A810.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a8xx_gpu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
index 1515ade22578..89a494bcea74 100644
--- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
@@ -255,8 +255,8 @@ static void a8xx_set_cp_protect(struct msm_gpu *gpu)
* Last span feature is only supported on PIPE specific register.
* So update those here
*/
- a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_CP_PROTECT_PIPE(protect->count_max), final_cfg);
- a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_CP_PROTECT_PIPE(protect->count_max), final_cfg);
+ a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_CP_PROTECT_PIPE(15), final_cfg);
+ a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_CP_PROTECT_PIPE(15), final_cfg);
a8xx_aperture_clear(gpu);
}
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v3 4/7] drm/msm/adreno: set cx_misc_mmio regardless of if platform has LLCC
From: Alexander Koskovich @ 2026-04-08 1:45 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich, Konrad Dybcio
In-Reply-To: <20260407-adreno-810-v3-0-30cb7f196ed4@pm.me>
Platforms without a LLCC (e.g. milos) still need to be able to read and
write to the cx_mem region. Previously if LLCC slices were unavailable
the cx_misc_mmio mapping was overwritten with ERR_PTR, causing a crash
when the GMU later accessed cx_mem.
Move the cx_misc_mmio mapping out of a6xx_llc_slices_init() into
a6xx_gpu_init() so that cx_mem mapping is independent of LLCC.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 38 ++++++++++++++++-------------------
1 file changed, 17 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 9847f83b92af..d691ad1f88b3 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -2039,7 +2039,7 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct msm_gpu *gpu = &adreno_gpu->base;
u32 cntl1_regval = 0;
- if (IS_ERR(a6xx_gpu->cx_misc_mmio))
+ if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2098,7 +2098,7 @@ static void a7xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
struct msm_gpu *gpu = &adreno_gpu->base;
- if (IS_ERR(a6xx_gpu->cx_misc_mmio))
+ if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2135,31 +2135,12 @@ static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu)
static void a6xx_llc_slices_init(struct platform_device *pdev,
struct a6xx_gpu *a6xx_gpu, bool is_a7xx)
{
- struct device_node *phandle;
-
/* No LLCC on non-RPMh (and by extension, non-GMU) SoCs */
if (adreno_has_gmu_wrapper(&a6xx_gpu->base))
return;
- /*
- * There is a different programming path for A6xx targets with an
- * mmu500 attached, so detect if that is the case
- */
- phandle = of_parse_phandle(pdev->dev.of_node, "iommus", 0);
- a6xx_gpu->have_mmu500 = (phandle &&
- of_device_is_compatible(phandle, "arm,mmu-500"));
- of_node_put(phandle);
-
- if (is_a7xx || !a6xx_gpu->have_mmu500)
- a6xx_gpu->cx_misc_mmio = msm_ioremap(pdev, "cx_mem");
- else
- a6xx_gpu->cx_misc_mmio = NULL;
-
a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU);
a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
-
- if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
- a6xx_gpu->cx_misc_mmio = ERR_PTR(-EINVAL);
}
#define GBIF_CLIENT_HALT_MASK BIT(0)
@@ -2621,6 +2602,7 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
struct platform_device *pdev = priv->gpu_pdev;
struct adreno_platform_config *config = pdev->dev.platform_data;
const struct adreno_info *info = config->info;
+ struct device_node *phandle;
struct device_node *node;
struct a6xx_gpu *a6xx_gpu;
struct adreno_gpu *adreno_gpu;
@@ -2656,6 +2638,20 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
+ /*
+ * There is a different programming path for A6xx targets with an
+ * mmu500 attached, so detect if that is the case
+ */
+ phandle = of_parse_phandle(pdev->dev.of_node, "iommus", 0);
+ a6xx_gpu->have_mmu500 = (phandle &&
+ of_device_is_compatible(phandle, "arm,mmu-500"));
+ of_node_put(phandle);
+
+ if (is_a7xx || !a6xx_gpu->have_mmu500)
+ a6xx_gpu->cx_misc_mmio = msm_ioremap(pdev, "cx_mem");
+ else
+ a6xx_gpu->cx_misc_mmio = NULL;
+
ret = a6xx_set_supported_hw(&pdev->dev, a6xx_gpu, info);
if (ret) {
a6xx_llc_slices_destroy(a6xx_gpu);
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v3 3/7] drm/msm/adreno: rename llc_mmio to cx_misc_mmio
From: Alexander Koskovich @ 2026-04-08 1:45 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich
In-Reply-To: <20260407-adreno-810-v3-0-30cb7f196ed4@pm.me>
This region is used for more than just LLCC, it also provides access to
software fuse values (raytracing, etc).
Rename relevant symbols from _llc to _cx_misc for use in a follow up
change that decouples this from LLCC.
Reviewed-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++++----
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 16 ++++++++--------
drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 14 +++++++-------
drivers/gpu/drm/msm/adreno/a8xx_gpu.c | 2 +-
4 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index b7166a883b01..6a369682bb80 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -947,7 +947,7 @@ static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
/* Turn on TCM (Tightly Coupled Memory) retention */
if (adreno_is_a7xx(adreno_gpu))
- a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);
+ a6xx_cx_misc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);
else if (!adreno_is_a8xx(adreno_gpu))
gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
@@ -1215,7 +1215,7 @@ static int a6xx_gmu_secure_init(struct a6xx_gpu *a6xx_gpu)
if (!qcom_scm_is_available()) {
dev_warn_once(gpu->dev->dev,
"SCM is not available, poking fuse register\n");
- a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
+ a6xx_cx_misc_write(a6xx_gpu, REG_A7XX_CX_MISC_SW_FUSE_VALUE,
A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING |
A7XX_CX_MISC_SW_FUSE_VALUE_FASTBLEND |
A7XX_CX_MISC_SW_FUSE_VALUE_LPAC);
@@ -1236,7 +1236,7 @@ static int a6xx_gmu_secure_init(struct a6xx_gpu *a6xx_gpu)
* firmware, find out whether that's the case. The scm call
* above sets the fuse register.
*/
- fuse_val = a6xx_llc_read(a6xx_gpu,
+ fuse_val = a6xx_cx_misc_read(a6xx_gpu,
REG_A7XX_CX_MISC_SW_FUSE_VALUE);
adreno_gpu->has_ray_tracing =
!!(fuse_val & A7XX_CX_MISC_SW_FUSE_VALUE_RAYTRACING);
@@ -1343,7 +1343,7 @@ int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
/* Check to see if we are doing a cold or warm boot */
if (adreno_is_a7xx(adreno_gpu) || adreno_is_a8xx(adreno_gpu)) {
- status = a6xx_llc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?
+ status = a6xx_cx_misc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?
GMU_WARM_BOOT : GMU_COLD_BOOT;
} else if (gmu->legacy) {
status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index e1eae6cb1e40..9847f83b92af 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -2039,7 +2039,7 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct msm_gpu *gpu = &adreno_gpu->base;
u32 cntl1_regval = 0;
- if (IS_ERR(a6xx_gpu->llc_mmio))
+ if (IS_ERR(a6xx_gpu->cx_misc_mmio))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2078,14 +2078,14 @@ static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
* pagetables
*/
if (!a6xx_gpu->have_mmu500) {
- a6xx_llc_write(a6xx_gpu,
+ a6xx_cx_misc_write(a6xx_gpu,
REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval);
/*
* Program cacheability overrides to not allocate cache
* lines on a write miss
*/
- a6xx_llc_rmw(a6xx_gpu,
+ a6xx_cx_misc_rmw(a6xx_gpu,
REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03);
return;
}
@@ -2098,7 +2098,7 @@ static void a7xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
struct msm_gpu *gpu = &adreno_gpu->base;
- if (IS_ERR(a6xx_gpu->llc_mmio))
+ if (IS_ERR(a6xx_gpu->cx_misc_mmio))
return;
if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
@@ -2151,15 +2151,15 @@ static void a6xx_llc_slices_init(struct platform_device *pdev,
of_node_put(phandle);
if (is_a7xx || !a6xx_gpu->have_mmu500)
- a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem");
+ a6xx_gpu->cx_misc_mmio = msm_ioremap(pdev, "cx_mem");
else
- a6xx_gpu->llc_mmio = NULL;
+ a6xx_gpu->cx_misc_mmio = NULL;
a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU);
a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
- a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
+ a6xx_gpu->cx_misc_mmio = ERR_PTR(-EINVAL);
}
#define GBIF_CLIENT_HALT_MASK BIT(0)
@@ -2560,7 +2560,7 @@ static int a6xx_read_speedbin(struct device *dev, struct a6xx_gpu *a6xx_gpu,
return ret;
if (info->quirks & ADRENO_QUIRK_SOFTFUSE) {
- *speedbin = a6xx_llc_read(a6xx_gpu, REG_A8XX_CX_MISC_SW_FUSE_FREQ_LIMIT_STATUS);
+ *speedbin = a6xx_cx_misc_read(a6xx_gpu, REG_A8XX_CX_MISC_SW_FUSE_FREQ_LIMIT_STATUS);
*speedbin = A8XX_CX_MISC_SW_FUSE_FREQ_LIMIT_STATUS_FINALFREQLIMIT(*speedbin);
return 0;
}
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index eb431e5e00b1..648608c1c98e 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -102,7 +102,7 @@ struct a6xx_gpu {
bool has_whereami;
- void __iomem *llc_mmio;
+ void __iomem *cx_misc_mmio;
void *llc_slice;
void *htw_llc_slice;
bool have_mmu500;
@@ -240,19 +240,19 @@ static inline bool a6xx_has_gbif(struct adreno_gpu *gpu)
return true;
}
-static inline void a6xx_llc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
+static inline void a6xx_cx_misc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
{
- return msm_rmw(a6xx_gpu->llc_mmio + (reg << 2), mask, or);
+ return msm_rmw(a6xx_gpu->cx_misc_mmio + (reg << 2), mask, or);
}
-static inline u32 a6xx_llc_read(struct a6xx_gpu *a6xx_gpu, u32 reg)
+static inline u32 a6xx_cx_misc_read(struct a6xx_gpu *a6xx_gpu, u32 reg)
{
- return readl(a6xx_gpu->llc_mmio + (reg << 2));
+ return readl(a6xx_gpu->cx_misc_mmio + (reg << 2));
}
-static inline void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
+static inline void a6xx_cx_misc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
{
- writel(value, a6xx_gpu->llc_mmio + (reg << 2));
+ writel(value, a6xx_gpu->cx_misc_mmio + (reg << 2));
}
#define shadowptr(_a6xx_gpu, _ring) ((_a6xx_gpu)->shadow_iova + \
diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
index edfd04bf6cd1..1515ade22578 100644
--- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c
@@ -103,7 +103,7 @@ void a8xx_gpu_get_slice_info(struct msm_gpu *gpu)
return;
}
- slice_mask &= a6xx_llc_read(a6xx_gpu,
+ slice_mask &= a6xx_cx_misc_read(a6xx_gpu,
REG_A8XX_CX_MISC_SLICE_ENABLE_FINAL);
a6xx_gpu->slice_mask = slice_mask;
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v3 2/7] dt-bindings: display/msm/gpu: Document A810 GPU
From: Alexander Koskovich @ 2026-04-08 1:45 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich
In-Reply-To: <20260407-adreno-810-v3-0-30cb7f196ed4@pm.me>
Document the GPU compatible string used for the Adreno 810.
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
Documentation/devicetree/bindings/display/msm/gpu.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/display/msm/gpu.yaml b/Documentation/devicetree/bindings/display/msm/gpu.yaml
index ec84b64d4c00..90ae435146d5 100644
--- a/Documentation/devicetree/bindings/display/msm/gpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gpu.yaml
@@ -434,6 +434,7 @@ allOf:
- qcom,adreno-43050a01
- qcom,adreno-43050c01
- qcom,adreno-43051401
+ - qcom,adreno-44010000
then: # Starting with A6xx, the clocks are usually defined in the GMU node
properties:
--
2.53.0
^ permalink raw reply related
* [PATCH RFC v3 1/7] dt-bindings: display/msm/gmu: Document Adreno 810 GMU
From: Alexander Koskovich @ 2026-04-08 1:45 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Konrad Dybcio, Akhil P Oommen,
Bjorn Andersson
Cc: Luca Weiss, linux-arm-msm, dri-devel, freedreno, devicetree,
linux-kernel, Alexander Koskovich, Krzysztof Kozlowski
In-Reply-To: <20260407-adreno-810-v3-0-30cb7f196ed4@pm.me>
Document Adreno 810 GMU in the dt-binding specification.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Alexander Koskovich <akoskovich@pm.me>
---
.../devicetree/bindings/display/msm/gmu.yaml | 30 ++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml b/Documentation/devicetree/bindings/display/msm/gmu.yaml
index e32056ae0f5d..cc03cda67ea7 100644
--- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
@@ -299,6 +299,36 @@ allOf:
required:
- qcom,qmp
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,adreno-gmu-810.0
+ then:
+ properties:
+ reg:
+ items:
+ - description: Core GMU registers
+ reg-names:
+ items:
+ - const: gmu
+ clocks:
+ items:
+ - description: GPU AHB clock
+ - description: GMU clock
+ - description: GPU CX clock
+ - description: GPU AXI clock
+ - description: GPU MEMNOC clock
+ - description: GMU HUB clock
+ clock-names:
+ items:
+ - const: ahb
+ - const: gmu
+ - const: cxo
+ - const: axi
+ - const: memnoc
+ - const: hub
+
- if:
properties:
compatible:
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox