* Re: [PATCH V13 5/9] iio: imu: inv_icm42607: Add PM support for icm42607
From: Jonathan Cameron @ 2026-06-24 15:06 UTC (permalink / raw)
To: Chris Morgan
Cc: Chris Morgan, linux-iio, andy, nuno.sa, dlechner,
jean-baptiste.maneyrol, linux-rockchip, devicetree, heiko,
conor+dt, krzk+dt, robh, andriy.shevchenko
In-Reply-To: <PH0PR19MB99733833C502FDB1FA4927B8DEA5EE2@PH0PR19MB997338.namprd19.prod.outlook.com>
On Tue, 23 Jun 2026 13:08:02 -0500
Chris Morgan <macromorgan@hotmail.com> wrote:
> On Mon, Jun 22, 2026 at 09:34:10PM -0500, Chris Morgan wrote:
> > On Sun, Jun 21, 2026 at 06:19:48PM +0100, Jonathan Cameron wrote:
> > > On Mon, 15 Jun 2026 12:25:48 -0500
> > > Chris Morgan <macroalpha82@gmail.com> wrote:
> > >
> > > > From: Chris Morgan <macromorgan@hotmail.com>
> > > >
> > > > Add power management support for the ICM42607 device driver.
> > > >
> > > > Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> > > A few things from taking a look at the sashiko report:
> > > https://sashiko.dev/#/patchset/20260615172554.160910-1-macroalpha82%40gmail.com
> > >
> > > > ---
> > > > drivers/iio/imu/inv_icm42607/inv_icm42607.h | 18 +++
> > > > .../iio/imu/inv_icm42607/inv_icm42607_core.c | 139 ++++++++++++++++++
> > > > .../iio/imu/inv_icm42607/inv_icm42607_i2c.c | 1 +
> > > > .../iio/imu/inv_icm42607/inv_icm42607_spi.c | 1 +
> > > > 4 files changed, 159 insertions(+)
> > > >
> > > > diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607.h b/drivers/iio/imu/inv_icm42607/inv_icm42607.h
> > > > index a6a58571935f..4f4f541027dc 100644
> > > > --- a/drivers/iio/imu/inv_icm42607/inv_icm42607.h
> > > > +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607.h
> > >
> > > > @@ -334,11 +345,18 @@ struct inv_icm42607_state {
> > > > #define INV_ICM42607_GYRO_STOP_TIME_MS 45
> > > > #define INV_ICM42607_TEMP_STARTUP_TIME_MS 77
> > > >
> > > > +/*
> > > > + * Suspend delay assumed from other icm42600 series device, not
> > > > + * documented in datasheet.
> > > > + */
> > > > +#define INV_ICM42607_SUSPEND_DELAY_MS (2 * USEC_PER_MSEC)
> > >
> > > Sashiko had a valid comment on this. MSEC_PER_SEC seems more
> > > appropriate given this is 2 seconds in milli seconds.
> > >
> > > > +
> > > > typedef int (*inv_icm42607_bus_setup)(struct inv_icm42607_state *);
> > > >
> > > > extern const struct regmap_config inv_icm42607_regmap_config;
> > > > extern const struct inv_icm42607_hw inv_icm42607_hw_data;
> > > > extern const struct inv_icm42607_hw inv_icm42607p_hw_data;
> > > > +extern const struct dev_pm_ops inv_icm42607_pm_ops;
> > > >
> > > > int inv_icm42607_core_probe(struct regmap *regmap,
> > > > const struct inv_icm42607_hw *hw,
> > > > diff --git a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > > > index 4b8e19091786..64f5d263de4f 100644
> > > > --- a/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > > > +++ b/drivers/iio/imu/inv_icm42607/inv_icm42607_core.c
> > > > @@ -4,6 +4,7 @@
> > > > */
> > > >
> > > > #include <linux/bitfield.h>
> > > > +#include <linux/cleanup.h>
> > > > #include <linux/delay.h>
> > > > #include <linux/dev_printk.h>
> > > > #include <linux/device/devres.h>
> > > > @@ -11,6 +12,7 @@
> > > > #include <linux/iio/iio.h>
> > > > #include <linux/module.h>
> > > > #include <linux/mutex.h>
> > > > +#include <linux/pm_runtime.h>
> > > > #include <linux/regmap.h>
> > > > #include <linux/regulator/consumer.h>
> > > > #include <linux/time.h>
> > > > @@ -103,6 +105,63 @@ const struct inv_icm42607_hw inv_icm42607p_hw_data = {
> > > > };
> > > > EXPORT_SYMBOL_NS_GPL(inv_icm42607p_hw_data, "IIO_ICM42607");
> > > >
> > > > +static int inv_icm42607_set_pwr_mgmt0(struct inv_icm42607_state *st,
> > > > + enum inv_icm42607_sensor_mode gyro,
> > > > + enum inv_icm42607_sensor_mode accel,
> > > > + bool temp, unsigned int *sleep_ms)
> > > > +{
> > > > + enum inv_icm42607_sensor_mode oldaccel = st->conf.accel.mode;
> > > > + enum inv_icm42607_sensor_mode oldgyro = st->conf.gyro.mode;
> > > > + bool oldtemp = st->conf.temp_en;
> > > > + unsigned int sleepval_ms;
> > > > + unsigned int val;
> > > > + int ret;
> > > > +
> > > > + if (gyro == oldgyro && accel == oldaccel && temp == oldtemp)
> > > > + return 0;
> > > > +
> > > > + /*
> > > > + * Datasheet on page 14.26 says we need to ensure the gyro sensor is on
> > > > + * for a minimum of 45ms. So if we transition from an on state to an
> > > > + * off state wait 45ms to ensure a sufficient pause before power off.
> > >
> > > Sashiko commented on this.. I think what we could do with adding to the
> > > comment is what the path is that didn't pass through this function which would
> > > ensure we have been on for 30 of this msecs already.
> >
> > I'm going to track whatever time the gyro started, and then if less
> > than 45ms has elapsed just pause the remaining amount of time.
> >
> > >
> > > > + */
> > > > + if (!gyro && oldgyro)
> > > > + fsleep(INV_ICM42607_GYRO_STOP_TIME_MS * USEC_PER_MSEC);
> > > > +
> > > > + val = FIELD_PREP(INV_ICM42607_PWR_MGMT0_GYRO_MODE_MASK, gyro);
> > > > + val |= FIELD_PREP(INV_ICM42607_PWR_MGMT0_ACCEL_MODE_MASK, accel);
> > > > + ret = regmap_write(st->map, INV_ICM42607_REG_PWR_MGMT0, val);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > + st->conf.gyro.mode = gyro;
> > > > + st->conf.accel.mode = accel;
> > > > + st->conf.temp_en = temp;
> > > > +
> > > > + /*
> > > > + * If a state change occurs from off to on, sleep for the startup
> > > > + * time of the sensor, unless a sleep_ms is specified. Since more
> > > > + * than one sensor can be transitioned from off to on, select the
> > > > + * maximum time from each of the sensors changing from off to on.
> > > > + */
> > > > + sleepval_ms = 0;
> > > > + if (temp && !oldtemp)
> > > > + sleepval_ms = max(sleepval_ms, INV_ICM42607_TEMP_STARTUP_TIME_MS);
> > > > +
> > > > + if (accel && !oldaccel)
> > > > + sleepval_ms = max(sleepval_ms, INV_ICM42607_ACCEL_STARTUP_TIME_MS);
> > > > +
> > > > + if (gyro && !oldgyro)
> > > > + sleepval_ms = max(sleepval_ms, INV_ICM42607_GYRO_STARTUP_TIME_MS);
> > > > +
> > > > + if (sleep_ms)
> > > > + *sleep_ms = sleepval_ms;
> > > > + else if (sleepval_ms)
> > > > + fsleep(sleepval_ms * USEC_PER_MSEC);
> > > > +
> > > > + return 0;
> > > > +}
> > >
> > > >
> > > > int inv_icm42607_core_probe(struct regmap *regmap,
> > > > @@ -236,6 +305,8 @@ int inv_icm42607_core_probe(struct regmap *regmap,
> > > > if (!st)
> > > > return -ENOMEM;
> > > >
> > > > + dev_set_drvdata(dev, st);
> > > > +
> > > > ret = devm_mutex_init(dev, &st->lock);
> > > > if (ret)
> > > > return ret;
> > > > @@ -271,10 +342,78 @@ int inv_icm42607_core_probe(struct regmap *regmap,
> > > > if (ret)
> > > > return ret;
> > > >
> > > > + ret = devm_pm_runtime_set_active_enabled(dev);
> > > > + if (ret)
> > > > + return ret;
> > > > +
> > > > + pm_runtime_set_autosuspend_delay(dev, INV_ICM42607_SUSPEND_DELAY_MS);
> > > > + pm_runtime_use_autosuspend(dev);
> > > Sashiko does put out some stuff here. Please take a look and work out or
> > > test if it is right (I think not but haven't checked that carefully!)
> > > From a quick look I think that the auto disabling of autosuspend does a
> > > rpm_idle() that should result in it suspending...
> > >
> >
> > I see a few other drivers adding one more call to
> > devm_pm_runtime_enable() so I'm going to see how that works out.
>
> Obviously that didn't work, but digging in much deeper into the PM code
> I see that devm_pm_runtime_set_active_enabled() returns
> devm_pm_runtime_enable(), which sets devm_add_action_or_reset() on
> pm_runtime_disable_action(), which calls
> pm_runtime_dont_use_autosuspend() and pm_runtime_disable(). Shouldn't
> this work, or am I missing something? Basically when the driver
> detaches shouldn't this chain end up calling
> pm_runtime_dont_use_autosuspend()?
Agreed. That was how I read things. The only thing I didn't entirely
confirm (states involved were fiddly enough I'd want to check it
with the actual driver!) was that pm_runtime_dont_use_autosuspend()
ends up calling rpm_idle() in this case.
Jonathan
>
> Thank you,
> Chris
>
> >
> > >
> > > > +
> > > > return 0;
> > > > }
> > > > EXPORT_SYMBOL_NS_GPL(inv_icm42607_core_probe, "IIO_ICM42607");
> >
> > Thank you,
> > Chris
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: (subset) [PATCH v7 00/30] Add HDMI 2.0 support to DW HDMI QP TX
From: Luca Ceresoli @ 2026-06-24 14:08 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Sandy Huang,
Heiko Stübner, Andy Yan, Daniel Stone, Dave Stevenson,
Maíra Canal, Raspberry Pi Kernel Maintenance,
Cristian Ciocaltea
Cc: kernel, dri-devel, linux-kernel, linux-arm-kernel, linux-rockchip,
Dmitry Baryshkov, Diederik de Haas, Maud Spierings
In-Reply-To: <20260602-dw-hdmi-qp-scramb-v7-0-445eb54ee1ed@collabora.com>
On Tue, 02 Jun 2026 01:44:00 +0300, Cristian Ciocaltea wrote:
> Enable HDMI 2.0 display modes (e.g. 4K@60Hz) on the Synopsys DW HDMI QP
> TX controller, as found in Rockchip RK3576 & RK3588 SoCs, by adding SCDC
> management for high TMDS clock ratio and scrambling.
>
> Since SCDC state is lost on sink disconnects, the bridge driver needs to
> trigger a CRTC reset during connector detection. To support this, the
> series introduces the connector and bridge scrambling infrastructure
> (patches 1-8), wires it up through the bridge connector layer with an
> atomic-aware detect_ctx hook (patches 9-11), then implements the SCDC
> scrambling feature in the DW HDMI QP bridge driver (patches 12-15).
>
> [...]
Applied, thanks!
[01/30] drm/fb-helper: Remove unused local variable in hotplug_event()
commit: cdeb2ccd993ed8647adbbda2c3b103aa717fd6f7
Best regards,
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: [PATCH] clk: rockchip: rk3588: don't disable unused I2S MCLK output gates
From: Sebastian Reichel @ 2026-06-24 13:42 UTC (permalink / raw)
To: Daniele Briguglio
Cc: Michael Turquette, Stephen Boyd, Heiko Stuebner, linux-clk,
linux-arm-kernel, linux-rockchip, linux-kernel, Diederik de Haas,
Nicolas Frattaroli, Ricardo Pardini
In-Reply-To: <20260624123914.1767374-1-hello@superkali.me>
[-- Attachment #1.1: Type: text/plain, Size: 3905 bytes --]
Hi,
On Wed, Jun 24, 2026 at 02:39:14PM +0200, Daniele Briguglio wrote:
> No in-tree board references these gates yet. Boards drive the codec
> MCLK through the parent I2S*_8CH_MCLKOUT, and now that the gates are
> managed clocks, clk_disable_unused() turns them off at boot. On a board
> that relied on firmware leaving the output enabled, that cuts the MCLK
> and analog audio stops working.
>
> Mark the four gates CLK_IGNORE_UNUSED so an unreferenced gate keeps the
> state firmware left. A board that wants the kernel to own the gate can
> reference I2S*_8CH_MCLKOUT_TO_IO from DT instead.
>
> Fixes: 02b9b0bb6269 ("clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO")
> Reported-by: Diederik de Haas <diederik@cknow-tech.com>
> Closes: https://lore.kernel.org/linux-rockchip/DJGDSS875DDO.22TYPVYK5X8KZ@cknow-tech.com/
> Tested-by: Diederik de Haas <diederik@cknow-tech.com>
> Signed-off-by: Daniele Briguglio <hello@superkali.me>
> ---
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Greetings,
-- Sebastian
> drivers/clk/rockchip/clk-rk3588.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
> index 2ba9976654c..86953f9ffee 100644
> --- a/drivers/clk/rockchip/clk-rk3588.c
> +++ b/drivers/clk/rockchip/clk-rk3588.c
> @@ -895,7 +895,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
> MUX(I2S2_2CH_MCLKOUT, "i2s2_2ch_mclkout", i2s2_2ch_mclkout_p, CLK_SET_RATE_PARENT,
> RK3588_CLKSEL_CON(30), 2, 1, MFLAGS),
> GATE_GRF(I2S2_2CH_MCLKOUT_TO_IO, "i2s2_2ch_mclkout_to_io", "i2s2_2ch_mclkout",
> - 0, RK3588_SYSGRF_SOC_CON6, 2, GFLAGS, grf_type_sys),
> + CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 2, GFLAGS, grf_type_sys),
>
> COMPOSITE(CLK_I2S3_2CH_SRC, "clk_i2s3_2ch_src", gpll_aupll_p, 0,
> RK3588_CLKSEL_CON(30), 8, 1, MFLAGS, 3, 5, DFLAGS,
> @@ -912,7 +912,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
> MUX(I2S3_2CH_MCLKOUT, "i2s3_2ch_mclkout", i2s3_2ch_mclkout_p, CLK_SET_RATE_PARENT,
> RK3588_CLKSEL_CON(32), 2, 1, MFLAGS),
> GATE_GRF(I2S3_2CH_MCLKOUT_TO_IO, "i2s3_2ch_mclkout_to_io", "i2s3_2ch_mclkout",
> - 0, RK3588_SYSGRF_SOC_CON6, 7, GFLAGS, grf_type_sys),
> + CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 7, GFLAGS, grf_type_sys),
> GATE(PCLK_ACDCDIG, "pclk_acdcdig", "pclk_audio_root", 0,
> RK3588_CLKGATE_CON(7), 11, GFLAGS),
> GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio_root", 0,
> @@ -942,7 +942,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
> MUX(I2S0_8CH_MCLKOUT, "i2s0_8ch_mclkout", i2s0_8ch_mclkout_p, CLK_SET_RATE_PARENT,
> RK3588_CLKSEL_CON(28), 2, 2, MFLAGS),
> GATE_GRF(I2S0_8CH_MCLKOUT_TO_IO, "i2s0_8ch_mclkout_to_io", "i2s0_8ch_mclkout",
> - 0, RK3588_SYSGRF_SOC_CON6, 0, GFLAGS, grf_type_sys),
> + CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 0, GFLAGS, grf_type_sys),
>
> GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", 0,
> RK3588_CLKGATE_CON(9), 6, GFLAGS),
> @@ -2229,7 +2229,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
> MUX(I2S1_8CH_MCLKOUT, "i2s1_8ch_mclkout", i2s1_8ch_mclkout_p, CLK_SET_RATE_PARENT,
> RK3588_PMU_CLKSEL_CON(9), 2, 2, MFLAGS),
> GATE_GRF(I2S1_8CH_MCLKOUT_TO_IO, "i2s1_8ch_mclkout_to_io", "i2s1_8ch_mclkout",
> - 0, RK3588_SYSGRF_SOC_CON6, 1, GFLAGS, grf_type_sys),
> + CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 1, GFLAGS, grf_type_sys),
> GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu0_root", CLK_IS_CRITICAL,
> RK3588_PMU_CLKGATE_CON(1), 0, GFLAGS),
> GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "clk_pmu0", CLK_IGNORE_UNUSED,
>
> base-commit: 7edfb7fb58ee058298e18fde76a6077ef17d19d8
> --
> 2.47.3
>
>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 170 bytes --]
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* [PATCH] clk: rockchip: rk3588: don't disable unused I2S MCLK output gates
From: Daniele Briguglio @ 2026-06-24 12:39 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Heiko Stuebner
Cc: linux-clk, linux-arm-kernel, linux-rockchip, linux-kernel,
Diederik de Haas, Nicolas Frattaroli, Ricardo Pardini
No in-tree board references these gates yet. Boards drive the codec
MCLK through the parent I2S*_8CH_MCLKOUT, and now that the gates are
managed clocks, clk_disable_unused() turns them off at boot. On a board
that relied on firmware leaving the output enabled, that cuts the MCLK
and analog audio stops working.
Mark the four gates CLK_IGNORE_UNUSED so an unreferenced gate keeps the
state firmware left. A board that wants the kernel to own the gate can
reference I2S*_8CH_MCLKOUT_TO_IO from DT instead.
Fixes: 02b9b0bb6269 ("clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO")
Reported-by: Diederik de Haas <diederik@cknow-tech.com>
Closes: https://lore.kernel.org/linux-rockchip/DJGDSS875DDO.22TYPVYK5X8KZ@cknow-tech.com/
Tested-by: Diederik de Haas <diederik@cknow-tech.com>
Signed-off-by: Daniele Briguglio <hello@superkali.me>
---
drivers/clk/rockchip/clk-rk3588.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3588.c b/drivers/clk/rockchip/clk-rk3588.c
index 2ba9976654c..86953f9ffee 100644
--- a/drivers/clk/rockchip/clk-rk3588.c
+++ b/drivers/clk/rockchip/clk-rk3588.c
@@ -895,7 +895,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
MUX(I2S2_2CH_MCLKOUT, "i2s2_2ch_mclkout", i2s2_2ch_mclkout_p, CLK_SET_RATE_PARENT,
RK3588_CLKSEL_CON(30), 2, 1, MFLAGS),
GATE_GRF(I2S2_2CH_MCLKOUT_TO_IO, "i2s2_2ch_mclkout_to_io", "i2s2_2ch_mclkout",
- 0, RK3588_SYSGRF_SOC_CON6, 2, GFLAGS, grf_type_sys),
+ CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 2, GFLAGS, grf_type_sys),
COMPOSITE(CLK_I2S3_2CH_SRC, "clk_i2s3_2ch_src", gpll_aupll_p, 0,
RK3588_CLKSEL_CON(30), 8, 1, MFLAGS, 3, 5, DFLAGS,
@@ -912,7 +912,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
MUX(I2S3_2CH_MCLKOUT, "i2s3_2ch_mclkout", i2s3_2ch_mclkout_p, CLK_SET_RATE_PARENT,
RK3588_CLKSEL_CON(32), 2, 1, MFLAGS),
GATE_GRF(I2S3_2CH_MCLKOUT_TO_IO, "i2s3_2ch_mclkout_to_io", "i2s3_2ch_mclkout",
- 0, RK3588_SYSGRF_SOC_CON6, 7, GFLAGS, grf_type_sys),
+ CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 7, GFLAGS, grf_type_sys),
GATE(PCLK_ACDCDIG, "pclk_acdcdig", "pclk_audio_root", 0,
RK3588_CLKGATE_CON(7), 11, GFLAGS),
GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio_root", 0,
@@ -942,7 +942,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
MUX(I2S0_8CH_MCLKOUT, "i2s0_8ch_mclkout", i2s0_8ch_mclkout_p, CLK_SET_RATE_PARENT,
RK3588_CLKSEL_CON(28), 2, 2, MFLAGS),
GATE_GRF(I2S0_8CH_MCLKOUT_TO_IO, "i2s0_8ch_mclkout_to_io", "i2s0_8ch_mclkout",
- 0, RK3588_SYSGRF_SOC_CON6, 0, GFLAGS, grf_type_sys),
+ CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 0, GFLAGS, grf_type_sys),
GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", 0,
RK3588_CLKGATE_CON(9), 6, GFLAGS),
@@ -2229,7 +2229,7 @@ static struct rockchip_clk_branch rk3588_early_clk_branches[] __initdata = {
MUX(I2S1_8CH_MCLKOUT, "i2s1_8ch_mclkout", i2s1_8ch_mclkout_p, CLK_SET_RATE_PARENT,
RK3588_PMU_CLKSEL_CON(9), 2, 2, MFLAGS),
GATE_GRF(I2S1_8CH_MCLKOUT_TO_IO, "i2s1_8ch_mclkout_to_io", "i2s1_8ch_mclkout",
- 0, RK3588_SYSGRF_SOC_CON6, 1, GFLAGS, grf_type_sys),
+ CLK_IGNORE_UNUSED, RK3588_SYSGRF_SOC_CON6, 1, GFLAGS, grf_type_sys),
GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu0_root", CLK_IS_CRITICAL,
RK3588_PMU_CLKGATE_CON(1), 0, GFLAGS),
GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "clk_pmu0", CLK_IGNORE_UNUSED,
base-commit: 7edfb7fb58ee058298e18fde76a6077ef17d19d8
--
2.47.3
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Daniele Briguglio @ 2026-06-24 12:20 UTC (permalink / raw)
To: Heiko Stuebner, Diederik de Haas, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <2008560.6tgchFWduM@diego>
Hi Heiko,
> Care to send a patch for that change? :-)
Will do. I was only waiting for your call on the approach before sending,
so I'll get it out shortly.
Best regards,
Daniele
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: [PATCH 3/7] dt-bindings: net: rockchip-dwmac: Allow 9 clocks
From: Heiko Stübner @ 2026-06-24 11:50 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
David Wu, Maxime Coquelin, Alexandre Torgue, Yanan He
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-3-5aef608a3f64@gmail.com>
Am Mittwoch, 24. Juni 2026, 10:44:40 Mitteleuropäische Sommerzeit schrieb Yanan He:
> RV1126 has a separate GMAC Ethernet output clock used as the external
> PHY reference clock. This clock is described in addition to the existing
> GMAC clocks.
AS stated in the driver patch, this is the input clock for the phy
and ethernet phys are perfectly capable of handling their input
clocks. See reference in the driver patch.
Heiko
> Signed-off-by: Yanan He <grumpycat921013@gmail.com>
> ---
> Documentation/devicetree/bindings/net/rockchip-dwmac.yaml | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
> index 80c252845349..86a7e83675ae 100644
> --- a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
> +++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
> @@ -71,7 +71,7 @@ properties:
>
> clocks:
> minItems: 4
> - maxItems: 8
> + maxItems: 9
>
> clock-names:
> contains:
>
>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: [PATCH 4/7] net: stmmac: dwmac-rk: Enable refout clock for RGMII
From: Heiko Stübner @ 2026-06-24 11:49 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
David Wu, Maxime Coquelin, Alexandre Torgue, Yanan He
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-4-5aef608a3f64@gmail.com>
Hi,
Am Mittwoch, 24. Juni 2026, 10:44:41 Mitteleuropäische Sommerzeit schrieb Yanan He:
> Some Rockchip GMAC integrations use clk_mac_refout as an external PHY
> reference clock even when the MAC is configured for RGMII.
>
> RV1126 boards can route CLK_GMAC_ETHERNET_OUT to the external PHY as a
> 25 MHz reference clock. If the driver does not acquire and enable this
> clock in RGMII mode, the common clock framework may disable it as unused
> and the PHY can lose its reference clock.
>
> Enable the refout clock handling for RGMII in addition to RMII.
the clock your referencing is not limited to your rv1126 but instead
present on most (all?) Rockchip SoCs.
And it is an input clock for the phy itself, so should be handled there.
See for example
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi#n313
as a reference.
Heiko
> Signed-off-by: Yanan He <grumpycat921013@gmail.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> index 8d7042e68926..f6fdc0c5b475 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> @@ -1112,7 +1112,8 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
> bsp_priv->clk_enabled = false;
>
> bsp_priv->num_clks = ARRAY_SIZE(rk_clocks);
> - if (phy_iface == PHY_INTERFACE_MODE_RMII)
> + if (phy_iface == PHY_INTERFACE_MODE_RMII ||
> + phy_iface == PHY_INTERFACE_MODE_RGMII)
> bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks);
>
> bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks,
> @@ -1123,7 +1124,8 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
> for (i = 0; i < ARRAY_SIZE(rk_clocks); i++)
> bsp_priv->clks[i].id = rk_clocks[i];
>
> - if (phy_iface == PHY_INTERFACE_MODE_RMII) {
> + if (phy_iface == PHY_INTERFACE_MODE_RMII ||
> + phy_iface == PHY_INTERFACE_MODE_RGMII) {
> for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++)
> bsp_priv->clks[i++].id = rk_rmii_clocks[j];
> }
>
>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: [PATCH v4 5/5] clk: rockchip: rk3588: add GATE_GRF clocks for I2S MCLK output to IO
From: Heiko Stübner @ 2026-06-24 11:45 UTC (permalink / raw)
To: Daniele Briguglio, Diederik de Haas, Michael Turquette,
Stephen Boyd, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Diederik de Haas
Cc: Nicolas Frattaroli, linux-clk, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel, Ricardo Pardini
In-Reply-To: <DJGM4D19H31O.4I5N79CG5Z8C@cknow-tech.com>
Am Dienstag, 23. Juni 2026, 19:42:05 Mitteleuropäische Sommerzeit schrieb Diederik de Haas:
> Hi,
>
> On Tue Jun 23, 2026 at 4:10 PM CEST, Daniele Briguglio wrote:
> >> So IIUC that means I'd be testing both variants.
> >
> > Right, that covers both: the mux path and the consumer path. Looking
> > forward to the results.
>
> Analog audio works on both. Plus with _TO_IO and LTS without in their
> respective DTS's. So I guess CLK_IGNORE_UNUSED works.
> Whether it's a good/right fix, I'll leave up to others.
It is the correct fix, as it returns the original way things worked for
boards not activly handling that clock.
So while boards should do that, this makes the clock-addition
backwards compatible.
Care to send a patch for that change? :-)
Heiko
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: [RFC PATCH 1/6] media: mc: Implement shared media graph
From: Kieran Bingham @ 2026-06-24 10:39 UTC (permalink / raw)
To: Paul Elder, laurent.pinchart
Cc: Paul Elder, michael.riesch, xuhf, stefan.klug, dan.scally,
jacopo.mondi, linux-media, linux-arm-kernel, linux-rockchip,
linux-kernel, hverkuil+cisco, nicolas.dufresne, ribalda,
sakari.ailus
In-Reply-To: <20260619052637.1110672-2-paul.elder@ideasonboard.com>
Hi Paul,
I'm taking a first read through, some comments inline, but not
necessarily a full review:
Quoting Paul Elder (2026-06-19 06:26:28)
> Currently, a media graph contains a main device whose driver is
> responsible for creating the media device. We have however recently run
> into devices that have multiple devices that can quality as a main
s/quality/qualify/
> device. Examples are the RK3588 which has a VICAP and two ISP
> instances, and another example is the i.MX8MP which has an ISI and two
> ISP instances. As there is currently no way to reconcile who the main
> device is in the media device, these setups simple cannot be used
> simultaneously.
I'm very excited to see how we could apply this to the NXP i.MX8MP to
resolve the ISI+ISP issue!
> This patch extends the media controller API with a "shared media graph"
> framework. This allows drivers to share a media device, thus enabling
> the setups mentioned above. Instead of owning and creating a media
> device, drivers can join-or-create a shared media device via the shared
> media graph API. The matching is done automatically based on the
> detected endpoints in the device tree.
Sounds great! I'll read on...
>
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> ---
> drivers/media/mc/Makefile | 2 +-
> drivers/media/mc/mc-shared-graph.c | 335 +++++++++++++++++++++++++++++
> include/media/mc-shared-graph.h | 92 ++++++++
> 3 files changed, 428 insertions(+), 1 deletion(-)
> create mode 100644 drivers/media/mc/mc-shared-graph.c
> create mode 100644 include/media/mc-shared-graph.h
>
> diff --git a/drivers/media/mc/Makefile b/drivers/media/mc/Makefile
> index 2b7af42ba59c..1d502fdc52ad 100644
> --- a/drivers/media/mc/Makefile
> +++ b/drivers/media/mc/Makefile
> @@ -1,7 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0
>
> mc-objs := mc-device.o mc-devnode.o mc-entity.o \
> - mc-request.o
> + mc-request.o mc-shared-graph.o
>
> ifneq ($(CONFIG_USB),)
> mc-objs += mc-dev-allocator.o
> diff --git a/drivers/media/mc/mc-shared-graph.c b/drivers/media/mc/mc-shared-graph.c
> new file mode 100644
> index 000000000000..c4067e5b861d
> --- /dev/null
> +++ b/drivers/media/mc/mc-shared-graph.c
> @@ -0,0 +1,335 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * mc-shared-graph.c - Media Controller Shared Graph API
> + *
> + * Copyright (c) 2026 Paul Elder <paul.elder@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds the Media Controller Shared Graph API. This allows drivers
> + * to create shared media graphs or join existing media graphs from other
> + * drivers, so that they can all be in the same media graph. This allows us to
> + * have more complex media graphs chaining more complex hardware together,
> + * instead of simple async subdevs.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/fwnode.h>
> +#include <linux/kref.h>
> +#include <linux/property.h>
> +
> +#include <media/media-device.h>
> +
> +#include <media/mc-shared-graph.h>
> +
> +static LIST_HEAD(media_device_shared_list);
> +static DEFINE_MUTEX(media_device_shared_lock);
> +
> +struct media_device_shared_member {
> + struct device *dev;
> + struct fwnode_handle *fwnode;
> + struct list_head list;
> +};
> +
> +struct media_device_shared_link {
> + struct media_entity *source;
> + u16 source_pad;
> + struct media_entity *sink;
> + u16 sink_pad;
> + u32 flags;
> + struct list_head list;
> +};
> +
> +// TODO figure out locking for when multiple drivers touch the media graph;
> +// maybe macros for shared versions?
Do you mean for when drivers are trying to change link state directly?
> +struct media_device_shared {
> + struct media_device mdev;
> + struct list_head members;
> + struct list_head links;
> +
> + struct list_head list;
> + struct kref refcount;
> +
> + struct device *removed_device;
> +};
> +
> +static inline struct media_device_shared *
> +to_media_device_shared(struct media_device *mdev)
> +{
> + return container_of(mdev, struct media_device_shared, mdev);
> +}
> +
> +static void media_device_shared_release(struct kref *kref)
> +{
> + struct media_device_shared *mds =
> + container_of(kref, struct media_device_shared, refcount);
> +
> + dev_dbg(mds->removed_device, "%s: releasing Media Device\n", __func__);
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + media_device_unregister(&mds->mdev);
> + media_device_cleanup(&mds->mdev);
> +
> + list_del(&mds->list);
> + mutex_unlock(&media_device_shared_lock);
> +
> + kfree(mds);
> +}
> +
> +/* Callers should hold media_device_shared_lock when calling this function */
Lets add a lockdep_assert then?
> +static bool __media_device_shared_find_match(struct media_device_shared *mds,
> + struct fwnode_handle *fwnode)
> +{
> + struct media_device_shared_member *member;
> + struct fwnode_handle *ep;
> + struct fwnode_handle *remote_ep;
> + bool match = false;
> +
is it just as easy as:
lockdep_assert_held(&media_device_shared_lock);
?
> + // TODO: parse the device tree endpoints graph instead of finding just the
> + // first-level neighbours
> + fwnode_graph_for_each_endpoint(fwnode, ep) {
> + list_for_each_entry(member, &mds->members, list) {
> + remote_ep = fwnode_graph_get_remote_port_parent(ep);
> + match = (member->fwnode == remote_ep);
> + fwnode_handle_put(remote_ep);
> +
> + if (!match)
> + continue;
> +
> + goto match_complete;
> + }
> + }
> +
> +match_complete:
> + fwnode_handle_put(ep);
> + return match;
> +}
> +
> +/* Callers should hold media_device_shared_lock when calling this function */
Lets add a lockdep check too then :D (same everywhere/anywhere it's
needed)
> +static struct media_device *__media_device_shared_get(struct device *dev)
> +{
> + struct media_device_shared *mds;
> + struct media_device_shared_member *member;
> + struct fwnode_handle *fwnode = dev_fwnode(dev);
> + bool ret;
> +
> + dev_dbg(dev, "%s: searching for media device for %pfwf", __func__, fwnode);
> +
> + list_for_each_entry(mds, &media_device_shared_list, list) {
> + ret = __media_device_shared_find_match(mds, fwnode);
> + if (ret)
> + break;
> + }
> +
> + if (!ret)
> + return NULL;
> +
> + member = kzalloc_obj(*member);
> + if (!member)
> + return NULL;
> +
> + member->dev = dev;
> + member->fwnode = fwnode;
> + list_add_tail(&member->list, &mds->members);
> + kref_get(&mds->refcount);
> +
> + dev_dbg(dev, "%s: %pfwf joined media device of %pfwf",
> + __func__, fwnode,
> + list_first_entry(&mds->members, struct media_device_shared_member, list)->fwnode);
> +
> + return &mds->mdev;
> +}
> +
> +/* Callers should hold media_device_shared_lock when calling this function */
> +static struct media_device *__media_device_shared_create(struct device *dev)
> +{
> + struct media_device_shared *mds;
> + struct media_device_shared_member *member;
> + struct fwnode_handle *fwnode = dev_fwnode(dev);
> + int ret;
> +
> + mds = kzalloc_obj(*mds);
> + if (!mds)
> + return NULL;
> +
> + member = kzalloc_obj(*member);
> + if (!member)
> + goto err_free_mds;
> +
> + media_device_init(&mds->mdev);
> +
> + ret = media_device_register(&mds->mdev);
> + if (ret)
> + goto err_free_member;
> +
> + INIT_LIST_HEAD(&mds->members);
> + member->dev = dev;
> + member->fwnode = fwnode;
> + list_add_tail(&member->list, &mds->members);
> +
> + INIT_LIST_HEAD(&mds->links);
> +
> + kref_init(&mds->refcount);
> + list_add_tail(&mds->list, &media_device_shared_list);
> +
> + // TODO figure out how to reconcile this with multiple members
Aha, right - becuse the 'media_device dev' becomes whoever registers first.
I wonder where it's actually used, and maybe that's ok ?
> + mds->mdev.dev = dev;
> +
> + devv_dbg(dev, "%s: Allocated media device with %pfwf at %p\n",
> + __func__, fwnode, &mds->mdev);
> + return &mds->mdev;
> +
> +err_free_member:
> + kfree(member);
> +err_free_mds:
> + kfree(mds);
> + return NULL;
> +}
> +
> +// TODO figure out how to resolve the identifiers (model, driver name, etc);
> +// atm it's racy and whoever gets it last wins
Maybe that's something we need to pass or set up explicitly then, so
it's clear it's a 'specific graph'
Would this give us a way to represent the hardware in a new form - i.e.
thinking about IMX8MP - the existing graph wouldn't be available - so it
wouldn't be any worry from a UABI perspective because it's just a whole
new interface/media-device name....
> +struct media_device *media_device_shared_join(struct device *dev)
> +{
> + struct media_device *mdev;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + mdev = __media_device_shared_get(dev);
> + if (!!mdev) {
> + dev_dbg(dev, "%s: found media device for %pfwf", __func__, dev_fwnode(dev));
> + mutex_unlock(&media_device_shared_lock);
> + return mdev;
> + }
> +
> + mdev = __media_device_shared_create(dev);
> + if (!mdev) {
> + dev_warn(dev, "%s: failed to create media device for %pfwf", __func__, dev_fwnode(dev));
> + mutex_unlock(&media_device_shared_lock);
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + dev_dbg(dev, "%s: created media device for %pfwf", __func__, dev_fwnode(dev));
> + mutex_unlock(&media_device_shared_lock);
> + return mdev;
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_join);
> +
> +void media_device_shared_leave(struct media_device *mdev, struct device *dev)
> +{
> + struct media_device_shared *mds = to_media_device_shared(mdev);
> + struct media_device_shared_member *member;
> + struct media_device_shared_member *member_tmp;
> + bool removed = false;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + list_for_each_entry_safe(member, member_tmp, &mds->members, list) {
> + if (member->dev == dev) {
> + list_del(&member->list);
> + kfree(member);
> + removed = true;
> + }
> + }
> +
> + if (!removed)
> + dev_err(dev, "%s: %pfwf trying to leave from graph in which not a member",
> + __func__, dev_fwnode(dev));
> +
> + mds->removed_device = dev;
> + mutex_unlock(&media_device_shared_lock);
> + kref_put(&mds->refcount, media_device_shared_release);
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_leave);
> +
> +int media_device_shared_join_link_source(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *source,
> + u16 source_pad, u32 flags)
> +{
> + struct media_device_shared *mds = to_media_device_shared(mdev);
> + struct media_device_shared_link *link;
> + struct media_device_shared_link *link_tmp;
> + int ret = 0;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + /*
> + * TODO Figure out flags. Should we use greatest common denominator? Or
> + * prioritize sink? Or whoever wins the race? For now we just take the flags
> + * from the sink.
> + *
> + * TODO Figure out how to actually do the matching. For now we just match
> + * whoever comes in first. This works with the simple example we're running
> + * with now (rkcif + one rkisp2) but with setups with multiple copies of
> + * hardware this will cause problems, like with rkcif + two rkisp2 and
> + * imx8-isi + two rkisp1.
> + */
> + list_for_each_entry_safe(link, link_tmp, &mds->links, list) {
> + if (link->sink) {
> + ret = media_create_pad_link(source, source_pad,
> + link->sink, link->sink_pad,
> + link->flags);
> + list_del(&link->list);
> + kfree(link);
> + goto exit_join_link_source;
> + }
> + }
> +
> + link = kzalloc_obj(*link);
> + if (!link) {
> + ret = -ENOMEM;
> + goto exit_join_link_source;
> + }
> +
> + link->source = source;
> + link->source_pad = source_pad;
> + link->flags = flags;
> + list_add_tail(&link->list, &mds->links);
> +
> +exit_join_link_source:
> + mutex_unlock(&media_device_shared_lock);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_join_link_source);
> +
> +// TODO deduplicate from above
Indeed, it does look like an opportunity.
> +int media_device_shared_join_link_sink(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *sink,
> + u16 sink_pad, u32 flags)
> +{
> + struct media_device_shared *mds = to_media_device_shared(mdev);
> + struct media_device_shared_link *link;
> + struct media_device_shared_link *link_tmp;
> + int ret = 0;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + list_for_each_entry_safe(link, link_tmp, &mds->links, list) {
> + if (link->source) {
> + ret = media_create_pad_link(link->source, link->source_pad,
> + sink, sink_pad,
> + flags);
> + list_del(&link->list);
> + kfree(link);
> + goto exit_join_link_sink;
> + }
> + }
> +
> + link = kzalloc_obj(*link);
> + if (!link) {
> + ret = -ENOMEM;
> + goto exit_join_link_sink;
> + }
> +
> + link->sink = sink;
> + link->sink_pad = sink_pad;
> + link->flags = flags;
> + list_add_tail(&link->list, &mds->links);
> +
> +exit_join_link_sink:
> + mutex_unlock(&media_device_shared_lock);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_join_link_sink);
> diff --git a/include/media/mc-shared-graph.h b/include/media/mc-shared-graph.h
> new file mode 100644
> index 000000000000..487325163f84
> --- /dev/null
> +++ b/include/media/mc-shared-graph.h
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * mc-shared-graph.h - Media Controller Shared Graph API
> + *
> + * Copyright (c) 2026 Paul Elder <paul.elder@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds the Media Controller Shared Graph API. This allows drivers
> + * to create shared media graphs or join existing media graphs from other
> + * drivers, so that they can all be in the same media graph. This allows us to
> + * have more complex media graphs chaining more complex hardware together,
> + * instead of simple async subdevs.
> + */
> +
> +#include <linux/types.h>
> +
> +#ifndef _MEDIA_SHARED_GRAPH_H
> +#define _MEDIA_SHARED_GRAPH_H
> +
> +struct device;
> +struct media_device;
> +struct media_entity;
> +
> +#if defined(CONFIG_MEDIA_CONTROLLER)
> +/**
> + * media_device_shared_join() - Join or create a new shared media device
> + *
> + * @dev: struct &device pointer
> + *
> + * This is the entrance function for a device to join or create a new shared
> + * media device. It searches for an existing shared media device based on the
> + * neighbours in the device's device tree ports node. If found, then this
> + * functions returns the existing shared media device and joins it. If one is
> + * not found then one is created and initialized and returned.
> + */
> +struct media_device *media_device_shared_join(struct device *dev);
> +
> +/**
> + * media_device_shared_leave() - Leave the shared media device.
> + *
> + * @mdev: struct &media_device pointer
> + * @dev: struct &device pointer
> + *
> + * This function makes the device leave the shared media device. When all
> + * members have left the media device it will be freed.
> + */
> +void media_device_shared_leave(struct media_device *mdev, struct device *dev);
> +
> +/**
> + * media_device_shared_join_link_source() - Register a link source in the shared media device
> + *
> + * @mdev: The struct &media_device pointer that is part of a shared media device
> + * @dev: struct &device pointer
> + * @source: The link source
> + * @source_pad: The pad
> + * @flags: The flags
> + *
> + * This function registers with the shared media device the source part of a
> + * link. When the shared media device receives the matching sink part of a link
> + * via media_device_shared_join_link_sink() then the link will be fully created.
> + */
> +int media_device_shared_join_link_source(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *source,
> + u16 source_pad, u32 flags);
> +
> +/**
> + * media_device_shared_join_link_sink() - Register a link sink in the shared media device
> + *
> + * Same as media_device_shared_join_link_source() but for sink instead of
> + * source.
> + */
> +int media_device_shared_join_link_sink(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *sink,
> + u16 sink_pad, u32 flags);
> +#else
> +static inline struct media_device *media_device_shared_join(struct device *dev)
> +{ return NULL; }
> +static inline void media_device_shared_leave(struct media_device *mdev,
> + struct device *dev) { }
> +static inline int media_device_shared_join_link_source(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *source,
> + u16 source_pad, u32 flags) { }
> +static inline int media_device_shared_join_link_sink(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *sink,
> + u16 sink_pad, u32 flags) { }
Should these two stubs which return an int return an error code? -ENODEV or such ?
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> +#endif /* _MEDIA_DEV_SHARED_GRAPH_H */
> --
> 2.47.2
>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* [PATCH 7/7] ARM: dts: rockchip: Add Alientek DLRV1126
From: Yanan He @ 2026-06-24 9:02 UTC (permalink / raw)
To: robh, krzk+dt, conor+dt, heiko, andrew+netdev, davem, edumazet,
kuba, pabeni, david.wu, mcoquelin.stm32, alexandre.torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, grumpycat921013
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-0-dc42d99f75a7@gmail.com>
The board consists of a CLRV1126F core module and a DLRV1126 carrier
board. The core module contains the RV1126 SoC, eMMC and RK809 PMIC,
while the carrier board provides Ethernet, SD card, AP6212 WiFi and
Bluetooth, PCF8563 RTC, ADC keys, GPIO LEDs and audio connectors.
The board has been tested with Ethernet/NFS boot, eMMC, SD card, SDIO
WiFi enumeration, Bluetooth LE scanning, RTC, ADC keys, GPIO LEDs and
RK809 audio card registration.
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
arch/arm/boot/dts/rockchip/Makefile | 1 +
.../dts/rockchip/rv1126-alientek-clrv1126f.dtsi | 277 +++++++++++++++++++++
.../boot/dts/rockchip/rv1126-alientek-dlrv1126.dts | 258 +++++++++++++++++++
3 files changed, 536 insertions(+)
diff --git a/arch/arm/boot/dts/rockchip/Makefile b/arch/arm/boot/dts/rockchip/Makefile
index d0154fd7ff24..e9f9e0ac3bfd 100644
--- a/arch/arm/boot/dts/rockchip/Makefile
+++ b/arch/arm/boot/dts/rockchip/Makefile
@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rv1108-evb.dtb \
rv1109-relfor-saib.dtb \
rv1109-sonoff-ihost.dtb \
+ rv1126-alientek-dlrv1126.dtb \
rv1126-edgeble-neu2-io.dtb \
rv1126-sonoff-ihost.dtb \
rk3036-evb.dtb \
diff --git a/arch/arm/boot/dts/rockchip/rv1126-alientek-clrv1126f.dtsi b/arch/arm/boot/dts/rockchip/rv1126-alientek-clrv1126f.dtsi
new file mode 100644
index 000000000000..9bee424b1797
--- /dev/null
+++ b/arch/arm/boot/dts/rockchip/rv1126-alientek-clrv1126f.dtsi
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2026 Yanan He <grumpycat921013@gmail.com>
+ */
+
+#include "rv1126.dtsi"
+
+/ {
+ compatible = "alientek,clrv1126f", "rockchip,rv1126";
+
+ aliases {
+ mmc0 = &emmc;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&emmc {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_rstnout>;
+ rockchip,default-sample-phase = <90>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB1 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <1>;
+ #sound-dai-cells = <0>;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ clock-names = "mclk";
+ clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
+ assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
+ assigned-clock-parents = <&cru MCLK_I2S0_TX>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ rockchip,system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc_buck5>;
+ vcc6-supply = <&vcc_buck5>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+
+ regulators {
+ vdd_npu_vepu: DCDC_REG1 {
+ regulator-name = "vdd_npu_vepu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <6001>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_arm: DCDC_REG2 {
+ regulator-name = "vdd_arm";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc3v3_sys: DCDC_REG4 {
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_buck5: DCDC_REG5 {
+ regulator-name = "vcc_buck5";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2200000>;
+ };
+ };
+
+ vcc_0v8: LDO_REG1 {
+ regulator-name = "vcc_0v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8_pmu: LDO_REG2 {
+ regulator-name = "vcc1v8_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd0v8_pmu: LDO_REG3 {
+ regulator-name = "vcc0v8_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <800000>;
+ };
+ };
+
+ vcc_1v8: LDO_REG4 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc_dovdd: LDO_REG5 {
+ regulator-name = "vcc_dovdd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_dvdd: LDO_REG6 {
+ regulator-name = "vcc_dvdd";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_avdd: LDO_REG7 {
+ regulator-name = "vcc_avdd";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG8 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: LDO_REG9 {
+ regulator-name = "vcc3v3_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_5v0: SWITCH_REG1 {
+ regulator-name = "vcc_5v0";
+ };
+
+ vcc_3v3: SWITCH_REG2 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+&pinctrl {
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio0-supply = <&vcc3v3_sys>;
+ pmuio1-supply = <&vcc3v3_sys>;
+ vccio1-supply = <&vcc_1v8>;
+ vccio2-supply = <&vccio_sd>;
+ vccio3-supply = <&vcc_1v8>;
+ vccio4-supply = <&vcc_3v3>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_3v3>;
+ vccio7-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/rockchip/rv1126-alientek-dlrv1126.dts b/arch/arm/boot/dts/rockchip/rv1126-alientek-dlrv1126.dts
new file mode 100644
index 000000000000..c8123a3c4746
--- /dev/null
+++ b/arch/arm/boot/dts/rockchip/rv1126-alientek-dlrv1126.dts
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2026 Yanan He <grumpycat921013@gmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "rv1126-alientek-clrv1126f.dtsi"
+
+/ {
+ model = "Alientek ATK-DLRV1126";
+ compatible = "alientek,dlrv1126", "alientek,clrv1126f", "rockchip,rv1126";
+
+ aliases {
+ ethernet0 = &gmac;
+ mmc1 = &sdio;
+ mmc2 = &sdmmc;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-esc {
+ label = "esc";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <0>;
+ };
+
+ button-right {
+ label = "right";
+ linux,code = <KEY_RIGHT>;
+ press-threshold-microvolt = <400781>;
+ };
+
+ button-left {
+ label = "left";
+ linux,code = <KEY_LEFT>;
+ press-threshold-microvolt = <801562>;
+ };
+
+ button-menu {
+ label = "menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <1198828>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "sys-led";
+ gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ default-state = "on";
+ };
+
+ led-1 {
+ label = "user-led";
+ gpios = <&gpio3 RK_PD6 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "none";
+ default-state = "on";
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Analog RK809";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Speaker", "Speaker",
+ "Headphone", "Headphones",
+ "Microphone", "Mic Jack";
+ simple-audio-card,routing =
+ "Speaker", "SPKO",
+ "Headphones", "HPOL",
+ "Headphones", "HPOR",
+ "MICL", "Mic Jack";
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0>;
+ };
+
+ simple-audio-card,codec {
+ sound-dai = <&rk809>;
+ };
+ };
+
+ vcc5v0_sys: regulator-vcc5v0-sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ sdio_pwrseq: pwrseq-sdio {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h>;
+ reset-gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
+ post-power-on-delay-ms = <200>;
+ power-off-delay-us = <20000>;
+ };
+};
+
+&i2c5 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pcf8563: rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <RK_PD0 IRQ_TYPE_LEVEL_LOW>;
+ clock-output-names = "xin32k";
+ };
+};
+
+&gmac {
+ phy-mode = "rgmii";
+ clock_in_out = "input";
+ assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>,
+ <&cru CLK_GMAC_ETHERNET_OUT>;
+ assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>,
+ <&cru RGMII_MODE_CLK>;
+ assigned-clock-rates = <125000000>, <0>, <25000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmiim1_miim &rgmiim1_bus2 &rgmiim1_bus4
+ &clk_out_ethernetm1_pins>;
+ tx_delay = <0x2a>;
+ rx_delay = <0x1a>;
+ phy-handle = <&phy>;
+ status = "okay";
+};
+
+&mdio {
+ phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1>;
+ clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
+ pinctrl-names = "default";
+ pinctrl-0 = <ð_phy_rst>;
+ reset-gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ };
+};
+
+&pinctrl {
+ ethernet {
+ eth_phy_rst: eth-phy-rst {
+ rockchip,pins = <3 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ bt {
+ bt_enable: bt-enable {
+ rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_dev: bt-wake-dev {
+ rockchip,pins = <1 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host: bt-wake-host {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wifi {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdio {
+ bus-width = <4>;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ max-frequency = <25000000>;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_clk &sdmmc1_cmd &sdmmc1_bus4>;
+ rockchip,default-sample-phase = <90>;
+ vmmc-supply = <&vcc3v3_sd>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>;
+ rockchip,default-sample-phase = <90>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_ctsn &uart0_rtsn>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm43430a1-bt";
+ shutdown-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
+ device-wakeup-gpios = <&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
+ clocks = <&rk809 1>;
+ clock-names = "lpo";
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA5 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "host-wakeup";
+ max-speed = <115200>;
+ vbat-supply = <&vcc_3v3>;
+ vddio-supply = <&vcc_1v8>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_enable>, <&bt_wake_dev>, <&bt_wake_host>;
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&i2s0 {
+ rockchip,trcm-sync-tx-only;
+ rockchip,i2s-rx-route = <3 1 2 0>;
+ rockchip,i2s-tx-route = <0 1 2 3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0m0_sclk_tx>,
+ <&i2s0m0_mclk>,
+ <&i2s0m0_lrck_tx>,
+ <&i2s0m0_sdo0>,
+ <&i2s0m0_sdo1_sdi3>;
+ status = "okay";
+};
--
2.54.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* Re: [PATCH v1] ASoC: rockchip: rockchip_sai: #include <linux/platform_device.h> explicitly
From: Nicolas Frattaroli @ 2026-06-24 8:57 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
Uwe Kleine-König (The Capable Hub)
Cc: Heiko Stuebner, linux-rockchip, linux-sound, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260624083708.254517-2-u.kleine-koenig@baylibre.com>
On Wednesday, 24 June 2026 10:37:07 Central European Summer Time Uwe Kleine-König (The Capable Hub) wrote:
> Currently that header is only included via:
>
> <sound/dmaengine_pcm.h> ->
> <sound/soc.h> ->
> <linux/platform_device.h>
>
> which doesn't look reliable, still more in the presence of the comment:
>
> /* For the current users of sound/soc.h to avoid build issues */
>
> in <sound/soc.h>.
>
> Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
> ---
> sound/soc/rockchip/rockchip_sai.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c
> index a195e96fed0a..37e81d56bc16 100644
> --- a/sound/soc/rockchip/rockchip_sai.c
> +++ b/sound/soc/rockchip/rockchip_sai.c
> @@ -11,6 +11,7 @@
> #include <linux/delay.h>
> #include <linux/of_device.h>
> #include <linux/clk.h>
> +#include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> #include <linux/regmap.h>
> #include <linux/reset.h>
>
> base-commit: ef0c9f75a19532d7675384708fc8621e10850104
>
Makes sense.
Reviewed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* [PATCH 6/7] ARM: dts: rockchip: Add RV1126 I2C5
From: Yanan He @ 2026-06-24 8:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, David Wu, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-0-5aef608a3f64@gmail.com>
The controller is present in the SoC and can be used by boards for
external peripherals, such as an RTC on the Alientek DLRV1126 carrier
board.
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi | 10 ++++++++++
arch/arm/boot/dts/rockchip/rv1126.dtsi | 15 +++++++++++++++
2 files changed, 25 insertions(+)
diff --git a/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi b/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi
index 35ef6732281f..1d883b80aed4 100644
--- a/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi
@@ -123,6 +123,16 @@ i2c3m2_xfer: i2c3m2-xfer {
<1 RK_PD7 3 &pcfg_pull_none>;
};
};
+ i2c5 {
+ /omit-if-no-ref/
+ i2c5m0_xfer: i2c5m0-xfer {
+ rockchip,pins =
+ /* i2c5_scl_m0 */
+ <2 RK_PA5 7 &pcfg_pull_none_drv_level_0_smt>,
+ /* i2c5_sda_m0 */
+ <2 RK_PB3 7 &pcfg_pull_none_drv_level_0_smt>;
+ };
+ };
i2s0 {
i2s0m0_lrck_tx: i2s0m0-lrck-tx {
rockchip,pins =
diff --git a/arch/arm/boot/dts/rockchip/rv1126.dtsi b/arch/arm/boot/dts/rockchip/rv1126.dtsi
index 5b1ee06dc035..483576de841e 100644
--- a/arch/arm/boot/dts/rockchip/rv1126.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126.dtsi
@@ -23,6 +23,7 @@ aliases {
i2c0 = &i2c0;
i2c2 = &i2c2;
i2c3 = &i2c3;
+ i2c5 = &i2c5;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
@@ -400,6 +401,20 @@ i2c3: i2c@ff520000 {
status = "disabled";
};
+ i2c5: i2c@ff540000 {
+ compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
+ reg = <0xff540000 0x1000>;
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
+ clock-names = "i2c", "pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c5m0_xfer>;
+ rockchip,grf = <&pmugrf>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
pwm8: pwm@ff550000 {
compatible = "rockchip,rv1126-pwm", "rockchip,rk3328-pwm";
reg = <0xff550000 0x10>;
--
2.54.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* [PATCH 5/7] ARM: dts: rockchip: Add RV1126 GMAC refout clock
From: Yanan He @ 2026-06-24 8:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, David Wu, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-0-5aef608a3f64@gmail.com>
This clock can be routed to an external Ethernet PHY as its reference
clock. Boards using this clock need the clock to be described so the
dwmac-rk driver can acquire and keep it enabled.
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
arch/arm/boot/dts/rockchip/rv1126.dtsi | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/rockchip/rv1126.dtsi b/arch/arm/boot/dts/rockchip/rv1126.dtsi
index d6e8b63daa42..5b1ee06dc035 100644
--- a/arch/arm/boot/dts/rockchip/rv1126.dtsi
+++ b/arch/arm/boot/dts/rockchip/rv1126.dtsi
@@ -624,10 +624,11 @@ gmac: ethernet@ffc40000 {
rockchip,grf = <&grf>;
clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>,
<&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_REF>,
+ <&cru CLK_GMAC_ETHERNET_OUT>,
<&cru ACLK_GMAC>, <&cru PCLK_GMAC>,
<&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_PTPREF>;
clock-names = "stmmaceth", "mac_clk_rx",
- "mac_clk_tx", "clk_mac_ref",
+ "mac_clk_tx", "clk_mac_ref", "clk_mac_refout",
"aclk_mac", "pclk_mac",
"clk_mac_speed", "ptp_ref";
resets = <&cru SRST_GMAC_A>;
--
2.54.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* [PATCH 4/7] net: stmmac: dwmac-rk: Enable refout clock for RGMII
From: Yanan He @ 2026-06-24 8:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, David Wu, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-0-5aef608a3f64@gmail.com>
Some Rockchip GMAC integrations use clk_mac_refout as an external PHY
reference clock even when the MAC is configured for RGMII.
RV1126 boards can route CLK_GMAC_ETHERNET_OUT to the external PHY as a
25 MHz reference clock. If the driver does not acquire and enable this
clock in RGMII mode, the common clock framework may disable it as unused
and the PHY can lose its reference clock.
Enable the refout clock handling for RGMII in addition to RMII.
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 8d7042e68926..f6fdc0c5b475 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1112,7 +1112,8 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
bsp_priv->clk_enabled = false;
bsp_priv->num_clks = ARRAY_SIZE(rk_clocks);
- if (phy_iface == PHY_INTERFACE_MODE_RMII)
+ if (phy_iface == PHY_INTERFACE_MODE_RMII ||
+ phy_iface == PHY_INTERFACE_MODE_RGMII)
bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks);
bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks,
@@ -1123,7 +1124,8 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
for (i = 0; i < ARRAY_SIZE(rk_clocks); i++)
bsp_priv->clks[i].id = rk_clocks[i];
- if (phy_iface == PHY_INTERFACE_MODE_RMII) {
+ if (phy_iface == PHY_INTERFACE_MODE_RMII ||
+ phy_iface == PHY_INTERFACE_MODE_RGMII) {
for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++)
bsp_priv->clks[i++].id = rk_rmii_clocks[j];
}
--
2.54.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* [PATCH 3/7] dt-bindings: net: rockchip-dwmac: Allow 9 clocks
From: Yanan He @ 2026-06-24 8:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, David Wu, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-0-5aef608a3f64@gmail.com>
RV1126 has a separate GMAC Ethernet output clock used as the external
PHY reference clock. This clock is described in addition to the existing
GMAC clocks.
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
Documentation/devicetree/bindings/net/rockchip-dwmac.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
index 80c252845349..86a7e83675ae 100644
--- a/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/rockchip-dwmac.yaml
@@ -71,7 +71,7 @@ properties:
clocks:
minItems: 4
- maxItems: 8
+ maxItems: 9
clock-names:
contains:
--
2.54.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* [PATCH 2/7] dt-bindings: arm: rockchip: Add Alientek DLRV1126
From: Yanan He @ 2026-06-24 8:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, David Wu, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-0-5aef608a3f64@gmail.com>
The board consists of a DLRV1126 carrier board and a CLRV1126F core
module based on the Rockchip RV1126 SoC.
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
Documentation/devicetree/bindings/arm/rockchip.yaml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 1a9dde18626d..9058f2a461d5 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -162,6 +162,13 @@ properties:
- const: coolpi,pi-4b
- const: rockchip,rk3588s
+ - description: Alientek CLRV1126F SoM based boards
+ items:
+ - enum:
+ - alientek,dlrv1126
+ - const: alientek,clrv1126f
+ - const: rockchip,rv1126
+
- description: Edgeble Neural Compute Module 2(Neu2) SoM based boards
items:
- const: edgeble,neural-compute-module-2-io # Edgeble Neural Compute Module 2 IO Board
--
2.54.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* [PATCH 1/7] dt-bindings: vendor-prefixes: add alientek
From: Yanan He @ 2026-06-24 8:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, David Wu, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
In-Reply-To: <20260624-rv1126-alientek-dlrv1126-v1-0-5aef608a3f64@gmail.com>
Add a vendor prefix for Alientek, a board and module vendor used by the
ATK-DLRV1126 board.
Link: https://en.alientek.com
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 28784d66ae7b..a23508a61373 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -88,6 +88,8 @@ patternProperties:
description: ALFA Network Inc.
"^algoltek,.*":
description: AlgolTek, Inc.
+ "^alientek,.*":
+ description: Guangzhou Xingyi Intelligent Technology Co., Ltd.
"^allegro,.*":
description: Allegro DVT
"^allegromicro,.*":
--
2.54.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* [PATCH 0/7] ARM: rockchip: rv1126: Add support for Alientek ATK-DLRV1126
From: Yanan He @ 2026-06-24 8:44 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, David Wu, Maxime Coquelin, Alexandre Torgue
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-rockchip,
netdev, linux-stm32, Yanan He
The ATK-DLRV1126 board consists of a CLRV1126F core module and a
DLRV1126 carrier board. The core module contains the Rockchip RV1126
SoC, eMMC and RK809 PMIC. The carrier board provides Gigabit Ethernet,
SD card, AP6212 WiFi and Bluetooth, PCF8563 RTC, ADC keys, GPIO LEDs and
audio connectors.
This series adds the Alientek vendor prefix and board compatible, updates
the Rockchip DWMAC binding and driver for the RV1126 GMAC reference
output clock, adds missing RV1126 SoC description pieces, and finally
adds the CLRV1126F core module and DLRV1126 carrier board device trees.
The board was tested with Ethernet/NFS boot, eMMC, SD card, SDIO WiFi
enumeration, Bluetooth LE scanning, RTC, ADC keys, GPIO LEDs and RK809
audio card registration.
Signed-off-by: Yanan He <grumpycat921013@gmail.com>
---
Yanan He (7):
dt-bindings: vendor-prefixes: add alientek
dt-bindings: arm: rockchip: Add Alientek DLRV1126
dt-bindings: net: rockchip-dwmac: Allow 9 clocks
net: stmmac: dwmac-rk: Enable refout clock for RGMII
ARM: dts: rockchip: Add RV1126 GMAC refout clock
ARM: dts: rockchip: Add RV1126 I2C5
ARM: dts: rockchip: Add Alientek DLRV1126
.../devicetree/bindings/arm/rockchip.yaml | 7 +
.../devicetree/bindings/net/rockchip-dwmac.yaml | 2 +-
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
arch/arm/boot/dts/rockchip/Makefile | 1 +
.../dts/rockchip/rv1126-alientek-clrv1126f.dtsi | 277 +++++++++++++++++++++
.../boot/dts/rockchip/rv1126-alientek-dlrv1126.dts | 258 +++++++++++++++++++
arch/arm/boot/dts/rockchip/rv1126-pinctrl.dtsi | 10 +
arch/arm/boot/dts/rockchip/rv1126.dtsi | 18 +-
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 6 +-
9 files changed, 577 insertions(+), 4 deletions(-)
---
base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6
change-id: 20260618-rv1126-alientek-dlrv1126-d94abdcf8580
Best regards,
--
Yanan He <grumpycat921013@gmail.com>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* [PATCH v1] ASoC: rockchip: rockchip_sai: #include <linux/platform_device.h> explicitly
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-24 8:37 UTC (permalink / raw)
To: Nicolas Frattaroli, Liam Girdwood, Mark Brown, Jaroslav Kysela,
Takashi Iwai
Cc: Heiko Stuebner, linux-rockchip, linux-sound, linux-arm-kernel,
linux-kernel
Currently that header is only included via:
<sound/dmaengine_pcm.h> ->
<sound/soc.h> ->
<linux/platform_device.h>
which doesn't look reliable, still more in the presence of the comment:
/* For the current users of sound/soc.h to avoid build issues */
in <sound/soc.h>.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
sound/soc/rockchip/rockchip_sai.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/rockchip/rockchip_sai.c b/sound/soc/rockchip/rockchip_sai.c
index a195e96fed0a..37e81d56bc16 100644
--- a/sound/soc/rockchip/rockchip_sai.c
+++ b/sound/soc/rockchip/rockchip_sai.c
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/of_device.h>
#include <linux/clk.h>
+#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
base-commit: ef0c9f75a19532d7675384708fc8621e10850104
--
2.47.3
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* Re: [PATCH 0/2] gpio: fix sleeping-in-atomic in shared-proxy; restore meson non-sleeping
From: Bartosz Golaszewski @ 2026-06-24 7:25 UTC (permalink / raw)
To: Robin Murphy
Cc: Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Diederik de Haas, linux-gpio, linux-arm-kernel, linux-amlogic,
linux-kernel, linux-rockchip, Heiko Stuebner, Marek Szyprowski,
Viacheslav Bocharov, Linus Walleij, Bartosz Golaszewski
In-Reply-To: <112d2563-e650-4881-bba0-335f6a3fcb8a@arm.com>
On Tue, 23 Jun 2026 17:16:44 +0200, Robin Murphy <robin.murphy@arm.com> said:
> On 11/06/2026 9:26 am, Marek Szyprowski wrote:
>> Hi Viachesla,
>>
>> On 10.06.2026 17:32, Viacheslav Bocharov wrote:
>>> gpio-shared-proxy chooses its descriptor lock (mutex vs spinlock) from
>>> the underlying chip's can_sleep, but under that lock it calls config and
>>> direction ops that reach sleeping pinctrl paths. On a controller with
>>> non-sleeping MMIO value ops the lock is a spinlock, so a sleeping call
>>> runs from atomic context:
>>>
...
>>
>> I've checked this patchset with these two reverted and no warning was reported.
>
> If it hadn't already been fixed (...)
>
About that - Viacheslav, do you still plan to submit v2 of this?
Bart
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* [PATCH] can: rockchip_canfd: Propagate reset failures on start
From: Pengpeng Hou @ 2026-06-24 5:50 UTC (permalink / raw)
To: Marc Kleine-Budde, kernel, Vincent Mailhol, Heiko Stuebner,
Philipp Zabel
Cc: linux-can, linux-arm-kernel, linux-rockchip, linux-kernel,
Pengpeng Hou
The Rockchip CAN-FD driver requires a reset controller, but
rkcanfd_chip_set_reset_mode() ignores reset assert/deassert failures.
rkcanfd_open() and CAN_MODE_START can then report success after the
controller failed to enter a known reset state.
Return reset errors from the reset/start helpers and propagate them
before enabling RX offload, requesting the IRQ, or starting the netdev
queue.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
.../net/can/rockchip/rockchip_canfd-core.c | 40 +++++++++++++++----
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/drivers/net/can/rockchip/rockchip_canfd-core.c b/drivers/net/can/rockchip/rockchip_canfd-core.c
index 29de0c01e4ed..89bc402b76e8 100644
--- a/drivers/net/can/rockchip/rockchip_canfd-core.c
+++ b/drivers/net/can/rockchip/rockchip_canfd-core.c
@@ -102,13 +102,23 @@ static const struct can_bittiming_const rkcanfd_data_bittiming_const = {
.brp_inc = 2, /* value from data sheet x2 */
};
-static void rkcanfd_chip_set_reset_mode(const struct rkcanfd_priv *priv)
+static int rkcanfd_chip_set_reset_mode(const struct rkcanfd_priv *priv)
{
- reset_control_assert(priv->reset);
+ int err;
+
+ err = reset_control_assert(priv->reset);
+ if (err)
+ return err;
+
udelay(2);
- reset_control_deassert(priv->reset);
+
+ err = reset_control_deassert(priv->reset);
+ if (err)
+ return err;
rkcanfd_write(priv, RKCANFD_REG_MODE, 0x0);
+
+ return 0;
}
static void rkcanfd_chip_set_work_mode(const struct rkcanfd_priv *priv)
@@ -246,11 +256,14 @@ static void rkcanfd_chip_fifo_setup(struct rkcanfd_priv *priv)
netdev_reset_queue(priv->ndev);
}
-static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
+static int rkcanfd_chip_start(struct rkcanfd_priv *priv)
{
u32 reg;
+ int err;
- rkcanfd_chip_set_reset_mode(priv);
+ err = rkcanfd_chip_set_reset_mode(priv);
+ if (err)
+ return err;
/* Receiving Filter: accept all */
rkcanfd_write(priv, RKCANFD_REG_IDCODE, 0x0);
@@ -309,13 +322,16 @@ static void rkcanfd_chip_start(struct rkcanfd_priv *priv)
netdev_dbg(priv->ndev, "%s: reg_mode=0x%08x\n", __func__,
rkcanfd_read(priv, RKCANFD_REG_MODE));
+
+ return 0;
}
static void __rkcanfd_chip_stop(struct rkcanfd_priv *priv, const enum can_state state)
{
priv->can.state = state;
- rkcanfd_chip_set_reset_mode(priv);
+ if (rkcanfd_chip_set_reset_mode(priv))
+ netdev_err(priv->ndev, "Failed to reset CAN-FD controller\n");
rkcanfd_chip_interrupts_disable(priv);
}
@@ -339,10 +355,14 @@ static int rkcanfd_set_mode(struct net_device *ndev,
enum can_mode mode)
{
struct rkcanfd_priv *priv = netdev_priv(ndev);
+ int err;
switch (mode) {
case CAN_MODE_START:
- rkcanfd_chip_start(priv);
+ err = rkcanfd_chip_start(priv);
+ if (err)
+ return err;
+
rkcanfd_chip_interrupts_enable(priv);
netif_wake_queue(ndev);
break;
@@ -719,7 +739,10 @@ static int rkcanfd_open(struct net_device *ndev)
if (err)
goto out_close_candev;
- rkcanfd_chip_start(priv);
+ err = rkcanfd_chip_start(priv);
+ if (err)
+ goto out_runtime_put;
+
can_rx_offload_enable(&priv->offload);
err = request_irq(ndev->irq, rkcanfd_irq, IRQF_SHARED, ndev->name, priv);
@@ -734,6 +757,7 @@ static int rkcanfd_open(struct net_device *ndev)
out_rkcanfd_chip_stop:
rkcanfd_chip_stop_sync(priv, CAN_STATE_STOPPED);
+out_runtime_put:
pm_runtime_put(ndev->dev.parent);
out_close_candev:
close_candev(ndev);
--
2.50.1 (Apple Git-155)
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply related
* Re: [RFC PATCH 1/6] media: mc: Implement shared media graph
From: Paul Elder @ 2026-06-24 4:47 UTC (permalink / raw)
To: laurent.pinchart
Cc: michael.riesch, xuhf, stefan.klug, kieran.bingham, dan.scally,
jacopo.mondi, linux-media, linux-arm-kernel, linux-rockchip,
linux-kernel, hverkuil+cisco, nicolas.dufresne, ribalda,
sakari.ailus
In-Reply-To: <20260619052637.1110672-2-paul.elder@ideasonboard.com>
Hi me,
You have a typo...
Quoting Paul Elder (2026-06-19 14:26:28)
> Currently, a media graph contains a main device whose driver is
> responsible for creating the media device. We have however recently run
> into devices that have multiple devices that can quality as a main
> device. Examples are the RK3588 which has a VICAP and two ISP
> instances, and another example is the i.MX8MP which has an ISI and two
> ISP instances. As there is currently no way to reconcile who the main
> device is in the media device, these setups simple cannot be used
> simultaneously.
>
> This patch extends the media controller API with a "shared media graph"
> framework. This allows drivers to share a media device, thus enabling
> the setups mentioned above. Instead of owning and creating a media
> device, drivers can join-or-create a shared media device via the shared
> media graph API. The matching is done automatically based on the
> detected endpoints in the device tree.
>
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> ---
> drivers/media/mc/Makefile | 2 +-
> drivers/media/mc/mc-shared-graph.c | 335 +++++++++++++++++++++++++++++
> include/media/mc-shared-graph.h | 92 ++++++++
> 3 files changed, 428 insertions(+), 1 deletion(-)
> create mode 100644 drivers/media/mc/mc-shared-graph.c
> create mode 100644 include/media/mc-shared-graph.h
>
> diff --git a/drivers/media/mc/Makefile b/drivers/media/mc/Makefile
> index 2b7af42ba59c..1d502fdc52ad 100644
> --- a/drivers/media/mc/Makefile
> +++ b/drivers/media/mc/Makefile
> @@ -1,7 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0
>
> mc-objs := mc-device.o mc-devnode.o mc-entity.o \
> - mc-request.o
> + mc-request.o mc-shared-graph.o
>
> ifneq ($(CONFIG_USB),)
> mc-objs += mc-dev-allocator.o
> diff --git a/drivers/media/mc/mc-shared-graph.c b/drivers/media/mc/mc-shared-graph.c
> new file mode 100644
> index 000000000000..c4067e5b861d
> --- /dev/null
> +++ b/drivers/media/mc/mc-shared-graph.c
> @@ -0,0 +1,335 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * mc-shared-graph.c - Media Controller Shared Graph API
> + *
> + * Copyright (c) 2026 Paul Elder <paul.elder@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds the Media Controller Shared Graph API. This allows drivers
> + * to create shared media graphs or join existing media graphs from other
> + * drivers, so that they can all be in the same media graph. This allows us to
> + * have more complex media graphs chaining more complex hardware together,
> + * instead of simple async subdevs.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/fwnode.h>
> +#include <linux/kref.h>
> +#include <linux/property.h>
> +
> +#include <media/media-device.h>
> +
> +#include <media/mc-shared-graph.h>
> +
> +static LIST_HEAD(media_device_shared_list);
> +static DEFINE_MUTEX(media_device_shared_lock);
> +
> +struct media_device_shared_member {
> + struct device *dev;
> + struct fwnode_handle *fwnode;
> + struct list_head list;
> +};
> +
> +struct media_device_shared_link {
> + struct media_entity *source;
> + u16 source_pad;
> + struct media_entity *sink;
> + u16 sink_pad;
> + u32 flags;
> + struct list_head list;
> +};
> +
> +// TODO figure out locking for when multiple drivers touch the media graph;
> +// maybe macros for shared versions?
> +struct media_device_shared {
> + struct media_device mdev;
> + struct list_head members;
> + struct list_head links;
> +
> + struct list_head list;
> + struct kref refcount;
> +
> + struct device *removed_device;
> +};
> +
> +static inline struct media_device_shared *
> +to_media_device_shared(struct media_device *mdev)
> +{
> + return container_of(mdev, struct media_device_shared, mdev);
> +}
> +
> +static void media_device_shared_release(struct kref *kref)
> +{
> + struct media_device_shared *mds =
> + container_of(kref, struct media_device_shared, refcount);
> +
> + dev_dbg(mds->removed_device, "%s: releasing Media Device\n", __func__);
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + media_device_unregister(&mds->mdev);
> + media_device_cleanup(&mds->mdev);
> +
> + list_del(&mds->list);
> + mutex_unlock(&media_device_shared_lock);
> +
> + kfree(mds);
> +}
> +
> +/* Callers should hold media_device_shared_lock when calling this function */
> +static bool __media_device_shared_find_match(struct media_device_shared *mds,
> + struct fwnode_handle *fwnode)
> +{
> + struct media_device_shared_member *member;
> + struct fwnode_handle *ep;
> + struct fwnode_handle *remote_ep;
> + bool match = false;
> +
> + // TODO: parse the device tree endpoints graph instead of finding just the
> + // first-level neighbours
> + fwnode_graph_for_each_endpoint(fwnode, ep) {
> + list_for_each_entry(member, &mds->members, list) {
> + remote_ep = fwnode_graph_get_remote_port_parent(ep);
> + match = (member->fwnode == remote_ep);
> + fwnode_handle_put(remote_ep);
> +
> + if (!match)
> + continue;
> +
> + goto match_complete;
> + }
> + }
> +
> +match_complete:
> + fwnode_handle_put(ep);
> + return match;
> +}
> +
> +/* Callers should hold media_device_shared_lock when calling this function */
> +static struct media_device *__media_device_shared_get(struct device *dev)
> +{
> + struct media_device_shared *mds;
> + struct media_device_shared_member *member;
> + struct fwnode_handle *fwnode = dev_fwnode(dev);
> + bool ret;
> +
> + dev_dbg(dev, "%s: searching for media device for %pfwf", __func__, fwnode);
> +
> + list_for_each_entry(mds, &media_device_shared_list, list) {
> + ret = __media_device_shared_find_match(mds, fwnode);
> + if (ret)
> + break;
> + }
> +
> + if (!ret)
> + return NULL;
> +
> + member = kzalloc_obj(*member);
> + if (!member)
> + return NULL;
> +
> + member->dev = dev;
> + member->fwnode = fwnode;
> + list_add_tail(&member->list, &mds->members);
> + kref_get(&mds->refcount);
> +
> + dev_dbg(dev, "%s: %pfwf joined media device of %pfwf",
> + __func__, fwnode,
> + list_first_entry(&mds->members, struct media_device_shared_member, list)->fwnode);
> +
> + return &mds->mdev;
> +}
> +
> +/* Callers should hold media_device_shared_lock when calling this function */
> +static struct media_device *__media_device_shared_create(struct device *dev)
> +{
> + struct media_device_shared *mds;
> + struct media_device_shared_member *member;
> + struct fwnode_handle *fwnode = dev_fwnode(dev);
> + int ret;
> +
> + mds = kzalloc_obj(*mds);
> + if (!mds)
> + return NULL;
> +
> + member = kzalloc_obj(*member);
> + if (!member)
> + goto err_free_mds;
> +
> + media_device_init(&mds->mdev);
> +
> + ret = media_device_register(&mds->mdev);
> + if (ret)
> + goto err_free_member;
> +
> + INIT_LIST_HEAD(&mds->members);
> + member->dev = dev;
> + member->fwnode = fwnode;
> + list_add_tail(&member->list, &mds->members);
> +
> + INIT_LIST_HEAD(&mds->links);
> +
> + kref_init(&mds->refcount);
> + list_add_tail(&mds->list, &media_device_shared_list);
> +
> + // TODO figure out how to reconcile this with multiple members
> + mds->mdev.dev = dev;
> +
> + devv_dbg(dev, "%s: Allocated media device with %pfwf at %p\n",
here:
s/devv/dev/
Paul
> + __func__, fwnode, &mds->mdev);
> + return &mds->mdev;
> +
> +err_free_member:
> + kfree(member);
> +err_free_mds:
> + kfree(mds);
> + return NULL;
> +}
> +
> +// TODO figure out how to resolve the identifiers (model, driver name, etc);
> +// atm it's racy and whoever gets it last wins
> +struct media_device *media_device_shared_join(struct device *dev)
> +{
> + struct media_device *mdev;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + mdev = __media_device_shared_get(dev);
> + if (!!mdev) {
> + dev_dbg(dev, "%s: found media device for %pfwf", __func__, dev_fwnode(dev));
> + mutex_unlock(&media_device_shared_lock);
> + return mdev;
> + }
> +
> + mdev = __media_device_shared_create(dev);
> + if (!mdev) {
> + dev_warn(dev, "%s: failed to create media device for %pfwf", __func__, dev_fwnode(dev));
> + mutex_unlock(&media_device_shared_lock);
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + dev_dbg(dev, "%s: created media device for %pfwf", __func__, dev_fwnode(dev));
> + mutex_unlock(&media_device_shared_lock);
> + return mdev;
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_join);
> +
> +void media_device_shared_leave(struct media_device *mdev, struct device *dev)
> +{
> + struct media_device_shared *mds = to_media_device_shared(mdev);
> + struct media_device_shared_member *member;
> + struct media_device_shared_member *member_tmp;
> + bool removed = false;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + list_for_each_entry_safe(member, member_tmp, &mds->members, list) {
> + if (member->dev == dev) {
> + list_del(&member->list);
> + kfree(member);
> + removed = true;
> + }
> + }
> +
> + if (!removed)
> + dev_err(dev, "%s: %pfwf trying to leave from graph in which not a member",
> + __func__, dev_fwnode(dev));
> +
> + mds->removed_device = dev;
> + mutex_unlock(&media_device_shared_lock);
> + kref_put(&mds->refcount, media_device_shared_release);
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_leave);
> +
> +int media_device_shared_join_link_source(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *source,
> + u16 source_pad, u32 flags)
> +{
> + struct media_device_shared *mds = to_media_device_shared(mdev);
> + struct media_device_shared_link *link;
> + struct media_device_shared_link *link_tmp;
> + int ret = 0;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + /*
> + * TODO Figure out flags. Should we use greatest common denominator? Or
> + * prioritize sink? Or whoever wins the race? For now we just take the flags
> + * from the sink.
> + *
> + * TODO Figure out how to actually do the matching. For now we just match
> + * whoever comes in first. This works with the simple example we're running
> + * with now (rkcif + one rkisp2) but with setups with multiple copies of
> + * hardware this will cause problems, like with rkcif + two rkisp2 and
> + * imx8-isi + two rkisp1.
> + */
> + list_for_each_entry_safe(link, link_tmp, &mds->links, list) {
> + if (link->sink) {
> + ret = media_create_pad_link(source, source_pad,
> + link->sink, link->sink_pad,
> + link->flags);
> + list_del(&link->list);
> + kfree(link);
> + goto exit_join_link_source;
> + }
> + }
> +
> + link = kzalloc_obj(*link);
> + if (!link) {
> + ret = -ENOMEM;
> + goto exit_join_link_source;
> + }
> +
> + link->source = source;
> + link->source_pad = source_pad;
> + link->flags = flags;
> + list_add_tail(&link->list, &mds->links);
> +
> +exit_join_link_source:
> + mutex_unlock(&media_device_shared_lock);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_join_link_source);
> +
> +// TODO deduplicate from above
> +int media_device_shared_join_link_sink(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *sink,
> + u16 sink_pad, u32 flags)
> +{
> + struct media_device_shared *mds = to_media_device_shared(mdev);
> + struct media_device_shared_link *link;
> + struct media_device_shared_link *link_tmp;
> + int ret = 0;
> +
> + mutex_lock(&media_device_shared_lock);
> +
> + list_for_each_entry_safe(link, link_tmp, &mds->links, list) {
> + if (link->source) {
> + ret = media_create_pad_link(link->source, link->source_pad,
> + sink, sink_pad,
> + flags);
> + list_del(&link->list);
> + kfree(link);
> + goto exit_join_link_sink;
> + }
> + }
> +
> + link = kzalloc_obj(*link);
> + if (!link) {
> + ret = -ENOMEM;
> + goto exit_join_link_sink;
> + }
> +
> + link->sink = sink;
> + link->sink_pad = sink_pad;
> + link->flags = flags;
> + list_add_tail(&link->list, &mds->links);
> +
> +exit_join_link_sink:
> + mutex_unlock(&media_device_shared_lock);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(media_device_shared_join_link_sink);
> diff --git a/include/media/mc-shared-graph.h b/include/media/mc-shared-graph.h
> new file mode 100644
> index 000000000000..487325163f84
> --- /dev/null
> +++ b/include/media/mc-shared-graph.h
> @@ -0,0 +1,92 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * mc-shared-graph.h - Media Controller Shared Graph API
> + *
> + * Copyright (c) 2026 Paul Elder <paul.elder@ideasonboard.com>
> + */
> +
> +/*
> + * This file adds the Media Controller Shared Graph API. This allows drivers
> + * to create shared media graphs or join existing media graphs from other
> + * drivers, so that they can all be in the same media graph. This allows us to
> + * have more complex media graphs chaining more complex hardware together,
> + * instead of simple async subdevs.
> + */
> +
> +#include <linux/types.h>
> +
> +#ifndef _MEDIA_SHARED_GRAPH_H
> +#define _MEDIA_SHARED_GRAPH_H
> +
> +struct device;
> +struct media_device;
> +struct media_entity;
> +
> +#if defined(CONFIG_MEDIA_CONTROLLER)
> +/**
> + * media_device_shared_join() - Join or create a new shared media device
> + *
> + * @dev: struct &device pointer
> + *
> + * This is the entrance function for a device to join or create a new shared
> + * media device. It searches for an existing shared media device based on the
> + * neighbours in the device's device tree ports node. If found, then this
> + * functions returns the existing shared media device and joins it. If one is
> + * not found then one is created and initialized and returned.
> + */
> +struct media_device *media_device_shared_join(struct device *dev);
> +
> +/**
> + * media_device_shared_leave() - Leave the shared media device.
> + *
> + * @mdev: struct &media_device pointer
> + * @dev: struct &device pointer
> + *
> + * This function makes the device leave the shared media device. When all
> + * members have left the media device it will be freed.
> + */
> +void media_device_shared_leave(struct media_device *mdev, struct device *dev);
> +
> +/**
> + * media_device_shared_join_link_source() - Register a link source in the shared media device
> + *
> + * @mdev: The struct &media_device pointer that is part of a shared media device
> + * @dev: struct &device pointer
> + * @source: The link source
> + * @source_pad: The pad
> + * @flags: The flags
> + *
> + * This function registers with the shared media device the source part of a
> + * link. When the shared media device receives the matching sink part of a link
> + * via media_device_shared_join_link_sink() then the link will be fully created.
> + */
> +int media_device_shared_join_link_source(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *source,
> + u16 source_pad, u32 flags);
> +
> +/**
> + * media_device_shared_join_link_sink() - Register a link sink in the shared media device
> + *
> + * Same as media_device_shared_join_link_source() but for sink instead of
> + * source.
> + */
> +int media_device_shared_join_link_sink(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *sink,
> + u16 sink_pad, u32 flags);
> +#else
> +static inline struct media_device *media_device_shared_join(struct device *dev)
> +{ return NULL; }
> +static inline void media_device_shared_leave(struct media_device *mdev,
> + struct device *dev) { }
> +static inline int media_device_shared_join_link_source(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *source,
> + u16 source_pad, u32 flags) { }
> +static inline int media_device_shared_join_link_sink(struct media_device *mdev,
> + struct device *dev,
> + struct media_entity *sink,
> + u16 sink_pad, u32 flags) { }
> +#endif /* CONFIG_MEDIA_CONTROLLER */
> +#endif /* _MEDIA_DEV_SHARED_GRAPH_H */
> --
> 2.47.2
>
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* Re: [REGRESSION][BISECTED] No display on rk3399-gru-kevin
From: Damon Ding @ 2026-06-24 4:00 UTC (permalink / raw)
To: Vicente Bergas
Cc: Heiko Stübner, Shawn Lin, Sandy Huang, Andy Yan,
open list:ARM/Rockchip SoC...
In-Reply-To: <CAAMcf8D-d+5n=H44KeKBSqWY42m+o32W+mO-r15VqWNyYhJL7Q@mail.gmail.com>
On 6/23/2026 1:08 AM, Vicente Bergas wrote:
> On Mon, Jun 22, 2026 at 4:02 AM Damon Ding <damon.ding@rock-chips.com> wrote:
>>
>> Hi Vicente,
>>
>> On 6/19/2026 7:51 AM, Vicente Bergas wrote:
>>> On Thu, Jun 18, 2026 at 5:49 AM Damon Ding <damon.ding@rock-chips.com> wrote:
>>>>
>>>> Hi Vicente,
>>>>
>>>> On 6/18/2026 7:15 AM, Vicente Bergas wrote:
>>>>> On Wed, Jun 17, 2026 at 10:45 AM Heiko Stübner <heiko@sntech.de> wrote:
>>>>>>
>>>>>> Hi Vicente,
>>>>>>
>>>>>> Am Mittwoch, 17. Juni 2026, 01:05:27 Mitteleuropäische Sommerzeit schrieb Vicente Bergas:
>>>>>>> Hello,
>>>>>>> there are two issues that result on a black screen on the rk3399-gru-kevin.
>>>>>>>
>>>>>>> The first one is due to:
>>>>>>> c8079f83e0bf312645050c17d9c87deb707369c1
>>>>>>> gpio: rockchip: convert to dynamic GPIO base allocation
>>>>>>
>>>>>> can you check that your kernel contains
>>>>>> "gpio: rockchip: Fix GPIO regression after conversion to dynamic base allocation"
>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=5cd9c6d332f46d1de8b68117fe2a3f1b08ee80ff
>>>>>
>>>>> Yes, that commit is in v7.1 and it indeed fixes the gpio issue.
>>>>> I tested reverting c8079f83 alone and reverting all three.
>>>>> Now i've tested only reverting 51eb548a and d84b087c, and it works.
>>>>> The thing is both bugs coexisted at some point and
>>>>> git bisect finds them in order.
>>>>>
>>>>>>> Reverting this does not fix the problem as there is a second one:
>>>>>>> 51eb548ade20158b4f4f8693a95b1f31a2480e8e
>>>>>>> drm/bridge: analogix_dp: Apply DP helper API drm_dp_channel_eq_ok()
>>>>>>>
>>>>>>> That second one depends on:
>>>>>>> d84b087c7662dd65cd51b228219987c31b1cee02
>>>>>>> drm/bridge: analogix_dp: Apply DP helper APIs to get adjusted voltages
>>>>>>> and pre-emphasises
>>>>>>>
>>>>>>> Reverting all three commits from v7.1 make the display work again.
>>>>>>>
>>>>>>> Please, can this be resolved?
>>>>>>
>>>>>> and as Damon wrote, please provide logs, so we can see the actual problem
>>>>>
>>>>> It is quite difficult to read the logs from a black screen...
>>>>> Jokes apart, here they are:
>>>>>
>>>>> Relevant log entries:
>>>>> <6>[ 0.043668] /dp@fec00000: Fixed dependency cycle(s) with /vop@ff8f0000
>>>>> <6>[ 0.043735] /vop@ff8f0000: Fixed dependency cycle(s) with /dp@fec00000
>>>>> <6>[ 0.044192] /dp@fec00000: Fixed dependency cycle(s) with /vop@ff900000
>>>>> <6>[ 0.044250] /vop@ff900000: Fixed dependency cycle(s) with /dp@fec00000
>>>>> <6>[ 0.045064] /vop@ff900000: Fixed dependency cycle(s) with /dp@ff970000
>>>>> <6>[ 0.045122] /vop@ff8f0000: Fixed dependency cycle(s) with /dp@ff970000
>>>>> <6>[ 0.045194] /dp@ff970000: Fixed dependency cycle(s) with /vop@ff8f0000
>>>>> <6>[ 0.045264] /dp@ff970000: Fixed dependency cycle(s) with /vop@ff900000
>>>>> <6>[ 0.058590] /dp@ff970000: Fixed dependency cycle(s) with /edp-panel
>>>>> <6>[ 0.058733] /edp-panel: Fixed dependency cycle(s) with /dp@ff970000
>>>>> <6>[ 0.101266] platform ff8f0000.vop: Adding to iommu group 2
>>>>> <6>[ 0.102073] platform ff900000.vop: Adding to iommu group 3
>>>>> <3>[ 0.105258] rockchip-dp ff970000.dp: no DP phy configured
>>>>> <3>[ 0.308638] rockchip-dp ff970000.dp: no DP phy configured
>>>>> <6>[ 0.310104] panfrost ff9a0000.gpu: clock rate = 500000000
>>>>> <6>[ 0.311210] panfrost ff9a0000.gpu: mali-t860 id 0x860 major 0x2
>>>>> minor 0x0 status 0x0
>>>>> <6>[ 0.311223] panfrost ff9a0000.gpu: features: 00000000,00000407,
>>>>> issues: 00000000,24040400
>>>>> <6>[ 0.311231] panfrost ff9a0000.gpu: Features: L2:0x07120206
>>>>> Shader:0x00000000 Tiler:0x00000809 Mem:0x1 MMU:0x00002830 AS:0xff
>>>>> JS:0x7
>>>>> <6>[ 0.311239] panfrost ff9a0000.gpu: shader_present=0xf l2_present=0x1
>>>>> <6>[ 0.312664] [drm] Initialized panfrost 1.6.0 for ff9a0000.gpu on minor 0
>>>>> <3>[ 0.624232] rockchip-dp ff970000.dp: no DP phy configured
>>>>> <3>[ 0.639611] rockchip-dp ff970000.dp: no DP phy configured
>>>>> <6>[ 0.641512] rockchip-drm display-subsystem: bound ff900000.vop
>>>>> (ops 0xffff800080c9a3c8)
>>>>> <6>[ 0.642646] rockchip-drm display-subsystem: bound ff8f0000.vop
>>>>> (ops 0xffff800080c9a3c8)
>>>>> <4>[ 0.643198] [drm] Missing drm_bridge_add() before attach
>>>>> <6>[ 0.643238] rockchip-drm display-subsystem: bound ff970000.dp
>>>>> (ops 0xffff800080c9e840)
>>>>> <6>[ 0.644029] rockchip-drm display-subsystem: bound fec00000.dp
>>>>> (ops 0xffff800080c9f0c8)
>>>>> <6>[ 0.644102] cdn-dp fec00000.dp: [drm:cdn_dp_pd_event_work] Not
>>>>> connected; disabling cdn
>>>>> <6>[ 0.644837] [drm] Initialized rockchip 1.0.0 for
>>>>> display-subsystem on minor 1
>>>>> <4>[ 0.786773] panel-edp edp-panel: Skipping disable of already
>>>>> disabled panel
>>>>> <3>[ 0.796517] rockchip-dp ff970000.dp: EQ Max loop
>>>>> <3>[ 0.797745] rockchip-dp ff970000.dp: LT EQ failed!
>>>>> <3>[ 0.797757] rockchip-dp ff970000.dp: eDP link training failed (-5)
>>>>> <3>[ 0.797770] rockchip-dp ff970000.dp: unable to do link train, ret=-5
>>>>> <3>[ 0.797783] [drm:analogix_dp_bridge_atomic_enable] *ERROR* dp
>>>>> commit error, ret = -5
>>>>> <3>[ 0.797823] rockchip-dp ff970000.dp: failed to set bridge, retry: 0
>>>>> <4>[ 0.797937] panel-edp edp-panel: Skipping disable of already
>>>>> disabled panel
>>>>> <3>[ 0.808097] rockchip-dp ff970000.dp: EQ Max loop
>>>>> <3>[ 0.809284] rockchip-dp ff970000.dp: LT EQ failed!
>>>>> <3>[ 0.809299] rockchip-dp ff970000.dp: eDP link training failed (-5)
>>>>> <3>[ 0.809314] rockchip-dp ff970000.dp: unable to do link train, ret=-5
>>>>> <3>[ 0.809326] [drm:analogix_dp_bridge_atomic_enable] *ERROR* dp
>>>>> commit error, ret = -5
>>>>> <3>[ 0.809353] rockchip-dp ff970000.dp: failed to set bridge, retry: 1
>>>>> <4>[ 0.809463] panel-edp edp-panel: Skipping disable of already
>>>>> disabled panel
>>>>> <3>[ 0.819481] rockchip-dp ff970000.dp: EQ Max loop
>>>>> <3>[ 0.820745] rockchip-dp ff970000.dp: LT EQ failed!
>>>>> <3>[ 0.820758] rockchip-dp ff970000.dp: eDP link training failed (-5)
>>>>> <3>[ 0.820772] rockchip-dp ff970000.dp: unable to do link train, ret=-5
>>>>> <3>[ 0.820781] [drm:analogix_dp_bridge_atomic_enable] *ERROR* dp
>>>>> commit error, ret = -5
>>>>> <3>[ 0.820806] rockchip-dp ff970000.dp: failed to set bridge, retry: 2
>>>>> <4>[ 0.820919] panel-edp edp-panel: Skipping disable of already
>>>>> disabled panel
>>>>> <3>[ 0.831075] rockchip-dp ff970000.dp: EQ Max loop
>>>>> <3>[ 0.832336] rockchip-dp ff970000.dp: LT EQ failed!
>>>>> <3>[ 0.832346] rockchip-dp ff970000.dp: eDP link training failed (-5)
>>>>> <3>[ 0.832356] rockchip-dp ff970000.dp: unable to do link train, ret=-5
>>>>> <3>[ 0.832367] [drm:analogix_dp_bridge_atomic_enable] *ERROR* dp
>>>>> commit error, ret = -5
>>>>> <3>[ 0.832388] rockchip-dp ff970000.dp: failed to set bridge, retry: 3
>>>>> <4>[ 0.832496] panel-edp edp-panel: Skipping disable of already
>>>>> disabled panel
>>>>> <3>[ 0.842613] rockchip-dp ff970000.dp: EQ Max loop
>>>>> <3>[ 0.843754] rockchip-dp ff970000.dp: LT EQ failed!
>>>>> <3>[ 0.843765] rockchip-dp ff970000.dp: eDP link training failed (-5)
>>>>> <3>[ 0.843778] rockchip-dp ff970000.dp: unable to do link train, ret=-5
>>>>> <3>[ 0.843791] [drm:analogix_dp_bridge_atomic_enable] *ERROR* dp
>>>>> commit error, ret = -5
>>>>> <3>[ 0.843815] rockchip-dp ff970000.dp: failed to set bridge, retry: 4
>>>>> <3>[ 0.843857] rockchip-dp ff970000.dp: too many times retry set
>>>>> bridge, give it up
>>>>> <6>[ 0.854625] Console: switching to colour frame buffer device 300x100
>>>>> <6>[ 0.887526] rockchip-drm display-subsystem: [drm] fb0:
>>>>> rockchipdrmfb frame buffer device
>>>>>
>>>>>
>>>>
>>>> I have tested RK3399 IND EVB locally based on kernel v7.1, and eDP
>>>> training completes successfully with normal display output with patch
>>>> 0001-arm64-dts-rockchip-Enable-eDP-display-for-RK3399-IND.patch applied.
>>>>
>>>> From your logs, the failure occurs during the EQ stage of eDP training.
>>>> Please apply the additional patch
>>>> 0002-drm-bridge-analogix_dp-Read-CR-EQ-delay-from-DPCD-in.patch without
>>>> reverting the two commits mentioned above (51eb548a and d84b087c), then
>>>> retest to check if the issue gets improved.
>>>> (BTW: This is a test-only temporary patch with minor style flaws, but
>>>> the patch needs upstreaming. I'll rework and send a formal version soon.)
>>>
>>> Hi Damon,
>>> applying patch 0001 and 0002 does not fix the issue.
>>> The logs are mostly the same.
>>>
>>>> If the problem persists, try adding a small delay at the location
>>>> mentioned below for further verification:
>>>
>>> applying the extra delay results are the same, just small noise in the
>>> dmesg timestamps.
>>>
>>> Besides this, i've done another test:
>>> i have reverted 51eb548a while keeping d84b087c, which i had to rebase.
>>> The result is again the same: black screen and the logs are again equivalent.
>>> That proves that both patches 51eb548a and d84b087c each introduce a regression.
>>>
>>
>> Thanks a lot for all these thorough tests, your results give me much
>> clearer clues.
>>
>> I suspect the root cause is not the EQ training delay, but incorrect PE
>> (pre-emphasis) and VS (voltage swing) register configuration.
>>
>> Please do not revert any of the two commits mentioned above. Instead,
>> apply the following patch which may properly resolve the black screen
>> issue you are seeing:
>>
>> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> index a5dc645d7005..30ad952c5c12 100644
>> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
>> @@ -306,7 +306,9 @@ static void
>> analogix_dp_get_adjust_training_lane(struct analogix_dp_device *dp,
>> lane_count = dp->link_train.lane_count;
>> for (lane = 0; lane < lane_count; lane++) {
>> voltage_swing =
>> drm_dp_get_adjust_request_voltage(link_status, lane);
>> + voltage_swing >>= DP_TRAIN_VOLTAGE_SWING_SHIFT;
>> pre_emphasis =
>> drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
>> + pre_emphasis >>= DP_TRAIN_PRE_EMPHASIS_SHIFT;
>> training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
>> DPCD_PRE_EMPHASIS_SET(pre_emphasis);
>>
>> @@ -352,7 +354,9 @@ static int analogix_dp_process_clock_recovery(struct
>> analogix_dp_device *dp)
>> for (lane = 0; lane < lane_count; lane++) {
>> training_lane = analogix_dp_get_lane_link_training(dp,
>> lane);
>> voltage_swing =
>> drm_dp_get_adjust_request_voltage(link_status, lane);
>> + voltage_swing >>= DP_TRAIN_VOLTAGE_SWING_SHIFT;
>> pre_emphasis =
>> drm_dp_get_adjust_request_pre_emphasis(link_status, lane);
>> + pre_emphasis >>= DP_TRAIN_PRE_EMPHASIS_SHIFT;
>>
>> if (DPCD_VOLTAGE_SWING_GET(training_lane) ==
>> voltage_swing &&
>> DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis)
>>
>>
>> Without this fix, there is no obvious error when pre-emphasis equals 0,
>> but wrong register values will be programmed once PE is non-zero.
>
> You found it!
> Applying the shifts makes it work.
>
Great to hear the shift logic resolves the issue!
I've submitted the finalized patches to drm-misc branch. If the patches
resolve the issue on your hardware, I'd appreciate a Reviewed-by or
Tested-by tag.
Best regards,
Damon
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* RE: [PATCH 4/4] media: qcom: camss: use fwnode_graph_for_each_endpoint_scoped() to simpifly code
From: G.N. Zhou @ 2026-06-24 3:17 UTC (permalink / raw)
To: Frank Li (OSS), Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Mauro Carvalho Chehab, Dafna Hirschfeld,
Laurent Pinchart, Heiko Stuebner, Bryan O'Donoghue,
Vladimir Zapolskiy, Loic Poulain
Cc: driver-core@lists.linux.dev, linux-acpi@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
linux-rockchip@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
linux-arm-msm@vger.kernel.org, imx@lists.linux.dev, Frank Li
In-Reply-To: <20260622-fw_scoped-v1-4-a37d0aac0a68@nxp.com>
Hi Frank,
> -----Original Message-----
> From: Frank Li (OSS) <frank.li@oss.nxp.com>
> Sent: Monday, June 22, 2026 10:30 PM
> To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>; Daniel Scally
> <djrscally@gmail.com>; Heikki Krogerus <heikki.krogerus@linux.intel.com>;
> Sakari Ailus <sakari.ailus@linux.intel.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Rafael J. Wysocki <rafael@kernel.org>; Danilo
> Krummrich <dakr@kernel.org>; Mauro Carvalho Chehab
> <mchehab@kernel.org>; Dafna Hirschfeld <dafna@fastmail.com>; Laurent
> Pinchart <laurent.pinchart@ideasonboard.com>; Heiko Stuebner
> <heiko@sntech.de>; Bryan O'Donoghue <bryan.odonoghue@linaro.org>;
> Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>; Loic Poulain
> <loic.poulain@oss.qualcomm.com>
> Cc: driver-core@lists.linux.dev; linux-acpi@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-media@vger.kernel.org; linux-
> rockchip@lists.infradead.org; linux-arm-kernel@lists.infradead.org; linux-arm-
> msm@vger.kernel.org; imx@lists.linux.dev; G.N. Zhou
> <guoniu.zhou@nxp.com>; Frank Li <frank.li@nxp.com>
> Subject: [PATCH 4/4] media: qcom: camss: use
> fwnode_graph_for_each_endpoint_scoped() to simpifly code
>
> From: Frank Li <Frank.Li@nxp.com>
>
> Use fwnode_graph_for_each_endpoint_scoped() to simpifly code.
s/simpifly/simplify/ both in message title and body.
With this addressed:
Reviewed-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
>
> No functional changes.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/media/platform/qcom/camss/camss.c | 17 +++++------------
> 1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss.c
> b/drivers/media/platform/qcom/camss/camss.c
> index 2123f6388e3d7..23f3cc30a15a5 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -4793,30 +4793,23 @@ static int camss_parse_endpoint_node(struct
> device *dev, static int camss_parse_ports(struct camss *camss) {
> struct device *dev = camss->dev;
> - struct fwnode_handle *fwnode = dev_fwnode(dev), *ep;
> + struct fwnode_handle *fwnode = dev_fwnode(dev);
> int ret;
>
> - fwnode_graph_for_each_endpoint(fwnode, ep) {
> + fwnode_graph_for_each_endpoint_scoped(fwnode, ep) {
> struct camss_async_subdev *csd;
>
> csd = v4l2_async_nf_add_fwnode_remote(&camss->notifier,
> ep,
> typeof(*csd));
> - if (IS_ERR(csd)) {
> - ret = PTR_ERR(csd);
> - goto err_cleanup;
> - }
> + if (IS_ERR(csd))
> + return PTR_ERR(csd);
>
> ret = camss_parse_endpoint_node(dev, ep, csd);
> if (ret < 0)
> - goto err_cleanup;
> + return ret;
> }
>
> return 0;
> -
> -err_cleanup:
> - fwnode_handle_put(ep);
> -
> - return ret;
> }
>
> /*
>
> --
> 2.43.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
* RE: [PATCH 2/4] media: mc: use fwnode_graph_for_each_endpoint_scoped() to simpilfy code
From: G.N. Zhou @ 2026-06-24 3:15 UTC (permalink / raw)
To: Frank Li (OSS), Andy Shevchenko, Daniel Scally, Heikki Krogerus,
Sakari Ailus, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Mauro Carvalho Chehab, Dafna Hirschfeld,
Laurent Pinchart, Heiko Stuebner, Bryan O'Donoghue,
Vladimir Zapolskiy, Loic Poulain
Cc: driver-core@lists.linux.dev, linux-acpi@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
linux-rockchip@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
linux-arm-msm@vger.kernel.org, imx@lists.linux.dev, Frank Li
In-Reply-To: <20260622-fw_scoped-v1-2-a37d0aac0a68@nxp.com>
Hi Frank,
> -----Original Message-----
> From: Frank Li (OSS) <frank.li@oss.nxp.com>
> Sent: Monday, June 22, 2026 10:30 PM
> To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>; Daniel Scally
> <djrscally@gmail.com>; Heikki Krogerus <heikki.krogerus@linux.intel.com>;
> Sakari Ailus <sakari.ailus@linux.intel.com>; Greg Kroah-Hartman
> <gregkh@linuxfoundation.org>; Rafael J. Wysocki <rafael@kernel.org>; Danilo
> Krummrich <dakr@kernel.org>; Mauro Carvalho Chehab
> <mchehab@kernel.org>; Dafna Hirschfeld <dafna@fastmail.com>; Laurent
> Pinchart <laurent.pinchart@ideasonboard.com>; Heiko Stuebner
> <heiko@sntech.de>; Bryan O'Donoghue <bryan.odonoghue@linaro.org>;
> Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>; Loic Poulain
> <loic.poulain@oss.qualcomm.com>
> Cc: driver-core@lists.linux.dev; linux-acpi@vger.kernel.org; linux-
> kernel@vger.kernel.org; linux-media@vger.kernel.org; linux-
> rockchip@lists.infradead.org; linux-arm-kernel@lists.infradead.org; linux-arm-
> msm@vger.kernel.org; imx@lists.linux.dev; G.N. Zhou
> <guoniu.zhou@nxp.com>; Frank Li <frank.li@nxp.com>
> Subject: [PATCH 2/4] media: mc: use
> fwnode_graph_for_each_endpoint_scoped() to simpilfy code
>
> From: Frank Li <Frank.Li@nxp.com>
>
> Use cleanup helper fwnode_graph_for_each_endpoint_scoped() to simpilfy
s/simpifly/simplify/ both in message title and body.
With this addressed:
Reviewed-by: Guoniu Zhou <guoniu.zhou@oss.nxp.com>
> code.
>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/media/v4l2-core/v4l2-mc.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-
> mc.c
> index 937d358697e19..5d7fcd67dc42e 100644
> --- a/drivers/media/v4l2-core/v4l2-mc.c
> +++ b/drivers/media/v4l2-core/v4l2-mc.c
> @@ -324,12 +324,10 @@
> EXPORT_SYMBOL_GPL(v4l_vb2q_enable_media_source);
> int v4l2_create_fwnode_links_to_pad(struct v4l2_subdev *src_sd,
> struct media_pad *sink, u32 flags) {
> - struct fwnode_handle *endpoint;
> -
> if (!(sink->flags & MEDIA_PAD_FL_SINK))
> return -EINVAL;
>
> - fwnode_graph_for_each_endpoint(src_sd->fwnode, endpoint) {
> + fwnode_graph_for_each_endpoint_scoped(src_sd->fwnode, endpoint)
> {
> struct fwnode_handle *remote_ep;
> int src_idx, sink_idx, ret;
> struct media_pad *src;
> @@ -397,7 +395,6 @@ int v4l2_create_fwnode_links_to_pad(struct
> v4l2_subdev *src_sd,
> src_sd->entity.name, src_idx,
> sink->entity->name, sink_idx, ret);
>
> - fwnode_handle_put(endpoint);
> return ret;
> }
> }
>
> --
> 2.43.0
_______________________________________________
Linux-rockchip mailing list
Linux-rockchip@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip
^ permalink raw reply
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