* [PATCH v8 1/2] dt-bindings: ufs: Document static TX Equalization settings properties
From: Can Guo @ 2026-06-15 8:50 UTC (permalink / raw)
To: krzk, bvanassche, beanhuo, peter.wang, martin.petersen, mani
Cc: linux-scsi, Can Guo, Alim Akhtar, Avri Altman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Ram Kumar Dwivedi,
Zhaoming Luo,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <20260615085027.2102882-1-can.guo@oss.qualcomm.com>
UFS v5.0/UFSHCI v5.0 adds HS-G6 support (46.6 Gbps/lane) via UniPro
v3.0 and M-PHY v6.0. These specs define TX Equalization for all
High-Speed Gears (not only HS-G6) to compensate channel loss and
improve signal integrity at high speed.
For HS-G6, M-PHY uses PAM4 1b1b line coding. Pre-Coding may also be
required depending on channel characteristics.
Document vendor-neutral properties in ufs-common.yaml:
- txeq-preshoot-g[1-6]
- txeq-deemphasis-g[1-6]
- tx-precode-enable-g6
Values are per-lane Host/Device tuples (2 values for x1, 4 values for
x2). PreShoot/DeEmphasis range from 0..7, and Precode is 0/1.
These are board-specific signal-integrity tuning values. They depend on
channel SI/PHY characterization and validation (host PHY, device PHY,
package, and board routing), and are determined by HW/PHY designers.
Although UFSHCI v5.0 supports TX Equalization Training via UniPro v3.0,
which allows host software to determine optimal TX Equalization at
runtime, static board-specific TX Equalization settings in the Device
Tree are still necessary because:
- TX Equalization Training is not supported for HS-G3 and below
- TX Equalization Training is disabled on some platforms
Signed-off-by: Can Guo <can.guo@oss.qualcomm.com>
---
.../devicetree/bindings/ufs/ufs-common.yaml | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/Documentation/devicetree/bindings/ufs/ufs-common.yaml b/Documentation/devicetree/bindings/ufs/ufs-common.yaml
index ed97f5682509..145a6416e1df 100644
--- a/Documentation/devicetree/bindings/ufs/ufs-common.yaml
+++ b/Documentation/devicetree/bindings/ufs/ufs-common.yaml
@@ -105,6 +105,61 @@ properties:
Restricts the UFS controller to rate-a or rate-b for both TX and
RX directions.
+ tx-precode-enable-g6:
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ oneOf:
+ - items:
+ - description: Host_Lane0 precode
+ - description: Device_Lane0 precode
+ - items:
+ - description: Host_Lane0 precode
+ - description: Device_Lane0 precode
+ - description: Host_Lane1 precode
+ - description: Device_Lane1 precode
+ items:
+ enum: [0, 1]
+ description:
+ Static TX Precode enable values for HS-G6 only.
+
+patternProperties:
+ "^txeq-preshoot-g[1-6]$":
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ oneOf:
+ - items:
+ - description: Host_Lane0 Preshoot value
+ - description: Device_Lane0 Preshoot value
+ - items:
+ - description: Host_Lane0 Preshoot value
+ - description: Device_Lane0 Preshoot value
+ - description: Host_Lane1 Preshoot value
+ - description: Device_Lane1 Preshoot value
+ items:
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ description: |
+ Static TX Equalization PreShoot settings for High Speed Gears. These
+ values are programmed to the corresponding UniPro PA layer attribute
+ PA_TxEQG[1-6]Setting. Each value selects a Pre-Shoot level as defined
+ by the MIPI M-PHY specification (TX_HS_PreShoot_Setting).
+
+ "^txeq-deemphasis-g[1-6]$":
+ $ref: /schemas/types.yaml#/definitions/uint32-matrix
+ oneOf:
+ - items:
+ - description: Host_Lane0 DeEmphasis value
+ - description: Device_Lane0 DeEmphasis value
+ - items:
+ - description: Host_Lane0 DeEmphasis value
+ - description: Device_Lane0 DeEmphasis value
+ - description: Host_Lane1 DeEmphasis value
+ - description: Device_Lane1 DeEmphasis value
+ items:
+ enum: [0, 1, 2, 3, 4, 5, 6, 7]
+ description: |
+ Static TX Equalization DeEmphasis settings for High Speed Gears. These
+ values are programmed to the corresponding UniPro PA layer attribute
+ PA_TxEQG[1-6]Setting. Each value selects a De-Emphasis level as defined
+ by the MIPI M-PHY specification (TX_HS_DeEmphasis_Setting).
+
dependencies:
freq-table-hz: [ clocks ]
operating-points-v2: [ clocks, clock-names ]
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v4 4/6] drm/verisilicon: add DC8000 (DCUltraLite) display controller support
From: Icenowy Zheng @ 2026-06-15 8:51 UTC (permalink / raw)
To: Joey Lu, maarten.lankhorst, mripard, tzimmermann, airlied, simona,
robh, krzk+dt, conor+dt
Cc: ychuang3, schung, yclu4, dri-devel, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260615065003.76661-5-a0987203069@gmail.com>
在 2026-06-15一的 14:50 +0800,Joey Lu写道:
> The Nuvoton MA35D1 SoC integrates a Verisilicon DCUltraLite display
> controller whose register layout differs from the DC8200 in several
> important ways:
>
> 1. No CONFIG_EX commit path: framebuffer updates use the enable (bit
> 0)
> and reset (bit 4) bits in FB_CONFIG instead of the DC8200 staging
> registers (FB_CONFIG_EX, FB_TOP_LEFT, FB_BOTTOM_RIGHT,
> FB_BLEND_CONFIG, PANEL_CONFIG_EX).
>
> 2. No PANEL_START register: panel output starts when
> PANEL_CONFIG.RUNNING is set; there is no multi-display sync start
> register.
>
> 3. Different IRQ registers: DCUltraLite uses DISP_IRQ_STA (0x147C) /
> DISP_IRQ_EN (0x1480) versus DC8200's TOP_IRQ_ACK (0x0010) /
> TOP_IRQ_EN (0x0014).
>
> 4. Per-frame commit cycle: DCUltraLite requires the VALID bit in
> FB_CONFIG to be set at the start of each atomic commit
> (crtc_begin)
> and cleared after (crtc_flush).
>
> 5. Simpler clock topology: only 'core' (bus gate) and 'pix0' (pixel
> divider) clocks; no axi or ahb clocks required. Make axi_clk and
> ahb_clk optional (devm_clk_get_optional_enabled) so DC8000 nodes
> without those clocks are handled gracefully.
>
> Add vs_dc8000.c implementing the vs_dc_funcs vtable for the above
> differences. The probe now selects vs_dc8000_funcs when the
> identified
> generation is VSDC_GEN_DC8000 (DCUltraLite reads model 0x0,
> revision 0x5560, customer_id 0x305).
>
> Signed-off-by: Joey Lu <a0987203069@gmail.com>
> ---
> drivers/gpu/drm/verisilicon/Makefile | 2 +-
> drivers/gpu/drm/verisilicon/vs_dc.c | 9 ++-
> drivers/gpu/drm/verisilicon/vs_dc.h | 1 +
> drivers/gpu/drm/verisilicon/vs_dc8000.c | 78
> +++++++++++++++++++++++++
> 4 files changed, 86 insertions(+), 4 deletions(-)
> create mode 100644 drivers/gpu/drm/verisilicon/vs_dc8000.c
>
> diff --git a/drivers/gpu/drm/verisilicon/Makefile
> b/drivers/gpu/drm/verisilicon/Makefile
> index 9d4cd16452fa..d2fd8e4dff24 100644
> --- a/drivers/gpu/drm/verisilicon/Makefile
> +++ b/drivers/gpu/drm/verisilicon/Makefile
> @@ -1,6 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0-only
>
> -verisilicon-dc-objs := vs_bridge.o vs_crtc.o vs_dc.o vs_dc8200.o
> vs_drm.o vs_hwdb.o \
> +verisilicon-dc-objs := vs_bridge.o vs_crtc.o vs_dc.o vs_dc8200.o
> vs_dc8000.o vs_drm.o vs_hwdb.o \
> vs_plane.o vs_primary_plane.o vs_cursor_plane.o
>
> obj-$(CONFIG_DRM_VERISILICON_DC) += verisilicon-dc.o
> diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c
> b/drivers/gpu/drm/verisilicon/vs_dc.c
> index 9729b693d360..9499fffbca58 100644
> --- a/drivers/gpu/drm/verisilicon/vs_dc.c
> +++ b/drivers/gpu/drm/verisilicon/vs_dc.c
> @@ -90,13 +90,13 @@ static int vs_dc_probe(struct platform_device
> *pdev)
> return PTR_ERR(dc->core_clk);
> }
>
> - dc->axi_clk = devm_clk_get_enabled(dev, "axi");
> + dc->axi_clk = devm_clk_get_optional_enabled(dev, "axi");
> if (IS_ERR(dc->axi_clk)) {
> dev_err(dev, "can't get axi clock\n");
> return PTR_ERR(dc->axi_clk);
> }
>
> - dc->ahb_clk = devm_clk_get_enabled(dev, "ahb");
> + dc->ahb_clk = devm_clk_get_optional_enabled(dev, "ahb");
Please make the clock change a separated patch for atomicity.
BTW the MA35D1 manual's clock tree shows that DCUltra appears on AXI2
ACLK, AHB_HCLK2, behind a mux of SYS-PLL/EPLL-DIV2 (which seems to be
the core clock), and behind a divider (which seems to be the pixel
clock).
However it's weird that only one DCUltra Clock Enable Bit exists
despite both bus clocks have "ICG" (I think it means "Integrated Clock
Gating"). In addition the linux clk-ma35d1 driver assigns "dcu_gate" as
a downstream of "dcu_mux", although the Figure 6.5-2 in the TRM shows
no ICG after the "Display core CLK" mux.
Is the two bus clocks controlled by a single gate bit, and is the bit
also gating DC core clock?
Thanks,
Icenowy
> if (IS_ERR(dc->ahb_clk)) {
> dev_err(dev, "can't get ahb clock\n");
> return PTR_ERR(dc->ahb_clk);
> @@ -134,7 +134,10 @@ static int vs_dc_probe(struct platform_device
> *pdev)
> dev_info(dev, "Found DC%x rev %x customer %x\n", dc-
> >identity.model,
> dc->identity.revision, dc->identity.customer_id);
>
> - dc->funcs = &vs_dc8200_funcs;
> + if (dc->identity.generation == VSDC_GEN_DC8200)
> + dc->funcs = &vs_dc8200_funcs;
> + else
> + dc->funcs = &vs_dc8000_funcs;
>
> if (port_count > dc->identity.display_count) {
> dev_err(dev, "too many downstream ports than HW
> capability\n");
> diff --git a/drivers/gpu/drm/verisilicon/vs_dc.h
> b/drivers/gpu/drm/verisilicon/vs_dc.h
> index 544e1a37065b..5218e8cf63e2 100644
> --- a/drivers/gpu/drm/verisilicon/vs_dc.h
> +++ b/drivers/gpu/drm/verisilicon/vs_dc.h
> @@ -66,5 +66,6 @@ struct vs_dc {
> };
>
> extern const struct vs_dc_funcs vs_dc8200_funcs;
> +extern const struct vs_dc_funcs vs_dc8000_funcs;
>
> #endif /* _VS_DC_H_ */
> diff --git a/drivers/gpu/drm/verisilicon/vs_dc8000.c
> b/drivers/gpu/drm/verisilicon/vs_dc8000.c
> new file mode 100644
> index 000000000000..be0c0d7baf52
> --- /dev/null
> +++ b/drivers/gpu/drm/verisilicon/vs_dc8000.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 Joey Lu <yclu4@nuvoton.com>
> + */
> +
> +#include <linux/regmap.h>
> +
> +#include "vs_crtc_regs.h"
> +#include "vs_dc.h"
> +#include "vs_primary_plane_regs.h"
> +
> +static void vs_dc8000_panel_enable_ex(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_set_bits(dc->regs, VSDC_FB_CONFIG(output),
> + VSDC_FB_CONFIG_RESET);
> +}
> +
> +static void vs_dc8000_panel_disable_ex(struct vs_dc *dc, unsigned
> int output)
> +{
> + regmap_clear_bits(dc->regs, VSDC_FB_CONFIG(output),
> + VSDC_FB_CONFIG_RESET);
> +}
> +
> +static void vs_dc8000_crtc_begin(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_set_bits(dc->regs, VSDC_FB_CONFIG(output),
> + VSDC_FB_CONFIG_VALID);
> +}
> +
> +static void vs_dc8000_crtc_flush(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_clear_bits(dc->regs, VSDC_FB_CONFIG(output),
> + VSDC_FB_CONFIG_VALID);
> +}
> +
> +static void vs_dc8000_crtc_enable(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_set_bits(dc->regs, VSDC_FB_CONFIG(output),
> + VSDC_FB_CONFIG_ENABLE);
> +}
> +
> +static void vs_dc8000_crtc_disable(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_clear_bits(dc->regs, VSDC_FB_CONFIG(output),
> + VSDC_FB_CONFIG_ENABLE);
> +}
> +
> +static void vs_dc8000_enable_vblank(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_set_bits(dc->regs, VSDC_DISP_IRQ_EN,
> + VSDC_DISP_IRQ_VSYNC(output));
> +}
> +
> +static void vs_dc8000_disable_vblank(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_clear_bits(dc->regs, VSDC_DISP_IRQ_EN,
> + VSDC_DISP_IRQ_VSYNC(output));
> +}
> +
> +static u32 vs_dc8000_irq_ack(struct vs_dc *dc)
> +{
> + u32 irqs;
> +
> + regmap_read(dc->regs, VSDC_DISP_IRQ_STA, &irqs);
> + return irqs;
> +}
> +
> +const struct vs_dc_funcs vs_dc8000_funcs = {
> + .panel_enable_ex = vs_dc8000_panel_enable_ex,
> + .panel_disable_ex = vs_dc8000_panel_disable_ex,
> + .crtc_begin = vs_dc8000_crtc_begin,
> + .crtc_flush = vs_dc8000_crtc_flush,
> + .crtc_enable = vs_dc8000_crtc_enable,
> + .crtc_disable = vs_dc8000_crtc_disable,
> + .enable_vblank = vs_dc8000_enable_vblank,
> + .disable_vblank = vs_dc8000_disable_vblank,
> + .irq_ack = vs_dc8000_irq_ack,
> +};
^ permalink raw reply
* Re: [PATCH v4 7/7] arm64: dts: qcom: mahua: Switch pcie5_phy ref clock to RPMH_CXO_CLK
From: Qiang Yu @ 2026-06-15 8:51 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Taniya Das,
Konrad Dybcio, linux-arm-msm, linux-clk, devicetree, linux-kernel,
krishna.chundru
In-Reply-To: <db074223-ac01-4ffe-ae82-187ef0cb2cbb@oss.qualcomm.com>
On Tue, Jun 09, 2026 at 03:06:02PM +0200, Konrad Dybcio wrote:
> On 5/28/26 4:29 AM, Qiang Yu wrote:
> > PCIe5 PHY on Mahua gets refclk from CXO0 pad directly, so no QREF
> > clkref_en voting is required. Override the clock list to use RPMH_CXO_CLK
> > directly instead.
>
> This is the last piece of the puzzle that this series is missing.
> There's no QREF clkref_en, but there is a refgen that needs to be
> powered. For PCIe5 on Mahua this would be L2F_E0 (0p9) and L4H_E0
> (1p2).
>
> I think the easiest (laziest?) solution would be to add dummy clocks
> in the clkref driver and only toggle the required regulators. Another
> option is to defer back to individual drivers (such as PCIe QMPPHY).
>
> I kinda like the "one central node to drive power" approach, but I'm
> not sure others agree, since it stretches truth just a tiny bit
> (although not as much as one would think since there are *some*
> controls for the transparent-to-the-OS hw pieces in these paths still
> in TCSR).. Dmitry, Krzysztof, would you object to that?
>
PCIe5 PHY on Mahua does not use QREF at all, so there is no refgen for
QREF either. The refgen supplies you mentioned are for the PCIe5 PHY
itself, not for QREF. For other PHYs that do use QREF, there are two
refgens: one for QREF (voted here in the TCSR clkref driver) and one for
the PHY (which should be voted in the PHY driver).
- Qiang Yu
> Konrad
^ permalink raw reply
* Re: Re: [PATCH net-next v8 2/6] dt-bindings: ethernet: eswin: add EIC7700 eth1 RX clock inversion variant
From: 李志 @ 2026-06-15 8:49 UTC (permalink / raw)
To: sashiko-reviews; +Cc: robh, devicetree, conor+dt
In-Reply-To: <20260611013249.E03641F00893@smtp.kernel.org>
> -----Original Messages-----
> From: sashiko-bot@kernel.org
> Send time:Thursday, 11/06/2026 09:32:49
> To: lizhi2@eswincomputing.com
> Cc: robh@kernel.org, devicetree@vger.kernel.org, conor+dt@kernel.org
> Subject: Re: [PATCH net-next v8 2/6] dt-bindings: ethernet: eswin: add EIC7700 eth1 RX clock inversion variant
>
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Using a top-level `oneOf` partition for `compatible`-based constraints breaks schema extensibility and violates dt-schema conditional patterns.
> --
>
> commit c1875936c193e91a73baa1d661559e819f16e710
> Author: Zhi Li <lizhi2@eswincomputing.com>
>
> dt-bindings: ethernet: eswin: add EIC7700 eth1 RX clock inversion variant
>
> This commit adds a new compatible string for the EIC7700 eth1 MAC variant
> to handle RX clock inversion requirements. It introduces specific
> tx-internal-delay-ps constraints for each variant using a oneOf block.
>
> > diff --git a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
> > index 4e02fedae5c67..8cb7545c56e87 100644
> > --- a/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
> > +++ b/Documentation/devicetree/bindings/net/eswin,eic7700-eth.yaml
>
> [ ... ]
>
> > allOf:
> > - $ref: snps,dwmac.yaml#
> >
> > +oneOf:
> > + - properties:
> > + compatible:
> > + contains:
> > + const: eswin,eic7700-qos-eth
> > + tx-internal-delay-ps:
> > + minimum: 0
> > + maximum: 2540
> > + multipleOf: 20
> > +
> > + - properties:
> > + compatible:
> > + contains:
> > + const: eswin,eic7700-qos-eth-clk-inversion
> > + tx-internal-delay-ps:
> > + minimum: 2000
> > + maximum: 4540
> > + multipleOf: 20
>
> [Severity: Medium]
> According to the device tree bindings subsystem guidelines, YAML binding
> schemas typically use allOf with if-then blocks to apply different
> constraints based on the compatible string.
>
> Does placing a oneOf block at the root level create a mutually-exclusive
> validation partition that will break schema extensibility?
>
> If a new compatible string is added to the enum in the future, it looks
> like it might fail the entire oneOf block by not matching either arm,
> causing the whole document to fail validation.
>
> Could this be rewritten using allOf and if-then conditionals?
>
> [ ... ]
>
> > @@ -67,11 +89,6 @@ properties:
> > maximum: 2540
> > multipleOf: 20
> >
> > - tx-internal-delay-ps:
> > - minimum: 0
> > - maximum: 2540
> > - multipleOf: 20
> > -
> > eswin,hsp-sp-csr:
> > description:
> > HSP CSR is to control and get status of different high-speed peripherals
>
> [Severity: Medium]
> Is it intended to remove tx-internal-delay-ps entirely from the main
> properties block?
>
> Removing the property from the root properties block is usually considered
> a schema anti-pattern. Should the base property definition remain here,
> with only the range constraints being overridden in the conditional blocks
> above?
>
> --
I am planning to switch the schema from a top-level oneOf
to an allOf + if/then based approach.
The idea is to:
- define a global tx-internal-delay-ps range in properties (0–4540 ps)
- then apply per-compatible constraints using if/then:
- eswin,eic7700-qos-eth: max 2540 ps
- eswin,eic7700-qos-eth-clk-inversion: min 2000 ps
Does this align with the preferred dt-schema pattern for
modeling variant-specific constraints, compared to using oneOf?
^ permalink raw reply
* Re: [PATCH v2 3/5] pinctrl: samsung: Add Exynos8855 pinctrl configuration
From: sashiko-bot @ 2026-06-15 8:49 UTC (permalink / raw)
To: Alim Akhtar; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260615085252.1964423-4-alim.akhtar@samsung.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] The CMGP pin controller (instance 1) is missing the `.eint_wkup_init` callback, but its pin banks are configured for wakeup interrupts (`EINT_TYPE_WKUP`).
- [Low] The ALIVE and CMGP controllers erroneously configure `eint_gpio_init`, triggering spurious boot errors.
Pre-existing issues:
- [High] Calculating the PMU wakeup mask using the newly introduced, extremely sparse `eint_offset` values triggers C undefined behavior by shifting beyond 63 bits.
--
commit 9e3fddb96151cd82aa6084b7afbcf1a84a9843ef
Author: Alim Akhtar <alim.akhtar@samsung.com>
pinctrl: samsung: Add Exynos8855 pinctrl configuration
Add pinctrl configuration for Exynos8855. The bank type
macros are reused from Exynos850 SoC.
> diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> index fe9f92cb037ea..db120ae4d847a 100644
> --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
[ ... ]
> +/* pin banks of exynos8855 pin-controller 0 (ALIVE) */
> +static const struct samsung_pin_bank_data exynos8855_pin_banks0[] __initconst = {
> + /* Must start with EINTG banks, ordered by EINT group number. */
> + EXYNOS850_PIN_BANK_EINTW(8, 0x000, "gpa0", 0x00),
[ ... ]
> + EXYNOS850_PIN_BANK_EINTW(1, 0x260, "gpj0", 0x4c),
> + EXYNOS850_PIN_BANK_EINTW(1, 0x280, "gpj1", 0x50),
> + EXYNOS850_PIN_BANK_EINTW(1, 0x2a0, "gpj2", 0x54),
[Severity: High]
This isn't a bug introduced by this patch, but the new Exynos8855 pin
definitions expose it. The new pin layout introduces extremely sparse
eint_offset values up to 0x54 (like gpj2 here).
In exynos_wkup_irq_set_wake(), the wake mask bit is calculated as:
unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
...
eint_wake_mask_values[0] |= bit;
When computing the shift for an offset of 0x54 (84), the expression evaluates
to 1UL << 168. Since 1UL is 64 bits wide on ARM64, this left shift invokes
C undefined behavior.
Even ignoring the undefined behavior, the result is implicitly cast to u32
when OR'd into eint_wake_mask_values[0], effectively truncating it to 0.
Does this completely break PMU wakeup configuration for all pins with an
eint_offset >= 0x10?
> +};
[ ... ]
> +static const struct samsung_pin_ctrl exynos8855_pin_ctrl[] __initconst = {
> + {
> + /* pin-controller instance 0 ALIVE data */
> + .pin_banks = exynos8855_pin_banks0,
> + .nr_banks = ARRAY_SIZE(exynos8855_pin_banks0),
> + .eint_wkup_init = exynos_eint_wkup_init,
> + .eint_gpio_init = exynos_eint_gpio_init,
> + }, {
[Severity: Low]
Does the ALIVE controller need to configure eint_gpio_init?
Neither the ALIVE nor the CMGP instances contain any EINT_TYPE_GPIO banks
(they only contain EINT_TYPE_WKUP and EINT_TYPE_NONE). Because wake-up only
controllers typically do not have a generic hardware IRQ mapped for standard
GPIOs in the device tree, exynos_eint_gpio_init unconditionally attempts to
retrieve it, prints a spurious error, and returns -EINVAL:
dev_err(dev, "irq number not available\n");
Could this cause unnecessary boot log pollution and attempts to initialize
GPIO IRQ domains for zero eligible banks?
> + /* pin-controller instance 1 CMGP data */
> + .pin_banks = exynos8855_pin_banks1,
> + .nr_banks = ARRAY_SIZE(exynos8855_pin_banks1),
> + .eint_gpio_init = exynos_eint_gpio_init,
> + }, {
[Severity: High]
Is the .eint_wkup_init callback missing here for the CMGP pin controller?
The CMGP pin controller banks (exynos8855_pin_banks1) are exclusively defined
using the EXYNOS850_PIN_BANK_EINTW macro, which sets .eint_type to
EINT_TYPE_WKUP. However, this instance only configures .eint_gpio_init and
omits .eint_wkup_init.
During initialization, exynos_eint_gpio_init() skips any banks that are not
EINT_TYPE_GPIO. Because .eint_wkup_init is missing, it looks like the wakeup
interrupts for gpm0 through gpm21 will never be registered, leaving them
without functional external wakeup interrupts.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615085252.1964423-1-alim.akhtar@samsung.com?part=3
^ permalink raw reply
* Re: [PATCH v5 1/9] block: partitions: of: Skip child nodes without reg property
From: Bartosz Golaszewski @ 2026-06-15 8:47 UTC (permalink / raw)
To: Loic Poulain
Cc: linux-mmc, devicetree, linux-kernel, linux-arm-msm, linux-block,
linux-wireless, ath10k, linux-bluetooth, netdev, daniel,
Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Bjorn Andersson, Konrad Dybcio, Jens Axboe, Johannes Berg,
Jeff Johnson, Bartosz Golaszewski, Marcel Holtmann,
Luiz Augusto von Dentz, Balakrishna Godavarthi, Rocky Liao,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Srinivas Kandagatla, Andrew Lunn, Heiner Kallweit,
Russell King, Saravana Kannan
In-Reply-To: <20260612-block-as-nvmem-v5-1-95e0b30fff90@oss.qualcomm.com>
On Fri, 12 Jun 2026 15:20:53 +0200, Loic Poulain
<loic.poulain@oss.qualcomm.com> said:
> Child nodes of a fixed-partitions node are not necessarily partition
> entries, for example an nvmem-layout node has no reg property. The
> current code passes a NULL reg pointer and uninitialized len to the
> length check, which can result in a kernel panic or silent failure to
> register any partitions.
>
> Fix validate_of_partition() to return a skip indicator when no reg
> property is present. Guard add_of_partition() with a reg property
> check for the same reason.
>
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
I think this warrants a Cc: stable and backporting as well as a Fixes tag.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v3 3/3] regulator: qcom-refgen: add support for the IPQ9650 SoC
From: sashiko-bot @ 2026-06-15 8:46 UTC (permalink / raw)
To: Kathiravan Thirumoorthy; +Cc: conor+dt, robh, devicetree
In-Reply-To: <20260615-ipq9650_refgen-v3-3-5f611623629c@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The `.is_enabled` callback maps to `regulator_is_enabled_regmap` without enabling clocks, causing a synchronous bus hang on IPQ9650 during probe.
--
commit 57e8a1a06a52f828e01d53b16f6c708e7f6df23e
Author: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
regulator: qcom-refgen: add support for the IPQ9650 SoC
This commit adds support for the IPQ9650 SoC to the qcom-refgen regulator
driver. It introduces explicit clock management for the REFGEN blocks, as
they are not enabled on power up for this specific SoC.
> diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c
> index 6a3795469927e..4b8aa40d7efe0 100644
> --- a/drivers/regulator/qcom-refgen-regulator.c
> +++ b/drivers/regulator/qcom-refgen-regulator.c
[ ... ]
> +static const struct regulator_desc ipq9650_refgen_desc = {
> + .enable_reg = REFGEN_REG_REFGEN_STATUS,
> + .enable_mask = REFGEN_STATUS_OUT_MASK,
> + .enable_val = REFGEN_STATUS_OUT_ENABLE,
> + .enable_time = 5,
> + .name = "refgen",
> + .owner = THIS_MODULE,
> + .type = REGULATOR_CURRENT,
> + .ops = &(const struct regulator_ops) {
> + .enable = qcom_ipq9650_refgen_enable,
> + .disable = qcom_ipq9650_refgen_disable,
> + .is_enabled = regulator_is_enabled_regmap,
[Severity: High]
Does this result in an unclocked MMIO read?
During device probe, the regulator core calls the is_enabled callback via
devm_regulator_register() to determine the initial state:
qcom_refgen_probe()
devm_regulator_register()
regulator_is_enabled_regmap()
Since the IPQ9650 clocks are disabled on power up and only enabled later in
qcom_ipq9650_refgen_enable(), regulator_is_enabled_regmap() will perform an
MMIO read on the REFGEN_REG_REFGEN_STATUS register without the required
clocks enabled.
Could this cause a synchronous external abort and a kernel panic during
boot?
> + },
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615-ipq9650_refgen-v3-0-5f611623629c@oss.qualcomm.com?part=3
^ permalink raw reply
* Re: [PATCH v5 5/9] block: implement NVMEM provider
From: Loic Poulain @ 2026-06-15 8:45 UTC (permalink / raw)
To: sashiko-reviews; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260613132137.D65B51F000E9@smtp.kernel.org>
On Sat, Jun 13, 2026 at 3:21 PM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
> - [High] NVMEM provider opens the block device with exclusive write restriction, causing conflicts on mounted systems.
> - [High] Hardcoded 4GB size limit incorrectly rejects modern eMMC devices.
> - [High] Integer overflow in size assignment exposes massive out-of-bounds size.
> - [High] Stale `dev_t` reference can cause data leaks across block device hotplugs (ABA problem).
> - [High] Using `__free(fput)` defers block device claim release, creating race conditions.
> --
>
> commit 459b659c960efdc8a9e2177c5bc4f832e7ee5730
> Author: Daniel Golle <daniel@makrotopia.org>
>
> block: implement NVMEM provider
>
> On embedded devices using an eMMC it is common that one or more partitions
> on the eMMC are used to store MAC addresses and Wi-Fi calibration EEPROM
> data. Allow referencing the partition in device tree for the kernel and
> Wi-Fi drivers accessing it via the NVMEM layer.
>
> > diff --git a/block/blk-nvmem.c b/block/blk-nvmem.c
> > new file mode 100644
> > index 0000000000000..c005f059d9fe5
> > --- /dev/null
> > +++ b/block/blk-nvmem.c
> > @@ -0,0 +1,109 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> [ ... ]
> > +static int blk_nvmem_reg_read(void *priv, unsigned int from, void *val, size_t bytes)
> > +{
> > + blk_mode_t mode = BLK_OPEN_READ | BLK_OPEN_RESTRICT_WRITES;
>
> [Severity: High]
> Since the NVMEM provider claims the whole disk (disk->part0), will opening it
> with BLK_OPEN_RESTRICT_WRITES and an exclusive holder (priv) return -EBUSY if
> any partition on the disk is already mounted or opened for writing?
It only blocks writes on part0, not on its logical partition block
devices. That said, I don’t see a strong reason to use
BLK_OPEN_RESTRICT_WRITES here.
>
> > + dev_t devt = (dev_t)(uintptr_t)priv;
> > + size_t bytes_left = bytes;
> > + loff_t pos = from;
> > + int ret = 0;
> > +
> > + struct file *bdev_file __free(fput) = bdev_file_open_by_dev(devt, mode, priv, NULL);
>
> [Severity: High]
> Does using __free(fput) defer the release of the block device claim? Because
> fput() schedules the file release asynchronously, could another subsystem
> trying to mount or claim the device immediately after an NVMEM read
> sporadically fail with -EBUSY?
>
> Should this use bdev_fput() instead to synchronously yield the claim before
> the rest of the file release?
Here, we're ok with the deferred file release.
>
> > + if (IS_ERR(bdev_file))
> > + return PTR_ERR(bdev_file);
> [ ... ]
> > +void blk_nvmem_add(struct block_device *bdev)
> > +{
> [ ... ]
> > + /*
> > + * skip block device too large to be represented as NVMEM devices,
> > + * the NVMEM reg_read callback uses an unsigned int offset
> > + */
> > + if (bdev_nr_bytes(bdev) > UINT_MAX) {
>
> [Severity: High]
> Since the NVMEM provider is registered against the whole disk rather than the
> individual NVMEM partition, does this 4GB limit incorrectly reject most modern
> eMMC devices?
No, most of them have hardware partitions such as boot partition or
custom raw-user partitions separated from the main 'large' user area.
>
> > + dev_warn(dev, "block device too large to be an NVMEM provider\n");
> > + return;
> > + }
> > +
> > + config.id = NVMEM_DEVID_NONE;
> > + config.dev = dev;
> > + config.name = dev_name(dev);
> > + config.owner = THIS_MODULE;
> > + config.priv = (void *)(uintptr_t)dev->devt;
>
> [Severity: High]
> Can storing the ephemeral dev_t identifier without holding a pinned block
> device reference cause an ABA problem?
>
> If the block device is removed, blk_nvmem_del() calls nvmem_unregister()
> which drops a reference but does not synchronously wait for consumers to
> close. If a new device is plugged in and reuses the same dev_t, could a
> consumer reading from the still-alive NVMEM device inadvertently access the
> unrelated new block device?
Not, It's fixed in another Bartosz series.
>
> > + config.reg_read = blk_nvmem_reg_read;
> > + config.size = bdev_nr_bytes(bdev);
>
> [Severity: High]
> Can this assignment cause an integer overflow?
>
> The config.size field in struct nvmem_config is a signed 32-bit int, so disk
> sizes between 2GB and 4GB will overflow to a negative value. When
> nvmem_register() sign-extends this into its 64-bit size_t field, won't it
> result in a massive out-of-bounds size being exposed via sysfs?
Yes we need to change the above guard to INT_MAX.
>
> > + config.word_size = 1;
> > + config.stride = 1;
> > + config.read_only = true;
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260612-block-as-nvmem-v5-0-95e0b30fff90@oss.qualcomm.com?part=5
^ permalink raw reply
* Re: [PATCH v4 3/7] clk: qcom: tcsrcc-glymur: Migrate tcsr_pcie_N_clkref_en to clk_ref common helper
From: Qiang Yu @ 2026-06-15 8:46 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Taniya Das,
Konrad Dybcio, linux-arm-msm, linux-clk, devicetree, linux-kernel,
krishna.chundru
In-Reply-To: <747f0319-68e1-4cd7-9dd1-4a675d882f99@oss.qualcomm.com>
On Tue, Jun 09, 2026 at 03:02:27PM +0200, Konrad Dybcio wrote:
> On 5/28/26 4:29 AM, Qiang Yu wrote:
> > Replace local clk_branch-based clkref definitions with descriptor-based
> > registration via qcom_clk_ref_probe().
> >
> > This keeps the glymur driver focused on clock metadata and reuses common
> > runtime logic for regulator handling, enable/disable sequencing, and OF
> > provider wiring.
> >
> > Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> > ---
>
> You can remove the of.h include. Apart from that:
>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>
> Also, attaching a diff to complete the regulator map. I'm fairly sure
> these are correct, but it never hurts to triple-check.
>
> You can add:
>
> Co-developed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
>
> if you squash them together. FYI e.g. the tertiary USB QMPPHY would
> only start every 20 boots or so without this, running on pure luck..
>
Okay, will sqash them and add above tags in next version.
- Qiang Yu
> Konrad
>
> diff --git a/drivers/clk/qcom/tcsrcc-glymur.c b/drivers/clk/qcom/tcsrcc-glymur.c
> index e317003398d1..eb4ee8ec9ad7 100644
> --- a/drivers/clk/qcom/tcsrcc-glymur.c
> +++ b/drivers/clk/qcom/tcsrcc-glymur.c
> @@ -21,6 +21,14 @@ static const char * const glymur_tcsr_tx0_rx5_regulators[] = {
> "vdda-qreftx0-1p2",
> };
>
> +static const char * const glymur_tcsr_tx1_rpt0_rx0_regulators[] = {
> + "vdda-refgen4-0p9",
> + "vdda-refgen4-1p2",
> + "vdda-qreftx1-0p9",
> + "vdda-qrefrpt0-0p9",
> + "vdda-qrefrx0-0p9",
> +};
> +
> static const char * const glymur_tcsr_tx1_rpt01_rx1_regulators[] = {
> "vdda-refgen4-0p9",
> "vdda-refgen4-1p2",
> @@ -40,6 +48,15 @@ static const char * const glymur_tcsr_tx1_rpt012_rx2_regulators[] = {
> "vdda-qrefrx2-0p9",
> };
>
> +static const char * const glymur_tcsr_tx1_rpt34_rx4_regulators[] = {
> + "vdda-refgen2-0p9",
> + "vdda-refgen2-1p2",
> + "vdda-qreftx1-0p9",
> + "vdda-qrefrpt3-0p9",
> + "vdda-qrefrpt4-0p9",
> + "vdda-qrefrx4-0p9",
> +};
> +
> static const struct regmap_config tcsr_cc_glymur_regmap_config = {
> .reg_bits = 32,
> .reg_stride = 4,
> @@ -52,6 +69,8 @@ static const struct qcom_clk_ref_desc tcsr_cc_glymur_clk_descs[] = {
> [TCSR_EDP_CLKREF_EN] = {
> .name = "tcsr_edp_clkref_en",
> .offset = 0x60,
> + .regulator_names = glymur_tcsr_tx1_rpt0_rx0_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt0_rx0_regulators),
> },
> [TCSR_PCIE_1_CLKREF_EN] = {
> .name = "tcsr_pcie_1_clkref_en",
> @@ -80,34 +99,50 @@ static const struct qcom_clk_ref_desc tcsr_cc_glymur_clk_descs[] = {
> [TCSR_USB2_1_CLKREF_EN] = {
> .name = "tcsr_usb2_1_clkref_en",
> .offset = 0x6c,
> + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators),
> },
> [TCSR_USB2_2_CLKREF_EN] = {
> .name = "tcsr_usb2_2_clkref_en",
> .offset = 0x70,
> + .regulator_names = glymur_tcsr_tx1_rpt01_rx1_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt01_rx1_regulators),
> },
> [TCSR_USB2_3_CLKREF_EN] = {
> .name = "tcsr_usb2_3_clkref_en",
> .offset = 0x74,
> + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators),
> },
> [TCSR_USB2_4_CLKREF_EN] = {
> .name = "tcsr_usb2_4_clkref_en",
> .offset = 0x88,
> + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators),
> },
> [TCSR_USB3_0_CLKREF_EN] = {
> .name = "tcsr_usb3_0_clkref_en",
> .offset = 0x64,
> + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators),
> },
> [TCSR_USB3_1_CLKREF_EN] = {
> .name = "tcsr_usb3_1_clkref_en",
> .offset = 0x68,
> + .regulator_names = glymur_tcsr_tx1_rpt34_rx4_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt34_rx4_regulators),
> },
> [TCSR_USB4_1_CLKREF_EN] = {
> .name = "tcsr_usb4_1_clkref_en",
> .offset = 0x44,
> + .regulator_names = glymur_tcsr_tx0_rx5_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx0_rx5_regulators),
> },
> [TCSR_USB4_2_CLKREF_EN] = {
> .name = "tcsr_usb4_2_clkref_en",
> .offset = 0x5c,
> + .regulator_names = glymur_tcsr_tx1_rpt01_rx1_regulators,
> + .num_regulators = ARRAY_SIZE(glymur_tcsr_tx1_rpt01_rx1_regulators),
> },
> };
>
^ permalink raw reply
* Re: [PATCH v2 4/5] arm64: dts: exynos: add initial support for Samsung Exynos8855 smdk
From: sashiko-bot @ 2026-06-15 8:46 UTC (permalink / raw)
To: Alim Akhtar; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260615085252.1964423-5-alim.akhtar@samsung.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Missing `interrupts` property for multiplexed pinctrl blocks breaks GPIO interrupts.
- [Low] The timer node incorrectly uses the legacy GIC_CPU_MASK_SIMPLE macro for its GICv3 PPI interrupts.
- [Low] Usage of magic numbers instead of standard macros for pinctrl configurations.
- [Low] Board device tree header comment references the wrong SoC and hardware.
--
commit 8b3b2980b627113d8b255b5b20a2fd0b03fe40a0
Author: Alim Akhtar <alim.akhtar@samsung.com>
arm64: dts: exynos: add initial support for Samsung Exynos8855 smdk
Add initial devicetree support for Samsung smdk board using
Exynos8855 SoC.
> diff --git a/arch/arm64/boot/dts/exynos/exynos8855-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos8855-pinctrl.dtsi
> new file mode 100644
> index 0000000000000..df69b2b3e96ad
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos8855-pinctrl.dtsi
[ ... ]
> + uart0_pins: uart0-pins {
> + samsung,pins = "gpq0-0", "gpq0-1";
> + samsung,pin-function = <2>;
> + samsung,pin-pud = <3>;
[Severity: Low]
This isn't a bug, but could we use standard device tree binding macros like
EXYNOS_PIN_FUNC_2 and EXYNOS_PIN_PULL_UP from <dt-bindings/pinctrl/samsung.h>
here instead of magic numbers?
> + };
> +
> +};
[ ... ]
> diff --git a/arch/arm64/boot/dts/exynos/exynos8855-smdk.dts b/arch/arm64/boot/dts/exynos/exynos8855-smdk.dts
> new file mode 100644
> index 0000000000000..f5132bcaa47c8
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos8855-smdk.dts
> @@ -0,0 +1,32 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Samsung Exynos8855 SMDK board device tree source
> + *
> + * Copyright (C) 2026 Samsung Electronics Co., Ltd.
> + *
> + * Device tree source file for WinLink's E850-96 board which is based on
> + * Samsung Exynos8855 SoC.
[Severity: Low]
This isn't a bug, but does this comment refer to the wrong board? The text
mentions the WinLink E850-96 board instead of the Exynos 8855 SMDK board.
> + */
> +
> +/dts-v1/;
[ ... ]
> diff --git a/arch/arm64/boot/dts/exynos/exynos8855.dtsi b/arch/arm64/boot/dts/exynos/exynos8855.dtsi
> new file mode 100644
> index 0000000000000..d403f41bbecb5
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos8855.dtsi
[ ... ]
> + pinctrl_peric: pinctrl@15440000 {
> + compatible = "samsung,exynos8855-pinctrl";
> + reg = <0x15440000 0x1000>;
> + };
[Severity: High]
Is an interrupts property missing for this node and the other non-alive
pinctrl nodes (like pinctrl_usi, pinctrl_pericmmc, and pinctrl_hsi_ufs)?
These blocks contain child GPIO banks that are marked as interrupt
controllers, but the exynos pinctrl driver relies on the parent's interrupts
property to initialize the IRQ domain.
Without it, exynos_eint_gpio_init() will return -EINVAL, breaking GPIO
interrupt functionality for these pins.
> +
> + pinctrl_pericmmc: pinctrl@154f0000 {
> + compatible = "samsung,exynos8855-pinctrl";
> + reg = <0x154f0000 0x1000>;
> + };
> +
> + pinctrl_hsi_ufs: pinctrl@17040000 {
> + compatible = "samsung,exynos8855-pinctrl";
> + reg = <0x17040000 0x1000>;
> + };
> + };
> +
> + timer {
> + compatible = "arm,armv8-timer";
> + /* Hypervisor Virtual Timer interrupt is not wired to GIC */
> + interrupts =
> + <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
[Severity: Low]
Is it correct to use the GIC_CPU_MASK_SIMPLE macro here?
The interrupt controller is arm,gic-v3. GIC_CPU_MASK_SIMPLE sets bits [15:8],
which violates the GICv3 DT binding that strictly expects trigger type and
level flags in bits [3:0] for the third cell.
While the upper bits are masked during parsing, this will trigger dtbs_check
validation errors.
> + };
> +};
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615085252.1964423-1-alim.akhtar@samsung.com?part=4
^ permalink raw reply
* Re: [PATCH v2 2/5] dt-binding: pinctrl: samsung: Add exynos8855-pinctrl compatible
From: sashiko-bot @ 2026-06-15 8:44 UTC (permalink / raw)
To: Alim Akhtar; +Cc: robh, devicetree, conor+dt
In-Reply-To: <20260615085252.1964423-3-alim.akhtar@samsung.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The commit adds `samsung,exynos8855-pinctrl` to the main pin controller binding, but fails to add the corresponding wake-up interrupt controller compatible (e.g., `samsung,exynos8855-wakeup-eint`) to the related `samsung,pinctrl-wakeup-interrupt.yaml` schema.
--
commit 899082861559d7c752e009f7ed23cca09b5d64d4
Author: Alim Akhtar <alim.akhtar@samsung.com>
dt-binding: pinctrl: samsung: Add exynos8855-pinctrl compatible
Document pin controller support on Exynos8855 SoC.
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
> index 7b006009ca0e7..c4773701c92e3 100644
> --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
> @@ -53,6 +53,7 @@ properties:
> - samsung,exynos7870-pinctrl
> - samsung,exynos7885-pinctrl
> - samsung,exynos850-pinctrl
> + - samsung,exynos8855-pinctrl
[Severity: Medium]
When adding support for a new Exynos pin controller, should the corresponding
wake-up interrupt controller compatible (like samsung,exynos8855-wakeup-eint)
also be added to the compatible enum in the related file:
Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml?
When related binding files in the same family don't receive matching updates,
it can prevent complete device tree schema validation for the new hardware.
If omitted, device tree files might be forced to define the node using older
generic compatibles without an SoC-specific compatible string just to pass
dt_binding_check.
> - samsung,exynos8890-pinctrl
> - samsung,exynos8895-pinctrl
> - samsung,exynos9610-pinctrl
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260615085252.1964423-1-alim.akhtar@samsung.com?part=2
^ permalink raw reply
* Re: [PATCH 2/4] ASoC: qcom: sc8280xp: add Ayaneo Pocket S2 card with special WSA channel mapping
From: Srinivas Kandagatla @ 2026-06-15 8:42 UTC (permalink / raw)
To: Neil Armstrong, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: kancy2333, linux-sound, linux-arm-msm, linux-kernel, devicetree
In-Reply-To: <20260610-topic-sm8650-ayaneo-pocket-s2-wsa2-fix-v1-2-18bb19c5ca22@linaro.org>
Thanks Neil for the patch.
On 6/10/26 8:41 AM, Neil Armstrong wrote:
> The WSA Speakers are connected on the WSA2 interface, but the
> WSA and WSA2 links are handled as a single dai and DSP interface, so
> we need to specify the channel mapping of the Ayaneo Pocket S2 for the
> WSA dai in order to have functional playback and avoid DSP errors.
>
> Let's add a special entry for the Ayaneo Pocket S2 adding a prepare
> callback in order to set the proper channel mapping.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> sound/soc/qcom/sc8280xp.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 56 insertions(+)
>
> diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c
> index 1f3afc6d015c..2f1688c9f317 100644
> --- a/sound/soc/qcom/sc8280xp.c
> +++ b/sound/soc/qcom/sc8280xp.c
> @@ -14,6 +14,7 @@
> #include "qdsp6/q6afe.h"
> #include "qdsp6/q6apm.h"
> #include "qdsp6/q6prm.h"
> +#include "qdsp6/q6dsp-common.h"
> #include "common.h"
> #include "sdw.h"
>
> @@ -49,6 +50,7 @@ struct snd_soc_common {
> bool codec_sysclk_set;
> bool mi2s_mclk_enable;
> bool mi2s_bclk_enable;
> + int (*snd_prepare)(struct snd_pcm_substream *substream);
> };
>
> struct sc8280xp_snd_data {
> @@ -193,12 +195,58 @@ static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream,
> return 0;
> }
>
> +/*
> + * WSA and WSA2 are handled as a single interface with the
> + * following channels mask:
It should not be handled as single interface in this case, you could use
WSA2 as it is.
> + * __________________________________________________
> + * | Bits | 3 | 2 | 1 | 0 |
> + * ---------------------------------------------------
> + * | Line | WSA2 Ch2 | WSA2 Ch1 | WSA Ch2 | WSA Ch1 |
> + * ---------------------------------------------------
> + *
> + * The Ayaneo Pocket S2 speakers are connected only to
> + * the WSA2 interface and the WSA interface is not enabled.
> + *
> + * Set the channel mapping on the WSA2 channels only.
> + */
> +static const unsigned int ayaneo_ps2_channels_mapping[] = {
> + 0, /* WSA Ch1 */
> + 0, /* WSA Ch2 */
> + PCM_CHANNEL_FL, /* WSA2 Ch1 */
> + PCM_CHANNEL_FR /* WSA2 Ch2 */
> +};
So we are are playing 4 channels on a 2 channel speakers?
There is also a patch by Abel, on allowing userspace/ucm to set the
channel map for WSA at https://lkml.org/lkml/2026/6/10/1002
Its worth having a look.
--srini
> +
> +static int ayaneo_ps2_snd_prepare(struct snd_pcm_substream *substream)
> +{
> + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
> + unsigned int channels = substream->runtime->channels;
> +
> + if (cpu_dai->id != WSA_CODEC_DMA_RX_0)
> + return 0;
> +
> + if (channels != 2)
> + return -EINVAL;
> +
> + return snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
> + ARRAY_SIZE(ayaneo_ps2_channels_mapping),
> + ayaneo_ps2_channels_mapping);
> +}
> +
> static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream)
> {
> struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
> struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card);
>
> + if (data->snd_soc_common_priv->snd_prepare) {
> + int ret;
> +
> + ret = data->snd_soc_common_priv->snd_prepare(substream);
> + if (ret)
> + return ret;
> + }
> +
> return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]);
> }
>
> @@ -273,6 +321,13 @@ static int sc8280xp_platform_probe(struct platform_device *pdev)
> return devm_snd_soc_register_card(dev, card);
> }
>
> +static struct snd_soc_common ayaneo_ps2_priv_data = {
> + .driver_name = "ayaneo-ps2",
> + .dapm_widgets = sc8280xp_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(sc8280xp_dapm_widgets),
> + .snd_prepare = ayaneo_ps2_snd_prepare,
> +};
> +
> static struct snd_soc_common kaanapali_priv_data = {
> .driver_name = "kaanapali",
> .dapm_widgets = sc8280xp_dapm_widgets,
> @@ -341,6 +396,7 @@ static struct snd_soc_common sm8750_priv_data = {
> };
>
> static const struct of_device_id snd_sc8280xp_dt_match[] = {
> + {.compatible = "ayaneo,pocket-s2-sndcard", .data = &ayaneo_ps2_priv_data},
> {.compatible = "qcom,kaanapali-sndcard", .data = &kaanapali_priv_data},
> {.compatible = "qcom,qcm6490-idp-sndcard", .data = &qcm6490_priv_data},
> {.compatible = "qcom,qcs615-sndcard", .data = &qcs615_priv_data},
>
^ permalink raw reply
* Re: [PATCH v4 2/7] clk: qcom: Add generic clkref_en support
From: Qiang Yu @ 2026-06-15 8:40 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Taniya Das,
Konrad Dybcio, linux-arm-msm, linux-clk, devicetree, linux-kernel,
krishna.chundru
In-Reply-To: <b0479824-0c6d-498d-bdc8-63f678a6f2ee@oss.qualcomm.com>
On Tue, Jun 09, 2026 at 02:57:52PM +0200, Konrad Dybcio wrote:
> On 5/28/26 4:29 AM, Qiang Yu wrote:
> > Before XO refclk is distributed to PCIe/USB/eDP PHYs, it passes through
> > a QREF block. QREF is powered by dedicated LDO rails, and the clkref_en
> > register controls whether refclk is gated through to the PHY side.
> >
> > These clkref controls are different from typical GCC branch clocks:
> > - only a single enable bit is present, without branch-style config bits
> > - regulators must be voted before enable and unvoted after disable
> >
> > Model this as a dedicated clk_ref clock type with custom clk_ops instead
> > of reusing struct clk_branch semantics.
> >
> > Also provide a common registration/probe API so the same clkref model
> > can be reused regardless of where clkref_en registers are placed, e.g.
> > TCSR on glymur and TLMM on SM8750.
> >
> > Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> > ---
>
> [...]
>
> > +static int qcom_clk_ref_enable(struct clk_hw *hw)
> > +{
> > + struct qcom_clk_ref *rclk = to_qcom_clk_ref(hw);
> > + int ret;
> > +
> > + ret = regmap_update_bits(rclk->regmap, rclk->desc.offset, QCOM_CLK_REF_EN_MASK,
> > + QCOM_CLK_REF_EN_MASK);
>
> regmap_set_bits()
>
> > + if (ret)
> > + return ret;
> > +
> > + udelay(10);
> > +
> > + return 0;
> > +}
> > +
> > +static void qcom_clk_ref_disable(struct clk_hw *hw)
> > +{
> > + struct qcom_clk_ref *rclk = to_qcom_clk_ref(hw);
> > +
> > + regmap_update_bits(rclk->regmap, rclk->desc.offset, QCOM_CLK_REF_EN_MASK, 0);
>
> regmap_clear_bits()
>
> [...]
>
Will use regmap_clear_bits in next version.
> > +static int qcom_clk_ref_register(struct device *dev, struct regmap *regmap,
> > + struct qcom_clk_ref *clk_refs,
> > + const struct qcom_clk_ref_desc *descs,
> > + size_t num_clk_refs)
> > +{
> > + const struct qcom_clk_ref_desc *desc;
> > + struct qcom_clk_ref *clk_ref;
> > + size_t clk_idx;
> > + unsigned int i;
> > + int ret;
> > +
> > + for (clk_idx = 0; clk_idx < num_clk_refs; clk_idx++) {
> > + clk_ref = &clk_refs[clk_idx];
> > + desc = &descs[clk_idx];
> > +
> > + if (!desc->name)
> > + continue;
>
> // this allows "holes" in dt-bindings for $reasons
> if (!desc)
> continue;
>
> // this makes sure the programmer did not omit something important
> // while not taking the entire system down
> if (WARN_ON(!desc->name)
> continue;
>
The NULL name check is intentional - the descriptor array is indexed by
clock ID, and mahua has fewer clocks than glymur, leaving holes at
certain indices. So this is expected at runtime. WARN_ON would be noise
log here.
- Qiang Yu
>
> Konrad
^ permalink raw reply
* Re: [PATCH 1/4] ASoC: qcom: audioreach: compute active channel maps from channel_map
From: Srinivas Kandagatla @ 2026-06-15 8:38 UTC (permalink / raw)
To: Neil Armstrong, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai, Bjorn Andersson, Konrad Dybcio,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: kancy2333, linux-sound, linux-arm-msm, linux-kernel, devicetree,
Srinivas Kandagatla
In-Reply-To: <20260610-topic-sm8650-ayaneo-pocket-s2-wsa2-fix-v1-1-18bb19c5ca22@linaro.org>
On 6/10/26 8:41 AM, Neil Armstrong wrote:
> The Qualcom SM8650 based Ayaneo Pocket S2 gaming device has a set
> of 2 WSA speakers connected on the WSA2 lines.
>
> But the Audioreach DSP only handles WSA2 in pair with the WSA
> interface by using the upper bits of the active_channels_mask
> for WSA2 and the lower bits for WSA:
>
> /-------------------------------------------------\
> | Bits | 3 | 2 | 1 | 0 |
> |-------------------------------------------------|
> | Line | WSA2 Ch2 | WSA2 Ch1 | WSA Ch2 | WSA Ch1 |
> \-------------------------------------------------/
>
No, this is not totally correct, if the setup only has WSA2, then
channel 0 and 1 should be WSA2 channels.
What is the backend dai id that is in DT, it should be
sound-dai = <&q6apmbedai WSA2_CODEC_DMA_RX_0>;
I also noticed that you are using
https://github.com/linux-msm/audioreach-topology/blob/main/SM8550-HDK.m4
which has WSA as backend dai, that is not correct, you should have WSA2.
> Setting only the WSA2 upper bits is perfectly valid and
> functional but the current Audioreach code builds the bitmask
> from the channels count with:
> active_channels_mask = (1 << num_channels) - 1;
>
> In order to enable the WSA2 bits the channel count should be 4,
> but the lower WSA bits are then also enabled and the DSP errors
> out when trying to play on the disabled WSA interface.
>
> A solution would've been to add a fake WSA2 topology element which
> would be translated into the top bits only, but it's not clean and
> add some special exceptions in the generic Audioreach code.
>
> The solution suggested by Srinivas is to use the channel mapping to
> set this bitmask.
>
> This works but makes all the other calls using the channel mapping fail
> because the DSP requires the channel_mapping table to start from index 0
> and using num_channel length in order to apply the mapping on the
> active_channels_mask bits in order.
>
> So we need to skip the empty channel mapping entries in all other
> users of the channel_map to build valid channel_mapping tables.
>
> This should not break any other usecases since the default channel
> mapping always start from index 0, and will add flexibilty to allow
> some special non linear mapping for other interfaces as well.
>
> Suggested-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> sound/soc/qcom/qdsp6/audioreach.c | 47 ++++++++++++++++++++++++++++++---------
> 1 file changed, 37 insertions(+), 10 deletions(-)
>
> diff --git a/sound/soc/qcom/qdsp6/audioreach.c b/sound/soc/qcom/qdsp6/audioreach.c
> index a13f753eff98..9b80cfa56e8a 100644
> --- a/sound/soc/qcom/qdsp6/audioreach.c
> +++ b/sound/soc/qcom/qdsp6/audioreach.c
> @@ -703,6 +703,7 @@ static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
> int pm_sz = APM_HW_EP_PMODE_CFG_PSIZE;
> int size = ic_sz + ep_sz + fs_sz + pm_sz;
> void *p;
> + int i;
>
> struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(size, APM_CMD_SET_CFG, 0);
> if (IS_ERR(pkt))
> @@ -741,7 +742,12 @@ static int audioreach_codec_dma_set_media_format(struct q6apm_graph *graph,
>
> intf_cfg->cfg.lpaif_type = module->hw_interface_type;
> intf_cfg->cfg.intf_index = module->hw_interface_idx;
> - intf_cfg->cfg.active_channels_mask = (1 << cfg->num_channels) - 1;
> + intf_cfg->cfg.active_channels_mask = 0;
> + /* Convert the physical channel mapping into a bit field */
> + for (i = 0; i < AR_PCM_MAX_NUM_CHANNEL; i++)
> + if (cfg->channel_map[i])
> + intf_cfg->cfg.active_channels_mask |= BIT(i);
> +
This one looks good, this should be a bug fix patch.
> p += ic_sz;
>
> pm_cfg = p;
> @@ -840,7 +846,7 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
> uint32_t num_channels = cfg->num_channels;
> int payload_size = APM_MFC_CFG_PSIZE(media_format, num_channels) +
> APM_MODULE_PARAM_DATA_SIZE;
> - int i;
> + int i, j;
> void *p;
>
> struct gpr_pkt *pkt __free(kfree) = audioreach_alloc_apm_cmd_pkt(payload_size, APM_CMD_SET_CFG, 0);
> @@ -860,8 +866,12 @@ static int audioreach_mfc_set_media_format(struct q6apm_graph *graph,
> media_format->sample_rate = cfg->sample_rate;
> media_format->bit_width = cfg->bit_width;
> media_format->num_channels = cfg->num_channels;
> - for (i = 0; i < num_channels; i++)
> - media_format->channel_mapping[i] = cfg->channel_map[i];
> + /* Convert the physical mapping to a logical mapping of the channels */
> + for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
> + if (!cfg->channel_map[i])
> + continue;
> + media_format->channel_mapping[j++] = cfg->channel_map[i];
Each element i of the channel_mapping[i] array, describes the channel i
inside the buffer where i is less than num_channels. An unused channel
is set to 0.
For some reason I get impression that user is trying to set a 4 channels
instead of 2 channel.
Can you fix the backend-dai id and play it directly on WSA2 instead of WSA.
Or was there a reason for not doing it otherwise?
--srini
> + }
>
> return q6apm_send_cmd_sync(graph->apm, pkt, 0);
> }
> @@ -1080,6 +1090,7 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
> struct apm_pcm_module_media_fmt_cmd *cfg;
> struct apm_module_param_data *param_data;
> int payload_size;
> + int i, j;
>
> if (num_channels > 4) {
> dev_err(graph->dev, "Error: Invalid channels (%d)!\n", num_channels);
> @@ -1113,7 +1124,12 @@ static int audioreach_pcm_set_media_format(struct q6apm_graph *graph,
> media_cfg->num_channels = mcfg->num_channels;
> media_cfg->q_factor = mcfg->bit_width - 1;
> media_cfg->bits_per_sample = mcfg->bit_width;
> - memcpy(media_cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);
> + /* Convert the physical mapping to a logical mapping of the channels */
> + for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < mcfg->num_channels; i++) {
> + if (!mcfg->channel_map[i])
> + continue;
> + media_cfg->channel_mapping[j++] = mcfg->channel_map[i];
> + }
>
> return q6apm_send_cmd_sync(graph->apm, pkt, 0);
> }
> @@ -1127,6 +1143,7 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
> struct payload_media_fmt_pcm *cfg;
> struct media_format *header;
> int rc, payload_size;
> + int i, j;
> void *p;
>
> if (num_channels > 4) {
> @@ -1166,7 +1183,12 @@ static int audioreach_shmem_set_media_format(struct q6apm_graph *graph,
> cfg->q_factor = mcfg->bit_width - 1;
> cfg->endianness = PCM_LITTLE_ENDIAN;
> cfg->num_channels = mcfg->num_channels;
> - memcpy(cfg->channel_mapping, mcfg->channel_map, mcfg->num_channels);
> + /* Convert the physical mapping to a logical mapping of the channels */
> + for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < cfg->num_channels; i++) {
> + if (!mcfg->channel_map[i])
> + continue;
> + cfg->channel_mapping[j++] = mcfg->channel_map[i];
> + }
> } else {
> rc = audioreach_set_compr_media_format(header, p, mcfg);
> if (rc)
> @@ -1243,7 +1265,7 @@ static int audioreach_speaker_protection_vi(struct q6apm_graph *graph,
> struct apm_module_sp_vi_ex_mode_cfg *ex_cfg;
> int op_sz, cm_sz, ex_sz;
> struct apm_module_param_data *param_data;
> - int rc, i, payload_size;
> + int rc, i, payload_size, j;
> struct gpr_pkt *pkt;
> void *p;
>
> @@ -1284,14 +1306,19 @@ static int audioreach_speaker_protection_vi(struct q6apm_graph *graph,
> param_data->param_size = cm_sz - APM_MODULE_PARAM_DATA_SIZE;
>
> cm_cfg->cfg.num_channels = num_channels * 2;
> - for (i = 0; i < num_channels; i++) {
> + /* Convert the physical mapping to a logical mapping of the channels */
> + for (i = 0, j = 0; i < AR_PCM_MAX_NUM_CHANNEL && j < num_channels; i++) {
> + if (!mcfg->channel_map[i])
> + continue;
> /*
> * Map speakers into Vsense and then Isense of each channel.
> * E.g. for PCM_CHANNEL_FL and PCM_CHANNEL_FR to:
> * [1, 2, 3, 4]
> */
> - cm_cfg->cfg.channel_mapping[2 * i] = (mcfg->channel_map[i] - 1) * 2 + 1;
> - cm_cfg->cfg.channel_mapping[2 * i + 1] = (mcfg->channel_map[i] - 1) * 2 + 2;
> + cm_cfg->cfg.channel_mapping[2 * j] = (mcfg->channel_map[i] - 1) * 2 + 1;
> + cm_cfg->cfg.channel_mapping[2 * j + 1] = (mcfg->channel_map[i] - 1) * 2 + 2;
> +
> + ++j;
> }
>
> p += cm_sz;
>
^ permalink raw reply
* Re: [PATCH v4 3/6] drm/verisilicon: introduce per-variant hardware ops table
From: Icenowy Zheng @ 2026-06-15 8:37 UTC (permalink / raw)
To: Joey Lu, maarten.lankhorst, mripard, tzimmermann, airlied, simona,
robh, krzk+dt, conor+dt
Cc: ychuang3, schung, yclu4, dri-devel, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260615065003.76661-4-a0987203069@gmail.com>
在 2026-06-15一的 14:50 +0800,Joey Lu写道:
> The DC8200 and DCUltraLite share a broadly similar register layout
> but
> differ in how the bridge, CRTC, primary plane and IRQ paths are
> driven.
> Introduce a vs_dc_funcs vtable so each variant can supply its own
> implementation without scattering conditionals across multiple files.
>
> Add enum vs_dc_generation (VSDC_GEN_DC8000 / VSDC_GEN_DC8200) to
> vs_hwdb.h and a generation field to struct vs_chip_identity.
> Annotate
> all four existing DC8200 HWDB entries with VSDC_GEN_DC8200.
>
> Extract the DC8200-specific hardware ops into a new vs_dc8200.c:
> panel_enable_ex / panel_disable_ex - PANEL_CONFIG/START + CONFIG_EX
> commit
> enable_vblank / disable_vblank - TOP_IRQ_EN VSYNC bit
> primary_plane_enable_ex / disable_ex / update_ex - FB_CONFIG_EX
> path
> irq_ack - reads TOP_IRQ_ACK
>
> Update vs_bridge.c, vs_crtc.c, vs_primary_plane.c and vs_dc.c to
> dispatch through dc->funcs instead of directly touching registers.
> vs_crtc.c gains atomic_begin and atomic_flush hooks to allow variants
> to gate per-frame commit cycles.
>
> No behaviour change for existing DC8200 platforms.
>
> Signed-off-by: Joey Lu <a0987203069@gmail.com>
> ---
> drivers/gpu/drm/verisilicon/Makefile | 2 +-
> drivers/gpu/drm/verisilicon/vs_bridge.c | 20 +---
> drivers/gpu/drm/verisilicon/vs_crtc.c | 38 ++++++-
> drivers/gpu/drm/verisilicon/vs_dc.c | 6 +-
> drivers/gpu/drm/verisilicon/vs_dc.h | 32 ++++++
> drivers/gpu/drm/verisilicon/vs_dc8200.c | 107
> ++++++++++++++++++
> drivers/gpu/drm/verisilicon/vs_hwdb.c | 4 +
> drivers/gpu/drm/verisilicon/vs_hwdb.h | 6 +
> .../gpu/drm/verisilicon/vs_primary_plane.c | 32 +-----
> 9 files changed, 196 insertions(+), 51 deletions(-)
> create mode 100644 drivers/gpu/drm/verisilicon/vs_dc8200.c
>
> diff --git a/drivers/gpu/drm/verisilicon/Makefile
> b/drivers/gpu/drm/verisilicon/Makefile
> index 426f4bcaa834..9d4cd16452fa 100644
> --- a/drivers/gpu/drm/verisilicon/Makefile
> +++ b/drivers/gpu/drm/verisilicon/Makefile
> @@ -1,6 +1,6 @@
> # SPDX-License-Identifier: GPL-2.0-only
>
> -verisilicon-dc-objs := vs_bridge.o vs_crtc.o vs_dc.o vs_drm.o
> vs_hwdb.o \
> +verisilicon-dc-objs := vs_bridge.o vs_crtc.o vs_dc.o vs_dc8200.o
> vs_drm.o vs_hwdb.o \
> vs_plane.o vs_primary_plane.o vs_cursor_plane.o
>
> obj-$(CONFIG_DRM_VERISILICON_DC) += verisilicon-dc.o
> diff --git a/drivers/gpu/drm/verisilicon/vs_bridge.c
> b/drivers/gpu/drm/verisilicon/vs_bridge.c
> index 7a93049368db..6ff2ac745b15 100644
> --- a/drivers/gpu/drm/verisilicon/vs_bridge.c
> +++ b/drivers/gpu/drm/verisilicon/vs_bridge.c
> @@ -162,15 +162,8 @@ static void vs_bridge_enable_common(struct
> vs_crtc *crtc,
> VSDC_DISP_PANEL_CONFIG_DE_EN |
> VSDC_DISP_PANEL_CONFIG_DAT_EN |
> VSDC_DISP_PANEL_CONFIG_CLK_EN);
> - regmap_set_bits(dc->regs, VSDC_DISP_PANEL_CONFIG(output),
> - VSDC_DISP_PANEL_CONFIG_RUNNING);
> - regmap_clear_bits(dc->regs, VSDC_DISP_PANEL_START,
> - VSDC_DISP_PANEL_START_MULTI_DISP_SYNC);
> - regmap_set_bits(dc->regs, VSDC_DISP_PANEL_START,
> - VSDC_DISP_PANEL_START_RUNNING(output));
> -
> - regmap_set_bits(dc->regs, VSDC_DISP_PANEL_CONFIG_EX(crtc-
> >id),
> - VSDC_DISP_PANEL_CONFIG_EX_COMMIT);
> +
> + dc->funcs->panel_enable_ex(dc, output);
> }
>
> static void vs_bridge_atomic_enable_dpi(struct drm_bridge *bridge,
> @@ -228,14 +221,7 @@ static void vs_bridge_atomic_disable(struct
> drm_bridge *bridge,
> struct vs_dc *dc = crtc->dc;
> unsigned int output = crtc->id;
>
> - regmap_clear_bits(dc->regs, VSDC_DISP_PANEL_START,
> - VSDC_DISP_PANEL_START_MULTI_DISP_SYNC |
> - VSDC_DISP_PANEL_START_RUNNING(output));
> - regmap_clear_bits(dc->regs, VSDC_DISP_PANEL_CONFIG(output),
> - VSDC_DISP_PANEL_CONFIG_RUNNING);
> -
> - regmap_set_bits(dc->regs, VSDC_DISP_PANEL_CONFIG_EX(crtc-
> >id),
> - VSDC_DISP_PANEL_CONFIG_EX_COMMIT);
> + dc->funcs->panel_disable_ex(dc, output);
> }
>
> static const struct drm_bridge_funcs vs_dpi_bridge_funcs = {
> diff --git a/drivers/gpu/drm/verisilicon/vs_crtc.c
> b/drivers/gpu/drm/verisilicon/vs_crtc.c
> index 0b8a35d09cd2..679d6541ba1b 100644
> --- a/drivers/gpu/drm/verisilicon/vs_crtc.c
> +++ b/drivers/gpu/drm/verisilicon/vs_crtc.c
> @@ -16,10 +16,33 @@
> #include "vs_crtc_regs.h"
> #include "vs_crtc.h"
> #include "vs_dc.h"
> -#include "vs_dc_top_regs.h"
> #include "vs_drm.h"
> #include "vs_plane.h"
>
> +static void vs_crtc_atomic_begin(struct drm_crtc *crtc,
> + struct drm_atomic_commit *state)
> +{
> + struct vs_crtc *vcrtc = drm_crtc_to_vs_crtc(crtc);
> + struct vs_dc *dc = vcrtc->dc;
> + unsigned int output = vcrtc->id;
> +
> + if (dc->funcs->crtc_begin)
> + dc->funcs->crtc_begin(dc, output);
> +}
> +
> +static void vs_crtc_atomic_flush(struct drm_crtc *crtc,
> + struct drm_atomic_commit *state)
> +{
> + struct vs_crtc *vcrtc = drm_crtc_to_vs_crtc(crtc);
> + struct vs_dc *dc = vcrtc->dc;
> + unsigned int output = vcrtc->id;
> +
> + if (dc->funcs->crtc_flush)
> + dc->funcs->crtc_flush(dc, output);
> +
> + drm_crtc_vblank_atomic_flush(crtc, state);
> +}
> +
> static void vs_crtc_atomic_disable(struct drm_crtc *crtc,
> struct drm_atomic_commit *state)
> {
> @@ -30,6 +53,9 @@ static void vs_crtc_atomic_disable(struct drm_crtc
> *crtc,
> drm_crtc_vblank_off(crtc);
>
> clk_disable_unprepare(dc->pix_clk[output]);
> +
> + if (dc->funcs->crtc_disable)
> + dc->funcs->crtc_disable(dc, output);
Should this be `crtc_disable_ex` ? Because the clock-related operation
is shared.
> }
>
> static void vs_crtc_atomic_enable(struct drm_crtc *crtc,
> @@ -42,6 +68,9 @@ static void vs_crtc_atomic_enable(struct drm_crtc
> *crtc,
> drm_WARN_ON(&dc->drm_dev->base,
> clk_prepare_enable(dc->pix_clk[output]));
>
> + if (dc->funcs->crtc_enable)
> + dc->funcs->crtc_enable(dc, output);
Ditto for appending `_ex` .
> +
> drm_crtc_vblank_on(crtc);
> }
>
> @@ -119,7 +148,8 @@ static bool vs_crtc_mode_fixup(struct drm_crtc
> *crtc,
> }
>
> static const struct drm_crtc_helper_funcs vs_crtc_helper_funcs = {
> - .atomic_flush = drm_crtc_vblank_atomic_flush,
> + .atomic_begin = vs_crtc_atomic_begin,
> + .atomic_flush = vs_crtc_atomic_flush,
> .atomic_enable = vs_crtc_atomic_enable,
> .atomic_disable = vs_crtc_atomic_disable,
> .mode_set_nofb = vs_crtc_mode_set_nofb,
> @@ -132,7 +162,7 @@ static int vs_crtc_enable_vblank(struct drm_crtc
> *crtc)
> struct vs_crtc *vcrtc = drm_crtc_to_vs_crtc(crtc);
> struct vs_dc *dc = vcrtc->dc;
>
> - regmap_set_bits(dc->regs, VSDC_TOP_IRQ_EN,
> VSDC_TOP_IRQ_VSYNC(vcrtc->id));
> + dc->funcs->enable_vblank(dc, vcrtc->id);
>
> return 0;
> }
> @@ -142,7 +172,7 @@ static void vs_crtc_disable_vblank(struct
> drm_crtc *crtc)
> struct vs_crtc *vcrtc = drm_crtc_to_vs_crtc(crtc);
> struct vs_dc *dc = vcrtc->dc;
>
> - regmap_clear_bits(dc->regs, VSDC_TOP_IRQ_EN,
> VSDC_TOP_IRQ_VSYNC(vcrtc->id));
> + dc->funcs->disable_vblank(dc, vcrtc->id);
> }
>
> static const struct drm_crtc_funcs vs_crtc_funcs = {
> diff --git a/drivers/gpu/drm/verisilicon/vs_dc.c
> b/drivers/gpu/drm/verisilicon/vs_dc.c
> index dad9967bc10b..9729b693d360 100644
> --- a/drivers/gpu/drm/verisilicon/vs_dc.c
> +++ b/drivers/gpu/drm/verisilicon/vs_dc.c
> @@ -8,9 +8,7 @@
> #include <linux/of.h>
> #include <linux/of_graph.h>
>
> -#include "vs_crtc.h"
> #include "vs_dc.h"
> -#include "vs_dc_top_regs.h"
> #include "vs_drm.h"
> #include "vs_hwdb.h"
>
> @@ -33,7 +31,7 @@ static irqreturn_t vs_dc_irq_handler(int irq, void
> *private)
> struct vs_dc *dc = private;
> u32 irqs;
>
> - regmap_read(dc->regs, VSDC_TOP_IRQ_ACK, &irqs);
> + irqs = dc->funcs->irq_ack(dc);
The definition of bits in 0x0010 seems to be different to ones in
0x147C, although the first 2 bits are the same. (e.g. `BIT(2)` is
"cursor interrupt" in DC8000 0x147C but "secure reset done" in DC8200
0x0010).
Should some kind of translation be done in `irq_ack` ? (and add a
unified interrupt definition that aims to be the translation target).
Thanks,
Icenowy
>
> vs_drm_handle_irq(dc, irqs);
>
> @@ -136,6 +134,8 @@ static int vs_dc_probe(struct platform_device
> *pdev)
> dev_info(dev, "Found DC%x rev %x customer %x\n", dc-
> >identity.model,
> dc->identity.revision, dc->identity.customer_id);
>
> + dc->funcs = &vs_dc8200_funcs;
> +
> if (port_count > dc->identity.display_count) {
> dev_err(dev, "too many downstream ports than HW
> capability\n");
> ret = -EINVAL;
> diff --git a/drivers/gpu/drm/verisilicon/vs_dc.h
> b/drivers/gpu/drm/verisilicon/vs_dc.h
> index ed1016f18758..544e1a37065b 100644
> --- a/drivers/gpu/drm/verisilicon/vs_dc.h
> +++ b/drivers/gpu/drm/verisilicon/vs_dc.h
> @@ -14,6 +14,7 @@
> #include <linux/reset.h>
>
> #include <drm/drm_device.h>
> +#include <drm/drm_plane.h>
>
> #include "vs_hwdb.h"
>
> @@ -22,6 +23,34 @@
>
> struct vs_drm_dev;
> struct vs_crtc;
> +struct vs_dc;
> +
> +struct vs_dc_funcs {
> + /* Bridge: atomic_enable, atomic_disable */
> + void (*panel_enable_ex)(struct vs_dc *dc, unsigned int
> output);
> + void (*panel_disable_ex)(struct vs_dc *dc, unsigned int
> output);
> +
> + /* CRTC: atomic_begin, atomic_flush */
> + void (*crtc_begin)(struct vs_dc *dc, unsigned int output);
> + void (*crtc_flush)(struct vs_dc *dc, unsigned int output);
> +
> + /* CRTC: atomic_enable, atomic_disable */
> + void (*crtc_enable)(struct vs_dc *dc, unsigned int output);
> + void (*crtc_disable)(struct vs_dc *dc, unsigned int output);
> +
> + /* CRTC: enable_vblank, disable_vblank */
> + void (*enable_vblank)(struct vs_dc *dc, unsigned int
> output);
> + void (*disable_vblank)(struct vs_dc *dc, unsigned int
> output);
> +
> + /* Primary plane: atomic_enable, atomic_disable,
> atomic_update */
> + void (*primary_plane_enable_ex)(struct vs_dc *dc, unsigned
> int output);
> + void (*primary_plane_disable_ex)(struct vs_dc *dc, unsigned
> int output);
> + void (*primary_plane_update_ex)(struct vs_dc *dc, unsigned
> int output,
> + struct drm_plane_state
> *state);
> +
> + /* IRQ acknowledge */
> + u32 (*irq_ack)(struct vs_dc *dc);
> +};
>
> struct vs_dc {
> struct regmap *regs;
> @@ -33,6 +62,9 @@ struct vs_dc {
>
> struct vs_drm_dev *drm_dev;
> struct vs_chip_identity identity;
> + const struct vs_dc_funcs *funcs;
> };
>
> +extern const struct vs_dc_funcs vs_dc8200_funcs;
> +
> #endif /* _VS_DC_H_ */
> diff --git a/drivers/gpu/drm/verisilicon/vs_dc8200.c
> b/drivers/gpu/drm/verisilicon/vs_dc8200.c
> new file mode 100644
> index 000000000000..800df9279e9b
> --- /dev/null
> +++ b/drivers/gpu/drm/verisilicon/vs_dc8200.c
> @@ -0,0 +1,107 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2025 Icenowy Zheng <uwu@icenowy.me>
> + */
> +
> +#include <linux/regmap.h>
> +
> +#include "vs_bridge_regs.h"
> +#include "vs_dc.h"
> +#include "vs_dc_top_regs.h"
> +#include "vs_plane.h"
> +#include "vs_primary_plane_regs.h"
> +
> +static void vs_dc8200_panel_enable_ex(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_set_bits(dc->regs, VSDC_DISP_PANEL_CONFIG(output),
> + VSDC_DISP_PANEL_CONFIG_RUNNING);
> + regmap_clear_bits(dc->regs, VSDC_DISP_PANEL_START,
> + VSDC_DISP_PANEL_START_MULTI_DISP_SYNC);
> + regmap_set_bits(dc->regs, VSDC_DISP_PANEL_START,
> + VSDC_DISP_PANEL_START_RUNNING(output));
> +
> + regmap_set_bits(dc->regs, VSDC_DISP_PANEL_CONFIG_EX(output),
> + VSDC_DISP_PANEL_CONFIG_EX_COMMIT);
> +}
> +
> +static void vs_dc8200_panel_disable_ex(struct vs_dc *dc, unsigned
> int output)
> +{
> + regmap_clear_bits(dc->regs, VSDC_DISP_PANEL_CONFIG(output),
> + VSDC_DISP_PANEL_CONFIG_RUNNING);
> + regmap_clear_bits(dc->regs, VSDC_DISP_PANEL_START,
> + VSDC_DISP_PANEL_START_MULTI_DISP_SYNC |
> + VSDC_DISP_PANEL_START_RUNNING(output));
> +
> + regmap_set_bits(dc->regs, VSDC_DISP_PANEL_CONFIG_EX(output),
> + VSDC_DISP_PANEL_CONFIG_EX_COMMIT);
> +}
> +
> +static void vs_dc8200_enable_vblank(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_set_bits(dc->regs, VSDC_TOP_IRQ_EN,
> + VSDC_TOP_IRQ_VSYNC(output));
> +}
> +
> +static void vs_dc8200_disable_vblank(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_clear_bits(dc->regs, VSDC_TOP_IRQ_EN,
> + VSDC_TOP_IRQ_VSYNC(output));
> +}
> +
> +static void vs_dc8200_plane_commit(struct vs_dc *dc, unsigned int
> output)
> +{
> + regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> + VSDC_FB_CONFIG_EX_COMMIT);
> +}
> +
> +static void vs_dc8200_primary_plane_enable_ex(struct vs_dc *dc,
> unsigned int output)
> +{
> + regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> + VSDC_FB_CONFIG_EX_FB_EN);
> + regmap_update_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> + VSDC_FB_CONFIG_EX_DISPLAY_ID_MASK,
> + VSDC_FB_CONFIG_EX_DISPLAY_ID(output));
> +
> + vs_dc8200_plane_commit(dc, output);
> +}
> +
> +static void vs_dc8200_primary_plane_disable_ex(struct vs_dc *dc,
> unsigned int output)
> +{
> + regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> + VSDC_FB_CONFIG_EX_FB_EN);
> +
> + vs_dc8200_plane_commit(dc, output);
> +}
> +
> +static void vs_dc8200_primary_plane_update_ex(struct vs_dc *dc,
> unsigned int output,
> + struct drm_plane_state
> *state)
> +{
> + regmap_write(dc->regs, VSDC_FB_TOP_LEFT(output),
> + VSDC_MAKE_PLANE_POS(state->crtc_x, state-
> >crtc_y));
> + regmap_write(dc->regs, VSDC_FB_BOTTOM_RIGHT(output),
> + VSDC_MAKE_PLANE_POS(state->crtc_x + state-
> >crtc_w,
> + state->crtc_y + state-
> >crtc_h));
> + regmap_write(dc->regs, VSDC_FB_BLEND_CONFIG(output),
> + VSDC_FB_BLEND_CONFIG_BLEND_DISABLE);
> +
> + vs_dc8200_plane_commit(dc, output);
> +}
> +
> +static u32 vs_dc8200_irq_ack(struct vs_dc *dc)
> +{
> + u32 irqs;
> +
> + regmap_read(dc->regs, VSDC_TOP_IRQ_ACK, &irqs);
> + return irqs;
> +}
> +
> +const struct vs_dc_funcs vs_dc8200_funcs = {
> + .panel_enable_ex = vs_dc8200_panel_enable_ex,
> + .panel_disable_ex =
> vs_dc8200_panel_disable_ex,
> + .enable_vblank = vs_dc8200_enable_vblank,
> + .disable_vblank =
> vs_dc8200_disable_vblank,
> + .primary_plane_enable_ex =
> vs_dc8200_primary_plane_enable_ex,
> + .primary_plane_disable_ex =
> vs_dc8200_primary_plane_disable_ex,
> + .primary_plane_update_ex =
> vs_dc8200_primary_plane_update_ex,
> + .irq_ack = vs_dc8200_irq_ack,
> +};
> diff --git a/drivers/gpu/drm/verisilicon/vs_hwdb.c
> b/drivers/gpu/drm/verisilicon/vs_hwdb.c
> index 2a0f7c59afa3..91524d16f778 100644
> --- a/drivers/gpu/drm/verisilicon/vs_hwdb.c
> +++ b/drivers/gpu/drm/verisilicon/vs_hwdb.c
> @@ -94,6 +94,7 @@ static struct vs_chip_identity vs_chip_identities[]
> = {
> .revision = 0x5720,
> .customer_id = ~0U,
>
> + .generation = VSDC_GEN_DC8200,
> .display_count = 2,
> .max_cursor_size = 64,
> .formats = &vs_formats_no_yuv444,
> @@ -103,6 +104,7 @@ static struct vs_chip_identity
> vs_chip_identities[] = {
> .revision = 0x5721,
> .customer_id = 0x30B,
>
> + .generation = VSDC_GEN_DC8200,
> .display_count = 2,
> .max_cursor_size = 64,
> .formats = &vs_formats_no_yuv444,
> @@ -112,6 +114,7 @@ static struct vs_chip_identity
> vs_chip_identities[] = {
> .revision = 0x5720,
> .customer_id = 0x310,
>
> + .generation = VSDC_GEN_DC8200,
> .display_count = 2,
> .max_cursor_size = 64,
> .formats = &vs_formats_with_yuv444,
> @@ -121,6 +124,7 @@ static struct vs_chip_identity
> vs_chip_identities[] = {
> .revision = 0x5720,
> .customer_id = 0x311,
>
> + .generation = VSDC_GEN_DC8200,
> .display_count = 2,
> .max_cursor_size = 64,
> .formats = &vs_formats_no_yuv444,
> diff --git a/drivers/gpu/drm/verisilicon/vs_hwdb.h
> b/drivers/gpu/drm/verisilicon/vs_hwdb.h
> index 2065ecb73043..a15c8b565604 100644
> --- a/drivers/gpu/drm/verisilicon/vs_hwdb.h
> +++ b/drivers/gpu/drm/verisilicon/vs_hwdb.h
> @@ -9,6 +9,11 @@
> #include <linux/regmap.h>
> #include <linux/types.h>
>
> +enum vs_dc_generation {
> + VSDC_GEN_DC8000,
> + VSDC_GEN_DC8200,
> +};
> +
> struct vs_formats {
> const u32 *array;
> unsigned int num;
> @@ -19,6 +24,7 @@ struct vs_chip_identity {
> u32 revision;
> u32 customer_id;
>
> + enum vs_dc_generation generation;
> u32 display_count;
> /*
> * The hardware only supports square cursor planes, so this
> field
> diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> index 1f2be41ae496..f992cb277f61 100644
> --- a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> +++ b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
> @@ -53,12 +53,6 @@ static int vs_primary_plane_atomic_check(struct
> drm_plane *plane,
> return 0;
> }
>
> -static void vs_primary_plane_commit(struct vs_dc *dc, unsigned int
> output)
> -{
> - regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> - VSDC_FB_CONFIG_EX_COMMIT);
> -}
> -
> static void vs_primary_plane_atomic_enable(struct drm_plane *plane,
> struct drm_atomic_commit
> *atomic_state)
> {
> @@ -69,13 +63,8 @@ static void vs_primary_plane_atomic_enable(struct
> drm_plane *plane,
> unsigned int output = vcrtc->id;
> struct vs_dc *dc = vcrtc->dc;
>
> - regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> - VSDC_FB_CONFIG_EX_FB_EN);
> - regmap_update_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> - VSDC_FB_CONFIG_EX_DISPLAY_ID_MASK,
> - VSDC_FB_CONFIG_EX_DISPLAY_ID(output));
> -
> - vs_primary_plane_commit(dc, output);
> + if (dc->funcs->primary_plane_enable_ex)
> + dc->funcs->primary_plane_enable_ex(dc, output);
> }
>
> static void vs_primary_plane_atomic_disable(struct drm_plane *plane,
> @@ -88,10 +77,8 @@ static void vs_primary_plane_atomic_disable(struct
> drm_plane *plane,
> unsigned int output = vcrtc->id;
> struct vs_dc *dc = vcrtc->dc;
>
> - regmap_set_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
> - VSDC_FB_CONFIG_EX_FB_EN);
> -
> - vs_primary_plane_commit(dc, output);
> + if (dc->funcs->primary_plane_disable_ex)
> + dc->funcs->primary_plane_disable_ex(dc, output);
> }
>
> static void vs_primary_plane_atomic_update(struct drm_plane *plane,
> @@ -133,18 +120,11 @@ static void
> vs_primary_plane_atomic_update(struct drm_plane *plane,
> regmap_write(dc->regs, VSDC_FB_STRIDE(output),
> fb->pitches[0]);
>
> - regmap_write(dc->regs, VSDC_FB_TOP_LEFT(output),
> - VSDC_MAKE_PLANE_POS(state->crtc_x, state-
> >crtc_y));
> - regmap_write(dc->regs, VSDC_FB_BOTTOM_RIGHT(output),
> - VSDC_MAKE_PLANE_POS(state->crtc_x + state-
> >crtc_w,
> - state->crtc_y + state-
> >crtc_h));
> regmap_write(dc->regs, VSDC_FB_SIZE(output),
> VSDC_MAKE_PLANE_SIZE(state->crtc_w, state-
> >crtc_h));
>
> - regmap_write(dc->regs, VSDC_FB_BLEND_CONFIG(output),
> - VSDC_FB_BLEND_CONFIG_BLEND_DISABLE);
> -
> - vs_primary_plane_commit(dc, output);
> + if (dc->funcs->primary_plane_update_ex)
> + dc->funcs->primary_plane_update_ex(dc, output,
> state);
> }
>
> static const struct drm_plane_helper_funcs
> vs_primary_plane_helper_funcs = {
^ permalink raw reply
* RE: [PATCH 5/5] MAINTAINERS: Add entry for Samsung Exynos8855 SoC
From: Alim Akhtar @ 2026-06-15 8:37 UTC (permalink / raw)
To: 'Krzysztof Kozlowski', 'Linus Walleij'
Cc: peter.griffin, robh, conor+dt, linux-samsung-soc, linux-kernel,
devicetree, linux-gpio, hajun.sung
In-Reply-To: <419fe57b-fed0-411d-8bd6-eb452e767784@kernel.org>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Monday, June 15, 2026 1:47 PM
> To: Alim Akhtar <alim.akhtar@samsung.com>; 'Linus Walleij'
> <linusw@kernel.org>
> Cc: peter.griffin@linaro.org; robh@kernel.org; conor+dt@kernel.org; linux-
> samsung-soc@vger.kernel.org; linux-kernel@vger.kernel.org;
> devicetree@vger.kernel.org; linux-gpio@vger.kernel.org;
> hajun.sung@samsung.com
> Subject: Re: [PATCH 5/5] MAINTAINERS: Add entry for Samsung Exynos8855
> SoC
>
> On 15/06/2026 10:12, Krzysztof Kozlowski wrote:
> > On 15/06/2026 10:04, Alim Akhtar wrote:
> >> Thanks Linus for your review
> >>
> >>> -----Original Message-----
> >>> From: Linus Walleij <linusw@kernel.org>
> >>> Sent: Monday, June 15, 2026 12:51 PM
> >>> To: Alim Akhtar <alim.akhtar@samsung.com>
> >>> Cc: krzk@kernel.org; peter.griffin@linaro.org; robh@kernel.org;
> >>> conor+dt@kernel.org; linux-samsung-soc@vger.kernel.org; linux-
> >>> kernel@vger.kernel.org; devicetree@vger.kernel.org; linux-
> >>> gpio@vger.kernel.org; hajun.sung@samsung.com
> >>> Subject: Re: [PATCH 5/5] MAINTAINERS: Add entry for Samsung
> >>> Exynos8855 SoC
> >>>
> >>> Hi Alim,
> >>>
> >>> On Fri, Jun 12, 2026 at 6:11 PM Alim Akhtar
> >>> <alim.akhtar@samsung.com>
> >>> wrote:
> >>>
> >>>> Add maintainers entry for the Samsung Exynos8855 SoC based
> >>>> platforms
> >>>>
> >>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> >>> (...)
> >>>> +SAMSUNG EXYNOS8855 SoC SUPPORT
> >>>> +M: Alim Akhtar <alim.akhtar@samsung.com>
> >>>> +L: linux-arm-kernel@lists.infradead.org (moderated for non-
> >>> subscribers)
> >>>> +L: linux-samsung-soc@vger.kernel.org
> >>>> +S: Maintained
> >>>> +F: arch/arm64/boot/dts/exynos/exynos8855*
> >>>
> >>> If you really want to single out a single platform like this (and I
> >>> don't even know if that is a good idea... how do you keep the big
> >>> picture in mind?) you should probably want to also add a wildcard
> >>> for all the
> >>> 8855 device tree files.
> >>>
> >> I am also not sure, just followed what was done historically, other
> >> Exynos8855 file will get added once they are posted for review, e.g. clock
> driver.
> >> Let me discuss with Krzk during OSS (Mumbai) and see how do we handle
> this or any other better ways.
> >>
> >
> > You are Alim already reviewer for entire Samsung, so not sure if this
> > is beneficial but I also do not mind.
> >
> > For Exynos850 and Google GS101, these were added because folks wanted
> > to be involved in these specific bits. In the past I was voting for
> > per-DTS file maintainer entry and rejecting per-board maintainer
> > entries. There
>
> Lemme clarify: "voting for in-DTS file maintainer entry", so like we have for
> DT bindings, which lists maintainers.
>
Sounds interesting to me, lets see what community thinks about this.
^ permalink raw reply
* [PATCH v3 3/3] regulator: qcom-refgen: add support for the IPQ9650 SoC
From: Kathiravan Thirumoorthy @ 2026-06-15 8:35 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, devicetree, Kathiravan Thirumoorthy,
Dmitry Baryshkov
In-Reply-To: <20260615-ipq9650_refgen-v3-0-5f611623629c@oss.qualcomm.com>
IPQ9650 SoC has 2 REFGEN blocks providing the reference current to the
PCIe and USB, UNIPHY PHYs. For the other SoCs, clock for this block is
enabled on power up but that's not the case for IPQ9650 and we have to
enable those clocks explicitly to bring up the PHYs properly.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
---
drivers/regulator/qcom-refgen-regulator.c | 89 +++++++++++++++++++++++++++++--
1 file changed, 85 insertions(+), 4 deletions(-)
diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c
index 6a3795469927..4b8aa40d7efe 100644
--- a/drivers/regulator/qcom-refgen-regulator.c
+++ b/drivers/regulator/qcom-refgen-regulator.c
@@ -3,6 +3,7 @@
// Copyright (c) 2023, Linaro Limited
#include <linux/bitfield.h>
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -16,6 +17,10 @@
#define REFGEN_BIAS_EN_ENABLE 0x7
#define REFGEN_BIAS_EN_DISABLE 0x6
+#define REFGEN_REG_REFGEN_STATUS 0xc
+#define REFGEN_STATUS_OUT_MASK BIT(3)
+ #define REFGEN_STATUS_OUT_ENABLE 0x8
+
#define REFGEN_REG_BG_CTRL 0x14
#define REFGEN_BG_CTRL_MASK GENMASK(2, 1)
#define REFGEN_BG_CTRL_ENABLE 0x3
@@ -25,6 +30,16 @@
#define REFGEN_PWRDWN_CTRL5_MASK BIT(0)
#define REFGEN_PWRDWN_CTRL5_ENABLE 0x1
+struct qcom_refgen_regulator_data {
+ const struct regulator_desc *rdesc;
+ bool has_clocks;
+};
+
+struct qcom_refgen_drvdata {
+ struct clk_bulk_data *clks;
+ int num_clks;
+};
+
static int qcom_sdm845_refgen_enable(struct regulator_dev *rdev)
{
regmap_update_bits(rdev->regmap, REFGEN_REG_BG_CTRL, REFGEN_BG_CTRL_MASK,
@@ -62,6 +77,42 @@ static int qcom_sdm845_refgen_is_enabled(struct regulator_dev *rdev)
return 1;
}
+static int qcom_ipq9650_refgen_enable(struct regulator_dev *rdev)
+{
+ struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
+ int ret;
+
+ ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int qcom_ipq9650_refgen_disable(struct regulator_dev *rdev)
+{
+ struct qcom_refgen_drvdata *drvdata = rdev_get_drvdata(rdev);
+
+ clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
+
+ return 0;
+}
+
+static const struct regulator_desc ipq9650_refgen_desc = {
+ .enable_reg = REFGEN_REG_REFGEN_STATUS,
+ .enable_mask = REFGEN_STATUS_OUT_MASK,
+ .enable_val = REFGEN_STATUS_OUT_ENABLE,
+ .enable_time = 5,
+ .name = "refgen",
+ .owner = THIS_MODULE,
+ .type = REGULATOR_CURRENT,
+ .ops = &(const struct regulator_ops) {
+ .enable = qcom_ipq9650_refgen_enable,
+ .disable = qcom_ipq9650_refgen_disable,
+ .is_enabled = regulator_is_enabled_regmap,
+ },
+};
+
static const struct regulator_desc sdm845_refgen_desc = {
.enable_time = 5,
.name = "refgen",
@@ -90,6 +141,19 @@ static const struct regulator_desc sm8250_refgen_desc = {
},
};
+static const struct qcom_refgen_regulator_data ipq9650_data = {
+ .rdesc = &ipq9650_refgen_desc,
+ .has_clocks = true,
+};
+
+static const struct qcom_refgen_regulator_data sdm845_data = {
+ .rdesc = &sdm845_refgen_desc,
+};
+
+static const struct qcom_refgen_regulator_data sm8250_data = {
+ .rdesc = &sm8250_refgen_desc,
+};
+
static const struct regmap_config qcom_refgen_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
@@ -98,6 +162,8 @@ static const struct regmap_config qcom_refgen_regmap_config = {
static int qcom_refgen_probe(struct platform_device *pdev)
{
+ const struct qcom_refgen_regulator_data *data;
+ struct qcom_refgen_drvdata *drvdata = NULL;
struct regulator_init_data *init_data;
struct regulator_config config = {};
const struct regulator_desc *rdesc;
@@ -106,10 +172,23 @@ static int qcom_refgen_probe(struct platform_device *pdev)
struct regmap *regmap;
void __iomem *base;
- rdesc = of_device_get_match_data(dev);
- if (!rdesc)
+ data = of_device_get_match_data(dev);
+ if (!data)
return -ENODATA;
+ if (data->has_clocks) {
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ drvdata->num_clks = devm_clk_bulk_get_all(dev, &drvdata->clks);
+ if (drvdata->num_clks < 0)
+ return dev_err_probe(dev, drvdata->num_clks,
+ "failed to get clocks\n");
+ }
+
+ rdesc = data->rdesc;
+
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -126,6 +205,7 @@ static int qcom_refgen_probe(struct platform_device *pdev)
config.init_data = init_data;
config.of_node = dev->of_node;
config.regmap = regmap;
+ config.driver_data = drvdata;
rdev = devm_regulator_register(dev, rdesc, &config);
if (IS_ERR(rdev))
@@ -135,8 +215,9 @@ static int qcom_refgen_probe(struct platform_device *pdev)
}
static const struct of_device_id qcom_refgen_match_table[] = {
- { .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_refgen_desc },
- { .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_refgen_desc },
+ { .compatible = "qcom,ipq9650-refgen-regulator", .data = &ipq9650_data },
+ { .compatible = "qcom,sdm845-refgen-regulator", .data = &sdm845_data },
+ { .compatible = "qcom,sm8250-refgen-regulator", .data = &sm8250_data },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_refgen_match_table);
--
2.34.1
^ permalink raw reply related
* [PATCH v3 2/3] regulator: dt-bindings: qcom,sdm845-refgen-regulator: Document IPQ9650
From: Kathiravan Thirumoorthy @ 2026-06-15 8:35 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, devicetree, Kathiravan Thirumoorthy
In-Reply-To: <20260615-ipq9650_refgen-v3-0-5f611623629c@oss.qualcomm.com>
IPQ9650 has two REFGEN blocks which provide reference current to the PCIe,
USB and UNIPHY PHYs. Unlike other supported platforms, IPQ9650 requires the
REFGEN clocks to be enabled explicitly.
Document the IPQ9650 compatible and the required clocks for it.
While at it, move the allOf block after the 'required' property section.
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
---
.../regulator/qcom,sdm845-refgen-regulator.yaml | 31 +++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml
index 40f9223d4c27..0bbf7c806fbc 100644
--- a/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/qcom,sdm845-refgen-regulator.yaml
@@ -13,9 +13,6 @@ description:
The REFGEN (reference voltage generator) regulator provides reference
voltage for on-chip IPs (like PHYs) on some Qualcomm SoCs.
-allOf:
- - $ref: regulator.yaml#
-
properties:
compatible:
oneOf:
@@ -39,16 +36,44 @@ properties:
- const: qcom,sm8250-refgen-regulator
- enum:
+ - qcom,ipq9650-refgen-regulator
- qcom,sdm845-refgen-regulator
- qcom,sm8250-refgen-regulator
reg:
maxItems: 1
+ clocks:
+ items:
+ - description: Core reference clock
+ - description: AHB interface clock
+
+ clock-names:
+ items:
+ - const: core
+ - const: hclk
+
required:
- compatible
- reg
+allOf:
+ - $ref: regulator.yaml#
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,ipq9650-refgen-regulator
+ then:
+ required:
+ - clocks
+ - clock-names
+ else:
+ properties:
+ clocks: false
+ clock-names: false
+
unevaluatedProperties: false
examples:
--
2.34.1
^ permalink raw reply related
* [PATCH v3 1/3] regulator: qcom-refgen: correct the regulator type to CURRENT
From: Kathiravan Thirumoorthy @ 2026-06-15 8:35 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, devicetree, Kathiravan Thirumoorthy,
stable, Konrad Dybcio
In-Reply-To: <20260615-ipq9650_refgen-v3-0-5f611623629c@oss.qualcomm.com>
As per the REFGEN IP team, this block supplies the reference current to
the PHYs in the SoC. So, correct the regulator type to REGULATOR_CURRENT
to match with the HW behavior.
Fixes: 7cbfbe237960 ("regulator: Introduce Qualcomm REFGEN regulator driver")
Cc: stable@vger.kernel.org
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
---
drivers/regulator/qcom-refgen-regulator.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/qcom-refgen-regulator.c b/drivers/regulator/qcom-refgen-regulator.c
index 299ac3c8c3bc..6a3795469927 100644
--- a/drivers/regulator/qcom-refgen-regulator.c
+++ b/drivers/regulator/qcom-refgen-regulator.c
@@ -66,7 +66,7 @@ static const struct regulator_desc sdm845_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
- .type = REGULATOR_VOLTAGE,
+ .type = REGULATOR_CURRENT,
.ops = &(const struct regulator_ops) {
.enable = qcom_sdm845_refgen_enable,
.disable = qcom_sdm845_refgen_disable,
@@ -82,7 +82,7 @@ static const struct regulator_desc sm8250_refgen_desc = {
.enable_time = 5,
.name = "refgen",
.owner = THIS_MODULE,
- .type = REGULATOR_VOLTAGE,
+ .type = REGULATOR_CURRENT,
.ops = &(const struct regulator_ops) {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
--
2.34.1
^ permalink raw reply related
* [PATCH v3 0/3] Add support for the REFGEN in the IPQ9650 SoC
From: Kathiravan Thirumoorthy @ 2026-06-15 8:35 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, devicetree, Kathiravan Thirumoorthy,
stable, Konrad Dybcio, Dmitry Baryshkov
IPQ9650 SoC has 2 REFGEN blocks providing the reference current to
the PCIe and USB, UNIPHY PHYs. For the other SoCs, clocks for this block
is enabled on power up but that's not the case for IPQ9650 and we have
to explicitly enable those clocks.
Document the same and add support for it.
Correct the regulator type to REGULATOR_CURRENT, as the REFGEN block
supplies the reference current to PHYs in the SoC, per the REFGEN IP
team, aligning it with the hardware behavior.
Signed-off-by: Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
---
Changes in v3:
- Pick up the R-b tags
- Use the lower case hex number in patch 2
- Document the IPQ9650 compatible as separate one not as a fallback and
move the allOf block after the 'required:' section
- Link to v2: https://patch.msgid.link/20260611-ipq9650_refgen-v2-0-d96a91d5b99e@oss.qualcomm.com
Changes in v2:
- New patch 1/3 - change the regulator type to align with HW behavior
- Add the constraints for clock and clock-names property in the binding
- Read the REFGEN_STATUS register to find out the regulator is enabled
- Dropped the unused slab.h
- Link to v1: https://patch.msgid.link/20260602-ipq9650_refgen-v1-0-55e2afa5ff64@oss.qualcomm.com
To: Liam Girdwood <lgirdwood@gmail.com>
To: Mark Brown <broonie@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Konrad Dybcio <konradybcio@kernel.org>
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
Kathiravan Thirumoorthy (3):
regulator: qcom-refgen: correct the regulator type to CURRENT
regulator: dt-bindings: qcom,sdm845-refgen-regulator: Document IPQ9650
regulator: qcom-refgen: add support for the IPQ9650 SoC
.../regulator/qcom,sdm845-refgen-regulator.yaml | 31 +++++++-
drivers/regulator/qcom-refgen-regulator.c | 93 ++++++++++++++++++++--
2 files changed, 115 insertions(+), 9 deletions(-)
---
base-commit: c425609d6ac4012c8bbf01ec2e10e801b1923a7b
change-id: 20260520-ipq9650_refgen-196b570d8bc0
Best regards,
--
Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
^ permalink raw reply
* [PATCH v4 6/6] arm64: dts: qcom: shikra-iqs-evk-imx577-camera: Add DT overlay
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta
In-Reply-To: <20260615-shikra-camss-review-v4-0-bcb51081735b@oss.qualcomm.com>
Shikra IQS is an industrial-grade variant using PM8150 PMIC, requiring
different CSIPHY and sensor supply rails compared to the retail boards
(CQM and CQS) which use PM4125.
Add a dedicated overlay for optional IMX577 integration via CSIPHY1.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 2 +
.../dts/qcom/shikra-iqs-evk-imx577-camera.dtso | 79 ++++++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 76b8f144983827f4905a72935e8d5291a227dc97..09f2318d1c12c4239a6a7bac4ecbca38eb65ffa2 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -340,9 +340,11 @@ dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk.dtb
shikra-cqm-evk-imx577-camera-dtbs := shikra-cqm-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
shikra-cqs-evk-imx577-camera-dtbs := shikra-cqs-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
+shikra-iqs-evk-imx577-camera-dtbs := shikra-iqs-evk.dtb shikra-iqs-evk-imx577-camera.dtbo
dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk-imx577-camera.dtb
dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk-imx577-camera.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk-imx577-camera.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso b/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso
new file mode 100644
index 0000000000000000000000000000000000000000..d8c968a918c67cdebc0e7c6fc14ef820c97ecb75
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,shikra-gcc.h>
+#include <dt-bindings/gpio/gpio.h>
+
+&camss {
+ vdd-csiphy-1p2-supply = <&pm8150_l11>;
+ vdd-csiphy-1p8-supply = <&pm8150_l12>;
+
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ csiphy1_ep: endpoint {
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&imx577_ep1>;
+ };
+ };
+ };
+};
+
+&cci {
+ status = "okay";
+};
+
+&cci_i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera@1a {
+ compatible = "sony,imx577";
+ reg = <0x1a>;
+
+ reset-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&cam_mclk1_default &cam1_reset_default>;
+ pinctrl-names = "default";
+
+ clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
+ assigned-clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
+ assigned-clock-rates = <24000000>;
+
+ /*
+ * avdd and dvdd are supplied by on-board regulators on the
+ * IMX577 module from the connector's 3.3 V rail; they are
+ * not SoC-controlled. dovdd (1.8 V) powers the carrier board
+ * level-shifter that translates CCI I2C and reset lines
+ * between the SoC and the connector.
+ */
+ dovdd-supply = <&pm8150_l15>;
+
+ port {
+ imx577_ep1: endpoint {
+ link-frequencies = /bits/ 64 <600000000>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csiphy1_ep>;
+ };
+ };
+ };
+};
+
+&tlmm {
+ cam1_reset_default: cam1-reset-default-state {
+ pins = "gpio33";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v4 2/7] clk: qcom: Add generic clkref_en support
From: Qiang Yu @ 2026-06-15 8:34 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Taniya Das,
Konrad Dybcio, linux-arm-msm, linux-clk, devicetree, linux-kernel,
krishna.chundru
In-Reply-To: <034a70bb-43f7-4b94-8a85-dce466081473@oss.qualcomm.com>
On Tue, Jun 09, 2026 at 02:38:08PM +0200, Konrad Dybcio wrote:
> On 5/28/26 4:29 AM, Qiang Yu wrote:
> > Before XO refclk is distributed to PCIe/USB/eDP PHYs, it passes through
> > a QREF block. QREF is powered by dedicated LDO rails, and the clkref_en
> > register controls whether refclk is gated through to the PHY side.
> >
> > These clkref controls are different from typical GCC branch clocks:
> > - only a single enable bit is present, without branch-style config bits
> > - regulators must be voted before enable and unvoted after disable
> >
> > Model this as a dedicated clk_ref clock type with custom clk_ops instead
> > of reusing struct clk_branch semantics.
> >
> > Also provide a common registration/probe API so the same clkref model
> > can be reused regardless of where clkref_en registers are placed, e.g.
> > TCSR on glymur and TLMM on SM8750.
> >
> > Signed-off-by: Qiang Yu <qiang.yu@oss.qualcomm.com>
> > ---
>
> [...]
>
> > +struct qcom_clk_ref {
> > + struct clk_hw hw;
> > + struct clk_init_data init_data;
>
> We don't need init_data for each one of these, we can construct it in
> probe scope:
>
> struct clk_init_data init_data = { };
>
> init_data.name = clk_ref->desc.name;
> init_data.parent_data = &qcom_clk_ref_parent_data;
> init_data.num_parents = 1;
> init_data.ops = &qcom_clk_ref_ops;
> clk_ref->hw.init = &init_data;
>
> ret = devm_clk_hw_register(dev, hw);
> // not needed past that point, __clk_register zeroes hw->init internally
>
Thanks, will fix in next version.
- Qiang Yu
> Konrad
^ permalink raw reply
* [PATCH v2 5/5] MAINTAINERS: Add entry for Samsung Exynos8855 SoC
From: Alim Akhtar @ 2026-06-15 8:52 UTC (permalink / raw)
To: krzk, peter.griffin, robh, conor+dt, linusw
Cc: linux-samsung-soc, linux-kernel, devicetree, linux-gpio,
hajun.sung, Alim Akhtar
In-Reply-To: <20260615085252.1964423-1-alim.akhtar@samsung.com>
Add maintainers entry for the Samsung Exynos8855 SoC based platforms
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
---
MAINTAINERS | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 49a10f0ceb07..fb9b24220258 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23914,6 +23914,13 @@ F: arch/arm64/boot/dts/exynos/exynos850*
F: drivers/clk/samsung/clk-exynos850.c
F: include/dt-bindings/clock/exynos850.h
+SAMSUNG EXYNOS8855 SoC SUPPORT
+M: Alim Akhtar <alim.akhtar@samsung.com>
+L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+L: linux-samsung-soc@vger.kernel.org
+S: Maintained
+F: arch/arm64/boot/dts/exynos/exynos8855*
+
SAMSUNG EXYNOS ACPM MAILBOX PROTOCOL
M: Tudor Ambarus <tudor.ambarus@linaro.org>
L: linux-kernel@vger.kernel.org
--
2.34.1
^ permalink raw reply related
* [PATCH v4 5/6] arm64: dts: qcom: shikra-cqm-cqs-evk-imx577-camera: Add DT overlay
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta
In-Reply-To: <20260615-shikra-camss-review-v4-0-bcb51081735b@oss.qualcomm.com>
Shikra CQM and CQS are retail variants sharing the same PM4125 PMIC
and identical camera supply rails. The only difference between them
is the integrated modem on CQM, which does not affect camera hardware.
Add a shared overlay for optional IMX577 integration via CSIPHY1,
used by both CQM and CQS EVK boards.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/Makefile | 6 ++
.../dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso | 79 ++++++++++++++++++++++
2 files changed, 85 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index a9e9d829fb962386b3975f345ec006504607130a..76b8f144983827f4905a72935e8d5291a227dc97 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -337,6 +337,12 @@ dtb-$(CONFIG_ARCH_QCOM) += sdx75-idp.dtb
dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk.dtb
dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk.dtb
dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk.dtb
+
+shikra-cqm-evk-imx577-camera-dtbs := shikra-cqm-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
+shikra-cqs-evk-imx577-camera-dtbs := shikra-cqs-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk-imx577-camera.dtb
+dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk-imx577-camera.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb
dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso b/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso
new file mode 100644
index 0000000000000000000000000000000000000000..3a481d972cd27a2a324d96d8f47c161e11ea54f3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,shikra-gcc.h>
+#include <dt-bindings/gpio/gpio.h>
+
+&camss {
+ vdd-csiphy-1p2-supply = <&pm4125_l5>;
+ vdd-csiphy-1p8-supply = <&pm4125_l13>;
+
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ csiphy1_ep: endpoint {
+ data-lanes = <0 1 2 3>;
+ remote-endpoint = <&imx577_ep1>;
+ };
+ };
+ };
+};
+
+&cci {
+ status = "okay";
+};
+
+&cci_i2c1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ camera@1a {
+ compatible = "sony,imx577";
+ reg = <0x1a>;
+
+ reset-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&cam_mclk1_default &cam1_reset_default>;
+ pinctrl-names = "default";
+
+ clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
+ assigned-clocks = <&gcc GCC_CAMSS_MCLK1_CLK>;
+ assigned-clock-rates = <24000000>;
+
+ /*
+ * avdd and dvdd are supplied by on-board regulators on the
+ * IMX577 module from the connector's 3.3 V rail; they are
+ * not SoC-controlled. dovdd (1.8 V) powers the carrier board
+ * level-shifter that translates CCI I2C and reset lines
+ * between the SoC and the connector.
+ */
+ dovdd-supply = <&pm4125_l15>;
+
+ port {
+ imx577_ep1: endpoint {
+ link-frequencies = /bits/ 64 <600000000>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&csiphy1_ep>;
+ };
+ };
+ };
+};
+
+&tlmm {
+ cam1_reset_default: cam1-reset-default-state {
+ pins = "gpio33";
+ function = "gpio";
+ drive-strength = <2>;
+ bias-disable;
+ };
+};
--
2.34.1
^ permalink raw reply related
* [PATCH v4 4/6] arm64: dts: qcom: shikra: Add pin configuration for mclks
From: Nihal Kumar Gupta @ 2026-06-15 8:33 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Loic Poulain,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Robert Foss, Andi Shyti, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel, linux-i2c,
imx, linux-arm-kernel, Suresh Vankadara, Vikram Sharma,
Nihal Kumar Gupta
In-Reply-To: <20260615-shikra-camss-review-v4-0-bcb51081735b@oss.qualcomm.com>
Add pinctrl configuration for the four available camera master clocks.
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Nihal Kumar Gupta <nihal.gupta@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
index 57732804a6c6a114a407a4a541a1cc7af7635ea2..16b547131e8b14541abc68ff7cda126ba777ad80 100644
--- a/arch/arm64/boot/dts/qcom/shikra.dtsi
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -380,6 +380,34 @@ cci_i2c1_sleep: cci-i2c1-sleep-state {
bias-pull-down;
};
+ cam_mclk0_default: cam-mclk0-default-state {
+ pins = "gpio34";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk1_default: cam-mclk1-default-state {
+ pins = "gpio35";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk2_default: cam-mclk2-default-state {
+ pins = "gpio96";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
+ cam_mclk3_default: cam-mclk3-default-state {
+ pins = "gpio98";
+ function = "cam_mclk";
+ drive-strength = <2>;
+ bias-disable;
+ };
+
qup_uart0_default: qup-uart0-default-state {
pins = "gpio0", "gpio1";
function = "qup0_se0";
--
2.34.1
^ 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