* Re: [PATCH 6/9] iommu/arm-smmu-v3: Directly encode simple commands
From: Pranjal Shrivastava @ 2026-05-10 18:59 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: iommu, Jonathan Hunter, Joerg Roedel, linux-arm-kernel,
linux-tegra, Robin Murphy, Thierry Reding, Krishna Reddy,
Will Deacon, David Matlack, Pasha Tatashin, patches,
Samiullah Khawaja, Mostafa Saleh
In-Reply-To: <20260508233629.GI9254@nvidia.com>
On Fri, May 08, 2026 at 08:36:29PM -0300, Jason Gunthorpe wrote:
> On Fri, May 08, 2026 at 08:09:33PM +0000, Pranjal Shrivastava wrote:
> > > > > +static void arm_smmu_cmdq_batch_add_cmd_p(struct arm_smmu_device *smmu,
> > > > > + struct arm_smmu_cmdq_batch *cmds,
> > > > > + struct arm_smmu_cmd *cmd)
> > > >
> > > > Nit: Same here, why not __arm_smmu_cmdq_batch_add_cmd? I understand
> > > > that _p just means we'll aceept ptr.. but the name's kinda wonky.
> > >
> > > Which becomes a fairly widly used public entry point, so I didn't want
> > > to have the __
> > >
> > > Though there is no external user of arm_smmu_cmdq_issue_cmd_p()
> > >
> >
> > It's just that we're calling "arm_smmu_cmdq_batch_add_cmd_p" at one
> > place and using `arm_smmu_make_cmd_<cmd_name>` at the other. It makes
> > one think what's "_p" in issue_cmd, only to realize "_p: pointer variant
> >
> > I guess I didn't like the new _p ones but I guess it's fine. Happy to
> > leave it at your discretion.
>
> I don't much care for the _p (and yes it means pointer variation) but
> do like it better than __ and failed to come up with another idea :)
>
Yea, I can't come up with much either (without __ or _p), maybe we could
leave this as is..
The only alternatives in my mind are arm_smmu_cmdq_issue_cmd_ptr() which
is similar.
Thanks,
Praan
^ permalink raw reply
* Re: [PATCH v1 1/4] drm/bridge: dw-hdmi: Pass bridge attach flags for dw_hdmi_bind()
From: Jonas Karlman @ 2026-05-10 18:49 UTC (permalink / raw)
To: Damon Ding
Cc: andrzej.hajda, neil.armstrong, rfoss, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, hjc, heiko, andy.yan, wens, samuel,
luca.ceresoli, Laurent.pinchart, jernej.skrabec, victor.liu,
dmitry.baryshkov, shengjiu.wang, dri-devel, linux-kernel,
linux-arm-kernel, linux-rockchip, linux-sunxi
In-Reply-To: <20260403070032.447102-2-damon.ding@rock-chips.com>
Hi Damon,
On 4/3/2026 9:00 AM, Damon Ding wrote:
> For Rockchip and Allwinner platforms, the HDMI encoder attaches the
> dw-hdmi bridge via dw_hdmi_bind(). This additional bridge attach flag
> serves as preparation for the Rockchip dw-hdmi driver to support the
> bridge-connector framework.
We should not extend the dw_hdmi_bind() function with a new flag.
Each driver can instead call dw_hdmi_probe() and drm_bridge_attach() on
their own, similar as the other dw-hdmi drivers that currently use the
bridge connector.
Regards,
Jonas
>
> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
> ---
> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 5 +++--
> drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 2 +-
> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c | 2 +-
> include/drm/bridge/dw_hdmi.h | 4 +++-
> 4 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index ada45e8b3e2c..dd50dda3a4f5 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -3619,7 +3619,8 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
> */
> struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
> struct drm_encoder *encoder,
> - const struct dw_hdmi_plat_data *plat_data)
> + const struct dw_hdmi_plat_data *plat_data,
> + enum drm_bridge_attach_flags flags)
> {
> struct dw_hdmi *hdmi;
> int ret;
> @@ -3628,7 +3629,7 @@ struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
> if (IS_ERR(hdmi))
> return hdmi;
>
> - ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, 0);
> + ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, flags);
> if (ret) {
> dw_hdmi_remove(hdmi);
> return ERR_PTR(ret);
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index 0dc1eb5d2ae3..21b141b7cb9c 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -608,7 +608,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
>
> platform_set_drvdata(pdev, hdmi);
>
> - hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
> + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data, 0);
>
> /*
> * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
> diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> index 96532709c2a7..04173335f7e7 100644
> --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> @@ -188,7 +188,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master,
>
> platform_set_drvdata(pdev, hdmi);
>
> - hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
> + hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data, 0);
>
> /*
> * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index 8500dd4f99d8..e789fb451ef2 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -6,6 +6,7 @@
> #ifndef __DW_HDMI__
> #define __DW_HDMI__
>
> +#include <drm/drm_bridge.h>
> #include <sound/hdmi-codec.h>
>
> struct drm_display_info;
> @@ -182,7 +183,8 @@ void dw_hdmi_remove(struct dw_hdmi *hdmi);
> void dw_hdmi_unbind(struct dw_hdmi *hdmi);
> struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
> struct drm_encoder *encoder,
> - const struct dw_hdmi_plat_data *plat_data);
> + const struct dw_hdmi_plat_data *plat_data,
> + enum drm_bridge_attach_flags flags);
>
> void dw_hdmi_resume(struct dw_hdmi *hdmi);
>
^ permalink raw reply
* Re: [PATCH v2 1/2] phy: rockchip: inno-hdmi: Add configure() and validate() ops
From: Jonas Karlman @ 2026-05-10 18:43 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Heiko Stuebner
Cc: linux-phy, linux-rockchip, linux-arm-kernel, linux-kernel
In-Reply-To: <20260510095731.1222705-2-jonas@kwiboo.se>
On 5/10/2026 11:57 AM, Jonas Karlman wrote:
> The commit 10ed34d6eaaf ("phy: Add HDMI configuration options")
> introduced a way for HDMI PHYs to be configured through the generic
> phy_configure() function.
>
> This driver derives the TMDS character rate from the pixel clock and the
> PHY bus width setting. However, no in-tree consumer of this PHY has ever
> called phy_set_bus_width() to change the TMDS character rate as only
> 8-bit RGB output is supported by the HDMI display driver.
>
> Add configure() and validate() ops to allow consumers to configure the
> TMDS character rate using phy_configure(). Fallback to the deprecated
> way of using the PHY bus width to configure the TMDS character rate.
I have now posted a patch "drm/rockchip: dw_hdmi: Configure HDMI PHY
in atomic_mode_set()" [1] that adds phy_validate() and phy_configure()
calls for this HDMI PHY.
[1] https://lore.kernel.org/dri-devel/20260510183114.1248840-10-jonas@kwiboo.se/
Regards,
Jonas
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> ---
> Changes in v2:
> - Add validate() ops to validate that the TMDS rate is supported
> - Split out parts that remove the old workaround into a separate patch
> ---
> drivers/phy/rockchip/phy-rockchip-inno-hdmi.c | 47 ++++++++++++++++++-
> 1 file changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
> index 1483907413fa..9cfe956fefe7 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
> @@ -245,6 +245,7 @@ struct inno_hdmi_phy {
> struct clk *phyclk;
> unsigned long pixclock;
> unsigned long tmdsclock;
> + struct phy_configure_opts_hdmi hdmi_cfg;
> };
>
> struct pre_pll_config {
> @@ -554,7 +555,12 @@ static inline void inno_update_bits(struct inno_hdmi_phy *inno, u8 reg,
> static unsigned long inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy *inno,
> unsigned long rate)
> {
> - int bus_width = phy_get_bus_width(inno->phy);
> + int bus_width;
> +
> + if (inno->hdmi_cfg.tmds_char_rate)
> + return inno->hdmi_cfg.tmds_char_rate;
> +
> + bus_width = phy_get_bus_width(inno->phy);
>
> switch (bus_width) {
> case 4:
> @@ -602,6 +608,42 @@ static irqreturn_t inno_hdmi_phy_rk3328_irq(int irq, void *dev_id)
> return IRQ_HANDLED;
> }
>
> +static int inno_hdmi_phy_validate(struct phy *phy, enum phy_mode mode,
> + int submode, union phy_configure_opts *opts)
> +{
> + const struct pre_pll_config *cfg = pre_pll_cfg_table;
> + unsigned long tmdsclock;
> +
> + if (!(mode == PHY_MODE_HDMI && submode == PHY_HDMI_MODE_TMDS))
> + return -EINVAL;
> +
> + if (!opts->hdmi.tmds_char_rate || opts->hdmi.tmds_char_rate > 594000000)
> + return -EINVAL;
> +
> + tmdsclock = opts->hdmi.tmds_char_rate;
> + for (; cfg->pixclock != 0; cfg++)
> + if (cfg->pixclock == tmdsclock && cfg->tmdsclock == tmdsclock)
> + return 0;
> +
> + return -EINVAL;
> +}
> +
> +static int inno_hdmi_phy_configure(struct phy *phy,
> + union phy_configure_opts *opts)
> +{
> + struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = inno_hdmi_phy_validate(phy, phy_get_mode(phy),
> + PHY_HDMI_MODE_TMDS, opts);
> + if (ret)
> + return ret;
> +
> + inno->hdmi_cfg = opts->hdmi;
> +
> + return 0;
> +}
> +
> static int inno_hdmi_phy_power_on(struct phy *phy)
> {
> struct inno_hdmi_phy *inno = phy_get_drvdata(phy);
> @@ -670,6 +712,8 @@ static const struct phy_ops inno_hdmi_phy_ops = {
> .owner = THIS_MODULE,
> .power_on = inno_hdmi_phy_power_on,
> .power_off = inno_hdmi_phy_power_off,
> + .configure = inno_hdmi_phy_configure,
> + .validate = inno_hdmi_phy_validate,
> };
>
> static const
> @@ -1392,6 +1436,7 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev)
> }
>
> phy_set_drvdata(inno->phy, inno);
> + phy_set_mode_ext(inno->phy, PHY_MODE_HDMI, PHY_HDMI_MODE_TMDS);
> phy_set_bus_width(inno->phy, 8);
>
> if (inno->plat_data->ops->init) {
^ permalink raw reply
* Re: [PATCH 3/3] arm64: dts: allwinner: a523: add gpadc node
From: Chen-Yu Tsai @ 2026-05-10 18:34 UTC (permalink / raw)
To: Michal Piekos
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jernej Skrabec,
Samuel Holland, Maksim Kiselev, linux-iio, devicetree,
linux-arm-kernel, linux-sunxi, linux-kernel
In-Reply-To: <20260510-sunxi-a523-gpadc-v1-3-4f6b0f4000fb@mmpsystems.pl>
On Sun, May 10, 2026 at 9:02 PM Michal Piekos
<michal.piekos@mmpsystems.pl> wrote:
>
> Describe high speed timer block on Allwinner D1S-T113.
>
> Tested on Radxa Cubie A5E:
> - 2 connected channels are showing voltages in agreement with
> schematics.
> BOOT-SEL-ADC ~500mV
> BOM-ADC ~1800mV
> - 3rd channel exposed on 40pin header is showing correct voltages when
> connected to known voltage source.
>
> Signed-off-by: Michal Piekos <michal.piekos@mmpsystems.pl>
> ---
> arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> index 5afa8d92acbf..f6c5cae5b23a 100644
> --- a/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi
> @@ -340,6 +340,18 @@ ledc: led-controller@2008000 {
> status = "disabled";
> };
>
> + gpadc: adc@2009000 {
> + compatible = "allwinner,sun55i-a523-gpadc",
> + "allwinner,sun20i-d1-gpadc";
> + reg = <0x2009000 0x400>;
> + clocks = <&ccu CLK_BUS_GPADC0>, <&ccu CLK_GPADC0>;
> + clock-names = "bus", "mod";
> + resets = <&ccu RST_BUS_GPADC0>;
> + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> + status = "disabled";
> + #io-channel-cells = <1>;
status should always be the last property.
> + };
> +
> wdt: watchdog@2050000 {
> compatible = "allwinner,sun55i-a523-wdt";
> reg = <0x2050000 0x20>;
>
> --
> 2.43.0
>
>
^ permalink raw reply
* [PATCH 08/10] drm/rockchip: dw_hdmi: Set output_port for RK3568/RK3566
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
All in-tree RK3568/RK3566 device trees using HDMI also include the
required hdmi-connector node at port@1 since their introduction.
Define the output_port for RK3568 so that dw-hdmi bridge driver can pick
up the display-connector bridge once the dw-hdmi connector is replaced
with a bridge connector in a future change.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index a55a89040590..9d3bb6cd5670 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -459,6 +459,7 @@ static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
.phy_config = rockchip_phy_config,
.phy_data = &rk3568_chip_data,
.use_drm_infoframe = true,
+ .output_port = 1,
};
static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
--
2.54.0
^ permalink raw reply related
* [PATCH 07/10] drm/rockchip: dw_hdmi: Clean up whitespace
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
Move the blank line before the RK3328 definitions for readability and
make the phy_config table spacing consistent with other tables.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 6aefdba0f1f9..a55a89040590 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -31,8 +31,8 @@
#define RK3288_GRF_SOC_CON6 0x025C
#define RK3288_HDMI_LCDC_SEL BIT(4)
-#define RK3328_GRF_SOC_CON2 0x0408
+#define RK3328_GRF_SOC_CON2 0x0408
#define RK3328_HDMI_SDAIN_MSK BIT(11)
#define RK3328_HDMI_SCLIN_MSK BIT(10)
#define RK3328_HDMI_HPD_IOE BIT(2)
@@ -190,11 +190,11 @@ static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
/*pixelclk symbol term vlev*/
- { 74250000, 0x8009, 0x0004, 0x0272},
- { 165000000, 0x802b, 0x0004, 0x0209},
- { 297000000, 0x8039, 0x0005, 0x028d},
- { 594000000, 0x8039, 0x0000, 0x019d},
- { ~0UL, 0x0000, 0x0000, 0x0000}
+ { 74250000, 0x8009, 0x0004, 0x0272 },
+ { 165000000, 0x802b, 0x0004, 0x0209 },
+ { 297000000, 0x8039, 0x0005, 0x028d },
+ { 594000000, 0x8039, 0x0000, 0x019d },
+ { ~0UL, 0x0000, 0x0000, 0x0000 },
};
static enum drm_mode_status
--
2.54.0
^ permalink raw reply related
* [PATCH 09/10] drm/rockchip: dw_hdmi: Configure HDMI PHY in atomic_mode_set()
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
The HDMI helpers negotiated TMDS character rate and output bpc are
available from the connector state. Change the encoder helper from
mode_set() to atomic_mode_set() so these values can be used to configure
the HDMI PHY using phy_configure().
This has no impact until the dw-hdmi bridge is fully converted into a
HDMI bridge and HDMI helpers are used to assign hdmi.tmds_char_rate.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 +++++++++++++++++----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 9d3bb6cd5670..94a30579a736 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -226,11 +226,22 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
return MODE_OK;
}
-static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adj_mode)
+static void
+dw_hdmi_rockchip_encoder_atomic_mode_set(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+ struct drm_display_mode *adj_mode = &crtc_state->adjusted_mode;
+
+ if (hdmi->phy && conn_state->hdmi.tmds_char_rate) {
+ union phy_configure_opts opts = {};
+
+ opts.hdmi.bpc = conn_state->hdmi.output_bpc;
+ opts.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
+
+ phy_configure(hdmi->phy, &opts);
+ }
clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000);
}
@@ -270,15 +281,23 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_connector_state *conn_state)
{
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+ union phy_configure_opts opts = {};
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
- return 0;
+ if (!hdmi->phy || !conn_state->hdmi.tmds_char_rate)
+ return 0;
+
+ opts.hdmi.bpc = conn_state->hdmi.output_bpc;
+ opts.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
+
+ return phy_validate(hdmi->phy, PHY_MODE_HDMI, PHY_HDMI_MODE_TMDS, &opts);
}
static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
- .mode_set = dw_hdmi_rockchip_encoder_mode_set,
+ .atomic_mode_set = dw_hdmi_rockchip_encoder_atomic_mode_set,
.enable = dw_hdmi_rockchip_encoder_enable,
.atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
};
--
2.54.0
^ permalink raw reply related
* [PATCH 10/10] drm/rockchip: dw_hdmi: Propagate bus format to display driver
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
The HDMI block is currently hardcoded to expect RGB output from the
display controller. However, the VOP in some SoCs are capable of YCbCr
output to the HDMI block.
Read the negotiated bus format from the bridge state and propagate it to
the CRCT state in form of output mode and bus format. Treat the format
MEDIA_BUS_FMT_FIXED as RGB888 and reject any unsupported formats.
This has no inpact until dw-hdmi bridge is fully converted to a HDMI
bridge and also adds support for the "color format" connector property.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 44 ++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 94a30579a736..b52114d5fe9c 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -5,6 +5,7 @@
#include <linux/clk.h>
#include <linux/hw_bitfield.h>
+#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -275,6 +276,26 @@ static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
dev_dbg(hdmi->dev, "vop %s output to hdmi\n", ret ? "LIT" : "BIG");
}
+static u32 dw_hdmi_rockchip_get_bus_format(struct drm_encoder *encoder,
+ struct drm_connector_state *conn_state)
+{
+ struct drm_bridge *bridge __free(drm_bridge_put) = NULL;
+ struct drm_bridge_state *bridge_state;
+
+ bridge = drm_bridge_chain_get_first_bridge(encoder);
+ if (!bridge)
+ return 0;
+
+ bridge_state = drm_atomic_get_bridge_state(conn_state->state, bridge);
+ if (!bridge_state)
+ return 0;
+
+ if (bridge_state->input_bus_cfg.format != MEDIA_BUS_FMT_FIXED)
+ return bridge_state->input_bus_cfg.format;
+
+ return bridge_state->output_bus_cfg.format;
+}
+
static int
dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
@@ -283,9 +304,30 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
union phy_configure_opts opts = {};
+ u32 bus_format;
+
+ bus_format = dw_hdmi_rockchip_get_bus_format(encoder, conn_state);
+
+ switch (bus_format) {
+ case MEDIA_BUS_FMT_FIXED:
+ bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+ fallthrough;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ case MEDIA_BUS_FMT_RGB101010_1X30:
+ case MEDIA_BUS_FMT_YUV8_1X24:
+ case MEDIA_BUS_FMT_YUV10_1X30:
+ s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
+ break;
+ case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
+ case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
+ s->output_mode = ROCKCHIP_OUT_MODE_YUV420;
+ break;
+ default:
+ return -EINVAL;
+ }
- s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
s->output_type = DRM_MODE_CONNECTOR_HDMIA;
+ s->bus_format = bus_format;
if (!hdmi->phy || !conn_state->hdmi.tmds_char_rate)
return 0;
--
2.54.0
^ permalink raw reply related
* [PATCH 00/10] drm/rockchip: dw_hdmi: Misc cleanup and propagate bus format
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, dri-devel, linux-rockchip, linux-arm-kernel,
linux-kernel, Jonas Karlman
This series include misc cleanup of the dwhdmi-rockchip driver and
prepares for future support of YCbCr output and Deep Color modes.
Patch 1-7 cleanup and changes to use drmres helpers for the encoder.
Patch 8 prepare for use of a display-connector bridge for RK3568/RK3566.
Patch 9-10 prepares for future support of YCbCr and Deep Color modes.
This series depends on the patch "drm/rockchip: dw_hdmi: avoid direct
dereference of phy->dev.of_node" [1] from the series "Split Generic PHY
consumer and provider API" [2].
[1] https://lore.kernel.org/linux-phy/20260505100523.1922388-16-vladimir.oltean@nxp.com/
[2] https://lore.kernel.org/linux-phy/20260505100523.1922388-1-vladimir.oltean@nxp.com/
This series is part of a multi series effort to:
- phy: rockchip: inno-hdmi: Change TMDS rate handling to configure() ops [v2]
- drm/rockchip: dw_hdmi: Misc cleanup and propagate bus format [v1]
- drm: bridge: dw_hdmi: Misc enable/disable, CEC and EDID cleanup [v5]
- drm/bridge: dw-hdmi: Improve input/output bus format handling
- drm/bridge: dw-hdmi: Convert to a HDMI bridge and use of bridge connector
- drm/bridge: dw-hdmi: Add and use tmds_char_rate_valid() plat data ops
- drm/meson: hdmi: Misc cleanup and use CEC notifier helpers
- drm/rockchip: dw_hdmi: Enable YCbCr and Deep Color modes
Link to snapshot: https://github.com/Kwiboo/linux-rockchip/commits/next-20260508-rk-hdmi-v3/
Jonas Karlman (10):
drm/rockchip: dw_hdmi: Use of_device_get_match_data() to get match
data
drm/rockchip: dw_hdmi: Use local dev variable consistently in bind()
drm/rockchip: dw_hdmi: Use drmres helpers for encoder resources
drm/rockchip: dw_hdmi: Inline resource lookup into bind()
drm/rockchip: dw_hdmi: Hold a reference to the dw-hdmi bridge
drm/rockchip: dw_hdmi: Remove empty encoder helper funcs
drm/rockchip: dw_hdmi: Clean up whitespace
drm/rockchip: dw_hdmi: Set output_port for RK3568/RK3566
drm/rockchip: dw_hdmi: Configure HDMI PHY in atomic_mode_set()
drm/rockchip: dw_hdmi: Propagate bus format to display driver
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 220 ++++++++++++--------
1 file changed, 129 insertions(+), 91 deletions(-)
--
2.54.0
^ permalink raw reply
* [PATCH 06/10] drm/rockchip: dw_hdmi: Remove empty encoder helper funcs
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
Remove the empty disable() and static return true mode_fixup() encoder
helper funcs as they do not provide any useful functionality.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 18 ++----------------
1 file changed, 2 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index c7933f3eb64f..6aefdba0f1f9 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -226,18 +226,6 @@ dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
return MODE_OK;
}
-static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
-{
-}
-
-static bool
-dw_hdmi_rockchip_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adj_mode)
-{
- return true;
-}
-
static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
@@ -290,10 +278,8 @@ dw_hdmi_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
}
static const struct drm_encoder_helper_funcs dw_hdmi_rockchip_encoder_helper_funcs = {
- .mode_fixup = dw_hdmi_rockchip_encoder_mode_fixup,
- .mode_set = dw_hdmi_rockchip_encoder_mode_set,
- .enable = dw_hdmi_rockchip_encoder_enable,
- .disable = dw_hdmi_rockchip_encoder_disable,
+ .mode_set = dw_hdmi_rockchip_encoder_mode_set,
+ .enable = dw_hdmi_rockchip_encoder_enable,
.atomic_check = dw_hdmi_rockchip_encoder_atomic_check,
};
--
2.54.0
^ permalink raw reply related
* [PATCH 03/10] drm/rockchip: dw_hdmi: Use drmres helpers for encoder resources
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
Change to use drmres helpers drmm_kzalloc() to allocate driver data
and drmm_encoder_init() to initialize the encoder. With use of drmres
the manual encoder cleanup in failure path and unbind is also removed.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 ++++++++-------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 435352f91b88..982d0829f278 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -14,6 +14,7 @@
#include <drm/bridge/dw_hdmi.h>
#include <drm/drm_edid.h>
+#include <drm/drm_managed.h>
#include <drm/drm_of.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_simple_kms_helper.h>
@@ -550,13 +551,14 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
if (!drv_data)
return -ENODEV;
- hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+ hdmi = drmm_kzalloc(drm, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
- plat_data = devm_kmemdup(dev, drv_data, sizeof(*drv_data), GFP_KERNEL);
+ plat_data = drmm_kzalloc(drm, sizeof(*drv_data), GFP_KERNEL);
if (!plat_data)
return -ENOMEM;
+ memcpy(plat_data, drv_data, sizeof(*drv_data));
hdmi->dev = dev;
hdmi->plat_data = plat_data;
@@ -608,28 +610,20 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
FIELD_PREP_WM16(RK3568_HDMI_SCLIN_MSK, 1));
}
+ ret = drmm_encoder_init(drm, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to init encoder\n");
+
drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
- drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
platform_set_drvdata(pdev, hdmi);
hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
-
- /*
- * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
- * which would have called the encoder cleanup. Do it manually.
- */
- if (IS_ERR(hdmi->hdmi)) {
- ret = PTR_ERR(hdmi->hdmi);
- goto err_bind;
- }
+ if (IS_ERR(hdmi->hdmi))
+ return dev_err_probe(dev, PTR_ERR(hdmi->hdmi),
+ "failed to bind encoder\n");
return 0;
-
-err_bind:
- drm_encoder_cleanup(encoder);
-
- return ret;
}
static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
@@ -638,7 +632,6 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
dw_hdmi_unbind(hdmi->hdmi);
- drm_encoder_cleanup(&hdmi->encoder.encoder);
}
static const struct component_ops dw_hdmi_rockchip_ops = {
--
2.54.0
^ permalink raw reply related
* [PATCH 04/10] drm/rockchip: dw_hdmi: Inline resource lookup into bind()
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
Inline rockchip_hdmi_parse_dt() into dw_hdmi_rockchip_bind() so the
probe path is easier to follow in one place. Also ensure failures in
bind() use dev_err_probe() so probe deferrals and errors are reported
consistently.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 74 +++++++++------------
1 file changed, 30 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 982d0829f278..c5cdf2d1f04b 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -196,41 +196,6 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
{ ~0UL, 0x0000, 0x0000, 0x0000}
};
-static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
-{
- struct device_node *np = hdmi->dev->of_node;
- int ret;
-
- hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
- if (IS_ERR(hdmi->regmap)) {
- dev_err(hdmi->dev, "Unable to get rockchip,grf\n");
- return PTR_ERR(hdmi->regmap);
- }
-
- hdmi->ref_clk = devm_clk_get_optional_enabled(hdmi->dev, "ref");
- if (!hdmi->ref_clk)
- hdmi->ref_clk = devm_clk_get_optional_enabled(hdmi->dev, "vpll");
-
- if (IS_ERR(hdmi->ref_clk)) {
- ret = PTR_ERR(hdmi->ref_clk);
- return dev_err_probe(hdmi->dev, ret, "failed to get reference clock\n");
- }
-
- hdmi->grf_clk = devm_clk_get_optional(hdmi->dev, "grf");
- if (IS_ERR(hdmi->grf_clk)) {
- ret = PTR_ERR(hdmi->grf_clk);
- return dev_err_probe(hdmi->dev, ret, "failed to get grf clock\n");
- }
-
- ret = devm_regulator_get_enable(hdmi->dev, "avdd-0v9");
- if (ret)
- return ret;
-
- ret = devm_regulator_get_enable(hdmi->dev, "avdd-1v8");
-
- return ret;
-}
-
static enum drm_mode_status
dw_hdmi_rockchip_mode_valid(struct dw_hdmi *dw_hdmi, void *data,
const struct drm_display_info *info,
@@ -578,18 +543,39 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
* the required CRTC is added later.
*/
if (encoder->possible_crtcs == 0)
- return -EPROBE_DEFER;
+ return dev_err_probe(dev, -EPROBE_DEFER,
+ "failed to find possible crtcs\n");
- ret = rockchip_hdmi_parse_dt(hdmi);
- if (ret) {
- return dev_err_probe(dev, ret, "Unable to parse OF data\n");
- }
+ hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+ if (IS_ERR(hdmi->regmap))
+ return dev_err_probe(dev, PTR_ERR(hdmi->regmap),
+ "failed to get rockchip,grf\n");
+
+ hdmi->ref_clk = devm_clk_get_optional_enabled(dev, "ref");
+ if (!hdmi->ref_clk)
+ hdmi->ref_clk = devm_clk_get_optional_enabled(dev, "vpll");
+
+ if (IS_ERR(hdmi->ref_clk))
+ return dev_err_probe(dev, PTR_ERR(hdmi->ref_clk),
+ "failed to get reference clock\n");
+
+ hdmi->grf_clk = devm_clk_get_optional(dev, "grf");
+ if (IS_ERR(hdmi->grf_clk))
+ return dev_err_probe(dev, PTR_ERR(hdmi->grf_clk),
+ "failed to get grf clock\n");
+
+ ret = devm_regulator_get_enable(dev, "avdd-0v9");
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to enable avdd-0v9\n");
+
+ ret = devm_regulator_get_enable(dev, "avdd-1v8");
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to enable avdd-1v8\n");
hdmi->phy = devm_phy_optional_get(dev, "hdmi");
- if (IS_ERR(hdmi->phy)) {
- ret = PTR_ERR(hdmi->phy);
- return dev_err_probe(dev, ret, "failed to get phy\n");
- }
+ if (IS_ERR(hdmi->phy))
+ return dev_err_probe(dev, PTR_ERR(hdmi->phy),
+ "failed to get phy\n");
index = of_property_match_string(np, "phy-names", "hdmi");
if (index >= 0) {
--
2.54.0
^ permalink raw reply related
* [PATCH 02/10] drm/rockchip: dw_hdmi: Use local dev variable consistently in bind()
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
Replace indirect struct device accesses via hdmi->dev and pdev->dev with
the local dev parameter already available in dw_hdmi_rockchip_bind(),
for consistency and readability.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 34a2248f6b4b..435352f91b88 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -550,16 +550,15 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
if (!drv_data)
return -ENODEV;
- hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+ hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
- plat_data = devm_kmemdup(&pdev->dev, drv_data,
- sizeof(*drv_data), GFP_KERNEL);
+ plat_data = devm_kmemdup(dev, drv_data, sizeof(*drv_data), GFP_KERNEL);
if (!plat_data)
return -ENOMEM;
- hdmi->dev = &pdev->dev;
+ hdmi->dev = dev;
hdmi->plat_data = plat_data;
hdmi->chip_data = plat_data->phy_data;
plat_data->phy_data = hdmi;
@@ -581,13 +580,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
ret = rockchip_hdmi_parse_dt(hdmi);
if (ret) {
- return dev_err_probe(hdmi->dev, ret, "Unable to parse OF data\n");
+ return dev_err_probe(dev, ret, "Unable to parse OF data\n");
}
hdmi->phy = devm_phy_optional_get(dev, "hdmi");
if (IS_ERR(hdmi->phy)) {
ret = PTR_ERR(hdmi->phy);
- return dev_err_probe(hdmi->dev, ret, "failed to get phy\n");
+ return dev_err_probe(dev, ret, "failed to get phy\n");
}
index = of_property_match_string(np, "phy-names", "hdmi");
--
2.54.0
^ permalink raw reply related
* [PATCH 05/10] drm/rockchip: dw_hdmi: Hold a reference to the dw-hdmi bridge
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
Take a reference on the dw-hdmi bridge during bind and drop it again
from unbind to ensure the bridge is kept alive for the lifetime of the
encoder component.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index c5cdf2d1f04b..c7933f3eb64f 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -79,6 +79,7 @@ struct rockchip_hdmi {
struct clk *hdmiphy_clk;
struct clk *ref_clk;
struct clk *grf_clk;
+ struct drm_bridge *bridge;
struct dw_hdmi *hdmi;
struct phy *phy;
};
@@ -609,6 +610,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
return dev_err_probe(dev, PTR_ERR(hdmi->hdmi),
"failed to bind encoder\n");
+ hdmi->bridge = of_drm_find_and_get_bridge(np);
+ if (!hdmi->bridge) {
+ dw_hdmi_remove(hdmi->hdmi);
+ return dev_err_probe(dev, -ENODEV,
+ "failed to find bridge\n");
+ }
+
return 0;
}
@@ -617,6 +625,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
{
struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
+ drm_bridge_put(hdmi->bridge);
dw_hdmi_unbind(hdmi->hdmi);
}
--
2.54.0
^ permalink raw reply related
* [PATCH 01/10] drm/rockchip: dw_hdmi: Use of_device_get_match_data() to get match data
From: Jonas Karlman @ 2026-05-10 18:31 UTC (permalink / raw)
To: Heiko Stübner, Sandy Huang, Andy Yan, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter
Cc: dri-devel, linux-rockchip, linux-arm-kernel, linux-kernel,
Jonas Karlman
In-Reply-To: <20260510183114.1248840-1-jonas@kwiboo.se>
Change to use of_device_get_match_data() to get match data prior to
allocating private data. All current entries in the of_device_id match
table provide match data, so no functional change is intended.
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
---
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 8c0e433fbda2..34a2248f6b4b 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -536,8 +536,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
{
struct platform_device *pdev = to_platform_device(dev);
struct device_node *np = dev_of_node(dev);
+ const struct dw_hdmi_plat_data *drv_data;
struct dw_hdmi_plat_data *plat_data;
- const struct of_device_id *match;
struct drm_device *drm = data;
struct drm_encoder *encoder;
struct rockchip_hdmi *hdmi;
@@ -546,13 +546,16 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
if (!np)
return -ENODEV;
+ drv_data = of_device_get_match_data(dev);
+ if (!drv_data)
+ return -ENODEV;
+
hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
- match = of_match_node(dw_hdmi_rockchip_dt_ids, np);
- plat_data = devm_kmemdup(&pdev->dev, match->data,
- sizeof(*plat_data), GFP_KERNEL);
+ plat_data = devm_kmemdup(&pdev->dev, drv_data,
+ sizeof(*drv_data), GFP_KERNEL);
if (!plat_data)
return -ENOMEM;
--
2.54.0
^ permalink raw reply related
* Re: [PATCH] arm: boot: ep93xx: don't rely on machine_is_*() for removed board files
From: Alexander Sverdlin @ 2026-05-10 17:40 UTC (permalink / raw)
To: Ethan Nelson-Moore, linux-arm-kernel, linux-kernel
Cc: Russell King, Hartley Sweeten, Nikita Shubin
In-Reply-To: <20260509223820.50347-1-enelsonmoore@gmail.com>
Hi Ethan,
On Sat, 2026-05-09 at 15:38 -0700, Ethan Nelson-Moore wrote:
> Code in misc-ep93xx.h relies on machine_is_*() macros for several
> boards that no longer have legacy board files. They were removed in
> commit e5ef574dda70 ("ARM: ep93xx: delete all boardfiles"). This
> prevents the removal of machine IDs no longer used by the kernel from
> mach-types. To resolve this issue, create local copies of these macros.
> (The checks themselves are still valid because the IDs are still passed
> in by the bootloader on these machines.) Also take the opportunity to
> remove three repeated checks for the same ID.
I most probably miss something, but what is the reason for removing
the machine IDs from the mach-types, especially if they are still used
by the kernel (though only in its decompressor code)?
> Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
> ---
> arch/arm/boot/compressed/misc-ep93xx.h | 20 ++++++++++++++++----
> 1 file changed, 16 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/boot/compressed/misc-ep93xx.h b/arch/arm/boot/compressed/misc-ep93xx.h
> index 65b4121d1490..b0a1b42aab31 100644
> --- a/arch/arm/boot/compressed/misc-ep93xx.h
> +++ b/arch/arm/boot/compressed/misc-ep93xx.h
> @@ -3,7 +3,22 @@
> * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
> */
>
> -#include <asm/mach-types.h>
> +/*
> + * These machine IDs are no longer used by the kernel since EP93xx was converted
> + * to DT booting, but they are still passed in by bootloaders, so we use our own
> + * local definitions of the relevant macros.
> + */
> +#define machine_is_bk3() (__machine_arch_type == 1880)
> +#define machine_is_edb9301() (__machine_arch_type == 462)
> +#define machine_is_edb9302a() (__machine_arch_type == 1127)
> +#define machine_is_edb9302() (__machine_arch_type == 538)
> +#define machine_is_edb9307a() (__machine_arch_type == 1128)
> +#define machine_is_edb9307() (__machine_arch_type == 607)
> +#define machine_is_edb9312() (__machine_arch_type == 451)
> +#define machine_is_edb9315a() (__machine_arch_type == 772)
> +#define machine_is_edb9315() (__machine_arch_type == 463)
> +#define machine_is_ts72xx() (__machine_arch_type == 673)
> +#define machine_is_vision_ep9307() (__machine_arch_type == 1578)
>
> static inline unsigned int __raw_readl(unsigned int ptr)
> {
> @@ -60,14 +75,11 @@ static inline void ep93xx_decomp_setup(void)
> if (machine_is_edb9301() ||
> machine_is_edb9302() ||
> machine_is_edb9302a() ||
> - machine_is_edb9302a() ||
> machine_is_edb9307() ||
> machine_is_edb9307a() ||
> - machine_is_edb9307a() ||
> machine_is_edb9312() ||
> machine_is_edb9315() ||
> machine_is_edb9315a() ||
> - machine_is_edb9315a() ||
> machine_is_ts72xx() ||
> machine_is_bk3() ||
> machine_is_vision_ep9307())
--
Alexander Sverdlin.
^ permalink raw reply
* [PATCH v2 4/4] firmware: arm_scmi: optee: Rework transport probe sequence
From: Cristian Marussi @ 2026-05-10 16:05 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
gatien.chevallier, u.kleine-koenig, dakr, Cristian Marussi
In-Reply-To: <20260510160527.3537474-1-cristian.marussi@arm.com>
Use the new per-instance transport handles helpers to synchronize and
optionally defer the core SCMI driver probe up until the transport driver
has completely been initialized and it is fully operational as a supplier.
Introduce proper module init/exit routines while removing the ugly trick of
registering a driver from within the probe sequence of another one, just to
avoid to have to deal with probe deferrals.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 -> v2
- fixed __MUTEX_INITILIAZER() usage
- use common generic supplier definitions
- get rid of init/cleanup wrappers
- use proper barrier on scmi_optee_agent
---
drivers/firmware/arm_scmi/transports/optee.c | 46 +++++++++++++++-----
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/drivers/firmware/arm_scmi/transports/optee.c b/drivers/firmware/arm_scmi/transports/optee.c
index 07ae18d5279d..dbe32e141748 100644
--- a/drivers/firmware/arm_scmi/transports/optee.c
+++ b/drivers/firmware/arm_scmi/transports/optee.c
@@ -154,6 +154,8 @@ static struct scmi_transport_core_operations *core;
/* There can be only 1 SCMI service in OP-TEE we connect to */
static struct scmi_optee_agent *scmi_optee_private;
+static DEFINE_SCMI_TRANSPORT_SUPPLIER(scmi_optee_supplier);
+
/* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */
static int open_session(struct scmi_optee_agent *agent, u32 *tee_session)
{
@@ -522,7 +524,7 @@ static struct scmi_desc scmi_optee_desc = {
};
static const struct of_device_id scmi_of_match[] = {
- { .compatible = "linaro,scmi-optee" },
+ { .compatible = "linaro,scmi-optee", .data = &scmi_optee_supplier.th},
{ /* Sentinel */ },
};
@@ -561,18 +563,20 @@ static int scmi_optee_service_probe(struct tee_client_device *scmi_pta)
if (ret)
goto err;
- /* Ensure agent resources are all visible before scmi_optee_private is */
+ /* Ensure initialized scmi_optee_private is visible */
smp_mb();
scmi_optee_private = agent;
- ret = platform_driver_register(&scmi_optee_driver);
- if (ret) {
- scmi_optee_private = NULL;
- goto err;
- }
+ ret = scmi_transport_supplier_put(&scmi_optee_supplier.th, agent->dev);
+ if (ret)
+ goto err_put;
return 0;
+err_put:
+ /* Ensure cleared reference is visible before resources are released */
+ smp_store_mb(scmi_optee_private, NULL);
+
err:
tee_client_close_context(tee_ctx);
@@ -586,13 +590,12 @@ static void scmi_optee_service_remove(struct tee_client_device *scmi_pta)
if (!scmi_optee_private)
return;
- platform_driver_unregister(&scmi_optee_driver);
-
if (!list_empty(&scmi_optee_private->channel_list))
return;
/* Ensure cleared reference is visible before resources are released */
smp_store_mb(scmi_optee_private, NULL);
+ scmi_transport_supplier_put(&scmi_optee_supplier.th, agent->dev);
tee_client_close_context(agent->tee_ctx);
}
@@ -616,7 +619,30 @@ static struct tee_client_driver scmi_optee_service_driver = {
},
};
-module_tee_client_driver(scmi_optee_service_driver);
+static int __init scmi_transport_optee_init(void)
+{
+ int ret;
+
+ ret = tee_client_driver_register(&scmi_optee_service_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&scmi_optee_driver);
+ if (ret) {
+ tee_client_driver_unregister(&scmi_optee_service_driver);
+ return ret;
+ }
+
+ return ret;
+}
+module_init(scmi_transport_optee_init);
+
+static void __exit scmi_transport_optee_exit(void)
+{
+ platform_driver_unregister(&scmi_optee_driver);
+ tee_client_driver_unregister(&scmi_optee_service_driver);
+}
+module_exit(scmi_transport_optee_exit);
MODULE_AUTHOR("Etienne Carriere <etienne.carriere@foss.st.com>");
MODULE_DESCRIPTION("SCMI OPTEE Transport driver");
--
2.53.0
^ permalink raw reply related
* [PATCH v2 3/4] firmware: arm_scmi: virtio: Rework transport probe sequence
From: Cristian Marussi @ 2026-05-10 16:05 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
gatien.chevallier, u.kleine-koenig, dakr, Cristian Marussi
In-Reply-To: <20260510160527.3537474-1-cristian.marussi@arm.com>
Use the new per-instance transport handles helpers to synchronize and
optionally defer the core SCMI driver probe up until the transport driver
has completely been initialized and it is fully operational as a supplier.
Introduce proper module init/exit routines while removing the ugly trick of
registering a driver from within the probe sequence of another one, just to
avoid to have to deal with probe deferrals.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 -> v2
- fixed __MUTEX_INITILIAZER() usage
- use common generic supplier definitions
- get rid of init/cleanup wrappers
- fixed possible race between supplier made available and scmi_dev
made visible
- restored initial virtio_device_ready() logic, taking care to reset
device on failure too
---
drivers/firmware/arm_scmi/transports/virtio.c | 52 +++++++++++++++----
1 file changed, 43 insertions(+), 9 deletions(-)
diff --git a/drivers/firmware/arm_scmi/transports/virtio.c b/drivers/firmware/arm_scmi/transports/virtio.c
index 326c4a93e44b..3282d8271839 100644
--- a/drivers/firmware/arm_scmi/transports/virtio.c
+++ b/drivers/firmware/arm_scmi/transports/virtio.c
@@ -4,7 +4,7 @@
* (SCMI).
*
* Copyright (C) 2020-2022 OpenSynergy.
- * Copyright (C) 2021-2024 ARM Ltd.
+ * Copyright (C) 2021-2026 ARM Ltd.
*/
/**
@@ -116,6 +116,8 @@ static struct scmi_transport_core_operations *core;
/* Only one SCMI VirtIO device can possibly exist */
static struct virtio_device *scmi_vdev;
+static DEFINE_SCMI_TRANSPORT_SUPPLIER(scmi_virtio_supplier);
+
static void scmi_vio_channel_ready(struct scmi_vio_channel *vioch,
struct scmi_chan_info *cinfo)
{
@@ -394,6 +396,10 @@ static bool virtio_chan_available(struct device_node *of_node, int idx)
return false;
}
+ dev_dbg(&scmi_vdev->dev, "%s Channel %sAVAILABLE on SCMI Virtio device.\n",
+ idx == VIRTIO_SCMI_VQ_TX ? "TX" : "RX",
+ (vioch && !vioch->cinfo) ? "" : "NOT ");
+
return vioch && !vioch->cinfo;
}
@@ -410,7 +416,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
int i;
if (!scmi_vdev)
- return -EPROBE_DEFER;
+ return -EINVAL;
vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
@@ -460,6 +466,9 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
scmi_vio_channel_ready(vioch, cinfo);
+ dev_dbg(&scmi_vdev->dev, "%s Channel SETUP on SCMI Virtio device.\n",
+ tx ? "TX" : "RX");
+
return 0;
}
@@ -801,7 +810,7 @@ static struct scmi_desc scmi_virtio_desc = {
};
static const struct of_device_id scmi_of_match[] = {
- { .compatible = "arm,scmi-virtio" },
+ { .compatible = "arm,scmi-virtio", .data = &scmi_virtio_supplier.th},
{ /* Sentinel */ },
};
@@ -864,33 +873,33 @@ static int scmi_vio_probe(struct virtio_device *vdev)
sz = MSG_TOKEN_MAX;
}
channels[i].max_msg = sz;
+ dev_dbg(dev, "VQ%d initialized with max_msg: %d\n", i, sz);
}
vdev->priv = channels;
-
/* Ensure initialized scmi_vdev is visible */
smp_store_mb(scmi_vdev, vdev);
/* Set device ready */
virtio_device_ready(vdev);
- ret = platform_driver_register(&scmi_virtio_driver);
+ ret = scmi_transport_supplier_put(&scmi_virtio_supplier.th, &vdev->dev);
if (ret) {
+ virtio_reset_device(vdev);
vdev->priv = NULL;
vdev->config->del_vqs(vdev);
/* Ensure NULLified scmi_vdev is visible */
smp_store_mb(scmi_vdev, NULL);
-
return ret;
}
+ dev_dbg(dev, "Probed and initialized SCMI Virtio device.\n");
+
return 0;
}
static void scmi_vio_remove(struct virtio_device *vdev)
{
- platform_driver_unregister(&scmi_virtio_driver);
-
/*
* Once we get here, virtio_chan_free() will have already been called by
* the SCMI core for any existing channel and, as a consequence, all the
@@ -900,8 +909,10 @@ static void scmi_vio_remove(struct virtio_device *vdev)
*/
virtio_reset_device(vdev);
vdev->config->del_vqs(vdev);
+
/* Ensure scmi_vdev is visible as NULL */
smp_store_mb(scmi_vdev, NULL);
+ scmi_transport_supplier_put(&scmi_virtio_supplier.th, &vdev->dev);
}
static int scmi_vio_validate(struct virtio_device *vdev)
@@ -936,7 +947,30 @@ static struct virtio_driver virtio_scmi_driver = {
.validate = scmi_vio_validate,
};
-module_virtio_driver(virtio_scmi_driver);
+static int __init scmi_transport_virtio_init(void)
+{
+ int ret;
+
+ ret = register_virtio_driver(&virtio_scmi_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&scmi_virtio_driver);
+ if (ret) {
+ unregister_virtio_driver(&virtio_scmi_driver);
+ return ret;
+ }
+
+ return ret;
+}
+module_init(scmi_transport_virtio_init);
+
+static void __exit scmi_transport_virtio_exit(void)
+{
+ platform_driver_unregister(&scmi_virtio_driver);
+ unregister_virtio_driver(&virtio_scmi_driver);
+}
+module_exit(scmi_transport_virtio_exit);
MODULE_AUTHOR("Igor Skalkin <igor.skalkin@opensynergy.com>");
MODULE_AUTHOR("Peter Hilber <peter.hilber@opensynergy.com>");
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/4] firmware: arm_scmi: Add transport instance handles
From: Cristian Marussi @ 2026-05-10 16:05 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
gatien.chevallier, u.kleine-koenig, dakr, Cristian Marussi
In-Reply-To: <20260510160527.3537474-1-cristian.marussi@arm.com>
SCMI transport drivers are initialized first and then the control is passed
to the SCMI core stack: some of these transports are dependent also on some
external subsytem which will have to be initialized upfront, before the
transport driver itself can be deemed operational.
Transport drivers like virtio or optee need a way to defer the core SCMI
probing till they are fully initialized and operational and also a way to
pass back the device reference to be used as a supplier while building the
devlink relations.
SCMI transport drivers can be probed multiple times when used in a multiple
instance configuration but the capability to carry-on with multiple probes
depends on the support provided by the underlying transport driver.
This change will also allow for the removal of the frowned-upon trick of
registering a platform driver only after the end of the transport drivers
porbe to avoid explicit probe deferrals.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 -> v2
- saving *th handle into scmi_transport to simplify freeing path
- add a return value to supplier_put
---
drivers/firmware/arm_scmi/common.h | 52 +++++++++++++++++++++++++++---
1 file changed, 48 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 7c9617d080a0..af6f9f498e14 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -17,6 +17,7 @@
#include <linux/hashtable.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/property.h>
#include <linux/refcount.h>
#include <linux/scmi_protocol.h>
#include <linux/spinlock.h>
@@ -462,6 +463,28 @@ struct scmi_transport_core_operations {
const struct scmi_message_operations *msg;
};
+/**
+ * struct scmi_transport_handle - Transport instance handle
+ * @supplier_get: A helper to retrieve the device descriptor, identifying the
+ * transport driver serving this SCMI instance, which will be
+ * used as a supplier for the core SCMI driver: returning an
+ * error here causes the probe sequence to be interrupted and
+ * return that same error code, so that each transport can decide
+ * which policy to implement by choosing an appropriate error.
+ * @supplier_put: A helper to signal that the specified transport supplier is
+ * no more being used and it is made available again.
+ *
+ * Note that these helpers are needed and provided only by those transports
+ * whose initialization relies on some other subsystem and whose relations to
+ * the core SCMI driver is not tracked by firmware descriptions.
+ */
+struct scmi_transport_handle {
+ struct device __must_check *(*supplier_get)
+ (const struct scmi_transport_handle *th);
+ int (*supplier_put)(const struct scmi_transport_handle *th,
+ struct device *dev);
+};
+
/**
* struct scmi_transport - A structure representing a configured transport
*
@@ -470,35 +493,52 @@ struct scmi_transport_core_operations {
* @desc: Transport descriptor
* @core_ops: A pointer to a pointer used by the core SCMI stack to make the
* core transport operations accessible to the transports.
+ * @th: An optional pointer to the transport handle
*/
struct scmi_transport {
struct device *supplier;
struct scmi_desc desc;
struct scmi_transport_core_operations **core_ops;
+ const struct scmi_transport_handle *th;
};
#define DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\
static void __tag##_dev_free(void *data) \
{ \
struct platform_device *spdev = data; \
+ struct scmi_transport *strans; \
+ \
+ strans = dev_get_platdata(&spdev->dev); \
+ if (strans && strans->th) \
+ strans->th->supplier_put(strans->th, strans->supplier); \
\
platform_device_unregister(spdev); \
} \
\
static int __tag##_probe(struct platform_device *pdev) \
{ \
- struct device *dev = &pdev->dev; \
+ struct device *dev = &pdev->dev, *supplier; \
struct platform_device *spdev; \
struct scmi_transport strans; \
int ret; \
\
+ supplier = dev; \
+ strans.th = device_get_match_data(dev); \
+ if (strans.th) { \
+ supplier = strans.th->supplier_get(strans.th); \
+ if (IS_ERR(supplier)) \
+ return PTR_ERR(supplier); \
+ } \
+ \
spdev = platform_device_alloc("arm-scmi", PLATFORM_DEVID_AUTO); \
- if (!spdev) \
- return -ENOMEM; \
+ if (!spdev) { \
+ ret = -ENOMEM; \
+ goto err_mem; \
+ } \
\
device_set_of_node_from_dev(&spdev->dev, dev); \
\
- strans.supplier = dev; \
+ strans.supplier = supplier; \
memcpy(&strans.desc, &(__desc), sizeof(strans.desc)); \
strans.core_ops = &(__core_ops); \
\
@@ -515,6 +555,10 @@ static int __tag##_probe(struct platform_device *pdev) \
\
err: \
platform_device_put(spdev); \
+err_mem: \
+ if (strans.th) \
+ strans.th->supplier_put(strans.th, supplier); \
+ \
return ret; \
} \
\
--
2.53.0
^ permalink raw reply related
* [PATCH v2 2/4] firmware: arm_scmi: Add a generic transport supplier
From: Cristian Marussi @ 2026-05-10 16:05 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
gatien.chevallier, u.kleine-koenig, dakr, Cristian Marussi
In-Reply-To: <20260510160527.3537474-1-cristian.marussi@arm.com>
Add the capability to define a common generic transport supplier which
embeds the logic needed to support one single unique instance of transport
supplier.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
drivers/firmware/arm_scmi/common.h | 111 +++++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index af6f9f498e14..e2885173594a 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -502,6 +502,117 @@ struct scmi_transport {
const struct scmi_transport_handle *th;
};
+/**
+ * struct scmi_transport_supplier - Transport descriptor
+ * @mtx: A mutex to protect @available
+ * @available: A reference to an initialized transport device, when available.
+ * This reference is implicitly used to track the status of the
+ * supplier and it can cycle through the following 3 states:
+ * 1. NOT_READY - PTR_ERR(-EPROBE_DEFER): no supplier available;
+ * this is the transport initial state.
+ * 2. AVAILABLE - <supplier_dev>: a transport supplier has been
+ * initialized and it is available, ready to use.
+ * 3. BUSY _ PTR_ERR(-EBUSY): transport supplier is currently in use.
+ * @th: An embedded transport handle object that embeds the helpers
+ * implementing the above mentioned logic
+ *
+ * Note that this transport driver enforces single instance probing.
+ */
+struct scmi_transport_supplier {
+ /* Protect @available */
+ struct mutex mtx;
+ struct device *available;
+ const struct scmi_transport_handle th;
+};
+
+#define to_sup(t) container_of(t, struct scmi_transport_supplier, th)
+
+/**
+ * scmi_transport_supplier_put - A helper to dispose of a supplier
+ * @th: A reference to the transport handle to use
+ * @supplier: A reference to the device supplier to manage, cannot be NULL
+ * or ERR_PTR.
+ *
+ * Note that putting a supplier will have different effect based on the
+ * current state of scmi_transport_supplier.available:
+ * - NOT_READY/BUSY: @supplier will be set as the new available device: this
+ * can be used to made available a supplier OR stop using one.
+ * - AVAILABLE: if the @supplier we are disposing of matches the currently
+ * available one, roll back to NOT_READY state.
+ * Any other attempt to override an available supplier with a
+ * new one is rejected, effectively enforcing one single supplier.
+ *
+ * Return: 0 on Success, errno otherwise.
+ */
+static inline int
+scmi_transport_supplier_put(const struct scmi_transport_handle *th,
+ struct device *supplier)
+{
+ struct scmi_transport_supplier *sup = to_sup(th);
+
+ /* Nothing to do when the provided supplier was never real */
+ if (IS_ERR_OR_NULL(supplier))
+ return 0;
+
+ guard(mutex)(&sup->mtx);
+ switch (PTR_ERR_OR_ZERO(sup->available)) {
+ case -EPROBE_DEFER:
+ case -EBUSY:
+ sup->available = supplier;
+ break;
+ case 0:
+ /* Putting a supplier when in the AVAILABLE state causes a
+ * transition back to the NOT_READY state, BUT only if the
+ * supplier we are disposing of was exactly the device that was
+ * previously made readily available.
+ */
+ if (supplier != sup->available)
+ return -EINVAL;
+ sup->available = ERR_PTR(-EPROBE_DEFER);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * scmi_transport_supplier_get - A helper to get hold of a supplier
+ * @th: A reference to the transport handle to use
+ *
+ * Note that, trying to get a supplier device can return:
+ * - a ready to use supplier device, (subsequently made unavailable)
+ * - PTR_ERR(-EPROBE_DEFER): no supplier is available
+ * - PTR_ERR(-BUSY): supplier was already taken by a previous get
+ *
+ * This allows the probe to defer and wait when a possible device can
+ * be reasonably expected to appear.
+ *
+ * Return: a usable supplier device on Success or PTR_ERR on Failure.
+ */
+static inline struct device *
+scmi_transport_supplier_get(const struct scmi_transport_handle *th)
+{
+ struct scmi_transport_supplier *sup = to_sup(th);
+ struct device *supplier;
+
+ guard(mutex)(&sup->mtx);
+ supplier = sup->available;
+ if (!IS_ERR(sup->available))
+ sup->available = ERR_PTR(-EBUSY);
+
+ return supplier;
+}
+
+#define DEFINE_SCMI_TRANSPORT_SUPPLIER(__supplier) \
+struct scmi_transport_supplier __supplier = { \
+ .mtx = __MUTEX_INITIALIZER(__supplier.mtx), \
+ .available = INIT_ERR_PTR(-EPROBE_DEFER), \
+ .th.supplier_get = scmi_transport_supplier_get, \
+ .th.supplier_put = scmi_transport_supplier_put, \
+}
+
#define DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\
static void __tag##_dev_free(void *data) \
{ \
--
2.53.0
^ permalink raw reply related
* [PATCH v2 0/4] Rework SCMI transport drivers probing sequence
From: Cristian Marussi @ 2026-05-10 16:05 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi
Cc: sudeep.holla, philip.radford, james.quinlan, f.fainelli,
vincent.guittot, etienne.carriere, peng.fan, michal.simek,
gatien.chevallier, u.kleine-koenig, dakr, Cristian Marussi
Hi,
when the SCMI transports were split out into standalone drivers [1] the
probe sequence was laid out in such a way that:
- the transport drivers would have probed first, triggered by the firmware
driven discovery process (DT/ACPI)
- afterwards the control would have been passed to the core SCMI stack
driver via the creation of a dedicated device that would have inherited
the original firmware descriptor (since that same DT/ACPI node would
have been still needed by the SCMI core driver to be parsed)
The tricky part came around with some transport driver like virtio and
optee since they are, in turn, upfront dependent on an external distinct
kernel subsystem; IOW these have first to undergo their own subsystem
specific probe/initialization to become fully operational as transports:
this kind of initialization sequencing of course must deal with the
possibility of probe deferrals BUT at that time we avoided this by using
the trick in virtio/optee transports to register the next stage drivers
ONLY at the end of the subsystem specific probe routine, from within the
probe itself.
This register_while_probing behaviour is ugly and has 2 main issues:
- it is frowned upon and can lead to hangs in the driver core whenever
some core locking is changed as exposed in [2][3]
- it limits these transport drivers to a single instance probing since of
course you cannot register the same driver more than once
Note also that such dependencies are NOT explicitly represented in any way
within the firmware description tables: i.e. we cannot play the fw_devlink
card and enjoy correct sequencing out of the box.
With this series we remove the ugly register_while_probing trick and
introduce some basic mechanism to allow the probe to be deferred until the
underlying transport has probed and it is fully operational so as that can
be used as a supplier device. This is obtained by:
- moving the problematic platform driver registration away from the probe
into its own module_init/exit
- adding a few common well-known optional helpers that can be invoked
to retrieve the supplier reference, if ready, OR defer the probe when
neeeded.
Instead, we do NOT introduce in this series (as we attempted in the RFC)
a mechanism to support multiple instance probing also for optee and virtio
transports, because there is currently NO possible way to bind such probed
transport driver instances to the related SCMI instances, so that this
would narrow down the applicability of this multiple instance scenario to
the case in which each underlying SCMI server instance is setup in exactly
the same way. (same protocols for each instance node)
Based on v7.1-rc2
Tested on:
- an emulated environment against a mock SCMI Server (virtio)
- a QEMU based setup against SCP-based server running in OPTEE (optee)
- JUNO with the standard SCP reference firmware (mailbox)
- RADXA ROCK_5B with Rockchip fw (smc)
Thanks,
Cristian
[1]: https://lore.kernel.org/arm-scmi/20240812173340.3912830-1-cristian.marussi@arm.com/
[2]: https://lore.kernel.org/lkml/aaA6t-J2gRy3dE1_@pluto/
[3]: https://lore.kernel.org/all/ad9cglZCwtsVsGmq@monoceros/
---
v1 -> v2
- fixed __MUTEX_INITILIAZER() usage
- reworked supplier state machine
- introduce common transport_supplier logic
- get rid of init/cleanup wrappers
- use common generic supplier definitions in virtio/optee
- optee: use proper barrier on scmi_optee_agent
- virtio: fixed possible race between supplier made available
and scmi_dev made visible
- virtio: restored initial virtio_device_ready() logic
- virtio: issue a proper reset device on probe failure
Cristian Marussi (4):
firmware: arm_scmi: Add transport instance handles
firmware: arm_scmi: Add a generic transport supplier
firmware: arm_scmi: virtio: Rework transport probe sequence
firmware: arm_scmi: optee: Rework transport probe sequence
drivers/firmware/arm_scmi/common.h | 163 +++++++++++++++++-
drivers/firmware/arm_scmi/transports/optee.c | 46 +++--
drivers/firmware/arm_scmi/transports/virtio.c | 52 +++++-
3 files changed, 238 insertions(+), 23 deletions(-)
--
2.53.0
^ permalink raw reply
* [PATCH v5 01/10] arm64: dts: lx2160a: extend 32-bit, and add 64-bit pci regions
From: Josua Mayer @ 2026-05-10 15:12 UTC (permalink / raw)
To: Shawn Guo, Li Yang, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Rob Herring, Krzysztof Kozlowski, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Yazan Shhady, Jon Nettleton, linux-arm-kernel, devicetree,
linux-kernel, imx, Josua Mayer
In-Reply-To: <20260510-lx2160-pci-v5-0-540b83852227@solid-run.com>
LX2160 SoC pci-e controller supports 64-bit memory regions up to 16GB,
32-bit regions up to 3GB and 16-bit regions up to 64k.
For each pci-e controller:
- extend the existing 32-bit regions to 3GB size
- drop IORESOURCE_BUSY flag
- add 64-bit region
See [1] and [2] for boot messages showing ranges before and after.
IORESOURCE_BUSY is dropped since it has no effect when specified in dts.
For LX2160A Silicon revision 1, the 16GB 64-bit area is split into 4
pieces, because the layerscape pcie driver fails to program atu for
larger ranges [3].
Similar memory allocation with similar flags was tested with UEFI and ACPI
on pcie3 and pcie5, on a variety of nxp vendor fork versions.
This patch was tested on Linux v7.1-rc1 and u-boot, with two pcie cards:
- pcie5: Radeon Pro WX2100
- pcie3: ADATA NVME
This fixes allocation of large, and 64-bit BARs as requested by many pci
cards - especially graphics processors or AI accelerators, e.g.:
[ 2.941187] pci 0000:01:00.0: BAR 0: no space for [mem size 0x200000000 64bit pref]
[ 2.948834] pci 0000:01:00.0: BAR 0: failed to assign [mem size 0x200000000 64bit pref]
[1] example of new allocations (pcie5):
[ 1.182745] layerscape-pcie 3800000.pcie: host bridge /soc/pcie@3800000 ranges:
[ 1.182760] layerscape-pcie 3800000.pcie: MEM 0xa400000000..0xa7ffffffff -> 0xa400000000
[ 1.182771] layerscape-pcie 3800000.pcie: MEM 0xa040000000..0xa0ffffffff -> 0x0040000000
[ 1.182778] layerscape-pcie 3800000.pcie: IO 0xa000010000..0xa00001ffff -> 0x0000000000
[ 1.183642] layerscape-pcie 3800000.pcie: iATU: unroll F, 256 ob, 24 ib, align 4K, limit 4G
[ 1.385429] layerscape-pcie 3800000.pcie: PCIe Gen.3 x8 link up
[ 1.385481] layerscape-pcie 3800000.pcie: PCI host bridge to bus 0001:00
[ 1.385484] pci_bus 0001:00: root bus resource [bus 00-ff]
[ 1.385488] pci_bus 0001:00: root bus resource [mem 0xa400000000-0xa7ffffffff pref]
[ 1.385491] pci_bus 0001:00: root bus resource [mem 0xa040000000-0xa0ffffffff] (bus address [0x40000000-0xffffffff])
[ 1.385494] pci_bus 0001:00: root bus resource [io 0x10000-0x1ffff] (bus address [0x0000-0xffff])
[ 1.385516] pci 0001:00:00.0: [1957:8d80] type 01 class 0x060400 PCIe Root Port
[ 1.385538] pci 0001:00:00.0: PCI bridge to [bus 01-ff]
[ 1.385544] pci 0001:00:00.0: bridge window [io 0x11000-0x11fff]
[ 1.385548] pci 0001:00:00.0: bridge window [mem 0xa040000000-0xa0502fffff]
[ 1.385605] pci 0001:00:00.0: supports D1 D2
[ 1.385607] pci 0001:00:00.0: PME# supported from D0 D1 D2 D3hot
[ 1.386778] pci 0001:01:00.0: [1002:6995] type 00 class 0x030000 PCIe Legacy Endpoint
[ 1.387336] pci 0001:01:00.0: BAR 0 [mem 0xa040000000-0xa04fffffff 64bit pref]
[ 1.387368] pci 0001:01:00.0: BAR 2 [mem 0xa050000000-0xa0501fffff 64bit pref]
[ 1.387385] pci 0001:01:00.0: BAR 4 [io 0x11000-0x110ff]
[ 1.387402] pci 0001:01:00.0: BAR 5 [mem 0xa050200000-0xa05023ffff]
[ 1.387418] pci 0001:01:00.0: ROM [mem 0xa050240000-0xa05025ffff pref]
[ 1.387493] pci 0001:01:00.0: enabling Extended Tags
[ 1.388960] pci 0001:01:00.0: supports D1 D2
[2] example of previous allocations (pcie5):
[ 1.716744] layerscape-pcie 3800000.pcie: host bridge /soc/pcie@3800000 ranges:
[ 1.724060] layerscape-pcie 3800000.pcie: MEM 0xa040000000..0xa07fffffff -> 0x0040000000
[ 1.733277] layerscape-pcie 3800000.pcie: iATU: unroll F, 256 ob, 24 ib, align 4K, limit 4G
[ 1.836220] layerscape-pcie 3800000.pcie: PCIe Gen.3 x8 link up
[ 1.842186] layerscape-pcie 3800000.pcie: PCI host bridge to bus 0001:00
[ 1.848883] pci_bus 0001:00: root bus resource [bus 00-ff]
[ 1.854363] pci_bus 0001:00: root bus resource [mem 0xa040000000-0xa07fffffff] (bus address [0x40000000-0x7fffffff])
[ 1.864892] pci 0001:00:00.0: [1957:8d80] type 01 class 0x060400 PCIe Root Port
[ 1.872216] pci 0001:00:00.0: PCI bridge to [bus 01-ff]
[ 1.877438] pci 0001:00:00.0: bridge window [io 0x1000-0x1fff]
[ 1.883526] pci 0001:00:00.0: bridge window [mem 0xa040000000-0xa0502fffff]
[3] error programming atu beyond 4GB:
[ 1.716762] layerscape-pcie 3800000.pcie: host bridge /soc/pcie@3800000 ranges:
[ 1.724080] layerscape-pcie 3800000.pcie: MEM 0xa400000000..0xa7ffffffff -> 0xa400000000
[ 1.732615] layerscape-pcie 3800000.pcie: MEM 0xa040000000..0xa0ffffffff -> 0x0040000000
[ 1.741142] layerscape-pcie 3800000.pcie: IO 0xa010000000..0xa01000ffff -> 0x0000000000
[ 1.750379] layerscape-pcie 3800000.pcie: iATU: unroll F, 256 ob, 24 ib, align 4K, limit 4G
[ 1.759089] layerscape-pcie 3800000.pcie: Failed to set MEM range [mem 0xa400000000-0xa7ffffffff flags 0x2200]
[ 1.769089] layerscape-pcie 3800000.pcie: probe with driver layerscape-pcie failed with error -22
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
.../arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi | 30 +++++++++++-------
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi | 37 ++++++++++++++++++----
2 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi
index f54005e37924b..318210ad5bec1 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-rev2.dtsi
@@ -14,8 +14,9 @@ &pcie1 {
0x80 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- ranges = <0x81000000 0x0 0x00000000 0x80 0x00010000 0x0 0x00010000
- 0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>;
+ ranges = <0x42000000 0x84 0x00000000 0x84 0x00000000 0x04 0x00000000>, /* 64-Bit - prefetchable - 16GB */
+ <0x02000000 0x00 0x40000000 0x80 0x40000000 0x00 0xc0000000>, /* 32-Bit - non-prefetchable */
+ <0x01000000 0x00 0x00000000 0x80 0x00010000 0x00 0x00010000>; /* 16-Bit IO Window */
interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
@@ -30,8 +31,9 @@ &pcie2 {
0x88 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- ranges = <0x81000000 0x0 0x00000000 0x88 0x00010000 0x0 0x00010000
- 0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>;
+ ranges = <0x42000000 0x8c 0x00000000 0x8c 0x00000000 0x04 0x00000000>, /* 64-Bit - prefetchable - 16GB */
+ <0x02000000 0x00 0x40000000 0x88 0x40000000 0x00 0xc0000000>, /* 32-Bit - non-prefetchable */
+ <0x01000000 0x00 0x00000000 0x88 0x00010000 0x00 0x00010000>; /* 16-Bit IO Window */
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
@@ -46,8 +48,9 @@ &pcie3 {
0x90 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- ranges = <0x81000000 0x0 0x00000000 0x90 0x00010000 0x0 0x00010000
- 0x82000000 0x0 0x40000000 0x90 0x40000000 0x0 0x40000000>;
+ ranges = <0x42000000 0x94 0x00000000 0x94 0x00000000 0x04 0x00000000>, /* 64-Bit - prefetchable - 16GB */
+ <0x02000000 0x00 0x40000000 0x90 0x40000000 0x00 0xc0000000>, /* 32-Bit - non-prefetchable */
+ <0x01000000 0x00 0x00000000 0x90 0x00010000 0x00 0x00010000>; /* 16-Bit IO Window */
interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
@@ -63,8 +66,9 @@ &pcie4 {
0x98 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- ranges = <0x81000000 0x0 0x00000000 0x98 0x00010000 0x0 0x00010000
- 0x82000000 0x0 0x40000000 0x98 0x40000000 0x0 0x40000000>;
+ ranges = <0x42000000 0x9c 0x00000000 0x9c 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 16GB */
+ <0x02000000 0x00 0x40000000 0x98 0x40000000 0x00 0xc0000000>, /* 32-Bit - non-prefetchable */
+ <0x01000000 0x00 0x00000000 0x98 0x00010000 0x00 0x00010000>; /* 16-Bit IO Window */
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
@@ -79,8 +83,9 @@ &pcie5 {
0xa0 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- ranges = <0x81000000 0x0 0x00000000 0xa0 0x00010000 0x0 0x00010000
- 0x82000000 0x0 0x40000000 0xa0 0x40000000 0x0 0x40000000>;
+ ranges = <0x42000000 0xa4 0x00000000 0xa4 0x00000000 0x04 0x00000000>, /* 64-Bit - prefetchable - 16GB */
+ <0x02000000 0x00 0x40000000 0xa0 0x40000000 0x00 0xc0000000>, /* 32-Bit - non-prefetchable */
+ <0x01000000 0x00 0x00000000 0xa0 0x00010000 0x00 0x00010000>; /* 16-Bit IO Window */
interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
@@ -95,8 +100,9 @@ &pcie6 {
0xa8 0x00000000 0x0 0x00002000>; /* configuration space */
reg-names = "regs", "config";
- ranges = <0x81000000 0x0 0x00000000 0xa8 0x00010000 0x0 0x00010000
- 0x82000000 0x0 0x40000000 0xa8 0x40000000 0x0 0x40000000>;
+ ranges = <0x42000000 0xac 0x00000000 0xac 0x00000000 0x04 0x00000000>, /* 64-Bit - prefetchable - 16GB */
+ <0x02000000 0x00 0x40000000 0xa8 0x40000000 0x00 0xc0000000>, /* 32-Bit - non-prefetchable */
+ <0x01000000 0x00 0x00000000 0xa8 0x00010000 0x00 0x00010000>; /* 16-Bit IO Window */
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "intr";
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
index 479982948ee53..3f63fbf2485e5 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
@@ -1193,7 +1193,12 @@ pcie1: pcie@3400000 {
apio-wins = <8>;
ppio-wins = <8>;
bus-range = <0x0 0xff>;
- ranges = <0x82000000 0x0 0x40000000 0x80 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ ranges = <0x42000000 0x87 0x00000000 0x87 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x86 0x00000000 0x86 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x85 0x00000000 0x85 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x84 0x00000000 0x84 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x02000000 0x00 0x40000000 0x80 0x40000000 0x00 0xc0000000>; /* 32-Bit - non-prefetchable */
+
msi-parent = <&its 0>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
@@ -1221,7 +1226,11 @@ pcie2: pcie@3500000 {
apio-wins = <8>;
ppio-wins = <8>;
bus-range = <0x0 0xff>;
- ranges = <0x82000000 0x0 0x40000000 0x88 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ ranges = <0x42000000 0x8f 0x00000000 0x8f 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x8e 0x00000000 0x8e 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x8d 0x00000000 0x8d 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x8c 0x00000000 0x8c 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x02000000 0x00 0x40000000 0x88 0x40000000 0x00 0xc0000000>; /* 32-Bit - non-prefetchable */
msi-parent = <&its 0>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
@@ -1249,7 +1258,11 @@ pcie3: pcie@3600000 {
apio-wins = <256>;
ppio-wins = <24>;
bus-range = <0x0 0xff>;
- ranges = <0x82000000 0x0 0x40000000 0x90 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ ranges = <0x42000000 0x97 0x00000000 0x97 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x96 0x00000000 0x96 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x95 0x00000000 0x95 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x94 0x00000000 0x94 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x02000000 0x00 0x40000000 0x90 0x40000000 0x00 0xc0000000>; /* 32-Bit - non-prefetchable */
msi-parent = <&its 0>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
@@ -1277,7 +1290,11 @@ pcie4: pcie@3700000 {
apio-wins = <8>;
ppio-wins = <8>;
bus-range = <0x0 0xff>;
- ranges = <0x82000000 0x0 0x40000000 0x98 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ ranges = <0x42000000 0x9f 0x00000000 0x9f 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x9e 0x00000000 0x9e 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x9d 0x00000000 0x9d 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0x9c 0x00000000 0x9c 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x02000000 0x00 0x40000000 0x98 0x40000000 0x00 0xc0000000>; /* 32-Bit - non-prefetchable */
msi-parent = <&its 0>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
@@ -1305,7 +1322,11 @@ pcie5: pcie@3800000 {
apio-wins = <256>;
ppio-wins = <24>;
bus-range = <0x0 0xff>;
- ranges = <0x82000000 0x0 0x40000000 0xa0 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ ranges = <0x42000000 0xa7 0x00000000 0xa7 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0xa6 0x00000000 0xa6 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0xa5 0x00000000 0xa5 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0xa4 0x00000000 0xa4 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x02000000 0x00 0x40000000 0xa0 0x40000000 0x00 0xc0000000>; /* 32-Bit - non-prefetchable */
msi-parent = <&its 0>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
@@ -1333,7 +1354,11 @@ pcie6: pcie@3900000 {
apio-wins = <8>;
ppio-wins = <8>;
bus-range = <0x0 0xff>;
- ranges = <0x82000000 0x0 0x40000000 0xa8 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
+ ranges = <0x42000000 0xaf 0x00000000 0xaf 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0xae 0x00000000 0xae 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0xad 0x00000000 0xad 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x42000000 0xac 0x00000000 0xac 0x00000000 0x01 0x00000000>, /* 64-Bit - prefetchable - 4GB chunk */
+ <0x02000000 0x00 0x40000000 0xa8 0x40000000 0x00 0xc0000000>; /* 32-Bit - non-prefetchable */
msi-parent = <&its 0>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 7>;
--
2.51.0
^ permalink raw reply related
* Re: [PATCH v3 2/5] dt-bindings: watchdog: apple,wdt: Add t8122 compatible
From: Guenter Roeck @ 2026-05-10 15:29 UTC (permalink / raw)
To: Janne Grunau
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Lorenzo Pieralisi,
Sven Peter, Neal Gompa, Wim Van Sebroeck, Mark Kettenis,
Sasha Finkelstein, Uwe Kleine-König, devicetree,
linux-kernel, asahi, linux-arm-kernel, linux-watchdog, linux-pwm,
Joshua Peisach
In-Reply-To: <20260507-apple-m3-initial-devicetrees-v3-2-ca07c81b5dc7@jannau.net>
On Thu, May 07, 2026 at 09:33:08AM +0200, Janne Grunau wrote:
> The watchdog on the Apple silicon t8122 (M3) SoC is compatible with the
> existing driver. Add "apple,t8122-wdt" as SoC specific compatible under
> "apple,t8103-wdt" used by the driver.
'"apple,t8103-wdt" used by the driver' is not true. The watchdog driver
only supports "apple,wdt".
>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
> Reviewed-by: Joshua Peisach <jpeisach@ubuntu.com>
> Reviewed-by: Neal Gompa <neal@gompa.dev>
> Signed-off-by: Janne Grunau <j@jannau.net>
> ---
> Documentation/devicetree/bindings/watchdog/apple,wdt.yaml | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml b/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
> index 05602678c070..845b5e8b5abc 100644
> --- a/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
> +++ b/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
> @@ -16,7 +16,9 @@ properties:
> compatible:
> oneOf:
> - items:
> - - const: apple,t6020-wdt
> + - enum:
> + - apple,t6020-wdt
> + - apple,t8122-wdt
> - const: apple,t8103-wdt
> - items:
> - enum:
I second Sashiko's findings that the driver will fail to bind because it
only supports "apple,wdt". I would not mind and apply the patch anyway,
but the statement in the description is just plain wrong and thus
misleading. Please fix.
Thanks,
Guenter
^ permalink raw reply
* Re: [PATCH v5 10/10] arm64: dts: Add support for LX2160 Twins board in single configuration
From: Josua Mayer @ 2026-05-10 15:23 UTC (permalink / raw)
To: Shawn Guo, Li Yang, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Rob Herring, Krzysztof Kozlowski, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Yazan Shhady, Jon Nettleton, linux-arm-kernel@lists.infradead.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev
In-Reply-To: <20260510-lx2160-pci-v5-10-540b83852227@solid-run.com>
Am 10.05.26 um 17:12 schrieb Josua Mayer:
> Add support for the SolidRun LX2160A Twins board in its single cpu
> configuration.
>
> The twins board is designed to host a pair of LX2160A CEX-7 modules,
> sharing a single PCI-E connector in multi-host mode.
>
> It may be assembled in two configurations (different assembly options
> facilitating signal re-routing), with a single or with dual CEX-7
> module. Their marketing names are:
>
> - SolidWAN Single LX2160
> - SolidWAN Dual LX2160
>
> This patch adds the single configuration, featuring:
> - 8x SFP (1Gbps)
> - 8x SFP+ (1/10Gbps)
> - PCI-E OCP card connector
> - USB-3.0 front-panel header with single port
> - microSD
> - dual hot-swappable power supplies
>
> Signed-off-by: Josua Mayer <josua@solid-run.com>
> ---
> arch/arm64/boot/dts/freescale/Makefile | 2 +
> .../boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts | 2 +-
> .../boot/dts/freescale/fsl-lx2160a-half-twins.dts | 822 +++++++++++++++++++++
> 3 files changed, 825 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 711e36cc2c990..59eee431562ef 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -51,6 +51,8 @@ DTC_FLAGS_fsl-lx2160a-bluebox3-rev-a := -Wno-interrupt_map
> dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-bluebox3-rev-a.dtb
> DTC_FLAGS_fsl-lx2160a-clearfog-cx := -Wno-interrupt_map
> dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-clearfog-cx.dtb
> +DTC_FLAGS_fsl-lx2160a-half-twins := -Wno-interrupt_map
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-half-twins.dtb
> DTC_FLAGS_fsl-lx2160a-honeycomb := -Wno-interrupt_map
> dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-honeycomb.dtb
> DTC_FLAGS_fsl-lx2160a-qds := -Wno-interrupt_map
> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts
> index 802d7611c6479..6078ce47fabf1 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts
> @@ -6,7 +6,7 @@
>
> /dts-v1/;
>
> -#include "fsl-lx2160a.dtsi"
> +#include "fsl-lx2160a-rev2.dtsi"
> #include "fsl-lx2160a-cex7.dtsi"
> #include "fsl-lx2160a-clearfog-itx.dtsi"
This was accidental leftover from testing pci patch, and will be removed in next version.
The clearfog-cx may have either silicon revision 1 or 2.
> diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-half-twins.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-half-twins.dts
> new file mode 100644
> index 0000000000000..434b3f4873008
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-half-twins.dts
> @@ -0,0 +1,822 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +//
> +// Device Tree file for single LX2160A CEX-7 on Twins board.
> +//
> +// Copyright 2022 SolidRun Ltd.
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/leds/common.h>
> +
> +#include "fsl-lx2160a-rev2.dtsi"
> +#include "fsl-lx2160a-cex7.dtsi"
> +
> +/ {
> + compatible = "solidrun,twins-single", "solidrun,lx2160a-cex7", "fsl,lx2160a";
> + model = "SolidRun LX2160A SolidWAN Single";
> +
> + aliases {
> + gpio0 = &gpio0;
> + gpio1 = &gpio1;
> + gpio2 = &gpio2;
> + gpio3 = &gpio3;
> + gpio4 = &expander0;
> + gpio5 = &expander1;
> + gpio6 = &expander2;
> + gpio7 = &expander3;
> + i2c0 = &i2c0;
> + i2c1 = &i2c2;
> + i2c2 = &i2c4;
> + i2c3 = &fan_i2c;
> + i2c4 = &power_i2c;
> + i2c5 = &i2c_smb;
> + i2c6 = &sfp0_i2c;
> + i2c7 = &sfp1_i2c;
> + i2c8 = &sfp2_i2c;
> + i2c9 = &sfp3_i2c;
> + i2c10 = &twins_sfp_c1_at_i2c;
> + i2c11 = &twins_sfp_c1_ab_i2c;
> + i2c12 = &twins_sfp_c1_bt_i2c;
> + i2c13 = &twins_sfp_c1_bb_i2c;
> + i2c14 = &twins_sfp_c2_at_i2c;
> + i2c15 = &twins_sfp_c2_ab_i2c;
> + i2c16 = &twins_sfp_c2_bt_i2c;
> + i2c17 = &twins_sfp_c2_bb_i2c;
> + i2c18 = &twins_sfp_c3_at_i2c;
> + i2c19 = &twins_sfp_c3_ab_i2c;
> + i2c20 = &twins_sfp_c3_bt_i2c;
> + i2c21 = &twins_sfp_c3_bb_i2c;
> + i2c22 = &htwins_sfp_c3_at_i2c;
> + i2c23 = &htwins_sfp_c3_ab_i2c;
> + i2c24 = &htwins_sfp_c3_bt_i2c;
> + i2c25 = &htwins_sfp_c3_bb_i2c;
> + i2c26 = &ddr_i2c;
> + mmc0 = &esdhc0;
> + mmc1 = &esdhc1;
> + serial0 = &uart0;
> + serial1 = &uart1;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +
> + leds {
> + compatible = "gpio-leds";
> +
> + led_ht_c3_bt: led-sfp-1 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <1>;
> + gpios = <&expander3 14 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac5>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_ht_c3_bb: led-sfp-2 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <2>;
> + gpios = <&expander3 13 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac15>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_ht_c3_at: led-sfp-3 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <2>;
> + gpios = <&expander3 11 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac6>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_ht_c3_ab: led-sfp-4 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <4>;
> + gpios = <&expander3 12 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac11>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c1_bt: led-sfp-9 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <9>;
> + gpios = <&expander1 4 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac4>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c1_bb: led-sfp-10 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <10>;
> + gpios = <&expander1 3 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac17>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c1_at: led-sfp-11 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <11>;
> + gpios = <&expander1 1 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac3>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c1_ab: led-sfp-12 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <12>;
> + gpios = <&expander1 2 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac12>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c2_bt: led-sfp-13 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <13>;
> + gpios = <&expander1 10 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac8>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c2_bb: led-sfp-14 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <14>;
> + gpios = <&expander1 9 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac16>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c2_at: led-sfp-15 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <15>;
> + gpios = <&expander1 5 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac7>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c2_ab: led-sfp-16 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <16>;
> + gpios = <&expander1 6 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac18>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c3_bt: led-sfp-17 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <17>;
> + gpios = <&expander1 14 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac10>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c3_bb: led-sfp-18 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <18>;
> + gpios = <&expander1 13 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac14>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c3_at: led-sfp-19 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <19>;
> + gpios = <&expander1 11 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac9>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led_c3_ab: led-sfp-20 {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_LAN;
> + function-enumerator = <20>;
> + gpios = <&expander1 12 GPIO_ACTIVE_LOW>;
> + trigger-sources = <&dpmac13>;
> + linux,default-trigger = "netdev";
> + };
> +
> + led-status {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_STATUS;
> + function-enumerator = <0>;
> + gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
> + linux,default-trigger = "heartbeat";
> + };
> +
> + led-status-twin {
> + color = <LED_COLOR_ID_GREEN>;
> + default-state = "off";
> + function = LED_FUNCTION_STATUS;
> + function-enumerator = <1>;
> + gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
> + };
> +
> + led-fault {
> + color = <LED_COLOR_ID_YELLOW>;
> + default-state = "off";
> + function = LED_FUNCTION_FAULT;
> + function-enumerator = <0>;
> + gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
> + panic-indicator;
> + };
> +
> + led-fault-twin {
> + color = <LED_COLOR_ID_YELLOW>;
> + default-state = "off";
> + function = LED_FUNCTION_FAULT;
> + function-enumerator = <1>;
> + gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
> + };
> + };
> +
> + mux-controller {
> + compatible = "gpio-mux";
> + #mux-control-cells = <0>;
> + /*
> + * This gpio controlled mux can route the tacho signals of 6 PWM FAN connectors
> + * to the tacho inputs of both CEX-7 modules (twins).
> + *
> + * The first twin controls this mux and monitors four fan connectors, two intended
> + * for itself, and two for the OCP card.
> + *
> + * The second twin monitors only two fan connectors intended for itself.
> + *
> + * The table below maps selector GPIO states to monitored fan connector per twin:
> + *
> + * | SEL1 | SEL0 | Twin 1 | Twin 2 |
> + * | ---: | ---: | :------| ------ |
> + * | 0 | 0 | J10 | J5024 |
> + * | 0 | 1 | J5016 | J5024 |
> + * | 1 | 0 | J5026 | J5025 |
> + * | 1 | 1 | J5013 | J5025 |
> + */
> + mux-gpios = <&expander0 8 GPIO_ACTIVE_HIGH>, /* SEL0 */
> + <&expander0 15 GPIO_ACTIVE_HIGH>; /* SEL1 */
> + };
> +
> + ht_c3_bt_sfp: sfp-1 {
> + compatible = "sff,sfp";
> + i2c-bus = <&htwins_sfp_c3_bt_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander2 13 GPIO_ACTIVE_LOW>;
> + };
> +
> + ht_c3_bb_sfp: sfp-2 {
> + compatible = "sff,sfp";
> + i2c-bus = <&htwins_sfp_c3_bb_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander2 14 GPIO_ACTIVE_LOW>;
> + };
> +
> + ht_c3_at_sfp: sfp-3 {
> + compatible = "sff,sfp";
> + i2c-bus = <&htwins_sfp_c3_at_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander2 11 GPIO_ACTIVE_LOW>;
> + };
> +
> + ht_c3_ab_sfp: sfp-4 {
> + compatible = "sff,sfp";
> + i2c-bus = <&htwins_sfp_c3_ab_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander2 12 GPIO_ACTIVE_LOW>;
> + };
> +
> + c1_bt_sfp: sfp-9 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c1_bt_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 3 GPIO_ACTIVE_LOW>;
> + };
> +
> + c1_bb_sfp: sfp-10 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c1_bb_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 4 GPIO_ACTIVE_LOW>;
> + };
> +
> + c1_at_sfp: sfp-11 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c1_at_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 1 GPIO_ACTIVE_LOW>;
> + };
> +
> + c1_ab_sfp: sfp-12 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c1_ab_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 2 GPIO_ACTIVE_LOW>;
> + };
> +
> + c2_bt_sfp: sfp-13 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c2_bt_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 9 GPIO_ACTIVE_LOW>;
> + };
> +
> + c2_bb_sfp: sfp-14 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c2_bb_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 10 GPIO_ACTIVE_LOW>;
> + };
> +
> + c2_at_sfp: sfp-15 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c2_at_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 5 GPIO_ACTIVE_LOW>;
> + };
> +
> + c2_ab_sfp: sfp-16 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c2_ab_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 6 GPIO_ACTIVE_LOW>;
> + };
> +
> + c3_bt_sfp: sfp-17 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c3_bt_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 13 GPIO_ACTIVE_LOW>;
> + };
> +
> + c3_bb_sfp: sfp-18 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c3_bb_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 14 GPIO_ACTIVE_LOW>;
> + };
> +
> + c3_at_sfp: sfp-19 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c3_at_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 11 GPIO_ACTIVE_LOW>;
> + };
> +
> + c3_ab_sfp: sfp-20 {
> + compatible = "sff,sfp";
> + i2c-bus = <&twins_sfp_c3_ab_i2c>;
> + maximum-power-milliwatt = <2000>;
> + mod-def0-gpios = <&expander0 12 GPIO_ACTIVE_LOW>;
> + };
> +};
> +
> +/*
> + * This board supports industrial grade temperatures,
> + * the LX2160A SoC maximum junction temperature is 105°C.
> + *
> + * Raise thermal thresholds to allow operation near maximum temperature.
> + */
> +&ccn_dpaa_alert {
> + temperature = <100000>;
> +};
> +
> +&ccn_dpaa_crit {
> + temperature = <105000>;
> +};
> +
> +&cluster2_3_alert {
> + temperature = <100000>;
> +};
> +
> +&cluster2_3_crit {
> + temperature = <105000>;
> +};
> +
> +&cluster4_alert {
> + temperature = <100000>;
> +};
> +
> +&cluster4_crit {
> + temperature = <105000>;
> +};
> +
> +&cluster5_alert {
> + temperature = <100000>;
> +};
> +
> +&cluster5_crit {
> + temperature = <105000>;
> +};
> +
> +&cluster6_7_alert {
> + temperature = <100000>;
> +};
> +
> +&cluster6_7_crit {
> + temperature = <105000>;
> +};
> +
> +&dce_qbman_alert {
> + temperature = <100000>;
> +};
> +
> +&dce_qbman_crit {
> + temperature = <105000>;
> +};
> +
> +/* sfp port 11 */
> +&dpmac3 {
> + managed = "in-band-status";
> + phys = <&serdes_1 7>;
> + sfp = <&c1_at_sfp>;
> +};
> +
> +/* sfp port 9 */
> +&dpmac4 {
> + managed = "in-band-status";
> + phys = <&serdes_1 6>;
> + sfp = <&c1_bt_sfp>;
> +};
> +
> +/* sfp port 1 */
> +&dpmac5 {
> + managed = "in-band-status";
> + phys = <&serdes_1 5>;
> + sfp = <&ht_c3_bt_sfp>;
> +};
> +
> +/* sfp port 3 */
> +&dpmac6 {
> + managed = "in-band-status";
> + phys = <&serdes_1 4>;
> + sfp = <&ht_c3_at_sfp>;
> +};
> +
> +/* sfp port 15 */
> +&dpmac7 {
> + managed = "in-band-status";
> + phys = <&serdes_1 3>;
> + sfp = <&c2_at_sfp>;
> +};
> +
> +/* sfp port 13 */
> +&dpmac8 {
> + managed = "in-band-status";
> + phys = <&serdes_1 2>;
> + sfp = <&c2_bt_sfp>;
> +};
> +
> +/* sfp port 19 */
> +&dpmac9 {
> + managed = "in-band-status";
> + phys = <&serdes_1 1>;
> + sfp = <&c3_at_sfp>;
> +};
> +
> +/* sfp port 17 */
> +&dpmac10 {
> + managed = "in-band-status";
> + phys = <&serdes_1 0>;
> + sfp = <&c3_bt_sfp>;
> +};
> +
> +/* sfp port 4 */
> +&dpmac11 {
> + managed = "in-band-status";
> + phys = <&serdes_2 0>;
> + sfp = <&ht_c3_ab_sfp>;
> +};
> +
> +/* sfp port 12 */
> +&dpmac12 {
> + managed = "in-band-status";
> + phys = <&serdes_2 1>;
> + sfp = <&c1_ab_sfp>;
> +};
> +
> +/* sfp port 20 */
> +&dpmac13 {
> + managed = "in-band-status";
> + phys = <&serdes_2 6>;
> + sfp = <&c3_ab_sfp>;
> +};
> +
> +/* sfp port 18 */
> +&dpmac14 {
> + managed = "in-band-status";
> + phys = <&serdes_2 7>;
> + sfp = <&c3_bb_sfp>;
> +};
> +
> +/* sfp port 2 */
> +&dpmac15 {
> + managed = "in-band-status";
> + phys = <&serdes_2 4>;
> + sfp = <&ht_c3_bb_sfp>;
> +};
> +
> +/* sfp port 14 */
> +&dpmac16 {
> + managed = "in-band-status";
> + phys = <&serdes_2 5>;
> + sfp = <&c2_bb_sfp>;
> +};
> +
> +/* sfp port 10 */
> +&dpmac17 {
> + /* override connection to on-COM phy */
> + /delete-property/ phy-handle;
> + /delete-property/ phy-connection-type;
> + managed = "in-band-status";
> + phys = <&serdes_2 2>;
> + sfp = <&c1_bb_sfp>;
> +};
> +
> +/* sfp port 16 */
> +&dpmac18 {
> + managed = "in-band-status";
> + phys = <&serdes_2 3>;
> + sfp = <&c2_ab_sfp>;
> +};
> +
> +&esdhc0 {
> + pinctrl-0 = <&esdhc0_cd_wp_pins>, <&esdhc0_cmd_data30_clk_vsel_pins>;
> + pinctrl-names = "default";
> + /*
> + * Disable 1.8V modes so that microsd state is same between
> + * power-on-reset, u-boot and linux.
> + * This avoids sporadic read errors after hard reset with some cards.
> + */
> + no-1-8-v;
> + status = "okay";
> +};
> +
> +&i2c2 {
> + expander0: gpio@20 {
> + compatible = "nxp,pca9555";
> + reg = <0x20>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + };
> +
> + expander1: gpio@21 {
> + compatible = "nxp,pca9555";
> + reg = <0x21>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + };
> +
> + expander2: gpio@24 {
> + compatible = "nxp,pca9555";
> + reg = <0x24>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + };
> +
> + expander3: gpio@25 {
> + compatible = "nxp,pca9555";
> + reg = <0x25>;
> + #gpio-cells = <2>;
> + gpio-controller;
> + };
> +
> + /* Half twins configuration; take over c3 from the other twin side */
> + i2c-mux@73 {
> + compatible = "nxp,pca9547";
> + reg = <0x73>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + i2c-mux-idle-disconnect;
> +
> + htwins_sfp_c3_at_i2c: i2c@3 {
> + reg = <3>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + htwins_sfp_c3_ab_i2c: i2c@4 {
> + reg = <4>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + htwins_sfp_c3_bt_i2c: i2c@5 {
> + reg = <5>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + htwins_sfp_c3_bb_i2c: i2c@6 {
> + reg = <6>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> + };
> +
> + i2c-mux@76 {
> + compatible = "nxp,pca9547";
> + reg = <0x76>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + i2c-mux-idle-disconnect;
> +
> + twins_sfp_c1_at_i2c: i2c@1 {
> + reg = <1>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c1_ab_i2c: i2c@2 {
> + reg = <2>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c1_bt_i2c: i2c@3 {
> + reg = <3>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c1_bb_i2c: i2c@4 {
> + reg = <4>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c2_at_i2c: i2c@5 {
> + reg = <5>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c2_ab_i2c: i2c@6 {
> + reg = <6>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> + };
> +
> + i2c-mux@77 {
> + compatible = "nxp,pca9547";
> + reg = <0x77>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + i2c-mux-idle-disconnect;
> +
> + twins_sfp_c2_bt_i2c: i2c@1 {
> + reg = <1>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c2_bb_i2c: i2c@2 {
> + reg = <2>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c3_at_i2c: i2c@3 {
> + reg = <3>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c3_ab_i2c: i2c@4 {
> + reg = <4>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c3_bt_i2c: i2c@5 {
> + reg = <5>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> +
> + twins_sfp_c3_bb_i2c: i2c@6 {
> + reg = <6>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + };
> + };
> +};
> +
> +&pcs_mdio3 {
> + status = "okay";
> +};
> +
> +&pcs_mdio4 {
> + status = "okay";
> +};
> +
> +&pcs_mdio5 {
> + status = "okay";
> +};
> +
> +&pcs_mdio6 {
> + status = "okay";
> +};
> +
> +&pcs_mdio7 {
> + status = "okay";
> +};
> +
> +&pcs_mdio8 {
> + status = "okay";
> +};
> +
> +&pcs_mdio9 {
> + status = "okay";
> +};
> +
> +&pcs_mdio10 {
> + status = "okay";
> +};
> +
> +&pcs_mdio11 {
> + status = "okay";
> +};
> +
> +&pcs_mdio12 {
> + status = "okay";
> +};
> +
> +&pcs_mdio13 {
> + status = "okay";
> +};
> +
> +&pcs_mdio14 {
> + status = "okay";
> +};
> +
> +&pcs_mdio15 {
> + status = "okay";
> +};
> +
> +&pcs_mdio16 {
> + status = "okay";
> +};
> +
> +&pcs_mdio17 {
> + status = "okay";
> +};
> +
> +&pcs_mdio18 {
> + status = "okay";
> +};
> +
> +&rgmii_phy1 {
> + /*
> + * COM has a phy at address 1 connected to SoC Ethernet Controller 1.
> + * It competes for WRIOP MAC17, and no connector has been wired.
> + */
> + status = "disabled";
> +};
> +
> +&serdes_2 {
> + status = "okay";
> +};
> +
> +&uart0 {
> + status = "okay";
> +};
> +
> +&uart1 {
> + status = "okay";
> +};
> +
> +&wriop_alert {
> + temperature = <100000>;
> +};
> +
> +&wriop_crit {
> + temperature = <105000>;
> +};
>
^ permalink raw reply
* [PATCH v5 03/10] arm64: dts: lx2162a-clearfog: cleanup superfluous status properties
From: Josua Mayer @ 2026-05-10 15:12 UTC (permalink / raw)
To: Shawn Guo, Li Yang, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Rob Herring, Krzysztof Kozlowski, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Yazan Shhady, Jon Nettleton, linux-arm-kernel, devicetree,
linux-kernel, imx, Josua Mayer
In-Reply-To: <20260510-lx2160-pci-v5-0-540b83852227@solid-run.com>
The SoC dtsi has always enabled serdes block 1, enabled dpmac and
disabled pcie nodes.
Drop the superfluous status properties on these nodes.
Further drop crypto alias as SoM dtsi already set it.
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
.../boot/dts/freescale/fsl-lx2162a-clearfog.dts | 21 ---------------------
1 file changed, 21 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
index f95e9c19bfc75..6fd85a5cac94e 100644
--- a/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-lx2162a-clearfog.dts
@@ -14,7 +14,6 @@ / {
compatible = "solidrun,lx2162a-clearfog", "solidrun,lx2162a-som", "fsl,lx2160a";
aliases {
- crypto = &crypto;
i2c0 = &i2c0;
i2c1 = &i2c2;
i2c2 = &i2c4;
@@ -124,42 +123,36 @@ &dpmac11 {
phys = <&serdes_2 0>;
phy-handle = <ðernet_phy3>;
phy-connection-type = "sgmii";
- status = "okay";
};
&dpmac12 {
phys = <&serdes_2 1>;
phy-handle = <ðernet_phy1>;
phy-connection-type = "sgmii";
- status = "okay";
};
&dpmac13 {
phys = <&serdes_2 6>;
phy-handle = <ðernet_phy6>;
phy-connection-type = "sgmii";
- status = "okay";
};
&dpmac14 {
phys = <&serdes_2 7>;
phy-handle = <ðernet_phy8>;
phy-connection-type = "sgmii";
- status = "okay";
};
&dpmac15 {
phys = <&serdes_2 4>;
phy-handle = <ðernet_phy4>;
phy-connection-type = "sgmii";
- status = "okay";
};
&dpmac16 {
phys = <&serdes_2 5>;
phy-handle = <ðernet_phy2>;
phy-connection-type = "sgmii";
- status = "okay";
};
&dpmac17 {
@@ -170,14 +163,12 @@ &dpmac17 {
phys = <&serdes_2 2>;
phy-handle = <ðernet_phy5>;
phy-connection-type = "sgmii";
- status = "okay";
};
&dpmac18 {
phys = <&serdes_2 3>;
phy-handle = <ðernet_phy7>;
phy-connection-type = "sgmii";
- status = "okay";
};
&emdio1 {
@@ -314,14 +305,6 @@ pcieclk_i2c: i2c@2 {
};
};
-&pcie3 {
- status = "disabled";
-};
-
-&pcie4 {
- status = "disabled";
-};
-
&pcs_mdio3 {
status = "okay";
};
@@ -370,10 +353,6 @@ &pcs_mdio18 {
status = "okay";
};
-&serdes_1 {
- status = "okay";
-};
-
&serdes_2 {
status = "okay";
};
--
2.51.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox