[PATCH 1/5] drm/dp: Pull drm_dp_link_power_up/down from Tegra to common drm_dp_helper
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
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
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
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
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
> 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
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
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
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
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
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
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
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
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
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
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
+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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
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()
… > 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()
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
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
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
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()
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
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
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
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
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
> 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
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
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
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
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
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
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
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()
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
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
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
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
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()
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
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
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
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/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
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
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
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
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
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
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
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
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
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
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()
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
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()
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
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
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
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
> 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
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