[PATCH 1/5] drm/dp: Pull drm_dp_link_power_up/down from Tegra to common drm_dp_helper

2025-03-13 Thread Andy Yan
From: Andy Yan 

The helper functions drm_dp_link_power_up/down were moved to Tegra
DRM at 2019[0].

Now since more and more users are duplicating the same code in their
own drivers, it's time to make them as DRM DP common helpers again.

[0]https://patchwork.freedesktop.org/patch/336850/?series=68031&rev=3
Signed-off-by: Andy Yan 
---

 drivers/gpu/drm/display/drm_dp_helper.c | 69 +
 drivers/gpu/drm/tegra/dp.c  | 67 
 drivers/gpu/drm/tegra/dp.h  |  2 -
 drivers/gpu/drm/tegra/sor.c |  4 +-
 include/drm/display/drm_dp_helper.h |  2 +
 5 files changed, 73 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index dbce1c3f4969..e5dec67e5fca 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -838,6 +838,75 @@ int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux 
*aux,
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_phy_link_status);
 
+/**
+ * drm_dp_link_power_up() - power up a DisplayPort link
+ * @aux: DisplayPort AUX channel
+ * @revision: DPCD revision supported on the link
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_link_power_up(struct drm_dp_aux *aux, unsigned char revision)
+{
+   u8 value;
+   int err;
+
+   /* DP_SET_POWER register is only available on DPCD v1.1 and later */
+   if (revision < DP_DPCD_REV_11)
+   return 0;
+
+   err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
+   if (err < 0)
+   return err;
+
+   value &= ~DP_SET_POWER_MASK;
+   value |= DP_SET_POWER_D0;
+
+   err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
+   if (err < 0)
+   return err;
+
+   /*
+* According to the DP 1.1 specification, a "Sink Device must exit the
+* power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
+* Control Field" (register 0x600).
+*/
+   usleep_range(1000, 2000);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_link_power_up);
+
+/**
+ * drm_dp_link_power_down() - power down a DisplayPort link
+ * @aux: DisplayPort AUX channel
+ * @revision: DPCD revision supported on the link
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_link_power_down(struct drm_dp_aux *aux, unsigned char revision)
+{
+   u8 value;
+   int err;
+
+   /* DP_SET_POWER register is only available on DPCD v1.1 and later */
+   if (revision < DP_DPCD_REV_11)
+   return 0;
+
+   err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
+   if (err < 0)
+   return err;
+
+   value &= ~DP_SET_POWER_MASK;
+   value |= DP_SET_POWER_D3;
+
+   err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
+   if (err < 0)
+   return err;
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_link_power_down);
+
 static int read_payload_update_status(struct drm_dp_aux *aux)
 {
int ret;
diff --git a/drivers/gpu/drm/tegra/dp.c b/drivers/gpu/drm/tegra/dp.c
index 08fbd8f151a1..990e744b0923 100644
--- a/drivers/gpu/drm/tegra/dp.c
+++ b/drivers/gpu/drm/tegra/dp.c
@@ -255,73 +255,6 @@ int drm_dp_link_probe(struct drm_dp_aux *aux, struct 
drm_dp_link *link)
return 0;
 }
 
-/**
- * drm_dp_link_power_up() - power up a DisplayPort link
- * @aux: DisplayPort AUX channel
- * @link: pointer to a structure containing the link configuration
- *
- * Returns 0 on success or a negative error code on failure.
- */
-int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link)
-{
-   u8 value;
-   int err;
-
-   /* DP_SET_POWER register is only available on DPCD v1.1 and later */
-   if (link->revision < 0x11)
-   return 0;
-
-   err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
-   if (err < 0)
-   return err;
-
-   value &= ~DP_SET_POWER_MASK;
-   value |= DP_SET_POWER_D0;
-
-   err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
-   if (err < 0)
-   return err;
-
-   /*
-* According to the DP 1.1 specification, a "Sink Device must exit the
-* power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
-* Control Field" (register 0x600).
-*/
-   usleep_range(1000, 2000);
-
-   return 0;
-}
-
-/**
- * drm_dp_link_power_down() - power down a DisplayPort link
- * @aux: DisplayPort AUX channel
- * @link: pointer to a structure containing the link configuration
- *
- * Returns 0 on success or a negative error code on failure.
- */
-int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link)
-{
-   u8 value;
-   int err;
-
-   /* DP_SET_POWER register is only available on DPCD v1.1 and later */
-   if (link->revision < 0x11)
-   return 0;
-
-   err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
-   if (err < 

[PATCH 2/5] drm/bridge: cdns-mhdp8546: Switch to common helpers to power up/down dp link

2025-03-13 Thread Andy Yan
From: Andy Yan 

Use the common dp link power up/down helpers to avoid duplicating code.

Signed-off-by: Andy Yan 
---

 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 74 +--
 1 file changed, 2 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 81fad14c2cd5..6094ecde35ff 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -545,76 +545,6 @@ int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp, 
unsigned int nlanes,
return ret;
 }
 
-/**
- * cdns_mhdp_link_power_up() - power up a DisplayPort link
- * @aux: DisplayPort AUX channel
- * @link: pointer to a structure containing the link configuration
- *
- * Returns 0 on success or a negative error code on failure.
- */
-static
-int cdns_mhdp_link_power_up(struct drm_dp_aux *aux, struct cdns_mhdp_link 
*link)
-{
-   u8 value;
-   int err;
-
-   /* DP_SET_POWER register is only available on DPCD v1.1 and later */
-   if (link->revision < 0x11)
-   return 0;
-
-   err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
-   if (err < 0)
-   return err;
-
-   value &= ~DP_SET_POWER_MASK;
-   value |= DP_SET_POWER_D0;
-
-   err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
-   if (err < 0)
-   return err;
-
-   /*
-* According to the DP 1.1 specification, a "Sink Device must exit the
-* power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
-* Control Field" (register 0x600).
-*/
-   usleep_range(1000, 2000);
-
-   return 0;
-}
-
-/**
- * cdns_mhdp_link_power_down() - power down a DisplayPort link
- * @aux: DisplayPort AUX channel
- * @link: pointer to a structure containing the link configuration
- *
- * Returns 0 on success or a negative error code on failure.
- */
-static
-int cdns_mhdp_link_power_down(struct drm_dp_aux *aux,
- struct cdns_mhdp_link *link)
-{
-   u8 value;
-   int err;
-
-   /* DP_SET_POWER register is only available on DPCD v1.1 and later */
-   if (link->revision < 0x11)
-   return 0;
-
-   err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
-   if (err < 0)
-   return err;
-
-   value &= ~DP_SET_POWER_MASK;
-   value |= DP_SET_POWER_D3;
-
-   err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
-   if (err < 0)
-   return err;
-
-   return 0;
-}
-
 /**
  * cdns_mhdp_link_configure() - configure a DisplayPort link
  * @aux: DisplayPort AUX channel
@@ -1453,7 +1383,7 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device 
*mhdp)
mhdp->link.capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
 
dev_dbg(mhdp->dev, "Set sink device power state via DPCD\n");
-   cdns_mhdp_link_power_up(&mhdp->aux, &mhdp->link);
+   drm_dp_link_power_up(&mhdp->aux, mhdp->link.revision);
 
cdns_mhdp_fill_sink_caps(mhdp, dpcd);
 
@@ -1500,7 +1430,7 @@ static void cdns_mhdp_link_down(struct cdns_mhdp_device 
*mhdp)
WARN_ON(!mutex_is_locked(&mhdp->link_mutex));
 
if (mhdp->plugged)
-   cdns_mhdp_link_power_down(&mhdp->aux, &mhdp->link);
+   drm_dp_link_power_down(&mhdp->aux, mhdp->link.revision);
 
mhdp->link_up = false;
 }
-- 
2.34.1



[PATCH 4/5] drm/bridge: anx78xx: Switch to common helpers to power up/down dp link

2025-03-13 Thread Andy Yan
From: Andy Yan 

Use the common dp link power up/down helpers to avoid duplicating code.

Signed-off-by: Andy Yan 
---

 .../drm/bridge/analogix/analogix-anx78xx.c| 30 +--
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c 
b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index f74694bb9c50..3d9daa885eef 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -656,35 +656,7 @@ static int anx78xx_dp_link_training(struct anx78xx 
*anx78xx)
if (err)
return err;
 
-   /*
-* Power up the sink (DP_SET_POWER register is only available on DPCD
-* v1.1 and later).
-*/
-   if (anx78xx->dpcd[DP_DPCD_REV] >= 0x11) {
-   err = drm_dp_dpcd_readb(&anx78xx->aux, DP_SET_POWER, &dpcd[0]);
-   if (err < 0) {
-   DRM_ERROR("Failed to read DP_SET_POWER register: %d\n",
- err);
-   return err;
-   }
-
-   dpcd[0] &= ~DP_SET_POWER_MASK;
-   dpcd[0] |= DP_SET_POWER_D0;
-
-   err = drm_dp_dpcd_writeb(&anx78xx->aux, DP_SET_POWER, dpcd[0]);
-   if (err < 0) {
-   DRM_ERROR("Failed to power up DisplayPort link: %d\n",
- err);
-   return err;
-   }
-
-   /*
-* According to the DP 1.1 specification, a "Sink Device must
-* exit the power saving state within 1 ms" (Section 2.5.3.1,
-* Table 5-52, "Sink Control Field" (register 0x600).
-*/
-   usleep_range(1000, 2000);
-   }
+   drm_dp_link_power_up(&anx78xx->aux, anx78xx->dpcd[DP_DPCD_REV]);
 
/* Possibly enable downspread on the sink */
err = regmap_write(anx78xx->map[I2C_IDX_TX_P0],
-- 
2.34.1



[PATCH 5/5] drm/bridge: it6505: Switch to common helpers to power up/down dp link

2025-03-13 Thread Andy Yan
From: Andy Yan 

Use the common dp link power up/down helpers to avoid duplicating code.

Signed-off-by: Andy Yan 
---

 drivers/gpu/drm/bridge/ite-it6505.c | 46 +++--
 1 file changed, 4 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
b/drivers/gpu/drm/bridge/ite-it6505.c
index 8a607558ac89..b05fc82bb667 100644
--- a/drivers/gpu/drm/bridge/ite-it6505.c
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
@@ -771,40 +771,6 @@ static void it6505_calc_video_info(struct it6505 *it6505)
 DRM_MODE_ARG(&it6505->video_info));
 }
 
-static int it6505_drm_dp_link_set_power(struct drm_dp_aux *aux,
-   struct it6505_drm_dp_link *link,
-   u8 mode)
-{
-   u8 value;
-   int err;
-
-   /* DP_SET_POWER register is only available on DPCD v1.1 and later */
-   if (link->revision < DPCD_V_1_1)
-   return 0;
-
-   err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
-   if (err < 0)
-   return err;
-
-   value &= ~DP_SET_POWER_MASK;
-   value |= mode;
-
-   err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
-   if (err < 0)
-   return err;
-
-   if (mode == DP_SET_POWER_D0) {
-   /*
-* According to the DP 1.1 specification, a "Sink Device must
-* exit the power saving state within 1 ms" (Section 2.5.3.1,
-* Table 5-52, "Sink Control Field" (register 0x600).
-*/
-   usleep_range(1000, 2000);
-   }
-
-   return 0;
-}
-
 static void it6505_clear_int(struct it6505 *it6505)
 {
it6505_write(it6505, INT_STATUS_01, 0xFF);
@@ -2578,8 +2544,7 @@ static void it6505_irq_hpd(struct it6505 *it6505)
}
it6505->auto_train_retry = AUTO_TRAIN_RETRY;
 
-   it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
-DP_SET_POWER_D0);
+   drm_dp_link_power_up(&it6505->aux, it6505->link.revision);
dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT);
it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count);
 
@@ -2910,8 +2875,7 @@ static enum drm_connector_status it6505_detect(struct 
it6505 *it6505)
}
 
if (it6505->hpd_state) {
-   it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
-DP_SET_POWER_D0);
+   drm_dp_link_power_up(&it6505->aux, it6505->link.revision);
dp_sink_count = it6505_dpcd_read(it6505, DP_SINK_COUNT);
it6505->sink_count = DP_GET_SINK_COUNT(dp_sink_count);
DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count:%d branch:%d",
@@ -3233,8 +3197,7 @@ static void it6505_bridge_atomic_enable(struct drm_bridge 
*bridge,
it6505_int_mask_enable(it6505);
it6505_video_reset(it6505);
 
-   it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
-DP_SET_POWER_D0);
+   drm_dp_link_power_up(&it6505->aux, it6505->link.revision);
 }
 
 static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
@@ -3246,8 +3209,7 @@ static void it6505_bridge_atomic_disable(struct 
drm_bridge *bridge,
DRM_DEV_DEBUG_DRIVER(dev, "start");
 
if (it6505->powered) {
-   it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
-DP_SET_POWER_D3);
+   drm_dp_link_power_down(&it6505->aux, it6505->link.revision);
it6505_video_disable(it6505);
}
 }
-- 
2.34.1



[PATCH 3/5] drm/bridge: anx6345: Switch to common helpers to power up/down dp link

2025-03-13 Thread Andy Yan
From: Andy Yan 

Use the common dp link power up/down helpers to avoid duplicating code.

Signed-off-by: Andy Yan 
---

 .../drm/bridge/analogix/analogix-anx6345.c| 30 +--
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c 
b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
index 83d711ee3a2e..f4fffe4bbb30 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
@@ -143,35 +143,7 @@ static int anx6345_dp_link_training(struct anx6345 
*anx6345)
if (err)
return err;
 
-   /*
-* Power up the sink (DP_SET_POWER register is only available on DPCD
-* v1.1 and later).
-*/
-   if (anx6345->dpcd[DP_DPCD_REV] >= 0x11) {
-   err = drm_dp_dpcd_readb(&anx6345->aux, DP_SET_POWER, &dpcd[0]);
-   if (err < 0) {
-   DRM_ERROR("Failed to read DP_SET_POWER register: %d\n",
- err);
-   return err;
-   }
-
-   dpcd[0] &= ~DP_SET_POWER_MASK;
-   dpcd[0] |= DP_SET_POWER_D0;
-
-   err = drm_dp_dpcd_writeb(&anx6345->aux, DP_SET_POWER, dpcd[0]);
-   if (err < 0) {
-   DRM_ERROR("Failed to power up DisplayPort link: %d\n",
- err);
-   return err;
-   }
-
-   /*
-* According to the DP 1.1 specification, a "Sink Device must
-* exit the power saving state within 1 ms" (Section 2.5.3.1,
-* Table 5-52, "Sink Control Field" (register 0x600).
-*/
-   usleep_range(1000, 2000);
-   }
+   drm_dp_link_power_up(&anx6345->aux, anx6345->dpcd[DP_DPCD_REV]);
 
/* Possibly enable downspread on the sink */
err = regmap_write(anx6345->map[I2C_IDX_DPTX],
-- 
2.34.1



Re: [PATCH v2 1/2] lib/vsprintf: Add support for generic FourCCs by extending %p4cc

2025-03-13 Thread Aditya Garg


> On 13 Mar 2025, at 4:49 PM, Aditya Garg  wrote:
> 
> From: Hector Martin 
> 
> %p4cc is designed for DRM/V4L2 FourCCs with their specific quirks, but
> it's useful to be able to print generic 4-character codes formatted as
> an integer. Extend it to add format specifiers for printing generic
> 32-bit FourCCs with various endian semantics:
> 
> %p4ch Host byte order
> %p4cn Network byte order
> %p4cl Little-endian
> %p4cb Big-endian
> 
> The endianness determines how bytes are interpreted as a u32, and the
> FourCC is then always printed MSByte-first (this is the opposite of
> V4L/DRM FourCCs). This covers most practical cases, e.g. %p4cn would
> allow printing LSByte-first FourCCs stored in host endian order
> (other than the hex form being in character order, not the integer
> value).
> 
> Acked-by: Rasmus Villemoes 
> Reviewed-by: Andy Shevchenko 
> Reviewed-by: Petr Mladek 
> Tested-by: Petr Mladek 
> Signed-off-by: Hector Martin 
> Signed-off-by: Aditya Garg 
> ---
> Documentation/core-api/printk-formats.rst | 32 +
> lib/vsprintf.c| 35 +++
> scripts/checkpatch.pl |  2 +-
> 3 files changed, 62 insertions(+), 7 deletions(-)

FWIW, the test_printf.c part, as suggested by Petr, which was removed in v2, 
has been sent to Kees here:

https://lore.kernel.org/lkml/4378ddfe-3263-497a-8364-433dc1984...@live.com/T/#u

The series should be good to merge now.

Re: [PATCH 4/5] drm/bridge: anx78xx: Switch to common helpers to power up/down dp link

2025-03-13 Thread Dmitry Baryshkov
On Fri, Mar 14, 2025 at 11:38:43AM +0800, Andy Yan wrote:
> From: Andy Yan 
> 
> Use the common dp link power up/down helpers to avoid duplicating code.
> 
> Signed-off-by: Andy Yan 
> ---
> 
>  .../drm/bridge/analogix/analogix-anx78xx.c| 30 +--
>  1 file changed, 1 insertion(+), 29 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov 

-- 
With best wishes
Dmitry


Re: [PATCH 5/5] drm/bridge: it6505: Switch to common helpers to power up/down dp link

2025-03-13 Thread Dmitry Baryshkov
On Fri, Mar 14, 2025 at 11:38:44AM +0800, Andy Yan wrote:
> From: Andy Yan 
> 
> Use the common dp link power up/down helpers to avoid duplicating code.
> 
> Signed-off-by: Andy Yan 
> ---
> 
>  drivers/gpu/drm/bridge/ite-it6505.c | 46 +++--
>  1 file changed, 4 insertions(+), 42 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov 
-- 
With best wishes
Dmitry


[PATCH RFC v4 3/6] drm/display: dp: use new DCPD access helpers

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Switch drm_dp_helper.c to use new set of DPCD read / write helpers.

Reviewed-by: Lyude Paul 
Acked-by: Jani Nikula 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/display/drm_dp_helper.c | 296 +---
 1 file changed, 116 insertions(+), 180 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 
410be0be233ad94702af423262a7d98e21afbfeb..e2439c8a7fefe116b04aaa689b557e2387b05540
 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -327,7 +327,7 @@ static int __read_delay(struct drm_dp_aux *aux, const u8 
dpcd[DP_RECEIVER_CAP_SI
if (offset < DP_RECEIVER_CAP_SIZE) {
rd_interval = dpcd[offset];
} else {
-   if (drm_dp_dpcd_readb(aux, offset, &rd_interval) != 1) {
+   if (drm_dp_dpcd_read_byte(aux, offset, &rd_interval) < 0) {
drm_dbg_kms(aux->drm_dev, "%s: failed rd interval 
read\n",
aux->name);
/* arbitrary default delay */
@@ -358,7 +358,7 @@ int drm_dp_128b132b_read_aux_rd_interval(struct drm_dp_aux 
*aux)
int unit;
u8 val;
 
-   if (drm_dp_dpcd_readb(aux, DP_128B132B_TRAINING_AUX_RD_INTERVAL, &val) 
!= 1) {
+   if (drm_dp_dpcd_read_byte(aux, DP_128B132B_TRAINING_AUX_RD_INTERVAL, 
&val) < 0) {
drm_err(aux->drm_dev, "%s: failed rd interval read\n",
aux->name);
/* default to max */
@@ -807,30 +807,20 @@ int drm_dp_dpcd_read_phy_link_status(struct drm_dp_aux 
*aux,
 {
int ret;
 
-   if (dp_phy == DP_PHY_DPRX) {
-   ret = drm_dp_dpcd_read(aux,
-  DP_LANE0_1_STATUS,
-  link_status,
-  DP_LINK_STATUS_SIZE);
-
-   if (ret < 0)
-   return ret;
+   if (dp_phy == DP_PHY_DPRX)
+   return drm_dp_dpcd_read_data(aux,
+DP_LANE0_1_STATUS,
+link_status,
+DP_LINK_STATUS_SIZE);
 
-   WARN_ON(ret != DP_LINK_STATUS_SIZE);
-
-   return 0;
-   }
-
-   ret = drm_dp_dpcd_read(aux,
-  DP_LANE0_1_STATUS_PHY_REPEATER(dp_phy),
-  link_status,
-  DP_LINK_STATUS_SIZE - 1);
+   ret = drm_dp_dpcd_read_data(aux,
+   DP_LANE0_1_STATUS_PHY_REPEATER(dp_phy),
+   link_status,
+   DP_LINK_STATUS_SIZE - 1);
 
if (ret < 0)
return ret;
 
-   WARN_ON(ret != DP_LINK_STATUS_SIZE - 1);
-
/* Convert the LTTPR to the sink PHY link status layout */
memmove(&link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS + 1],
&link_status[DP_SINK_STATUS - DP_LANE0_1_STATUS],
@@ -846,7 +836,7 @@ static int read_payload_update_status(struct drm_dp_aux 
*aux)
int ret;
u8 status;
 
-   ret = drm_dp_dpcd_readb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
+   ret = drm_dp_dpcd_read_byte(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, 
&status);
if (ret < 0)
return ret;
 
@@ -873,21 +863,21 @@ int drm_dp_dpcd_write_payload(struct drm_dp_aux *aux,
int ret;
int retries = 0;
 
-   drm_dp_dpcd_writeb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,
-  DP_PAYLOAD_TABLE_UPDATED);
+   drm_dp_dpcd_write_byte(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS,
+  DP_PAYLOAD_TABLE_UPDATED);
 
payload_alloc[0] = vcpid;
payload_alloc[1] = start_time_slot;
payload_alloc[2] = time_slot_count;
 
-   ret = drm_dp_dpcd_write(aux, DP_PAYLOAD_ALLOCATE_SET, payload_alloc, 3);
-   if (ret != 3) {
+   ret = drm_dp_dpcd_write_data(aux, DP_PAYLOAD_ALLOCATE_SET, 
payload_alloc, 3);
+   if (ret < 0) {
drm_dbg_kms(aux->drm_dev, "failed to write payload allocation 
%d\n", ret);
goto fail;
}
 
 retry:
-   ret = drm_dp_dpcd_readb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status);
+   ret = drm_dp_dpcd_read_byte(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, 
&status);
if (ret < 0) {
drm_dbg_kms(aux->drm_dev, "failed to read payload table status 
%d\n", ret);
goto fail;
@@ -1043,15 +1033,15 @@ bool drm_dp_send_real_edid_checksum(struct drm_dp_aux 
*aux,
 {
u8 link_edid_read = 0, auto_test_req = 0, test_resp = 0;
 
-   if (drm_dp_dpcd_read(aux, DP_DEVICE_SERVICE_IRQ_VECTOR,
-&auto_test_req, 1) < 1) {
+   if (drm_dp_dpcd_read_byte(aux, DP_DEVICE_SERVICE_IRQ_VECTOR,
+ &auto_test_re

[PATCH RFC v4 5/6] drm/display: dp-mst-topology: use new DCPD access helpers

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Switch drm_dp_mst_topology.c to use new set of DPCD read / write helpers.

Reviewed-by: Lyude Paul 
Acked-by: Jani Nikula 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/display/drm_dp_mst_topology.c | 105 +-
 1 file changed, 51 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
b/drivers/gpu/drm/display/drm_dp_mst_topology.c
index 
3a1f1ffc7b5528b940485e7d96b1913bd85b0153..de3fc6090c906efce3dbaa8462d736ebf9094b34
 100644
--- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -2201,15 +2201,12 @@ static int drm_dp_check_mstb_guid(struct 
drm_dp_mst_branch *mstb, guid_t *guid)
 mstb->port_parent,
 DP_GUID, sizeof(buf), buf);
} else {
-   ret = drm_dp_dpcd_write(mstb->mgr->aux,
-   DP_GUID, buf, sizeof(buf));
+   ret = drm_dp_dpcd_write_data(mstb->mgr->aux,
+DP_GUID, buf, sizeof(buf));
}
}
 
-   if (ret < 16 && ret > 0)
-   return -EPROTO;
-
-   return ret == 16 ? 0 : ret;
+   return ret;
 }
 
 static void build_mst_prop_path(const struct drm_dp_mst_branch *mstb,
@@ -2744,14 +2741,13 @@ static int drm_dp_send_sideband_msg(struct 
drm_dp_mst_topology_mgr *mgr,
do {
tosend = min3(mgr->max_dpcd_transaction_bytes, 16, total);
 
-   ret = drm_dp_dpcd_write(mgr->aux, regbase + offset,
-   &msg[offset],
-   tosend);
-   if (ret != tosend) {
-   if (ret == -EIO && retries < 5) {
-   retries++;
-   goto retry;
-   }
+   ret = drm_dp_dpcd_write_data(mgr->aux, regbase + offset,
+&msg[offset],
+tosend);
+   if (ret == -EIO && retries < 5) {
+   retries++;
+   goto retry;
+   } else if (ret < 0) {
drm_dbg_kms(mgr->dev, "failed to dpcd write %d %d\n", 
tosend, ret);
 
return -EIO;
@@ -3624,7 +3620,7 @@ enum drm_dp_mst_mode drm_dp_read_mst_cap(struct 
drm_dp_aux *aux,
if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_12)
return DRM_DP_SST;
 
-   if (drm_dp_dpcd_readb(aux, DP_MSTM_CAP, &mstm_cap) != 1)
+   if (drm_dp_dpcd_read_byte(aux, DP_MSTM_CAP, &mstm_cap) < 0)
return DRM_DP_SST;
 
if (mstm_cap & DP_MST_CAP)
@@ -3679,10 +3675,10 @@ int drm_dp_mst_topology_mgr_set_mst(struct 
drm_dp_mst_topology_mgr *mgr, bool ms
mgr->mst_primary = mstb;
drm_dp_mst_topology_get_mstb(mgr->mst_primary);
 
-   ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
-DP_MST_EN |
-DP_UP_REQ_EN |
-DP_UPSTREAM_IS_SRC);
+   ret = drm_dp_dpcd_write_byte(mgr->aux, DP_MSTM_CTRL,
+DP_MST_EN |
+DP_UP_REQ_EN |
+DP_UPSTREAM_IS_SRC);
if (ret < 0)
goto out_unlock;
 
@@ -3697,7 +3693,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct 
drm_dp_mst_topology_mgr *mgr, bool ms
mstb = mgr->mst_primary;
mgr->mst_primary = NULL;
/* this can fail if the device is gone */
-   drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0);
+   drm_dp_dpcd_write_byte(mgr->aux, DP_MSTM_CTRL, 0);
ret = 0;
mgr->payload_id_table_cleared = false;
 
@@ -3763,8 +3759,8 @@ EXPORT_SYMBOL(drm_dp_mst_topology_queue_probe);
 void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr)
 {
mutex_lock(&mgr->lock);
-   drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
-  DP_MST_EN | DP_UPSTREAM_IS_SRC);
+   drm_dp_dpcd_write_byte(mgr->aux, DP_MSTM_CTRL,
+  DP_MST_EN | DP_UPSTREAM_IS_SRC);
mutex_unlock(&mgr->lock);
flush_work(&mgr->up_req_work);
flush_work(&mgr->work);
@@ -3813,18 +3809,18 @@ int drm_dp_mst_topology_mgr_resume(struct 
drm_dp_mst_topology_mgr *mgr,
goto out_fail;
}
 
-   ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL,
-DP_MST_EN |
-DP_UP_REQ_EN |
-DP_UPSTREAM_IS_SRC);
+   ret = drm_dp_dpcd_write_byte(mgr->aux, DP_MSTM_CTRL,

[PATCH RFC v4 1/6] drm/display: dp: implement new access helpers

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Existing DPCD access functions return an error code or the number of
bytes being read / write in case of partial access. However a lot of
drivers either (incorrectly) ignore partial access or mishandle error
codes. In other cases this results in a boilerplate code which compares
returned value with the size.

Implement new set of DPCD access helpers, which ignore partial access,
always return 0 or an error code.

Suggested-by: Jani Nikula 
Acked-by: Jani Nikula 
Reviewed-by: Lyude Paul 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/display/drm_dp_helper.c |  4 ++
 include/drm/display/drm_dp_helper.h | 92 -
 2 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 
dbce1c3f49691fc687fee2404b723c73d533f23d..e43a8f4a252dae22eeaae1f4ca94da064303033d
 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -704,6 +704,8 @@ EXPORT_SYMBOL(drm_dp_dpcd_set_powered);
  * function returns -EPROTO. Errors from the underlying AUX channel transfer
  * function, with the exception of -EBUSY (which causes the transaction to
  * be retried), are propagated to the caller.
+ *
+ * In most of the cases you want to use drm_dp_dpcd_read_data() instead.
  */
 ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
 void *buffer, size_t size)
@@ -752,6 +754,8 @@ EXPORT_SYMBOL(drm_dp_dpcd_read);
  * function returns -EPROTO. Errors from the underlying AUX channel transfer
  * function, with the exception of -EBUSY (which causes the transaction to
  * be retried), are propagated to the caller.
+ *
+ * In most of the cases you want to use drm_dp_dpcd_write_data() instead.
  */
 ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
  void *buffer, size_t size)
diff --git a/include/drm/display/drm_dp_helper.h 
b/include/drm/display/drm_dp_helper.h
index 
5ae4241959f24e2c1fb581d7c7d770485d603099..21e22289d1caebe616b57a304061b12592ad41ea
 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -527,6 +527,64 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned 
int offset,
 ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
  void *buffer, size_t size);
 
+/**
+ * drm_dp_dpcd_read_data() - read a series of bytes from the DPCD
+ * @aux: DisplayPort AUX channel (SST or MST)
+ * @offset: address of the (first) register to read
+ * @buffer: buffer to store the register values
+ * @size: number of bytes in @buffer
+ *
+ * Returns zero (0) on success, or a negative error
+ * code on failure. -EIO is returned if the request was NAKed by the sink or
+ * if the retry count was exceeded. If not all bytes were transferred, this
+ * function returns -EPROTO. Errors from the underlying AUX channel transfer
+ * function, with the exception of -EBUSY (which causes the transaction to
+ * be retried), are propagated to the caller.
+ */
+static inline int drm_dp_dpcd_read_data(struct drm_dp_aux *aux,
+   unsigned int offset,
+   void *buffer, size_t size)
+{
+   int ret;
+
+   ret = drm_dp_dpcd_read(aux, offset, buffer, size);
+   if (ret < 0)
+   return ret;
+   if (ret < size)
+   return -EPROTO;
+
+   return 0;
+}
+
+/**
+ * drm_dp_dpcd_write_data() - write a series of bytes to the DPCD
+ * @aux: DisplayPort AUX channel (SST or MST)
+ * @offset: address of the (first) register to write
+ * @buffer: buffer containing the values to write
+ * @size: number of bytes in @buffer
+ *
+ * Returns zero (0) on success, or a negative error
+ * code on failure. -EIO is returned if the request was NAKed by the sink or
+ * if the retry count was exceeded. If not all bytes were transferred, this
+ * function returns -EPROTO. Errors from the underlying AUX channel transfer
+ * function, with the exception of -EBUSY (which causes the transaction to
+ * be retried), are propagated to the caller.
+ */
+static inline int drm_dp_dpcd_write_data(struct drm_dp_aux *aux,
+unsigned int offset,
+void *buffer, size_t size)
+{
+   int ret;
+
+   ret = drm_dp_dpcd_write(aux, offset, buffer, size);
+   if (ret < 0)
+   return ret;
+   if (ret < size)
+   return -EPROTO;
+
+   return 0;
+}
+
 /**
  * drm_dp_dpcd_readb() - read a single byte from the DPCD
  * @aux: DisplayPort AUX channel
@@ -534,7 +592,8 @@ ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned 
int offset,
  * @valuep: location where the value of the register will be stored
  *
  * Returns the number of bytes transferred (1) on success, or a negative
- * error code on failure.
+ * error code on failure

[PATCH RFC v4 4/6] drm/display: dp-cec: use new DCPD access helpers

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Switch drm_dp_cec.c to use new set of DPCD read / write helpers.

Reviewed-by: Lyude Paul 
Acked-by: Jani Nikula 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/display/drm_dp_cec.c | 37 ++--
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_cec.c 
b/drivers/gpu/drm/display/drm_dp_cec.c
index 
56a4965e518cc237c992a2e31b9f6de05c14766a..ed31471bd0e28826254ecedac48c5c126729d470
 100644
--- a/drivers/gpu/drm/display/drm_dp_cec.c
+++ b/drivers/gpu/drm/display/drm_dp_cec.c
@@ -96,7 +96,7 @@ static int drm_dp_cec_adap_enable(struct cec_adapter *adap, 
bool enable)
u32 val = enable ? DP_CEC_TUNNELING_ENABLE : 0;
ssize_t err = 0;
 
-   err = drm_dp_dpcd_writeb(aux, DP_CEC_TUNNELING_CONTROL, val);
+   err = drm_dp_dpcd_write_byte(aux, DP_CEC_TUNNELING_CONTROL, val);
return (enable && err < 0) ? err : 0;
 }
 
@@ -112,7 +112,7 @@ static int drm_dp_cec_adap_log_addr(struct cec_adapter 
*adap, u8 addr)
la_mask |= adap->log_addrs.log_addr_mask | (1 << addr);
mask[0] = la_mask & 0xff;
mask[1] = la_mask >> 8;
-   err = drm_dp_dpcd_write(aux, DP_CEC_LOGICAL_ADDRESS_MASK, mask, 2);
+   err = drm_dp_dpcd_write_data(aux, DP_CEC_LOGICAL_ADDRESS_MASK, mask, 2);
return (addr != CEC_LOG_ADDR_INVALID && err < 0) ? err : 0;
 }
 
@@ -123,15 +123,14 @@ static int drm_dp_cec_adap_transmit(struct cec_adapter 
*adap, u8 attempts,
unsigned int retries = min(5, attempts - 1);
ssize_t err;
 
-   err = drm_dp_dpcd_write(aux, DP_CEC_TX_MESSAGE_BUFFER,
-   msg->msg, msg->len);
+   err = drm_dp_dpcd_write_data(aux, DP_CEC_TX_MESSAGE_BUFFER,
+msg->msg, msg->len);
if (err < 0)
return err;
 
-   err = drm_dp_dpcd_writeb(aux, DP_CEC_TX_MESSAGE_INFO,
-(msg->len - 1) | (retries << 4) |
-DP_CEC_TX_MESSAGE_SEND);
-   return err < 0 ? err : 0;
+   return drm_dp_dpcd_write_byte(aux, DP_CEC_TX_MESSAGE_INFO,
+ (msg->len - 1) | (retries << 4) |
+ DP_CEC_TX_MESSAGE_SEND);
 }
 
 static int drm_dp_cec_adap_monitor_all_enable(struct cec_adapter *adap,
@@ -144,13 +143,13 @@ static int drm_dp_cec_adap_monitor_all_enable(struct 
cec_adapter *adap,
if (!(adap->capabilities & CEC_CAP_MONITOR_ALL))
return 0;
 
-   err = drm_dp_dpcd_readb(aux, DP_CEC_TUNNELING_CONTROL, &val);
-   if (err >= 0) {
+   err = drm_dp_dpcd_read_byte(aux, DP_CEC_TUNNELING_CONTROL, &val);
+   if (!err) {
if (enable)
val |= DP_CEC_SNOOPING_ENABLE;
else
val &= ~DP_CEC_SNOOPING_ENABLE;
-   err = drm_dp_dpcd_writeb(aux, DP_CEC_TUNNELING_CONTROL, val);
+   err = drm_dp_dpcd_write_byte(aux, DP_CEC_TUNNELING_CONTROL, 
val);
}
return (enable && err < 0) ? err : 0;
 }
@@ -194,7 +193,7 @@ static int drm_dp_cec_received(struct drm_dp_aux *aux)
u8 rx_msg_info;
ssize_t err;
 
-   err = drm_dp_dpcd_readb(aux, DP_CEC_RX_MESSAGE_INFO, &rx_msg_info);
+   err = drm_dp_dpcd_read_byte(aux, DP_CEC_RX_MESSAGE_INFO, &rx_msg_info);
if (err < 0)
return err;
 
@@ -202,7 +201,7 @@ static int drm_dp_cec_received(struct drm_dp_aux *aux)
return 0;
 
msg.len = (rx_msg_info & DP_CEC_RX_MESSAGE_LEN_MASK) + 1;
-   err = drm_dp_dpcd_read(aux, DP_CEC_RX_MESSAGE_BUFFER, msg.msg, msg.len);
+   err = drm_dp_dpcd_read_data(aux, DP_CEC_RX_MESSAGE_BUFFER, msg.msg, 
msg.len);
if (err < 0)
return err;
 
@@ -215,7 +214,7 @@ static void drm_dp_cec_handle_irq(struct drm_dp_aux *aux)
struct cec_adapter *adap = aux->cec.adap;
u8 flags;
 
-   if (drm_dp_dpcd_readb(aux, DP_CEC_TUNNELING_IRQ_FLAGS, &flags) < 0)
+   if (drm_dp_dpcd_read_byte(aux, DP_CEC_TUNNELING_IRQ_FLAGS, &flags) < 0)
return;
 
if (flags & DP_CEC_RX_MESSAGE_INFO_VALID)
@@ -230,7 +229,7 @@ static void drm_dp_cec_handle_irq(struct drm_dp_aux *aux)
 (DP_CEC_TX_ADDRESS_NACK_ERROR | DP_CEC_TX_DATA_NACK_ERROR))
cec_transmit_attempt_done(adap, CEC_TX_STATUS_NACK |
CEC_TX_STATUS_MAX_RETRIES);
-   drm_dp_dpcd_writeb(aux, DP_CEC_TUNNELING_IRQ_FLAGS, flags);
+   drm_dp_dpcd_write_byte(aux, DP_CEC_TUNNELING_IRQ_FLAGS, flags);
 }
 
 /**
@@ -253,13 +252,13 @@ void drm_dp_cec_irq(struct drm_dp_aux *aux)
if (!aux->cec.adap)
goto unlock;
 
-   ret = drm_dp_dpcd_readb(aux, DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1,
-   &cec_irq);
+   ret = drm_dp_dpcd_read_byte(aux, DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1,
+   

[PATCH RFC v4 0/6] drm/display: dp: add new DPCD access functions

2025-03-13 Thread Dmitry Baryshkov
Existing DPCD access functions return an error code or the number of
bytes being read / write in case of partial access. However a lot of
drivers either (incorrectly) ignore partial access or mishandle error
codes. In other cases this results in a boilerplate code which compares
returned value with the size.

As suggested by Jani implement new set of DPCD access helpers, which
ignore partial access, always return 0 or an error code. Implement
new helpers using existing functions to ensure backwards compatibility
and to assess necessity to handle incomplete reads on a global scale.
Currently only one possible place has been identified, dp-aux-dev, which
needs to handle possible holes in DPCD.

This series targets only the DRM helpers code. If the approach is found
to be acceptable, each of the drivers should be converted on its own.

Signed-off-by: Dmitry Baryshkov 
---
Changes in v4:
- Actually dropped the dp-aux-dev patch (Lyude).
- Added two missing full stops in linuxdoc (Lyude).
- Link to v3: 
https://lore.kernel.org/r/20250307-drm-rework-dpcd-access-v3-0-9044a3a86...@linaro.org

Changes in v3:
- Fixed cover letter (Jani)
- Added intel-gfx and intel-xe to get the series CI-tested (Jani)
- Link to v2: 
https://lore.kernel.org/r/20250301-drm-rework-dpcd-access-v2-0-4d92602fc...@linaro.org

Changes in v2:
- Reimplemented new helpers using old ones (Lyude)
- Reworked the drm_dp_dpcd_read_link_status() patch (Lyude)
- Dropped the dp-aux-dev patch (Jani)
- Link to v1: 
https://lore.kernel.org/r/20250117-drm-rework-dpcd-access-v1-0-7fc020e04...@linaro.org

---
Dmitry Baryshkov (6):
  drm/display: dp: implement new access helpers
  drm/display: dp: change drm_dp_dpcd_read_link_status() return value
  drm/display: dp: use new DCPD access helpers
  drm/display: dp-cec: use new DCPD access helpers
  drm/display: dp-mst-topology: use new DCPD access helpers
  drm/display: dp-tunnel: use new DCPD access helpers

 drivers/gpu/drm/amd/amdgpu/atombios_dp.c   |   8 +-
 .../gpu/drm/bridge/cadence/cdns-mhdp8546-core.c|   2 +-
 drivers/gpu/drm/display/drm_dp_cec.c   |  37 ++-
 drivers/gpu/drm/display/drm_dp_helper.c| 307 +
 drivers/gpu/drm/display/drm_dp_mst_topology.c  | 105 ---
 drivers/gpu/drm/display/drm_dp_tunnel.c|  20 +-
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c   |   4 +-
 drivers/gpu/drm/msm/dp/dp_ctrl.c   |  24 +-
 drivers/gpu/drm/msm/dp/dp_link.c   |  18 +-
 drivers/gpu/drm/radeon/atombios_dp.c   |   8 +-
 include/drm/display/drm_dp_helper.h|  92 +-
 11 files changed, 317 insertions(+), 308 deletions(-)
---
base-commit: b0894e40afe2bd05d1fda68cc364665ac2b00e09
change-id: 20241231-drm-rework-dpcd-access-b0fc2e47d613

Best regards,
-- 
Dmitry Baryshkov 



[PATCH v2 10/10] arm64: dts: qcom: sar2130p: add display nodes

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Add display controller, two DSI hosts, two DSI PHYs and a single DP
controller. Link DP to the QMP Combo PHY.

Signed-off-by: Dmitry Baryshkov 
---
 arch/arm64/boot/dts/qcom/sar2130p.dtsi | 394 +
 1 file changed, 394 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sar2130p.dtsi 
b/arch/arm64/boot/dts/qcom/sar2130p.dtsi
index 
dd832e6816be85817fd1ecc853f8d4c800826bc4..4e1816fcda8168e98e27b8bc0f8b5150c03276d2
 100644
--- a/arch/arm64/boot/dts/qcom/sar2130p.dtsi
+++ b/arch/arm64/boot/dts/qcom/sar2130p.dtsi
@@ -6,6 +6,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1854,6 +1855,7 @@ port@2 {
reg = <2>;
 
usb_dp_qmpphy_dp_in: endpoint {
+   remote-endpoint = 
<&mdss_dp0_out>;
};
};
};
@@ -1951,6 +1953,398 @@ usb_1_dwc3_ss: endpoint {
};
};
 
+   mdss: display-subsystem@ae0 {
+   compatible = "qcom,sar2130p-mdss";
+   reg = <0x0 0x0ae0 0x0 0x1000>;
+   reg-names = "mdss";
+
+   interrupts = ;
+   interrupt-controller;
+   #interrupt-cells = <1>;
+
+   clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
+<&gcc GCC_DISP_AHB_CLK>,
+<&gcc GCC_DISP_HF_AXI_CLK>,
+<&dispcc DISP_CC_MDSS_MDP_CLK>;
+
+   resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
+
+   power-domains = <&dispcc MDSS_GDSC>;
+
+   interconnects = <&mmss_noc MASTER_MDP 
QCOM_ICC_TAG_ACTIVE_ONLY
+&mc_virt SLAVE_EBI1 
QCOM_ICC_TAG_ACTIVE_ONLY>,
+   <&gem_noc MASTER_APPSS_PROC 
QCOM_ICC_TAG_ACTIVE_ONLY
+&config_noc SLAVE_DISPLAY_CFG 
QCOM_ICC_TAG_ACTIVE_ONLY>;
+   interconnect-names = "mdp0-mem", "cpu-cfg";
+
+   iommus = <&apps_smmu 0x2000 0x402>;
+
+   #address-cells = <2>;
+   #size-cells = <2>;
+   ranges;
+
+   status = "disabled";
+
+   mdss_mdp: display-controller@ae01000 {
+   compatible = "qcom,sar2130p-dpu";
+   reg = <0x0 0x0ae01000 0x0 0x8f000>,
+ <0x0 0x0aeb 0x0 0x2008>;
+   reg-names = "mdp",
+   "vbif";
+
+   interrupt-parent = <&mdss>;
+   interrupts = <0>;
+
+   clocks = <&gcc GCC_DISP_AHB_CLK>,
+<&gcc GCC_DISP_HF_AXI_CLK>,
+<&dispcc DISP_CC_MDSS_AHB_CLK>,
+<&dispcc DISP_CC_MDSS_MDP_LUT_CLK>,
+<&dispcc DISP_CC_MDSS_MDP_CLK>,
+<&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+   clock-names = "bus",
+ "nrt_bus",
+ "iface",
+ "lut",
+ "core",
+ "vsync";
+
+   power-domains = <&rpmhpd RPMHPD_MMCX>;
+
+   assigned-clocks = <&dispcc 
DISP_CC_MDSS_VSYNC_CLK>;
+   assigned-clock-rates = <1920>;
+
+   operating-points-v2 = <&mdp_opp_table>;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   port@0 {
+   reg = <0>;
+
+   dpu_intf1_out: endpoint {
+   remote-endpoint = 
<&mdss_dsi0_in>;
+   };
+   };
+
+   port@1 {
+   reg = <1>;
+
+   dpu_intf2_out: endpoint {
+   remote-endpoint = 
<&mdss_dsi1_in>;
+   };
+   };
+
+ 

[PATCH v2 07/10] drm/msm/dsi/phy: add configuration for SAR2130P

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Qualcomm SAR2130P requires slightly different setup for the DSI PHY. It
is a 5nm PHY (like SM8450), so supplies are the same, but the rest of
the configuration is the same as SM8550 DSI PHY.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c |  2 ++
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.h |  1 +
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 23 +++
 3 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c 
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
index 
c0bcc68289633fd7506ce4f1f963655d862e8f08..a58bafe9fe8635730cb82e8c82ec1ded394988cd
 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -581,6 +581,8 @@ static const struct of_device_id dsi_phy_dt_match[] = {
  .data = &dsi_phy_7nm_cfgs },
{ .compatible = "qcom,dsi-phy-7nm-8150",
  .data = &dsi_phy_7nm_8150_cfgs },
+   { .compatible = "qcom,sar2130p-dsi-phy-5nm",
+ .data = &dsi_phy_5nm_sar2130p_cfgs },
{ .compatible = "qcom,sc7280-dsi-phy-7nm",
  .data = &dsi_phy_7nm_7280_cfgs },
{ .compatible = "qcom,sm6375-dsi-phy-7nm",
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h 
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
index 
1925418da24263d6621299cae78f1fb9455c..1ed08b56e056094bc0096d07d4470b89d9824060
 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
@@ -59,6 +59,7 @@ extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_5nm_sar2130p_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs;
 
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c 
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
index 
a92decbee5b5433853ed973747f7705d9079068d..cad55702746b8d35949d22090796cca60f03b9e1
 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
@@ -1289,6 +1289,29 @@ const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs = {
.quirks = DSI_PHY_7NM_QUIRK_V4_3,
 };
 
+const struct msm_dsi_phy_cfg dsi_phy_5nm_sar2130p_cfgs = {
+   .has_phy_lane = true,
+   .regulator_data = dsi_phy_7nm_97800uA_regulators,
+   .num_regulators = ARRAY_SIZE(dsi_phy_7nm_97800uA_regulators),
+   .ops = {
+   .enable = dsi_7nm_phy_enable,
+   .disable = dsi_7nm_phy_disable,
+   .pll_init = dsi_pll_7nm_init,
+   .save_pll_state = dsi_7nm_pll_save_state,
+   .restore_pll_state = dsi_7nm_pll_restore_state,
+   .set_continuous_clock = dsi_7nm_set_continuous_clock,
+   },
+   .min_pll_rate = 6UL,
+#ifdef CONFIG_64BIT
+   .max_pll_rate = 50UL,
+#else
+   .max_pll_rate = ULONG_MAX,
+#endif
+   .io_start = { 0xae95000, 0xae97000 },
+   .num_dsi_phy = 2,
+   .quirks = DSI_PHY_7NM_QUIRK_V5_2,
+};
+
 const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = {
.has_phy_lane = true,
.regulator_data = dsi_phy_7nm_98400uA_regulators,

-- 
2.39.5



[PATCH RFC v4 2/6] drm/display: dp: change drm_dp_dpcd_read_link_status() return value

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

drm_dp_dpcd_read_link_status() follows the "return error code or number
of bytes read" protocol, with the code returning less bytes than
requested in case of some errors. However most of the drivers
interpreted that as "return error code in case of any error". Switch
drm_dp_dpcd_read_link_status() to drm_dp_dpcd_read_data() and make it
follow that protocol too.

Acked-by: Jani Nikula 
Reviewed-by: Lyude Paul 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/amd/amdgpu/atombios_dp.c   |  8 
 .../gpu/drm/bridge/cadence/cdns-mhdp8546-core.c|  2 +-
 drivers/gpu/drm/display/drm_dp_helper.c|  7 +++
 drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c   |  4 ++--
 drivers/gpu/drm/msm/dp/dp_ctrl.c   | 24 +-
 drivers/gpu/drm/msm/dp/dp_link.c   | 18 
 drivers/gpu/drm/radeon/atombios_dp.c   |  8 
 7 files changed, 28 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c 
b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
index 
521b9faab18059ed92ebb1dc9a9847e8426e7403..492813ab1b54197ba842075bc2909984c39bd5c1
 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
@@ -458,8 +458,8 @@ bool amdgpu_atombios_dp_needs_link_train(struct 
amdgpu_connector *amdgpu_connect
u8 link_status[DP_LINK_STATUS_SIZE];
struct amdgpu_connector_atom_dig *dig = amdgpu_connector->con_priv;
 
-   if (drm_dp_dpcd_read_link_status(&amdgpu_connector->ddc_bus->aux, 
link_status)
-   <= 0)
+   if (drm_dp_dpcd_read_link_status(&amdgpu_connector->ddc_bus->aux,
+link_status) < 0)
return false;
if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
return false;
@@ -616,7 +616,7 @@ amdgpu_atombios_dp_link_train_cr(struct 
amdgpu_atombios_dp_link_train_info *dp_i
drm_dp_link_train_clock_recovery_delay(dp_info->aux, 
dp_info->dpcd);
 
if (drm_dp_dpcd_read_link_status(dp_info->aux,
-dp_info->link_status) <= 0) {
+dp_info->link_status) < 0) {
DRM_ERROR("displayport link status failed\n");
break;
}
@@ -681,7 +681,7 @@ amdgpu_atombios_dp_link_train_ce(struct 
amdgpu_atombios_dp_link_train_info *dp_i
drm_dp_link_train_channel_eq_delay(dp_info->aux, dp_info->dpcd);
 
if (drm_dp_dpcd_read_link_status(dp_info->aux,
-dp_info->link_status) <= 0) {
+dp_info->link_status) < 0) {
DRM_ERROR("displayport link status failed\n");
break;
}
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c 
b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 
81fad14c2cd598045d989c7d51f292bafb92c144..8d5420a5b691180c4d051a450d5d3d869a558d1a
 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -2305,7 +2305,7 @@ static int cdns_mhdp_update_link_status(struct 
cdns_mhdp_device *mhdp)
 * If everything looks fine, just return, as we don't handle
 * DP IRQs.
 */
-   if (ret > 0 &&
+   if (!ret &&
drm_dp_channel_eq_ok(status, mhdp->link.num_lanes) &&
drm_dp_clock_recovery_ok(status, mhdp->link.num_lanes))
goto out;
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
b/drivers/gpu/drm/display/drm_dp_helper.c
index 
e43a8f4a252dae22eeaae1f4ca94da064303033d..410be0be233ad94702af423262a7d98e21afbfeb
 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -778,14 +778,13 @@ EXPORT_SYMBOL(drm_dp_dpcd_write);
  * @aux: DisplayPort AUX channel
  * @status: buffer to store the link status in (must be at least 6 bytes)
  *
- * Returns the number of bytes transferred on success or a negative error
- * code on failure.
+ * Returns a negative error code on failure or 0 on success.
  */
 int drm_dp_dpcd_read_link_status(struct drm_dp_aux *aux,
 u8 status[DP_LINK_STATUS_SIZE])
 {
-   return drm_dp_dpcd_read(aux, DP_LANE0_1_STATUS, status,
-   DP_LINK_STATUS_SIZE);
+   return drm_dp_dpcd_read_data(aux, DP_LANE0_1_STATUS, status,
+DP_LINK_STATUS_SIZE);
 }
 EXPORT_SYMBOL(drm_dp_dpcd_read_link_status);
 
diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c 
b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c
index 
f6355c16cc0ab2e28408ab8a7246f4ca17710456..a3b78b0fd53ef854a54edf40fb333766da88f1c6
 100644
--- a/drivers/gpu/drm

Re: [PATCH v4 4/7] dt-bindings: gpu: v3d: Add per-compatible register restrictions

2025-03-13 Thread Maíra Canal

+Cc Stefan

Hi Krzysztof,

On 13/03/25 12:03, Krzysztof Kozlowski wrote:

On 13/03/2025 15:43, Maíra Canal wrote:

In order to enforce per-SoC register rules, add per-compatible
restrictions. V3D 3.3 (represented by brcm,7268-v3d) has a cache
controller (GCA), which is not present in other V3D generations.
Declaring these differences helps ensure the DTB accurately reflect
the hardware design.

While not ideal, this commit keeps the register order flexible for
brcm,7268-v3d with the goal to keep the ABI backwards compatible.

Signed-off-by: Maíra Canal 
---
  .../devicetree/bindings/gpu/brcm,bcm-v3d.yaml  | 73 ++
  1 file changed, 61 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml 
b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
index 
dc078ceeca9ac3447ba54a7c8830821f0b2a7f9f..9867b617c60c6fe34a0f88a3ee2f581a94b69a5c
 100644
--- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
+++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
@@ -22,20 +22,10 @@ properties:
- brcm,7278-v3d
  
reg:

-items:
-  - description: hub register (required)
-  - description: core0 register (required)
-  - description: GCA cache controller register (if GCA controller present)
-  - description: bridge register (if no external reset controller)
-minItems: 2


Widest constraints always stay here, so you cannot remove minItems.


+maxItems: 4


  
reg-names:

-items:
-  - const: hub
-  - const: core0
-  - enum: [ bridge, gca ]
-  - enum: [ bridge, gca ]
-minItems: 2


Same problem.


+maxItems: 4
  
interrupts:

  items:
@@ -58,6 +48,65 @@ required:
- reg-names
- interrupts


...


+  - if:
+  properties:
+compatible:
+  contains:
+const: brcm,7268-v3d
+then:
+  properties:
+reg:
+  items:
+- description: hub register
+- description: core0 register
+- description: GCA cache controller register
+- description: bridge register (if no external reset controller)
+  minItems: 3
+reg-names:
+  items:
+- const: hub
+- const: core0
+- enum: [ bridge, gca ]



> So GCA is always there? Then this should be just 'gca'. Your list for

GCA is always there for V3D 3.3, therefore it is always there for
brcm,7268-v3d.


'reg' already says that third item must be GCA. I understand that you do
not want to affect the ABI, but it already kind of is with enforcing GCA
in 'reg'.


I'm adding Stefan to the loop as he was the one that converted this DT
binding to YAML. Stefan, could you share your thoughts about breaking
the ABI for BCM7268? We would enforce the following order: hub, core0,
bridge, and gca.



I anyway do not understand why 'gca' or 'bridge' are supposed to be
optional. Does the given SoC differ between boards? What is the external
reset controller here? External like outside of SoC?


TBH I never saw BCM7268 or BCM7278 in the wild, but you are correct,
"bridge" shouldn't change for the same SoC. I'll do my diligence and
research more about those SoCs.

Best Regards,
- Maíra



Best regards,
Krzysztof




Re: [PATCH v5 04/16] drm/atomic: Introduce helper to lookup connector by encoder

2025-03-13 Thread Dmitry Baryshkov
On Fri, Mar 14, 2025 at 08:50:29AM +0800, Andy Yan wrote:
> 
> Hi Maxime and Simona,
> 
> 
> At 2025-03-13 19:55:33, "Maxime Ripard"  wrote:
> >Hi,
> >
> >On Thu, Mar 13, 2025 at 04:09:54PM +0800, Andy Yan wrote:
> >> At 2025-03-05 19:55:19, "Andy Yan"  wrote:
> >> >At 2025-03-04 19:10:47, "Maxime Ripard"  wrote:
> >> >>With the bridges switching over to drm_bridge_connector, the direct
> >> >>association between a bridge driver and its connector was lost.
> >> >>
> >> >>This is mitigated for atomic bridge drivers by the fact you can access
> >> >>the encoder, and then call drm_atomic_get_old_connector_for_encoder() or
> >> >>drm_atomic_get_new_connector_for_encoder() with drm_atomic_state.
> >> >>
> >> >>This was also made easier by providing drm_atomic_state directly to all
> >> >>atomic hooks bridges can implement.
> >> >>
> >> >>However, bridge drivers don't have a way to access drm_atomic_state
> >> >>outside of the modeset path, like from the hotplug interrupt path or any
> >> >>interrupt handler.
> >> >>
> >> >>Let's introduce a function to retrieve the connector currently assigned
> >> >>to an encoder, without using drm_atomic_state, to make these drivers'
> >> >>life easier.
> >> >>
> >> >>Reviewed-by: Dmitry Baryshkov 
> >> >>Co-developed-by: Simona Vetter 
> >> >>Signed-off-by: Maxime Ripard 
> >> >>---
> >> >> drivers/gpu/drm/drm_atomic.c | 45 
> >> >> 
> >> >> include/drm/drm_atomic.h |  3 +++
> >> >> 2 files changed, 48 insertions(+)
> >> >>
> >> >>diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >> >>index 
> >> >>9ea2611770f43ce7ccba410406d5f2c528aab022..b926b132590e78f8d41d48eb4da4bccf170ee236
> >> >> 100644
> >> >>--- a/drivers/gpu/drm/drm_atomic.c
> >> >>+++ b/drivers/gpu/drm/drm_atomic.c
> >> >>@@ -985,10 +985,55 @@ drm_atomic_get_new_connector_for_encoder(const 
> >> >>struct drm_atomic_state *state,
> >> >> 
> >> >> return NULL;
> >> >> }
> >> >> EXPORT_SYMBOL(drm_atomic_get_new_connector_for_encoder);
> >> >> 
> >> >>+/**
> >> >>+ * drm_atomic_get_connector_for_encoder - Get connector currently 
> >> >>assigned to an encoder
> >> >>+ * @encoder: The encoder to find the connector of
> >> >>+ * @ctx: Modeset locking context
> >> >>+ *
> >> >>+ * This function finds and returns the connector currently assigned to
> >> >>+ * an @encoder.
> >> >>+ *
> >> >>+ * Returns:
> >> >>+ * The connector connected to @encoder, or an error pointer otherwise.
> >> >>+ * When the error is EDEADLK, a deadlock has been detected and the
> >> >>+ * sequence must be restarted.
> >> >>+ */
> >> >>+struct drm_connector *
> >> >>+drm_atomic_get_connector_for_encoder(const struct drm_encoder *encoder,
> >> >>+ struct drm_modeset_acquire_ctx 
> >> >>*ctx)
> >> >>+{
> >> >>+struct drm_connector_list_iter conn_iter;
> >> >>+struct drm_connector *out_connector = ERR_PTR(-EINVAL);
> >> >>+struct drm_connector *connector;
> >> >>+struct drm_device *dev = encoder->dev;
> >> >>+int ret;
> >> >>+
> >> >>+ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx);
> >> >>+if (ret)
> >> >>+return ERR_PTR(ret);
> >> >
> >> >It seems that this will cause a deadlock when called from a  hotplug 
> >> >handling path,
> >> >I have a WIP DP diver[0],  which suggested by Dmitry to use this API from 
> >> >a 
> >> >&drm_bridge_funcs.detect callback to get the connector,  as detect is 
> >> >called by drm_helper_probe_detect,
> >> >which will hold connection_mutex first, so the deaklock happens:
> >> >
> >> >
> >> >drm_helper_probe_detect(struct drm_connector *connector,
> >> >struct drm_modeset_acquire_ctx *ctx,
> >> >bool force)
> >> >{
> >> >const struct drm_connector_helper_funcs *funcs = 
> >> > connector->helper_private;
> >> >struct drm_device *dev = connector->dev;
> >> >int ret;
> >> >
> >> >if (!ctx)
> >> >return drm_helper_probe_detect_ctx(connector, force);
> >> >
> >> >ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx);
> >> >if (ret)
> >> >return ret;
> >> >
> >> >if (funcs->detect_ctx)
> >> >ret = funcs->detect_ctx(connector, ctx, force);
> >> >else if (connector->funcs->detect)
> >> >ret = connector->funcs->detect(connector, force);
> >> >else
> >> >ret = connector_status_connected;
> >> >
> >> >if (ret != connector->status)
> >> >connector->epoch_counter += 1;
> >> >
> >> >So I wonder can we let drm_bridge_funcs.detect pass a connector for this 
> >> >case ?
> >> >
> >> >
> >> >
> >> >[0]https://lore.kernel.org/linux-rockchip/047eecfc-7e55-44ec-896f-13fe04333...@gmail.com/T/#m25bc53b79f5cc7bddfcb7aae5656f68df396f094
> >> >>+
> >> >>+drm_connector_list_iter_begin(dev, &conn_iter);
> >

[PATCH v2 04/10] dt-bindings: display/msm: qcom,sc7280-dpu: describe SAR2130P

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Describe DPU controller present on Qualcomm SAR2130P platform.

Signed-off-by: Dmitry Baryshkov 
Reviewed-by: Krzysztof Kozlowski 
---
 Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml
index 
6902795b4e2c249c2b543c1c5350f739a30553f2..df9ec15ad6c3ca1f77bebaab19ffa3adb985733d
 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sc7280-dpu.yaml
@@ -17,6 +17,7 @@ $ref: /schemas/display/msm/dpu-common.yaml#
 properties:
   compatible:
 enum:
+  - qcom,sar2130p-dpu
   - qcom,sc7280-dpu
   - qcom,sc8280xp-dpu
   - qcom,sm8350-dpu

-- 
2.39.5



[PATCH v2 05/10] dt-bindings: display/msm: Add Qualcomm SAR2130P

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Describe the Mobile Display SubSystem (MDSS) device present on the
Qualcomm SAR2130P platform. It looks pretty close to SM8550 on the
system level. SAR2130P features two DSI hosts and single DisplayPort
controller.

Signed-off-by: Dmitry Baryshkov 
Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Dmitry Baryshkov 
---
 .../bindings/display/msm/qcom,sar2130p-mdss.yaml   | 439 +
 1 file changed, 439 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sar2130p-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sar2130p-mdss.yaml
new file mode 100644
index 
..870144b53cec9d3e0892276e14b49b745d021879
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sar2130p-mdss.yaml
@@ -0,0 +1,439 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/qcom,sar2130p-mdss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SAR2130P Display MDSS
+
+maintainers:
+  - Dmitry Baryshkov 
+
+description:
+  SAR2310P MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks 
like
+  DPU display controller, DSI and DP interfaces etc.
+
+$ref: /schemas/display/msm/mdss-common.yaml#
+
+properties:
+  compatible:
+const: qcom,sar2130p-mdss
+
+  clocks:
+items:
+  - description: Display MDSS AHB
+  - description: Display AHB
+  - description: Display hf AXI
+  - description: Display core
+
+  iommus:
+maxItems: 1
+
+  interconnects:
+items:
+  - description: Interconnect path from mdp0 port to the data bus
+  - description: Interconnect path from CPU to the reg bus
+
+  interconnect-names:
+items:
+  - const: mdp0-mem
+  - const: cpu-cfg
+
+patternProperties:
+  "^display-controller@[0-9a-f]+$":
+type: object
+additionalProperties: true
+properties:
+  compatible:
+const: qcom,sar2130p-dpu
+
+  "^displayport-controller@[0-9a-f]+$":
+type: object
+additionalProperties: true
+properties:
+  compatible:
+contains:
+  const: qcom,sar2130p-dp
+
+  "^dsi@[0-9a-f]+$":
+type: object
+additionalProperties: true
+properties:
+  compatible:
+contains:
+  const: qcom,sar2130p-dsi-ctrl
+
+  "^phy@[0-9a-f]+$":
+type: object
+additionalProperties: true
+properties:
+  compatible:
+const: qcom,sar2130p-dsi-phy-5nm
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+display-subsystem@ae0 {
+compatible = "qcom,sar2130p-mdss";
+reg = <0x0ae0 0x1000>;
+reg-names = "mdss";
+
+interconnects = <&mmss_noc_master_mdp &mc_virt_slave_ebi1>,
+<&gem_noc_master_appss_proc 
&config_noc_slave_display_cfg>;
+interconnect-names = "mdp0-mem", "cpu-cfg";
+
+resets = <&dispcc_disp_cc_mdss_core_bcr>;
+
+power-domains = <&dispcc_mdss_gdsc>;
+
+clocks = <&dispcc_disp_cc_mdss_ahb_clk>,
+ <&gcc_gcc_disp_ahb_clk>,
+ <&gcc_gcc_disp_hf_axi_clk>,
+ <&dispcc_disp_cc_mdss_mdp_clk>;
+clock-names = "iface", "bus", "nrt_bus", "core";
+
+interrupts = ;
+interrupt-controller;
+#interrupt-cells = <1>;
+
+iommus = <&apps_smmu 0x1c00 0x2>;
+
+#address-cells = <1>;
+#size-cells = <1>;
+ranges;
+
+display-controller@ae01000 {
+compatible = "qcom,sar2130p-dpu";
+reg = <0x0ae01000 0x8f000>,
+  <0x0aeb 0x2008>;
+reg-names = "mdp", "vbif";
+
+clocks = <&gcc_gcc_disp_ahb_clk>,
+ <&gcc_gcc_disp_hf_axi_clk>,
+ <&dispcc_disp_cc_mdss_ahb_clk>,
+ <&dispcc_disp_cc_mdss_mdp_lut_clk>,
+ <&dispcc_disp_cc_mdss_mdp_clk>,
+ <&dispcc_disp_cc_mdss_vsync_clk>;
+clock-names = "bus",
+  "nrt_bus",
+  "iface",
+  "lut",
+  "core",
+  "vsync";
+
+assigned-clocks = <&dispcc_disp_cc_mdss_vsync_clk>;
+assigned-clock-rates = <1920>;
+
+operating-points-v2 = <&mdp_opp_table>;
+power-domains = <&rpmhpd RPMHPD_MMCX>;
+
+interrupt-parent = <&mdss>;
+interrupts = <0>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+
+dpu_intf0_out: endpoint {
+remote-endpoint = <&mdss_dp0_in>;
+};
+};
+
+port@1 {
+reg = <1>;
+
+dpu_in

[PATCH v2 00/10] drm/msm: add support for SAR2130P

2025-03-13 Thread Dmitry Baryshkov
Add support for the Mobile Display SubSystem (MDSS) device present on
the Qualcomm SAR2130P platform. The MDSS device is similar to SM8550, it
features two MIPI DSI controllers, two MIPI DSI PHYs and one DisplayPort
controller.

Note, due to the technical limitations DP controller wasn't completely
evaluated.

Signed-off-by: Dmitry Baryshkov 
---
Changes in v2:
- In MDSS schema switched from list items to contains: (Krzyztof)
- In MDSS schema dropped extra empty lines (Krzysztof)
- Fixed .ubwc_bank_spread in msm_mdss. (LKP)
- Link to v1: 
https://lore.kernel.org/r/20250308-sar2130p-display-v1-0-1d4c30f43...@linaro.org

---
Dmitry Baryshkov (10):
  dt-bindings: display/msm: dp-controller: describe SAR2130P
  dt-bindings: display/msm: dsi-controller-main: describe SAR2130P
  dt-bindings: display/msm: dsi-phy-7nm: describe SAR2130P
  dt-bindings: display/msm: qcom,sc7280-dpu: describe SAR2130P
  dt-bindings: display/msm: Add Qualcomm SAR2130P
  drm/msm/mdss: add SAR2130P device configuration
  drm/msm/dsi/phy: add configuration for SAR2130P
  drm/msm/dpu: add catalog entry for SAR2130P
  iommu/arm-smmu-qcom: Add SAR2130P MDSS compatible
  arm64: dts: qcom: sar2130p: add display nodes

 .../bindings/display/msm/dp-controller.yaml|   1 +
 .../bindings/display/msm/dsi-controller-main.yaml  |   2 +
 .../bindings/display/msm/dsi-phy-7nm.yaml  |   1 +
 .../bindings/display/msm/qcom,sar2130p-mdss.yaml   | 439 +
 .../bindings/display/msm/qcom,sc7280-dpu.yaml  |   1 +
 arch/arm64/boot/dts/qcom/sar2130p.dtsi | 394 ++
 .../drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h   | 434 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   1 +
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c  |   2 +
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.h  |   1 +
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c  |  23 ++
 drivers/gpu/drm/msm/msm_mdss.c |  11 +
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c |   1 +
 15 files changed, 1313 insertions(+), 1 deletion(-)
---
base-commit: 613af589b566093ce7388bf3202fca70d742c166
change-id: 20250308-sar2130p-display-b0601fcfeb30

Best regards,
-- 
Dmitry Baryshkov 



[PATCH v2 06/10] drm/msm/mdss: add SAR2130P device configuration

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Add compatible and device configuration for the Qualcomm SAR2130P
platform.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/msm_mdss.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index 
dcb49fd30402b80edd2cb5971f95a78eaad6081f..f706e44231a9c360ac4abe26e4050e416d8c3940
 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -592,6 +592,16 @@ static const struct msm_mdss_data sa8775p_data = {
.reg_bus_bw = 74000,
 };
 
+static const struct msm_mdss_data sar2130p_data = {
+   .ubwc_enc_version = UBWC_3_0, /* 4.0.2 in hw */
+   .ubwc_dec_version = UBWC_4_3,
+   .ubwc_swizzle = 6,
+   .ubwc_bank_spread = true,
+   .highest_bank_bit = 0,
+   .macrotile_mode = 1,
+   .reg_bus_bw = 74000,
+};
+
 static const struct msm_mdss_data sc7180_data = {
.ubwc_enc_version = UBWC_2_0,
.ubwc_dec_version = UBWC_2_0,
@@ -738,6 +748,7 @@ static const struct of_device_id mdss_dt_match[] = {
{ .compatible = "qcom,msm8998-mdss", .data = &msm8998_data },
{ .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data },
{ .compatible = "qcom,sa8775p-mdss", .data = &sa8775p_data },
+   { .compatible = "qcom,sar2130p-mdss", .data = &sar2130p_data },
{ .compatible = "qcom,sdm670-mdss", .data = &sdm670_data },
{ .compatible = "qcom,sdm845-mdss", .data = &sdm845_data },
{ .compatible = "qcom,sc7180-mdss", .data = &sc7180_data },

-- 
2.39.5



[PATCH v2 03/10] dt-bindings: display/msm: dsi-phy-7nm: describe SAR2130P

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Describe MIPI DSI PHY present on Qualcomm SAR2130P platform.

Signed-off-by: Dmitry Baryshkov 
Reviewed-by: Krzysztof Kozlowski 
---
 Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml
index 
321470435e654f1d569fc54f6a810e3f70fb168c..f79be422b8892484216b407f7385789764c2de1b
 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-phy-7nm.yaml
@@ -17,6 +17,7 @@ properties:
 enum:
   - qcom,dsi-phy-7nm
   - qcom,dsi-phy-7nm-8150
+  - qcom,sar2130p-dsi-phy-5nm
   - qcom,sc7280-dsi-phy-7nm
   - qcom,sm6375-dsi-phy-7nm
   - qcom,sm8350-dsi-phy-5nm

-- 
2.39.5



[PATCH v2 01/10] dt-bindings: display/msm: dp-controller: describe SAR2130P

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Describe DisplayPort controller present on Qualcomm SAR2130P platform.

Signed-off-by: Dmitry Baryshkov 
Reviewed-by: Krzysztof Kozlowski 
---
 Documentation/devicetree/bindings/display/msm/dp-controller.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml 
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 
e00b88332f2fed2fc33f6d72c5cc3d827cd7594e..246bbb509bea18bed32e3a442d0926a24498c960
 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -31,6 +31,7 @@ properties:
   - qcom,sm8650-dp
   - items:
   - enum:
+  - qcom,sar2130p-dp
   - qcom,sm6350-dp
   - qcom,sm8150-dp
   - qcom,sm8250-dp

-- 
2.39.5



[PATCH v2 08/10] drm/msm/dpu: add catalog entry for SAR2130P

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Add DPU driver support for the Qualcomm SAR2130P platform. It is mostly
the same as SM8550, minor differences in the CDP configuration.

Signed-off-by: Dmitry Baryshkov 
---
 .../drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h   | 434 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   1 +
 4 files changed, 437 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h 
b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h
new file mode 100644
index 
..22dd16c6e210e9520ecb7a851bee402032fa1ee2
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h
@@ -0,0 +1,434 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_9_1_SAR2130P_H
+#define _DPU_9_1_SAR2130P_H
+
+static const struct dpu_caps sar2130p_dpu_caps = {
+   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .max_mixer_blendstages = 0xb,
+   .has_src_split = true,
+   .has_dim_layer = true,
+   .has_idle_pc = true,
+   .has_3d_merge = true,
+   .max_linewidth = 5120,
+   .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sar2130p_mdp = {
+   .name = "top_0",
+   .base = 0, .len = 0x494,
+   .features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+   .clk_ctrls = {
+   [DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+   },
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL 
support */
+static const struct dpu_ctl_cfg sar2130p_ctl[] = {
+   {
+   .name = "ctl_0", .id = CTL_0,
+   .base = 0x15000, .len = 0x290,
+   .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+   }, {
+   .name = "ctl_1", .id = CTL_1,
+   .base = 0x16000, .len = 0x290,
+   .features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+   }, {
+   .name = "ctl_2", .id = CTL_2,
+   .base = 0x17000, .len = 0x290,
+   .features = CTL_SM8550_MASK,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+   }, {
+   .name = "ctl_3", .id = CTL_3,
+   .base = 0x18000, .len = 0x290,
+   .features = CTL_SM8550_MASK,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+   }, {
+   .name = "ctl_4", .id = CTL_4,
+   .base = 0x19000, .len = 0x290,
+   .features = CTL_SM8550_MASK,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+   }, {
+   .name = "ctl_5", .id = CTL_5,
+   .base = 0x1a000, .len = 0x290,
+   .features = CTL_SM8550_MASK,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+   },
+};
+
+static const struct dpu_sspp_cfg sar2130p_sspp[] = {
+   {
+   .name = "sspp_0", .id = SSPP_VIG0,
+   .base = 0x4000, .len = 0x344,
+   .features = VIG_SDM845_MASK_SDMA,
+   .sblk = &dpu_vig_sblk_qseed3_3_2,
+   .xin_id = 0,
+   .type = SSPP_TYPE_VIG,
+   }, {
+   .name = "sspp_1", .id = SSPP_VIG1,
+   .base = 0x6000, .len = 0x344,
+   .features = VIG_SDM845_MASK_SDMA,
+   .sblk = &dpu_vig_sblk_qseed3_3_2,
+   .xin_id = 4,
+   .type = SSPP_TYPE_VIG,
+   }, {
+   .name = "sspp_2", .id = SSPP_VIG2,
+   .base = 0x8000, .len = 0x344,
+   .features = VIG_SDM845_MASK_SDMA,
+   .sblk = &dpu_vig_sblk_qseed3_3_2,
+   .xin_id = 8,
+   .type = SSPP_TYPE_VIG,
+   }, {
+   .name = "sspp_3", .id = SSPP_VIG3,
+   .base = 0xa000, .len = 0x344,
+   .features = VIG_SDM845_MASK_SDMA,
+   .sblk = &dpu_vig_sblk_qseed3_3_2,
+   .xin_id = 12,
+   .type = SSPP_TYPE_VIG,
+   }, {
+   .name = "sspp_8", .id = SSPP_DMA0,
+   .base = 0x24000, .len = 0x344,
+   .features = DMA_SDM845_MASK_SDMA,
+   .sblk = &dpu_dma_sblk,
+   .xin_id = 1,
+   .type = SSPP_TYPE_DMA,
+   }, {
+   .name = "sspp_9", .id = SSPP_DMA1,
+   .base = 0x26000, .len = 0x344,
+   .features = DMA_SDM845_MASK_SDMA,
+   .sblk = &dpu_dma_sblk,
+   .xin_id = 5,
+   .type = SSPP_TYPE_DMA,
+   }, {
+ 

[PATCH v2] fbcon: Use static attribute groups for sysfs entries

2025-03-13 Thread oushixiong1025
From: Shixiong Ou 

Using device_create_with_groups() to simplify creation and removal.
Same as commit 1083a7be4504 ("tty: Use static attribute groups for
sysfs entries").

Signed-off-by: Shixiong Ou 
---
 drivers/video/fbdev/core/fbcon.c | 69 +---
 1 file changed, 19 insertions(+), 50 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 07d127110ca4..1d792bd11063 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -160,7 +160,6 @@ static int info_idx = -1;
 
 /* console rotation */
 static int initial_rotation = -1;
-static int fbcon_has_sysfs;
 static int margin_color;
 
 static const struct consw fb_con;
@@ -3159,7 +3158,7 @@ static const struct consw fb_con = {
.con_debug_leave= fbcon_debug_leave,
 };
 
-static ssize_t store_rotate(struct device *device,
+static ssize_t rotate_store(struct device *device,
struct device_attribute *attr, const char *buf,
size_t count)
 {
@@ -3181,7 +3180,7 @@ static ssize_t store_rotate(struct device *device,
return count;
 }
 
-static ssize_t store_rotate_all(struct device *device,
+static ssize_t rotate_all_store(struct device *device,
struct device_attribute *attr,const char *buf,
size_t count)
 {
@@ -3203,7 +3202,7 @@ static ssize_t store_rotate_all(struct device *device,
return count;
 }
 
-static ssize_t show_rotate(struct device *device,
+static ssize_t rotate_show(struct device *device,
   struct device_attribute *attr,char *buf)
 {
struct fb_info *info;
@@ -3222,7 +3221,7 @@ static ssize_t show_rotate(struct device *device,
return sysfs_emit(buf, "%d\n", rotate);
 }
 
-static ssize_t show_cursor_blink(struct device *device,
+static ssize_t cursor_blink_show(struct device *device,
 struct device_attribute *attr, char *buf)
 {
struct fb_info *info;
@@ -3247,7 +3246,7 @@ static ssize_t show_cursor_blink(struct device *device,
return sysfs_emit(buf, "%d\n", blink);
 }
 
-static ssize_t store_cursor_blink(struct device *device,
+static ssize_t cursor_blink_store(struct device *device,
  struct device_attribute *attr,
  const char *buf, size_t count)
 {
@@ -3281,35 +3280,18 @@ static ssize_t store_cursor_blink(struct device *device,
return count;
 }
 
-static struct device_attribute device_attrs[] = {
-   __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
-   __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all),
-   __ATTR(cursor_blink, S_IRUGO|S_IWUSR, show_cursor_blink,
-  store_cursor_blink),
-};
-
-static int fbcon_init_device(void)
-{
-   int i, error = 0;
+static DEVICE_ATTR_RW(rotate);
+static DEVICE_ATTR_WO(rotate_all);
+static DEVICE_ATTR_RW(cursor_blink);
 
-   fbcon_has_sysfs = 1;
-
-   for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
-   error = device_create_file(fbcon_device, &device_attrs[i]);
-
-   if (error)
-   break;
-   }
-
-   if (error) {
-   while (--i >= 0)
-   device_remove_file(fbcon_device, &device_attrs[i]);
-
-   fbcon_has_sysfs = 0;
-   }
+static struct attribute *fbcon_device_attrs[] = {
+   &dev_attr_rotate.attr,
+   &dev_attr_rotate_all.attr,
+   &dev_attr_cursor_blink.attr,
+   NULL
+};
 
-   return 0;
-}
+ATTRIBUTE_GROUPS(fbcon_device);
 
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
 static void fbcon_register_existing_fbs(struct work_struct *work)
@@ -3367,16 +3349,16 @@ void __init fb_console_init(void)
int i;
 
console_lock();
-   fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
-"fbcon");
+   fbcon_device = device_create_with_groups(fb_class, NULL,
+MKDEV(0, 0), NULL,
+fbcon_device_groups, "fbcon");
 
if (IS_ERR(fbcon_device)) {
printk(KERN_WARNING "Unable to create device "
   "for fbcon; errno = %ld\n",
   PTR_ERR(fbcon_device));
fbcon_device = NULL;
-   } else
-   fbcon_init_device();
+   }
 
for (i = 0; i < MAX_NR_CONSOLES; i++)
con2fb_map[i] = -1;
@@ -3387,18 +3369,6 @@ void __init fb_console_init(void)
 
 #ifdef MODULE
 
-static void __exit fbcon_deinit_device(void)
-{
-   int i;
-
-   if (fbcon_has_sysfs) {
-   for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
-   device_remove_file(fbcon_device, &device_attrs[i]);
-
-   fbcon_has_sysfs = 0;
-   }
-}
-
 void __exit fb_console_exit(void)
 {
 #ifdef

[PATCH v2 09/10] iommu/arm-smmu-qcom: Add SAR2130P MDSS compatible

2025-03-13 Thread Dmitry Baryshkov
From: Dmitry Baryshkov 

Add the SAR2130P compatible to clients compatible list, the device
require identity domain.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c 
b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 
59d02687280e8d37b5e944619fcfe4ebd1bd6926..ecc4a1bc9477b766f317a58ef8b5dbcfe448afa9
 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -356,6 +356,7 @@ static const struct of_device_id 
qcom_smmu_client_of_match[] __maybe_unused = {
{ .compatible = "qcom,mdp4" },
{ .compatible = "qcom,mdss" },
{ .compatible = "qcom,qcm2290-mdss" },
+   { .compatible = "qcom,sar2130p-mdss" },
{ .compatible = "qcom,sc7180-mdss" },
{ .compatible = "qcom,sc7180-mss-pil" },
{ .compatible = "qcom,sc7280-mdss" },

-- 
2.39.5



Re: [PATCH] drm/msm/dpu: Fix error pointers in dpu_plane_virtual_atomic_check

2025-03-13 Thread Dmitry Baryshkov
On Thu, Mar 13, 2025 at 08:10:04PM -0500, Chenyuan Yang wrote:
> The function dpu_plane_virtual_atomic_check was dereferencing pointers
> returned by drm_atomic_get_plane_state without checking for errors. This
> could lead to undefined behavior if the function returns an error pointer.
> 
> This commit adds checks using IS_ERR to ensure that plane_state is
> valid before dereferencing them.
> 
> Similar to commit da29abe71e16
> ("drm/amd/display: Fix error pointers in amdgpu_dm_crtc_mem_type_changed").
> 
> Fixes: 774bcfb73176 ("drm/msm/dpu: add support for virtual planes")
> Signed-off-by: Chenyuan Yang 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 3 +++
>  1 file changed, 3 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov 
-- 
With best wishes
Dmitry


[PATCH] drm/panel/synaptics-r63353: Use _multi variants

2025-03-13 Thread Anusha Srivatsa
Move away from using deprecated API and use _multi
variants if available. Use mipi_dsi_msleep()
and mipi_dsi_usleep_range() instead of msleep()
and usleep_range() respectively.

Used Coccinelle to find the _multi variant APIs,
replacing mpi_dsi_msleep() where necessary and for returning
dsi_ctx.accum_err in these functions. Manually handled the
reset step before returning from r63353_panel_activate()

v2: Do not skip the reset in case of error during
panel activate (Dmitry)
- Convert all usleep_range()

v3: mipi_dsi_usleep_range() is to be used only when in
between _multi commands(Doug)
- Check for error once in the end while using _multi
variants (Doug)

@rule_1@
identifier dsi_var;
identifier r;
identifier func;
type t;
position p;
expression dsi_device;
expression list es;
@@
t func(...) {
...
struct mipi_dsi_device *dsi_var = dsi_device;
+struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi_var };
<+...
(
-r = mipi_dsi_dcs_nop(dsi_var)@p;
+mipi_dsi_dcs_nop_multi(&dsi_ctx);
|
-r = mipi_dsi_dcs_exit_sleep_mode(dsi_var)@p;
+mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
|
-r = mipi_dsi_dcs_enter_sleep_mode(dsi_var)@p;
+mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
|
-r = mipi_dsi_dcs_write_buffer(dsi_var,es)@p;
+mipi_dsi_dcs_write_buffer_multi(&dsi_ctx,es);
|
-r = mipi_dsi_dcs_set_display_off(dsi_var,es)@p;
+mipi_dsi_dcs_set_display_off_multi(&dsi_ctx,es);
|
-r = mipi_dsi_compression_mode_ext(dsi_var,es)@p;
+mipi_dsi_compression_mode_ext_multi(&dsi_ctx,es);
|
-r = mipi_dsi_compression_mode(dsi_var,es)@p;
+mipi_dsi_compression_mode_multi(&dsi_ctx,es);
|
-r = mipi_dsi_picture_parameter_set(dsi_var,es)@p;
+mipi_dsi_picture_parameter_set_multi(&dsi_ctx,es);
|
-r = mipi_dsi_dcs_set_display_on(dsi_var,es)@p;
+mipi_dsi_dcs_set_display_on_multi(&dsi_ctx,es);
|
-r = mipi_dsi_dcs_set_tear_on(dsi_var)@p;
+mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx);
|
-r = mipi_dsi_turn_on_peripheral(dsi_var)@p;
+mipi_dsi_turn_on_peripheral_multi(&dsi_ctx);
|
-r = mipi_dsi_dcs_soft_reset(dsi_var)@p;
+mipi_dsi_dcs_soft_reset_multi(&dsi_ctx);
|
-r = mipi_dsi_dcs_set_display_brightness(dsi_var,es)@p;
+mipi_dsi_dcs_set_display_brightness_multi(&dsi_ctx,es);
|
-r = mipi_dsi_dcs_set_pixel_format(dsi_var,es)@p;
+mipi_dsi_dcs_set_pixel_format_multi(&dsi_ctx,es);
|
-r = mipi_dsi_dcs_set_column_address(dsi_var,es)@p;
+mipi_dsi_dcs_set_column_address_multi(&dsi_ctx,es);
|
-r = mipi_dsi_dcs_set_page_address(dsi_var,es)@p;
+mipi_dsi_dcs_set_page_address_multi(&dsi_ctx,es);
|
-r = mipi_dsi_dcs_set_tear_scanline(dsi_var,es)@p;
+mipi_dsi_dcs_set_tear_scanline_multi(&dsi_ctx,es);
)
-if(r < 0) {
-...
-}
...+>
}

@rule_2@
identifier dsi_var;
identifier r;
identifier func;
type t;
position p;
expression dsi_device;
expression list es;
@@
t func(...) {
...
struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi_var };
<+...
(
-r = msleep(es)@p;
+r = mipi_dsi_msleep(&dsi_ctx,es);
|
-msleep(es)@p;
+mipi_dsi_msleep(&dsi_ctx,es);
|
-r = usleep_range(es)@p;
+r = mipi_dsi_usleep_range(&dsi_ctx,es);
|
-usleep_range(es)@p;
+mipi_dsi_usleep_range(&dsi_ctx,es);
)
...+>
}

@rule_3@
identifier dsi_var;
identifier func;
type t;
position p;
expression list es;
@@
t func(...) {
...
struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi_var };
...
-return 0;
+return dsi_ctx.accum_err;
}

Cc: Maxime Ripard 
Cc: Dmitry Baryshkov 
Cc: Tejas Vipin 
Cc: Doug Anderson 
Signed-off-by: Anusha Srivatsa 
---
Previous attempt for this change was addressed in:[1]
The series did not handle returns properly and still
used msleep() and usleep_range() API.
It also collided with an Tejas's similar efforts.

Will be sending the patches per driver instead of
major haul of changes.

Following [2] for reference.

[1] -> https://patchwork.freedesktop.org/series/144824/
[2] -> 
https://lore.kernel.org/dri-devel/20250220045721.145905-1-tejasvipi...@gmail.com/#iZ31drivers:gpu:drm:panel:panel-sony-td4353-jdi.c
---
Changes in v3:
- Modify the script to handle returns and msleeps ()
- handle reset in case of error properly

- Link to v2: 
https://lore.kernel.org/all/20250310-mipi-synaptic-1-v2-1-20ee4397c...@redhat.com/
__
Changes in v2:
- Handle the reset case properly 
- Handle msleep() and  usleep_range()

- Link to v1: 
https://lore.kernel.org/r/20250305-mipi-synaptic-1-v1-1-92017cd19...@redhat.com
---
 drivers/gpu/drm/panel/panel-synaptics-r63353.c | 66 --
 1 file changed, 19 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-synaptics-r63353.c 
b/drivers/gpu/drm/panel/panel-synaptics-r63353.c
index 
17349825543fe6a117bbfd9cb92a564ce433d13a..e792d6124183d881d07cbafdd0e2dd1a0d034a6f
 100644
--- a/drivers/gpu/drm/panel/panel-synaptics-r63353.c
+++ b/drivers/gpu/drm/panel/panel-synaptics-r63353.c
@@ -106,53 +106,34 @@ static int r63353_panel_power_off(struct r63353_panel 
*rpanel)
 static int r63353_panel_activate(struct r63353_panel *rpanel)
 {
struct mipi_dsi_device *dsi = rpanel->dsi;
-   struct device *dev = &dsi->dev;
-   int i, ret;
+ 

Re: [PATCH 2/5] drm/bridge: cdns-mhdp8546: Switch to common helpers to power up/down dp link

2025-03-13 Thread Dmitry Baryshkov
On Fri, Mar 14, 2025 at 11:38:41AM +0800, Andy Yan wrote:
> From: Andy Yan 
> 
> Use the common dp link power up/down helpers to avoid duplicating code.
> 
> Signed-off-by: Andy Yan 
> ---
> 
>  .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 74 +--
>  1 file changed, 2 insertions(+), 72 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov 

-- 
With best wishes
Dmitry


Re: [PATCH 3/5] drm/bridge: anx6345: Switch to common helpers to power up/down dp link

2025-03-13 Thread Dmitry Baryshkov
On Fri, Mar 14, 2025 at 11:38:42AM +0800, Andy Yan wrote:
> From: Andy Yan 
> 
> Use the common dp link power up/down helpers to avoid duplicating code.
> 
> Signed-off-by: Andy Yan 
> ---
> 
>  .../drm/bridge/analogix/analogix-anx6345.c| 30 +--
>  1 file changed, 1 insertion(+), 29 deletions(-)
> 

Reviewed-by: Dmitry Baryshkov 

-- 
With best wishes
Dmitry


[PATCH v4 10/14] s390: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because
__func__ is not a define but a virtual variable).

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Cc: Heiko Carstens 
Cc: Vasily Gorbik 
Cc: Alexander Gordeev 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 arch/s390/include/asm/bug.h | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index c500d45fb465..44d4e9f24ae0 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -8,6 +8,15 @@
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR"   .long   %0-.\n"
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNC_PTR
+# define __BUG_FUNCNULL
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+
 #define __EMIT_BUG(x) do { \
asm_inline volatile(\
"0: mc  0,0\n"  \
@@ -17,10 +26,12 @@
".section __bug_table,\"aw\"\n" \
"2: .long   0b-.\n" \
"   .long   1b-.\n" \
-   "   .short  %0,%1\n"\
-   "   .org2b+%2\n"\
+   __BUG_FUNC_PTR  \
+   "   .short  %1,%2\n"\
+   "   .org2b+%3\n"\
".previous\n"   \
-   : : "i" (__LINE__), \
+   : : "i" (__BUG_FUNC),   \
+   "i" (__LINE__), \
"i" (x),\
"i" (sizeof(struct bug_entry)));\
 } while (0)
-- 
2.34.1



[PATCH v4 14/14] powerpc: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because __func__
is not a define but a virtual variable).

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Cc: Michael Ellerman 
Signed-off-by: Guenter Roeck 
Acked-by: Michael Ellerman 
Signed-off-by: Alessandro Carminati 
---
 arch/powerpc/include/asm/bug.h | 37 +-
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index 1db485aacbd9..5b06745d20aa 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -14,6 +14,9 @@
 .section __bug_table,"aw"
 5001:   .4byte \addr - .
 .4byte 5002f - .
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+.4byte 0
+#endif
 .short \line, \flags
 .org 5001b+BUG_ENTRY_SIZE
 .previous
@@ -32,30 +35,46 @@
 #endif /* verbose */
 
 #else /* !__ASSEMBLY__ */
-/* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
-   sizeof(struct bug_entry), respectively */
+/* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3,%4 to be FILE, __func__, LINE, 
flags
+   and sizeof(struct bug_entry), respectively */
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR"   .4byte %1 - .\n"
+#else
+# define __BUG_FUNC_PTR
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+
 #define _EMIT_BUG_ENTRY\
".section __bug_table,\"aw\"\n" \
"2: .4byte 1b - .\n"\
"   .4byte %0 - .\n"\
-   "   .short %1, %2\n"\
-   ".org 2b+%3\n"  \
+   __BUG_FUNC_PTR  \
+   "   .short %2, %3\n"\
+   ".org 2b+%4\n"  \
".previous\n"
 #else
 #define _EMIT_BUG_ENTRY\
".section __bug_table,\"aw\"\n" \
"2: .4byte 1b - .\n"\
-   "   .short %2\n"\
-   ".org 2b+%3\n"  \
+   "   .short %3\n"\
+   ".org 2b+%4\n"  \
".previous\n"
 #endif
 
+#ifdef HAVE_BUG_FUNCTION
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNCNULL
+#endif
+
 #define BUG_ENTRY(insn, flags, ...)\
__asm__ __volatile__(   \
"1: " insn "\n" \
_EMIT_BUG_ENTRY \
-   : : "i" (__FILE__), "i" (__LINE__), \
+   : : "i" (__FILE__), "i" (__BUG_FUNC),   \
+ "i" (__LINE__),   \
  "i" (flags),  \
  "i" (sizeof(struct bug_entry)),   \
  ##__VA_ARGS__)
@@ -80,7 +99,7 @@
if (x)  \
BUG();  \
} else {\
-   BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "r" ((__force long)(x)));  
\
+   BUG_ENTRY(PPC_TLNEI " %5, 0", 0, "r" ((__force long)(x)));  
\
}   \
 } while (0)
 
@@ -90,7 +109,7 @@
if (__ret_warn_on)  \
__WARN();   \
} else {\
-   BUG_ENTRY(PPC_TLNEI " %4, 0",   \
+   BUG_ENTRY(PPC_TLNEI " %5, 0",   \
  BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN),  \
  "r" (__ret_warn_on)); \
}   \
-- 
2.34.1



[PATCH v4 13/14] riscv: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because __func__
is not a define but a virtual variable).

To simplify the implementation, unify the __BUG_ENTRY_ADDR and
__BUG_ENTRY_FILE macros into a single macro named __BUG_REL() which takes
the address, file, or function reference as parameter.

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Cc: Paul Walmsley 
Cc: Palmer Dabbelt 
Cc: Albert Ou 
Signed-off-by: Guenter Roeck 
Reviewed-by: Charlie Jenkins 
Signed-off-by: Alessandro Carminati 
---
 arch/riscv/include/asm/bug.h | 38 
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
index 1aaea81fb141..79f360af4ad8 100644
--- a/arch/riscv/include/asm/bug.h
+++ b/arch/riscv/include/asm/bug.h
@@ -30,26 +30,39 @@
 typedef u32 bug_insn_t;
 
 #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
-#define __BUG_ENTRY_ADDR   RISCV_INT " 1b - ."
-#define __BUG_ENTRY_FILE   RISCV_INT " %0 - ."
+#define __BUG_REL(val) RISCV_INT " " __stringify(val) " - ."
 #else
-#define __BUG_ENTRY_ADDR   RISCV_PTR " 1b"
-#define __BUG_ENTRY_FILE   RISCV_PTR " %0"
+#define __BUG_REL(val) RISCV_PTR " " __stringify(val)
 #endif
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR__BUG_REL(%1)
+#else
+# define __BUG_FUNC_PTR
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+
 #define __BUG_ENTRY\
-   __BUG_ENTRY_ADDR "\n\t" \
-   __BUG_ENTRY_FILE "\n\t" \
-   RISCV_SHORT " %1\n\t"   \
-   RISCV_SHORT " %2"
+   __BUG_REL(1b) "\n\t"\
+   __BUG_REL(%0) "\n\t"\
+   __BUG_FUNC_PTR "\n\t"   \
+   RISCV_SHORT " %2\n\t"   \
+   RISCV_SHORT " %3"
 #else
 #define __BUG_ENTRY\
-   __BUG_ENTRY_ADDR "\n\t" \
-   RISCV_SHORT " %2"
+   __BUG_REL(1b) "\n\t"\
+   RISCV_SHORT " %3"
 #endif
 
 #ifdef CONFIG_GENERIC_BUG
+#ifdef HAVE_BUG_FUNCTION
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNCNULL
+#endif
+
 #define __BUG_FLAGS(flags) \
 do {   \
__asm__ __volatile__ (  \
@@ -58,10 +71,11 @@ do {
\
".pushsection __bug_table,\"aw\"\n\t"   \
"2:\n\t"\
__BUG_ENTRY "\n\t"  \
-   ".org 2b + %3\n\t"  \
+   ".org 2b + %4\n\t"  \
".popsection"   \
:   \
-   : "i" (__FILE__), "i" (__LINE__),   \
+   : "i" (__FILE__), "i" (__BUG_FUNC), \
+ "i" (__LINE__),   \
  "i" (flags),  \
  "i" (sizeof(struct bug_entry)));  \
 } while (0)
-- 
2.34.1



[PATCH v4 09/14] parisc: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because __func__
is not a define but a virtual variable).

While at it, declare assembler parameters as constants where possible.
Refine .blockz instructions to calculate the necessary padding instead
of using fixed values.

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Acked-by: Helge Deller 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 arch/parisc/include/asm/bug.h | 29 +
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h
index 833555f74ffa..b59c3f7380bf 100644
--- a/arch/parisc/include/asm/bug.h
+++ b/arch/parisc/include/asm/bug.h
@@ -23,8 +23,17 @@
 # define __BUG_REL(val) ".word " __stringify(val)
 #endif
 
-
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR__BUG_REL(%c1)
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNC_PTR
+# define __BUG_FUNCNULL
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+
 #define BUG()  \
do {\
asm volatile("\n"   \
@@ -33,10 +42,12 @@
 "\t.align 4\n" \
 "2:\t" __BUG_REL(1b) "\n"  \
 "\t" __BUG_REL(%c0)  "\n"  \
-"\t.short %1, %2\n"\
-"\t.blockz %3-2*4-2*2\n"   \
+"\t" __BUG_FUNC_PTR  "\n"  \
+"\t.short %c2, %c3\n"  \
+"\t.blockz %c4-(.-2b)\n"   \
 "\t.popsection"\
-: : "i" (__FILE__), "i" (__LINE__),\
+: : "i" (__FILE__), "i" (__BUG_FUNC),  \
+"i" (__LINE__),\
 "i" (0), "i" (sizeof(struct bug_entry)) ); \
unreachable();  \
} while(0)
@@ -58,10 +69,12 @@
 "\t.align 4\n" \
 "2:\t" __BUG_REL(1b) "\n"  \
 "\t" __BUG_REL(%c0)  "\n"  \
-"\t.short %1, %2\n"\
-"\t.blockz %3-2*4-2*2\n"   \
+"\t" __BUG_FUNC_PTR  "\n"  \
+"\t.short %c2, %3\n"   \
+"\t.blockz %c4-(.-2b)\n"   \
 "\t.popsection"\
-: : "i" (__FILE__), "i" (__LINE__),\
+: : "i" (__FILE__), "i" (__BUG_FUNC),  \
+"i" (__LINE__),\
 "i" (BUGFLAG_WARNING|(flags)), \
 "i" (sizeof(struct bug_entry)) );  \
} while(0)
@@ -74,7 +87,7 @@
 "\t.align 4\n" \
 "2:\t" __BUG_REL(1b) "\n"  \
 "\t.short %0\n"\
-"\t.blockz %1-4-2\n"   \
+"\t.blockz %c1-(.-2b)\n"   \
 "\t.popsection"\
 : : "i" (BUGFLAG_WARNING|(flags)), \
 "i" (sizeof(struct bug_entry)) );  \
-- 
2.34.1



[PATCH v4 07/14] arm64: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because __func__
is not a define but a virtual variable).

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Cc: Catalin Marinas 
Cc: Will Deacon 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 arch/arm64/include/asm/asm-bug.h | 27 ++-
 arch/arm64/include/asm/bug.h |  8 +++-
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/asm-bug.h b/arch/arm64/include/asm/asm-bug.h
index 6e73809f6492..bf0a5ba81611 100644
--- a/arch/arm64/include/asm/asm-bug.h
+++ b/arch/arm64/include/asm/asm-bug.h
@@ -8,37 +8,46 @@
 #include 
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
-#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line)
-#define __BUGVERBOSE_LOCATION(file, line)  \
+
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR(func)  .long func - .;
+#else
+# define __BUG_FUNC_PTR(func)
+#endif
+
+#define _BUGVERBOSE_LOCATION(file, func, line) __BUGVERBOSE_LOCATION(file, 
func, line)
+#define __BUGVERBOSE_LOCATION(file, func, line)\
.pushsection .rodata.str,"aMS",@progbits,1; \
14472:  .string file;   \
.popsection;\
\
.long 14472b - .;   \
+   __BUG_FUNC_PTR(func)\
.short line;
 #else
-#define _BUGVERBOSE_LOCATION(file, line)
+#define _BUGVERBOSE_LOCATION(file, func, line)
 #endif
 
 #ifdef CONFIG_GENERIC_BUG
 
-#define __BUG_ENTRY(flags) \
+#define __BUG_ENTRY(flags, func)   \
.pushsection __bug_table,"aw";  \
.align 2;   \
14470:  .long 14471f - .;   \
-_BUGVERBOSE_LOCATION(__FILE__, __LINE__)   \
+_BUGVERBOSE_LOCATION(__FILE__, func, __LINE__) \
.short flags;   \
.align 2;   \
.popsection;\
14471:
 #else
-#define __BUG_ENTRY(flags)
+#define __BUG_ENTRY(flags, func)
 #endif
 
-#define ASM_BUG_FLAGS(flags)   \
-   __BUG_ENTRY(flags)  \
+#define ASM_BUG_FLAGS(flags, func) \
+   __BUG_ENTRY(flags, func)\
brk BUG_BRK_IMM
 
-#define ASM_BUG()  ASM_BUG_FLAGS(0)
+#define ASM_BUG()  ASM_BUG_FLAGS(0, .)
 
 #endif /* __ASM_ASM_BUG_H */
diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h
index 28be048db3f6..044c5e24a17d 100644
--- a/arch/arm64/include/asm/bug.h
+++ b/arch/arm64/include/asm/bug.h
@@ -11,8 +11,14 @@
 
 #include 
 
+#ifdef HAVE_BUG_FUNCTION
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNCNULL
+#endif
+
 #define __BUG_FLAGS(flags) \
-   asm volatile (__stringify(ASM_BUG_FLAGS(flags)));
+   asm volatile (__stringify(ASM_BUG_FLAGS(flags, %c0)) : : "i" 
(__BUG_FUNC));
 
 #define BUG() do { \
__BUG_FLAGS(0); \
-- 
2.34.1



[PATCH v4 05/14] drm: Suppress intentional warning backtraces in scaling unit tests

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

The drm_test_rect_calc_hscale and drm_test_rect_calc_vscale unit tests
intentionally trigger warning backtraces by providing bad parameters to
the tested functions. What is tested is the return value, not the existence
of a warning backtrace. Suppress the backtraces to avoid clogging the
kernel log and distraction from real problems.

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Acked-by: Maíra Canal 
Cc: Maarten Lankhorst 
Cc: David Airlie 
Cc: Daniel Vetter 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 drivers/gpu/drm/tests/drm_rect_test.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/tests/drm_rect_test.c 
b/drivers/gpu/drm/tests/drm_rect_test.c
index 17e1f34b7610..e8d707b4a101 100644
--- a/drivers/gpu/drm/tests/drm_rect_test.c
+++ b/drivers/gpu/drm/tests/drm_rect_test.c
@@ -406,22 +406,38 @@ KUNIT_ARRAY_PARAM(drm_rect_scale, drm_rect_scale_cases, 
drm_rect_scale_case_desc
 
 static void drm_test_rect_calc_hscale(struct kunit *test)
 {
+   DEFINE_SUPPRESSED_WARNING(drm_calc_scale);
const struct drm_rect_scale_case *params = test->param_value;
int scaling_factor;
 
+   /*
+* drm_rect_calc_hscale() generates a warning backtrace whenever bad
+* parameters are passed to it. This affects all unit tests with an
+* error code in expected_scaling_factor.
+*/
+   KUNIT_START_SUPPRESSED_WARNING(drm_calc_scale);
scaling_factor = drm_rect_calc_hscale(¶ms->src, ¶ms->dst,
  params->min_range, 
params->max_range);
+   KUNIT_END_SUPPRESSED_WARNING(drm_calc_scale);
 
KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
 }
 
 static void drm_test_rect_calc_vscale(struct kunit *test)
 {
+   DEFINE_SUPPRESSED_WARNING(drm_calc_scale);
const struct drm_rect_scale_case *params = test->param_value;
int scaling_factor;
 
+   /*
+* drm_rect_calc_vscale() generates a warning backtrace whenever bad
+* parameters are passed to it. This affects all unit tests with an
+* error code in expected_scaling_factor.
+*/
+   KUNIT_START_SUPPRESSED_WARNING(drm_calc_scale);
scaling_factor = drm_rect_calc_vscale(¶ms->src, ¶ms->dst,
  params->min_range, 
params->max_range);
+   KUNIT_END_SUPPRESSED_WARNING(drm_calc_scale);
 
KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
 }
-- 
2.34.1



[PATCH v4 04/14] kunit: Add documentation for warning backtrace suppression API

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Document API functions for suppressing warning backtraces.

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Reviewed-by: Kees Cook 
Signed-off-by: Guenter Roeck 
Reviewed-by: David Gow 
Signed-off-by: Alessandro Carminati 
---
 Documentation/dev-tools/kunit/usage.rst | 30 -
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/Documentation/dev-tools/kunit/usage.rst 
b/Documentation/dev-tools/kunit/usage.rst
index 22955d56b379..b2f1e56d53b4 100644
--- a/Documentation/dev-tools/kunit/usage.rst
+++ b/Documentation/dev-tools/kunit/usage.rst
@@ -157,6 +157,34 @@ Alternatively, one can take full control over the error 
message by using
if (some_setup_function())
KUNIT_FAIL(test, "Failed to setup thing for testing");
 
+Suppressing warning backtraces
+--
+
+Some unit tests trigger warning backtraces either intentionally or as side
+effect. Such backtraces are normally undesirable since they distract from
+the actual test and may result in the impression that there is a problem.
+
+Such backtraces can be suppressed. To suppress a backtrace in some_function(),
+use the following code.
+
+.. code-block:: c
+
+   static void some_test(struct kunit *test)
+   {
+   DEFINE_SUPPRESSED_WARNING(some_function);
+
+   KUNIT_START_SUPPRESSED_WARNING(some_function);
+   trigger_backtrace();
+   KUNIT_END_SUPPRESSED_WARNING(some_function);
+   }
+
+SUPPRESSED_WARNING_COUNT() returns the number of suppressed backtraces. If the
+suppressed backtrace was triggered on purpose, this can be used to check if
+the backtrace was actually triggered.
+
+.. code-block:: c
+
+   KUNIT_EXPECT_EQ(test, SUPPRESSED_WARNING_COUNT(some_function), 1);
 
 Test Suites
 ~~~
@@ -857,4 +885,4 @@ For example:
dev_managed_string = devm_kstrdup(fake_device, "Hello, World!");
 
// Everything is cleaned up automatically when the test ends.
-   }
\ No newline at end of file
+   }
-- 
2.34.1



Re: [PATCH v4 07/14] arm64: Add support for suppressing warning backtraces

2025-03-13 Thread Will Deacon
On Thu, Mar 13, 2025 at 11:43:22AM +, Alessandro Carminati wrote:
> diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h
> index 28be048db3f6..044c5e24a17d 100644
> --- a/arch/arm64/include/asm/bug.h
> +++ b/arch/arm64/include/asm/bug.h
> @@ -11,8 +11,14 @@
>  
>  #include 
>  
> +#ifdef HAVE_BUG_FUNCTION
> +# define __BUG_FUNC  __func__
> +#else
> +# define __BUG_FUNC  NULL
> +#endif
> +
>  #define __BUG_FLAGS(flags)   \
> - asm volatile (__stringify(ASM_BUG_FLAGS(flags)));
> + asm volatile (__stringify(ASM_BUG_FLAGS(flags, %c0)) : : "i" 
> (__BUG_FUNC));

Why is 'i' the right asm constraint to use here? It seems a bit odd to
use that for a pointer.

Will



Re: [PATCH 1/2] lib/vsprintf: Add support for generic FourCCs by extending %p4cc

2025-03-13 Thread Andy Shevchenko
On Thu, Mar 13, 2025 at 08:53:28AM +, Aditya Garg wrote:
> > On 13 Mar 2025, at 2:19 PM, Andy Shevchenko 
> >  wrote:
> > On Thu, Mar 13, 2025 at 07:26:05AM +, Aditya Garg wrote:
>  On 13 Mar 2025, at 12:58 AM, Andy Shevchenko 
>   wrote:
> >>> On Wed, Mar 12, 2025 at 07:14:36PM +, Aditya Garg wrote:
> > On 12 Mar 2025, at 9:05 PM, Sven Peter  wrote:
> > On Wed, Mar 12, 2025, at 13:03, Aditya Garg wrote:

...

> > I don't have a strong opinion either way: for SMC I just need to print
> > FourCC keys for debugging / information in a few places.
> > 
> > I'm preparing the SMC driver for upstreaming again (after a two year 
> > delay :-()
> > and was just going to use macros to print the SMC FourCC keys similar to
> > DRM_MODE_FMT/DRM_MODE_ARG for now to keep the series smaller and revisit
> > the topic later.
> > 
> > Right now I have these in my local tree (only compile tested so far):
> > 
> > #define SMC_KEY_FMT "%c%c%c%c (0x%08x)"
> > #define SMC_KEY_ARG(k) (k)>>24, (k)>>16, (k)>>8, (k), (k)
>  
>  That seems to be a nice alternative, which I guess Thomas was also 
>  suggesting.
> >>> 
> >>> I don't think it's "nice". Each of the approaches has pros and cons.
> >>> You can start from bloat-o-meter here and compare it with your %p 
> >>> extension.
> >>> 
> >>> Also, can you show the bloat-o-meter output for the vsprintf.c?
> >> 
> >> Here are your outputs:
> > 
> > Thank you!
> > 
> >> -
> >> For appletbdrm:
> >> 
> >> aditya@MacBook:~/linux$ ./scripts/bloat-o-meter $P4 $MACRO
> >> add/remove: 0/0 grow/shrink: 1/1 up/down: 64/-19 (45)
> >> Function old new   delta
> >> appletbdrm_read_response 395 459 +64
> >> appletbdrm_probe17861767 -19
> >> Total: Before=13418, After=13463, chg +0.34%
> > 
> > This is enough, no need to repeat this for every parameter.
> > 
> >> -
> >> For vsprintf:
> >> 
> >> aditya@MacBook:~/linux$ ./scripts/bloat-o-meter $OLD $NEW
> >> add/remove: 0/0 grow/shrink: 1/0 up/down: 220/0 (220)
> >> Function old new   delta
> >> fourcc_string479 699+220
> >> Total: Before=26454, After=26674, chg +0.83%
> > 
> > So, we get +220 bytes vs +43 bytes. It means if we found 5+ users, it worth
> > doing.
> 
> Will it also depend upon the number of times it's being used? In appletbdrm,
> it is being used 3 times. Probably more in Asahi SMC.

Right, it depends on the usage count. Also on different architectures it may
give different results. On 32-bit it probably gives better statistics.

> > which are then used like this:
> > 
> > dev_info(dev,
> > "Initialized (%d keys " SMC_KEY_FMT " .. " SMC_KEY_FMT ")\n",
> >  smc->key_count, SMC_KEY_ARG(smc->first_key),
> >  SMC_KEY_ARG(smc->last_key));

-- 
With Best Regards,
Andy Shevchenko




[PATCH v4 03/14] kunit: Add test cases for backtrace warning suppression

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add unit tests to verify that warning backtrace suppression works.

If backtrace suppression does _not_ work, the unit tests will likely
trigger unsuppressed backtraces, which should actually help to get
the affected architectures / platforms fixed.

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Reviewed-by: Kees Cook 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 lib/kunit/Makefile |   7 +-
 lib/kunit/backtrace-suppression-test.c | 104 +
 2 files changed, 109 insertions(+), 2 deletions(-)
 create mode 100644 lib/kunit/backtrace-suppression-test.c

diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
index 3195e861d63c..539a044a9f12 100644
--- a/lib/kunit/Makefile
+++ b/lib/kunit/Makefile
@@ -18,11 +18,14 @@ endif
 
 # KUnit 'hooks' and bug handling are built-in even when KUnit is built
 # as a module.
-obj-y +=   hooks.o \
-   bug.o
+obj-y +=   hooks.o
+obj-$(CONFIG_KUNIT_SUPPRESS_BACKTRACE) += bug.o
 
 obj-$(CONFIG_KUNIT_TEST) +=kunit-test.o
 obj-$(CONFIG_KUNIT_TEST) +=platform-test.o
+ifeq ($(CONFIG_KUNIT_SUPPRESS_BACKTRACE),y)
+obj-$(CONFIG_KUNIT_TEST) +=backtrace-suppression-test.o
+endif
 
 # string-stream-test compiles built-in only.
 ifeq ($(CONFIG_KUNIT_TEST),y)
diff --git a/lib/kunit/backtrace-suppression-test.c 
b/lib/kunit/backtrace-suppression-test.c
new file mode 100644
index ..8b4125af2481
--- /dev/null
+++ b/lib/kunit/backtrace-suppression-test.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for suppressing warning tracebacks
+ *
+ * Copyright (C) 2024, Guenter Roeck
+ * Author: Guenter Roeck 
+ */
+
+#include 
+#include 
+
+static void backtrace_suppression_test_warn_direct(struct kunit *test)
+{
+   DEFINE_SUPPRESSED_WARNING(backtrace_suppression_test_warn_direct);
+
+   KUNIT_START_SUPPRESSED_WARNING(backtrace_suppression_test_warn_direct);
+   WARN(1, "This backtrace should be suppressed");
+   KUNIT_END_SUPPRESSED_WARNING(backtrace_suppression_test_warn_direct);
+
+   KUNIT_EXPECT_EQ(test, 
SUPPRESSED_WARNING_COUNT(backtrace_suppression_test_warn_direct), 1);
+}
+
+static void trigger_backtrace_warn(void)
+{
+   WARN(1, "This backtrace should be suppressed");
+}
+
+static void backtrace_suppression_test_warn_indirect(struct kunit *test)
+{
+   DEFINE_SUPPRESSED_WARNING(trigger_backtrace_warn);
+
+   KUNIT_START_SUPPRESSED_WARNING(trigger_backtrace_warn);
+   trigger_backtrace_warn();
+   KUNIT_END_SUPPRESSED_WARNING(trigger_backtrace_warn);
+
+   KUNIT_EXPECT_EQ(test, SUPPRESSED_WARNING_COUNT(trigger_backtrace_warn), 
1);
+}
+
+static void backtrace_suppression_test_warn_multi(struct kunit *test)
+{
+   DEFINE_SUPPRESSED_WARNING(trigger_backtrace_warn);
+   DEFINE_SUPPRESSED_WARNING(backtrace_suppression_test_warn_multi);
+
+   KUNIT_START_SUPPRESSED_WARNING(backtrace_suppression_test_warn_multi);
+   KUNIT_START_SUPPRESSED_WARNING(trigger_backtrace_warn);
+   WARN(1, "This backtrace should be suppressed");
+   trigger_backtrace_warn();
+   KUNIT_END_SUPPRESSED_WARNING(trigger_backtrace_warn);
+   KUNIT_END_SUPPRESSED_WARNING(backtrace_suppression_test_warn_multi);
+
+   KUNIT_EXPECT_EQ(test, 
SUPPRESSED_WARNING_COUNT(backtrace_suppression_test_warn_multi), 1);
+   KUNIT_EXPECT_EQ(test, SUPPRESSED_WARNING_COUNT(trigger_backtrace_warn), 
1);
+}
+
+static void backtrace_suppression_test_warn_on_direct(struct kunit *test)
+{
+   DEFINE_SUPPRESSED_WARNING(backtrace_suppression_test_warn_on_direct);
+
+   if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE) && 
!IS_ENABLED(CONFIG_KALLSYMS))
+   kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE or 
CONFIG_KALLSYMS");
+
+   
KUNIT_START_SUPPRESSED_WARNING(backtrace_suppression_test_warn_on_direct);
+   WARN_ON(1);
+   KUNIT_END_SUPPRESSED_WARNING(backtrace_suppression_test_warn_on_direct);
+
+   KUNIT_EXPECT_EQ(test,
+   
SUPPRESSED_WARNING_COUNT(backtrace_suppression_test_warn_on_direct), 1);
+}
+
+static void trigger_backtrace_warn_on(void)
+{
+   WARN_ON(1);
+}
+
+static void backtrace_suppression_test_warn_on_indirect(struct kunit *test)
+{
+   DEFINE_SUPPRESSED_WARNING(trigger_backtrace_warn_on);
+
+   if (!IS_ENABLED(CONFIG_DEBUG_BUGVERBOSE))
+   kunit_skip(test, "requires CONFIG_DEBUG_BUGVERBOSE");
+
+   KUNIT_START_SUPPRESSED_WARNING(trigger_backtrace_warn_on);
+   trigger_backtrace_warn_on();
+   KUNIT_END_SUPPRESSED_WARNING(trigger_backtrace_warn_on);
+
+   KUNIT_EXPECT_EQ(test, 
SUPPRESSED_WARNING_COUNT(trigger_backtrace_warn_on), 1);
+}
+
+static struct kunit_case backtrace_suppression_test_cases[] = {
+   KUNIT_CASE(backtrace_suppression_test_warn_direct),
+   KUNIT_CASE(backtra

[PATCH v4 08/14] loongarch: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because __func__
is not a define but a virtual variable).

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Cc: Huacai Chen 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 arch/loongarch/include/asm/bug.h | 42 ++--
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/arch/loongarch/include/asm/bug.h b/arch/loongarch/include/asm/bug.h
index f6f254f2c5db..b79ff6696ce6 100644
--- a/arch/loongarch/include/asm/bug.h
+++ b/arch/loongarch/include/asm/bug.h
@@ -3,49 +3,65 @@
 #define __ASM_BUG_H
 
 #include 
+#include 
 #include 
 #include 
 
 #ifndef CONFIG_DEBUG_BUGVERBOSE
-#define _BUGVERBOSE_LOCATION(file, line)
+#define _BUGVERBOSE_LOCATION(file, func, line)
 #else
-#define __BUGVERBOSE_LOCATION(file, line)  \
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR(func)  .long func - .;
+#else
+# define __BUG_FUNC_PTR(func)
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+
+#define __BUGVERBOSE_LOCATION(file, func, line)\
.pushsection .rodata.str, "aMS", @progbits, 1;  \
10002:  .string file;   \
.popsection;\
\
.long 10002b - .;   \
+   __BUG_FUNC_PTR(func)\
.short line;
-#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line)
+#define _BUGVERBOSE_LOCATION(file, func, line) __BUGVERBOSE_LOCATION(file, 
func, line)
 #endif
 
 #ifndef CONFIG_GENERIC_BUG
-#define __BUG_ENTRY(flags)
+#define __BUG_ENTRY(flags, func)
 #else
-#define __BUG_ENTRY(flags) \
+#define __BUG_ENTRY(flags, func)   \
.pushsection __bug_table, "aw"; \
.align 2;   \
1:  .long 10001f - .;   \
-   _BUGVERBOSE_LOCATION(__FILE__, __LINE__)\
+   _BUGVERBOSE_LOCATION(__FILE__, func, __LINE__)  \
.short flags;   \
.popsection;\
10001:
 #endif
 
-#define ASM_BUG_FLAGS(flags)   \
-   __BUG_ENTRY(flags)  \
+#define ASM_BUG_FLAGS(flags, func) \
+   __BUG_ENTRY(flags, func)\
break   BRK_BUG;
 
-#define ASM_BUG()  ASM_BUG_FLAGS(0)
+#define ASM_BUG()  ASM_BUG_FLAGS(0, .)
+
+#ifdef HAVE_BUG_FUNCTION
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNCNULL
+#endif
 
-#define __BUG_FLAGS(flags, extra)  \
-   asm_inline volatile (__stringify(ASM_BUG_FLAGS(flags))  \
-extra);
+#define __BUG_FLAGS(flags, extra)  \
+   asm_inline volatile (__stringify(ASM_BUG_FLAGS(flags, %0)) \
+extra : : "i" (__BUG_FUNC) );
 
 #define __WARN_FLAGS(flags)\
 do {   \
instrumentation_begin();\
-   __BUG_FLAGS(BUGFLAG_WARNING|(flags), ANNOTATE_REACHABLE(10001b));\
+   if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) \
+   __BUG_FLAGS(BUGFLAG_WARNING|(flags), 
ANNOTATE_REACHABLE(10001b));\
instrumentation_end();  \
 } while (0)
 
-- 
2.34.1



[PATCH v4 12/14] sh: Move defines needed for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Declaring the defines needed for suppressing warning inside
'#ifdef CONFIG_DEBUG_BUGVERBOSE' results in a kerneldoc warning.

.../bug.h:29: warning: expecting prototype for _EMIT_BUG_ENTRY().
Prototype was for HAVE_BUG_FUNCTION() instead

Move the defines above the kerneldoc entry for _EMIT_BUG_ENTRY
to make kerneldoc happy.

Reported-by: Simon Horman 
Cc: Simon Horman 
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: John Paul Adrian Glaubitz 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 arch/sh/include/asm/bug.h | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index 470ce6567d20..bf4947d51d69 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -11,6 +11,15 @@
 #define HAVE_ARCH_BUG
 #define HAVE_ARCH_WARN_ON
 
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR"\t.long %O2\n"
+#else
+# define __BUG_FUNC_PTR
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+#endif /* CONFIG_DEBUG_BUGVERBOSE */
+
 /**
  * _EMIT_BUG_ENTRY
  * %1 - __FILE__
@@ -25,13 +34,6 @@
  */
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 
-#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
-# define HAVE_BUG_FUNCTION
-# define __BUG_FUNC_PTR"\t.long %O2\n"
-#else
-# define __BUG_FUNC_PTR
-#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
-
 #define _EMIT_BUG_ENTRY\
"\t.pushsection __bug_table,\"aw\"\n"   \
"2:\t.long 1b, %O1\n"   \
-- 
2.34.1



[PATCH v6 02/16] drm/bridge: Provide a helper to retrieve current bridge state

2025-03-13 Thread Maxime Ripard
The current bridge state is accessible from the drm_bridge structure,
but since it's fairly indirect it's not easy to figure out.

Provide a helper to retrieve it.

Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Maxime Ripard 
---
 include/drm/drm_bridge.h | 32 
 1 file changed, 32 insertions(+)

diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 
884ff1faa4c896c28a38399ceaa5016ab704c886..cdad3b78a195aa39776c93e2371217d3d3fb6064
 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -955,10 +955,42 @@ static inline struct drm_bridge 
*of_drm_find_bridge(struct device_node *np)
 {
return NULL;
 }
 #endif
 
+/**
+ * drm_bridge_get_current_state() - Get the current bridge state
+ * @bridge: bridge object
+ *
+ * This function must be called with the modeset lock held.
+ *
+ * RETURNS:
+ *
+ * The current bridge state, or NULL if there is none.
+ */
+static inline struct drm_bridge_state *
+drm_bridge_get_current_state(struct drm_bridge *bridge)
+{
+   if (!bridge)
+   return NULL;
+
+   /*
+* Only atomic bridges will have bridge->base initialized by
+* drm_atomic_private_obj_init(), so we need to make sure we're
+* working with one before we try to use the lock.
+*/
+   if (!bridge->funcs || !bridge->funcs->atomic_reset)
+   return NULL;
+
+   drm_modeset_lock_assert_held(&bridge->base.lock);
+
+   if (!bridge->base.state)
+   return NULL;
+
+   return drm_priv_to_bridge_state(bridge->base.state);
+}
+
 /**
  * drm_bridge_get_next_bridge() - Get the next bridge in the chain
  * @bridge: bridge object
  *
  * RETURNS:

-- 
2.48.1



[PATCH v6 01/16] drm/bridge: Add encoder parameter to drm_bridge_funcs.attach

2025-03-13 Thread Maxime Ripard
The drm_bridge structure contains an encoder pointer that is widely used
by bridge drivers. This pattern is largely documented as deprecated in
other KMS entities for atomic drivers.

However, one of the main use of that pointer is done in attach to just
call drm_bridge_attach on the next bridge to add it to the bridge list.
While this dereferences the bridge->encoder pointer, it's effectively
the same encoder the bridge was being attached to.

We can make it more explicit by adding the encoder the bridge is
attached to to the list of attach parameters. This also removes the need
to dereference bridge->encoder in most drivers.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Douglas Anderson 
Tested-by: Douglas Anderson 
Tested-by: Luca Ceresoli 
Reviewed-by: Luca Ceresoli 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/adp/adp-mipi.c   |  3 ++-
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c |  3 ++-
 drivers/gpu/drm/bridge/analogix/analogix-anx6345.c   |  3 ++-
 drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c   |  3 ++-
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c   |  2 +-
 drivers/gpu/drm/bridge/analogix/anx7625.c|  3 ++-
 drivers/gpu/drm/bridge/aux-bridge.c  |  3 ++-
 drivers/gpu/drm/bridge/aux-hpd-bridge.c  |  1 +
 drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c   |  3 ++-
 drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c  |  1 +
 drivers/gpu/drm/bridge/chipone-icn6211.c |  6 --
 drivers/gpu/drm/bridge/chrontel-ch7033.c |  5 +++--
 drivers/gpu/drm/bridge/display-connector.c   |  1 +
 drivers/gpu/drm/bridge/fsl-ldb.c |  3 ++-
 drivers/gpu/drm/bridge/imx/imx-ldb-helper.c  |  7 +++
 drivers/gpu/drm/bridge/imx/imx-ldb-helper.h  |  2 +-
 drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c   |  3 ++-
 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c |  3 ++-
 drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c  |  3 ++-
 drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c  |  3 ++-
 drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c |  3 ++-
 drivers/gpu/drm/bridge/ite-it6263.c  |  7 ---
 drivers/gpu/drm/bridge/ite-it6505.c  |  1 +
 drivers/gpu/drm/bridge/ite-it66121.c |  3 ++-
 drivers/gpu/drm/bridge/lontium-lt8912b.c |  3 ++-
 drivers/gpu/drm/bridge/lontium-lt9211.c  |  3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611.c  |  3 ++-
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c   |  3 ++-
 drivers/gpu/drm/bridge/lvds-codec.c  |  3 ++-
 drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c |  1 +
 drivers/gpu/drm/bridge/microchip-lvds.c  |  3 ++-
 drivers/gpu/drm/bridge/nwl-dsi.c |  3 ++-
 drivers/gpu/drm/bridge/nxp-ptn3460.c |  5 +++--
 drivers/gpu/drm/bridge/panel.c   |  3 ++-
 drivers/gpu/drm/bridge/parade-ps8622.c   |  1 +
 drivers/gpu/drm/bridge/parade-ps8640.c   |  3 ++-
 drivers/gpu/drm/bridge/samsung-dsim.c|  3 ++-
 drivers/gpu/drm/bridge/sii902x.c |  5 +++--
 drivers/gpu/drm/bridge/sil-sii8620.c |  1 +
 drivers/gpu/drm/bridge/simple-bridge.c   |  5 +++--
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c|  3 ++-
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c|  5 +++--
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c   |  5 +++--
 drivers/gpu/drm/bridge/tc358762.c|  3 ++-
 drivers/gpu/drm/bridge/tc358764.c|  3 ++-
 drivers/gpu/drm/bridge/tc358767.c|  2 ++
 drivers/gpu/drm/bridge/tc358768.c|  3 ++-
 drivers/gpu/drm/bridge/tc358775.c|  3 ++-
 drivers/gpu/drm/bridge/tda998x_drv.c |  1 +
 drivers/gpu/drm/bridge/thc63lvd1024.c|  3 ++-
 drivers/gpu/drm/bridge/ti-dlpc3433.c |  4 ++--
 drivers/gpu/drm/bridge/ti-sn65dsi83.c|  3 ++-
 drivers/gpu/drm/bridge/ti-sn65dsi86.c|  3 ++-
 drivers/gpu/drm/bridge/ti-tdp158.c   |  6 --
 drivers/gpu/drm/bridge/ti-tfp410.c   |  5 +++--
 drivers/gpu/drm/bridge/ti-tpd12s015.c|  3 ++-
 drivers/gpu/drm/drm_bridge.c |  2 +-
 drivers/gpu/drm/imx/ipuv3/parallel-display.c |  3 ++-
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c|  5 +++--
 drivers/gpu/drm/mcde/mcde_dsi.c  |  3 ++-
 drivers/gpu/drm/mediatek/mtk_dp.c|  3 ++-
 drivers/gpu/drm/mediatek/mtk_dpi.c   |  3 ++-
 drivers/gpu/drm/me

[PATCH v6 03/16] drm/tests: Add kunit tests for bridges

2025-03-13 Thread Maxime Ripard
None of the drm_bridge function have kunit tests so far. Let's change
that, starting with drm_bridge_get_current_state().

Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Maxime Ripard 
---
 drivers/gpu/drm/Kconfig |   1 +
 drivers/gpu/drm/tests/Makefile  |   1 +
 drivers/gpu/drm/tests/drm_bridge_test.c | 210 
 3 files changed, 212 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 
e5b59de28216385f3783373e636d193d38d02646..9b406123132912f0578e9c8288d4c80e65f75f67
 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -72,10 +72,11 @@ config DRM_KUNIT_TEST_HELPERS
  KUnit Helpers for KMS drivers.
 
 config DRM_KUNIT_TEST
tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
depends on DRM && KUNIT && MMU
+   select DRM_BRIDGE_CONNECTOR
select DRM_BUDDY
select DRM_DISPLAY_DP_HELPER
select DRM_DISPLAY_HDMI_STATE_HELPER
select DRM_DISPLAY_HELPER
select DRM_EXEC
diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile
index 
0109bcf7faa54993cce337f522eae78f0fa6ffcb..6691c577d2d4581a4185bac2ce89a6b14b339b35
 100644
--- a/drivers/gpu/drm/tests/Makefile
+++ b/drivers/gpu/drm/tests/Makefile
@@ -3,10 +3,11 @@
 obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \
drm_kunit_helpers.o
 
 obj-$(CONFIG_DRM_KUNIT_TEST) += \
drm_atomic_state_test.o \
+   drm_bridge_test.o \
drm_buddy_test.o \
drm_cmdline_parser_test.o \
drm_connector_test.o \
drm_damage_helper_test.o \
drm_dp_mst_helper_test.o \
diff --git a/drivers/gpu/drm/tests/drm_bridge_test.c 
b/drivers/gpu/drm/tests/drm_bridge_test.c
new file mode 100644
index 
..c0a05c459d957c3f9d281957f002f6bd36cce367
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_bridge_test.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Kunit test for drm_bridge functions
+ */
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+struct drm_bridge_init_priv {
+   struct drm_device drm;
+   struct drm_plane *plane;
+   struct drm_crtc *crtc;
+   struct drm_encoder encoder;
+   struct drm_bridge bridge;
+   struct drm_connector *connector;
+};
+
+static const struct drm_bridge_funcs drm_test_bridge_legacy_funcs = {
+};
+
+static const struct drm_bridge_funcs drm_test_bridge_atomic_funcs = {
+   .atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
+   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+   .atomic_reset   = drm_atomic_helper_bridge_reset,
+};
+
+KUNIT_DEFINE_ACTION_WRAPPER(drm_bridge_remove_wrapper,
+   drm_bridge_remove,
+   struct drm_bridge *);
+
+static int drm_kunit_bridge_add(struct kunit *test,
+   struct drm_bridge *bridge)
+{
+   drm_bridge_add(bridge);
+
+   return kunit_add_action_or_reset(test,
+drm_bridge_remove_wrapper,
+bridge);
+}
+
+static struct drm_bridge_init_priv *
+drm_test_bridge_init(struct kunit *test, const struct drm_bridge_funcs *funcs)
+{
+   struct drm_bridge_init_priv *priv;
+   struct drm_encoder *enc;
+   struct drm_bridge *bridge;
+   struct drm_device *drm;
+   struct device *dev;
+   int ret;
+
+   dev = drm_kunit_helper_alloc_device(test);
+   if (IS_ERR(dev))
+   return ERR_CAST(dev);
+
+   priv = drm_kunit_helper_alloc_drm_device(test, dev,
+struct drm_bridge_init_priv, 
drm,
+DRIVER_MODESET | 
DRIVER_ATOMIC);
+   if (IS_ERR(priv))
+   return ERR_CAST(priv);
+
+   drm = &priv->drm;
+   priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
+   NULL,
+   NULL,
+   NULL, 0,
+   NULL);
+   if (IS_ERR(priv->plane))
+   return ERR_CAST(priv->plane);
+
+   priv->crtc = drm_kunit_helper_create_crtc(test, drm,
+ priv->plane, NULL,
+ NULL,
+ NULL);
+   if (IS_ERR(priv->crtc))
+   return ERR_CAST(priv->crtc);
+
+   enc = &priv->encoder;
+   ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
+   if (ret)
+   return ERR_PTR(ret);
+
+   enc->possible_crtcs = drm_crtc_mask(priv->crtc);
+
+   bridge = &priv->bridge;
+   bridge->type = DRM_MODE_CONNECTOR_VIRTUAL;
+   bridge->funcs = funcs;
+
+   ret = 

[PATCH v6 00/16] drm/bridge: Various quality of life improvements

2025-03-13 Thread Maxime Ripard
Hi,

Here's a series of changes after to the KMS helpers and bridge API
following a bunch of reviews I did.

It's mostly centered across providing an easier time to deal with bridge
states, and a somewhat consistent with the other entities API.

It's build tested only, with arm64 allmodconfig.

Maxime

Signed-off-by: Maxime Ripard 
---
Changes in v6:
- Rebased on top of current drm-misc-next
- Doc improvements
- Link to v5: 
https://lore.kernel.org/r/20250304-bridge-connector-v5-0-aacf461d2...@kernel.org

Changes in v5:
- Rebased on top of current drm-misc-next
- Split the new crtc / connector enabling helper into two patches
- Fix a depmod breakage with drm_bridge_reset_crtc()
- Renamed drm_bridge_reset_crtc() to drm_bridge_helper_reset_crtc()
- Add new test case for drm_bridge_helper_reset_crtc() when the bridge
  is disabled.
- Fix a few commit logs
- Link to v4: 
https://lore.kernel.org/r/20250225-bridge-connector-v4-0-7ecb07b09...@kernel.org

Changes in v4:
- Rebased on top of drm-misc-next-2025-02-20
- Changed the approach to helpers suggested by Sima, dropped the tags
  affected by the rework
- Drop drm_bridge_state->crtc and connector fields
- Drop drm_bridge->encoder deprecation
- Introduced kunit tests
- Link to v3: 
https://lore.kernel.org/r/20250213-bridge-connector-v3-0-e71598f49...@kernel.org

Changes in v3:
- Add tags
- Fix compilation breakages
- Reword some commit messages
- Create drm_bridge_is_atomic() helper
- Retrieve the CRTC state through drm_atomic_get_new_crtc_state()
  instead of crtc->state in bridges
- Fix ti-sn65dsi86
- Link to v2: 
https://lore.kernel.org/r/20250204-bridge-connector-v2-0-35dd6c834...@kernel.org

Changes in v2:
- Pass the full atomic state to bridge atomic hooks
- Make attach take the encoder as a parameter
- Mark bridge->encoder as deprecated
- Rework the logic to detect if a bridge uses a state or not at
  atomic_check time
- Add lockdep assertion to drm_bridge_get_current_state()
- Link to v1: 
https://lore.kernel.org/r/20250115-bridge-connector-v1-0-9a2fecd88...@kernel.org

---
Maxime Ripard (16):
  drm/bridge: Add encoder parameter to drm_bridge_funcs.attach
  drm/bridge: Provide a helper to retrieve current bridge state
  drm/tests: Add kunit tests for bridges
  drm/atomic: Introduce helper to lookup connector by encoder
  drm/tests: helpers: Create new helper to enable output
  drm/tests: hdmi_state_helpers: Switch to new helper
  drm/tests: Create tests for drm_atomic
  drm/bridge: Add helper to reset bridge pipeline
  drm/tests: bridge: Provide tests for drm_bridge_helper_reset_crtc
  drm/bridge: ti-sn65dsi83: Switch to drm_bridge_helper_reset_crtc
  drm/bridge: Introduce drm_bridge_is_atomic() helper
  drm/bridge: cdns-csi: Switch to atomic helpers
  drm/bridge: tc358775: Switch to atomic commit
  drm/bridge: tc358768: Stop disabling when failing to enable
  drm/bridge: tc358768: Convert to atomic helpers
  drm/bridge: ti-sn65dsi86: Remove drm_encoder->crtc use

 drivers/gpu/drm/Kconfig|   1 +
 drivers/gpu/drm/Makefile   |   1 +
 drivers/gpu/drm/adp/adp-mipi.c |   3 +-
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   |   3 +-
 drivers/gpu/drm/bridge/analogix/analogix-anx6345.c |   3 +-
 drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c |   3 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |   2 +-
 drivers/gpu/drm/bridge/analogix/anx7625.c  |   3 +-
 drivers/gpu/drm/bridge/aux-bridge.c|   3 +-
 drivers/gpu/drm/bridge/aux-hpd-bridge.c|   1 +
 drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c |  34 +-
 .../gpu/drm/bridge/cadence/cdns-mhdp8546-core.c|   1 +
 drivers/gpu/drm/bridge/chipone-icn6211.c   |   6 +-
 drivers/gpu/drm/bridge/chrontel-ch7033.c   |   5 +-
 drivers/gpu/drm/bridge/display-connector.c |   1 +
 drivers/gpu/drm/bridge/fsl-ldb.c   |   3 +-
 drivers/gpu/drm/bridge/imx/imx-ldb-helper.c|   7 +-
 drivers/gpu/drm/bridge/imx/imx-ldb-helper.h|   2 +-
 drivers/gpu/drm/bridge/imx/imx-legacy-bridge.c |   3 +-
 drivers/gpu/drm/bridge/imx/imx8mp-hdmi-pvi.c   |   3 +-
 .../gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c|   3 +-
 drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c|   3 +-
 drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c   |   3 +-
 drivers/gpu/drm/bridge/ite-it6263.c|   7 +-
 drivers/gpu/drm/bridge/ite-it6505.c|   1 +
 drivers/gpu/drm/bridge/ite-it66121.c   |   3 +-
 drivers/gpu/drm/bridge/lontium-lt8912b.c   |   3 +-
 drivers/gpu/drm/bridge/lontium-lt9211.c|   3 +-
 drivers/gpu/drm/bridge/lontium-lt9611.c|   3 +-
 drivers/gpu/drm/bridge/lontium-lt9611uxc.c |   3 +-
 drivers/gpu/drm/bridge/lvds-codec.c|   3 +-
 .../drm/bridge/megachips-stdp-ge-b850v3-fw.c   |   1 +
 drivers/gpu/drm/br

drm-ci: mediatek: kms_atomic_transition@plane-all-modeset-transition-internal-panels flake

2025-03-13 Thread Vignesh Raman

Hi Maintainers,

There are some flake test reported for mediatek driver testing in drm-ci.

# Board Name: mt8183-kukui-jacuzzi-juniper-sku16
# Failure Rate: 20
# IGT Version: 1.30-g04bedb923
# Linux Version: 6.14.0-rc4
kms_atomic_transition@plane-all-modeset-transition-internal-panels

11:34:51.896: DEBUG - Begin test 
kms_atomic_transition@plane-all-modeset-transition-internal-panels
11:34:56.978: [  356.928738] [IGT] kms_bw: finished subtest 
linear-tiling-13-displays-3840x2160p, SKIP

11:34:56.978: [  356.937111] [IGT] kms_bw: exiting, ret=77
11:34:56.978: [  356.942557] Console: switching to colour frame buffer 
device 170x48

11:34:56.978: [  357.125173] Console: switching to colour dummy device 80x25
11:34:56.978: [  357.131172] [IGT] kms_bw: executing
11:34:56.978: [  357.142820] [IGT] kms_bw: starting subtest 
linear-tiling-2-displays-2560x1440p
11:34:56.978: [  357.150596] [IGT] kms_bw: finished subtest 
linear-tiling-2-displays-2560x1440p, SKIP

11:34:56.978: [  357.158858] [IGT] kms_bw: exiting, ret=77
11:34:56.978: [  357.164180] Console: switching to colour frame buffer 
device 170x48

11:34:56.978: [  357.318688] Console: switching to colour dummy device 80x25
11:34:56.978: [  357.324648] [IGT] kms_bw: executing
11:34:56.978: [  357.333681] [IGT] kms_bw: starting subtest 
linear-tiling-6-displays-2160x1440p
11:34:56.979: [  357.341401] [IGT] kms_bw: finished subtest 
linear-tiling-6-displays-2160x1440p, SKIP

11:34:56.979: [  357.349597] [IGT] kms_bw: exiting, ret=77
11:34:56.979: [  357.354845] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  357.505411] Console: switching to colour dummy device 80x25
11:34:56.979: [  357.511255] [IGT] kms_plane_scaling: executing
11:34:56.979: [  357.522411] [IGT] kms_plane_scaling: starting subtest 
plane-downscale-factor-0-25-with-modifiers
11:34:56.979: [  357.531718] [IGT] kms_plane_scaling: starting dynamic 
subtest pipe-A
11:34:56.979: [  357.539109] [IGT] kms_plane_scaling: finished subtest 
pipe-A, SKIP
11:34:56.979: [  357.545910] [IGT] kms_plane_scaling: finished subtest 
plane-downscale-factor-0-25-with-modifiers, SKIP

11:34:56.979: [  357.572515] [IGT] kms_plane_scaling: exiting, ret=77
11:34:56.979: [  357.578308] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  357.727532] Console: switching to colour dummy device 80x25
11:34:56.979: [  357.733486] [IGT] kms_selftest: executing
11:34:56.979: [  357.745874] [IGT] kms_selftest: starting subtest 
drm_cmdline_parser
11:34:56.979: [  357.752866] [IGT] kms_selftest: finished subtest 
drm_cmdline_parser, SKIP

11:34:56.979: [  357.763629] [IGT] kms_selftest: exiting, ret=77
11:34:56.979: [  357.769361] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  357.939908] Console: switching to colour dummy device 80x25
11:34:56.979: [  357.945870] [IGT] syncobj_timeline: executing
11:34:56.979: [  357.953079] [IGT] syncobj_timeline: exiting, ret=77
11:34:56.979: [  357.959018] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  358.090580] Console: switching to colour dummy device 80x25
11:34:56.979: [  358.096444] [IGT] kms_frontbuffer_tracking: executing
11:34:56.979: [  358.140292] [IGT] kms_frontbuffer_tracking: exiting, ret=77
11:34:56.979: [  358.147183] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  358.309815] Console: switching to colour dummy device 80x25
11:34:56.979: [  358.315957] [IGT] kms_frontbuffer_tracking: executing
11:34:56.979: [  358.356383] [IGT] kms_frontbuffer_tracking: exiting, ret=77
11:34:56.979: [  358.363247] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  358.526047] Console: switching to colour dummy device 80x25
11:34:56.979: [  358.531928] [IGT] kms_frontbuffer_tracking: executing
11:34:56.979: [  358.589328] [IGT] kms_frontbuffer_tracking: exiting, ret=77
11:34:56.979: [  358.596300] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  358.754092] Console: switching to colour dummy device 80x25
11:34:56.979: [  358.76] [IGT] kms_draw_crc: executing
11:34:56.979: [  358.803687] [IGT] kms_draw_crc: exiting, ret=77
11:34:56.979: [  358.809585] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  358.971580] Console: switching to colour dummy device 80x25
11:34:56.979: [  358.977535] [IGT] prime_self_import: executing
11:34:56.979: [  358.983703] [IGT] prime_self_import: starting subtest 
basic-with_one_bo_two_files
11:34:56.979: [  359.019495] [IGT] prime_self_import: finished subtest 
basic-with_one_bo_two_files, SKIP

11:34:56.979: [  359.028121] [IGT] prime_self_import: exiting, ret=77
11:34:56.979: [  359.034326] Console: switching to colour frame buffer 
device 170x48

11:34:56.979: [  359.165297] Console: switching to colour dummy device 80x25
11:34:56.979: [  359.171219] [IGT] kms_pm_rpm: executing
11:34:56.980: [  359.201837] [IGT] kms_pm_rpm: exiting, ret=77
11:34:56.

Re: drm-ci: vkms: kms_flip@modeset-vs-vblank-race flake

2025-03-13 Thread Louis Chauvet




Le 13/03/2025 à 11:45, Vignesh Raman a écrit :

Hi Maintainers,



Hi Vignesh,

Thanks for the report.

On my setup, this test passed, and the others are skipped.

I think the issue on this specific test may be due to performance (seems 
to be a timing issue, I will try to slow down my VM). The other tests 
require suspend/resume, which I failed to setup on my VM.


To understand what is wrong, I would like to have an environment very 
similar to the CI, how can I reproduce this on my machine? Is there a 
setup script somewhere I can run to create a virtual machine?


Thanks,
Louis Chauvet


There are some flake test reported for vkms driver testing in drm-ci.

# Board Name: vkms
# Failure Rate: 20
# IGT Version: 1.30-g04bedb923
# Linux Version: 6.14.0-rc4
kms_flip@modeset-vs-vblank-race

DEBUG - Begin test kms_flip@modeset-vs-vblank-race
ERROR - Igt error: (kms_flip:1250) CRITICAL: Test assertion failure
function run_test_step, file ../tests/kms_flip.c:979:
ERROR - Igt error: (kms_flip:1250) CRITICAL: Failed assertion: end -
start > 0.9 * actual_frame_time(o) && end - start < 2.6 *
actual_frame_time(o)
ERROR - Igt error: (kms_flip:1250) CRITICAL: wait for two vblanks took
47374 usec (frame time 16665.60 usec)
ERROR - Igt error: Dynamic subtest A-Virtual17 failed.
ERROR - Igt error:  DEBUG 
ERROR - Igt error: (kms_flip:1250) igt_fb-DEBUG:
igt_create_fb_with_bo_size(width=1024, height=768,
format=XR24(0x34325258), modifier=0x0, size=0)
ERROR - Igt error: (kms_flip:1250) igt_fb-DEBUG:
igt_create_fb_with_bo_size(handle=1, pitch=4096)
ERROR - Igt error: (kms_flip:1250) ioctl_wrappers-DEBUG: Test
requirement passed: igt_has_fb_modifiers(fd)
ERROR - Igt error: (kms_flip:1250) igt_fb-DEBUG:
igt_create_fb_with_bo_size(width=1024, height=768,
format=XR24(0x34325258), modifier=0x0, size=0)
ERROR - Igt error: (kms_flip:1250) igt_fb-DEBUG:
igt_create_fb_with_bo_size(handle=2, pitch=4096)
ERROR - Igt error: (kms_flip:1250) ioctl_wrappers-DEBUG: Test
requirement passed: igt_has_fb_modifiers(fd)
ERROR - Igt error: (kms_flip:1250) igt_fb-DEBUG: Test requirement
passed: cairo_surface_status(fb->cairo_surface) == CAIRO_STATUS_SUCCESS
ERROR - Igt error: (kms_flip:1250) igt_fb-DEBUG: Test requirement
passed: cairo_surface_status(fb->cairo_surface) == CAIRO_STATUS_SUCCESS
ERROR - Igt error: (kms_flip:1250) igt_kms-INFO:   1024x768: 60 65000
1024 1048 1184 1344 768 771 777 806 0x48 0xa
ERROR - Igt error: (kms_flip:1250) DEBUG: No stale events found
ERROR - Igt error: (kms_flip:1250) INFO: Expected frametime: 1us;
measured 16665.6us +- 0.500us accuracy 0.01%
ERROR - Igt error: (kms_flip:1250) CRITICAL: Test assertion failure
function run_test_step, file ../tests/kms_flip.c:979:
ERROR - Igt error: (kms_flip:1250) CRITICAL: Failed assertion: end -
start > 0.9 * actual_frame_time(o) && end - start < 2.6 *
actual_frame_time(o)
ERROR - Igt error: (kms_flip:1250) CRITICAL: wait for two vblanks took
47374 usec (frame time 16665.60 usec)
ERROR - Igt error: (kms_flip:1250) igt_core-INFO: Stack trace:
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #0
../lib/igt_core.c:2055 __igt_fail_assert()
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #1
../tests/kms_flip.c:1023 run_test_on_crtc_set.constprop.0()
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #2
../tests/kms_flip.c:1845 run_test()
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #3
../tests/kms_flip.c:2078 __igt_uniquereal_main2001()
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #4
../tests/kms_flip.c:2001 main()
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #5
[__libc_init_first+0x8a]
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #6
[__libc_start_main+0x85]
ERROR - Igt error: (kms_flip:1250) igt_core-INFO:   #7 [_start+0x21]
ERROR - Igt error:   END  
ERROR - Igt error: (kms_flip:1250) igt_kms-CRITICAL: Test assertion
failure function kmstest_set_connector_dpms, file ../lib/igt_kms.c:2246:
ERROR - Igt error: (kms_flip:1250) igt_kms-CRITICAL: Failed assertion:
found_it
ERROR - Igt error: (kms_flip:1250) igt_kms-CRITICAL: Last errno: 9, Bad
file descriptor
ERROR - Igt error: (kms_flip:1250) igt_kms-CRITICAL: DPMS property not
found on 39
ERROR - Test kms_flip@modeset-vs-vblank-race: Fail: See
"/builds/vigneshraman/linux/results/igt.kms_f...@modeset-vs-vblank-race.log"
DEBUG - End test kms_flip@modeset-vs-vblank-race

Pipeline: https://gitlab.freedesktop.org/vigneshraman/linux/-/jobs/72473690

Please could you have a look at these test results and let us know if
you need more information. Thank you.

Regards,
Vignesh


--
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com



Re: [PATCH] drm/amd/display: avoid NPD when ASIC does not support DMUB

2025-03-13 Thread Leo Li




On 2025-03-13 07:29, Thadeu Lima de Souza Cascardo wrote:

On Wed, Feb 05, 2025 at 10:06:38AM -0300, Thadeu Lima de Souza Cascardo wrote:

ctx->dmub_srv will de NULL if the ASIC does not support DMUB, which is
tested in dm_dmub_sw_init.

However, it will be dereferenced in dmub_hw_lock_mgr_cmd if
should_use_dmub_lock returns true.

This has been the case since dmub support has been added for PSR1.


This bug has landed on stable trees. Any chance for a review here?

Thanks.
Cascardo.


Thanks for the ping and fix!

Reviewed-by: Leo Li 





Fix this by checking for dmub_srv in should_use_dmub_lock.

[   37.440832] BUG: kernel NULL pointer dereference, address: 0058
[   37.447808] #PF: supervisor read access in kernel mode
[   37.452959] #PF: error_code(0x) - not-present page
[   37.458112] PGD 0 P4D 0
[   37.460662] Oops: Oops:  [#1] PREEMPT SMP NOPTI
[   37.465553] CPU: 2 UID: 1000 PID: 1745 Comm: DrmThread Not tainted 
6.14.0-rc1-3-gd62e938120f0 #23 99720e1cb1e0fc4773b8513150932a07de3c6e88
[   37.478324] Hardware name: Google Morphius/Morphius, BIOS 
Google_Morphius.13434.858.0 10/26/2023
[   37.487103] RIP: 0010:dmub_hw_lock_mgr_cmd+0x77/0xb0
[   37.492074] Code: 44 24 0e 00 00 00 00 48 c7 04 24 45 00 00 0c 40 88 74 24 0d 0f 
b6 02 88 44 24 0c 8b 01 89 44 24 08 85 f6 75 05 c6 44 24 0e 01 <48> 8b 7f 58 48 
89 e6 ba 01 00 00 00 e8 08 3c 2a 00 65 48 8b 04 5
[   37.510822] RSP: 0018:969442853300 EFLAGS: 00010202
[   37.516052] RAX:  RBX: 92db0300 RCX: 969442853358
[   37.523185] RDX: 969442853368 RSI: 0001 RDI: 
[   37.530322] RBP: 0001 R08: 04a7 R09: 04a5
[   37.537453] R10: 0476 R11: 0062 R12: 92db0ade8000
[   37.544589] R13: 92da01180ae0 R14: 92da011802a8 R15: 92db0300
[   37.551725] FS:  784a9cdfc6c0() GS:92db2af0() 
knlGS:
[   37.559814] CS:  0010 DS:  ES:  CR0: 80050033
[   37.565562] CR2: 0058 CR3: 000112b1c000 CR4: 003506f0
[   37.572697] Call Trace:
[   37.575152]  
[   37.577258]  ? __die_body+0x66/0xb0
[   37.580756]  ? page_fault_oops+0x3e7/0x4a0
[   37.584861]  ? exc_page_fault+0x3e/0xe0
[   37.588706]  ? exc_page_fault+0x5c/0xe0
[   37.592550]  ? asm_exc_page_fault+0x22/0x30
[   37.596742]  ? dmub_hw_lock_mgr_cmd+0x77/0xb0
[   37.601107]  dcn10_cursor_lock+0x1e1/0x240
[   37.605211]  program_cursor_attributes+0x81/0x190
[   37.609923]  commit_planes_for_stream+0x998/0x1ef0
[   37.614722]  update_planes_and_stream_v2+0x41e/0x5c0
[   37.619703]  dc_update_planes_and_stream+0x78/0x140
[   37.624588]  amdgpu_dm_atomic_commit_tail+0x4362/0x49f0
[   37.629832]  ? srso_return_thunk+0x5/0x5f
[   37.633847]  ? mark_held_locks+0x6d/0xd0
[   37.637774]  ? _raw_spin_unlock_irq+0x24/0x50
[   37.642135]  ? srso_return_thunk+0x5/0x5f
[   37.646148]  ? lockdep_hardirqs_on+0x95/0x150
[   37.650510]  ? srso_return_thunk+0x5/0x5f
[   37.654522]  ? _raw_spin_unlock_irq+0x2f/0x50
[   37.658883]  ? srso_return_thunk+0x5/0x5f
[   37.662897]  ? wait_for_common+0x186/0x1c0
[   37.666998]  ? srso_return_thunk+0x5/0x5f
[   37.671009]  ? drm_crtc_next_vblank_start+0xc3/0x170
[   37.675983]  commit_tail+0xf5/0x1c0
[   37.679478]  drm_atomic_helper_commit+0x2a2/0x2b0
[   37.684186]  drm_atomic_commit+0xd6/0x100
[   37.688199]  ? __cfi___drm_printfn_info+0x10/0x10
[   37.692911]  drm_atomic_helper_update_plane+0xe5/0x130
[   37.698054]  drm_mode_cursor_common+0x501/0x670
[   37.702600]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
[   37.707572]  drm_mode_cursor_ioctl+0x48/0x70
[   37.711851]  drm_ioctl_kernel+0xf2/0x150
[   37.715781]  drm_ioctl+0x363/0x590
[   37.719189]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
[   37.724165]  amdgpu_drm_ioctl+0x41/0x80
[   37.728013]  __se_sys_ioctl+0x7f/0xd0
[   37.731685]  do_syscall_64+0x87/0x100
[   37.735355]  ? vma_end_read+0x12/0xe0
[   37.739024]  ? srso_return_thunk+0x5/0x5f
[   37.743041]  ? find_held_lock+0x47/0xf0
[   37.746884]  ? vma_end_read+0x12/0xe0
[   37.750552]  ? srso_return_thunk+0x5/0x5f
[   37.754565]  ? lock_release+0x1c4/0x2e0
[   37.758406]  ? vma_end_read+0x12/0xe0
[   37.762079]  ? exc_page_fault+0x84/0xe0
[   37.765921]  ? srso_return_thunk+0x5/0x5f
[   37.769938]  ? lockdep_hardirqs_on+0x95/0x150
[   37.774303]  ? srso_return_thunk+0x5/0x5f
[   37.778317]  ? exc_page_fault+0x84/0xe0
[   37.782163]  entry_SYSCALL_64_after_hwframe+0x55/0x5d
[   37.787218] RIP: 0033:0x784aa5ec3059
[   37.790803] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10 c7 45 b0 10 00 
00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 
f0 ff ff 77 1d 48 8b 45 c8 64 48 2b 04 25 28 00 0
[   37.809553] RSP: 002b:784a9cdf90e0 EFLAGS: 0246 ORIG_RAX: 
0010
[   37.817121] RAX: ffda RBX: 784a9cdf917c RCX: 784aa5ec3059
[   37.824256] RDX: 784a9cdf917c RSI: c01c64a3 RDI: 0

Re: [PATCH v4 4/7] dt-bindings: gpu: v3d: Add per-compatible register restrictions

2025-03-13 Thread Krzysztof Kozlowski
On 13/03/2025 15:43, Maíra Canal wrote:
> In order to enforce per-SoC register rules, add per-compatible
> restrictions. V3D 3.3 (represented by brcm,7268-v3d) has a cache
> controller (GCA), which is not present in other V3D generations.
> Declaring these differences helps ensure the DTB accurately reflect
> the hardware design.
> 
> While not ideal, this commit keeps the register order flexible for
> brcm,7268-v3d with the goal to keep the ABI backwards compatible.
> 
> Signed-off-by: Maíra Canal 
> ---
>  .../devicetree/bindings/gpu/brcm,bcm-v3d.yaml  | 73 
> ++
>  1 file changed, 61 insertions(+), 12 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml 
> b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
> index 
> dc078ceeca9ac3447ba54a7c8830821f0b2a7f9f..9867b617c60c6fe34a0f88a3ee2f581a94b69a5c
>  100644
> --- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
> +++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
> @@ -22,20 +22,10 @@ properties:
>- brcm,7278-v3d
>  
>reg:
> -items:
> -  - description: hub register (required)
> -  - description: core0 register (required)
> -  - description: GCA cache controller register (if GCA controller 
> present)
> -  - description: bridge register (if no external reset controller)
> -minItems: 2

Widest constraints always stay here, so you cannot remove minItems.

> +maxItems: 4

>  
>reg-names:
> -items:
> -  - const: hub
> -  - const: core0
> -  - enum: [ bridge, gca ]
> -  - enum: [ bridge, gca ]
> -minItems: 2

Same problem.

> +maxItems: 4
>  
>interrupts:
>  items:
> @@ -58,6 +48,65 @@ required:
>- reg-names
>- interrupts

...

> +  - if:
> +  properties:
> +compatible:
> +  contains:
> +const: brcm,7268-v3d
> +then:
> +  properties:
> +reg:
> +  items:
> +- description: hub register
> +- description: core0 register
> +- description: GCA cache controller register
> +- description: bridge register (if no external reset controller)
> +  minItems: 3
> +reg-names:
> +  items:
> +- const: hub
> +- const: core0
> +- enum: [ bridge, gca ]

So GCA is always there? Then this should be just 'gca'. Your list for
'reg' already says that third item must be GCA. I understand that you do
not want to affect the ABI, but it already kind of is with enforcing GCA
in 'reg'.

I anyway do not understand why 'gca' or 'bridge' are supposed to be
optional. Does the given SoC differ between boards? What is the external
reset controller here? External like outside of SoC?

Best regards,
Krzysztof


[PATCH v8 6/6] drm/sched: Add a basic test for checking credit limit

2025-03-13 Thread Tvrtko Ursulin
Add a basic test for checking whether scheduler respects the configured
credit limit.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
Acked-by: Christian König 
---
 drivers/gpu/drm/scheduler/tests/tests_basic.c | 60 ++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/scheduler/tests/tests_basic.c 
b/drivers/gpu/drm/scheduler/tests/tests_basic.c
index 996cac00bb52..7230057e0594 100644
--- a/drivers/gpu/drm/scheduler/tests/tests_basic.c
+++ b/drivers/gpu/drm/scheduler/tests/tests_basic.c
@@ -412,7 +412,65 @@ static struct kunit_suite drm_sched_modify_sched = {
.test_cases = drm_sched_modify_sched_tests,
 };
 
+static void drm_sched_test_credits(struct kunit *test)
+{
+   struct drm_mock_sched_entity *entity;
+   struct drm_mock_scheduler *sched;
+   struct drm_mock_sched_job *job[2];
+   bool done;
+   int i;
+
+   /*
+* Check that the configured credit limit is respected.
+*/
+
+   sched = drm_mock_sched_new(test, MAX_SCHEDULE_TIMEOUT);
+   sched->base.credit_limit = 1;
+
+   entity = drm_mock_sched_entity_new(test,
+  DRM_SCHED_PRIORITY_NORMAL,
+  sched);
+
+   job[0] = drm_mock_sched_job_new(test, entity);
+   job[1] = drm_mock_sched_job_new(test, entity);
+
+   drm_mock_sched_job_submit(job[0]);
+   drm_mock_sched_job_submit(job[1]);
+
+   done = drm_mock_sched_job_wait_scheduled(job[0], HZ);
+   KUNIT_ASSERT_TRUE(test, done);
+
+   done = drm_mock_sched_job_wait_scheduled(job[1], HZ);
+   KUNIT_ASSERT_FALSE(test, done);
+
+   i = drm_mock_sched_advance(sched, 1);
+   KUNIT_ASSERT_EQ(test, i, 1);
+
+   done = drm_mock_sched_job_wait_scheduled(job[1], HZ);
+   KUNIT_ASSERT_TRUE(test, done);
+
+   i = drm_mock_sched_advance(sched, 1);
+   KUNIT_ASSERT_EQ(test, i, 1);
+
+   done = drm_mock_sched_job_wait_finished(job[1], HZ);
+   KUNIT_ASSERT_TRUE(test, done);
+
+   drm_mock_sched_entity_free(entity);
+   drm_mock_sched_fini(sched);
+}
+
+static struct kunit_case drm_sched_credits_tests[] = {
+   KUNIT_CASE(drm_sched_test_credits),
+   {}
+};
+
+static struct kunit_suite drm_sched_credits = {
+   .name = "drm_sched_basic_credits_tests",
+   .test_cases = drm_sched_credits_tests,
+};
+
 kunit_test_suites(&drm_sched_basic,
  &drm_sched_timeout,
  &drm_sched_priority,
- &drm_sched_modify_sched);
+ &drm_sched_modify_sched,
+ &drm_sched_credits);
-- 
2.48.0



[PATCH v2] drm/mxsfb: fix missing rollback on failure in mxsfb_probe()

2025-03-13 Thread Luca Ceresoli
When aperture_remove_all_conflicting_devices() fails, the current code
returns without going through the rollback actions at the end of the
function, thus the actions done by drm_dev_alloc() and mxsfb_load() are not
undone.

Fix by moving this call at the very beginning of the probe function, so
that no rollback is needed if it fails. Conflicting drivers need to be
kicked out before setting up DRM anyway.

Fixes: c8e7b185d45b ("drm/mxsfb: Remove generic DRM drivers in probe function")
Suggested-by: Thomas Zimmermann 
Signed-off-by: Luca Ceresoli 
---
The offending commit is not yet merged into master, and even less in a
released kernel, so this does not need to go through stable.

Changes in v2:
- move this call at the beginning instead of adding a goto
---
 drivers/gpu/drm/mxsfb/mxsfb_drv.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c 
b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 
c183b1112bc4e9fe4f3b048a2b6e4c98d1d47cb3..ee64053d381448360140c419fed1dc4fe9f7c68e
 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -352,14 +352,6 @@ static int mxsfb_probe(struct platform_device *pdev)
struct drm_device *drm;
int ret;
 
-   drm = drm_dev_alloc(&mxsfb_driver, &pdev->dev);
-   if (IS_ERR(drm))
-   return PTR_ERR(drm);
-
-   ret = mxsfb_load(drm, device_get_match_data(&pdev->dev));
-   if (ret)
-   goto err_free;
-
/*
 * Remove early framebuffers (ie. simplefb). The framebuffer can be
 * located anywhere in RAM
@@ -369,6 +361,14 @@ static int mxsfb_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, ret,
 "can't kick out existing framebuffers\n");
 
+   drm = drm_dev_alloc(&mxsfb_driver, &pdev->dev);
+   if (IS_ERR(drm))
+   return PTR_ERR(drm);
+
+   ret = mxsfb_load(drm, device_get_match_data(&pdev->dev));
+   if (ret)
+   goto err_free;
+
ret = drm_dev_register(drm, 0);
if (ret)
goto err_unload;

---
base-commit: f9f087d946266bc5da7c3a17bd8fd9d01969e3cf
change-id: 20250313-mxsfb_probe-fix-rollback-on-error-3074b9080f34

Best regards,
-- 
Luca Ceresoli 



Re: [PATCH] drm/amd/display: avoid NPD when ASIC does not support DMUB

2025-03-13 Thread Alex Deucher
Applied.  Thanks.

Alex

On Thu, Mar 13, 2025 at 11:17 AM Leo Li  wrote:
>
>
>
> On 2025-03-13 07:29, Thadeu Lima de Souza Cascardo wrote:
> > On Wed, Feb 05, 2025 at 10:06:38AM -0300, Thadeu Lima de Souza Cascardo 
> > wrote:
> >> ctx->dmub_srv will de NULL if the ASIC does not support DMUB, which is
> >> tested in dm_dmub_sw_init.
> >>
> >> However, it will be dereferenced in dmub_hw_lock_mgr_cmd if
> >> should_use_dmub_lock returns true.
> >>
> >> This has been the case since dmub support has been added for PSR1.
> >
> > This bug has landed on stable trees. Any chance for a review here?
> >
> > Thanks.
> > Cascardo.
>
> Thanks for the ping and fix!
>
> Reviewed-by: Leo Li 
>
> >
> >>
> >> Fix this by checking for dmub_srv in should_use_dmub_lock.
> >>
> >> [   37.440832] BUG: kernel NULL pointer dereference, address: 
> >> 0058
> >> [   37.447808] #PF: supervisor read access in kernel mode
> >> [   37.452959] #PF: error_code(0x) - not-present page
> >> [   37.458112] PGD 0 P4D 0
> >> [   37.460662] Oops: Oops:  [#1] PREEMPT SMP NOPTI
> >> [   37.465553] CPU: 2 UID: 1000 PID: 1745 Comm: DrmThread Not tainted 
> >> 6.14.0-rc1-3-gd62e938120f0 #23 99720e1cb1e0fc4773b8513150932a07de3c6e88
> >> [   37.478324] Hardware name: Google Morphius/Morphius, BIOS 
> >> Google_Morphius.13434.858.0 10/26/2023
> >> [   37.487103] RIP: 0010:dmub_hw_lock_mgr_cmd+0x77/0xb0
> >> [   37.492074] Code: 44 24 0e 00 00 00 00 48 c7 04 24 45 00 00 0c 40 88 74 
> >> 24 0d 0f b6 02 88 44 24 0c 8b 01 89 44 24 08 85 f6 75 05 c6 44 24 0e 01 
> >> <48> 8b 7f 58 48 89 e6 ba 01 00 00 00 e8 08 3c 2a 00 65 48 8b 04 5
> >> [   37.510822] RSP: 0018:969442853300 EFLAGS: 00010202
> >> [   37.516052] RAX:  RBX: 92db0300 RCX: 
> >> 969442853358
> >> [   37.523185] RDX: 969442853368 RSI: 0001 RDI: 
> >> 
> >> [   37.530322] RBP: 0001 R08: 04a7 R09: 
> >> 04a5
> >> [   37.537453] R10: 0476 R11: 0062 R12: 
> >> 92db0ade8000
> >> [   37.544589] R13: 92da01180ae0 R14: 92da011802a8 R15: 
> >> 92db0300
> >> [   37.551725] FS:  784a9cdfc6c0() GS:92db2af0() 
> >> knlGS:
> >> [   37.559814] CS:  0010 DS:  ES:  CR0: 80050033
> >> [   37.565562] CR2: 0058 CR3: 000112b1c000 CR4: 
> >> 003506f0
> >> [   37.572697] Call Trace:
> >> [   37.575152]  
> >> [   37.577258]  ? __die_body+0x66/0xb0
> >> [   37.580756]  ? page_fault_oops+0x3e7/0x4a0
> >> [   37.584861]  ? exc_page_fault+0x3e/0xe0
> >> [   37.588706]  ? exc_page_fault+0x5c/0xe0
> >> [   37.592550]  ? asm_exc_page_fault+0x22/0x30
> >> [   37.596742]  ? dmub_hw_lock_mgr_cmd+0x77/0xb0
> >> [   37.601107]  dcn10_cursor_lock+0x1e1/0x240
> >> [   37.605211]  program_cursor_attributes+0x81/0x190
> >> [   37.609923]  commit_planes_for_stream+0x998/0x1ef0
> >> [   37.614722]  update_planes_and_stream_v2+0x41e/0x5c0
> >> [   37.619703]  dc_update_planes_and_stream+0x78/0x140
> >> [   37.624588]  amdgpu_dm_atomic_commit_tail+0x4362/0x49f0
> >> [   37.629832]  ? srso_return_thunk+0x5/0x5f
> >> [   37.633847]  ? mark_held_locks+0x6d/0xd0
> >> [   37.637774]  ? _raw_spin_unlock_irq+0x24/0x50
> >> [   37.642135]  ? srso_return_thunk+0x5/0x5f
> >> [   37.646148]  ? lockdep_hardirqs_on+0x95/0x150
> >> [   37.650510]  ? srso_return_thunk+0x5/0x5f
> >> [   37.654522]  ? _raw_spin_unlock_irq+0x2f/0x50
> >> [   37.658883]  ? srso_return_thunk+0x5/0x5f
> >> [   37.662897]  ? wait_for_common+0x186/0x1c0
> >> [   37.666998]  ? srso_return_thunk+0x5/0x5f
> >> [   37.671009]  ? drm_crtc_next_vblank_start+0xc3/0x170
> >> [   37.675983]  commit_tail+0xf5/0x1c0
> >> [   37.679478]  drm_atomic_helper_commit+0x2a2/0x2b0
> >> [   37.684186]  drm_atomic_commit+0xd6/0x100
> >> [   37.688199]  ? __cfi___drm_printfn_info+0x10/0x10
> >> [   37.692911]  drm_atomic_helper_update_plane+0xe5/0x130
> >> [   37.698054]  drm_mode_cursor_common+0x501/0x670
> >> [   37.702600]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
> >> [   37.707572]  drm_mode_cursor_ioctl+0x48/0x70
> >> [   37.711851]  drm_ioctl_kernel+0xf2/0x150
> >> [   37.715781]  drm_ioctl+0x363/0x590
> >> [   37.719189]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
> >> [   37.724165]  amdgpu_drm_ioctl+0x41/0x80
> >> [   37.728013]  __se_sys_ioctl+0x7f/0xd0
> >> [   37.731685]  do_syscall_64+0x87/0x100
> >> [   37.735355]  ? vma_end_read+0x12/0xe0
> >> [   37.739024]  ? srso_return_thunk+0x5/0x5f
> >> [   37.743041]  ? find_held_lock+0x47/0xf0
> >> [   37.746884]  ? vma_end_read+0x12/0xe0
> >> [   37.750552]  ? srso_return_thunk+0x5/0x5f
> >> [   37.754565]  ? lock_release+0x1c4/0x2e0
> >> [   37.758406]  ? vma_end_read+0x12/0xe0
> >> [   37.762079]  ? exc_page_fault+0x84/0xe0
> >> [   37.765921]  ? srso_return_thunk+0x5/0x5f
> >> [   37.769938]  ? lockdep_hardirqs_on+0x95/0x150
> >> [   37.774303]  ? srso_return_thunk+0x5/0x5f
> >> [   37.778317]  ? exc_p

Re: [PATCH] drm/amdgpu/gfx12: correct cleanup of 'me' field with gfx_v12_0_me_fini()

2025-03-13 Thread Markus Elfring
…
> can only release 'pfp' field of 'gfx'. The release function of 'me' field
> should be gfx_v12_0_me_fini().

Do you care for an imperative wording in such a change description?
https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v6.14-rc6#n94

Regards,
Markus


Re: [PATCH] drm/komeda: Remove unnecessary NULL check before clk_prepare_enable()

2025-03-13 Thread Liviu Dudau
On Thu, Mar 13, 2025 at 04:29:07PM +0800, Chen Ni wrote:
> clk_prepare_enable() already checked NULL clock parameter.
> Remove unneeded NULL check for clk here.

You're not saving anything here. If mdev->aclk is NULL you still end up
calling clk_prepare() and clk_enable() even if they return zero immediately.
And if you don't like the check for mdev->aclk not being NULL, you should
also move the clk_disable_unprepare() call outside the if() {...} block.

Best regards,
Liviu

> 
> Signed-off-by: Chen Ni 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> index 5ba62e637a61..2b59830f0572 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> @@ -282,8 +282,7 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
>  
>   debugfs_remove_recursive(mdev->debugfs_root);
>  
> - if (mdev->aclk)
> - clk_prepare_enable(mdev->aclk);
> + clk_prepare_enable(mdev->aclk);
>  
>   for (i = 0; i < mdev->n_pipelines; i++) {
>   komeda_pipeline_destroy(mdev, mdev->pipelines[i]);
> -- 
> 2.25.1
> 

-- 

| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---
¯\_(ツ)_/¯


[PATCH v4 11/14] sh: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because __func__
is not a define but a virtual variable).

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: John Paul Adrian Glaubitz 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 arch/sh/include/asm/bug.h | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/arch/sh/include/asm/bug.h b/arch/sh/include/asm/bug.h
index 05a485c4fabc..470ce6567d20 100644
--- a/arch/sh/include/asm/bug.h
+++ b/arch/sh/include/asm/bug.h
@@ -24,21 +24,36 @@
  * The offending file and line are encoded in the __bug_table section.
  */
 #ifdef CONFIG_DEBUG_BUGVERBOSE
+
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR"\t.long %O2\n"
+#else
+# define __BUG_FUNC_PTR
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+
 #define _EMIT_BUG_ENTRY\
"\t.pushsection __bug_table,\"aw\"\n"   \
"2:\t.long 1b, %O1\n"   \
-   "\t.short %O2, %O3\n"   \
-   "\t.org 2b+%O4\n"   \
+   __BUG_FUNC_PTR  \
+   "\t.short %O3, %O4\n"   \
+   "\t.org 2b+%O5\n"   \
"\t.popsection\n"
 #else
 #define _EMIT_BUG_ENTRY\
"\t.pushsection __bug_table,\"aw\"\n"   \
"2:\t.long 1b\n"\
-   "\t.short %O3\n"\
-   "\t.org 2b+%O4\n"   \
+   "\t.short %O4\n"\
+   "\t.org 2b+%O5\n"   \
"\t.popsection\n"
 #endif
 
+#ifdef HAVE_BUG_FUNCTION
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNCNULL
+#endif
+
 #define BUG()  \
 do {   \
__asm__ __volatile__ (  \
@@ -47,6 +62,7 @@ do {  \
 :  \
 : "n" (TRAPA_BUG_OPCODE),  \
   "i" (__FILE__),  \
+  "i" (__BUG_FUNC),\
   "i" (__LINE__), "i" (0), \
   "i" (sizeof(struct bug_entry))); \
unreachable();  \
@@ -60,6 +76,7 @@ do {  \
 :  \
 : "n" (TRAPA_BUG_OPCODE),  \
   "i" (__FILE__),  \
+  "i" (__BUG_FUNC),\
   "i" (__LINE__),  \
   "i" (BUGFLAG_WARNING|(flags)),   \
   "i" (sizeof(struct bug_entry))); \
@@ -85,6 +102,7 @@ do { \
 :  \
 : "n" (TRAPA_BUG_OPCODE),  \
   "i" (__FILE__),  \
+  "i" (__BUG_FUNC),\
   "i" (__LINE__),  \
   "i" (BUGFLAG_UNWINDER),  \
   "i" (sizeof(struct bug_entry))); \
-- 
2.34.1



[PATCH v8 2/6] drm/sched: Add scheduler unit testing infrastructure and some basic tests

2025-03-13 Thread Tvrtko Ursulin
Implement a mock scheduler backend and add some basic test to exercise the
core scheduler code paths.

Mock backend (kind of like a very simple mock GPU) can either process jobs
by tests manually advancing the "timeline" job at a time, or alternatively
jobs can be configured with a time duration in which case they get
completed asynchronously from the unit test code.

Core scheduler classes are subclassed to support this mock implementation.

The tests added are just a few simple submission patterns.

Signed-off-by: Tvrtko Ursulin 
Suggested-by: Philipp Stanner 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
Acked-by: Christian König 
---
 drivers/gpu/drm/Kconfig.debug |  12 +
 drivers/gpu/drm/scheduler/.kunitconfig|  12 +
 drivers/gpu/drm/scheduler/Makefile|   2 +
 drivers/gpu/drm/scheduler/tests/Makefile  |   7 +
 .../gpu/drm/scheduler/tests/mock_scheduler.c  | 330 ++
 drivers/gpu/drm/scheduler/tests/sched_tests.h | 222 
 drivers/gpu/drm/scheduler/tests/tests_basic.c | 198 +++
 7 files changed, 783 insertions(+)
 create mode 100644 drivers/gpu/drm/scheduler/.kunitconfig
 create mode 100644 drivers/gpu/drm/scheduler/tests/Makefile
 create mode 100644 drivers/gpu/drm/scheduler/tests/mock_scheduler.c
 create mode 100644 drivers/gpu/drm/scheduler/tests/sched_tests.h
 create mode 100644 drivers/gpu/drm/scheduler/tests/tests_basic.c

diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/Kconfig.debug
index 601d7e07d421..6fd4c5669400 100644
--- a/drivers/gpu/drm/Kconfig.debug
+++ b/drivers/gpu/drm/Kconfig.debug
@@ -99,5 +99,17 @@ config DRM_TTM_KUNIT_TEST
 
  If in doubt, say "N".
 
+config DRM_SCHED_KUNIT_TEST
+   tristate "KUnit tests for the DRM scheduler" if !KUNIT_ALL_TESTS
+   select DRM_SCHED
+   depends on DRM && KUNIT
+   default KUNIT_ALL_TESTS
+   help
+ Choose this option to build unit tests for the DRM scheduler.
+
+ Recommended for driver developers only.
+
+ If in doubt, say "N".
+
 config DRM_EXPORT_FOR_TESTS
bool
diff --git a/drivers/gpu/drm/scheduler/.kunitconfig 
b/drivers/gpu/drm/scheduler/.kunitconfig
new file mode 100644
index ..cece53609fcf
--- /dev/null
+++ b/drivers/gpu/drm/scheduler/.kunitconfig
@@ -0,0 +1,12 @@
+CONFIG_KUNIT=y
+CONFIG_DRM=y
+CONFIG_DRM_SCHED_KUNIT_TEST=y
+CONFIG_EXPERT=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_LOCKDEP=y
+CONFIG_DEBUG_LOCKDEP=y
+CONFIG_DEBUG_LIST=y
diff --git a/drivers/gpu/drm/scheduler/Makefile 
b/drivers/gpu/drm/scheduler/Makefile
index 53863621829f..6e13e4c63e9d 100644
--- a/drivers/gpu/drm/scheduler/Makefile
+++ b/drivers/gpu/drm/scheduler/Makefile
@@ -23,3 +23,5 @@
 gpu-sched-y := sched_main.o sched_fence.o sched_entity.o
 
 obj-$(CONFIG_DRM_SCHED) += gpu-sched.o
+
+obj-$(CONFIG_DRM_SCHED_KUNIT_TEST) += tests/
diff --git a/drivers/gpu/drm/scheduler/tests/Makefile 
b/drivers/gpu/drm/scheduler/tests/Makefile
new file mode 100644
index ..5bf707bad373
--- /dev/null
+++ b/drivers/gpu/drm/scheduler/tests/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+drm-sched-tests-y := \
+mock_scheduler.o \
+tests_basic.o
+
+obj-$(CONFIG_DRM_SCHED_KUNIT_TEST) += drm-sched-tests.o
diff --git a/drivers/gpu/drm/scheduler/tests/mock_scheduler.c 
b/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
new file mode 100644
index ..b7d4890a1651
--- /dev/null
+++ b/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2025 Valve Corporation */
+
+#include "sched_tests.h"
+
+/*
+ * Here we implement the mock "GPU" (or the scheduler backend) which is used by
+ * the DRM scheduler unit tests in order to exercise the core functionality.
+ *
+ * Test cases are implemented in a separate file.
+ */
+
+/**
+ * drm_mock_sched_entity_new - Create a new mock scheduler entity
+ *
+ * @test: KUnit test owning the entity
+ * @priority: Scheduling priority
+ * @sched: Mock scheduler on which the entity can be scheduled
+ *
+ * Returns: New mock scheduler entity with allocation managed by the test
+ */
+struct drm_mock_sched_entity *
+drm_mock_sched_entity_new(struct kunit *test,
+ enum drm_sched_priority priority,
+ struct drm_mock_scheduler *sched)
+{
+   struct drm_mock_sched_entity *entity;
+   struct drm_gpu_scheduler *drm_sched;
+   int ret;
+
+   entity = kunit_kzalloc(test, sizeof(*entity), GFP_KERNEL);
+   KUNIT_ASSERT_NOT_NULL(test, entity);
+
+   drm_sched = &sched->base;
+   ret = drm_sched_entity_init(&entity->base,
+   priority,
+   &drm_sched, 1,
+   NULL);
+   KUNIT_ASSERT_EQ(test, ret, 0);
+
+   

[PATCH v8 4/6] drm/sched: Add basic priority tests

2025-03-13 Thread Tvrtko Ursulin
Add some basic tests for exercising entity priority handling.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
Acked-by: Christian König 
---
 drivers/gpu/drm/scheduler/tests/tests_basic.c | 95 ++-
 1 file changed, 94 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/scheduler/tests/tests_basic.c 
b/drivers/gpu/drm/scheduler/tests/tests_basic.c
index 0e1fa4767b0d..10378b7ca457 100644
--- a/drivers/gpu/drm/scheduler/tests/tests_basic.c
+++ b/drivers/gpu/drm/scheduler/tests/tests_basic.c
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright (c) 2025 Valve Corporation */
 
+#include 
+
 #include "sched_tests.h"
 
 /*
@@ -254,5 +256,96 @@ static struct kunit_suite drm_sched_timeout = {
.test_cases = drm_sched_timeout_tests,
 };
 
+static void drm_sched_priorities(struct kunit *test)
+{
+   struct drm_mock_sched_entity *entity[DRM_SCHED_PRIORITY_COUNT];
+   struct drm_mock_scheduler *sched = test->priv;
+   struct drm_mock_sched_job *job;
+   const unsigned int qd = 100;
+   unsigned int i, cur_ent = 0;
+   enum drm_sched_priority p;
+   bool done;
+
+   /*
+* Submit a bunch of jobs against entities configured with different
+* priorities.
+*/
+
+   BUILD_BUG_ON(DRM_SCHED_PRIORITY_KERNEL > DRM_SCHED_PRIORITY_LOW);
+   BUILD_BUG_ON(ARRAY_SIZE(entity) != DRM_SCHED_PRIORITY_COUNT);
+
+   for (p = DRM_SCHED_PRIORITY_KERNEL; p <= DRM_SCHED_PRIORITY_LOW; p++)
+   entity[p] = drm_mock_sched_entity_new(test, p, sched);
+
+   for (i = 0; i < qd; i++) {
+   job = drm_mock_sched_job_new(test, entity[cur_ent++]);
+   cur_ent %= ARRAY_SIZE(entity);
+   drm_mock_sched_job_set_duration_us(job, 1000);
+   drm_mock_sched_job_submit(job);
+   }
+
+   done = drm_mock_sched_job_wait_finished(job, HZ);
+   KUNIT_ASSERT_TRUE(test, done);
+
+   for (i = 0; i < ARRAY_SIZE(entity); i++)
+   drm_mock_sched_entity_free(entity[i]);
+}
+
+static void drm_sched_change_priority(struct kunit *test)
+{
+   struct drm_mock_sched_entity *entity[DRM_SCHED_PRIORITY_COUNT];
+   struct drm_mock_scheduler *sched = test->priv;
+   struct drm_mock_sched_job *job;
+   const unsigned int qd = 1000;
+   unsigned int i, cur_ent = 0;
+   enum drm_sched_priority p;
+
+   /*
+* Submit a bunch of jobs against entities configured with different
+* priorities and while waiting for them to complete, periodically keep
+* changing their priorities.
+*
+* We set up the queue-depth (qd) and job duration so the priority
+* changing loop has some time to interact with submissions to the
+* backend and job completions as they progress.
+*/
+
+   for (p = DRM_SCHED_PRIORITY_KERNEL; p <= DRM_SCHED_PRIORITY_LOW; p++)
+   entity[p] = drm_mock_sched_entity_new(test, p, sched);
+
+   for (i = 0; i < qd; i++) {
+   job = drm_mock_sched_job_new(test, entity[cur_ent++]);
+   cur_ent %= ARRAY_SIZE(entity);
+   drm_mock_sched_job_set_duration_us(job, 1000);
+   drm_mock_sched_job_submit(job);
+   }
+
+   do {
+   drm_sched_entity_set_priority(&entity[cur_ent]->base,
+ (entity[cur_ent]->base.priority + 
1) %
+ DRM_SCHED_PRIORITY_COUNT);
+   cur_ent++;
+   cur_ent %= ARRAY_SIZE(entity);
+   usleep_range(200, 500);
+   } while (!drm_mock_sched_job_is_finished(job));
+
+   for (i = 0; i < ARRAY_SIZE(entity); i++)
+   drm_mock_sched_entity_free(entity[i]);
+}
+
+static struct kunit_case drm_sched_priority_tests[] = {
+   KUNIT_CASE(drm_sched_priorities),
+   KUNIT_CASE(drm_sched_change_priority),
+   {}
+};
+
+static struct kunit_suite drm_sched_priority = {
+   .name = "drm_sched_basic_priority_tests",
+   .init = drm_sched_basic_init,
+   .exit = drm_sched_basic_exit,
+   .test_cases = drm_sched_priority_tests,
+};
+
 kunit_test_suites(&drm_sched_basic,
- &drm_sched_timeout);
+ &drm_sched_timeout,
+ &drm_sched_priority);
-- 
2.48.0



Re: [PATCH] drm/amdgpu/gfx12: correct cleanup of 'me' field with gfx_v12_0_me_fini()

2025-03-13 Thread Alex Deucher
Applied.  Thanks!

Alex

On Wed, Mar 12, 2025 at 6:09 AM Wentao Liang  wrote:
>
> In gfx_v12_0_cp_gfx_load_me_microcode_rs64(), gfx_v12_0_pfp_fini() is
> incorrectly used to free 'me' field of 'gfx', since gfx_v12_0_pfp_fini()
> can only release 'pfp' field of 'gfx'. The release function of 'me' field
> should be gfx_v12_0_me_fini().
>
> Fixes: 52cb80c12e8a ("drm/amdgpu: Add gfx v12_0 ip block support (v6)")
> Cc: sta...@vger.kernel.org # 6.11+
> Signed-off-by: Wentao Liang 
> ---
>  drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
> index da327ab48a57..02bc2eddf0c0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
> @@ -2413,7 +2413,7 @@ static int 
> gfx_v12_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev)
>   (void **)&adev->gfx.me.me_fw_data_ptr);
> if (r) {
> dev_err(adev->dev, "(%d) failed to create me data bo\n", r);
> -   gfx_v12_0_pfp_fini(adev);
> +   gfx_v12_0_me_fini(adev);
> return r;
> }
>
> --
> 2.42.0.windows.2
>


Re: [RFC PATCH 00/19] drm, drm/xe: Multi-device GPUSVM

2025-03-13 Thread Thomas Hellström
On Thu, 2025-03-13 at 13:57 +0100, Christian König wrote:
> Am 13.03.25 um 13:50 schrieb Thomas Hellström:
> > Hi, Christian
> > 
> > On Thu, 2025-03-13 at 11:19 +0100, Christian König wrote:
> > > Am 12.03.25 um 22:03 schrieb Thomas Hellström:
> > > > This RFC implements and requests comments for a way to handle
> > > > SVM
> > > > with multi-device,
> > > > typically with fast interconnects. It adds generic code and
> > > > helpers
> > > > in drm, and
> > > > device-specific code for xe.
> > > > 
> > > > For SVM, devices set up maps of device-private struct pages,
> > > > using
> > > > a struct dev_pagemap,
> > > > The CPU virtual address space (mm), can then be set up using
> > > > special page-table entries
> > > > to point to such pages, but they can't be accessed directly by
> > > > the
> > > > CPU, but possibly
> > > > by other devices using a fast interconnect. This series aims to
> > > > provide helpers to
> > > > identify pagemaps that take part in such a fast interconnect
> > > > and to
> > > > aid in migrating
> > > > between them.
> > > > 
> > > > This is initially done by augmenting the struct dev_pagemap
> > > > with a
> > > > struct drm_pagemap,
> > > > and having the struct drm_pagemap implement a "populate_mm"
> > > > method,
> > > > where a region of
> > > > the CPU virtual address space (mm) is populated with
> > > > device_private
> > > > pages from the
> > > > dev_pagemap associated with the drm_pagemap, migrating data
> > > > from
> > > > system memory or other
> > > > devices if necessary. The drm_pagemap_populate_mm() function is
> > > > then typically called
> > > > from a fault handler, using the struct drm_pagemap pointer of
> > > > choice. It could be
> > > > referencing a local drm_pagemap or a remote one. The migration
> > > > is
> > > > now completely done
> > > > by drm_pagemap callbacks, (typically using a copy-engine local
> > > > to
> > > > the dev_pagemap local
> > > > memory).
> > > Up till here that makes sense. Maybe not necessary to be put into
> > > the
> > > DRM layer, but that is an implementation detail.
> > > 
> > > > In addition there are helpers to build a drm_pagemap UAPI using
> > > > file-descripors
> > > > representing struct drm_pagemaps, and a helper to register
> > > > devices
> > > > with a common
> > > > fast interconnect. The UAPI is intended to be private to the
> > > > device, but if drivers
> > > > agree to identify struct drm_pagemaps by file descriptors one
> > > > could
> > > > in theory
> > > > do cross-driver multi-device SVM if a use-case were found.
> > > But this completely eludes me.
> > > 
> > > Why would you want an UAPI for representing pagemaps as file
> > > descriptors? Isn't it the kernel which enumerates the
> > > interconnects
> > > of the devices?
> > > 
> > > I mean we somehow need to expose those interconnects between
> > > devices
> > > to userspace, e.g. like amdgpu does with it's XGMI connectors.
> > > But
> > > that is static for the hardware (unless HW is hot removed/added)
> > > and
> > > so I would assume exposed through sysfs.
> > Thanks for the feedback.
> > 
> > The idea here is not to expose the interconnects but rather have a
> > way
> > for user-space to identify a drm_pagemap and some level of access-
> > and
> > lifetime control.
> 
> Well that's what I get I just don't get why?
> 
> I mean when you want to have the pagemap as optional feature you can
> turn on and off I would say make that a sysfs file.
> 
> It's a global feature anyway and not bound in any way to the file
> descriptor, isn't it?

As it is currently coded in Xe, the drm_pagemap is revoked when the the
struct files backing the fds are released. (After a delay that is, to
avoid repeatedly destroying and re-creating the pagemap).

Will take the sysfs switch back to the team and discuss what's the
preferred option.

> 
> > For Xe, If an application wants to use a particular drm_pagemap it
> > calls an ioctl:
> > 
> > pagemap_fd = drm_xe_ioctl_pagemap_open(exporting_device_fd,
> > memory_region);
> 
> Well should userspace deal with physical addresses here, or what
> exactly is memory_region here?

On some hardware we have multiple VRAM banks per device, one per
"tile". The memory_region selects which one to use.

/Thomas


> 
> Regards,
> Christian.
> 
> > 
> > And then when it's no longer used
> > close(pagemap_fd)
> > 
> > To use it for a memory range, the intended idea is call gpu madvise
> > ioctl:
> >  
> > err = drm_xe_ioctl_gpu_madvise(local_device_fd, range, pagemap_fd);
> > 
> > Now, if there is no fast interconnect between the two, the madvise
> > call
> > could just return an error. All this ofc assumes that user-space is
> > somehow aware of the fast interconnect topology but how that is
> > exposed
> > is beyond the scope of this first series. (Suggestions welcome).
> > 
> > The advantage of the above approach is
> > 1) We get some level of access control. If the user doesn't have
> > access
> > to the exporting device, he/she can't ob

[PATCH RFC 0/3] Initial work for Rust abstraction for HID device driver development

2025-03-13 Thread Rahul Rameshbabu
Hello,

I am a hobbyist developer who has been working on a project to create a new Rust
HID device driver and the needed core abstractions for writing more HID device
drivers in Rust. My goal is to support the USB Monitor Control Class needed for
functionality such as backlight control for monitors like the Apple Studio
Display and Apple Pro Display XDR. A new backlight API will be required to
support multiple backlight instances and will be mapped per DRM connector. The
current backlight API is designed around the assumption of only a single
internal panel being present. I am currently working on making this new API for
DRM in parallel to my work on the HID side of the stack for supporting these
displays.

  https://binary-eater.github.io/tags/usb-monitor-control/

Julius Zint had attempted to do so a year ago with a C HID driver but was gated
by the lack of an appropriate backlight API for external displays. I asked him
for permission to do the work need in Rust and plan to accredit him for the HID
report handling for backlight in the USB Monitor Control Class standard.

  https://lore.kernel.org/lkml/f95da7ff-06dd-2c0e-d563-7e5ad61c3...@redhat.com/

I was hoping to get initial feedback on this work to make sure I am on the right
path for making a Rust HID abstraction that would be acceptable upstream. The
patches compile with WERROR being disabled. This is necessary since Rust treats
missing documentation comments as warnings (which is a good thing). I also need
to go in and add more SAFETY comments.

Thanks,
Rahul Rameshbabu

Rahul Rameshbabu (3):
  rust: core abstractions for HID drivers
  rust: hid: USB Monitor Control Class driver
  rust: hid: demo the core abstractions for probe and remove

 drivers/hid/Kconfig|  16 ++
 drivers/hid/Makefile   |   1 +
 drivers/hid/hid_monitor_control.rs |  42 +
 rust/bindings/bindings_helper.h|   1 +
 rust/kernel/hid.rs | 245 +
 rust/kernel/lib.rs |   2 +
 6 files changed, 307 insertions(+)
 create mode 100644 drivers/hid/hid_monitor_control.rs
 create mode 100644 rust/kernel/hid.rs

-- 
2.47.2




[PATCH RFC 3/3] rust: hid: demo the core abstractions for probe and remove

2025-03-13 Thread Rahul Rameshbabu
This is a very basic "hello, world!" implementation to illustrate that the
probe and remove callbacks are working as expected. I chose an arbitrary
device I had on hand for populating in the HID device id table.

  [  +0.012968] monitor_control: Probing HID device vendor: 2389 product: 29204 
using Rust!
  [  +0.000108] monitor_control: Removing HID device vendor: 2389 product: 
29204 using Rust!

Signed-off-by: Rahul Rameshbabu 
---
 drivers/hid/hid_monitor_control.rs | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid_monitor_control.rs 
b/drivers/hid/hid_monitor_control.rs
index 18afd69a56d5..aeb6e4058a6b 100644
--- a/drivers/hid/hid_monitor_control.rs
+++ b/drivers/hid/hid_monitor_control.rs
@@ -8,17 +8,22 @@
 Driver,
 };
 
+const USB_VENDOR_ID_NVIDIA: u32 = 0x0955;
+const USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER: u32 = 0x7214;
+
 struct HidMonitorControl;
 
 #[vtable]
 impl Driver for HidMonitorControl {
 fn probe(dev: &mut hid::Device, id: &hid::DeviceId) -> Result<()> {
 /* TODO implement */
+pr_info!("Probing HID device vendor: {} product: {} using Rust!\n", 
id.vendor(), id.product());
 Ok(())
 }
 
 fn remove(dev: &mut hid::Device) {
 /* TODO implement */
+pr_info!("Removing HID device vendor: {} product: {} using Rust!\n", 
dev.vendor(), dev.product());
 }
 }
 
@@ -26,8 +31,8 @@ fn remove(dev: &mut hid::Device) {
 driver: HidMonitorControl,
 id_table: [
 kernel::usb_device! {
-vendor: /* TODO fill in */,
-product: /* TODO fill in */,
+vendor: USB_VENDOR_ID_NVIDIA,
+product: USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER,
 },
 ],
 name: "monitor_control",
-- 
2.47.2




[PATCH v8 1/6] drm: Move some options to separate new Kconfig

2025-03-13 Thread Tvrtko Ursulin
Move some options out into a new debug specific kconfig file in order to
make things a bit cleaner.

Signed-off-by: Tvrtko Ursulin 
Cc: Christian König 
Cc: Danilo Krummrich 
Cc: Matthew Brost 
Cc: Philipp Stanner 
Acked-by: Christian König 
---
 drivers/gpu/drm/Kconfig   | 109 ++
 drivers/gpu/drm/Kconfig.debug | 103 
 2 files changed, 108 insertions(+), 104 deletions(-)
 create mode 100644 drivers/gpu/drm/Kconfig.debug

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1be14d8634f4..d32d70c3ddf1 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -26,6 +26,11 @@ menuconfig DRM
  details.  You should also select and configure AGP
  (/dev/agpgart) support if it is available for your platform.
 
+menu "DRM debugging options"
+depends on DRM
+source "drivers/gpu/drm/Kconfig.debug"
+endmenu
+
 if DRM
 
 config DRM_MIPI_DBI
@@ -37,65 +42,6 @@ config DRM_MIPI_DSI
bool
depends on DRM
 
-config DRM_DEBUG_MM
-   bool "Insert extra checks and debug info into the DRM range managers"
-   default n
-   depends on DRM
-   depends on STACKTRACE_SUPPORT
-   select STACKDEPOT
-   help
- Enable allocation tracking of memory manager and leak detection on
- shutdown.
-
- Recommended for driver developers only.
-
- If in doubt, say "N".
-
-config DRM_USE_DYNAMIC_DEBUG
-   bool "use dynamic debug to implement drm.debug"
-   default n
-   depends on BROKEN
-   depends on DRM
-   depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
-   depends on JUMP_LABEL
-   help
- Use dynamic-debug to avoid drm_debug_enabled() runtime overheads.
- Due to callsite counts in DRM drivers (~4k in amdgpu) and 56
- bytes per callsite, the .data costs can be substantial, and
- are therefore configurable.
-
-config DRM_KUNIT_TEST_HELPERS
-   tristate
-   depends on DRM && KUNIT
-   select DRM_KMS_HELPER
-   help
- KUnit Helpers for KMS drivers.
-
-config DRM_KUNIT_TEST
-   tristate "KUnit tests for DRM" if !KUNIT_ALL_TESTS
-   depends on DRM && KUNIT && MMU
-   select DRM_BUDDY
-   select DRM_DISPLAY_DP_HELPER
-   select DRM_DISPLAY_HDMI_STATE_HELPER
-   select DRM_DISPLAY_HELPER
-   select DRM_EXEC
-   select DRM_EXPORT_FOR_TESTS if m
-   select DRM_GEM_SHMEM_HELPER
-   select DRM_KUNIT_TEST_HELPERS
-   select DRM_LIB_RANDOM
-   select PRIME_NUMBERS
-   default KUNIT_ALL_TESTS
-   help
- This builds unit tests for DRM. This option is not useful for
- distributions or general kernels, but only for kernel
- developers working on DRM and associated drivers.
-
- For more information on KUnit and unit tests in general,
- please refer to the KUnit documentation in
- Documentation/dev-tools/kunit/.
-
- If in doubt, say "N".
-
 config DRM_KMS_HELPER
tristate
depends on DRM
@@ -247,23 +193,6 @@ config DRM_TTM
  GPU memory types. Will be enabled automatically if a device driver
  uses it.
 
-config DRM_TTM_KUNIT_TEST
-tristate "KUnit tests for TTM" if !KUNIT_ALL_TESTS
-default n
-depends on DRM && KUNIT && MMU && (UML || COMPILE_TEST)
-select DRM_TTM
-select DRM_BUDDY
-select DRM_EXPORT_FOR_TESTS if m
-select DRM_KUNIT_TEST_HELPERS
-default KUNIT_ALL_TESTS
-help
-  Enables unit tests for TTM, a GPU memory manager subsystem used
-  to manage memory buffers. This option is mostly useful for kernel
-  developers. It depends on (UML || COMPILE_TEST) since no other driver
-  which uses TTM can be loaded while running the tests.
-
-  If in doubt, say "N".
-
 config DRM_EXEC
tristate
depends on DRM
@@ -474,9 +403,6 @@ config DRM_HYPERV
 
 If M is selected the module will be called hyperv_drm.
 
-config DRM_EXPORT_FOR_TESTS
-   bool
-
 # Separate option as not all DRM drivers use it
 config DRM_PANEL_BACKLIGHT_QUIRKS
tristate
@@ -489,31 +415,6 @@ config DRM_PRIVACY_SCREEN
bool
default n
 
-config DRM_WERROR
-   bool "Compile the drm subsystem with warnings as errors"
-   depends on DRM && EXPERT
-   depends on !WERROR
-   default n
-   help
- A kernel build should not cause any compiler warnings, and this
- enables the '-Werror' flag to enforce that rule in the drm subsystem.
-
- The drm subsystem enables more warnings than the kernel default, so
- this config option is disabled by default.
-
- If in doubt, say N.
-
-config DRM_HEADER_TEST
-   bool "Ensure DRM headers are self-contained and pass kernel-doc"
-   depends on DRM && EXPERT
-   default n
-   help
- Ensure the DRM subsystem headers both under drivers/gpu/d

Re: [PATCH v2 2/7] drm/bridge: synopsys: Add DW DPTX Controller support library

2025-03-13 Thread Piotr Oniszczuk



> Wiadomość napisana przez Andy Yan  w dniu 13 mar 2025, o 
> godz. 01:23:
> 
> 
> Hi Piotr,
> 在 2025-03-12 22:23:15,"Piotr Oniszczuk"  写道:
> 
> This series still  based on Linux 6.14 rc4.
> 
> Did you apply the three dependency patch mentioned in my cover letter?

Thx!
I noticed 
https://lore.kernel.org/linux-rockchip/20250302115257.188774-1-andys...@163.com/
 was missing
Sorry for false alarm.
Now v2 works ok for me on rock5a and rock5itx
 

Re: [PATCH 1/2] lib/vsprintf: Add support for generic FourCCs by extending %p4cc

2025-03-13 Thread Andy Shevchenko
On Thu, Mar 13, 2025 at 11:06:54AM +, Aditya Garg wrote:
> > On 13 Mar 2025, at 4:18 PM, Petr Mladek  wrote:
> > On Thu 2025-03-13 09:13:23, Aditya Garg wrote:
> >>> On 13 Mar 2025, at 2:27 PM, Andy Shevchenko 
> >>>  wrote:
> >>> On Thu, Mar 13, 2025 at 08:53:28AM +, Aditya Garg wrote:
> >> On 13 Mar 2025, at 2:19 PM, Andy Shevchenko 
> >>  wrote:
> > On Thu, Mar 13, 2025 at 07:26:05AM +, Aditya Garg wrote:
>  On 13 Mar 2025, at 12:58 AM, Andy Shevchenko 
>   wrote:
> >>> On Wed, Mar 12, 2025 at 07:14:36PM +, Aditya Garg wrote:
> > On 12 Mar 2025, at 9:05 PM, Sven Peter  wrote:
> > On Wed, Mar 12, 2025, at 13:03, Aditya Garg wrote:

...

> > I don't have a strong opinion either way: for SMC I just need to 
> > print
> > FourCC keys for debugging / information in a few places.
> > 
> > I'm preparing the SMC driver for upstreaming again (after a two 
> > year delay :-()
> > and was just going to use macros to print the SMC FourCC keys 
> > similar to
> > DRM_MODE_FMT/DRM_MODE_ARG for now to keep the series smaller and 
> > revisit
> > the topic later.
> > 
> > Right now I have these in my local tree (only compile tested so 
> > far):
> > 
> > #define SMC_KEY_FMT "%c%c%c%c (0x%08x)"
> > #define SMC_KEY_ARG(k) (k)>>24, (k)>>16, (k)>>8, (k), (k)
>  
>  That seems to be a nice alternative, which I guess Thomas was also 
>  suggesting.
> >>> 
> >>> I don't think it's "nice". Each of the approaches has pros and cons.
> >>> You can start from bloat-o-meter here and compare it with your %p 
> >>> extension.
> >>> 
> >>> Also, can you show the bloat-o-meter output for the vsprintf.c?
> >> 
> >> Here are your outputs:
> > 
> > Thank you!
> > 
> >> -
> >> For appletbdrm:
> >> 
> >> aditya@MacBook:~/linux$ ./scripts/bloat-o-meter $P4 $MACRO
> >> add/remove: 0/0 grow/shrink: 1/1 up/down: 64/-19 (45)
> >> Function old new   delta
> >> appletbdrm_read_response 395 459 +64
> >> appletbdrm_probe17861767 -19
> >> Total: Before=13418, After=13463, chg +0.34%
> > 
> > This is enough, no need to repeat this for every parameter.
> > 
> >> -
> >> For vsprintf:
> >> 
> >> aditya@MacBook:~/linux$ ./scripts/bloat-o-meter $OLD $NEW
> >> add/remove: 0/0 grow/shrink: 1/0 up/down: 220/0 (220)
> >> Function old new   delta
> >> fourcc_string479 699+220
> >> Total: Before=26454, After=26674, chg +0.83%
> > 
> > So, we get +220 bytes vs +43 bytes. It means if we found 5+ users, it 
> > worth
> > doing.
>  
>  Will it also depend upon the number of times it's being used? In 
>  appletbdrm,
>  it is being used 3 times. Probably more in Asahi SMC.
> >>> 
> >>> Right, it depends on the usage count. Also on different architectures it 
> >>> may
> >>> give different results. On 32-bit it probably gives better statistics.
> >> 
> >> Best to go ahead with vsprintf then. Petr, are you still there?
> > 
> > I am here but there were many other things in the queue ;-)
> > 
> > I do not have strong opinion. I am not familiar with the FourCC
> > format and it looks like a magic to me. But it seems that it makes
> > sense for the users.
> > 
> > I personally find the %pcX modifiers a bit less hacky than
> > the two macros SMC_KEY_FMT/SMC_KEY_ARG.
> > 
> > So I am fine with this patch:
> > 
> > Reviewed-by: Petr Mladek 
> > Tested-by: Petr Mladek 
> > 
> > 
> > Now, the question is how to get this patch into the mainline.
> > 
> > Normally, it would make perfect sense to queue it via the DRM tree
> > because drivers/gpu/drm/tiny/appletbdrm.c is a new driver...
> > 
> > But this time there is a conflicting patchset which is reworking
> > the entire lib/test_printf.c file, see
> > 20250307-printf-kunit-convert-v6-0-4d85c361c...@gmail.com
> 
> Link seems to be broken

It works fine. Because it's not a link, it's Message-ID, you need to add
https://lore.kernel.org/r/ in front of it.

> > And it will likely be ready for the next merge window as well.
> > I am going to review it right away.
> > 
> > It is even more complicated because the patchset converting
> > the printf test module to KUNIT depends on another changes
> > in Kees' tree (moving kunit test modules to lib/tests/).
> > So it might be easier when it goes via Kees' tree.
> > 
> > And it might be easier when even this patch goes via Kees' tree.
> > 
> > My proposal:
> > 
> > I suggest to separate the fourcc_point

[PATCH v4 6/7] drm/v3d: Use V3D_SMS registers for power on/off and reset on V3D 7.x

2025-03-13 Thread Maíra Canal
In addition to the standard reset controller, V3D 7.x requires configuring
the V3D_SMS registers for proper power on/off and reset. Add the new
registers to `v3d_regs.h` and ensure they are properly configured during
device probing, removal, and reset.

This change fixes GPU reset issues on the Raspberry Pi 5 (BCM2712).
Without exposing these registers, a GPU reset causes the GPU to hang,
stopping any further job execution and freezing the desktop GUI. The same
issue occurs when unloading and loading the v3d driver.

Link: https://github.com/raspberrypi/linux/issues/6660
Reviewed-by: Iago Toral Quiroga 
Signed-off-by: Maíra Canal 
---
 drivers/gpu/drm/v3d/v3d_drv.c  | 40 
 drivers/gpu/drm/v3d/v3d_drv.h  | 11 +++
 drivers/gpu/drm/v3d/v3d_gem.c  | 17 +
 drivers/gpu/drm/v3d/v3d_regs.h | 26 ++
 4 files changed, 94 insertions(+)

diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c
index 
c63f0ed1bd8a3d5511085e76ed2fbd6ee7df6f80..122848cdccc4a02039d9ea2e77aa2f377886b5d6
 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.c
+++ b/drivers/gpu/drm/v3d/v3d_drv.c
@@ -263,6 +263,36 @@ static const struct of_device_id v3d_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, v3d_of_match);
 
+static void
+v3d_idle_sms(struct v3d_dev *v3d)
+{
+   if (v3d->ver < V3D_GEN_71)
+   return;
+
+   V3D_SMS_WRITE(V3D_SMS_TEE_CS, V3D_SMS_CLEAR_POWER_OFF);
+
+   if (wait_for((V3D_GET_FIELD(V3D_SMS_READ(V3D_SMS_TEE_CS),
+   V3D_SMS_STATE) == V3D_SMS_IDLE), 100)) {
+   DRM_ERROR("Failed to power up SMS\n");
+   }
+
+   v3d_reset_sms(v3d);
+}
+
+static void
+v3d_power_off_sms(struct v3d_dev *v3d)
+{
+   if (v3d->ver < V3D_GEN_71)
+   return;
+
+   V3D_SMS_WRITE(V3D_SMS_TEE_CS, V3D_SMS_POWER_OFF);
+
+   if (wait_for((V3D_GET_FIELD(V3D_SMS_READ(V3D_SMS_TEE_CS),
+   V3D_SMS_STATE) == V3D_SMS_POWER_OFF_STATE), 
100)) {
+   DRM_ERROR("Failed to power off SMS\n");
+   }
+}
+
 static int
 map_regs(struct v3d_dev *v3d, void __iomem **regs, const char *name)
 {
@@ -300,6 +330,12 @@ static int v3d_platform_drm_probe(struct platform_device 
*pdev)
if (ret)
return ret;
 
+   if (v3d->ver >= V3D_GEN_71) {
+   ret = map_regs(v3d, &v3d->sms_regs, "sms");
+   if (ret)
+   return ret;
+   }
+
v3d->clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(v3d->clk))
return dev_err_probe(dev, PTR_ERR(v3d->clk), "Failed to get V3D 
clock\n");
@@ -310,6 +346,8 @@ static int v3d_platform_drm_probe(struct platform_device 
*pdev)
return ret;
}
 
+   v3d_idle_sms(v3d);
+
mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
mask = DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH));
ret = dma_set_mask_and_coherent(dev, mask);
@@ -410,6 +448,8 @@ static void v3d_platform_drm_remove(struct platform_device 
*pdev)
dma_free_wc(v3d->drm.dev, 4096, v3d->mmu_scratch,
v3d->mmu_scratch_paddr);
 
+   v3d_power_off_sms(v3d);
+
clk_disable_unprepare(v3d->clk);
 }
 
diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h
index 
de4a9e18f6a9039edf57f406ab1cee9dad4c0a49..b51f0b648a08011f737317ec1841d5ab316355b2
 100644
--- a/drivers/gpu/drm/v3d/v3d_drv.h
+++ b/drivers/gpu/drm/v3d/v3d_drv.h
@@ -118,6 +118,7 @@ struct v3d_dev {
void __iomem *core_regs[3];
void __iomem *bridge_regs;
void __iomem *gca_regs;
+   void __iomem *sms_regs;
struct clk *clk;
struct reset_control *reset;
 
@@ -268,6 +269,15 @@ to_v3d_fence(struct dma_fence *fence)
 #define V3D_GCA_READ(offset) readl(v3d->gca_regs + offset)
 #define V3D_GCA_WRITE(offset, val) writel(val, v3d->gca_regs + offset)
 
+#define V3D_SMS_IDLE   0x0
+#define V3D_SMS_ISOLATING_FOR_RESET0xa
+#define V3D_SMS_RESETTING  0xb
+#define V3D_SMS_ISOLATING_FOR_POWER_OFF0xc
+#define V3D_SMS_POWER_OFF_STATE0xd
+
+#define V3D_SMS_READ(offset) readl(v3d->sms_regs + (offset))
+#define V3D_SMS_WRITE(offset, val) writel(val, v3d->sms_regs + (offset))
+
 #define V3D_CORE_READ(core, offset) readl(v3d->core_regs[core] + offset)
 #define V3D_CORE_WRITE(core, offset, val) writel(val, v3d->core_regs[core] + 
offset)
 
@@ -546,6 +556,7 @@ struct dma_fence *v3d_fence_create(struct v3d_dev *v3d, 
enum v3d_queue queue);
 /* v3d_gem.c */
 int v3d_gem_init(struct drm_device *dev);
 void v3d_gem_destroy(struct drm_device *dev);
+void v3d_reset_sms(struct v3d_dev *v3d);
 void v3d_reset(struct v3d_dev *v3d);
 void v3d_invalidate_caches(struct v3d_dev *v3d);
 void v3d_clean_caches(struct v3d_dev *v3d);
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
index 
1ea6d3832c2212d

[PATCH v4 3/7] drm/v3d: Associate a V3D tech revision to all supported devices

2025-03-13 Thread Maíra Canal
The V3D driver currently determines the GPU tech version (33, 41...)
by reading a register. This approach has worked so far since this
information wasn’t needed before powering on the GPU.

V3D 7.1 introduces new registers that must be written to power on the
GPU, requiring us to know the V3D version beforehand. To address this,
associate each supported SoC with the corresponding VideoCore GPU version
as part of the device data.

To prevent possible mistakes, add an assertion to verify that the version
specified in the device data matches the one reported by the hardware.
If there is a mismatch, the kernel will trigger a warning.

Reviewed-by: Iago Toral Quiroga 
Signed-off-by: Maíra Canal 
---
 drivers/gpu/drm/v3d/v3d_debugfs.c | 126 +++---
 drivers/gpu/drm/v3d/v3d_drv.c |  22 +--
 drivers/gpu/drm/v3d/v3d_drv.h |  11 +++-
 drivers/gpu/drm/v3d/v3d_gem.c |  10 +--
 drivers/gpu/drm/v3d/v3d_irq.c |   6 +-
 drivers/gpu/drm/v3d/v3d_perfmon.c |   4 +-
 drivers/gpu/drm/v3d/v3d_sched.c   |   6 +-
 7 files changed, 101 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_debugfs.c 
b/drivers/gpu/drm/v3d/v3d_debugfs.c
index 
76816f2551c10026a775e4331ad7eb2f008cfb0a..7e789e181af0ac138044f194a29555c30ab01836
 100644
--- a/drivers/gpu/drm/v3d/v3d_debugfs.c
+++ b/drivers/gpu/drm/v3d/v3d_debugfs.c
@@ -21,74 +21,74 @@ struct v3d_reg_def {
 };
 
 static const struct v3d_reg_def v3d_hub_reg_defs[] = {
-   REGDEF(33, 42, V3D_HUB_AXICFG),
-   REGDEF(33, 71, V3D_HUB_UIFCFG),
-   REGDEF(33, 71, V3D_HUB_IDENT0),
-   REGDEF(33, 71, V3D_HUB_IDENT1),
-   REGDEF(33, 71, V3D_HUB_IDENT2),
-   REGDEF(33, 71, V3D_HUB_IDENT3),
-   REGDEF(33, 71, V3D_HUB_INT_STS),
-   REGDEF(33, 71, V3D_HUB_INT_MSK_STS),
-
-   REGDEF(33, 71, V3D_MMU_CTL),
-   REGDEF(33, 71, V3D_MMU_VIO_ADDR),
-   REGDEF(33, 71, V3D_MMU_VIO_ID),
-   REGDEF(33, 71, V3D_MMU_DEBUG_INFO),
-
-   REGDEF(71, 71, V3D_GMP_STATUS(71)),
-   REGDEF(71, 71, V3D_GMP_CFG(71)),
-   REGDEF(71, 71, V3D_GMP_VIO_ADDR(71)),
+   REGDEF(V3D_GEN_33, V3D_GEN_42, V3D_HUB_AXICFG),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_UIFCFG),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT0),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT1),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT2),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_IDENT3),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_INT_STS),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_HUB_INT_MSK_STS),
+
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_CTL),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_VIO_ADDR),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_VIO_ID),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_MMU_DEBUG_INFO),
+
+   REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_GMP_STATUS(71)),
+   REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_GMP_CFG(71)),
+   REGDEF(V3D_GEN_71, V3D_GEN_71, V3D_GMP_VIO_ADDR(71)),
 };
 
 static const struct v3d_reg_def v3d_gca_reg_defs[] = {
-   REGDEF(33, 33, V3D_GCA_SAFE_SHUTDOWN),
-   REGDEF(33, 33, V3D_GCA_SAFE_SHUTDOWN_ACK),
+   REGDEF(V3D_GEN_33, V3D_GEN_33, V3D_GCA_SAFE_SHUTDOWN),
+   REGDEF(V3D_GEN_33, V3D_GEN_33, V3D_GCA_SAFE_SHUTDOWN_ACK),
 };
 
 static const struct v3d_reg_def v3d_core_reg_defs[] = {
-   REGDEF(33, 71, V3D_CTL_IDENT0),
-   REGDEF(33, 71, V3D_CTL_IDENT1),
-   REGDEF(33, 71, V3D_CTL_IDENT2),
-   REGDEF(33, 71, V3D_CTL_MISCCFG),
-   REGDEF(33, 71, V3D_CTL_INT_STS),
-   REGDEF(33, 71, V3D_CTL_INT_MSK_STS),
-   REGDEF(33, 71, V3D_CLE_CT0CS),
-   REGDEF(33, 71, V3D_CLE_CT0CA),
-   REGDEF(33, 71, V3D_CLE_CT0EA),
-   REGDEF(33, 71, V3D_CLE_CT1CS),
-   REGDEF(33, 71, V3D_CLE_CT1CA),
-   REGDEF(33, 71, V3D_CLE_CT1EA),
-
-   REGDEF(33, 71, V3D_PTB_BPCA),
-   REGDEF(33, 71, V3D_PTB_BPCS),
-
-   REGDEF(33, 42, V3D_GMP_STATUS(33)),
-   REGDEF(33, 42, V3D_GMP_CFG(33)),
-   REGDEF(33, 42, V3D_GMP_VIO_ADDR(33)),
-
-   REGDEF(33, 71, V3D_ERR_FDBGO),
-   REGDEF(33, 71, V3D_ERR_FDBGB),
-   REGDEF(33, 71, V3D_ERR_FDBGS),
-   REGDEF(33, 71, V3D_ERR_STAT),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_IDENT0),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_IDENT1),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_IDENT2),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_MISCCFG),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_INT_STS),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CTL_INT_MSK_STS),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT0CS),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT0CA),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT0EA),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT1CS),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT1CA),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_CLE_CT1EA),
+
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_PTB_BPCA),
+   REGDEF(V3D_GEN_33, V3D_GEN_71, V3D_PTB_BPCS),
+
+   REGDEF(V3D_GEN_33, V3D_GEN_42, V3D_GMP_ST

[PATCH v4 1/7] drm/v3d: Don't run jobs that have errors flagged in its fence

2025-03-13 Thread Maíra Canal
The V3D driver still relies on `drm_sched_increase_karma()` and
`drm_sched_resubmit_jobs()` for resubmissions when a timeout occurs.
The function `drm_sched_increase_karma()` marks the job as guilty, while
`drm_sched_resubmit_jobs()` sets an error (-ECANCELED) in the DMA fence of
that guilty job.

Because of this, we must check whether the job’s DMA fence has been
flagged with an error before executing the job. Otherwise, the same guilty
job may be resubmitted indefinitely, causing repeated GPU resets.

This patch adds a check for an error on the job's fence to prevent running
a guilty job that was previously flagged when the GPU timed out.

Note that the CPU and CACHE_CLEAN queues do not require this check, as
their jobs are executed synchronously once the DRM scheduler starts them.

Cc: sta...@vger.kernel.org
Fixes: d223f98f0209 ("drm/v3d: Add support for compute shader dispatch.")
Fixes: 1584f16ca96e ("drm/v3d: Add support for submitting jobs to the TFU.")
Reviewed-by: Iago Toral Quiroga 
Signed-off-by: Maíra Canal 
---
 drivers/gpu/drm/v3d/v3d_sched.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
index 
80466ce8c7df669280e556c0793490b79e75d2c7..c2010ecdb08f4ba3b54f7783ed33901552d0eba1
 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -327,11 +327,15 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job)
struct drm_device *dev = &v3d->drm;
struct dma_fence *fence;
 
+   if (unlikely(job->base.base.s_fence->finished.error))
+   return NULL;
+
+   v3d->tfu_job = job;
+
fence = v3d_fence_create(v3d, V3D_TFU);
if (IS_ERR(fence))
return NULL;
 
-   v3d->tfu_job = job;
if (job->base.irq_fence)
dma_fence_put(job->base.irq_fence);
job->base.irq_fence = dma_fence_get(fence);
@@ -369,6 +373,9 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)
struct dma_fence *fence;
int i, csd_cfg0_reg;
 
+   if (unlikely(job->base.base.s_fence->finished.error))
+   return NULL;
+
v3d->csd_job = job;
 
v3d_invalidate_caches(v3d);

-- 
Git-154)



[PATCH v4 4/7] dt-bindings: gpu: v3d: Add per-compatible register restrictions

2025-03-13 Thread Maíra Canal
In order to enforce per-SoC register rules, add per-compatible
restrictions. V3D 3.3 (represented by brcm,7268-v3d) has a cache
controller (GCA), which is not present in other V3D generations.
Declaring these differences helps ensure the DTB accurately reflect
the hardware design.

While not ideal, this commit keeps the register order flexible for
brcm,7268-v3d with the goal to keep the ABI backwards compatible.

Signed-off-by: Maíra Canal 
---
 .../devicetree/bindings/gpu/brcm,bcm-v3d.yaml  | 73 ++
 1 file changed, 61 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml 
b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
index 
dc078ceeca9ac3447ba54a7c8830821f0b2a7f9f..9867b617c60c6fe34a0f88a3ee2f581a94b69a5c
 100644
--- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
+++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
@@ -22,20 +22,10 @@ properties:
   - brcm,7278-v3d
 
   reg:
-items:
-  - description: hub register (required)
-  - description: core0 register (required)
-  - description: GCA cache controller register (if GCA controller present)
-  - description: bridge register (if no external reset controller)
-minItems: 2
+maxItems: 4
 
   reg-names:
-items:
-  - const: hub
-  - const: core0
-  - enum: [ bridge, gca ]
-  - enum: [ bridge, gca ]
-minItems: 2
+maxItems: 4
 
   interrupts:
 items:
@@ -58,6 +48,65 @@ required:
   - reg-names
   - interrupts
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - brcm,2711-v3d
+  - brcm,7278-v3d
+then:
+  properties:
+reg:
+  items:
+- description: hub register
+- description: core0 register
+- description: bridge register (if no external reset controller)
+  minItems: 2
+reg-names:
+  items:
+- const: hub
+- const: core0
+- const: bridge
+  minItems: 2
+  - if:
+  properties:
+compatible:
+  contains:
+const: brcm,2712-v3d
+then:
+  properties:
+reg:
+  items:
+- description: hub register
+- description: core0 register
+reg-names:
+  items:
+- const: hub
+- const: core0
+  - if:
+  properties:
+compatible:
+  contains:
+const: brcm,7268-v3d
+then:
+  properties:
+reg:
+  items:
+- description: hub register
+- description: core0 register
+- description: GCA cache controller register
+- description: bridge register (if no external reset controller)
+  minItems: 3
+reg-names:
+  items:
+- const: hub
+- const: core0
+- enum: [ bridge, gca ]
+- enum: [ bridge, gca ]
+  minItems: 3
+
 additionalProperties: false
 
 examples:

-- 
Git-154)



[PATCH v4 2/7] drm/v3d: Set job pointer to NULL when the job's fence has an error

2025-03-13 Thread Maíra Canal
Similar to commit e4b5ccd392b9 ("drm/v3d: Ensure job pointer is set to
NULL after job completion"), ensure the job pointer is set to `NULL` when
a job's fence has an error. Failing to do so can trigger kernel warnings
in specific scenarios, such as:

1. v3d_csd_job_run() assigns `v3d->csd_job = job`
2. CSD job exceeds hang limit, causing a timeout → v3d_gpu_reset_for_timeout()
3. GPU reset
4. drm_sched_resubmit_jobs() sets the job's fence to `-ECANCELED`.
5. v3d_csd_job_run() detects the fence error and returns NULL, not
   submitting the job to the GPU
6. User-space runs `modprobe -r v3d`
7. v3d_gem_destroy()

v3d_gem_destroy() triggers a warning indicating that the CSD job never
ended, as we didn't set `v3d->csd_job` to NULL after the timeout. The same
can also happen to BIN, RENDER, and TFU jobs.

Reviewed-by: Iago Toral Quiroga 
Signed-off-by: Maíra Canal 
---
 drivers/gpu/drm/v3d/v3d_sched.c | 18 ++
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
index 
c2010ecdb08f4ba3b54f7783ed33901552d0eba1..34c42d6e12cde656d3b51a18be324976199eceae
 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -226,8 +226,12 @@ static struct dma_fence *v3d_bin_job_run(struct 
drm_sched_job *sched_job)
struct dma_fence *fence;
unsigned long irqflags;
 
-   if (unlikely(job->base.base.s_fence->finished.error))
+   if (unlikely(job->base.base.s_fence->finished.error)) {
+   spin_lock_irqsave(&v3d->job_lock, irqflags);
+   v3d->bin_job = NULL;
+   spin_unlock_irqrestore(&v3d->job_lock, irqflags);
return NULL;
+   }
 
/* Lock required around bin_job update vs
 * v3d_overflow_mem_work().
@@ -281,8 +285,10 @@ static struct dma_fence *v3d_render_job_run(struct 
drm_sched_job *sched_job)
struct drm_device *dev = &v3d->drm;
struct dma_fence *fence;
 
-   if (unlikely(job->base.base.s_fence->finished.error))
+   if (unlikely(job->base.base.s_fence->finished.error)) {
+   v3d->render_job = NULL;
return NULL;
+   }
 
v3d->render_job = job;
 
@@ -327,8 +333,10 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job)
struct drm_device *dev = &v3d->drm;
struct dma_fence *fence;
 
-   if (unlikely(job->base.base.s_fence->finished.error))
+   if (unlikely(job->base.base.s_fence->finished.error)) {
+   v3d->tfu_job = NULL;
return NULL;
+   }
 
v3d->tfu_job = job;
 
@@ -373,8 +381,10 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)
struct dma_fence *fence;
int i, csd_cfg0_reg;
 
-   if (unlikely(job->base.base.s_fence->finished.error))
+   if (unlikely(job->base.base.s_fence->finished.error)) {
+   v3d->csd_job = NULL;
return NULL;
+   }
 
v3d->csd_job = job;
 

-- 
Git-154)



Re: [PATCH RFC 1/2] drm/panel: Add new helpers for refcounted panel allocatons

2025-03-13 Thread Maxime Ripard
Hi Anusha,

In addition to the feedback Luca already provided, I have a few comments

On Wed, Mar 12, 2025 at 08:54:42PM -0400, Anusha Srivatsa wrote:
> Introduce reference counted allocations for panels to avoid
> use-after-free. The patch adds the macro devm_drm_bridge_alloc()
> to allocate a new refcounted panel. Followed the documentation for
> drmm_encoder_alloc() and devm_drm_dev_alloc and other similar
> implementations for this purpose.
> 
> Also adding drm_panel_get() and drm_panel_put() to suitably
> increment and decrement the refcount
> 
> Signed-off-by: Anusha Srivatsa 
> ---
>  drivers/gpu/drm/drm_panel.c | 50 ++
>  include/drm/drm_panel.h | 58 
> +
>  2 files changed, 108 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
> index 
> c627e42a7ce70459f50eb5095fffc806ca45dabf..b55e380e4a2f7ffd940c207e841c197d85113907
>  100644
> --- a/drivers/gpu/drm/drm_panel.c
> +++ b/drivers/gpu/drm/drm_panel.c
> @@ -79,6 +79,7 @@ EXPORT_SYMBOL(drm_panel_init);
>   */
>  void drm_panel_add(struct drm_panel *panel)
>  {
> + drm_panel_get(panel);
>   mutex_lock(&panel_lock);
>   list_add_tail(&panel->list, &panel_list);
>   mutex_unlock(&panel_lock);
> @@ -96,6 +97,7 @@ void drm_panel_remove(struct drm_panel *panel)
>   mutex_lock(&panel_lock);
>   list_del_init(&panel->list);
>   mutex_unlock(&panel_lock);
> + drm_panel_put(panel);
>  }
>  EXPORT_SYMBOL(drm_panel_remove);

I think these two should be added as a separate patch, with some
additional comment on why it's needed (because we store a pointer in the
panel list).

>  
> @@ -355,6 +357,54 @@ struct drm_panel *of_drm_find_panel(const struct 
> device_node *np)
>  }
>  EXPORT_SYMBOL(of_drm_find_panel);
>  
> +/* Internal function (for refcounted panels) */
> +void __drm_panel_free(struct kref *kref)
> +{
> + struct drm_panel *panel = container_of(kref, struct drm_panel, 
> refcount);
> + void *container = ((void *)panel) - panel->container_offset;
> +
> + kfree(container);
> +}
> +EXPORT_SYMBOL(__drm_panel_free);
> +
> +static void drm_panel_put_void(void *data)
> +{
> + struct drm_panel *panel = (struct drm_panel *)data;
> +
> + drm_panel_put(panel);
> +}
> +
> +void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
> +  const struct drm_panel_funcs *funcs)
> +{
> + void *container;
> + struct drm_panel *panel;
> + int err;
> +
> + if (!funcs) {
> + dev_warn(dev, "Missing funcs pointer\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + container = kzalloc(size, GFP_KERNEL);
> + if (!container)
> + return ERR_PTR(-ENOMEM);
> +
> + panel = container + offset;
> + panel->container_offset = offset;
> + panel->funcs = funcs;
> + kref_init(&panel->refcount);
> +
> + err = devm_add_action_or_reset(dev, drm_panel_put_void, panel);
> + if (err)
> + return ERR_PTR(err);
> +
> + drm_panel_init(panel, dev, funcs, panel->connector_type);
> +
> + return container;
> +}
> +EXPORT_SYMBOL(__devm_drm_panel_alloc);

Similarly, here, I think we'd need to split that some more. Ideally, we
should have a series of patches doing

1: Adding that allocation function you have right now, but using
   devm_kzalloc

2: Adding the reference counting to drm_panel, with drm_panel_get /
   drm_panel_put and the devm_action to put the reference in
   __devm_drm_panel_alloc()

3: Adding X patches to add calls to drm_bridge_get/drm_bridge_put
   everywhere it's needed, starting indeed by
   drm_panel_add/drm_panel_put. We don't have to do all of them in that
   series though. of_drm_find_panel though will probably merit a series
   of its own, given we'd have to fix all its callers too.

4: Convert some panels to the new allocation function. You already did
   that with panel_simple so there's nothing to change yet, but once we
   agree on the API we should mass convert all the panels.

Maxime


signature.asc
Description: PGP signature


[PATCH] drm/mxsfb: fix missing rollback on failure in mxsfb_probe()

2025-03-13 Thread Luca Ceresoli
When aperture_remove_all_conflicting_devices() fails, the current code
returns without going through the rollback actions at the end of the
function, thus the actions done by drm_dev_alloc() and mxsfb_load() are not
undone.

Fix by using a goto statament, as done for the previous and following error
conditions.

Fixes: c8e7b185d45b ("drm/mxsfb: Remove generic DRM drivers in probe function")
Signed-off-by: Luca Ceresoli 
---
The offending commit is not yet merged into master, and even less in a
released kernel, so this does not need to go through stable.
---
 drivers/gpu/drm/mxsfb/mxsfb_drv.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c 
b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 
c183b1112bc4e9fe4f3b048a2b6e4c98d1d47cb3..b4273e678d26dbc3dee2014266d61470da4e8010
 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -365,9 +365,10 @@ static int mxsfb_probe(struct platform_device *pdev)
 * located anywhere in RAM
 */
ret = aperture_remove_all_conflicting_devices(mxsfb_driver.name);
-   if (ret)
-   return dev_err_probe(&pdev->dev, ret,
-"can't kick out existing framebuffers\n");
+   if (ret) {
+   dev_err_probe(&pdev->dev, ret, "can't kick out existing 
framebuffers\n");
+   goto err_unload;
+   }
 
ret = drm_dev_register(drm, 0);
if (ret)

---
base-commit: f9f087d946266bc5da7c3a17bd8fd9d01969e3cf
change-id: 20250313-mxsfb_probe-fix-rollback-on-error-3074b9080f34

Best regards,
-- 
Luca Ceresoli 



Re: [PATCH RFC 1/2] drm/panel: Add new helpers for refcounted panel allocatons

2025-03-13 Thread Maxime Ripard
On Thu, Mar 13, 2025 at 11:09:44AM +0100, Luca Ceresoli wrote:
> Hello Anusha,
> 
> On Wed, 12 Mar 2025 20:54:42 -0400
> Anusha Srivatsa  wrote:
> 
> > Introduce reference counted allocations for panels to avoid
> > use-after-free. The patch adds the macro devm_drm_bridge_alloc()
> > to allocate a new refcounted panel. Followed the documentation for
> > drmm_encoder_alloc() and devm_drm_dev_alloc and other similar
> > implementations for this purpose.
> > 
> > Also adding drm_panel_get() and drm_panel_put() to suitably
> > increment and decrement the refcount
> > 
> > Signed-off-by: Anusha Srivatsa 
> 
> I'm very happy to see the very first step of the panel rework mentioned
> by Maxime see the light! :-)
> 
> This patch looks mostly good to me, and the similarity with my bridge
> refcounting work is by itself reassuring.
> 
> I have a few notes, one is relevant and the others are minor details,
> see below.
> 
> In the Subject line: s/allocatons/allocations/
> 
> [...]
> 
> > +void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t 
> > offset,
> > +const struct drm_panel_funcs *funcs)
> > +{
> > +   void *container;
> > +   struct drm_panel *panel;
> > +   int err;
> > +
> > +   if (!funcs) {
> > +   dev_warn(dev, "Missing funcs pointer\n");
> > +   return ERR_PTR(-EINVAL);
> > +   }
> > +
> > +   container = kzalloc(size, GFP_KERNEL);
> > +   if (!container)
> > +   return ERR_PTR(-ENOMEM);
> > +
> > +   panel = container + offset;
> > +   panel->container_offset = offset;
> > +   panel->funcs = funcs;
> > +   kref_init(&panel->refcount);
> > +
> > +   err = devm_add_action_or_reset(dev, drm_panel_put_void, panel);
> > +   if (err)
> > +   return ERR_PTR(err);
> > +
> > +   drm_panel_init(panel, dev, funcs, panel->connector_type);
> 
> panel->connector_type here is uninitialized. You are passing
> panel->connector_type to drm_panel_init(), which will then copy it into
> panel->connector_type itself.

Yeah, we need to have the connector type as a parameter.

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v16 5/7] drm/vkms: Create KUnit tests for YUV conversions

2025-03-13 Thread Maxime Ripard
Hi,

On Mon, Mar 10, 2025 at 11:12:59AM +0200, Pekka Paalanen wrote:
> On Fri, 7 Mar 2025 15:50:41 +0100
> Louis Chauvet  wrote:
> 
> > Le 07/03/2025 à 11:20, Maxime Ripard a écrit :
> > > On Wed, Feb 19, 2025 at 02:35:14PM +0100, Louis Chauvet wrote:  
> > >>
> > >>
> > >> Le 19/02/2025 à 11:15, Maxime Ripard a écrit :  
> > >>> On Wed, Feb 05, 2025 at 04:32:07PM +0100, Louis Chauvet wrote:  
> >  On 05/02/25 - 09:55, Maxime Ripard wrote:  
> > > On Mon, Jan 27, 2025 at 11:48:23AM +0100, Louis Chauvet wrote:  
> > >> On 26/01/25 - 18:06, Maxime Ripard wrote:  
> > >>> On Tue, Jan 21, 2025 at 11:48:06AM +0100, Louis Chauvet wrote:  
> >  +static struct yuv_u8_to_argb_u16_case yuv_u8_to_argb_u16_cases[] 
> >  = {
> >  +  /*
> >  +   * colour.RGB_to_YCbCr(,
> >  +   * K=colour.WEIGHTS_YCBCR["ITU-R BT.601"],
> >  +   * in_bits = 16,
> >  +   * in_legal = False,
> >  +   * in_int = True,
> >  +   * out_bits = 8,
> >  +   * out_legal = False,
> >  +   * out_int = True)
> >  +   *
> >  +   * Test cases for conversion between YUV BT601 full range and 
> >  RGB
> >  +   * using the ITU-R BT.601 weights.
> >  +   */  
> > >>>
> > >>> What are the input and output formats?
> > >>>
> > >>> Ditto for all the other tests.  
> > >>
> > >> There is no really "input" and "output" format, they are reference 
> > >> values
> > >> for conversion, you should be able to use it in both direction. They 
> > >> are
> > >> generated by RGB_to_YCbCr (RGB input, YUV output) just because it was
> > >> easier to create the colors from RGB values.  
> > >
> > > RGB and YUV aren't formats, they are color models. XRGB is a 
> > > format.
> > > NV12 is a format.
> > >  
> > >> If you think we should specify what is was used as input and output 
> > >> to
> > >> generate those values, I can modify the comment to:
> > >>
> > >>  Tests cases for color conversion generated by converting RGB
> > >>  values to YUV BT601 full range using the ITU-R BT.601 weights.  
> > >
> > > My point is that those comments should provide a way to reimplement 
> > > the
> > > test from scratch, and compare to the actual implementation. It's 
> > > useful
> > > when you have a test failure and start to wonder if the implementation
> > > or the test is at fault.
> > >
> > > By saying only RGB and YUV, you can't possibly do that.  
> > 
> >  I understand your concern, but I believe there might be a slight
> >  misunderstanding. The table in question stores reference values for
> >  specific color models, not formats. Therefore, it doesn't specify any
> >  particular format like XRGB or NV12.
> > 
> >  To clarify this, I can rename the format_pair struct to value_pair. 
> >  This
> >  should make it clearer that we are dealing with color model values 
> >  rather
> >  than formats.
> > 
> >  If you want to test a specific format conversion, such as
> >  YUV420_to_argbu16, you would need to follow a process like this:
> > 
> > // Recreate a YUV420 data
> > plane_1[0] = test_case.yuv.y
> > plane_2[0] = test_case.yuv.u
> > plane_2[1] = test_case.yuv.v
> > 
> > // convertion to test from YUV420 format to argb_u16
> > rgb_u16 = convert_YUV420_to_argbu16(plane_1, plane_2)
> > 
> > // ensure the conversion is valid
> > assert_eq(rgb_u16, test_case.rgb)
> > 
> >  The current test is not performing this kind of format conversion.
> >  Instead, it verifies that for given (y, u, v) values, the correct (r, 
> >  g,
> >  b, a) values are obtained.  
> > >>>
> > >>> You already stated that you check for the A, R, G, and B components. On
> > >>> how many bits are the values you are comparing stored? The YUV values
> > >>> you are comparing are stored on how many bits for each channel? With
> > >>> subsampling?
> > >>>
> > >>> If you want to compare values, you need to encode a given color into
> > >>> bits, and the way that encoding is done is what the format is about.
> > >>>
> > >>> You might not compare the memory layout but each component individually,
> > >>> but it's still a format.  
> > >>
> > >> Sorry, I think I misunderstood what a format really is.  
> > > 
> > > Ultimately, a format is how a given "color value" is stored. How many
> > > bits will you use? If you have an unaligned number of bits, how many
> > > bits of padding you'll use, where the padding is? If there's multiple
> > > bytes, what's the endianness?
> > > 
> > > The answer to all these questions is "the for

Re: [PATCH v2 0/2] Use proper printk format in appletbdrm

2025-03-13 Thread Alyssa Rosenzweig
series looks ok to me. Who is pushing this to drm-misc-next? (I can if
nobody else does)


Re: [RFC PATCH 0/3] gpu: nova-core: add basic timer subdevice implementation

2025-03-13 Thread Simona Vetter
On Fri, Mar 07, 2025 at 10:55:57AM -0400, Jason Gunthorpe wrote:
> On Fri, Mar 07, 2025 at 02:09:12PM +0100, Simona Vetter wrote:
> 
> > > A driver can do a health check immediately in remove() and make a
> > > decision if the device is alive or not to speed up removal in the
> > > hostile hot unplug case.
> > 
> > Hm ... I guess when you get an all -1 read you check with a specific
> > register to make sure it's not a false positive? Since for some registers
> > that's a valid value.
> 
> Yes. mlx5 has HW designed to support this, but I imagine on most
> devices you could find an ID register or something that won't be -1.
> 
> > - The "at least we don't blow up with memory safety issues" bare minimum
> >   that the rust abstractions should guarantee. So revocable and friends.
> 
> I still really dislike recovable because it imposes a cost that is
> unnecessary.
> 
> > And I think the latter safety fallback does not prevent you from doing the
> > full fancy design, e.g. for revocable resources that only happens after
> > your explicitly-coded ->remove() callback has finished. Which means you
> > still have full access to the hw like anywhere else.
> 
> Yes, if you use rust bindings with something like RDMA then I would
> expect that by the time remove is done everything is cleaned up and
> all the revokable stuff was useless and never used.
> 
> This is why I dislike revoke so much. It is adding a bunch of garbage
> all over the place that is *never used* if the driver is working
> correctly.
> 
> I believe it is much better to runtime check that the driver is
> correct and not burden the API design with this.

You can do that with for example runtime proofs. R4l has that with
Mutex from one structure protecting other structures (like in a tree). But
since the compiler can't prove those you trade in the possibility that you
will hit a runtime BUG if things don't line up.

So subsystems that ensure that driver callbacks never run concurrently
with a revocation could guarantee that revocable resources are always
present.

> Giving people these features will only encourage them to write wrong
> drivers.

So I think you can still achieve that building on top of revocable and a
few more abstractions that are internally unsafe. Or are you thinking of
different runtime checks?

> This is not even a new idea, devm introduces automatic lifetime into
> the kernel and I've sat in presentations about how devm has all sorts
> of bug classes because of misuse. :\

Yeah automatic lifetime is great, until people mix up things with
different lifetimes, then it all goes wrong.

> > Does this sounds like a possible conclusion of this thread, or do we need
> > to keep digging?
> 
> IDK, I think this should be socialized more. It is important as it
> effects all drivers here out, and it is radically different to how the
> kernel works today.
> 
> > Also now that I look at this problem as a two-level issue, I think drm is
> > actually a lot better than what I explained. If you clean up driver state
> > properly in ->remove (or as stack automatic cleanup functions that run
> > before all the mmio/irq/whatever stuff disappears), then we are largely
> > there already with being able to fully quiescent driver state enough to
> > make sure no new requests can sneak in. 
> 
> That is the typical subsystem design!

Yeah maybe we're not that far really. But I'm still not clear how to do
an entirely revoke-less world.
-Sima
-- 
Simona Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


Re: [PATCH] drm/mxsfb: fix missing rollback on failure in mxsfb_probe()

2025-03-13 Thread Thomas Zimmermann

Hi

Am 13.03.25 um 15:25 schrieb Luca Ceresoli:

When aperture_remove_all_conflicting_devices() fails, the current code
returns without going through the rollback actions at the end of the
function, thus the actions done by drm_dev_alloc() and mxsfb_load() are not
undone.

Fix by using a goto statament, as done for the previous and following error
conditions.

Fixes: c8e7b185d45b ("drm/mxsfb: Remove generic DRM drivers in probe function")
Signed-off-by: Luca Ceresoli 
---
The offending commit is not yet merged into master, and even less in a
released kernel, so this does not need to go through stable.
---
  drivers/gpu/drm/mxsfb/mxsfb_drv.c | 7 ---
  1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c 
b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 
c183b1112bc4e9fe4f3b048a2b6e4c98d1d47cb3..b4273e678d26dbc3dee2014266d61470da4e8010
 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -365,9 +365,10 @@ static int mxsfb_probe(struct platform_device *pdev)
 * located anywhere in RAM
 */
ret = aperture_remove_all_conflicting_devices(mxsfb_driver.name);
-   if (ret)
-   return dev_err_probe(&pdev->dev, ret,
-"can't kick out existing framebuffers\n");
+   if (ret) {
+   dev_err_probe(&pdev->dev, ret, "can't kick out existing 
framebuffers\n");
+   goto err_unload;
+   }


I must have missed that when I reviewed the patch. But this call should 
happen much earlier. right at the top of the probe function before 
drm_dev_alloc(). Conflicting drivers need to be kicked out before 
setting up DRM. Could you please send a patch to move the call to the 
top? No extra cleanup would be required then.


Best regards
Thomas

  
  	ret = drm_dev_register(drm, 0);

if (ret)

---
base-commit: f9f087d946266bc5da7c3a17bd8fd9d01969e3cf
change-id: 20250313-mxsfb_probe-fix-rollback-on-error-3074b9080f34

Best regards,


--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



Re: [PATCH] drm/amd/display: avoid NPD when ASIC does not support DMUB

2025-03-13 Thread Thadeu Lima de Souza Cascardo
On Wed, Feb 05, 2025 at 10:06:38AM -0300, Thadeu Lima de Souza Cascardo wrote:
> ctx->dmub_srv will de NULL if the ASIC does not support DMUB, which is
> tested in dm_dmub_sw_init.
> 
> However, it will be dereferenced in dmub_hw_lock_mgr_cmd if
> should_use_dmub_lock returns true.
> 
> This has been the case since dmub support has been added for PSR1.

This bug has landed on stable trees. Any chance for a review here?

Thanks.
Cascardo.

> 
> Fix this by checking for dmub_srv in should_use_dmub_lock.
> 
> [   37.440832] BUG: kernel NULL pointer dereference, address: 0058
> [   37.447808] #PF: supervisor read access in kernel mode
> [   37.452959] #PF: error_code(0x) - not-present page
> [   37.458112] PGD 0 P4D 0
> [   37.460662] Oops: Oops:  [#1] PREEMPT SMP NOPTI
> [   37.465553] CPU: 2 UID: 1000 PID: 1745 Comm: DrmThread Not tainted 
> 6.14.0-rc1-3-gd62e938120f0 #23 99720e1cb1e0fc4773b8513150932a07de3c6e88
> [   37.478324] Hardware name: Google Morphius/Morphius, BIOS 
> Google_Morphius.13434.858.0 10/26/2023
> [   37.487103] RIP: 0010:dmub_hw_lock_mgr_cmd+0x77/0xb0
> [   37.492074] Code: 44 24 0e 00 00 00 00 48 c7 04 24 45 00 00 0c 40 88 74 24 
> 0d 0f b6 02 88 44 24 0c 8b 01 89 44 24 08 85 f6 75 05 c6 44 24 0e 01 <48> 8b 
> 7f 58 48 89 e6 ba 01 00 00 00 e8 08 3c 2a 00 65 48 8b 04 5
> [   37.510822] RSP: 0018:969442853300 EFLAGS: 00010202
> [   37.516052] RAX:  RBX: 92db0300 RCX: 
> 969442853358
> [   37.523185] RDX: 969442853368 RSI: 0001 RDI: 
> 
> [   37.530322] RBP: 0001 R08: 04a7 R09: 
> 04a5
> [   37.537453] R10: 0476 R11: 0062 R12: 
> 92db0ade8000
> [   37.544589] R13: 92da01180ae0 R14: 92da011802a8 R15: 
> 92db0300
> [   37.551725] FS:  784a9cdfc6c0() GS:92db2af0() 
> knlGS:
> [   37.559814] CS:  0010 DS:  ES:  CR0: 80050033
> [   37.565562] CR2: 0058 CR3: 000112b1c000 CR4: 
> 003506f0
> [   37.572697] Call Trace:
> [   37.575152]  
> [   37.577258]  ? __die_body+0x66/0xb0
> [   37.580756]  ? page_fault_oops+0x3e7/0x4a0
> [   37.584861]  ? exc_page_fault+0x3e/0xe0
> [   37.588706]  ? exc_page_fault+0x5c/0xe0
> [   37.592550]  ? asm_exc_page_fault+0x22/0x30
> [   37.596742]  ? dmub_hw_lock_mgr_cmd+0x77/0xb0
> [   37.601107]  dcn10_cursor_lock+0x1e1/0x240
> [   37.605211]  program_cursor_attributes+0x81/0x190
> [   37.609923]  commit_planes_for_stream+0x998/0x1ef0
> [   37.614722]  update_planes_and_stream_v2+0x41e/0x5c0
> [   37.619703]  dc_update_planes_and_stream+0x78/0x140
> [   37.624588]  amdgpu_dm_atomic_commit_tail+0x4362/0x49f0
> [   37.629832]  ? srso_return_thunk+0x5/0x5f
> [   37.633847]  ? mark_held_locks+0x6d/0xd0
> [   37.637774]  ? _raw_spin_unlock_irq+0x24/0x50
> [   37.642135]  ? srso_return_thunk+0x5/0x5f
> [   37.646148]  ? lockdep_hardirqs_on+0x95/0x150
> [   37.650510]  ? srso_return_thunk+0x5/0x5f
> [   37.654522]  ? _raw_spin_unlock_irq+0x2f/0x50
> [   37.658883]  ? srso_return_thunk+0x5/0x5f
> [   37.662897]  ? wait_for_common+0x186/0x1c0
> [   37.666998]  ? srso_return_thunk+0x5/0x5f
> [   37.671009]  ? drm_crtc_next_vblank_start+0xc3/0x170
> [   37.675983]  commit_tail+0xf5/0x1c0
> [   37.679478]  drm_atomic_helper_commit+0x2a2/0x2b0
> [   37.684186]  drm_atomic_commit+0xd6/0x100
> [   37.688199]  ? __cfi___drm_printfn_info+0x10/0x10
> [   37.692911]  drm_atomic_helper_update_plane+0xe5/0x130
> [   37.698054]  drm_mode_cursor_common+0x501/0x670
> [   37.702600]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
> [   37.707572]  drm_mode_cursor_ioctl+0x48/0x70
> [   37.711851]  drm_ioctl_kernel+0xf2/0x150
> [   37.715781]  drm_ioctl+0x363/0x590
> [   37.719189]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
> [   37.724165]  amdgpu_drm_ioctl+0x41/0x80
> [   37.728013]  __se_sys_ioctl+0x7f/0xd0
> [   37.731685]  do_syscall_64+0x87/0x100
> [   37.735355]  ? vma_end_read+0x12/0xe0
> [   37.739024]  ? srso_return_thunk+0x5/0x5f
> [   37.743041]  ? find_held_lock+0x47/0xf0
> [   37.746884]  ? vma_end_read+0x12/0xe0
> [   37.750552]  ? srso_return_thunk+0x5/0x5f
> [   37.754565]  ? lock_release+0x1c4/0x2e0
> [   37.758406]  ? vma_end_read+0x12/0xe0
> [   37.762079]  ? exc_page_fault+0x84/0xe0
> [   37.765921]  ? srso_return_thunk+0x5/0x5f
> [   37.769938]  ? lockdep_hardirqs_on+0x95/0x150
> [   37.774303]  ? srso_return_thunk+0x5/0x5f
> [   37.778317]  ? exc_page_fault+0x84/0xe0
> [   37.782163]  entry_SYSCALL_64_after_hwframe+0x55/0x5d
> [   37.787218] RIP: 0033:0x784aa5ec3059
> [   37.790803] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10 c7 45 b0 
> 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10 00 00 00 0f 05 <41> 89 
> c0 3d 00 f0 ff ff 77 1d 48 8b 45 c8 64 48 2b 04 25 28 00 0
> [   37.809553] RSP: 002b:784a9cdf90e0 EFLAGS: 0246 ORIG_RAX: 
> 0010
> [   37.817121] RAX: ffda RBX: 784a9cdf917c RCX: 

[PATCH v4 02/14] kunit: bug: Count suppressed warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Count suppressed warning backtraces to enable code which suppresses
warning backtraces to check if the expected backtrace(s) have been
observed.

Using atomics for the backtrace count resulted in build errors on some
architectures due to include file recursion, so use a plain integer
for now.

Acked-by: Dan Carpenter 
Reviewed-by: Kees Cook 
Tested-by: Linux Kernel Functional Testing 
Signed-off-by: Guenter Roeck 
Reviewed-by: David Gow 
Signed-off-by: Alessandro Carminati 
---
 include/kunit/bug.h | 7 ++-
 lib/kunit/bug.c | 4 +++-
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/kunit/bug.h b/include/kunit/bug.h
index 0a8e62c1fcaf..44efa7d5c902 100644
--- a/include/kunit/bug.h
+++ b/include/kunit/bug.h
@@ -20,6 +20,7 @@
 struct __suppressed_warning {
struct list_head node;
const char *function;
+   int counter;
 };
 
 void __kunit_start_suppress_warning(struct __suppressed_warning *warning);
@@ -28,7 +29,7 @@ bool __kunit_is_suppressed_warning(const char *function);
 
 #define DEFINE_SUPPRESSED_WARNING(func)\
struct __suppressed_warning __kunit_suppress_##func = \
-   { .function = __stringify(func) }
+   { .function = __stringify(func), .counter = 0 }
 
 #define KUNIT_START_SUPPRESSED_WARNING(func) \
__kunit_start_suppress_warning(&__kunit_suppress_##func)
@@ -39,12 +40,16 @@ bool __kunit_is_suppressed_warning(const char *function);
 #define KUNIT_IS_SUPPRESSED_WARNING(func) \
__kunit_is_suppressed_warning(func)
 
+#define SUPPRESSED_WARNING_COUNT(func) \
+   (__kunit_suppress_##func.counter)
+
 #else /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
 
 #define DEFINE_SUPPRESSED_WARNING(func)
 #define KUNIT_START_SUPPRESSED_WARNING(func)
 #define KUNIT_END_SUPPRESSED_WARNING(func)
 #define KUNIT_IS_SUPPRESSED_WARNING(func) (false)
+#define SUPPRESSED_WARNING_COUNT(func) (0)
 
 #endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
 #endif /* __ASSEMBLY__ */
diff --git a/lib/kunit/bug.c b/lib/kunit/bug.c
index 351f9a595a71..84c05b1a9e8b 100644
--- a/lib/kunit/bug.c
+++ b/lib/kunit/bug.c
@@ -32,8 +32,10 @@ bool __kunit_is_suppressed_warning(const char *function)
return false;
 
list_for_each_entry(warning, &suppressed_warnings, node) {
-   if (!strcmp(function, warning->function))
+   if (!strcmp(function, warning->function)) {
+   warning->counter++;
return true;
+   }
}
return false;
 }
-- 
2.34.1




Re: [PATCH v5 RESEND 1/2] dmaengine: qcom: gpi: Add GPI Block event interrupt support

2025-03-13 Thread Jyothi Kumar Seerapu

Hi Vinod, Thanks for the review comments.

On 3/11/2025 2:30 AM, Vinod Koul wrote:

On 12-02-25, 17:35, Jyothi Kumar Seerapu wrote:

GSI hardware generates an interrupt for each transfer completion.
For multiple messages within a single transfer, this results in
N interrupts for N messages, leading to significant software
interrupt latency.

To mitigate this latency, utilize Block Event Interrupt (BEI) mechanism.
Enabling BEI instructs the GSI hardware to prevent interrupt generation
and BEI is disabled when an interrupt is necessary.

When using BEI, consider splitting a single multi-message transfer into
chunks of 8 messages internally and so interrupts are not expected for
the first 7 message completions, only the last message triggers
an interrupt, indicating the completion of 8 messages.

This BEI mechanism enhances overall transfer efficiency.


That sounds good but I dont like the idea that we add a custom interface
for this. Please use DMA_PREP_INTERRUPT instead. Adding this flag should
trigger N interrupts, absence of this should lead to Block events only

The DMA_PREP_INTERRUPT flag in DMA operations is used to indicate that 
an interrupt should be generated once the DMA transfer is completed.
However, this flag itself does not block interrupt generation at the GPI 
DMA hardware level. The GPI DMA hardware can still raise interrupts even 
in the absence of the DMA_PREP_INTERRUPT flag.


To block interrupts at the GPI DMA hardware level, we need to use the 
Block Event Interrupt (BEI) bit (as explained in the commit log).
As an example : for 100 transfers, we only want to receive one interrupt 
at the 100th transfer. This helps us significantly reduce latencies, as 
handling back-to-back 100 interrupts can take a few milliseconds.


Hope this explains it well. Please let me know if there are any other 
concerns or feedback.




Re: [PATCH 1/2] fbcon: Register sysfs groups through device_add_group

2025-03-13 Thread Shixiong Ou



在 2025/3/13 00:47, Thomas Weißschuh 写道:

Hi,

On Tue, Mar 11, 2025 at 07:28:55PM +0800, oushixiong1...@163.com wrote:

From: Shixiong Ou 

Use device_add_group() to simplify creation and removal.

Signed-off-by: Shixiong Ou 
---
  drivers/video/fbdev/core/fbcon.c | 48 +++-
  1 file changed, 22 insertions(+), 26 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 07d127110ca4..51c3e8a5a092 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -3159,7 +3159,7 @@ static const struct consw fb_con = {
.con_debug_leave= fbcon_debug_leave,
  };
  
-static ssize_t store_rotate(struct device *device,

+static ssize_t rotate_store(struct device *device,
struct device_attribute *attr, const char *buf,
size_t count)
  {
@@ -3181,7 +3181,7 @@ static ssize_t store_rotate(struct device *device,
return count;
  }
  
-static ssize_t store_rotate_all(struct device *device,

+static ssize_t rotate_all_store(struct device *device,
struct device_attribute *attr,const char *buf,
size_t count)
  {
@@ -3203,7 +3203,7 @@ static ssize_t store_rotate_all(struct device *device,
return count;
  }
  
-static ssize_t show_rotate(struct device *device,

+static ssize_t rotate_show(struct device *device,
   struct device_attribute *attr,char *buf)
  {
struct fb_info *info;
@@ -3222,7 +3222,7 @@ static ssize_t show_rotate(struct device *device,
return sysfs_emit(buf, "%d\n", rotate);
  }
  
-static ssize_t show_cursor_blink(struct device *device,

+static ssize_t cursor_blink_show(struct device *device,
 struct device_attribute *attr, char *buf)
  {
struct fb_info *info;
@@ -3247,7 +3247,7 @@ static ssize_t show_cursor_blink(struct device *device,
return sysfs_emit(buf, "%d\n", blink);
  }
  
-static ssize_t store_cursor_blink(struct device *device,

+static ssize_t cursor_blink_store(struct device *device,
  struct device_attribute *attr,
  const char *buf, size_t count)
  {
@@ -3281,32 +3281,30 @@ static ssize_t store_cursor_blink(struct device *device,
return count;
  }
  
-static struct device_attribute device_attrs[] = {

-   __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
-   __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all),
-   __ATTR(cursor_blink, S_IRUGO|S_IWUSR, show_cursor_blink,
-  store_cursor_blink),
+static DEVICE_ATTR_RW(rotate);
+static DEVICE_ATTR_WO(rotate_all);
+static DEVICE_ATTR_RW(cursor_blink);
+
+static struct attribute *fbcon_device_attrs[] = {
+   &dev_attr_rotate.attr,
+   &dev_attr_rotate_all.attr,
+   &dev_attr_cursor_blink.attr,
+   NULL,

No trailing commas after sentinel values.


+};
+
+static const struct attribute_group fbcon_device_attr_group = {
+   .attrs  = fbcon_device_attrs,
  };
  
  static int fbcon_init_device(void)

  {
-   int i, error = 0;
+   int ret;
  
  	fbcon_has_sysfs = 1;
  
-	for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {

-   error = device_create_file(fbcon_device, &device_attrs[i]);
-
-   if (error)
-   break;
-   }
-
-   if (error) {
-   while (--i >= 0)
-   device_remove_file(fbcon_device, &device_attrs[i]);
-
+   ret = device_add_group(fbcon_device, &fbcon_device_attr_group);
+   if (ret)
fbcon_has_sysfs = 0;
-   }
  
  	return 0;

  }
@@ -3389,11 +3387,9 @@ void __init fb_console_init(void)
  
  static void __exit fbcon_deinit_device(void)

  {
-   int i;
  
  	if (fbcon_has_sysfs) {

-   for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
-   device_remove_file(fbcon_device, &device_attrs[i]);
+   device_remove_group(fb_info->dev, &fbcon_device_attr_group);

Please at least compile-test your changes before submission.

  
  		fbcon_has_sysfs = 0;

}

All of this can be simplified even more:

* fbcon_deinit_device() can be removed easily, as the attributes are
   automatically removed when the device is destroyed.
* Using device_create_with_groups() the device core will take complete care of
   the attribute lifecycle, also allowing to remove fbcon_init_device()


Thanks for your advice, I will fix and refactor this code in the next patch.

Thanks and Regards,
Shixiong Ou.



Thomas




Re: [PATCH v2 07/10] arm64: dts: qcom: sa8775p-ride: add anx7625 DSI to DP bridge nodes

2025-03-13 Thread Ayushi Makhija
On 3/12/2025 5:18 PM, Krzysztof Kozlowski wrote:
> On Tue, Mar 11, 2025 at 05:54:42PM +0530, Ayushi Makhija wrote:
>> Add anx7625 DSI to DP bridge device nodes.
>>
>> Signed-off-by: Ayushi Makhija 
>> ---
>>  arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi | 208 -
>>  1 file changed, 207 insertions(+), 1 deletion(-)
>>
> 
> So you just gave up after one comment? Context of every email should be
> trimmed, so if it is not trimmed means something is still there. I know
> there are reviewers who respond with huge unrelated context, but that's
> just disrespectful to our time and don't take it as normal.
> 
> 
> This is a friendly reminder during the review process.
> 
> It seems my or other reviewer's previous comments were not fully
> addressed. Maybe the feedback got lost between the quotes, maybe you
> just forgot to apply it. Please go back to the previous discussion and
> either implement all requested changes or keep discussing them.
> 
> Thank you.
> 
> 

Hi Krzysztof,

Thanks, for the review.

I apologize for any confusion or oversight regarding the recent review comments.
Thank you for your patience and understanding. I value your time and feedback 
and will work to improve the review process.

Below are the comments on the patch 7 and patch 8 of the version 1 of the 
series, that I have addressed in version 2 of patch 7 of the series.
Let me know, If I did some mistake or if you have any other suggestions.

Comments from Konard:

comment 1

> - pinctrl-0 = <&qup_i2c18_default>;
> + pinctrl-0 = <&qup_i2c18_default>,
> + <&io_expander_intr_active>,
> + <&io_expander_reset_active>;

Please align the '<'s

comment 2

> + interrupt-parent = <&tlmm>;
> + interrupts = <98 IRQ_TYPE_EDGE_BOTH>;

use interrupts-extended, here and below

These above two comments were from the konard in patch 7 in version 1 of the 
series.
I have addressed both the above comments in the version 2 of patch 7 of the 
series.



Comments from Krzysztof:

comment 1

> +
> + dsi0_int_pin: gpio2_cfg {
No underscores, see DTS coding style.

I have corrected the above comment in the version 2 of patch 7 of the series.

comment 2

> +
> + anx_bridge_1: anx7625@58 {

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

In this I have changed the node name as anx_bridge1 : anx7625@58.
Let me know, if I did some mistake or you have any other suggestion over the 
node name.

I have took the reference from below:
linux/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi at 
629c635eafbaf18260c8083360745c71674640d2 · torvalds/linux · GitHub

comment 3

> + enable-gpios = <&io_expander 1 0>;
> + reset-gpios = <&io_expander 0 0>;
Use proper defines.

For this above comment,  I have changed above lines into below lines in patch 7 
of version 2 of the series.

> + enable-gpios = <&io_expander 1 
> GPIO_ACTIVE_HIGH>;
> + reset-gpios = <&io_expander 0 GPIO_ACTIVE_HIGH>;

comment 4

> +
> + anx_bridge_2: anx7625@58 {

Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

In this I have changed the node name as anx_bridge2 : anx7625@58.
Let me know, if I did some mistake or you have any other suggestion over the 
node name.

I have took the reference from below:
linux/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi at 
629c635eafbaf18260c8083360745c71674640d2 · torvalds/linux · GitHub

comment 5

And as Rob's bot pointed out: insufficient testing. :(
Please be 100% sure everything is tested before you post new version.
You shouldn't use reviewers for the job of tools, that's quite waste of
our time.

Fixed the  above warning from DT checker against DT binding in patch 7 of 
version 2 of the series.


Comments from Dmitry:

comment 1

Missing dp-connector devices. Please add them together with the bridges. 

comment 2

Please squash into the previous patch. It doesn't make a lot of sense 
separately.

These both above commented from Dmitry I have addressed in the version 2 of 
patch 7 of the series.
I have squash patch 8 into patch 7 of version 1 into patch 7 of version 2 of 
the series.


Thanks,
Ayushi


Re: [RFC PATCH 00/19] drm, drm/xe: Multi-device GPUSVM

2025-03-13 Thread Christian König
Am 13.03.25 um 13:50 schrieb Thomas Hellström:
> Hi, Christian
>
> On Thu, 2025-03-13 at 11:19 +0100, Christian König wrote:
>> Am 12.03.25 um 22:03 schrieb Thomas Hellström:
>>> This RFC implements and requests comments for a way to handle SVM
>>> with multi-device,
>>> typically with fast interconnects. It adds generic code and helpers
>>> in drm, and
>>> device-specific code for xe.
>>>
>>> For SVM, devices set up maps of device-private struct pages, using
>>> a struct dev_pagemap,
>>> The CPU virtual address space (mm), can then be set up using
>>> special page-table entries
>>> to point to such pages, but they can't be accessed directly by the
>>> CPU, but possibly
>>> by other devices using a fast interconnect. This series aims to
>>> provide helpers to
>>> identify pagemaps that take part in such a fast interconnect and to
>>> aid in migrating
>>> between them.
>>>
>>> This is initially done by augmenting the struct dev_pagemap with a
>>> struct drm_pagemap,
>>> and having the struct drm_pagemap implement a "populate_mm" method,
>>> where a region of
>>> the CPU virtual address space (mm) is populated with device_private
>>> pages from the
>>> dev_pagemap associated with the drm_pagemap, migrating data from
>>> system memory or other
>>> devices if necessary. The drm_pagemap_populate_mm() function is
>>> then typically called
>>> from a fault handler, using the struct drm_pagemap pointer of
>>> choice. It could be
>>> referencing a local drm_pagemap or a remote one. The migration is
>>> now completely done
>>> by drm_pagemap callbacks, (typically using a copy-engine local to
>>> the dev_pagemap local
>>> memory).
>> Up till here that makes sense. Maybe not necessary to be put into the
>> DRM layer, but that is an implementation detail.
>>
>>> In addition there are helpers to build a drm_pagemap UAPI using
>>> file-descripors
>>> representing struct drm_pagemaps, and a helper to register devices
>>> with a common
>>> fast interconnect. The UAPI is intended to be private to the
>>> device, but if drivers
>>> agree to identify struct drm_pagemaps by file descriptors one could
>>> in theory
>>> do cross-driver multi-device SVM if a use-case were found.
>> But this completely eludes me.
>>
>> Why would you want an UAPI for representing pagemaps as file
>> descriptors? Isn't it the kernel which enumerates the interconnects
>> of the devices?
>>
>> I mean we somehow need to expose those interconnects between devices
>> to userspace, e.g. like amdgpu does with it's XGMI connectors. But
>> that is static for the hardware (unless HW is hot removed/added) and
>> so I would assume exposed through sysfs.
> Thanks for the feedback.
>
> The idea here is not to expose the interconnects but rather have a way
> for user-space to identify a drm_pagemap and some level of access- and
> lifetime control.

Well that's what I get I just don't get why?

I mean when you want to have the pagemap as optional feature you can turn on 
and off I would say make that a sysfs file.

It's a global feature anyway and not bound in any way to the file descriptor, 
isn't it?

> For Xe, If an application wants to use a particular drm_pagemap it
> calls an ioctl:
>
> pagemap_fd = drm_xe_ioctl_pagemap_open(exporting_device_fd,
> memory_region);

Well should userspace deal with physical addresses here, or what exactly is 
memory_region here?

Regards,
Christian.

>
> And then when it's no longer used
> close(pagemap_fd)
>
> To use it for a memory range, the intended idea is call gpu madvise
> ioctl:
>  
> err = drm_xe_ioctl_gpu_madvise(local_device_fd, range, pagemap_fd);
>
> Now, if there is no fast interconnect between the two, the madvise call
> could just return an error. All this ofc assumes that user-space is
> somehow aware of the fast interconnect topology but how that is exposed
> is beyond the scope of this first series. (Suggestions welcome).
>
> The advantage of the above approach is
> 1) We get some level of access control. If the user doesn't have access
> to the exporting device, he/she can't obtain a pagemap file descriptor.
>
> 2) Lifetime control. The pagemaps are memory hungry, but also take
> considerable time to set up and tear down.
>
> 3) It's a driver-independent approach.
>
> One could ofc use a different approach by feeding the gpu_madvise()
> ioctl with a remote device file descriptor and whatever information is
> needed for the remote device to identify the drm_pagemap. That would
> not be driver independent, though. Not sure how important that is.
>
> /Thomas
>
>
>> Thanks,
>> Christian.
>>
>>> The implementation for the Xe driver uses dynamic pagemaps which
>>> are created on first
>>> use and removed 5s after the last reference is gone. Pagemaps are
>>> revoked on
>>> device unbind, and data is then migrated to system.
>>>
>>> Status:
>>> This is a POC series. It has been tested with an IGT test soon to
>>> be published, with a
>>> DG1 drm_pagemap and a BattleMage SVM client. There is separate work
>>> ongoing 

[PATCH v4 00/14] Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
Some unit tests intentionally trigger warning backtraces by passing bad
parameters to kernel API functions. Such unit tests typically check the
return value from such calls, not the existence of the warning backtrace.

Such intentionally generated warning backtraces are neither desirable
nor useful for a number of reasons.
- They can result in overlooked real problems.
- A warning that suddenly starts to show up in unit tests needs to be
  investigated and has to be marked to be ignored, for example by
  adjusting filter scripts. Such filters are ad-hoc because there is
  no real standard format for warnings. On top of that, such filter
  scripts would require constant maintenance.

One option to address problem would be to add messages such as "expected
warning backtraces start / end here" to the kernel log.  However, that
would again require filter scripts, it might result in missing real
problematic warning backtraces triggered while the test is running, and
the irrelevant backtrace(s) would still clog the kernel log.

Solve the problem by providing a means to identify and suppress specific
warning backtraces while executing test code. Support suppressing multiple
backtraces while at the same time limiting changes to generic code to the
absolute minimum. Architecture specific changes are kept at minimum by
retaining function names only if both CONFIG_DEBUG_BUGVERBOSE and
CONFIG_KUNIT are enabled.

The first patch of the series introduces the necessary infrastructure.
The second patch introduces support for counting suppressed backtraces.
This capability is used in patch three to implement unit tests.
Patch four documents the new API.
The next two patches add support for suppressing backtraces in drm_rect
and dev_addr_lists unit tests. These patches are intended to serve as
examples for the use of the functionality introduced with this series.
The remaining patches implement the necessary changes for all
architectures with GENERIC_BUG support.

With CONFIG_KUNIT enabled, image size increase with this series applied is
approximately 1%. The image size increase (and with it the functionality
introduced by this series) can be avoided by disabling
CONFIG_KUNIT_SUPPRESS_BACKTRACE.

This series is based on the RFC patch and subsequent discussion at
https://patchwork.kernel.org/project/linux-kselftest/patch/02546e59-1afe-4b08-ba81-d94f3b691c9a@moroto.mountain/
and offers a more comprehensive solution of the problem discussed there.

Design note:
  Function pointers are only added to the __bug_table section if both
  CONFIG_KUNIT_SUPPRESS_BACKTRACE and CONFIG_DEBUG_BUGVERBOSE are enabled
  to avoid image size increases if CONFIG_KUNIT is disabled. There would be
  some benefits to adding those pointers all the time (reduced complexity,
  ability to display function names in BUG/WARNING messages). That change,
  if desired, can be made later.

Checkpatch note:
  Remaining checkpatch errors and warnings were deliberately ignored.
  Some are triggered by matching coding style or by comments interpreted
  as code, others by assembler macros which are disliked by checkpatch.
  Suggestions for improvements are welcome.

Changes since RFC:
- Introduced CONFIG_KUNIT_SUPPRESS_BACKTRACE
- Minor cleanups and bug fixes
- Added support for all affected architectures
- Added support for counting suppressed warnings
- Added unit tests using those counters
- Added patch to suppress warning backtraces in dev_addr_lists tests

Changes since v1:
- Rebased to v6.9-rc1
- Added Tested-by:, Acked-by:, and Reviewed-by: tags
  [I retained those tags since there have been no functional changes]
- Introduced KUNIT_SUPPRESS_BACKTRACE configuration option, enabled by
  default.

Changes since v2:
- Rebased to v6.9-rc2
- Added comments to drm warning suppression explaining why it is needed.
- Added patch to move conditional code in arch/sh/include/asm/bug.h
  to avoid kerneldoc warning
- Added architecture maintainers to Cc: for architecture specific patches
- No functional changes

Changes since v3:
- Rebased to v6.14-rc6
- Dropped net: "kunit: Suppress lock warning noise at end of dev_addr_lists 
tests"
  since 3db3b62955cd6d73afde05a17d7e8e106695c3b9
- Added __kunit_ and KUNIT_ prefixes.
- Tested on interessed architectures.


Guenter Roeck (14):
  bug/kunit: Core support for suppressing warning backtraces
  kunit: bug: Count suppressed warning backtraces
  kunit: Add test cases for backtrace warning suppression
  kunit: Add documentation for warning backtrace suppression API
  drm: Suppress intentional warning backtraces in scaling unit tests
  x86: Add support for suppressing warning backtraces
  arm64: Add support for suppressing warning backtraces
  loongarch: Add support for suppressing warning backtraces
  parisc: Add support for suppressing warning backtraces
  s390: Add support for suppressing warning backtraces
  sh: Add support for suppressing warning backtraces
  sh: Move defines needed for suppressing warning backtraces
  

[PATCH v4 01/14] bug/kunit: Core support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Some unit tests intentionally trigger warning backtraces by passing
bad parameters to API functions. Such unit tests typically check the
return value from those calls, not the existence of the warning backtrace.

Such intentionally generated warning backtraces are neither desirable
nor useful for a number of reasons.
- They can result in overlooked real problems.
- A warning that suddenly starts to show up in unit tests needs to be
  investigated and has to be marked to be ignored, for example by
  adjusting filter scripts. Such filters are ad-hoc because there is
  no real standard format for warnings. On top of that, such filter
  scripts would require constant maintenance.

One option to address problem would be to add messages such as "expected
warning backtraces start / end here" to the kernel log.  However, that
would again require filter scripts, it might result in missing real
problematic warning backtraces triggered while the test is running, and
the irrelevant backtrace(s) would still clog the kernel log.

Solve the problem by providing a means to identify and suppress specific
warning backtraces while executing test code. Since the new functionality
results in an image size increase of about 1% if CONFIG_KUNIT is enabled,
provide configuration option KUNIT_SUPPRESS_BACKTRACE to be able to disable
the new functionality. This option is by default enabled since almost all
systems with CONFIG_KUNIT enabled will want to benefit from it.

Cc: Dan Carpenter 
Cc: Daniel Diaz 
Cc: Naresh Kamboju 
Cc: Kees Cook 
Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Reviewed-by: Kees Cook 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 include/asm-generic/bug.h | 16 +---
 include/kunit/bug.h   | 51 +++
 include/kunit/test.h  |  1 +
 include/linux/bug.h   | 13 ++
 lib/bug.c | 51 ---
 lib/kunit/Kconfig |  9 +++
 lib/kunit/Makefile|  6 +++--
 lib/kunit/bug.c   | 40 ++
 8 files changed, 178 insertions(+), 9 deletions(-)
 create mode 100644 include/kunit/bug.h
 create mode 100644 lib/kunit/bug.c

diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 387720933973..9194cf743ec3 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -18,6 +18,7 @@
 #endif
 
 #ifndef __ASSEMBLY__
+#include 
 #include 
 #include 
 
@@ -39,8 +40,14 @@ struct bug_entry {
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
const char  *file;
+#ifdef HAVE_BUG_FUNCTION
+   const char  *function;
+#endif
 #else
signed int  file_disp;
+#ifdef HAVE_BUG_FUNCTION
+   signed int  function_disp;
+#endif
 #endif
unsigned short  line;
 #endif
@@ -96,15 +103,18 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, 
...);
 #define __WARN()   __WARN_printf(TAINT_WARN, NULL)
 #define __WARN_printf(taint, arg...) do {  \
instrumentation_begin();\
-   warn_slowpath_fmt(__FILE__, __LINE__, taint, arg);  \
+   if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) 
\
+   warn_slowpath_fmt(__FILE__, __LINE__, taint, arg);\
instrumentation_end();  \
} while (0)
 #else
 #define __WARN()   __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN))
 #define __WARN_printf(taint, arg...) do {  \
instrumentation_begin();\
-   __warn_printk(arg); \
-   __WARN_FLAGS(BUGFLAG_NO_CUT_HERE | BUGFLAG_TAINT(taint));\
+   if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) {   
\
+   __warn_printk(arg); \
+   __WARN_FLAGS(BUGFLAG_NO_CUT_HERE | 
BUGFLAG_TAINT(taint));\
+   }   \
instrumentation_end();  \
} while (0)
 #define WARN_ON_ONCE(condition) ({ \
diff --git a/include/kunit/bug.h b/include/kunit/bug.h
new file mode 100644
index ..0a8e62c1fcaf
--- /dev/null
+++ b/include/kunit/bug.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * KUnit helpers for backtrace suppression
+ *
+ * Copyright (c) 2024 Guenter Roeck 
+ */
+
+#ifndef _KUNIT_BUG_H
+#define _KUNIT_BUG_H
+
+#ifndef __ASSEMBLY__
+
+#include 
+
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+
+#include 
+#include 
+
+struct __suppressed_warning {
+   struct list_head node;
+   const char *function;
+};
+
+void __kunit_start_suppress_warning(struct __suppressed_warning *warning);
+vo

[PATCH v4 06/14] x86: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
From: Guenter Roeck 

Add name of functions triggering warning backtraces to the __bug_table
object section to enable support for suppressing WARNING backtraces.

To limit image size impact, the pointer to the function name is only added
to the __bug_table section if both CONFIG_KUNIT_SUPPRESS_BACKTRACE and
CONFIG_DEBUG_BUGVERBOSE are enabled. Otherwise, the __func__ assembly
parameter is replaced with a (dummy) NULL parameter to avoid an image size
increase due to unused __func__ entries (this is necessary because __func__
is not a define but a virtual variable).

Tested-by: Linux Kernel Functional Testing 
Acked-by: Dan Carpenter 
Cc: Thomas Gleixner 
Cc: Ingo Molnar 
Cc: Borislav Petkov 
Cc: Dave Hansen 
Signed-off-by: Guenter Roeck 
Signed-off-by: Alessandro Carminati 
---
 arch/x86/include/asm/bug.h | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index e85ac0c7c039..f6e13fc675ab 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -35,18 +35,28 @@
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 
+#ifdef CONFIG_KUNIT_SUPPRESS_BACKTRACE
+# define HAVE_BUG_FUNCTION
+# define __BUG_FUNC_PTR__BUG_REL(%c1)
+# define __BUG_FUNC__func__
+#else
+# define __BUG_FUNC_PTR
+# define __BUG_FUNCNULL
+#endif /* CONFIG_KUNIT_SUPPRESS_BACKTRACE */
+
 #define _BUG_FLAGS(ins, flags, extra)  \
 do {   \
asm_inline volatile("1:\t" ins "\n" \
 ".pushsection __bug_table,\"aw\"\n"\
 "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"   \
 "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"   \
-"\t.word %c1""\t# bug_entry::line\n"   \
-"\t.word %c2""\t# bug_entry::flags\n"  \
-"\t.org 2b+%c3\n"  \
+"\t"  __BUG_FUNC_PTR "\t# bug_entry::function\n"   \
+"\t.word %c2""\t# bug_entry::line\n"   \
+"\t.word %c3""\t# bug_entry::flags\n"  \
+"\t.org 2b+%c4\n"  \
 ".popsection\n"\
 extra  \
-: : "i" (__FILE__), "i" (__LINE__),\
+: : "i" (__FILE__), "i" (__BUG_FUNC), "i" (__LINE__),\
 "i" (flags),   \
 "i" (sizeof(struct bug_entry)));   \
 } while (0)
@@ -92,7 +102,8 @@ do { 
\
 do {   \
__auto_type __flags = BUGFLAG_WARNING|(flags);  \
instrumentation_begin();\
-   _BUG_FLAGS(ASM_UD2, __flags, ANNOTATE_REACHABLE(1b));   \
+   if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) \
+   _BUG_FLAGS(ASM_UD2, __flags, ANNOTATE_REACHABLE(1b));   \
instrumentation_end();  \
 } while (0)
 
-- 
2.34.1



Re: [PATCH v5 04/16] drm/atomic: Introduce helper to lookup connector by encoder

2025-03-13 Thread Maxime Ripard
Hi,

On Thu, Mar 13, 2025 at 04:09:54PM +0800, Andy Yan wrote:
> At 2025-03-05 19:55:19, "Andy Yan"  wrote:
> >At 2025-03-04 19:10:47, "Maxime Ripard"  wrote:
> >>With the bridges switching over to drm_bridge_connector, the direct
> >>association between a bridge driver and its connector was lost.
> >>
> >>This is mitigated for atomic bridge drivers by the fact you can access
> >>the encoder, and then call drm_atomic_get_old_connector_for_encoder() or
> >>drm_atomic_get_new_connector_for_encoder() with drm_atomic_state.
> >>
> >>This was also made easier by providing drm_atomic_state directly to all
> >>atomic hooks bridges can implement.
> >>
> >>However, bridge drivers don't have a way to access drm_atomic_state
> >>outside of the modeset path, like from the hotplug interrupt path or any
> >>interrupt handler.
> >>
> >>Let's introduce a function to retrieve the connector currently assigned
> >>to an encoder, without using drm_atomic_state, to make these drivers'
> >>life easier.
> >>
> >>Reviewed-by: Dmitry Baryshkov 
> >>Co-developed-by: Simona Vetter 
> >>Signed-off-by: Maxime Ripard 
> >>---
> >> drivers/gpu/drm/drm_atomic.c | 45 
> >> 
> >> include/drm/drm_atomic.h |  3 +++
> >> 2 files changed, 48 insertions(+)
> >>
> >>diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> >>index 
> >>9ea2611770f43ce7ccba410406d5f2c528aab022..b926b132590e78f8d41d48eb4da4bccf170ee236
> >> 100644
> >>--- a/drivers/gpu/drm/drm_atomic.c
> >>+++ b/drivers/gpu/drm/drm_atomic.c
> >>@@ -985,10 +985,55 @@ drm_atomic_get_new_connector_for_encoder(const struct 
> >>drm_atomic_state *state,
> >> 
> >>return NULL;
> >> }
> >> EXPORT_SYMBOL(drm_atomic_get_new_connector_for_encoder);
> >> 
> >>+/**
> >>+ * drm_atomic_get_connector_for_encoder - Get connector currently assigned 
> >>to an encoder
> >>+ * @encoder: The encoder to find the connector of
> >>+ * @ctx: Modeset locking context
> >>+ *
> >>+ * This function finds and returns the connector currently assigned to
> >>+ * an @encoder.
> >>+ *
> >>+ * Returns:
> >>+ * The connector connected to @encoder, or an error pointer otherwise.
> >>+ * When the error is EDEADLK, a deadlock has been detected and the
> >>+ * sequence must be restarted.
> >>+ */
> >>+struct drm_connector *
> >>+drm_atomic_get_connector_for_encoder(const struct drm_encoder *encoder,
> >>+struct drm_modeset_acquire_ctx *ctx)
> >>+{
> >>+   struct drm_connector_list_iter conn_iter;
> >>+   struct drm_connector *out_connector = ERR_PTR(-EINVAL);
> >>+   struct drm_connector *connector;
> >>+   struct drm_device *dev = encoder->dev;
> >>+   int ret;
> >>+
> >>+   ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx);
> >>+   if (ret)
> >>+   return ERR_PTR(ret);
> >
> >It seems that this will cause a deadlock when called from a  hotplug 
> >handling path,
> >I have a WIP DP diver[0],  which suggested by Dmitry to use this API from a 
> >&drm_bridge_funcs.detect callback to get the connector,  as detect is called 
> >by drm_helper_probe_detect,
> >which will hold connection_mutex first, so the deaklock happens:
> >
> >
> >drm_helper_probe_detect(struct drm_connector *connector,
> >struct drm_modeset_acquire_ctx *ctx,
> >bool force)
> >{
> >const struct drm_connector_helper_funcs *funcs = 
> > connector->helper_private;
> >struct drm_device *dev = connector->dev;
> >int ret;
> >
> >if (!ctx)
> >return drm_helper_probe_detect_ctx(connector, force);
> >
> >ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx);
> >if (ret)
> >return ret;
> >
> >if (funcs->detect_ctx)
> >ret = funcs->detect_ctx(connector, ctx, force);
> >else if (connector->funcs->detect)
> >ret = connector->funcs->detect(connector, force);
> >else
> >ret = connector_status_connected;
> >
> >if (ret != connector->status)
> >connector->epoch_counter += 1;
> >
> >So I wonder can we let drm_bridge_funcs.detect pass a connector for this 
> >case ?
> >
> >
> >
> >[0]https://lore.kernel.org/linux-rockchip/047eecfc-7e55-44ec-896f-13fe04333...@gmail.com/T/#m25bc53b79f5cc7bddfcb7aae5656f68df396f094
> >>+
> >>+   drm_connector_list_iter_begin(dev, &conn_iter);
> >>+   drm_for_each_connector_iter(connector, &conn_iter) {
> >>+   if (!connector->state)
> >>+   continue;
> >>+
> >>+   if (encoder == connector->state->best_encoder) {
> >>+   out_connector = connector;
> 
> 
> When try to use this patch in my bridge driver,  I found that the 
> connector->state->best_encoder 
>  maybe NULL when   drm_bridge_funcs.detect or drm_bridge_funcs.detect_ctx is  
> called:
> 
> [   52.713030] Invalid return value -22 for connector detection
> [   52.713539] WARNING: CPU: 7 P

[PATCH] fbcon: Use static attribute groups for sysfs entries

2025-03-13 Thread oushixiong1025
From: Shixiong Ou 

Using device_create_with_groups() to simplify creation and removal.
Same as commit 1083a7be4504 ("tty: Use static attribute groups for
sysfs entries").

Signed-off-by: Shixiong Ou 
---
 drivers/video/fbdev/core/fbcon.c | 67 +---
 1 file changed, 19 insertions(+), 48 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index e8b4e8c119b5..7f96b60c07f5 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -160,7 +160,6 @@ static int info_idx = -1;
 
 /* console rotation */
 static int initial_rotation = -1;
-static int fbcon_has_sysfs;
 static int margin_color;
 
 static const struct consw fb_con;
@@ -3157,7 +3156,7 @@ static const struct consw fb_con = {
.con_debug_leave= fbcon_debug_leave,
 };
 
-static ssize_t store_rotate(struct device *device,
+static ssize_t rotate_store(struct device *device,
struct device_attribute *attr, const char *buf,
size_t count)
 {
@@ -3179,7 +3178,7 @@ static ssize_t store_rotate(struct device *device,
return count;
 }
 
-static ssize_t store_rotate_all(struct device *device,
+static ssize_t rotate_all_store(struct device *device,
struct device_attribute *attr,const char *buf,
size_t count)
 {
@@ -3201,7 +3200,7 @@ static ssize_t store_rotate_all(struct device *device,
return count;
 }
 
-static ssize_t show_rotate(struct device *device,
+static ssize_t rotate_show(struct device *device,
   struct device_attribute *attr,char *buf)
 {
struct fb_info *info;
@@ -3220,7 +3219,7 @@ static ssize_t show_rotate(struct device *device,
return sysfs_emit(buf, "%d\n", rotate);
 }
 
-static ssize_t show_cursor_blink(struct device *device,
+static ssize_t cursor_blink_show(struct device *device,
 struct device_attribute *attr, char *buf)
 {
struct fb_info *info;
@@ -3245,7 +3244,7 @@ static ssize_t show_cursor_blink(struct device *device,
return sysfs_emit(buf, "%d\n", blink);
 }
 
-static ssize_t store_cursor_blink(struct device *device,
+static ssize_t cursor_blink_store(struct device *device,
  struct device_attribute *attr,
  const char *buf, size_t count)
 {
@@ -3279,35 +3278,18 @@ static ssize_t store_cursor_blink(struct device *device,
return count;
 }
 
-static struct device_attribute device_attrs[] = {
-   __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
-   __ATTR(rotate_all, S_IWUSR, NULL, store_rotate_all),
-   __ATTR(cursor_blink, S_IRUGO|S_IWUSR, show_cursor_blink,
-  store_cursor_blink),
-};
-
-static int fbcon_init_device(void)
-{
-   int i, error = 0;
+static DEVICE_ATTR_RW(rotate);
+static DEVICE_ATTR_WO(rotate_all);
+static DEVICE_ATTR_RW(cursor_blink);
 
-   fbcon_has_sysfs = 1;
-
-   for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
-   error = device_create_file(fbcon_device, &device_attrs[i]);
-
-   if (error)
-   break;
-   }
-
-   if (error) {
-   while (--i >= 0)
-   device_remove_file(fbcon_device, &device_attrs[i]);
-
-   fbcon_has_sysfs = 0;
-   }
+static struct attribute *fbcon_device_attrs[] = {
+   &dev_attr_rotate.attr,
+   &dev_attr_rotate_all.attr,
+   &dev_attr_cursor_blink.attr,
+   NULL
+};
 
-   return 0;
-}
+ATTRIBUTE_GROUPS(fbcon_device);
 
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
 static void fbcon_register_existing_fbs(struct work_struct *work)
@@ -3367,14 +3349,16 @@ void __init fb_console_init(void)
console_lock();
fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
 "fbcon");
+   fbcon_device = device_create_with_groups(fb_class, NULL,
+MKDEV(0, 0), NULL,
+fbcon_device_groups, "fbcon");
 
if (IS_ERR(fbcon_device)) {
printk(KERN_WARNING "Unable to create device "
   "for fbcon; errno = %ld\n",
   PTR_ERR(fbcon_device));
fbcon_device = NULL;
-   } else
-   fbcon_init_device();
+   }
 
for (i = 0; i < MAX_NR_CONSOLES; i++)
con2fb_map[i] = -1;
@@ -3385,18 +3369,6 @@ void __init fb_console_init(void)
 
 #ifdef MODULE
 
-static void __exit fbcon_deinit_device(void)
-{
-   int i;
-
-   if (fbcon_has_sysfs) {
-   for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
-   device_remove_file(fbcon_device, &device_attrs[i]);
-
-   fbcon_has_sysfs = 0;
-   }
-}
-
 void __exit fb_console_exit(void)
 {
 #ifdef CONFIG_FRAMEBUFF

Re: [PATCH v4 5/7] dt-bindings: gpu: v3d: Add SMS register to BCM2712 compatible

2025-03-13 Thread Krzysztof Kozlowski
On 13/03/2025 15:43, Maíra Canal wrote:
> V3D 7.1 exposes a new register block, called V3D_SMS. As BCM2712 has a
> V3D 7.1 core, add a new register item to its compatible. Similar to the
> GCA, which is specific for V3D 3.3, SMS should only be added for V3D 7.1
> variants (such as brcm,2712-v3d).
> 
> Signed-off-by: Maíra Canal 
> ---

Acked-by: Krzysztof Kozlowski 

Best regards,
Krzysztof


[PATCH v4 7/7] dt-bindings: gpu: Add V3D driver maintainer as DT maintainer

2025-03-13 Thread Maíra Canal
As established in commit 89d04995f76c ("MAINTAINERS: Drop Emma Anholt
from all M lines."), Emma is no longer active in the Linux kernel and
dropped the V3D maintainership. Therefore, remove Emma as one of the DT
maintainers and add the current V3D driver maintainer.

Acked-by: Emma Anholt 
Acked-by: Rob Herring (Arm) 
Signed-off-by: Maíra Canal 
---
 Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml 
b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
index 
739e8afcacebe63ac6cd8853a58750f4f83146d3..82bc2f7c4006055df1031ddd4c64432c5ed3a14f
 100644
--- a/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
+++ b/Documentation/devicetree/bindings/gpu/brcm,bcm-v3d.yaml
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Broadcom V3D GPU
 
 maintainers:
-  - Eric Anholt 
+  - Maíra Canal 
   - Nicolas Saenz Julienne 
 
 properties:

-- 
Git-154)



Re: [PATCH] drm/amd/display: avoid NPD when ASIC does not support DMUB

2025-03-13 Thread Rodrigo Siqueira
On 03/13, Thadeu Lima de Souza Cascardo wrote:
> On Wed, Feb 05, 2025 at 10:06:38AM -0300, Thadeu Lima de Souza Cascardo wrote:
> > ctx->dmub_srv will de NULL if the ASIC does not support DMUB, which is
> > tested in dm_dmub_sw_init.
> > 
> > However, it will be dereferenced in dmub_hw_lock_mgr_cmd if
> > should_use_dmub_lock returns true.
> > 
> > This has been the case since dmub support has been added for PSR1.
> 
> This bug has landed on stable trees. Any chance for a review here?
> 
> Thanks.
> Cascardo.
> 
> > 
> > Fix this by checking for dmub_srv in should_use_dmub_lock.
> > 
> > [   37.440832] BUG: kernel NULL pointer dereference, address: 
> > 0058
> > [   37.447808] #PF: supervisor read access in kernel mode
> > [   37.452959] #PF: error_code(0x) - not-present page
> > [   37.458112] PGD 0 P4D 0
> > [   37.460662] Oops: Oops:  [#1] PREEMPT SMP NOPTI
> > [   37.465553] CPU: 2 UID: 1000 PID: 1745 Comm: DrmThread Not tainted 
> > 6.14.0-rc1-3-gd62e938120f0 #23 99720e1cb1e0fc4773b8513150932a07de3c6e88
> > [   37.478324] Hardware name: Google Morphius/Morphius, BIOS 
> > Google_Morphius.13434.858.0 10/26/2023
> > [   37.487103] RIP: 0010:dmub_hw_lock_mgr_cmd+0x77/0xb0
> > [   37.492074] Code: 44 24 0e 00 00 00 00 48 c7 04 24 45 00 00 0c 40 88 74 
> > 24 0d 0f b6 02 88 44 24 0c 8b 01 89 44 24 08 85 f6 75 05 c6 44 24 0e 01 
> > <48> 8b 7f 58 48 89 e6 ba 01 00 00 00 e8 08 3c 2a 00 65 48 8b 04 5
> > [   37.510822] RSP: 0018:969442853300 EFLAGS: 00010202
> > [   37.516052] RAX:  RBX: 92db0300 RCX: 
> > 969442853358
> > [   37.523185] RDX: 969442853368 RSI: 0001 RDI: 
> > 
> > [   37.530322] RBP: 0001 R08: 04a7 R09: 
> > 04a5
> > [   37.537453] R10: 0476 R11: 0062 R12: 
> > 92db0ade8000
> > [   37.544589] R13: 92da01180ae0 R14: 92da011802a8 R15: 
> > 92db0300
> > [   37.551725] FS:  784a9cdfc6c0() GS:92db2af0() 
> > knlGS:
> > [   37.559814] CS:  0010 DS:  ES:  CR0: 80050033
> > [   37.565562] CR2: 0058 CR3: 000112b1c000 CR4: 
> > 003506f0
> > [   37.572697] Call Trace:
> > [   37.575152]  
> > [   37.577258]  ? __die_body+0x66/0xb0
> > [   37.580756]  ? page_fault_oops+0x3e7/0x4a0
> > [   37.584861]  ? exc_page_fault+0x3e/0xe0
> > [   37.588706]  ? exc_page_fault+0x5c/0xe0
> > [   37.592550]  ? asm_exc_page_fault+0x22/0x30
> > [   37.596742]  ? dmub_hw_lock_mgr_cmd+0x77/0xb0
> > [   37.601107]  dcn10_cursor_lock+0x1e1/0x240
> > [   37.605211]  program_cursor_attributes+0x81/0x190
> > [   37.609923]  commit_planes_for_stream+0x998/0x1ef0
> > [   37.614722]  update_planes_and_stream_v2+0x41e/0x5c0
> > [   37.619703]  dc_update_planes_and_stream+0x78/0x140
> > [   37.624588]  amdgpu_dm_atomic_commit_tail+0x4362/0x49f0
> > [   37.629832]  ? srso_return_thunk+0x5/0x5f
> > [   37.633847]  ? mark_held_locks+0x6d/0xd0
> > [   37.637774]  ? _raw_spin_unlock_irq+0x24/0x50
> > [   37.642135]  ? srso_return_thunk+0x5/0x5f
> > [   37.646148]  ? lockdep_hardirqs_on+0x95/0x150
> > [   37.650510]  ? srso_return_thunk+0x5/0x5f
> > [   37.654522]  ? _raw_spin_unlock_irq+0x2f/0x50
> > [   37.658883]  ? srso_return_thunk+0x5/0x5f
> > [   37.662897]  ? wait_for_common+0x186/0x1c0
> > [   37.666998]  ? srso_return_thunk+0x5/0x5f
> > [   37.671009]  ? drm_crtc_next_vblank_start+0xc3/0x170
> > [   37.675983]  commit_tail+0xf5/0x1c0
> > [   37.679478]  drm_atomic_helper_commit+0x2a2/0x2b0
> > [   37.684186]  drm_atomic_commit+0xd6/0x100
> > [   37.688199]  ? __cfi___drm_printfn_info+0x10/0x10
> > [   37.692911]  drm_atomic_helper_update_plane+0xe5/0x130
> > [   37.698054]  drm_mode_cursor_common+0x501/0x670
> > [   37.702600]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
> > [   37.707572]  drm_mode_cursor_ioctl+0x48/0x70
> > [   37.711851]  drm_ioctl_kernel+0xf2/0x150
> > [   37.715781]  drm_ioctl+0x363/0x590
> > [   37.719189]  ? __cfi_drm_mode_cursor_ioctl+0x10/0x10
> > [   37.724165]  amdgpu_drm_ioctl+0x41/0x80
> > [   37.728013]  __se_sys_ioctl+0x7f/0xd0
> > [   37.731685]  do_syscall_64+0x87/0x100
> > [   37.735355]  ? vma_end_read+0x12/0xe0
> > [   37.739024]  ? srso_return_thunk+0x5/0x5f
> > [   37.743041]  ? find_held_lock+0x47/0xf0
> > [   37.746884]  ? vma_end_read+0x12/0xe0
> > [   37.750552]  ? srso_return_thunk+0x5/0x5f
> > [   37.754565]  ? lock_release+0x1c4/0x2e0
> > [   37.758406]  ? vma_end_read+0x12/0xe0
> > [   37.762079]  ? exc_page_fault+0x84/0xe0
> > [   37.765921]  ? srso_return_thunk+0x5/0x5f
> > [   37.769938]  ? lockdep_hardirqs_on+0x95/0x150
> > [   37.774303]  ? srso_return_thunk+0x5/0x5f
> > [   37.778317]  ? exc_page_fault+0x84/0xe0
> > [   37.782163]  entry_SYSCALL_64_after_hwframe+0x55/0x5d
> > [   37.787218] RIP: 0033:0x784aa5ec3059
> > [   37.790803] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10 c7 45 
> > b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 4

Re: [PATCH] drm/mxsfb: fix missing rollback on failure in mxsfb_probe()

2025-03-13 Thread Luca Ceresoli
Hello Thomas,

On Thu, 13 Mar 2025 15:40:43 +0100
Thomas Zimmermann  wrote:

> > @@ -365,9 +365,10 @@ static int mxsfb_probe(struct platform_device *pdev)
> >  * located anywhere in RAM
> >  */
> > ret = aperture_remove_all_conflicting_devices(mxsfb_driver.name);
> > -   if (ret)
> > -   return dev_err_probe(&pdev->dev, ret,
> > -"can't kick out existing framebuffers\n");
> > +   if (ret) {
> > +   dev_err_probe(&pdev->dev, ret, "can't kick out existing 
> > framebuffers\n");
> > +   goto err_unload;
> > +   }  
> 
> I must have missed that when I reviewed the patch. But this call should 
> happen much earlier. right at the top of the probe function before 
> drm_dev_alloc(). Conflicting drivers need to be kicked out before 
> setting up DRM. Could you please send a patch to move the call to the 
> top? No extra cleanup would be required then.

Sure, sending v2 in a moment.

Luca

-- 
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Re: [PATCH RFC 0/3] Initial work for Rust abstraction for HID device driver development

2025-03-13 Thread Benjamin Tissoires
Hi,

[quick reply because I am completely under the water for the next 2
weeks]

On Mar 13 2025, Rahul Rameshbabu wrote:
> Hello,
> 
> I am a hobbyist developer who has been working on a project to create a new 
> Rust
> HID device driver and the needed core abstractions for writing more HID device
> drivers in Rust. My goal is to support the USB Monitor Control Class needed 
> for
> functionality such as backlight control for monitors like the Apple Studio
> Display and Apple Pro Display XDR. A new backlight API will be required to
> support multiple backlight instances and will be mapped per DRM connector. The
> current backlight API is designed around the assumption of only a single
> internal panel being present. I am currently working on making this new API 
> for
> DRM in parallel to my work on the HID side of the stack for supporting these
> displays.

Thanks a lot for this work, though I wonder if your goal is not too big,
too far from the HID point of view. HID is simple, and there is only a
few bindings that you would need to be able to make "simple" HID
drivers.

My assumption would be to introduce the binding with a functional but
small driver (like one that just changes the report descriptor, or does
a sime raw event processing). Then we can look at integrating with the
DRM interface.

Though it's up to you to decide how you want to play ;)

> 
>   https://binary-eater.github.io/tags/usb-monitor-control/
> 
> Julius Zint had attempted to do so a year ago with a C HID driver but was 
> gated
> by the lack of an appropriate backlight API for external displays. I asked him
> for permission to do the work need in Rust and plan to accredit him for the 
> HID
> report handling for backlight in the USB Monitor Control Class standard.
> 
>   
> https://lore.kernel.org/lkml/f95da7ff-06dd-2c0e-d563-7e5ad61c3...@redhat.com/
> 
> I was hoping to get initial feedback on this work to make sure I am on the 
> right
> path for making a Rust HID abstraction that would be acceptable upstream. The
> patches compile with WERROR being disabled. This is necessary since Rust 
> treats
> missing documentation comments as warnings (which is a good thing). I also 
> need
> to go in and add more SAFETY comments.

K, I'll give you my opinion in the patches as the HID co-maintainer. I
do have a very little rust experience, but this is my first in kernel,
so I hope the more experience rust people here will chime in as well.

Cheers,
Benjamin

> 
> Thanks,
> Rahul Rameshbabu
> 
> Rahul Rameshbabu (3):
>   rust: core abstractions for HID drivers
>   rust: hid: USB Monitor Control Class driver
>   rust: hid: demo the core abstractions for probe and remove
> 
>  drivers/hid/Kconfig|  16 ++
>  drivers/hid/Makefile   |   1 +
>  drivers/hid/hid_monitor_control.rs |  42 +
>  rust/bindings/bindings_helper.h|   1 +
>  rust/kernel/hid.rs | 245 +
>  rust/kernel/lib.rs |   2 +
>  6 files changed, 307 insertions(+)
>  create mode 100644 drivers/hid/hid_monitor_control.rs
>  create mode 100644 rust/kernel/hid.rs
> 
> -- 
> 2.47.2
> 
> 


[PATCH] drm/komeda: Remove unnecessary NULL check before clk_prepare_enable()

2025-03-13 Thread Chen Ni
clk_prepare_enable() already checked NULL clock parameter.
Remove unneeded NULL check for clk here.

Signed-off-by: Chen Ni 
---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 5ba62e637a61..2b59830f0572 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -282,8 +282,7 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
 
debugfs_remove_recursive(mdev->debugfs_root);
 
-   if (mdev->aclk)
-   clk_prepare_enable(mdev->aclk);
+   clk_prepare_enable(mdev->aclk);
 
for (i = 0; i < mdev->n_pipelines; i++) {
komeda_pipeline_destroy(mdev, mdev->pipelines[i]);
-- 
2.25.1



[PATCH v7 5/6] drm/xe/xe_gt_pagefault: Add address_type field to pagefaults

2025-03-13 Thread Jonathan Cavitt
Add a new field to the xe_pagefault struct, address_type, that tracks
the type of fault the pagefault incurred.

Signed-off-by: Jonathan Cavitt 
---
 drivers/gpu/drm/xe/xe_gt_pagefault.c | 3 +++
 drivers/gpu/drm/xe/xe_gt_pagefault.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.c 
b/drivers/gpu/drm/xe/xe_gt_pagefault.c
index 7661b9ad1cd0..69ac8f437d11 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -206,11 +206,13 @@ static int handle_pagefault(struct xe_gt *gt, struct 
xe_pagefault *pf)
 
vma = lookup_vma(vm, pf->page_addr);
if (!vma) {
+   pf->address_type = DRM_XE_FAULT_ADDRESS_TYPE_NONE_EXT;
err = -EINVAL;
goto unlock_vm;
}
 
if (xe_vma_read_only(vma) && pf->access_type != 
XE_PAGEFAULT_ACCESS_TYPE_READ) {
+   pf->address_type = DRM_XE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT;
err = -EPERM;
goto unlock_vm;
}
@@ -284,6 +286,7 @@ static bool get_pagefault(struct pf_queue *pf_queue, struct 
xe_pagefault *pf)
pf->asid = FIELD_GET(PFD_ASID, desc->dw1);
pf->vfid = FIELD_GET(PFD_VFID, desc->dw2);
pf->access_type = FIELD_GET(PFD_ACCESS_TYPE, desc->dw2);
+   pf->address_type = 0;
pf->fault_type = FIELD_GET(PFD_FAULT_TYPE, desc->dw2);
pf->page_addr = (u64)(FIELD_GET(PFD_VIRTUAL_ADDR_HI, 
desc->dw3)) <<
PFD_VIRTUAL_ADDR_HI_SHIFT;
diff --git a/drivers/gpu/drm/xe/xe_gt_pagefault.h 
b/drivers/gpu/drm/xe/xe_gt_pagefault.h
index 33616043d17a..969f7b458d3f 100644
--- a/drivers/gpu/drm/xe/xe_gt_pagefault.h
+++ b/drivers/gpu/drm/xe/xe_gt_pagefault.h
@@ -17,6 +17,7 @@ struct xe_pagefault {
u16 pdata;
u8 vfid;
u8 access_type;
+   u8 address_type;
u8 fault_type;
u8 fault_level;
u8 engine_class;
-- 
2.43.0



[RFC PATCH 06/19] drm/pagemap, drm/xe: Add refcounting to struct drm_pagemap and manage lifetime

2025-03-13 Thread Thomas Hellström
Remove the xe embedded drm_pagemap, and instead allocate and
reference count.
This is a step towards adding drm_pagemaps on demand.

Signed-off-by: Thomas Hellström 
---
 drivers/gpu/drm/drm_pagemap.c| 58 +++-
 drivers/gpu/drm/xe/xe_device_types.h |  2 +-
 drivers/gpu/drm/xe/xe_svm.c  | 27 +
 drivers/gpu/drm/xe/xe_tile.h |  2 +-
 include/drm/drm_pagemap.h| 25 
 5 files changed, 102 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index 99394c7d1d66..8a0bdf38fc65 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -61,6 +61,7 @@
  *
  * @refcount: Reference count for the zdd
  * @devmem_allocation: device memory allocation
+ * @dpagemap: Pointer to the struct drm_pagemap.
  * @device_private_page_owner: Device private pages owner
  *
  * This structure serves as a generic wrapper installed in
@@ -73,11 +74,13 @@
 struct drm_pagemap_zdd {
struct kref refcount;
struct drm_pagemap_devmem *devmem_allocation;
+   struct drm_pagemap *dpagemap;
void *device_private_page_owner;
 };
 
 /**
  * drm_pagemap_zdd_alloc() - Allocate a zdd structure.
+ * @dpagemap: Pointer to the struct drm_pagemap.
  * @device_private_page_owner: Device private pages owner
  *
  * This function allocates and initializes a new zdd structure. It sets up the
@@ -86,7 +89,7 @@ struct drm_pagemap_zdd {
  * Return: Pointer to the allocated zdd on success, ERR_PTR() on failure.
  */
 static struct drm_pagemap_zdd *
-drm_pagemap_zdd_alloc(void *device_private_page_owner)
+drm_pagemap_zdd_alloc(struct drm_pagemap *dpagemap, void 
*device_private_page_owner)
 {
struct drm_pagemap_zdd *zdd;
 
@@ -97,6 +100,7 @@ drm_pagemap_zdd_alloc(void *device_private_page_owner)
kref_init(&zdd->refcount);
zdd->devmem_allocation = NULL;
zdd->device_private_page_owner = device_private_page_owner;
+   zdd->dpagemap = dpagemap;
 
return zdd;
 }
@@ -340,7 +344,7 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem 
*devmem_allocation,
dma_addr = buf + (2 * sizeof(*migrate.src) * npages);
pages = buf + (2 * sizeof(*migrate.src) + sizeof(*dma_addr)) * npages;
 
-   zdd = drm_pagemap_zdd_alloc(pgmap_owner);
+   zdd = drm_pagemap_zdd_alloc(devmem_allocation->dpagemap, pgmap_owner);
if (!zdd) {
err = -ENOMEM;
goto err_free;
@@ -484,6 +488,56 @@ static int drm_pagemap_migrate_populate_ram_pfn(struct 
vm_area_struct *vas,
return -ENOMEM;
 }
 
+static void drm_pagemap_release(struct kref *ref)
+{
+   struct drm_pagemap *dpagemap = container_of(ref, typeof(*dpagemap), 
ref);
+
+   kfree(dpagemap);
+}
+
+/**
+ * drm_pagemap_create() - Create a struct drm_pagemap.
+ * @dev: Pointer to a struct device providing the device-private memory.
+ * @pagemap: Pointer to a pre-setup struct dev_pagemap providing the struct 
pages.
+ * @ops: Pointer to the struct drm_pagemap_ops.
+ *
+ * Allocate and initialize a struct drm_pagemap.
+ *
+ * Return: A refcounted pointer to a struct drm_pagemap on success.
+ * Error pointer on error.
+ */
+struct drm_pagemap *
+drm_pagemap_create(struct device *dev,
+  struct dev_pagemap *pagemap,
+  const struct drm_pagemap_ops *ops)
+{
+   struct drm_pagemap *dpagemap = kzalloc(sizeof(*dpagemap), GFP_KERNEL);
+
+   if (!dpagemap)
+   return ERR_PTR(-ENOMEM);
+
+   kref_init(&dpagemap->ref);
+   dpagemap->dev = dev;
+   dpagemap->ops = ops;
+   dpagemap->pagemap = pagemap;
+
+   return dpagemap;
+}
+EXPORT_SYMBOL(drm_pagemap_create);
+
+/**
+ * drm_pagemap_put() - Put a struct drm_pagemap reference
+ * @dpagemap: Pointer to a struct drm_pagemap object.
+ *
+ * Puts a struct drm_pagemap reference and frees the drm_pagemap object
+ * if the refount reaches zero.
+ */
+void drm_pagemap_put(struct drm_pagemap *dpagemap)
+{
+   kref_put(&dpagemap->ref, drm_pagemap_release);
+}
+EXPORT_SYMBOL(drm_pagemap_put);
+
 /**
  * drm_pagemap_evict_to_ram() - Evict GPU SVM range to RAM
  * @devmem_allocation: Pointer to the device memory allocation
diff --git a/drivers/gpu/drm/xe/xe_device_types.h 
b/drivers/gpu/drm/xe/xe_device_types.h
index d288a5880508..40c6f88f5933 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -116,7 +116,7 @@ struct xe_vram_region {
 * @dpagemap: The struct drm_pagemap of the ZONE_DEVICE memory
 * pages of this tile.
 */
-   struct drm_pagemap dpagemap;
+   struct drm_pagemap *dpagemap;
/**
 * @hpa_base: base host physical address
 *
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index 36ae7d6a218b..37e1607052ed 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -670,7 +670,8 @@ static int xe_dr

[PULL] drm-xe-fixes

2025-03-13 Thread Rodrigo Vivi
Hi Dave and Sima,

Here goes xe fixes for this week.

It is worth mention that we are disabling D3Cold on BMG because
we found some bugs where depending on the combination of BMG
card and the host, the PCI upstream port link port re-training
might fail on D3Cold -> D0 blowing things up. But while we
work with that and propagating this protection to the end
users, we are not disabling in our drm-tip to ensure that our
developers and CI can continue working with D3Cold enabled.
Everything we disable behind flags for developers will likely
be forgotten and regressions will pile up and be harder later
to re-enable it.

So, topic/xe-for-CI re-enables D3Cold. If developers ends up
having a bad combination they can workaround it by boot
parameter pcie_port_pm=off or with
echo 0 > /sys/bus/pci/devices//vram_d3cold_threshold

Also, the topic branch solution helps us to avoid adding the
controversial module parameters. But if there's any concern
or issues with this approach, please let me know.

Thanks,
Rodrigo.

drm-xe-fixes-2025-03-13:
- Release guc ids before cancelling work (Tejas)
- Fix new warnings around userptr (Thomas)
- Temporaritly disable D3Cold on BMG (Rodrigo)
- Retry and wait longer for GuC PC to start (Rodrigo)
- Remove redundant check in xe_vm_create_ioctl (Xin)
The following changes since commit 80e54e84911a923c40d7bee33a34c1b4be148d7a:

  Linux 6.14-rc6 (2025-03-09 13:45:25 -1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/xe/kernel.git tags/drm-xe-fixes-2025-03-13

for you to fetch changes up to f5d4e81774c42d9c2ea3980e570f3330ff2ed5d2:

  drm/xe: remove redundant check in xe_vm_create_ioctl() (2025-03-10 14:01:43 
-0400)


- Release guc ids before cancelling work (Tejas)
- Fix new warnings around userptr (Thomas)
- Temporaritly disable D3Cold on BMG (Rodrigo)
- Retry and wait longer for GuC PC to start (Rodrigo)
- Remove redundant check in xe_vm_create_ioctl (Xin)


Rodrigo Vivi (2):
  drm/xe/pm: Temporarily disable D3Cold on BMG
  drm/xe/guc_pc: Retry and wait longer for GuC PC start

Tejas Upadhyay (1):
  drm/xe: Release guc ids before cancelling work

Thomas Hellström (1):
  drm/xe/userptr: Fix an incorrect assert

Xin Wang (1):
  drm/xe: remove redundant check in xe_vm_create_ioctl()

 drivers/gpu/drm/xe/xe_guc_pc.c | 53 --
 drivers/gpu/drm/xe/xe_guc_submit.c |  2 +-
 drivers/gpu/drm/xe/xe_hmm.c|  6 -
 drivers/gpu/drm/xe/xe_pm.c | 13 +-
 drivers/gpu/drm/xe/xe_vm.c |  3 ---
 5 files changed, 58 insertions(+), 19 deletions(-)


Re: [PATCH 1/2] lib/vsprintf: Add support for generic FourCCs by extending %p4cc

2025-03-13 Thread Aditya Garg


> On 13 Mar 2025, at 2:19 PM, Andy Shevchenko 
>  wrote:
> 
> On Thu, Mar 13, 2025 at 07:26:05AM +, Aditya Garg wrote:
 On 13 Mar 2025, at 12:58 AM, Andy Shevchenko 
  wrote:
>>> On Wed, Mar 12, 2025 at 07:14:36PM +, Aditya Garg wrote:
> On 12 Mar 2025, at 9:05 PM, Sven Peter  wrote:
> On Wed, Mar 12, 2025, at 13:03, Aditya Garg wrote:
> 
> ...
> 
> I don't have a strong opinion either way: for SMC I just need to print
> FourCC keys for debugging / information in a few places.
> 
> I'm preparing the SMC driver for upstreaming again (after a two year 
> delay :-()
> and was just going to use macros to print the SMC FourCC keys similar to
> DRM_MODE_FMT/DRM_MODE_ARG for now to keep the series smaller and revisit
> the topic later.
> 
> Right now I have these in my local tree (only compile tested so far):
> 
> #define SMC_KEY_FMT "%c%c%c%c (0x%08x)"
> #define SMC_KEY_ARG(k) (k)>>24, (k)>>16, (k)>>8, (k), (k)
 
 That seems to be a nice alternative, which I guess Thomas was also 
 suggesting.
>>> 
>>> I don't think it's "nice". Each of the approaches has pros and cons.
>>> You can start from bloat-o-meter here and compare it with your %p extension.
>>> 
>>> Also, can you show the bloat-o-meter output for the vsprintf.c?
>> 
>> Here are your outputs:
> 
> Thank you!
> 
>> -
>> For appletbdrm:
>> 
>> aditya@MacBook:~/linux$ ./scripts/bloat-o-meter $P4 $MACRO
>> add/remove: 0/0 grow/shrink: 1/1 up/down: 64/-19 (45)
>> Function old new   delta
>> appletbdrm_read_response 395 459 +64
>> appletbdrm_probe17861767 -19
>> Total: Before=13418, After=13463, chg +0.34%
> 
> This is enough, no need to repeat this for every parameter.
> 
>> -
>> For vsprintf:
>> 
>> aditya@MacBook:~/linux$ ./scripts/bloat-o-meter $OLD $NEW
>> add/remove: 0/0 grow/shrink: 1/0 up/down: 220/0 (220)
>> Function old new   delta
>> fourcc_string479 699+220
>> Total: Before=26454, After=26674, chg +0.83%
> 
> So, we get +220 bytes vs +43 bytes. It means if we found 5+ users, it worth
> doing.
> 

Will it also depend upon the number of times it's being used? In appletbdrm, it 
is being used 3 times. Probably more in Asahi SMC.
> which are then used like this:
> 
> dev_info(dev,
> "Initialized (%d keys " SMC_KEY_FMT " .. " SMC_KEY_FMT ")\n",
>  smc->key_count, SMC_KEY_ARG(smc->first_key),
>  SMC_KEY_ARG(smc->last_key));
> 
> --
> With Best Regards,
> Andy Shevchenko
> 
> 


Re: [PATCH v4 07/14] arm64: Add support for suppressing warning backtraces

2025-03-13 Thread Alessandro Carminati
Hello Will,

On Thu, Mar 13, 2025 at 1:25 PM Will Deacon  wrote:
>
> On Thu, Mar 13, 2025 at 11:43:22AM +, Alessandro Carminati wrote:
> > diff --git a/arch/arm64/include/asm/bug.h b/arch/arm64/include/asm/bug.h
> > index 28be048db3f6..044c5e24a17d 100644
> > --- a/arch/arm64/include/asm/bug.h
> > +++ b/arch/arm64/include/asm/bug.h
> > @@ -11,8 +11,14 @@
> >
> >  #include 
> >
> > +#ifdef HAVE_BUG_FUNCTION
> > +# define __BUG_FUNC  __func__
> > +#else
> > +# define __BUG_FUNC  NULL
> > +#endif
> > +
> >  #define __BUG_FLAGS(flags)   \
> > - asm volatile (__stringify(ASM_BUG_FLAGS(flags)));
> > + asm volatile (__stringify(ASM_BUG_FLAGS(flags, %c0)) : : "i" 
> > (__BUG_FUNC));
>
> Why is 'i' the right asm constraint to use here? It seems a bit odd to
> use that for a pointer.

I received this code as legacy from a previous version.
In my review, I considered the case when HAVE_BUG_FUNCTION is defined:
Here, __BUG_FUNC is defined as __func__, which is the name of the
current function as a string literal.
Using the constraint "i" seems appropriate to me in this case.

However, when HAVE_BUG_FUNCTION is not defined:
__BUG_FUNC is defined as NULL. Initially, I considered it literal 0,
but after investigating your concern, I found:

```
$ echo -E "#include \n#include \nint main()
{\nreturn 0;\n}" | aarch64-linux-gnu-gcc -E -dM - | grep NULL
#define NULL ((void *)0)
```

I realized that NULL is actually a pointer that is not a link time
symbol, and using the "i" constraint with NULL may result in undefined
behavior.

Would the following alternative definition for __BUG_FUNC be more convincing?

```
#ifdef HAVE_BUG_FUNCTION
#define __BUG_FUNC __func__
#else
#define __BUG_FUNC (uintptr_t)0
#endif
```
Let me know your thoughts.

>
> Will
>



--
---
172



  1   2   3   >