* Re: [PATCH v9 0/4] Introduce ASPEED AST27xx BMC SoC
From: patchwork-bot+linux-riscv @ 2026-06-26 8:21 UTC (permalink / raw)
To: Ryan Chen
Cc: linux-riscv, robh, krzk+dt, conor+dt, joel, andrew,
catalin.marinas, will, arnd, krzk, alexandre.belloni, linusw,
fustini, pjw, palmer, aou, alex, devicetree, linux-arm-kernel,
linux-aspeed, linux-kernel, soc, conor.dooley
In-Reply-To: <20260609-upstream_ast2700-v9-0-f631752f0cb1@aspeedtech.com>
Hello:
This series was applied to riscv/linux.git (fixes)
by Arnd Bergmann <arnd@arndb.de>:
On Tue, 9 Jun 2026 10:47:17 +0800 you wrote:
> This introduces initial support for the Aspeed AST27xx SoC and the AST2700
> Evaluation Board (EVB) to the Linux kernel. The AST27xx is the 8th
> generation Baseboard Management Controller (BMC) SoC from Aspeed,
> featuring improved performance, enhanced security, and expanded I/O
> capabilities compared to previous generations.
>
> AST27xx SOC Family
> - https://www.aspeedtech.com/server_ast2700/
> - https://www.aspeedtech.com/server_ast2720/
> - https://www.aspeedtech.com/server_ast2750/
>
> [...]
Here is the summary with links:
- [v9,1/4] dt-bindings: arm: aspeed: Add AST2700 board compatible
https://git.kernel.org/riscv/c/34efd73379ff
- [v9,2/4] arm64: Kconfig: Add ASPEED SoC family Kconfig support
https://git.kernel.org/riscv/c/df6f379eb4ac
- [v9,3/4] arm64: dts: aspeed: Add initial AST27xx SoC device tree
https://git.kernel.org/riscv/c/e77bb5dc5759
- [v9,4/4] arm64: configs: Update defconfig for AST2700 platform support
https://git.kernel.org/riscv/c/512cef2af615
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v3 00/11] kdump: reduce vmcore size and capture time
From: patchwork-bot+linux-riscv @ 2026-06-26 8:21 UTC (permalink / raw)
To: Wandun
Cc: linux-riscv, linux-arm-kernel, linux-kernel, loongarch,
devicetree, kexec, iommu, zhaomeijing, catalin.marinas, will,
chenhuacai, kernel, pjw, palmer, aou, alex, robh, saravanak, akpm,
bhe, rppt, pasha.tatashin, pratyush, ruirui.yang, m.szyprowski,
robin.murphy, quic_obabatun
In-Reply-To: <20260527032917.3385849-1-chenwandun1@gmail.com>
Hello:
This series was applied to riscv/linux.git (fixes)
by Rob Herring (Arm) <robh@kernel.org>:
On Wed, 27 May 2026 11:29:06 +0800 you wrote:
> From: Wandun Chen <chenwandun@lixiang.com>
>
> On SoCs that carve out large firmware-owned reserved memory (GPU
> firmware, DSP, modem, camera ISP, NPU, ...), kdump currently dumps
> those carveouts as part of system RAM even though their contents are
> firmware state that is not useful for kernel crash analysis.
>
> [...]
Here is the summary with links:
- [v3,01/11] of: reserved_mem: handle NULL name in of_reserved_mem_lookup()
https://git.kernel.org/riscv/c/cfba13a18672
- [v3,02/11] kexec/crash: provide crash_exclude_mem_range() stub when CONFIG_CRASH_DUMP=n
(no matching commit)
- [v3,03/11] of: reserved_mem: avoid post-init UAF when alloc_reserved_mem_array() fails
(no matching commit)
- [v3,04/11] of: reserved_mem: zero total_reserved_mem_cnt if no valid /reserved-memory entry
https://git.kernel.org/riscv/c/50a488de5fcc
- [v3,05/11] of: reserved_mem: split alloc_reserved_mem_array() from fdt_scan_reserved_mem_late()
(no matching commit)
- [v3,06/11] of: reserved_mem: add dumpable flag to opt-in vmcore
(no matching commit)
- [v3,07/11] of: reserved_mem: save /memreserve/ entries into the reserved_mem array
(no matching commit)
- [v3,08/11] of: reserved_mem: add kdump helpers to exclude non-dumpable regions
(no matching commit)
- [v3,09/11] arm64: kdump: exclude non-dumpable reserved memory regions from vmcore
(no matching commit)
- [v3,10/11] riscv: kdump: exclude non-dumpable reserved memory regions from vmcore
(no matching commit)
- [v3,11/11] loongarch: kdump: exclude non-dumpable reserved memory regions from vmcore
(no matching commit)
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v1] dt-bindings: soc: microchip: document irqmux on pic64gx
From: patchwork-bot+linux-riscv @ 2026-06-26 8:21 UTC (permalink / raw)
To: Conor Dooley
Cc: linux-riscv, conor.dooley, daire.mcnamara, robh, krzk+dt,
devicetree, linux-kernel
In-Reply-To: <20260407-headache-reward-ae93bacdba0e@spud>
Hello:
This patch was applied to riscv/linux.git (fixes)
by Conor Dooley <conor.dooley@microchip.com>:
On Tue, 7 Apr 2026 16:29:31 +0100 you wrote:
> From: Conor Dooley <conor.dooley@microchip.com>
>
> Being practically identical to PolarFire SoC, pic64gx has a irqmux
> that's entirely compatible with that on mpfs.
>
> Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
>
> [...]
Here is the summary with links:
- [v1] dt-bindings: soc: microchip: document irqmux on pic64gx
https://git.kernel.org/riscv/c/17d9064987ca
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v5 0/9] driver core: Fix some race conditions
From: patchwork-bot+linux-riscv @ 2026-06-26 8:21 UTC (permalink / raw)
To: Doug Anderson
Cc: linux-riscv, gregkh, rafael, dakr, stern, aik, johan, edumazet,
leon, hch, robin.murphy, maz, aleksander.lobakin, saravanak, akpm,
Frank.Li, jgg, alex, alexander.stein, andre.przywara, andrew,
andrew, andriy.shevchenko, aou, ardb, astewart, bhelgaas, brgl,
broonie, catalin.marinas, chleroy, davem, david, devicetree,
dmaengine, driver-core, gbatra, gregory.clement, hkallweit1,
iommu, jirislaby, joel, joro, kees, kevin.brodsky, kuba, lenb,
lgirdwood, linux-acpi, linux-arm-kernel, linux-aspeed, linux-cxl,
linux-kernel, linux-mips, linux-mm, linux-pci, linux-serial,
linux-snps-arc, linux-usb, linux, linuxppc-dev, m.szyprowski,
maddy, mani, miko.lenczewski, mpe, netdev, npiggin, osalvador,
oupton, pabeni, palmer, peter.ujfalusi, peterz, pjw, robh,
sebastian.hesselbarth, tglx, tsbogend, vgupta, vkoul, will, willy,
yangyicong, yeoreum.yun
In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org>
Hello:
This patch was applied to riscv/linux.git (fixes)
by Danilo Krummrich <dakr@kernel.org>:
On Mon, 6 Apr 2026 16:22:53 -0700 you wrote:
> The main goal of this series is to fix the observed bug talked about
> in the first patch ("driver core: Don't let a device probe until it's
> ready"). That patch fixes a problem that has been observed in the real
> world and could land even if the rest of the patches are found
> unacceptable or need to be spun.
>
> That said, during patch review Danilo correctly pointed out that many
> of the bitfield accesses in "struct device" are unsafe. I added a
> bunch of patches in the series to address each one.
>
> [...]
Here is the summary with links:
- [v5,7/9] driver core: Replace dev->dma_coherent with dev_dma_coherent()
https://git.kernel.org/riscv/c/3e2c1e213ac2
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v6 2/2] drm/bridge: Add Lontium LT9611C(EX/UXD) MIPI DSI to HDMI driver
From: Maxime Ripard @ 2026-06-26 8:26 UTC (permalink / raw)
To: Sunyun Yang
Cc: Krzysztof Kozlowski, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, dmitry.baryshkov, maarten.lankhorst, rfoss,
Laurent.pinchart, tzimmermann, jonas, jernej.skrabec, devicetree,
dri-devel, linux-kernel, xmzhu, xmzhu, rlyu, xbpeng
In-Reply-To: <CAFQXuNbN1bW3DVGUtVf7--dW_UhSk4LZdk+v14P=VSbDU4ZzsQ@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4990 bytes --]
On Fri, Jun 26, 2026 at 04:13:18PM +0800, Sunyun Yang wrote:
> Maxime Ripard <mripard@kernel.org> 于2026年6月26日周五 15:49写道:
> >
> > On Fri, Jun 26, 2026 at 10:15:03AM +0800, Sunyun Yang wrote:
> > > Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 21:51写道:
> > > >
> > > > On 25/06/2026 15:40, Sunyun Yang wrote:
> > > > > Sunyun Yang <syyang@lontium.com> 于2026年6月25日周四 21:26写道:
> > > > >>
> > > > >> Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 21:17写道:
> > > > >>>
> > > > >>> On 25/06/2026 15:14, Sunyun Yang wrote:
> > > > >>>> Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 20:54写道:
> > > > >>>>>
> > > > >>>>> On 08/05/2026 15:40, syyang@lontium.com wrote:
> > > > >>>>>> +
> > > > >>>>>> +static void lt9611c_reset(struct lt9611c *lt9611c)
> > > > >>>>>> +{
> > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > >>>>>> + msleep(20);
> > > > >>>>>> +
> > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 0);
> > > > >>>>>> + msleep(20);
> > > > >>>>>> +
> > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > >>>>>
> > > > >>>>> This is just plain wrong. Why do you assert, then de-assert and then
> > > > >>>>> finally assert AGAIN the reset leaving the device in powerdown stage?
> > > > >>>>>
> > > > >>>> I am using software to emulate the hardware RESET button on our EVB.
> > > > >>>> When the hardware RESET button is pressed while our chip is running,
> > > > >>>> the signal level changes from HIGH to LOW and then back to HIGH.
> > > > >>>>
> > > > >>>> Of course, we can also use the following:
> > > > >>>> static void lt9611c_reset(struct lt9611c *lt9611c)
> > > > >>>> {
> > > > >>>> gpiod_set_value_cansleep(lt9611c->reset_gpio, 0);
> > > > >>>> msleep(50);
> > > > >>>> gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > >>>> msleep(20);
> > > > >>>> }
> > > > >>>
> > > > >>> Makes no sense either and you just did not get the point and did not
> > > > >>> answer my question. I asked WHY you leave asserted. Answer "we emulate"
> > > > >>> is just plain wrong.
> > > > >>>
> > > > >>> So again please answer:
> > > > >>>
> > > > >>> Why do you leave device with reset asserted?
> > > > >>>
> > > > >>
> > > > >> devicetree: reset-gpios = <&tlmm 128 GPIO_ACTIVE_HIGH>;
> > > > >>
> > > > >> GPIO_ACTIVE_HIGH:
> > > > >>
> > > > >> gpiod_set_value_cansleep(lt9611c->reset_gpio, 0); ------ reset pin
> > > > >> is Low level : Clear the register configuration in the chip to stop
> > > > >> the chip from working.
> > > > >>
> > > > >> gpiod_set_value_cansleep(lt9611c->reset_gpio, 1); ------ reset pin
> > > > >> is high level: The chip resumes operation.
> > > > >>
> > > > >>
> > > > >
> > > > > Our purpose is: pull the level low to clear the register configuration
> > > > > in the chip, and then pull it high to allow the MCU inside the chip to
> > > > > re‑initialize the registers.
> > > >
> > > >
> > > > And you do completely opposite... so that confirms your code is just wrong.
> > > >
> > >
> > > The lontium-lt9611.yaml uses GPIO_ACTIVE_HIGH. I am just following the
> > > rule of this device tree. If I modify the device tree to use
> > > GPIO_ACTIVE_LOW,
> > > and use the following code in my driver, then my driver would be correct.
> > > However, would the existing kernel drivers lontium-lt9611uxc.c and
> > > lontium-lt9611.c be affected?
> >
> > It might, but then it's a DT problem. The GPIO API for drivers always
> > considers the logical state of a GPIO, so if you need to assert a
> > signal, you'll always need to set 1. That's what Krzysztof was trying to
> > explain.
> >
> > The DT will provide with GPIO_ACTIVE_* how that logical state translates
> > to a physical GPIO state.
> >
> > If the DT says that this particular GPIO is active-high, then it means
> > that we need to set the GPIO to 1 to assert reset. Now of course, it
> > might not make sense for the controller itself, but it might for the
> > board if there's a GPIO inverter in the middle for example.
> >
> > Anyway, in the case you're raising, the issue definitely lies in the DT,
> > and that's what would need to be fixed.
> >
> > I also wouldn't be too concerned about lontium-lt9611.yaml, it's just an
> > example.
> >
> > Maxime
>
> thanks Maxime, I will modify this code in the next version of the
> driver, and I hope you can accept these changes.
>
> Maxime:
> I have another question I would like to ask you
> regarding sashiko-bot@kernel.org. Since sashiko-bot sometimes has
> opinions that differ from yours, whose advice should I follow?
>
> If I do not adopt sashiko-bot's suggestions, will my patches still be
> accepted into the upstream Linux kernel?
I can't give a blanket answer. It depends on what you ignore exactly.
Maxime
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]
^ permalink raw reply
* Re: [PATCH v4] dt-bindings: pwm: st,sti-pwm: convert to DT schema
From: Krzysztof Kozlowski @ 2026-06-26 8:31 UTC (permalink / raw)
To: Charan Pedumuru
Cc: Uwe Kleine-König, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lee Jones, linux-pwm, devicetree, linux-kernel
In-Reply-To: <20260625-st-pwm-v4-1-958d7d6bdf39@gmail.com>
On Thu, Jun 25, 2026 at 11:24:15AM +0000, Charan Pedumuru wrote:
> +maintainers:
> + - Lee Jones <lee.jones@linaro.org>
> +
> +description:
> + The STiH41x PWM controller supports both PWM output and input capture
> + functionality. It provides multiple PWM output channels for generating
> + variable duty-cycle waveforms, and multiple input capture channels for
> + measuring external signal periods and pulse widths. PWM output channels
> + and input capture channels are configured independently via
> + st,pwm-num-chan and st,capture-num-chan respectively.
> +
> +allOf:
> + - $ref: pwm.yaml#
> +
> +properties:
> + compatible:
> + const: st,sti-pwm
> +
> + reg:
> + maxItems: 1
> +
> + "#pwm-cells":
> + const: 2
> +
> + pinctrl-names:
> + const: default
> +
> + clock-names:
items:
minItems: 1
- const: pwm
- const: capture
> + items:
> + enum: [pwm, capture]
> + minItems: 1
> + maxItems: 2
> +
> + clocks:
> + minItems: 1
> + maxItems: 2
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v4 1/2] dt-bindings: PCI: qcom: Document the Hawi PCIe Controller
From: Krzysztof Kozlowski @ 2026-06-26 8:32 UTC (permalink / raw)
To: Matthew Leung
Cc: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, linux-arm-msm, linux-pci,
devicetree, linux-kernel
In-Reply-To: <20260625-hawi-pcie-v4-1-1a578603cd86@oss.qualcomm.com>
On Thu, Jun 25, 2026 at 08:38:58PM +0000, Matthew Leung wrote:
> Add a dedicated schema for the PCIe controllers found on the Hawi
> platform.
>
> Signed-off-by: Matthew Leung <matthew.leung@oss.qualcomm.com>
> ---
> .../devicetree/bindings/pci/qcom,hawi-pcie.yaml | 196 +++++++++++++++++++++
> 1 file changed, 196 insertions(+)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v3 5/9] ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible
From: Krzysztof Kozlowski @ 2026-06-26 8:39 UTC (permalink / raw)
To: Binbin Zhou
Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
Takashi Iwai, Keguang Zhang, Huacai Chen, Xuerui Wang, loongarch,
devicetree, linux-sound
In-Reply-To: <183d809cd51874bcb78743273e4b7617f120fedb.1782439646.git.zhoubinbin@loongson.cn>
On Fri, Jun 26, 2026 at 10:27:26AM +0800, Binbin Zhou wrote:
> Add a new compatible string `loongson,ls2k0300-forever-pi-audio-card`
> for the audio card on Loongson-2K0300 ctcisz forever pi SoC. It uses a
> different DAI format compared to existing Loongson platforms.
>
> The existing "loongson,ls-audio-card" remains valid for LS7A,
> Loongson-2K1000 and Loongson-2K2000.
>
> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> ---
> .../devicetree/bindings/sound/loongson,ls-audio-card.yaml | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v6 2/2] drm/bridge: Add Lontium LT9611C(EX/UXD) MIPI DSI to HDMI driver
From: Sunyun Yang @ 2026-06-26 8:40 UTC (permalink / raw)
To: Maxime Ripard
Cc: Krzysztof Kozlowski, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, dmitry.baryshkov, maarten.lankhorst, rfoss,
Laurent.pinchart, tzimmermann, jonas, jernej.skrabec, devicetree,
dri-devel, linux-kernel, xmzhu, xmzhu, rlyu, xbpeng
In-Reply-To: <20260626-flawless-axiomatic-slug-c480c9@houat>
Maxime Ripard <mripard@kernel.org> 于2026年6月26日周五 16:26写道:
>
> On Fri, Jun 26, 2026 at 04:13:18PM +0800, Sunyun Yang wrote:
> > Maxime Ripard <mripard@kernel.org> 于2026年6月26日周五 15:49写道:
> > >
> > > On Fri, Jun 26, 2026 at 10:15:03AM +0800, Sunyun Yang wrote:
> > > > Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 21:51写道:
> > > > >
> > > > > On 25/06/2026 15:40, Sunyun Yang wrote:
> > > > > > Sunyun Yang <syyang@lontium.com> 于2026年6月25日周四 21:26写道:
> > > > > >>
> > > > > >> Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 21:17写道:
> > > > > >>>
> > > > > >>> On 25/06/2026 15:14, Sunyun Yang wrote:
> > > > > >>>> Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 20:54写道:
> > > > > >>>>>
> > > > > >>>>> On 08/05/2026 15:40, syyang@lontium.com wrote:
> > > > > >>>>>> +
> > > > > >>>>>> +static void lt9611c_reset(struct lt9611c *lt9611c)
> > > > > >>>>>> +{
> > > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > > >>>>>> + msleep(20);
> > > > > >>>>>> +
> > > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 0);
> > > > > >>>>>> + msleep(20);
> > > > > >>>>>> +
> > > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > > >>>>>
> > > > > >>>>> This is just plain wrong. Why do you assert, then de-assert and then
> > > > > >>>>> finally assert AGAIN the reset leaving the device in powerdown stage?
> > > > > >>>>>
> > > > > >>>> I am using software to emulate the hardware RESET button on our EVB.
> > > > > >>>> When the hardware RESET button is pressed while our chip is running,
> > > > > >>>> the signal level changes from HIGH to LOW and then back to HIGH.
> > > > > >>>>
> > > > > >>>> Of course, we can also use the following:
> > > > > >>>> static void lt9611c_reset(struct lt9611c *lt9611c)
> > > > > >>>> {
> > > > > >>>> gpiod_set_value_cansleep(lt9611c->reset_gpio, 0);
> > > > > >>>> msleep(50);
> > > > > >>>> gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > > >>>> msleep(20);
> > > > > >>>> }
> > > > > >>>
> > > > > >>> Makes no sense either and you just did not get the point and did not
> > > > > >>> answer my question. I asked WHY you leave asserted. Answer "we emulate"
> > > > > >>> is just plain wrong.
> > > > > >>>
> > > > > >>> So again please answer:
> > > > > >>>
> > > > > >>> Why do you leave device with reset asserted?
> > > > > >>>
> > > > > >>
> > > > > >> devicetree: reset-gpios = <&tlmm 128 GPIO_ACTIVE_HIGH>;
> > > > > >>
> > > > > >> GPIO_ACTIVE_HIGH:
> > > > > >>
> > > > > >> gpiod_set_value_cansleep(lt9611c->reset_gpio, 0); ------ reset pin
> > > > > >> is Low level : Clear the register configuration in the chip to stop
> > > > > >> the chip from working.
> > > > > >>
> > > > > >> gpiod_set_value_cansleep(lt9611c->reset_gpio, 1); ------ reset pin
> > > > > >> is high level: The chip resumes operation.
> > > > > >>
> > > > > >>
> > > > > >
> > > > > > Our purpose is: pull the level low to clear the register configuration
> > > > > > in the chip, and then pull it high to allow the MCU inside the chip to
> > > > > > re‑initialize the registers.
> > > > >
> > > > >
> > > > > And you do completely opposite... so that confirms your code is just wrong.
> > > > >
> > > >
> > > > The lontium-lt9611.yaml uses GPIO_ACTIVE_HIGH. I am just following the
> > > > rule of this device tree. If I modify the device tree to use
> > > > GPIO_ACTIVE_LOW,
> > > > and use the following code in my driver, then my driver would be correct.
> > > > However, would the existing kernel drivers lontium-lt9611uxc.c and
> > > > lontium-lt9611.c be affected?
> > >
> > > It might, but then it's a DT problem. The GPIO API for drivers always
> > > considers the logical state of a GPIO, so if you need to assert a
> > > signal, you'll always need to set 1. That's what Krzysztof was trying to
> > > explain.
> > >
> > > The DT will provide with GPIO_ACTIVE_* how that logical state translates
> > > to a physical GPIO state.
> > >
> > > If the DT says that this particular GPIO is active-high, then it means
> > > that we need to set the GPIO to 1 to assert reset. Now of course, it
> > > might not make sense for the controller itself, but it might for the
> > > board if there's a GPIO inverter in the middle for example.
> > >
> > > Anyway, in the case you're raising, the issue definitely lies in the DT,
> > > and that's what would need to be fixed.
> > >
> > > I also wouldn't be too concerned about lontium-lt9611.yaml, it's just an
> > > example.
> > >
> > > Maxime
> >
> > thanks Maxime, I will modify this code in the next version of the
> > driver, and I hope you can accept these changes.
> >
> > Maxime:
> > I have another question I would like to ask you
> > regarding sashiko-bot@kernel.org. Since sashiko-bot sometimes has
> > opinions that differ from yours, whose advice should I follow?
> >
> > If I do not adopt sashiko-bot's suggestions, will my patches still be
> > accepted into the upstream Linux kernel?
>
> I can't give a blanket answer. It depends on what you ignore exactly.
>
Okay, another question: sashiko-bot is an AI bot. Are its review
comments optional, or must they be followed?
> Maxime
^ permalink raw reply
* Re: Re: Re: [PATCH 3/7] riscv: dts: eswin: eic7700: add pinctrl support
From: Yulin Lu @ 2026-06-26 8:42 UTC (permalink / raw)
To: Conor Dooley
Cc: Conor Dooley, Pinkesh Vaghela, Lee Jones, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, devicetree, linux-kernel, linux-riscv,
Min Lin, Samuel Holland, Darshan Prajapati, Pritesh Patel
In-Reply-To: <20260626-headway-rewind-93c9239bd865@wendy>
> > Hi, Conor. Thanks for your review.
> >
> > > On Mon, Jun 15, 2026 at 05:50:12PM +0530, Pinkesh Vaghela wrote:
> > > > From: Yulin Lu <luyulin@eswincomputing.com>
> > > >
> > > > Add pinctrl node and related pin configuration for EIC7700 SoC
> > > >
> > > > Co-developed-by: Pritesh Patel <pritesh.patel@einfochips.com>
> > > > Signed-off-by: Pritesh Patel <pritesh.patel@einfochips.com>
> > > > Signed-off-by: Yulin Lu <luyulin@eswincomputing.com>
> > > > Signed-off-by: Pinkesh Vaghela <pinkesh.vaghela@einfochips.com>
> > > > ---
> > > > .../dts/eswin/eic7700-hifive-premier-p550.dts | 109 +++
> > > > .../riscv/boot/dts/eswin/eic7700-pinctrl.dtsi | 888 ++++++++++++++++++
> > > > arch/riscv/boot/dts/eswin/eic7700.dtsi | 5 +
> > > > 3 files changed, 1002 insertions(+)
> > > > create mode 100644 arch/riscv/boot/dts/eswin/eic7700-pinctrl.dtsi
> > > >
> > > > diff --git a/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts b/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts
> > > > index 1fb92f0e7c55..e7bb96e14958 100644
> > > > --- a/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts
> > > > +++ b/arch/riscv/boot/dts/eswin/eic7700-hifive-premier-p550.dts
> > > > @@ -6,6 +6,7 @@
> > > > /dts-v1/;
> > > >
> > > > #include "eic7700.dtsi"
> > > > +#include "eic7700-pinctrl.dtsi"
> > > >
> >
> > ...
> >
> > > > +&gpio79_pins {
> > > > + bias-disable;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&gpio80_pins {
> > > > + bias-pull-up;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&gpio82_pins {
> > > > + bias-pull-up;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&gpio84_pins {
> > > > + bias-disable;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&gpio85_pins {
> > > > + bias-pull-up;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&gpio94_pins {
> > > > + bias-disable;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&gpio106_pins {
> > > > + bias-disable;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&gpio111_pins {
> > > > + bias-disable;
> > > > + input-disable;
> > > > +};
> > > > +
> > > > +&pinctrl {
> > > > + vrgmii-supply = <&vcc_1v8>;
> > > > +};
> > > > +
> > > > &uart0 {
> > > > status = "okay";
> > > > };
> > > > diff --git a/arch/riscv/boot/dts/eswin/eic7700-pinctrl.dtsi b/arch/riscv/boot/dts/eswin/eic7700-pinctrl.dtsi
> > > > new file mode 100644
> > > > index 000000000000..7293df146aa7
> > > > --- /dev/null
> > > > +++ b/arch/riscv/boot/dts/eswin/eic7700-pinctrl.dtsi
> > > > @@ -0,0 +1,888 @@
> > > > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > > > +/*
> > > > + * Copyright (c) 2025 Beijing ESWIN Computing Technology Co., Ltd.
> > > > + *
> > > > + * ESWIN's EIC7700 SoC pin-mux and pin-config options are listed as
> > > > + * device tree nodes in this file.
> > > > + *
> > > > + * Authors: Yulin Lu <luyulin@eswincomputing.com>
> > > > + */
> > > > +
> > >
> > > I don't really understand the groups here. I think you should make more
> > > effort to put more pins in each group.
> > >
> > > > + gpio1_pins: gpio1-pins {
> > > > + pins = "jtag0_tck";
> > > > + function = "gpio";
> > > > + };
> > > > +
> > > > + gpio2_pins: gpio2-pins {
> > > > + pins = "jtag0_tms";
> > > > + function = "gpio";
> > > > + };
> > > > +
> > > > + gpio3_pins: gpio3-pins {
> > > > + pins = "jtag0_tdi";
> > > > + function = "gpio";
> > > > + };
> > > > +
> > > > + gpio4_pins: gpio4-pins {
> > > > + pins = "jtag0_tdo";
> > > > + function = "gpio";
> > > > + };
> > >
> > > Like these 4 for example, why not group these?
> >
> > The 'group' is used to correspond to the '-grp' tag in the YAML file and
> > has no practical significance.
> > Different board designs have different requirements for pin multiplexing.
> > Therefore, eic7700-pinctrl.dtsi only provides pins for the board-level DTS.
> > Pins are combined and used in the board-level DTS via pinctrl-0 property.
>
> These 4 pins in the driver are represented as:
> EIC7700_PIN(14, "jtag0_tck", [0] = F_JTAG, [1] = F_SPI, [2] = F_GPIO),
> EIC7700_PIN(15, "jtag0_tms", [0] = F_JTAG, [1] = F_SPI, [2] = F_GPIO),
> EIC7700_PIN(16, "jtag0_tdi", [0] = F_JTAG, [1] = F_SPI, [2] = F_GPIO),
> EIC7700_PIN(17, "jtag0_tdo", [0] = F_JTAG, [1] = F_SPI, [2] = F_GPIO),
>
> EIC7700_PIN(18, "gpio5", [0] = F_GPIO, [1] = F_SPI),
>
> There is no reason to ever partially use these as GPIO. Either they will
> be all jtag, all spi or all gpio. pin 18 on the other than makes sense to have
> in a dedicated group.
Hi, Conor. Thanks for your reply.
For pins 14 to 18, when they are not multiplexed as JTAG or SPI,
they can be used as GPIO. The corresponding -pins combinations
for JTAG, SPI, and GPIO are all implemented in eic7700-pinctrl.dtsi.
Take pin 14 as an example. In eic7700-pinctrl.dtsi, it is defined:
dual_spi2_pins: dual-spi2-pins {
pins = "spi2_cs0_n", "jtag0_tck", "jtag0_tms", "jtag0_tdi";
function = "spi";
};
quad_spi2_pins: quad-spi2-pins {
pins = "spi2_cs0_n", "spi2_cs1_n", "jtag0_tck", "jtag0_tms",
"jtag0_tdi", "jtag0_tdo", "gpio5";
function = "spi";
};
gpio1_pins: gpio1-pins {
pins = "jtag0_tck";
function = "gpio";
};
jtag0_pins: jtag0-pins {
pins = "jtag0_tck", "jtag0_tms", "jtag0_tdi", "jtag0_tdo";
function = "jtag";
};
Which specific combination is called, and how they are combined,
depends on the board-level system design and is referenced in
the device nodes of the board-level DTS. For example:
pinctrl-0 = <&gpio1_pins>, <&jtag2_pins>;
The pin multiplexing configuration depends on the board-level system design.
Using combinations of '-pins' is sufficient to satisfy all requirements,
and there is no need to rely on '-grp' for this purpose.
Regards,
Yulin Lu
^ permalink raw reply
* RE: [PATCH v2 1/4] iio: dac: ad3530r: Refactor setup to table-driven register bank approach
From: Paller, Kim Seer @ 2026-06-26 8:44 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, David Lechner, Sa, Nuno, Andy Shevchenko,
Hennerich, Michael, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-iio@vger.kernel.org,
linux-kernel@vger.kernel.org, linux, devicetree@vger.kernel.org
In-Reply-To: <ai_PCrlH49Qqw-Po@ashevche-desk.local>
> -----Original Message-----
> From: Andy Shevchenko <andriy.shevchenko@intel.com>
> Sent: Monday, June 15, 2026 6:08 PM
> To: Paller, Kim Seer <KimSeer.Paller@analog.com>
> Cc: Jonathan Cameron <jic23@kernel.org>; David Lechner
> <dlechner@baylibre.com>; Sa, Nuno <Nuno.Sa@analog.com>; Andy
> Shevchenko <andy@kernel.org>; Hennerich, Michael
> <Michael.Hennerich@analog.com>; Rob Herring <robh@kernel.org>; Krzysztof
> Kozlowski <krzk+dt@kernel.org>; Conor Dooley <conor+dt@kernel.org>; linux-
> iio@vger.kernel.org; linux-kernel@vger.kernel.org; linux <linux@analog.com>;
> devicetree@vger.kernel.org
> Subject: Re: [PATCH v2 1/4] iio: dac: ad3530r: Refactor setup to table-driven
> register bank approach
>
> [External]
>
> On Mon, Jun 15, 2026 at 02:20:15PM +0800, Kim Seer Paller wrote:
> > Replace direct register calls in ad3530r_setup() with per-chip
> > register address arrays and bank helpers (ad3530r_set_reg_bank_bits,
> > ad3530r_write_reg_banks). Convert sw_ldac_trig_reg from a static
> > register address to a function pointer for per-bank LDAC trigger
> > register selection. Switch spi_device_id to named initializers.
>
> ...
>
> > +static int ad3530r_set_reg_bank_bits(const struct ad3530r_state *st,
> > + const unsigned int *regs,
> > + unsigned int num_regs,
> > + unsigned int mask)
> > +{
> > + int ret;
> > +
> > + for (unsigned int i = 0; i < num_regs; i++) {
> > + ret = regmap_update_bits(st->regmap, regs[i], mask, mask);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int ad3530r_write_reg_banks(const struct ad3530r_state *st,
> > + const unsigned int *regs,
> > + unsigned int num_regs,
> > + unsigned int val)
> > +{
> > + int ret;
> > +
> > + for (unsigned int i = 0; i < num_regs; i++) {
> > + ret = regmap_write(st->regmap, regs[i], val);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
>
> Can the above helpers use bulk operations or regmap_multi_reg_write()?
I think bulk operations don't apply for the AD3532R case, since bank 0 is around 0x102x
and bank 1 around 0x302x two register banks, not one continuous block.
For regmap_multi_reg_write(), since all the registers get the same value, we would
have to build a reg_sequence, and it ends up being the same number of writes with
just more code. So I think the simple loop helper is better here, but happy to switch if
regmap_multi_reg_write() is the preferred form.
>
> --
> With Best Regards,
> Andy Shevchenko
>
^ permalink raw reply
* Re: [EXTERNAL] Re: [PATCH v4 1/3] perf: marvell: Add MPAM partid filtering to CN10K TAD PMU
From: Ben Horgan @ 2026-06-26 8:57 UTC (permalink / raw)
To: Geethasowjanya Akula, linux-perf-users@vger.kernel.org,
linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org
Cc: mark.rutland@arm.com, will@kernel.org, krzk+dt@kernel.org,
james.morse@arm.com, Sunil Kovvuri Goutham, Tanmay Jagdale
In-Reply-To: <CH0PR18MB43394668EAEBD367DB4D4990CDEB2@CH0PR18MB4339.namprd18.prod.outlook.com>
Hi Geetha,
On 6/26/26 07:21, Geethasowjanya Akula wrote:
>
>
>> -----Original Message-----
>> From: Ben Horgan <ben.horgan@arm.com>
>> Sent: Thursday, June 25, 2026 7:23 PM
>> To: Geethasowjanya Akula <gakula@marvell.com>; linux-perf-
>> users@vger.kernel.org; linux-kernel@vger.kernel.org; linux-arm-
>> kernel@lists.infradead.org; devicetree@vger.kernel.org
>> Cc: mark.rutland@arm.com; will@kernel.org; krzk+dt@kernel.org;
>> james.morse@arm.com
>> Subject: [EXTERNAL] Re: [PATCH v4 1/3] perf: marvell: Add MPAM partid
>> filtering to CN10K TAD PMU
>> Hi Geetha,
>>
>> +CC James
>>
>> On 6/18/26 16:36, Geetha sowjanya wrote:
>>> From: Tanmay Jagdale <tanmay@marvell.com>
>>>
>>> The TAD PMU exposes counters that can be filtered by MPAM partition id
>>> for a subset of allocation and hit events.
>>>
>>> Add a 9-bit partid format attribute (config1) and route counter
>>> programming through variant-specific ops so CN10K keeps MPAM-capable
>>> programming while Odyssey keeps the reduced event set without advertising
>> partid in sysfs.
>>>
>>> Probe no longer mutates the platform_device MMIO resource (walk a
>>> local map_start), rejects tad-cnt / page sizes of zero, validates the
>>> memory window against tad-cnt, and registers the perf PMU before
>>> hotplug with correct unwind.
>>>
>>> Example:
>>> perf stat -e tad/tad_alloc_any,partid=0x12,partid_en=1/ -- <program>
>>
>> Where is the user expected to get the PARTID from? The MPAM driver
>> considers the PARTID as an internal only value.
>>
>> resctrl does support a 'debug' mount option which will show the CLOSID
>> associated with a control group. Whilst the CLOSID is often the PARTID, it is
>> really a set of PARTIDs. When the cdp mount option is used, CLOSID maps to 2
>> PARTIDs and if we use PARTID narrowing to give us more monitors, as in
>> proposed in [1], then the set of PARTIDs may be bigger.
>> Furthermore, if the PARTID narrowing scheme is made dynamic the size of the
>> PARTID set may change when control or monitoring groups are created or
>> deleted.
>>
>> It seems that a way to map from a resctrl control group to the set of PARTIDs is
>> required and a mechanism to tie this to lifetime of the resctrl mount.
>>
>> Perhaps some helpers along the lines of:
>>
>> int resctrl_mount_generation(void)
>> int mpam_rdtgrp_to_partid_is_static(int mount_gen) int
>> resctrl_rdtgrp_generation(char *name) int
>> mpam_rdtgrp_to_partid_count(char *name, int rdt_gen) int
>> mpam_rdtgrp_to_partid_array(char *name, int rdt_gen, int* partids)
>>
>> The rdtgrp generation is to an attempt to avoid having to use a debug interface
>> in anger and cope with renaming of control groups in resctrl.
>> This does seem a bit unwieldly so hopefully there is better way to do this.
>>
>> Sorry to throw a spanner in the works.
> On …, … wrote:
>> Where is the user expected to get the PARTID from? The MPAM driver
>> considers the PARTID as an internal only value.
>> …
>> Perhaps some helpers along the lines of:
>> int resctrl_mount_generation(void)
>> …
> Hi Ben,
>
> Thank you for the detailed feedback — the concern you raise is valid, particularly when
> viewed from the perspective of resctrl-managed deployments.
>
> However, to clarify the intent of this patch: the exposure of partid in the TAD PMU is deliberately
> a low-level, hardware-facing interface, and is not intended to integrate with or mirror the
> abstractions provided by resctrl. It is mainly meant for platform bring-up and low-level
> performance/debug users, who already have explicit knowledge of the MPAM configuration,
> typically provisioned by firmware or other privileged software layers (e.g. EL3/EL2).
> In such environments, PARTIDs are known out-of-band, so the expectation is that the
> user supplying partid is already aware of the MPAM IDs programmed on the system.
When this was proposed before, [1], there was feedback asking to
document how to get the PARTID.
Thanks,
Ben
[1]
https://lore.kernel.org/linux-arm-kernel/c981692b-af7b-453d-39af-402221e174f5@arm.com/>
> A proper “profile this resctrl group” path would require MPAM–resctrl support (e.g. something along the lines of the helpers you suggest)
> to resolve a group to its PARTID set. This is indeed important, but it constitutes a separate design discussion that is outside the scope of this driver patch.
>
> We will clarify this in the commit message and avoid implying that users normally obtain PARTIDs from resctrl today.
>
>
> Thanks,
> Geetha
>>
>> Thanks,
>>
>> Ben
>>
>>>
>>> Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
>>> Signed-off-by: Geetha sowjanya <gakula@marvell.com>
>>> ---
>>>
>>> Changelog (since v3)
>>> --------------------
>>> - Restore cpuhp_state_add_instance_nocalls before perf_pmu_register in
>> probe
>>> so users cannot attach events before the hotplug instance exists; unwind
>>> removes the hotplug instance if perf registration fails.
>>> - Add perf_ready: tad_pmu_offline_cpu skips perf_pmu_migrate_context
>> until after
>>> successful perf_pmu_register, so a CPU offline between hotplug add and
>> perf
>>> register does not touch perf core state for an unregistered PMU.
>>>
>>> Changelog (since v2)
>>> --------------------
>>> - Validate the eventId using an appropriate mask to ensure
>>> it is restricted to 8 bits.
>>>
>>> Changelog (since v1)
>>> --------------------
>>> - Fix config1 filter enable to use bit 9 consistently with the PMU format
>>> string (partid_en) and reject reserved bits with GENMASK(9, 0).
>>> - Register perf_pmu_register before cpuhp_state_add_instance_nocalls and
>>> unregister on hotplug failure.
>>>
>>> drivers/perf/marvell_cn10k_tad_pmu.c | 220
>>> +++++++++++++++++++++------
>>> 1 file changed, 171 insertions(+), 49 deletions(-)
>>>
>>> diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c
>>> b/drivers/perf/marvell_cn10k_tad_pmu.c
>>> index 51ccb0befa05..340be3776fe7 100644
>>> --- a/drivers/perf/marvell_cn10k_tad_pmu.c
>>> +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
>>> @@ -7,6 +7,8 @@
>>> #define pr_fmt(fmt) "tad_pmu: " fmt
>>>
>>> #include <linux/io.h>
>>> +#include <linux/bits.h>
>>> +#include <linux/compiler.h>
>>> #include <linux/module.h>
>>> #include <linux/of.h>
>>> #include <linux/cpuhotplug.h>
>>> @@ -14,12 +16,20 @@
>>> #include <linux/platform_device.h>
>>> #include <linux/acpi.h>
>>>
>>> -#define TAD_PFC_OFFSET 0x800
>>> -#define TAD_PFC(counter) (TAD_PFC_OFFSET | (counter << 3))
>>> #define TAD_PRF_OFFSET 0x900
>>> -#define TAD_PRF(counter) (TAD_PRF_OFFSET | (counter << 3))
>>> +#define TAD_PFC_OFFSET 0x800
>>> +#define TAD_PFC(base, counter) ((base) | ((u64)(counter) << 3))
>>> +#define TAD_PRF(base, counter) ((base) | ((u64)(counter) << 3))
>>> #define TAD_PRF_CNTSEL_MASK 0xFF
>>> +#define TAD_PRF_MATCH_PARTID BIT(8)
>>> +#define TAD_PRF_PARTID_NS BIT(10)
>>> +/*
>>> + * config1: bits 0..8 MPAM partition id (including 0); bit 9 requests
>>> + * filtering for MPAM-capable events. All-zero config1 means no filter.
>>> + */
>>> +#define TAD_PARTID_FILTER_EN BIT(9)
>>> #define TAD_MAX_COUNTERS 8
>>> +#define TAD_EVENT_SEL_MASK GENMASK(7, 0)
>>>
>>> #define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
>>>
>>> @@ -27,30 +37,94 @@ struct tad_region {
>>> void __iomem *base;
>>> };
>>>
>>> +enum mrvl_tad_pmu_version {
>>> + TAD_PMU_V1 = 1,
>>> + TAD_PMU_V2,
>>> +};
>>> +
>>> +struct tad_pmu_data {
>>> + int id;
>>> + u64 tad_prf_offset;
>>> + u64 tad_pfc_offset;
>>> +};
>>> +
>>> struct tad_pmu {
>>> struct pmu pmu;
>>> struct tad_region *regions;
>>> u32 region_cnt;
>>> unsigned int cpu;
>>> + /* Set after successful perf_pmu_register(); gates offline migration. */
>>> + bool perf_ready;
>>> + const struct tad_pmu_ops *ops;
>>> + const struct tad_pmu_data *pdata;
>>> struct hlist_node node;
>>> struct perf_event *events[TAD_MAX_COUNTERS];
>>> DECLARE_BITMAP(counters_map, TAD_MAX_COUNTERS); };
>>>
>>> -enum mrvl_tad_pmu_version {
>>> - TAD_PMU_V1 = 1,
>>> - TAD_PMU_V2,
>>> -};
>>> -
>>> -struct tad_pmu_data {
>>> - int id;
>>> +struct tad_pmu_ops {
>>> + void (*start_counter)(struct tad_pmu *pmu, struct perf_event
>>> +*event);
>>> };
>>>
>>> static int tad_pmu_cpuhp_state;
>>>
>>> +static void tad_pmu_start_counter(struct tad_pmu *pmu,
>>> + struct perf_event *event)
>>> +{
>>> + const struct tad_pmu_data *pdata = pmu->pdata;
>>> + struct hw_perf_event *hwc = &event->hw;
>>> + u32 event_idx = (u32)(event->attr.config & TAD_EVENT_SEL_MASK);
>>> + u32 counter_idx = hwc->idx;
>>> + u64 partid_filter = 0;
>>> + u64 reg_val;
>>> + u64 cfg1 = event->attr.config1;
>>> + bool use_mpam = cfg1 & TAD_PARTID_FILTER_EN;
>>> + u32 partid = (u32)(cfg1 & GENMASK(8, 0));
>>> + int i;
>>> +
>>> + for (i = 0; i < pmu->region_cnt; i++)
>>> + writeq_relaxed(0, pmu->regions[i].base +
>>> + TAD_PFC(pdata->tad_pfc_offset, counter_idx));
>>> +
>>> + if (use_mpam && event_idx > 0x19 && event_idx < 0x21) {
>>> + partid_filter = TAD_PRF_MATCH_PARTID |
>> TAD_PRF_PARTID_NS |
>>> + ((u64)partid << 11);
>>> + }
>>> +
>>> +
>>> + for (i = 0; i < pmu->region_cnt; i++) {
>>> + reg_val = event_idx & 0xFF;
>>> + reg_val |= partid_filter;
>>> + writeq_relaxed(reg_val, pmu->regions[i].base +
>>> + TAD_PRF(pdata->tad_prf_offset, counter_idx));
>>> + }
>>> +}
>>> +
>>> +static void tad_pmu_v2_start_counter(struct tad_pmu *pmu,
>>> + struct perf_event *event)
>>> +{
>>> + const struct tad_pmu_data *pdata = pmu->pdata;
>>> + struct hw_perf_event *hwc = &event->hw;
>>> + u32 event_idx = (u32)(event->attr.config & TAD_EVENT_SEL_MASK);
>>> + u32 counter_idx = hwc->idx;
>>> + u64 reg_val;
>>> + int i;
>>> +
>>> + for (i = 0; i < pmu->region_cnt; i++)
>>> + writeq_relaxed(0, pmu->regions[i].base +
>>> + TAD_PFC(pdata->tad_pfc_offset, counter_idx));
>>> +
>>> + for (i = 0; i < pmu->region_cnt; i++) {
>>> + reg_val = event_idx & 0xFF;
>>> + writeq_relaxed(reg_val, pmu->regions[i].base +
>>> + TAD_PRF(pdata->tad_prf_offset, counter_idx));
>>> + }
>>> +}
>>> +
>>> static void tad_pmu_event_counter_read(struct perf_event *event) {
>>> struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>>> + const struct tad_pmu_data *pdata = tad_pmu->pdata;
>>> struct hw_perf_event *hwc = &event->hw;
>>> u32 counter_idx = hwc->idx;
>>> u64 prev, new;
>>> @@ -60,7 +134,7 @@ static void tad_pmu_event_counter_read(struct
>> perf_event *event)
>>> prev = local64_read(&hwc->prev_count);
>>> for (i = 0, new = 0; i < tad_pmu->region_cnt; i++)
>>> new += readq(tad_pmu->regions[i].base +
>>> - TAD_PFC(counter_idx));
>>> + TAD_PFC(pdata->tad_pfc_offset,
>> counter_idx));
>>> } while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev);
>>>
>>> local64_add(new - prev, &event->count); @@ -69,16 +143,14 @@
>> static
>>> void tad_pmu_event_counter_read(struct perf_event *event) static void
>>> tad_pmu_event_counter_stop(struct perf_event *event, int flags) {
>>> struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>>> + const struct tad_pmu_data *pdata = tad_pmu->pdata;
>>> struct hw_perf_event *hwc = &event->hw;
>>> u32 counter_idx = hwc->idx;
>>> int i;
>>>
>>> - /* TAD()_PFC() stop counting on the write
>>> - * which sets TAD()_PRF()[CNTSEL] == 0
>>> - */
>>> for (i = 0; i < tad_pmu->region_cnt; i++) {
>>> writeq_relaxed(0, tad_pmu->regions[i].base +
>>> - TAD_PRF(counter_idx));
>>> + TAD_PRF(pdata->tad_prf_offset, counter_idx));
>>> }
>>>
>>> tad_pmu_event_counter_read(event);
>>> @@ -89,26 +161,10 @@ static void tad_pmu_event_counter_start(struct
>>> perf_event *event, int flags) {
>>> struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>>> struct hw_perf_event *hwc = &event->hw;
>>> - u32 event_idx = event->attr.config;
>>> - u32 counter_idx = hwc->idx;
>>> - u64 reg_val;
>>> - int i;
>>>
>>> hwc->state = 0;
>>>
>>> - /* Typically TAD_PFC() are zeroed to start counting */
>>> - for (i = 0; i < tad_pmu->region_cnt; i++)
>>> - writeq_relaxed(0, tad_pmu->regions[i].base +
>>> - TAD_PFC(counter_idx));
>>> -
>>> - /* TAD()_PFC() start counting on the write
>>> - * which sets TAD()_PRF()[CNTSEL] != 0
>>> - */
>>> - for (i = 0; i < tad_pmu->region_cnt; i++) {
>>> - reg_val = event_idx & 0xFF;
>>> - writeq_relaxed(reg_val, tad_pmu->regions[i].base +
>>> - TAD_PRF(counter_idx));
>>> - }
>>> + tad_pmu->ops->start_counter(tad_pmu, event);
>>> }
>>>
>>> static void tad_pmu_event_counter_del(struct perf_event *event, int
>>> flags) @@ -128,7 +184,6 @@ static int tad_pmu_event_counter_add(struct
>> perf_event *event, int flags)
>>> struct hw_perf_event *hwc = &event->hw;
>>> int idx;
>>>
>>> - /* Get a free counter for this event */
>>> idx = find_first_zero_bit(tad_pmu->counters_map,
>> TAD_MAX_COUNTERS);
>>> if (idx == TAD_MAX_COUNTERS)
>>> return -EAGAIN;
>>> @@ -148,6 +203,9 @@ static int tad_pmu_event_counter_add(struct
>>> perf_event *event, int flags) static int tad_pmu_event_init(struct
>>> perf_event *event) {
>>> struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu);
>>> + const struct tad_pmu_data *pdata = tad_pmu->pdata;
>>> + u32 event_idx = (u32)(event->attr.config & TAD_EVENT_SEL_MASK);
>>> + u64 cfg1 = event->attr.config1;
>>>
>>> if (event->attr.type != event->pmu->type)
>>> return -ENOENT;
>>> @@ -158,6 +216,23 @@ static int tad_pmu_event_init(struct perf_event
>> *event)
>>> if (event->state != PERF_EVENT_STATE_OFF)
>>> return -EINVAL;
>>>
>>> + if (event->attr.config & ~TAD_EVENT_SEL_MASK)
>>> + return -EINVAL;
>>> +
>>> + if (pdata->id == TAD_PMU_V2) {
>>> + if (cfg1)
>>> + return -EINVAL;
>>> + } else {
>>> + if ((cfg1 & GENMASK(8, 0)) && !(cfg1 &
>> TAD_PARTID_FILTER_EN))
>>> + return -EINVAL;
>>> + if (cfg1 & TAD_PARTID_FILTER_EN) {
>>> + if (event_idx <= 0x19 || event_idx >= 0x21)
>>> + return -EINVAL;
>>> + }
>>> + if (cfg1 & ~GENMASK(9, 0))
>>> + return -EINVAL;
>>> + }
>>> +
>>> event->cpu = tad_pmu->cpu;
>>> event->hw.idx = -1;
>>> event->hw.config_base = event->attr.config; @@ -232,7 +307,7 @@
>>> static struct attribute *ody_tad_pmu_event_attrs[] = {
>>> TAD_PMU_EVENT_ATTR(tad_hit_ltg, 0x1e),
>>> TAD_PMU_EVENT_ATTR(tad_hit_any, 0x1f),
>>> TAD_PMU_EVENT_ATTR(tad_tag_rd, 0x20),
>>> - TAD_PMU_EVENT_ATTR(tad_tot_cycle, 0xFF),
>>> + TAD_PMU_EVENT_ATTR(tad_tot_cycle, 0xff),
>>> NULL
>>> };
>>>
>>> @@ -242,9 +317,13 @@ static const struct attribute_group
>>> ody_tad_pmu_events_attr_group = { };
>>>
>>> PMU_FORMAT_ATTR(event, "config:0-7");
>>> +PMU_FORMAT_ATTR(partid, "config1:0-8"); PMU_FORMAT_ATTR(partid_en,
>>> +"config1:9-9");
>>>
>>> static struct attribute *tad_pmu_format_attrs[] = {
>>> &format_attr_event.attr,
>>> + &format_attr_partid.attr,
>>> + &format_attr_partid_en.attr,
>>> NULL
>>> };
>>>
>>> @@ -253,6 +332,16 @@ static struct attribute_group
>> tad_pmu_format_attr_group = {
>>> .attrs = tad_pmu_format_attrs,
>>> };
>>>
>>> +static struct attribute *ody_tad_pmu_format_attrs[] = {
>>> + &format_attr_event.attr,
>>> + NULL
>>> +};
>>> +
>>> +static struct attribute_group ody_tad_pmu_format_attr_group = {
>>> + .name = "format",
>>> + .attrs = ody_tad_pmu_format_attrs,
>>> +};
>>> +
>>> static ssize_t tad_pmu_cpumask_show(struct device *dev,
>>> struct device_attribute *attr, char *buf) { @@
>> -281,16 +370,25
>>> @@ static const struct attribute_group *tad_pmu_attr_groups[] = {
>>>
>>> static const struct attribute_group *ody_tad_pmu_attr_groups[] = {
>>> &ody_tad_pmu_events_attr_group,
>>> - &tad_pmu_format_attr_group,
>>> + &ody_tad_pmu_format_attr_group,
>>> &tad_pmu_cpumask_attr_group,
>>> NULL
>>> };
>>>
>>> +static const struct tad_pmu_ops tad_pmu_ops = {
>>> + .start_counter = tad_pmu_start_counter, };
>>> +
>>> +static const struct tad_pmu_ops tad_pmu_v2_ops = {
>>> + .start_counter = tad_pmu_v2_start_counter, };
>>> +
>>> static int tad_pmu_probe(struct platform_device *pdev) {
>>> const struct tad_pmu_data *dev_data;
>>> struct device *dev = &pdev->dev;
>>> struct tad_region *regions;
>>> + resource_size_t map_start;
>>> struct tad_pmu *tad_pmu;
>>> struct resource *res;
>>> u32 tad_pmu_page_size;
>>> @@ -298,7 +396,6 @@ static int tad_pmu_probe(struct platform_device
>> *pdev)
>>> u32 tad_cnt;
>>> int version;
>>> int i, ret;
>>> - char *name;
>>>
>>> tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu),
>> GFP_KERNEL);
>>> if (!tad_pmu)
>>> @@ -312,6 +409,7 @@ static int tad_pmu_probe(struct platform_device
>> *pdev)
>>> return -ENODEV;
>>> }
>>> version = dev_data->id;
>>> + tad_pmu->pdata = dev_data;
>>>
>>> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> if (!res) {
>>> @@ -338,22 +436,31 @@ static int tad_pmu_probe(struct platform_device
>> *pdev)
>>> dev_err(&pdev->dev, "Can't find tad-cnt property\n");
>>> return ret;
>>> }
>>> + if (!tad_cnt || !tad_page_size || !tad_pmu_page_size) {
>>> + dev_err(&pdev->dev, "Invalid tad-cnt or page size\n");
>>> + return -EINVAL;
>>> + }
>>>
>>> regions = devm_kcalloc(&pdev->dev, tad_cnt,
>>> sizeof(*regions), GFP_KERNEL);
>>> if (!regions)
>>> return -ENOMEM;
>>>
>>> - /* ioremap the distributed TAD pmu regions */
>>> - for (i = 0; i < tad_cnt && res->start < res->end; i++) {
>>> - regions[i].base = devm_ioremap(&pdev->dev,
>>> - res->start,
>>> + map_start = res->start;
>>> + for (i = 0; i < tad_cnt; i++) {
>>> + if (map_start > res->end ||
>>> + tad_pmu_page_size > (resource_size_t)(res->end -
>> map_start + 1)) {
>>> + dev_err(&pdev->dev, "TAD PMU mem window too
>> small for tad-cnt=%u\n",
>>> + tad_cnt);
>>> + return -EINVAL;
>>> + }
>>> + regions[i].base = devm_ioremap(&pdev->dev, map_start,
>>> tad_pmu_page_size);
>>> if (!regions[i].base) {
>>> dev_err(&pdev->dev, "TAD%d ioremap fail\n", i);
>>> return -ENOMEM;
>>> }
>>> - res->start += tad_page_size;
>>> + map_start += tad_page_size;
>>> }
>>>
>>> tad_pmu->regions = regions;
>>> @@ -374,14 +481,16 @@ static int tad_pmu_probe(struct platform_device
>> *pdev)
>>> .read = tad_pmu_event_counter_read,
>>> };
>>>
>>> - if (version == TAD_PMU_V1)
>>> + if (version == TAD_PMU_V1) {
>>> tad_pmu->pmu.attr_groups = tad_pmu_attr_groups;
>>> - else
>>> + tad_pmu->ops = &tad_pmu_ops;
>>> + } else {
>>> tad_pmu->pmu.attr_groups = ody_tad_pmu_attr_groups;
>>> + tad_pmu->ops = &tad_pmu_v2_ops;
>>> + }
>>>
>>> tad_pmu->cpu = raw_smp_processor_id();
>>>
>>> - /* Register pmu instance for cpu hotplug */
>>> ret = cpuhp_state_add_instance_nocalls(tad_pmu_cpuhp_state,
>>> &tad_pmu->node);
>>> if (ret) {
>>> @@ -389,19 +498,24 @@ static int tad_pmu_probe(struct platform_device
>> *pdev)
>>> return ret;
>>> }
>>>
>>> - name = "tad";
>>> - ret = perf_pmu_register(&tad_pmu->pmu, name, -1);
>>> - if (ret)
>>> + ret = perf_pmu_register(&tad_pmu->pmu, "tad", -1);
>>> + if (ret) {
>>> + dev_err(&pdev->dev, "Error %d registering perf PMU\n", ret);
>>> cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
>>> &tad_pmu->node);
>>> + return ret;
>>> + }
>>>
>>> - return ret;
>>> + WRITE_ONCE(tad_pmu->perf_ready, true);
>>> +
>>> + return 0;
>>> }
>>>
>>> static void tad_pmu_remove(struct platform_device *pdev) {
>>> struct tad_pmu *pmu = platform_get_drvdata(pdev);
>>>
>>> + WRITE_ONCE(pmu->perf_ready, false);
>>> cpuhp_state_remove_instance_nocalls(tad_pmu_cpuhp_state,
>>> &pmu->node);
>>> perf_pmu_unregister(&pmu->pmu);
>>> @@ -410,12 +524,17 @@ static void tad_pmu_remove(struct
>>> platform_device *pdev) #if defined(CONFIG_OF) || defined(CONFIG_ACPI)
>>> static const struct tad_pmu_data tad_pmu_data = {
>>> .id = TAD_PMU_V1,
>>> + .tad_prf_offset = TAD_PRF_OFFSET,
>>> + .tad_pfc_offset = TAD_PFC_OFFSET,
>>> };
>>> +
>>> #endif
>>>
>>> #ifdef CONFIG_ACPI
>>> static const struct tad_pmu_data tad_pmu_v2_data = {
>>> .id = TAD_PMU_V2,
>>> + .tad_prf_offset = TAD_PRF_OFFSET,
>>> + .tad_pfc_offset = TAD_PFC_OFFSET,
>>> };
>>> #endif
>>>
>>> @@ -451,6 +570,9 @@ static int tad_pmu_offline_cpu(unsigned int cpu,
>> struct hlist_node *node)
>>> struct tad_pmu *pmu = hlist_entry_safe(node, struct tad_pmu, node);
>>> unsigned int target;
>>>
>>> + if (!READ_ONCE(pmu->perf_ready))
>>> + return 0;
>>> +
>>> if (cpu != pmu->cpu)
>>> return 0;
>>>
>>> @@ -491,6 +613,6 @@ static void __exit tad_pmu_exit(void)
>>> module_init(tad_pmu_init); module_exit(tad_pmu_exit);
>>>
>>> -MODULE_DESCRIPTION("Marvell CN10K LLC-TAD Perf driver");
>>> +MODULE_DESCRIPTION("Marvell CN10K LLC-TAD perf driver");
>>> MODULE_AUTHOR("Bhaskara Budiredla <bbudiredla@marvell.com>");
>>> MODULE_LICENSE("GPL v2");
>
^ permalink raw reply
* Re: [PATCH v5 1/7] dt-bindings: display: verisilicon,dc: generalize for single-output variants
From: Conor Dooley @ 2026-06-26 8:57 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Conor Dooley, Joey Lu, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, ychuang3, schung, yclu4,
dri-devel, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <84b93c496fabdeee05d2f962a1b764fdbfaacdb7.camel@iscas.ac.cn>
[-- Attachment #1: Type: text/plain, Size: 3174 bytes --]
On Fri, Jun 26, 2026 at 03:58:14PM +0800, Icenowy Zheng wrote:
> 在 2026-06-26五的 08:22 +0100,Conor Dooley写道:
> > On Thu, Jun 25, 2026 at 05:33:37PM +0100, Conor Dooley wrote:
> > > On Thu, Jun 25, 2026 at 05:44:43PM +0800, Joey Lu wrote:
> > > > +
> > > > + - if:
> > > > + properties:
> > > > + compatible:
> > > > + contains:
> > > > + const: nuvoton,ma35d1-dcu
> > > > + then:
> > > > + properties:
> > > > + clocks:
> > > > + minItems: 2
> > >
> > > Anything that updates the minimum constraint should be done at the
> > > top
> > > level of this schema. The conditional section should then tighten
> > > the
> > > constraint, in this case that means only having maxItems.
> > >
> > > > + maxItems: 2
> > > > +
> > > > + clock-names:
> > > > + items:
> > > > + - const: core
> > > > + - const: pix0
> > >
> > > Does this even work when the top level schema thinks clock 2 should
> > > be
> > > called axi?
> >
> > Additionally here, only have core and pix0 seems like it might be an
> > oversimplification. I doubt removing the second output port means
> > that
> > the axi and ahb clocks are no longer needed.
> > Is it the case that your device supplies the same clock to core, ahb
> > and
> > axi? If so, then you should fill those clocks in in your devicetree
> > and
> > this can just constrain the number of clocks/clock-names to 4.
>
> The clock controller of that SoC is quite weird -- it has only a single
> gate bit, but controlling 3 clock gates. All core, ahb and axi clocks
> have gates controlled by this single bit, so it's why currently it's
> modelled as only core clock supplied.
Yeah, then what's in the binding is definitely wrong.
Even if the same clock was provided to all clock inputs in the IP, all
individual clock should be listed in the devicetree - although it will
look a little silly to see clocks = <&foo 2>, <&foo 2>, <&foo 2>, <&foo 2>;
In this case, 3 clocks controlled by 1 gate bit is an implementation detail
of the SoC's clocking hardware, and not relevant to how the dc instance
should be described.
> Well it might be worthful to supply the bus clock before the gate as
> ahb/axi, especially axi, because both the AXI clock and the core clock
> constraints the maximum pixel clock.
Right. And looking at patch 4/7, and the wording:
| The Nuvoton MA35D1 SoC integrates a DCUltraLite display controller whose
| AXI and AHB bus clocks share a single gate enable bit with the display
| core clock, so the clock driver does not expose them separately. This
| patch makes the axi and ahb clocks optional in the probe.
It sounds like there's probably some issues with how things are modelled
clock wise in this device, unless this is not an accurate statement and
there's actually one clock provided to all three inputs. If they're
distinct clocks, with different rates, only having one exposed has a lot
of potential to be problematic!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v5 1/7] dt-bindings: display: verisilicon,dc: generalize for single-output variants
From: Icenowy Zheng @ 2026-06-26 9:00 UTC (permalink / raw)
To: Conor Dooley
Cc: Conor Dooley, Joey Lu, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, ychuang3, schung, yclu4,
dri-devel, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260626-astrology-mural-853d3860e048@wendy>
在 2026-06-26五的 08:19 +0100,Conor Dooley写道:
> On Fri, Jun 26, 2026 at 01:27:21PM +0800, Icenowy Zheng wrote:
> > 在 2026-06-25四的 17:33 +0100,Conor Dooley写道:
> > > On Thu, Jun 25, 2026 at 05:44:43PM +0800, Joey Lu wrote:
> > > > +allOf:
> > > > + - if:
> > > > + properties:
> > > > + compatible:
> > > > + contains:
> > > > + const: thead,th1520-dc8200
> > > > + then:
> > > > + properties:
> > > > + clocks:
> > > > + minItems: 5
> > > > + maxItems: 5
> > > > +
> > > > + clock-names:
> > > > + minItems: 5
> > > > + maxItems: 5
> > >
> > > All the maxItems here repeat the maximum constraint and do
> > > nothing.
> > >
> > > Since you didn't change the minimum constraint at the top level,
> > > your
> > > minItems also do nothing.
> > >
> > > > +
> > > > + resets:
> > > > + minItems: 3
> > > > + maxItems: 3
> > > > +
> > > > + reset-names:
> > > > + minItems: 3
> > > > + maxItems: 3
> > > > +
> > > > + required:
> > > > + - resets
> > > > + - reset-names
> > >
> > > Both conditional sections have this, but the original binding
> > > doesn't
> > > require these for the thead device. This is a functional change
> > > therefore and shouldn't be in a patch calling itself "generalise
> > > for
> > > single ended variants".
> >
> > Well yes they're required.
> >
> > Should I send a patch adding the `thead,th1520-dc8200` part of the
> > schema?
>
> If you mean the code above, no. Adding a conditional section when
> there's only that compatible doesn't make sense.
>
> What you could do is just add it at the top level though, which would
> also benefit this patch since it'd not have to be conditionally added
> for the new nuvoton device.
> Just note in your commit message about what the ABI impact of the
> change
> to required properties is (effectively nothing because it's optional
> in
> the driver and the only user has the properties).
Okay, I will craft such a patch and send it.
>
> > > > +
> > > > + resets:
> > > > + minItems: 1
> > > > + maxItems: 1
> > > > +
> > > > + reset-names:
> > > > + items:
> > > > + - const: core
> > >
> > > This is just maxItems: 1.
> >
> > Well the implicit rules of DT binding schemas are quite weird...
>
> I don't think it is that strange, as the binding has
> reset-names:
> items:
> - const: core
> - const: axi
> - const: ahb
Ah does the list constraint the order of items? If it constrains the
order, it partly breaks the intention of having names; if it does not
constrain the order, it needs to be clarified that the required 1 reset
is core instead of the other two.
Thanks,
Icenowy
> so just constraining to one item is the simplest way to do this
> without
> duplication.
^ permalink raw reply
* Re: [PATCH v6 2/2] drm/bridge: Add Lontium LT9611C(EX/UXD) MIPI DSI to HDMI driver
From: Sunyun Yang @ 2026-06-26 9:05 UTC (permalink / raw)
To: Maxime Ripard
Cc: Krzysztof Kozlowski, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, dmitry.baryshkov, maarten.lankhorst, rfoss,
Laurent.pinchart, tzimmermann, jonas, jernej.skrabec, devicetree,
dri-devel, linux-kernel, xmzhu, xmzhu, rlyu, xbpeng
In-Reply-To: <CAFQXuNa330ctD3VgAVxDSzovwyy0hwVPTfm6pKzeLZDGeq=_=Q@mail.gmail.com>
Sunyun Yang <syyang@lontium.com> 于2026年6月26日周五 16:40写道:
>
> Maxime Ripard <mripard@kernel.org> 于2026年6月26日周五 16:26写道:
> >
> > On Fri, Jun 26, 2026 at 04:13:18PM +0800, Sunyun Yang wrote:
> > > Maxime Ripard <mripard@kernel.org> 于2026年6月26日周五 15:49写道:
> > > >
> > > > On Fri, Jun 26, 2026 at 10:15:03AM +0800, Sunyun Yang wrote:
> > > > > Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 21:51写道:
> > > > > >
> > > > > > On 25/06/2026 15:40, Sunyun Yang wrote:
> > > > > > > Sunyun Yang <syyang@lontium.com> 于2026年6月25日周四 21:26写道:
> > > > > > >>
> > > > > > >> Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 21:17写道:
> > > > > > >>>
> > > > > > >>> On 25/06/2026 15:14, Sunyun Yang wrote:
> > > > > > >>>> Krzysztof Kozlowski <krzk@kernel.org> 于2026年6月25日周四 20:54写道:
> > > > > > >>>>>
> > > > > > >>>>> On 08/05/2026 15:40, syyang@lontium.com wrote:
> > > > > > >>>>>> +
> > > > > > >>>>>> +static void lt9611c_reset(struct lt9611c *lt9611c)
> > > > > > >>>>>> +{
> > > > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > > > >>>>>> + msleep(20);
> > > > > > >>>>>> +
> > > > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 0);
> > > > > > >>>>>> + msleep(20);
> > > > > > >>>>>> +
> > > > > > >>>>>> + gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > > > >>>>>
> > > > > > >>>>> This is just plain wrong. Why do you assert, then de-assert and then
> > > > > > >>>>> finally assert AGAIN the reset leaving the device in powerdown stage?
> > > > > > >>>>>
> > > > > > >>>> I am using software to emulate the hardware RESET button on our EVB.
> > > > > > >>>> When the hardware RESET button is pressed while our chip is running,
> > > > > > >>>> the signal level changes from HIGH to LOW and then back to HIGH.
> > > > > > >>>>
> > > > > > >>>> Of course, we can also use the following:
> > > > > > >>>> static void lt9611c_reset(struct lt9611c *lt9611c)
> > > > > > >>>> {
> > > > > > >>>> gpiod_set_value_cansleep(lt9611c->reset_gpio, 0);
> > > > > > >>>> msleep(50);
> > > > > > >>>> gpiod_set_value_cansleep(lt9611c->reset_gpio, 1);
> > > > > > >>>> msleep(20);
> > > > > > >>>> }
> > > > > > >>>
> > > > > > >>> Makes no sense either and you just did not get the point and did not
> > > > > > >>> answer my question. I asked WHY you leave asserted. Answer "we emulate"
> > > > > > >>> is just plain wrong.
> > > > > > >>>
> > > > > > >>> So again please answer:
> > > > > > >>>
> > > > > > >>> Why do you leave device with reset asserted?
> > > > > > >>>
> > > > > > >>
> > > > > > >> devicetree: reset-gpios = <&tlmm 128 GPIO_ACTIVE_HIGH>;
> > > > > > >>
> > > > > > >> GPIO_ACTIVE_HIGH:
> > > > > > >>
> > > > > > >> gpiod_set_value_cansleep(lt9611c->reset_gpio, 0); ------ reset pin
> > > > > > >> is Low level : Clear the register configuration in the chip to stop
> > > > > > >> the chip from working.
> > > > > > >>
> > > > > > >> gpiod_set_value_cansleep(lt9611c->reset_gpio, 1); ------ reset pin
> > > > > > >> is high level: The chip resumes operation.
> > > > > > >>
> > > > > > >>
> > > > > > >
> > > > > > > Our purpose is: pull the level low to clear the register configuration
> > > > > > > in the chip, and then pull it high to allow the MCU inside the chip to
> > > > > > > re‑initialize the registers.
> > > > > >
> > > > > >
> > > > > > And you do completely opposite... so that confirms your code is just wrong.
> > > > > >
> > > > >
> > > > > The lontium-lt9611.yaml uses GPIO_ACTIVE_HIGH. I am just following the
> > > > > rule of this device tree. If I modify the device tree to use
> > > > > GPIO_ACTIVE_LOW,
> > > > > and use the following code in my driver, then my driver would be correct.
> > > > > However, would the existing kernel drivers lontium-lt9611uxc.c and
> > > > > lontium-lt9611.c be affected?
> > > >
> > > > It might, but then it's a DT problem. The GPIO API for drivers always
> > > > considers the logical state of a GPIO, so if you need to assert a
> > > > signal, you'll always need to set 1. That's what Krzysztof was trying to
> > > > explain.
> > > >
> > > > The DT will provide with GPIO_ACTIVE_* how that logical state translates
> > > > to a physical GPIO state.
> > > >
> > > > If the DT says that this particular GPIO is active-high, then it means
> > > > that we need to set the GPIO to 1 to assert reset. Now of course, it
> > > > might not make sense for the controller itself, but it might for the
> > > > board if there's a GPIO inverter in the middle for example.
> > > >
> > > > Anyway, in the case you're raising, the issue definitely lies in the DT,
> > > > and that's what would need to be fixed.
> > > >
> > > > I also wouldn't be too concerned about lontium-lt9611.yaml, it's just an
> > > > example.
> > > >
> > > > Maxime
> > >
> > > thanks Maxime, I will modify this code in the next version of the
> > > driver, and I hope you can accept these changes.
> > >
> > > Maxime:
> > > I have another question I would like to ask you
> > > regarding sashiko-bot@kernel.org. Since sashiko-bot sometimes has
> > > opinions that differ from yours, whose advice should I follow?
> > >
> > > If I do not adopt sashiko-bot's suggestions, will my patches still be
> > > accepted into the upstream Linux kernel?
> >
> > I can't give a blanket answer. It depends on what you ignore exactly.
> >
>
> Okay, another question: sashiko-bot is an AI bot. Are its review
> comments optional, or must they be followed?
>
For example, in my driver, there is a function for upgrading the chip
firmware. During debugging or production, upgrading the chip firmware
will acquire a lock, which will block the DRM callback and affect
display. It will be fine after the upgrade is completed and some
devices are restarted. As long as there is no subsequent upgrade,
display can work normally.
From a purely software perspective, the AI bot considered this
approach unacceptable and proposed synchronizing the pre-upgrade state
to the DRM framework. From my personal perspective, I think the AI
bot's suggestion would only make my driver more complex and redundant.
Do you think I need to adopt the AI bot's suggestion?
In addition, if I follow the AI bot's suggestion, the
lontium-lt9611uxc.c and lontium-lt8713sx.c drivers that have been
merged into the upstream Linux kernel would not meet the AI bot's
requirements.
When I get a reviewer's Reviewed-by flag, can I ignore the opinion of
sashiko-bot (the AI bot)?
> > Maxime
^ permalink raw reply
* Re: [PATCH v5 1/7] dt-bindings: display: verisilicon,dc: generalize for single-output variants
From: Icenowy Zheng @ 2026-06-26 9:09 UTC (permalink / raw)
To: Conor Dooley
Cc: Conor Dooley, Joey Lu, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, ychuang3, schung, yclu4,
dri-devel, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260626-agreement-express-b16c71315f7b@wendy>
在 2026-06-26五的 09:57 +0100,Conor Dooley写道:
> On Fri, Jun 26, 2026 at 03:58:14PM +0800, Icenowy Zheng wrote:
> > 在 2026-06-26五的 08:22 +0100,Conor Dooley写道:
> > > On Thu, Jun 25, 2026 at 05:33:37PM +0100, Conor Dooley wrote:
> > > > On Thu, Jun 25, 2026 at 05:44:43PM +0800, Joey Lu wrote:
> > > > > +
> > > > > + - if:
> > > > > + properties:
> > > > > + compatible:
> > > > > + contains:
> > > > > + const: nuvoton,ma35d1-dcu
> > > > > + then:
> > > > > + properties:
> > > > > + clocks:
> > > > > + minItems: 2
> > > >
> > > > Anything that updates the minimum constraint should be done at
> > > > the
> > > > top
> > > > level of this schema. The conditional section should then
> > > > tighten
> > > > the
> > > > constraint, in this case that means only having maxItems.
> > > >
> > > > > + maxItems: 2
> > > > > +
> > > > > + clock-names:
> > > > > + items:
> > > > > + - const: core
> > > > > + - const: pix0
> > > >
> > > > Does this even work when the top level schema thinks clock 2
> > > > should
> > > > be
> > > > called axi?
> > >
> > > Additionally here, only have core and pix0 seems like it might be
> > > an
> > > oversimplification. I doubt removing the second output port means
> > > that
> > > the axi and ahb clocks are no longer needed.
> > > Is it the case that your device supplies the same clock to core,
> > > ahb
> > > and
> > > axi? If so, then you should fill those clocks in in your
> > > devicetree
> > > and
> > > this can just constrain the number of clocks/clock-names to 4.
> >
> > The clock controller of that SoC is quite weird -- it has only a
> > single
> > gate bit, but controlling 3 clock gates. All core, ahb and axi
> > clocks
> > have gates controlled by this single bit, so it's why currently
> > it's
> > modelled as only core clock supplied.
>
> Yeah, then what's in the binding is definitely wrong.
> Even if the same clock was provided to all clock inputs in the IP,
> all
> individual clock should be listed in the devicetree - although it
> will
> look a little silly to see clocks = <&foo 2>, <&foo 2>, <&foo 2>,
> <&foo 2>;
> In this case, 3 clocks controlled by 1 gate bit is an implementation
> detail
> of the SoC's clocking hardware, and not relevant to how the dc
> instance
> should be described.
>
> > Well it might be worthful to supply the bus clock before the gate
> > as
> > ahb/axi, especially axi, because both the AXI clock and the core
> > clock
> > constraints the maximum pixel clock.
>
> Right. And looking at patch 4/7, and the wording:
> > The Nuvoton MA35D1 SoC integrates a DCUltraLite display controller
> > whose
> > AXI and AHB bus clocks share a single gate enable bit with the
> > display
> > core clock, so the clock driver does not expose them separately.
> > This
> > patch makes the axi and ahb clocks optional in the probe.
>
> It sounds like there's probably some issues with how things are
> modelled
> clock wise in this device, unless this is not an accurate statement
> and
> there's actually one clock provided to all three inputs. If they're
> distinct clocks, with different rates, only having one exposed has a
> lot
> of potential to be problematic!
Yes, I agree with this, they're different clocks according to the
manual.
I added the clk people to the CC list in a reply of the previous
revision, but they didn't react yet. I don't know how to represent
multiple clock gates sharing a single control bit in the clock
framework...
Maybe just supplying the ungated AXI/AHB clocks here, and let the core
clock manage the gate?
Thanks,
Icenowy
^ permalink raw reply
* Re: [RFC PATCH 1/3] dt-bindings: pinctrl: mt8516/mt8167: Move compatibles from mt66xx to mt6795
From: Luca Leonardo Scorcia @ 2026-06-26 9:12 UTC (permalink / raw)
To: Conor Dooley
Cc: linux-mediatek, Sean Wang, Linus Walleij, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel
In-Reply-To: <20260625-unearth-suffering-e2c59d39da0f@spud>
> Usually when making ABI changes because something was inaccurate (but
> not wrong to the point that it didn't work at all) it's possible to
> support both new and old ABIs at the same time because of new properties
> etc. This is a difficult one because it's using the same properties in
> different ways. A new compatible would definitely be required for a
> genuine fresh start while retaining kernel support for the old mechanism
> in this case.
All things considered, the cleanest solution seems to be adding a new
compatible, mark the old one as deprecated and also try to fix the old
driver code. I'll try to do that before submitting again.
Thank you for your help!
--
Luca Leonardo Scorcia
l.scorcia@gmail.com
^ permalink raw reply
* [RFC v3 PATCH 0/2] Add Lenovo ThinkEdge SE70 carrier board support
From: Jiqi Li @ 2026-06-26 9:13 UTC (permalink / raw)
To: linux-tegra
Cc: devicetree, robh+dt, krzk+dt, conor+dt, jonathanh, thierry.reding,
mpearson-lenovo, Jiqi Li
This patch set introduces device tree binding and standalone DTS file
for Lenovo ThinkEdge SE70, a fanless industrial edge gateway powered by
NVIDIA Tegra194 (Xavier NX P3509-0000 + P3668-0001) SOM.
Patch 1 updates tegra.yaml bindings to add three-stage compatible string
matching board + SOM + SoC, aligning with existing Tegra carrier board specs.
Patch 2 adds full compliant carrier DTS implementing 40-pin header pinmux,
400kHz I2C bus, dedicated SD card 3.3V power regulator; disables unpopulated
PWM/tach hardware per real hardware layout.
All static device tree checks pass: dtbs compile, dt_binding_check complete
without failures.
We maintain internal downstream DTS for mass-production SE70 hardware.
Upstreaming follows the same OEM contribution pattern as Google/Xiaomi Tegra
boards, reduces long-term out-of-tree patch maintenance burden.
This industrial platform has a full 7-year production support lifecycle until
2028, Lenovo will continuously backport DT fixes throughout its service window.
All peripherals rely on generic mainline drivers, no proprietary extensions.
Changes in v3:
- Fix all Sashiko static DT violations:
1. Reorganize pinctrl, put all pin configs under pinmux@2430000
2. Rename sdhci@3440000 to mmc@3440000 to match upstream
3. Move pwm-fan disable node to root level
4. Remove disabled overrides for non-existent nodes
5. Drop unused #address-cells / #size-cells from fixed-regulators
- Extend compatible string to board+SOM+tegra194 triple format
Jiqi Li (2):
dt-bindings: arm: tegra: Add lenovo,thinkedge-se70 compatible string
arm64: tegra: Add Lenovo ThinkEdge SE70 carrier board DTS
.../devicetree/bindings/arm/tegra.yaml | 5 +
arch/arm64/boot/dts/nvidia/Makefile | 1 +
.../nvidia/tegra194-lenovo-thinkedge-se70.dts | 124 ++++++++++++++++++
3 files changed, 130 insertions(+)
create mode 100644 arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts
--
2.43.0
^ permalink raw reply
* [PATCH 2/2] arm64: tegra: Add Lenovo ThinkEdge SE70 carrier board DTS
From: Jiqi Li @ 2026-06-26 9:13 UTC (permalink / raw)
To: linux-tegra
Cc: devicetree, robh+dt, krzk+dt, conor+dt, jonathanh, thierry.reding,
mpearson-lenovo, Jiqi Li
In-Reply-To: <20260626091349.570091-1-lijq9@lenovo.com>
ThinkEdge SE70 is a fanless industrial edge gateway built around
NVIDIA Tegra194 Xavier NX SOM. This patch adds a standalone device
tree file describing core carrier board peripherals:
- Custom 40-pin header pinmux configuration
- External SD card slot with dedicated 3.3V fixed regulator
No fan, PWM, tachometer, extra camera/spi peripherals are present
on this passively cooled platform, so unused nodes are explicitly
disabled following mainline device tree best practices.
Static verification passed: dt_binding_check and dtbs compilation
complete without errors.
Signed-off-by: Jiqi Li <lijq9@lenovo.com>
---
arch/arm64/boot/dts/nvidia/Makefile | 1 +
.../nvidia/tegra194-lenovo-thinkedge-se70.dts | 124 ++++++++++++++++++
2 files changed, 125 insertions(+)
create mode 100644 arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts
diff --git a/arch/arm64/boot/dts/nvidia/Makefile b/arch/arm64/boot/dts/nvidia/Makefile
index 72c0cb5efa47..736a3f8a923f 100644
--- a/arch/arm64/boot/dts/nvidia/Makefile
+++ b/arch/arm64/boot/dts/nvidia/Makefile
@@ -29,6 +29,7 @@ dtb-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186-p3509-0000+p3636-0001.dtb
dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p2972-0000.dtb
dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p3509-0000+p3668-0000.dtb
dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-p3509-0000+p3668-0001.dtb
+dtb-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra194-lenovo-thinkedge-se70.dtb
dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-sim-vdk.dtb
dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3737-0000+p3701-0000.dtb
dtb-$(CONFIG_ARCH_TEGRA_234_SOC) += tegra234-p3737-0000+p3701-0008.dtb
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts b/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts
new file mode 100644
index 000000000000..44a7ae9a05bf
--- /dev/null
+++ b/arch/arm64/boot/dts/nvidia/tegra194-lenovo-thinkedge-se70.dts
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra194-p3668-0001.dtsi"
+#include "tegra194-p3509-0000.dtsi"
+
+/ {
+ model = "Lenovo ThinkEdge SE70";
+ compatible = "lenovo,thinkedge-se70", "nvidia,p3509-0000+p3668-0001", "nvidia,tegra194";
+
+ chosen {
+ bootargs = "console=ttyTCU0,115200";
+ };
+
+ /* Fixed 3.3V regulator for external SD card slot */
+ fixed-regulators {
+ compatible = "simple-bus";
+ ap2306gn_3v3_sd: ap2306gn-3v3-sd {
+ compatible = "regulator-fixed";
+ regulator-name = "ap2306gn-3v3-sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio TEGRA194_MAIN_GPIO(Q, 5) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ status = "okay";
+ };
+ };
+
+ bus@0 {
+
+ /* Custom pinmux configurations for 40-pin expansion header */
+ pinmux@2430000 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdr40_pinmux>;
+
+ hdr40_pinmux: header-40pin-pinmux {
+ pin7 {
+ nvidia,pins = "aud_mclk_ps4";
+ nvidia,function = "aud";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pin11 {
+ nvidia,pins = "uart1_rts_pr4";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ pin12 {
+ nvidia,pins = "dap5_sclk_pt5";
+ nvidia,function = "i2s5";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pin35 {
+ nvidia,pins = "dap5_fs_pu0";
+ nvidia,function = "i2s5";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pin36 {
+ nvidia,pins = "uart1_cts_pr5";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pin38 {
+ nvidia,pins = "dap5_din_pt7";
+ nvidia,function = "i2s5";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+ pin40 {
+ nvidia,pins = "dap5_dout_pt6";
+ nvidia,function = "i2s5";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ /* Configure i2c bus clock to 400kHz for carrier board peripherals */
+ i2c@3160000 {
+ clock-frequency = <400000>;
+ status = "okay";
+ };
+
+ /* SDMMC3 for external user SD card slot with dedicated 3.3V power */
+ mmc@3440000 {
+ vmmc-supply = <&ap2306gn_3v3_sd>;
+ cd-gpios = <&gpio_aon TEGRA194_AON_GPIO(CC, 4) GPIO_ACTIVE_HIGH>;
+ status = "okay";
+ };
+
+ pwm@c340000 {
+ status = "disabled";
+ };
+ pwm@3280000 {
+ status = "disabled";
+ };
+ pwm@32c0000 {
+ status = "disabled";
+ };
+ pwm@32d0000 {
+ status = "disabled";
+ };
+ pwm@32f0000 {
+ status = "disabled";
+ };
+ };
+
+ /* Disable fan hardware not populated on SE70 carrier board */
+ pwm-fan {
+ status = "disabled";
+ };
+};
--
2.43.0
^ permalink raw reply related
* [PATCH 1/2] dt-bindings: arm: tegra: Add lenovo,thinkedge-se70 compatible string
From: Jiqi Li @ 2026-06-26 9:13 UTC (permalink / raw)
To: linux-tegra
Cc: devicetree, robh+dt, krzk+dt, conor+dt, jonathanh, thierry.reding,
mpearson-lenovo, Jiqi Li
In-Reply-To: <20260626091349.570091-1-lijq9@lenovo.com>
Lenovo ThinkEdge SE70 is a fanless industrial edge gateway carrier
board based on NVIDIA Tegra194 (Xavier NX) SOM.
Add the corresponding compatible string for device tree validation.
Signed-off-by: Jiqi Li <lijq9@lenovo.com>
---
Documentation/devicetree/bindings/arm/tegra.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml
index 033a63f6c068..1a71b4195114 100644
--- a/Documentation/devicetree/bindings/arm/tegra.yaml
+++ b/Documentation/devicetree/bindings/arm/tegra.yaml
@@ -268,6 +268,11 @@ properties:
items:
- const: nvidia,p3509-0000+p3668-0001
- const: nvidia,tegra194
+ - description: Lenovo ThinkEdge SE70
+ items:
+ - const: lenovo,thinkedge-se70
+ - const: nvidia,p3509-0000+p3668-0001
+ - const: nvidia,tegra194
- items:
- const: nvidia,tegra234-vdk
- const: nvidia,tegra234
--
2.43.0
^ permalink raw reply related
* [PATCH v2 0/4] PCI: mediatek-gen3: Add 2-lanes mode support + clock
From: Christian Marangi @ 2026-06-26 9:20 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ryder Lee, Michael Turquette, Stephen Boyd,
Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
This small series introduce support for 2-lanes mode for Airoha AN7581
SoC. This is needed for correctly functionality of Eagle WiFi Card
normally attached to this SoC that require a 2-line PCIe card to
correctly work (and give the proper performance)
The first 2 patch address a limitation of the PCIe implementation
where the PERSTOUT reset were indirectly asserted and deasserted
all at the same time (for all the 3 PCIe card) with PCIe
enable and disable.
The 2 patch address this and introduce correct reset to control
reset line for the relevant PCIe line.
The last 2 patch add additional logic and support to assert
and deassert the PERSTOUT and also apply the required configuration
for 2-lanes mode.
2-lanes mode is implemented in DT by adding the required property
and by defining the "num-lanes" to 2.
Changes v2:
- Address typo regs -> reg in Documentation
- Address typo lan -> lane in Documentation
- Apply a suggested fix from Airoha for PCIe MUX configuration
before PHY init
- Parse secondary reg in probe
- Add missing reset_status handling for inverted bits
- Move SCU to local handling in power_up
- Add check for max num-lanes for EN7581
Christian Marangi (4):
dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT
clk: en7523: add support for dedicated PCIe PERSTOUT reset
dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document
2-lanes
PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581
.../bindings/pci/airoha,en7581-pcie.yaml | 251 ++++++++++++++++++
.../bindings/pci/mediatek-pcie-gen3.yaml | 77 +-----
drivers/clk/clk-en7523.c | 39 ++-
drivers/pci/controller/pcie-mediatek-gen3.c | 101 +++++--
.../dt-bindings/reset/airoha,en7581-reset.h | 4 +
5 files changed, 370 insertions(+), 102 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
--
2.53.0
^ permalink raw reply
* [PATCH v2 1/4] dt-bindings: clock: airoha: Add additional reset for PCIe PERSTOUT
From: Christian Marangi @ 2026-06-26 9:20 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ryder Lee, Michael Turquette, Stephen Boyd,
Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
In-Reply-To: <20260626092029.3525264-1-ansuelsmth@gmail.com>
Add additional reset to control PCIe PERSTOUT reset line for each of the 3
PCIe lines.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
include/dt-bindings/reset/airoha,en7581-reset.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/dt-bindings/reset/airoha,en7581-reset.h b/include/dt-bindings/reset/airoha,en7581-reset.h
index 6544a1790b83..25e75534daa9 100644
--- a/include/dt-bindings/reset/airoha,en7581-reset.h
+++ b/include/dt-bindings/reset/airoha,en7581-reset.h
@@ -62,5 +62,9 @@
#define EN7581_CPU_TIMER_RST 50
#define EN7581_PCIE_HB_RST 51
#define EN7581_XPON_MAC_RST 52
+/* RST_PCIC */
+#define EN7581_PCIC_PERSTOUT0_RST 53
+#define EN7581_PCIC_PERSTOUT1_RST 54
+#define EN7581_PCIC_PERSTOUT2_RST 55
#endif /* __DT_BINDINGS_RESET_CONTROLLER_AIROHA_EN7581_H_ */
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/4] clk: en7523: add support for dedicated PCIe PERSTOUT reset
From: Christian Marangi @ 2026-06-26 9:20 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ryder Lee, Michael Turquette, Stephen Boyd,
Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
In-Reply-To: <20260626092029.3525264-1-ansuelsmth@gmail.com>
Add support for resetting the PCIe lines with the PERSTOUT reset. These
special reset are controlled by the PCIC register and are specific to each
of the 3 PCIe lines.
Notice that reset logic is inverted for these bit where 0 is assert and 1
deassert. This is intenrally handled in the reset function.
PCI enable/disable are updated to drop PERSTOUT bits in favor dedicated
reset handling.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/clk/clk-en7523.c | 39 ++++++++++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
index 1ab0e2eca5d3..c9b21d9bf2f3 100644
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -338,6 +338,7 @@ static const struct en_clk_desc en7581_base_clks[] = {
static const u16 en7581_rst_ofs[] = {
REG_RST_CTRL2,
REG_RST_CTRL1,
+ REG_NP_SCU_PCIC,
};
static const u16 en751221_rst_ofs[] = {
@@ -450,6 +451,11 @@ static const u16 en7581_rst_map[] = {
[EN7581_CPU_TIMER_RST] = RST_NR_PER_BANK + 28,
[EN7581_PCIE_HB_RST] = RST_NR_PER_BANK + 29,
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
+
+ /* RST_PCIC */
+ [EN7581_PCIC_PERSTOUT0_RST] = 2 * RST_NR_PER_BANK + 29,
+ [EN7581_PCIC_PERSTOUT1_RST] = 2 * RST_NR_PER_BANK + 26,
+ [EN7581_PCIC_PERSTOUT2_RST] = 2 * RST_NR_PER_BANK + 16,
};
static const u16 en751221_rst_map[] = {
@@ -635,9 +641,7 @@ static int en7581_pci_enable(struct clk_hw *hw)
void __iomem *np_base = cg->base;
u32 val, mask;
- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
- REG_PCI_CONTROL_PERSTOUT;
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
val = readl(np_base + REG_PCI_CONTROL);
writel(val | mask, np_base + REG_PCI_CONTROL);
@@ -650,9 +654,7 @@ static void en7581_pci_disable(struct clk_hw *hw)
void __iomem *np_base = cg->base;
u32 val, mask;
- mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
- REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
- REG_PCI_CONTROL_PERSTOUT;
+ mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
val = readl(np_base + REG_PCI_CONTROL);
writel(val & ~mask, np_base + REG_PCI_CONTROL);
usleep_range(1000, 2000);
@@ -754,14 +756,21 @@ static int en7523_reset_update(struct reset_controller_dev *rcdev,
unsigned long id, bool assert)
{
struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ void __iomem *addr = rst_data->base + offset;
+ bool inverted = false;
u32 val;
+ /* For PCIC reset logic is inverted, 0:assert 1:deassert*/
+ if (offset == REG_NP_SCU_PCIC)
+ inverted = true;
+
val = readl(addr);
+ val &= ~BIT(id % RST_NR_PER_BANK);
if (assert)
- val |= BIT(id % RST_NR_PER_BANK);
+ val |= inverted ? 0 : BIT(id % RST_NR_PER_BANK);
else
- val &= ~BIT(id % RST_NR_PER_BANK);
+ val |= inverted ? BIT(id % RST_NR_PER_BANK) : 0;
writel(val, addr);
return 0;
@@ -783,9 +792,17 @@ static int en7523_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
- void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK];
+ void __iomem *addr = rst_data->base + offset;
+ bool inverted = false;
+ u32 val;
+
+ /* For PCIC reset logic is inverted, 0:assert 1:deassert*/
+ if (offset == REG_NP_SCU_PCIC)
+ inverted = true;
- return !!(readl(addr) & BIT(id % RST_NR_PER_BANK));
+ val = readl(addr) & BIT(id % RST_NR_PER_BANK);
+ return inverted ? !val : !!val;
}
static int en7523_reset_xlate(struct reset_controller_dev *rcdev,
--
2.53.0
^ permalink raw reply related
* [PATCH v2 3/4] dt-bindings: PCI: mediatek-gen3: Split Airoha schema and document 2-lanes
From: Christian Marangi @ 2026-06-26 9:20 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ryder Lee, Michael Turquette, Stephen Boyd,
Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
In-Reply-To: <20260626092029.3525264-1-ansuelsmth@gmail.com>
To permit proper documentation of required property to support PCIe
configured for 2-lanes mode, split the Airoha schema part from the
mediatek-gen3 schema to a dedicated schema.
A PCIe configured for 2-lanes mode require an additional reg for the
secondary PCIe to be configured and the airoha,scu phandle to correctly
configure the PCIe MUX.
Rework the mediatek-gen3 schema to drop any redundant constraint previsouly
introduced for Airoha PCIe properties.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
.../bindings/pci/airoha,en7581-pcie.yaml | 251 ++++++++++++++++++
.../bindings/pci/mediatek-pcie-gen3.yaml | 77 +-----
2 files changed, 256 insertions(+), 72 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
diff --git a/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml b/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
new file mode 100644
index 000000000000..c690ba7f207c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/airoha,en7581-pcie.yaml
@@ -0,0 +1,251 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/airoha,en7581-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Gen3 PCIe controller on Airoha SoCs
+
+maintainers:
+ - Christian Marangi <ansuelsmth@gmail.com>
+
+description: |+
+ PCIe Gen3 MAC controller for Airoha SoCs, it supports Gen3 speed
+ and compatible with Gen2, Gen1 speed.
+
+ This PCIe controller supports up to 256 MSI vectors, the MSI hardware
+ block diagram is as follows:
+
+ +-----+
+ | GIC |
+ +-----+
+ ^
+ |
+ port->irq
+ |
+ +-+-+-+-+-+-+-+-+
+ |0|1|2|3|4|5|6|7| (PCIe intc)
+ +-+-+-+-+-+-+-+-+
+ ^ ^ ^
+ | | ... |
+ +-------+ +------+ +-----------+
+ | | |
+ +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+
+ |0|1|...|30|31| |0|1|...|30|31| |0|1|...|30|31| (MSI sets)
+ +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+
+ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+ | | | | | | | | | | | | (MSI vectors)
+ | | | | | | | | | | | |
+
+ (MSI SET0) (MSI SET1) ... (MSI SET7)
+
+ With 256 MSI vectors supported, the MSI vectors are composed of 8 sets,
+ each set has its own address for MSI message, and supports 32 MSI vectors
+ to generate interrupt.
+
+properties:
+ compatible:
+ const: airoha,en7581-pcie
+
+ reg:
+ minItems: 1
+ maxItems: 2
+
+ reg-names:
+ minItems: 1
+ maxItems: 2
+
+ interrupts:
+ maxItems: 1
+
+ ranges:
+ minItems: 1
+ maxItems: 8
+
+ iommu-map:
+ maxItems: 1
+
+ iommu-map-mask:
+ const: 0
+
+ resets:
+ minItems: 1
+ maxItems: 4
+
+ reset-names:
+ minItems: 1
+ maxItems: 4
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: sys-ck
+
+ phys:
+ maxItems: 1
+
+ phy-names:
+ items:
+ - const: pcie-phy
+
+ num-lanes:
+ enum: [1, 2]
+
+ mediatek,pbus-csr:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle to pbus-csr syscon
+ - description: offset of pbus-csr base address register
+ - description: offset of pbus-csr base address mask register
+ description:
+ Phandle with two arguments to the syscon node used to detect if
+ a given address is accessible on PCIe controller.
+
+ airoha,scu:
+ $ref: /schemas/types.yaml#/definitions/phandle-array
+ items:
+ - items:
+ - description: phandle to airoha SCU syscon
+ description:
+ Phandle to SCU syscon to configure PCIe MUX for 2 lines support.
+
+ '#interrupt-cells':
+ const: 1
+
+ interrupt-controller:
+ description: Interrupt controller node for handling legacy PCI interrupts.
+ type: object
+ properties:
+ '#address-cells':
+ const: 0
+ '#interrupt-cells':
+ const: 1
+ interrupt-controller: true
+
+ required:
+ - '#address-cells'
+ - '#interrupt-cells'
+ - interrupt-controller
+
+ additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - interrupts
+ - ranges
+ - clocks
+ - clock-names
+ - '#interrupt-cells'
+ - interrupt-controller
+
+allOf:
+ - $ref: /schemas/pci/pci-host-bridge.yaml#
+ - if:
+ properties:
+ num-lanes:
+ const: 2
+ then:
+ properties:
+ reg:
+ minItems: 2
+
+ reg-names:
+ items:
+ - const: pcie-mac
+ - const: sec-pcie-mac
+
+ resets:
+ minItems: 4
+
+ reset-names:
+ items:
+ - const: phy-lane0
+ - const: phy-lane1
+ - const: perstout
+ - const: sec-perstout
+
+ required:
+ - airoha,scu
+
+ else:
+ properties:
+ reg:
+ maxItems: 1
+
+ reg-names:
+ items:
+ - const: pcie-mac
+
+ resets:
+ minItems: 2
+ maxItems: 3
+
+ reset-names:
+ minItems: 2
+ items:
+ - enum: [ phy-lane0, phy-lane1, phy-lane2 ]
+ - enum: [ phy-lane1, perstout ]
+ - const: phy-lane2
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ pcie@1fc00000 {
+ compatible = "airoha,en7581-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ reg = <0x0 0x1fc00000 0x0 0x1670>,
+ <0x0 0x1fc20000 0x0 0x1670>;
+ reg-names = "pcie-mac", "sec-pcie-mac";
+
+ clocks = <&scuclk 7>;
+ clock-names = "sys-ck";
+
+ phys = <&pciephy>;
+ phy-names = "pcie-phy";
+
+ ranges = <0x02000000 0 0x20000000 0x0 0x20000000 0 0x4000000>;
+
+ resets = <&scuclk 48>,
+ <&scuclk 49>,
+ <&scuclk 53>,
+ <&scuclk 54>;
+ reset-names = "phy-lane0", "phy-lane1",
+ "perstout", "sec-perstout";
+
+ num-lanes = <2>;
+
+ mediatek,pbus-csr = <&pbus_csr 0x0 0x4>;
+
+ airoha,scu = <&scuclk>;
+
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+ bus-range = <0x00 0xff>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0x7>;
+ interrupt-map = <0 0 0 1 &pcie_intc 0>,
+ <0 0 0 2 &pcie_intc 1>,
+ <0 0 0 3 &pcie_intc 2>,
+ <0 0 0 4 &pcie_intc 3>;
+ pcie_intc: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
index 4db700fc36ba..510f1f2b1c5a 100644
--- a/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-gen3.yaml
@@ -59,7 +59,6 @@ properties:
- const: mediatek,mt8196-pcie
- const: mediatek,mt8192-pcie
- const: mediatek,mt8196-pcie
- - const: airoha,en7581-pcie
reg:
maxItems: 1
@@ -83,20 +82,20 @@ properties:
resets:
minItems: 1
- maxItems: 3
+ maxItems: 2
reset-names:
minItems: 1
- maxItems: 3
+ maxItems: 2
items:
- enum: [ phy, mac, phy-lane0, phy-lane1, phy-lane2 ]
+ enum: [ phy, mac ]
clocks:
- minItems: 1
+ minItems: 4
maxItems: 6
clock-names:
- minItems: 1
+ minItems: 4
maxItems: 6
assigned-clocks:
@@ -115,17 +114,6 @@ properties:
power-domains:
maxItems: 1
- mediatek,pbus-csr:
- $ref: /schemas/types.yaml#/definitions/phandle-array
- items:
- - items:
- - description: phandle to pbus-csr syscon
- - description: offset of pbus-csr base address register
- - description: offset of pbus-csr base address mask register
- description:
- Phandle with two arguments to the syscon node used to detect if
- a given address is accessible on PCIe controller.
-
'#interrupt-cells':
const: 1
@@ -177,16 +165,6 @@ allOf:
- const: peri_26m
- const: top_133m
- resets:
- minItems: 1
- maxItems: 2
-
- reset-names:
- minItems: 1
- maxItems: 2
-
- mediatek,pbus-csr: false
-
- if:
properties:
compatible:
@@ -208,16 +186,6 @@ allOf:
- const: peri_26m
- const: peri_mem
- resets:
- minItems: 1
- maxItems: 2
-
- reset-names:
- minItems: 1
- maxItems: 2
-
- mediatek,pbus-csr: false
-
- if:
properties:
compatible:
@@ -246,8 +214,6 @@ allOf:
- const: phy
- const: mac
- mediatek,pbus-csr: false
-
- if:
properties:
compatible:
@@ -257,7 +223,6 @@ allOf:
then:
properties:
clocks:
- minItems: 4
maxItems: 4
clock-names:
@@ -267,38 +232,6 @@ allOf:
- const: peri_26m
- const: top_133m
- resets:
- minItems: 1
- maxItems: 2
-
- reset-names:
- minItems: 1
- maxItems: 2
-
- mediatek,pbus-csr: false
-
- - if:
- properties:
- compatible:
- const: airoha,en7581-pcie
- then:
- properties:
- clocks:
- maxItems: 1
-
- clock-names:
- items:
- - const: sys-ck
-
- resets:
- minItems: 3
-
- reset-names:
- items:
- - const: phy-lane0
- - const: phy-lane1
- - const: phy-lane2
-
unevaluatedProperties: false
examples:
--
2.53.0
^ permalink raw reply related
* [PATCH v2 4/4] PCI: mediatek-gen3: Add 2-lanes mode support for Airoha AN7581
From: Christian Marangi @ 2026-06-26 9:20 UTC (permalink / raw)
To: Bjorn Helgaas, Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ryder Lee, Michael Turquette, Stephen Boyd,
Brian Masney, Philipp Zabel, Matthias Brugger,
AngeloGioacchino Del Regno, Christian Marangi, Jianjun Wang,
linux-pci, devicetree, linux-kernel, linux-mediatek, linux-clk,
linux-arm-kernel
In-Reply-To: <20260626092029.3525264-1-ansuelsmth@gmail.com>
The Airoha AN7581 SoC supports configuring the first PCIe0 line to 2-lanes
mode by bonding it with the second PCIe line. This is done by configuring
the PCIe MUX in the SCU register.
To correctly configure the line for 2-lanes mode, it's required to define
in DT an additional reg, 'sec-pcie-mac' for the secondary PCIe.
It's also needed to define the additional reset and the PERSTOUT reset.
Also 'airoha,scu' property is mandatory to correctly configure the SCU
register for the PCIe MUX.
Finally to toggle 2-lanes mode, it's needed to define in DT 'num-lanes' as
2.
In such configuration the EQ preset are configured to the same values.
To permit correct configuration of the PCIe line, additional logic is added
to assert and deassert the PERSTOUT resets.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/pci/controller/pcie-mediatek-gen3.c | 101 ++++++++++++++++----
1 file changed, 82 insertions(+), 19 deletions(-)
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index b0accd828589..14893cff135a 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -32,6 +32,11 @@
#include "../pci.h"
+/* AN7581 SCU register */
+#define SCU_PCIC 0x88
+#define SCU_PCIC_PCIE_CTRL GENMASK(7, 0)
+
+/* PCIe register */
#define PCIE_BASE_CFG_REG 0x14
#define PCIE_BASE_CFG_SPEED GENMASK(15, 8)
@@ -131,6 +136,7 @@
#define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2)
#define MAX_NUM_PHY_RESETS 3
+#define MAX_NUM_PERSTOUT_RESETS 2
#define PCIE_MTK_RESET_TIME_US 10
@@ -203,9 +209,11 @@ struct mtk_msi_set {
struct mtk_gen3_pcie {
struct device *dev;
void __iomem *base;
+ void __iomem *sec_base;
phys_addr_t reg_base;
struct reset_control *mac_reset;
struct reset_control_bulk_data phy_resets[MAX_NUM_PHY_RESETS];
+ struct reset_control_bulk_data perstout_resets[MAX_NUM_PERSTOUT_RESETS];
struct phy *phy;
struct clk_bulk_data *clks;
int num_clks;
@@ -928,6 +936,14 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
if (ret)
return dev_err_probe(dev, ret, "failed to get PHY bulk reset\n");
+ pcie->perstout_resets[0].id = "perstout";
+ pcie->perstout_resets[1].id = "sec-perstout";
+
+ ret = devm_reset_control_bulk_get_optional_exclusive(dev, MAX_NUM_PERSTOUT_RESETS,
+ pcie->perstout_resets);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get PERSTOUT bulk reset\n");
+
pcie->mac_reset = devm_reset_control_get_optional_exclusive(dev, "mac");
if (IS_ERR(pcie->mac_reset))
return dev_err_probe(dev, PTR_ERR(pcie->mac_reset), "failed to get MAC reset\n");
@@ -949,18 +965,38 @@ static int mtk_pcie_parse_port(struct mtk_gen3_pcie *pcie)
pcie->num_lanes = num_lanes;
}
+ /* Map secondary PCIe for 2-lanes mode for EN7581 */
+ if (num_lanes == 2 && device_is_compatible(dev, "airoha,en7581-pcie")) {
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec-pcie-mac");
+ if (!regs)
+ return -EINVAL;
+ pcie->sec_base = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(pcie->sec_base))
+ return dev_err_probe(dev, PTR_ERR(pcie->sec_base), "failed to map secondary register base\n");
+ }
+
return 0;
}
static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
{
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
+ unsigned int num_lanes = max(1, pcie->num_lanes);
+ struct regmap *pbus_regmap, *scu;
struct device *dev = pcie->dev;
struct resource_entry *entry;
- struct regmap *pbus_regmap;
u32 val, args[2], size;
resource_size_t addr;
- int err;
+ int i, err;
+
+ if (num_lanes > 2)
+ return dev_err_probe(dev, -EINVAL, "unsupported num-lanes, maximum 2 lanes supported\n");
+
+ if (num_lanes == 2) {
+ scu = syscon_regmap_lookup_by_phandle(dev->of_node, "airoha,scu");
+ if (IS_ERR(scu))
+ return dev_err_probe(dev, PTR_ERR(scu), "failed to map SCU regmap\n");
+ }
/*
* The controller may have been left out of reset by the bootloader
@@ -992,6 +1028,19 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
size = lower_32_bits(resource_size(entry->res));
regmap_write(pbus_regmap, args[1], GENMASK(31, __fls(size)));
+ /* Assert PERSTOUT for all relevant lines */
+ err = reset_control_bulk_assert(MAX_NUM_PERSTOUT_RESETS,
+ pcie->perstout_resets);
+ if (err) {
+ dev_err(dev, "failed to assert PERSTOUTs\n");
+ return err;
+ }
+
+ /* Configure SCU MUX to disable PCIE1 for 2 lines mode */
+ if (num_lanes == 2)
+ regmap_update_bits(scu, SCU_PCIC, SCU_PCIC_PCIE_CTRL,
+ FIELD_PREP(SCU_PCIC_PCIE_CTRL, BIT(1)));
+
/*
* Unlike the other MediaTek Gen3 controllers, the Airoha EN7581
* requires PHY initialization and power-on before PHY reset deassert.
@@ -1024,33 +1073,47 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
- val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
- FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
- FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
- FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
- writel_relaxed(val, pcie->base + PCIE_EQ_PRESET_01_REG);
-
- val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
- FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
- FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
- FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
- writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
-
err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
if (err) {
dev_err(dev, "failed to prepare clock\n");
goto err_clk_prepare_enable;
}
- /*
- * Airoha EN7581 performs PCIe reset via clk callbacks since it has a
- * hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to
- * complete the PCIe reset.
- */
+ /* Wait for refclk to stabilize */
msleep(PCIE_T_PVPERL_MS);
+ /* Configure all the lines to the same EQ config */
+ for (i = 0; i < num_lanes; i++) {
+ void __iomem *base = pcie->base;
+
+ if (i == 1)
+ base = pcie->sec_base;
+
+ val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
+ FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
+ FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
+ FIELD_PREP(PCIE_VAL_LN1_UPSTREAM, 0x41);
+ writel_relaxed(val, base + PCIE_EQ_PRESET_01_REG);
+
+ val = PCIE_K_PHYPARAM_QUERY | PCIE_K_QUERY_TIMEOUT |
+ FIELD_PREP(PCIE_K_PRESET_TO_USE_16G, 0x80) |
+ FIELD_PREP(PCIE_K_PRESET_TO_USE, 0x2) |
+ FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
+ writel_relaxed(val, base + PCIE_PIPE4_PIE8_REG);
+ }
+
+ /* Deassert PERSTOUT for all relevant lines */
+ err = reset_control_bulk_deassert(MAX_NUM_PERSTOUT_RESETS,
+ pcie->perstout_resets);
+ if (err) {
+ dev_err(dev, "failed to deassert PERSTOUTs\n");
+ goto err_perstout_deassert;
+ }
+
return 0;
+err_perstout_deassert:
+ clk_bulk_disable_unprepare(pcie->num_clks, pcie->clks);
err_clk_prepare_enable:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
--
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